Passed
Push — dev ( 0792b6...473109 )
by 世昌
02:27
created

ApplicationLoader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace suda\application\loader;
4
5
use suda\framework\Config;
6
use suda\application\Module;
7
use suda\application\Application;
8
use suda\application\ApplicationModule;
9
10
/**
11
 * 应用程序
12
 */
13
class ApplicationLoader extends ApplicationBaseLoader
14
{
15
16
    const CACHE_ROUTE = 'application-route';
17
    const CACHE_ROUTE_RUNNABLE = 'application-route-runnable';
18
19
    /**
20
     * @var Application
21
     */
22
    protected $application;
23
24
    /**
25
     * ApplicationLoader constructor.
26
     * @param Application $application
27
     */
28
    public function __construct(Application $application)
29
    {
30
        parent::__construct($application);
31
    }
32
33
    /**
34
     * 加载路由
35
     */
36
    public function loadRoute()
37
    {
38
        $name = 'application-route';
39
        $this->application->debug()->time($name);
40
        if (static::isDebug()) {
41
            $this->loadRouteFromModules();
42
            if ($this->application->getRoute()->isContainClosure()) {
43
                $this->application->debug()->warning('route contain closure, route prepare cannot be cacheables');
44
            } else {
45
                $this->application->cache()->set(ApplicationLoader::CACHE_ROUTE, $this->application->getRoute()->getRouteCollection());
46
                $this->application->cache()->set(ApplicationLoader::CACHE_ROUTE_RUNNABLE, $this->application->getRoute()->getRunnable());
47
            }
48
        } elseif ($this->routeCacheAvailable()) {
49
            $route = $this->application->cache()->get(ApplicationLoader::CACHE_ROUTE);
50
            $runnable = $this->application->cache()->get(ApplicationLoader::CACHE_ROUTE_RUNNABLE);
51
            $this->application->getRoute()->setRouteCollection($route);
52
            $this->application->getRoute()->setRunnable($runnable);
53
            $this->application->debug()->info('load route from cache');
54
        } else {
55
            $this->loadRouteFromModules();
56
        }
57
        $this->application->debug()->timeEnd($name);
58
    }
59
60
    /**
61
     * 从模块中加载路由
62
     */
63
    private function loadRouteFromModules()
64
    {
65
        foreach ($this->application->getModules() as $name => $module) {
66
            if ($module->getStatus() === Module::REACHABLE) {
67
                $this->loadModuleRoute($module);
68
                $this->application->debug()->debug('reachable # ' . $module->getFullName());
69
            }
70
        }
71
    }
72
73
    /**
74
     * @return bool
75
     */
76
    private function routeCacheAvailable()
77
    {
78
        return $this->application->cache()->has(ApplicationLoader::CACHE_ROUTE)
79
            && $this->application->cache()->has(ApplicationLoader::CACHE_ROUTE_RUNNABLE);
80
    }
81
82
    /**
83
     * 加载路由
84
     * @param Module $module
85
     */
86
    protected function loadModuleRoute(Module $module)
87
    {
88
        foreach ($this->application->getRouteGroup() as $group) {
89
            $this->loadRouteGroup($module, $group);
90
        }
91
    }
92
93
    /**
94
     * 加载路由组
95
     *
96
     * @param Module $module
97
     * @param string $groupName
98
     * @return void
99
     */
100
    protected function loadRouteGroup(Module $module, string $groupName)
101
    {
102
        $group = $groupName === 'default' ? '' : '-' . $groupName;
103
        if ($path = $module->getResource()->getConfigResourcePath('config/route' . $group)) {
104
            $routeConfig = Config::loadConfig($path, [
105
                'module' => $module->getName(),
106
                'group' => $groupName,
107
                'property' => $module->getProperty(),
108
                'config' => $module->getConfig(),
109
            ]);
110
            if ($routeConfig !== null) {
111
                $prefix = $module->getConfig('route-prefix.' . $groupName, '');
112
                $this->loadRouteConfig($module, $prefix, $groupName, $routeConfig);
113
            }
114
        }
115
    }
116
117
    /**
118
     * 加载模块路由配置
119
     *
120
     * @param Module $module
121
     * @param string $prefix
122
     * @param string $groupName
123
     * @param array $routeConfig
124
     * @return void
125
     */
126
    protected function loadRouteConfig(Module $module, string $prefix, string $groupName, array $routeConfig)
127
    {
128
        $module = $module->getFullName();
129
        foreach ($routeConfig as $name => $config) {
130
            $exname = $this->application->getRouteName($name, $module, $groupName);
131
            $method = $config['method'] ?? [];
132
            $attributes = [];
133
            $attributes['module'] = $module;
134
            $attributes['config'] = $config;
135
            $attributes['group'] = $groupName;
136
            $attributes['route'] = $exname;
137
            $uri = $config['uri'] ?? '/';
138
            $anti = array_key_exists('anti-prefix', $config) && $config['anti-prefix'];
139
            if ($anti) {
140
                $uri = '/' . trim($uri, '/');
141
            } else {
142
                $uri = '/' . trim($prefix . $uri, '/');
143
            }
144
            $this->application->request($method, $exname, $uri, $attributes);
145
        }
146
    }
147
}
148