Passed
Pull Request — master (#32)
by Jitendra
02:52
created

Extension::schedule()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 1
nop 2
1
<?php
2
3
namespace PhalconExt\Cli;
4
5
use Ahc\Cli\Application;
0 ignored issues
show
Bug introduced by
The type Ahc\Cli\Application 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...
6
use Ahc\Cli\Input\Command;
0 ignored issues
show
Bug introduced by
The type Ahc\Cli\Input\Command 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...
7
use Ahc\Cli\IO\Interactor;
0 ignored issues
show
Bug introduced by
The type Ahc\Cli\IO\Interactor 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...
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
24
    /** @var array Scheduled taskIds mapped to schedule time */
25
    protected $scheduled = [];
26
27
    /** @var array Raw argv sent to handle() [OR read from $_SERVER] */
28
    protected $rawArgv = [];
29
30
    /** @var array Normalized argv */
31
    protected $argv = [];
32
33
    /** @var string */
34
    protected $lastTask;
35
36
    public function __construct(DiInterface $di, string $name, string $version = '0.0.1')
37
    {
38
        parent::__construct($di);
39
40
        $di->setShared('console', $this);
41
        $di->setShared('interactor', Interactor::class);
42
43
        $this->initialize($name, $version);
44
        $this->bindEvents($this);
45
    }
46
47
    protected function initialize(string $name, string $version)
48
    {
49
        $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...
50
            return false;
51
        });
52
53
        $this->factoryTasks = [
54
            'schedule' => ScheduleTask::class,
55
        ];
56
57
        $this->initTasks();
58
    }
59
60
    public function app()
61
    {
62
        return $this->app;
63
    }
64
65
    public function argv(bool $raw = true): array
66
    {
67
        if ($raw) {
68
            return $this->rawArgv;
69
        }
70
71
        return $this->argv;
72
    }
73
74
    public function handle(array $argv = null)
75
    {
76
        $this->rawArgv = $argv ?? $_SERVER['argv'];
77
78
        $params = $this->getTaskParameters($this->rawArgv);
79
80
        // Normalize in the form: ['app', 'task:action', 'param1', 'param2', ...]
81
        $this->argv = \array_merge(
82
            [$argv[0] ?? null, $params['task'] . ':' . $params['action']],
83
            $params['params']
84
        );
85
86
        return $this->doHandle($params);
87
    }
88
89
    public function doHandle(array $parameters)
90
    {
91
        if (isset($this->namespaces[$parameters['task']])) {
92
            $parameters['task'] = $this->namespaces[$parameters['task']];
93
        }
94
95
        return parent::handle($parameters);
96
    }
97
98
    public function addTask(string $task, string $descr = '', bool $allowUnknown = false): Command
99
    {
100
        $this->lastTask = $taskId = \str_ireplace(['task', 'action'], '', $task);
101
102
        if (\strpos($task, ':main')) {
103
            $alias = \str_replace(':main', '', $taskId);
104
        }
105
106
        if (\strpos($task, ':') === false) {
107
            $alias = $taskId . ':main';
108
        }
109
110
        return $this->app->command($taskId, $descr, $alias ?? '', $allowUnknown);
111
    }
112
113
    public function schedule(string $cronExpr, string $taskId = ''): self
114
    {
115
        $taskId = $taskId ?: $this->lastTask;
116
117
        $this->scheduled[$taskId] = $cronExpr;
118
119
        return $this;
120
    }
121
122
    public function scheduled(): array
123
    {
124
        return $this->scheduled;
125
    }
126
127
    protected function getTaskParameters(array $argv)
128
    {
129
        $taskAction = [];
130
        \array_shift($argv);
131
132
        foreach ($argv as $i => $value) {
133
            if ($value[0] === '-' || isset($taskAction[1])) {
134
                break;
135
            }
136
137
            $taskAction = \array_merge($taskAction, \explode(':', $value, 2));
138
            unset($argv[$i]);
139
        }
140
141
        // Respect phalcon default.
142
        $taskAction += ['main', 'main'];
143
144
        return [
145
            'task'   => $taskAction[0],
146
            'action' => $taskAction[1],
147
            // For BC, still send params to handle()
148
            'params' => \array_values($argv),
149
        ];
150
    }
151
152
    public function initTasks()
153
    {
154
        foreach ($this->getTaskClasses() as $name => $class) {
155
            if (!$this->di()->has($class)) {
156
                // Force load!
157
                $this->di($class);
158
            }
159
160
            $this->namespaces[$name] = \preg_replace('#Task$#', '', $class);
161
        }
162
163
        return $this;
164
    }
165
166
    protected function getTaskClasses(): array
167
    {
168
        if ($tasks = $this->di('config')->path('console.tasks')) {
169
            $tasks = $tasks->toArray();
170
        }
171
172
        return $this->factoryTasks + ($tasks ?: []);
173
    }
174
}
175