Создание собственного действия для клонирования / дублирования объекта extbase TYPO3 8.7 с вложенными дочерними элементами - PullRequest
0 голосов
/ 27 августа 2018

Я строю свое расширение на основе extbase TYPO3 в TYPO3 8.7. Это бэкэнд-модуль. В контроллере я пишу свое собственное действие для клонирования объекта. В этом примере я хочу клонировать / продублировать объект 'Campaign' и сохранить его с измененным заголовком, например добавить текст 'copy' к заголовку. Но новый объект должен также иметь свои собственные дочерние элементы, которые должны быть точными копиями. Когда вызывается действие, я получаю только копию объекта, но не дочерние. Есть ли пример или лучший случай, как справиться с этой задачей? Я не нашел, даже я нашел некоторые вопросы и ответы на ту же тему, но более старую версию. Я надеюсь, что на сегодняшний день есть более прямое решение. Спасибо за каждый намек, который указывает мне на правильные идеи и, возможно, обновленный пример и версию. Вот что у меня есть, мой контроллер. Как мне реализовать рекурсивное копирование всех дочерних элементов (и у некоторых дочерних тоже есть дочерние элементы)?

    /**
     * action clone
     * @param \ABC\Copytest\Domain\Model\Campaign $campaign
     * @return void
     * @var \ABC\Copytest\Domain\Model\Campaign $newCampaign
     */

    public function cloneAction(\ABC\Copytest\Domain\Model\Campaign $campaign) {
        $newCampaign = $this->objectManager->get("ABC\Copytest\Domain\Model\Campaign");
        $properties = $campaign->_getProperties();
        unset($properties['uid']);
        foreach ($properties as $key => $value) {
            $newCampaign->_setProperty($key, $value);
        }
        $newCampaign->_setProperty('title', $properties['title']. ' COPY');
        $this->campaignRepository->add($newCampaign);
        $this->addFlashMessage('Clone was created', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::OK);
        $this->redirect('list');
    }

1 Ответ

0 голосов
/ 27 августа 2018

Существует один подход, который решает этот сценарий использования из другого POV, а именно, что значения аргумента запроса без идентификатора автоматически помещаются в свежие объекты, которые затем могут быть сохранены. Это в основном клонирует оригинальные объекты. Вот что вам нужно сделать:

  1. Добавьте представление, которое имеет поля для всех свойств вашего объекта, скрытые поля тоже подойдут. Это может быть, например, представление edit с отдельной кнопкой отправки для вызова действия clone.
  2. Добавьте initializeCloneAction() и получите необработанные аргументы запроса через $this->request->getArguments().
  3. Теперь выполните unset($arguments[<argumentName>]['__identity']);, сделайте то же самое для каждого отношения, которое имеет ваш объект, если вы хотите копировать вместо общих ссылок.
  4. Сохраните необработанные аргументы запроса снова через $this->request->setArguments($arguments).
  5. Наконец, разрешите создание новых объектов в конфигурации сопоставления свойств вашего аргумента и, возможно, всех свойств отношений.

Вот как может выглядеть полный initializeCloneAction():

public function initializeCloneAction()
{
    $arguments = $this->request->getArguments();

    unset(
        $arguments['campaign']['__identity'],
        $arguments['campaign']['singleRelation']['__identity'],
    );

    foreach (array_keys($arguments['campaign']['multiRelation']) as $i) {
        unset($arguments['campaign']['multiRelation'][$i]['__identity']);
    }

    $this->request->setArguments($arguments);

    // Allow object creation now that we have new objects
    $this->arguments->getArgument('campaign')->getPropertyMappingConfiguration()
        ->setTypeConverterOption(PersistentObjectConverter::class, PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true)
        ->allowCreationForSubProperty('singleRelation')
        ->getConfigurationFor('multiRelation')
            ->allowCreationForSubProperty('*');
}

Теперь, если вы отправите форму, используя действие clone, ваше действие clone получит полностью заполненный, но новый объект, который вы можете хранить в своем хранилище как обычно. Ваш cloneAction() будет очень простым:

public function cloneAction(Campaign $campaign)
{
    $this->campaignRepository->add($campaign);

    $this->addFlashMessage('Campaign was copied successfully!');
    $this->redirect('list');
}
...