Skip to content

Commit

Permalink
Merge pull request #43 from City-of-Helsinki/UHF-7126
Browse files Browse the repository at this point in the history
UHF-7126: Allow non-html values to be processed, UHF-7193: fixed radioactivity
  • Loading branch information
tuutti authored Oct 25, 2022
2 parents be69a56 + 0a19c6b commit e75e953
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 49 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['8.0']
php-versions: ['8.0', '8.1']
container:
image: ghcr.io/city-of-helsinki/drupal-php-docker:${{ matrix.php-versions }}-alpine

Expand Down Expand Up @@ -83,7 +83,7 @@ jobs:
- name: Create an artifact from test report
uses: actions/upload-artifact@v2
if: always()
if: failure()
with:
name: results
path: |
Expand Down
11 changes: 11 additions & 0 deletions helfi_proxy.module
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ function helfi_proxy_js_settings_alter(
}
$settings[$key] = helfi_proxy_absolute_url($settings[$key]);
}
if (isset($settings['radioactivity'])) {
/** @var \Drupal\helfi_proxy\ActiveSitePrefix $service */
$service = \Drupal::service('helfi_proxy.active_prefix');

if (!$prefix = $service->getPrefix()) {
// Fallback to /en if site has no prefixes configured, like Etusivu
// for example.
$prefix = '/en';
}
$settings['radioactivity']['endpoint'] = sprintf('%s/radioactivity/emit', $prefix);
}
}

/**
Expand Down
8 changes: 6 additions & 2 deletions helfi_proxy.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ parameters:
- hel.fi
- docker.so
services:
helfi_proxy.active_prefix:
class: Drupal\helfi_proxy\ActiveSitePrefix
arguments: ['@language_manager', '@config.factory']

helfi_proxy.http_middleware:
class: Drupal\helfi_proxy\HttpMiddleware\AssetHttpMiddleware
arguments: ['@helfi_proxy.proxy_manager']
Expand All @@ -20,7 +24,7 @@ services:

helfi_proxy.path_processor:
class: Drupal\helfi_proxy\PathProcessor\SitePrefixPathProcessor
arguments: ['@config.factory']
arguments: ['@helfi_proxy.active_prefix']
tags:
# Must be run before PathProcessorFront (200 weight).
- { name: path_processor_inbound, priority: 201 }
Expand All @@ -35,7 +39,7 @@ services:

cache_context.site_prefix:
class: Drupal\helfi_proxy\Cache\Context\SitePrefixCacheContext
arguments: ['@config.factory']
arguments: ['@helfi_proxy.active_prefix']
tags:
- { name: cache.context }

Expand Down
74 changes: 74 additions & 0 deletions src/ActiveSitePrefix.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types = 1);

namespace Drupal\helfi_proxy;

use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;

/**
* A service to figure out currently active site prefix.
*/
final class ActiveSitePrefix implements RefinableCacheableDependencyInterface {

use RefinableCacheableDependencyTrait;

/**
* The configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
private ImmutableConfig $config;

/**
* Constructs a new instance.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
* The language manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
*/
public function __construct(
private LanguageManagerInterface $languageManager,
ConfigFactoryInterface $configFactory
) {
$this->config = $configFactory->get('helfi_proxy.settings');
$this->addCacheableDependency($this->config);
}

/**
* Gets the site prefixes.
*
* @return array
* The prefixes.
*/
public function getPrefixes() : array {
if (!$prefixes = $this->config->get(ProxyManagerInterface::PREFIXES)) {
return [];
}
return $prefixes;
}

/**
* Gets the currently active site prefix.
*
* @return string|null
* The active prefix.
*/
public function getPrefix(string $langcode = NULL) : ? string {
$prefixes = $this->getPrefixes();

if (!$langcode) {
$langcode = $this->languageManager
->getCurrentLanguage(LanguageInterface::TYPE_URL)
->getId();
}
return $prefixes[$langcode] ?? NULL;
}

}
26 changes: 9 additions & 17 deletions src/Cache/Context/SitePrefixCacheContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CalculatedCacheContextInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\helfi_proxy\ActiveSitePrefix;

