Commit adc7e5e3 authored by Stefan Busemann's avatar Stefan Busemann

Merge branch 'develop-v10' into 'master'

Working with version 10

See merge request t3o/t3olayout!580
parents 785446e8 7abc0593
......@@ -26,7 +26,7 @@ test:php:
- php-cs-fixer fix --dry-run --config=Build/.php_cs --diff --diff-format=udiff
build:
image: node:9
image: node:12
stage: build
before_script:
- npm config set cache cache/npm/ --global
......
......@@ -59,7 +59,7 @@ FlyOutAjaxLogin.prototype.authenticationRequest = function(event, form) {
FlyOutAjaxLogin.prototype.initMenuBar = function() {
const returnUrl = encodeURIComponent(window.location.href);
FlyOutAjaxLogin.callAjax('/index.php?eID=FlyOutAjaxLoginController&returnUrl=' + returnUrl, function (response) {
FlyOutAjaxLogin.callAjax('/index.php?load=FlyOutAjaxLogin&returnUrl=' + returnUrl, function (response) {
if (response !== null || response !== undefined || response !== '') {
const login = JSON.parse(response);
const container = document.querySelector('._login');
......
This diff is collapsed.
......@@ -4,21 +4,21 @@
"private": true,
"main": "Gulpfile.js",
"dependencies": {
"@fancyapps/fancybox": "^3.2.5",
"@fortawesome/fontawesome-free": "^5.5.0",
"baguettebox.js": "^1.9.1",
"bootstrap": "^4.4.1",
"bootstrap4-notify": "^4.0.3",
"cookieconsent": "^3.1.0",
"datatables.net-bs4": "^1.10.19",
"gravatar": "^1.6.0",
"h5bp-print-styles": "^4.3.2",
"jquery": "^3.4",
"jquery-typeahead": "^2.10.4",
"popper.js": "^1.14.4",
"slick-carousel": "^1.8.1",
"source-sans-pro": "^2.40.0",
"tether": "^1.4.3"
"@fancyapps/fancybox": "3.2.5",
"@fortawesome/fontawesome-free": "5.5.0",
"baguettebox.js": "1.9.1",
"bootstrap": "4.4.1",
"bootstrap4-notify": "4.0.3",
"cookieconsent": "3.1.0",
"datatables.net-bs4": "1.10.19",
"gravatar": "1.6.0",
"h5bp-print-styles": "4.3.2",
"jquery": "3.4.1",
"jquery-typeahead": "2.10.4",
"popper.js": "1.14.4",
"slick-carousel": "1.8.1",
"source-sans-pro": "2.40.0",
"tether": "1.4.3"
},
"devDependencies": {
"babel-core": "^6.26.3",
......@@ -53,9 +53,9 @@
}
},
"scripts": {
"build": "./node_modules/.bin/gulp build",
"build-prod": "./node_modules/.bin/gulp build-prod",
"start": "./node_modules/.bin/gulp default",
"ci": "./node_modules/.bin/gulp ci"
"build": "npx gulp build",
"build-prod": "npx gulp build-prod",
"start": "npx gulp default",
"ci": "npx gulp ci"
}
}
......@@ -2,9 +2,13 @@
namespace T3o\T3olayout\Backend\ViewHelpers;
class ResolveFileReferenceViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
class ResolveFileReferenceViewHelper extends AbstractViewHelper
{
use \TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use CompileWithRenderStatic;
/**
* Initialize arguments
......@@ -22,9 +26,9 @@ class ResolveFileReferenceViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\Ab
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return string
* @throws Exception
* @throws \Exception
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
return \TYPO3\CMS\Backend\Utility\BackendUtility::resolveFileReferences('tt_content', 'assets', $arguments['row']);
}
......
<?php
namespace T3o\T3olayout\Controller;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Web\Response;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Utility\EidUtility;
/**
* Class AjaxFrontendLoginController
*
* @target Frontend
*/
class FlyOutAjaxLoginController
{
public static function processLogin()
{
EidUtility::initTCA();
self::getTypoScriptFrontendController();
$feUser = EidUtility::initFeUser();
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$response = $objectManager->get(Response::class);
$response->setHeader('Content-Type', 'application/json; charset=utf-8');
$configurationManager = $objectManager->get(ConfigurationManager::class);
$typoScriptSetup = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
$contentObjectRenderer = $objectManager->get(ContentObjectRenderer::class);
$loginPid = $contentObjectRenderer->cObjGetSingle(
$typoScriptSetup['lib.']['loginPid'],
$typoScriptSetup['lib.']['loginPid.']
);
$loginFormPid = $contentObjectRenderer->cObjGetSingle(
$typoScriptSetup['lib.']['loginFormPid'],
$typoScriptSetup['lib.']['loginFormPid.']
);
$menuBarTemplate = $objectManager->get(StandaloneView::class);
$menuBarTemplate->setTemplatePathAndFilename('EXT:t3olayout/Resources/Private/Templates/Felogin/MenuBarAjaxLogin.html');
$menuBarTemplate->assign('user', $feUser->user);
$menuBarTemplate->assign('loginPid', $loginPid);
$menuBarTemplate->assign('loginFormPid', $loginFormPid);
echo json_encode(
[
'loginPid' => $loginPid,
'loginFormPid' => $loginFormPid,
'loggedIn' => $feUser->user['ses_userid'] > 0,
'menuBarTemplate' => $menuBarTemplate->render()
]
);
$response->send();
exit;
}
/**
* Initialize the typoscript frontend controller
*
* @param int $pid
*/
private static function getTypoScriptFrontendController($pid = 1)
{
/** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontend */
$frontend = GeneralUtility::makeInstance(
\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class,
null,
$pid,
0
);
$GLOBALS['TSFE'] = $frontend;
$frontend->initFEuser();
$frontend->determineId();
$frontend->initTemplate();
$frontend->getConfigArray();
}
}
<?php
namespace T3o\T3olayout\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\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentDataProcessor;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
/**
* This menu processor utilizes HMENU to generate a json encoded menu
* string that will be decoded again and assigned to FLUIDTEMPLATE as
* variable. Additional DataProcessing is supported and will be applied
* to each record.
*
* Options:
* as - The variable to be used within the result
* levels - Number of levels of the menu
* expandAll = If false, submenus will only render if the parent page is active
* includeSpacer = If true, pagetype spacer will be included in the menu
* titleField = Field that should be used for the title
*
* See HMENU docs for more options.
* https://docs.typo3.org/typo3cms/TyposcriptReference/ContentObjects/Hmenu/Index.html
*
*
* Example TypoScript configuration:
*
* 10 = t3o\t3olayout\DataProcessing\MenuProcessor
* 10 {
* special = list
* special.value.field = pages
* levels = 7
* as = menu
* expandAll = 1
* includeSpacer = 1
* titleField = nav_title // title
* dataProcessing {
* 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
* 10 {
* references.fieldName = media
* }
* }
* }
*/
class MenuProcessor implements DataProcessorInterface
{
const LINK_PLACEHOLDER = '###LINKPLACEHOLDER###';
const TARGET_PLACEHOLDER = '###TARGETPLACEHOLDER###';
/**
* The content object renderer
*
* @var ContentObjectRenderer
*/
public $cObj;
/**
* The processor configuration
*
* @var array
*/
protected $processorConfiguration;
/**
* Allowed configuration keys for menu generation, other keys
* will throw an exception to prevent configuration errors.
*
* @var array
*/
public $allowedConfigurationKeys = [
'cache_period',
'entryLevel',
'entryLevel.',
'special',
'special.',
'minItems',
'minItems.',
'maxItems',
'maxItems.',
'begin',
'begin.',
'excludeUidList',
'excludeUidList.',
'excludeDoktypes',
'includeNotInMenu',
'alwaysActivePIDlist',
'alwaysActivePIDlist.',
'protectLvar',
'addQueryString',
'if',
'if.',
'levels',
'expandAll',
'includeSpacer',
'as',
'titleField',
'dataProcessing',
'dataProcessing.'
];
/**
* Remove keys from configuration that should not be passed
* to HMENU to prevent configuration errors
*
* @var array
*/
public $removeConfigurationKeysForHmenu = [
'levels',
'expandAll',
'includeSpacer',
'as',
'titleField',
'dataProcessing',
'dataProcessing.'
];
/**
* @var array
*/
protected $menuConfig = [
'wrap' => '[|]'
];
/**
* @var array
*/
protected $menuLevelConfig = [
'doNotLinkIt' => '1',
'wrapItemAndSub' => '{|}, |*| {|}, |*| {|}',
'stdWrap.' => [
'cObject' => 'COA',
'cObject.' => [
'10' => 'USER',
'10.' => [
'userFunc' => 't3o\t3olayout\DataProcessing\MenuProcessor->getDataAsJson',
'stdWrap.' => [
'wrap' => '"data":|'
]
],
'20' => 'TEXT',
'20.' => [
'field' => 'nav_title // title',
'trim' => '1',
'wrap' => ',"title":|',
'preUserFunc' => 't3o\t3olayout\DataProcessing\MenuProcessor->jsonEncodeUserFunc'
],
'21' => 'TEXT',
'21.' => [
'value' => self::LINK_PLACEHOLDER,
'wrap' => ',"link":|',
],
'22' => 'TEXT',
'22.' => [
'value' => self::TARGET_PLACEHOLDER,
'wrap' => ',"target":|',
],
'30' => 'TEXT',
'30.' => [
'value' => '0',
'wrap' => ',"active":|'
],
'40' => 'TEXT',
'40.' => [
'value' => '0',
'wrap' => ',"current":|'
],
'50' => 'TEXT',
'50.' => [
'value' => '0',
'wrap' => ',"spacer":|'
]
]
]
];
/**
* @var array
*/
public $menuDefaults = [
'levels' => 1,
'expandAll' => 1,
'includeSpacer' => 0,
'as' => 'menu',
'titleField' => 'nav_title // title'
];
/**
* @var int
*/
protected $menuLevels;
/**
* @var int
*/
protected $menuExpandAll;
/**
* @var int
*/
protected $menuIncludeSpacer;
/**
* @var string
*/
protected $menuTitleField;
/**
* @var string
*/
protected $menuTargetVariableName;
/**
* @var ContentDataProcessor
*/
protected $contentDataProcessor;
/**
* Constructor
*/
public function __construct()
{
$this->contentDataProcessor = GeneralUtility::makeInstance(ContentDataProcessor::class);
}
/**
* Get configuration value from processorConfiguration
*
* @param string $key
* @return string
*/
protected function getConfigurationValue($key)
{
return $this->cObj->stdWrapValue($key, $this->processorConfiguration, $this->menuDefaults[$key]);
}
/**
* Validate configuration
*
* @throws \InvalidArgumentException
*/
public function validateConfiguration()
{
$invalidArguments = [];
foreach ($this->processorConfiguration as $key => $value) {
if (!in_array($key, $this->allowedConfigurationKeys)) {
$invalidArguments[str_replace('.', '', $key)] = $key;
}
}
if (!empty($invalidArguments)) {
throw new \InvalidArgumentException('MenuProcessor Configuration contains invalid Arguments: ' . implode(', ', $invalidArguments), 1478806566);
}
}
/**
* Prepare Configuration
*/
public function prepareConfiguration()
{
$this->menuConfig += $this->processorConfiguration;
// Filter configuration
foreach ($this->menuConfig as $key => $value) {
if (in_array($key, $this->removeConfigurationKeysForHmenu)) {
unset($this->menuConfig[$key]);
}
}
// Process special value
if (isset($this->menuConfig['special.']['value.'])) {
$this->menuConfig['special.']['value'] = $this->cObj->stdWrap($this->menuConfig['special.']['value'], $this->menuConfig['special.']['value.']);
unset($this->menuConfig['special.']['value.']);
}
}
/**
*/
public function prepareLevelConfiguration()
{
$this->menuLevelConfig['stdWrap.']['cObject.'] = array_replace_recursive(
$this->menuLevelConfig['stdWrap.']['cObject.'],
[
'20.' => [
'field' => $this->menuTitleField,
]
]
);
}
/**
*/
public function prepareLevelLanguageConfiguration()
{
if ($this->menuConfig['special'] === 'language') {
$this->menuLevelConfig['stdWrap.']['cObject.'] = array_replace_recursive(
$this->menuLevelConfig['stdWrap.']['cObject.'],
[
'60' => 'TEXT',
'60.' => [
'value' => '1',
'wrap' => ',"available":|'
],
'70' => 'TEXT',
'70.' => [
'value' => $this->menuConfig['special.']['value'],
'listNum.' => [
'stdWrap.' => [
'data' => 'register:count_HMENU_MENUOBJ',
'wrap' => '|-1'
],
'splitChar' => ','
],
'wrap' => ',"languageUid":"|"'
]
]
);
}
}
/**
*/
public function buildConfiguration()
{
for ($i = 1; $i <= $this->menuLevels; $i++) {
$this->menuConfig[$i] = 'TMENU';
$this->menuConfig[$i . '.']['IProcFunc'] = 't3o\t3olayout\DataProcessing\MenuProcessor->replacePlaceholderInRenderedMenuItem';
if ($i > 1) {
$this->menuConfig[$i . '.']['stdWrap.']['wrap'] = ',"children": [|]';
}
$this->menuConfig[$i . '.']['expAll'] = $this->menuExpandAll;
$this->menuConfig[$i . '.']['NO'] = '1';
$this->menuConfig[$i . '.']['NO.'] = $this->menuLevelConfig;
if ($this->menuIncludeSpacer) {
$this->menuConfig[$i . '.']['SPC'] = '1';
$this->menuConfig[$i . '.']['SPC.'] = $this->menuConfig[$i . '.']['NO.'];
$this->menuConfig[$i . '.']['SPC.']['stdWrap.']['cObject.']['50.']['value'] = '1';
}
$this->menuConfig[$i . '.']['IFSUB'] = '1';
$this->menuConfig[$i . '.']['IFSUB.'] = $this->menuConfig[$i . '.']['NO.'];
$this->menuConfig[$i . '.']['ACT'] = '1';
$this->menuConfig[$i . '.']['ACT.'] = $this->menuConfig[$i . '.']['NO.'];
$this->menuConfig[$i . '.']['ACT.']['stdWrap.']['cObject.']['30.']['value'] = '1';
$this->menuConfig[$i . '.']['ACTIFSUB'] = '1';
$this->menuConfig[$i . '.']['ACTIFSUB.'] = $this->menuConfig[$i . '.']['ACT.'];
$this->menuConfig[$i . '.']['CUR'] = '1';
$this->menuConfig[$i . '.']['CUR.'] = $this->menuConfig[$i . '.']['ACT.'];
$this->menuConfig[$i . '.']['CUR.']['stdWrap.']['cObject.']['40.']['value'] = '1';
$this->menuConfig[$i . '.']['CURIFSUB'] = '1';
$this->menuConfig[$i . '.']['CURIFSUB.'] = $this->menuConfig[$i . '.']['CUR.'];
if ($this->menuConfig['special'] === 'language') {
$this->menuConfig[$i . '.']['USERDEF1'] = $this->menuConfig[$i . '.']['NO'];
$this->menuConfig[$i . '.']['USERDEF1.'] = $this->menuConfig[$i . '.']['NO.'];
$this->menuConfig[$i . '.']['USERDEF1.']['stdWrap.']['cObject.']['60.']['value'] = '0';
$this->menuConfig[$i . '.']['USERDEF2'] = $this->menuConfig[$i . '.']['ACT'];
$this->menuConfig[$i . '.']['USERDEF2.'] = $this->menuConfig[$i . '.']['ACT.'];
$this->menuConfig[$i . '.']['USERDEF2.']['stdWrap.']['cObject.']['60.']['value'] = '0';
}
}
}
/**
* @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)
{
$this->cObj = $cObj;
$this->processorConfiguration = $processorConfiguration;
// Get Configuration
$this->menuLevels = (int)$this->getConfigurationValue('levels') ?: 1;
$this->menuExpandAll = (int)$this->getConfigurationValue('expandAll');
$this->menuIncludeSpacer = (int)$this->getConfigurationValue('includeSpacer');
$this->menuTargetVariableName = $this->getConfigurationValue('as');
$this->menuTitleField = $this->getConfigurationValue('titleField');
// Validate Configuration
$this->validateConfiguration();
// Build Configuration
$this->prepareConfiguration();
$this->prepareLevelConfiguration();
$this->prepareLevelLanguageConfiguration();
$this->buildConfiguration();
// Process Configuration
$menuContentObject = $cObj->getContentObject('HMENU');
$renderedMenu = $menuContentObject->render($this->menuConfig);