Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Support mixing of fluidpages with other backend layouts #367

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
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: 13 additions & 2 deletions Classes/Provider/PageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use FluidTYPO3\Fluidpages\Controller\PageControllerInterface;
use FluidTYPO3\Fluidpages\Service\ConfigurationService;
use FluidTYPO3\Fluidpages\Service\PageService;
use FluidTYPO3\Fluidpages\UserFunction\LayoutSelect;
use FluidTYPO3\Flux\Form;
use FluidTYPO3\Flux\Provider\AbstractProvider;
use FluidTYPO3\Flux\Provider\ProviderInterface;
Expand Down Expand Up @@ -106,6 +107,15 @@ public function injectPageService(PageService $pageService)
$this->pageService = $pageService;
}

/**
* @param LayoutSelect $layoutSelect
* @return void
*/
public function injectLayoutSelect(LayoutSelect $layoutSelect)
{
$this->layoutSelect = $layoutSelect;
}

/**
* @param ConfigurationService $pageConfigurationService
* @return void
Expand Down Expand Up @@ -199,8 +209,9 @@ public function getControllerActionFromRecord(array $row)
*/
public function getControllerActionReferenceFromRecord(array $row)
{
if (true === empty($row[self::FIELD_ACTION_MAIN])) {
$row = $this->pageService->getPageTemplateConfiguration($row['uid']);
$useFluidpages = $this->layoutSelect->isFluidpagesBackendLayout($row['backend_layout']);
if (true === empty($row[self::FIELD_ACTION_MAIN]) || false === $useFluidpages) {
$row = $this->layoutSelect->getPageTemplateConfiguration($row['uid']);
}
return $row[self::FIELD_ACTION_MAIN];
}
Expand Down
58 changes: 4 additions & 54 deletions Classes/Service/PageService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* LICENSE.md file that was distributed with this source code.
*/

use FluidTYPO3\Fluidpages\UserFunction\LayoutSelect;
use FluidTYPO3\Flux\Form;
use FluidTYPO3\Flux\Service\WorkspacesAwareRecordService;
use FluidTYPO3\Flux\Utility\ExtensionNamingUtility;
Expand Down Expand Up @@ -97,63 +98,12 @@ public function injectWorkspacesAwareRecordService(WorkspacesAwareRecordService
* @param integer $pageUid
* @return array|NULL
* @api
* @deprecated
*/
public function getPageTemplateConfiguration($pageUid)
{
$pageUid = (integer) $pageUid;
if (1 > $pageUid) {
return null;
}
$cacheId = 'fluidpages-template-configuration-' . $pageUid;
$runtimeCache = $this->getRuntimeCache();
$fromCache = $runtimeCache->get($cacheId);
if ($fromCache) {
return $fromCache;
}
$fieldList = 'tx_fed_page_controller_action_sub,t3ver_oid,pid,uid';
$page = $this->workspacesAwareRecordService->getSingle(
'pages',
'tx_fed_page_controller_action,' . $fieldList,
$pageUid
);

// Initialize with possibly-empty values and loop root line
// to fill values as they are detected.
$resolvedMainTemplateIdentity = $page['tx_fed_page_controller_action'];
$resolvedSubTemplateIdentity = $page['tx_fed_page_controller_action_sub'];
do {
$containsSubDefinition = (false !== strpos($page['tx_fed_page_controller_action_sub'], '->'));
$isCandidate = ((integer) $page['uid'] !== $pageUid);
if (true === $containsSubDefinition && true === $isCandidate) {
$resolvedSubTemplateIdentity = $page['tx_fed_page_controller_action_sub'];
if (true === empty($resolvedMainTemplateIdentity)) {
// Conditions met: current page is not $pageUid, original page did not
// contain a "this page" layout, current rootline page has "sub" selection.
// Then, set our "this page" value to use the "sub" selection that was detected.
$resolvedMainTemplateIdentity = $resolvedSubTemplateIdentity;
}
break;
}
// Note: 't3ver_oid' is analysed in order to make versioned records inherit the original record's
// configuration as an emulated first parent page.
$resolveParentPageUid = (integer) (0 > $page['pid'] ? $page['t3ver_oid'] : $page['pid']);
$page = $this->workspacesAwareRecordService->getSingle(
'pages',
$fieldList,
$resolveParentPageUid
);
} while (null !== $page);
if (true === empty($resolvedMainTemplateIdentity) && true === empty($resolvedSubTemplateIdentity)) {
// Neither directly configured "this page" nor inherited "sub" contains a valid value;
// no configuration was detected at all.
return null;
}
$configurarion = [
'tx_fed_page_controller_action' => $resolvedMainTemplateIdentity,
'tx_fed_page_controller_action_sub' => $resolvedSubTemplateIdentity
];
$runtimeCache->set($cacheId, $configurarion);
return $configurarion;
$layoutSelect = GeneralUtility::makeInstance(LayoutSelect::class);
return $layoutSelect->getPageTemplateConfiguration($pageUid);
}

/**
Expand Down
182 changes: 182 additions & 0 deletions Classes/UserFunction/LayoutSelect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php
namespace FluidTYPO3\Fluidpages\UserFunction;

use FluidTYPO3\Flux\Service\WorkspacesAwareRecordService;;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Form\FormDataProvider\EvaluateDisplayConditions;
use TYPO3\CMS\Extbase\Object\ObjectManager;

/**
* Decide if fluidpages shall be used to render a page
*/
class LayoutSelect
{
/**
* @var WorkspacesAwareRecordService
*/
protected $workspacesAwareRecordService;

/**
* Decide if the "Page layouts" fields and "Page configuration" flexform
* shall be shown in the page settings.
*
* The first conditionParameters parameter determines if the subpages
* settings are meant or not.
*
* @param array $parameters Parameters with key:
* - record (page db row)
* - flexformValueKey
* - conditionParameters (displayCond config)
* @param EvaluateDisplayConditions $caller Object calling the method
*
* @return boolean True if it shall be shown
*/
public function doShowPageConfiguration($parameters, EvaluateDisplayConditions $caller)
{
$sub = (boolean) $parameters['conditionParameters'][0];

$conf = $this->getPageTemplateConfiguration($parameters['record']['uid']);
if (null === $conf) {
return false;
}

if ($sub) {
return false === empty($conf['tx_fed_page_controller_action_sub']);
} else {
return false === empty($conf['tx_fed_page_controller_action']);
}
}

/**
* Process RootLine to find first usable, configured Fluid Page Template.
* WARNING: do NOT use the output of this feature to overwrite $row - the
* record returned may or may not be the same record as defined in $id.
*
* @param integer $pageUid
* @return array|NULL Array with two keys:
* - tx_fed_page_controller_action
* - tx_fed_page_controller_action_sub
* @api
*/
public function getPageTemplateConfiguration($pageUid)
{
$pageUid = (integer) $pageUid;
if (1 > $pageUid) {
return null;
}
$cacheId = 'fluidpages-template-configuration-' . $pageUid;
$runtimeCache = $this->getRuntimeCache();
$fromCache = $runtimeCache->get($cacheId);
if ($fromCache) {
return $fromCache;
}
$fieldList = 'tx_fed_page_controller_action_sub,backend_layout,backend_layout_next_level,t3ver_oid,pid,uid';
$page = $this->getWorkspacesAwareRecordService()->getSingle(
'pages',
'tx_fed_page_controller_action,' . $fieldList,
$pageUid
);

$checkUsage = true;
$useMainTemplate = $this->isFluidpagesBackendLayout($page['backend_layout']);
$useSubTemplate = $this->isFluidpagesBackendLayout($page['backend_layout_next_level']);
$mainTemplate = $page['tx_fed_page_controller_action'];
$subTemplate = $page['tx_fed_page_controller_action_sub'];
$isFirstPage = true;

do {
if (false === $isFirstPage) {
if ($checkUsage) {
if ($this->isFluidpagesBackendLayout($page['backend_layout_next_level'])) {
$useMainTemplate = true;
$useSubTemplate = true;
} else if (false === empty($page['backend_layout_next_level'])) {
//we have a different layout in between, so do not look further up
$checkUsage = false;
}
}
$containsSubDefinition = (false !== strpos($page['tx_fed_page_controller_action_sub'], '->'));
if ($containsSubDefinition) {
if (empty($mainTemplate)) {
$mainTemplate = $page['tx_fed_page_controller_action_sub'];
}
if (empty($subTemplate)) {
$subTemplate = $page['tx_fed_page_controller_action_sub'];
}
}
}
// Note: 't3ver_oid' is analysed in order to make versioned records inherit the original record's
// configuration as an emulated first parent page.
$resolveParentPageUid = (integer) (0 > $page['pid'] ? $page['t3ver_oid'] : $page['pid']);
$page = $this->getWorkspacesAwareRecordService()->getSingle(
'pages',
$fieldList,
$resolveParentPageUid
);
$isFirstPage = false;
} while ($page);

if (empty($mainTemplate)) {
$useMainTemplate = false;
}
if (empty($subTemplate)) {
$useSubTemplate = false;
}
if (false === $useMainTemplate && false === $useSubTemplate) {
//BC return value
return null;
}
$configuration = [
'tx_fed_page_controller_action' => $useMainTemplate ? $mainTemplate : null,
'tx_fed_page_controller_action_sub' => $useSubTemplate ? $subTemplate : null
];
$runtimeCache->set($cacheId, $configuration);
return $configuration;
}

/**
* Determine if the given backend layout string is a fluidpages layout
*
* @param string $belayout Page row backend_layout value
*
* @return boolean True if fluidpages should be used to render
*/
public function isFluidpagesBackendLayout($belayout)
{
return substr($belayout, 0, 12) == 'fluidpages__';
}

/**
* @return \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend
*/
protected function getRuntimeCache()
{
return GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
}

/**
* @return WorkspacesAwareRecordService
*/
protected function getWorkspacesAwareRecordService()
{
if (null === $this->workspacesAwareRecordService) {
$this->workspacesAwareRecordService = GeneralUtility::makeInstance(ObjectManager::class)
->get(WorkspacesAwareRecordService::class);
}
return $this->workspacesAwareRecordService;
}

/**
* Used in unit tests.
*
* @param WorkspacesAwareRecordService $workspacesAwareRecordService
*
* @return void
*/
public function setWorkspacesAwareRecordService(WorkspacesAwareRecordService $workspacesAwareRecordService)
{
$this->workspacesAwareRecordService = $workspacesAwareRecordService;
}
}
?>
12 changes: 8 additions & 4 deletions Configuration/TCA/Overrides/pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
'disabled' => false
]
]
]
],
'displayCond' => 'USER:FluidTYPO3\\Fluidpages\\UserFunction\\LayoutSelect->doShowPageConfiguration:0',
],
'tx_fed_page_controller_action_sub' => [
'exclude' => 1,
Expand All @@ -32,7 +33,8 @@
'disabled' => false
]
]
]
],
'displayCond' => 'USER:FluidTYPO3\\Fluidpages\\UserFunction\\LayoutSelect->doShowPageConfiguration:1',
],
'tx_fed_page_flexform' => [
'exclude' => 1,
Expand All @@ -42,7 +44,8 @@
'ds' => [
'default' => '<T3DataStructure><ROOT><el></el></ROOT></T3DataStructure>'
]
]
],
'displayCond' => 'USER:FluidTYPO3\\Fluidpages\\UserFunction\\LayoutSelect->doShowPageConfiguration:0',
],
'tx_fed_page_flexform_sub' => [
'exclude' => 1,
Expand All @@ -52,7 +55,8 @@
'ds' => [
'default' => '<T3DataStructure><ROOT><el></el></ROOT></T3DataStructure>'
]
]
],
'displayCond' => 'USER:FluidTYPO3\\Fluidpages\\UserFunction\\LayoutSelect->doShowPageConfiguration:1',
],
]);

Expand Down
Loading