Initial commit - Typo3 11.5.41
This commit is contained in:
@@ -0,0 +1,649 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
use GeorgRinger\News\Backend\RecordList\NewsDatabaseRecordList;
|
||||
use GeorgRinger\News\Domain\Model\Dto\AdministrationDemand;
|
||||
use GeorgRinger\News\Domain\Repository\AdministrationRepository;
|
||||
use GeorgRinger\News\Domain\Repository\CategoryRepository;
|
||||
use GeorgRinger\News\Domain\Repository\NewsRepository;
|
||||
use GeorgRinger\News\Domain\Repository\TagRepository;
|
||||
use GeorgRinger\News\Event\AdministrationExtendMenuEvent;
|
||||
use GeorgRinger\News\Event\AdministrationIndexActionEvent;
|
||||
use GeorgRinger\News\Event\AdministrationNewsPidListingActionEvent;
|
||||
use GeorgRinger\News\Utility\Page;
|
||||
use TYPO3\CMS\Backend\Clipboard\Clipboard;
|
||||
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
|
||||
use TYPO3\CMS\Backend\Template\Components\Menu\Menu;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as BackendUtilityCore;
|
||||
use TYPO3\CMS\Backend\View\BackendTemplateView;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\HttpUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Administration controller
|
||||
*/
|
||||
class AdministrationController extends NewsController
|
||||
{
|
||||
/** @var int */
|
||||
protected $pageUid = 0;
|
||||
|
||||
/** @var array */
|
||||
protected $tsConfiguration = [];
|
||||
|
||||
/**
|
||||
* @var \GeorgRinger\News\Domain\Repository\AdministrationRepository
|
||||
*/
|
||||
protected $administrationRepository;
|
||||
|
||||
/** @var ConfigurationManagerInterface */
|
||||
protected $configurationManager;
|
||||
|
||||
/** @var array */
|
||||
protected $pageInformation = [];
|
||||
|
||||
/** @var array */
|
||||
protected $allowedNewTables = [];
|
||||
|
||||
/** @var array */
|
||||
protected $deniedNewTables = [];
|
||||
|
||||
public function initializeAction()
|
||||
{
|
||||
$this->pageUid = (int)GeneralUtility::_GET('id');
|
||||
$this->pageInformation = BackendUtilityCore::readPageAccess($this->pageUid, '');
|
||||
$this->setTsConfig();
|
||||
parent::initializeAction();
|
||||
}
|
||||
|
||||
/** @var BackendTemplateView */
|
||||
protected $view;
|
||||
|
||||
/** @var IconFactory */
|
||||
protected $iconFactory;
|
||||
|
||||
/** @var string */
|
||||
protected $defaultViewObjectName = BackendTemplateView::class;
|
||||
|
||||
/**
|
||||
* AdministrationController constructor.
|
||||
* @param NewsRepository $newsRepository
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param TagRepository $tagRepository
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
* @param AdministrationRepository $administrationRepository
|
||||
* @param AdministrationRepository $iconFactory
|
||||
*/
|
||||
public function __construct(
|
||||
NewsRepository $newsRepository,
|
||||
CategoryRepository $categoryRepository,
|
||||
TagRepository $tagRepository,
|
||||
ConfigurationManagerInterface $configurationManager,
|
||||
AdministrationRepository $administrationRepository,
|
||||
IconFactory $iconFactory
|
||||
) {
|
||||
parent::__construct($newsRepository, $categoryRepository, $tagRepository, $configurationManager);
|
||||
$this->administrationRepository = $administrationRepository;
|
||||
$this->iconFactory = $iconFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ViewInterface $view
|
||||
*/
|
||||
protected function initializeView(ViewInterface $view)
|
||||
{
|
||||
parent::initializeView($view);
|
||||
$view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation([]);
|
||||
|
||||
$pageRenderer = $this->view->getModuleTemplate()->getPageRenderer();
|
||||
$pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DateTimePicker');
|
||||
$pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
|
||||
$pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/AjaxDataHandler');
|
||||
$pageRenderer->loadRequireJsModule('TYPO3/CMS/News/AdministrationModule');
|
||||
$pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf');
|
||||
$dateFormat = ($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? ['MM-DD-YYYY', 'HH:mm MM-DD-YYYY'] : ['DD-MM-YYYY', 'HH:mm DD-MM-YYYY']);
|
||||
$pageRenderer->addInlineSetting('DateTimePicker', 'DateFormat', $dateFormat);
|
||||
|
||||
$web_list_modTSconfig = BackendUtilityCore::getPagesTSconfig($this->pageUid)['mod.']['web_list.'] ?? [];
|
||||
$this->allowedNewTables = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$web_list_modTSconfig['allowedNewTables'] ?? '',
|
||||
true
|
||||
);
|
||||
$this->deniedNewTables = GeneralUtility::trimExplode(
|
||||
',',
|
||||
$web_list_modTSconfig['deniedNewTables'] ?? '',
|
||||
true
|
||||
);
|
||||
|
||||
$this->createMenu();
|
||||
$this->createButtons();
|
||||
|
||||
$view->assign('showSupportArea', $this->showSupportArea());
|
||||
}
|
||||
|
||||
protected function createMenu(): void
|
||||
{
|
||||
$uriBuilder = $this->objectManager->get(UriBuilder::class);
|
||||
$uriBuilder->setRequest($this->request);
|
||||
|
||||
$menu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
|
||||
$menu->setIdentifier('news');
|
||||
|
||||
$actions = [
|
||||
['action' => 'index', 'label' => 'newsListing'],
|
||||
['action' => 'newsPidListing', 'label' => 'newsPidListing'],
|
||||
['action' => 'donate', 'label' => 'donate']
|
||||
];
|
||||
foreach ($actions as $action) {
|
||||
$item = $menu->makeMenuItem()
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:module.' . $action['label']))
|
||||
->setHref($uriBuilder->uriFor($action['action'], [], 'Administration', 'News', 'web_NewsAdministration'))
|
||||
->setActive($this->request->getControllerActionName() === $action['action']);
|
||||
$menu->addMenuItem($item);
|
||||
}
|
||||
|
||||
$menu = $this->extendMenu($menu);
|
||||
|
||||
if ($menu instanceof Menu) {
|
||||
$this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
|
||||
}
|
||||
if (is_array($this->pageInformation)) {
|
||||
$this->view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation($this->pageInformation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends menu selector with items from 3rd party extensions.
|
||||
*
|
||||
* @param Menu $menu
|
||||
* @return Menu
|
||||
*/
|
||||
protected function extendMenu(Menu $menu): Menu
|
||||
{
|
||||
$event = $this->eventDispatcher->dispatch(new AdministrationExtendMenuEvent($this, $menu));
|
||||
|
||||
return $event->getMenu();
|
||||
}
|
||||
|
||||
protected function createButtons(): void
|
||||
{
|
||||
$buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
|
||||
|
||||
$uriBuilder = $this->objectManager->get(UriBuilder::class);
|
||||
$uriBuilder->setRequest($this->request);
|
||||
|
||||
if ($this->request->getControllerActionName() === 'index' && $this->isFilteringEnabled()) {
|
||||
$toggleButton = $buttonBar->makeLinkButton()
|
||||
->setHref('#')
|
||||
->setDataAttributes([
|
||||
'togglelink' => '1',
|
||||
'toggle' => 'tooltip',
|
||||
'placement' => 'bottom',
|
||||
])
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:administration.toggleForm'))
|
||||
->setIcon($this->iconFactory->getIcon('actions-filter', Icon::SIZE_SMALL));
|
||||
$buttonBar->addButton($toggleButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
|
||||
}
|
||||
|
||||
$buttons = [
|
||||
[
|
||||
'table' => 'tx_news_domain_model_news',
|
||||
'label' => 'module.createNewNewsRecord',
|
||||
'action' => 'newNews',
|
||||
'icon' => 'ext-news-type-default'
|
||||
],
|
||||
[
|
||||
'table' => 'tx_news_domain_model_tag',
|
||||
'label' => 'module.createNewTag',
|
||||
'action' => 'newTag',
|
||||
'icon' => 'ext-news-tag'
|
||||
],
|
||||
[
|
||||
'table' => 'sys_category',
|
||||
'label' => 'module.createNewCategory',
|
||||
'action' => 'newCategory',
|
||||
'icon' => 'mimetypes-x-sys_category'
|
||||
]
|
||||
];
|
||||
foreach ($buttons as $key => $tableConfiguration) {
|
||||
if ($this->showButton($tableConfiguration['table'])) {
|
||||
$title = $this->getLanguageService()->sL('LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:' . $tableConfiguration['label']);
|
||||
$viewButton = $buttonBar->makeLinkButton()
|
||||
->setHref($uriBuilder->reset()->setRequest($this->request)->uriFor(
|
||||
$tableConfiguration['action'],
|
||||
[],
|
||||
'Administration'
|
||||
))
|
||||
->setDataAttributes([
|
||||
'toggle' => 'tooltip',
|
||||
'placement' => 'bottom',
|
||||
'title' => $title])
|
||||
->setTitle($title)
|
||||
->setIcon($this->iconFactory->getIcon($tableConfiguration['icon'], Icon::SIZE_SMALL, 'overlay-new'));
|
||||
$buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 2);
|
||||
}
|
||||
}
|
||||
|
||||
$clipBoard = GeneralUtility::makeInstance(Clipboard::class);
|
||||
$clipBoard->initializeClipboard();
|
||||
$elFromTable = $clipBoard->elFromTable('tx_news_domain_model_news');
|
||||
if (!empty($elFromTable)) {
|
||||
$viewButton = $buttonBar->makeLinkButton()
|
||||
->setHref($clipBoard->pasteUrl('', $this->pageUid))
|
||||
->setOnClick('return ' . $clipBoard->confirmMsgText(
|
||||
'pages',
|
||||
BackendUtilityCore::getRecord('pages', $this->pageUid),
|
||||
'into',
|
||||
$elFromTable
|
||||
))
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:clip_pasteInto'))
|
||||
->setIcon($this->iconFactory->getIcon('actions-document-paste-into', Icon::SIZE_SMALL));
|
||||
$buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 4);
|
||||
}
|
||||
|
||||
// Donation
|
||||
$donationButton = $buttonBar->makeLinkButton()
|
||||
->setHref($uriBuilder->reset()->setRequest($this->request)->uriFor(
|
||||
'donate',
|
||||
[],
|
||||
'Administration'
|
||||
))
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:administration.donation.title'))
|
||||
->setIcon($this->iconFactory->getIcon('ext-news-donation', Icon::SIZE_SMALL));
|
||||
$buttonBar->addButton($donationButton, ButtonBar::BUTTON_POSITION_RIGHT);
|
||||
|
||||
// Refresh
|
||||
$refreshButton = $buttonBar->makeLinkButton()
|
||||
->setHref(GeneralUtility::getIndpEnv('REQUEST_URI'))
|
||||
->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.reload'))
|
||||
->setIcon($this->iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
|
||||
$buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);
|
||||
|
||||
// Shortcut
|
||||
if ($this->getBackendUser()->mayMakeShortcut()) {
|
||||
$shortcutButton = $buttonBar->makeShortcutButton()
|
||||
->setGetVariables(['route', 'module', 'id'])
|
||||
->setModuleName($this->request->getPluginName())
|
||||
->setDisplayName('Shortcut');
|
||||
$buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
protected function showButton(string $table): bool
|
||||
{
|
||||
if (!$this->getBackendUser()->check('tables_modify', $table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No deny/allow tables are set:
|
||||
if (empty($this->allowedNewTables) && empty($this->deniedNewTables)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$showButton = !in_array($table, $this->deniedNewTables, true) &&
|
||||
(empty($this->allowedNewTables) || in_array($table, $this->allowedNewTables, true));
|
||||
|
||||
return $showButton;
|
||||
}
|
||||
|
||||
public function indexAction(): void
|
||||
{
|
||||
$this->redirectToPageOnStart();
|
||||
|
||||
$demandVars = GeneralUtility::_GET('tx_news_web_newsadministration');
|
||||
$demand = GeneralUtility::makeInstance(AdministrationDemand::class);
|
||||
$autoSubmitForm = 0;
|
||||
if (!empty($demandVars['demand'] ?? [])) {
|
||||
foreach ($demandVars['demand'] as $key => $value) {
|
||||
if (property_exists(AdministrationDemand::class, $key)) {
|
||||
$getter = 'set' . ucfirst($key);
|
||||
$demand->$getter($value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Preselect by TsConfig (e.g. tx_news.module.preselect.topNewsRestriction = 1)
|
||||
if (isset($this->tsConfiguration['preselect.'])
|
||||
&& is_array($this->tsConfiguration['preselect.'])
|
||||
) {
|
||||
$anyPropertySet = false;
|
||||
unset($this->tsConfiguration['preselect.']['orderByAllowed']);
|
||||
|
||||
foreach ($this->tsConfiguration['preselect.'] as $propertyName => $propertyValue) {
|
||||
$propertySet = ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
|
||||
if ($propertySet) {
|
||||
$anyPropertySet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($anyPropertySet && !GeneralUtility::_GET('formSubmitted')) {
|
||||
$autoSubmitForm = 1;
|
||||
}
|
||||
}
|
||||
if (!(bool)($this->tsConfiguration['alwaysShowFilter'] ?? false) || !$this->isFilteringEnabled()) {
|
||||
$this->view->assign('hideForm', true);
|
||||
}
|
||||
}
|
||||
$this->view->assign('autoSubmitForm', $autoSubmitForm);
|
||||
|
||||
$categories = $this->categoryRepository->findParentCategoriesByPid($this->pageUid);
|
||||
$idList = [];
|
||||
foreach ($categories as $c) {
|
||||
$idList[] = $c->getUid();
|
||||
}
|
||||
if (empty($idList) && !$this->getBackendUser()->isAdmin()) {
|
||||
$idList = $this->getBackendUser()->getCategoryMountPoints();
|
||||
}
|
||||
|
||||
if (!empty($this->tsConfiguration['allowedCategoryRootIds'])) {
|
||||
$allowedList = GeneralUtility::intExplode(',', $this->tsConfiguration['allowedCategoryRootIds'], true);
|
||||
if (!empty($allowedList)) {
|
||||
$idList = array_intersect($idList, $allowedList);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the dblist object:
|
||||
$dblist = GeneralUtility::makeInstance(NewsDatabaseRecordList::class);
|
||||
$this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ActionDispatcher');
|
||||
$this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
|
||||
|
||||
$pageinfo = BackendUtilityCore::readPageAccess($this->pageUid, $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW));
|
||||
$dblist->pageRow = $pageinfo;
|
||||
$majorVersion = GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion();
|
||||
if ($majorVersion <= 10) {
|
||||
$dblist->calcPerms = Permission::CONTENT_EDIT;
|
||||
} else {
|
||||
$dblist->calcPerms->set(Permission::CONTENT_EDIT);
|
||||
if ($majorVersion >= 11) {
|
||||
$dblist->displayColumnSelector = false;
|
||||
$dblist->displayRecordDownload = false;
|
||||
}
|
||||
}
|
||||
$dblist->disableSingleTableView = true;
|
||||
$dblist->clickTitleMode = 'edit';
|
||||
$dblist->allFields = 1;
|
||||
$dblist->displayFields = false;
|
||||
$dblist->dontShowClipControlPanels = true;
|
||||
$pointer = MathUtility::forceIntegerInRange(GeneralUtility::_GP('pointer'), 0);
|
||||
$limit = isset($this->settings['list']['paginate']['itemsPerPage']) ? (int)$this->settings['list']['paginate']['itemsPerPage'] : 20;
|
||||
$dblist->start(
|
||||
$this->pageUid,
|
||||
'tx_news_domain_model_news',
|
||||
$pointer,
|
||||
'',
|
||||
$demand->getRecursive(),
|
||||
$limit
|
||||
);
|
||||
$dblist->setDispFields();
|
||||
$dblist->noControlPanels = !(bool)($this->tsConfiguration['controlPanels'] ?? false);
|
||||
$dblist->setFields = [
|
||||
'tx_news_domain_model_news' => GeneralUtility::trimExplode(',', $this->tsConfiguration['columns'] ?? 'teaser,istopnews,datetime,categories', true)
|
||||
];
|
||||
|
||||
$tableRendering = $dblist->generateList();
|
||||
if (!$tableRendering && GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() <= 10) {
|
||||
$tableRendering = $dblist->HTMLcode;
|
||||
}
|
||||
$tableRendering = trim($tableRendering);
|
||||
|
||||
$counter = !empty($tableRendering);
|
||||
$this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Recordlist/Recordlist');
|
||||
|
||||
$assignedValues = [
|
||||
'moduleToken' => $this->getToken(true),
|
||||
'page' => $this->pageUid,
|
||||
'demand' => $demand,
|
||||
'news' => $tableRendering,
|
||||
'newsCount' => $counter,
|
||||
'showSearchForm' => (!is_null($demand) || $counter > 0),
|
||||
'requestUri' => GeneralUtility::quoteJSvalue(rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'))),
|
||||
'categories' => $this->categoryRepository->findTree($idList),
|
||||
'filters' => $this->tsConfiguration['filters.'],
|
||||
'enableFiltering' => $this->isFilteringEnabled(),
|
||||
'dateformat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new AdministrationIndexActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a page tree including count of news + category records
|
||||
*/
|
||||
public function newsPidListingAction(int $treeLevel = 2): void
|
||||
{
|
||||
$tree = Page::pageTree($this->pageUid, $treeLevel);
|
||||
|
||||
$rawTree = [];
|
||||
foreach ($tree->tree as $row) {
|
||||
$this->countRecordsOnPage($row);
|
||||
$rawTree[] = $row;
|
||||
}
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new AdministrationNewsPidListingActionEvent($this, $rawTree, $treeLevel));
|
||||
|
||||
$this->view->assignMultiple([
|
||||
'tree' => $event->getRawTree(),
|
||||
'treeLevel' => $event->getTreeLevel(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function donateAction(): void
|
||||
{
|
||||
$this->view->assignMultiple([
|
||||
'counts' => $this->administrationRepository->getTotalCounts()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to form to create a news record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function newNewsAction(): void
|
||||
{
|
||||
$this->redirectToCreateNewRecord('tx_news_domain_model_news');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to form to create a category record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function newCategoryAction(): void
|
||||
{
|
||||
$this->redirectToCreateNewRecord('sys_category');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to form to create a tag record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function newTagAction(): void
|
||||
{
|
||||
$this->redirectToCreateNewRecord('tx_news_domain_model_tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update page record array with count of news & category records
|
||||
*
|
||||
* @param array $row page record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function countRecordsOnPage(array &$row): void
|
||||
{
|
||||
$pageUid = (int)$row['row']['uid'];
|
||||
|
||||
$counts = [
|
||||
'countNews' => 'tx_news_domain_model_news',
|
||||
'countCategories' => 'sys_category',
|
||||
'countTags' => 'tx_news_domain_model_tag',
|
||||
];
|
||||
foreach ($counts as $key => $table) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
$row[$key] = $queryBuilder->count('*')
|
||||
->from($table)
|
||||
->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pageUid, \PDO::PARAM_INT)))
|
||||
->execute()
|
||||
->fetchColumn(0);
|
||||
}
|
||||
|
||||
$row['countAll'] = ($row['countNews'] + $row['countCategories'] + $row['countTags']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to creating a new record
|
||||
*
|
||||
* @param string $table table name
|
||||
*/
|
||||
private function redirectToCreateNewRecord(string $table): void
|
||||
{
|
||||
$pid = $this->pageUid;
|
||||
if ($pid === 0 && isset($this->tsConfiguration['defaultPid.'])
|
||||
&& is_array($this->tsConfiguration['defaultPid.'])
|
||||
&& isset($this->tsConfiguration['defaultPid.'][$table])
|
||||
) {
|
||||
$pid = (int)$this->tsConfiguration['defaultPid.'][$table];
|
||||
}
|
||||
|
||||
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
|
||||
|
||||
$returnUrl = $uriBuilder->buildUriFromRoutePath('/module/web/NewsAdministration/', [
|
||||
'id' => $this->pageUid,
|
||||
'token' => $this->getToken(true)
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'edit[' . $table . '][' . $pid . ']' => 'new',
|
||||
'returnUrl' => (string)$returnUrl
|
||||
];
|
||||
$url = $uriBuilder->buildUriFromRoute('record_edit', $params);
|
||||
HttpUtility::redirect((string)$url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the TsConfig configuration for the extension
|
||||
*/
|
||||
protected function setTsConfig(): void
|
||||
{
|
||||
$tsConfig = BackendUtilityCore::getPagesTSconfig($this->pageUid);
|
||||
if (isset($tsConfig['tx_news.']['module.']) && is_array($tsConfig['tx_news.']['module.'])) {
|
||||
$this->tsConfiguration = $tsConfig['tx_news.']['module.'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if at least one filter is enabled
|
||||
*/
|
||||
protected function isFilteringEnabled(): bool
|
||||
{
|
||||
if (isset($this->tsConfiguration['filters.'])) {
|
||||
foreach ($this->tsConfiguration['filters.'] as $filter => $enabled) {
|
||||
if ($enabled == 1) {
|
||||
// Check dependencies on other filter
|
||||
if (($filter === 'categoryConjunction' || $filter === 'includeSubCategories')
|
||||
&& $this->tsConfiguration['filters.']['categories'] == 0) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If defined in TsConfig with tx_news.module.redirectToPageOnStart = 123
|
||||
* and the current page id is 0, a redirect to the given page will be done
|
||||
*/
|
||||
protected function redirectToPageOnStart(): void
|
||||
{
|
||||
$allowedPage = (int)($this->tsConfiguration['allowedPage'] ?? 0);
|
||||
$redirectPageOnStart = (int)($this->tsConfiguration['redirectToPageOnStart'] ?? 0);
|
||||
if ($allowedPage > 0 && $this->pageUid !== $allowedPage) {
|
||||
$id = $allowedPage;
|
||||
} elseif ($this->pageUid === 0 && $redirectPageOnStart > 0) {
|
||||
$id = $redirectPageOnStart;
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
|
||||
$url = $uriBuilder->buildUriFromRoutePath('/module/web/NewsAdministration/', [
|
||||
'id' => $id,
|
||||
'token' => $this->getToken(true)
|
||||
]);
|
||||
HttpUtility::redirect((string)$url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a CSRF token
|
||||
*
|
||||
* @param bool $tokenOnly Set it to TRUE to get only the token, otherwise including the &moduleToken= as prefix
|
||||
*/
|
||||
protected function getToken(bool $tokenOnly = false): string
|
||||
{
|
||||
$tokenParameterName = 'token';
|
||||
$token = FormProtectionFactory::get('backend')->generateToken('route', 'web_NewsAdministration');
|
||||
|
||||
if ($tokenOnly) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
return '&' . $tokenParameterName . '=' . $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show support area only for admins in given percent of time
|
||||
*
|
||||
* @param int $probabilityInPercent
|
||||
*/
|
||||
private function showSupportArea(int $probabilityInPercent = 10): bool
|
||||
{
|
||||
if (!$this->getBackendUser()->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mt_rand() % 100 <= $probabilityInPercent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
protected function getBackendUser(): BackendUserAuthentication
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
use GeorgRinger\News\Event\CategoryListActionEvent;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Category controller
|
||||
*/
|
||||
class CategoryController extends NewsController
|
||||
{
|
||||
/**
|
||||
* List categories
|
||||
*
|
||||
* @param array $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function listAction(array $overwriteDemand = null)
|
||||
{
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ($overwriteDemand !== null && $this->settings['disableOverrideDemand'] != 1) {
|
||||
$demand = $this->overwriteDemandObject($demand, $overwriteDemand);
|
||||
}
|
||||
|
||||
$idList = is_array($demand->getCategories()) ? $demand->getCategories() : explode(',', $demand->getCategories());
|
||||
|
||||
$startingPoint = null;
|
||||
if (!empty($this->settings['startingpoint'])) {
|
||||
$startingPoint = $this->settings['startingpoint'];
|
||||
}
|
||||
|
||||
$assignedValues = [
|
||||
'categories' => $this->categoryRepository->findTree($idList, $startingPoint),
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'demand' => $demand,
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new CategoryListActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use Exception;
|
||||
use GeorgRinger\News\Domain\Model\Dto\EmConfiguration;
|
||||
use GeorgRinger\News\Jobs\ImportJobInterface;
|
||||
use GeorgRinger\News\Utility\ImportJob;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Backend\View\BackendTemplateView;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\HttpUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Controller to import news records
|
||||
*/
|
||||
class ImportController extends ActionController
|
||||
{
|
||||
|
||||
/**
|
||||
* Backend Template Container
|
||||
*
|
||||
* @var BackendTemplateView
|
||||
*/
|
||||
protected $defaultViewObjectName = BackendTemplateView::class;
|
||||
|
||||
/**
|
||||
* Retrieve all available import jobs by traversing trough registered
|
||||
* import jobs and checking "isEnabled".
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getAvailableJobs(): array
|
||||
{
|
||||
$availableJobs = [];
|
||||
$registeredJobs = ImportJob::getRegisteredJobs();
|
||||
|
||||
foreach ($registeredJobs as $registeredJob) {
|
||||
$jobInstance = $this->objectManager->get($registeredJob['className']);
|
||||
if ($jobInstance instanceof ImportJobInterface && $jobInstance->isEnabled()) {
|
||||
$availableJobs[$registeredJob['className']] = $GLOBALS['LANG']->sL($registeredJob['title']);
|
||||
}
|
||||
}
|
||||
|
||||
return $availableJobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the import jobs selection .
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function indexAction(): void
|
||||
{
|
||||
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
|
||||
$pageRenderer->loadRequireJsModule('TYPO3/CMS/News/Import');
|
||||
|
||||
$this->view->assignMultiple(
|
||||
[
|
||||
'error' => $this->checkCorrectConfiguration(),
|
||||
'availableJobs' => array_merge([0 => ''], $this->getAvailableJobs()),
|
||||
'moduleUrl' => $uriBuilder->buildUriFromRoute($this->request->getPluginName())
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for correct configuration
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
* @throws \TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
|
||||
*/
|
||||
protected function checkCorrectConfiguration(): string
|
||||
{
|
||||
$error = '';
|
||||
|
||||
$settings = GeneralUtility::makeInstance(EmConfiguration::class);
|
||||
|
||||
try {
|
||||
$storageId = (int)$settings->getStorageUidImporter();
|
||||
$path = $settings->getResourceFolderImporter();
|
||||
if ($storageId === 0) {
|
||||
throw new UnexpectedValueException('import.error.configuration.storageUidImporter');
|
||||
}
|
||||
if (empty($path)) {
|
||||
throw new UnexpectedValueException('import.error.configuration.resourceFolderImporter');
|
||||
}
|
||||
$storage = $this->getResourceFactory()->getStorageObject($storageId);
|
||||
$pathExists = $storage->hasFolder($path);
|
||||
if (!$pathExists) {
|
||||
throw new FolderDoesNotExistException('Folder does not exist', 1474827988);
|
||||
}
|
||||
} catch (FolderDoesNotExistException $e) {
|
||||
$error = 'import.error.configuration.resourceFolderImporter.notExist';
|
||||
} catch (UnexpectedValueException $e) {
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an actual job.
|
||||
*
|
||||
* @param string $jobClassName
|
||||
* @param int $offset
|
||||
* @return string
|
||||
*/
|
||||
public function runJobAction($jobClassName, $offset = 0): string
|
||||
{
|
||||
/** @var ImportJobInterface $job */
|
||||
$job = $this->objectManager->get($jobClassName);
|
||||
$job->run($offset);
|
||||
|
||||
return 'OK';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the job info of a given jobClass
|
||||
*
|
||||
* @param string $jobClassName
|
||||
* @return string
|
||||
*/
|
||||
public function jobInfoAction($jobClassName): string
|
||||
{
|
||||
$response = null;
|
||||
try {
|
||||
/** @var ImportJobInterface $job */
|
||||
$job = $this->objectManager->get($jobClassName);
|
||||
$response = $job->getInfo();
|
||||
} catch (Exception $e) {
|
||||
$response['message'] = $e->getMessage();
|
||||
$response['line'] = $e->getLine();
|
||||
$response['trace'] = $e->getTrace();
|
||||
|
||||
HttpUtility::setResponseCode(HttpUtility::HTTP_STATUS_400);
|
||||
}
|
||||
|
||||
return json_encode($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResourceFactory
|
||||
*/
|
||||
protected function getResourceFactory(): ResourceFactory
|
||||
{
|
||||
return GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\Dto\EmConfiguration;
|
||||
use TYPO3\CMS\Core\Http\ImmediateResponseException;
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\HttpUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
|
||||
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
|
||||
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||
use TYPO3\CMS\Frontend\Controller\ErrorController;
|
||||
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
|
||||
|
||||
/**
|
||||
* Base controller
|
||||
*/
|
||||
class NewsBaseController extends ActionController
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes the view before invoking an action method.
|
||||
* Override this method to solve assign variables common for all actions
|
||||
* or prepare the view in another way before the action is called.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view The view to be initialized
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initializeView(ViewInterface $view)
|
||||
{
|
||||
$view->assign('contentObjectData', $this->configurationManager->getContentObject()->data);
|
||||
$view->assign('emConfiguration', GeneralUtility::makeInstance(EmConfiguration::class));
|
||||
if (isset($GLOBALS['TSFE']) && is_object($GLOBALS['TSFE'])) {
|
||||
$view->assign('pageData', $GLOBALS['TSFE']->page);
|
||||
}
|
||||
parent::initializeView($view);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param RequestInterface $request
|
||||
// * @param ResponseInterface $response
|
||||
// * @throws \Exception
|
||||
// */
|
||||
// public function processRequest(RequestInterface $request, ResponseInterface $response)
|
||||
// {
|
||||
// try {
|
||||
// parent::processRequest($request, $response);
|
||||
// } catch (\Exception $exception) {
|
||||
// $this->handleKnownExceptionsElseThrowAgain($exception);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param \Exception $exception
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function handleKnownExceptionsElseThrowAgain(\Exception $exception): void
|
||||
{
|
||||
$previousException = $exception->getPrevious();
|
||||
|
||||
if (
|
||||
$this->actionMethodName === 'detailAction'
|
||||
&& $previousException instanceof \TYPO3\CMS\Extbase\Property\Exception
|
||||
&& isset($this->settings['detail']['errorHandling'])
|
||||
) {
|
||||
$this->handleNoNewsFoundError($this->settings['detail']['errorHandling']);
|
||||
} else {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handling if no news entry is found
|
||||
*
|
||||
* @param string $configuration configuration what will be done
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function handleNoNewsFoundError($configuration): string
|
||||
{
|
||||
if (empty($configuration)) {
|
||||
return '';
|
||||
}
|
||||
$options = GeneralUtility::trimExplode(',', $configuration, true);
|
||||
|
||||
switch ($options[0]) {
|
||||
case 'redirectToListView':
|
||||
$this->redirect('list');
|
||||
break;
|
||||
case 'redirectToPage':
|
||||
if (count($options) === 1 || count($options) > 3) {
|
||||
$msg = sprintf(
|
||||
'If error handling "%s" is used, either 2 or 3 arguments, split by "," must be used',
|
||||
$options[0]
|
||||
);
|
||||
throw new \InvalidArgumentException($msg);
|
||||
}
|
||||
$this->uriBuilder->reset();
|
||||
$this->uriBuilder->setTargetPageUid($options[1]);
|
||||
$this->uriBuilder->setCreateAbsoluteUri(true);
|
||||
if (GeneralUtility::getIndpEnv('TYPO3_SSL')) {
|
||||
$this->uriBuilder->setAbsoluteUriScheme('https');
|
||||
}
|
||||
$url = $this->uriBuilder->build();
|
||||
|
||||
if (isset($options[2])) {
|
||||
$this->redirectToUri($url, 0, (int)$options[2]);
|
||||
} else {
|
||||
$this->redirectToUri($url);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'pageNotFoundHandler':
|
||||
$typo3Information = GeneralUtility::makeInstance(Typo3Version::class);
|
||||
if ($typo3Information->getMajorVersion() === 9) {
|
||||
$response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction($GLOBALS['TYPO3_REQUEST'], 'No news entry found.');
|
||||
throw new ImmediateResponseException($response);
|
||||
}
|
||||
$message = 'No news entry found!';
|
||||
$response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
|
||||
$GLOBALS['TYPO3_REQUEST'],
|
||||
$message
|
||||
);
|
||||
throw new ImmediateResponseException($response, 1590468229);
|
||||
|
||||
break;
|
||||
case 'showStandaloneTemplate':
|
||||
if (isset($options[2])) {
|
||||
$statusCode = constant(HttpUtility::class . '::HTTP_STATUS_' . $options[2]);
|
||||
} else {
|
||||
$statusCode = HttpUtility::HTTP_STATUS_404;
|
||||
}
|
||||
HttpUtility::setResponseCode($statusCode);
|
||||
|
||||
$this->getTypoScriptFrontendController()->set_no_cache('News record not found');
|
||||
|
||||
$standaloneTemplate = GeneralUtility::makeInstance(StandaloneView::class);
|
||||
$standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($options[1]));
|
||||
return $standaloneTemplate->render();
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTypoScriptFrontendController(): TypoScriptFrontendController
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,703 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\Dto\NewsDemand;
|
||||
use GeorgRinger\News\Domain\Model\Dto\Search;
|
||||
use GeorgRinger\News\Domain\Model\News;
|
||||
use GeorgRinger\News\Domain\Repository\CategoryRepository;
|
||||
use GeorgRinger\News\Domain\Repository\NewsRepository;
|
||||
use GeorgRinger\News\Domain\Repository\TagRepository;
|
||||
use GeorgRinger\News\Event\NewsCheckPidOfNewsRecordFailedInDetailActionEvent;
|
||||
use GeorgRinger\News\Event\NewsDateMenuActionEvent;
|
||||
use GeorgRinger\News\Event\NewsDetailActionEvent;
|
||||
use GeorgRinger\News\Event\NewsListActionEvent;
|
||||
use GeorgRinger\News\Event\NewsListSelectedActionEvent;
|
||||
use GeorgRinger\News\Event\NewsSearchFormActionEvent;
|
||||
use GeorgRinger\News\Event\NewsSearchResultActionEvent;
|
||||
use GeorgRinger\News\Pagination\QueryResultPaginator;
|
||||
use GeorgRinger\News\Seo\NewsTitleProvider;
|
||||
use GeorgRinger\News\Utility\Cache;
|
||||
use GeorgRinger\News\Utility\ClassCacheManager;
|
||||
use GeorgRinger\News\Utility\Page;
|
||||
use GeorgRinger\News\Utility\TypoScript;
|
||||
use GeorgRinger\NumberedPagination\NumberedPagination;
|
||||
use TYPO3\CMS\Core\Pagination\SimplePagination;
|
||||
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Fluid\View\TemplateView;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controller of news records
|
||||
*
|
||||
*/
|
||||
class NewsController extends NewsBaseController
|
||||
{
|
||||
/**
|
||||
* @var \GeorgRinger\News\Domain\Repository\NewsRepository
|
||||
*/
|
||||
protected $newsRepository;
|
||||
|
||||
/**
|
||||
* @var \GeorgRinger\News\Domain\Repository\CategoryRepository
|
||||
*/
|
||||
protected $categoryRepository;
|
||||
|
||||
/**
|
||||
* @var \GeorgRinger\News\Domain\Repository\TagRepository
|
||||
*/
|
||||
protected $tagRepository;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/** @var array */
|
||||
protected $ignoredSettingsForOverride = ['demandclass', 'orderbyallowed', 'selectedList'];
|
||||
|
||||
/**
|
||||
* Original settings without any magic done by stdWrap and skipping empty values
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $originalSettings = [];
|
||||
|
||||
/**
|
||||
* NewsController constructor.
|
||||
* @param NewsRepository $newsRepository
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param TagRepository $tagRepository
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function __construct(
|
||||
NewsRepository $newsRepository,
|
||||
CategoryRepository $categoryRepository,
|
||||
TagRepository $tagRepository,
|
||||
ConfigurationManagerInterface $configurationManager
|
||||
) {
|
||||
$this->newsRepository = $newsRepository;
|
||||
$this->categoryRepository = $categoryRepository;
|
||||
$this->tagRepository = $tagRepository;
|
||||
$this->configurationManager = $configurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the current action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeAction()
|
||||
{
|
||||
GeneralUtility::makeInstance(ClassCacheManager::class)->reBuildSimple();
|
||||
$this->buildSettings();
|
||||
if (isset($this->settings['format'])) {
|
||||
$this->request->setFormat($this->settings['format']);
|
||||
}
|
||||
// Only do this in Frontend Context
|
||||
if (!empty($GLOBALS['TSFE']) && is_object($GLOBALS['TSFE'])) {
|
||||
// We only want to set the tag once in one request, so we have to cache that statically if it has been done
|
||||
static $cacheTagsSet = false;
|
||||
|
||||
/** @var $typoScriptFrontendController \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */
|
||||
$typoScriptFrontendController = $GLOBALS['TSFE'];
|
||||
if (!$cacheTagsSet) {
|
||||
$typoScriptFrontendController->addCacheTags(['tx_news']);
|
||||
$cacheTagsSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the demand object which define which records will get shown
|
||||
*
|
||||
* @param array $settings
|
||||
* @param string $class optional class which must be an instance of \GeorgRinger\News\Domain\Model\Dto\NewsDemand
|
||||
* @return \GeorgRinger\News\Domain\Model\Dto\NewsDemand
|
||||
*/
|
||||
protected function createDemandObjectFromSettings(
|
||||
array $settings,
|
||||
$class = NewsDemand::class
|
||||
): \GeorgRinger\News\Domain\Model\Dto\NewsDemand {
|
||||
$class = isset($settings['demandClass']) && !empty($settings['demandClass']) ? $settings['demandClass'] : $class;
|
||||
|
||||
/* @var $demand NewsDemand */
|
||||
$demand = GeneralUtility::makeInstance($class, $settings);
|
||||
if (!$demand instanceof NewsDemand) {
|
||||
throw new \UnexpectedValueException(
|
||||
sprintf(
|
||||
'The demand object must be an instance of %s, but %s given!',
|
||||
NewsDemand::class,
|
||||
$class
|
||||
),
|
||||
1423157953
|
||||
);
|
||||
}
|
||||
|
||||
$demand->setCategories(GeneralUtility::trimExplode(',', $settings['categories'] ?? '', true));
|
||||
$demand->setCategoryConjunction((string)($settings['categoryConjunction'] ?? ''));
|
||||
$demand->setIncludeSubCategories((bool)($settings['includeSubCategories'] ?? false));
|
||||
$demand->setTags((string)($settings['tags'] ?? ''));
|
||||
|
||||
$demand->setTopNewsRestriction((int)($settings['topNewsRestriction'] ?? 0));
|
||||
$demand->setTimeRestriction($settings['timeRestriction'] ?? '');
|
||||
$demand->setTimeRestrictionHigh($settings['timeRestrictionHigh'] ?? '');
|
||||
$demand->setArchiveRestriction((string)($settings['archiveRestriction'] ?? ''));
|
||||
$demand->setExcludeAlreadyDisplayedNews((bool)($settings['excludeAlreadyDisplayedNews'] ?? false));
|
||||
$demand->setHideIdList((string)($settings['hideIdList'] ?? ''));
|
||||
|
||||
if ($settings['orderBy'] ?? '') {
|
||||
$demand->setOrder($settings['orderBy'] . ' ' . $settings['orderDirection']);
|
||||
}
|
||||
$demand->setOrderByAllowed((string)($settings['orderByAllowed'] ?? ''));
|
||||
|
||||
$demand->setTopNewsFirst((bool)($settings['topNewsFirst'] ?? false));
|
||||
|
||||
$demand->setLimit((int)($settings['limit'] ?? 0));
|
||||
$demand->setOffset((int)($settings['offset'] ?? 0));
|
||||
|
||||
$demand->setSearchFields((string)($settings['search']['fields'] ?? ''));
|
||||
$demand->setDateField((string)($settings['dateField'] ?? ''));
|
||||
$demand->setMonth((int)($settings['month'] ?? 0));
|
||||
$demand->setYear((int)($settings['year'] ?? 0));
|
||||
|
||||
$demand->setStoragePage(Page::extendPidListByChildren(
|
||||
(string)($settings['startingpoint'] ?? ''),
|
||||
(int)($settings['recursive'] ?? 0)
|
||||
));
|
||||
|
||||
if ($hooks = $GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Controller/NewsController.php']['createDemandObjectFromSettings'] ?? []) {
|
||||
$params = [
|
||||
'demand' => $demand,
|
||||
'settings' => $settings,
|
||||
'class' => $class,
|
||||
];
|
||||
foreach ($hooks as $reference) {
|
||||
GeneralUtility::callUserFunction($reference, $params, $this);
|
||||
}
|
||||
}
|
||||
return $demand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites a given demand object by an propertyName => $propertyValue array
|
||||
*
|
||||
* @param \GeorgRinger\News\Domain\Model\Dto\NewsDemand $demand
|
||||
* @param array $overwriteDemand
|
||||
* @return \GeorgRinger\News\Domain\Model\Dto\NewsDemand
|
||||
*/
|
||||
protected function overwriteDemandObject(NewsDemand $demand, array $overwriteDemand): \GeorgRinger\News\Domain\Model\Dto\NewsDemand
|
||||
{
|
||||
foreach ($this->ignoredSettingsForOverride as $property) {
|
||||
unset($overwriteDemand[$property]);
|
||||
}
|
||||
|
||||
foreach ($overwriteDemand as $propertyName => $propertyValue) {
|
||||
if (in_array(strtolower($propertyName), $this->ignoredSettingsForOverride, true)) {
|
||||
continue;
|
||||
}
|
||||
if ($propertyValue !== '' || $this->settings['allowEmptyStringsForOverwriteDemand']) {
|
||||
if (in_array($propertyName, ['categories'], true)) {
|
||||
$propertyValue = GeneralUtility::trimExplode(',', $propertyValue, true);
|
||||
}
|
||||
ObjectAccess::setProperty($demand, $propertyName, $propertyValue);
|
||||
}
|
||||
}
|
||||
return $demand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a list view of news
|
||||
*
|
||||
* @param array|null $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function listAction(array $overwriteDemand = null)
|
||||
{
|
||||
$this->forwardToDetailActionWhenRequested();
|
||||
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ((int)($this->settings['disableOverrideDemand'] ?? 1) !== 1 && $overwriteDemand !== null) {
|
||||
$demand = $this->overwriteDemandObject($demand, $overwriteDemand);
|
||||
}
|
||||
$newsRecords = $this->newsRepository->findDemanded($demand);
|
||||
|
||||
// pagination
|
||||
$paginationConfiguration = $this->settings['list']['paginate'] ?? [];
|
||||
$itemsPerPage = (int)(($paginationConfiguration['itemsPerPage'] ?? '') ?: 10);
|
||||
$maximumNumberOfLinks = (int)($paginationConfiguration['maximumNumberOfLinks'] ?? 0);
|
||||
|
||||
$currentPage = $this->request->hasArgument('currentPage') ? (int)$this->request->getArgument('currentPage') : 1;
|
||||
$paginator = GeneralUtility::makeInstance(QueryResultPaginator::class, $newsRecords, $currentPage, $itemsPerPage, (int)($this->settings['limit'] ?? 0), (int)($this->settings['offset'] ?? 0));
|
||||
$paginationClass = $paginationConfiguration['class'] ?? SimplePagination::class;
|
||||
if (class_exists(NumberedPagination::class) && $paginationClass === NumberedPagination::class && $maximumNumberOfLinks) {
|
||||
$pagination = GeneralUtility::makeInstance(NumberedPagination::class, $paginator, $maximumNumberOfLinks);
|
||||
} elseif (class_exists($paginationClass)) {
|
||||
$pagination = GeneralUtility::makeInstance($paginationClass, $paginator);
|
||||
} else {
|
||||
$pagination = GeneralUtility::makeInstance(SimplePagination::class, $paginator);
|
||||
}
|
||||
|
||||
$assignedValues = [
|
||||
'news' => $newsRecords,
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'demand' => $demand,
|
||||
'categories' => null,
|
||||
'tags' => null,
|
||||
'settings' => $this->settings,
|
||||
'pagination' => [
|
||||
'currentPage' => $currentPage,
|
||||
'paginator' => $paginator,
|
||||
'pagination' => $pagination,
|
||||
]
|
||||
];
|
||||
|
||||
if ($demand->getCategories() !== '') {
|
||||
$categoriesList = $demand->getCategories();
|
||||
if (is_string($categoriesList)) {
|
||||
$categoriesList = GeneralUtility::trimExplode(',', $categoriesList);
|
||||
}
|
||||
if (!empty($categoriesList)) {
|
||||
$assignedValues['categories'] = $this->categoryRepository->findByIdList($categoriesList);
|
||||
}
|
||||
}
|
||||
|
||||
if ($demand->getTags() !== '') {
|
||||
$tagList = $demand->getTags();
|
||||
if (!is_array($tagList)) {
|
||||
$tagList = GeneralUtility::trimExplode(',', $tagList);
|
||||
}
|
||||
if (!empty($tagList)) {
|
||||
$assignedValues['tags'] = $this->tagRepository->findByIdList($tagList);
|
||||
}
|
||||
}
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsListActionEvent($this, $assignedValues));
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
|
||||
Cache::addPageCacheTagsByDemandObject($demand);
|
||||
}
|
||||
|
||||
/**
|
||||
* When list action is called along with a news argument, we forward to detail action.
|
||||
*/
|
||||
protected function forwardToDetailActionWhenRequested()
|
||||
{
|
||||
if (!$this->isActionAllowed('detail')
|
||||
|| !$this->request->hasArgument('news')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->forward('detail', null, null, ['news' => $this->request->getArgument('news')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an action is enabled in switchableControllerActions configuration
|
||||
*
|
||||
* @param string $action
|
||||
* @return bool
|
||||
*/
|
||||
protected function isActionAllowed(string $action): bool
|
||||
{
|
||||
$frameworkConfiguration = $this->configurationManager->getConfiguration($this->configurationManager::CONFIGURATION_TYPE_FRAMEWORK);
|
||||
$allowedActions = $frameworkConfiguration['controllerConfiguration']['News']['actions'] ?? [];
|
||||
|
||||
return \in_array($action, $allowedActions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a selected list view of news
|
||||
*/
|
||||
public function selectedListAction(): void
|
||||
{
|
||||
$newsRecords = [];
|
||||
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if (empty($this->originalSettings['orderBy'] ?? '')) {
|
||||
$idList = GeneralUtility::trimExplode(',', $this->settings['selectedList'], true);
|
||||
foreach ($idList as $id) {
|
||||
$news = $this->newsRepository->findByIdentifier($id);
|
||||
if ($news) {
|
||||
$newsRecords[] = $news;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$demand->setIdList($this->settings['selectedList']);
|
||||
$newsRecords = $this->newsRepository->findDemanded($demand);
|
||||
}
|
||||
|
||||
$assignedValues = [
|
||||
'news' => $newsRecords,
|
||||
'demand' => $demand,
|
||||
'settings' => $this->settings
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsListSelectedActionEvent($this, $assignedValues));
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
|
||||
if (!empty($newsRecords) && is_a($newsRecords[0], News::class)) {
|
||||
Cache::addCacheTagsByNewsRecords($newsRecords);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single view of a news record
|
||||
*
|
||||
* @param \GeorgRinger\News\Domain\Model\News $news news item
|
||||
* @param int $currentPage current page for optional pagination
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function detailAction(News $news = null, $currentPage = 1)
|
||||
{
|
||||
if ($news === null || ($this->settings['isShortcut'] ?? false)) {
|
||||
$previewNewsId = (int)($this->settings['singleNews'] ?? 0);
|
||||
if ($this->request->hasArgument('news_preview')) {
|
||||
$previewNewsId = (int)$this->request->getArgument('news_preview');
|
||||
}
|
||||
|
||||
if ($previewNewsId > 0) {
|
||||
if ($this->isPreviewOfHiddenRecordsEnabled()) {
|
||||
$news = $this->newsRepository->findByUid($previewNewsId, false);
|
||||
} else {
|
||||
$news = $this->newsRepository->findByUid($previewNewsId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_a($news, News::class) && ($this->settings['detail']['checkPidOfNewsRecord'] ?? false)
|
||||
) {
|
||||
$news = $this->checkPidOfNewsRecord($news);
|
||||
}
|
||||
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
$assignedValues = [
|
||||
'newsItem' => $news,
|
||||
'currentPage' => (int)$currentPage,
|
||||
'demand' => $demand,
|
||||
'settings' => $this->settings
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsDetailActionEvent($this, $assignedValues));
|
||||
$assignedValues = $event->getAssignedValues();
|
||||
|
||||
$news = $assignedValues['newsItem'];
|
||||
$this->view->assignMultiple($assignedValues);
|
||||
|
||||
// reset news if type is internal or external
|
||||
if ($news && !($this->settings['isShortcut'] ?? false) && ($news->getType() === '1' || $news->getType() === '2')) {
|
||||
$news = null;
|
||||
}
|
||||
|
||||
if ($news !== null) {
|
||||
Page::setRegisterProperties($this->settings['detail']['registerProperties'] ?? false, $news);
|
||||
Cache::addCacheTagsByNewsRecords([$news]);
|
||||
|
||||
if ($this->settings['detail']['pageTitle']['_typoScriptNodeValue'] ?? false) {
|
||||
$providerConfiguration = $this->settings['detail']['pageTitle'] ?? [];
|
||||
$providerClass = $providerConfiguration['provider'] ?? NewsTitleProvider::class;
|
||||
|
||||
/** @var NewsTitleProvider $provider */
|
||||
$provider = GeneralUtility::makeInstance($providerClass);
|
||||
$provider->setTitleByNews($news, $providerConfiguration);
|
||||
}
|
||||
} elseif (isset($this->settings['detail']['errorHandling'])) {
|
||||
$errorContent = $this->handleNoNewsFoundError($this->settings['detail']['errorHandling']);
|
||||
if ($errorContent) {
|
||||
return $errorContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the news pid could be found in the startingpoint settings of the detail plugin and
|
||||
* if the pid could not be found it return NULL instead of the news object.
|
||||
*
|
||||
* @param \GeorgRinger\News\Domain\Model\News $news
|
||||
* @return \GeorgRinger\News\Domain\Model\News|null
|
||||
*/
|
||||
protected function checkPidOfNewsRecord(News $news): ?\GeorgRinger\News\Domain\Model\News
|
||||
{
|
||||
$allowedStoragePages = GeneralUtility::trimExplode(
|
||||
',',
|
||||
Page::extendPidListByChildren(
|
||||
$this->settings['startingpoint'],
|
||||
$this->settings['recursive']
|
||||
),
|
||||
true
|
||||
);
|
||||
if (count($allowedStoragePages) > 0 && !in_array($news->getPid(), $allowedStoragePages)) {
|
||||
$this->eventDispatcher->dispatch(new NewsCheckPidOfNewsRecordFailedInDetailActionEvent($this, $news));
|
||||
$news = null;
|
||||
}
|
||||
return $news;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if preview is enabled either in TS or FlexForm
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPreviewOfHiddenRecordsEnabled(): bool
|
||||
{
|
||||
if (!empty($this->settings['previewHiddenRecords']) && $this->settings['previewHiddenRecords'] == 2) {
|
||||
$previewEnabled = !empty($this->settings['enablePreviewOfHiddenRecords']);
|
||||
} else {
|
||||
$previewEnabled = !empty($this->settings['previewHiddenRecords']);
|
||||
}
|
||||
return $previewEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a menu by dates, e.g. years, months or dates
|
||||
*
|
||||
* @param array|null $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dateMenuAction(array $overwriteDemand = null): void
|
||||
{
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ($this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== null) {
|
||||
$overwriteDemandTemp = $overwriteDemand;
|
||||
unset($overwriteDemandTemp['year']);
|
||||
unset($overwriteDemandTemp['month']);
|
||||
$demand = $this->overwriteDemandObject(
|
||||
$demand,
|
||||
$overwriteDemandTemp
|
||||
);
|
||||
unset($overwriteDemandTemp);
|
||||
}
|
||||
|
||||
// It might be that those are set, @see http://forge.typo3.org/issues/44759
|
||||
$demand->setLimit(0);
|
||||
$demand->setOffset(0);
|
||||
// @todo: find a better way to do this related to #13856
|
||||
if (!$dateField = $this->settings['dateField']) {
|
||||
$dateField = 'datetime';
|
||||
}
|
||||
$demand->setOrder($dateField . ' ' . $this->settings['orderDirection']);
|
||||
$newsRecords = $this->newsRepository->findDemanded($demand);
|
||||
|
||||
$demand->setOrder($this->settings['orderDirection']);
|
||||
$statistics = $this->newsRepository->countByDate($demand);
|
||||
|
||||
$assignedValues = [
|
||||
'listPid' => ($this->settings['listPid'] ? $this->settings['listPid'] : $GLOBALS['TSFE']->id),
|
||||
'dateField' => $dateField,
|
||||
'data' => $statistics,
|
||||
'news' => $newsRecords,
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'demand' => $demand,
|
||||
'settings' => $this->settings
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsDateMenuActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the search form
|
||||
*
|
||||
* @param \GeorgRinger\News\Domain\Model\Dto\Search $search
|
||||
* @param array $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function searchFormAction(
|
||||
Search $search = null,
|
||||
array $overwriteDemand = []
|
||||
): void {
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ($this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== null) {
|
||||
$demand = $this->overwriteDemandObject($demand, $overwriteDemand);
|
||||
}
|
||||
|
||||
if (is_null($search)) {
|
||||
$search = GeneralUtility::makeInstance(Search::class);
|
||||
}
|
||||
$demand->setSearch($search);
|
||||
|
||||
$assignedValues = [
|
||||
'search' => $search,
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'demand' => $demand,
|
||||
'settings' => $this->settings
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsSearchFormActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the search result
|
||||
*
|
||||
* @param \GeorgRinger\News\Domain\Model\Dto\Search $search
|
||||
* @param array $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function searchResultAction(
|
||||
Search $search = null,
|
||||
array $overwriteDemand = []
|
||||
): void {
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ($this->settings['disableOverrideDemand'] != 1 && $overwriteDemand !== null) {
|
||||
$demand = $this->overwriteDemandObject($demand, $overwriteDemand);
|
||||
}
|
||||
|
||||
if (!is_null($search)) {
|
||||
$search->setFields($this->settings['search']['fields']);
|
||||
$search->setDateField($this->settings['dateField']);
|
||||
$search->setSplitSubjectWords((bool)$this->settings['search']['splitSearchWord']);
|
||||
}
|
||||
|
||||
$demand->setSearch($search);
|
||||
|
||||
$assignedValues = [
|
||||
'news' => $this->newsRepository->findDemanded($demand),
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'search' => $search,
|
||||
'demand' => $demand,
|
||||
'settings' => $this->settings
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new NewsSearchResultActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize search result action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeSearchResultAction(): void
|
||||
{
|
||||
$this->initializeSearchActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize search form action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeSearchFormAction(): void
|
||||
{
|
||||
$this->initializeSearchActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize searchForm and searchResult actions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initializeSearchActions(): void
|
||||
{
|
||||
if ($this->arguments->hasArgument('search')) {
|
||||
$propertyMappingConfiguration = $this->arguments['search']->getPropertyMappingConfiguration();
|
||||
$propertyMappingConfiguration->allowAllProperties();
|
||||
$propertyMappingConfiguration->setTypeConverterOption('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* helper
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Injects the Configuration Manager and is initializing the framework settings
|
||||
*
|
||||
* @param ConfigurationManagerInterface $configurationManager Instance of the Configuration Manager
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildSettings()
|
||||
{
|
||||
$tsSettings = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
|
||||
'news',
|
||||
'news_pi1'
|
||||
);
|
||||
$originalSettings = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS
|
||||
);
|
||||
|
||||
$propertiesNotAllowedViaFlexForms = ['orderByAllowed'];
|
||||
foreach ($propertiesNotAllowedViaFlexForms as $property) {
|
||||
$originalSettings[$property] = ($tsSettings['settings'] ?? [])[$property] ?? ($originalSettings[$property] ?? '');
|
||||
}
|
||||
$this->originalSettings = $originalSettings;
|
||||
|
||||
// Use stdWrap for given defined settings
|
||||
|
||||
if (isset($originalSettings['useStdWrap']) && !empty($originalSettings['useStdWrap'])) {
|
||||
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
|
||||
$typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($originalSettings);
|
||||
$stdWrapProperties = GeneralUtility::trimExplode(',', $originalSettings['useStdWrap'], true);
|
||||
foreach ($stdWrapProperties as $key) {
|
||||
if (is_array($typoScriptArray[$key . '.'])) {
|
||||
$originalSettings[$key] = $this->configurationManager->getContentObject()->stdWrap(
|
||||
$typoScriptArray[$key],
|
||||
$typoScriptArray[$key . '.']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start override
|
||||
if (isset($tsSettings['settings']['overrideFlexformSettingsIfEmpty'])) {
|
||||
$typoScriptUtility = GeneralUtility::makeInstance(TypoScript::class);
|
||||
$originalSettings = $typoScriptUtility->override($originalSettings, $tsSettings);
|
||||
}
|
||||
|
||||
foreach ($hooks = ($GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Controller/NewsController.php']['overrideSettings'] ?? []) as $_funcRef) {
|
||||
$_params = [
|
||||
'originalSettings' => $originalSettings,
|
||||
'tsSettings' => $tsSettings,
|
||||
];
|
||||
$originalSettings = GeneralUtility::callUserFunction($_funcRef, $_params, $this);
|
||||
}
|
||||
|
||||
$this->settings = $originalSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects a view.
|
||||
* This function is for testing purposes only.
|
||||
*
|
||||
* @param \TYPO3\CMS\Fluid\View\TemplateView $view the view to inject
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setView(TemplateView $view): void
|
||||
{
|
||||
$this->view = $view;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Controller;
|
||||
|
||||
use GeorgRinger\News\Event\TagListActionEvent;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tag controller
|
||||
*/
|
||||
class TagController extends NewsController
|
||||
{
|
||||
/**
|
||||
* List tags
|
||||
*
|
||||
* @param array $overwriteDemand
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function listAction(array $overwriteDemand = null)
|
||||
{
|
||||
// Default value is wrong for tags
|
||||
if ($this->settings['orderBy'] === 'datetime') {
|
||||
unset($this->settings['orderBy']);
|
||||
}
|
||||
|
||||
$demand = $this->createDemandObjectFromSettings($this->settings);
|
||||
$demand->setActionAndClass(__METHOD__, __CLASS__);
|
||||
|
||||
if ($overwriteDemand !== null && $this->settings['disableOverrideDemand'] != 1) {
|
||||
$demand = $this->overwriteDemandObject($demand, $overwriteDemand);
|
||||
}
|
||||
|
||||
$assignedValues = [
|
||||
'tags' => $this->tagRepository->findDemanded($demand),
|
||||
'overwriteDemand' => $overwriteDemand,
|
||||
'demand' => $demand,
|
||||
];
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new TagListActionEvent($this, $assignedValues));
|
||||
|
||||
$this->view->assignMultiple($event->getAssignedValues());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user