/**
* Defines the SitePrefixCacheContext service, for "per site prefix" caching.
Expand All @@ -16,35 +16,27 @@
*/
final class SitePrefixCacheContext implements CalculatedCacheContextInterface {

/**
* The config.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
private ImmutableConfig $config;

/**
* Constructs a new instance.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
* @param \Drupal\helfi_proxy\ActiveSitePrefix $sitePrefix
* The active site prefix service.
*/
public function __construct(ConfigFactoryInterface $configFactory) {
$this->config = $configFactory->get('helfi_proxy.settings');
public function __construct(private ActiveSitePrefix $sitePrefix) {
}

/**
* {@inheritdoc}
*/
public static function getLabel() {
return t('Site prefix');
public static function getLabel() : string {
return (string) new TranslatableMarkup('Site prefix');
}

/**
* {@inheritdoc}
*/
public function getContext($prefix = NULL) {
$prefixes = $this->config->get('prefixes') ?? [];
public function getContext($prefix = NULL) : string {
$prefixes = $this->sitePrefix->getPrefixes();

if ($prefix === NULL) {
return implode(',', $prefixes);
Expand Down
3 changes: 2 additions & 1 deletion src/Controller/FrontController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\helfi_proxy\ProxyManagerInterface;

/**
* Empty front page controller.
Expand Down Expand Up @@ -36,7 +37,7 @@ public function index() : array {
* The title.
*/
public function title() : string {
if ($title = $this->config('helfi_proxy.settings')->get('front_page_title')) {
if ($title = $this->config('helfi_proxy.settings')->get(ProxyManagerInterface::FRONT_PAGE_TITLE)) {
return $title;
}
return (string) $this->t('Front');
Expand Down
28 changes: 10 additions & 18 deletions src/PathProcessor/SitePrefixPathProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

namespace Drupal\helfi_proxy\PathProcessor;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\helfi_proxy\ActiveSitePrefix;
use Symfony\Component\HttpFoundation\Request;

/**
Expand All @@ -19,31 +18,23 @@
*/
final class SitePrefixPathProcessor implements OutboundPathProcessorInterface, InboundPathProcessorInterface {

/**
* The config.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
private ImmutableConfig $config;

/**
* Constructs a new instance.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
* @param \Drupal\helfi_proxy\ActiveSitePrefix $sitePrefix
* The site prefix service.
*/
public function __construct(ConfigFactoryInterface $configFactory) {
$this->config = $configFactory->get('helfi_proxy.settings');
public function __construct(private ActiveSitePrefix $sitePrefix) {
}

/**
* {@inheritdoc}
*/
public function processInbound($path, Request $request) {
public function processInbound($path, Request $request) : string {
$parts = explode('/', trim($path, '/'));
$prefix = array_shift($parts);

if (in_array($prefix, $this->config->get('prefixes') ?? [])) {
if (in_array($prefix, $this->sitePrefix->getPrefixes())) {
$path = '/' . implode('/', $parts);
}

Expand All @@ -63,16 +54,17 @@ public function processOutbound(
if (!isset($options['language'])) {
return $path;
}

$language = $options['language'];

if ($options['language'] instanceof LanguageInterface) {
$language = $options['language']->getId();
}
$prefix = $this->config->get('prefixes')[$language] ?? NULL;
// Use already resolved language to figure out active prefix
// since it might be different from content language.
$prefix = $this->sitePrefix->getPrefix($language);

$bubbleable_metadata?->addCacheContexts(['site_prefix:' . $prefix])
->addCacheableDependency($this->config);
->addCacheableDependency($this->sitePrefix);

if ($prefix) {
$options['prefix'] .= $prefix . '/';
Expand Down
33 changes: 26 additions & 7 deletions src/ProxyManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\helfi_proxy\Selector\AbsoluteUriAttributeSelector;
use Drupal\helfi_proxy\Selector\AttributeSelector;
use Drupal\helfi_proxy\Selector\MultiValueAttributeSelector;
use Drupal\helfi_proxy\Selector\SelectorInterface;
use Drupal\helfi_proxy\Selector\SelectorRepositoryTrait;
use Drupal\helfi_proxy\Selector\StringValue;
use Symfony\Component\HttpFoundation\Request;

/**
Expand Down Expand Up @@ -48,7 +49,7 @@ public function getConfig(string $key, mixed $defaultValue = NULL) : mixed {
/**
* {@inheritdoc}
*/
public function processHtml(string $html, Request $request, array $selectors = []) : string {
public function processHtml(string $html, Request $request = NULL, array $selectors = []) : string {
$dom = new \DOMDocument();
$previousXmlErrorBehavior = libxml_use_internal_errors(TRUE);
$encoding = '<?xml encoding="utf-8" ?>';
Expand All @@ -65,8 +66,8 @@ public function processHtml(string $html, Request $request, array $selectors = [
$value = $this
->getAttributeValue(
$selector,
$request,
$row->getAttribute($selector->attribute),
$request
);

if (!$value) {
Expand All @@ -82,20 +83,35 @@ public function processHtml(string $html, Request $request, array $selectors = [
return str_replace($encoding, '', $result);
}

/**
* {@inheritdoc}
*/
public function processValue(string $value, Request $request = NULL, array $selectors = []) : string {
$value = trim($value);

if (!$selectors) {
$selectors[] = new StringValue();
}
foreach ($selectors as $selector) {
$value = $this->getAttributeValue($selector, $value, $request);
}
return $value;
}

/**
* Gets the attribute value.
*
* @param \Drupal\helfi_proxy\Selector\AttributeSelector $selector
* @param \Drupal\helfi_proxy\Selector\SelectorInterface $selector
* The selector.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
* @param string|null $value
* The value.
* @param null|\Symfony\Component\HttpFoundation\Request $request
* The request.
*
* @return string|null
* The attribute value.
*/
private function getAttributeValue(AttributeSelector $selector, Request $request, ?string $value) : ? string {
private function getAttributeValue(SelectorInterface $selector, ?string $value, Request $request = NULL) : ? string {
// Skip if value is being served from CDN already.
if (!$value || $this->isCdnAddress($value)) {
return $value;
Expand All @@ -104,6 +120,9 @@ private function getAttributeValue(AttributeSelector $selector, Request $request
// Certain elements might be absolute URLs already (such as og:image:url).
// Make sure locally hosted files are always served from correct domain.
if ($selector instanceof AbsoluteUriAttributeSelector) {
if (!$request) {
throw new \LogicException('Missing required Request $request.');
}
$parts = parse_url($value);

if (empty($parts['path'])) {
Expand Down
19 changes: 17 additions & 2 deletions src/ProxyManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,30 @@ interface ProxyManagerInterface {
*
* @param string $html
* The html to manipulate.
* @param \Symfony\Component\HttpFoundation\Request $request
* @param null|\Symfony\Component\HttpFoundation\Request $request
* The request.
* @param array $selectors
* The selectors.
*
* @return \Symfony\Component\HttpFoundation\Response
* The manipulated response.
*/
public function processHtml(string $html, Request $request, array $selectors = []) : string;
public function processHtml(string $html, Request $request = NULL, array $selectors = []) : string;

/**
* Processes a string value.
*
* @param string $value
* The value.
* @param null|\Symfony\Component\HttpFoundation\Request $request
* The request.
* @param array $selectors
* The selectors.
*
* @return string
* The processed value.
*/
public function processValue(string $value, Request $request = NULL, array $selectors = []) : string;

/**
* Whether the proxy is configured or not.
Expand Down
Loading

0 comments on commit e75e953

Please sign in to comment.