first commit
This commit is contained in:
commit
1218dd1517
12716 files changed
+989233
No files matched your search
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Backend\ToolbarItem;
|
||||
|
||||
use TYPO3\CMS\Backend\Backend\ToolbarItems\SystemInformationToolbarItem;
|
||||
use TYPO3\CMS\Core\Utility\CommandUtility;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/**
|
||||
* VersionToolbarItem
|
||||
*/
|
||||
class VersionToolbarItem
|
||||
{
|
||||
/**
|
||||
* Called by the system information toolbar signal/slot dispatch.
|
||||
*
|
||||
* @param SystemInformationToolbarItem $systemInformation
|
||||
*/
|
||||
public function addVersionInformation(SystemInformationToolbarItem $systemInformation)
|
||||
{
|
||||
$value = null;
|
||||
$extensionDirectory = ExtensionManagementUtility::extPath('bootstrap_package');
|
||||
|
||||
// Try to get current version from git
|
||||
if (file_exists($extensionDirectory . '.git')) {
|
||||
CommandUtility::exec('git --version', $_, $returnCode);
|
||||
if ((int)$returnCode === 0) {
|
||||
$currentDir = getcwd();
|
||||
chdir($extensionDirectory);
|
||||
$tag = trim(CommandUtility::exec('git tag -l --points-at HEAD'));
|
||||
if ($tag) {
|
||||
$value = $tag;
|
||||
} else {
|
||||
$branch = trim(CommandUtility::exec('git rev-parse --abbrev-ref HEAD'));
|
||||
$revision = trim(CommandUtility::exec('git rev-parse --short HEAD'));
|
||||
$value = $branch . ', ' . $revision;
|
||||
}
|
||||
chdir($currentDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to version from extension manager
|
||||
if ($value === null) {
|
||||
$value = ExtensionManagementUtility::getExtensionVersion('bootstrap_package');
|
||||
}
|
||||
|
||||
// Set system information entry
|
||||
$systemInformation->addSystemInformation(
|
||||
'Bootstrap Package',
|
||||
htmlspecialchars($value, ENT_QUOTES | ENT_HTML5),
|
||||
'systeminformation-bootstrappackage'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\DataProcessing;
|
||||
|
||||
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
|
||||
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
|
||||
/**
|
||||
* Minimal TypoScript configuration
|
||||
* Assign all available typoscript constants for a key to template view, the
|
||||
* default key that is used is `page` and the default variable is `constants`.
|
||||
*
|
||||
* 10 = BK2K\BootstrapPackage\DataProcessing\ConstantsProcessor
|
||||
*
|
||||
*
|
||||
* Advanced TypoScript configuration
|
||||
*
|
||||
* 10 = BK2K\BootstrapPackage\DataProcessing\ConstantsProcessor
|
||||
* 10 {
|
||||
* key = page
|
||||
* as = constants
|
||||
* }
|
||||
*/
|
||||
class ConstantsProcessor implements DataProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
* @return array the processed data as key/value store
|
||||
*/
|
||||
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
|
||||
{
|
||||
// The key to process
|
||||
$key = $cObj->stdWrapValue('key', $processorConfiguration);
|
||||
if (empty($key)) {
|
||||
$key = 'page';
|
||||
}
|
||||
|
||||
// Collect variables
|
||||
$flatConstants = $this->getFlatConstants($key);
|
||||
$typoScriptParser = GeneralUtility::makeInstance(TypoScriptParser::class);
|
||||
$typoScriptParser->parse($flatConstants);
|
||||
$typoScriptArray = $typoScriptParser->setup;
|
||||
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
|
||||
$constants = $typoScriptService->convertTypoScriptArrayToPlainArray($typoScriptArray);
|
||||
|
||||
// Set the target variable
|
||||
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration);
|
||||
if (!empty($targetVariableName)) {
|
||||
$processedData[$targetVariableName] = $constants;
|
||||
} else {
|
||||
$processedData['constants'] = $constants;
|
||||
}
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
protected function getFlatConstants($key)
|
||||
{
|
||||
$flatvariables = '';
|
||||
$prefix = $key . '.';
|
||||
if ($GLOBALS['TSFE']->tmpl->flatSetup === null
|
||||
|| !is_array($GLOBALS['TSFE']->tmpl->flatSetup)
|
||||
|| count($GLOBALS['TSFE']->tmpl->flatSetup) === 0) {
|
||||
$GLOBALS['TSFE']->tmpl->generateConfig();
|
||||
}
|
||||
foreach ($GLOBALS['TSFE']->tmpl->flatSetup as $constant => $value) {
|
||||
if (strpos($constant, $prefix) === 0) {
|
||||
$flatvariables .= substr($constant, strlen($prefix)) . ' = ' . $value . PHP_EOL;
|
||||
}
|
||||
}
|
||||
return $flatvariables;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\DataProcessing;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\FileReference;
|
||||
use TYPO3\CMS\Core\Resource\ProcessedFile;
|
||||
use TYPO3\CMS\Core\Utility\CsvUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\DataProcessing\FilesProcessor;
|
||||
|
||||
/**
|
||||
* CsvFileProcessor
|
||||
*/
|
||||
class CsvFileProcessor extends FilesProcessor
|
||||
{
|
||||
/**
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
* @return array the processed data as key/value store
|
||||
*/
|
||||
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
|
||||
{
|
||||
// Set the maximum amount of columns
|
||||
$maximumColumns = $cObj->stdWrapValue('maximumColumns', $processorConfiguration, 0);
|
||||
|
||||
// Set the field delimiter which is "," by default
|
||||
$fieldDelimiter = $cObj->stdWrapValue('fieldDelimiter', $processorConfiguration, ',');
|
||||
|
||||
// Set the field enclosure which is " by default
|
||||
$fieldEnclosure = $cObj->stdWrapValue('fieldEnclosure', $processorConfiguration, '"');
|
||||
|
||||
// Get processed files
|
||||
$processedData = parent::process($cObj, $contentObjectConfiguration, $processorConfiguration, $processedData);
|
||||
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'files');
|
||||
$files = $processedData[$targetVariableName];
|
||||
unset($processedData[$targetVariableName]);
|
||||
|
||||
foreach ($files as $key => $value) {
|
||||
if (is_object($value) && in_array(get_class($value), [FileReference::class, File::class], true)) {
|
||||
/** @var ProcessedFile $value */
|
||||
if ($value->getExtension() !== 'csv') {
|
||||
unset($files[$key]);
|
||||
} else {
|
||||
$originalFile = $value->getOriginalFile();
|
||||
$content = $originalFile->getContents();
|
||||
$files[$key] = [
|
||||
'file' => $value,
|
||||
'bodytext' => $content,
|
||||
'table' => CsvUtility::csvToArray(
|
||||
$content,
|
||||
$fieldDelimiter,
|
||||
$fieldEnclosure,
|
||||
(int)$maximumColumns
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$files = array_values(array_filter($files));
|
||||
$processedData[$targetVariableName] = $files;
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\DataProcessing;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\FileReference;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
|
||||
/**
|
||||
* File Filter Processor
|
||||
* The DataProcessor requires a prepared array with Files or FilesReferences.
|
||||
* This required array is usually generated by the FilesProcessor so it must be
|
||||
* called first.
|
||||
*
|
||||
* Please note that the output variable name of the FilesProcessor
|
||||
* must be provided to the FileFilterProcessor.
|
||||
*
|
||||
*
|
||||
* Options:
|
||||
* variableName - Resultset to work on
|
||||
* predefinedList - Can be 'image', 'media' or 'text', will reference the
|
||||
* global TYPO3 settings for that file type, for example:
|
||||
* ['GFX']['imagefile_ext'] or ['SYS']['mediafile_ext']
|
||||
* allowedFileExtensions - List of allowed file extensions,
|
||||
* if set predefinedList will be overridden
|
||||
*
|
||||
*
|
||||
* Basic Example:
|
||||
* 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
|
||||
* 10 {
|
||||
* references.fieldName = image
|
||||
* folders.field = image_folder
|
||||
* sorting.field = filelink_sorting
|
||||
* as = files
|
||||
* }
|
||||
* 20 = BK2K\BootstrapPackage\DataProcessing\FileFilterProcessor
|
||||
* 20 {
|
||||
* variableName = files
|
||||
* predefinedList = image
|
||||
* }
|
||||
*
|
||||
*
|
||||
* Advanced Example:
|
||||
* 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
|
||||
* 10 {
|
||||
* references.fieldName = image
|
||||
* }
|
||||
* 20 = BK2K\BootstrapPackage\DataProcessing\FileFilterProcessor
|
||||
* 20 {
|
||||
* allowedFileExtensions = jpg, jpeg, gif
|
||||
* }
|
||||
*/
|
||||
class FileFilterProcessor implements DataProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
* @return array the processed data as key/value store
|
||||
*/
|
||||
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
|
||||
{
|
||||
$confVars = $GLOBALS['TYPO3_CONF_VARS'];
|
||||
$predefinedLists = [
|
||||
'image' => isset($confVars['GFX']['imagefile_ext']) ? $confVars['GFX']['imagefile_ext'] : 'gif,jpg,jpeg,tif,tiff,bmp,pcx,tga,png,pdf,ai,svg',
|
||||
'media' => isset($confVars['SYS']['mediafile_ext']) ? $confVars['SYS']['mediafile_ext'] : 'gif,jpg,jpeg,bmp,png,pdf,svg,ai,mp3,wav,mp4,ogg,flac,opus,webm,youtube,vimeo',
|
||||
'text' => isset($confVars['SYS']['textfile_ext']) ? $confVars['SYS']['textfile_ext'] : 'txt,ts,typoscript,html,htm,css,tmpl,js,sql,xml,csv,xlf,yaml,yml',
|
||||
];
|
||||
$predefinedList = $cObj->stdWrapValue('predefinedList', $processorConfiguration, 'image');
|
||||
$allowedFileExtensions = array_key_exists($predefinedList, $predefinedLists) ? $predefinedLists[$predefinedList] : '';
|
||||
$allowedFileExtensions = GeneralUtility::trimExplode(',', $cObj->stdWrapValue('allowedFileExtensions', $processorConfiguration, $allowedFileExtensions));
|
||||
if (empty($allowedFileExtensions)) {
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
$variableName = $cObj->stdWrapValue('variableName', $processorConfiguration, 'files');
|
||||
if (!isset($processedData[$variableName]) || empty($processedData[$variableName])) {
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
foreach ($processedData[$variableName] as $key => $value) {
|
||||
if (is_object($value)
|
||||
&& in_array(get_class($value), [FileReference::class, File::class], true)
|
||||
&& !in_array($value->getExtension(), $allowedFileExtensions, true)
|
||||
) {
|
||||
unset($processedData[$variableName][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\DataProcessing;
|
||||
|
||||
use TYPO3\CMS\Core\Service\FlexFormService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
|
||||
/**
|
||||
* Minimal TypoScript configuration
|
||||
* Process field pi_flexform and overrides the values stored in data
|
||||
*
|
||||
* 10 = BK2K\BootstrapPackage\DataProcessing\FlexFormProcessor
|
||||
*
|
||||
*
|
||||
* Advanced TypoScript configuration
|
||||
* Process field assigned in fieldName and stores processed data to new key
|
||||
*
|
||||
* 10 = BK2K\BootstrapPackage\DataProcessing\FlexFormProcessor
|
||||
* 10 {
|
||||
* fieldName = pi_flexform
|
||||
* as = flexform
|
||||
* }
|
||||
*/
|
||||
class FlexFormProcessor implements DataProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @var FlexFormService
|
||||
*/
|
||||
protected $flexFormService;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
* @return array the processed data as key/value store
|
||||
*/
|
||||
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
|
||||
{
|
||||
// The field name to process
|
||||
$fieldName = $cObj->stdWrapValue('fieldName', $processorConfiguration);
|
||||
if (empty($fieldName)) {
|
||||
$fieldName = 'pi_flexform';
|
||||
}
|
||||
if (!$processedData['data'][$fieldName]) {
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
// Process Flexform
|
||||
$originalValue = $processedData['data'][$fieldName];
|
||||
if (!is_string($originalValue)) {
|
||||
return $processedData;
|
||||
}
|
||||
$flexformData = $this->flexFormService->convertFlexFormContentToArray($originalValue);
|
||||
|
||||
// Set the target variable
|
||||
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration);
|
||||
if (!empty($targetVariableName)) {
|
||||
$processedData[$targetVariableName] = $flexformData;
|
||||
} else {
|
||||
$processedData['data'][$fieldName] = $flexformData;
|
||||
}
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\DataProcessing;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
|
||||
/**
|
||||
* This processor generates a set of file objects.
|
||||
*
|
||||
* 10 = BK2K\BootstrapPackage\DataProcessing\StaticFilesProcessor
|
||||
* 10 {
|
||||
* files {
|
||||
* 0.field = image
|
||||
* 1 = EXT:bootstrap_package/Resources/Public/Images/Icons/icon-1.png
|
||||
* circle = EXT:bootstrap_package/Resources/Public/Images/Icons/icon-circle.png
|
||||
* }
|
||||
* as = staticFiles
|
||||
* }
|
||||
*/
|
||||
class StaticFilesProcessor implements DataProcessorInterface
|
||||
{
|
||||
/**
|
||||
* @param ContentObjectRenderer $cObj The data of the content element or page
|
||||
* @param array $contentObjectConfiguration The configuration of Content Object
|
||||
* @param array $processorConfiguration The configuration of this processor
|
||||
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
|
||||
* @return array the processed data as key/value store
|
||||
*/
|
||||
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
|
||||
{
|
||||
if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
// Collect possible files
|
||||
$files = [];
|
||||
if (!empty($processorConfiguration['files.'])) {
|
||||
$filesConfiguration = $processorConfiguration['files.'];
|
||||
foreach ($filesConfiguration as $key => $file) {
|
||||
$key = substr($key, -1) === '.' ? substr_replace($key, '', -1) : $key;
|
||||
$value = $cObj->stdWrapValue($key, $filesConfiguration);
|
||||
if (!empty($value)) {
|
||||
$files[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get file objects
|
||||
$images = [];
|
||||
if (!empty($files)) {
|
||||
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
foreach ($files as $key => $file) {
|
||||
$absFilename = GeneralUtility::getFileAbsFileName($file);
|
||||
if (file_exists($absFilename)) {
|
||||
$images[$key] = $resourceFactory->retrieveFileOrFolderObject($absFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the target variable
|
||||
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration);
|
||||
if (!empty($targetVariableName)) {
|
||||
$processedData[$targetVariableName] = $images;
|
||||
} else {
|
||||
$processedData['staticFiles'] = $images;
|
||||
}
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ExpressionLanguage;
|
||||
|
||||
use TYPO3\CMS\Core\ExpressionLanguage\AbstractProvider;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* ConditionProvider
|
||||
*/
|
||||
class ConditionProvider extends AbstractProvider
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->expressionLanguageVariables = [
|
||||
'extension' => GeneralUtility::makeInstance(ExtensionWrapper::class)
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ExpressionLanguage;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/**
|
||||
* ExtensionWrapper
|
||||
*/
|
||||
class ExtensionWrapper
|
||||
{
|
||||
/**
|
||||
* @param string $extensionKey
|
||||
* @return bool
|
||||
*/
|
||||
public function isLoaded($extensionKey): bool
|
||||
{
|
||||
return ExtensionManagementUtility::isLoaded($extensionKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Hooks\PageRenderer;
|
||||
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\TypoScript\TemplateService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
use TYPO3\CMS\Frontend\Resource\FilePathSanitizer;
|
||||
|
||||
/**
|
||||
* FontLoaderHook
|
||||
*/
|
||||
class FontLoaderHook
|
||||
{
|
||||
/**
|
||||
* @var FilePathSanitizer
|
||||
*/
|
||||
protected $filePathSanitizer;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $includeMapping = [
|
||||
'includeCSSLibs' => 'cssLibs',
|
||||
'includeCSS' => 'cssFiles'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param FilePathSanitizer|null $filePathSanitizer
|
||||
*/
|
||||
public function __construct(FilePathSanitizer $filePathSanitizer = null)
|
||||
{
|
||||
if ($filePathSanitizer === null) {
|
||||
$filePathSanitizer = GeneralUtility::makeInstance(FilePathSanitizer::class);
|
||||
}
|
||||
$this->filePathSanitizer = $filePathSanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param PageRenderer $pagerenderer
|
||||
*/
|
||||
public function execute(&$params, &$pagerenderer)
|
||||
{
|
||||
if (TYPO3_MODE !== 'FE' ||
|
||||
(!is_array($params['cssFiles']) && !is_array($params['cssLibs']))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$webFonts = [];
|
||||
foreach ($this->includeMapping as $include => $section) {
|
||||
$webFonts = array_merge($webFonts, $this->collectWebFonts($include, $section));
|
||||
}
|
||||
|
||||
$urls = [];
|
||||
$families = [];
|
||||
if (count($webFonts) > 0) {
|
||||
foreach ($webFonts as $font) {
|
||||
if (isset($params[$font['section']][$font['filename']])) {
|
||||
unset($params[$font['section']][$font['filename']]);
|
||||
$urls = array_merge($urls, [$font['url']]);
|
||||
$families = array_merge($families, $font['families']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$config = [];
|
||||
if (count($urls) > 0 || count($families) > 0) {
|
||||
$config['custom']['urls'] = $urls;
|
||||
$config['custom']['families'] = $families;
|
||||
$config['timeout'] = 1000;
|
||||
$generatedCss = $this->generateCss();
|
||||
if (!empty($generatedCss)) {
|
||||
$params['headerData'][] = '<style>' . $generatedCss . '</style>';
|
||||
}
|
||||
$generatedJavaScript = $this->generateJavaScript($config);
|
||||
if (!empty($generatedJavaScript)) {
|
||||
$params['headerData'][] = '<script>' . $generatedJavaScript . '</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $include
|
||||
* @param $section
|
||||
* @return array
|
||||
*/
|
||||
private function collectWebFonts($include, $section)
|
||||
{
|
||||
$webFonts = [];
|
||||
$cssIncludes = $this->getPageCssConfiguration($include);
|
||||
foreach ($cssIncludes as $key => $filename) {
|
||||
if (substr($key, -1) === '.') {
|
||||
continue;
|
||||
}
|
||||
if ($cssIncludes[$key . '.']['fontLoader.']['enabled']) {
|
||||
$filename = $this->filePathSanitizer->sanitize($filename);
|
||||
$url = str_replace(' ', '+', $filename);
|
||||
$url = $this->getUriForFileName($url);
|
||||
$webFonts[$section . '_' . $key] = [
|
||||
'include' => $include,
|
||||
'section' => $section,
|
||||
'filename' => $filename,
|
||||
'url' => $url,
|
||||
'families' => $cssIncludes[$key . '.']['fontLoader.']['families.'] ?: []
|
||||
];
|
||||
}
|
||||
}
|
||||
return $webFonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
* @return string
|
||||
*/
|
||||
private function generateJavaScript($config)
|
||||
{
|
||||
$inlineJavaScript = [];
|
||||
$inlineJavaScript[] = 'WebFontConfig=' . json_encode($config) . ';';
|
||||
$inlineJavaScript[] = '(function(d){var wf=d.createElement(\'script\'),s=d.scripts[0];';
|
||||
$inlineJavaScript[] = 'wf.src=\'' . $this->getUriForFileName('EXT:bootstrap_package/Resources/Public/Contrib/webfontloader/webfontloader.js') . '\';';
|
||||
$inlineJavaScript[] = 'wf.async=false;';
|
||||
$inlineJavaScript[] = 's.parentNode.insertBefore(wf,s);';
|
||||
$inlineJavaScript[] = '})(document);';
|
||||
return implode('', $inlineJavaScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateCss()
|
||||
{
|
||||
$inlineStyle = [];
|
||||
|
||||
if ($this->getTypoScriptConstant('page.preloader.enable')) {
|
||||
$bodyStyles = [];
|
||||
$bodyStyles[] = 'user-select:none;';
|
||||
$bodyStyles[] = 'pointer-events:none;';
|
||||
$bodyStyles[] = 'background-position:center center;';
|
||||
$bodyStyles[] = 'background-repeat:no-repeat;';
|
||||
$bodyStyles[] = 'content:\'\';';
|
||||
$bodyStyles[] = 'position:fixed;';
|
||||
$bodyStyles[] = 'top:-100%;';
|
||||
$bodyStyles[] = 'left:0;';
|
||||
$bodyStyles[] = 'z-index:10000;';
|
||||
$bodyStyles[] = 'opacity:0;';
|
||||
$bodyStyles[] = 'height:100%;';
|
||||
$bodyStyles[] = 'width:100%;';
|
||||
|
||||
$backgroundColor = $this->getTypoScriptConstant('page.preloader.backgroundColor');
|
||||
if (!empty($backgroundColor)) {
|
||||
$bodyStyles[] = 'background-color:' . $backgroundColor . ';';
|
||||
} else {
|
||||
$bodyStyles[] = 'background-color:#ffffff;';
|
||||
}
|
||||
|
||||
$logo = $this->getTypoScriptConstant('page.preloader.logo.file');
|
||||
if (!empty($logo)) {
|
||||
$logoFile = $this->getUriForFileName($logo);
|
||||
$logoHeight = (int) $this->getTypoScriptConstant('page.preloader.logo.height');
|
||||
$logoWidth = (int) $this->getTypoScriptConstant('page.preloader.logo.width');
|
||||
$bodyStyles[] = 'background-image: url(\'' . $logoFile . '\');';
|
||||
$bodyStyles[] = 'background-size:' . $logoWidth . 'px ' . $logoHeight . 'px;';
|
||||
}
|
||||
|
||||
$loadingStyles = [];
|
||||
$bodyStyles[] = 'user-select:initial;';
|
||||
$bodyStyles[] = 'pointer-events:initial;';
|
||||
$loadingStyles[] = 'top:0;';
|
||||
$loadingStyles[] = 'opacity:1!important;';
|
||||
|
||||
$duration = (float) $this->getTypoScriptConstant('page.preloader.fadeDuration');
|
||||
$transition = 'opacity ' . $duration . 's ease-out';
|
||||
$activeStyles = [];
|
||||
$activeStyles[] = 'top: 0;';
|
||||
$activeStyles[] = 'opacity:0!important;';
|
||||
$activeStyles[] = 'user-select:none;';
|
||||
$activeStyles[] = 'pointer-events:none;';
|
||||
$activeStyles[] = '-webkit-transition:' . $transition . ';';
|
||||
$activeStyles[] = '-moz-transition:' . $transition . ';';
|
||||
$activeStyles[] = '-o-transition:' . $transition . ';';
|
||||
$activeStyles[] = 'transition:' . $transition . ';';
|
||||
|
||||
$inlineStyle[] = 'body:before{' . implode('', $bodyStyles) . '}';
|
||||
$inlineStyle[] = '.js body:before,.wf-loading body:before{' . implode('', $loadingStyles) . '}';
|
||||
$inlineStyle[] = '.wf-active body:before,.wf-inactive body:before{' . implode('', $activeStyles) . '}';
|
||||
}
|
||||
|
||||
return implode('', $inlineStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $section
|
||||
* @return array
|
||||
*/
|
||||
private function getPageCssConfiguration($section)
|
||||
{
|
||||
if (isset($this->getTemplateService()->setup['page.'][$section . '.'])) {
|
||||
return $this->getTemplateService()->setup['page.'][$section . '.'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $typoscriptConstant
|
||||
* @return string
|
||||
*/
|
||||
private function getTypoScriptConstant($typoscriptConstant)
|
||||
{
|
||||
if (!isset($this->getTemplateService()->flatSetup)
|
||||
|| !is_array($this->getTemplateService()->flatSetup)
|
||||
|| count($this->getTemplateService()->flatSetup) === 0) {
|
||||
$this->getTemplateService()->generateConfig();
|
||||
}
|
||||
if (isset($this->getTemplateService()->flatSetup[$typoscriptConstant])) {
|
||||
return $this->getTemplateService()->flatSetup[$typoscriptConstant];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateService
|
||||
*/
|
||||
private function getTemplateService()
|
||||
{
|
||||
return $GLOBALS['TSFE']->tmpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private function getUriForFileName($filename)
|
||||
{
|
||||
if (strpos($filename, '://')) {
|
||||
return $filename;
|
||||
}
|
||||
$urlPrefix = '';
|
||||
if (strpos($filename, 'EXT:') === 0) {
|
||||
$absoluteFilename = GeneralUtility::getFileAbsFileName($filename);
|
||||
$filename = '';
|
||||
if ($absoluteFilename !== '') {
|
||||
$filename = PathUtility::getAbsoluteWebPath($absoluteFilename);
|
||||
}
|
||||
} elseif (strpos($filename, '/') !== 0) {
|
||||
$urlPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
|
||||
}
|
||||
return $urlPrefix . $filename;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Hooks\PageRenderer;
|
||||
|
||||
use BK2K\BootstrapPackage\Service\GoogleFontService;
|
||||
use TYPO3\CMS\Core\TypoScript\TemplateService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* GoogleFontHook
|
||||
*/
|
||||
class GoogleFontHook
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $includeMapping = [
|
||||
'includeCSSLibs' => 'cssLibs',
|
||||
'includeCSS' => 'cssFiles'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var \BK2K\BootstrapPackage\Service\GoogleFontService
|
||||
*/
|
||||
protected $googleFontService;
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param \TYPO3\CMS\Core\Page\PageRenderer $pagerenderer
|
||||
*/
|
||||
public function execute(&$params, &$pagerenderer)
|
||||
{
|
||||
if (TYPO3_MODE !== 'FE' ||
|
||||
(!is_array($params['cssFiles']) && !is_array($params['cssLibs']))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->includeMapping as $include => $section) {
|
||||
if (is_array($params[$section])) {
|
||||
$files = [];
|
||||
foreach ($params[$section] as $file => $settings) {
|
||||
$cachedFile = $this->getGoogleFontService()->getCachedFile($file);
|
||||
if ($cachedFile !== false) {
|
||||
$this->adjustTypoScriptCssConfiguration($include, $file, $cachedFile);
|
||||
$settings['file'] = $cachedFile;
|
||||
$files[$cachedFile] = $settings;
|
||||
} else {
|
||||
$files[$file] = $settings;
|
||||
}
|
||||
$params[$section] = $files;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $include
|
||||
* @param string $file
|
||||
* @param string $cachedFile
|
||||
*/
|
||||
protected function adjustTypoScriptCssConfiguration($include, $file, $cachedFile)
|
||||
{
|
||||
$includeFilesConfiguration = $this->getTemplateService()->setup['page.'][$include . '.'];
|
||||
if (!empty($includeFilesConfiguration)) {
|
||||
foreach ($includeFilesConfiguration as $includeKey => $includeFilename) {
|
||||
if (substr($includeKey, -1) === '.') {
|
||||
continue;
|
||||
}
|
||||
if ($file === $includeFilename) {
|
||||
$this->getTemplateService()->setup['page.'][$include . '.'][$includeKey] = $cachedFile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the google font service
|
||||
*
|
||||
* @return GoogleFontService
|
||||
*/
|
||||
protected function getGoogleFontService()
|
||||
{
|
||||
if ($this->googleFontService === null) {
|
||||
$this->googleFontService = GeneralUtility::makeInstance(GoogleFontService::class);
|
||||
}
|
||||
return $this->googleFontService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateService
|
||||
*/
|
||||
private function getTemplateService()
|
||||
{
|
||||
return $GLOBALS['TSFE']->tmpl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Hooks\PageRenderer;
|
||||
|
||||
use BK2K\BootstrapPackage\Service\CompileService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* PreProcessHook
|
||||
*/
|
||||
class PreProcessHook
|
||||
{
|
||||
/**
|
||||
* @var \BK2K\BootstrapPackage\Service\CompileService
|
||||
*/
|
||||
protected $compileService;
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @param \TYPO3\CMS\Core\Page\PageRenderer $pagerenderer
|
||||
*/
|
||||
public function execute(&$params, &$pagerenderer)
|
||||
{
|
||||
if (TYPO3_MODE !== 'FE') {
|
||||
return;
|
||||
}
|
||||
foreach (['cssLibs', 'cssFiles'] as $key) {
|
||||
$files = [];
|
||||
if (is_array($params[$key])) {
|
||||
foreach ($params[$key] as $file => $settings) {
|
||||
$compiledFile = $this->getCompileService()->getCompiledFile($file);
|
||||
if ($compiledFile !== false) {
|
||||
$settings['file'] = $compiledFile;
|
||||
$files[$compiledFile] = $settings;
|
||||
} else {
|
||||
$files[$file] = $settings;
|
||||
}
|
||||
}
|
||||
$params[$key] = $files;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compile service
|
||||
*
|
||||
* @return CompileService
|
||||
*/
|
||||
protected function getCompileService()
|
||||
{
|
||||
if ($this->compileService === null) {
|
||||
$this->compileService = GeneralUtility::makeInstance(CompileService::class);
|
||||
}
|
||||
return $this->compileService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Parser;
|
||||
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* AbstractParser
|
||||
*/
|
||||
abstract class AbstractParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $extension
|
||||
* @return bool
|
||||
*/
|
||||
public function supports($extension)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
public function compile($file, $settings)
|
||||
{
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return bool
|
||||
*/
|
||||
protected function isCached($file, $settings)
|
||||
{
|
||||
$cacheIdentifier = $this->getCacheIdentifier($file, $settings);
|
||||
$cacheFile = $this->getCacheFile($cacheIdentifier, $settings['cache']['tempDirectory']);
|
||||
$cacheFileMeta = $this->getCacheFileMeta($cacheFile);
|
||||
|
||||
return file_exists($cacheFile) && file_exists($cacheFileMeta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cacheFile
|
||||
* @param string $cacheFileMeta
|
||||
* @param array $settings
|
||||
* @return bool
|
||||
*/
|
||||
protected function needsCompile($cacheFile, $cacheFileMeta, $settings)
|
||||
{
|
||||
$needCompilation = false;
|
||||
$fileModificationTime = filemtime($cacheFile);
|
||||
$metadata = unserialize(file_get_contents($cacheFileMeta), ['allowed_classes' => false]);
|
||||
|
||||
foreach ($metadata['files'] as $file => $cacheTime) {
|
||||
$currentTime = filemtime($file);
|
||||
if ($currentTime !== $cacheTime || $currentTime > $fileModificationTime) {
|
||||
$needCompilation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$needCompilation && $settings['variables'] !== $metadata['variables']) {
|
||||
$needCompilation = true;
|
||||
}
|
||||
|
||||
if (!$needCompilation && $settings['options']['sourceMap'] !== $metadata['sourceMap']) {
|
||||
$needCompilation = true;
|
||||
}
|
||||
|
||||
return $needCompilation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cacheIdentifier
|
||||
* @param string $tempDirectory
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheFile($cacheIdentifier, $tempDirectory)
|
||||
{
|
||||
return $tempDirectory . $cacheIdentifier . '.css';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheFileMeta($filename)
|
||||
{
|
||||
return $filename . '.meta';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheIdentifier($file, $settings)
|
||||
{
|
||||
$filehash = md5($file);
|
||||
$hash = hash('sha256', $filehash . serialize($settings));
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
|
||||
return basename($file, '.' . $extension) . '-' . $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getPathSite()
|
||||
{
|
||||
return Environment::getPublicPath() . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all page caches
|
||||
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException
|
||||
*/
|
||||
protected function clearPageCaches()
|
||||
{
|
||||
GeneralUtility::makeInstance(CacheManager::class)->flushCachesInGroup('pages');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Parser;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* LessParser
|
||||
*/
|
||||
class LessParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!class_exists('Less_Cache')) {
|
||||
require_once ExtensionManagementUtility::extPath('bootstrap_package') . '/Contrib/less.php/Less.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension
|
||||
* @return bool
|
||||
*/
|
||||
public function supports($extension)
|
||||
{
|
||||
return $extension === 'less';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
public function compile($file, $settings)
|
||||
{
|
||||
$cacheIdentifier = $this->getCacheIdentifier($file, $settings);
|
||||
$cacheFile = $this->getCacheFile($cacheIdentifier, $settings['cache']['tempDirectory']);
|
||||
$cacheFileMeta = $this->getCacheFileMeta($cacheFile);
|
||||
$compile = false;
|
||||
|
||||
if (!$this->isCached($file, $settings)
|
||||
|| $this->needsCompile($cacheFile, $cacheFileMeta, $settings)) {
|
||||
$compile = true;
|
||||
}
|
||||
|
||||
if ($compile) {
|
||||
$result = $this->parseFile($file, $settings);
|
||||
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFile), $result['css']);
|
||||
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFileMeta), serialize($result['cache']));
|
||||
$this->clearPageCaches();
|
||||
}
|
||||
|
||||
return $cacheFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function parseFile($file, $settings)
|
||||
{
|
||||
$options = [];
|
||||
$options['compress'] = true;
|
||||
if ($settings['options']['sourceMap']) {
|
||||
$options['compress'] = false;
|
||||
$options['sourceMap'] = true;
|
||||
$options['sourceMapBasepath'] = realpath($this->getPathSite());
|
||||
$options['sourceMapRootpath'] = $settings['cache']['tempDirectoryRelativeToRoot'];
|
||||
}
|
||||
|
||||
$parser = new \Less_Parser($options);
|
||||
$parser->parseFile(GeneralUtility::getFileAbsFileName($file));
|
||||
$parser->ModifyVars($settings['variables']);
|
||||
$css = $parser->getCss();
|
||||
|
||||
// Correct relative urls
|
||||
$absoluteFilename = GeneralUtility::getFileAbsFileName($file);
|
||||
$relativePath = $settings['cache']['tempDirectoryRelativeToRoot'] . dirname(substr($absoluteFilename, strlen($this->getPathSite()))) . '/';
|
||||
$search = '%url\s*\(\s*[\\\'"]?(?!(((?:https?:)?\/\/)|(?:data:?:)))([^\\\'")]+)[\\\'"]?\s*\)%';
|
||||
$replace = 'url("' . $relativePath . '$3")';
|
||||
$css = preg_replace($search, $replace, $css);
|
||||
|
||||
$parsedFiles = [];
|
||||
foreach ($parser::AllParsedFiles() as $parsedfile) {
|
||||
$parsedFiles[$parsedfile] = filemtime($parsedfile);
|
||||
}
|
||||
|
||||
return [
|
||||
'css' => $css,
|
||||
'cache' => [
|
||||
'version' => \Less_Version::version,
|
||||
'date' => date('r'),
|
||||
'css' => $css,
|
||||
'etag' => md5($css),
|
||||
'files' => $parsedFiles,
|
||||
'variables' => $settings['variables'],
|
||||
'sourceMap' => $settings['options']['sourceMap']
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Parser;
|
||||
|
||||
/**
|
||||
* ParserInterface
|
||||
*/
|
||||
interface ParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $extension
|
||||
* @return bool
|
||||
*/
|
||||
public function supports($extension);
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
public function compile($file, $settings);
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Parser;
|
||||
|
||||
use ScssPhp\ScssPhp\Compiler;
|
||||
use ScssPhp\ScssPhp\Formatter\Compressed;
|
||||
use ScssPhp\ScssPhp\Version;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
/**
|
||||
* ScssParser
|
||||
*/
|
||||
class ScssParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!class_exists('ScssPhp\ScssPhp\Version')) {
|
||||
require_once ExtensionManagementUtility::extPath('bootstrap_package') . '/Contrib/scssphp/scss.inc.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension
|
||||
* @return bool
|
||||
*/
|
||||
public function supports($extension)
|
||||
{
|
||||
return $extension === 'scss';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return string
|
||||
*/
|
||||
public function compile($file, $settings)
|
||||
{
|
||||
$cacheIdentifier = $this->getCacheIdentifier($file, $settings);
|
||||
$cacheFile = $this->getCacheFile($cacheIdentifier, $settings['cache']['tempDirectory']);
|
||||
$cacheFileMeta = $this->getCacheFileMeta($cacheFile);
|
||||
$compile = false;
|
||||
|
||||
if (!$this->isCached($file, $settings)
|
||||
|| $this->needsCompile($cacheFile, $cacheFileMeta, $settings)) {
|
||||
$compile = true;
|
||||
}
|
||||
|
||||
if ($compile) {
|
||||
$result = $this->parseFile($file, $settings);
|
||||
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFile), $result['css']);
|
||||
GeneralUtility::writeFile(GeneralUtility::getFileAbsFileName($cacheFileMeta), serialize($result['cache']));
|
||||
$this->clearPageCaches();
|
||||
}
|
||||
|
||||
return $cacheFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function parseFile($file, $settings)
|
||||
{
|
||||
$scss = new Compiler();
|
||||
$scss->setFormatter(Compressed::class);
|
||||
$scss->setVariables($settings['variables']);
|
||||
if ($settings['options']['sourceMap']) {
|
||||
$scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
|
||||
$scss->setSourceMapOptions([
|
||||
'sourceMapRootpath' => $settings['cache']['tempDirectoryRelativeToRoot'],
|
||||
'sourceMapBasepath' => '<PATH DOES NOT EXIST BUT SUPRESSES WARNINGS>'
|
||||
]);
|
||||
}
|
||||
$absoluteFilename = $settings['file']['absolute'];
|
||||
// Adds visual directory path of the initial file as import path
|
||||
// This scenarios happens, when e.g. developing packages using the `path`
|
||||
// repository feature of Composer - having one package in `public/typo3conf/ext/`
|
||||
// and the other one symlinked in e.g. `packages/`.
|
||||
// Since the PHP SCSS parser works on resolved real paths, the symlinked context is lost.
|
||||
$visualImportPath = dirname($absoluteFilename);
|
||||
$scss->addImportPath(function ($url) use ($visualImportPath) {
|
||||
// Resolve potential back paths manually using PathUtility::getCanonicalPath,
|
||||
// but make sure we do not break out of TYPO3 application path using GeneralUtility::getFileAbsFileName
|
||||
// Also resolve EXT: paths if given
|
||||
$isTypo3Absolute = (strpos($url, 'EXT:') === 0) || PathUtility::isAbsolutePath($url);
|
||||
$fileName = $isTypo3Absolute ? $url : $visualImportPath . '/' . $url;
|
||||
$full = GeneralUtility::getFileAbsFileName(PathUtility::getCanonicalPath($fileName));
|
||||
// The API forces us to check the existence of files paths, with or without url.
|
||||
// We must only return a string if the file to be imported actually exists.
|
||||
$hasExtension = preg_match('/[.]s?css$/', $url);
|
||||
if (
|
||||
is_file($file = $full . '.scss') ||
|
||||
($hasExtension && is_file($file = $full))
|
||||
) {
|
||||
// We could trigger a deprecation message here at some point
|
||||
return $file;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
// Add extensions path to import paths, so that we can use paths relative to this directory to resolve imports
|
||||
$scss->addImportPath(Environment::getExtensionsPath());
|
||||
|
||||
// Make paths in url() statements relative to site root
|
||||
$absoluteFilePath = dirname($absoluteFilename);
|
||||
$relativeFilePath = PathUtility::getAbsoluteWebPath($absoluteFilePath);
|
||||
$absoluteBootstrapPackageThemePath =
|
||||
ExtensionManagementUtility::extPath('bootstrap_package') . 'Resources/Public/Scss/Theme';
|
||||
$relativeBootstrapPackageThemePath = PathUtility::getAbsoluteWebPath($absoluteBootstrapPackageThemePath);
|
||||
$scss->registerFunction(
|
||||
'url',
|
||||
function ($args) use (
|
||||
$scss,
|
||||
$absoluteFilePath,
|
||||
$relativeFilePath,
|
||||
$absoluteBootstrapPackageThemePath,
|
||||
$relativeBootstrapPackageThemePath
|
||||
) {
|
||||
$marker = $args[0][1];
|
||||
$args[0][1] = '';
|
||||
$result = $scss->compileValue($args[0]);
|
||||
if (substr_compare($result, 'data:', 0, 5, true) !== 0) {
|
||||
if (is_file(PathUtility::getCanonicalPath($absoluteFilePath . '/' . $result))) {
|
||||
$result = PathUtility::getCanonicalPath($relativeFilePath . '/' . $result);
|
||||
} elseif (is_file(PathUtility::getCanonicalPath($absoluteBootstrapPackageThemePath . '/' . $result))) {
|
||||
$result = PathUtility::getCanonicalPath($relativeBootstrapPackageThemePath . '/' . $result);
|
||||
}
|
||||
$result = substr($result, 0, 1) === '/' ? substr($result, 1) : $result;
|
||||
}
|
||||
return 'url(' . $marker . $result . $marker . ')';
|
||||
}
|
||||
);
|
||||
|
||||
// Compile file
|
||||
$css = $scss->compile('@import "' . $absoluteFilename . '"');
|
||||
|
||||
// Fix paths in url() statements to be relative to temp directory
|
||||
$relativeTempPath = $settings['cache']['tempDirectoryRelativeToRoot'];
|
||||
$search = '%url\s*\(\s*[\\\'"]?(?!(((?:https?:)?\/\/)|(?:data:?:)))([^\\\'")]+)[\\\'"]?\s*\)%';
|
||||
$replace = 'url("' . $relativeTempPath . '$3")';
|
||||
$css = preg_replace($search, $replace, $css);
|
||||
|
||||
return [
|
||||
'css' => $css,
|
||||
'cache' => [
|
||||
'version' => Version::VERSION,
|
||||
'date' => date('r'),
|
||||
'css' => $css,
|
||||
'etag' => md5($css),
|
||||
'files' => $scss->getParsedFiles(),
|
||||
'variables' => $settings['variables'],
|
||||
'sourceMap' => $settings['options']['sourceMap']
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* BrandingService
|
||||
*/
|
||||
class BrandingService
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const EXT_KEY = 'bootstrap_package';
|
||||
|
||||
/**
|
||||
* @param string $extension
|
||||
*/
|
||||
public function setBackendStyling($extension = null)
|
||||
{
|
||||
if ($extension === self::EXT_KEY && class_exists(ExtensionConfiguration::class)) {
|
||||
$extensionConfiguration = GeneralUtility::makeInstance(
|
||||
ExtensionConfiguration::class
|
||||
);
|
||||
$backendConfiguration = $extensionConfiguration->get('backend');
|
||||
|
||||
if (!isset($backendConfiguration['loginLogo']) || empty(trim($backendConfiguration['loginLogo']))) {
|
||||
$backendConfiguration['loginLogo'] = 'EXT:bootstrap_package/Resources/Public/Images/Backend/login-logo.svg';
|
||||
}
|
||||
if (!isset($backendConfiguration['loginBackgroundImage']) || empty(trim($backendConfiguration['loginBackgroundImage']))) {
|
||||
$backendConfiguration['loginBackgroundImage'] = 'EXT:bootstrap_package/Resources/Public/Images/Backend/login-background-image.jpg';
|
||||
}
|
||||
if (!isset($backendConfiguration['backendLogo']) || empty(trim($backendConfiguration['backendLogo']))) {
|
||||
$backendConfiguration['backendLogo'] = 'EXT:bootstrap_package/Resources/Public/Images/Backend/backend-logo.svg';
|
||||
}
|
||||
|
||||
$reflection = new \ReflectionClass(ExtensionConfiguration::class);
|
||||
$parameters = $reflection->getMethod('set')->getParameters();
|
||||
|
||||
if (count($parameters) === 3) {
|
||||
$extensionConfiguration->set('backend', '', $backendConfiguration);
|
||||
} else {
|
||||
$extensionConfiguration->set('backend', $backendConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Service;
|
||||
|
||||
use BK2K\BootstrapPackage\Parser\ParserInterface;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This service handles the parsing of less files for the frontend.
|
||||
*/
|
||||
class CompileService
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tempDirectory = 'typo3temp/assets/bootstrappackage/css/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tempDirectoryRelativeToRoot = '../../../../';
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return bool|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getCompiledFile($file)
|
||||
{
|
||||
$absoluteFile = GeneralUtility::getFileAbsFileName($file);
|
||||
$configuration = ($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_bootstrappackage.']['settings.'] ?: []);
|
||||
|
||||
// Ensure cache directory exists
|
||||
if (!file_exists(Environment::getPublicPath() . '/' . $this->tempDirectory)) {
|
||||
GeneralUtility::mkdir_deep(Environment::getPublicPath() . '/' . $this->tempDirectory);
|
||||
}
|
||||
|
||||
// Settings
|
||||
$settings = [
|
||||
'file' => [
|
||||
'absolute' => $absoluteFile,
|
||||
'relative' => $file,
|
||||
'info' => pathinfo($absoluteFile)
|
||||
],
|
||||
'cache' => [
|
||||
'tempDirectory' => $this->tempDirectory,
|
||||
'tempDirectoryRelativeToRoot' => $this->tempDirectoryRelativeToRoot,
|
||||
],
|
||||
'options' => [
|
||||
'override' => $configuration['overrideParserVariables'] ? true: false,
|
||||
'sourceMap' => $configuration['cssSourceMapping'] ? true : false,
|
||||
'compress' => true
|
||||
],
|
||||
'variables' => []
|
||||
];
|
||||
|
||||
// Parser
|
||||
if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/bootstrap-package/css']['parser'])) {
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/bootstrap-package/css']['parser'] as $className) {
|
||||
/** @var ParserInterface $parser */
|
||||
$parser = GeneralUtility::makeInstance($className);
|
||||
if ($parser->supports($settings['file']['info']['extension'])) {
|
||||
if ($configuration['overrideParserVariables']) {
|
||||
$settings['variables'] = $this->getVariablesFromConstants($settings['file']['info']['extension']);
|
||||
}
|
||||
try {
|
||||
return $parser->compile($file, $settings);
|
||||
} catch (\Exception $e) {
|
||||
$this->clearCompilerCaches();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension
|
||||
* @return array
|
||||
*/
|
||||
protected function getVariablesFromConstants($extension)
|
||||
{
|
||||
$constants = $this->getConstants();
|
||||
$extension = strtolower($extension);
|
||||
$variables = [];
|
||||
|
||||
// Fetch Google Font
|
||||
$variables['google-webfont'] = 'sans-serif';
|
||||
if (!empty($constants['page.theme.googleFont.enable'])
|
||||
&& !empty($constants['page.theme.googleFont.font'])) {
|
||||
$variables['google-webfont'] = $constants['page.theme.googleFont.font'];
|
||||
}
|
||||
|
||||
// Fetch SCSS / Less settings
|
||||
$prefix = 'plugin.bootstrap_package.settings.' . $extension . '.';
|
||||
foreach ($constants as $constant => $value) {
|
||||
if (strpos($constant, $prefix) === 0) {
|
||||
$variables[substr($constant, strlen($prefix))] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getConstants()
|
||||
{
|
||||
if ($GLOBALS['TSFE']->tmpl->flatSetup === null
|
||||
|| !is_array($GLOBALS['TSFE']->tmpl->flatSetup)
|
||||
|| count($GLOBALS['TSFE']->tmpl->flatSetup) === 0) {
|
||||
$GLOBALS['TSFE']->tmpl->generateConfig();
|
||||
}
|
||||
return $GLOBALS['TSFE']->tmpl->flatSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all caches for the compiler.
|
||||
*/
|
||||
protected function clearCompilerCaches()
|
||||
{
|
||||
GeneralUtility::rmdir(Environment::getPublicPath() . '/' . $this->tempDirectory, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Service;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* GoogleFontService
|
||||
*/
|
||||
class GoogleFontService
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tempDirectory = 'typo3temp/assets/bootstrappackage/fonts';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $googleFontApiUrl = 'fonts.googleapis.com/css';
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return bool|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getCachedFile($file)
|
||||
{
|
||||
if (!$this->supports($file)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->isCached($file)) {
|
||||
return $this->getCssFileCacheName($file);
|
||||
}
|
||||
return $this->cacheFile($file) ? $this->getCssFileCacheName($file) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
protected function cacheFile($file)
|
||||
{
|
||||
/** @var RequestFactory */
|
||||
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
|
||||
|
||||
/** @var ResponseInterface */
|
||||
$response = $requestFactory->request($file, 'GET', [
|
||||
'headers' => ['User-Agent' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)']
|
||||
]);
|
||||
|
||||
if ($response->getStatusCode() >= 300) {
|
||||
return false;
|
||||
} else {
|
||||
$content = $response->getBody()->getContents();
|
||||
}
|
||||
|
||||
// Ensure cache directory exists
|
||||
GeneralUtility::mkdir_deep($this->tempDirectory . '/' . $this->getCacheIdentifier($file));
|
||||
|
||||
// Find and Download font files
|
||||
$pattern = '%url\((.*?)\)%';
|
||||
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);
|
||||
$fontFiles = [];
|
||||
foreach ($matches as $match) {
|
||||
$fontFiles[$match[1]] = $match[1];
|
||||
}
|
||||
foreach ($fontFiles as $fontFile) {
|
||||
$localFontFile = $this->getCacheDirectory($file) . '/' . basename($fontFile);
|
||||
/** @var ResponseInterface */
|
||||
$response = $requestFactory->request($fontFile);
|
||||
if ($response->getStatusCode() >= 300) {
|
||||
continue;
|
||||
} else {
|
||||
$fontFileContent = $response->getBody()->getContents();
|
||||
}
|
||||
file_put_contents($localFontFile, $fontFileContent);
|
||||
GeneralUtility::fixPermissions($localFontFile);
|
||||
$content = str_replace($fontFile, basename($fontFile), $content);
|
||||
}
|
||||
|
||||
// Save CSS File
|
||||
$cacheFile = $this->getCacheDirectory($file) . '/' . 'webfont.css';
|
||||
file_put_contents(GeneralUtility::getFileAbsFileName($cacheFile), $content);
|
||||
GeneralUtility::fixPermissions($cacheFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
protected function supports($file)
|
||||
{
|
||||
return strpos($file, $this->googleFontApiUrl) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
protected function isCached($file)
|
||||
{
|
||||
$cacheFile = $this->getCssFileCacheName($file);
|
||||
$absoluteFile = GeneralUtility::getFileAbsFileName($cacheFile);
|
||||
|
||||
if (!file_exists($absoluteFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Discard cache after 24 hours
|
||||
if ((time() - filemtime($absoluteFile)) > 86400) {
|
||||
GeneralUtility::rmdir($this->getCacheDirectory($file));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
protected function getCssFileCacheName($file)
|
||||
{
|
||||
return $this->getCacheDirectory($file) . '/' . 'webfont.css';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheDirectory($file)
|
||||
{
|
||||
return $this->tempDirectory . '/' . $this->getCacheIdentifier($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheIdentifier($file)
|
||||
{
|
||||
return hash('sha256', $file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessageService;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* InstallService
|
||||
*/
|
||||
class InstallService
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const EXT_KEY = 'bootstrap_package';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $messageQueueByIdentifier = '';
|
||||
|
||||
/**
|
||||
* Initializes the install service
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->messageQueueByIdentifier = 'extbase.flashmessages.tx_extensionmanager_tools_extensionmanagerextensionmanager';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension
|
||||
*/
|
||||
public function generateApacheHtaccess($extension = null)
|
||||
{
|
||||
if ($extension === self::EXT_KEY) {
|
||||
if (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === 0) {
|
||||
$this->createConfigurationFile('.htaccess');
|
||||
} elseif (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === 0) {
|
||||
$this->createConfigurationFile('web.config');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates webserver configuration file inside the root directory
|
||||
*
|
||||
* @param $filename
|
||||
*/
|
||||
private function createConfigurationFile($filename)
|
||||
{
|
||||
$absFilename = GeneralUtility::getFileAbsFileName($filename);
|
||||
if (file_exists($absFilename)) {
|
||||
// Add Flashmessage that there is already an configuration file and we are not going to override this.
|
||||
$flashMessage = GeneralUtility::makeInstance(
|
||||
FlashMessage::class,
|
||||
'There is already an ' . $filename . ' configuration file in the root directory, '
|
||||
. 'please make sure that configuration files are protected and the url rewritings are set properly. '
|
||||
. 'An example configuration is located at: "typo3conf/ext/bootstrap_package/Configuration/Server/_' . $filename . '"',
|
||||
'Webserver configuration file "' . $filename . '" already exists',
|
||||
FlashMessage::NOTICE,
|
||||
true
|
||||
);
|
||||
$this->addFlashMessage($flashMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
$filecontent = GeneralUtility::getUrl(ExtensionManagementUtility::extPath(self::EXT_KEY) . '/Configuration/Server/_' . $filename);
|
||||
if ($filecontent && is_string($filecontent)) {
|
||||
GeneralUtility::writeFile($absFilename, $filecontent, true);
|
||||
// Add Flashmessage that the example configuration file was placed in the root directory
|
||||
$flashMessage = GeneralUtility::makeInstance(
|
||||
FlashMessage::class,
|
||||
'For securing configuration files and optimization purposes an example ' . $filename . ' file was placed in your root directory.',
|
||||
'Webserver configuration file "' . $filename . '" was placed in the root directory.',
|
||||
FlashMessage::OK,
|
||||
true
|
||||
);
|
||||
$this->addFlashMessage($flashMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Flash Message to the Flash Message Queue
|
||||
*
|
||||
* @param FlashMessage $flashMessage
|
||||
*/
|
||||
public function addFlashMessage(FlashMessage $flashMessage)
|
||||
{
|
||||
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
|
||||
$flashMessageQueue = $flashMessageService->getMessageQueueByIdentifier($this->messageQueueByIdentifier);
|
||||
$flashMessageQueue->enqueue($flashMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* AccordionContentElementUpdate
|
||||
*/
|
||||
class AccordionContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate accordion content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_accordion', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_accordion', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('CType', 'accordion');
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* AccordionMediaOrientUpdate
|
||||
*/
|
||||
class AccordionMediaOrientUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tx_bootstrappackage_accordion_item';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'mediaorient';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
0 => 'left',
|
||||
1 => 'right'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate media orientation of accordion content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
$this->mapValues($record[$this->field])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* BackendLayoutUpdate
|
||||
*/
|
||||
class BackendLayoutUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'pages';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'backend_layout';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
'pagets__clean' => 'pagets__simple',
|
||||
'pagets__default_clean' => 'pagets__simple',
|
||||
'pagets__default_2_columns' => 'pagets__2_columns',
|
||||
'pagets__default_2_columns_25_75' => 'pagets__2_columns_25_75',
|
||||
'pagets__default_2_columns_50_50' => 'pagets__2_columns_50_50',
|
||||
'pagets__default_2_columns_offset_right' => 'pagets__2_columns_offset_right',
|
||||
'pagets__default_3_columns' => 'pagets__3_columns',
|
||||
'pagets__default_subnavigation_right' => 'pagets__subnavigation_right',
|
||||
'pagets__default_subnavigation_right_2_columns' => 'pagets__subnavigation_right_2_columns',
|
||||
'pagets__default_subnavigation_left' => 'pagets__subnavigation_left',
|
||||
'pagets__default_subnavigation_left_2_columns' => 'pagets__subnavigation_left_2_columns'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate backend layouts';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
'backend_layout',
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->orWhere(
|
||||
$queryBuilder->expr()->in(
|
||||
'backend_layout_next_level',
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'backend_layout', 'backend_layout_next_level')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
'backend_layout',
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->orWhere(
|
||||
$queryBuilder->expr()->in(
|
||||
'backend_layout_next_level',
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
'backend_layout',
|
||||
($this->mapValues($record['backend_layout']) ?: $record['backend_layout'])
|
||||
)
|
||||
->set(
|
||||
'backend_layout_next_level',
|
||||
($this->mapValues($record['backend_layout_next_level']) ?: $record['backend_layout_next_level'])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* BulletContentElementUpdate
|
||||
*/
|
||||
class BulletContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate bullet content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bullets', \PDO::PARAM_STR)),
|
||||
$queryBuilder->expr()->in('layout', [100, 110, 120, 130])
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'layout')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bullets', \PDO::PARAM_STR)),
|
||||
$queryBuilder->expr()->in('layout', [100, 110, 120, 130])
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('layout', 0, false)
|
||||
->set('bullets_type', $this->mapValues($record['layout']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $layout
|
||||
* @return int
|
||||
*/
|
||||
protected function mapValues($layout)
|
||||
{
|
||||
$mapping = [
|
||||
110 => 1
|
||||
];
|
||||
if (array_key_exists($layout, $mapping)) {
|
||||
return $mapping[$layout];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* CarouselContentElementUpdate
|
||||
*/
|
||||
class CarouselContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate carousel content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_carousel', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'layout')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_carousel', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('layout', $this->resetLayout($record['layout']), false)
|
||||
->set('CType', $this->mapValues($record['layout']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $layout
|
||||
* @return string
|
||||
*/
|
||||
protected function resetLayout($layout)
|
||||
{
|
||||
if (in_array($layout, [100, 110, 120], true)) {
|
||||
return '0';
|
||||
}
|
||||
return (string)$layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $layout
|
||||
* @return string
|
||||
*/
|
||||
protected function mapValues($layout)
|
||||
{
|
||||
$mapping = [
|
||||
110 => 'carousel_small',
|
||||
120 => 'carousel_fullscreen'
|
||||
];
|
||||
if (array_key_exists($layout, $mapping)) {
|
||||
return $mapping[$layout];
|
||||
}
|
||||
return 'carousel';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* CarouselItemTypeUpdate
|
||||
*/
|
||||
class CarouselItemTypeUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate carousel item types';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_bootstrappackage_carousel_item');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tx_bootstrappackage_carousel_item')
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
'item_type',
|
||||
$queryBuilder->createNamedParameter(
|
||||
['textandimage', 'backgroundimage'],
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_bootstrappackage_carousel_item');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'item_type')
|
||||
->from('tx_bootstrappackage_carousel_item')
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
'item_type',
|
||||
$queryBuilder->createNamedParameter(
|
||||
['textandimage', 'backgroundimage'],
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tx_bootstrappackage_carousel_item')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('item_type', $this->mapValues($record['item_type']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
* @return string
|
||||
*/
|
||||
protected function mapValues($type)
|
||||
{
|
||||
$mapping = [
|
||||
'textandimage' => 'text_and_image',
|
||||
'backgroundimage' => 'background_image'
|
||||
];
|
||||
if (array_key_exists($type, $mapping)) {
|
||||
return $mapping[$type];
|
||||
}
|
||||
return 'header';
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* ExternalMediaContentElementUpdate
|
||||
*/
|
||||
class ExternalMediaContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate external media content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_external_media', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_external_media', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('CType', 'external_media');
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* FrameClassToBackgroundUpdate
|
||||
*/
|
||||
class FrameClassToBackgroundUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tt_content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'frame_class';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
'well' => 'light',
|
||||
'jumbotron' => 'primary'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate obsolete frame_class options to background color';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
'default'
|
||||
)
|
||||
->set(
|
||||
'background_color_class',
|
||||
$this->mapValues($record[$this->field])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* FrameClassUpdate
|
||||
*/
|
||||
class FrameClassUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate the field "section_frame" for all content elements to "frame_class"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$tableColumns = $connection->getSchemaManager()->listTableColumns('tt_content');
|
||||
// Only proceed if section_frame field still exists
|
||||
if (!isset($tableColumns['section_frame'])) {
|
||||
return false;
|
||||
}
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->gt('section_frame', 0)
|
||||
)
|
||||
->execute()
|
||||
->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
$statement = $queryBuilder->select('uid', 'section_frame')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->gt('section_frame', 0)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('section_frame', 0, false)
|
||||
->set('frame_class', $this->mapSectionFrame($record['section_frame']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $sectionFrame
|
||||
* @return string
|
||||
*/
|
||||
protected function mapSectionFrame($sectionFrame)
|
||||
{
|
||||
$mapping = [
|
||||
0 => 'default',
|
||||
5 => 'ruler-before',
|
||||
6 => 'ruler-after',
|
||||
10 => 'indent',
|
||||
11 => 'indent-left',
|
||||
12 => 'indent-right',
|
||||
20 => 'well',
|
||||
21 => 'jumbotron',
|
||||
66 => 'none'
|
||||
];
|
||||
if (array_key_exists($sectionFrame, $mapping)) {
|
||||
return $mapping[$sectionFrame];
|
||||
}
|
||||
return 'custom-' . (int) $sectionFrame;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* ListGroupContentElementUpdate
|
||||
*/
|
||||
class ListGroupContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate list group content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_listgroup', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_listgroup', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('CType', 'listgroup');
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* PanelContentElementUpdate
|
||||
*/
|
||||
class PanelContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate panel content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_panel', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'layout')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_panel', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('layout', 0, false)
|
||||
->set('CType', 'panel')
|
||||
->set('panel_class', $this->mapValues($record['layout']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $layout
|
||||
* @return string
|
||||
*/
|
||||
protected function mapValues($layout)
|
||||
{
|
||||
$mapping = [
|
||||
110 => 'primary',
|
||||
120 => 'success',
|
||||
130 => 'info',
|
||||
140 => 'warning',
|
||||
150 => 'danger',
|
||||
];
|
||||
if (array_key_exists($layout, $mapping)) {
|
||||
return $mapping[$layout];
|
||||
}
|
||||
return 'default';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TabContentElementUpdate
|
||||
*/
|
||||
class TabContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate tab content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_tab', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_tab', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('CType', 'tab');
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TabMediaOrientUpdate
|
||||
*/
|
||||
class TabMediaOrientUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tx_bootstrappackage_tab_item';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'mediaorient';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
0 => 'left',
|
||||
1 => 'right'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate media orientation of tab content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
$this->mapValues($record[$this->field])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TableContentElementUpdate
|
||||
*/
|
||||
class TableContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate table content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('table', \PDO::PARAM_STR)),
|
||||
$queryBuilder->expr()->in('layout', [100, 110, 120, 130, 140, 150])
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', 'layout')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('table', \PDO::PARAM_STR)),
|
||||
$queryBuilder->expr()->in('layout', [100, 110, 120, 130, 140, 150])
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('layout', 0, false)
|
||||
->set('table_class', $this->mapValues($record['layout']));
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $layout
|
||||
* @return string
|
||||
*/
|
||||
protected function mapValues($layout)
|
||||
{
|
||||
$mapping = [
|
||||
100 => '',
|
||||
110 => '',
|
||||
120 => 'striped',
|
||||
130 => 'bordered',
|
||||
140 => 'hover',
|
||||
150 => 'condensed',
|
||||
];
|
||||
return $mapping[$layout];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TexticonContentElementUpdate
|
||||
*/
|
||||
class TexticonContentElementUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate text and icon content element';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_texticon', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->from('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('bootstrap_package_texticon', \PDO::PARAM_STR))
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set('CType', 'texticon');
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TexticonIconUpdate
|
||||
*/
|
||||
class TexticonIconUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tt_content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'icon';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate text and icon identifier and name';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->orWhere(
|
||||
$queryBuilder->expr()->like(
|
||||
$this->field,
|
||||
$queryBuilder->expr()->literal('Glyphicons%')
|
||||
),
|
||||
$queryBuilder->expr()->like(
|
||||
$this->field,
|
||||
$queryBuilder->expr()->literal('Ionicons%')
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->orWhere(
|
||||
$queryBuilder->expr()->like(
|
||||
$this->field,
|
||||
$queryBuilder->expr()->literal('Glyphicons%')
|
||||
),
|
||||
$queryBuilder->expr()->like(
|
||||
$this->field,
|
||||
$queryBuilder->expr()->literal('Ionicons%')
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$icon = explode('__', $record[$this->field]);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
'icon_set',
|
||||
'EXT:bootstrap_package/Resources/Public/Images/Icons/' . $icon[0] . '/'
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
'EXT:bootstrap_package/Resources/Public/Images/Icons/' . $icon[0] . '/' . $icon[1] . '.svg'
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TexticonSizeUpdate
|
||||
*/
|
||||
class TexticonSizeUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tt_content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'icon_size';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
0 => 'default',
|
||||
1 => 'medium',
|
||||
2 => 'large',
|
||||
3 => 'awesome'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate text and icon size options';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
$this->mapValues($record[$this->field])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\RepeatableInterface;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* TexticonTypeUpdate
|
||||
*/
|
||||
class TexticonTypeUpdate implements UpgradeWizardInterface, RepeatableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'tt_content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $field = 'icon_type';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mapping = [
|
||||
0 => 'default',
|
||||
1 => 'square',
|
||||
2 => 'circle'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return '[Bootstrap Package] Migrate text and icon type options';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$elementCount = $queryBuilder->count('uid')
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute()->fetchColumn(0);
|
||||
return (bool)$elementCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
|
||||
$statement = $queryBuilder->select('uid', $this->field)
|
||||
->from($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
$this->field,
|
||||
$queryBuilder->createNamedParameter(
|
||||
array_keys($this->mapping),
|
||||
Connection::PARAM_STR_ARRAY
|
||||
)
|
||||
)
|
||||
)
|
||||
->execute();
|
||||
while ($record = $statement->fetch()) {
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$queryBuilder->update($this->table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->set(
|
||||
$this->field,
|
||||
$this->mapValues($record[$this->field])
|
||||
);
|
||||
$queryBuilder->execute();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
* @return string|null
|
||||
*/
|
||||
protected function mapValues($value)
|
||||
{
|
||||
if (array_key_exists($value, $this->mapping)) {
|
||||
return $this->mapping[$value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Userfuncs;
|
||||
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
|
||||
class Tca
|
||||
{
|
||||
public function timelineItemLabel(&$parameters)
|
||||
{
|
||||
$record = BackendUtility::getRecord($parameters['table'], $parameters['row']['uid']);
|
||||
$parameters['title'] = $record['date'] . ' - ' . $record['header'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* ExternalMediaUtility
|
||||
*/
|
||||
class ExternalMediaUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array Provider that can be handled, the provider is equal the hostname and needs a process function
|
||||
*/
|
||||
protected $mediaProvider = [
|
||||
'youtube',
|
||||
'youtu',
|
||||
'vimeo'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the embed code for the given url if possible
|
||||
* and add a css class on the iframe
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $class
|
||||
* @return string
|
||||
*/
|
||||
public function getEmbedCode($url, $class)
|
||||
{
|
||||
// Prepare url
|
||||
$url = $this->setProtocolToHttps($url);
|
||||
// Get method
|
||||
$method = $this->getMethod($url);
|
||||
if ($method !== null) {
|
||||
$embedUrl = $this->{$method}($url);
|
||||
if ($embedUrl) {
|
||||
return '<iframe ' . GeneralUtility::implodeAttributes([
|
||||
'class' => $class,
|
||||
'src' => $embedUrl,
|
||||
'frameborder' => 0
|
||||
], true) . ' allowfullscreen></iframe>';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves if possible a method name to process the url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getMethod($url)
|
||||
{
|
||||
$urlInformation = @parse_url($url);
|
||||
if ($urlInformation) {
|
||||
$hostName = GeneralUtility::trimExplode('.', $urlInformation['host'], true);
|
||||
foreach ($this->mediaProvider as $provider) {
|
||||
$functionName = 'process' . ucfirst($provider);
|
||||
if (in_array($provider, $hostName) && is_callable([$this, $functionName])) {
|
||||
return $functionName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes YouTube url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function processYoutube($url)
|
||||
{
|
||||
$firstMatches = [];
|
||||
$pattern = '%^(?:https?://)?(?:www\.)?(?:youtu\.be/|youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=))([^"&?/ ]{11})(?:.+)?$%xs';
|
||||
if (preg_match($pattern, $url, $firstMatches)) {
|
||||
$toEmbed = $firstMatches[1];
|
||||
$patternForAdditionalParams = '%^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=))(?:[^"&?\/ ]{11})(.+)?(?:.+)?$%xs';
|
||||
$secondMatches = [];
|
||||
if (preg_match($patternForAdditionalParams, $url, $secondMatches) > 1) {
|
||||
$toEmbed .= '?' . substr($secondMatches[1], 1);
|
||||
}
|
||||
return 'https://www.youtube-nocookie.com/embed/' . $toEmbed;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process YouTube short url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function processYoutu($url)
|
||||
{
|
||||
return $this->processYoutube($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes Vimeo url
|
||||
*
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
protected function processVimeo($url)
|
||||
{
|
||||
$matches = [];
|
||||
if (preg_match('/[\\/#](\\d+)$/', $url, $matches)) {
|
||||
return 'https://player.vimeo.com/video/' . $matches[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change every protocol to https and add it if missing
|
||||
*
|
||||
* @param string $url URL
|
||||
* @return string
|
||||
*/
|
||||
protected function setProtocolToHttps($url)
|
||||
{
|
||||
$processUrl = trim($url);
|
||||
if (strpos($url, 'http://') === 0) {
|
||||
$processUrl = substr($processUrl, 7);
|
||||
} elseif (strpos($processUrl, 'https://') === 0) {
|
||||
$processUrl = substr($processUrl, 8);
|
||||
} elseif (strpos($processUrl, '//') === 0) {
|
||||
$processUrl = substr($processUrl, 2);
|
||||
}
|
||||
return 'https://' . $processUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Utility;
|
||||
|
||||
/**
|
||||
* Calculate image variants
|
||||
*/
|
||||
class ImageVariantsUtility
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $allowedVariantProperties = [
|
||||
'breakpoint',
|
||||
'width',
|
||||
'sizes',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $defaultVariants = [
|
||||
'default' => [
|
||||
'breakpoint' => 1200,
|
||||
'width' => 1100
|
||||
],
|
||||
'large' => [
|
||||
'breakpoint' => 992,
|
||||
'width' => 920
|
||||
],
|
||||
'medium' => [
|
||||
'breakpoint' => 768,
|
||||
'width' => 680
|
||||
],
|
||||
'small' => [
|
||||
'breakpoint' => 576,
|
||||
'width' => 500
|
||||
],
|
||||
'extrasmall' => [
|
||||
'width' => 374
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @param array $multiplier
|
||||
* @param array $gutters
|
||||
* @param array $corrections
|
||||
* @return array
|
||||
*/
|
||||
public static function getImageVariants($variants = [], $multiplier = [], $gutters = [], $corrections = []): array
|
||||
{
|
||||
$variants = self::processVariants($variants);
|
||||
$variants = self::processResolutions($variants);
|
||||
$variants = self::addGutters($variants, $gutters);
|
||||
$variants = self::processMultiplier($variants, $multiplier);
|
||||
$variants = self::removeGutters($variants, $gutters);
|
||||
$variants = self::processCorrections($variants, $corrections);
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @return array
|
||||
*/
|
||||
protected static function processResolutions($variants): array
|
||||
{
|
||||
foreach ($variants as $variant => $properties) {
|
||||
if (!array_key_exists('sizes', $properties)) {
|
||||
$properties['sizes'] = [];
|
||||
}
|
||||
$properties['sizes'] = self::processSizes($properties['sizes']);
|
||||
$variants[$variant] = $properties;
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $sizes
|
||||
* @return array
|
||||
*/
|
||||
protected static function processSizes($sizes): array
|
||||
{
|
||||
$resultSizes = [];
|
||||
$workingSizes = [];
|
||||
foreach ($sizes as $key => $settings) {
|
||||
if (!array_key_exists('multiplier', $settings) ||
|
||||
!is_numeric($settings['multiplier']) ||
|
||||
$settings['multiplier'] < 1 ||
|
||||
!self::isValidSizeKey($key)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$workingSizes[substr($key, 0, -1) . ''] = [
|
||||
'multiplier' => 1 * $settings['multiplier'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!array_key_exists(1, $workingSizes)) {
|
||||
$workingSizes[(float) 1 . ''] = ['multiplier' => 1];
|
||||
}
|
||||
ksort($workingSizes);
|
||||
foreach ($workingSizes as $workingKey => $workingSettings) {
|
||||
$resultSizes[$workingKey . 'x'] = $workingSettings;
|
||||
}
|
||||
|
||||
return $resultSizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @return array
|
||||
*/
|
||||
protected static function processVariants($variants): array
|
||||
{
|
||||
$variants = is_array($variants) && !empty($variants) ? $variants : self::$defaultVariants;
|
||||
foreach ($variants as $variant => $properties) {
|
||||
if (!is_array($properties)) {
|
||||
unset($variants[$variant]);
|
||||
continue;
|
||||
}
|
||||
foreach ($properties as $key => $value) {
|
||||
if (!in_array($key, self::$allowedVariantProperties, true)) {
|
||||
unset($variants[$variant][$key]);
|
||||
continue;
|
||||
}
|
||||
if ($key === 'sizes') {
|
||||
continue;
|
||||
} elseif (is_numeric($value) && $value > 0) {
|
||||
$variants[$variant][$key] = (int) $value;
|
||||
} else {
|
||||
unset($variants[$variant][$key]);
|
||||
}
|
||||
}
|
||||
if (empty($variants[$variant]) || !isset($variants[$variant]['width'])) {
|
||||
unset($variants[$variant]);
|
||||
}
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @param array $gutters
|
||||
* @return array
|
||||
*/
|
||||
protected static function addGutters($variants, $gutters): array
|
||||
{
|
||||
$gutters = is_array($gutters) ? $gutters : [];
|
||||
foreach ($gutters as $variant => $value) {
|
||||
if (is_numeric($value) && $value > 0 && isset($variants[$variant]['width'])) {
|
||||
$variants[$variant]['width'] = (int) ceil($variants[$variant]['width'] + $value);
|
||||
}
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @param array $gutters
|
||||
* @return array
|
||||
*/
|
||||
protected static function removeGutters($variants, $gutters): array
|
||||
{
|
||||
$gutters = is_array($gutters) ? $gutters : [];
|
||||
foreach ($gutters as $variant => $value) {
|
||||
if (is_numeric($value) && $value > 0 && isset($variants[$variant]['width'])) {
|
||||
$variants[$variant]['width'] = (int) ceil($variants[$variant]['width'] - $value);
|
||||
}
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @param array $multiplier
|
||||
* @return array
|
||||
*/
|
||||
protected static function processMultiplier($variants, $multiplier): array
|
||||
{
|
||||
$multiplier = is_array($multiplier) ? $multiplier : [];
|
||||
foreach ($multiplier as $variant => $value) {
|
||||
if (is_numeric($value) && $value > 0 && isset($variants[$variant]['width'])) {
|
||||
$variants[$variant]['width'] = (int) ceil($variants[$variant]['width'] * $value);
|
||||
}
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variants
|
||||
* @param array $corrections
|
||||
* @return array
|
||||
*/
|
||||
protected static function processCorrections($variants, $corrections): array
|
||||
{
|
||||
$corrections = is_array($corrections) ? $corrections : [];
|
||||
foreach ($corrections as $variant => $value) {
|
||||
if (is_numeric($value) && $value > 0 && isset($variants[$variant]['width'])) {
|
||||
$variants[$variant]['width'] -= $value;
|
||||
}
|
||||
}
|
||||
return $variants;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidSizeKey($key): bool
|
||||
{
|
||||
return !(
|
||||
!is_string($key) ||
|
||||
substr($key, -1, 1) !== 'x' ||
|
||||
!is_numeric(substr($key, 0, -1)) ||
|
||||
(float) substr($key, 0, -1) < 1 ||
|
||||
(float) substr($key, 0, -1) !== round((float) substr($key, 0, -1), 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* TextIconUtility
|
||||
*/
|
||||
class TextIconUtility
|
||||
{
|
||||
/**
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function addIconItems(array $parameters)
|
||||
{
|
||||
$directory = $parameters['row']['icon_set'][0];
|
||||
if ($directory !== '') {
|
||||
$icons = $this->getIcons($directory);
|
||||
if ($icons) {
|
||||
$parameters['items'] = array_merge($parameters['items'], $icons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function getIcons($directory)
|
||||
{
|
||||
$icons = [];
|
||||
if (strpos($directory, 'EXT:') !== 0 || !strpos($directory, 'Resources/Public')) {
|
||||
return false;
|
||||
}
|
||||
$path = GeneralUtility::getFileAbsFileName($directory);
|
||||
if (!is_dir($path)) {
|
||||
return false;
|
||||
}
|
||||
$files = iterator_to_array(
|
||||
new \FilesystemIterator(
|
||||
$path,
|
||||
\FilesystemIterator::KEY_AS_PATHNAME
|
||||
)
|
||||
);
|
||||
ksort($files);
|
||||
foreach ($files as $key => $fileinfo) {
|
||||
if ($fileinfo->isFile() && in_array($fileinfo->getExtension(), ['svg', 'png', 'gif'])) {
|
||||
$icons[] = [
|
||||
$fileinfo->getBasename('.' . $fileinfo->getExtension()),
|
||||
$directory . $fileinfo->getFilename(),
|
||||
$directory . $fileinfo->getFilename()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $icons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\Data;
|
||||
|
||||
use BK2K\BootstrapPackage\Utility\ImageVariantsUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* ImageVariantsViewHelper
|
||||
*/
|
||||
class ImageVariantsViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('as', 'string', 'Name of variable to create', true);
|
||||
$this->registerArgument('variants', 'array', 'Variants for responsive images', false);
|
||||
$this->registerArgument('multiplier', 'array', 'Multiplier to calculate responsive image widths', false);
|
||||
$this->registerArgument('gutters', 'array', 'Gutter that needs to be respected when calculating responsive image widths', false);
|
||||
$this->registerArgument('corrections', 'array', 'Corrections to be applied after calculationof image widths', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$variants = ImageVariantsUtility::getImageVariants($arguments['variants'], $arguments['multiplier'], $arguments['gutters'], $arguments['corrections']);
|
||||
$renderingContext->getVariableProvider()->add($arguments['as'], $variants);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* ExplodeViewHelper
|
||||
*/
|
||||
class ExplodeViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('data', 'string', 'The input string', true);
|
||||
$this->registerArgument('as', 'string', 'Name of variable to create', false, 'items');
|
||||
$this->registerArgument('delimiter', 'string', 'The boundary string', false, LF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$content = '';
|
||||
if (isset($arguments['data'])) {
|
||||
$variableProvider = $renderingContext->getVariableProvider();
|
||||
$items = GeneralUtility::trimExplode($arguments['delimiter'], $arguments['data']);
|
||||
$variableProvider->add($arguments['as'], $items);
|
||||
$content = $renderChildrenClosure();
|
||||
$variableProvider->remove($arguments['as']);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers;
|
||||
|
||||
use BK2K\BootstrapPackage\Utility\ExternalMediaUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* ExternalMediaViewHelper
|
||||
*/
|
||||
class ExternalMediaViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('url', 'string', 'External media url');
|
||||
$this->registerArgument('class', 'string', 'CSS class rendered on the generated iframe code');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the URL is a valid YouTube/Vimeo Link is. If the video id can
|
||||
* be extracted the embed code will be returned, else the content of the
|
||||
* ViewHelper will be displayed.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$variableProvider = $renderingContext->getVariableProvider();
|
||||
$externalMediaUtility = GeneralUtility::makeInstance(ExternalMediaUtility::class);
|
||||
$externalMedia = $externalMediaUtility->getEmbedCode($arguments['url'], $arguments['class']);
|
||||
$variableProvider->add('externalMedia', $externalMedia);
|
||||
$content = $renderChildrenClosure();
|
||||
$variableProvider->remove('externalMedia');
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* FalViewHelper
|
||||
*/
|
||||
class FalViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('data', 'array', 'Data of current record', true);
|
||||
$this->registerArgument('table', 'string', 'table', false, 'tt_content');
|
||||
$this->registerArgument('field', 'string', 'field', false, 'image');
|
||||
$this->registerArgument('as', 'string', 'Name of variable to create', false, 'items');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$variableProvider = $renderingContext->getVariableProvider();
|
||||
if (is_array($arguments['data']) && $arguments['data']['uid'] && $arguments['data'][$arguments['field']]) {
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$items = $fileRepository->findByRelation(
|
||||
$arguments['table'],
|
||||
$arguments['field'],
|
||||
$arguments['data']['uid']
|
||||
);
|
||||
$localizedId = null;
|
||||
if (isset($arguments['data']['_LOCALIZED_UID'])) {
|
||||
$localizedId = $arguments['data']['_LOCALIZED_UID'];
|
||||
} elseif (isset($arguments['data']['_PAGES_OVERLAY_UID'])) {
|
||||
$localizedId = $arguments['data']['_PAGES_OVERLAY_UID'];
|
||||
}
|
||||
$isTableLocalizable = (
|
||||
!empty($GLOBALS['TCA'][$arguments['table']]['ctrl']['languageField'])
|
||||
&& !empty($GLOBALS['TCA'][$arguments['table']]['ctrl']['transOrigPointerField'])
|
||||
);
|
||||
if ($isTableLocalizable && $localizedId !== null) {
|
||||
$items = $fileRepository->findByRelation($arguments['table'], $arguments['field'], $localizedId);
|
||||
}
|
||||
} else {
|
||||
$items = null;
|
||||
}
|
||||
$variableProvider->add($arguments['as'], $items);
|
||||
$content = $renderChildrenClosure();
|
||||
$variableProvider->remove($arguments['as']);
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\File;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\FileReference;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class IsAudioViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$file = $renderChildrenClosure();
|
||||
$allowedFileExtensions = $GLOBALS['TYPO3_CONF_VARS']['SYS']['audiofile_ext'] ?? '';
|
||||
$allowedFileExtensions = GeneralUtility::trimExplode(',', $allowedFileExtensions);
|
||||
|
||||
if (is_object($file)
|
||||
&& in_array(get_class($file), [FileReference::class, File::class], true)
|
||||
&& (
|
||||
in_array($file->getExtension(), $allowedFileExtensions, true)
|
||||
|| $file->getType() === File::FILETYPE_AUDIO
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\File;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\FileReference;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class IsImageViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$file = $renderChildrenClosure();
|
||||
$allowedFileExtensions = $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] ?? '';
|
||||
$allowedFileExtensions = GeneralUtility::trimExplode(',', $allowedFileExtensions);
|
||||
|
||||
if (is_object($file)
|
||||
&& in_array(get_class($file), [FileReference::class, File::class], true)
|
||||
&& (
|
||||
in_array($file->getExtension(), $allowedFileExtensions, true)
|
||||
|| $file->getType() === File::FILETYPE_IMAGE
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\File;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\FileReference;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
class IsMediaViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$file = $renderChildrenClosure();
|
||||
$allowedFileExtensions = $GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] ?? '';
|
||||
$allowedFileExtensions = GeneralUtility::trimExplode(',', $allowedFileExtensions);
|
||||
|
||||
if (is_object($file)
|
||||
&& in_array(get_class($file), [FileReference::class, File::class], true)
|
||||
&& (
|
||||
in_array($file->getExtension(), $allowedFileExtensions, true)
|
||||
|| $file->getType() === File::FILETYPE_VIDEO
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* LowercaseDashedViewHelper
|
||||
*/
|
||||
class LowercaseDashedViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return string the formatted amount
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
preg_match_all(
|
||||
'!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!',
|
||||
$renderChildrenClosure(),
|
||||
$matches
|
||||
);
|
||||
$ret = $matches[0];
|
||||
foreach ($ret as &$match) {
|
||||
$match = $match === strtoupper($match) ? strtolower($match) : lcfirst($match);
|
||||
}
|
||||
return implode('-', $ret);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* TrimViewHelper
|
||||
*/
|
||||
class TrimViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return string the formatted amount
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
return trim($renderChildrenClosure());
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* UpperCamelCaseViewHelper
|
||||
*/
|
||||
class UpperCamelCaseViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
*
|
||||
* @return string the formatted amount
|
||||
*/
|
||||
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
|
||||
{
|
||||
return str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($renderChildrenClosure()))));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Extbase\Service\ImageService;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* InlineSvgViewHelper
|
||||
*/
|
||||
class InlineSvgViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('image', 'object', 'a FAL object');
|
||||
$this->registerArgument('src', 'string', 'a path to a file');
|
||||
$this->registerArgument('class', 'string', 'Css class for the svg');
|
||||
$this->registerArgument('width', 'string', 'Width of the svg.', false);
|
||||
$this->registerArgument('height', 'string', 'Height of the svg.', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$src = (string)$arguments['src'];
|
||||
$image = $arguments['image'];
|
||||
|
||||
if (($src === '' && $image === null) || ($src !== '' && $image !== null)) {
|
||||
throw new \Exception('You must either specify a string src or a File object.', 1530601100);
|
||||
}
|
||||
|
||||
try {
|
||||
$imageService = self::getImageService();
|
||||
$image = $imageService->getImage($src, $image, false);
|
||||
if ($image->getProperty('extension') !== 'svg') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$svgContent = $image->getContents();
|
||||
$svgContent = trim(preg_replace('/<script[\s\S]*?>[\s\S]*?<\/script>/i', '', $svgContent));
|
||||
|
||||
// Exit if file does not contain content
|
||||
if (empty($svgContent)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
|
||||
$previousValueOfEntityLoader = libxml_disable_entity_loader(true);
|
||||
$svgElement = simplexml_load_string($svgContent);
|
||||
libxml_disable_entity_loader($previousValueOfEntityLoader);
|
||||
|
||||
// Override css class
|
||||
$svgElement = self::setAttribute($svgElement, 'class', htmlspecialchars($arguments['class'] ?? ''));
|
||||
$svgElement = self::setAttribute($svgElement, 'width', (int)$arguments['width']);
|
||||
$svgElement = self::setAttribute($svgElement, 'height', (int)$arguments['height']);
|
||||
|
||||
// remove xml version tag
|
||||
$domXml = dom_import_simplexml($svgElement);
|
||||
return $domXml->ownerDocument->saveXML($domXml->ownerDocument->documentElement);
|
||||
} catch (ResourceDoesNotExistException $e) {
|
||||
// thrown if file does not exist
|
||||
throw new \Exception($e->getMessage(), 1530601100, $e);
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
// thrown if a file has been replaced with a folder
|
||||
throw new \Exception($e->getMessage(), 1530601101, $e);
|
||||
} catch (\RuntimeException $e) {
|
||||
// RuntimeException thrown if a file is outside of a storage
|
||||
throw new \Exception($e->getMessage(), 1530601102, $e);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// thrown if file storage does not exist
|
||||
throw new \Exception($e->getMessage(), 1530601103, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SimpleXMLElement $element
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected static function setAttribute(\SimpleXMLElement $element, $attribute, $value): \SimpleXMLElement
|
||||
{
|
||||
if ($value) {
|
||||
if (isset($element->attributes()->$attribute)) {
|
||||
$element->attributes()->$attribute = $value;
|
||||
} else {
|
||||
$element->addAttribute($attribute, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of ImageService using object manager
|
||||
*
|
||||
* @return ImageService
|
||||
*/
|
||||
protected static function getImageService()
|
||||
{
|
||||
/** @var ObjectManager $objectManager */
|
||||
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
|
||||
return $objectManager->get(ImageService::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* LastImageInfoViewHelper
|
||||
*/
|
||||
class LastImageInfoViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $imageInfoMapping = [
|
||||
'width' => 0,
|
||||
'height' => 1,
|
||||
'type' => 2,
|
||||
'file' => 3,
|
||||
'origFile' => 'origFile',
|
||||
'origFile_mtime' => 'origFile_mtime',
|
||||
'originalFile' => 'originalFile',
|
||||
'processedFile' => 'processedFile',
|
||||
'fileCacheHash' => 'fileCacheHash'
|
||||
];
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('property', 'string', 'Possible values: width, height, type, file, origFile, origFile_mtime, originalFile, processedFile, fileCacheHash');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
if (self::getTypoScriptFrontendController()->lastImageInfo) {
|
||||
$property = array_key_exists($arguments['property'], self::$imageInfoMapping)
|
||||
? self::$imageInfoMapping[$arguments['property']]
|
||||
: self::$imageInfoMapping['file'];
|
||||
return self::getTypoScriptFrontendController()->lastImageInfo[$property];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
|
||||
*/
|
||||
protected static function getTypoScriptFrontendController()
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the package bk2k/bootstrap-package.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace BK2K\BootstrapPackage\ViewHelpers\TypoScript;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* ConstantViewHelper
|
||||
*/
|
||||
class ConstantViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
|
||||
*/
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('constant', 'string', 'TypoScript constant');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @param \Closure $renderChildrenClosure
|
||||
* @param RenderingContextInterface $renderingContext
|
||||
* @return string
|
||||
*/
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
\Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
$constant = trim($arguments['constant']);
|
||||
if ($GLOBALS['TSFE']->tmpl->flatSetup === null
|
||||
|| !is_array($GLOBALS['TSFE']->tmpl->flatSetup)
|
||||
|| count($GLOBALS['TSFE']->tmpl->flatSetup) === 0) {
|
||||
$GLOBALS['TSFE']->tmpl->generateConfig();
|
||||
}
|
||||
if (!array_key_exists($constant, $GLOBALS['TSFE']->tmpl->flatSetup)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $GLOBALS['TSFE']->tmpl->flatSetup[$constant];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user