Completed
Push — master ( a7d764...b698e6 )
by Dmitry
03:16
created

Runner::getMapping()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 18
cts 18
cp 1
rs 9.1608
c 0
b 0
f 0
cc 5
nc 2
nop 0
crap 5
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 45
    public function __construct(Application $app)
16
    {
17 45
        $this->app = $app;
18 45
    }
19
20 45
    public function getMapping() : array
21
    {
22 45
        if (!$this->mapping) {
23 45
            $jobs = [];
24 45
            foreach ($this->app->get(Framework::class)->listClasses('Job') as $class) {
25 45
                $jobs[substr($class, strlen('Basis\\Job\\'))] = $class;
26
            }
27 45
            $serviceName = ucfirst($this->app->get(Config::class)['service']);
28 45
            foreach ($this->app->get(Filesystem::class)->listClasses('Job') as $class) {
29 45
                $jobs[$serviceName.'\\'.substr($class, strlen('Job\\'))] = $class;
30 45
                $jobs[$serviceName.'\\'.lcfirst(substr($class, strlen('Job\\')))] = $class;
31 45
                $jobs[substr($class, strlen('Job\\'))] = $class;
32 45
                $jobs[lcfirst(substr($class, strlen('Job\\')))] = $class;
33
            }
34
35
36 45
            foreach ($jobs as $part => $class) {
37 45
                $nick = str_replace('\\', '.', $part);
38 45
                $jobs[$nick] = $class;
39 45
                $jobs[lcfirst($nick)] = $class;
40 45
                $jobs[strtolower($nick)] = $class;
41
            }
42
43 45
            $this->mapping = $jobs;
44
        }
45
46 45
        return $this->mapping;
47
    }
48
49 45
    public function hasJob(string $nick) : bool
50
    {
51 45
        return array_key_exists($nick, $this->getMapping());
52
    }
53
54 45
    public function getJobClass(string $nick) : string
55
    {
56 45
        $mapping = $this->getMapping();
57 45
        if (!array_key_exists($nick, $mapping)) {
58
            throw new LogicException("No job $nick");
59
        }
60
61 45
        $class = $mapping[$nick];
62
63 45
        if (!class_exists($class)) {
64
            throw new LogicException("No class for job $nick");
65
        }
66 45
        return $class;
67
    }
68
69 45
    public function dispatch(string $nick, array $arguments = [])
70
    {
71 45
        $converter = $this->app->get(Converter::class);
72 45
        if (count($arguments)) {
73 9
            if ($converter->isTuple($arguments) && is_array($arguments[0])) {
74 1
                $result = [];
75 1
                foreach ($arguments as $params) {
76 1
                    $result[] = $this->dispatch($nick, $params);
77
                }
78 1
                return $result;
79
            }
80
        }
81
82 45
        $class = $this->getJobClass($nick);
83
84 45
        $instance = $this->app->get($class);
85 45
        if (array_key_exists(0, $arguments)) {
86 2
            $arguments = $this->castArguments($class, $arguments);
87
        }
88
89 45
        foreach ($arguments as $k => $v) {
90 9
            if (is_array($v) && !$converter->isTuple($v)) {
91
                $v = $converter->toObject($v);
92
            }
93 9
            $instance->$k = $v;
94
        }
95 45
        return $converter->toObject($this->app->call([$instance, 'run']));
96
    }
97
98 2
    private function castArguments(string $class, array $arguments) : array
99
    {
100 2
        $reflection = new ReflectionClass($class);
101 2
        $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
102 2
        if (count($properties) == 1) {
103
            return [
104 2
                $properties[0]->getName() => count($arguments) == 1
105 2
                    ? $arguments[0]
106 2
                    : implode(' ', $arguments)
107
            ];
108
        }
109
        return $arguments;
110
    }
111
}
112