This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | // +---------------------------------------------------------------------------+ |
||
4 | // | This file is part of the Agavi package. | |
||
5 | // | Copyright (c) 2005-2011 the Agavi Project. | |
||
6 | // | Based on the Mojavi3 MVC Framework, Copyright (c) 2003-2005 Sean Kerr. | |
||
7 | // | | |
||
8 | // | For the full copyright and license information, please view the LICENSE | |
||
9 | // | file that was distributed with this source code. You can also view the | |
||
10 | // | LICENSE file online at http://www.agavi.org/LICENSE.txt | |
||
11 | // | vi: set noexpandtab: | |
||
12 | // | Local Variables: | |
||
13 | // | indent-tabs-mode: t | |
||
14 | // | End: | |
||
15 | // +---------------------------------------------------------------------------+ |
||
16 | |||
17 | namespace Agavi\Config; |
||
18 | |||
19 | use Agavi\Exception\AgaviException; |
||
20 | use Agavi\Exception\CacheException; |
||
21 | use Agavi\Util\Toolkit; |
||
22 | use Agavi\Core\Context; |
||
23 | use Agavi\Exception\UnreadableException; |
||
24 | use Agavi\Exception\ConfigurationException; |
||
25 | |||
26 | /** |
||
27 | * ConfigCache allows you to customize the format of a configuration |
||
28 | * file to make it easy-to-use, yet still provide a PHP formatted result |
||
29 | * for direct inclusion into your modules. |
||
30 | * |
||
31 | * @package agavi |
||
32 | * @subpackage config |
||
33 | * |
||
34 | * @author Sean Kerr <[email protected]> |
||
35 | * @copyright Authors |
||
36 | * @copyright The Agavi Project |
||
37 | * |
||
38 | * @since 0.9.0 |
||
39 | * |
||
40 | * @version $Id$ |
||
41 | */ |
||
42 | class ConfigCache |
||
43 | { |
||
44 | const CACHE_SUBDIR = 'config'; |
||
45 | |||
46 | /** |
||
47 | * @var array An array of config handler instructions. |
||
48 | */ |
||
49 | protected static $handlers = null; |
||
50 | |||
51 | /** |
||
52 | * @var array A string=>bool array containing config handler files and |
||
53 | * their loaded status. |
||
54 | */ |
||
55 | protected static $handlerFiles = array(); |
||
56 | |||
57 | /** |
||
58 | * @var bool Whether there is an entry in self::$handlerFiles that |
||
59 | * needs processing. |
||
60 | */ |
||
61 | protected static $handlersDirty = true; |
||
62 | |||
63 | /** |
||
64 | * @var bool Whether the config handler files have been required. |
||
65 | */ |
||
66 | protected static $filesIncluded = false; |
||
67 | |||
68 | /** |
||
69 | * Load a configuration handler. |
||
70 | * |
||
71 | * @param string $name The path of the originally requested configuration file. |
||
72 | * @param string $config An absolute filesystem path to a configuration file. |
||
73 | * @param string $cache An absolute filesystem path to the cache file that |
||
74 | * will be written. |
||
75 | * @param string $context The context which we're currently running. |
||
76 | * @param array $handlerInfo Optional config handler info array. |
||
77 | * |
||
78 | * @throws <b>ConfigurationException</b> If a requested configuration |
||
79 | * file does not have an |
||
80 | * associated config handler. |
||
81 | * |
||
82 | * @author David Zülke <[email protected]> |
||
83 | * @author Dominik del Bondio <[email protected]> |
||
84 | * @author Felix Gilcher <[email protected]> |
||
85 | * @since 0.9.0 |
||
86 | */ |
||
87 | protected static function callHandler($name, $config, $cache, $context, array $handlerInfo = null) |
||
88 | { |
||
89 | self::setupHandlers(); |
||
90 | |||
91 | if (null === $handlerInfo) { |
||
92 | // we need to load the handlers first |
||
93 | $handlerInfo = self::getHandlerInfo($name); |
||
94 | } |
||
95 | |||
96 | if ($handlerInfo === null) { |
||
97 | // we do not have a registered handler for this file |
||
98 | $error = 'Configuration file "%s" does not have a registered handler'; |
||
99 | $error = sprintf($error, $name); |
||
100 | throw new ConfigurationException($error); |
||
101 | } |
||
102 | |||
103 | $data = self::executeHandler($config, $context, $handlerInfo); |
||
104 | self::writeCacheFile($config, $cache, $data, false); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Set up all config handler definitions. |
||
109 | * |
||
110 | * Checks whether the handlers have been loaded or the dirtyHandlers flat is |
||
111 | * set, and loads any handler that has not been loaded. |
||
112 | * |
||
113 | * @author Felix Gilcher <[email protected]> |
||
114 | * @since 1.0.0 |
||
115 | */ |
||
116 | protected static function setupHandlers() |
||
117 | { |
||
118 | self::loadConfigHandlers(); |
||
119 | |||
120 | if (self::$handlersDirty) { |
||
121 | // set handlersdirty to false, prevent an infinite loop |
||
122 | self::$handlersDirty = false; |
||
123 | // load additional config handlers |
||
124 | foreach (self::$handlerFiles as $filename => &$loaded) { |
||
125 | if (!$loaded) { |
||
126 | self::loadConfigHandlersFile($filename); |
||
127 | $loaded = true; |
||
128 | } |
||
129 | } |
||
130 | } |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * Fetch the handler information for the given filename. |
||
135 | * |
||
136 | * @param string $name The name of the config file (partial path). |
||
137 | * |
||
138 | * @return array The handler info. |
||
139 | * |
||
140 | * @author Felix Gilcher <[email protected]> |
||
141 | * @since 1.0.0 |
||
142 | */ |
||
143 | protected static function getHandlerInfo($name) |
||
144 | { |
||
145 | // grab the base name of the originally requested config path |
||
146 | $basename = basename($name); |
||
147 | |||
148 | $handlerInfo = null; |
||
149 | |||
150 | if (isset(self::$handlers[$name])) { |
||
151 | // we have a handler associated with the full configuration path |
||
152 | $handlerInfo = self::$handlers[$name]; |
||
153 | } elseif (isset(self::$handlers[$basename])) { |
||
154 | // we have a handler associated with the configuration base name |
||
155 | $handlerInfo = self::$handlers[$basename]; |
||
156 | } else { |
||
157 | // let's see if we have any wildcard handlers registered that match |
||
158 | // this basename |
||
159 | foreach (self::$handlers as $key => $value) { |
||
160 | // replace wildcard chars in the configuration and create the pattern |
||
161 | $pattern = sprintf('#%s#', str_replace('\*', '.*?', preg_quote($key, '#'))); |
||
162 | |||
163 | if (preg_match($pattern, $name)) { |
||
164 | $handlerInfo = $value; |
||
165 | break; |
||
166 | } |
||
167 | } |
||
168 | } |
||
169 | |||
170 | return $handlerInfo; |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Execute the config handler for the given file. |
||
175 | * |
||
176 | * @param string $config The path to the config file (full path). |
||
177 | * @param string $context The context which we're currently running. |
||
178 | * @param array $handlerInfo The config handler info. |
||
179 | * |
||
180 | * @return string The compiled data. |
||
181 | * |
||
182 | * @author Felix Gilcher <[email protected]> |
||
183 | * @since 1.0.0 |
||
184 | */ |
||
185 | protected static function executeHandler($config, $context, array $handlerInfo) |
||
186 | { |
||
187 | // call the handler and retrieve the cache data |
||
188 | /** @var ConfigHandler $handler */ |
||
189 | $handler = new $handlerInfo['class']; |
||
190 | if ($handler instanceof XmlConfigHandlerInterface) { |
||
191 | // a new-style config handler |
||
192 | // it does not parse the config itself; instead, it is given a complete and merged DOM document |
||
193 | $doc = XmlConfigParser::run($config, Config::get('core.environment'), $context, $handlerInfo['transformations'], $handlerInfo['validations']); |
||
194 | |||
195 | if ($context !== null) { |
||
196 | $context = Context::getInstance($context); |
||
197 | } |
||
198 | |||
199 | $handler->initialize($context, $handlerInfo['parameters']); |
||
200 | |||
201 | try { |
||
202 | $data = $handler->execute($doc); |
||
203 | } catch (AgaviException $e) { |
||
204 | throw new $e(sprintf("Compilation of configuration file '%s' failed for the following reason(s):\n\n%s", $config, $e->getMessage()), 0, $e); |
||
205 | } |
||
206 | } else { |
||
207 | $validationFile = null; |
||
208 | if (isset($handlerInfo['validations'][XmlConfigParser::STAGE_SINGLE][XmlConfigParser::STEP_TRANSFORMATIONS_AFTER][XmlConfigParser::VALIDATION_TYPE_XMLSCHEMA][0])) { |
||
209 | $validationFile = $handlerInfo['validations'][XmlConfigParser::STAGE_SINGLE][XmlConfigParser::STEP_TRANSFORMATIONS_AFTER][XmlConfigParser::VALIDATION_TYPE_XMLSCHEMA][0]; |
||
210 | } |
||
211 | $handler->initialize($validationFile, null, $handlerInfo['parameters']); |
||
212 | $data = $handler->execute($config, $context); |
||
213 | } |
||
214 | |||
215 | return $data; |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Check to see if a configuration file has been modified and if so |
||
220 | * recompile the cache file associated with it. |
||
221 | * |
||
222 | * If the configuration file path is relative, the path itself is relative |
||
223 | * to the Agavi "core.app_dir" application setting. |
||
224 | * |
||
225 | * @param string $config A filesystem path to a configuration file. |
||
226 | * @param string $context An optional context name for which the config should be read. |
||
227 | * |
||
228 | * @return string An absolute filesystem path to the cache filename |
||
229 | * associated with this specified configuration file. |
||
230 | * |
||
231 | * @throws <b>UnreadableException</b> If a requested configuration |
||
232 | * file does not exist. |
||
233 | * |
||
234 | * @author Sean Kerr <[email protected]> |
||
235 | * @since 0.9.0 |
||
236 | */ |
||
237 | public static function checkConfig($config, $context = null) |
||
238 | { |
||
239 | $config = Toolkit::normalizePath($config); |
||
240 | // the full filename path to the config, which might not be what we were given. |
||
241 | $filename = Toolkit::isPathAbsolute($config) ? $config : Toolkit::normalizePath(Config::get('core.app_dir')) . '/' . $config; |
||
242 | |||
243 | $filename = realpath($filename); |
||
244 | if (!is_readable($filename)) { |
||
245 | throw new UnreadableException('Configuration file "' . $filename . '" does not exist or is unreadable.'); |
||
246 | } |
||
247 | |||
248 | // the cache filename we'll be using |
||
249 | $cache = self::getCacheName($config, $context); |
||
250 | |||
251 | if (self::isModified($filename, $cache)) { |
||
252 | // configuration file has changed so we need to reparse it |
||
253 | self::callHandler($config, $filename, $cache, $context); |
||
254 | } |
||
255 | |||
256 | return $cache; |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * Check if the cached version of a file is up to date. |
||
261 | * |
||
262 | * @param string $filename The source file. |
||
263 | * @param string $cachename The name of the cached version. |
||
264 | * |
||
265 | * @return bool Whether or not the cached file must be updated. |
||
266 | * |
||
267 | * @author David Zülke <[email protected]> |
||
268 | * @since 0.11.0 |
||
269 | */ |
||
270 | public static function isModified($filename, $cachename) |
||
271 | { |
||
272 | return (!is_readable($cachename) || filemtime($filename) > filemtime($cachename)); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Clear all configuration cache files. |
||
277 | * |
||
278 | * @author Sean Kerr <[email protected]> |
||
279 | * @since 0.9.0 |
||
280 | */ |
||
281 | public static function clear() |
||
282 | { |
||
283 | Toolkit::clearCache(self::CACHE_SUBDIR); |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * Convert a normal filename into a cache filename. |
||
288 | * |
||
289 | * @param string $config A normal filename. |
||
290 | * @param string $context A context name. |
||
291 | * |
||
292 | * @return string An absolute filesystem path to a cache filename. |
||
293 | * |
||
294 | * @author Sean Kerr <[email protected]> |
||
295 | * @since 0.9.0 |
||
296 | */ |
||
297 | public static function getCacheName($config, $context = null) |
||
298 | { |
||
299 | $environment = Config::get('core.environment'); |
||
300 | |||
301 | if (strlen($config) > 3 && ctype_alpha($config[0]) && $config[1] == ':' && ($config[2] == '\\' || $config[2] == '/')) { |
||
302 | // file is a windows absolute path, strip off the drive letter |
||
303 | $config = substr($config, 3); |
||
304 | } |
||
305 | |||
306 | // replace unfriendly filename characters with an underscore and postfix the name with a php extension |
||
307 | // see http://trac.agavi.org/wiki/RFCs/Ticket932 for an explanation how cache names are constructed |
||
308 | $cacheName = sprintf( |
||
309 | '%1$s_%2$s.php', |
||
310 | preg_replace( |
||
311 | '/[^\w-_.]/i', |
||
312 | '_', |
||
313 | sprintf( |
||
314 | '%1$s_%2$s_%3$s', |
||
315 | basename($config), |
||
316 | $environment, |
||
317 | $context |
||
318 | ) |
||
319 | ), |
||
320 | sha1( |
||
321 | sprintf( |
||
322 | '%1$s_%2$s_%3$s', |
||
323 | $config, |
||
324 | $environment, |
||
325 | $context |
||
326 | ) |
||
327 | ) |
||
328 | ); |
||
329 | |||
330 | return Config::get('core.cache_dir') . DIRECTORY_SEPARATOR . self::CACHE_SUBDIR . DIRECTORY_SEPARATOR . $cacheName; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * Import a configuration file. |
||
335 | * |
||
336 | * If the configuration file path is relative, the path itself is relative |
||
337 | * to the Agavi "core.app_dir" application setting. |
||
338 | * |
||
339 | * @param string $config A filesystem path to a configuration file. |
||
340 | * @param string $context A context name. |
||
341 | * @param bool $once Only allow this configuration file to be included once |
||
342 | * per request? |
||
343 | * |
||
344 | * @author Sean Kerr <[email protected]> |
||
345 | * @since 0.9.0 |
||
346 | */ |
||
347 | public static function load($config, $context = null, $once = true) |
||
348 | { |
||
349 | $cache = self::checkConfig($config, $context); |
||
350 | |||
351 | if ($once) { |
||
352 | include_once($cache); |
||
353 | } else { |
||
354 | include($cache); |
||
355 | } |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Load all configuration application and module level handlers. |
||
360 | * |
||
361 | * @throws ConfigurationException If a configuration related |
||
362 | * error occurs. |
||
363 | * |
||
364 | * @author Sean Kerr <[email protected]> |
||
365 | * @since 0.9.0 |
||
366 | */ |
||
367 | protected static function loadConfigHandlers() |
||
368 | { |
||
369 | if (self::$handlers !== null) { |
||
370 | return; |
||
371 | } else { |
||
372 | self::$handlers = array(); |
||
373 | } |
||
374 | |||
375 | // some checks first |
||
376 | if (!defined('LIBXML_DOTTED_VERSION') || (!Config::get('core.ignore_broken_libxml', false) && !version_compare(LIBXML_DOTTED_VERSION, '2.6.16', 'gt'))) { |
||
0 ignored issues
–
show
|
|||
377 | throw new \Exception("A libxml version greater than 2.6.16 is highly recommended. With version 2.6.16 and possibly later releases, validation of XML configuration files will not work and Form Population Filter will eventually fail randomly on some documents due to *severe bugs* in older libxml releases (2.6.16 was released in November 2004, so it is really getting time to update).\n\nIf you still would like to try your luck, disable this message by doing\nAgaviConfig::set('core.ignore_broken_libxml', true);\nand\nAgaviConfig::set('core.skip_config_validation', true);\nbefore calling\nAgavi::bootstrap();\nin index.php (app/config.php is not the right place for this).\n\nBut be advised that you *will* run into segfaults and other sad situations eventually, so what you should really do is upgrade your libxml install."); |
||
378 | } |
||
379 | |||
380 | $agaviDir = Config::get('core.agavi_dir'); |
||
381 | |||
382 | // :NOTE: fgilcher, 2008-12-03 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
42% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
383 | // we need this method reentry safe for unit testing |
||
384 | // sorry for the testing code in the class, but I don't have |
||
385 | // any other idea to solve the issue |
||
386 | if (!self::$filesIncluded) { |
||
387 | // since we only need the parser and handlers when the config is not cached |
||
388 | // it is sufficient to include them at this stage |
||
389 | require_once($agaviDir . '/config/LegacyConfigHandler.interface.php'); |
||
390 | require_once($agaviDir . '/config/XmlConfigHandler.interface.php'); |
||
391 | require_once($agaviDir . '/config/BaseConfigHandler.class.php'); |
||
392 | require_once($agaviDir . '/config/ConfigHandler.class.php'); |
||
393 | require_once($agaviDir . '/config/XmlConfigHandler.class.php'); |
||
394 | require_once($agaviDir . '/config/AutoloadConfigHandler.class.php'); |
||
395 | require_once($agaviDir . '/config/ConfigHandlersConfigHandler.class.php'); |
||
396 | require_once($agaviDir . '/config/ConfigValueHolder.class.php'); |
||
397 | require_once($agaviDir . '/config/ConfigParser.class.php'); |
||
398 | require_once($agaviDir . '/config/XmlConfigParser.class.php'); |
||
399 | // extended DOM* classes |
||
400 | require_once($agaviDir . '/config/util/dom/XmlConfigDomAttr.class.php'); |
||
401 | require_once($agaviDir . '/config/util/dom/XmlConfigDomCharacterData.class.php'); |
||
402 | require_once($agaviDir . '/config/util/dom/XmlConfigDomComment.class.php'); |
||
403 | require_once($agaviDir . '/config/util/dom/XmlConfigDomDocument.class.php'); |
||
404 | require_once($agaviDir . '/config/util/dom/XmlConfigDomDocumentFragment.class.php'); |
||
405 | require_once($agaviDir . '/config/util/dom/XmlConfigDomDocumentType.class.php'); |
||
406 | require_once($agaviDir . '/config/util/dom/XmlConfigDomElement.class.php'); |
||
407 | require_once($agaviDir . '/config/util/dom/XmlConfigDomEntity.class.php'); |
||
408 | require_once($agaviDir . '/config/util/dom/XmlConfigDomEntityReference.class.php'); |
||
409 | require_once($agaviDir . '/config/util/dom/XmlConfigDomNode.class.php'); |
||
410 | require_once($agaviDir . '/config/util/dom/XmlConfigDomNotation.class.php'); |
||
411 | require_once($agaviDir . '/config/util/dom/XmlConfigDomProcessingInstruction.class.php'); |
||
412 | require_once($agaviDir . '/config/util/dom/XmlConfigDomText.class.php'); |
||
413 | // schematron processor |
||
414 | require_once($agaviDir . '/util/SchematronProcessor.class.php'); |
||
415 | // extended XSL* classes |
||
416 | if (!Config::get('core.skip_config_transformations', false)) { |
||
0 ignored issues
–
show
false is of type boolean , but the function expects a string|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
417 | if (!extension_loaded('xsl')) { |
||
418 | throw new ConfigurationException("You do not have the XSL extension for PHP (ext/xsl) installed or enabled. The extension is used by Agavi to perform XSL transformations in the configuration system to guarantee forwards compatibility of applications.\n\nIf you do not want to or can not install ext/xsl, you may disable all transformations by setting\nAgaviConfig::set('core.skip_config_transformations', true);\nbefore calling\nAgavi::bootstrap();\nin index.php (app/config.php is not the right place for this because this is a setting that's specific to your environment or machine).\n\nKeep in mind that disabling transformations mean you *have* to use the latest configuration file formats and namespace versions. Also, certain additional configuration file validations implemented via Schematron will not be performed."); |
||
419 | } |
||
420 | require($agaviDir . '/util/XsltProcessor.class.php'); |
||
421 | } |
||
422 | self::$filesIncluded = true; |
||
423 | } |
||
424 | |||
425 | // manually create our config_handlers.xml handler |
||
426 | self::$handlers['config_handlers.xml'] = array( |
||
427 | 'class' => '\\Agavi\\Config\\ConfigHandlersConfigHandler', |
||
428 | 'parameters' => array( |
||
429 | ), |
||
430 | 'transformations' => array( |
||
431 | XmlConfigParser::STAGE_SINGLE => array( |
||
432 | // 0.11 -> 1.0 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
433 | $agaviDir . '/config/xsl/config_handlers.xsl', |
||
434 | // 1.0 -> 1.0 with AgaviReturnArrayConfigHandler <transformation> for Agavi 1.1 |
||
435 | $agaviDir . '/config/xsl/config_handlers.xsl', |
||
436 | ), |
||
437 | XmlConfigParser::STAGE_COMPILATION => array( |
||
438 | ), |
||
439 | ), |
||
440 | 'validations' => array( |
||
441 | XmlConfigParser::STAGE_SINGLE => array( |
||
442 | XmlConfigParser::STEP_TRANSFORMATIONS_BEFORE => array( |
||
443 | ), |
||
444 | XmlConfigParser::STEP_TRANSFORMATIONS_AFTER => array( |
||
445 | XmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array( |
||
446 | $agaviDir . '/config/xsd/config_handlers.xsd', |
||
447 | ), |
||
448 | XmlConfigParser::VALIDATION_TYPE_SCHEMATRON => array( |
||
449 | $agaviDir . '/config/sch/config_handlers.sch', |
||
450 | ), |
||
451 | ), |
||
452 | ), |
||
453 | XmlConfigParser::STAGE_COMPILATION => array( |
||
454 | XmlConfigParser::STEP_TRANSFORMATIONS_BEFORE => array(), |
||
455 | XmlConfigParser::STEP_TRANSFORMATIONS_AFTER => array() |
||
456 | ), |
||
457 | ), |
||
458 | ); |
||
459 | |||
460 | $cfg = Config::get('core.config_dir') . '/config_handlers.xml'; |
||
461 | if (!is_readable($cfg)) { |
||
462 | $cfg = Config::get('core.system_config_dir') . '/config_handlers.xml'; |
||
463 | } |
||
464 | // application configuration handlers |
||
465 | self::loadConfigHandlersFile($cfg); |
||
466 | } |
||
467 | |||
468 | /** |
||
469 | * Load the config handlers from the given config file. |
||
470 | * Existing handlers will not be overwritten. |
||
471 | * |
||
472 | * @param string $cfg The path to a config_handlers.xml file. |
||
473 | * |
||
474 | * @author Felix Gilcher <[email protected]> |
||
475 | * @since 1.0.0 |
||
476 | */ |
||
477 | protected static function loadConfigHandlersFile($cfg) |
||
478 | { |
||
479 | self::$handlers = (array)self::$handlers + include(ConfigCache::checkConfig($cfg)); |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * Schedules a config handlers file to be loaded. |
||
484 | * |
||
485 | * @param string $filename The path to a config_handlers.xml file. |
||
486 | * |
||
487 | * @author Dominik del Bondio <[email protected]> |
||
488 | * @since 1.0.0 |
||
489 | */ |
||
490 | public static function addConfigHandlersFile($filename) |
||
491 | { |
||
492 | if (!isset(self::$handlerFiles[$filename])) { |
||
493 | if (!is_readable($filename)) { |
||
494 | throw new UnreadableException('Configuration file "' . $filename . '" does not exist or is unreadable.'); |
||
495 | } |
||
496 | |||
497 | self::$handlerFiles[$filename] = false; |
||
498 | self::$handlersDirty = true; |
||
499 | } |
||
500 | } |
||
501 | |||
502 | /** |
||
503 | * Write a cache file. |
||
504 | * |
||
505 | * @param string $config An absolute filesystem path to a configuration file. |
||
506 | * @param string $cache An absolute filesystem path to the cache file that |
||
507 | * will be written. |
||
508 | * @param string $data Data to be written to the cache file. |
||
509 | * @param bool $append Should we append the data? |
||
510 | * |
||
511 | * @throws <b>CacheException</b> If the cache file cannot be written. |
||
512 | * |
||
513 | * @author Sean Kerr <[email protected]> |
||
514 | * @since 0.9.0 |
||
515 | */ |
||
516 | public static function writeCacheFile($config, $cache, $data, $append = false) |
||
517 | { |
||
518 | $perms = fileperms(Config::get('core.cache_dir')) ^ 0x4000; |
||
519 | |||
520 | $cacheDir = Config::get('core.cache_dir') . DIRECTORY_SEPARATOR . self::CACHE_SUBDIR; |
||
521 | |||
522 | Toolkit::mkdir($cacheDir, $perms); |
||
523 | |||
524 | if ($append && is_readable($cache)) { |
||
525 | $data = file_get_contents($cache) . $data; |
||
526 | } |
||
527 | |||
528 | $tmpName = @tempnam($cacheDir, basename($cache)); |
||
529 | if (@file_put_contents($tmpName, $data) !== false) { |
||
530 | // that worked, but that doesn't mean we're safe yet |
||
531 | // first, we cannot know if the destination directory really was writeable, as tempnam() falls back to the system temp dir |
||
532 | // second, with php < 5.2.6 on win32 renaming to an already existing file doesn't work, but copy does |
||
533 | // so we simply assume that when rename() fails that we are on win32 and try to use copy() followed by unlink() |
||
534 | // if that also fails, we know something's odd |
||
535 | if (@rename($tmpName, $cache) || (@copy($tmpName, $cache) && unlink($tmpName))) { |
||
536 | // alright, it did work after all. chmod() and bail out. |
||
537 | chmod($cache, $perms); |
||
538 | return; |
||
539 | } |
||
540 | } |
||
541 | |||
542 | // still here? |
||
543 | // that means we could not write the cache file |
||
544 | $error = 'Failed to write cache file "%s" generated from ' . 'configuration file "%s".'; |
||
545 | $error .= "\n\n"; |
||
546 | $error .= 'Please make sure you have set correct write permissions for directory "%s".'; |
||
547 | $error = sprintf($error, $cache, $config, Config::get('core.cache_dir')); |
||
548 | throw new CacheException($error); |
||
549 | } |
||
550 | |||
551 | /** |
||
552 | * Parses a config file with the ConfigParser for the extension of the given |
||
553 | * file. |
||
554 | * |
||
555 | * @param string $config An absolute filesystem path to a configuration file. |
||
556 | * @param bool $autoloadParser Whether the config parser class should be autoloaded if |
||
557 | * the class doesn't exist. |
||
558 | * @param string $validationFile A path to a validation file for this config file. |
||
559 | * @param string $parserClass A class name which specifies an parser to be used. |
||
560 | * |
||
561 | * @return ConfigValueHolder An abstract representation of the |
||
562 | * config file. |
||
563 | * |
||
564 | * @throws <b>AgaviConfigurationException</b> If the parser for the |
||
565 | * extension couldn't be found. |
||
566 | * |
||
567 | * @author Dominik del Bondio <[email protected]> |
||
568 | * @author David Zülke <[email protected]> |
||
569 | * @since 0.11.0 |
||
570 | * |
||
571 | * @deprecated New-style config handlers don't call this method anymore. To be |
||
572 | * removed in Agavi 1.1 |
||
573 | */ |
||
574 | public static function parseConfig($config, $autoloadParser = true, $validationFile = null, $parserClass = null) |
||
0 ignored issues
–
show
|
|||
575 | { |
||
576 | $parser = new ConfigParser(); |
||
0 ignored issues
–
show
The class
Agavi\Config\ConfigParser has been deprecated with message: Superseded by XmlConfigParser, will be removed in Agavi 1.1
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead. ![]() |
|||
577 | |||
578 | return $parser->parse($config, $validationFile); |
||
0 ignored issues
–
show
It seems like
$validationFile defined by parameter $validationFile on line 574 can also be of type string ; however, Agavi\Config\ConfigParser::parse() does only seem to accept array|null , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
579 | } |
||
580 | } |
||
581 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: