-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathModule.php
206 lines (178 loc) · 5.39 KB
/
Module.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php
namespace cyneek\yii2\routes;
use cyneek\yii2\routes\components\Route;
use cyneek\yii2\routes\models\Route as RouteDb;
use DirectoryIterator;
use Yii;
use yii\caching\TagDependency;
class Module extends \yii\base\Module
{
/**
* Defines the database tableName
*/
public static $tableName = 'site_routes';
/**
* @var bool
*/
public $enablePretttyUrl = TRUE;
/**
* @var bool
*/
public $enableStrictParsing = TRUE;
/**
* @var bool
*/
public $showScriptName = FALSE;
/**
* String array that will hold all the directories in which we will have
* the routes files
*
* @var string[]
*/
public $routes_dir = [];
/**
* Defines if the routing system is active or not. It's useful for testing purposes
*
* @var bool
*/
public $active = TRUE;
/**
* Defines if the routing system will use a database table to hold some of its routes
*
* @var bool
*/
public $activate_database_routes = FALSE;
/**
* @inheritdoc
*
* @throws \Exception
*/
public function init()
{
parent::init();
if ($this->active === TRUE)
{
// basic urlManager configuration
$this->initUrlManager();
// load urls into urlManager
$this->loadUrlRoutes($this->routes_dir);
$this->loadDBRoutes();
// get the route data (filters, routes, etc...)
$routeData = Route::map();
// add the routes
foreach ($routeData as $from => $data)
{
Yii::$app->urlManager->addRules([$from => $data['to']]);
$routeData[$from]['route'] = end(Yii::$app->urlManager->rules);
}
// only attaches the behavior of the active route
foreach ($routeData as $from => $data)
{
if ($data['route']->parseRequest(Yii::$app->urlManager, Yii::$app->getRequest()) !== FALSE)
{
foreach ($data['filters'] as $filter_name => $filter_data)
{
Yii::$app->attachBehavior($filter_name, $filter_data);
}
}
}
// relaunch init with the new data
Yii::$app->urlManager->init();
}
}
/**
* Initializes basic config for urlManager for using Yii2 as Laravel routes
*
* This method will set manually
*/
function initUrlManager()
{
// custom initialization code goes here
// routes should be always pretty url and strict parsed, any
// url out of the route files will be treated as a 404 error.
Yii::$app->urlManager->enablePrettyUrl = $this->enablePretttyUrl;
Yii::$app->urlManager->enableStrictParsing = $this->enableStrictParsing;
Yii::$app->urlManager->showScriptName = $this->showScriptName;
}
/**
* Initializes basic config for urlManager for using Yii2 as Laravel routes
*
* This method will call [[buildRules()]] to parse the given rule declarations and then append or insert
* them to the existing [[rules]].
*
* @param string[] $routesDir
* @throws \Exception
*/
function loadUrlRoutes($routesDir)
{
if (!is_array($routesDir))
{
$routesDir = [$routesDir];
}
foreach ($routesDir as $dir)
{
if (!is_string($dir))
{
continue;
}
$dir = Yii::getAlias($dir);
if (is_dir($dir))
{
/** @var \DirectoryIterator $fileInfo */
foreach (new DirectoryIterator($dir) as $fileInfo)
{
if ($fileInfo->isDot())
{
continue;
}
if ($fileInfo->isFile() && $fileInfo->isReadable())
{
// loads the file and executes the Route:: calls
include_once($fileInfo->getPathName());
}
}
}
else
{
throw new \Exception($dir . ' it\'s not a valid directory.');
}
}
}
/**
* Load routes from Database if the $activate_database_routes parameter is true
*
* @throws \Exception
*/
function loadDBRoutes()
{
if ($this->activate_database_routes === TRUE)
{
$dependency = new TagDependency(array('tags' => [self::className()]));
$route_list = RouteDb::getDb()->cache(function ($db)
{
return RouteDb::find()->where(['app' => Yii::$app->id])
->all();
}, 0, $dependency);
foreach ($route_list as $route)
{
$options = json_decode($route['config'], TRUE);
if (is_null($options))
{
$options = [];
}
Route::$route['type']($route['uri'], $route['route'], $options);
}
}
}
/**
* Resets the cache of the route retrieval query only in case it's activated.
*
*/
function resetDBCache()
{
if (!is_null(Yii::$app->cache))
{
TagDependency::invalidate(Yii::$app->cache, [self::className()]);
}
}
}