altcolor-1.0.0-beta1/src/Theme/ColorPreviewThemeNegotiator.php
src/Theme/ColorPreviewThemeNegotiator.php
<?php
namespace Drupal\altcolor\Theme;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Theme\ThemeNegotiatorInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Allows rendering of the front page in a different theme for color previews.
*/
class ColorPreviewThemeNegotiator implements ThemeNegotiatorInterface {
/**
* The temp store.
*
* @var \Drupal\Core\TempStore\PrivateTempStore
*/
protected $tempStore;
/**
* Constructs a ColorPreviewThemeNegotiator.
*
* @param \Drupal\Core\Extension\ThemeHandlerInterface $themeHandler
* The theme handler.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack.
* @param \Drupal\Core\Session\AccountProxyInterface $currentUser
* The current user.
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The temp store factory.
*/
public function __construct(
protected ThemeHandlerInterface $themeHandler,
protected RequestStack $requestStack,
protected AccountProxyInterface $currentUser,
PrivateTempStoreFactory $temp_store_factory,
) {
$this->tempStore = $temp_store_factory->get('altcolor');
}
/**
* Gets the theme.
*
* @return string
* The theme system name if found, or NULL otherwise.
*/
protected function getTheme() {
$altcolor_preview_theme = $this->tempStore->get($this->currentUser->id() . ':preview_theme');
// Check if this is an existing theme and if it is enabled.
if ($this->themeHandler->themeExists($altcolor_preview_theme)) {
return $altcolor_preview_theme;
}
return NULL;
}
/**
* {@inheritdoc}
*/
public function applies(RouteMatchInterface $route_match) {
// This negotiator should only work for the form preview page. We use
// several methods to check this. We do not check for an administration
// permission here because it is assumed that this was already checked on
// the page where the iframe is being rendered.
if (
// First, check if the query parameter is set.
$this->requestStack->getCurrentRequest()->query->get('altcolor_preview') == '1'
// Then check if the request is coming from our own site...
&& $this->requestStack->getCurrentRequest()->headers->get('Sec-Fetch-Site') == 'same-origin'
// ...and the request is coming from an iframe...
&& $this->requestStack->getCurrentRequest()->headers->get('Sec-Fetch-Dest') == 'iframe'
// ...and the theme resolves.
&& $this->getTheme()
) {
return TRUE;
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function determineActiveTheme(RouteMatchInterface $route_match) {
return $this->getTheme();
}
}
