在前端显示、编辑和更新隐藏记录 (TYPO3) [英] Show, edit and update hidden records in FrontEnd (TYPO3)

查看:38
本文介绍了在前端显示、编辑和更新隐藏记录 (TYPO3)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建扩展程序(分类广告).前端用户可以选择将他的广告设置为隐藏,或者一段时间后(广告过期),广告获得隐藏状态.我遇到了两个问题:

I am building an extension (Classified Ads). The FrontEnd user has the option to set his Ad to hidden or the Ad gets the hidden status after some time (Ad expired). I faced two problems:

  1. 如果我尝试在 showAction() 上调用它,那么 TYPO3 会返回一个错误,指出尚未找到对象,这是有道理的,因为存在限制.
  2. 在列表操作中,显示操作的 URL 不会呈现,因为 persistedAliasMapper 方面发送了一个包含相同限制的请求.
  1. if i try to call it on the showAction() then TYPO3 gives back an error saying that the Object hasn't been found, which makes sense since there are restrictions.
  2. In the list action the URL to the show action won't render since the persistedAliasMapper aspect sents a request including the same restrictions.

如何解决这些问题,以便用户可以编辑他的广告?

How do i get these problems solved so the user can edit his Ad?

环境:

  • TYPO3:10
  • 模式:作曲家
  • PHP:7.4

推荐答案

首先,我们必须取消限制,以便可以呈现 listAction() 中的 URL.这很容易,因为方面使用函数 createQueryBuilder(),所以这里唯一要做的就是覆盖该函数并删除 Hidden 限制.为了做到这一点,我们必须扩展 PersistedAliasMapper 类.首先我们必须声明这个类.

First we have to remove the restriction so the URL in the listAction() can be rendered. It is quite easy since the aspect uses a function createQueryBuilder() so the only thing to do here is to just override the function and remove the Hidden restriction. In order to do that, we have to extend the PersistedAliasMapper class. First we have to declare the class.

your_extension/ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['AdPersistedAliasMapper'] = \Vendor\YourExtension\Routing\AdPersistedAliasMapper::class;

下一步是实际扩展类.我们不会每次都覆盖这些限制,但我们会在 PersistedAliasMapper 参数中再包含一个字段,以便我们可以在特定配置中使用它.

Next step is to actually extend the class. We are not going to override the restrictions every time but we include one more field on the PersistedAliasMapper arguments so we can use it on specific configurations.

your_extension/Classes/Routing/AdPersistedAliasMapper.php

<?php
namespace Vendor\YourExtension\Routing;

use InvalidArgumentException;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendGroupRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
use TYPO3\CMS\Core\Routing\Aspect\PersistedAliasMapper;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class AdPersistedAliasMapper extends PersistedAliasMapper
{
    /**
     * @var bool
     */
    protected $ignoreEnablefields;

    /**
     * @param array $settings
     * @throws InvalidArgumentException
     */
    public function __construct(array $settings)
    {
        $ignoreEnablefields = $settings['ignoreEnablefields'] ?? false;
        $this->ignoreEnablefields = $ignoreEnablefields;
        parent::__construct($settings);
    }

    protected function createQueryBuilder(): QueryBuilder
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getQueryBuilderForTable($this->tableName)
            ->from($this->tableName);
        if ($this->ignoreEnablefields) {
            $queryBuilder
                ->getRestrictions()
                ->removeAll()
                ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
        }
        else {
            $queryBuilder->setRestrictions(
                GeneralUtility::makeInstance(FrontendRestrictionContainer::class, $this->context)
            );
        }
        $queryBuilder->getRestrictions()->removeByType(FrontendGroupRestriction::class);
        return $queryBuilder;
    }
}

这样做是为了评估 ignoreEnablefields 字段是否在 config.yaml 中定义.如果是,那么这个

What this does, is to evaluate if the field ignoreEnablefields is defined in the config.yaml. If yes, then this

$queryBuilder
      ->getRestrictions()
      ->removeAll()
      ->add(GeneralUtility::makeInstance(DeletedRestriction::class));

