Completed
Push — master ( e7b929...ba2691 )
by Dmitry
03:11
created

Runner::getJobClass()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 0
cts 8
cp 0
rs 9.4285
cc 3
eloc 8
nc 3
nop 1
crap 12
1
<?php
2
3
namespace Basis;
4
5
use LogicException;
6
use League\Container\Container;
7
use ReflectionClass;
8
use ReflectionProperty;
9
10
class Runner
11
{
12
    private $app;
13
    private $mapping;
14
15 2
    public function __construct(Application $app)
16
    {
17 2
        $this->app = $app;
18 2
    }
19
20 2
    public function getMapping() : array
21
    {
22 2
        if (!$this->mapping) {
23 2
            $jobs = [];
24 2
            foreach ($this->app->get(Framework::class)->listClasses('Job') as $class) {
25 2
                $jobs[substr($class, strlen('Basis\\Job\\'))] = $class;
26
            }
27 2
            $serviceName = ucfirst($this->app->get(Config::class)['service']);
28
            foreach ($this->app->get(Filesystem::class)->listClasses('Job') as $class) {
29
                $jobs[$serviceName.'\\'.substr($class, strlen('Job\\'))] = $class;
30
                $jobs[substr($class, strlen('Job\\'))] = $class;
31
            }
32
33
34
            foreach ($jobs as $part => $class) {
35
                $nick = str_replace('\\', '.', $part);
36
                $jobs[$nick] = $class;
37
                $jobs[strtolower($nick)] = $class;
38
            }
39
40
            $this->mapping = $jobs;
41
        }
42
43
        return $this->mapping;
44
    }
45
46 2
    public function hasJob(string $nick) : bool
47
    {
48 2
        return array_key_exists($nick, $this->getMapping());
49
    }
50
51
    public function getJobClass(string $nick) : string
52
    {
53
        $mapping = $this->getMapping();
54
        if (!array_key_exists($nick, $mapping)) {
55
            throw new LogicException("No job $nick");
56
        }
57
58
        $class = $mapping[$nick];
59
60
        if (!class_exists($class)) {
61
            throw new LogicException("No class for job $nick");
62
        }
63
        return $class;
64
    }
65
66
    public function dispatch(string $nick, array $arguments = [])
67
    {
68
        $class = $this->getJobClass($nick);
69
70
        $instance = $this->app->get($class);
71
        if (array_key_exists(0, $arguments)) {
72
            $arguments = $this->castArguments($class, $arguments);
73
        }
74
75
        foreach ($arguments as $k => $v) {
76
            $instance->$k = $v;
77
        }
78
79
        return $this->app->call([$instance, 'run']);
80
    }
81
82
    private function castArguments(string $class, array $arguments) : array
83
    {
84
        $reflection = new ReflectionClass($class);
85
        $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
86
        if (count($properties) == 1) {
87
            return [
88
                $properties[0]->getName() => count($arguments) == 1
89
                    ? $arguments[0]
90
                    : implode(' ', $arguments)
91
            ];
92
        }
93
        return $arguments;
94
    }
95
}
96