Completed
Push — master ( 897567...887f9d )
by Andrii
03:40
created

AbstractController::normalizeTasks()   B

Complexity

Conditions 6
Paths 11

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6.0493

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 8
cts 9
cp 0.8889
rs 8.8571
cc 6
eloc 9
nc 11
nop 1
crap 6.0493
1
<?php
2
/**
3
 * Automation tool mixed with code generator for easier continuous development.
4
 *
5
 * @link      https://github.com/hiqdev/hidev
6
 * @package   hidev
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hidev\controllers;
12
13
use hidev\helpers\Helper;
14
use Yii;
15
use yii\console\Response;
16
17
/**
18
 * Abstract controller.
19
 */
20
abstract class AbstractController extends \hidev\base\Controller
21
{
22
    protected $_before = [];
23
    protected $_after  = [];
24
    protected $_make   = ['load', 'save'];
25
26
    /**
27
     * @var array list of performed actions
28
     */
29
    protected $_done = [];
30
31
    /**
32
     * {@inheritdoc}
33
     */
34 3
    public function options($actionId)
35
    {
36 3
        return array_merge(parent::options($actionId), array_keys(Helper::getPublicVars(get_called_class())));
37
    }
38
39 2
    public function perform($action = 'make')
40
    {
41 2
        return $this->runActions(['before', $action, 'after']);
42
    }
43
44 5
    public function actionBefore()
45
    {
46 5
        return $this->runRequests($this->getBefore());
47
    }
48
49
    /**
50
     * @return int|Response exit code
51
     */
52 5
    public function actionMake()
53
    {
54 5
        return $this->runActions($this->getMake());
55
    }
56
57 5
    public function actionAfter()
58
    {
59 5
        return $this->runRequests($this->getAfter());
60
    }
61
62
    public function actionLoad()
63
    {
64
        Yii::trace("Loading nothing for '$this->id'");
65
    }
66
67
    public function actionSave()
68
    {
69
        Yii::trace("Saving nothing for '$this->id'");
70
    }
71
72
    public function setBefore($requests)
73
    {
74
        $this->_before = array_merge($this->getBefore(), $this->normalizeTasks($requests));
75
    }
76
77 5
    public function getBefore()
78
    {
79 5
        return $this->_before;
80
    }
81
82
    public function setMake($requests)
83
    {
84
        $this->_make = array_merge($this->getMake(), $this->normalizeTasks($requests));
85
    }
86
87 5
    public function getMake()
88
    {
89 5
        return $this->_make;
90
    }
91
92
    public function setAfter($requests)
93
    {
94
        $this->_after = array_merge($this->getAfter(), $this->normalizeTasks($requests));
95
    }
96
97 5
    public function getAfter()
98
    {
99 5
        return $this->_after;
100
    }
101
102 5
    public function normalizeTasks($tasks)
103
    {
104 5
        if (!$tasks) {
105 5
            return [];
106 5
        } elseif (!is_array($tasks)) {
107
            $tasks = [(string) $tasks => 1];
108
        }
109 5
        $res = [];
110 5
        foreach ($tasks as $dep => $enabled) {
111 5
            $res[(string) (is_int($dep) ? $enabled : $dep)] = (bool) (is_int($dep) ? 1 : $enabled);
112
        }
113
114 5
        return $res;
115
    }
116
117
    /**
118
     * Runs array of requests. Stops on failure and returns exit code.
119
     * @param null|string|array $requests
120
     * @return int|Response exit code
121
     */
122 5 View Code Duplication
    public function runRequests($requests)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
    {
124 5
        foreach ($this->normalizeTasks($requests) as $request => $enabled) {
125
            if ($enabled) {
126
                $res = $this->runRequest($request);
127
                if (static::isNotOk($res)) {
128
                    return $res;
129
                }
130
            }
131
        }
132
133 5
        return 0;
134
    }
135
136
    public function runRequest($request)
137
    {
138
        return $request === null ? null : $this->module->runRequest($request);
139
    }
140
141
    /**
142
     * Is response NOT Ok.
143
     * @param Response|int $res
144
     * @return bool
145
     */
146 5
    public static function isNotOk($res)
147
    {
148 5
        return is_object($res) ? $res->exitStatus : $res;
149
    }
150
151
    /**
152
     * Is response Ok.
153
     * @param Response|int $res
154
     * @return bool
155
     */
156
    public static function isOk($res)
157
    {
158
        return !static::isNotOk($res);
159
    }
160
161
    /**
162
     * Runs list of actions.
163
     * TODO: think to redo with runRequests.
164
     * @param null|string|array $actions
165
     * @return int|Response exit code
166
     */
167 5 View Code Duplication
    public function runActions($actions)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
    {
169 5
        foreach ($this->normalizeTasks($actions) as $action => $enabled) {
170 5
            if ($enabled) {
171 5
                $res = $this->runAction($action);
172 5
                if (static::isNotOk($res)) {
173
                    return $res;
174
                }
175
            }
176
        }
177
178 5
        return 0;
179
    }
180
181 5
    public function runAction($id, $params = [])
182
    {
183 5
        if ($this->isDone($id)) {
184
            return;
185
        }
186 5
        $result = parent::runAction($id, $params);
187 5
        $this->markDone($id);
188
189 5
        return $result;
190
    }
191
192 5
    public function isDone($action, $timestamp = null)
0 ignored issues
show
Unused Code introduced by
The parameter $timestamp 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...
193
    {
194 5
        if (isset($this->_done[$action])) {
195
            Yii::trace("Already done: '$this->id/$action'");
196
197
            return true;
198
        }
199
200 5
        return false;
201
    }
202
203
    /**
204
     * Mark action as already done.
205
     *
206
     * @param string $action action id
207
     * @param int $time microtime when action was done, false for action was not done
208
     */
209 5
    public function markDone($action, $time = null)
210
    {
211 5
        $this->_done[$action] = ($time === null || $time === true) ? microtime(1) : $time;
212 5
    }
213
214
    /**
215
     * Runs given binary with given arguments. Returns exit code.
216
     * @param string $name
217
     * @param array|string $args
218
     * @return int exit code
219
     */
220
    public function passthru($name, $args = [])
221
    {
222
        return $this->takeGoal('binaries')->passthruBinary($name, $args);
223
    }
224
225
    /**
226
     * Runs given binary with given arguments. Returns stdout array.
227
     * @param string $name
228
     * @param string $args
229
     * @param bool $returnExitCode, default false
0 ignored issues
show
Documentation introduced by
There is no parameter named $returnExitCode,. Did you maybe mean $returnExitCode?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
230
     * @return array|int stdout or exitcode
231
     */
232
    public function exec($name, $args = '', $returnExitCode = false)
233
    {
234
        return $this->takeGoal('binaries')->execBinary($name, $args, $returnExitCode);
235
    }
236
237
    public function execCode($name, $args = '')
238
    {
239
        return $this->takeGoal('binaries')->execBinary($name, $args, true);
240
    }
241
242
    public function readline($prompt)
243
    {
244
        return readline($prompt);
245
    }
246
247
    public function readpassword($prompt)
248
    {
249
        echo $prompt;
250
        system('stty -echo');
251
        $password = rtrim(fgets(STDIN), PHP_EOL);
252
        system('stty echo');
253
        echo "\n";
254
255
        return $password;
256
    }
257
258 2
    public function takeGoal($id)
259
    {
260 2
        return $this->module->get('config')->getGoal($id);
261
    }
262
263 4
    public function takeConfig()
264
    {
265 4
        return $this->module->get('config');
266
    }
267
268 2
    public function takeVendor()
269
    {
270 2
        return $this->takeGoal('vendor');
271
    }
272
273 1
    public function takePackage()
274
    {
275 1
        return $this->takeGoal('package');
276
    }
277
278 2
    public function takeVcs()
279
    {
280 2
        return $this->takeConfig()->getVcs();
281
    }
282
}
283