/** * {@inheritdoc} */ public function getTitle(Request $request, Route $route) { $route_title = NULL; // A dynamic title takes priority. Route::getDefault() returns NULL if the // named default is not set. By testing the value directly, we also avoid // trying to use empty values. if ($callback = $route->getDefault('_title_callback')) { $callable = $this->controllerResolver->getControllerFromDefinition($callback); $arguments = $this->controllerResolver->getArguments($request, $callable); $route_title = call_user_func_array($callable, $arguments); } elseif ($title = $route->getDefault('_title')) { $options = array(); if ($context = $route->getDefault('_title_context')) { $options['context'] = $context; } $args = array(); if ($raw_parameters = $request->attributes->get('_raw_variables')) { foreach ($raw_parameters->all() as $key => $value) { $args['@' . $key] = $value; $args['%' . $key] = $value; } } if ($title_arguments = $route->getDefault('_title_arguments')) { $args = array_merge($args, (array) $title_arguments); } // Fall back to a static string from the route. $route_title = $this->t($title, $args, $options); } return $route_title; }
public function buildForPreprocessor(Request $request, Route $preprocessorRoute) { // NO RabbitMQ case here: preprocessor are called synchronously. // Localhost case if ($preprocessorRoute->getDefault('_http_host') === $request->getHttpHost()) { $this->logger->info("InternalForwarder built for preprocessor: Localhost forwarder.", ['host' => $request->getHttpHost()]); return $this->container->get('prestashop.public_writer.protocol.internal_forwarder.localhost'); } // HTTP forward case if ($this->container->has('prestashop.saas.protocol.internal_forwarder.http')) { $this->logger->info("InternalForwarder built for forward: HTTP forwarder.", ['host' => $preprocessorRoute->getDefault('_http_host')]); return $this->container->get('prestashop.saas.protocol.internal_forwarder.http'); } // Error case: localhost case was not matching, but there is no other forwarder available. $this->logger->error("InternalForwarder built for preprocessor: NO forwarder found to reach distant host.", ['host' => $request->getHttpHost()]); throw new \ErrorException("InternalForwarder building for preprocessor: NO forwarder found to reach distant host: " . $request->getHttpHost()); }
/** * @param Route $route * @param UserVO $user * @throws MethodNotAllowedException */ protected function checkForRole(Route $route, UserVO $user) { if ($route->hasDefault('_role')) { $role = $route->getDefault('_role'); if (!in_array($role, $user->roles)) { throw new MethodNotAllowedException([], sprintf('Need role %s', $role)); } } }
/** * Checks new registrations are permitted on an event. */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account, RegistrationTypeInterface $registration_type = NULL) { if ($event = $route->getDefault('event')) { $context = ['event' => $route_match->getParameter($event)]; $access_control_handler = $this->entityManager->getAccessControlHandler('registration'); return $access_control_handler->createAccess($registration_type, $account, $context, TRUE); } return AccessResult::forbidden(); }
private function convertController(Route $route) { $nameParser = $this->getContainer()->get('controller_name_converter'); if ($route->hasDefault('_controller')) { try { $route->setDefault('_controller', $nameParser->build($route->getDefault('_controller'))); } catch (\InvalidArgumentException $e) { } } }
/** * Checks that an entity is an event type. */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) { if ($event = $route->getDefault('event')) { $event = $route_match->getParameter($event); if ($event instanceof EntityInterface) { return AccessResult::allowedIf($this->eventManager->isEvent($event)); } } return AccessResult::neutral(); }
/** * Checks access to the overview based on permissions and translatability. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(Route $route, AccountInterface $account) { /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ $mapper = $this->configMapperManager->createInstance($route->getDefault('plugin_id')); $this->sourceLanguage = $this->languageManager->getLanguage($mapper->getLangcode()); // Allow access to the translation overview if the proper permission is // granted, the configuration has translatable pieces, and the source // language is not locked if it is present. $source_language_access = is_null($this->sourceLanguage) || !$this->sourceLanguage->isLocked(); $access = $account->hasPermission('translate configuration') && $mapper->hasSchema() && $mapper->hasTranslatable() && $source_language_access; return AccessResult::allowedIf($access)->cachePerRole(); }
public function access(Route $route, RouteMatch $match, AccountInterface $account) { $tempstore_id = $route->getDefault('tempstore_id'); $id = $match->getParameter($route->getRequirement('_ctools_access')); if ($tempstore_id && $id) { $cached_values = $this->getTempstore()->get($tempstore_id)->get($id); if (!empty($cached_values['access']) && $cached_values['access'] instanceof CToolsAccessInterface) { return $cached_values['access']->access($account); } } return AccessResult::forbidden(); }
/** * Checks access to the overview based on permissions and translatability. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Symfony\Component\HttpFoundation\Request $request * The request object. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * * @return string * A \Drupal\Core\Access\AccessInterface constant value. */ public function access(Route $route, Request $request, AccountInterface $account) { /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */ $mapper = $this->configMapperManager->createInstance($route->getDefault('plugin_id')); $mapper->populateFromRequest($request); $this->sourceLanguage = $mapper->getLanguageWithFallback(); // Allow access to the translation overview if the proper permission is // granted, the configuration has translatable pieces, and the source // language is not locked. $access = $account->hasPermission('translate configuration') && $mapper->hasSchema() && $mapper->hasTranslatable() && !$this->sourceLanguage->locked; return $access ? static::ALLOW : static::DENY; }
/** * Determines if a given route is the edit-form for an entity. * * @param \Symfony\Component\Routing\Route $route * The route definition. * * @return bool * Returns TRUE if the route is the edit form of an entity, FALSE otherwise. */ protected function isEditFormPage(Route $route) { if ($default = $route->getDefault('_entity_form')) { // If no operation is provided, use 'default'. $default .= '.default'; list($entity_type_id, $operation) = explode('.', $default); if (!$this->entityManager->hasDefinition($entity_type_id)) { return FALSE; } $entity_type = $this->entityManager->getDefinition($entity_type_id); return $operation == 'edit' && $entity_type && $entity_type->isRevisionable(); } }
/** * {@inheritDoc} */ public function generateI18nPatterns($routeName, Route $route) { $patterns = array(); foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) { // Check if translation exists in the translation catalogue to avoid errors being logged by // the new LoggingTranslator of Symfony 2.6. However, the LoggingTranslator did not implement // the interface until Symfony 2.6.5, so an extra check is needed. if ($this->translator instanceof TranslatorBagInterface || $this->translator instanceof LoggingTranslator) { // Check if route is translated. if (!$this->translator->getCatalogue($locale)->has($routeName, $this->translationDomain)) { // No translation found. $i18nPattern = $route->getPath(); } else { // Get translation. $i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale); } } else { // if no translation exists, we use the current pattern if ($routeName === ($i18nPattern = $this->translator->trans($routeName, array(), $this->translationDomain, $locale))) { $i18nPattern = $route->getPath(); } } /////////////////////////////////////// // Begin customizations // prefix with zikula module url if requested if ($route->hasDefault('_zkModule')) { $module = $route->getDefault('_zkModule'); $zkNoBundlePrefix = $route->getOption('zkNoBundlePrefix'); if (!isset($zkNoBundlePrefix) || !$zkNoBundlePrefix) { $untranslatedPrefix = $this->getModUrlString($module); if ($this->translator->getCatalogue($locale)->has($untranslatedPrefix, strtolower($module))) { $prefix = $this->translator->trans($untranslatedPrefix, [], strtolower($module), $locale); } else { $prefix = $untranslatedPrefix; } $i18nPattern = "/" . $prefix . $i18nPattern; } } // End customizations /////////////////////////////////////// // prefix with locale if requested if (self::STRATEGY_PREFIX === $this->strategy || self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale) { $i18nPattern = '/' . $locale . $i18nPattern; if (null !== $route->getOption('i18n_prefix')) { $i18nPattern = $route->getOption('i18n_prefix') . $i18nPattern; } } $patterns[$i18nPattern][] = $locale; } return $patterns; }
private function processRoute(Route $importedRoute, $serviceName, $controllerClass) { $controllerName = $importedRoute->getDefault('_controller'); if ($this->containsClassNameNotServiceName($controllerName)) { // service has already been assigned to this controller -> skip return; } $controllerClassLength = strlen($controllerClass); $controllerClassFromName = substr($controllerName, 0, $controllerClassLength); if ($controllerClassFromName !== $controllerClass) { throw new \InvalidArgumentException('Something is wrong with controller class: ' . $controllerClass); } $importedRoute->setDefault('_controller', $this->getServiceControllerName($serviceName, $controllerName, $controllerClassLength)); }
/** * @param Route $route * * @return string */ protected function getNameFromController(Route $route) { $result = $route->getDefault('_controller'); if (!empty($result)) { if (false !== ($pos = strpos($result, 'Controller::'))) { $result = substr($result, 0, $pos); } if (false !== ($pos = strrpos($result, '\\'))) { $result = substr($result, $pos + 1); } $result = strtolower($result); } return $result; }
public function isGranted(Route $route, User $user) { if ($Ctrl = $route->getDefault('_controller')) { $Ctrl = str_replace(array('Bundle', 'Controller', 'Action'), '', $Ctrl); list(, $Bundle, , $C) = explode("\\", strtolower($Ctrl)); list($Controller, $Action) = explode("::", $C); } foreach ($user->getRoles() as $Role) { if ($Role->isGranted($Bundle, $Controller, $Action) === TRUE) { return TRUE; } } return FALSE; }
/** * {@inheritdoc} */ public function handle(ApiDoc $annotation, array $annotations, Route $route, \ReflectionMethod $method) { if ($route->getOption('group') !== DictionaryEntityRouteOptionsResolver::ROUTE_GROUP) { return; } $pluralAlias = $route->getDefault(DictionaryEntityRouteOptionsResolver::ENTITY_ATTRIBUTE); if (!$pluralAlias) { return; } $className = $this->entityAliasResolver->getClassByPluralAlias($pluralAlias); $pluralName = $this->entityClassNameProvider->getEntityClassPluralName($className); if ($pluralName) { $annotation->setDescription(strtr(static::DESCRIPTION_TEMPLATE, ['{plural_name}' => $pluralName])); $annotation->setDocumentation(strtr(static::DOCUMENTATION_TEMPLATE, ['{plural_name}' => $pluralName])); } else { $annotation->setDescription(strtr(static::FALLBACK_DESCRIPTION_TEMPLATE, ['{class}' => $className])); $annotation->setDocumentation(strtr(static::FALLBACK_DOCUMENTATION_TEMPLATE, ['{class}' => $className])); } }
public function access(Route $route, RouteMatch $match, AccountInterface $account) { $tempstore_id = $match->getParameter('tempstore_id') ? $match->getParameter('tempstore_id') : $route->getDefault('tempstore_id'); $id = $match->getParameter($route->getRequirement('_ctools_access')); if ($tempstore_id && $id) { $cached_values = $this->getTempstore()->get($tempstore_id)->get($id); if (!empty($cached_values['access']) && $cached_values['access'] instanceof CToolsAccessInterface) { $access = $cached_values['access']->access($account); } else { $access = AccessResult::allowed(); } } else { $access = AccessResult::forbidden(); } // The different wizards will have different tempstore ids and adding this // cache context allows us to nuance the access per wizard. $access->addCacheContexts(['url.query_args:tempstore_id']); return $access; }
/** * Checks access to the form mode. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Symfony\Component\HttpFoundation\Request $request * The request object. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * @param string $form_mode_name * (optional) The form mode. Defaults to 'default'. * @param string $bundle * (optional) The bundle. Different entity types can have different names * for their bundle key, so if not specified on the route via a {bundle} * parameter, the access checker determines the appropriate key name, and * gets the value from the corresponding request attribute. For example, * for nodes, the bundle key is "node_type", so the value would be * available via the {node_type} parameter rather than a {bundle} * parameter. * * @return string * A \Drupal\Core\Access\AccessInterface constant value. */ public function access(Route $route, Request $request, AccountInterface $account, $form_mode_name = 'default', $bundle = NULL) { if ($entity_type_id = $route->getDefault('entity_type_id')) { if (!isset($bundle)) { $entity_type = $this->entityManager->getDefinition($entity_type_id); $bundle = $request->attributes->get('_raw_variables')->get($entity_type->getBundleEntityType()); } $visibility = FALSE; if ($form_mode_name == 'default') { $visibility = TRUE; } elseif ($entity_display = $this->entityManager->getStorage('entity_form_display')->load($entity_type_id . '.' . $bundle . '.' . $form_mode_name)) { $visibility = $entity_display->status(); } if ($visibility) { $permission = $route->getRequirement('_field_ui_form_mode_access'); return $account->hasPermission($permission) ? static::ALLOW : static::DENY; } } return static::DENY; }
public function generateI18nPatterns($routeName, Route $route) { $patterns = []; /** @var FrozenParameterBag $parameterBag */ $parameterBag = $this->container->getParameterBag(); if (empty($this->offices)) { $this->offices = $this->container->get('doctrine')->getRepository('OctavaMuiBundle:Office')->getRoutingOffices(); } $translation = null; if ($structureId = $route->getDefault(Structure::ROUTING_ID_NAME)) { $structureRepository = $this->container->get('doctrine.orm.entity_manager')->getRepository('OctavaStructureBundle:Structure'); $translation = $structureRepository->getTranslations($structureRepository->getById($structureId)); } foreach (array_keys($this->offices) as $locale) { if ($translation !== null && empty($translation[$locale]['state'])) { // отключенная страница continue; } $office = $this->offices[$locale]; $i18nPattern = $route->getPath(); $paths = $route->getOption('translatable_path'); if (!empty($paths[$locale])) { $i18nPattern = $paths[$locale]; } if ($office->getIncludeLangInUrl()) { $i18nPattern = '/{_locale}' . $i18nPattern; } if (null !== ($prefix = $route->getOption('i18n_prefix'))) { $prefix = $parameterBag->resolveValue($prefix); $i18nPattern = $prefix . $i18nPattern; } $host = $office->getHost(); if (empty($patterns[$i18nPattern][$host])) { $patterns[$i18nPattern][$host] = []; } $patterns[$i18nPattern][$host][] = $locale; } return $patterns; }
/** * Checks access to the form mode. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The parametrized route. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * @param string $form_mode_name * (optional) The form mode. Defaults to 'default'. * @param string $bundle * (optional) The bundle. Different entity types can have different names * for their bundle key, so if not specified on the route via a {bundle} * parameter, the access checker determines the appropriate key name, and * gets the value from the corresponding request attribute. For example, * for nodes, the bundle key is "node_type", so the value would be * available via the {node_type} parameter rather than a {bundle} * parameter. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account, $form_mode_name = 'default', $bundle = NULL) { $access = AccessResult::neutral(); if ($entity_type_id = $route->getDefault('entity_type_id')) { if (empty($bundle)) { $entity_type = $this->entityManager->getDefinition($entity_type_id); $bundle = $route_match->getRawParameter($entity_type->getBundleEntityType()); } $visibility = FALSE; if ($form_mode_name == 'default') { $visibility = TRUE; } elseif ($entity_display = $this->entityManager->getStorage('entity_form_display')->load($entity_type_id . '.' . $bundle . '.' . $form_mode_name)) { $visibility = $entity_display->status(); } if ($form_mode_name != 'default' && $entity_display) { $access->addCacheableDependency($entity_display); } if ($visibility) { $permission = $route->getRequirement('_field_ui_form_mode_access'); $access = $access->orIf(AccessResult::allowedIfHasPermission($account, $permission)); } } return $access; }
/** * Gets the controller from a Route * * @param Route $route Route * * @return bool|object The controller or false */ public function getControllerFromRoute(Route $route) { $ret = false; $actionParts = explode(':', $route->getDefault('_controller')); if (count($actionParts) == 2) { $ret = $this->container->get($actionParts[0]); } return $ret; }
/** * {@inheritdoc} */ public static function buildBasicRenderable($view_id, $display_id, array $args = [], Route $route = NULL) { $build = parent::buildBasicRenderable($view_id, $display_id, $args); if ($route) { $build['#view_id'] = $route->getDefault('view_id'); $build['#view_display_plugin_id'] = $route->getOption('_view_display_plugin_id'); $build['#view_display_show_admin_links'] = $route->getOption('_view_display_show_admin_links'); } else { throw new \BadFunctionCallException('Missing route parameters.'); } return $build; }
/** * @param Route $route * @return ApiResource|null */ private function getResource(Route $route) { if (!($entity = $route->getDefault('_entity'))) { return; } return $this->manager->getResourceForEntity($entity); }
/** * get collection and id from route * * @param Route $route route to look at * @param string $value value of reference as URI * * @return array */ private function getDataFromRoute(Route $route, $value) { if ($route->getRequirement('id') !== null && $route->getMethods() === ['GET'] && preg_match($route->compile()->getRegex(), $value, $matches)) { $id = $matches['id']; list($routeService) = explode(':', $route->getDefault('_controller')); list($core, $bundle, , $name) = explode('.', $routeService); $serviceName = implode('.', [$core, $bundle, 'rest', $name]); $collection = array_search($serviceName, $this->mapping); return [$collection, $id]; } return [null, null]; }
/** * If the _locale parameter is allowed by the requirements of the route * and it is the default locale, remove it from the parameters so that we * do not get an unneeded ?_locale= query string. * * @param SymfonyRoute $route The route being generated. * @param array $parameters The parameters used, will be modified to * remove the _locale field if needed. */ protected function unsetLocaleIfNotNeeded(SymfonyRoute $route, array &$parameters) { $locale = $this->getLocale($parameters); if (null !== $locale) { if (preg_match('/' . $route->getRequirement('_locale') . '/', $locale) && $locale == $route->getDefault('_locale')) { $compiledRoute = $route->compile(); if (!in_array('_locale', $compiledRoute->getVariables())) { unset($parameters['_locale']); } } } }
/** * Sets the upcasting information using the _entity_* route defaults. * * Supports the '_entity_view' and '_entity_form' route defaults. * * @param \Symfony\Component\Routing\Route $route * The route object. */ protected function setParametersFromEntityInformation(Route $route) { if ($entity_view = $route->getDefault('_entity_view')) { list($entity_type) = explode('.', $entity_view, 2); } elseif ($entity_form = $route->getDefault('_entity_form')) { list($entity_type) = explode('.', $entity_form, 2); } if (isset($entity_type) && isset($this->getEntityTypes()[$entity_type])) { $parameter_definitions = $route->getOption('parameters') ?: array(); // First try to figure out whether there is already a parameter upcasting // the same entity type already. foreach ($parameter_definitions as $info) { if (isset($info['type'])) { // The parameter types are in the form 'entity:$entity_type'. list(, $parameter_entity_type) = explode(':', $info['type'], 2); if ($parameter_entity_type == $entity_type) { return; } } } if (!isset($parameter_definitions[$entity_type])) { $parameter_definitions[$entity_type] = array(); } $parameter_definitions[$entity_type] += array('type' => 'entity:' . $entity_type); if (!empty($parameter_definitions)) { $route->setOption('parameters', $parameter_definitions); } } }
/** * Tests setRouteOptions() with an entity type parameter, upcasting. * * @covers ::setRouteOptions() * @covers ::getController() * @covers ::getEntityTypes() * @covers ::setParametersFromReflection() */ public function testSetRouteOptionsWithEntityTypeUpcasting() { $this->setupEntityTypes(); $route = new Route('/example/{entity_test}', array('_content' => 'Drupal\\Tests\\Core\\Entity\\BasicControllerClass::exampleControllerWithEntityUpcasting')); $this->setupControllerResolver($route->getDefault('_content')); $defaults = $route->getDefaults(); $this->entityResolverManager->setRouteOptions($route); $this->assertEquals($defaults, $route->getDefaults()); $parameters = $route->getOption('parameters'); $this->assertEquals(array('entity_test' => array('type' => 'entity:entity_test')), $parameters); }
/** * @param Route $route * @return array */ private function convertRouteToConfig(Route $route) { $className = $route->getOption(self::RESOURCE_ENTITY_CLASS_OPTION); $converter = $this->defaultConverter; if ($route->hasOption(self::RESOURCE_CONVERTER_OPTION)) { $converter = $route->getOption(self::RESOURCE_CONVERTER_OPTION); } if ($route->hasOption(self::RESOURCE_SINGULAR_NAME)) { $singular = $route->getOption(self::RESOURCE_SINGULAR_NAME); } else { $classNameParts = explode('\\', $className); end($classNameParts); $singular = strtolower(current($classNameParts)); } if ($route->hasOption(self::RESOURCE_PLURAL_NAME)) { $plural = $route->getOption(self::RESOURCE_PLURAL_NAME); } else { $plural = $this->inflector->pluralize($singular); } return ['route' => $route->getDefault('_route'), 'class' => $className, 'converter' => $converter, 'singular_name' => $singular, 'plural_name' => $plural]; }
/** * @param $routeName * @param SymfonyRoute $route */ public function importRoute($routeName, SymfonyRoute $route) { $routeEntity = $this->routeRepo->saveIfNotExists($routeName); $routeEntity->setPath($route->getPath()); $this->routeRepo->save($routeEntity); $compiledRoute = $route->compile(); $requiredType = $this->routeParameterTypeRepo->findRequiredType(); $parametersToRemove = []; /** @var RouteParameter $parameterEntity */ foreach ($routeEntity->getParameters() as $parameterEntity) { $parametersToRemove[$parameterEntity->getId()] = $parameterEntity; } foreach ($compiledRoute->getVariables() as $parameter) { $parameterEntity = $this->routeParameterRepo->saveIfNotExists($routeEntity, $parameter, $requiredType); $parameterEntity->setRequirement($route->getRequirement($parameter)); $parameterEntity->setDefaultValue($route->getDefault($parameter)); $this->routeParameterRepo->save($parameterEntity); unset($parametersToRemove[$parameterEntity->getId()]); } // if ($route->getSchemes()) { // $schemeParameterEntity = $this->routeParameterRepo->saveIfNotExists($routeEntity, '_scheme', $requiredType); // $schemeParameterEntity->setRequirement(implode('|', $route->getSchemes())); // $schemeParameterEntity->setDefaultValue($route->getDefault('_scheme')); // $this->routeParameterRepo->save($schemeParameterEntity); // unset($parametersToRemove[$schemeParameterEntity->getId()]); // } else { // $schemeParameterEntity = $this->routeParameterRepo->findOneByRouteAndParameter($routeEntity, '_scheme'); // if ($schemeParameterEntity) { // $this->routeParameterRepo->remove($schemeParameterEntity); // } // } /** @var RouteParameter $parameterEntity */ foreach ($parametersToRemove as $parameterEntity) { $this->routeParameterRepo->remove($parameterEntity); } }
/** * Sort callback for routes based on the variant weight. */ protected function routeWeightSort(Route $a, Route $b) { $a_weight = $a->getDefault('page_manager_page_variant_weight'); $b_weight = $b->getDefault('page_manager_page_variant_weight'); if ($a_weight === $b_weight) { return 0; } elseif ($a_weight === NULL) { return 1; } elseif ($b_weight === NULL) { return -1; } return $a_weight < $b_weight ? -1 : 1; }
/** * Merges the methods from $restRoute into the _method default of $optionsRoute. * * @param Route $restRoute * @param Route $optionsRoute * * @return Route $optionsRoute with the methods from $restRoute in the _methods default */ public function mergeMethodsDefault(Route $optionsRoute, Route $restRoute) { $mergedRoute = clone $optionsRoute; $mergedRoute->setDefault('allowedMethods', implode(',', array_unique(array_merge(explode(',', $optionsRoute->getDefault('allowedMethods')), $restRoute->getMethods())))); return $mergedRoute; }