/**
  * {@inheritdoc}
  */
 public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id)
 {
     $parameters = $route_match->getParameters()->all();
     $entity_type_id = $parameters['entity_type_id'];
     // Attempt to load the content entity.
     if (isset($parameters[$entity_type_id]) && $parameters[$entity_type_id] instanceof ContentEntityInterface) {
         $this->contentEntity = $parameters[$entity_type_id];
     }
     return $this->entityLayoutManager->getFromRouteMatch($route_match);
 }
Exemple #2
0
 /**
  * Wizards are not instantiated as simply as forms, so this method is unused.
  */
 protected function getFormObject(RouteMatchInterface $route_match, $form_arg)
 {
     if (!is_subclass_of($form_arg, '\\Drupal\\ctools\\Wizard\\FormWizardInterface')) {
         throw new \Exception("The _wizard default must reference a class instance of \\Drupal\\ctools\\Wizard\\FormWizardInterface.");
     }
     $parameters = $route_match->getParameters()->all();
     $parameters += $form_arg::getParameters();
     $parameters['route_match'] = $route_match;
     return $this->wizardFactory->createWizard($form_arg, $parameters);
 }
 /**
  * Loads the default revision of the entity this route is for.
  *
  * @param \Symfony\Component\Routing\Route $route
  *   The route to check against.
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The parametrized route
  *
  * @return ContentEntityInterface|null
  *   returns the Entity in question, or NULL if for some reason no entity
  *   is available.
  */
 protected function loadEntity(Route $route, RouteMatchInterface $route_match)
 {
     // Split the entity type and the operation.
     $requirement = $route->getRequirement('_entity_access');
     list($entity_type, $operation) = explode('.', $requirement);
     // If there is valid entity of the given entity type, check its access.
     $parameters = $route_match->getParameters();
     if ($parameters->has($entity_type)) {
         $entity = $parameters->get($entity_type);
         if ($entity instanceof EntityInterface) {
             return $entity;
         }
     }
     return NULL;
 }
 /**
  * Checks whether the embed button is enabled for the given text editor.
  *
  * Returns allowed if the editor toolbar contains the embed button or neutral
  * otherwise.
  *
  * @code
  * pattern: '/foo/{editor}/{embed_button}'
  * requirements:
  *   _embed_button_filter_access: 'TRUE'
  * @endcode
  *
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The current route match.
  * @param \Drupal\Core\Session\AccountInterface $account
  *   The currently logged in account.
  *
  * @return \Drupal\Core\Access\AccessResultInterface
  *   The access result.
  */
 public function access(RouteMatchInterface $route_match, AccountInterface $account)
 {
     $parameters = $route_match->getParameters();
     $access_result = AccessResult::allowedIf($parameters->has('editor') && $parameters->has('embed_button'))->addCacheContexts(['route']);
     if ($access_result->isAllowed()) {
         $editor = $parameters->get('editor');
         $embed_button = $parameters->get('embed_button');
         if ($editor instanceof EditorInterface && $embed_button instanceof EmbedButtonInterface) {
             return $access_result->andIf($editor->getFilterFormat()->access('use', $account, TRUE))->andIf($this->checkButtonEditorAccess($embed_button, $editor));
         }
     }
     // No opinion, so other access checks should decide if access should be
     // allowed or not.
     return $access_result;
 }
 /**
  * {@inheritdoc}
  */
 public function getRuntimeContexts(array $unqualified_context_ids)
 {
     $result = [];
     $value = NULL;
     if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['rdf_entity'])) {
         /** @var \Drupal\rdf_entity\RdfInterface $collection */
         if ($collection = $this->routeMatch->getParameter('rdf_entity')) {
             if ($collection->bundle() == 'collection') {
                 $value = $collection;
             }
         }
     } elseif (($route_parameters = $this->routeMatch->getParameters()) && in_array($this->routeMatch->getRouteName(), $this->getSupportedRoutes())) {
         foreach ($route_parameters as $route_parameter) {
             if ($route_parameter instanceof ContentEntityInterface) {
                 $bundle = $route_parameter->bundle();
                 $entity_type = $route_parameter->getEntityTypeId();
                 // Check if the object is a og content entity.
                 if (Og::isGroupContent($entity_type, $bundle) && ($groups = $this->membershipManager->getGroupIds($route_parameter, 'rdf_entity', 'collection'))) {
                     // A content can belong to only one rdf_entity.
                     // Check that the content is not an orphaned one.
                     if ($collection_id = reset($groups['rdf_entity'])) {
                         $collection = Rdf::load($collection_id);
                         $value = $collection;
                     }
                 }
             }
         }
     }
     $cacheability = new CacheableMetadata();
     $cacheability->setCacheContexts(['route']);
     $collection_context_definition = new ContextDefinition('entity', $this->t('Organic group provided by collection'), FALSE);
     $context = new Context($collection_context_definition, $value);
     $context->addCacheableDependency($cacheability);
     $result['og'] = $context;
     return $result;
 }
