Passed
Push — dev ( 8b4395...7454ac )
by 世昌
02:34
created

RunnableRequestProcessor::createChainFromRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace suda\application\processor;
5
6
7
use suda\application\Application;
8
use suda\framework\Request;
9
use suda\framework\Response;
10
use suda\framework\runnable\Runnable;
11
12
class RunnableRequestProcessor implements RequestProcessor
13
{
14
    /**
15
     * @var string[]|null
16
     */
17
    protected $runnable = null;
18
19
    /**
20
     * @param Application $application
21
     * @param Request $request
22
     * @param Response $response
23
     * @return mixed
24
     */
25
    public function onRequest(Application $application, Request $request, Response $response)
26
    {
27
        $runnable = $this->getNextRunnable($application, $request);
28
        if ($runnable === null) {
29
            return null;
30
        }
31
        return $runnable($application, $request, $response, $this);
32
    }
33
34
    /**
35
     * @param Application $application
36
     * @param Request $request
37
     * @return Runnable|null
38
     */
39
    protected function getNextRunnable(Application $application, Request $request)
40
    {
41
        $runnable = $this->getNextRunnableFromChain($application, $request);
42
        if ($runnable === null) {
43
            return null;
44
        }
45
        return new Runnable($runnable);
46
    }
47
48
    /**
49
     * @param Application $application
50
     * @param Request $request
51
     * @return string|null
52
     */
53
    protected function getNextRunnableFromChain(Application $application, Request $request)
54
    {
55
        if ($this->runnable === null) {
56
            $this->runnable = $this->createRunnable($application, $request);
57
        }
58
        if (count($this->runnable) === 0) {
59
            return null;
60
        }
61
        return array_shift($this->runnable);
62
    }
63
64
    /**
65
     * @param Application $application
66
     * @param Request $request
67
     * @return array
68
     */
69
    protected function createRunnable(Application $application, Request $request)
70
    {
71
        $class = $application->getConfig()->get('processor', []);
72
        $processor = $this->formatClassAsRunnable($class);
73
        $runnable = $this->createChainFromRequest($request);
74
        return array_merge($processor, $runnable);
75
    }
76
77
    /**
78
     * @param Request $request
79
     * @return array
80
     */
81
    protected function createChainFromRequest(Request $request)
82
    {
83
        $runnable = $request->getAttribute('runnable');
84
        if (is_string($runnable)) {
85
            return [$runnable];
86
        }
87
        if (is_array($runnable)) {
88
            return $runnable;
89
        }
90
        $class = $request->getAttribute('class', []);
91
        return $this->formatClassAsRunnable($class);
92
    }
93
94
    /**
95
     * @param string|array $class
96
     * @return array
97
     */
98
    private function formatClassAsRunnable($class)
99
    {
100
        if (is_string($class)) {
101
            $class = [$class];
102
        }
103
        foreach ($class as $index => $className) {
104
            $class[$index] = $this->className($className) . '->onRequest';
105
        }
106
        return $class;
107
    }
108
109
    /**
110
     * 转换类名
111
     *
112
     * @param string $name
113
     * @return string
114
     */
115
    private function className(string $name)
116
    {
117
        return trim(str_replace(['.', '/'], '\\', $name), '\\');
118
    }
119
}