Completed
Push — master ( b0e284...41b1ba )
by Dmitry
04:41
created

StartController::requireAll()   D

Complexity

Conditions 9
Paths 25

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 13.2714

Importance

Changes 2
Bugs 1 Features 0
Metric Value
dl 0
loc 25
ccs 5
cts 8
cp 0.625
rs 4.909
c 2
b 1
f 0
cc 9
eloc 17
nc 25
nop 0
crap 13.2714
1
<?php
2
3
/*
4
 * Automation tool mixed with code generator for easier continuous development
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
use yii\helpers\ArrayHelper;
18
19
/**
20
 * Start goal.
21
 * Chdirs to the project's root directory and loads dependencies and configs.
22
 */
23
class StartController extends CommonController
24
{
25
    /**
26
     * @var string absolute path to the project root directory
27
     */
28
    protected $_rootDir;
29
30
    /**
31
     * @var bool hidev already started flag
32
     */
33
    public static $started = false;
34
35
    /**
36
     * Make action.
37
     */
38 2
    public function actionMake()
39
    {
40 2
        self::$started = true;
41
        $this->getRootDir();
42
        $this->includeMainConfig();
43
        $this->addAliases();
44
        $this->addAutoloader();
45
        $this->requireAll();
46
        $this->includeAll();
47
        $this->loadConfig();
48
        $this->includeMainConfig();
49 2
    }
50
51
    public function includeMainConfig()
52
    {
53
        $this->takeConfig()->includeConfig('.hidev/config.yml');
54
        if (file_exists('.hidev/config-local.yml')) {
55
            $this->takeConfig()->includeConfig('.hidev/config-local.yml');
56
        }
57
    }
58
59 2
    public function addAutoloader()
60
    {
61
        $autoloader = Yii::getAlias('@root/vendor/autoload.php');
62
        if (file_exists($autoloader)) {
63
            spl_autoload_unregister(['Yii', 'autoload']);
64
            require $autoloader;
65
            spl_autoload_register(['Yii', 'autoload'], true, true);
66
        }
67 2
    }
68
69
    /**
70
     * Update action.
71
     * @return int exit code
72
     */
73
    public function actionUpdate()
74
    {
75
        if (file_exists('.hidev/composer.json')) {
76
            return $this->passthru('composer', ['update', '-d', '.hidev', '--prefer-source', '--ansi']);
77
        }
78
    }
79
80
    /**
81
     * Adds aliases:
82
     * - @root alias to current project root dir
83
     * - current package namespace for it could be used from hidev.
84
     */
85 2
    public function addAliases()
86
    {
87
        Yii::setAlias('@root', $this->getRootDir());
88
        $config = $this->takeConfig()->rawItem('package');
89
        $alias  = strtr($config['namespace'], '\\', '/');
90 2
        if ($alias && !Yii::getAlias('@' . $alias, false)) {
91
            $srcdir = Yii::getAlias('@root/' . ($config['src'] ?: 'src'));
92
            Yii::setAlias($alias, $srcdir);
0 ignored issues
show
Bug introduced by
It seems like $srcdir defined by \Yii::getAlias('@root/' ...onfig['src'] ?: 'src')) on line 91 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...
93
        }
94
        $aliases = $this->takeConfig()->rawItem('aliases');
95
        if (!empty($aliases) && is_array($aliases)) {
96
            foreach ($aliases as $alias => $path) {
97
                if (!$this->hasAlias($alias)) {
98
                    Yii::setAlias($alias, $path);
99
                }
100
            }
101
        }
102 2
    }
103
104 2
    public function hasAlias($alias, $exact = true)
0 ignored issues
show
Unused Code introduced by
The parameter $exact is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
    {
106
        $pos = strpos($alias, '/');
107
108
        return $pos === false ? isset(Yii::$aliases[$alias]) : isset(Yii::$aliases[substr($alias, 0, $pos)][$alias]);
109 2
    }
110
111
    /**
112
     * Require all configured requires.
113
     */
114 2
    protected function requireAll()
115
    {
116
        $plugins = $this->takeConfig()->rawItem('plugins');
117 2
        $vendors = [];
118 2
        if ($plugins) {
119
            $file = File::create('.hidev/composer.json');
120
            $data = ArrayHelper::merge($file->load(), ['require' => $plugins]);
121
            if ($file->save($data) || !is_dir('.hidev/vendor')) {
122
                $this->runAction('update');
123
            }
124
            $vendors[] = '.hidev/vendor';
125
        } elseif ($this->needsComposerInstall()) {
126
            if ($this->passthru('composer', ['install', '--ansi'])) {
127
                throw new InvalidParamException('Failed initialize project with composer install');
128
            }
129
        }
130
        if (file_exists('vendor/hiqdev/config/hidev.php')) {
131
            $vendors[] = 'vendor';
132
        }
133 2
        if (!empty($vendors)) {
134
            foreach (array_unique($vendors) as $dir) {
135
                $this->module->loadExtraVendor($dir);
136
            }
137
        }
138 2
    }
139
140 2
    public function needsComposerInstall()
141
    {
142
        if (file_exists('vendor')) {
143
            return false;
144
        }
145
        if (!file_exists('composer.json')) {
146 2
            return false;
147
        }
148
        $data = File::create('composer.json')->load();
149
        foreach (['require', 'require-dev'] as $key) {
150
            if (isset($data[$key])) {
151
                foreach ($data[$key] as $package => $version) {
152
                    list(, $name) = explode('/', $package);
153
                    if (strncmp($name, 'hidev-', 6) === 0) {
154
                        return true;
155
                    }
156
                }
157
            }
158
        }
159
160
        return false;
161
    }
162
163
    /**
164
     * Include all configs.
165
     */
166 2
    public function includeAll()
167
    {
168 2
        $still = true;
169
        while ($still) {
170 2
            $still = false;
171
            $include = $this->takeConfig()->rawItem('include');
172 2
            if ($include) {
173
                foreach ($include as $path) {
174
                    $still = $still || $this->takeConfig()->includeConfig($path);
175
                }
176
            }
177
        }
178 2
    }
179
180
    /**
181
     * Load project's config if configured.
182
     */
183 2
    public function loadConfig()
184
    {
185
        $path = $this->takeConfig()->rawItem('config');
186 2
        if ($path) {
187
            $this->module->loadExtraConfig($path);
188
        }
189 2
    }
190
191
    public function setRootDir($value)
192
    {
193
        $this->_rootDir = $value;
194
    }
195
196
    public function getRootDir()
197
    {
198
        if ($this->_rootDir === null) {
199
            $this->_rootDir = $this->findRootDir();
200
        }
201
202
        return $this->_rootDir;
203
    }
204
205
    /**
206
     * Chdirs to project's root by looking for config file in the current directory and up.
207
     * @throws InvalidParamException when failed to find
208
     * @return string path to the root directory of hidev project
209
     */
210 2
    protected function findRootDir()
211
    {
212 2
        $configDir = '.hidev';
213
        for ($i = 0; $i < 9; ++$i) {
214
            if (is_dir($configDir)) {
215
                return getcwd();
216
            }
217
            chdir('..');
218 2
        }
219
        throw new InvalidParamException("Not a hidev project (or any of the parent directories).\nUse `hidev init` to initialize hidev project.");
220
    }
221
222
    public function buildRootPath($subpath)
223
    {
224
        return $this->getRootDir() . DIRECTORY_SEPARATOR . $subpath;
225
    }
226
}
227