Completed
Push — 8.x-3.x ( 971daa...8c5245 )
by Philipp
02:20
created

Route::isLanguageAwareField()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql_core\Plugin\GraphQL\Fields\Routing;
4
5
use Drupal\Core\Path\PathValidatorInterface;
6
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
7
use Drupal\graphql\GraphQL\Cache\CacheableValue;
8
use Drupal\graphql\GraphQL\Execution\ResolveContext;
9
use Drupal\graphql\Plugin\GraphQL\Fields\FieldPluginBase;
10
use Drupal\language\LanguageNegotiator;
11
use GraphQL\Type\Definition\ResolveInfo;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
use Symfony\Component\HttpFoundation\Request;
14
15
/**
16
 * Retrieve a route object based on a path.
17
 *
18
 * @GraphQLField(
19
 *   id = "url_route",
20
 *   secure = true,
21
 *   name = "route",
22
 *   description = @Translation("Loads a route by its path."),
23
 *   type = "Url",
24
 *   arguments = {
25
 *     "path" = "String!"
26
 *   }
27
 * )
28
 */
29
class Route extends FieldPluginBase implements ContainerFactoryPluginInterface {
30
31
  /**
32
   * The path validator service.
33
   *
34
   * @var \Drupal\Core\Path\PathValidatorInterface
35
   */
36
  protected $pathValidator;
37
38
  /**
39
   * The language negotiator service.
40
   *
41
   * @var \Drupal\language\LanguageNegotiator
42
   */
43
  protected $languageNegotiator;
44
45
  /**
46
   * {@inheritdoc}
47
   */
48
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
49
    return new static(
50
      $configuration,
51
      $plugin_id,
52
      $plugin_definition,
53
      $container->get('path.validator'),
54
      $container->has('language_negotiator') ? $container->get('language_negotiator') : NULL
55
    );
56
  }
57
58
  /**
59
   * Route constructor.
60
   *
61
   * @param array $configuration
62
   *   The plugin configuration.
63
   * @param string $pluginId
64
   *   The plugin id.
65
   * @param mixed $pluginDefinition
66
   *   The plugin definition.
67
   * @param \Drupal\Core\Path\PathValidatorInterface $pathValidator
68
   *   The path validator service.
69
   * @param \Drupal\language\LanguageNegotiator|null $languageNegotiator
70
   *   The language negotiator.
71
   */
72
  public function __construct(
73
    array $configuration,
74
    $pluginId,
75
    $pluginDefinition,
76
    PathValidatorInterface $pathValidator,
77
    $languageNegotiator
78
  ) {
79
    parent::__construct($configuration, $pluginId, $pluginDefinition);
80
    $this->pathValidator = $pathValidator;
81
    $this->languageNegotiator = $languageNegotiator;
82
  }
83
84
  /**
85
   * {@inheritdoc}
86
   *
87
   * Execute routing in language context.
88
   *
89
   * Language context has to be inferred from the path prefix, but set before
90
   * `resolveValues` is invoked.
91
   */
92
  public function resolve($value, array $args, ResolveContext $context, ResolveInfo $info) {
93
    // For now we just take the "url" negotiator into account.
94
    if ($this->languageNegotiator) {
95
      if ($negotiator = $this->languageNegotiator->getNegotiationMethodInstance('language-url')) {
96
        $context->setContext('language', $negotiator->getLangcode(Request::create($args['path'])), $info);
97
      }
98
    }
99
100
    return parent::resolve($value, $args, $context, $info);
101
  }
102
103
  /**
104
   * {@inheritdoc}
105
   *
106
   * Route field is always language aware since it sets it's context from
107
   * the prefix.
108
   */
109
  protected function isLanguageAwareField() {
110
    return TRUE;
111
  }
112
113
  /**
114
   * {@inheritdoc}
115
   */
116
  public function resolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
117
    if (($url = $this->pathValidator->getUrlIfValidWithoutAccessCheck($args['path'])) && $url->access()) {
118
      yield $url;
119
    }
120
    else {
121
      yield (new CacheableValue(NULL))->addCacheTags(['4xx-response']);
122
    }
123
  }
124
125
}
126