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

}