first commit

This commit is contained in:
salam committed 2026-10-19 08:18:39 +02:00
commit 1218dd1517
12716 files changed
+989233

No files matched your search

@@ -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);
}
}