router.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. $this->cache_key = OC_Cache::generateCacheKeyFromFiles($files);
  47. }
  48. return $this->cache_key;
  49. }
  50. /**
  51. * loads the api routes
  52. */
  53. public function loadRoutes() {
  54. // TODO cache
  55. $this->root = $this->getCollection('root');
  56. foreach(OC_APP::getEnabledApps() as $app){
  57. $file = OC_App::getAppPath($app).'/appinfo/routes.php';
  58. if(file_exists($file)){
  59. $this->useCollection($app);
  60. require_once($file);
  61. $collection = $this->getCollection($app);
  62. $this->root->addCollection($collection, '/apps/'.$app);
  63. }
  64. }
  65. // include ocs routes
  66. require_once(OC::$SERVERROOT.'/ocs/routes.php');
  67. $collection = $this->getCollection('ocs');
  68. $this->root->addCollection($collection, '/ocs');
  69. foreach($this->getRoutingFiles() as $app => $file) {
  70. $this->useCollection($app);
  71. require_once $file;
  72. $collection = $this->getCollection($app);
  73. $this->root->addCollection($collection, '/apps/'.$app);
  74. }
  75. $this->useCollection('root');
  76. require_once 'settings/routes.php';
  77. require_once 'core/routes.php';
  78. }
  79. protected function getCollection($name) {
  80. if (!isset($this->collections[$name])) {
  81. $this->collections[$name] = new RouteCollection();
  82. }
  83. return $this->collections[$name];
  84. }
  85. /**
  86. * Sets the collection to use for adding routes
  87. *
  88. * @param string $name Name of the colletion to use.
  89. */
  90. public function useCollection($name) {
  91. $this->collection = $this->getCollection($name);
  92. }
  93. /**
  94. * Create a OC_Route.
  95. *
  96. * @param string $name Name of the route to create.
  97. * @param string $pattern The pattern to match
  98. * @param array $defaults An array of default parameter values
  99. * @param array $requirements An array of requirements for parameters (regexes)
  100. */
  101. public function create($name, $pattern, array $defaults = array(), array $requirements = array()) {
  102. $route = new OC_Route($pattern, $defaults, $requirements);
  103. $this->collection->add($name, $route);
  104. return $route;
  105. }
  106. /**
  107. * Find the route matching $url.
  108. *
  109. * @param string $url The url to find
  110. */
  111. public function match($url) {
  112. $matcher = new UrlMatcher($this->root, $this->context);
  113. $parameters = $matcher->match($url);
  114. if (isset($parameters['action'])) {
  115. $action = $parameters['action'];
  116. if (!is_callable($action)) {
  117. var_dump($action);
  118. throw new Exception('not a callable action');
  119. }
  120. unset($parameters['action']);
  121. call_user_func($action, $parameters);
  122. } elseif (isset($parameters['file'])) {
  123. include $parameters['file'];
  124. } else {
  125. throw new Exception('no action available');
  126. }
  127. }
  128. /**
  129. * Get the url generator
  130. *
  131. */
  132. public function getGenerator()
  133. {
  134. if (null !== $this->generator) {
  135. return $this->generator;
  136. }
  137. return $this->generator = new UrlGenerator($this->root, $this->context);
  138. }
  139. /**
  140. * Generate url based on $name and $parameters
  141. *
  142. * @param string $name Name of the route to use.
  143. * @param array $parameters Parameters for the route
  144. */
  145. public function generate($name, $parameters = array(), $absolute = false)
  146. {
  147. return $this->getGenerator()->generate($name, $parameters, $absolute);
  148. }
  149. /**
  150. * Generate JSON response for routing in javascript
  151. */
  152. public static function JSRoutes()
  153. {
  154. $router = OC::getRouter();
  155. $etag = $router->getCacheKey();
  156. OC_Response::enableCaching();
  157. OC_Response::setETagHeader($etag);
  158. $root = $router->getCollection('root');
  159. $routes = array();
  160. foreach($root->all() as $name => $route) {
  161. $compiled_route = $route->compile();
  162. $defaults = $route->getDefaults();
  163. unset($defaults['action']);
  164. $routes[$name] = array(
  165. 'tokens' => $compiled_route->getTokens(),
  166. 'defaults' => $defaults,
  167. );
  168. }
  169. OCP\JSON::success ( array( 'data' => $routes ) );
  170. }
  171. }