Commit 13260d99 authored by Georg Ringer's avatar Georg Ringer Committed by Benni Mack
Browse files

[FEATURE] Make position of sys notes configurable

Add a new field "position" to allow editors to define where the
sys_note record is rendered.

Resolves: #83965
Releases: master
Change-Id: I22c6b5c66ce5ab58a112f844fd763a18788552f9
Reviewed-on: https://review.typo3.org/55976


Reviewed-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer's avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: default avatarDaniel Goerz <ervaude@gmail.com>
Tested-by: default avatarDaniel Goerz <ervaude@gmail.com>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: default avatarGuido Schmechel <littlegee@web.de>
Tested-by: default avatarGuido Schmechel <littlegee@web.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent a25e07a4
.. include:: ../../Includes.txt
=========================================================
Feature: #83965 - Make position of sys notes configurable
=========================================================
See :issue:`83965`
Description
===========
Sys_note records can now be rendered either in the top or bottom of the page and list module by
defining the position in the record itself.
.. index:: Backend, ext:sys_note
...@@ -40,15 +40,16 @@ class NoteController ...@@ -40,15 +40,16 @@ class NoteController
* Render notes by single PID or PID list * Render notes by single PID or PID list
* *
* @param string $pids Single PID or comma separated list of PIDs * @param string $pids Single PID or comma separated list of PIDs
* @param int|null $position null for no restriction, integer for defined position
* @return string * @return string
*/ */
public function listAction($pids): string public function listAction($pids, int $position = null): string
{ {
if (empty($pids) || empty($GLOBALS['BE_USER']->user['uid'])) { if (empty($pids) || empty($GLOBALS['BE_USER']->user['uid'])) {
return ''; return '';
} }
$notes = $this->notesRepository->findByPidsAndAuthorId($pids, (int)$GLOBALS['BE_USER']->user['uid']); $notes = $this->notesRepository->findByPidsAndAuthorId($pids, (int)$GLOBALS['BE_USER']->user['uid'], $position);
if ($notes) { if ($notes) {
$view = GeneralUtility::makeInstance(StandaloneView::class); $view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName( $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName(
......
...@@ -26,21 +26,24 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; ...@@ -26,21 +26,24 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
*/ */
class SysNoteRepository class SysNoteRepository
{ {
const SYS_NOTE_POSITION_BOTTOM = 0;
const SYS_NOTE_POSITION_TOP = 1;
/** /**
* Find notes by given pids and author * Find notes by given pids and author
* *
* @param string $pids Single PID or comma separated list of PIDs * @param string $pids Single PID or comma separated list of PIDs
* @param int $author author uid * @param int $author author uid
* @param int|null $position null for no restriction, integer for defined position
* @return array * @return array
*/ */
public function findByPidsAndAuthorId($pids, int $author): array public function findByPidsAndAuthorId($pids, int $author, int $position = null): array
{ {
$pids = GeneralUtility::intExplode(',', (string)$pids); $pids = GeneralUtility::intExplode(',', (string)$pids);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_note'); ->getQueryBuilderForTable('sys_note');
$rows = $queryBuilder $res = $queryBuilder
->select('sys_note.*', 'be_users.username', 'be_users.realName') ->select('sys_note.*', 'be_users.username', 'be_users.realName')
->from('sys_note') ->from('sys_note')
->leftJoin( ->leftJoin(
...@@ -57,9 +60,14 @@ class SysNoteRepository ...@@ -57,9 +60,14 @@ class SysNoteRepository
) )
) )
->orderBy('sorting', 'asc') ->orderBy('sorting', 'asc')
->addOrderBy('crdate', 'desc') ->addOrderBy('crdate', 'desc');
->execute()->fetchAll();
return $rows; if ($position !== null) {
$res->andWhere(
$queryBuilder->expr()->eq('sys_note.position', $queryBuilder->createNamedParameter($position, \PDO::PARAM_INT))
);
}
return $res->execute()->fetchAll();
} }
} }
...@@ -17,12 +17,27 @@ namespace TYPO3\CMS\SysNote\Hook; ...@@ -17,12 +17,27 @@ namespace TYPO3\CMS\SysNote\Hook;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\SysNote\Controller\NoteController; use TYPO3\CMS\SysNote\Controller\NoteController;
use TYPO3\CMS\SysNote\Domain\Repository\SysNoteRepository;
/** /**
* Hook for the page module * Hook for the page module
*/ */
class PageHook class PageHook
{ {
/**
* Add sys_notes as additional content to the header of the page module
*
* @param array $params
* @param \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject
* @return string
*/
public function renderInHeader(array $params = [], \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject)
{
$controller = GeneralUtility::makeInstance(NoteController::class);
return $controller->listAction($parentObject->id, SysNoteRepository::SYS_NOTE_POSITION_TOP);
}
/** /**
* Add sys_notes as additional content to the footer of the page module * Add sys_notes as additional content to the footer of the page module
* *
...@@ -30,9 +45,9 @@ class PageHook ...@@ -30,9 +45,9 @@ class PageHook
* @param \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject * @param \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject
* @return string * @return string
*/ */
public function render(array $params = [], \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject) public function renderInFooter(array $params = [], \TYPO3\CMS\Backend\Controller\PageLayoutController $parentObject)
{ {
$controller = GeneralUtility::makeInstance(NoteController::class); $controller = GeneralUtility::makeInstance(NoteController::class);
return $controller->listAction($parentObject->id); return $controller->listAction($parentObject->id, SysNoteRepository::SYS_NOTE_POSITION_BOTTOM);
} }
} }
...@@ -17,12 +17,26 @@ namespace TYPO3\CMS\SysNote\Hook; ...@@ -17,12 +17,26 @@ namespace TYPO3\CMS\SysNote\Hook;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\SysNote\Controller\NoteController; use TYPO3\CMS\SysNote\Controller\NoteController;
use TYPO3\CMS\SysNote\Domain\Repository\SysNoteRepository;
/** /**
* Hook for the list module * Hook for the list module
*/ */
class RecordListHook class RecordListHook
{ {
/**
* Add sys_notes as additional content to the header of the list module
*
* @param array $params
* @param \TYPO3\CMS\Recordlist\RecordList $parentObject
* @return string
*/
public function renderInHeader(array $params = [], \TYPO3\CMS\Recordlist\RecordList $parentObject)
{
$controller = GeneralUtility::makeInstance(NoteController::class);
return $controller->listAction($parentObject->id, SysNoteRepository::SYS_NOTE_POSITION_TOP);
}
/** /**
* Add sys_notes as additional content to the footer of the list module * Add sys_notes as additional content to the footer of the list module
* *
...@@ -30,9 +44,9 @@ class RecordListHook ...@@ -30,9 +44,9 @@ class RecordListHook
* @param \TYPO3\CMS\Recordlist\RecordList $parentObject * @param \TYPO3\CMS\Recordlist\RecordList $parentObject
* @return string * @return string
*/ */
public function render(array $params = [], \TYPO3\CMS\Recordlist\RecordList $parentObject) public function renderInFooter(array $params = [], \TYPO3\CMS\Recordlist\RecordList $parentObject)
{ {
$controller = GeneralUtility::makeInstance(NoteController::class); $controller = GeneralUtility::makeInstance(NoteController::class);
return $controller->listAction($parentObject->id); return $controller->listAction($parentObject->id, SysNoteRepository::SYS_NOTE_POSITION_BOTTOM);
} }
} }
...@@ -58,12 +58,35 @@ return [ ...@@ -58,12 +58,35 @@ return [
'config' => [ 'config' => [
'type' => 'check' 'type' => 'check'
] ]
],
'position' => [
'label' => 'LLL:EXT:sys_note/Resources/Private/Language/locallang_tca.xlf:sys_note.position',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
[
'LLL:EXT:sys_note/Resources/Private/Language/locallang_tca.xlf:sys_note.position.top',
\TYPO3\CMS\SysNote\Domain\Repository\SysNoteRepository::SYS_NOTE_POSITION_TOP
],
[
'LLL:EXT:sys_note/Resources/Private/Language/locallang_tca.xlf:sys_note.position.bottom',
\TYPO3\CMS\SysNote\Domain\Repository\SysNoteRepository::SYS_NOTE_POSITION_BOTTOM
],
],
'default' => \TYPO3\CMS\SysNote\Domain\Repository\SysNoteRepository::SYS_NOTE_POSITION_BOTTOM,
'fieldWizard' => [
'selectIcons' => [
'disabled' => false,
],
],
]
] ]
], ],
'types' => [ 'types' => [
'0' => ['showitem' => ' '0' => ['showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
category, subject,message, category, subject,message,position,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
personal, personal,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
......
...@@ -27,6 +27,15 @@ ...@@ -27,6 +27,15 @@
<trans-unit id="sys_note.personal"> <trans-unit id="sys_note.personal">
<source>Personal:</source> <source>Personal:</source>
</trans-unit> </trans-unit>
<trans-unit id="sys_note.position">
<source>Position</source>
</trans-unit>
<trans-unit id="sys_note.position.top">
<source>Top</source>
</trans-unit>
<trans-unit id="sys_note.position.bottom">
<source>Bottom</source>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
defined('TYPO3_MODE') or die(); defined('TYPO3_MODE') or die();
// Hook into the list module // Hook into the list module
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/Modules/Recordlist/index.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\RecordListHook::class . '->render'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/Modules/Recordlist/index.php']['drawHeaderHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\RecordListHook::class . '->renderInHeader';
// Hook into the page module $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/Modules/Recordlist/index.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\RecordListHook::class . '->renderInFooter';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\PageHook::class . '->render'; // Hook into the page modules
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawHeaderHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\PageHook::class . '->renderInHeader';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\PageHook::class . '->renderInFooter';
// Hook into the info module // Hook into the info module
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/web_info/class.tx_cms_webinfo.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\InfoModuleHook::class . '->render'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/web_info/class.tx_cms_webinfo.php']['drawFooterHook']['sys_note'] = \TYPO3\CMS\SysNote\Hook\InfoModuleHook::class . '->render';
...@@ -12,6 +12,7 @@ CREATE TABLE sys_note ( ...@@ -12,6 +12,7 @@ CREATE TABLE sys_note (
message text, message text,
personal tinyint(3) unsigned DEFAULT '0' NOT NULL, personal tinyint(3) unsigned DEFAULT '0' NOT NULL,
category tinyint(3) unsigned DEFAULT '0' NOT NULL, category tinyint(3) unsigned DEFAULT '0' NOT NULL,
position int(11) DEFAULT '0' NOT NULL,
sorting int(11) DEFAULT '0' NOT NULL, sorting int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (uid), PRIMARY KEY (uid),
KEY parent (pid) KEY parent (pid)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment