diff --git a/.ddev/config.yaml b/.ddev/config.yaml index cf5d96b..088d0ff 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -2,7 +2,7 @@ APIVersion: v1.10.2 name: querybuilder type: typo3 docroot: .build/public -php_version: "7.2" +php_version: "7.4" webserver_type: nginx-fpm router_http_port: "80" router_https_port: "443" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9df4d45..997c83b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: max-parallel: 4 fail-fast: false matrix: - php: ['7.2', '7.3'] + php: ['7.4'] steps: - name: Start database server run: | diff --git a/Classes/Controller/QuerybuilderController.php b/Classes/Controller/QuerybuilderController.php index 92b81e8..fb9c512 100644 --- a/Classes/Controller/QuerybuilderController.php +++ b/Classes/Controller/QuerybuilderController.php @@ -12,18 +12,35 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Context\AspectInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\UserAspect; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Http\JsonResponse; -use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Main script class for saving query */ class QuerybuilderController { + + /** + * @var ConnectionPool + */ + protected $connectionPool; + + /** + * @var Context + */ + protected $context; + + public function __construct(ConnectionPool $connectionPool, Context $context) + { + $this->connectionPool = $connectionPool; + $this->context = $context; + } + /** * @param ServerRequestInterface $request * @param ResponseInterface $response @@ -39,9 +56,9 @@ public function ajaxSaveQuery(ServerRequestInterface $request): ResponseInterfac $result->status = 'ok'; $requestParams = $request->getQueryParams(); - /** @var \TYPO3\CMS\Core\Database\Query\QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_querybuilder'); + /** @var QueryBuilder $queryBuilder */ + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_querybuilder'); + $uid = (int)$requestParams['uid']; if ($uid > 0 && (int)$requestParams['override'] === 1) { $result->uid = $uid; @@ -83,8 +100,7 @@ public function ajaxGetRecentQueries(ServerRequestInterface $request): ResponseI { $requestParams = $request->getQueryParams(); /** @var QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) - ->getQueryBuilderForTable('sys_querybuilder'); + $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_querybuilder'); $results = $queryBuilder ->select('uid', 'queryname', 'where_parts') @@ -106,8 +122,8 @@ public function ajaxGetRecentQueries(ServerRequestInterface $request): ResponseI * @return UserAspect * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException */ - protected function getBackendUserAspect(): UserAspect + protected function getBackendUserAspect(): AspectInterface { - return GeneralUtility::makeInstance(Context::class)->getAspect('backend.user'); + return $this->context->getAspect('backend.user'); } } diff --git a/Classes/Hooks/PageRenderer.php b/Classes/Hooks/PageRenderer.php index 0ea5003..92ef00c 100644 --- a/Classes/Hooks/PageRenderer.php +++ b/Classes/Hooks/PageRenderer.php @@ -23,6 +23,17 @@ */ class PageRenderer { + /** + * @var \TYPO3\CMS\Core\Page\PageRenderer + */ + protected $pageRenderer; + + public function __construct(\TYPO3\CMS\Core\Page\PageRenderer $pageRenderer, QueryBuilder $queryBuilder) + { + $this->pageRenderer = $pageRenderer; + $this->queryBuilder = $queryBuilder; + } + /** * @param array $params * @@ -37,13 +48,11 @@ public function renderPreProcess(array $params): void $table = $queryParams['table'] ?? ''; $route = $queryParams['route'] ?? ''; if (!empty($table) && $route === '/module/web/list') { - $pageRenderer = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class); + $this->pageRenderer->addInlineLanguageLabelFile('EXT:querybuilder/Resources/Private/Language/querybuilder-js.xlf'); + $this->pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/query-builder.default.css'); + $this->pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/custom-query-builder.css'); - $pageRenderer->addInlineLanguageLabelFile('EXT:querybuilder/Resources/Private/Language/querybuilder-js.xlf'); - $pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/query-builder.default.css'); - $pageRenderer->addCssFile('EXT:querybuilder/Resources/Public/Css/custom-query-builder.css'); - - $pageRenderer->addRequireJsConfiguration([ + $this->pageRenderer->addRequireJsConfiguration([ 'paths' => [ 'query-builder' => PathUtility::getAbsoluteWebPath('../typo3conf/ext/querybuilder/Resources/Public/JavaScript/query-builder.standalone'), 'query-builder/lang' => PathUtility::getAbsoluteWebPath('../typo3conf/ext/querybuilder/Resources/Public/JavaScript/Language'), @@ -56,16 +65,14 @@ public function renderPreProcess(array $params): void } $query = json_decode($queryParams['query'] ?? ''); - $pageRenderer->addJsInlineCode('tx_querybuilder_query', 'var tx_querybuilder_query = ' . json_encode($query) . ';'); - - $queryBuilder = GeneralUtility::makeInstance(QueryBuilder::class); + $this->pageRenderer->addJsInlineCode('tx_querybuilder_query', 'var tx_querybuilder_query = ' . json_encode($query) . ';'); $pageId = (int)$queryParams['id']; - $filter = $queryBuilder->buildFilterFromTca($table, $pageId); - $pageRenderer->addJsInlineCode('tx_querybuilder_filter', 'var tx_querybuilder_filter = ' . json_encode($filter) . ';'); + $filter = $this->queryBuilder->buildFilterFromTca($table, $pageId); + $this->pageRenderer->addJsInlineCode('tx_querybuilder_filter', 'var tx_querybuilder_filter = ' . json_encode($filter) . ';'); - $pageRenderer->loadRequireJsModule($languageModule); - $pageRenderer->loadRequireJsModule('TYPO3/CMS/Querybuilder/QueryBuilder', 'function(QueryBuilder) { + $this->pageRenderer->loadRequireJsModule($languageModule); + $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Querybuilder/QueryBuilder', 'function(QueryBuilder) { QueryBuilder.initialize(tx_querybuilder_query, tx_querybuilder_filter); }'); } diff --git a/Classes/QueryBuilder.php b/Classes/QueryBuilder.php index 0de081d..06a6d2d 100644 --- a/Classes/QueryBuilder.php +++ b/Classes/QueryBuilder.php @@ -28,6 +28,38 @@ class QueryBuilder private const FORMAT_DATE = 'YYYY-MM-DD'; private const FORMAT_TIME = 'HH:mm'; + /** + * @var FilterFactory + */ + protected $filterFactory; + + /** + * @var PluginFactory + */ + protected $pluginFactory; + + /** + * @var ValidationFactory + */ + protected $validationFactory; + + /** + * @var TcaDatabaseRecord + */ + protected $formDataGroup; + + public function __construct( + FilterFactory $filterFactory, + PluginFactory $pluginFactory, + ValidationFactory $validationFactory, + TcaDatabaseRecord $formDataGroup + ) { + $this->filterFactory = $filterFactory; + $this->pluginFactory = $pluginFactory; + $this->validationFactory = $validationFactory; + $this->formDataGroup = $formDataGroup; + } + /** * Build the filter configuration from TCA * @@ -50,7 +82,7 @@ public function buildFilterFromTca(string $table, int $pageId) : array } // Filter:Types: string, integer, double, date, time, datetime and boolean. // Filter:Required: id, type, values* - $filter = GeneralUtility::makeInstance(FilterFactory::class) + $filter = $this->filterFactory ->create([ 'id' => $filterField, 'type' => $this->determineFilterType($fieldConfig), @@ -196,7 +228,7 @@ protected function determineAndAddExtras(Filter $filter): void default: } $filter->setPlugin( - GeneralUtility::makeInstance(PluginFactory::class) + $this->pluginFactory ->create([ 'identifier' => 'datetimepicker', 'configuration' => $pluginConfiguration, @@ -205,7 +237,7 @@ protected function determineAndAddExtras(Filter $filter): void if (!empty($pluginConfiguration['format'])) { $filter->setValidation( - GeneralUtility::makeInstance(ValidationFactory::class) + $this->validationFactory ->create([ 'format' => $pluginConfiguration['format'], ]) @@ -221,8 +253,8 @@ protected function determineAndAddExtras(Filter $filter): void */ protected function prepareTca(string $tableName, int $pageId) : array { - $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class); - $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup); +// TODO: check how to DI this? + $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $this->formDataGroup); $formDataCompilerInput = [ 'tableName' => $tableName, diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml new file mode 100644 index 0000000..d941c08 --- /dev/null +++ b/Configuration/Services.yaml @@ -0,0 +1,17 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + T3G\Querybuilder\: + resource: '../Classes/*' + + T3G\Querybuilder\Hooks\PageRenderer: + public: true; + + T3G\Querybuilder\Controller\QuerybuilderController: + public: true; + + T3G\Querybuilder\QueryBuilder: + public: true; \ No newline at end of file diff --git a/Resources/Public/JavaScript/QueryBuilder.js b/Resources/Public/JavaScript/QueryBuilder.js index bf34c64..cef206a 100644 --- a/Resources/Public/JavaScript/QueryBuilder.js +++ b/Resources/Public/JavaScript/QueryBuilder.js @@ -21,7 +21,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Storage/Client', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Notification', - 'twbs/bootstrap-datetimepicker', + 'TYPO3/CMS/Backend/DateTimePicker', 'query-builder' ], function ($, moment, Severity, ClientStorage, Modal, Notification) { 'use strict'; @@ -47,12 +47,6 @@ define(['jquery', table: $('table[data-table]').data('table'), querySelector: null, instance: null, - plugins: { - 'bt-tooltip-errors': {delay: 100}, - //'sortable': { icon: 'fa fa-sort' }, - 'invert': {}, - 'filter-description': {icon: 'fa fa-info'} - }, icon: 'fa fa-sort', // Filter:Types: string, integer, double, date, time, datetime and boolean. // Filter:Required: id, type, values* @@ -195,18 +189,20 @@ define(['jquery', table: QueryBuilder.table }, success: function(data) { - for (var j = 0; j < data.length; j++) { - var $query = $('