Completed
Push — master ( 006d7e...37c840 )
by Andrii
03:23
created

StartController::addAutoloader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 0
cts 9
cp 0
rs 9.6666
cc 2
eloc 6
nc 2
nop 0
crap 6
1
<?php
2
3
/*
4
 * Task runner, code generator and build tool for easier continuos integration
5
 *
6
 * @link      https://github.com/hiqdev/hidev
7
 * @package   hidev
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hidev\controllers;
13
14
use hidev\base\File;
15
use Yii;
16
use yii\base\InvalidParamException;
17
18
/**
19
 * Start goal.
20
 * Chdirs to the project's root directory and loads dependencies and configs.
21
 */
22
class StartController extends CommonController
23
{
24
    const MAIN_CONFIG = '.hidev/config.yml';
25
26
    /**
27
     * @var string absolute path to the project root directory
28
     */
29
    public $prjdir;
30
31
    /**
32
     * @var bool hidev already started flag
33
     */
34
    public static $started = false;
35
36
    /**
37
     * Make action.
38
     */
39
    public function actionMake()
40
    {
41
        $this->getPrjDir();
42
        $this->takeConfig()->includeConfig(static::MAIN_CONFIG);
43
        $this->addAliases();
44
        $this->addAutoloader();
45
        $this->requireAll();
46
        $this->includeAll();
47
        $this->loadConfig();
48
        self::$started = true;
49
    }
50
51
    public function addAutoloader()
52
    {
53
        $autoloader = Yii::getAlias('@prjdir/vendor/autoload.php');
54
        if (file_exists($autoloader)) {
55
            spl_autoload_unregister(['Yii', 'autoload']);
56
            require $autoloader;
57
            spl_autoload_register(['Yii', 'autoload'], true, true);
58
        }
59
    }
60
61
    /**
62
     * Update action.
63
     * @return int exit code
64
     */
65
    public function actionUpdate()
66
    {
67
        return $this->passthru('composer', ['update', '-d', '.hidev', '--prefer-source', '--ansi']);
68
    }
69
70
    /**
71
     * Adds aliases:
72
     * - @prjdir alias to current project root dir
73
     * - current package namespace for it could be used from hidev.
74
     */
75
    public function addAliases()
76
    {
77
        Yii::setAlias('@prjdir', $this->getPrjDir());
78
        $config = $this->takeConfig()->rawItem('package');
79
        $alias  = strtr($config['namespace'], '\\', '/');
80
        if ($alias && !Yii::getAlias('@' . $alias, false)) {
81
            $srcdir = Yii::getAlias('@prjdir/' . ($config['src'] ?: 'src'));
82
            Yii::setAlias($alias, $srcdir);
0 ignored issues
show
Bug introduced by
It seems like $srcdir defined by \Yii::getAlias('@prjdir/...onfig['src'] ?: 'src')) on line 81 can also be of type boolean; however, yii\BaseYii::setAlias() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
83
        }
84
    }
85
86
    /**
87
     * Require all configured requires.
88
     */
89
    protected function requireAll()
90
    {
91
        $plugins = $this->takeConfig()->rawItem('plugins');
92
        $vendors = [];
93
        if ($plugins) {
94
            $saved = File::create('.hidev/composer.json')->save(['require' => $plugins]);
95
            if ($saved || !is_dir('.hidev/vendor')) {
96
                $this->runAction('update');
97
            }
98
            $vendors[] = '.hidev/vendor';
99
        } elseif ($this->needsComposerInstall()) {
100
            if ($this->passthru('composer', ['install', '--ansi'])) {
101
                throw new InvalidParamException("Failed initialize project with composer install");
102
            }
103
        }
104
        if (file_exists('vendor/hiqdev/hidev-config.php')) {
105
            $vendors[] = 'vendor';
106
        }
107
        if (!empty($vendors)) {
108
            /// backup config then reset with extra config then restore
109
            $config = $this->takeConfig()->getItems();
110
            Yii::$app->clear('config');
111
            foreach (array_unique($vendors) as $dir) {
112
                Yii::$app->loadExtraVendor($dir);
113
            }
114
            $this->takeConfig()->mergeItems($config);
115
        }
116
    }
117
118
    public function needsComposerInstall()
119
    {
120
        if (file_exists('vendor')) {
121
            return false;
122
        }
123
        if (!file_exists('composer.json')) {
124
            return false;
125
        }
126
        $data = File::create('composer.json')->load();
127
        foreach (['require', 'require-dev'] as $key) {
128
            if (isset($data[$key])) {
129
                foreach ($data[$key] as $package => $version) {
130
                    list(, $name) = explode('/', $package);
131
                    if (strncmp($name, 'hidev-', 6) === 0) {
132
                        return true;
133
                    }
134
                }
135
            }
136
        }
137
138
        return false;
139
    }
140
141
    /**
142
     * Include all configs.
143
     */
144
    public function includeAll()
145
    {
146
        $still = true;
147
        while ($still) {
148
            $still = false;
149
            $include = $this->takeConfig()->rawItem('include');
150
            if ($include) {
151
                foreach ($include as $path) {
152
                    $still = $still || $this->takeConfig()->includeConfig($path);
153
                }
154
            }
155
        }
156
    }
157
158
    /**
159
     * Load project's config if configured.
160
     */
161
    public function loadConfig()
162
    {
163
        $path = $this->takeConfig()->rawItem('config');
164
        if ($path) {
165
            Yii::$app->loadExtraConfig($path);
166
        }
167
    }
168
169
    public function getPrjDir()
170
    {
171
        if ($this->prjdir === null) {
172
            $this->prjdir = $this->findPrjDir();
173
        }
174
175
        return $this->prjdir;
176
    }
177
178
    /**
179
     * Chdirs to project's root by looking for config file in the current directory and up.
180
     * @throws InvalidParamException when failed to find
181
     * @return string path to the root directory of hidev project
182
     */
183
    protected function findPrjDir()
184
    {
185
        $configDir = '.hidev';
186
        for ($i = 0;$i < 9;++$i) {
187
            if (is_dir($configDir)) {
188
                $this->prjdir = getcwd();
189
                return $this->prjdir;
190
            }
191
            chdir('..');
192
        }
193
        throw new InvalidParamException("Not a hidev project (or any of the parent directories).\nUse `hidev init` to initialize hidev project.");
194
    }
195
}
196