Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Update/UpdateKernel.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | c2387f117808 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Update; | |
4 | |
5 use Drupal\Core\DrupalKernel; | |
6 use Drupal\Core\Session\AnonymousUserSession; | |
7 use Drupal\Core\Site\Settings; | |
8 use Symfony\Cmf\Component\Routing\RouteObjectInterface; | |
9 use Symfony\Component\HttpFoundation\ParameterBag; | |
10 use Symfony\Component\HttpFoundation\Request; | |
11 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | |
12 | |
13 /** | |
14 * Defines a kernel which is used primarily to run the update of Drupal. | |
15 * | |
16 * We use a dedicated kernel + front controller (update.php) in order to be able | |
17 * to repair Drupal if it is in a broken state. | |
18 * | |
19 * @see update.php | |
20 * @see \Drupal\system\Controller\DbUpdateController | |
21 */ | |
22 class UpdateKernel extends DrupalKernel { | |
23 | |
24 /** | |
25 * {@inheritdoc} | |
26 */ | |
27 public function discoverServiceProviders() { | |
28 parent::discoverServiceProviders(); | |
29 | |
30 $this->serviceProviderClasses['app']['update_kernel'] = 'Drupal\Core\Update\UpdateServiceProvider'; | |
31 } | |
32 | |
33 /** | |
34 * {@inheritdoc} | |
35 */ | |
36 protected function initializeContainer() { | |
37 // Always force a container rebuild, in order to be able to override some | |
38 // services, see \Drupal\Core\Update\UpdateServiceProvider. | |
39 $this->containerNeedsRebuild = TRUE; | |
40 $container = parent::initializeContainer(); | |
41 return $container; | |
42 } | |
43 | |
44 /** | |
45 * {@inheritdoc} | |
46 */ | |
47 protected function cacheDrupalContainer(array $container_definition) { | |
48 // Don't save this particular container to cache, so it does not leak into | |
49 // the main site at all. | |
50 return FALSE; | |
51 } | |
52 | |
53 /** | |
54 * {@inheritdoc} | |
55 */ | |
56 public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) { | |
57 try { | |
58 static::bootEnvironment(); | |
59 | |
60 // First boot up basic things, like loading the include files. | |
61 $this->initializeSettings($request); | |
62 $this->boot(); | |
63 $container = $this->getContainer(); | |
64 /** @var \Symfony\Component\HttpFoundation\RequestStack $request_stack */ | |
65 $request_stack = $container->get('request_stack'); | |
66 $request_stack->push($request); | |
67 $this->preHandle($request); | |
68 | |
69 // Handle the actual request. We need the session both for authentication | |
70 // as well as the DB update, like | |
71 // \Drupal\system\Controller\DbUpdateController::batchFinished. | |
72 $this->bootSession($request, $type); | |
73 $result = $this->handleRaw($request); | |
74 $this->shutdownSession($request); | |
75 | |
76 return $result; | |
77 } | |
78 catch (\Exception $e) { | |
79 return $this->handleException($e, $request, $type); | |
80 } | |
81 } | |
82 | |
83 /** | |
84 * Generates the actual result of update.php. | |
85 * | |
86 * The actual logic of the update is done in the db update controller. | |
87 * | |
88 * @param \Symfony\Component\HttpFoundation\Request $request | |
89 * The incoming request. | |
90 * | |
91 * @return \Symfony\Component\HttpFoundation\Response | |
92 * A response object. | |
93 * | |
94 * @see \Drupal\system\Controller\DbUpdateController | |
95 */ | |
96 protected function handleRaw(Request $request) { | |
97 $container = $this->getContainer(); | |
98 | |
99 $this->handleAccess($request, $container); | |
100 | |
101 /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */ | |
102 $controller_resolver = $container->get('controller_resolver'); | |
103 | |
104 /** @var callable $db_update_controller */ | |
105 $db_update_controller = $controller_resolver->getControllerFromDefinition('\Drupal\system\Controller\DbUpdateController::handle'); | |
106 | |
107 $this->setupRequestMatch($request); | |
108 | |
109 $arguments = $controller_resolver->getArguments($request, $db_update_controller); | |
110 return call_user_func_array($db_update_controller, $arguments); | |
111 } | |
112 | |
113 /** | |
114 * Boots up the session. | |
115 * | |
116 * bootSession() + shutdownSession() basically simulates what | |
117 * \Drupal\Core\StackMiddleware\Session does. | |
118 * | |
119 * @param \Symfony\Component\HttpFoundation\Request $request | |
120 * The incoming request. | |
121 */ | |
122 protected function bootSession(Request $request) { | |
123 $container = $this->getContainer(); | |
124 /** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */ | |
125 $session = $container->get('session'); | |
126 $session->start(); | |
127 $request->setSession($session); | |
128 } | |
129 | |
130 /** | |
131 * Ensures that the session is saved. | |
132 * | |
133 * @param \Symfony\Component\HttpFoundation\Request $request | |
134 * The incoming request. | |
135 */ | |
136 protected function shutdownSession(Request $request) { | |
137 if ($request->hasSession()) { | |
138 $request->getSession()->save(); | |
139 } | |
140 } | |
141 | |
142 /** | |
143 * Set up the request with fake routing data for update.php. | |
144 * | |
145 * This fake routing data is needed in order to make batch API work properly. | |
146 * | |
147 * @param \Symfony\Component\HttpFoundation\Request $request | |
148 * The incoming request. | |
149 */ | |
150 protected function setupRequestMatch(Request $request) { | |
151 $path = $request->getPathInfo(); | |
152 $args = explode('/', ltrim($path, '/')); | |
153 | |
154 $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'system.db_update'); | |
155 $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $this->getContainer()->get('router.route_provider')->getRouteByName('system.db_update')); | |
156 $op = $args[0] ?: 'info'; | |
157 $request->attributes->set('op', $op); | |
158 $request->attributes->set('_raw_variables', new ParameterBag(['op' => $op])); | |
159 } | |
160 | |
161 /** | |
162 * Checks if the current user has rights to access updates page. | |
163 * | |
164 * If the current user does not have the rights, an exception is thrown. | |
165 * | |
166 * @param \Symfony\Component\HttpFoundation\Request $request | |
167 * The incoming request. | |
168 * | |
169 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException | |
170 * Thrown when update.php should not be accessible. | |
171 */ | |
172 protected function handleAccess(Request $request) { | |
173 /** @var \Drupal\Core\Authentication\AuthenticationManager $authentication_manager */ | |
174 $authentication_manager = $this->getContainer()->get('authentication'); | |
175 $account = $authentication_manager->authenticate($request) ?: new AnonymousUserSession(); | |
176 | |
177 /** @var \Drupal\Core\Session\AccountProxyInterface $current_user */ | |
178 $current_user = $this->getContainer()->get('current_user'); | |
179 $current_user->setAccount($account); | |
180 | |
181 /** @var \Drupal\system\Access\DbUpdateAccessCheck $db_update_access */ | |
182 $db_update_access = $this->getContainer()->get('access_check.db_update'); | |
183 | |
184 if (!Settings::get('update_free_access', FALSE) && !$db_update_access->access($account)->isAllowed()) { | |
185 throw new AccessDeniedHttpException('In order to run update.php you need to either be logged in as admin or have set $settings[\'update_free_access\'] in your settings.php.'); | |
186 } | |
187 } | |
188 | |
189 } |