Skip to content
Snippets Groups Projects
Verified Commit 72354fa4 authored by Kevin Ditscheid's avatar Kevin Ditscheid
Browse files

[TASK] Remove deprecated plugin preview and allowTableOnStandardPages

parent f1fd857a
No related branches found
No related tags found
1 merge request!48[TASK] Require TYPO3 12
Showing
with 134 additions and 413 deletions
<?php
/***************************************************************
* 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!
***************************************************************/
namespace SGalinski\SgJobs\Preview;
namespace SGalinski\SgJobs\EventListeners;
use TYPO3\CMS\Backend\Preview\PreviewRendererInterface;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Core\Localization\LanguageService;
use SGalinski\SgJobs\Preview\PreviewService;
use TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent;
/**
*
*/
class PreviewRenderer implements PreviewRendererInterface {
/**
* @var LanguageService $languageService
*/
protected $languageService;
class PageContentPreviewRenderingEventListener {
/**
* @var PreviewService $previewService
*/
protected $previewService;
protected PreviewService $previewService;
public function __construct(LanguageService $languageService, PreviewService $previewService) {
$this->languageService = $languageService;
public function __construct(PreviewService $previewService) {
$this->previewService = $previewService;
}
/**
* Dedicated method for rendering preview header HTML for
* the page module only. Receives $item which is an instance of
* GridColumnItem which has a getter method to return the record.
*
* @param GridColumnItem $item
* @return string
*/
public function renderPageModulePreviewHeader(GridColumnItem $item): string {
// @todo: when v12 hits, add header from PluginRenderer
return '';
}
/**
* Dedicated method for rendering preview body HTML for
* the page module only.
*
* @param GridColumnItem $item
* @return string
*/
public function renderPageModulePreviewContent(GridColumnItem $item): string {
$row = $item->getRecord();
switch ($row['list_type']) {
case 'sgjobs_jobapplication':
$view = $this->previewService->getApplicationView($row);
return $view->render();
case 'sgjobs_joblist':
$view = $this->previewService->getJoblistView($row);
return $view->render();
case 'sgjobs_jobteaser':
$view = $this->previewService->getTeaserView($row);
return $view->render();
default:
// No need to do anything
public function __invoke(PageContentPreviewRenderingEvent $event): void {
if ($event->getTable() === 'tt_content') {
$record = $event->getRecord();
switch ($record['list_type']) {
case 'sgjobs_jobapplication':
$event->setPreviewContent(
$this->previewService->getApplicationView($record)->render('JobApplication')
);
break;
case 'sgjobs_joblist':
$event->setPreviewContent(
$this->previewService->getJoblistView($record)->render('Joblist')
);
break;
case 'sgjobs_jobteaser':
$event->setPreviewContent(
$this->previewService->getTeaserView($record)->render('JobTeaser')
);
break;
}
}
return '';
}
/**
* Render a footer for the record to display in page module below
* the body of the item's preview.
*
* @param GridColumnItem $item
* @return string
*/
public function renderPageModulePreviewFooter(GridColumnItem $item): string {
return '';
}
/**
* Dedicated method for wrapping a preview header and body HTML.
*
* @param string $previewHeader
* @param string $previewContent
* @param GridColumnItem $item
* @return string
*/
public function wrapPageModulePreview(string $previewHeader, string $previewContent, GridColumnItem $item): string {
return $previewHeader . $previewContent;
}
}
<?php
/***************************************************************
* 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!
***************************************************************/
namespace SGalinski\SgJobs\Hooks\PageLayoutView;
use SGalinski\SgJobs\Preview\PreviewService;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\PageLayoutView;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class PluginRenderer - Renders backend previews for plugins.
*
* @package SGalinski\SgJobs\Hooks\PageLayoutView
*/
class PluginRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface {
/**
* @var PreviewService $previewService
*/
protected $previewService;
public function init() {
$this->previewService = GeneralUtility::makeInstance(PreviewService::class);
}
/**
* @inheritDoc
* @noinspection ReferencingObjectsInspection
*/
public function preProcess(
PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
): void {
$this->init();
switch ($row['list_type']) {
case 'sgjobs_jobapplication':
$drawItem = FALSE;
$this->adaptPluginHeaderContent($headerContent, $row);
$view = $this->previewService->getApplicationView($row);
$itemContent .= $view->render();
break;
case 'sgjobs_joblist':
$drawItem = FALSE;
$this->adaptPluginHeaderContent($headerContent, $row);
$view = $this->previewService->getJoblistView($row);
$itemContent .= $view->render();
break;
case 'sgjobs_jobteaser':
$drawItem = FALSE;
$this->adaptPluginHeaderContent($headerContent, $row);
$view = $this->previewService->getTeaserView($row);
$itemContent .= $view->render();
break;
default:
// No need to do anything
}
}
/**
* Adapts the given $headerContent.
* To be used in all plugin previews so the Header Contents appear similarly.
*
* @param string $headerContent
* @param array $row
*/
protected function adaptPluginHeaderContent(&$headerContent, $row): void {
$headerContent = '<h4>' . $this->getPluginNameForHeaderContent(
(int) $row['pid'],
$row['list_type']
) . $headerContent . '</h4>';
}
/**
* Finds the label of the given $listType element on the page with the given $pid
* and returns it wrapped for use in the backend preview's header content.
*
* @param int $pid
* @param string $listType
* @return string
*/
protected function getPluginNameForHeaderContent(int $pid, string $listType): string {
$languageService = GeneralUtility::makeInstance(LanguageService::class);
$pluginName = $languageService->sL(
BackendUtility::getLabelFromItemListMerged(
$pid,
'tt_content',
'list_type',
$listType
)
);
return '<span class="label label-primary">' . $pluginName . '</span>&nbsp;';
}
}
......@@ -43,7 +43,7 @@ class PreviewService {
* @return StandaloneView
*/
public function getApplicationView(array $row): StandaloneView {
$view = $this->createViewWithTemplate('JobApplication');
$view = $this->createView();
$view->assign('uid', $row['uid']);
// Get available plugin settings and their values from flexform
......@@ -62,6 +62,12 @@ class PreviewService {
];
$view->assign('data', $templateData);
$view->assign('headerLabel', BackendUtility::getLabelFromItemListMerged(
$row['pid'],
'tt_content',
'list_type',
$row['list_type']
));
return $view;
}
......@@ -72,7 +78,7 @@ class PreviewService {
* @return StandaloneView
*/
public function getJoblistView(array $row): StandaloneView {
$view = $this->createViewWithTemplate('Joblist');
$view = $this->createView();
$view->assign('uid', $row['uid']);
// Get available plugin settings and their values from flexform
......@@ -113,11 +119,17 @@ class PreviewService {
) : ''
);
$view->assign('recursive', $row['recursive']);
$view->assign('headerLabel', BackendUtility::getLabelFromItemListMerged(
$row['pid'],
'tt_content',
'list_type',
$row['list_type']
));
return $view;
}
public function getTeaserView(array $row): StandaloneView {
$view = $this->createViewWithTemplate('JobTeaser');
$view = $this->createView();
$view->assign('uid', $row['uid']);
// Get available plugin settings and their values from flexform
......@@ -146,6 +158,12 @@ class PreviewService {
];
$view->assign('data', $templateData);
$view->assign('headerLabel', BackendUtility::getLabelFromItemListMerged(
$row['pid'],
'tt_content',
'list_type',
$row['list_type']
));
return $view;
}
......@@ -172,18 +190,13 @@ class PreviewService {
* Creates a new StandaloneView object with template and partial root paths,
* attaches the template with the given name to it and returns it.
*
* @param string $templateName
* @return StandaloneView
*/
protected function createViewWithTemplate(string $templateName): StandaloneView {
protected function createView(): StandaloneView {
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplateRootPaths(['EXT:sg_jobs/Resources/Private/Backend/Templates/']);
$view->setPartialRootPaths(['EXT:sg_jobs/Resources/Private/Backend/Partials/']);
$view->setLayoutRootPaths(['EXT:sg_jobs/Resources/Private/Backend/Layouts/']);
if (!str_ends_with($templateName, '.html')) {
$templateName .= '.html';
}
$view->setTemplate($templateName);
return $view;
}
......@@ -214,6 +227,7 @@ class PreviewService {
$recordsWithTitlesArray[] = $record[$field] . ' [' . $recordId . ']';
}
return implode(', ', $recordsWithTitlesArray);
}
}
<?php
/**
* 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!
*/
namespace SGalinski\SgJobs\Updates;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
/**
* Class DepartmentUpdateWizard
*/
class DepartmentUpdateWizard implements UpgradeWizardInterface {
/**
* The wizard identifier
*/
public const IDENTIFIER = 'tx_sgjobs_departmentupdatewizward';
/**
* Check if the job table has a deleted area field
*
* @return bool
*/
protected function hasDeletedAreaField(): bool {
return $this->hasField('zzz_deleted_area');
}
/**
* Check if the job table has an area field
*
* @return bool
*/
protected function hasAreaField(): bool {
return $this->hasField('area');
}
/**
* Check if the job database table has a field with the given name in it
*
* @param string $fieldName
* @return bool
*/
protected function hasField(string $fieldName): bool {
$connection = $this->getDatabaseConnection();
$tableColumns = $connection->getSchemaManager()->listTableColumns('tx_sgjobs_domain_model_job');
if (\array_key_exists($fieldName, $tableColumns)) {
return TRUE;
}
return FALSE;
}
/**
* Get the database query builder
*
* @return Connection
*/
protected function getDatabaseConnection(): Connection {
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
return $connectionPool->getConnectionForTable('tx_sgjobs_domain_model_job');
}
/**
* @return string
*/
public function getIdentifier(): string {
return self::IDENTIFIER;
}
/**
* @return string
*/
public function getTitle(): string {
return 'Migrate old fulltext job areas to department records';
}
/**
* @return string
*/
public function getDescription(): string {
return '';
}
/**
* @return bool
*/
public function executeUpdate(): bool {
$connection = $this->getDatabaseConnection();
$queryBuilder = $connection->createQueryBuilder();
$field = $this->hasDeletedAreaField() ? 'zzz_deleted_area' : 'area';
$queryBuilder->getRestrictions()->removeAll();
/**
* @var array $jobs
*/
$jobs = $queryBuilder->select('uid', 'pid', 'sys_language_uid', $field)
->from('tx_sgjobs_domain_model_job')
->execute()
->fetchAll();
$newDepartments = [];
if (\count($jobs) > 0) {
foreach ($jobs as $index => $job) {
if ($job[$field]) {
$identifier = $job[$field] . '-' . $job['pid'] . '-' . $job['sys_language_uid'];
$newDepartments[$identifier] = [
'title' => $job[$field],
'pid' => $job['pid'],
'sys_language_uid' => $job['sys_language_uid']
];
} else {
unset($jobs[$index]);
}
}
if (\count($jobs) > 0) {
\array_walk(
$newDepartments,
function ($department) use (&$dbQueries, $connection) {
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->insert('tx_sgjobs_domain_model_department')->values($department)->execute();
$dbQueries[] = $queryBuilder->getSQL();
}
);
$queryBuilder = $connection->createQueryBuilder();
$departments = $queryBuilder->select('uid', 'pid', 'sys_language_uid', 'title')
->from('tx_sgjobs_domain_model_department')
->execute()
->fetchAll();
$identifiedDepartments = [];
foreach ($departments as $department) {
$identifier = $department['title'] . '-' . $department['pid'] . '-' . $department['sys_language_uid'];
$identifiedDepartments[$identifier] = $department;
}
$dbQueries[] = $queryBuilder->getSQL();
foreach ($jobs as $index => $job) {
$identifier = $job[$field] . '-' . $job['pid'] . '-' . $job['sys_language_uid'];
if (isset($identifiedDepartments[$identifier])) {
$jobs[$index]['department'] = $identifiedDepartments[$identifier]['uid'];
unset($jobs[$index][$field]);
} else {
unset($jobs[$index]);
}
}
if (\count($jobs) > 0) {
\array_walk(
$jobs,
function ($job) use ($connection) {
$queryBuilder = $connection->createQueryBuilder();
$queryBuilder->update('tx_sgjobs_domain_model_job')
->set('department', (int) $job['department'])
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->createNamedParameter($job['uid'], \PDO::PARAM_INT)
)
)->execute();
}
);
}
}
}
return TRUE;
}
/**
* @return bool
*/
public function updateNecessary(): bool {
if (
!GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_sgjobs_domain_model_department')
->getSchemaManager()
->tablesExist(['tx_sgjobs_domain_model_department'])
) {
return FALSE;
}
if (
$this->hasAreaField() ||
$this->hasDeletedAreaField()
) {
return TRUE;
}
return FALSE;
}
/**
* @return array|string[]
*/
public function getPrerequisites(): array {
return [
DatabaseUpdatedPrerequisite::class
];
}
}
<?php
use SGalinski\SgJobs\Controller\BackendController;
return [
'web_SgJobs_backend' => [
'parent' => 'web',
'position' => ['after' => ''],
'access' => 'user,group',
'workspaces' => 'live',
'path' => '/module/web/sg_jobs_backend',
'labels' => 'LLL:EXT:sg_jobs/Resources/Private/Language/locallang_backend.xlf',
'iconIdentifier' => 'extension-sg_jobs-module',
'extensionName' => 'SgJobs',
'controllerActions' => [
BackendController::class => ['index']
]
]
];
......@@ -25,10 +25,11 @@
use SGalinski\SgJobs\Event\Listener\AccessPageListEventListener;
use SGalinski\SgJobs\Event\Listener\ExcludeFromReferenceIndexListener;
use SGalinski\SgJobs\Preview\PreviewRenderer;
use SGalinski\SgJobs\EventListeners\PageContentPreviewRenderingEventListener;
use SGalinski\SgJobs\Service\BackendService;
use SGalinski\SgJobs\Service\SitemapService;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent;
use TYPO3\CMS\Core\DataHandling\Event\IsTableExcludedFromReferenceIndexEvent;
return static function (ContainerConfigurator $containerConfigurator): void {
......@@ -41,7 +42,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(SitemapService::class)->public();
$services->set(BackendService::class)->public();
$services->set(PreviewRenderer::class)->public();
if (class_exists('\SGalinski\SgSeo\Events\AccessPageListEvent')) {
$services->set(AccessPageListEventListener::class)
......@@ -56,4 +56,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
'identifier' => 'sg-jobs/excludeFromRefIndex',
'event' => IsTableExcludedFromReferenceIndexEvent::class
]);
$services->set(PageContentPreviewRenderingEventListener::class)
->tag('event.listener', [
'event' => PageContentPreviewRenderingEvent::class
]);
};
......@@ -45,7 +45,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_company.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_company.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -47,7 +47,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_contact.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_contact.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -45,7 +45,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_department.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_department.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -45,7 +45,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_experience_level.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_experience_level.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -49,7 +49,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_job.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_job.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -47,7 +47,10 @@ $columns = [
'endtime' => 'endtime',
],
'sortby' => 'sorting',
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_job.svg'
'iconfile' => 'EXT:sg_jobs/Resources/Public/Icons/tx_sgjobs_domain_model_job.svg',
'security' => [
'ignorePageTypeRestriction' => TRUE
]
],
'interface' => [],
'types' => [
......
......@@ -50,10 +50,6 @@ call_user_func(
]
);
// Backend preview for plugins
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['sg_jobs']
= \SGalinski\SgJobs\Hooks\PageLayoutView\PluginRenderer::class;
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptConstants(
'@import "EXT:sg_jobs/Configuration/TypoScript/Backend/constants.typoscript"'
);
......@@ -66,10 +62,6 @@ call_user_func(
$GLOBALS['sg_mail']['sg_jobs']['ApplicationMail'] = 'EXT:sg_jobs/Configuration/SgMail/ApplicationMail.php';
$GLOBALS['sg_mail']['sg_jobs']['ApplicantMail'] = 'EXT:sg_jobs/Configuration/SgMail/ApplicantMail.php';
// Register the upgrade wizard
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\SGalinski\SgJobs\Updates\DepartmentUpdateWizard::IDENTIFIER]
= \SGalinski\SgJobs\Updates\DepartmentUpdateWizard::class;
//include Plugin sg_jobs
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
'@import "EXT:sg_jobs/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig"'
......
<?php
call_user_func(
static function () {
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_job'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_contact'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_company'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_job_application'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_department'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages(
'tx_sgjobs_domain_model_experience_level'
);
// Register backend modules
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
'SgJobs',
'web',
'Backend',
'',
[
\SGalinski\SgJobs\Controller\BackendController::class => 'index',
],
[
'access' => 'user,group',
'iconIdentifier' => 'extension-sg_jobs-module',
'labels' => 'LLL:EXT:sg_jobs/Resources/Private/Language/locallang_backend.xlf',
]
);
}
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment