TYPO3 9 从页面获取资源和分类,queryBuilder join问题
TYPO3 9 get resources and categories from pages, queryBuilder join problems
此解决方案一直有效到 TYPO3 8.7
。但在 TYPO3 9
中中断。
我有一些 submenu
显示来自 page-resources
的图像并使用 categories.descriptions
用于 css
。
为此,我使用自定义 viewhelpers
。但是现在 JOIN-sql
坏了...不知道为什么,因为它在 8.7
和以前的版本中有效。
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @var integer $uid (CE)
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* @var integer $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category','sys_category_record_mm','MM', $queryBuilder->expr()->andX($queryBuilder->expr()->eq('MM.uid_foreign', $uid),$queryBuilder->expr()->eq('MM.uid_local', 'uid')))
->setMaxResults(1);
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysCategoryDetailArray', $res);
}
}
ERRORMESSAGE
(1/2) Doctrine\DBAL\Exception\SyntaxErrorException
执行时出现异常
SELECT * FROM sys_category INNER JOIN sys_category_record_mm MM ON
(`MM`.`uid_foreign` = ) AND (MM.uid_local = uid)
LIMIT 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND (MM
.uid_local
= uid) LIMIT 1' at line 1
对于错误:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class FalResourceViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @author INGENIUMDESIGN
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* @var mixed $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file');
if($uid) {
$query = $queryBuilder
->select('*')
->from('sys_file')
->join('sys_file', 'sys_file_reference', 'MM',
$queryBuilder->expr()->andX(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $uid),
$queryBuilder->expr()->eq('MM.tablenames', '"pages"')
),
$queryBuilder->expr()->eq('MM.uid_local', 'sys_file.uid')
)
)
->setMaxResults(1);
//die($query->getSQL());
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysFileArray', $res);
}
}
}
Can anybody check those queryBuilder-statements?
Thanx in advance
EnzephaloN
解决方法如下:
FalResourceViewhelper
只需使用 TYPO3 核心方法 $fileRepository->findByRelation();此returns 页面相关资源。
像这样使用:
<e:falResource data="{page.data}" table="pages" field="media" as="sysFileArray">
<f:if condition="{sysFileArray.0.uid}!=0">
<f:image src="{sysFileArray.0.uid}" treatIdAsReference="1" class="img-responsive"/>
</f:if>
</e:falResouce>
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
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 FalResourceViewHelper 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;
}
}
很简单。
--
SysCategoryViewHelper 是这样工作的:
<e:sysCategory data="{page.data}" as="sysCategoryDetailArray">
<f:if condition="{sysCategoryDetailArray.0}">
<i class="fa fa-4x {sysCategoryDetailArray.0.description}"></i>
</f:if>
</e:sysCategory>
这是代码:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
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;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\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('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']) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category', 'sys_category_record_mm', 'MM', $queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $arguments['data']['uid']),
$queryBuilder->expr()->eq('MM.uid_local','sys_category.uid')));
$result = $query->execute();
$items = [];
while ($row = $result->fetch()) {
$items[] = $row;
}
} else {
$items = null;
}
$variableProvider->add($arguments['as'], $items);
$content = $renderChildrenClosure();
$variableProvider->remove($arguments['as']);
return $content;
}
}
此解决方案一直有效到 TYPO3 8.7
。但在 TYPO3 9
中中断。
我有一些 submenu
显示来自 page-resources
的图像并使用 categories.descriptions
用于 css
。
为此,我使用自定义 viewhelpers
。但是现在 JOIN-sql
坏了...不知道为什么,因为它在 8.7
和以前的版本中有效。
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @var integer $uid (CE)
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* @var integer $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category','sys_category_record_mm','MM', $queryBuilder->expr()->andX($queryBuilder->expr()->eq('MM.uid_foreign', $uid),$queryBuilder->expr()->eq('MM.uid_local', 'uid')))
->setMaxResults(1);
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysCategoryDetailArray', $res);
}
}
ERRORMESSAGE
(1/2) Doctrine\DBAL\Exception\SyntaxErrorException
执行时出现异常
SELECT * FROM sys_category INNER JOIN sys_category_record_mm MM ON
(`MM`.`uid_foreign` = ) AND (MM.uid_local = uid)
LIMIT 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND (
MM
.uid_local
= uid) LIMIT 1' at line 1
对于错误:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class FalResourceViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @author INGENIUMDESIGN
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* @var mixed $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file');
if($uid) {
$query = $queryBuilder
->select('*')
->from('sys_file')
->join('sys_file', 'sys_file_reference', 'MM',
$queryBuilder->expr()->andX(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $uid),
$queryBuilder->expr()->eq('MM.tablenames', '"pages"')
),
$queryBuilder->expr()->eq('MM.uid_local', 'sys_file.uid')
)
)
->setMaxResults(1);
//die($query->getSQL());
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysFileArray', $res);
}
}
}
Can anybody check those queryBuilder-statements?
Thanx in advance
EnzephaloN
解决方法如下:
FalResourceViewhelper
只需使用 TYPO3 核心方法 $fileRepository->findByRelation();此returns 页面相关资源。 像这样使用:
<e:falResource data="{page.data}" table="pages" field="media" as="sysFileArray">
<f:if condition="{sysFileArray.0.uid}!=0">
<f:image src="{sysFileArray.0.uid}" treatIdAsReference="1" class="img-responsive"/>
</f:if>
</e:falResouce>
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
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 FalResourceViewHelper 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;
}
}
很简单。
--
SysCategoryViewHelper 是这样工作的:
<e:sysCategory data="{page.data}" as="sysCategoryDetailArray">
<f:if condition="{sysCategoryDetailArray.0}">
<i class="fa fa-4x {sysCategoryDetailArray.0.description}"></i>
</f:if>
</e:sysCategory>
这是代码:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
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;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\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('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']) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category', 'sys_category_record_mm', 'MM', $queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $arguments['data']['uid']),
$queryBuilder->expr()->eq('MM.uid_local','sys_category.uid')));
$result = $query->execute();
$items = [];
while ($row = $result->fetch()) {
$items[] = $row;
}
} else {
$items = null;
}
$variableProvider->add($arguments['as'], $items);
$content = $renderChildrenClosure();
$variableProvider->remove($arguments['as']);
return $content;
}
}