Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .github/workflows/tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [ '8.1', '8.2', '8.3' ]
typo3: [ '11', '12' ]
php: [ '8.1', '8.2', '8.3', '8.4' ]
typo3: [ '11', '12', '13' ]
exclude:
- php: '8.1'
typo3: '13'
- php: '8.4'
typo3: '11'
steps:
- name: Setup PHP with PECL extension
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- uses: actions/checkout@v2
- uses: actions/cache@v3
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ~/.composer/cache/files
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
key: ${{ runner.os }}-${{ matrix.php }}
restore-keys: |
${{ runner.os }}-${{ matrix.php }}-composer-
- run: composer require typo3/minimal="^${{ matrix.typo3 }}" -W --dev
- run: composer install --no-interaction --no-progress
- run: composer update --with typo3/minimal="^${{ matrix.typo3 }}" --no-interaction --no-progress -W --dev
- run: ./vendor/bin/grumphp run --ansi

ter-release:
Expand Down
39 changes: 0 additions & 39 deletions Classes/Cache/ClearCache.php

This file was deleted.

9 changes: 7 additions & 2 deletions Classes/Cache/Frontend/SsiIncludeCacheFrontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace AUS\SsiInclude\Cache\Frontend;

use AUS\SsiInclude\Cache\Backend\SsiIncludeCacheBackend;
use InvalidArgumentException;
use TYPO3\CMS\Core\Cache\Exception;
use TYPO3\CMS\Core\Cache\Exception\InvalidDataException;
use TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend;
use Webimpress\SafeWriter\Exception\ExceptionInterface;

/**
* A cache frontend for SSI include cache entries.
Expand All @@ -19,9 +21,10 @@ class SsiIncludeCacheFrontend extends AbstractFrontend

/**
* @inheritdoc
* @throws Exception
* @throws InvalidDataException
* @param list<string> $tags
* @throws InvalidDataException
* @throws Exception
* @throws ExceptionInterface
*/
public function set($entryIdentifier, $data, array $tags = [], $lifetime = null): void
{
Expand All @@ -39,6 +42,8 @@ public function set($entryIdentifier, $data, array $tags = [], $lifetime = null)
}
}

assert($this->backend instanceof SsiIncludeCacheBackend);
assert(is_string($data));
$this->backend->set($entryIdentifier, $data, $tags, $lifetime);
}

Expand Down
1 change: 1 addition & 0 deletions Classes/Proxy/Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

/**
* @implements ArrayAccess<int, mixed>
* @implements Iterator<mixed, mixed>
*/
final class Proxy implements Iterator, Countable, Stringable, ArrayAccess
{
Expand Down
64 changes: 27 additions & 37 deletions Classes/ViewHelpers/RenderIncludeViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
use AUS\SsiInclude\Event\RenderedEvent;
use AUS\SsiInclude\Register\LastRenderedContentRegister;
use AUS\SsiInclude\Utility\FilenameUtility;
use Closure;
use Exception;
use Override;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Exception\InvalidDataException;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException;
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException;
Expand All @@ -22,8 +21,8 @@
use TYPO3\CMS\Core\Context\UserAspect;
use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\ViewHelpers\RenderViewHelper;
use Webimpress\SafeWriter\Exception\ExceptionInterface;

use function assert;

Expand All @@ -48,48 +47,29 @@ public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument('name', 'string', 'Specifies the file name of the cache (without .html ending)', true);
$this->registerArgument('cacheLifeTime', 'int', 'Specifies the lifetime in seconds (defaults to 300)', false, 300);
$this->registerArgument('cacheLifeTime', 'int|null', 'Specifies the lifetime in seconds');
$this->registerArgument('cacheTags', 'array', 'Tags to set that can clear with flushByTags', false, []);
}

