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 😉
Danke, das hat geholfen! Ich finde es eine nette Variante es so zu machen.
hi, vielen dank für die vorarbeit. das macht sich echt super. kann es aber sein, dass du im zweiten codeblock in zeile 77 ein bischen was “ungünstig” geschrieben hast? z.b. wird $overrideValues ja immer wieder mit einem leeren array vorbelegt und so mommen die daten nie an, die man überschreiben möchte. aber ansonsten echt toll. danke
hi. danke und schön das es geholfen hat. ja das stimmt, kleiner c&p fehler für die Veröffentlichung hier.
Very good blog post.Really thank you! Fantastic.
I have recently started a web site, the info you provide on this site has helped me greatly. Thank you for all of your time & work. There can be no real freedom without the freedom to fail. by Erich Fromm.
Vielen Dank nochmals für den Beitrag. Funktioniert auch in TYPO3 7.6 tadellos.
Can I just say what a comfort to find somebody that really knows what they are discussing on the net.
You actually understand how to bring a problem to light
and make it important. More and more people
should check this out and understand this side of
the story. I can’t believe you are not more popular since you
most certainly have the gift.
Hallo,
es scheint, als wird TYPO3\\CMS\\Backend\\FrontendBackendUserAuthentication deprecated (https://docs.typo3.org/typo3cms/extensions/core/Changelog/9.5/Deprecation-86288-FrontendBackendUserAuthenticationMethods.html). Reicht es einfach TYPO3\\CMS\\Backend\\FrontendBackendUserAuthentication mit TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication zu ersetzen?
Hallo,
anscheinend werden nur einige Veraltete Funktionen entfernt, nicht die ganze Klasse.
checkBackendAccessSettingsFromInitPhp()
extPageReadAccess()
extGetTreeList()
extGetLL()
und wenn ich mich recht erinnere, hab ich keine der Funktionen verwendet 😉
Grüsse