diff --git a/Classes/Command/MigrateNewsCommandController.php b/Classes/Command/MigrateNewsCommandController.php index a2883ae130c90bcddca3c6f792c683693802bbeb..2947e61e87e60cb7755040c7e6ceb404f2e5ecb0 100644 --- a/Classes/Command/MigrateNewsCommandController.php +++ b/Classes/Command/MigrateNewsCommandController.php @@ -76,8 +76,15 @@ class MigrateNewsCommandController extends Command { ->addArgument('copyPageId', InputArgument::REQUIRED, 'The page id of the template that should be copied') ->addArgument('categoryPid', InputArgument::REQUIRED, 'The page id of the category page') ->addArgument('year', InputArgument::OPTIONAL, 'Only news from that year will be migrated', 2015) - ->addArgument('languageMapAsJson', InputArgument::OPTIONAL, 'A json, mapping language ids (old => new). this is needed if the sys_language_uids have changed', '{"3":1,"1":0,"2":2,"0":3}') - ->addArgument('categoryMapAsJson', InputArgument::OPTIONAL, 'A json, mapping sys_category ids (old => new).', '{"2":17,"3":16,"4":15,"5":14,"6":14,"7":15,"8":16,"9":17}') + ->addArgument( + 'languageMapAsJson', InputArgument::OPTIONAL, + 'A json, mapping language ids (old => new). this is needed if the sys_language_uids have changed', + '{"3":1,"1":0,"2":2,"0":3}' + ) + ->addArgument( + 'categoryMapAsJson', InputArgument::OPTIONAL, 'A json, mapping sys_category ids (old => new).', + '{"2":17,"3":16,"4":15,"5":14,"6":14,"7":15,"8":16,"9":17}' + ) ->addArgument('pId', InputArgument::OPTIONAL, 'Only news from that pid will be migrated', 52); } @@ -86,11 +93,8 @@ class MigrateNewsCommandController extends Command { * * @param InputInterface $input * @param OutputInterface $output - * @return int|void - * @throws IllegalObjectTypeException - * @throws UnknownObjectException + * @return void * @throws \JsonException - * @throws \TYPO3\CMS\Extbase\Object\Exception */ public function execute(InputInterface $input, OutputInterface $output) { $objectManager = GeneralUtility::makeInstance(ObjectManager::class); @@ -108,7 +112,9 @@ class MigrateNewsCommandController extends Command { $this->languageMap = json_decode($languageMapAsJson, TRUE, 512, JSON_THROW_ON_ERROR); $this->categoryMap = json_decode($categoryMapAsJson, TRUE, 512, JSON_THROW_ON_ERROR); - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_news_domain_model_news'); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable( + 'tx_news_domain_model_news' + ); $queryBuilder->getRestrictions()->removeByType(StartTimeRestriction::class); $rows = $queryBuilder->select('*') ->from('tx_news_domain_model_news') @@ -180,13 +186,21 @@ class MigrateNewsCommandController extends Command { $persistenceManager->persistAll(); // update content element from the new page - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable( + 'tt_content' + ); $queryBuilder->getRestrictions()->removeAll(); $queryBuilder->update('tt_content') ->where( $queryBuilder->expr()->andX( - $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($newPageId, Connection::PARAM_INT)), - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($this->languageMap[(int) $row['sys_language_uid']], \PDO::PARAM_INT)) + $queryBuilder->expr()->eq( + 'pid', $queryBuilder->createNamedParameter($newPageId, Connection::PARAM_INT) + ), + $queryBuilder->expr()->eq( + 'sys_language_uid', $queryBuilder->createNamedParameter( + $this->languageMap[(int) $row['sys_language_uid']], \PDO::PARAM_INT + ) + ) ) ) ->set('bodytext', $row['bodytext'], TRUE) @@ -207,15 +221,21 @@ class MigrateNewsCommandController extends Command { */ private function getMatchingFile(array $row) { // match old page id with old file reference id - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference_news_migration'); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable( + 'sys_file_reference_news_migration' + ); $queryBuilder->getRestrictions()->removeAll(); $fileReferenceResult = $queryBuilder->select('uid', 'uid_local') ->from('sys_file_reference_news_migration') ->where( $queryBuilder->expr()->andX( - $queryBuilder->expr()->eq('tablenames', $queryBuilder->createNamedParameter('tx_news_domain_model_news')), + $queryBuilder->expr()->eq( + 'tablenames', $queryBuilder->createNamedParameter('tx_news_domain_model_news') + ), $queryBuilder->expr()->eq('fieldname', $queryBuilder->createNamedParameter('fal_media')), - $queryBuilder->expr()->eq('uid_foreign', $queryBuilder->createNamedParameter($row['uid'], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid_foreign', $queryBuilder->createNamedParameter($row['uid'], Connection::PARAM_INT) + ) ) ) ->execute()->fetch(); @@ -223,12 +243,16 @@ class MigrateNewsCommandController extends Command { return NULL; } - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_news_migration'); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable( + 'sys_file_news_migration' + ); $queryBuilder->getRestrictions()->removeAll(); $fileResult = $queryBuilder->select('identifier') ->from('sys_file_news_migration') ->where( - $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileReferenceResult['uid_local'], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid', $queryBuilder->createNamedParameter($fileReferenceResult['uid_local'], Connection::PARAM_INT) + ) ) ->execute()->fetch(); if (!$fileResult) { @@ -251,12 +275,16 @@ class MigrateNewsCommandController extends Command { * @param array $row */ private function setMatchingTag(array $row) { - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category_record_mm_news_migration'); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable( + 'sys_category_record_mm_news_migration' + ); $queryBuilder->getRestrictions()->removeAll(); $mmRows = $queryBuilder->select('uid_local', 'sorting_foreign') ->from('sys_category_record_mm_news_migration') ->where( - $queryBuilder->expr()->eq('uid_foreign', $queryBuilder->createNamedParameter($row['uid'], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid_foreign', $queryBuilder->createNamedParameter($row['uid'], Connection::PARAM_INT) + ) ) ->execute()->fetchAll(); foreach ($mmRows as $mmRow) { @@ -293,22 +321,34 @@ class MigrateNewsCommandController extends Command { // if its the new default, there is no l18n_parent if ((int) $this->languageMap[(int) $row['sys_language_uid'] === 0]) { $queryBuilder->where( - $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($originalContentElement[0], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid', $queryBuilder->createNamedParameter($originalContentElement[0], Connection::PARAM_INT) + ) ); } else { $queryBuilder->where( - $queryBuilder->expr()->eq('l18n_parent', $queryBuilder->createNamedParameter($originalContentElement[0], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'l18n_parent', + $queryBuilder->createNamedParameter($originalContentElement[0], Connection::PARAM_INT) + ) ); } // look up the correct language id, if they have changed if (isset($this->languageMap[(int) $row['sys_language_uid']])) { $queryBuilder->andWhere( - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($this->languageMap[(int) $row['sys_language_uid']], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'sys_language_uid', $queryBuilder->createNamedParameter( + $this->languageMap[(int) $row['sys_language_uid']], Connection::PARAM_INT + ) + ) ); } else { $queryBuilder->andWhere( - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($row['sys_language_uid'], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'sys_language_uid', + $queryBuilder->createNamedParameter($row['sys_language_uid'], Connection::PARAM_INT) + ) ); } $queryBuilder->set('bodytext', $row['bodytext'], TRUE) @@ -321,16 +361,24 @@ class MigrateNewsCommandController extends Command { $result = $queryBuilder->select('title', 'subtitle') ->from('pages') ->where( - $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT) + ) ) ->execute()->fetch(); if ($result) { $queryBuilder->where( - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($this->languageMap[0], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'sys_language_uid', + $queryBuilder->createNamedParameter($this->languageMap[0], Connection::PARAM_INT) + ) ); $queryBuilder->update('pages') ->andWhere( - $queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($this->languageMap[0], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'l10n_parent', + $queryBuilder->createNamedParameter($this->languageMap[0], Connection::PARAM_INT) + ) ); $queryBuilder->set('title', $result['title'], TRUE) ->set('subtitle', $result['subtitle'], TRUE) @@ -341,7 +389,9 @@ class MigrateNewsCommandController extends Command { $newTitle = date('Y-m-d', $row['datetime']) . ' - ' . $row['title']; $queryBuilder->update('pages') ->where( - $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'uid', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT) + ) ) ->set('title', $newTitle, TRUE) ->set('subtitle', $row['title'], TRUE) @@ -351,17 +401,28 @@ class MigrateNewsCommandController extends Command { } else { $queryBuilder->update('pages') ->where( - $queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'l10n_parent', $queryBuilder->createNamedParameter($parentId, Connection::PARAM_INT) + ) ); - // finally translate the page title if necessary - if (isset($this->languageMap[(int) $row['sys_language_uid']]) && $this->languageMap[(int) $row['sys_language_uid']] > 0) { + // translate the page title if necessary + if (isset($this->languageMap[(int) $row['sys_language_uid']]) && + $this->languageMap[(int) $row['sys_language_uid']] > 0 + ) { $queryBuilder->andWhere( - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($this->languageMap[(int) $row['sys_language_uid']], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'sys_language_uid', $queryBuilder->createNamedParameter( + $this->languageMap[(int) $row['sys_language_uid']], Connection::PARAM_INT + ) + ) ); } else { $queryBuilder->andWhere( - $queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($row['sys_language_uid'], Connection::PARAM_INT)) + $queryBuilder->expr()->eq( + 'sys_language_uid', + $queryBuilder->createNamedParameter($row['sys_language_uid'], Connection::PARAM_INT) + ) ); } $queryBuilder->set('title', date('Y-m-d', $row['datetime']) . ' - ' . $row['title'], TRUE) diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php index 27101357c42cdec3d1d395628506f22bf5f06f46..1c710e0e2bc6a2f36737ab58669751ddac1875e5 100644 --- a/Classes/Controller/AbstractController.php +++ b/Classes/Controller/AbstractController.php @@ -74,15 +74,15 @@ abstract class AbstractController extends ActionController { /** * Error Handler * - * @throws \RuntimeException * @return void + * @throws \RuntimeException */ public function errorAction() { throw new RuntimeException(parent::errorAction()); } /** - * Returns the meta data of the given news. + * Returns the metadata of the given news. * * @param News $news * @param Category $category @@ -146,7 +146,9 @@ abstract class AbstractController extends ActionController { if ($singleNewsImage) { $singleNewsImageObject = $singleNewsImage; $originalResource = $singleNewsImage->getOriginalResource(); - $singleNewsImage = $originalResource->getPublicUrl(); + if ($originalResource) { + $singleNewsImage = $originalResource->getPublicUrl(); + } if ($singleNewsImage) { $singleNewsImage = $GLOBALS['TSFE']->absRefPrefix . $singleNewsImage; @@ -183,7 +185,9 @@ abstract class AbstractController extends ActionController { if ($teaserImage) { $teaserImageObject = $teaserImage; $originalResource = $teaserImage->getOriginalResource(); - $teaserImage = $originalResource->getPublicUrl(); + if ($originalResource) { + $teaserImage = $originalResource->getPublicUrl(); + } if ($teaserImage) { $teaserImage = $GLOBALS['TSFE']->absRefPrefix . $teaserImage; @@ -200,10 +204,10 @@ abstract class AbstractController extends ActionController { * Calculate the pagination offset * * @param int $currentPageBrowserPage - * @param int $newsLimitPerPage + * @param int|null $newsLimitPerPage * @return int */ - protected function calculatePaginationOffset(int $currentPageBrowserPage, int $newsLimitPerPage = NULL){ + protected function calculatePaginationOffset(int $currentPageBrowserPage, int $newsLimitPerPage = NULL) { $offset = 0; $newsPerPage = $newsLimitPerPage ?? (int) $this->settings['newsLimitPerPage']; if ($currentPageBrowserPage > 0 && $newsPerPage > 0) { diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index 730f87ef24ed127bee12544f390200080bb6e5e2..3db08d161509b3d0b0b21df28311baa094ad2bb1 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -27,7 +27,6 @@ namespace SGalinski\SgNews\Controller; ***************************************************************/ use SGalinski\SgNews\Utility\BackendNewsUtility; -use TYPO3\CMS\Backend\Clipboard\Clipboard; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Template\Components\ButtonBar; use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent; @@ -66,21 +65,6 @@ class BackendController extends ActionController { */ private $rootPageUid = 0; - /** - * Command array on the form [tablename][uid][command] = value. - * This array may get additional data set internally based on clipboard commands send in CB var! - * - * @var array - */ - private $command; - - /** - * Clipboard command array. May trigger changes in "cmd" - * - * @var array - */ - private $clipboardCommandArray; - /** * Currently selected language * @@ -95,17 +79,6 @@ class BackendController extends ActionController { */ private $docHeaderComponent; - /** - * Initialize action for all actions - * - * @throws \InvalidArgumentException - */ - public function initializeAction() { - $this->command = GeneralUtility::_GP('cmd'); - $this->clipboardCommandArray = GeneralUtility::_GP('CB'); - $this->initClipboard(); - } - /** * Initializes the view before invoking an action method. * @@ -234,8 +207,6 @@ class BackendController extends ActionController { ) ->setSetVariables([]); $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT); - - $this->docHeaderComponent->getButtonBar(); } /** @@ -265,36 +236,4 @@ class BackendController extends ActionController { } $this->docHeaderComponent->getMenuRegistry()->addMenu($languageMenu); } - - /** - * Clipboard pasting and deleting. - * - * @throws \InvalidArgumentException - */ - public function initClipboard() { - if (\is_array($this->clipboardCommandArray)) { - $clipObj = GeneralUtility::makeInstance(Clipboard::class); - $clipObj->initializeClipboard(); - if ($this->clipboardCommandArray['paste']) { - $clipObj->setCurrentPad($this->clipboardCommandArray['pad']); - $this->command = $clipObj->makePasteCmdArray( - $this->clipboardCommandArray['paste'], - $this->command, - $this->clipboardCommandArray['update'] ?? NULL - ); - } - - if ($this->clipboardCommandArray['delete']) { - $clipObj->setCurrentPad($this->clipboardCommandArray['pad']); - $this->command = $clipObj->makeDeleteCmdArray($this->command); - } - - if ($this->clipboardCommandArray['el']) { - $this->clipboardCommandArray['setP'] = 'normal'; - $clipObj->setCmd($this->clipboardCommandArray); - $clipObj->cleanCurrent(); - $clipObj->endClipboard(); - } - } - } } diff --git a/Classes/Controller/LatestController.php b/Classes/Controller/LatestController.php index 9dbfd3be2af3280b1ad0f418bdb1d890feb0890d..bca9fa889f123eee4517e583c31963d27e6dcb4a 100644 --- a/Classes/Controller/LatestController.php +++ b/Classes/Controller/LatestController.php @@ -115,7 +115,6 @@ class LatestController extends AbstractController { } } - $this->view->assign('newsMetaData', $newsMetaData); } diff --git a/Classes/Controller/OverviewController.php b/Classes/Controller/OverviewController.php index f025892a899767d44c88092cc603c8654ab2ec3b..809957e9b290811bf590d2be13d92333ca02cfa3 100644 --- a/Classes/Controller/OverviewController.php +++ b/Classes/Controller/OverviewController.php @@ -58,14 +58,36 @@ class OverviewController extends AbstractController { */ protected $newsRepository; + /** + * @param CategoryRepository $categoryRepository + */ + public function injectCategoryRepository(CategoryRepository $categoryRepository + ) { + $this->categoryRepository = $categoryRepository; + } + + /** + * @param NewsRepository $newsRepository + */ + public function injectNewsRepository(NewsRepository $newsRepository) { + $this->newsRepository = $newsRepository; + } + + /** + * @param TagRepository $tagRepository + */ + public function injectTagRepository(TagRepository $tagRepository) { + $this->tagRepository = $tagRepository; + } + /** * Initialize the overviewAction to set the currentPageBrowserPage parameter * * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException */ - public function initializeOverviewAction(){ + public function initializeOverviewAction() { $currentPageBrowserPage = (int) GeneralUtility::_GP('tx_sgnews_pagebrowser')['currentPage']; - if($currentPageBrowserPage > 0){ + if ($currentPageBrowserPage > 0) { $this->request->setArgument('currentPageBrowserPage', $currentPageBrowserPage); } } @@ -81,7 +103,7 @@ class OverviewController extends AbstractController { * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ - public function overviewAction(array $newsFilter = [], $currentPageBrowserPage = 0) { + public function overviewAction(array $newsFilter = [], int $currentPageBrowserPage = 0) { switch ((int) $this->settings['groupBy']) { case 1: $this->overviewWithCategories([], [], $newsFilter, $currentPageBrowserPage); @@ -98,10 +120,9 @@ class OverviewController extends AbstractController { /** * Highlights the best fitting news in the meta data of the page * - * @param array $categoryIds - * @param array $tagIds + * @param array|null $categoryIds + * @param array|null $tagIds * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException - * @throws \InvalidArgumentException */ protected function highlightBestFitNews(array $categoryIds = NULL, array $tagIds = NULL) { $startTime = (int) $this->settings['starttime']; @@ -143,7 +164,7 @@ class OverviewController extends AbstractController { * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ protected function overviewWithCategories( - array $newsByCategory = [], array $allNews = [], array $newsFilter = [], $currentPageBrowserPage = 0 + array $newsByCategory = [], array $allNews = [], array $newsFilter = [], int $currentPageBrowserPage = 0 ) { $newsLimitPerCategory = (int) $this->settings['newsLimit']; $this->categoryRepository->setDefaultOrderings(['sorting' => Query::ORDER_ASCENDING]); @@ -192,7 +213,7 @@ class OverviewController extends AbstractController { $categoriesById = []; $newsMetaData = []; foreach ($categories as $category) { - /** @var $category Category */ + /** @var Category $category */ $categoryId = $category->getUid(); $categoryIdsForSelect = [$categoryId]; $categoryIds[] = $category->getUid(); @@ -213,13 +234,13 @@ class OverviewController extends AbstractController { } foreach ($categoryIdsForSelect as $categoryIdsForSelectId) { $news = $this->newsRepository->findAllSortedNewsByCategories( - [$categoryIdsForSelectId], $newsLimitPerCategory, $offset, $sortBy, $tagIds, $startTime, $endTime, $sortDirection + [$categoryIdsForSelectId], $newsLimitPerCategory, $offset, $sortBy, $tagIds, $startTime, $endTime, + $sortDirection ); $newsMetaData[$categoryIdsForSelectId] = []; foreach ($news as $newsEntry) { /** @var News $newsEntry */ - $categoryId = $newsEntry->getPid(); $category = $categoriesById[$categoryIdsForSelectId]; if (!$category) { // Category isn't visible. @@ -239,9 +260,9 @@ class OverviewController extends AbstractController { continue; } - /** @var $category Category */ + /** @var Category $category */ if (isset($newsByCategory[$categoryId])) { - /** @var $category Category */ + /** @var Category $category */ $newsByCategory[$categoryId]['newsMetaData'] = array_merge($newsByCategory[$categoryId]['newsMetaData'], $newsMetaData[$categoryId], $newsFilter); } else { @@ -325,7 +346,7 @@ class OverviewController extends AbstractController { * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ protected function overviewWithTags( - array $newsByTag = [], array $allNews = [], array $newsFilter = [], $currentPageBrowserPage = 0 + array $newsByTag = [], array $allNews = [], array $newsFilter = [], int $currentPageBrowserPage = 0 ) { $startTime = (int) $this->settings['starttime']; $endTime = (int) $this->settings['endtime']; @@ -426,6 +447,7 @@ class OverviewController extends AbstractController { if (!isset($categoriesById[$categoryId])) { $categoriesById[$categoryId] = $this->categoryRepository->findByUid($categoryId); } + /** @var Category $category */ $category = $categoriesById[$categoryId]; if (!$category) { // Category isn't visible. @@ -473,35 +495,13 @@ class OverviewController extends AbstractController { * * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException */ - public function initializeOverviewWithoutCategoriesAction(){ + public function initializeOverviewWithoutCategoriesAction() { $currentPageBrowserPage = (int) GeneralUtility::_GP('tx_sgnews_pagebrowser')['currentPage']; - if($currentPageBrowserPage > 0){ + if ($currentPageBrowserPage > 0) { $this->request->setArgument('currentPageBrowserPage', $currentPageBrowserPage); } } - /** - * @param CategoryRepository $categoryRepository - */ - public function injectCategoryRepository(CategoryRepository $categoryRepository - ) { - $this->categoryRepository = $categoryRepository; - } - - /** - * @param NewsRepository $newsRepository - */ - public function injectNewsRepository(NewsRepository $newsRepository) { - $this->newsRepository = $newsRepository; - } - - /** - * @param TagRepository $tagRepository - */ - public function injectTagRepository(TagRepository $tagRepository) { - $this->tagRepository = $tagRepository; - } - /** * Renders the news in a paginated list * @@ -515,7 +515,7 @@ class OverviewController extends AbstractController { * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ protected function overviewWithoutCategoriesAction( - array $newsMetaData = [], array $newsFilter = NULL, $currentPageBrowserPage = 0 + array $newsMetaData = [], array $newsFilter = NULL, int $currentPageBrowserPage = 0 ) { // remember selection of the filter values, if any $selectedTag = $this->tagRepository->findByUid((int) $newsFilter['tag']); @@ -544,7 +544,9 @@ class OverviewController extends AbstractController { $categoriesById[$category->getUid()] = $category; $categoryIds[] = $category->getUid(); if ($category->_getProperty('_languageUid') > 0) { - $originalLangCategory = $this->categoryRepository->findOriginalLanguageById($category->getUid()); + $originalLangCategory = $this->categoryRepository->findOriginalLanguageById( + $category->getUid() + ); if ($originalLangCategory) { $categoryIds[] = $originalLangCategory->getUid(); $categoriesById[$originalLangCategory->getUid()] = $originalLangCategory; diff --git a/Classes/Controller/PageBrowserController.php b/Classes/Controller/PageBrowserController.php deleted file mode 100644 index 519d4d430db156bdea5b3010923427843e56d3ad..0000000000000000000000000000000000000000 --- a/Classes/Controller/PageBrowserController.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -namespace SGalinski\SgNews\Controller; - -/*************************************************************** - * Copyright notice - * - * (c) sgalinski Internet Services (https://www.sgalinski.de) - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; - -/** - * Controller that handles the page browser. - */ -class PageBrowserController extends ActionController { - /** - * @var string - */ - protected $pageParameterName = ''; - - /** - * @var int - */ - protected $numberOfPages = 0; - - /** - * @var int - */ - protected $currentPage = 0; - - /** - * @var int - */ - protected $pagesBefore = 0; - - /** - * @var int - */ - protected $pagesAfter = 0; - - /** - * @var bool - */ - protected $enableMorePages = FALSE; - - /** - * @var bool - */ - protected $enableLessPages = FALSE; - - /** - * Renders the index view. - * - * @param int $currentPage - * @return void - */ - public function indexAction($currentPage = 0) { - $this->currentPage = (int) $currentPage; - - $this->initializeConfiguration(); - $this->addDataToView(); - } - - /** - * Initializes the configuration. - * - * @return void - */ - protected function initializeConfiguration() { - $this->pageParameterName = 'tx_sgnews_pagebrowser[currentPage]'; - $this->numberOfPages = (int) $this->settings['numberOfPages']; - $this->pagesBefore = (int) $this->settings['pagesBefore']; - $this->pagesAfter = (int) $this->settings['pagesAfter']; - $this->enableMorePages = (bool) $this->settings['enableMorePages']; - $this->enableLessPages = (bool) $this->settings['enableLessPages']; - } - - /** - * Adds the necessary data to the view. - * - * @return void - */ - protected function addDataToView() { - if ($this->numberOfPages <= 1) { - $this->view = NULL; - return; - } - - $pageLinks = []; - $start = \max($this->currentPage - $this->pagesBefore, 0); - $end = \min($this->numberOfPages, $this->currentPage + $this->pagesAfter + 1); - for ($i = $start; $i < $end; $i++) { - $pageLinks[] = [ - 'number' => $i + 1, - 'link' => $this->getPageLink($i), - 'isCurrentPage' => $i === $this->currentPage, - ]; - } - - $this->view->assignMultiple( - [ - 'enableLessPages' => $this->enableLessPages, - 'enableMorePages' => $this->enableMorePages, - 'previousLink' => $this->getPageLink($this->currentPage - 1), - 'nextLink' => $this->getPageLink($this->currentPage + 1), - 'enableLessPagesLink' => $this->getPageLink($this->currentPage - $this->pagesBefore - 1), - 'enableMorePagesLink' => $this->getPageLink($this->currentPage + $this->pagesAfter + 1), - 'pageLinks' => $pageLinks, - 'prevPageExist' => $this->currentPage > 0, - 'showLessPages' => ($this->currentPage - $this->pagesBefore) > 0, - 'showNextPages' => ($this->currentPage + $this->pagesAfter + 1) < $this->numberOfPages, - 'nextPageExist' => $this->currentPage < ($this->numberOfPages - 1), - ] - ); - } - - /** - * Generates page link. Keeps all current URL parameters except for cHash and tx_pagebrowse_pi1[page]. - * - * @param int $page Page number starting from 1 - * @return string - */ - protected function getPageLink($page): string { - return $this->uriBuilder->reset()->setAddQueryString(TRUE) - ->uriFor('index', ['currentPage' => $page,]); - } -} diff --git a/Classes/ViewHelpers/Backend/ControlViewHelper.php b/Classes/ViewHelpers/Backend/ControlViewHelper.php index a5bcaf803c97380a5866781ebf0c402dc97ee975..9ec52630991bc5cd0841d9dcf47903d301c01cc7 100644 --- a/Classes/ViewHelpers/Backend/ControlViewHelper.php +++ b/Classes/ViewHelpers/Backend/ControlViewHelper.php @@ -27,7 +27,6 @@ namespace SGalinski\SgNews\ViewHelpers\Backend; ***************************************************************/ use SGalinski\SgNews\ViewHelpers\AbstractViewHelper; -use TYPO3\CMS\Backend\Clipboard\Clipboard; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; @@ -49,7 +48,6 @@ class ControlViewHelper extends AbstractViewHelper { $this->registerArgument('table', 'string', 'The table to control', TRUE); $this->registerArgument('row', 'mixed', 'The row of the record', TRUE); $this->registerArgument('sortingData', 'array', 'The sorting data', FALSE, []); - $this->registerArgument('clipboard', 'bool', 'Use the clipboard', FALSE, FALSE); } /** @@ -63,7 +61,6 @@ class ControlViewHelper extends AbstractViewHelper { $table = $this->arguments['table']; $row = $this->arguments['row']; $sortingData = $this->arguments['sortingData']; - $clipboard = $this->arguments['clipboard']; if (!is_array($row)) { $row = BackendUtility::getRecord($table, $row->getUid()); } @@ -84,15 +81,8 @@ class ControlViewHelper extends AbstractViewHelper { } $out = $databaseRecordList->makeControl($table, $row); - if ($clipboard) { - $databaseRecordList->MOD_SETTINGS['clipBoard'] = TRUE; - $databaseRecordList->clipObj = GeneralUtility::makeInstance(Clipboard::class); - $databaseRecordList->clipObj->initializeClipboard(); - $GLOBALS['SOBE'] = $databaseRecordList; - $out .= $databaseRecordList->makeClip($table, $row); - } - if ($table === 'pages') { + /** @var IconFactory $iconFactory */ $iconFactory = GeneralUtility::makeInstance(IconFactory::class); $buttonLabel = LocalizationUtility::translate('backend.button.editPageContent', 'SgNews'); $path = ''; diff --git a/Classes/ViewHelpers/PageBrowserViewHelper.php b/Classes/ViewHelpers/PageBrowserViewHelper.php index b117695b1233e9fda7f722cfb1d4cb67655489f8..89d5e2f7f9a32e81c7da457f3095b17c82822722 100644 --- a/Classes/ViewHelpers/PageBrowserViewHelper.php +++ b/Classes/ViewHelpers/PageBrowserViewHelper.php @@ -26,9 +26,10 @@ namespace SGalinski\SgNews\ViewHelpers; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use TYPO3\CMS\Extbase\Object\ObjectManager; +use TYPO3\CMS\Core\TypoScript\TypoScriptService; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; -use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; /** * View helper that renders a page browser based upon the pagebrowse extension. @@ -47,20 +48,6 @@ class PageBrowserViewHelper extends AbstractViewHelper { */ protected $escapeOutput = FALSE; - /** - * @var ObjectManager - */ - protected $objectManager; - - /** - * Inject the ObjectManager - * - * @param ObjectManager $objectManager - */ - public function injectObjectManager(ObjectManager $objectManager) { - $this->objectManager = $objectManager; - } - /** * Initialize the ViewHelpers arguments */ @@ -76,13 +63,48 @@ class PageBrowserViewHelper extends AbstractViewHelper { * @throws \UnexpectedValueException */ public function render(): string { - $numberOfPages = $this->arguments['numberOfPages']; - $configuration = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_sgnews.']['pagebrowser.']; - $configuration['settings.']['numberOfPages'] = (int) $numberOfPages; + /** @var TypoScriptService $typoScriptService */ + $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class); + $configuration = $typoScriptService->convertTypoScriptArrayToPlainArray( + $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_sgnews.'] + ); + $view = GeneralUtility::makeInstance(StandaloneView::class); + $view->setRenderingContext($this->renderingContext); + $view->setTemplateRootPaths($configuration['view']['templateRootPaths']); + $view->setPartialRootPaths($configuration['view']['partialRootPaths']); + $view->setLayoutRootPaths($configuration['view']['layoutRootPaths']); + $view->setTemplate('PageBrowser/Index'); + $pageBrowserVars = GeneralUtility::_GP('tx_sgnews_pagebrowser'); + if (isset($pageBrowserVars['currentPage']) && (int) $pageBrowserVars['currentPage'] > 0) { + $currentPage = (int) $pageBrowserVars['currentPage']; + } else { + $currentPage = 0; + } + + $pageLinks = []; + $start = \max($currentPage - 2, 0); + $end = \min($this->arguments['numberOfPages'], $currentPage + 2); + for ($i = $start; $i < $end; $i++) { + $pageLinks[] = [ + 'number' => $i + 1, + 'page' => $i, + 'isCurrentPage' => $i === $currentPage, + ]; + } - /** @var ContentObjectRenderer $contentObject */ - $contentObject = $this->objectManager->get(ContentObjectRenderer::class); - $contentObject->start([]); - return $contentObject->cObjGetSingle('USER', $configuration); + $view->assignMultiple( + [ + 'enableLessPages' => 1, + 'enableMorePages' => 1, + 'pageLinks' => $pageLinks, + 'currentPage' => $currentPage, + 'prevPageExist' => $currentPage > 1, + 'showLessPages' => ($currentPage - 1) > 1, + 'showNextPages' => ($currentPage + 2) < $this->arguments['numberOfPages'], + 'nextPageExist' => $currentPage < $this->arguments['numberOfPages'] - 1, + 'numberOfPages' => $this->arguments['numberOfPages'] + ] + ); + return $view->render(); } } diff --git a/Configuration/FlexForms/Latest.xml b/Configuration/FlexForms/Latest.xml index ea0df7a698559ddd22c366480b6f8c9e430c8bf3..9592c27ca3da78f52cb479b9399c136a3b60c802 100644 --- a/Configuration/FlexForms/Latest.xml +++ b/Configuration/FlexForms/Latest.xml @@ -32,7 +32,7 @@ <size>5</size> <maxitems>99</maxitems> <foreign_table>pages</foreign_table> - <foreign_table_where>AND doktype = 117 ORDER BY title</foreign_table_where> + <foreign_table_where>AND pages.sys_language_uid IN (-1, 0) AND pages.doktype = 117 ORDER BY pages.title</foreign_table_where> </config> </TCEforms> </settings.categories> diff --git a/Configuration/TypoScript/Frontend/constants.typoscript b/Configuration/TypoScript/Frontend/constants.typoscript index da6da1a5d0022f813332387bbadee4dc55c9b18b..34a9c4da599228c1cc1b6f3069b7b9a49eab04db 100644 --- a/Configuration/TypoScript/Frontend/constants.typoscript +++ b/Configuration/TypoScript/Frontend/constants.typoscript @@ -20,18 +20,4 @@ plugin.tx_sgnews { # sort direction (DESC / ASC) sortDirection = DESC } - - pagebrowser.settings { - # Number of page links to show before the current page - pagesBefore = 1 - - # Number of page links to show before the current page - pagesAfter = 1 - - # Enables section for "more" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...). Notice that you can also hide it by emptying corresponding template section. - enableMorePages = 1 - - # Enables section for "less" pages. This section is shown after links to next pages, normally like three dots (... 1 2 3) Notice that you can also hide it by emptying corresponding template section. - enableLessPages = 1 - } } diff --git a/Configuration/TypoScript/Frontend/setup.typoscript b/Configuration/TypoScript/Frontend/setup.typoscript index 00c3c700ec0b91d47334ee5dd5c09c8f33262320..9a52fd4ef64e299d3c2fd12ce028ac75c9ebbf6a 100644 --- a/Configuration/TypoScript/Frontend/setup.typoscript +++ b/Configuration/TypoScript/Frontend/setup.typoscript @@ -66,17 +66,14 @@ plugin.tx_sgnews { view { templateRootPaths { 0 = {$plugin.tx_sgnews.view.templateRootPath} - 1 = } partialRootPaths { 0 = {$plugin.tx_sgnews.view.partialRootPath} - 1 = } layoutRootPaths { 0 = {$plugin.tx_sgnews.view.layoutRootPath} - 1 = } } @@ -121,41 +118,6 @@ plugin.tx_sgnews { legacy { enableLegacyFlashMessageHandling = 0 } - - pagebrowser = USER - pagebrowser { - userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run - extensionName = SgNews - pluginName = PageBrowser - vendorName = SGalinski - controller = PageBrowser - action = index - view < plugin.tx_sgnews.view - persistence < plugin.tx_sgnews.persistence - features < plugin.tx_sgnews.features - # cHash can't be generated for pageBrowser call; will cause a 404 error if not set to 0 - features.requireCHashArgumentForActionArguments = 0 - legacy < plugin.tx_sgnews.legacy - settings { - # Number of page links to show before the current page - pagesBefore = {$plugin.tx_sgnews.pagebrowser.settings.pagesBefore} - - # Number of page links to show before the current page - pagesAfter = {$plugin.tx_sgnews.pagebrowser.settings.pagesAfter} - - # Enables section for "more" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...). Notice that you can also hide it by emptying corresponding template section. - enableMorePages = {$plugin.tx_sgnews.pagebrowser.settings.enableMorePages} - - # Enables section for "less" pages. This section is shown after links to next pages, normally like three dots (... 1 2 3). Notice that you can also hide it by emptying corresponding template section. - enableLessPages = {$plugin.tx_sgnews.pagebrowser.settings.enableLessPages} - - # The number of the pages - numberOfPages = 0 - - # The current page - currentPage = 0 - } - } } plugin.tx_sgcomments { diff --git a/README.md b/README.md index 8c4c8d7f82f9b06e94eb9891675286c8f14bd78f..d4a25ba0780ea166aee0998e5b5a0b7b9c731da0 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,12 @@ additional meta information. ## Integration -Before using sg_news, you need to supply your frontend some information on how the extension needs to be integrated into your template. +Before using sg_news, you need to supply your frontend some information on how the extension needs to be integrated into +your template. -As the extension itself provides two new [doktypes](https://docs.typo3.org/typo3cms/CoreApiReference/PageTypes/Index.html), you can simply add a switch case to your Fluid template to provide different rendering paths. +As the extension itself provides two +new [doktypes](https://docs.typo3.org/typo3cms/CoreApiReference/PageTypes/Index.html), you can simply add a switch case +to your Fluid template to provide different rendering paths. ### Example @@ -70,24 +73,28 @@ lib.pageTemplate.default { } ``` -In this example we will load the first column for the intro section by default, -and the second column in the backend for the content below that. +In this example we will load the first column for the intro section by default, and the second column in the backend for +the content below that. -The news category (doktype 117) will render by default not the content on the page alone, but also the default category listing. +The news category (doktype 117) will render by default not the content on the page alone, but also the default category +listing. -With our example we don't want the intro section (116) and the default content to be rendered because the extension handles those parts. +With our example we don't want the intro section (116) and the default content to be rendered because the extension +handles those parts. -The single news plugin also needs some additional information so it can get the base content. -By default, it will resolve to the following code if not provided by you: +The single news plugin also needs some additional information so it can get the base content. By default, it will +resolve to the following code if not provided by you: ```TypoScript lib.mainContent < styles.content.col1 ``` ### Example integration into your page template + Finally, you need to output the `INTRO` and `CONTENT` variable in your page template: ```HTML + <main> <!--TYPO3SEARCH_begin--> <f:if condition="{INTRO}"> @@ -110,28 +117,28 @@ To enable the author id mapping in TYPO3 9, you need to add this routeEnhancer c ```YAML routeEnhancers: - NewsByAuthor: - type: Extbase - extension: SgNews - plugin: NewsByAuthor - routes: - - routePath: '/{authorTitle}' - _controller: 'NewsByAuthor::list' - _arguments: { 'authorTitle': authorId } - defaultController: 'NewsByAuthor::list' - aspects: - authorTitle: - type: PersistedAliasMapper - tableName: tx_sgnews_domain_model_author - routeFieldName: path_segment + NewsByAuthor: + type: Extbase + extension: SgNews + plugin: NewsByAuthor + routes: + - routePath: '/{authorTitle}' + _controller: 'NewsByAuthor::list' + _arguments: { 'authorTitle': authorId } + defaultController: 'NewsByAuthor::list' + aspects: + authorTitle: + type: PersistedAliasMapper + tableName: tx_sgnews_domain_model_author + routeFieldName: path_segment ``` ### Tags + In addition to categories, multiple tags can be created and specified for each news page. -Tags can be created by adding sys_category records to the root page of the news block (blog). -In order to differentiate each block's tags from the others, -the PageTS value of `TCEFORM.pages.tx_sgnews_tags.PAGE_TSCONFIG_ID` +Tags can be created by adding sys_category records to the root page of the news block (blog). In order to differentiate +each block's tags from the others, the PageTS value of `TCEFORM.pages.tx_sgnews_tags.PAGE_TSCONFIG_ID` can be set for each of the blocks containing the pid value for the selectable tags. To make sure that only the correct tags are displayed in the FE, the `plugin.tx_sgnews.settings.tagPid` @@ -143,11 +150,13 @@ Add the plugin **News Overview** and optionally the plugin **Latest News** to a After that you must create sites of type **Category** sites below the blog page level and name them accordingly. -On the next lower page level of each **Category** you can create pages of type **News**. -On these pages you can use all your usual content elements to visualize your news entries belonging to the specific category. +On the next lower page level of each **Category** you can create pages of type **News**. On these pages you can use all +your usual content elements to visualize your news entries belonging to the specific category. ### Plugins -General settings for the plugins can be found in the **Frontend/setup.typoscript** and **Frontend/constants.typoscript** files: + +General settings for the plugins can be found in the **Frontend/setup.typoscript** and **Frontend/constants.typoscript** +files: *setup.typoscript* @@ -182,13 +191,16 @@ settings { This extension comes with several plugins to display and categorize news: ###### News Overview + Provides an overview over all news. Additionally, there is a tab navigation for groups of news. Plugin options: -- **Group By**: By which aspect should your news be grouped in the tab navigation (none, category, tags) -- **News Limit**: The maximum amount news to be displayed. Further news can be displayed after the user clicks a button. -- **Only news within this page section**: Should only news from subpages be shown, or from all sites in this TYPO3 instance? +- **Group By**: By which aspect should your news be grouped in the tab navigation (none, category, tags) +- **News Limit**: The maximum amount news to be displayed. Further news can be displayed after the user clicks a + button. +- **Only news within this page section**: Should only news from subpages be shown, or from all sites in this TYPO3 + instance? --- @@ -200,7 +212,8 @@ Plugin options: - **News Limit per Page**: The maximum amount of news to be shown. - **Categories**: Here you can select which categories you want to be included (If none are selected, all are shown). -- **Tags**: Here you can select which tags the news entries need to have to be shown here (If none are selected, all are shown). +- **Tags**: Here you can select which tags the news entries need to have to be shown here (If none are selected, all are + shown). --- @@ -211,7 +224,9 @@ Provides a new page type **News** in the **Page Module**, that renders the conte --- ###### News Feed -Provides an RSS Feed **news.xml** as a typenum. The typenum is defined in the **Frontend/setup.typoscript** and needs to be included in your TypoScript template: + +Provides an RSS Feed **news.xml** as a typenum. The typenum is defined in the **Frontend/setup.typoscript** and needs to +be included in your TypoScript template: ```Typoscript # news feed as own page type @@ -258,7 +273,10 @@ newsFeed { } } ``` -If you need multiple news feeds with different content, you can duplicate the provided configuration and modify the typenum & parameters like showCategories / showTags: + +If you need multiple news feeds with different content, you can duplicate the provided configuration and modify the +typenum & parameters like showCategories / showTags: + ```Typoscript myOtherNewsFeed < newsFeed myOtherNewsFeed.typeNum = ENTER_YOUR_TYPENUM_HERE @@ -266,11 +284,12 @@ myOtherNewsFeed.10.settings.showCategories = myOtherNewsFeed.10.settings.showTags = ``` - --- + ###### PageBrowser -Automatically adds a pagination to the **News Overview** and **List News** plugins. -You find the settings in the **Fontend/constants.typoscript** configuration file: + +Automatically adds a pagination to the **News Overview** and **List News** plugins. You find the settings in the ** +Fontend/constants.typoscript** configuration file: ```Typoscript pagebrowser.settings { @@ -292,29 +311,37 @@ pagebrowser.settings { ###### addLike -Automatically adds an AJAX like button to each single news entry. -Make sure that the extension **sg_ajax** is installed, otherwise this feature will be disabled. -If it should be like this, then make sure to remove this button from the sg_news default templates. +Automatically adds an AJAX like button to each single news entry. Make sure that the extension **sg_ajax** is installed, +otherwise this feature will be disabled. If it should be like this, then make sure to remove this button from the +sg_news default templates. ## The Backend Module After a successful Installation, you have a new module in the "WEB" section of your TYPO3 Backend. -Clicking on it loads the administration panel. Using the drop-down above you can switch between the different languages set up in your TYPO3 installation. -Once you have selected a language, the module will display the news records and tag filter corresponding to that language. +Clicking on it loads the administration panel. Using the drop-down above you can switch between the different languages +set up in your TYPO3 installation. Once you have selected a language, the module will display the news records and tag +filter corresponding to that language. -If you have selected a root-page in the page-tree, the module will display a list of news pages corresponding to this root page, with respect to the current user permissions. Here you can filter the results by Category, Tags or by a search word. +If you have selected a root-page in the page-tree, the module will display a list of news pages corresponding to this +root page, with respect to the current user permissions. Here you can filter the results by Category, Tags or by a +search word. -Selecting a News Category Page in the page-tree, will display the list of news pages in this Category. The same functionality as for the root page, but without the category filter. +Selecting a News Category Page in the page-tree, will display the list of news pages in this Category. The same +functionality as for the root page, but without the category filter. ***Note*** : The search-word filter is language-sensitive. -You can also use the '<img height="20px" width="20px" src="https://camo.githubusercontent.com/cd0d2f12f28169acfbafd1c8bf8f291155f3d210/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d6e65772e737667"> Add News Record' and the '<img height="20px" width="20px" src="https://camo.githubusercontent.com/cd0d2f12f28169acfbafd1c8bf8f291155f3d210/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d6e65772e737667"> Add News Category' buttons to add News/Cateogry pages under the currelty selected page where available. - +You can also use +the '<img height="20px" width="20px" src="https://camo.githubusercontent.com/cd0d2f12f28169acfbafd1c8bf8f291155f3d210/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d6e65772e737667"> +Add News Record' and +the '<img height="20px" width="20px" src="https://camo.githubusercontent.com/cd0d2f12f28169acfbafd1c8bf8f291155f3d210/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d6e65772e737667"> +Add News Category' buttons to add News/Cateogry pages under the currelty selected page where available. ### Options for your news list items -For each news item in the paginated result list you have multiple editing/administration options, depending on the logged-in user's permissions. +For each news item in the paginated result list you have multiple editing/administration options, depending on the +logged-in user's permissions. You can click a list item's title to edit it (language sensitive) or use the menu buttons: @@ -348,26 +375,31 @@ You can click a list item's title to edit it (language sensitive) or use the men <br> <img height="20px" width="20px" src="https://camo.githubusercontent.com/2ba239d52c48bbcdc9d059a8aeca2eb7eb41a07a/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d6f70656e2e737667"> Edit Page Content -You can also handle the localisation of news pages for all the languages in your TYPO3 installation by using the localisation links under each record's title: +You can also handle the localisation of news pages for all the languages in your TYPO3 installation by using the +localisation links under each record's title: - **full-opacity flag icon** : Edit the existing localisation record -- **half-transparent flag icon with <img height="14px" width="14px" src="https://camo.githubusercontent.com/b10f4d50dc21b152cde15cef5983c139e77b1c34/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f6f7665726c61792f6f7665726c61792d6e65772e737667"/> overlay** : Create new localisation record +- **half-transparent flag icon + with <img height="14px" width="14px" src="https://camo.githubusercontent.com/b10f4d50dc21b152cde15cef5983c139e77b1c34/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f6f7665726c61792f6f7665726c61792d6e65772e737667"/> + overlay** : Create new localisation record ***Note*** : The extension also adds a News Module link in the Page Module of News/Category pages - ## Migrating tx_news to sg_news -This extension comes with the command controller task **** to migirate tx_news entries to sg_news. The task comes with the following parameters: +This extension comes with the command controller task **** to migirate tx_news entries to sg_news. The task comes with +the following parameters: -- **copyPageId** : You will need a template site, which will be the basis of each new news record. Create your content elements accordingly on this site. +- **copyPageId** : You will need a template site, which will be the basis of each new news record. Create your content + elements accordingly on this site. - **categoryPid** : This needs to be the category page id, you want your news to be children of. - **year** : Only news of this year will be migrated -- **languageMapAsJson** : a json string, mapping language ids (old => new). this is needed if the sys_language_uids have changed +- **languageMapAsJson** : a json string, mapping language ids (old => new). this is needed if the sys_language_uids have + changed - **categoryMapAsJson** : a json string, mapping sys_category ids (old => new). - **pId** : only news from that pid will be migrated ### Migrating File References -To use your old file references, you need to import your sys_file and sys_file_reference_table as sys_file_news_migration and sys_file_reference -into your database. The Filepaths must not change! +To use your old file references, you need to import your sys_file and sys_file_reference_table as +sys_file_news_migration and sys_file_reference into your database. The Filepaths must not change! diff --git a/Resources/Private/Templates/Backend/Index.html b/Resources/Private/Templates/Backend/Index.html index 25793dcfceba2699f395b63a23c4b9df3bae80df..164b931cd4f72f930dde5780cecb47611254e9f0 100644 --- a/Resources/Private/Templates/Backend/Index.html +++ b/Resources/Private/Templates/Backend/Index.html @@ -87,7 +87,7 @@ </td> <td nowrap="nowrap" class="col-control"> <f:format.raw> - <sg:backend.control table="pages" row="{singleNews}" clipboard="1" /> + <sg:backend.control table="pages" row="{singleNews}" /> </f:format.raw> </td> </tr> diff --git a/Resources/Private/Templates/PageBrowser/Index.html b/Resources/Private/Templates/PageBrowser/Index.html index 3350986bd86946d06a051aa604e89c7a8ed838d4..ada7581c1721836d540fb88f7b32db8a9a704079 100644 --- a/Resources/Private/Templates/PageBrowser/Index.html +++ b/Resources/Private/Templates/PageBrowser/Index.html @@ -8,9 +8,11 @@ <f:if condition="{prevPageExist}"> <f:then> <li class="tx-pagebrowse-prev"> - <a href="{previousLink}" aria-label="Previous"> + <f:variable name="prevPage" value="{currentPage - 1}" /> + <f:link.action additionalParams="{tx_sgnews_pagebrowser: {currentPage: prevPage}}" + additionalAttributes="{aria-label: 'Previous'}"> « - </a> + </f:link.action> </li> </f:then> <f:else> @@ -26,9 +28,10 @@ <f:if condition="{enableLessPages} && {showLessPages}"> <li> - <a href="{enableLessPagesLink}"> + <f:variable name="lessPage" value="{currentPage - 2}" /> + <f:link.action additionalParams="{tx_sgnews_pagebrowser: {currentPage: lessPage}}"> ... - </a> + </f:link.action> </li> </f:if> @@ -46,9 +49,9 @@ </f:then> <f:else> <li class="tx-pagebrowse-page"> - <a href="{pageLink.link}"> + <f:link.action additionalParams="{tx_sgnews_pagebrowser: {currentPage: pageLink.page}}"> {pageLink.number} - </a> + </f:link.action> </li> </f:else> </f:if> @@ -56,18 +59,21 @@ <f:if condition="{enableMorePages} && {showNextPages}"> <li> - <a href="{enableMorePagesLink}"> + <f:variable name="morePage" value="{currentPage + 2}" /> + <f:link.action additionalParams="{tx_sgnews_pagebrowser: {currentPage: morePage}}"> ... - </a> + </f:link.action> </li> </f:if> <f:if condition="{nextPageExist}"> <f:then> <li class="tx-pagebrowse-next"> - <a href="{nextLink}" aria-label="Next"> + <f:variable name="nextPage" value="{currentPage + 1}" /> + <f:link.action additionalParams="{tx_sgnews_pagebrowser: {currentPage: nextPage}}" + additionalAttributes="{aria-label: 'Next'}"> » - </a> + </f:link.action> </li> </f:then> <f:else> diff --git a/Resources/Public/JavaScript/ScrollBrowser.js b/Resources/Public/JavaScript/ScrollBrowser.js index 921313fed42715d94bc769e01b6089733119aad4..ae7c001d1e0271f06618eaf6f5adb3da97a3e341 100644 --- a/Resources/Public/JavaScript/ScrollBrowser.js +++ b/Resources/Public/JavaScript/ScrollBrowser.js @@ -10,20 +10,20 @@ export default class ScrollBrowser { this._element.style.display = 'none'; this._loadingIndicator = this._element.lastElementChild; if (!this._loadingIndicator) { - return; + return; } - this.url = document.querySelector('.tx-pagebrowse-next a').getAttribute('href'); + this.url = this._element.querySelector('.tx-pagebrowse-next a').getAttribute('href'); window.addEventListener('scroll', this.checkAndLoad.bind(this)); // Initial check this.checkAndLoad(); - } + } /** * Checks and loads the next page if required */ - checkAndLoad() { + checkAndLoad() { const recordLockedOrNotInPosition = this.lock || !this.checkPosition(); const urlIsInvalid = typeof this.url === 'undefined' || this.url === null || this.url === this.lastUrl; if (recordLockedOrNotInPosition || urlIsInvalid) { @@ -37,9 +37,9 @@ export default class ScrollBrowser { /** * Fetches the content of the next page via Ajax */ - fetchContent() { + fetchContent() { return new Promise((resolve) => { - const request = new XMLHttpRequest(); + const request = new XMLHttpRequest(); request.onreadystatechange = () => { if (request.readyState === XMLHttpRequest.DONE) { if (request.status === 200) { @@ -53,14 +53,14 @@ export default class ScrollBrowser { ); request.send(); }); - } + } /** * Adds fetched DOM nodes to the list * * @param {String} response The HTML of the AJAX response */ - displayNewData(response) { + displayNewData(response) { const parser = new DOMParser(); const doc = parser.parseFromString(response, 'text/html'); const results = Array.from(doc.querySelectorAll('.tx-sgnews-list')); @@ -74,26 +74,27 @@ export default class ScrollBrowser { if (!resultList) { resultList = document.querySelector('.tx-sgnews-list'); } - children.forEach((child) => { - resultList.appendChild(child); - }); - this._loadingIndicator = resultList.lastElementChild; + if (resultList) { + children.forEach((child) => { + resultList.appendChild(child); + }); + this._loadingIndicator = resultList.lastElementChild; + } }); this.lastUrl = this.url; this.url = doc.querySelector('.tx-pagebrowse-next a').getAttribute('href'); this.lock = false; - } + } /** * Checks the current position of the scrollbar in relation to the position of the load indicator. * * @return boolean */ - - checkPosition() { + checkPosition() { const loadingIndicatorPosition = this._loadingIndicator.getBoundingClientRect(); const windowScrollPosition = window.scrollY; return (windowScrollPosition > (loadingIndicatorPosition.top - 6000)); - } + } } diff --git a/UPGRADE_TO_TYPO3_9.md b/UPGRADE_TO_TYPO3_9.md deleted file mode 100644 index 361d2e3fe2518a10b99a7c95f1453e15eac4d032..0000000000000000000000000000000000000000 --- a/UPGRADE_TO_TYPO3_9.md +++ /dev/null @@ -1,34 +0,0 @@ -# Migration to TYPO3 9 - -Unfortunately TYPO3 fucked it completely up. There are several issues with translations afterwards that can only be -solved by doing manual work. - -## Migrate Tags - -All tags must be synchronized with the translated pages as pages_language_overlay was dropped and TYPO3 didn't handled this -properly. If you don't use tags, you are a lucky guy. If you used tags, you can now be lucky. Just execute the -following SQL. - -``` -# Hole alle Tags von Seiten, welche Ãœbersetzungen haben mit zugehörigem Page-Record der Ãœbersetzung -# UND synchronisiere die neuen Tags für die Ãœbersetzungen -INSERT INTO sys_category_record_mm (uid_local, uid_foreign, tablenames, fieldname, sorting, sorting_foreign) - SELECT sys_category_record_mm.uid_local, pages.uid, 'pages', 'tx_sgnews_tags', sys_category_record_mm.sorting, sys_category_record_mm.sorting_foreign FROM pages, sys_category_record_mm WHERE pages.l10n_parent IN ( - SELECT uid_foreign FROM sys_category_record_mm WHERE fieldname = 'tx_sgnews_tags' - ) AND sys_category_record_mm.uid_foreign = pages.l10n_parent; -``` - -## Migrate Images - -All images must be resynchronized in all translations as images must always be carefully translated now in ALL records -and not only pages. Unfortunately there is no automatic approach. You must do it on your own. To simplify the process, -you should use mass badge processing offered by TYPO3. - -1) Open the list view -2) Open the news category -3) Click on the table and the search icon in the top bar and choose 3 levels -4) All news should be listed for the category (you can also do that for the overview page if all news are grouped below) -5) At the very bottom, choose the higlight and teaser image fields now. -6) Click on the edit icon at the table header for hightlight images -7) Synchronize all images with the provided button and save -8) Do that now also for the teaser images and ALL pagination pages as TYPO3 loads only one page after the other. diff --git a/Upgrade.md b/Upgrade.md index 46954d1bba673691d031d2f86b9ecf3a3a58a2fb..f16523ce47f5682bf3dd619dd1d7d15a2fe9a087 100644 --- a/Upgrade.md +++ b/Upgrade.md @@ -1,3 +1,7 @@ +# Upgrade from ```8.x.x``` to ```9.x.x``` + +- Dropped TYPO3 8 support + # Upgrade from ```7.x.x``` to ```8.x.x``` ## Migrate the Authors @@ -55,6 +59,37 @@ In order for your module bundler to find the ```sgnews``` package, you need to a } ``` -## Version 9 Breaking Changes +## Migration to TYPO3 9 -- Dropped TYPO3 8 support +Unfortunately TYPO3 fucked it completely up. There are several issues with translations afterwards that can only be +solved by doing manual work. + +### Migrate Tags + +All tags must be synchronized with the translated pages as pages_language_overlay was dropped and TYPO3 didn't handled this +properly. If you don't use tags, you are a lucky guy. If you used tags, you can now be lucky. Just execute the +following SQL. + +``` +# Hole alle Tags von Seiten, welche Ãœbersetzungen haben mit zugehörigem Page-Record der Ãœbersetzung +# UND synchronisiere die neuen Tags für die Ãœbersetzungen +INSERT INTO sys_category_record_mm (uid_local, uid_foreign, tablenames, fieldname, sorting, sorting_foreign) + SELECT sys_category_record_mm.uid_local, pages.uid, 'pages', 'tx_sgnews_tags', sys_category_record_mm.sorting, sys_category_record_mm.sorting_foreign FROM pages, sys_category_record_mm WHERE pages.l10n_parent IN ( + SELECT uid_foreign FROM sys_category_record_mm WHERE fieldname = 'tx_sgnews_tags' + ) AND sys_category_record_mm.uid_foreign = pages.l10n_parent; +``` + +### Migrate Images + +All images must be resynchronized in all translations as images must always be carefully translated now in ALL records +and not only pages. Unfortunately there is no automatic approach. You must do it on your own. To simplify the process, +you should use mass badge processing offered by TYPO3. + +1) Open the list view +2) Open the news category +3) Click on the table and the search icon in the top bar and choose 3 levels +4) All news should be listed for the category (you can also do that for the overview page if all news are grouped below) +5) At the very bottom, choose the higlight and teaser image fields now. +6) Click on the edit icon at the table header for hightlight images +7) Synchronize all images with the provided button and save +8) Do that now also for the teaser images and ALL pagination pages as TYPO3 loads only one page after the other. diff --git a/composer.json b/composer.json index 7ef7646a60a43a843053f764f951f762b73fb45d..cb1fe76ff1e42a8f3575cac179d79db05d860eff 100644 --- a/composer.json +++ b/composer.json @@ -1,41 +1,38 @@ { - "name": "sgalinski/sg-news", - "type": "typo3-cms-extension", - "description": "News System", - "homepage": "https://www.sgalinski.de", - "license": [ - "GPL-2.0-or-later" - ], - "version": "9.3.7", - "support": { - }, - "repositories": [ - { - "type": "composer", - "url": "https://packages.sgalinski.de/" - } - ], - "require": { - "typo3/cms-core": "^9.5.0 || ^10.4.0" - }, - "require-dev": { - "roave/security-advisories": "dev-master" - }, - "suggest": { - "sgalinski/sg-ajax": "Needed for the like feature", - "sgalinski/sg-comments": "Flexible comments system" - }, - "replace": { - "sgalinski/sg_news": "self.version" - }, - "extra": { - "typo3/cms": { - "extension-key": "sg_news" - } - }, - "autoload": { - "psr-4": { - "SGalinski\\SgNews\\": "Classes/" - } - } + "name": "sgalinski/sg-news", + "type": "typo3-cms-extension", + "description": "News System", + "homepage": "https://www.sgalinski.de", + "license": [ + "GPL-2.0-or-later" + ], + "version": "9.3.7", + "support": { + }, + "repositories": [ + { + "type": "composer", + "url": "https://packages.sgalinski.de/" + } + ], + "require": { + "typo3/cms-core": "^9.5.0 || ^10.4.0" + }, + "suggest": { + "sgalinski/sg-ajax": "Required for the like feature", + "sgalinski/sg-comments": "Flexible comments system" + }, + "replace": { + "sgalinski/sg_news": "self.version" + }, + "extra": { + "typo3/cms": { + "extension-key": "sg_news" + } + }, + "autoload": { + "psr-4": { + "SGalinski\\SgNews\\": "Classes/" + } + } } diff --git a/ext_conf_template.txt b/ext_conf_template.txt deleted file mode 100644 index 5a0d655968734511aea82af803b0efdf5c632244..0000000000000000000000000000000000000000 --- a/ext_conf_template.txt +++ /dev/null @@ -1,2 +0,0 @@ -# cat=license; type=string; label=LLL:EXT:sg_news/Resources/Private/Language/locallang.xlf:configuration.licenseKey -key = diff --git a/ext_localconf.php b/ext_localconf.php index ea8dea0a1009cdd4ab3df7fb805645e6f4306a66..d08914f19d27a0e5a168b254eebdf2138548a874 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -74,13 +74,6 @@ call_user_func( ['ListByCategory' => '',] ); - \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( - 'SGalinski.sg_news', - 'PageBrowser', - ['PageBrowser' => 'index',], - ['PageBrowser' => '',] - ); - \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( 'SGalinski.sg_news', 'NewsByAuthor', @@ -134,7 +127,7 @@ call_user_func( \SGalinski\SgNews\Utility\BackendNewsUtility::registerIcons(); \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig( - '@import "EXT:sg_news/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig"' + '@import "EXT:sg_news/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig"' ); // Add upgrade wizards