Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ConfigOptimizer.php
001 <?php
002
003 /**
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2022 The s9e authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter\Configurator\JavaScript;
009
010 /**
011 * This class creates local variables to deduplicate complex configValues
012 */
013 class ConfigOptimizer
014 {
015 /**
016 * @var array Associative array of ConfigValue instances
017 */
018 protected $configValues;
019
020 /**
021 * @var Encoder
022 */
023 protected $encoder;
024
025 /**
026 * @var array Associative array with the length of the JavaScript representation of each value
027 */
028 protected $jsLengths;
029
030 /**
031 * Constructor
032 *
033 * @param Encoder $encoder
034 */
035 public function __construct(Encoder $encoder)
036 {
037 $this->encoder = $encoder;
038 $this->reset();
039 }
040
041 /**
042 * Return the var declarations for all deduplicated config values
043 *
044 * @return string JavaScript code
045 */
046 public function getVarDeclarations()
047 {
048 asort($this->jsLengths);
049
050 $src = '';
051 foreach (array_keys($this->jsLengths) as $varName)
052 {
053 $configValue = $this->configValues[$varName];
054 if ($configValue->isDeduplicated())
055 {
056 $src .= '/** @const */ var ' . $varName . '=' . $this->encoder->encode($configValue->getValue()) . ";\n";
057 }
058 }
059
060 return $src;
061 }
062
063 /**
064 * Optimize given config object
065 *
066 * @param array|Dictionary $object Original config object
067 * @return array|Dictionary Modified config object
068 */
069 public function optimize($object)
070 {
071 return current($this->optimizeObjectContent([$object]))->getValue();
072 }
073
074 /**
075 * Clear the deduplicated config values stored in this instance
076 *
077 * @return void
078 */
079 public function reset()
080 {
081 $this->configValues = [];
082 $this->jsLengths = [];
083 }
084
085 /**
086 * Test whether given value can be deduplicated
087 *
088 * @param mixed $value
089 * @return bool
090 */
091 protected function canDeduplicate($value)
092 {
093 if (is_array($value) || $value instanceof Dictionary)
094 {
095 // Do not deduplicate empty arrays and dictionaries
096 return (bool) count($value);
097 }
098
099 return ($value instanceof Code);
100 }
101
102 /**
103 * Mark ConfigValue instances that have been used multiple times
104 *
105 * @return void
106 */
107 protected function deduplicateConfigValues()
108 {
109 arsort($this->jsLengths);
110 foreach (array_keys($this->jsLengths) as $varName)
111 {
112 $configValue = $this->configValues[$varName];
113 if ($configValue->getUseCount() > 1)
114 {
115 $configValue->deduplicate();
116 }
117 }
118 }
119
120 /**
121 * Return the name of the variable that will a given value
122 *
123 * @param string $js JavaScript representation of the value
124 * @return string
125 */
126 protected function getVarName($js)
127 {
128 return sprintf('o%08X', crc32($js));
129 }
130
131 /**
132 * Test whether given value is iterable
133 *
134 * @param mixed $value
135 * @return bool
136 */
137 protected function isIterable($value)
138 {
139 return (is_array($value) || $value instanceof Dictionary);
140 }
141
142 /**
143 * Optimize given object's content
144 *
145 * @param array|Dictionary $object Original object
146 * @return array|Dictionary Modified object
147 */
148 protected function optimizeObjectContent($object)
149 {
150 $object = $this->recordObject($object);
151 $this->deduplicateConfigValues();
152
153 return $object->getValue();
154 }
155
156 /**
157 * Record a given config object as a ConfigValue instance
158 *
159 * @param array|Code|Dictionary $object Original object
160 * @return ConfigValue Stored ConfigValue instance
161 */
162 protected function recordObject($object)
163 {
164 $js = $this->encoder->encode($object);
165 $varName = $this->getVarName($js);
166
167 if ($this->isIterable($object))
168 {
169 $object = $this->recordObjectContent($object);
170 }
171
172 if (!isset($this->configValues[$varName]))
173 {
174 $this->configValues[$varName] = new ConfigValue($object, $varName);
175 $this->jsLengths[$varName] = strlen($js);
176 }
177 $this->configValues[$varName]->incrementUseCount();
178
179 return $this->configValues[$varName];
180 }
181
182 /**
183 * Record the content of given config object
184 *
185 * @param array|Dictionary $object Original object
186 * @return array|Dictionary Modified object containing ConfigValue instances
187 */
188 protected function recordObjectContent($object)
189 {
190 foreach ($object as $k => $v)
191 {
192 if ($this->canDeduplicate($v) && !$this->shouldPreserve($v))
193 {
194 $object[$k] = $this->recordObject($v);
195 }
196 }
197
198 return $object;
199 }
200
201 /**
202 * Test whether given value should be preserved and not deduplicated
203 *
204 * @param mixed $value
205 * @return bool
206 */
207 protected function shouldPreserve($value)
208 {
209 // Simple variables should be kept as-is
210 return ($value instanceof Code && preg_match('(^\\w+$)', $value));
211 }
212 }