Skip to content

Commit

Permalink
[FEATURE] Add SiteProcessor
Browse files Browse the repository at this point in the history
The SiteProcessor can be used to retrieve all properties of the site entity.
This is especially useful if the site configuration is extended with custom
configurations.

Resolves: #87748
Releases: master, 9.5
Change-Id: I650bc9745ca3f0236072aeab9f186b1ea24313e7
Reviewed-on: https://review.typo3.org/c/59824
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
  • Loading branch information
georgringer authored and bmack committed Mar 1, 2019
1 parent db9975f commit 61a59f8
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.. include:: ../../Includes.txt

===================================
Feature: #87748 - Add SiteProcessor
===================================

See :issue:`87748`

Description
===========

A new Site Processor has been introduced which can be used to fetch data from the site entity

.. code-block:: typoscript
tt_content.mycontent.20 = FLUIDTEMPLATE
tt_content.mycontent.20 {
file = EXT:myextension/Resources/Private/Templates/ContentObjects/MyContent.html
dataProcessing.10 = TYPO3\CMS\Frontend\DataProcessing\SiteProcessor
dataProcessing.10 {
as = site
}
}
In the Fluid template the properties of the site entity can be accessed

.. code-block:: html

<p>{site.rootPageId}</p>
<p>{site.someCustomConfiguration}</p>

.. index:: Fluid, Frontend, ext:frontend
85 changes: 85 additions & 0 deletions typo3/sysext/frontend/Classes/DataProcessing/SiteProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Frontend\DataProcessing;

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Routing\SiteMatcher;
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;

/**
* Fetch the site object containing all information about the current site
*
* Example TypoScript configuration:
*
* 10 = TYPO3\CMS\Frontend\DataProcessing\SiteProcessor
* 10 {
* as = site
* }
*
* where "as" names the variable containing the site object
*/
class SiteProcessor implements DataProcessorInterface
{

/**
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processorConfiguration The configuration of this processor
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
*/
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData): array
{
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'site');
$processedData[$targetVariableName] = $this->getCurrentSite();
return $processedData;
}

/**
* Returns the currently configured "site" if a site is configured (= resolved) in the current request.
*
* @return SiteInterface|null
*/
protected function getCurrentSite(): ?SiteInterface
{
try {
return $this->getMatcher()->matchByPageId($this->getCurrentPageId());
} catch (SiteNotFoundException $e) {
// Do nothing
}

return null;
}

/**
* @return SiteMatcher
*/
protected function getMatcher(): SiteMatcher
{
return GeneralUtility::makeInstance(SiteMatcher::class);
}

/**
* @return int
*/
protected function getCurrentPageId(): int
{
return (int)$GLOBALS['TSFE']->id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
declare(strict_types = 1);

namespace TYPO3\CMS\Frontend\Tests\Unit\DataProcessing;

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Routing\SiteMatcher;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\DataProcessing\SiteProcessor;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

/**
* Testcase
*/
class SiteProcessorTest extends UnitTestCase
{

/**
* @test
*/
public function siteIsRetrieved(): void
{
$processorConfiguration = ['as' => 'variable'];
$mockedContentObjectRenderer = $this->getAccessibleMock(ContentObjectRenderer::class, ['stdWrapValue'], [], '', false);
$mockedContentObjectRenderer->expects($this->any())->method('stdWrapValue')->with('as', $processorConfiguration, 'site')->willReturn('variable');

$site = new Site('site123', 123, []);

$subject = $this->getAccessibleMock(SiteProcessor::class, ['getCurrentSite'], []);
$subject->expects($this->any())->method('getCurrentSite')->willReturn($site);

$processedData = $subject->process($mockedContentObjectRenderer, [], $processorConfiguration, []);

$this->assertEquals($site, $processedData['variable']);
}

/**
* @test
*/
public function nullIsProvidedIfSiteCouldNotBeRetrieved(): void
{
$processorConfiguration = ['as' => 'variable'];
$mockedContentObjectRenderer = $this->getAccessibleMock(ContentObjectRenderer::class, ['stdWrapValue'], [], '', false);
$mockedContentObjectRenderer->expects($this->any())->method('stdWrapValue')->with('as', $processorConfiguration, 'site')->willReturn('variable');

$matcherMock = $this->getMockBuilder(SiteMatcher::class)->disableOriginalConstructor()->getMock();
$matcherMock->expects($this->any())->method('matchByPageId')->willThrowException(new SiteNotFoundException('message', 1550670118));

$subject = $this->getAccessibleMock(SiteProcessor::class, ['getMatcher', 'getCurrentPageId'], []);
$subject->expects($this->any())->method('getMatcher')->willReturn($matcherMock);
$subject->expects($this->any())->method('getCurrentPageId')->willReturn(1);

$processedData = $subject->process($mockedContentObjectRenderer, [], $processorConfiguration, []);

$this->assertNull($processedData['variable']);
}
}

0 comments on commit 61a59f8

Please sign in to comment.