You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

router.php 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. use Symfony\Component\Routing\Matcher\UrlMatcher;
  9. use Symfony\Component\Routing\Generator\UrlGenerator;
  10. use Symfony\Component\Routing\RequestContext;
  11. use Symfony\Component\Routing\RouteCollection;
  12. //use Symfony\Component\Routing\Route;
  13. class OC_Router {
  14. protected $collections = array();
  15. protected $collection = null;
  16. protected $root = null;
  17. protected $generator = null;
  18. protected $routing_files;
  19. protected $cache_key;
  20. public function __construct() {
  21. $baseUrl = OC_Helper::linkTo('', 'index.php');
  22. $method = $_SERVER['REQUEST_METHOD'];
  23. $host = OC_Request::serverHost();
  24. $schema = OC_Request::serverProtocol();
  25. $this->context = new RequestContext($baseUrl, $method, $host, $schema);
  26. // TODO cache
  27. $this->root = $this->getCollection('root');
  28. }
  29. public function getRoutingFiles() {
  30. if (!isset($this->routing_files)) {
  31. $this->routing_files = array();
  32. foreach(OC_APP::getEnabledApps() as $app) {
  33. $file = OC_App::getAppPath($app).'/appinfo/routes.php';
  34. if(file_exists($file)) {
  35. $this->routing_files[$app] = $file;
  36. }
  37. }
  38. }
  39. return $this->routing_files;
  40. }
  41. public function getCacheKey() {
  42. if (!isset($this->cache_key)) {
  43. $files = $this->getRoutingFiles();
  44. $files[] = 'settings/routes.php';
  45. $files[] = 'core/routes.php';
  46. $files[] = 'ocs/routes.php';
  47. $this->cache_key = OC_Cache::generateCacheKeyFromFiles($files);
  48. }
  49. return $this->cache_key;
  50. }
  51. /**
  52. * loads the api routes
  53. */
  54. public function loadRoutes() {
  55. foreach($this->getRoutingFiles() as $app => $file) {
  56. $this->useCollection($app);
  57. require_once $file;
  58. $collection = $this->getCollection($app);
  59. $this->root->addCollection($collection, '/apps/'.$app);
  60. }
  61. $this->useCollection('root');
  62. require_once 'settings/routes.php';
  63. require_once 'core/routes.php';
  64. // include ocs routes
  65. require_once 'ocs/routes.php';
  66. $collection = $this->getCollection('ocs');
  67. $this->root->addCollection($collection, '/ocs');
  68. }
  69. protected function getCollection($name) {
  70. if (!isset($this->collections[$name])) {
  71. $this->collections[$name] = new RouteCollection();
  72. }
  73. return $this->collections[$name];
  74. }
  75. /**
  76. * Sets the collection to use for adding routes
  77. *
  78. * @param string $name Name of the colletion to use.
  79. */
  80. public function useCollection($name) {
  81. $this->collection = $this->getCollection($name);
  82. }
  83. /**
  84. * Create a OC_Route.
  85. *
  86. * @param string $name Name of the route to create.
  87. * @param string $pattern The pattern to match
  88. * @param array $defaults An array of default parameter values
  89. * @param array $requirements An array of requirements for parameters (regexes)
  90. */
  91. public function create($name, $pattern, array $defaults = array(), array $requirements = array()) {
  92. $route = new OC_Route($pattern, $defaults, $requirements);
  93. $this->collection->add($name, $route);
  94. return $route;
  95. }
  96. /**
  97. * Find the route matching $url.
  98. *
  99. * @param string $url The url to find
  100. */
  101. public function match($url) {
  102. $matcher = new UrlMatcher($this->root, $this->context);
  103. $parameters = $matcher->match($url);
  104. if (isset($parameters['action'])) {
  105. $action = $parameters['action'];
  106. if (!is_callable($action)) {
  107. var_dump($action);
  108. throw new Exception('not a callable action');
  109. }
  110. unset($parameters['action']);
  111. call_user_func($action, $parameters);
  112. } elseif (isset($parameters['file'])) {
  113. include $parameters['file'];
  114. } else {
  115. throw new Exception('no action available');
  116. }
  117. }
  118. /**
  119. * Get the url generator
  120. *
  121. */
  122. public function getGenerator()
  123. {
  124. if (null !== $this->generator) {
  125. return $this->generator;
  126. }
  127. return $this->generator = new UrlGenerator($this->root, $this->context);
  128. }
  129. /**
  130. * Generate url based on $name and $parameters
  131. *
  132. * @param string $name Name of the route to use.
  133. * @param array $parameters Parameters for the route
  134. */
  135. public function generate($name, $parameters = array(), $absolute = false)
  136. {
  137. return $this->getGenerator()->generate($name, $parameters, $absolute);
  138. }
  139. /**
  140. * Generate JSON response for routing in javascript
  141. */
  142. public static function JSRoutes()
  143. {
  144. $router = OC::getRouter();
  145. $etag = $router->getCacheKey();
  146. OC_Response::enableCaching();
  147. OC_Response::setETagHeader($etag);
  148. $root = $router->getCollection('root');
  149. $routes = array();
  150. foreach($root->all() as $name => $route) {
  151. $compiled_route = $route->compile();
  152. $defaults = $route->getDefaults();
  153. unset($defaults['action']);
  154. $routes[$name] = array(
  155. 'tokens' => $compiled_route->getTokens(),
  156. 'defaults' => $defaults,
  157. );
  158. }
  159. OCP\JSON::success ( array( 'data' => $routes ) );
  160. }
  161. }