Completed
Push — master ( 6c7845...2aa843 )
by Andrii
02:41
created

StartController::hasAlias()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2.5

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 2
cts 4
cp 0.5
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 2
crap 2.5
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
        $this->getRootDir();
41
        $this->takeConfig()->includeConfig('.hidev/config.yml');
42
        if (file_exists('.hidev/config-local.yml')) {
43
            $this->takeConfig()->includeConfig('.hidev/config-local.yml');
44
        }
45
        $this->addAliases();
46
        $this->addAutoloader();
47
        $this->requireAll();
48
        $this->includeAll();
49
        $this->loadConfig();
50 2
        self::$started = true;
51 2
    }
52
53 2
    public function addAutoloader()
54
    {
55
        $autoloader = Yii::getAlias('@root/vendor/autoload.php');
56
        if (file_exists($autoloader)) {
57
            spl_autoload_unregister(['Yii', 'autoload']);
58
            require $autoloader;
59
            spl_autoload_register(['Yii', 'autoload'], true, true);
60
        }
61 2
    }
62
63
    /**
64
     * Update action.
65
     * @return int exit code
66
     */
67
    public function actionUpdate()
68
    {
69
        return $this->passthru('composer', ['update', '-d', '.hidev', '--prefer-source', '--ansi']);
70
    }
71
72
    /**
73
     * Adds aliases:
74
     * - @root alias to current project root dir
75
     * - current package namespace for it could be used from hidev.
76
     */
77 2
    public function addAliases()
78
    {
79
        Yii::setAlias('@root', $this->getRootDir());
80
        $config = $this->takeConfig()->rawItem('package');
81
        $alias  = strtr($config['namespace'], '\\', '/');
82 2
        if ($alias && !Yii::getAlias('@' . $alias, false)) {
83
            $srcdir = Yii::getAlias('@root/' . ($config['src'] ?: 'src'));
84
            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 83 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...
85
        }
86
        $aliases = $this->takeConfig()->rawItem('aliases');
87
        if (!empty($aliases) && is_array($aliases)) {
88
            foreach ($aliases as $alias => $path) {
89
                if (!$this->hasAlias($alias)) {
90
                    Yii::setAlias($alias, $path);
91
                }
92
            }
93
        }
94 2
    }
95
96 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...
97
    {
98
        $pos = strpos($alias, '/');
99
100
        return $pos === false ? isset(Yii::$aliases[$alias]) : isset(Yii::$aliases[substr($alias, 0, $pos)][$alias]);
101 2
    }
102
103
    /**
104
     * Require all configured requires.
105
     */
106 2
    protected function requireAll()
107
    {
108
        $plugins = $this->takeConfig()->rawItem('plugins');
109 2
        $vendors = [];
110 2
        if ($plugins) {
111
            $file = File::create('.hidev/composer.json');
112
            $data = ArrayHelper::merge($file->load(), ['require' => $plugins]);
113
            if ($file->save($data) || !is_dir('.hidev/vendor')) {
114
                $this->runAction('update');
115
            }
116
            $vendors[] = '.hidev/vendor';
117
        } elseif ($this->needsComposerInstall()) {
118
            if ($this->passthru('composer', ['install', '--ansi'])) {
119
                throw new InvalidParamException('Failed initialize project with composer install');
120
            }
121
        }
122
        if (file_exists('vendor/hiqdev/config/hidev.php')) {
123
            $vendors[] = 'vendor';
124
        }
125 2
        if (!empty($vendors)) {
126
            foreach (array_unique($vendors) as $dir) {
127
                $this->module->loadExtraVendor($dir);
128
            }
129
        }
130 2
    }
131
132 2
    public function needsComposerInstall()
133
    {
134
        if (file_exists('vendor')) {
135
            return false;
136
        }
137
        if (!file_exists('composer.json')) {
138 2
            return false;
139
        }
140
        $data = File::create('composer.json')->load();
141
        foreach (['require', 'require-dev'] as $key) {
142
            if (isset($data[$key])) {
143
                foreach ($data[$key] as $package => $version) {
144
                    list(, $name) = explode('/', $package);
145
                    if (strncmp($name, 'hidev-', 6) === 0) {
146
                        return true;
147
                    }
148
                }
149
            }
150
        }
151
152
        return false;
153
    }
154
155
    /**
156
     * Include all configs.
157
     */
158 2
    public function includeAll()
159
    {
160 2
        $still = true;
161
        while ($still) {
162 2
            $still = false;
163
            $include = $this->takeConfig()->rawItem('include');
164 2
            if ($include) {
165
                foreach ($include as $path) {
166
                    $still = $still || $this->takeConfig()->includeConfig($path);
167
                }
168
            }
169
        }
170 2
    }
171
172
    /**
173
     * Load project's config if configured.
174
     */
175 2
    public function loadConfig()
176
    {
177
        $path = $this->takeConfig()->rawItem('config');
178 2
        if ($path) {
179
            $this->module->loadExtraConfig($path);
180
        }
181 2
    }
182
183
    public function setRootDir($value)
184
    {
185
        $this->_rootDir = $value;
186
    }
187
188
    public function getRootDir()
189
    {
190
        if ($this->_rootDir === null) {
191
            $this->_rootDir = $this->findRootDir();
192
        }
193
194
        return $this->_rootDir;
195
    }
196
197
    /**
198
     * Chdirs to project's root by looking for config file in the current directory and up.
199
     * @throws InvalidParamException when failed to find
200
     * @return string path to the root directory of hidev project
201
     */
202 2
    protected function findRootDir()
203
    {
204 2
        $configDir = '.hidev';
205
        for ($i = 0;$i < 9;++$i) {
206
            if (is_dir($configDir)) {
207
                return getcwd();
208
            }
209
            chdir('..');
210 2
        }
211
        throw new InvalidParamException("Not a hidev project (or any of the parent directories).\nUse `hidev init` to initialize hidev project.");
212
    }
213
214
    public function buildRootPath($subpath)
215
    {
216
        return $this->getRootDir() . DIRECTORY_SEPARATOR . $subpath;
217
    }
218
}
219