Im Frontend eigene Extbase Objekte zu kopieren kann sehr mühsam werden.
Auch der Cloning Service der FED Extension schafft keine Abhilfe.
Entweder werden File-Referenzen oder Childobjekte nicht korrekt kopiert.
Mit folgender Serviceklasse könnt Ihr euch einen Backenduser simulieren und somit den “\TYPO3\CMS\Core\DataHandling\DataHandler” von TYPO3 nutzen um einwandfreie kopien ohne Einschränkungen eurer Objekte zu erstellen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/** * @param \VENDOR\Extname\Domain\Model\Page $page * @return void */ public function copyAction(\VENDOR\Extname\Domain\Model\Page $page) { /** * @var \VENDOR\Extname\Service\DataHandler $dataHandler */ $dataHandler = $this->objectManager->get('VENDOR\\Extname\\Service\\DataHandler'); $newUid = $dataHandler->copyRecord($page); // über $overrideValues könnt ihr direkt den Titel des kopierten Datensatzes anpassen. $this->redirect('list'); } |
Und so sieht die neue Serviceklasse aus:
Nicht vergessen im Backend einen Admin Benutzer namens “datahandler” anzulegen oder was euch sonst einfällt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<?php namespace VENDOR\Extname\Service; /*************************************************************** * Copyright notice * * (c) 2015 Marc Gutknecht * * All rights reserved * * This script is part of the TYPO3 project. The TYPO3 project is * free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * The GNU General Public License can be found at * http://www.gnu.org/copyleft/gpl.html. * * This script is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\DebuggerUtility; class DataHandler extends \TYPO3\CMS\Core\DataHandling\DataHandler { /** * __construct */ public function __construct() { parent::__construct(); } /** * Simulate Backend User for DataHandler */ public function simulateBackendUser() { /** @var \TYPO3\CMS\Backend\FrontendBackendUserAuthentication $BE_USER */ $BE_USER = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\FrontendBackendUserAuthentication'); $BE_USER->setBeUserByName('datahandler'); if ($BE_USER->user['uid']) { $BE_USER->fetchGroupData(); } $BE_USER->uc_default['copyLevels']= '9999'; $BE_USER->uc = $BE_USER->uc_default; $GLOBALS['PAGES_TYPES'][254]['allowedTables'] = '*'; return $BE_USER; } /** * Copying a single record * * @param \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $value * @param boolean $first Is a flag set, if the record copied is NOT a 'slave' to another record copied. That is, if this record was asked to be copied in the cmd-array * @param array $overrideValues Associative array with field/value pairs to override directly. Notice; Fields must exist in the table record and NOT be among excluded fields! * @param string $excludeFields Commalist of fields to exclude from the copy process (might get default values) * @param integer $language Language ID (from sys_language table) * @return integer ID of new record, if any */ public function copyRecord($object, $first = 0, $overrideValues = array(), $excludeFields = '', $language = 0) { if($object instanceof \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface){ $this->BE_USER = $this->simulateBackendUser(); $this->userid = $this->BE_USER->user['uid']; $this->username = $this->BE_USER->user['username']; $this->admin = true; if (!is_object($GLOBALS['LANG'])) { $GLOBALS['LANG'] = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Lang\\LanguageService'); $GLOBALS['LANG']->csConvObj = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Core\\Charset\\CharsetConverter'); } return parent::copyRecord(MyUtility::resolveTableName($object), $object->getUid(), $object->getPid(), 1, $overrideValues, $excludeFields, $language); } } } ?> |
Die Funktion resolveTableName ist bei mir eine von vielen statischen Funktionen (Quelle:/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php) und sieht wie folgt aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/** * Resolve the table name for the given class name * * @param \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $domainObject * @return string The table name */ public static function resolveTableName(\TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface $domainObject) { $className = get_class($domainObject); if (strpos($className, '\\') !== FALSE) { $classNameParts = explode('\\', $className, 6); // Skip vendor and product name for core classes if (strpos($className, 'TYPO3\\CMS\\') === 0) { $classPartsToSkip = 2; } else { $classPartsToSkip = 1; } $tableName = 'tx_' . strtolower(implode('_', array_slice($classNameParts, $classPartsToSkip))); } else { $tableName = strtolower($className); } return $tableName; } |
Hoffe es hat geholfen 😉