Exemple #6
0
 /**
  * Determines whether the route of a certain local task is currently active.
  *
  * @param string $current_route_name
  *   The route name of the current main request.
  * @param string $route_name
  *   The route name of the local task to determine the active status.
  * @param array $route_parameters
  *
  * @return bool
  *   Returns TRUE if the passed route_name and route_parameters is considered
  *   as the same as the one from the request, otherwise FALSE.
  */
 protected function isRouteActive($current_route_name, $route_name, $route_parameters)
 {
     // Flag the list element as active if this tab's route and parameters match
     // the current request's route and route variables.
     $active = $current_route_name == $route_name;
     if ($active) {
         // The request is injected, so we need to verify that we have the expected
         // _raw_variables attribute.
         $raw_variables_bag = $this->routeMatch->getRawParameters();
         // If we don't have _raw_variables, we assume the attributes are still the
         // original values.
         $raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $this->routeMatch->getParameters()->all();
         $active = array_intersect_assoc($route_parameters, $raw_variables) == $route_parameters;
     }
     return $active;
 }
Exemple #7
0
 /**
  * Checks access to the entity operation on the given route.
  *
  * The value of the '_entity_access' key must be in the pattern
  * 'entity_type.operation.' The entity type must match the {entity_type}
  * parameter in the route pattern. This will check a node for 'update' access:
  * @code
  * pattern: '/foo/{node}/bar'
  * requirements:
  *   _entity_access: 'node.update'
  * @endcode
  * Available operations are 'view', 'update', 'create', and 'delete'.
  *
  * @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.
  *
  * @return \Drupal\Core\Access\AccessResultInterface
  *   The access result.
  */
 public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account)
 {
     // Split the entity type and the operation.
     $requirement = $route->getRequirement('_entity_access');
     list($entity_type, $operation) = explode('.', $requirement);
     // If there is valid entity of the given entity type, check its access.
     $parameters = $route_match->getParameters();
     if ($parameters->has($entity_type)) {
         $entity = $parameters->get($entity_type);
         if ($entity instanceof EntityInterface) {
             return $entity->access($operation, $account, TRUE);
         }
     }
     // No opinion, so other access checks should decide if access should be
     // allowed or not.
     return AccessResult::neutral();
 }
 /**
  * {@inheritdoc}
  */
 public function getArgumentsResolver(RouteMatchInterface $route_match, AccountInterface $account, Request $request = NULL)
 {
     $route = $route_match->getRouteObject();
     // Defaults for the parameters defined on the route object need to be added
     // to the raw arguments.
     $raw_route_arguments = $route_match->getRawParameters()->all() + $route->getDefaults();
     $upcasted_route_arguments = $route_match->getParameters()->all();
     // Parameters which are not defined on the route object, but still are
     // essential for access checking are passed as wildcards to the argument
     // resolver. An access-check method with a parameter of type Route,
     // RouteMatchInterface, AccountInterface or Request will receive those
     // arguments regardless of the parameter name.
     $wildcard_arguments = [$route, $route_match, $account];
     if (isset($request)) {
         $wildcard_arguments[] = $request;
     }
     return new ArgumentsResolver($raw_route_arguments, $upcasted_route_arguments, $wildcard_arguments);
 }
 /**
  * Attempt to load an entity layout from the route match.
  *
  * @param RouteMatchInterface $route_match
  *   The route match object.
  *
  * @return \Drupal\entity_layout\EntityLayoutInterface|null
  *   The entity layout object if found.
  */
 public function getFromRouteMatch(RouteMatchInterface $route_match)
 {
     $parameters = $route_match->getParameters()->all();
     if (!isset($parameters['entity_type_id']) || !isset($parameters['bundle'])) {
         return NULL;
     }
     $entity_type_id = $parameters['entity_type_id'];
     $bundle = $parameters['bundle'];
     // If the page being loaded is for a content entity then we need to use
     // the bundle from the content entity instead as the bundle name since
     // the one supplied in the route parameters is the key for where the
     // bundle is stored in the database only.
     if (isset($parameters[$entity_type_id]) && $parameters[$entity_type_id] instanceof ContentEntityInterface) {
         /** @var ContentEntityInterface $content_entity */
         $content_entity = $parameters[$entity_type_id];
         $bundle = $content_entity->bundle();
     }
     return $this->getEntityLayout($entity_type_id, $bundle);
 }
 /**
  * Determines the entity.
  *
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match.
  * @param \Drupal\Core\Entity\EntityInterface $_entity
  *   (optional) The entity, set in
  *   \Drupal\Core\Entity\Enhancer\EntityRouteEnhancer.
  *
  * @return \Drupal\Core\Entity\EntityInterface|NULL
  *   The entity, if it is passed in directly or if the first parameter of the
  *   active route is an entity; otherwise, NULL.
  */
 protected function doGetEntity(RouteMatchInterface $route_match, EntityInterface $_entity = NULL)
 {
     if ($_entity) {
         $entity = $_entity;
     } else {
         // Let's look up in the route object for the name of upcasted values.
         foreach ($route_match->getParameters() as $parameter) {
             if ($parameter instanceof EntityInterface) {
                 $entity = $parameter;
                 break;
             }
         }
     }
     if ($entity) {
         return $this->entityManager->getTranslationFromContext($entity);
     }
 }
Exemple #11
0
 /**
  * @covers ::getParameters
  * @covers \Drupal\Core\Routing\RouteMatch::getParameterNames
  * @dataProvider routeMatchProvider
  */
 public function testGetParameters(RouteMatchInterface $route_match, Route $route, $parameters, $expected_filtered_parameters)
 {
     $this->assertSame($expected_filtered_parameters, $route_match->getParameters()->all());
 }
 /**
  * {@inheritdoc}
  */
 public function applies(RouteMatchInterface $route_match)
 {
     // This breadcrumb apply only for all articles.
     $parameters = $route_match->getParameters()->all();
     if (isset($parameters['node']) && is_object($parameters['node'])) {
         return $parameters['node']->getType() == 'article';
     }
     return FALSE;
 }
 /**
  * Handles a web API request.
  *
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The HTTP request object.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The response object.
  */
 public function handle(RouteMatchInterface $route_match, Request $request)
 {
     $plugin = $route_match->getRouteObject()->getDefault('_plugin');
     $method = strtolower($request->getMethod());
     $resource = $this->container->get('plugin.manager.rest')->getInstance(array('id' => $plugin));
     // Deserialize incoming data if available.
     $serializer = $this->container->get('serializer');
     $received = $request->getContent();
     $unserialized = NULL;
     if (!empty($received)) {
         $format = $request->getContentType();
         // Only allow serialization formats that are explicitly configured. If no
         // formats are configured allow all and hope that the serializer knows the
         // format. If the serializer cannot handle it an exception will be thrown
         // that bubbles up to the client.
         $config = $this->container->get('config.factory')->get('rest.settings')->get('resources');
         $method_settings = $config[$plugin][$request->getMethod()];
         if (empty($method_settings['supported_formats']) || in_array($format, $method_settings['supported_formats'])) {
             $definition = $resource->getPluginDefinition();
             $class = $definition['serialization_class'];
             try {
                 $unserialized = $serializer->deserialize($received, $class, $format, array('request_method' => $method));
             } catch (UnexpectedValueException $e) {
                 $error['error'] = $e->getMessage();
                 $content = $serializer->serialize($error, $format);
                 return new Response($content, 400, array('Content-Type' => $request->getMimeType($format)));
             }
         } else {
             throw new UnsupportedMediaTypeHttpException();
         }
     }
     // Determine the request parameters that should be passed to the resource
     // plugin.
     $route_parameters = $route_match->getParameters();
     $parameters = array();
     // Filter out all internal parameters starting with "_".
     foreach ($route_parameters as $key => $parameter) {
         if ($key[0] !== '_') {
             $parameters[] = $parameter;
         }
     }
     // Invoke the operation on the resource plugin.
     // All REST routes are restricted to exactly one format, so instead of
     // parsing it out of the Accept headers again, we can simply retrieve the
     // format requirement. If there is no format associated, just pick JSON.
     $format = $route_match->getRouteObject()->getRequirement('_format') ?: 'json';
     try {
         $response = call_user_func_array(array($resource, $method), array_merge($parameters, array($unserialized, $request)));
     } catch (HttpException $e) {
         $error['error'] = $e->getMessage();
         $content = $serializer->serialize($error, $format);
         // Add the default content type, but only if the headers from the
         // exception have not specified it already.
         $headers = $e->getHeaders() + array('Content-Type' => $request->getMimeType($format));
         return new Response($content, $e->getStatusCode(), $headers);
     }
     // Serialize the outgoing data for the response, if available.
     $data = $response->getResponseData();
     if ($data != NULL) {
         $output = $serializer->serialize($data, $format);
         $response->setContent($output);
         $response->headers->set('Content-Type', $request->getMimeType($format));
         // Add rest settings config's cache tags.
         $response->addCacheableDependency($this->container->get('config.factory')->get('rest.settings'));
     }
     return $response;
 }
