Elgg  Version 4.3
RouteRegistrationService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Router;
4 
10 
17 
18  use Loggable;
19 
23  protected $hooks;
24 
28  protected $routes;
29 
33  protected $generator;
34 
42  public function __construct(
46  ) {
47  $this->hooks = $hooks;
48  $this->routes = $routes;
49  $this->generator = $generator;
50  }
51 
74  public function register($name, array $params = []) {
75 
76  $params = $this->hooks->trigger('route:config', $name, $params, $params);
77 
78  $path = elgg_extract('path', $params);
79  $controller = elgg_extract('controller', $params);
80  $file = elgg_extract('file', $params);
81  $resource = elgg_extract('resource', $params);
82  $handler = elgg_extract('handler', $params);
83  $middleware = elgg_extract('middleware', $params, []);
84  $protected = elgg_extract('walled', $params, true);
85  $deprecated = elgg_extract('deprecated', $params, '');
86  $required_plugins = elgg_extract('required_plugins', $params, []);
87  $detect_page_owner = (bool) elgg_extract('detect_page_owner', $params, false);
88  $legacy_page_owner_detection = (bool) elgg_extract('legacy_page_owner_detection', $params, true);
89 
90  if (!$path || (!$controller && !$resource && !$handler && !$file)) {
91  throw new InvalidParameterException(
92  __METHOD__ . ' requires "path" and one of controller parameters ("resource", "controller", "file" or "handler") to be set'
93  );
94  }
95 
96  $defaults = elgg_extract('defaults', $params, []);
97  $requirements = elgg_extract('requirements', $params, []);
98  $methods = elgg_extract('methods', $params, []);
99 
100  $patterns = [
101  'guid' => '\d+',
102  'group_guid' => '\d+',
103  'container_guid' => '\d+',
104  'owner_guid' => '\d+',
105  'username' => '[\p{L}\p{M}\p{Nd}._-]+',
106  ];
107 
108  $path = trim($path, '/');
109  $segments = explode('/', $path);
110  foreach ($segments as &$segment) {
111  // look for segments that are defined as optional with added ?
112  // e.g. /blog/owner/{username?}
113 
114  $matches = [];
115  if (!preg_match('/\{(\w*)(\?)?\}/i', $segment, $matches)) {
116  continue;
117  }
118 
119  $wildcard = $matches[1];
120  if (!isset($defaults[$wildcard]) && isset($matches[2])) {
121  $defaults[$wildcard] = ''; // make it optional
122  }
123 
124  if (!isset($requirements[$wildcard])) {
125  if (array_key_exists($wildcard, $patterns)) {
126  $requirements[$wildcard] = $patterns[$wildcard];
127  } else {
128  $requirements[$wildcard] = '.+?';
129  }
130  }
131 
132  $segment = '{' . $wildcard . '}';
133  }
134 
135  $path = '/' . implode('/', $segments);
136 
137  if ($protected !== false) {
138  $middleware[] = WalledGarden::class;
139  }
140 
141  $middleware[] = MaintenanceGatekeeper::class;
142 
143  $defaults['_controller'] = $controller;
144  $defaults['_file'] = $file;
145  $defaults['_resource'] = $resource;
146  $defaults['_handler'] = $handler;
147  $defaults['_deprecated'] = $deprecated;
148  $defaults['_middleware'] = $middleware;
149  $defaults['_required_plugins'] = $required_plugins;
150  $defaults['_detect_page_owner'] = $detect_page_owner;
151  $defaults['_legacy_page_owner_detection'] = $legacy_page_owner_detection;
152 
153  $route = new Route($path, $defaults, $requirements, [
154  'utf8' => true,
155  ], '', [], $methods);
156 
157  $this->routes->add($name, $route);
158 
159  return $route;
160  }
161 
169  public function unregister($name) {
170  $this->routes->remove($name);
171  }
172 
180  public function get($name) {
181  return $this->routes->get($name);
182  }
183 
188  public function all() {
189  return $this->routes->all();
190  }
191 
200  public function generateUrl($name, array $parameters = []) {
201  try {
202  $route = $this->get($name);
203  if ($route instanceof Route) {
204  $deprecated = $route->getDefault('_deprecated');
205  if (!empty($deprecated)) {
206  elgg_deprecated_notice("The route \"{$name}\" has been deprecated.", $deprecated);
207  }
208  }
209 
210  $url = $this->generator->generate($name, $parameters, UrlGenerator::ABSOLUTE_URL);
211 
212  // make sure the url is always normalized so it is also usable in CLI
213  return elgg_normalize_url($url);
214  } catch (\Exception $exception) {
215  $this->getLogger()->notice($exception->getMessage());
216  }
217 
218  return false;
219  }
220 
230  public function resolveRouteParameters($name, \ElggEntity $entity = null, array $parameters = []) {
231  $route = $this->routes->get($name);
232  if (!$route) {
233  return false;
234  }
235 
236  $requirements = $route->getRequirements();
237  $defaults = $route->getDefaults();
238  $props = array_merge(array_keys($requirements), array_keys($defaults));
239 
240  foreach ($props as $prop) {
241  if (substr($prop, 0, 1) === '_') {
242  continue;
243  }
244 
245  if (isset($parameters[$prop])) {
246  continue;
247  }
248 
249  if (!$entity) {
250  $parameters[$prop] = '';
251  continue;
252  }
253 
254  switch ($prop) {
255  case 'title' :
256  case 'name' :
257  $parameters[$prop] = elgg_get_friendly_title($entity->getDisplayName());
258  break;
259 
260  default :
261  $parameters[$prop] = $entity->$prop;
262  break;
263  }
264  }
265 
266  return $parameters;
267  }
268 }
unregister($name)
Unregister a route by its name.
$params
Saves global plugin settings.
Definition: save.php:13
elgg_normalize_url($url)
Definition: output.php:153
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: deprecation.php:52
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
resolveRouteParameters($name,\ElggEntity $entity=null, array $parameters=[])
Populates route parameters from entity properties.
$defaults
$resource
$path
Definition: details.php:68
trait Loggable
Enables adding a logger.
Definition: Loggable.php:14
Route Wrapper.
Definition: Route.php:8
if(elgg_view_exists('elgg/admin.js')) $segments
Definition: admin.php:19
$entity
Definition: reset.php:8
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:547
getLogger()
Returns logger.
Definition: Loggable.php:37
RouteCollection Wrapper.
$exception
Definition: error.php:15
foreach($plugin_guids as $guid) if(empty($deactivated_plugins)) $url
Definition: deactivate.php:39
elgg_get_friendly_title($title)
When given a title, returns a version suitable for inclusion in a URL.
Definition: output.php:187
$handler
Definition: add.php:7
$methods
Definition: subscribe.php:8
__construct(PluginHooksService $hooks, RouteCollection $routes, UrlGenerator $generator)
Constructor.
generateUrl($name, array $parameters=[])
Generate a absolute URL for a named route.
UrlGenerator Wrapper.
Definition: UrlGenerator.php:8