Сначала нам нужно снять ограничение, чтобы можно было отобразить URL-адрес в listAction()
. Это довольно просто, поскольку аспект использует функцию createQueryBuilder()
, поэтому единственное, что здесь нужно сделать, - это просто переопределить функцию и удалить ограничение Скрытый. Для этого нам нужно расширить класс PersistedAliasMapper
. Сначала мы должны объявить класс.
ваше_расширение / ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['AdPersistedAliasMapper'] = \Vendor\YourExtension\Routing\AdPersistedAliasMapper::class;
Следующим шагом будет фактическое расширение класса. Мы не собираемся отменять ограничения каждый раз, но мы включаем еще одно поле в PersistedAliasMapper
аргументы, чтобы мы могли использовать его в определенных конфигурациях.
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
. Если да, то это
$queryBuilder
->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
снимет все ограничения и снова добавит DeletedRestriction
. Вы можете сделать наоборот, если хотите, чтобы удаленные, а не скрытые. Или вы можете просто удалить все, и все URL-адреса объектов будут отображены.
Если ignoreEnablefields
не установлен, TYPO3 продолжит нормальное поведение.
Теперь вы можете использовать следующую конфигурацию в своем 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
выглядит так:
/**
* action show
*
* @param Ad $ad
* @return void
*/
public function showAction(Ad $ad): void
{ }
Обычно TYPO3 получает uid и отправляет запрос на сервер, чтобы получить объект. Отсюда и ошибка. Поскольку объект установлен как скрытый, ограничения по умолчанию ищут UID
, hidden=0
и deleted=0
. TYPO3 ничего не находит, поэтому ломается. Но этого можно избежать, получив объект до того, как он достигнет showAction
. Для этого мы используем префикс метода initialize
в TYPO3 по умолчанию. Таким образом, на вашем контроллере должно быть установлено следующее:
ваше_расширение / Классы / Контроллер / AdController.php
protected function initializeShowAction(): void
{
$adUid = $this->request->getArguments()['ad'];
$ad = $this->adRepository->findByUidAndHidden($adUid);
}
При этом скрытый объект присваивается переменной $ad
, поэтому при вызове showAction()
переменная $ad
уже содержит объект, который действие ожидает в качестве параметра.
Теперь метод findByUidAndHidden()
не является функцией TYPO3 по умолчанию, поэтому мы должны его создать.
ваше_расширение / Классы / Домен / Репозиторий / 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 результат (если объект действительно существует).
То же самое вы можете использовать для функции редактирования или обновления.
С наилучшими пожеланиями
person
Aristeidis Karavas
schedule
18.09.2020