Exemple #14
0
  /**
   * Gets the bundle object from the route match.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $routeMatch
   *   The route match.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   The bundle object as determined from the passed-in route match.
   */
  protected function getBundleFromRouteMatch(RouteMatchInterface $routeMatch) {
    // Assume that the bundle is the last route parameter.
    $parameters = $routeMatch->getParameters()->all();
    $bundle = end($parameters);

    return $bundle;
  }
 /**
  * {@inheritdoc}
  */
 public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id)
 {
     $route_parameters = $route_match->getParameters()->all();
     return $this->getEntityDisplay($route_parameters['entity_type_id'], $route_parameters['bundle'], $route_parameters[$this->displayContext . '_mode_name']);
 }
 /**
  * Handles a web API request.
  *
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The HTTP request object.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The response object.
  */
 public function handle(RouteMatchInterface $route_match, Request $request)
 {
     $plugin = $route_match->getRouteObject()->getDefault('_plugin');
     $method = strtolower($request->getMethod());
     // Symfony is built to transparently map HEAD requests to a GET request. In
     // the case of the REST module's RequestHandler though, we essentially have
     // our own light-weight routing system on top of the Drupal/symfony routing
     // system. So, we have to do the same as what the UrlMatcher does: map HEAD
     // requests to the logic for GET. This also guarantees response headers for
     // HEAD requests are identical to those for GET requests, because we just
     // return a GET response. Response::prepare() will transform it to a HEAD
     // response at the very last moment.
     // @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
     // @see \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection()
     // @see \Symfony\Component\HttpFoundation\Response::prepare()
     if ($method === 'head') {
         $method = 'get';
     }
     $resource = $this->container->get('plugin.manager.rest')->getInstance(array('id' => $plugin));
     // Deserialize incoming data if available.
     $serializer = $this->container->get('serializer');
     $received = $request->getContent();
     $unserialized = NULL;
     if (!empty($received)) {
         $format = $request->getContentType();
         // Only allow serialization formats that are explicitly configured. If no
         // formats are configured allow all and hope that the serializer knows the
         // format. If the serializer cannot handle it an exception will be thrown
         // that bubbles up to the client.
         $config = $this->container->get('config.factory')->get('rest.settings')->get('resources');
         $method_settings = $config[$plugin][$request->getMethod()];
         if (empty($method_settings['supported_formats']) || in_array($format, $method_settings['supported_formats'])) {
             $definition = $resource->getPluginDefinition();
             $class = $definition['serialization_class'];
             try {
                 $unserialized = $serializer->deserialize($received, $class, $format, array('request_method' => $method));
             } catch (UnexpectedValueException $e) {
                 $error['error'] = $e->getMessage();
                 $content = $serializer->serialize($error, $format);
                 return new Response($content, 400, array('Content-Type' => $request->getMimeType($format)));
             }
         } else {
             throw new UnsupportedMediaTypeHttpException();
         }
     }
     // Determine the request parameters that should be passed to the resource
     // plugin.
     $route_parameters = $route_match->getParameters();
     $parameters = array();
     // Filter out all internal parameters starting with "_".
     foreach ($route_parameters as $key => $parameter) {
         if ($key[0] !== '_') {
             $parameters[] = $parameter;
         }
     }
     // Invoke the operation on the resource plugin.
     // All REST routes are restricted to exactly one format, so instead of
     // parsing it out of the Accept headers again, we can simply retrieve the
     // format requirement. If there is no format associated, just pick JSON.
     $format = $route_match->getRouteObject()->getRequirement('_format') ?: 'json';
     try {
         $response = call_user_func_array(array($resource, $method), array_merge($parameters, array($unserialized, $request)));
     } catch (HttpException $e) {
         $error['error'] = $e->getMessage();
         $content = $serializer->serialize($error, $format);
         // Add the default content type, but only if the headers from the
         // exception have not specified it already.
         $headers = $e->getHeaders() + array('Content-Type' => $request->getMimeType($format));
         return new Response($content, $e->getStatusCode(), $headers);
     }
     if ($response instanceof ResourceResponse) {
         $data = $response->getResponseData();
         // Serialization can invoke rendering (e.g., generating URLs), but the
         // serialization API does not provide a mechanism to collect the
         // bubbleable metadata associated with that (e.g., language and other
         // contexts), so instead, allow those to "leak" and collect them here in
         // a render context.
         // @todo Add test coverage for language negotiation contexts in
         //   https://www.drupal.org/node/2135829.
         $context = new RenderContext();
         $output = $this->container->get('renderer')->executeInRenderContext($context, function () use($serializer, $data, $format) {
             return $serializer->serialize($data, $format);
         });
         $response->setContent($output);
         if (!$context->isEmpty()) {
             $response->addCacheableDependency($context->pop());
         }
         $response->headers->set('Content-Type', $request->getMimeType($format));
         // Add rest settings config's cache tags.
         $response->addCacheableDependency($this->container->get('config.factory')->get('rest.settings'));
     }
     return $response;
 }
