Passed
Push — master ( de7c54...6228cb )
by Roeland
14:13 queued 10s
created
lib/private/Route/Router.php 1 patch
Indentation   +399 added lines, -399 removed lines patch added patch discarded remove patch
@@ -46,403 +46,403 @@
 block discarded – undo
46 46
 use Symfony\Component\Routing\RouteCollection;
47 47
 
48 48
 class Router implements IRouter {
49
-	/** @var RouteCollection[] */
50
-	protected $collections = [];
51
-	/** @var null|RouteCollection */
52
-	protected $collection = null;
53
-	/** @var null|string */
54
-	protected $collectionName = null;
55
-	/** @var null|RouteCollection */
56
-	protected $root = null;
57
-	/** @var null|UrlGenerator */
58
-	protected $generator = null;
59
-	/** @var string[] */
60
-	protected $routingFiles;
61
-	/** @var bool */
62
-	protected $loaded = false;
63
-	/** @var array */
64
-	protected $loadedApps = [];
65
-	/** @var ILogger */
66
-	protected $logger;
67
-	/** @var RequestContext */
68
-	protected $context;
69
-
70
-	/**
71
-	 * @param ILogger $logger
72
-	 */
73
-	public function __construct(ILogger $logger) {
74
-		$this->logger = $logger;
75
-		$baseUrl = \OC::$WEBROOT;
76
-		if (!(\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
77
-			$baseUrl .= '/index.php';
78
-		}
79
-		if (!\OC::$CLI && isset($_SERVER['REQUEST_METHOD'])) {
80
-			$method = $_SERVER['REQUEST_METHOD'];
81
-		} else {
82
-			$method = 'GET';
83
-		}
84
-		$request = \OC::$server->getRequest();
85
-		$host = $request->getServerHost();
86
-		$schema = $request->getServerProtocol();
87
-		$this->context = new RequestContext($baseUrl, $method, $host, $schema);
88
-		// TODO cache
89
-		$this->root = $this->getCollection('root');
90
-	}
91
-
92
-	/**
93
-	 * Get the files to load the routes from
94
-	 *
95
-	 * @return string[]
96
-	 */
97
-	public function getRoutingFiles() {
98
-		if (!isset($this->routingFiles)) {
99
-			$this->routingFiles = [];
100
-			foreach (\OC_APP::getEnabledApps() as $app) {
101
-				$appPath = \OC_App::getAppPath($app);
102
-				if ($appPath !== false) {
103
-					$file = $appPath . '/appinfo/routes.php';
104
-					if (file_exists($file)) {
105
-						$this->routingFiles[$app] = $file;
106
-					}
107
-				}
108
-			}
109
-		}
110
-		return $this->routingFiles;
111
-	}
112
-
113
-	/**
114
-	 * Loads the routes
115
-	 *
116
-	 * @param null|string $app
117
-	 */
118
-	public function loadRoutes($app = null) {
119
-		if (is_string($app)) {
120
-			$app = \OC_App::cleanAppId($app);
121
-		}
122
-
123
-		$requestedApp = $app;
124
-		if ($this->loaded) {
125
-			return;
126
-		}
127
-		if (is_null($app)) {
128
-			$this->loaded = true;
129
-			$routingFiles = $this->getRoutingFiles();
130
-		} else {
131
-			if (isset($this->loadedApps[$app])) {
132
-				return;
133
-			}
134
-			$file = \OC_App::getAppPath($app) . '/appinfo/routes.php';
135
-			if ($file !== false && file_exists($file)) {
136
-				$routingFiles = [$app => $file];
137
-			} else {
138
-				$routingFiles = [];
139
-			}
140
-		}
141
-		\OC::$server->getEventLogger()->start('loadroutes' . $requestedApp, 'Loading Routes');
142
-		foreach ($routingFiles as $app => $file) {
143
-			if (!isset($this->loadedApps[$app])) {
144
-				if (!\OC_App::isAppLoaded($app)) {
145
-					// app MUST be loaded before app routes
146
-					// try again next time loadRoutes() is called
147
-					$this->loaded = false;
148
-					continue;
149
-				}
150
-				$this->loadedApps[$app] = true;
151
-				$this->useCollection($app);
152
-				$this->requireRouteFile($file, $app);
153
-				$collection = $this->getCollection($app);
154
-				$this->root->addCollection($collection);
155
-
156
-				// Also add the OCS collection
157
-				$collection = $this->getCollection($app.'.ocs');
158
-				$collection->addPrefix('/ocsapp');
159
-				$this->root->addCollection($collection);
160
-			}
161
-		}
162
-		if (!isset($this->loadedApps['core'])) {
163
-			$this->loadedApps['core'] = true;
164
-			$this->useCollection('root');
165
-			require_once __DIR__ . '/../../../core/routes.php';
166
-
167
-			// Also add the OCS collection
168
-			$collection = $this->getCollection('root.ocs');
169
-			$collection->addPrefix('/ocsapp');
170
-			$this->root->addCollection($collection);
171
-		}
172
-		if ($this->loaded) {
173
-			$collection = $this->getCollection('ocs');
174
-			$collection->addPrefix('/ocs');
175
-			$this->root->addCollection($collection);
176
-		}
177
-		\OC::$server->getEventLogger()->end('loadroutes' . $requestedApp);
178
-	}
179
-
180
-	/**
181
-	 * @param string $name
182
-	 * @return \Symfony\Component\Routing\RouteCollection
183
-	 */
184
-	protected function getCollection($name) {
185
-		if (!isset($this->collections[$name])) {
186
-			$this->collections[$name] = new RouteCollection();
187
-		}
188
-		return $this->collections[$name];
189
-	}
190
-
191
-	/**
192
-	 * Sets the collection to use for adding routes
193
-	 *
194
-	 * @param string $name Name of the collection to use.
195
-	 * @return void
196
-	 */
197
-	public function useCollection($name) {
198
-		$this->collection = $this->getCollection($name);
199
-		$this->collectionName = $name;
200
-	}
201
-
202
-	/**
203
-	 * returns the current collection name in use for adding routes
204
-	 *
205
-	 * @return string the collection name
206
-	 */
207
-	public function getCurrentCollection() {
208
-		return $this->collectionName;
209
-	}
210
-
211
-
212
-	/**
213
-	 * Create a \OC\Route\Route.
214
-	 *
215
-	 * @param string $name Name of the route to create.
216
-	 * @param string $pattern The pattern to match
217
-	 * @param array $defaults An array of default parameter values
218
-	 * @param array $requirements An array of requirements for parameters (regexes)
219
-	 * @return \OC\Route\Route
220
-	 */
221
-	public function create($name,
222
-						   $pattern,
223
-						   array $defaults = [],
224
-						   array $requirements = []) {
225
-		$route = new Route($pattern, $defaults, $requirements);
226
-		$this->collection->add($name, $route);
227
-		return $route;
228
-	}
229
-
230
-	/**
231
-	 * Find the route matching $url
232
-	 *
233
-	 * @param string $url The url to find
234
-	 * @throws \Exception
235
-	 * @return array
236
-	 */
237
-	public function findMatchingRoute(string $url): array {
238
-		if (substr($url, 0, 6) === '/apps/') {
239
-			// empty string / 'apps' / $app / rest of the route
240
-			list(, , $app,) = explode('/', $url, 4);
241
-
242
-			$app = \OC_App::cleanAppId($app);
243
-			\OC::$REQUESTEDAPP = $app;
244
-			$this->loadRoutes($app);
245
-		} elseif (substr($url, 0, 13) === '/ocsapp/apps/') {
246
-			// empty string / 'ocsapp' / 'apps' / $app / rest of the route
247
-			list(, , , $app,) = explode('/', $url, 5);
248
-
249
-			$app = \OC_App::cleanAppId($app);
250
-			\OC::$REQUESTEDAPP = $app;
251
-			$this->loadRoutes($app);
252
-		} elseif (substr($url, 0, 10) === '/settings/') {
253
-			$this->loadRoutes('settings');
254
-		} elseif (substr($url, 0, 6) === '/core/') {
255
-			\OC::$REQUESTEDAPP = $url;
256
-			if (!\OC::$server->getConfig()->getSystemValueBool('maintenance') && !Util::needUpgrade()) {
257
-				\OC_App::loadApps();
258
-			}
259
-			$this->loadRoutes('core');
260
-		} else {
261
-			$this->loadRoutes();
262
-		}
263
-
264
-		$matcher = new UrlMatcher($this->root, $this->context);
265
-		try {
266
-			$parameters = $matcher->match($url);
267
-		} catch (ResourceNotFoundException $e) {
268
-			if (substr($url, -1) !== '/') {
269
-				// We allow links to apps/files? for backwards compatibility reasons
270
-				// However, since Symfony does not allow empty route names, the route
271
-				// we need to match is '/', so we need to append the '/' here.
272
-				try {
273
-					$parameters = $matcher->match($url . '/');
274
-				} catch (ResourceNotFoundException $newException) {
275
-					// If we still didn't match a route, we throw the original exception
276
-					throw $e;
277
-				}
278
-			} else {
279
-				throw $e;
280
-			}
281
-		}
282
-
283
-		return $parameters;
284
-	}
285
-
286
-	/**
287
-	 * Find and execute the route matching $url
288
-	 *
289
-	 * @param string $url The url to find
290
-	 * @throws \Exception
291
-	 * @return void
292
-	 */
293
-	public function match($url) {
294
-		$parameters = $this->findMatchingRoute($url);
295
-
296
-		\OC::$server->getEventLogger()->start('run_route', 'Run route');
297
-		if (isset($parameters['caller'])) {
298
-			$caller = $parameters['caller'];
299
-			unset($parameters['caller']);
300
-			unset($parameters['action']);
301
-			$application = $this->getApplicationClass($caller[0]);
302
-			\OC\AppFramework\App::main($caller[1], $caller[2], $application->getContainer(), $parameters);
303
-		} elseif (isset($parameters['action'])) {
304
-			$action = $parameters['action'];
305
-			if (!is_callable($action)) {
306
-				throw new \Exception('not a callable action');
307
-			}
308
-			unset($parameters['action']);
309
-			unset($parameters['caller']);
310
-			call_user_func($action, $parameters);
311
-		} elseif (isset($parameters['file'])) {
312
-			include $parameters['file'];
313
-		} else {
314
-			throw new \Exception('no action available');
315
-		}
316
-		\OC::$server->getEventLogger()->end('run_route');
317
-	}
318
-
319
-	/**
320
-	 * Get the url generator
321
-	 *
322
-	 * @return \Symfony\Component\Routing\Generator\UrlGenerator
323
-	 *
324
-	 */
325
-	public function getGenerator() {
326
-		if (null !== $this->generator) {
327
-			return $this->generator;
328
-		}
329
-
330
-		return $this->generator = new UrlGenerator($this->root, $this->context);
331
-	}
332
-
333
-	/**
334
-	 * Generate url based on $name and $parameters
335
-	 *
336
-	 * @param string $name Name of the route to use.
337
-	 * @param array $parameters Parameters for the route
338
-	 * @param bool $absolute
339
-	 * @return string
340
-	 */
341
-	public function generate($name,
342
-							 $parameters = [],
343
-							 $absolute = false) {
344
-		$referenceType = UrlGenerator::ABSOLUTE_URL;
345
-		if ($absolute === false) {
346
-			$referenceType = UrlGenerator::ABSOLUTE_PATH;
347
-		}
348
-		$name = $this->fixLegacyRootName($name);
349
-		if (strpos($name, '.') !== false) {
350
-			list($appName, $other) = explode('.', $name, 3);
351
-			// OCS routes are prefixed with "ocs."
352
-			if ($appName === 'ocs') {
353
-				$appName = $other;
354
-			}
355
-			$this->loadRoutes($appName);
356
-			try {
357
-				return $this->getGenerator()->generate($name, $parameters, $referenceType);
358
-			} catch (RouteNotFoundException $e) {
359
-			}
360
-		}
361
-
362
-		// Fallback load all routes
363
-		$this->loadRoutes();
364
-		try {
365
-			return $this->getGenerator()->generate($name, $parameters, $referenceType);
366
-		} catch (RouteNotFoundException $e) {
367
-			$this->logger->logException($e, ['level' => ILogger::INFO]);
368
-			return '';
369
-		}
370
-	}
371
-
372
-	protected function fixLegacyRootName(string $routeName): string {
373
-		if ($routeName === 'files.viewcontroller.showFile') {
374
-			return 'files.View.showFile';
375
-		}
376
-		if ($routeName === 'files_sharing.sharecontroller.showShare') {
377
-			return 'files_sharing.Share.showShare';
378
-		}
379
-		if ($routeName === 'files_sharing.sharecontroller.showAuthenticate') {
380
-			return 'files_sharing.Share.showAuthenticate';
381
-		}
382
-		if ($routeName === 'files_sharing.sharecontroller.authenticate') {
383
-			return 'files_sharing.Share.authenticate';
384
-		}
385
-		if ($routeName === 'files_sharing.sharecontroller.downloadShare') {
386
-			return 'files_sharing.Share.downloadShare';
387
-		}
388
-		if ($routeName === 'files_sharing.publicpreview.directLink') {
389
-			return 'files_sharing.PublicPreview.directLink';
390
-		}
391
-		if ($routeName === 'cloud_federation_api.requesthandlercontroller.addShare') {
392
-			return 'cloud_federation_api.RequestHandler.addShare';
393
-		}
394
-		if ($routeName === 'cloud_federation_api.requesthandlercontroller.receiveNotification') {
395
-			return 'cloud_federation_api.RequestHandler.receiveNotification';
396
-		}
397
-		return $routeName;
398
-	}
399
-
400
-	/**
401
-	 * To isolate the variable scope used inside the $file it is required in it's own method
402
-	 *
403
-	 * @param string $file the route file location to include
404
-	 * @param string $appName
405
-	 */
406
-	private function requireRouteFile($file, $appName) {
407
-		$this->setupRoutes(include_once $file, $appName);
408
-	}
409
-
410
-
411
-	/**
412
-	 * If a routes.php file returns an array, try to set up the application and
413
-	 * register the routes for the app. The application class will be chosen by
414
-	 * camelcasing the appname, e.g.: my_app will be turned into
415
-	 * \OCA\MyApp\AppInfo\Application. If that class does not exist, a default
416
-	 * App will be intialized. This makes it optional to ship an
417
-	 * appinfo/application.php by using the built in query resolver
418
-	 *
419
-	 * @param array $routes the application routes
420
-	 * @param string $appName the name of the app.
421
-	 */
422
-	private function setupRoutes($routes, $appName) {
423
-		if (is_array($routes)) {
424
-			$routeParser = new RouteParser();
425
-
426
-			$defaultRoutes = $routeParser->parseDefaultRoutes($routes, $appName);
427
-			$ocsRoutes = $routeParser->parseOCSRoutes($routes, $appName);
428
-
429
-			$this->root->addCollection($defaultRoutes);
430
-			$ocsRoutes->addPrefix('/ocsapp');
431
-			$this->root->addCollection($ocsRoutes);
432
-		}
433
-	}
434
-
435
-	private function getApplicationClass(string $appName) {
436
-		$appNameSpace = App::buildAppNamespace($appName);
437
-
438
-		$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
439
-
440
-		if (class_exists($applicationClassName)) {
441
-			$application = \OC::$server->query($applicationClassName);
442
-		} else {
443
-			$application = new App($appName);
444
-		}
445
-
446
-		return $application;
447
-	}
49
+    /** @var RouteCollection[] */
50
+    protected $collections = [];
51
+    /** @var null|RouteCollection */
52
+    protected $collection = null;
53
+    /** @var null|string */
54
+    protected $collectionName = null;
55
+    /** @var null|RouteCollection */
56
+    protected $root = null;
57
+    /** @var null|UrlGenerator */
58
+    protected $generator = null;
59
+    /** @var string[] */
60
+    protected $routingFiles;
61
+    /** @var bool */
62
+    protected $loaded = false;
63
+    /** @var array */
64
+    protected $loadedApps = [];
65
+    /** @var ILogger */
66
+    protected $logger;
67
+    /** @var RequestContext */
68
+    protected $context;
69
+
70
+    /**
71
+     * @param ILogger $logger
72
+     */
73
+    public function __construct(ILogger $logger) {
74
+        $this->logger = $logger;
75
+        $baseUrl = \OC::$WEBROOT;
76
+        if (!(\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
77
+            $baseUrl .= '/index.php';
78
+        }
79
+        if (!\OC::$CLI && isset($_SERVER['REQUEST_METHOD'])) {
80
+            $method = $_SERVER['REQUEST_METHOD'];
81
+        } else {
82
+            $method = 'GET';
83
+        }
84
+        $request = \OC::$server->getRequest();
85
+        $host = $request->getServerHost();
86
+        $schema = $request->getServerProtocol();
87
+        $this->context = new RequestContext($baseUrl, $method, $host, $schema);
88
+        // TODO cache
89
+        $this->root = $this->getCollection('root');
90
+    }
91
+
92
+    /**
93
+     * Get the files to load the routes from
94
+     *
95
+     * @return string[]
96
+     */
97
+    public function getRoutingFiles() {
98
+        if (!isset($this->routingFiles)) {
99
+            $this->routingFiles = [];
100
+            foreach (\OC_APP::getEnabledApps() as $app) {
101
+                $appPath = \OC_App::getAppPath($app);
102
+                if ($appPath !== false) {
103
+                    $file = $appPath . '/appinfo/routes.php';
104
+                    if (file_exists($file)) {
105
+                        $this->routingFiles[$app] = $file;
106
+                    }
107
+                }
108
+            }
109
+        }
110
+        return $this->routingFiles;
111
+    }
112
+
113
+    /**
114
+     * Loads the routes
115
+     *
116
+     * @param null|string $app
117
+     */
118
+    public function loadRoutes($app = null) {
119
+        if (is_string($app)) {
120
+            $app = \OC_App::cleanAppId($app);
121
+        }
122
+
123
+        $requestedApp = $app;
124
+        if ($this->loaded) {
125
+            return;
126
+        }
127
+        if (is_null($app)) {
128
+            $this->loaded = true;
129
+            $routingFiles = $this->getRoutingFiles();
130
+        } else {
131
+            if (isset($this->loadedApps[$app])) {
132
+                return;
133
+            }
134
+            $file = \OC_App::getAppPath($app) . '/appinfo/routes.php';
135
+            if ($file !== false && file_exists($file)) {
136
+                $routingFiles = [$app => $file];
137
+            } else {
138
+                $routingFiles = [];
139
+            }
140
+        }
141
+        \OC::$server->getEventLogger()->start('loadroutes' . $requestedApp, 'Loading Routes');
142
+        foreach ($routingFiles as $app => $file) {
143
+            if (!isset($this->loadedApps[$app])) {
144
+                if (!\OC_App::isAppLoaded($app)) {
145
+                    // app MUST be loaded before app routes
146
+                    // try again next time loadRoutes() is called
147
+                    $this->loaded = false;
148
+                    continue;
149
+                }
150
+                $this->loadedApps[$app] = true;
151
+                $this->useCollection($app);
152
+                $this->requireRouteFile($file, $app);
153
+                $collection = $this->getCollection($app);
154
+                $this->root->addCollection($collection);
155
+
156
+                // Also add the OCS collection
157
+                $collection = $this->getCollection($app.'.ocs');
158
+                $collection->addPrefix('/ocsapp');
159
+                $this->root->addCollection($collection);
160
+            }
161
+        }
162
+        if (!isset($this->loadedApps['core'])) {
163
+            $this->loadedApps['core'] = true;
164
+            $this->useCollection('root');
165
+            require_once __DIR__ . '/../../../core/routes.php';
166
+
167
+            // Also add the OCS collection
168
+            $collection = $this->getCollection('root.ocs');
169
+            $collection->addPrefix('/ocsapp');
170
+            $this->root->addCollection($collection);
171
+        }
172
+        if ($this->loaded) {
173
+            $collection = $this->getCollection('ocs');
174
+            $collection->addPrefix('/ocs');
175
+            $this->root->addCollection($collection);
176
+        }
177
+        \OC::$server->getEventLogger()->end('loadroutes' . $requestedApp);
178
+    }
179
+
180
+    /**
181
+     * @param string $name
182
+     * @return \Symfony\Component\Routing\RouteCollection
183
+     */
184
+    protected function getCollection($name) {
185
+        if (!isset($this->collections[$name])) {
186
+            $this->collections[$name] = new RouteCollection();
187
+        }
188
+        return $this->collections[$name];
189
+    }
190
+
191
+    /**
192
+     * Sets the collection to use for adding routes
193
+     *
194
+     * @param string $name Name of the collection to use.
195
+     * @return void
196
+     */
197
+    public function useCollection($name) {
198
+        $this->collection = $this->getCollection($name);
199
+        $this->collectionName = $name;
200
+    }
201
+
202
+    /**
203
+     * returns the current collection name in use for adding routes
204
+     *
205
+     * @return string the collection name
206
+     */
207
+    public function getCurrentCollection() {
208
+        return $this->collectionName;
209
+    }
210
+
211
+
212
+    /**
213
+     * Create a \OC\Route\Route.
214
+     *
215
+     * @param string $name Name of the route to create.
216
+     * @param string $pattern The pattern to match
217
+     * @param array $defaults An array of default parameter values
218
+     * @param array $requirements An array of requirements for parameters (regexes)
219
+     * @return \OC\Route\Route
220
+     */
221
+    public function create($name,
222
+                            $pattern,
223
+                            array $defaults = [],
224
+                            array $requirements = []) {
225
+        $route = new Route($pattern, $defaults, $requirements);
226
+        $this->collection->add($name, $route);
227
+        return $route;
228
+    }
229
+
230
+    /**
231
+     * Find the route matching $url
232
+     *
233
+     * @param string $url The url to find
234
+     * @throws \Exception
235
+     * @return array
236
+     */
237
+    public function findMatchingRoute(string $url): array {
238
+        if (substr($url, 0, 6) === '/apps/') {
239
+            // empty string / 'apps' / $app / rest of the route
240
+            list(, , $app,) = explode('/', $url, 4);
241
+
242
+            $app = \OC_App::cleanAppId($app);
243
+            \OC::$REQUESTEDAPP = $app;
244
+            $this->loadRoutes($app);
245
+        } elseif (substr($url, 0, 13) === '/ocsapp/apps/') {
246
+            // empty string / 'ocsapp' / 'apps' / $app / rest of the route
247
+            list(, , , $app,) = explode('/', $url, 5);
248
+
249
+            $app = \OC_App::cleanAppId($app);
250
+            \OC::$REQUESTEDAPP = $app;
251
+            $this->loadRoutes($app);
252
+        } elseif (substr($url, 0, 10) === '/settings/') {
253
+            $this->loadRoutes('settings');
254
+        } elseif (substr($url, 0, 6) === '/core/') {
255
+            \OC::$REQUESTEDAPP = $url;
256
+            if (!\OC::$server->getConfig()->getSystemValueBool('maintenance') && !Util::needUpgrade()) {
257
+                \OC_App::loadApps();
258
+            }
259
+            $this->loadRoutes('core');
260
+        } else {
261
+            $this->loadRoutes();
262
+        }
263
+
264
+        $matcher = new UrlMatcher($this->root, $this->context);
265
+        try {
266
+            $parameters = $matcher->match($url);
267
+        } catch (ResourceNotFoundException $e) {
268
+            if (substr($url, -1) !== '/') {
269
+                // We allow links to apps/files? for backwards compatibility reasons
270
+                // However, since Symfony does not allow empty route names, the route
271
+                // we need to match is '/', so we need to append the '/' here.
272
+                try {
273
+                    $parameters = $matcher->match($url . '/');
274
+                } catch (ResourceNotFoundException $newException) {
275
+                    // If we still didn't match a route, we throw the original exception
276
+                    throw $e;
277
+                }
278
+            } else {
279
+                throw $e;
280
+            }
281
+        }
282
+
283
+        return $parameters;
284
+    }
285
+
286
+    /**
287
+     * Find and execute the route matching $url
288
+     *
289
+     * @param string $url The url to find
290
+     * @throws \Exception
291
+     * @return void
292
+     */
293
+    public function match($url) {
294
+        $parameters = $this->findMatchingRoute($url);
295
+
296
+        \OC::$server->getEventLogger()->start('run_route', 'Run route');
297
+        if (isset($parameters['caller'])) {
298
+            $caller = $parameters['caller'];
299
+            unset($parameters['caller']);
300
+            unset($parameters['action']);
301
+            $application = $this->getApplicationClass($caller[0]);
302
+            \OC\AppFramework\App::main($caller[1], $caller[2], $application->getContainer(), $parameters);
303
+        } elseif (isset($parameters['action'])) {
304
+            $action = $parameters['action'];
305
+            if (!is_callable($action)) {
306
+                throw new \Exception('not a callable action');
307
+            }
308
+            unset($parameters['action']);
309
+            unset($parameters['caller']);
310
+            call_user_func($action, $parameters);
311
+        } elseif (isset($parameters['file'])) {
312
+            include $parameters['file'];
313
+        } else {
314
+            throw new \Exception('no action available');
315
+        }
316
+        \OC::$server->getEventLogger()->end('run_route');
317
+    }
318
+
319
+    /**
320
+     * Get the url generator
321
+     *
322
+     * @return \Symfony\Component\Routing\Generator\UrlGenerator
323
+     *
324
+     */
325
+    public function getGenerator() {
326
+        if (null !== $this->generator) {
327
+            return $this->generator;
328
+        }
329
+
330
+        return $this->generator = new UrlGenerator($this->root, $this->context);
331
+    }
332
+
333
+    /**
334
+     * Generate url based on $name and $parameters
335
+     *
336
+     * @param string $name Name of the route to use.
337
+     * @param array $parameters Parameters for the route
338
+     * @param bool $absolute
339
+     * @return string
340
+     */
341
+    public function generate($name,
342
+                                $parameters = [],
343
+                                $absolute = false) {
344
+        $referenceType = UrlGenerator::ABSOLUTE_URL;
345
+        if ($absolute === false) {
346
+            $referenceType = UrlGenerator::ABSOLUTE_PATH;
347
+        }
348
+        $name = $this->fixLegacyRootName($name);
349
+        if (strpos($name, '.') !== false) {
350
+            list($appName, $other) = explode('.', $name, 3);
351
+            // OCS routes are prefixed with "ocs."
352
+            if ($appName === 'ocs') {
353
+                $appName = $other;
354
+            }
355
+            $this->loadRoutes($appName);
356
+            try {
357
+                return $this->getGenerator()->generate($name, $parameters, $referenceType);
358
+            } catch (RouteNotFoundException $e) {
359
+            }
360
+        }
361
+
362
+        // Fallback load all routes
363
+        $this->loadRoutes();
364
+        try {
365
+            return $this->getGenerator()->generate($name, $parameters, $referenceType);
366
+        } catch (RouteNotFoundException $e) {
367
+            $this->logger->logException($e, ['level' => ILogger::INFO]);
368
+            return '';
369
+        }
370
+    }
371
+
372
+    protected function fixLegacyRootName(string $routeName): string {
373
+        if ($routeName === 'files.viewcontroller.showFile') {
374
+            return 'files.View.showFile';
375
+        }
376
+        if ($routeName === 'files_sharing.sharecontroller.showShare') {
377
+            return 'files_sharing.Share.showShare';
378
+        }
379
+        if ($routeName === 'files_sharing.sharecontroller.showAuthenticate') {
380
+            return 'files_sharing.Share.showAuthenticate';
381
+        }
382
+        if ($routeName === 'files_sharing.sharecontroller.authenticate') {
383
+            return 'files_sharing.Share.authenticate';
384
+        }
385
+        if ($routeName === 'files_sharing.sharecontroller.downloadShare') {
386
+            return 'files_sharing.Share.downloadShare';
387
+        }
388
+        if ($routeName === 'files_sharing.publicpreview.directLink') {
389
+            return 'files_sharing.PublicPreview.directLink';
390
+        }
391
+        if ($routeName === 'cloud_federation_api.requesthandlercontroller.addShare') {
392
+            return 'cloud_federation_api.RequestHandler.addShare';
393
+        }
394
+        if ($routeName === 'cloud_federation_api.requesthandlercontroller.receiveNotification') {
395
+            return 'cloud_federation_api.RequestHandler.receiveNotification';
396
+        }
397
+        return $routeName;
398
+    }
399
+
400
+    /**
401
+     * To isolate the variable scope used inside the $file it is required in it's own method
402
+     *
403
+     * @param string $file the route file location to include
404
+     * @param string $appName
405
+     */
406
+    private function requireRouteFile($file, $appName) {
407
+        $this->setupRoutes(include_once $file, $appName);
408
+    }
409
+
410
+
411
+    /**
412
+     * If a routes.php file returns an array, try to set up the application and
413
+     * register the routes for the app. The application class will be chosen by
414
+     * camelcasing the appname, e.g.: my_app will be turned into
415
+     * \OCA\MyApp\AppInfo\Application. If that class does not exist, a default
416
+     * App will be intialized. This makes it optional to ship an
417
+     * appinfo/application.php by using the built in query resolver
418
+     *
419
+     * @param array $routes the application routes
420
+     * @param string $appName the name of the app.
421
+     */
422
+    private function setupRoutes($routes, $appName) {
423
+        if (is_array($routes)) {
424
+            $routeParser = new RouteParser();
425
+
426
+            $defaultRoutes = $routeParser->parseDefaultRoutes($routes, $appName);
427
+            $ocsRoutes = $routeParser->parseOCSRoutes($routes, $appName);
428
+
429
+            $this->root->addCollection($defaultRoutes);
430
+            $ocsRoutes->addPrefix('/ocsapp');
431
+            $this->root->addCollection($ocsRoutes);
432
+        }
433
+    }
434
+
435
+    private function getApplicationClass(string $appName) {
436
+        $appNameSpace = App::buildAppNamespace($appName);
437
+
438
+        $applicationClassName = $appNameSpace . '\\AppInfo\\Application';
439
+
440
+        if (class_exists($applicationClassName)) {
441
+            $application = \OC::$server->query($applicationClassName);
442
+        } else {
443
+            $application = new App($appName);
444
+        }
445
+
446
+        return $application;
447
+    }
448 448
 }
Please login to merge, or discard this patch.