]> git.mxchange.org Git - friendica.git/blob - src/Util/Config/ConfigCacheSaver.php
Added first version of ConfigCacheSaver
[friendica.git] / src / Util / Config / ConfigCacheSaver.php
1 <?php
2
3 namespace Friendica\Util\Config;
4
5 /**
6  * The ConfigCacheSaver saves specific variables back from the ConfigCache (@see ConfigCache )
7  * into the config-files
8  *
9  * It is capable of loading the following config files:
10  * - *.config.php   (current)
11  * - *.ini.php      (deprecated)
12  * - *.htconfig.php (deprecated)
13  */
14 class ConfigCacheSaver extends ConfigCacheManager
15 {
16         /**
17          * The standard indentation for config files
18          * @var string
19          */
20         const INDENT = "\t";
21
22         /**
23          * Saves a given value to the config file
24          * Either it replaces the current value or it will get added
25          *
26          * @param string $cat   The configuration category
27          * @param string $key   The configuration key
28          * @param string $value The new value
29          */
30         public function saveToConfigFile($cat, $key, $value)
31         {
32                 $this->saveToLegacyConfig('htpreconfig', $cat, $key, $value);
33                 $this->saveToLegacyConfig('htconfig', $cat, $key, $value);
34                 $this->saveToCoreConfig('local', $cat, $key, $value);
35         }
36
37         /**
38          * Saves a value to either an config or an ini file
39          *
40          * @param string $name  The configuration file name ('local', 'addon', ..)
41          * @param string $cat   The configuration category
42          * @param string $key   The configuration key
43          * @param string $value The new value
44          */
45         private function saveToCoreConfig($name, $cat, $key, $value)
46         {
47                 if (!empty($this->getConfigFullName($name))) {
48                         $this->saveConfigFile($this->getConfigFullName($name), $cat, $key, $value);
49                 } elseif (!empty($this->getIniFullName($name))) {
50                         $this->saveINIConfigFile($this->getIniFullName($name), $cat, $key, $value);
51                 } else {
52                         return;
53                 }
54         }
55
56         /**
57          * Saves a value to a config file
58          *
59          * @param string $fullName The configuration full name (including the path)
60          * @param string $cat   The configuration category
61          * @param string $key   The configuration key
62          * @param string $value The new value
63          *
64          * @throws \Exception In case a file operation doesn't work
65          */
66         private function saveConfigFile($fullName, $cat, $key, $value)
67         {
68                 $reading = fopen($fullName, 'r');
69                 if (!$reading) {
70                         throw new \Exception('Cannot open config file \'' . $fullName . '\'.');
71                 }
72                 $writing = fopen($fullName . '.tmp', 'w');
73                 if (!$writing) {
74                         throw new \Exception('Cannot create temporary config file \'' . $fullName . '.tmp\'.');
75                 }
76                 $categoryFound = false;
77                 $categoryBracketFound = false;
78                 $lineFound = false;
79                 $lineArrowFound = false;
80                 while (!feof($reading)) {
81                         $line = fgets($reading);
82                         // find the first line like "'system' =>"
83                         if (!$categoryFound && stristr($line, sprintf('\'%s\'', $cat))) {
84                                 $categoryFound = true;
85                         }
86                         // find the first line with a starting bracket ( "[" )
87                         if ($categoryFound && !$categoryBracketFound && stristr($line, '[')) {
88                                 $categoryBracketFound = true;
89                         }
90                         // find the first line with the key like "'value'"
91                         if ($categoryBracketFound && !$lineFound && stristr($line, sprintf('\'%s\'', $key))) {
92                                 $lineFound = true;
93                         }
94                         // find the first line with an arrow ("=>") after finding the key
95                         if ($lineFound && !$lineArrowFound && stristr($line, '=>')) {
96                                 $lineArrowFound = true;
97                         }
98                         // find the current value and replace it
99                         if ($lineArrowFound && preg_match_all('/\'(.*?)\'/', $line, $matches, PREG_SET_ORDER)) {
100                                 $lineVal = end($matches)[0];
101                                 $writeLine = str_replace($lineVal, '\'' . $value . '\'', $line);
102                                 $categoryFound = false;
103                                 $categoryBracketFound = false;
104                                 $lineFound = false;
105                                 $lineArrowFound = false;
106                                 // if a line contains a closing bracket for the category ( "]" ) and we didn't find the key/value pair,
107                                 // add it as a new line before the closing bracket
108                         } elseif ($categoryBracketFound && !$lineArrowFound && stristr($line, ']')) {
109                                 $categoryFound = false;
110                                 $categoryBracketFound = false;
111                                 $lineFound = false;
112                                 $lineArrowFound = false;
113                                 $writeLine = sprintf(self::INDENT . self::INDENT .'\'%s\' => \'%s\',' . PHP_EOL, $key, $value);
114                                 $writeLine .= $line;
115                         } else {
116                                 $writeLine = $line;
117                         }
118                         fputs($writing, $writeLine);
119                 }
120                 if (!fclose($reading)) {
121                         throw new \Exception('Cannot close config file \'' . $fullName . '\'.');
122                 };
123                 if (!fclose($writing)) {
124                         throw new \Exception('Cannot close temporary config file \'' . $fullName . '.tmp\'.');
125                 };
126                 if (!rename($fullName, $fullName . '.old')) {
127                         throw new \Exception('Cannot backup current config file \'' . $fullName . '\'.');
128                 }
129                 if (!rename($fullName . '.tmp', $fullName)) {
130                         throw new \Exception('Cannot move temporary config file \'' . $fullName . '.tmp\' to current.');
131                 }
132         }
133
134         /**
135          * Saves a value to a ini file
136          *
137          * @param string $fullName The configuration full name (including the path)
138          * @param string $cat   The configuration category
139          * @param string $key   The configuration key
140          * @param string $value The new value
141          */
142         private function saveINIConfigFile($fullName, $cat, $key, $value)
143         {
144                 $reading = fopen($fullName, 'r');
145                 $writing = fopen($fullName . '.tmp', 'w');
146                 $categoryFound = false;
147                 while (!feof($reading)) {
148                         $line = fgets($reading);
149                         if (!$categoryFound && stristr($line, sprintf('[%s]', $cat))) {
150                                 $categoryFound = true;
151                                 $writeLine = $line;
152                         } elseif ($categoryFound && preg_match_all('/^' . $key . '\s*=\s*(.*?)$/', $line, $matches, PREG_SET_ORDER)) {
153                                 $writeLine = $key . ' = ' . $value . PHP_EOL;
154                                 $categoryFound = false;
155                         } elseif ($categoryFound && (preg_match_all('/^\[.*?\]$/', $line) || preg_match_all('/^INI;.*$/', $line))) {
156                                 $categoryFound = false;
157                                 $writeLine = $key . ' = ' .  $value . PHP_EOL;
158                                 $writeLine .= $line;
159                         } else {
160                                 $writeLine = $line;
161                         }
162                         fputs($writing, $writeLine);
163                 }
164                 fclose($reading);
165                 fclose($writing);
166                 rename($fullName, $fullName . '.old');
167                 rename($fullName . '.tmp', $fullName);
168         }
169
170         private function saveToLegacyConfig($name, $cat, $key, $value)
171         {
172                 if (empty($this->getHtConfigFullName($name))) {
173                         return;
174                 }
175                 $fullName = $this->getHtConfigFullName($name);
176                 $reading = fopen($fullName, 'r');
177                 $writing = fopen($fullName . '.tmp', 'w');
178                 $found = false;
179                 while (!feof($reading)) {
180                         $line = fgets($reading);
181                         if (preg_match_all('/^\$a\-\>config\[\'' . $cat . '\',\'' . $key . '\'\]\s*=\s\'*(.*?)\'$/', $line, $matches, PREG_SET_ORDER)) {
182                                 $writeLine = $key . ' = ' . $value . PHP_EOL;
183                                 $found = true;
184                         } else {
185                                 $writeLine = $line;
186                         }
187                         fputs($writing, $writeLine);
188                 }
189                 if (!$found) {
190                         $writeLine = $key . ' = ' . $value . PHP_EOL;
191                         fputs($writing, $writeLine);
192                 }
193                 fclose($reading);
194                 fclose($writing);
195                 rename($fullName, $fullName . '.old');
196                 rename($fullName . '.tmp', $fullName);
197         }
198 }