Security update for Core, with self-updated composer
[yaffs-website] / web / core / lib / Drupal / Core / EventSubscriber / MenuRouterRebuildSubscriber.php
1 <?php
2
3 namespace Drupal\Core\EventSubscriber;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Lock\LockBackendInterface;
7 use Drupal\Core\Menu\MenuLinkManagerInterface;
8 use Drupal\Core\Routing\RoutingEvents;
9 use Symfony\Component\EventDispatcher\Event;
10 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
11
12 /**
13  * Rebuilds the default menu links and runs menu-specific code if necessary.
14  */
15 class MenuRouterRebuildSubscriber implements EventSubscriberInterface {
16
17   /**
18    * @var \Drupal\Core\Lock\LockBackendInterface
19    */
20   protected $lock;
21
22   /**
23    * The menu link plugin manager.
24    *
25    * @var \Drupal\Core\Menu\MenuLinkManagerInterface
26    */
27   protected $menuLinkManager;
28
29   /**
30    * Constructs the MenuRouterRebuildSubscriber object.
31    *
32    * @param \Drupal\Core\Lock\LockBackendInterface $lock
33    *   The lock backend.
34    * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
35    *   The menu link plugin manager.
36    */
37   public function __construct(LockBackendInterface $lock, MenuLinkManagerInterface $menu_link_manager) {
38     $this->lock = $lock;
39     $this->menuLinkManager = $menu_link_manager;
40   }
41
42   /**
43    * Rebuilds the menu links and deletes the local_task cache tag.
44    *
45    * @param \Symfony\Component\EventDispatcher\Event $event
46    *   The event object.
47    */
48   public function onRouterRebuild(Event $event) {
49     $this->menuLinksRebuild();
50     Cache::invalidateTags(['local_task']);
51   }
52
53   /**
54    * Perform menu-specific rebuilding.
55    */
56   protected function menuLinksRebuild() {
57     if ($this->lock->acquire(__FUNCTION__)) {
58       $transaction = db_transaction();
59       try {
60         // Ensure the menu links are up to date.
61         $this->menuLinkManager->rebuild();
62         // Ignore any database replicas temporarily.
63         db_ignore_replica();
64       }
65       catch (\Exception $e) {
66         $transaction->rollBack();
67         watchdog_exception('menu', $e);
68       }
69
70       $this->lock->release(__FUNCTION__);
71     }
72     else {
73       // Wait for another request that is already doing this work.
74       // We choose to block here since otherwise the router item may not
75       // be available during routing resulting in a 404.
76       $this->lock->wait(__FUNCTION__);
77     }
78   }
79
80   /**
81    * {@inheritdoc}
82    */
83   public static function getSubscribedEvents() {
84     // Run after CachedRouteRebuildSubscriber.
85     $events[RoutingEvents::FINISHED][] = ['onRouterRebuild', 100];
86     return $events;
87   }
88
89 }