Elgg  Version 6.2
RouteRegistrationService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Router;
4 
9 use Elgg\Traits\Loggable;
10 
17 
18  use Loggable;
19 
27  public function __construct(
28  protected EventsService $events,
29  protected RouteCollection $routes,
30  protected UrlGenerator $generator
31  ) {
32  }
33 
57  public function register(string $name, array $params = []): Route {
58 
59  $params = $this->events->triggerResults('route:config', $name, $params, $params);
60 
61  $path = elgg_extract('path', $params);
62  $controller = elgg_extract('controller', $params);
63  $file = elgg_extract('file', $params);
64  $resource = elgg_extract('resource', $params);
65  $handler = elgg_extract('handler', $params);
66  $middleware = elgg_extract('middleware', $params, []);
67  $walled = elgg_extract('walled', $params, true);
68  $deprecated = elgg_extract('deprecated', $params, '');
69  $required_plugins = elgg_extract('required_plugins', $params, []);
70  $detect_page_owner = (bool) elgg_extract('detect_page_owner', $params, false);
71  $priority = (int) elgg_extract('priority', $params);
72 
73  if (!$path || (!$controller && !$resource && !$handler && !$file)) {
74  throw new InvalidArgumentException(
75  __METHOD__ . ' requires "path" and one of controller parameters ("resource", "controller", "file" or "handler") to be set'
76  );
77  }
78 
79  $defaults = elgg_extract('defaults', $params, []);
80  $requirements = elgg_extract('requirements', $params, []);
81  $methods = elgg_extract('methods', $params, []);
82 
83  $patterns = [
84  'guid' => '\d+',
85  'group_guid' => '\d+',
86  'container_guid' => '\d+',
87  'owner_guid' => '\d+',
88  'username' => '[\p{L}\p{M}\p{Nd}._-]+',
89  ];
90 
91  $path = trim($path, '/');
92  $segments = explode('/', $path);
93  foreach ($segments as &$segment) {
94  // look for segments that are defined as optional with added ?
95  // e.g. /blog/owner/{username?}
96 
97  $matches = [];
98  if (!preg_match('/\{(\w*)(\?)?\}/i', $segment, $matches)) {
99  continue;
100  }
101 
102  $wildcard = $matches[1];
103  if (!isset($defaults[$wildcard]) && isset($matches[2])) {
104  $defaults[$wildcard] = ''; // make it optional
105  }
106 
107  if (!isset($requirements[$wildcard])) {
108  if (array_key_exists($wildcard, $patterns)) {
109  $requirements[$wildcard] = $patterns[$wildcard];
110  } else {
111  $requirements[$wildcard] = '.+?';
112  }
113  }
114 
115  $segment = '{' . $wildcard . '}';
116  }
117 
118  $path = '/' . implode('/', $segments);
119 
120  if ($walled !== false) {
121  $middleware[] = WalledGarden::class;
122  }
123 
124  $middleware[] = MaintenanceGatekeeper::class;
125 
126  $defaults['_controller'] = $controller;
127  $defaults['_file'] = $file;
128  $defaults['_resource'] = $resource;
129  $defaults['_handler'] = $handler;
130  $defaults['_deprecated'] = $deprecated;
131  $defaults['_middleware'] = $middleware;
132  $defaults['_required_plugins'] = $required_plugins;
133  $defaults['_detect_page_owner'] = $detect_page_owner;
134 
135  $options = array_merge((array) elgg_extract('options', $params, []), ['utf8' => true]);
136 
137  $route = new Route($path, $defaults, $requirements, $options, '', [], $methods);
138 
139  $this->routes->add($name, $route, $priority);
140 
141  return $route;
142  }
143 
151  public function unregister(string $name): void {
152  $this->routes->remove($name);
153  }
154 
162  public function get(string $name): ?Route {
163  return $this->routes->get($name);
164  }
165 
170  public function all(): array {
171  return $this->routes->all();
172  }
173 
182  public function generateUrl(string $name, array $parameters = []): ?string {
183  try {
184  $route = $this->get($name);
185  if ($route instanceof Route) {
186  $deprecated = $route->getDefault('_deprecated');
187  if (!empty($deprecated)) {
188  elgg_deprecated_notice("The route \"{$name}\" has been deprecated.", $deprecated);
189  }
190  }
191 
192  $url = $this->generator->generate($name, $parameters, UrlGenerator::ABSOLUTE_URL);
193 
194  // make sure the url is always normalized so it is also usable in CLI
195  return elgg_normalize_url($url);
196  } catch (\Exception $exception) {
197  $this->getLogger()->notice($exception->getMessage());
198  }
199 
200  return null;
201  }
202 
212  public function resolveRouteParameters(string $name, ?\ElggEntity $entity = null, array $parameters = []) {
213  $route = $this->routes->get($name);
214  if (!$route) {
215  return false;
216  }
217 
218  $requirements = $route->getRequirements();
219  $defaults = $route->getDefaults();
220  $props = array_merge(array_keys($requirements), array_keys($defaults));
221 
222  foreach ($props as $prop) {
223  if (str_starts_with($prop, '_')) {
224  continue;
225  }
226 
227  if (isset($parameters[$prop])) {
228  continue;
229  }
230 
231  if (!$entity) {
232  $parameters[$prop] = '';
233  continue;
234  }
235 
236  switch ($prop) {
237  case 'title':
238  case 'name':
239  $parameters[$prop] = elgg_get_friendly_title($entity->getDisplayName());
240  break;
241 
242  default:
243  $parameters[$prop] = $entity->$prop;
244  break;
245  }
246  }
247 
248  return $parameters;
249  }
250 }
$entity
Definition: reset.php:8
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
$params
Saves global plugin settings.
Definition: save.php:13
$handler
Definition: add.php:7
return[ 'admin/delete_admin_notices'=>['access'=> 'admin'], 'admin/menu/save'=>['access'=> 'admin'], 'admin/plugins/activate'=>['access'=> 'admin'], 'admin/plugins/activate_all'=>['access'=> 'admin'], 'admin/plugins/deactivate'=>['access'=> 'admin'], 'admin/plugins/deactivate_all'=>['access'=> 'admin'], 'admin/plugins/set_priority'=>['access'=> 'admin'], 'admin/security/security_txt'=>['access'=> 'admin'], 'admin/security/settings'=>['access'=> 'admin'], 'admin/security/regenerate_site_secret'=>['access'=> 'admin'], 'admin/site/cache/invalidate'=>['access'=> 'admin'], 'admin/site/flush_cache'=>['access'=> 'admin'], 'admin/site/icons'=>['access'=> 'admin'], 'admin/site/set_maintenance_mode'=>['access'=> 'admin'], 'admin/site/set_robots'=>['access'=> 'admin'], 'admin/site/theme'=>['access'=> 'admin'], 'admin/site/unlock_upgrade'=>['access'=> 'admin'], 'admin/site/settings'=>['access'=> 'admin'], 'admin/upgrade'=>['access'=> 'admin'], 'admin/upgrade/reset'=>['access'=> 'admin'], 'admin/user/ban'=>['access'=> 'admin'], 'admin/user/bulk/ban'=>['access'=> 'admin'], 'admin/user/bulk/delete'=>['access'=> 'admin'], 'admin/user/bulk/unban'=>['access'=> 'admin'], 'admin/user/bulk/validate'=>['access'=> 'admin'], 'admin/user/change_email'=>['access'=> 'admin'], 'admin/user/delete'=>['access'=> 'admin'], 'admin/user/login_as'=>['access'=> 'admin'], 'admin/user/logout_as'=>[], 'admin/user/makeadmin'=>['access'=> 'admin'], 'admin/user/resetpassword'=>['access'=> 'admin'], 'admin/user/removeadmin'=>['access'=> 'admin'], 'admin/user/unban'=>['access'=> 'admin'], 'admin/user/validate'=>['access'=> 'admin'], 'annotation/delete'=>[], 'avatar/upload'=>[], 'comment/save'=>[], 'diagnostics/download'=>['access'=> 'admin'], 'entity/chooserestoredestination'=>[], 'entity/delete'=>[], 'entity/mute'=>[], 'entity/restore'=>[], 'entity/subscribe'=>[], 'entity/trash'=>[], 'entity/unmute'=>[], 'entity/unsubscribe'=>[], 'login'=>['access'=> 'logged_out'], 'logout'=>[], 'notifications/mute'=>['access'=> 'public'], 'plugins/settings/remove'=>['access'=> 'admin'], 'plugins/settings/save'=>['access'=> 'admin'], 'plugins/usersettings/save'=>[], 'register'=>['access'=> 'logged_out', 'middleware'=>[\Elgg\Router\Middleware\RegistrationAllowedGatekeeper::class,],], 'river/delete'=>[], 'settings/notifications'=>[], 'settings/notifications/subscriptions'=>[], 'user/changepassword'=>['access'=> 'public'], 'user/requestnewpassword'=>['access'=> 'public'], 'useradd'=>['access'=> 'admin'], 'usersettings/save'=>[], 'widgets/add'=>[], 'widgets/delete'=>[], 'widgets/move'=>[], 'widgets/save'=>[],]
Definition: actions.php:73
Events service.
Exception thrown if an argument is not of the expected type.
Protects a route if site is in maintenance mode.
Protects a route from non-authenticated users in a walled garden mode.
RouteCollection Wrapper.
resolveRouteParameters(string $name, ?\ElggEntity $entity=null, array $parameters=[])
Populates route parameters from entity properties.
__construct(protected EventsService $events, protected RouteCollection $routes, protected UrlGenerator $generator)
Constructor.
generateUrl(string $name, array $parameters=[])
Generate a absolute URL for a named route.
unregister(string $name)
Unregister a route by its name.
Route Wrapper.
Definition: Route.php:8
UrlGenerator Wrapper.
Delegates requests to controllers based on the registered configuration.
Definition: Router.php:26
if($who_can_change_language==='nobody') elseif($who_can_change_language==='admin_only' &&!elgg_is_admin_logged_in()) $options
Definition: language.php:20
foreach($plugin_guids as $guid) if(empty($deactivated_plugins)) $url
Definition: deactivate.php:39
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:117
elgg_extract($key, $array, $default=null, bool $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:256
$defaults
Generic entity header upload helper.
Definition: header.php:6
try
Definition: login_as.php:33
$resource
$path
Definition: details.php:70
elgg_normalize_url(string $url)
Definition: output.php:163
elgg_get_friendly_title(string $title)
When given a title, returns a version suitable for inclusion in a URL.
Definition: output.php:192
$exception
Definition: error.php:15
$priority
$methods
Definition: subscribe.php:8
$segments
Definition: admin.php:13