将删除所有限制并重新添加DeletedRestriction.如果你想删除而不是隐藏,你可以做相反的事情.或者,您可以删除所有内容,然后将呈现所有对象的 URL.

will remove all the restriction and add the DeletedRestriction back again. You can do the opposite if you want to get the deleted and not the hidden. Or you can just remove everything and all objects's URL will be rendered.

如果 ignoreEnablefields 未设置,TYPO3 将继续正常行为.

If the ignoreEnablefields is not set, the TYPO3 will continue with the normal behaviour.

您现在可以在 config.yaml 中使用以下配置:

You can now use the following configuration in your config.yaml:

config/sites/yourIdentifier/config.yaml

Ad:
    type: Extbase
    extension: YourExtension
    plugin: Yourextension
    routes:
      - routePath: '/{ad}'
         _controller: 'Ad::show'
         _arguments:
            ad: ad
    aspects:
      ad:
        type: AdPersistedAliasMapper
        tableName: tx_yourextension_domain_model_ad
        routeFieldName: path_segment
        ignoreEnablefields: true

现在我们必须取消获取对象的限制并避免错误未找到具有 UID x 的对象".我的 detailAction 看起来像这样:

Now we have to remove the restrictions from getting the Object and avoid the error "Object with the UID x has not been found". My detailAction looks like this:

/**
 * action show
 *
 * @param Ad $ad
 * @return void
 */
public function showAction(Ad $ad): void
{ }

TYPO3 通常所做的是获取 uid 并向服务器发送请求以检索对象.这就是错误的来源.由于对象设置为隐藏,默认限制搜索 UIDhidden=0deleted=0.TYPO3 没有找到任何东西,所以它坏了.但是我们可以通过在对象到达 showAction 之前获取它来避免这种情况.为此,我们使用 TYPO3 默认的 initialize 方法前缀.因此必须在您的控制器上设置以下内容:

What TYPO3 normally does is to get the uid and send a request to the server in order to retrieve the object. This is where the error comes from. Since the object is set to hidden, the default restrictions search for the UID and hidden=0 and deleted=0. TYPO3 does not find anything so it breaks. But we can avoid that by getting the object before it reaches the showAction. In order to do that we use the TYPO3 default initialize method prefix. So the following has to be set on your controller:

your_extension/Classes/Controller/AdController.php

protected function initializeShowAction(): void
{
    $adUid = $this->request->getArguments()['ad'];
    $ad = $this->adRepository->findByUidAndHidden($adUid);
}

这样做的目的是将隐藏对象分配给 $ad 变量,因此当 showAction() 被调用时,$ad> 变量已经包含了动作期望作为参数的对象.

What this does, is to assing the hidden object to the $ad variable so when the showAction() is called, the $ad variable already contains the object which is what the action expects as parameter.

现在 findByUidAndHidden() 方法不是 TYPO3 默认函数,所以我们必须创建它.

Now the findByUidAndHidden() method is not a TYPO3 default function so we have to create it.

your_extension/Classes/Domain/Repository/AdRepository.php

public function findByUidAndHidden($uid)
{
    $query = $this->createQuery();
    $query->getQuerySettings()->setIgnoreEnableFields(array('hidden'));
    $query->matching(
        $query->equals('uid', (int)$uid)
    );
    return $query->execute()[0];
}

这样做的目的是创建一个不考虑隐藏字段的查询.这意味着在发送请求时不会考虑隐藏列.该函数可以改用 findByIdentifier() 函数.[0] 只返回数组响应的第一个条目,因为总是只有 1 个结果(如果对象确实存在).

What this does, is to create a query which does not respect the hidden field. Meaning that the hidden column won't be taken into consideration when the request is sent. The function could use the findByIdentifier() function instead. The [0] just brings the first entry of the array response back since there is always only 1 result (if the object really exists).

同样的东西可以用于编辑或更新功能.

The same thing you can use for the edit or update function.

最好的问候

这篇关于在前端显示、编辑和更新隐藏记录 (TYPO3)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