/** * Given an array of RAML\Resources, this function will add each Resource * into the Symfony Route Collection, and set the corresponding method. * * @param BasicRoute[Resource] $resources * Associative array where the key is the method and full path, and the value contains * the path, method type (GET/POST etc.) and then the Raml\Method object * * @return array */ public function format(array $resources) { // Loop over the Resources foreach ($resources as $path => $resource) { // This is the path from the RAML, with or without a /. $path = $resource->getUri() . ($this->addTrailingSlash ? '/' : ''); // This is the baseUri + path, the complete URL. $url = $resource->getBaseUrl() . $path; // Now remove the host away, so we have the FULL path to the resource. // baseUri may also contain path that has been omitted for brevity in the // RAML creation. $host = parse_url($url, PHP_URL_HOST); $fullPath = substr($url, strpos($url, $host) + strlen($host)); // Now build our Route class. $route = new Route($fullPath); $route->setMethods($resource->getMethod()->getType()); $route->setSchemes($resource->getProtocols()); // Loop over each of the URI Parameters searching for validation patterns // or default values for parameters. foreach ($resource->getUriParameters() as $name => $param) { $route->setRequirement($name, $param->getValidationPattern()); if ($default = $param->getDefault()) { $route->setDefault($name, $default); } } $this->routes->add($resource->getType() . ' ' . $path, $route); } return $resources; }
/** * @covers ::applies */ public function testAppliesWithFormat() { $route_filter = new RequestFormatRouteFilter(); $route = new Route('/test'); $route->setRequirement('_format', 'json'); $this->assertTrue($route_filter->applies($route)); }
protected function addFormRoute(EntityTypeInterface $entity_type) { $route = new Route('entity.' . $entity_type->id() . '.add-form'); $route->setDefault('_controller', '\\Drupal\\content_entity_base\\Entity\\Controller\\EntityBaseController::addForm'); $route->setDefault('_title_callback', '\\Drupal\\content_entity_base\\Entity\\Controller\\EntityBaseController::getAddFormTitle'); $route->setDefault('entity_type', $entity_type->id()); $route->setRequirement('_entity_create_access', $entity_type->id()); return $route; }
protected function revisionDeleteRoute(EntityTypeInterface $entity_type) { $route = new Route($entity_type->getLinkTemplate('revision-delete')); $route->setDefault('_form', 'Drupal\\content_entity_base\\Entity\\Form\\EntityRevisionDeleteForm'); $route->setDefault('_title', 'Delete earlier revision'); $route->setRequirement('_entity_access_revision', $entity_type->id() . '.delete'); $route->setOption('parameters', [$entity_type->id() => ['type' => 'entity:' . $entity_type->id()], $entity_type->id() . '_revision' => ['type' => 'entity_revision:' . $entity_type->id()]]); return $route; }
/** * Configures the _controller default parameter and eventually the _method * requirement of a given Route instance. * * @param Route $route A route instance * @param \ReflectionClass $class A ReflectionClass instance * @param \ReflectionMethod $method A ReflectionClass method * @param mixed $annot The annotation class instance * * @throws \LogicException When the service option is specified on a method * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot) { $route->setDefault('_controller', $class->getName() . '::' . $method->getName()); // requirements (@Method) foreach ($this->reader->getMethodAnnotations($method) as $configuration) { if ($configuration instanceof Method) { $route->setRequirement('_method', implode('|', $configuration->getMethods())); } } }
/** * Returns the delete multiple form route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function deleteMultipleFormRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('delete-multiple-form')) { $route = new Route($entity_type->getLinkTemplate('delete-multiple-form')); $route->setDefault('_form', '\\Drupal\\entity\\Form\\DeleteMultiple'); $route->setDefault('entity_type_id', $entity_type->id()); $route->setRequirement('_permission', $entity_type->getAdminPermission()); return $route; } }
/** * {@inheritdoc} */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) { // Backup the original requirements. $original_requirements = $route->getRequirements(); // Replace it with our entity access value and run the parent access check. $route->setRequirement('_entity_access', $route->getRequirement('_page_access')); $access = parent::access($route, $route_match, $account); // Restore the original requirements. $route->setRequirements($original_requirements); return $access; }
/** * Returns the add form route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function addFormRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('add-form')) { $route = new Route($entity_type->getLinkTemplate('add-form')); $route->setDefault('_controller', '\\Drupal\\entity\\Controller\\EntityCreateController::addForm'); $route->setDefault('_title_callback', '\\Drupal\\entity\\Controller\\EntityCreateController::addFormTitle'); $route->setDefault('entity_type_id', $entity_type->id()); $route->setRequirement('_entity_create_access', $entity_type->id()); return $route; } }
/** * Tests the generate method with passing in a route object into generate(). * * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testGenerateByRoute() { $this->generator = new ProviderBasedGenerator($this->provider); // Setup a route with a numeric parameter, but pass in a string, so it // fails and getRouteDebugMessage should be triggered. $route = new Route('/test'); $route->setPath('/test/{number}'); $route->setRequirement('number', '\\+d'); $this->generator->setStrictRequirements(true); $context = new RequestContext(); $this->generator->setContext($context); $this->assertSame(null, $this->generator->generate($route, array('number' => 'string'))); }
/** * Gets the moderation-form route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function getLatestVersionRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('latest-version') && $entity_type->hasViewBuilderClass()) { $entity_type_id = $entity_type->id(); $route = new Route($entity_type->getLinkTemplate('latest-version')); $route->addDefaults(['_entity_view' => "{$entity_type_id}.full", '_title_callback' => '\\Drupal\\Core\\Entity\\Controller\\EntityController::title'])->setRequirement('_entity_access', "{$entity_type_id}.view")->setRequirement('_permission', 'view latest version,view any unpublished content')->setRequirement('_content_moderation_latest_version', 'TRUE')->setOption('_content_moderation_entity_type', $entity_type_id)->setOption('parameters', [$entity_type_id => ['type' => 'entity:' . $entity_type_id, 'load_forward_revision' => 1]]); // Entity types with serial IDs can specify this in their route // requirements, improving the matching process. if ($this->getEntityTypeIdKeyType($entity_type) === 'integer') { $route->setRequirement($entity_type_id, '\\d+'); } return $route; } }
/** * Configures the _controller default parameter and eventually the _method * requirement of a given Route instance. * * @param Route $route A Route instance * @param ReflectionClass $class A ReflectionClass instance * @param ReflectionMethod $method A ReflectionClass method */ protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot) { // controller $classAnnot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass); if ($classAnnot instanceof FrameworkExtraBundleRoute && ($service = $classAnnot->getService())) { $route->setDefault('_controller', $service . ':' . $method->getName()); } else { $route->setDefault('_controller', $class->getName() . '::' . $method->getName()); } // requirements (@Method) foreach ($this->reader->getMethodAnnotations($method) as $configuration) { if ($configuration instanceof Method) { $route->setRequirement('_method', implode('|', $configuration->getMethods())); } } }
public function providerTestGetAddPageRoute() { $data = []; $entity_type1 = $this->getEntityType(); $entity_type1->hasLinkTemplate('add-page')->willReturn(FALSE); $data['no_add_page_link_template'] = [NULL, $entity_type1->reveal()]; $entity_type2 = $this->getEntityType(); $entity_type2->hasLinkTemplate('add-page')->willReturn(TRUE); $entity_type2->getKey('bundle')->willReturn(NULL); $data['no_bundle'] = [NULL, $entity_type2->reveal()]; $entity_type3 = $this->getEntityType(); $entity_type3->hasLinkTemplate('add-page')->willReturn(TRUE); $entity_type3->getLinkTemplate('add-page')->willReturn('/the/add/page/link/template'); $entity_type3->id()->willReturn('the_entity_type_id'); $entity_type3->getKey('bundle')->willReturn('type'); $route = new Route('/the/add/page/link/template'); $route->setDefaults(['_controller' => 'Drupal\\Core\\Entity\\Controller\\EntityController::addPage', '_title_callback' => 'Drupal\\Core\\Entity\\Controller\\EntityController::addTitle', 'entity_type_id' => 'the_entity_type_id']); $route->setRequirement('_entity_create_any_access', 'the_entity_type_id'); $data['add_page'] = [clone $route, $entity_type3->reveal()]; return $data; }
/** * Tests the create access method. * * @covers ::access */ public function testCreateAccess() { // Set the mock translation handler. $translation_handler = $this->getMock('\\Drupal\\content_translation\\ContentTranslationHandlerInterface'); $translation_handler->expects($this->once())->method('getTranslationAccess')->will($this->returnValue(AccessResult::allowed())); $entity_manager = $this->getMock('Drupal\\Core\\Entity\\EntityManagerInterface'); $entity_manager->expects($this->once())->method('getHandler')->withAnyParameters()->will($this->returnValue($translation_handler)); // Set our source and target languages. $source = 'en'; $target = 'it'; // Set the mock language manager. $language_manager = $this->getMock('Drupal\\Core\\Language\\LanguageManagerInterface'); $language_manager->expects($this->at(0))->method('getLanguage')->with($this->equalTo($source))->will($this->returnValue(new Language(array('id' => 'en')))); $language_manager->expects($this->at(1))->method('getLanguages')->will($this->returnValue(array('en' => array(), 'it' => array()))); $language_manager->expects($this->at(2))->method('getLanguage')->with($this->equalTo($source))->will($this->returnValue(new Language(array('id' => 'en')))); $language_manager->expects($this->at(3))->method('getLanguage')->with($this->equalTo($target))->will($this->returnValue(new Language(array('id' => 'it')))); // Set the mock entity. We need to use ContentEntityBase for mocking due to // issues with phpunit and multiple interfaces. $entity = $this->getMockBuilder('Drupal\\Core\\Entity\\ContentEntityBase')->disableOriginalConstructor()->getMock(); $entity->expects($this->once())->method('getEntityTypeId'); $entity->expects($this->once())->method('getTranslationLanguages')->with()->will($this->returnValue(array())); $entity->expects($this->once())->method('getCacheContexts')->willReturn([]); $entity->expects($this->once())->method('getCacheMaxAge')->willReturn(Cache::PERMANENT); $entity->expects($this->once())->method('getCacheTags')->will($this->returnValue(array('node:1337'))); $entity->expects($this->once())->method('getCacheContexts')->willReturn(array()); // Set the route requirements. $route = new Route('test_route'); $route->setRequirement('_access_content_translation_manage', 'create'); // Set up the route match. $route_match = $this->getMock('Drupal\\Core\\Routing\\RouteMatchInterface'); $route_match->expects($this->once())->method('getParameter')->with('node')->will($this->returnValue($entity)); // Set the mock account. $account = $this->getMock('Drupal\\Core\\Session\\AccountInterface'); // The access check under test. $check = new ContentTranslationManageAccessCheck($entity_manager, $language_manager); // The request params. $language = 'en'; $entity_type_id = 'node'; $this->assertTrue($check->access($route, $route_match, $account, $source, $target, $language, $entity_type_id)->isAllowed(), "The access check matches"); }
/** * {@inheritdoc} */ public function processRoute(Route $route) { $route->setRequirement('_user_is_logged_in', 'TRUE'); }
/** * @param array $options * * @return Route */ protected function destroyRoute(array $options) { $route = new Route('/{id}/destroy'); $route->setMethods(['GET', 'POST']); $route->setDefault('_controller', $options['controller'] . ':destroy'); $route->setRequirement('id', '\\d+'); return $route; }
/** * Returns a Content-type restricted set of routes for testing. * * @return \Symfony\Component\Routing\RouteCollection */ public function contentRouteCollection() { $collection = new RouteCollection(); $route = new Route('path/three'); $route->setMethods(['POST']); $route->setRequirement('_content_type_format', 'json'); $collection->add('route_f', $route); $route = new Route('path/three'); $route->setMethods(['PATCH']); $route->setRequirement('_content_type_format', 'xml'); $collection->add('route_g', $route); return $collection; }
/** * Gets the delete-form route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function getDeleteFormRoute(EntityTypeInterface $entity_type) { if ($entity_type->hasLinkTemplate('delete-form')) { $entity_type_id = $entity_type->id(); $route = new Route($entity_type->getLinkTemplate('delete-form')); $route->addDefaults(['_entity_form' => "{$entity_type_id}.delete", '_title_callback' => '\\Drupal\\Core\\Entity\\Controller\\EntityController::deleteTitle'])->setRequirement('_entity_access', "{$entity_type_id}.delete")->setOption('parameters', [$entity_type_id => ['type' => 'entity:' . $entity_type_id]]); // Entity types with serial IDs can specify this in their route // requirements, improving the matching process. if ($this->getEntityTypeIdKeyType($entity_type) === 'integer') { $route->setRequirement($entity_type_id, '\\d+'); } return $route; } }
/** * {@inheritdoc} */ public function processRoute(Route $route) { $route->setRequirement('_entity_access', $this->getDerivativeId() . '.view'); }
/** * {@inheritdoc} */ public function alterRouteDefinition(Route $route) { if ($this->options['role']) { $route->setRequirement('_role', (string) implode('+', $this->options['role'])); } }
/** * {@inheritdoc} */ public function alterRouteDefinition(Route $route) { $route->setRequirement('_access', 'TRUE'); }
/** * Perform a placeholder URL match * * @param RedirectRule $rule * @param string $url * @return RedirectRule|bool */ private function matchPlaceholders(RedirectRule $rule, $url) { $route = new Route($rule->getFromUrl()); foreach ($rule->getRequirements() as $requirement) { try { $route->setRequirement(str_replace(['{', '}'], '', $requirement['placeholder']), $requirement['requirement']); } catch (\InvalidArgumentException $e) { // Catch empty requirement / placeholder } } $routeCollection = new RouteCollection(); $routeCollection->add($rule->getId(), $route); try { $matcher = new UrlMatcher($routeCollection, new RequestContext('/')); $match = $matcher->match($url); $items = array_except($match, '_route'); foreach ($items as $key => $value) { $placeholder = '{' . $key . '}'; $replacement = $this->findReplacementForPlaceholder($rule, $placeholder); $items[$placeholder] = $replacement === null ? $value : $replacement; unset($items[$key]); } $rule->setPlaceholderMatches($items); } catch (\Exception $e) { return false; } return $rule; }
/** * {@inheritdoc} */ public function alterRouteDefinition(Route $route) { $route->setRequirement('_permission', (string) implode('+', $this->permissions)); }
/** * {@inheritdoc} */ public function alterRouteDefinition(Route $route) { if (!empty($this->options['access'])) { $route->setRequirement('_access', 'TRUE'); } }
public function testRequirement() { $route = new Route('/{foo}'); $route->setRequirement('foo', '^\\d+$'); $this->assertEquals('\\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the pattern'); }
/** * Gets the entity revision version history route. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type. * * @return \Symfony\Component\Routing\Route|null * The generated route, if available. */ protected function getRevisionHistoryRoute($entity_type) { if ($entity_type->hasLinkTemplate('version-history')) { $entity_type_id = $entity_type->id(); $route = new Route($entity_type->getLinkTemplate('version-history')); $route->addDefaults(['_controller' => '\\Drupal\\entity\\Controller\\RevisionOverviewController::revisionOverviewController', '_title' => 'Revisions']); $route->setRequirement('_entity_access_revision', "{$entity_type_id}.list"); $route->setOption('entity_type_id', $entity_type->id()); $route->setOption('parameters', [$entity_type->id() => ['type' => 'entity:' . $entity_type->id()]]); return $route; } }
/** * {@inheritdoc} */ public function alterRouteDefinition(Route $route) { $route->setRequirement('_permission', $this->options['perm']); }
public function testCompile() { $route = new Route('/{foo}'); $this->assertInstanceOf('Symfony\\Component\\Routing\\CompiledRoute', $compiled = $route->compile(), '->compile() returns a compiled route'); $this->assertSame($compiled, $route->compile(), '->compile() only compiled the route once if unchanged'); $route->setRequirement('foo', '.*'); $this->assertNotSame($compiled, $route->compile(), '->compile() recompiles if the route was modified'); }
/** * @param Route $route * @param string $entityClass */ protected function setIdRequirement(Route $route, $entityClass) { $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass); $idFields = $metadata->getIdentifierFieldNames(); $idFieldCount = count($idFields); if ($idFieldCount === 1) { // single identifier $route->setRequirement(self::ID_ATTRIBUTE, $this->valueNormalizer->getRequirement($metadata->getTypeOfField(reset($idFields)), [RequestType::REST, RequestType::JSON_API])); } elseif ($idFieldCount > 1) { // combined identifier $requirements = []; foreach ($idFields as $field) { $requirements[] = $field . '=' . $this->valueNormalizer->getRequirement($metadata->getTypeOfField($field), [RequestType::REST, RequestType::JSON_API]); } $route->setRequirement(self::ID_ATTRIBUTE, implode(RestRequest::ARRAY_DELIMITER, $requirements)); } }