Completed
Push — develop ( 722f70...af048b )
by Jaap
15:12 queued 05:04
created

src/Application/Bootstrap.php (4 issues)

Upgrade to new PHP Analysis Engine

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.4
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\Application;
13
14
use Composer\Autoload\ClassLoader;
15
16
/**
17
 * This class provides a bootstrap for all application who wish to interface with phpDocumentor.
18
 *
19
 * The Bootstrapper is responsible for setting up the autoloader, profiling options and application, including
20
 * dependency injection container.
21
 *
22
 * The simplest usage would be:
23
 *
24
 *     $app = Bootstap::createInstance()->initialize();
25
 *
26
 * This will setup the autoloader and application, including Service Container, and return an instance of the
27
 * application ready to be ran using the `run` command.
28
 *
29
 * If you need more control you can do some of the steps manually:
30
 *
31
 *     $bootstrap = Bootstap::createInstance();
32
 *     $autoloader = $bootstrap->createAutoloader();
33
 *     $app = new Application($autoloader)
34
 */
35
class Bootstrap
36
{
37
    /**
38
     * Helper static function to get an instance of this class.
39
     *
40
     * Usually used to do a one-line initialization, such as:
41
     *
42
     *     \phpDocumentor\Bootstrap::createInstance()->initialize();
43
     *
44
     * @return Bootstrap
45
     */
46
    public static function createInstance()
47
    {
48
        return new self();
49
    }
50
51
    /**
52
     * Convenience method that does the complete initialization for phpDocumentor.
53
     *
54
     * @return Application
55
     */
56
    public function initialize()
57
    {
58
        $vendorPath = $this->findVendorPath();
59
60
        $this->createAutoloader($vendorPath);
61
62
        return new Application(['composer.vendor_path' => $vendorPath]);
63
    }
64
65
    /**
66
     * Sets up XHProf so that we can profile phpDocumentor using XHGUI.
67
     *
68
     * @return self
69
     */
70
    public function registerProfiler()
71
    {
72
        // check whether xhprof is loaded
73
        $profile = (bool)(getenv('PHPDOC_PROFILE') === 'on');
74
        $xhguiPath = getenv('XHGUI_PATH');
75
        if ($profile && $xhguiPath && extension_loaded('xhprof')) {
76
            echo 'PROFILING ENABLED' . PHP_EOL;
77
            include($xhguiPath . '/external/header.php');
78
        }
79
80
        return $this;
81
    }
82
83
    /**
84
     * Initializes and returns the autoloader.
85
     *
86
     * @param string|null $vendorDir A path (either absolute or relative to the current working directory) leading to
87
     *     the vendor folder where composer installed the dependencies.
88
     *
89
     * @throws \RuntimeException if no autoloader could be found.
90
     *
91
     * @return ClassLoader
92
     */
93
    public function createAutoloader($vendorDir = null)
94
    {
95
        if (!$vendorDir) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $vendorDir of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
96
            // @codeCoverageIgnoreStart
97
            $vendorDir = __DIR__ . '/../../vendor';
98
            // @codeCoverageIgnoreEnd
99
        }
100
101
        $autoloader_location = $vendorDir . '/autoload.php';
102
        if (!file_exists($autoloader_location) || !is_readable($autoloader_location)) {
103
            throw new \RuntimeException(
104
                'phpDocumentor expected to find an autoloader at "' . $autoloader_location . '" but it was not there. '
105
                . 'Usually this is because the "composer install" command has not been ran yet. If this is not the '
106
                . 'case, please open an issue at http://github.com/phpDocumentor/phpDocumentor2 detailing what '
107
                . 'installation method you used, which path is mentioned in this error message and any other relevant '
108
                . 'information.'
109
            );
110
        }
111
112
        return require $autoloader_location;
113
    }
114
115
    /**
116
     * Attempts to find the location of the vendor folder.
117
     *
118
     * This method tries to check for a composer.json in a directory 5 levels below the folder of this Bootstrap file.
119
     * This is the expected location if phpDocumentor is installed using composer because the current directory for
120
     * this file is expected to be 'vendor/phpdocumentor/phpdocumentor/src/phpDocumentor'.
121
     *
122
     * If a composer.json is found we will try to extract the vendor folder name using the 'vendor-dir' configuration
123
     * option of composer or assume it is vendor if that option is not set.
124
     *
125
     *
126
     * If no custom composer.json can be found, then we assume that the vendor folder is that of phpDocumentor itself,
127
     * which is `../../vendor` starting from this folder.
128
     *
129
     * If neither locations exist, then this method returns null because no vendor path could be found.
130
     *
131
     * @param string $baseDir parameter for test purposes only.
132
     *
133
     * @return string|null
134
     */
135
    public function findVendorPath($baseDir = __DIR__)
136
    {
137
        // default installation
138
        $vendorDir = $baseDir . '/../../vendor';
139
140
        // Composerised installation, vendor/phpdocumentor/phpdocumentor/src/phpDocumentor is __DIR__
141
        $rootFolderWhenInstalledWithComposer = $baseDir . '/../../../../../';
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $rootFolderWhenInstalledWithComposer exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
142
        $composerConfigurationPath = $rootFolderWhenInstalledWithComposer . 'composer.json';
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $composerConfigurationPath exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
143
        if (file_exists($composerConfigurationPath)) {
144
            $vendorDir = $rootFolderWhenInstalledWithComposer
145
                . $this->getCustomVendorPathFromComposer($composerConfigurationPath);
146
        }
147
148
        return file_exists($vendorDir) ? $vendorDir : null;
149
    }
150
151
    /**
152
     * Retrieves the custom vendor-dir from the given composer.json or returns 'vendor'.
153
     *
154
     * @param string $composerConfigurationPath the path pointing to the composer.json
155
     *
156
     * @return string
157
     */
158
    protected function getCustomVendorPathFromComposer($composerConfigurationPath)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $composerConfigurationPath exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
159
    {
160
        $composerFile = file_get_contents($composerConfigurationPath);
161
        $composerJson = json_decode($composerFile, true);
162
163
        return isset($composerJson['config']['vendor-dir']) ? $composerJson['config']['vendor-dir'] : 'vendor';
164
    }
165
}
166