Passed
Pull Request — master (#32)
by Jitendra
01:51
created

Extension   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 24
eloc 61
dl 0
loc 158
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A doHandle() 0 7 2
A addTask() 0 13 3
A schedule() 0 7 2
A initTasks() 0 12 3
A initialize() 0 7 1
A app() 0 3 1
A getTaskParameters() 0 22 4
A scheduled() 0 3 1
A argv() 0 7 2
A getTaskClasses() 0 7 3
A __construct() 0 9 1
A handle() 0 13 1
1
<?php
2
3
namespace PhalconExt\Cli;
4
5
use Ahc\Cli\Application;
6
use Ahc\Cli\Input\Command;
7
use Ahc\Cli\IO\Interactor;
8
use Phalcon\Cli\Task;
0 ignored issues
show
Bug introduced by
The type Phalcon\Cli\Task was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Phalcon\DiInterface;
0 ignored issues
show
Bug introduced by
The type Phalcon\DiInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use PhalconExt\Cli\Task\ScheduleTask;
11
use PhalconExt\Di\ProvidesDi;
12
13
trait Extension
14
{
15
    use ProvidesDi;
16
    use MiddlewareTrait;
17
18
    /** @var array Tasks namespaces */
19
    protected $namespaces = [];
20
21
    /** @var array Tasks provided by package already */
22
    protected $factoryTasks =  [
23
        'schedule' => ScheduleTask::class,
24
    ];
25
26
    /** @var array Scheduled taskIds mapped to schedule time */
27
    protected $scheduled = [];
28
29
    /** @var array Raw argv sent to handle() [OR read from $_SERVER] */
30
    protected $rawArgv = [];
31
32
    /** @var array Normalized argv */
33
    protected $argv = [];
34
35
    /** @var string */
36
    protected $lastTask;
37
38
    public function __construct(DiInterface $di, string $name, string $version = '0.0.1')
39
    {
40
        parent::__construct($di);
41
42
        $di->setShared('console', $this);
43
        $di->setShared('interactor', Interactor::class);
44
45
        $this->initialize($name, $version);
46
        $this->bindEvents($this);
47
    }
48
49
    protected function initialize(string $name, string $version)
50
    {
51
        $this->app = new Application($name, $version, function () {
0 ignored issues
show
Bug Best Practice introduced by
The property app does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
52
            return false;
53
        });
54
55
        $this->initTasks();
56
    }
57
58
    public function app()
59
    {
60
        return $this->app;
61
    }
62
63
    public function argv(bool $raw = true): array
64
    {
65
        if ($raw) {
66
            return $this->rawArgv;
67
        }
68
69
        return $this->argv;
70
    }
71
72
    public function handle(array $argv = null)
73
    {
74
        $this->rawArgv = $argv ?? $_SERVER['argv'];
75
76
        $params = $this->getTaskParameters($this->rawArgv);
77
78
        // Normalize in the form: ['app', 'task:action', 'param1', 'param2', ...]
79
        $this->argv = \array_merge(
80
            [$argv[0] ?? null, $params['task'] . ':' . $params['action']],
81
            $params['params']
82
        );
83
84
        return $this->doHandle($params);
85
    }
86
87
    public function doHandle(array $parameters)
88
    {
89
        if (isset($this->namespaces[$parameters['task']])) {
90
            $parameters['task'] = $this->namespaces[$parameters['task']];
91
        }
92
93
        return parent::handle($parameters);
94
    }
95
96
    public function addTask(string $task, string $descr = '', bool $allowUnknown = false): Command
97
    {
98
        $this->lastTask = $taskId = \str_ireplace(['task', 'action'], '', $task);
99
100
        if (\strpos($task, ':main')) {
101
            $alias = \str_replace(':main', '', $taskId);
102
        }
103
104
        if (\strpos($task, ':') === false) {
105
            $alias = $taskId . ':main';
106
        }
107
108
        return $this->app->command($taskId, $descr, $alias ?? '', $allowUnknown);
109
    }
110
111
    public function schedule(string $cronExpr, string $taskId = ''): self
112
    {
113
        $taskId = $taskId ?: $this->lastTask;
114
115
        $this->scheduled[$taskId] = $cronExpr;
116
117
        return $this;
118
    }
119
120
    public function scheduled(): array
121
    {
122
        return $this->scheduled;
123
    }
124
125
    protected function getTaskParameters(array $argv)
126
    {
127
        $taskAction = [];
128
        \array_shift($argv);
129
130
        foreach ($argv as $i => $value) {
131
            if ($value[0] === '-' || isset($taskAction[1])) {
132
                break;
133
            }
134
135
            $taskAction = \array_merge($taskAction, \explode(':', $value, 2));
136
            unset($argv[$i]);
137
        }
138
139
        // Respect phalcon default.
140
        $taskAction += ['main', 'main'];
141
142
        return [
143
            'task'   => $taskAction[0],
144
            'action' => $taskAction[1],
145
            // For BC, still send params to handle()
146
            'params' => \array_values($argv),
147
        ];
148
    }
149
150
    public function initTasks()
151
    {
152
        foreach ($this->getTaskClasses() as $name => $class) {
153
            if (!$this->di()->has($class)) {
154
                // Force load!
155
                $this->di($class);
156
            }
157
158
            $this->namespaces[$name] = \preg_replace('#Task$#', '', $class);
159
        }
160
161
        return $this;
162
    }
163
164
    protected function getTaskClasses(): array
165
    {
166
        if ($tasks = $this->di('config')->path('console.tasks')) {
167
            $tasks = $tasks->toArray();
168
        }
169
170
        return $this->factoryTasks + ($tasks ?: []);
171
    }
172
}
173