Skip to content

Commit

Permalink
Merge pull request #33 from b13/v12
Browse files Browse the repository at this point in the history
!!![TASK] complete refactoring
  • Loading branch information
bmack authored Oct 25, 2023
2 parents 885c6bf + d840986 commit 5e5036e
Show file tree
Hide file tree
Showing 38 changed files with 394 additions and 1,054 deletions.
21 changes: 4 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: [ '7.4', '7.3', '7.2' ]
TYPO3: [ '10' ]
include:
- TYPO3: '11'
php: '8.1'
- TYPO3: '11'
php: '8.0'
- TYPO3: '11'
php: '7.4'
php: [ '8.1', '8.2']
TYPO3: ['11', '12' ]
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -38,11 +31,5 @@ jobs:
- name: CGL
run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s cgl -n

# - name: phpstan
# run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s phpstan

- name: Unit Tests
run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -s unit

- name: Functional Tests with mariadb
run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s functional
- name: phpstan
run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s phpstan
17 changes: 0 additions & 17 deletions Build/phpstan10.neon

This file was deleted.

14 changes: 3 additions & 11 deletions Build/phpstan11.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ parameters:

paths:
- %currentWorkingDirectory%/Classes
- %currentWorkingDirectory%/Tests

ignoreErrors:
-
message: '#Constant ORIGINAL_ROOT not found.#'
path: %currentWorkingDirectory%/Tests
-
message: '#Call to an undefined method Prophecy\\Prophecy\\ObjectProphecy::.*#'
path: %currentWorkingDirectory%/Tests
-
message: '#Call to function in_array\(\) with arguments int, array<string> and true will always evaluate to false.#'
path: %currentWorkingDirectory%/Classes/Compiler/LanguageMenuCompiler.php
excludes_analyse:
- %currentWorkingDirectory%/Classes/Listener/AfterCacheIsPersisted.php

8 changes: 8 additions & 0 deletions Build/phpstan12.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
parameters:
level: 5

paths:
- %currentWorkingDirectory%/Classes

ignoreErrors:

49 changes: 0 additions & 49 deletions Build/sites/main/config.yaml

This file was deleted.

4 changes: 2 additions & 2 deletions Build/testing-docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ services:
set -x
fi
php -v | grep '^PHP';
if [ ${TYPO3} -eq 10 ]; then
if [ ${TYPO3} -eq 11 ]; then
composer install --no-progress --no-interaction;
else
composer remove typo3/cms* --dev --no-progress --no-interaction && composer require typo3/cms-install:^11.5 typo3/cms-fluid-styled-content:^11.5 --dev -W --no-progress --no-interaction
composer remove typo3/cms* --dev --no-progress --no-interaction && composer require typo3/cms-frontend:^12.4 typo3/cms-backend:^12.4 --dev -W --no-progress --no-interaction
fi
"
Expand Down
87 changes: 30 additions & 57 deletions Classes/Cache/Backend/ReverseProxyCacheBackend.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace B13\Proxycachemanager\Cache\Backend;

