These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * phpDocumentor |
||
4 | * |
||
5 | * PHP Version 5.3 |
||
6 | * |
||
7 | * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com) |
||
8 | * @license http://www.opensource.org/licenses/mit-license.php MIT |
||
9 | * @link http://phpdoc.org |
||
10 | */ |
||
11 | |||
12 | namespace phpDocumentor; |
||
13 | |||
14 | use Cilex\Application as Cilex; |
||
15 | use Cilex\Provider\JmsSerializerServiceProvider; |
||
16 | use Cilex\Provider\MonologServiceProvider; |
||
17 | use Cilex\Provider\ValidatorServiceProvider; |
||
18 | use Composer\Autoload\ClassLoader; |
||
19 | use Monolog\ErrorHandler; |
||
20 | use Monolog\Handler\NullHandler; |
||
21 | use Monolog\Handler\StreamHandler; |
||
22 | use Monolog\Logger; |
||
23 | use phpDocumentor\Command\Helper\ConfigurationHelper; |
||
24 | use phpDocumentor\Command\Helper\LoggerHelper; |
||
25 | use phpDocumentor\Console\Input\ArgvInput; |
||
26 | use Symfony\Component\Console\Application as ConsoleApplication; |
||
27 | use Symfony\Component\Console\Shell; |
||
28 | use Symfony\Component\Stopwatch\Stopwatch; |
||
29 | |||
30 | /** |
||
31 | * Application class for phpDocumentor. |
||
32 | * |
||
33 | * Can be used as bootstrap when the run method is not invoked. |
||
34 | */ |
||
35 | class Application extends Cilex |
||
0 ignored issues
–
show
Complexity
introduced
by
Loading history...
|
|||
36 | { |
||
37 | /** @var string $VERSION represents the version of phpDocumentor as stored in /VERSION */ |
||
38 | public static $VERSION; |
||
39 | |||
40 | /** |
||
41 | * Initializes all components used by phpDocumentor. |
||
42 | * |
||
43 | * @param ClassLoader $autoloader |
||
44 | * @param array $values |
||
45 | */ |
||
46 | public function __construct($autoloader = null, array $values = array()) |
||
47 | { |
||
48 | $this->defineIniSettings(); |
||
49 | |||
50 | self::$VERSION = strpos('@package_version@', '@') === 0 |
||
51 | ? trim(file_get_contents(__DIR__ . '/../../VERSION')) |
||
52 | : '@package_version@'; |
||
53 | |||
54 | parent::__construct('phpDocumentor', self::$VERSION, $values); |
||
55 | |||
56 | $this['kernel.timer.start'] = time(); |
||
57 | $this['kernel.stopwatch'] = function () { |
||
58 | return new Stopwatch(); |
||
59 | }; |
||
60 | |||
61 | $this['autoloader'] = $autoloader; |
||
62 | |||
63 | $this->register(new JmsSerializerServiceProvider()); |
||
64 | $this->register(new Configuration\ServiceProvider()); |
||
65 | |||
66 | $this->addEventDispatcher(); |
||
67 | $this->addLogging(); |
||
68 | |||
69 | $this->register(new ValidatorServiceProvider()); |
||
70 | $this->register(new Translator\ServiceProvider()); |
||
71 | $this->register(new Descriptor\ServiceProvider()); |
||
72 | $this->register(new Parser\ServiceProvider()); |
||
73 | $this->register(new Partials\ServiceProvider()); |
||
74 | $this->register(new Transformer\ServiceProvider()); |
||
75 | $this->register(new Plugin\ServiceProvider()); |
||
76 | |||
77 | $this->addCommandsForProjectNamespace(); |
||
78 | |||
79 | if (\Phar::running()) { |
||
80 | $this->addCommandsForPharNamespace(); |
||
81 | } |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * Removes all logging handlers and replaces them with handlers that can write to the given logPath and level. |
||
86 | * |
||
87 | * @param Logger $logger The logger instance that needs to be configured. |
||
88 | * @param integer $level The minimum level that will be written to the normal logfile; matches one of the |
||
89 | * constants in {@see \Monolog\Logger}. |
||
90 | * @param string $logPath The full path where the normal log file needs to be written. |
||
91 | * |
||
92 | * @return void |
||
93 | */ |
||
94 | public function configureLogger($logger, $level, $logPath = null) |
||
0 ignored issues
–
show
This operation has 288 execution paths which exceeds the configured maximum of 200.
A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods. You can also find more information in the “Code” section of your repository.
Loading history...
|
|||
95 | { |
||
96 | /** @var Logger $monolog */ |
||
97 | $monolog = $logger; |
||
98 | |||
99 | switch ($level) { |
||
100 | case 'emergency': |
||
101 | case 'emerg': |
||
102 | $level = Logger::EMERGENCY; |
||
103 | break; |
||
104 | case 'alert': |
||
105 | $level = Logger::ALERT; |
||
106 | break; |
||
107 | case 'critical': |
||
108 | case 'crit': |
||
109 | $level = Logger::CRITICAL; |
||
110 | break; |
||
111 | case 'error': |
||
112 | case 'err': |
||
113 | $level = Logger::ERROR; |
||
114 | break; |
||
115 | case 'warning': |
||
116 | case 'warn': |
||
117 | $level = Logger::WARNING; |
||
118 | break; |
||
119 | case 'notice': |
||
120 | $level = Logger::NOTICE; |
||
121 | break; |
||
122 | case 'info': |
||
123 | $level = Logger::INFO; |
||
124 | break; |
||
125 | case 'debug': |
||
126 | $level = Logger::DEBUG; |
||
127 | break; |
||
128 | } |
||
129 | |||
130 | $this['monolog.level'] = $level; |
||
131 | if ($logPath) { |
||
0 ignored issues
–
show
The expression
$logPath of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
132 | $logPath = str_replace( |
||
133 | array('{APP_ROOT}', '{DATE}'), |
||
134 | array(realpath(__DIR__.'/../..'), $this['kernel.timer.start']), |
||
135 | $logPath |
||
136 | ); |
||
137 | $this['monolog.logfile'] = $logPath; |
||
138 | } |
||
139 | |||
140 | // remove all handlers from the stack |
||
141 | try { |
||
142 | while ($monolog->popHandler()) { |
||
143 | } |
||
144 | } catch (\LogicException $e) { |
||
145 | // popHandler throws an exception when you try to pop the empty stack; to us this is not an |
||
146 | // error but an indication that the handler stack is empty. |
||
147 | } |
||
148 | |||
149 | if ($level === 'quiet') { |
||
150 | $monolog->pushHandler(new NullHandler()); |
||
151 | |||
152 | return; |
||
153 | } |
||
154 | |||
155 | // set our new handlers |
||
156 | if ($logPath) { |
||
0 ignored issues
–
show
The expression
$logPath of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
157 | $monolog->pushHandler(new StreamHandler($logPath, $level)); |
||
158 | } else { |
||
159 | $monolog->pushHandler(new StreamHandler('php://stdout', $level)); |
||
160 | } |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Run the application and if no command is provided, use project:run. |
||
165 | * |
||
166 | * @param bool $interactive Whether to run in interactive mode. |
||
167 | * |
||
168 | * @return void |
||
169 | */ |
||
170 | public function run($interactive = false) |
||
171 | { |
||
172 | /** @var ConsoleApplication $app */ |
||
173 | $app = $this['console']; |
||
174 | $app->setAutoExit(false); |
||
175 | |||
176 | if ($interactive) { |
||
177 | $app = new Shell($app); |
||
0 ignored issues
–
show
The class
Symfony\Component\Console\Shell has been deprecated with message: since version 2.8, to be removed in 3.0.
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.
Loading history...
|
|||
178 | } |
||
179 | |||
180 | $output = new Console\Output\Output(); |
||
181 | $output->setLogger($this['monolog']); |
||
182 | |||
183 | $app->run(new ArgvInput(), $output); |
||
0 ignored issues
–
show
The call to
Shell::run() has too many arguments starting with new \phpDocumentor\Console\Input\ArgvInput() .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the
Loading history...
|
|||
184 | } |
||
185 | |||
186 | /** |
||
187 | * Adjust php.ini settings. |
||
188 | * |
||
189 | * @return void |
||
190 | */ |
||
191 | protected function defineIniSettings() |
||
192 | { |
||
193 | $this->setTimezone(); |
||
194 | ini_set('memory_limit', -1); |
||
195 | |||
196 | // this code cannot be tested because we cannot control the system settings in unit tests |
||
197 | // @codeCoverageIgnoreStart |
||
198 | if (extension_loaded('Zend OPcache') && ini_get('opcache.enable') && ini_get('opcache.enable_cli')) { |
||
199 | if (ini_get('opcache.save_comments')) { |
||
200 | ini_set('opcache.load_comments', 1); |
||
201 | } else { |
||
202 | ini_set('opcache.enable', 0); |
||
203 | } |
||
204 | } |
||
205 | |||
206 | if (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.save_comments') == 0) { |
||
207 | throw new \RuntimeException('Please enable zend_optimizerplus.save_comments in php.ini.'); |
||
208 | } |
||
209 | // @codeCoverageIgnoreEnd |
||
210 | } |
||
211 | |||
212 | /** |
||
213 | * If the timezone is not set anywhere, set it to UTC. |
||
214 | * |
||
215 | * This is done to prevent any warnings being outputted in relation to using |
||
216 | * date/time functions. What is checked is php.ini, and if the PHP version |
||
217 | * is prior to 5.4, the TZ environment variable. |
||
218 | * |
||
219 | * @link http://php.net/manual/en/function.date-default-timezone-get.php for more information how PHP determines the |
||
220 | * default timezone. |
||
221 | * |
||
222 | * @codeCoverageIgnore this method is very hard, if not impossible, to unit test and not critical. |
||
223 | * |
||
224 | * @return void |
||
225 | */ |
||
226 | protected function setTimezone() |
||
227 | { |
||
228 | if (false == ini_get('date.timezone') |
||
0 ignored issues
–
show
|
|||
229 | || (version_compare(phpversion(), '5.4.0', '<') && false === getenv('TZ')) |
||
230 | ) { |
||
231 | date_default_timezone_set('UTC'); |
||
232 | } |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * Adds a logging provider to the container of phpDocumentor. |
||
237 | * |
||
238 | * @return void |
||
239 | */ |
||
240 | protected function addLogging() |
||
241 | { |
||
242 | $this->register( |
||
243 | new MonologServiceProvider(), |
||
244 | array( |
||
245 | 'monolog.name' => 'phpDocumentor', |
||
246 | 'monolog.logfile' => sys_get_temp_dir() . '/phpdoc.log', |
||
247 | 'monolog.debugfile' => sys_get_temp_dir() . '/phpdoc.debug.log', |
||
248 | 'monolog.level' => Logger::INFO, |
||
249 | ) |
||
250 | ); |
||
251 | |||
252 | $app = $this; |
||
253 | /** @var Configuration $configuration */ |
||
254 | $configuration = $this['config']; |
||
255 | $this['monolog.configure'] = $this->protect( |
||
256 | function ($log) use ($app, $configuration) { |
||
257 | $paths = $configuration->getLogging()->getPaths(); |
||
258 | $logLevel = $configuration->getLogging()->getLevel(); |
||
259 | |||
260 | $app->configureLogger($log, $logLevel, $paths['default'], $paths['errors']); |
||
0 ignored issues
–
show
The call to
Application::configureLogger() has too many arguments starting with $paths['errors'] .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the
Loading history...
|
|||
261 | } |
||
262 | ); |
||
263 | |||
264 | $this->extend( |
||
265 | 'console', |
||
266 | function (ConsoleApplication $console) use ($configuration) { |
||
267 | $console->getHelperSet()->set(new LoggerHelper()); |
||
268 | $console->getHelperSet()->set(new ConfigurationHelper($configuration)); |
||
269 | |||
270 | return $console; |
||
271 | } |
||
272 | ); |
||
273 | |||
274 | ErrorHandler::register($this['monolog']); |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * Adds the event dispatcher to phpDocumentor's container. |
||
279 | * |
||
280 | * @return void |
||
281 | */ |
||
282 | protected function addEventDispatcher() |
||
283 | { |
||
284 | $this['event_dispatcher'] = $this->share( |
||
285 | function () { |
||
286 | return Event\Dispatcher::getInstance(); |
||
287 | } |
||
288 | ); |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Adds the command to phpDocumentor that belong to the Project namespace. |
||
293 | * |
||
294 | * @return void |
||
295 | */ |
||
296 | protected function addCommandsForProjectNamespace() |
||
297 | { |
||
298 | $this->command(new Command\Project\RunCommand()); |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Adds the command to phpDocumentor that belong to the Phar namespace. |
||
303 | * |
||
304 | * @return void |
||
305 | */ |
||
306 | protected function addCommandsForPharNamespace() |
||
307 | { |
||
308 | $this->command(new Command\Phar\UpdateCommand()); |
||
309 | } |
||
310 | } |
||
311 |