TYPO3 v9.5 Extbase错误处理与routeenhancer



在我的Extbase TYPO3扩展中,我想在记录不再可用(隐藏或删除)时显示自定义流体模板。错误处理将加载一个流体模板,其中路径在setup.typoscript中定义。

但是当我在站点配置中添加routenhancer时。然后错误处理不再工作,它只显示默认的TYPO3错误页面:"请求的页面不存在"

在网站配置的文档中,我没有找到任何方法来为我的Ext设置一个特殊的错误处理。

下面是目前为止处理它的代码:

控制器:

class RecordController extends TYPO3CMSExtbaseMvcControllerActionController
{

/**
* Error handling if no entry is found
*
* @param string $configuration configuration what will be done
* @throws InvalidArgumentException
* @return string
*/
protected function handleNoRecordFoundError($configuration)
{
$statusCode = HttpUtility::HTTP_STATUS_404;
HttpUtility::setResponseCode($statusCode);
$this->getTypoScriptFrontendController()->set_no_cache('Record record not found');
$standaloneTemplate = GeneralUtility::makeInstance(StandaloneView::class);
$standaloneTemplate->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($configuration));
return $standaloneTemplate->render();
}
/**
* @return TypoScriptFrontendController
*/
protected function getTypoScriptFrontendController()
{
return $GLOBALS['TSFE'];
}
/**
* action show
* @param DigitalgizmoVehiclesDomainModelVehicle $vehicle
* @return void
*
*
*/
public function showAction(VendorMyExtDomainModelRecord $record = null)
{
if ($record !== null){
$this->view->assign('record', $record);
}
else {
$errorContent = $this->handleNoRecordFoundError($this->settings['show']['errorTemplate']);
if ($errorContent) {
return $errorContent;
}
}

}
}

config.yaml;

routeEnhancers:
MyExt:
type: Extbase
extension: MyExt
plugin: MyExt
routes:
-
routePath: '/staticName/{uid}/{slug}'
_controller: 'ControllerName::show'
_arguments:
slug: record
uid: id
defaultController: 'ControllerName::show'
aspects:
slug:
type: PersistedAliasMapper
tableName: tx_myext_domain_model_record
routeFieldName: slug
routeValuePrefix: /
uid:
type: PersistedAliasMapper
tableName: tx_myext_domain_model_record
routeFieldName: uid

如果记录可用,RoutEnhancer就可以正常工作。

我如何捕获这个错误,以便我可以处理它并显示我的流体模板?我的showAction甚至没有被加载(用XDebug测试)。我认为这是因为TYPO3内核抛出了错误。

这段代码看起来一切都很好,问题是RouteEnhancer受到与showAction相同的约束:一旦记录被删除,RouteEnhancer中的resolve方法将不再能够找到它或它的块格。

参考API中的resolve函数:https://api.typo3.org/9.5/_persisted_alias_mapper_8php_source.html。它实例化了一个queryBuilder,默认情况下,它构建了一个deleted=0子句。

得到删除的记录,你需要做的是建立一个自定义的RouteEnhancer,也许通过扩展PersistendAliasMapper类的方式,它也发现删除的记录,参考https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Routing/ExtendingRouting.html,但要注意的含义:即使使用eval=uniqueInSite选项集,您的模型中的slug字段也将不再能够找到碰撞的slug,因为它也只看到未删除的记录。

感谢j4k3

我已经为routeenhancer创建了自己的方面类型,它删除了已删除和隐藏的约束,因此不会抛出错误。

我按照下面的文档创建它:https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/Routing/ExtendingRouting.html

这是我的CustomMapper类。

use TYPO3CMSCoreDatabaseConnectionPool;
use TYPO3CMSCoreDatabaseQueryQueryBuilder;
use TYPO3CMSCoreDatabaseQueryRestrictionDeletedRestriction;
use TYPO3CMSCoreDatabaseQueryRestrictionFrontendGroupRestriction;
use TYPO3CMSCoreDatabaseQueryRestrictionFrontendRestrictionContainer;
use TYPO3CMSCoreDatabaseQueryRestrictionHiddenRestriction;
use TYPO3CMSCoreRoutingAspectPersistedAliasMapper;
use TYPO3CMSCoreUtilityGeneralUtility;

class CustomMapper extends PersistedAliasMapper
{
protected function createQueryBuilder(): QueryBuilder
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($this->tableName)
->from($this->tableName);
$queryBuilder->setRestrictions(
GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context)
);
// Frontend Groups are not available at this time (initialized via TSFE->determineId)
// So this must be excluded to allow access restricted records
$queryBuilder->getRestrictions()->removeByType(FrontendGroupRestriction::class);
$queryBuilder->getRestrictions()->removeByType(DeletedRestriction::class);
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
return $queryBuilder;
}
}

基本上我唯一添加的是删除DeletedRestriction和hiddenconstraint。

更进一步,我必须改变Slug字段是如何构建的。我将数据集的uid添加到鼻涕虫中,并删除了单独的uid GET参数,因此现在鼻涕虫在数据库中是唯一的。在我这样做之前,我遇到了一个问题,查询发现了多个相同的鼻涕虫值,它总是取第一个。

现在,由于在数据库表中,slug是唯一的,它将返回对象,不会抛出错误,所以我可以处理"error">

最新更新