Commit d401023d authored by Fabio Stegmeyer's avatar Fabio Stegmeyer

[BUGFIX] Fix flag saving and retrieval caused by cache in visibilityFlagRepo

[BUGFIX] Fix on-copy/move behaviour
parent 19ddbba7
......@@ -30,10 +30,8 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\Languagevisibility\Element\ElementFactory;
use TYPO3\Languagevisibility\Manager\CacheManager;
use TYPO3\Languagevisibility\Repository\VisibilityFlagRepository;
use TYPO3\Languagevisibility\Service\BackendServices;
......@@ -59,66 +57,69 @@ class TceMainHook {
$command, $table, $identity, $value, $dataHandler, $pasteUpdate, $pasteDatamap
) {
if ($command === 'copy' && $table === 'pages') {
$originalPageId = (int) $identity;
if ($originalPageId <= 0) {
return;
}
if (!isset($dataHandler->copyMappingArray['pages'])) {
return;
}
$newPageId = (int) $dataHandler->copyMappingArray['pages'][$originalPageId];
if ($newPageId <= 0) {
return;
}
$this->copyLanguageVisibilityFlagsFromParentPage($newPageId);
} elseif ($command === 'move') {
$this->copyLanguageVisibilityFlagsFromParentPage($identity);
}
if ($table === 'pages') {
if ($command === 'copy') {
$originalPageId = (int) $identity;
if ($originalPageId <= 0) {
return;
}
if ($command === 'copy' && $table !== 'pages' && in_array(
$table, VisibilityService::getSupportedTables(), TRUE
)) {
if (!isset($dataHandler->copyMappingArray['pages'])) {
return;
}
$oldId = $identity;
$newId = $dataHandler->copyMappingArray[$table][$identity];
$newPageId = (int) $dataHandler->copyMappingArray['pages'][$originalPageId];
if ($newPageId <= 0) {
return;
}
$visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
$this->copyLanguageVisibilityFlagsFromParentPage($newPageId);
} elseif ($command === 'move') {
$this->copyLanguageVisibilityFlagsFromParentPage($identity);
}
} else {
if ($command === 'copy' && in_array(
$table, VisibilityService::getSupportedTables(), TRUE
)) {
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
$oldId = $identity;
$newId = $dataHandler->copyMappingArray[$table][$identity];
$originalPageId = (int) $identity;
if ($originalPageId <= 0) {
return;
}
// get the pid of the new record
$newRecord = BackendUtility::getRecord($table, $newId);
if ($newRecord !== NULL) {
$newPid = $newRecord['pid'];
} else {
return;
}
$newPageId = (int) $dataHandler->copyMappingArray['pages'][$originalPageId];
$visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
$visibilityFlagRepository->flushFlagCache();
try {
$site = $siteFinder->getSiteByPageId($newPageId);
} catch (\Exception $e) {
return FALSE;
}
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
$availableLanguages = $site->getAllLanguages();
try {
$site = $siteFinder->getSiteByPageId($newPid);
} catch (\Exception $e) {
return;
}
$visibilityFlags = [];
$availableLanguages = $site->getAllLanguages();
$visibilityFlags = [];
foreach ($availableLanguages as $language) {
$lid = $language->getLanguageId();
foreach ($availableLanguages as $language) {
$lid = $language->getLanguageId();
$visibilityFlag = $visibilityFlagRepository->getVisibilityFlag($table, $oldId, $lid);
$visibilityFlag = $visibilityFlagRepository->getVisibilityFlag($table, $oldId, $lid);
if ($visibilityFlag !== FALSE && $visibilityFlag !== NULL) {
$visibilityFlags[$lid] = $visibilityFlag['flag'];
if ($visibilityFlag !== FALSE && $visibilityFlag !== NULL) {
$visibilityFlags[$lid] = $visibilityFlag['flag'];
}
}
}
foreach ($visibilityFlags as $lid => $flag) {
$visibilityFlagRepository->setVisibilityFlag($flag, $table, $newId, $lid);
foreach ($visibilityFlags as $lid => $flag) {
$visibilityFlagRepository->setVisibilityFlag($flag, $table, $newId, $lid);
}
}
}
}
......@@ -147,8 +148,8 @@ class TceMainHook {
if ($table === 'pages') {
$pid = $uid;
}else{
$pid = $destPid;
} else {
$pid = $resolvedPid;
}
try {
......@@ -163,6 +164,7 @@ class TceMainHook {
$lid = $language->getLanguageId();
$visibilityFlagRepository->flushFlagCache();
$visibilityFlag = $visibilityFlagRepository->getVisibilityFlag($table, $uid, $lid);
if ($visibilityFlag !== FALSE && $visibilityFlag !== NULL) {
......@@ -198,7 +200,8 @@ class TceMainHook {
$siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
try {
$site = $siteFinder->getSiteByPageId($pageId, []);
$rootline = BackendUtility::BEgetRootLine($pageId);
$site = $siteFinder->getSiteByPageId($pageId, $rootline);
} catch (\Exception $e) {
return;
}
......@@ -208,6 +211,7 @@ class TceMainHook {
// clear the existing/automatically copied flags on the copied/inserted/moved page
$visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
$visibilityFlagRepository->removeFlagsByTableAndPid('pages', $pageId);
$visibilityFlagRepository->flushFlagCache();
if ($availableLanguages && count($availableLanguages) > 0) {
......@@ -347,9 +351,6 @@ class TceMainHook {
// flush all caches
CacheManager::getInstance()->flushAllCaches();
GeneralUtility::makeInstance(VisibilityFlagRepository::class)
->deleteDefaultFlags();
// Flush TYPO3 Caching Framework caches
GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)
->getCache('tx_languagevisibility')
......@@ -402,6 +403,7 @@ class TceMainHook {
$childPageUid = (int) $childPage['uid'];
$visibilityFlagRepository->flushFlagCache();
$existingVisibilityFlag = $visibilityFlagRepository->getVisibilityFlag(
'pages', $childPageUid, $languageId
);
......@@ -561,4 +563,14 @@ class TceMainHook {
}
}
/**
* Removes the default flags after all database operations
*
* @param $dataHandler
*/
public function processCmdmap_afterFinish($dataHandler) {
GeneralUtility::makeInstance(VisibilityFlagRepository::class)
->deleteDefaultFlags();
}
}
......@@ -50,6 +50,7 @@ class VisibilityFlagRepository implements SingletonInterface {
*/
public function setVisibilityFlag($flag, $table, $recordUid, $lUid): void {
$this->flushFlagCache();
$existingVisibilityFlag = $this->getVisibilityFlag($table, $recordUid, $lUid);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
......@@ -149,6 +150,17 @@ class VisibilityFlagRepository implements SingletonInterface {
return $flagEntry;
}
/**
* This option must be used e.g. when flags are saved or edited, since the first call of the getVisibility function
* happens before the new/edited flags are saved to the DB, therefore they are missing/wrong in the cache when the
* function is called later in the same request with the intention to retrieve the existing flags
*
* @return void
*/
public function flushFlagCache(): void{
$this->cachedFlags = NULL;
}
/**
* Removes the flags for given table and pid.
*
......
......@@ -363,6 +363,11 @@ class VisibilityService implements SingletonInterface {
}
}
// this can happen, when a language doesn't have a record
if($this->cachedDefaultVisibilityForElements[$languageUid] === NULL){
$this->cachedDefaultVisibilityForElements[$languageUid] = 'f';
}
return $this->cachedDefaultVisibilityForElements[$languageUid];
}
......@@ -391,6 +396,11 @@ class VisibilityService implements SingletonInterface {
}
}
// this can happen, when a language doesn't have a record
if($this->cachedDefaultVisibilityForElements[$languageUid] === NULL){
$this->cachedDefaultVisibilityForElements[$languageUid] = 'f';
}
return $this->cachedDefaultVisibilityForPages[$languageUid];
}
}
......@@ -155,6 +155,7 @@ class FieldVisibilityUserFunction {
): array {
$this->visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
$this->visibilityFlagRepository->flushFlagCache();
$visibility = GeneralUtility::makeInstance(VisibilityService::class);
$infosStruct = [];
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
......
......@@ -36,6 +36,9 @@ call_user_func(
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['moveRecordClass'][$extKey] =
\TYPO3\Languagevisibility\Hook\TceMainHook::class;
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmap_afterFinish'][$extKey] =
\TYPO3\Languagevisibility\Hook\TceMainHook::class;
// overriding option because this is done by languagevisibility and will not work if set
$GLOBALS['TYPO3_CONF_VARS']['FE']['hidePagesIfNotTranslatedByDefault'] = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment