Completed
Push — master ( 4c5d1a...2ea30f )
by
unknown
31:11
created
lib/private/AppFramework/Routing/RouteParser.php 1 patch
Indentation   +234 added lines, -234 removed lines patch added patch discarded remove patch
@@ -12,243 +12,243 @@
 block discarded – undo
12 12
 use Symfony\Component\Routing\RouteCollection;
13 13
 
14 14
 class RouteParser {
15
-	/** @var string[] */
16
-	private $controllerNameCache = [];
17
-
18
-	private const rootUrlApps = [
19
-		'cloud_federation_api',
20
-		'core',
21
-		'files_sharing',
22
-		'files',
23
-		'globalsiteselector',
24
-		'profile',
25
-		'settings',
26
-		'spreed',
27
-	];
28
-
29
-	public function parseDefaultRoutes(array $routes, string $appName): RouteCollection {
30
-		$collection = $this->processIndexRoutes($routes, $appName);
31
-		$collection->addCollection($this->processIndexResources($routes, $appName));
32
-
33
-		return $collection;
34
-	}
35
-
36
-	public function parseOCSRoutes(array $routes, string $appName): RouteCollection {
37
-		$collection = $this->processOCS($routes, $appName);
38
-		$collection->addCollection($this->processOCSResources($routes, $appName));
39
-
40
-		return $collection;
41
-	}
42
-
43
-	private function processOCS(array $routes, string $appName): RouteCollection {
44
-		$collection = new RouteCollection();
45
-		$ocsRoutes = $routes['ocs'] ?? [];
46
-		foreach ($ocsRoutes as $ocsRoute) {
47
-			$result = $this->processRoute($ocsRoute, $appName, 'ocs.');
48
-
49
-			$collection->add($result[0], $result[1]);
50
-		}
51
-
52
-		return $collection;
53
-	}
54
-
55
-	/**
56
-	 * Creates one route base on the give configuration
57
-	 * @param array $routes
58
-	 * @throws \UnexpectedValueException
59
-	 */
60
-	private function processIndexRoutes(array $routes, string $appName): RouteCollection {
61
-		$collection = new RouteCollection();
62
-		$simpleRoutes = $routes['routes'] ?? [];
63
-		foreach ($simpleRoutes as $simpleRoute) {
64
-			$result = $this->processRoute($simpleRoute, $appName);
65
-
66
-			$collection->add($result[0], $result[1]);
67
-		}
68
-
69
-		return $collection;
70
-	}
71
-
72
-	private function processRoute(array $route, string $appName, string $routeNamePrefix = ''): array {
73
-		$name = $route['name'];
74
-		$postfix = $route['postfix'] ?? '';
75
-		$root = $this->buildRootPrefix($route, $appName, $routeNamePrefix);
76
-
77
-		$url = $root . '/' . ltrim($route['url'], '/');
78
-		$verb = strtoupper($route['verb'] ?? 'GET');
79
-
80
-		$split = explode('#', $name, 3);
81
-		if (count($split) !== 2) {
82
-			throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
83
-		}
84
-		[$controller, $action] = $split;
85
-
86
-		$controllerName = $this->buildControllerName($controller);
87
-		$actionName = $this->buildActionName($action);
88
-
89
-		/*
15
+    /** @var string[] */
16
+    private $controllerNameCache = [];
17
+
18
+    private const rootUrlApps = [
19
+        'cloud_federation_api',
20
+        'core',
21
+        'files_sharing',
22
+        'files',
23
+        'globalsiteselector',
24
+        'profile',
25
+        'settings',
26
+        'spreed',
27
+    ];
28
+
29
+    public function parseDefaultRoutes(array $routes, string $appName): RouteCollection {
30
+        $collection = $this->processIndexRoutes($routes, $appName);
31
+        $collection->addCollection($this->processIndexResources($routes, $appName));
32
+
33
+        return $collection;
34
+    }
35
+
36
+    public function parseOCSRoutes(array $routes, string $appName): RouteCollection {
37
+        $collection = $this->processOCS($routes, $appName);
38
+        $collection->addCollection($this->processOCSResources($routes, $appName));
39
+
40
+        return $collection;
41
+    }
42
+
43
+    private function processOCS(array $routes, string $appName): RouteCollection {
44
+        $collection = new RouteCollection();
45
+        $ocsRoutes = $routes['ocs'] ?? [];
46
+        foreach ($ocsRoutes as $ocsRoute) {
47
+            $result = $this->processRoute($ocsRoute, $appName, 'ocs.');
48
+
49
+            $collection->add($result[0], $result[1]);
50
+        }
51
+
52
+        return $collection;
53
+    }
54
+
55
+    /**
56
+     * Creates one route base on the give configuration
57
+     * @param array $routes
58
+     * @throws \UnexpectedValueException
59
+     */
60
+    private function processIndexRoutes(array $routes, string $appName): RouteCollection {
61
+        $collection = new RouteCollection();
62
+        $simpleRoutes = $routes['routes'] ?? [];
63
+        foreach ($simpleRoutes as $simpleRoute) {
64
+            $result = $this->processRoute($simpleRoute, $appName);
65
+
66
+            $collection->add($result[0], $result[1]);
67
+        }
68
+
69
+        return $collection;
70
+    }
71
+
72
+    private function processRoute(array $route, string $appName, string $routeNamePrefix = ''): array {
73
+        $name = $route['name'];
74
+        $postfix = $route['postfix'] ?? '';
75
+        $root = $this->buildRootPrefix($route, $appName, $routeNamePrefix);
76
+
77
+        $url = $root . '/' . ltrim($route['url'], '/');
78
+        $verb = strtoupper($route['verb'] ?? 'GET');
79
+
80
+        $split = explode('#', $name, 3);
81
+        if (count($split) !== 2) {
82
+            throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
83
+        }
84
+        [$controller, $action] = $split;
85
+
86
+        $controllerName = $this->buildControllerName($controller);
87
+        $actionName = $this->buildActionName($action);
88
+
89
+        /*
90 90
 		 * The route name has to be lowercase, for symfony to match it correctly.
91 91
 		 * This is required because symfony allows mixed casing for controller names in the routes.
92 92
 		 * To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
93 93
 		 * This is also safe on the PHP side because class and method names collide regardless of the casing.
94 94
 		 */
95
-		$routeName = strtolower($routeNamePrefix . $appName . '.' . $controller . '.' . $action . $postfix);
96
-
97
-		$routeObject = new Route($url);
98
-		$routeObject->method($verb);
99
-
100
-		// optionally register requirements for route. This is used to
101
-		// tell the route parser how url parameters should be matched
102
-		if (array_key_exists('requirements', $route)) {
103
-			$routeObject->requirements($route['requirements']);
104
-		}
105
-
106
-		// optionally register defaults for route. This is used to
107
-		// tell the route parser how url parameters should be default valued
108
-		$defaults = [];
109
-		if (array_key_exists('defaults', $route)) {
110
-			$defaults = $route['defaults'];
111
-		}
112
-
113
-		$defaults['caller'] = [$appName, $controllerName, $actionName];
114
-		$routeObject->defaults($defaults);
115
-
116
-		return [$routeName, $routeObject];
117
-	}
118
-
119
-	/**
120
-	 * For a given name and url restful OCS routes are created:
121
-	 *  - index
122
-	 *  - show
123
-	 *  - create
124
-	 *  - update
125
-	 *  - destroy
126
-	 *
127
-	 * @param array $routes
128
-	 */
129
-	private function processOCSResources(array $routes, string $appName): RouteCollection {
130
-		return $this->processResources($routes['ocs-resources'] ?? [], $appName, 'ocs.');
131
-	}
132
-
133
-	/**
134
-	 * For a given name and url restful routes are created:
135
-	 *  - index
136
-	 *  - show
137
-	 *  - create
138
-	 *  - update
139
-	 *  - destroy
140
-	 *
141
-	 * @param array $routes
142
-	 */
143
-	private function processIndexResources(array $routes, string $appName): RouteCollection {
144
-		return $this->processResources($routes['resources'] ?? [], $appName);
145
-	}
146
-
147
-	/**
148
-	 * For a given name and url restful routes are created:
149
-	 *  - index
150
-	 *  - show
151
-	 *  - create
152
-	 *  - update
153
-	 *  - destroy
154
-	 *
155
-	 * @param array $resources
156
-	 * @param string $routeNamePrefix
157
-	 */
158
-	private function processResources(array $resources, string $appName, string $routeNamePrefix = ''): RouteCollection {
159
-		// declaration of all restful actions
160
-		$actions = [
161
-			['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
162
-			['name' => 'show', 'verb' => 'GET'],
163
-			['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
164
-			['name' => 'update', 'verb' => 'PUT'],
165
-			['name' => 'destroy', 'verb' => 'DELETE'],
166
-		];
167
-
168
-		$collection = new RouteCollection();
169
-		foreach ($resources as $resource => $config) {
170
-			$root = $this->buildRootPrefix($config, $appName, $routeNamePrefix);
171
-
172
-			// the url parameter used as id to the resource
173
-			foreach ($actions as $action) {
174
-				$url = $root . '/' . ltrim($config['url'], '/');
175
-				$method = $action['name'];
176
-
177
-				$verb = strtoupper($action['verb'] ?? 'GET');
178
-				$collectionAction = $action['on-collection'] ?? false;
179
-				if (!$collectionAction) {
180
-					$url .= '/{id}';
181
-				}
182
-
183
-				$controller = $resource;
184
-
185
-				$controllerName = $this->buildControllerName($controller);
186
-				$actionName = $this->buildActionName($method);
187
-
188
-				$routeName = $routeNamePrefix . $appName . '.' . strtolower($resource) . '.' . $method;
189
-
190
-				$route = new Route($url);
191
-				$route->method($verb);
192
-
193
-				$route->defaults(['caller' => [$appName, $controllerName, $actionName]]);
194
-
195
-				$collection->add($routeName, $route);
196
-			}
197
-		}
198
-
199
-		return $collection;
200
-	}
201
-
202
-	private function buildRootPrefix(array $route, string $appName, string $routeNamePrefix): string {
203
-		$defaultRoot = $appName === 'core' ? '' : '/apps/' . $appName;
204
-		$root = $route['root'] ?? $defaultRoot;
205
-
206
-		if ($routeNamePrefix !== '') {
207
-			// In OCS all apps are whitelisted
208
-			return $root;
209
-		}
210
-
211
-		if (!\in_array($appName, self::rootUrlApps, true)) {
212
-			// Only allow root URLS for some apps
213
-			return  $defaultRoot;
214
-		}
215
-
216
-		return $root;
217
-	}
218
-
219
-	/**
220
-	 * Based on a given route name the controller name is generated
221
-	 * @param string $controller
222
-	 * @return string
223
-	 */
224
-	private function buildControllerName(string $controller): string {
225
-		if (!isset($this->controllerNameCache[$controller])) {
226
-			$this->controllerNameCache[$controller] = $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
227
-		}
228
-		return $this->controllerNameCache[$controller];
229
-	}
230
-
231
-	/**
232
-	 * Based on the action part of the route name the controller method name is generated
233
-	 * @param string $action
234
-	 * @return string
235
-	 */
236
-	private function buildActionName(string $action): string {
237
-		return $this->underScoreToCamelCase($action);
238
-	}
239
-
240
-	/**
241
-	 * Underscored strings are converted to camel case strings
242
-	 * @param string $str
243
-	 * @return string
244
-	 */
245
-	private function underScoreToCamelCase(string $str): string {
246
-		$pattern = '/_[a-z]?/';
247
-		return preg_replace_callback(
248
-			$pattern,
249
-			function ($matches) {
250
-				return strtoupper(ltrim($matches[0], '_'));
251
-			},
252
-			$str);
253
-	}
95
+        $routeName = strtolower($routeNamePrefix . $appName . '.' . $controller . '.' . $action . $postfix);
96
+
97
+        $routeObject = new Route($url);
98
+        $routeObject->method($verb);
99
+
100
+        // optionally register requirements for route. This is used to
101
+        // tell the route parser how url parameters should be matched
102
+        if (array_key_exists('requirements', $route)) {
103
+            $routeObject->requirements($route['requirements']);
104
+        }
105
+
106
+        // optionally register defaults for route. This is used to
107
+        // tell the route parser how url parameters should be default valued
108
+        $defaults = [];
109
+        if (array_key_exists('defaults', $route)) {
110
+            $defaults = $route['defaults'];
111
+        }
112
+
113
+        $defaults['caller'] = [$appName, $controllerName, $actionName];
114
+        $routeObject->defaults($defaults);
115
+
116
+        return [$routeName, $routeObject];
117
+    }
118
+
119
+    /**
120
+     * For a given name and url restful OCS routes are created:
121
+     *  - index
122
+     *  - show
123
+     *  - create
124
+     *  - update
125
+     *  - destroy
126
+     *
127
+     * @param array $routes
128
+     */
129
+    private function processOCSResources(array $routes, string $appName): RouteCollection {
130
+        return $this->processResources($routes['ocs-resources'] ?? [], $appName, 'ocs.');
131
+    }
132
+
133
+    /**
134
+     * For a given name and url restful routes are created:
135
+     *  - index
136
+     *  - show
137
+     *  - create
138
+     *  - update
139
+     *  - destroy
140
+     *
141
+     * @param array $routes
142
+     */
143
+    private function processIndexResources(array $routes, string $appName): RouteCollection {
144
+        return $this->processResources($routes['resources'] ?? [], $appName);
145
+    }
146
+
147
+    /**
148
+     * For a given name and url restful routes are created:
149
+     *  - index
150
+     *  - show
151
+     *  - create
152
+     *  - update
153
+     *  - destroy
154
+     *
155
+     * @param array $resources
156
+     * @param string $routeNamePrefix
157
+     */
158
+    private function processResources(array $resources, string $appName, string $routeNamePrefix = ''): RouteCollection {
159
+        // declaration of all restful actions
160
+        $actions = [
161
+            ['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
162
+            ['name' => 'show', 'verb' => 'GET'],
163
+            ['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
164
+            ['name' => 'update', 'verb' => 'PUT'],
165
+            ['name' => 'destroy', 'verb' => 'DELETE'],
166
+        ];
167
+
168
+        $collection = new RouteCollection();
169
+        foreach ($resources as $resource => $config) {
170
+            $root = $this->buildRootPrefix($config, $appName, $routeNamePrefix);
171
+
172
+            // the url parameter used as id to the resource
173
+            foreach ($actions as $action) {
174
+                $url = $root . '/' . ltrim($config['url'], '/');
175
+                $method = $action['name'];
176
+
177
+                $verb = strtoupper($action['verb'] ?? 'GET');
178
+                $collectionAction = $action['on-collection'] ?? false;
179
+                if (!$collectionAction) {
180
+                    $url .= '/{id}';
181
+                }
182
+
183
+                $controller = $resource;
184
+
185
+                $controllerName = $this->buildControllerName($controller);
186
+                $actionName = $this->buildActionName($method);
187
+
188
+                $routeName = $routeNamePrefix . $appName . '.' . strtolower($resource) . '.' . $method;
189
+
190
+                $route = new Route($url);
191
+                $route->method($verb);
192
+
193
+                $route->defaults(['caller' => [$appName, $controllerName, $actionName]]);
194
+
195
+                $collection->add($routeName, $route);
196
+            }
197
+        }
198
+
199
+        return $collection;
200
+    }
201
+
202
+    private function buildRootPrefix(array $route, string $appName, string $routeNamePrefix): string {
203
+        $defaultRoot = $appName === 'core' ? '' : '/apps/' . $appName;
204
+        $root = $route['root'] ?? $defaultRoot;
205
+
206
+        if ($routeNamePrefix !== '') {
207
+            // In OCS all apps are whitelisted
208
+            return $root;
209
+        }
210
+
211
+        if (!\in_array($appName, self::rootUrlApps, true)) {
212
+            // Only allow root URLS for some apps
213
+            return  $defaultRoot;
214
+        }
215
+
216
+        return $root;
217
+    }
218
+
219
+    /**
220
+     * Based on a given route name the controller name is generated
221
+     * @param string $controller
222
+     * @return string
223
+     */
224
+    private function buildControllerName(string $controller): string {
225
+        if (!isset($this->controllerNameCache[$controller])) {
226
+            $this->controllerNameCache[$controller] = $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
227
+        }
228
+        return $this->controllerNameCache[$controller];
229
+    }
230
+
231
+    /**
232
+     * Based on the action part of the route name the controller method name is generated
233
+     * @param string $action
234
+     * @return string
235
+     */
236
+    private function buildActionName(string $action): string {
237
+        return $this->underScoreToCamelCase($action);
238
+    }
239
+
240
+    /**
241
+     * Underscored strings are converted to camel case strings
242
+     * @param string $str
243
+     * @return string
244
+     */
245
+    private function underScoreToCamelCase(string $str): string {
246
+        $pattern = '/_[a-z]?/';
247
+        return preg_replace_callback(
248
+            $pattern,
249
+            function ($matches) {
250
+                return strtoupper(ltrim($matches[0], '_'));
251
+            },
252
+            $str);
253
+    }
254 254
 }
Please login to merge, or discard this patch.