Exemple #17
0
 /**
  * Handles a web API request.
  *
  * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  *   The route match.
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The HTTP request object.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The response object.
  */
 public function handle(RouteMatchInterface $route_match, Request $request)
 {
     $method = strtolower($request->getMethod());
     // Symfony is built to transparently map HEAD requests to a GET request. In
     // the case of the REST module's RequestHandler though, we essentially have
     // our own light-weight routing system on top of the Drupal/symfony routing
     // system. So, we have to do the same as what the UrlMatcher does: map HEAD
     // requests to the logic for GET. This also guarantees response headers for
     // HEAD requests are identical to those for GET requests, because we just
     // return a GET response. Response::prepare() will transform it to a HEAD
     // response at the very last moment.
     // @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
     // @see \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection()
     // @see \Symfony\Component\HttpFoundation\Response::prepare()
     if ($method === 'head') {
         $method = 'get';
     }
     $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');
     /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */
     $resource_config = $this->resourceStorage->load($resource_config_id);
     $resource = $resource_config->getResourcePlugin();
     // Deserialize incoming data if available.
     /** @var \Symfony\Component\Serializer\SerializerInterface $serializer */
     $serializer = $this->container->get('serializer');
     $received = $request->getContent();
     $unserialized = NULL;
     if (!empty($received)) {
         $format = $request->getContentType();
         // Only allow serialization formats that are explicitly configured. If no
         // formats are configured allow all and hope that the serializer knows the
         // format. If the serializer cannot handle it an exception will be thrown
         // that bubbles up to the client.
         $request_method = $request->getMethod();
         if (in_array($format, $resource_config->getFormats($request_method))) {
             $definition = $resource->getPluginDefinition();
             try {
                 if (!empty($definition['serialization_class'])) {
                     $unserialized = $serializer->deserialize($received, $definition['serialization_class'], $format, array('request_method' => $method));
                 } else {
                     $unserialized = $serializer->decode($received, $format, array('request_method' => $method));
                 }
             } catch (UnexpectedValueException $e) {
                 $error['error'] = $e->getMessage();
                 $content = $serializer->serialize($error, $format);
                 return new Response($content, 400, array('Content-Type' => $request->getMimeType($format)));
             }
         } else {
             throw new UnsupportedMediaTypeHttpException();
         }
     }
     // Determine the request parameters that should be passed to the resource
     // plugin.
     $route_parameters = $route_match->getParameters();
     $parameters = array();
     // Filter out all internal parameters starting with "_".
     foreach ($route_parameters as $key => $parameter) {
         if ($key[0] !== '_') {
             $parameters[] = $parameter;
         }
     }
     // Invoke the operation on the resource plugin.
     $format = $this->getResponseFormat($route_match, $request);
     $response = call_user_func_array(array($resource, $method), array_merge($parameters, array($unserialized, $request)));
     return $response instanceof ResourceResponseInterface ? $this->renderResponse($request, $response, $serializer, $format, $resource_config) : $response;
 }