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.