Initial commit - Typo3 11.5.41

This commit is contained in:
Matteo Gallo
2026-07-03 17:53:31 +02:00
commit 5ca4743197
6811 changed files with 568848 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
<?php
namespace MiniFranske\FsMediaGallery\Hooks;
/***************************************************************
* Copyright notice
*
* (c) 2014 Frans Saris <franssaris@gmail.com>
* 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 2 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\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Controller\BackendController;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* This class adds Filelist related JavaScript to the backend
*/
class BackendControllerHook
{
/**
* Adds Filelist JavaScript used e.g. by context menu
*
* @param array $configuration
* @param BackendController $backendController
*/
public function addJavaScript(array $configuration, BackendController $backendController)
{
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
$pageRenderer->addInlineSetting('FileEdit', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('file_edit'));
$pageRenderer->addInlineSetting('FileCreate', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('file_upload'));
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace MiniFranske\FsMediaGallery\Hooks;
/***************************************************************
* Copyright notice
*
* (c) 2014 Frans Saris <franssaris@gmail.com>
* 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 2 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 MiniFranske\FsMediaGallery\Service\AbstractBeAlbumButtons;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Hook to add extra button to DocHeaderButtons in file list
*/
class DocHeaderButtonsHook extends AbstractBeAlbumButtons
{
protected function createLink(string $title, string $shortTitle, Icon $icon, string $url, bool $addReturnUrl = true): array
{
return [
'title' => $title,
'icon' => $icon,
'url' => $url . ($addReturnUrl ? '&returnUrl=' . rawurlencode($_SERVER['REQUEST_URI']) : '')
];
}
/**
* Add media album buttons to file list
*/
public function moduleTemplateDocHeaderGetButtons(array $params, ButtonBar $buttonBar): array
{
$buttons = $params['buttons'];
if (GeneralUtility::_GP('M') === 'file_FilelistList'
|| GeneralUtility::_GP('route') === '/file/FilelistList/'
|| GeneralUtility::_GP('route') === '/module/file/FilelistList'
) {
foreach ($this->generateButtons((string)GeneralUtility::_GP('id')) as $buttonInfo) {
$button = $buttonBar->makeLinkButton();
$button->setShowLabelText(true);
$button->setIcon($buttonInfo['icon']);
$button->setTitle($buttonInfo['title']);
if (strpos($buttonInfo['url'], 'alert') === 0) {
// using CSS class to trigger confirmation in modal box
$button->setClasses('t3js-modal-trigger')
->setDataAttributes([
'severity' => 'warning',
'title' => $buttonInfo['title'],
'bs-content' => htmlspecialchars(substr($buttonInfo['url'], 6)),
]);
} else {
$button->setHref($buttonInfo['url']);
}
$buttons['left'][2][] = $button;
}
}
return $buttons;
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace MiniFranske\FsMediaGallery\Hooks;
/* *
* This script is part of the TYPO3 project. *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* ItemsProcFuncHook
*/
class ItemsProcFuncHook
{
/**
* Sets the available actions for settings.switchableControllerActions
*
* @param array &$config
* @return void
*/
public function getItemsForSwitchableControllerActions(array &$config)
{
$availableActions = [
'nestedList' => 'MediaAlbum->nestedList;MediaAlbum->showAsset',
'flatList' => 'MediaAlbum->flatList;MediaAlbum->showAlbum;MediaAlbum->showAsset',
'showAlbumByParam' => 'MediaAlbum->showAlbum;MediaAlbum->showAsset',
'showAlbumByConfig' => 'MediaAlbum->showAlbumByConfig;MediaAlbum->showAsset',
'randomAsset' => 'MediaAlbum->randomAsset',
];
$extConf = $this->getExtensionConfiguration();;
$allowedActions = [
// index action is always allowed
// this is needed to make sure the correct tabs/fields are shown in
// flexform when a new plugin is added
'index' => 'MediaAlbum->index',
];
$allowedActionsFromExtConf = [];
if (!empty($extConf['allowedActionsInFlexforms'])) {
$allowedActionsFromExtConf = GeneralUtility::trimExplode(',', $extConf['allowedActionsInFlexforms']);
}
foreach ($allowedActionsFromExtConf as $allowedActionFromExtConf) {
if (!empty($availableActions[$allowedActionFromExtConf])) {
$allowedActions[$allowedActionFromExtConf] = $availableActions[$allowedActionFromExtConf];
}
}
// check items; allow all actions if something went wrong (no action except of "indexAction" is allowed)
if (count($allowedActions) > 1) {
foreach ($config['items'] as $key => $item) {
if (!in_array($item[1], $allowedActions)) {
unset($config['items'][$key]);
}
}
}
}
/**
* Sets the available options for settings.list.orderBy
*
* @param array &$config
* @return void
*/
public function getItemsForListOrderBy(array &$config)
{
$availableOptions = ['datetime', 'crdate', 'sorting'];
$extConf = $this->getExtensionConfiguration();;
$allowedOptions = [];
$allowedOptionsFromExtConf = [];
if (!empty($extConf['list']['orderOptions'])) {
$allowedOptionsFromExtConf = GeneralUtility::trimExplode(',', $extConf['list']['orderOptions']);
}
foreach ($allowedOptionsFromExtConf as $allowedOptionFromExtConf) {
if (in_array($allowedOptionFromExtConf, $availableOptions)) {
$allowedOptions[] = $allowedOptionFromExtConf;
}
}
foreach ($config['items'] as $key => $item) {
// check items; empty value (inherit from TS) is always allowed
if (!empty($item[1]) && !in_array($item[1], $allowedOptions)) {
unset($config['items'][$key]);
}
}
}
/**
* Sets the available options for settings.album.assets.orderBy
*
* @param array &$config
* @return void
*/
public function getItemsForAssetsOrderBy(array &$config)
{
// default set
$allowedOptions = ['name', 'crdate', 'title', 'content_creation_date', 'content_modification_date'];
$availableOptions = [];
$extConf = $this->getExtensionConfiguration();;
if (!empty($extConf['asset']['orderOptions'])) {
$allowedOptions = GeneralUtility::trimExplode(',', $extConf['asset']['orderOptions']);
}
// check if field exists in TCA of sys_file or sys_file_metadata
foreach ($allowedOptions as $key => $option) {
if (
$option === 'crdate'
||
!empty($GLOBALS['TCA']['sys_file']['columns'][$option])
||
!empty($GLOBALS['TCA']['sys_file_metadata']['columns'][$option])
) {
$availableOptions[] = $option;
}
}
// @todo: add option to add custom options to the item list
// use label from TCA
foreach ($config['items'] as $key => $item) {
// check items; empty value (inherit from TS) is always allowed
if (!empty($item[1]) && !in_array($item[1], $availableOptions)) {
unset($config['items'][$key]);
}
}
}
/**
* Get extension configuration
*/
protected function getExtensionConfiguration() {
return GeneralUtility::makeInstance(
ExtensionConfiguration::class
)->get('fs_media_gallery');
}
}

View File

@@ -0,0 +1,250 @@
<?php
namespace MiniFranske\FsMediaGallery\Hooks;
/*
* This source file is proprietary property of Beech Applications B.V.
* Date: 28-09-2016
* All code (c) Beech Applications B.V. all rights reserved
*/
use TYPO3\CMS\Backend\Utility\BackendUtility as BackendUtilityCore;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\Connection;
/**
* Class PageLayoutView
*/
class PageLayoutView
{
/**
* @var string
*/
const LLPATH = 'LLL:EXT:fs_media_gallery/Resources/Private/Language/locallang_be.xlf:';
/**
* @var array
*/
private $summaryData = [];
/**
* @var array
*/
private $flexFormData = [];
public function getExtensionSummary(array $params): string
{
/** @var \TYPO3\CMS\Backend\View\PageLayoutView $pageLayoutView */
$pageLayoutView = $params['pObj'];
$row = $params['row'];
$this->flexFormData = GeneralUtility::xml2array($row['pi_flexform']);
$action = $this->getAction();
$result = '<strong>' . $pageLayoutView->linkEditContent($this->getLanguageService()->sL(self::LLPATH . 'mediagallery.title'), $row) . '</strong><br>';
$result .= $this->getDisplayMode($action);
$result .= '<hr>';
if (in_array($action, ['showAlbum', 'showAlbumByConfig'], true)) {
$this->addSelectedAlbumToSettingsSummary();
} else {
$this->addSelectedAlbumsToSettingsSummary();
}
$this->addStartingPointToSettingsSummary();
$result .= $this->renderSettingsAsTable();
return $result;
}
private function getAction(): string
{
// if flexForm data is found
$actions = $this->getFieldFromFlexform('switchableControllerActions');
$action = '';
if (!empty($actions)) {
$actionList = GeneralUtility::trimExplode(';', $actions);
// translate the first action into its translation
$action = str_replace('MediaAlbum->', '', $actionList[0]);
}
return $action;
}
private function getDisplayMode(string $action): string
{
switch ($action) {
case 'showalbum';
$actionTranslationKey = 'showAlbumByParam';
break;
default:
$actionTranslationKey = $action;
}
return $this->getLanguageService()->sL(self::LLPATH . 'flexforms.mediagallery.switchableControllerActions.I.' . $actionTranslationKey);
}
/**
* Get field value from flexform configuration,
* including checks if flexform configuration is available
*
* @param string $key name of the key
* @param string $sheet name of the sheet
* @return string|NULL if nothing found, value if found
*/
private function getFieldFromFlexform(string $key, string $sheet = 'general'): ?string
{
$flexform = $this->flexFormData;
if (isset($flexform['data'])) {
$flexform = $flexform['data'];
if (is_array($flexform) && is_array($flexform[$sheet]) && is_array($flexform[$sheet]['lDEF'])
&& is_array($flexform[$sheet]['lDEF'][$key]) && isset($flexform[$sheet]['lDEF'][$key]['vDEF'])
) {
return $flexform[$sheet]['lDEF'][$key]['vDEF'];
}
}
return null;
}
private function addSelectedAlbumToSettingsSummary(): void
{
$albumUid = (int)$this->getFieldFromFlexform('settings.mediaAlbum');
if ((int)$albumUid > 0) {
// Album record
$rowSysFileCollectionRecords = $this->getDatabaseConnection()->select(['*'], 'sys_file_collection', [
'uid' => (int)$albumUid,
'deleted' => 0,
])->fetchAllAssociative();
$albums = [];
foreach ($rowSysFileCollectionRecords as $record) {
$albums[] = htmlspecialchars(BackendUtilityCore::getRecordTitle('sys_file_collection', $record));
}
$this->summaryData[] = [
$this->getLanguageService()->sL(self::LLPATH . 'flexforms.mediagallery.mediaAlbum') .
'<br />',
implode(', ', $albums)
];
}
}
private function addSelectedAlbumsToSettingsSummary(): void
{
$filterMode = '';
$albums = [];
$albumUids = GeneralUtility::intExplode(',', $this->getFieldFromFlexform('settings.mediaAlbumsUids'), true);
if (count($albumUids) > 0) {
// Filter mode
$selectedFilerMode = $this->getFieldFromFlexform('settings.useAlbumFilterAsExclude');
if ($selectedFilerMode !== '') {
$filterMode = $this->getLanguageService()->sL(self::LLPATH . 'flexforms.general.I.inherit');
$filterMode = '<span style="font-weight:normal;font-style:italic">(' . htmlspecialchars($filterMode) . ')</span>';
}
// Album records
$q = $this->getDatabaseConnection()->createQueryBuilder();
$q->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$quotedIdentifiers = $q->createNamedParameter($albumUids, Connection::PARAM_INT_ARRAY);
$q->select('*')
->from('sys_file_collection')
->where(
$q->expr()->in('uid', $quotedIdentifiers)
);
$rowSysFileCollectionRecords = $q->execute()->fetchAllAssociative();
foreach ((array)$rowSysFileCollectionRecords as $record) {
$albums[] = htmlspecialchars(BackendUtilityCore::getRecordTitle('sys_file_collection', $record));
}
$this->summaryData[] = [
$this->getLanguageService()->sL(self::LLPATH . 'flexforms.mediagallery.mediaAlbumsUids') .
'<br />' . $filterMode,
implode(', ', $albums)
];
}
}
private function addStartingPointToSettingsSummary(): void
{
$value = $this->getFieldFromFlexform('settings.startingpoint');
if (!empty($value)) {
$pagesOut = [];
$q = $this->getDatabaseConnection('pages')->createQueryBuilder();
$quotedIdentifiers = $q->createNamedParameter(GeneralUtility::intExplode(',', $value, true), Connection::PARAM_INT_ARRAY);
$q->select('*')
->from('pages')
->where(
$q->expr()->in('uid', $quotedIdentifiers)
);
$rawPagesRecords = $q->execute()->fetchAllAssociative();
foreach ((array)$rawPagesRecords as $page) {
$pagesOut[] = htmlspecialchars(BackendUtilityCore::getRecordTitle('pages',
$page)) . ' (' . $page['uid'] . ')';
}
$recursiveLevel = (int)$this->getFieldFromFlexform('settings.recursive');
$recursiveLevelText = '';
if ($recursiveLevel === 250) {
$recursiveLevelText = $this->getLanguageService()->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:recursive.I.5');
} elseif ($recursiveLevel > 0) {
$recursiveLevelText = $this->getLanguageService()->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:recursive.I.' . $recursiveLevel);
}
if (!empty($recursiveLevelText)) {
$recursiveLevelText = '<br />' .
$this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.recursive') . ' ' .
$recursiveLevelText;
}
$this->summaryData[] = [
$this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.startingpoint'),
implode(', ', $pagesOut) . $recursiveLevelText
];
}
}
/**
* Render the settings as table for Web>Page module
*
* System settings are displayed in mono font
*/
private function renderSettingsAsTable(): string
{
if (count($this->summaryData) == 0) {
return '';
}
$content = '';
foreach ($this->summaryData as $line) {
$content .= '<strong>' . $line[0] . '</strong>' . ' ' . $line[1] . '<br />';
}
return '<pre style="white-space:normal">' . $content . '</pre>';
}
private function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
private function getDatabaseConnection(string $table = 'sys_file_collection'): Connection
{
return GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace MiniFranske\FsMediaGallery\Hooks;
/***************************************************************
* Copyright notice
*
* (c) 2014 Frans Saris <franssaris@gmail.com>
* 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 2 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\Core\DataHandling\DataHandler;
use TYPO3\CMS\Backend\Utility\BackendUtility;
/**
* Hooks called after sys_file_collection is added/updated/deleted
*/
class ProcessDatamapHook
{
/**
* Trigger updateFolderTree after change in sys_file_collection
*
* @param string $status
* @param string $table
* @param $id
* @param array $fieldArray
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler
*/
public function processDatamap_afterDatabaseOperations(
$status,
$table,
$id,
array $fieldArray,
DataHandler $dataHandler
) {
if ($table === 'sys_file_collection') {
BackendUtility::setUpdateSignal('updateFolderTree');
}
}
/**
* Trigger updateFolderTree after a sys_file_collection record is deleted
*
* @param string $command
* @param string $table
* @param int $id
* @param mixed $value
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler
* @param mixed $pasteUpdate
* @param array $pasteDatamap
*/
public function processCmdmap_postProcess(
$command,
$table,
$id,
$value,
DataHandler $dataHandler,
$pasteUpdate,
array $pasteDatamap
) {
if ($table === 'sys_file_collection') {
BackendUtility::setUpdateSignal('updateFolderTree');
}
}
}