For coders TYPO3 Tech Corner

Hidden Objects an Extbase Actions übergeben

Hidden Objects an Extbase Actions übergeben

Im nachfolgenden Beispiel im Extbase Controller sollen Objekte vom Typ Event bearbeitet und gespeichert werden können. Das Problem daran ist, dass diese Objekte in diesem Beispiel verborgen sind (per TCA ist das Feld hidden definiert - der Wert ist dann 1).

Übergabe eines Integer Values

Diesen Workarround kennen sicher einige von euch. An Stelle eines Objektes kann man auch einen Integer übergeben und diesen dann über eine eigene Repository Funktion händisch in ein Objekt umwandeln.

<?php declare(strict_types=1); namespace UniKn\UknCalendarize\Controller; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException; use UniKn\UknCalendarize\Domain\Model\Event; use UniKn\UknCalendarize\Property\TypeConverters\HiddenEventConverter; /** * Class FrontendController */ class FrontendController extends ActionController { ... /** * @param int $event * @return void */ public function editAction(int $event): void { $event = $this->eventRepository->findHiddenByUid($event); $this->view->assignMultiple([ 'event' => $event ]); } /** * @param int $event * @return void */ public function updateAction(int $event): void { $event = $this->eventRepository->findHiddenByUid($event); // Do something } }

Das Repository hierzu könnte so oder so ähnlich aussehen:

<?php declare(strict_types=1); namespace UniKn\UknCalendarize\Domain\Repository; use HDNET\Calendarize\Domain\Repository\AbstractRepository; use UniKn\UknCalendarize\Domain\Model\Event; /** * Class EventRepository */ class EventRepository extends AbstractRepository { /** * @param int $uid * @return Event|null */ public function findHiddenByUid(int $uid): ?Event { $query = $this->createQuery(); $query->getQuerySettings()->setIgnoreEnableFields(true); $query->matching( $query->logicalAnd( [ $query->equals('uid', $uid), $query->equals('hidden', true), $query->equals('deleted', false), ] ) ); /** @var Event $event */ $event = $query->execute()->getFirst(); return $event; } }
Lösung über einen eigenen TypeConverter

Über einen eigenen TypeConverter kann man auch verborgene Objekte an eine Action übergeben. Das Ganze ist dann schon eleganter - Beispiel Controller:

<?php declare(strict_types=1); namespace UniKn\UknCalendarize\Controller; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException; use UniKn\UknCalendarize\Domain\Model\Event; use UniKn\UknCalendarize\Property\TypeConverters\HiddenEventConverter; /** * Class FrontendController */ class FrontendController extends ActionController { ... /** * @return void * @throws NoSuchArgumentException */ public function initializeEditAction(): void { $this->arguments->getArgument('event')->getPropertyMappingConfiguration()->setTypeConverter( $this->objectManager->get(HiddenEventConverter::class) ); } /** * @param Event $event * @return void */ public function editAction(Event $event): void { $this->view->assignMultiple([ 'event' => $event ]); } /** * @return void * @throws NoSuchArgumentException */ public function initializeUpdateAction(): void { $this->arguments->getArgument('event')->getPropertyMappingConfiguration()->setTypeConverter( $this->objectManager->get(HiddenEventConverter::class) ); } /** * @param Event $event * @param array $uploads * @param array $links * @param bool $confirmation * @return void */ public function updateAction(Event $event): void { // Do something } }

Der TypeConverter:

<?php declare(strict_types=1); namespace UniKn\UknCalendarize\Property\TypeConverters; use TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException; use TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException; use TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter; use UniKn\UknCalendarize\Domain\Model\Event; /** * Class HiddenEventConverter */ class HiddenEventConverter extends PersistentObjectConverter { /** * @var string */ protected $targetType = Event::class; /** * @var int */ protected $priority = 2; /** * @param mixed $identity * @param string $targetType * @throws TargetNotFoundException * @throws InvalidSourceException * @return Event */ protected function fetchObjectFromPersistence($identity, string $targetType): object { if (ctype_digit((string)$identity)) { $query = $this->persistenceManager->createQueryForType($targetType); $query->getQuerySettings()->setIgnoreEnableFields(true); $object = $query->matching($query->equals('uid', $identity))->execute()->getFirst(); } else { throw new InvalidSourceException( 'The identity property "' . $identity . '" is no UID.', 1641904861 ); } if ($object === null) { throw new TargetNotFoundException( sprintf('Object of type %s with identity "%s" not found.', $targetType, print_r($identity, true)), 1641904896 ); } return $object; } }

Die ursprüngliche Idee hierzu stammt von Helmut in seinem Gist.

Zurück

Kennst du das: Immer nur schnell schnell?

Wie wäre es einmal mit Zeit und Respekt für Codequalität? Arbeiten im Team? Automatisierte Tests?

Komm zu uns