These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the FOSHttpCacheBundle package. |
||
5 | * |
||
6 | * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace FOS\HttpCacheBundle\EventListener; |
||
13 | |||
14 | use FOS\HttpCacheBundle\CacheManager; |
||
15 | use FOS\HttpCacheBundle\Configuration\Tag; |
||
16 | use FOS\HttpCacheBundle\Http\RuleMatcherInterface; |
||
17 | use FOS\HttpCacheBundle\Http\SymfonyResponseTagger; |
||
18 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||
19 | use Symfony\Component\ExpressionLanguage\ExpressionLanguage; |
||
20 | use Symfony\Component\HttpFoundation\Request; |
||
21 | use Symfony\Component\HttpKernel\Event\FilterResponseEvent; |
||
22 | use Symfony\Component\HttpKernel\HttpKernelInterface; |
||
23 | use Symfony\Component\HttpKernel\KernelEvents; |
||
24 | |||
25 | /** |
||
26 | * Event handler for the cache tagging tags. |
||
27 | * |
||
28 | * @author David de Boer <[email protected]> |
||
29 | */ |
||
30 | class TagListener extends AbstractRuleListener implements EventSubscriberInterface |
||
31 | { |
||
32 | /** |
||
33 | * @var CacheManager |
||
34 | */ |
||
35 | private $cacheManager; |
||
36 | |||
37 | /** |
||
38 | * @var SymfonyResponseTagger |
||
39 | */ |
||
40 | private $symfonyResponseTagger; |
||
41 | |||
42 | /** |
||
43 | * @var ExpressionLanguage |
||
44 | */ |
||
45 | private $expressionLanguage; |
||
46 | |||
47 | /** |
||
48 | * @var RuleMatcherInterface |
||
49 | */ |
||
50 | private $mustInvalidateRule; |
||
51 | |||
52 | /** |
||
53 | * @var RuleMatcherInterface |
||
54 | */ |
||
55 | private $cacheableRule; |
||
56 | |||
57 | /** |
||
58 | * Constructor. |
||
59 | * |
||
60 | * @param CacheManager $cacheManager |
||
61 | * @param SymfonyResponseTagger $tagHandler |
||
62 | * @param ExpressionLanguage|null $expressionLanguage |
||
63 | */ |
||
64 | 28 | View Code Duplication | public function __construct( |
65 | CacheManager $cacheManager, |
||
66 | SymfonyResponseTagger $tagHandler, |
||
67 | RuleMatcherInterface $cacheableRule, |
||
68 | RuleMatcherInterface $mustInvalidateRule, |
||
69 | ExpressionLanguage $expressionLanguage = null |
||
70 | ) { |
||
71 | 28 | $this->cacheManager = $cacheManager; |
|
72 | 28 | $this->symfonyResponseTagger = $tagHandler; |
|
73 | 28 | $this->cacheableRule = $cacheableRule; |
|
74 | 28 | $this->mustInvalidateRule = $mustInvalidateRule; |
|
75 | 28 | $this->expressionLanguage = $expressionLanguage ?: new ExpressionLanguage(); |
|
76 | 28 | } |
|
77 | |||
78 | /** |
||
79 | * Process the _tags request attribute, which is set when using the Tag |
||
80 | * annotation. |
||
81 | * |
||
82 | * - For a safe (GET or HEAD) request, the tags are set on the response. |
||
83 | * - For a non-safe request, the tags will be invalidated. |
||
84 | * |
||
85 | * @param FilterResponseEvent $event |
||
86 | */ |
||
87 | 27 | public function onKernelResponse(FilterResponseEvent $event) |
|
88 | { |
||
89 | 27 | $request = $event->getRequest(); |
|
90 | 27 | $response = $event->getResponse(); |
|
91 | |||
92 | 27 | if (!$this->cacheableRule->matches($request, $response) |
|
93 | 27 | && !$this->mustInvalidateRule->matches($request, $response) |
|
94 | ) { |
||
95 | 4 | return; |
|
96 | } |
||
97 | |||
98 | 23 | $tags = $this->getAnnotationTags($request); |
|
99 | |||
100 | 23 | $configuredTags = $this->matchRule($request); |
|
101 | 23 | if ($configuredTags) { |
|
102 | 5 | $tags = array_merge($tags, $configuredTags['tags']); |
|
103 | 5 | foreach ($configuredTags['expressions'] as $expression) { |
|
104 | 5 | $tags[] = $this->evaluateTag($expression, $request); |
|
105 | } |
||
106 | } |
||
107 | |||
108 | 23 | if ($this->cacheableRule->matches($request, $response)) { |
|
109 | // For safe requests (GET and HEAD), set cache tags on response |
||
110 | 15 | $this->symfonyResponseTagger->addTags($tags); |
|
111 | 15 | if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { |
|
112 | 15 | $this->symfonyResponseTagger->tagSymfonyResponse($response); |
|
113 | } |
||
114 | 8 | } elseif (count($tags) |
|
115 | 8 | && $this->mustInvalidateRule->matches($request, $response) |
|
116 | ) { |
||
117 | 4 | $this->cacheManager->invalidateTags($tags); |
|
118 | } |
||
119 | 23 | } |
|
120 | |||
121 | /** |
||
122 | * {@inheritdoc} |
||
123 | */ |
||
124 | 2 | public static function getSubscribedEvents() |
|
125 | { |
||
126 | return [ |
||
127 | 2 | KernelEvents::RESPONSE => 'onKernelResponse', |
|
128 | ]; |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Get the tags from the annotations on the controller that was used in the |
||
133 | * request. |
||
134 | * |
||
135 | * @param Request $request |
||
136 | * |
||
137 | * @return array List of tags affected by the request |
||
138 | */ |
||
139 | 23 | private function getAnnotationTags(Request $request) |
|
140 | { |
||
141 | // Check for _tag request attribute that is set when using @Tag |
||
142 | // annotation |
||
143 | /** @var $tagConfigurations Tag[] */ |
||
144 | 23 | if (!$tagConfigurations = $request->attributes->get('_tag')) { |
|
145 | 12 | return []; |
|
146 | } |
||
147 | |||
148 | 11 | $tags = []; |
|
149 | 11 | foreach ($tagConfigurations as $tagConfiguration) { |
|
150 | 11 | if (null !== $tagConfiguration->getExpression()) { |
|
151 | 3 | $tags[] = $this->evaluateTag( |
|
152 | 3 | $tagConfiguration->getExpression(), |
|
153 | 3 | $request |
|
154 | ); |
||
155 | } else { |
||
156 | 11 | $tags = array_merge($tags, $tagConfiguration->getTags()); |
|
157 | } |
||
158 | } |
||
159 | |||
160 | 11 | return $tags; |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * Evaluate a tag that contains expressions. |
||
165 | * |
||
166 | * @param string $expression |
||
167 | * @param Request $request |
||
168 | * |
||
169 | * @return string Evaluated tag |
||
0 ignored issues
–
show
|
|||
170 | */ |
||
171 | 8 | private function evaluateTag($expression, Request $request) |
|
172 | { |
||
173 | 8 | $values = $request->attributes->all(); |
|
174 | // if there is an attribute called "request", it needs to be accessed through the request. |
||
175 | 8 | $values['request'] = $request; |
|
176 | |||
177 | 8 | return $this->expressionLanguage->evaluate($expression, $values); |
|
178 | } |
||
179 | } |
||
180 |
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.