diff --git a/core/core.services.yml b/core/core.services.yml index 5095639..2b1a3da 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -68,6 +68,7 @@ services: arguments: [path] page_cache.internal: class: Drupal\Core\PageCache\InternalPageCache + arguments: ['@cache.page', '@content_negotiation', '@config.factory', '@settings'] page_cache.policy: class: Drupal\Core\PageCache\DefaultPageCachePolicy config.cachedstorage.storage: @@ -503,7 +504,7 @@ services: class: Drupal\Core\EventSubscriber\FinishResponseSubscriber tags: - { name: event_subscriber } - arguments: ['@language_manager'] + arguments: ['@language_manager', '@page_cache.policy', '@page_cache.internal', '@config.factory'] scope: request redirect_response_subscriber: class: Drupal\Core\EventSubscriber\RedirectResponseSubscriber diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index c8fc31f..19b6ad0 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1687,8 +1687,9 @@ function drupal_handle_request($test_only = FALSE) { $cache_policy->applyToRequest($request); // Attempt to serve a cached response from the internal page cache. - $page_cache = \Drupal::service('page_cache.internal'); - if ($page_cache->isDeliveryEnabled() && $cache_policy->isCacheable()) { + $use_internal_cache = \Drupal::config('system.performance')->get('cache.page.use_internal'); + if ($use_internal_cache && $cache_policy->isCacheable()) { + $page_cache = \Drupal::service('page_cache.internal'); if ($page_cache->deliver($request)) { exit(); } diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index dcc714f..c2321c2 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -7,8 +7,12 @@ namespace Drupal\Core\EventSubscriber; +use Drupal\Core\Config\Config; +use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; +use Drupal\Core\PageCache\InternalPageCacheInterface; +use Drupal\Core\PageCache\PageCachePolicyInterface; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -22,18 +26,49 @@ class FinishResponseSubscriber implements EventSubscriberInterface { /** * The LanguageManager object for retrieving the correct language code. * - * @var LanguageManager + * @var \Drupal\Core\Language\LanguageManager */ protected $languageManager; /** + * The PageCachePolicy object necessary to decide whether a page is cacheable. + * + * @var \Drupal\Core\PageCache\PageCachePolicyInterface + */ + protected $pageCachePolicy; + + /** + * The InternalPageCache object used to store cached pages. + * + * @var \Drupal\Core\PageCache\InternalPageCacheInterface + */ + protected $internalPageCache; + + /** + * A config object for the system performance configuration. + * + * @var \Drupal\Core\Config\Config + */ + protected $config; + + /** * Constructs a FinishResponseSubscriber object. * - * @param LanguageManager $language_manager - * The LanguageManager object for retrieving the correct language code. + * @param \Drupal\Core\Language\LanguageManager $language_manager + * The LanguageManager object for retrieving the correct language code. + * @param \Drupal\Core\PageCache\PageCachePolicyInterface $page_cache_policy + * The PageCachePolicy object necessary to decide whether a page is + * cacheable. + * @param \Drupal\Core\PageCache\InternalPageCacheInterface $internal_page_cache + * The InternalPageCache object used to store cached pages. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * A config factory for retrieving required config objects. */ - public function __construct(LanguageManager $language_manager) { + public function __construct(LanguageManager $language_manager, PageCachePolicyInterface $page_cache_policy, InternalPageCacheInterface $internal_page_cache, ConfigFactory $config_factory) { $this->languageManager = $language_manager; + $this->pageCachePolicy = $page_cache_policy; + $this->internalPageCache = $internal_page_cache; + $this->config = $config_factory->get('system.performance'); } /** @@ -100,11 +135,10 @@ public function onRespond(FilterResponseEvent $event) { $response->headers->set($name, $value, FALSE); } - $max_age = \Drupal::config('system.performance')->get('cache.page.max_age'); - $cache_policy = \Drupal::service('page_cache.policy'); - $cache_policy->applyToResponse($response, $request); - if ($max_age > 0 && $cache_policy->isCacheable()) { - \Drupal::service('page_cache.internal')->record($response, $request); + $max_age = $this->config->get('cache.page.max_age'); + $this->pageCachePolicy->applyToResponse($response, $request); + if ($max_age > 0 && $this->pageCachePolicy->isCacheable()) { + $this->internalPageCache->record($response, $request); } else { $response->setExpires(\DateTime::createFromFormat('j-M-Y H:i:s T', '19-Nov-1978 05:00:00 GMT')); diff --git a/core/lib/Drupal/Core/PageCache/InternalPageCache.php b/core/lib/Drupal/Core/PageCache/InternalPageCache.php index ab94d8c..9987f97 100644 --- a/core/lib/Drupal/Core/PageCache/InternalPageCache.php +++ b/core/lib/Drupal/Core/PageCache/InternalPageCache.php @@ -7,7 +7,11 @@ namespace Drupal\Core\PageCache; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Config\Config; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\ContentNegotiation; use Drupal\Core\Datetime\DrupalDateTime; +use Drupal\Component\Utility\Settings; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -15,28 +19,50 @@ * Page caching service based on the internal cache. */ class InternalPageCache implements InternalPageCacheInterface { + /** + * Cache backend for the page cache. + * + * @var \Drupal\Core\Cache\CacheBackendInterface + */ + protected $cache; /** - * Determine whether internal page caching is enabled. + * Content negotiation service. * - * @return bool - * TRUE when the current site configuration allows delivery of pages from - * the internal page cache. + * @var \Drupal\Core\ContentNegotiation */ - public function isDeliveryEnabled() { - require_once DRUPAL_ROOT . '/core/includes/database.inc'; + protected $negotiation; - // Check for a cache mode force from settings.php. - if (settings()->get('page_cache_without_database')) { - $cache_enabled = TRUE; - } - else { - drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE); - $config = \Drupal::config('system.performance'); - $cache_enabled = $config->get('cache.page.use_internal'); - } + /** + * A config object for the system performance configuration. + * + * @var \Drupal\Core\Config\Config + */ - return $cache_enabled; + /** + * The settings instance. + * + * @var \Drupal\Component\Utility\Settings + */ + protected $settings; + + /** + * Constructs a new InternalPageCache object. + * + * @param \Drupal\Core\Cache\CacheBackendInterface $cache + * The cache backend to use. + * @param \Drupal\Core\ContentNegotiation $negotiation + * The content negotiation service. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The configuration factory service. + * @param \Drupal\Component\Utility\Settings $settings + * The settings instance. + */ + public function __construct(CacheBackendInterface $cache, ContentNegotiation $negotiation, ConfigFactory $config_factory, Settings $settings) { + $this->cache = $cache; + $this->negotiation = $negotiation; + $this->config = $config_factory->get('system.performance'); + $this->settings = $settings; } /** @@ -49,21 +75,11 @@ public function isDeliveryEnabled() { * TRUE when the page was delivered from the cache. */ public function deliver(Request $request) { - global $user; - - // Make sure there is a user object because its timestamp will be checked. - if (!isset($user)) { - $user = drupal_anonymous_user(); - } // Get the page from the cache. - $cache = \Drupal::cache('page')->get($this->getCid($request)); - // If there is a cached page, display it. + $cache = $this->cache->get($this->getCid($request)); if (is_object($cache)) { $response = new Response(); $response->headers->set('X-Drupal-Cache', 'HIT'); - // Restore the metadata cached with the page. - _current_path($cache->data['path']); - drupal_set_title($cache->data['title'], PASS_THROUGH); date_default_timezone_set(drupal_get_user_timezone()); $this->populateResponse($cache, $response, $request); @@ -105,7 +121,7 @@ public function record(Response $response, Request $request) { protected function getCid(Request $request) { $cid_parts = array( $request->getUri(), - \Drupal::service('content_negotiation')->getContentType($request), + $this->negotiation->getContentType($request), ); return sha1(implode(':', $cid_parts)); } @@ -122,8 +138,6 @@ protected function getCid(Request $request) { * response is sent. */ protected function populateResponse(\stdClass $cache, Response $response, Request $request) { - $config = \Drupal::config('system.performance'); - // First half: we must determine if we should be returning a 304. // Negotiate whether to use compression. @@ -147,7 +161,7 @@ protected function populateResponse(\stdClass $cache, Response $response, Reques // to that one particular client due to Vary: Cookie. Thus, do not set // max-age > 0, allowing the page to be cached by external proxies, when a // session cookie is present unless the Vary header has been replaced. - $max_age = !$request->cookies->has(session_name()) || isset($boot_headers['vary']) ? $config->get('cache.page.max_age') : 0; + $max_age = !$request->cookies->has(session_name()) || isset($boot_headers['vary']) ? $this->config->get('cache.page.max_age') : 0; $response->headers->set('Cache-Control', 'public, max-age=' . $max_age); // Entity tag should change if the output changes. @@ -187,7 +201,7 @@ protected function populateResponse(\stdClass $cache, Response $response, Reques // fields that fully determines whether a cache is permitted to use the // response to reply to a subsequent request for a given URL without // revalidation. - if (!isset($boot_headers['vary']) && !settings()->get('omit_vary_cookie')) { + if (!isset($boot_headers['vary']) && !$this->settings->get('omit_vary_cookie')) { $response->setVary('Cookie', FALSE); } @@ -233,14 +247,12 @@ protected function populateResponse(\stdClass $cache, Response $response, Reques */ protected function set(Response $response, Request $request) { // Check if the current page may be compressed. - $page_compressed = \Drupal::config('system.performance')->get('response.gzip') && extension_loaded('zlib'); + $page_compressed = $this->config->get('response.gzip') && extension_loaded('zlib'); $cache = (object) array( 'cid' => $this->getCid($request), 'data' => array( - 'path' => $request->attributes->get('_system_path'), 'body' => $response->getContent(), - 'title' => drupal_get_title(), 'headers' => array(), // We need to store whether page was compressed or not, // because by the time it is read, the configuration might change. @@ -269,7 +281,7 @@ protected function set(Response $response, Request $request) { if ($page_compressed) { $cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP); } - cache('page')->set($cache->cid, $cache->data, $cache->expire, $cache->tags); + $this->cache->set($cache->cid, $cache->data, $cache->expire, $cache->tags); } return $cache; } diff --git a/core/lib/Drupal/Core/PageCache/InternalPageCacheInterface.php b/core/lib/Drupal/Core/PageCache/InternalPageCacheInterface.php index 8853ba3..90169e4 100644 --- a/core/lib/Drupal/Core/PageCache/InternalPageCacheInterface.php +++ b/core/lib/Drupal/Core/PageCache/InternalPageCacheInterface.php @@ -15,15 +15,6 @@ interface InternalPageCacheInterface { /** - * Determine whether internal page caching is enabled. - * - * @return bool - * TRUE when the current site configuration allows delivery of pages from - * the internal page cache. - */ - public function isDeliveryEnabled(); - - /** * Attempt to deliver the given request from the page cache. * * @param \Symfony\Component\HttpFoundation\Request $request