/*
Expand Down Expand Up @@ -29,45 +30,11 @@
*/
class ReverseProxyCacheBackend extends Typo3DatabaseBackend implements TransientBackendInterface
{
/**
* @var ProxyProviderInterface
*/
protected $reverseProxyProvider;

/**
* set from the AbstractCacheBackend when the object is instantiated.
*
* @param string $className
*/
public function setReverseProxyProvider(string $className)
{
if (empty($className)) {
throw new \InvalidArgumentException('Invalid cache proxy provider for Reverse Proxy Cache', 1231267264);
}
try {
$this->reverseProxyProvider = GeneralUtility::makeInstance($className);
} catch (\Exception $e) {
throw new \InvalidArgumentException(
'Invalid cache proxy provider class for Reverse Proxy Cache - Class "' . $className . '" not found.',
1231267264
);
}
}
protected ProxyProviderInterface $reverseProxyProvider;

/**
* set the hostnames of the reverse proxies
* set from the AbstractCacheBackend when the object is instantiated.
*
* @param string $endpoints
*/
public function setReverseProxyEndpoints($endpoints = null)
public function setReverseProxyProvider(ProxyProviderInterface $reverseProxyProvider)
{
// assume it the reverse proxy is on the same host
if (empty($endpoints)) {
$endpoints = GeneralUtility::getIndpEnv('HTTP_HOST');
}
$endpoints = GeneralUtility::trimExplode(',', $endpoints);
$this->reverseProxyProvider->setProxyEndpoints($endpoints);
$this->reverseProxyProvider = $reverseProxyProvider;
}

/**
Expand Down Expand Up @@ -95,11 +62,13 @@ public function remove($entryIdentifier)
*/
public function flush()
{
$urls = $this->getAllCachedUrls();
parent::flush();

// make the HTTP Purge call
$this->reverseProxyProvider->flushAllUrls($urls);
if ($this->reverseProxyProvider->isActive()) {
$urls = $this->getAllCachedUrls();
$this->reverseProxyProvider->flushAllUrls($urls);
}
}

/**
Expand All @@ -109,11 +78,13 @@ public function flush()
*/
public function flushByTag($tag)
{
$identifiers = $this->findIdentifiersByTag($tag);
foreach ($identifiers as $entryIdentifier) {
$url = $this->get($entryIdentifier);
if ($url) {
$this->reverseProxyProvider->flushCacheForUrl($url);
if ($this->reverseProxyProvider->isActive()) {
$identifiers = $this->findIdentifiersByTag($tag);
foreach ($identifiers as $entryIdentifier) {
$url = $this->get($entryIdentifier);
if ($url) {
$this->reverseProxyProvider->flushCacheForUrls([$url]);
}
}
}

Expand All @@ -127,32 +98,34 @@ public function flushByTag($tag)
*/
public function flushByTags(array $tags)
{
$identifiers = [];
foreach ($tags as $tag) {
$identifiers = array_merge($identifiers, $this->findIdentifiersByTag($tag));
}
$identifiers = array_unique($identifiers);
if ($this->reverseProxyProvider->isActive()) {
$identifiers = [];
foreach ($tags as $tag) {
$identifiers = array_merge($identifiers, $this->findIdentifiersByTag($tag));
}
$identifiers = array_unique($identifiers);

$urls = [];
foreach ($identifiers as $entryIdentifier) {
$urls[] = $this->get($entryIdentifier);
}
$urls = array_unique($urls);
$urls = [];
foreach ($identifiers as $entryIdentifier) {
$urls[] = $this->get($entryIdentifier);
}
$urls = array_unique($urls);

$this->reverseProxyProvider->flushCacheForUrls($urls);
$this->reverseProxyProvider->flushCacheForUrls($urls);
}

parent::flushByTags($tags);
}

/**
* Fetch all URLs in the cache.
*/
public function getAllCachedUrls()
protected function getAllCachedUrls(): array
{
$urls = [];
$conn = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->cacheTable);
$stmt = $conn->select(['content'], $this->cacheTable);
while ($url = $stmt->fetchOne(0)) {
while ($url = $stmt->fetchOne()) {
$urls[] = $url;
}
return $urls;
Expand Down
81 changes: 11 additions & 70 deletions Classes/Controller/CacheController.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

declare(strict_types=1);

namespace B13\Proxycachemanager\Controller;

/*
Expand All @@ -17,92 +18,32 @@
*/

use B13\Proxycachemanager\Provider\ProxyProviderInterface;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Toolbar\ClearCacheActionsHookInterface;
use B13\Proxycachemanager\ProxyConfiguration;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
* Class to handle flushing all caches
*/
class CacheController implements ClearCacheActionsHookInterface
class CacheController
{
protected ProxyProviderInterface $proxyProvider;

/**
* Modifies CacheMenuItems array and adds a "flush CDN caches"
*
* @param array $cacheActions Array of CacheMenuItems
* @param array $optionValues Array of AccessConfigurations-identifiers (typically used by userTS with options.clearCache.identifier)
*/
public function manipulateCacheActions(&$cacheActions, &$optionValues)
{
if ($this->shouldShowCacheFlushButton()) {
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$optionValues[] = 'clearProxyCache';
$item = [
'id' => 'clearProxyCache',
'title' => 'LLL:EXT:proxycachemanager/Resources/Private/Language/locallang.xlf:menuitem.title',
'description' => 'LLL:EXT:proxycachemanager/Resources/Private/Language/locallang.xlf:menuitem.description',
'href' => $uriBuilder->buildUriFromRoute('ajax_proxy_flushcaches'),
'iconIdentifier' => 'actions-system-cache-clear-impact-medium',
];
// Move "our" item on second place
$firstItem = array_shift($cacheActions);
array_unshift($cacheActions, $item);
array_unshift($cacheActions, $firstItem);
}
}

public function shouldShowCacheFlushButton()
public function __construct(protected FrontendInterface $cache, protected ProxyConfiguration $configuration)
{
$providerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_proxy']['options']['reverseProxyProvider'] ?? null;
if (empty($providerClassName)) {
return false;
}
$userTsConfig = $GLOBALS['BE_USER']->getTSConfig();
$isAdmin = $GLOBALS['BE_USER']->isAdmin();
// Clearing of proxy caches is only shown if explicitly enabled via TSConfig
// or if BE-User is admin and the TSconfig explicitly disables the possibility for admins.
// This is useful for big production systems where admins accidentally could slow down the system.
if (($userTsConfig['options.']['clearCache.']['proxy'] ?? false)
|| ($isAdmin && (bool)($userTsConfig['options.']['clearCache.']['proxy'] ?? true))) {
return true;
}
return false;
$this->proxyProvider = $configuration->getProxyProvider();
}

/**
* AJAX endpoint when triggering the call from the cache menu
* @return Response
*/
public function flushAction()
public function flushAction(): ResponseInterface
{
$providerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['tx_proxy']['options']['reverseProxyProvider'] ?? null;
if ($providerClassName) {
/** @var ProxyProviderInterface $cacheProvider */
$proxyProvider = GeneralUtility::makeInstance($providerClassName);
$proxyProvider->flushAllUrls();
$content = [
'success' => true,
'message' => $this->getLanguageService()->sL('LLL:EXT:proxycachemanager/Resources/Private/Language/locallang.xlf:purge.success'),
];
} else {
$content = [
'status' => true,
'message' => $this->getLanguageService()->sL('LLL:EXT:proxycachemanager/Resources/Private/Language/locallang.xlf:purge.failure'),
];
if ($this->proxyProvider->isActive() && $this->configuration->backendFlushEnabled()) {
$this->cache->flush();
}
// we cannot add our own message unfortunately
$response = new Response();
//$response->getBody()->write(json_encode($content));
return $response;
}

/**
* @return \TYPO3\CMS\Core\Localization\LanguageService
*/
protected function getLanguageService()
{
return $GLOBALS['LANG'];
}
}
Loading

0 comments on commit 5e5036e

Please sign in to comment.