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
5 changes: 4 additions & 1 deletion Build/Scripts/runTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ getPhpImageVersion() {
8.3)
echo -n "1.13"
;;
8.4)
echo -n "latest" # Ou la version la plus récente disponible sur ghcr.io/typo3/core-testing-php84
;;
esac
}

Expand Down Expand Up @@ -563,7 +566,7 @@ while getopts ":a:b:s:c:d:i:t:p:e:xy:o:nhug" OPT; do
;;
p)
PHP_VERSION=${OPTARG}
if ! [[ ${PHP_VERSION} =~ ^(8.2|8.3)$ ]]; then
if ! [[ ${PHP_VERSION} =~ ^(8.2|8.3|8.4)$ ]]; then
INVALID_OPTIONS+=("${OPTARG}")
fi
;;
Expand Down
27 changes: 22 additions & 5 deletions Classes/Cache/CloudFrontCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\ProcessedFile;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Connection;
Expand Down Expand Up @@ -103,6 +104,9 @@ public function cacheCmd(array $params, string|null $distributionIds = null): vo
*/
public function enqueue(string $link, string $distributionIds): void
{
if (!$distributionIds) {
return;
}
if ($link === '*') {
$link = '/*';
}
Expand Down Expand Up @@ -259,10 +263,10 @@ public function queueClearCache(int $pageId, bool $recursive = false, string|nul

if (count($languages) > 0) {
if ($this->isMultiLanguageDomains($entry)) {
$this->enqueue($this->buildLink($entry, array('_language' => 0)) . $wildcard, $this->distributionsMapping[(string)$languages[0]->getBase()->getHost()]);
foreach ($languages as $k => $lang) {
if ($lang->getLanguageId() != 0) {
$this->enqueue($this->buildLink($entry, array('_language' => $lang->getLanguageId())) . $wildcard, $this->distributionsMapping[$lang->getBase()->getHost()]);
$this->enqueue($this->buildLink($entry, array('_language' => 0)) . $wildcard, $this->distributionsMapping[$this->getLanguageHost($languages[0])]);
foreach ($languages as $k => $language) {
if ($language->getLanguageId() != 0) {
$this->enqueue($this->buildLink($entry, array('_language' => $language->getLanguageId())) . $wildcard, $this->distributionsMapping[$this->getLanguageHost($language)]);
}
}
} else {
Expand Down Expand Up @@ -320,12 +324,25 @@ public function getLanguagesDomains(int $uid_page): array
{
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($uid_page);
$domains = [];
// Récupération de l'hôte actuel via la requête si disponible
foreach ($site->getAllLanguages() as $language) {
$domains[$language->getLanguageId()] = $language->getBase()->getHost();
$domains[$language->getLanguageId()] = $this->getLanguageHost($language);
}
return $domains;
}

public function getLanguageHost(SiteLanguage $language): string {
if ($host = $language->getBase()->getHost()) {
return $host;
}
$currentRequest = $GLOBALS['TYPO3_REQUEST'] ?? null;
if ($currentRequest
&& $currentRequest instanceof \Psr\Http\Message\ServerRequestInterface) {
return $currentRequest->getUri()->getHost();
}
return '';
}

/**
* Check if the page has multiple languages with different domains.
*
Expand Down
4 changes: 2 additions & 2 deletions Classes/Hooks/ClearCachePostProc.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function clearCachePostProc(&$params, &$pObj): void
}

// Do nothing if the page is a sysfolder
/* if ( (!empty($params['uid_page']) && MathUtility::canBeInterpretedAsInteger($params['uid_page']))
/* if ( (!empty($params['uid_page']) && MathUtility::canBeInterpretedAsInteger($params['uid_page']))
|| (isset($params['cacheCmd']) && MathUtility::canBeInterpretedAsInteger($params['cacheCmd'])) ) {
$uid_page = (int)$params['uid_page'] ?: (int)$params['cacheCmd'];
$pageRecord = BackendUtility::getRecord('pages', $uid_page, 'doktype');
Expand Down Expand Up @@ -197,7 +197,7 @@ protected function getDistributionIds(int $uid_page, array $params): string

$sysLanguageUid = $row['sys_language_uid'] ?? 0;
$language = $site->getLanguageById($sysLanguageUid);
$domain = $language->getBase()->getHost();
$domain = $this->cacheManager->getLanguageHost($language);
}

$distributionIds = $this->distributionsMapping[$domain] ?? implode(',', array_values($this->distributionsMapping));
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This extension clears the AWS CloudFront cache based on the speaking path of a p

### Using Composer

1. **Require the extension via Composer**
1. **Require the extension via Composer**
In your TYPO3 project root, run:
```
composer require toumoro/tm-cloudfront
Expand All @@ -24,10 +24,11 @@ This extension clears the AWS CloudFront cache based on the speaking path of a p
'apisecret' => 'YOUR_AWS_SECRET',
'region' => 'us-east-1',
'version' => 'latest',
'distributionIds' => '{"domain1.com":"DIST_ID_1", "domain2.com":"DIST_ID_2", "cdn.domain3.com":"DIST_ID_3", "domain4.com":"DIST_ID_4, DIST_ID_5"}'
'distributionIds' => '{"domain1.com":"DIST_ID_1", "domain2.com":"DIST_ID_2", "cdn.domain3.com":"DIST_ID_3", "domain4.com":"DIST_ID_4, DIST_ID_5", "domain5.com":""}'
]
]
```
NB: to disable cache invalidation for a specific domain, set the distribution ID to an empty string. See domain5.com in the example above.

2. **Storage/CDN Mapping**

Expand All @@ -52,5 +53,5 @@ This extension clears the AWS CloudFront cache based on the speaking path of a p

```
composer install
RUNTESTS_DIR_BIN=.Build/bin/ ./Build/Scripts/runTests.sh -p 8.2 -s functional
RUNTESTS_DIR_BIN=.Build/bin/ ./Build/Scripts/runTests.sh -p 8.4 -s functional
```
2 changes: 2 additions & 0 deletions Tests/Functional/DataSet/translated_subpages.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
,6,3,"Sub Subpage Dansk",1,5,"/sub/subd","clearCache_disable =",1
,7,1,"Sys folder - English",0,0,"/sysfolder","clearCache_disable =",254
,8,1,"Sys folder - Dansk",1,7,"/sysfolderd","clearCache_disable =",254
,9,3,"Sub Subpage Español",2,5,"/sub/subes","clearCache_disable =",1
,10,1,"Subpage - Español",2,3,"/subtest","clearCache_disable =",1
16 changes: 11 additions & 5 deletions Tests/Functional/Fixtures/contentPageTests.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
simple:
pages:
- uid: 5
modification:
modification:
title: 'Testing 1'
expectedArray:
- pathsegment: '/en/sub*'
distributionId: 'WWWWWWWWW'
- pathsegment: '/dk/subtest*'
distributionId: 'WWWWWWWWW'
- pathsegment: '/es/subtest*'
distributionId: 'WWWWWWWWW'
- uid: 7
modification:
modification:
title: 'Renaming sysfolder'
tt_content:
- uid: 1
Expand All @@ -20,19 +22,23 @@ simple:
distributionId: 'WWWWWWWWW'
- pathsegment: '/dk/sub/subd'
distributionId: 'WWWWWWWWW'
- pathsegment: '/es/sub/subes'
distributionId: 'WWWWWWWWW'
- uid: 3
modification:
header: 'SysFolder Content modified'
multiDomain:
multiDomain:
pages:
- uid: 5
modification:
modification:
title: 'Multi-domain Test'
expectedArray:
- pathsegment: '/sub*'
distributionId: 'ENENENENENEN'
- pathsegment: '/subtest*'
distributionId: 'DKDKDKDKDKDK'
- pathsegment: '/'
distributionId: ''
tt_content:
- uid: 2
modification:
Expand All @@ -41,4 +47,4 @@ multiDomain:
- pathsegment: '/sub/sub'
distributionId: 'ENENENENENEN'
- pathsegment: '/sub/subd'
distributionId: 'DKDKDKDKDKDK'
distributionId: 'DKDKDKDKDKDK'
22 changes: 21 additions & 1 deletion Tests/Functional/Fixtures/languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ simple:
flag: 'dk'
fallbackType: 'fallback'
fallbacks: 0
2:
title: 'Español'
enabled: true
languageId: 2
base: '/es/'
typo3Language: 'es'
locale: 'es_ES.UTF-8'
iso-639-1: 'es'
flag: 'es'
fallbackType: 'fallback'
fallbacks: 0
multiDomain:
0:
title: 'English'
Expand All @@ -40,4 +51,13 @@ multiDomain:
typo3Language: 'dk'
locale: 'da_DK.UTF-8'
iso-639-1: 'da'
flag: 'dk'
flag: 'dk'
2:
title: 'Español'
enabled: true
languageId: 2
base: 'https://es.example.com/'
typo3Language: 'es'
locale: 'es_ES.UTF-8'
iso-639-1: 'es'
flag: 'es'
32 changes: 28 additions & 4 deletions Tests/Functional/Hooks/ClearCachePostProcTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ClearCachePostProcTest extends FunctionalTestCase
* | 5 | 3 | Testing 1 | 0 | 0 | /sub/sub |
* | 6 | 3 | Sub Subpage | 1 | 5 | /sub/sub |
* +-----+-----+-------------------+------------------+-------------+----------+
*
*
* tt_content table structure
* +-----+-----+-------------------+------------------+-------------+----------+
* | uid | pid | header | sys_language_uid | l18n_parent | colPos |
Expand All @@ -82,7 +82,7 @@ protected function setUp(): void
$this->setUpFrontendSite(1);

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['tm_cloudfront']['cloudfront'] = [
'distributionIds' => '{"www.example.com":"WWWWWWWWW","en.example.com":"ENENENENENEN","cdn.example.com":"CDNCDNCDNCDN","dk.example.com":"DKDKDKDKDKDK"}',
'distributionIds' => '{"www.example.com":"WWWWWWWWW","en.example.com":"ENENENENENEN","cdn.example.com":"CDNCDNCDNCDN","dk.example.com":"DKDKDKDKDKDK", "es.example.com":""}',
'mode' => 'table',
'region' => 'us',
'apikey' => 'AAAAAAAAAAAAAAA',
Expand Down Expand Up @@ -186,7 +186,17 @@ public function modifyMultiTest(): void
foreach ($allRecords as $record) {
var_dump($record['pathsegment'] . ' / ' . $record['distributionId']);
}
$this->assertCount(count($row['expectedArray'] ?? []), $allRecords, 'Nombre d’invalidation incorrect');
// Filtrage des éléments ayant un distributionId non vide
$expectedWithDistribution = array_filter(
$row['expectedArray'] ?? [],
fn(array $item) => !empty($item['distributionId'])
);

$this->assertCount(
count($expectedWithDistribution),
$allRecords,
'Nombre d’invalidation incorrect (excluant les domaines sans CloudFront)'
);

if (isset($row['expectedArray'])) {
foreach ($row['expectedArray'] as $expectedRow) {
Expand Down Expand Up @@ -446,8 +456,22 @@ protected function checkInvalidation(array $expectedRow): void
)
);
$row = $queryBuilder->executeQuery()->fetchAssociative();
if ($expectedRow['distributionId']) {
var_dump('Checking invalidation ' . $expectedRow['pathsegment'] . ' / ' . ($expectedRow['distributionId'] ?: "(vide)"));
$this->assertNotFalse(
$expectedRow['distributionId']
? $row
: $row === false,
'Aucune invalidation trouvée pour ' . $expectedRow['pathsegment'] . ' / ' . $expectedRow['distributionId']);
}
else {
var_dump('Checking no invalidation for ' . $expectedRow['pathsegment'] . ' / ' . ($expectedRow['distributionId'] ?: "(vide)"));
$this->assertFalse(
$row,
'Invalidation existante pour ' . $expectedRow['pathsegment'] . ' alors que distributionId vide'
);
}

$this->assertNotFalse($row, 'Aucune invalidation trouvée pour ' . $expectedRow['pathsegment'] . ' / ' . $expectedRow['distributionId']);
}

/**
Expand Down