/**
* @deprecated can be removed if parent class does not have renderStatic anymore.
*/
#[Override]
public static function renderStatic(array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string
{
/** @noinspection PhpUnhandledExceptionInspection */
$isDisabled = (bool)GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('ssi_include', 'disabled');
if ($isDisabled) {
return parent::renderStatic($arguments, $renderChildrenClosure, $renderingContext);
}

$self = GeneralUtility::makeInstance(self::class);
assert($self instanceof self);
/** @noinspection PhpUnhandledExceptionInspection */
return $self->renderNonStatic($arguments, $renderChildrenClosure, $renderingContext);
}

/**
* @param array<string, mixed>|null $arguments
* @throws Exception
* @throws ExtensionConfigurationExtensionNotConfiguredException
* @throws ExtensionConfigurationPathDoesNotExistException
* @throws NoSuchCacheException
* @throws \TYPO3\CMS\Core\Cache\Exception
* @throws InvalidDataException
* @throws AspectNotFoundException
* @throws ExtensionConfigurationPathDoesNotExistException
* @throws ExtensionConfigurationExtensionNotConfiguredException
* @throws ExceptionInterface
*/
public function renderNonStatic(?array $arguments = null, ?Closure $renderChildrenClosure = null, ?RenderingContextInterface $renderingContext = null): string
public function render(): string
{
$this->arguments = $arguments ?? $this->arguments;
$this->renderingContext = $renderingContext ?? $this->renderingContext;
$renderChildrenClosure ??= $this->buildRenderChildrenClosure();

// generate the cache filename
$name = $this->validateName($this->arguments);

if ($this->isBackendUser()) {
$content = parent::renderStatic($this->arguments, $renderChildrenClosure, $this->renderingContext);
$content = parent::render();
// Put the code to register to use in InternalSsiRedirectMiddleware if the site comes from page cache
assert(is_string($content));
$this->lastRenderedContentRegister->set($name, $content);
return $content;
}
Expand All @@ -107,15 +87,22 @@ public function renderNonStatic(?array $arguments = null, ?Closure $renderChildr
// If the cache has not the proper entry, generate it
$cache = $this->cacheManager->getCache('aus_ssi_include_cache');
assert($cache instanceof SsiIncludeCacheFrontend);

if (!$cache->has($filename)) {
$html = parent::renderStatic($this->arguments, $renderChildrenClosure, $this->renderingContext);
$html = parent::render();
assert(is_string($html));
$eventDispatcher = GeneralUtility::makeInstance(EventDispatcher::class);
$renderedHtmlEvent = new RenderedEvent($html);
$eventDispatcher->dispatch($renderedHtmlEvent);
$html = $renderedHtmlEvent->getHtml();

$cacheTags = ['tx_ssiinclude_' . $name, ...$this->arguments['cacheTags']];
$cache->set($filename, $html, $cacheTags, $this->arguments['cacheLifeTime']);
$cacheTags = $this->arguments['cacheTags'];
assert(is_array($cacheTags));
$cacheTags[] = 'tx_ssiinclude_' . $name;

$cacheLifeTime = $this->arguments['cacheLifeTime'];
assert(is_int($cacheLifeTime) || null === $cacheLifeTime);
$cache->set($filename, $html, $cacheTags, $cacheLifeTime);
$this->lastRenderedContentRegister->set($name, $html);
}

Expand All @@ -135,7 +122,8 @@ public function renderNonStatic(?array $arguments = null, ?Closure $renderChildr
*/
private function validateName(array $arguments): string
{
if (ctype_alnum((string)$arguments['name'])) {
assert(is_string($arguments['name']));
if (ctype_alnum($arguments['name'])) {
return $arguments['name'];
}

Expand All @@ -147,15 +135,17 @@ private function validateName(array $arguments): string
*/
protected function getLanguage(): int
{
return $this->context->getPropertyFromAspect('language', 'id');
$language = $this->context->getPropertyFromAspect('language', 'id');
assert(is_int($language));
return $language;
}

/**
* @throws AspectNotFoundException
*/
protected function isBackendUser(): bool
{
return $this->context->getPropertyFromAspect('backend.user', 'isLoggedIn');
return (bool)$this->context->getPropertyFromAspect('backend.user', 'isLoggedIn');
}

protected function getSiteName(): string
Expand Down
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ACT_IMAGE ?= efrecon/act:v0.2.80
WORKDIR ?= /work
UID_GID := $(shell id -u):$(shell id -g)
DOCKER_GID := $(shell stat -c '%g' /var/run/docker.sock)

PLATFORM ?= -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-24.04

# Secrets-File in ENV format
SECRETS ?= --secret-file .secrets

ACT_ARGS ?= \
--artifact-server-path /home/act/.cache/artifacts

define DOCKER_RUN
docker run --rm -it \
-u $(UID_GID) \
--group-add $(DOCKER_GID) \
-e HOME=/home/act \
-e XDG_CACHE_HOME=/home/act/.cache \
-e ACT_CACHE_DIR=/home/act/.cache/actcache \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):$(WORKDIR) -w $(WORKDIR) \
-v $$HOME/.cache:/home/act/.cache \
$(ACT_IMAGE)
endef

ci:
$(DOCKER_RUN) $(PLATFORM) $(SECRETS) $(ACT_ARGS)
Loading