From 6ee86b9a6b40dedf9830e8c3c3f5c31a3db4cea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= Date: Wed, 12 Jan 2022 15:33:54 +0100 Subject: [PATCH 1/2] update typo3 required version for 10.4 compat update the required typo3 version to 10.4 for compatibility --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fdc4e8e..eca9a4f 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "comsolit/owl_slider": "self.version" }, "require": { - "typo3/minimal": ">=9.0.0,<9.5.99", + "typo3/cms-core": "^9.5 || ^10.4", "php": ">=7.2.0" }, "autoload": { From cf8a5aa75eac7888cc6852f24fba6f39102876fe Mon Sep 17 00:00:00 2001 From: S0018577069 Date: Wed, 12 Jan 2022 23:07:18 +0100 Subject: [PATCH 2/2] [TASK] TYPO3 10.4 compatibility - migrate itemimage field to FAL (adds ItemImageUpdateWizard therefore) - fixes deprecations in TCA - fixes issues from deprecated or outdated TYPO3 API calls - fixes deprecations in flexform --- Classes/Controller/ItemController.php | 4 +- Classes/Domain/Model/Item.php | 29 +- .../PHP/tx_owlslider_addFieldsToFlexForm.php | 13 +- Classes/Updates/ItemImageUpdateWizard.php | 297 ++++++++++++++++++ .../AddJsFooterInlineCodeViewHelper.php | 2 +- .../FlexForms/flexform_owlslider.xml | 4 +- .../TCA/tx_owlslider_domain_model_item.php | 59 +++- Resources/Private/Partials/SimpleOwl.html | 4 +- Resources/Private/Partials/SyncedOwls.html | 4 +- ext_localconf.php | 5 +- ext_tables.php | 2 +- 11 files changed, 378 insertions(+), 45 deletions(-) create mode 100644 Classes/Updates/ItemImageUpdateWizard.php diff --git a/Classes/Controller/ItemController.php b/Classes/Controller/ItemController.php index 04370c5..fa67e8b 100644 --- a/Classes/Controller/ItemController.php +++ b/Classes/Controller/ItemController.php @@ -26,6 +26,8 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use TYPO3\CMS\Extbase\Annotation\Inject; + /** * * @package owl_slider @@ -37,8 +39,8 @@ class ItemController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController /** * itemRepository * + * @Inject * @var \Comsolit\OwlSlider\Domain\Repository\ItemRepository - * @inject */ protected $itemRepository; diff --git a/Classes/Domain/Model/Item.php b/Classes/Domain/Model/Item.php index 6b75884..42e0f0c 100644 --- a/Classes/Domain/Model/Item.php +++ b/Classes/Domain/Model/Item.php @@ -26,6 +26,8 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use TYPO3\CMS\Extbase\Annotation as Extbase; + /** * * @package owl_slider @@ -37,37 +39,36 @@ class Item extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity /** * Item name * - * @var \string - * @validate NotEmpty + * @var string + * @Extbase\Validate("NotEmpty") */ protected $itemname; /** * Item image * - * @var \string - * @validate NotEmpty + * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference */ protected $itemimage; /** * Item link * - * @var \string + * @var string */ protected $itemlink; /** * Item content * - * @var \string + * @var string */ protected $itemcontent; /** * Returns the itemname * - * @return \string $itemname + * @return string $itemname */ public function getItemname() { @@ -77,7 +78,7 @@ public function getItemname() /** * Sets the itemname * - * @param \string $itemname + * @param string $itemname * @return void */ public function setItemname($itemname) @@ -88,7 +89,7 @@ public function setItemname($itemname) /** * Returns the itemimage * - * @return \string $itemimage + * @return string $itemimage */ public function getItemimage() { @@ -98,7 +99,7 @@ public function getItemimage() /** * Sets the itemimage * - * @param \string $itemimage + * @param string $itemimage * @return void */ public function setItemimage($itemimage) @@ -109,7 +110,7 @@ public function setItemimage($itemimage) /** * Returns the itemlink * - * @return \string itemlink + * @return string itemlink */ public function getItemlink() { @@ -119,7 +120,7 @@ public function getItemlink() /** * Sets the itemlink * - * @param \string $itemlink + * @param string $itemlink * @return void */ public function setItemlink($itemlink) @@ -130,7 +131,7 @@ public function setItemlink($itemlink) /** * Returns the itemcontent * - * @return \string $itemcontent + * @return string $itemcontent */ public function getItemcontent() { @@ -140,7 +141,7 @@ public function getItemcontent() /** * Sets the itemcontent * - * @param \string $itemcontent + * @param string $itemcontent * @return void */ public function setItemcontent($itemcontent) diff --git a/Classes/PHP/tx_owlslider_addFieldsToFlexForm.php b/Classes/PHP/tx_owlslider_addFieldsToFlexForm.php index 30581f0..58dc672 100644 --- a/Classes/PHP/tx_owlslider_addFieldsToFlexForm.php +++ b/Classes/PHP/tx_owlslider_addFieldsToFlexForm.php @@ -1,5 +1,8 @@ getRootLine($pageUid); - $TSObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Core\TypoScript\ExtendedTemplateService'); + $sysPageObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(TYPO3\CMS\Core\Domain\Repository\PageRepository::class); + $rootlineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $pageUid); + $rootLine = $rootlineUtility->get(); + + $TSObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\ExtendedTemplateService::class); $TSObj->tt_track = 0; - $TSObj->init(); +// $TSObj->init(); $TSObj->runThroughTemplates($rootLine); $TSObj->generateConfig(); return $TSObj->setup; diff --git a/Classes/Updates/ItemImageUpdateWizard.php b/Classes/Updates/ItemImageUpdateWizard.php new file mode 100644 index 0000000..4509ae6 --- /dev/null +++ b/Classes/Updates/ItemImageUpdateWizard.php @@ -0,0 +1,297 @@ +logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); + } + + /** + * Get records from table where the field to migrate is not empty (NOT NULL and != '') + * and also not numeric (which means that it is migrated) + * + * @return array + * @throws RuntimeException + */ + protected function getRecordsFromTable(): array + { + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + $queryBuilder = $connectionPool->getQueryBuilderForTable($this->table); + $queryBuilder->getRestrictions()->removeAll(); + + try { + $result = $queryBuilder + ->select('uid', 'pid', $this->fieldToMigrate) + ->from($this->table) + ->where( + $queryBuilder->expr()->isNotNull($this->fieldToMigrate), + $queryBuilder->expr()->neq( + $this->fieldToMigrate, + $queryBuilder->createNamedParameter('') + ), + $queryBuilder->expr()->comparison( + 'CAST(CAST(' . $queryBuilder->quoteIdentifier($this->fieldToMigrate) . ' AS DECIMAL) AS CHAR)', + ExpressionBuilder::NEQ, + 'CAST(' . $queryBuilder->quoteIdentifier($this->fieldToMigrate) . ' AS CHAR)' + ) + ) + ->orderBy('uid') + ->execute(); + + return $result->fetchAll(); + } catch (DBALException $e) { + throw new RuntimeException( + 'Database query failed. Error was: ' . $e->getPrevious()->getMessage(), + 1511950673 + ); + } + } + + /** + * Migrates a single field. + * + * @param array $row + * @param string $customMessage + * + * @throws Exception + */ + protected function migrateField(array $row, string &$customMessage) + { + $fieldItems = GeneralUtility::trimExplode(',', $row[$this->fieldToMigrate], true); + if (empty($fieldItems) || is_numeric($row[$this->fieldToMigrate])) { + return; + } + $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/'; + $i = 0; + + $storageUid = $this->storage->getUid(); + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + + foreach ($fieldItems as $item) { + $fileUid = null; + $sourcePath = Environment::getPublicPath() . '/' . $this->sourcePath . $item; + $targetDirectory = Environment::getPublicPath() . '/' . $fileadminDirectory . $this->targetPath; + $targetPath = $targetDirectory . basename($item); + + // maybe the file was already moved, so check if the original file still exists + if (file_exists($sourcePath)) { + if (!is_dir($targetDirectory)) { + GeneralUtility::mkdir_deep($targetDirectory); + } + + // see if the file already exists in the storage + $fileSha1 = sha1_file($sourcePath); + + $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file'); + $queryBuilder->getRestrictions()->removeAll(); + $existingFileRecord = $queryBuilder->select('uid')->from('sys_file')->where( + $queryBuilder->expr()->eq( + 'sha1', + $queryBuilder->createNamedParameter($fileSha1) + ), + $queryBuilder->expr()->eq( + 'storage', + $queryBuilder->createNamedParameter($storageUid, PDO::PARAM_INT) + ) + )->execute()->fetch(); + + // the file exists, the file does not have to be moved again + if (is_array($existingFileRecord)) { + $fileUid = $existingFileRecord['uid']; + } else { + // just move the file (no duplicate) + rename($sourcePath, $targetPath); + } + } + + if ($fileUid === null) { + // get the File object if it hasn't been fetched before + try { + // if the source file does not exist, we should just continue, but leave a message in the docs; + // ideally, the user would be informed after the update as well. + /** @var File $file */ + $file = $this->storage->getFile($this->targetPath . $item); + $fileUid = $file->getUid(); + } catch (InvalidArgumentException $e) { + + // no file found, no reference can be set + $this->logger->notice( + 'File ' . $this->sourcePath . $item . ' does not exist. Reference was not migrated.', + [ + 'table' => $this->table, + 'record' => $row, + 'field' => $this->fieldToMigrate, + ] + ); + + $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.'; + + $message = sprintf( + $format, + $this->sourcePath . $item, + $this->table, + $row['uid'], + $this->fieldToMigrate + ); + $customMessage .= PHP_EOL . $message; + continue; + } + } + + + if ($fileUid > 0) { + $fields = [ + 'fieldname' => $this->fieldToMigrate, + 'table_local' => 'sys_file', + 'pid' => ($this->table === 'pages' ? $row['uid'] : $row['pid']), + 'uid_foreign' => $row['uid'], + 'uid_local' => $fileUid, + 'tablenames' => $this->table, + 'crdate' => time(), + 'tstamp' => time() + ]; + + $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file_reference'); + $queryBuilder->insert('sys_file_reference')->values($fields)->execute(); + ++$i; + } + } + + // Update referencing table's original field to now contain the count of references, + // but only if all new references could be set + if ($i === count($fieldItems)) { + $queryBuilder = $connectionPool->getQueryBuilderForTable($this->table); + $queryBuilder->update($this->table)->where( + $queryBuilder->expr()->eq( + 'uid', + $queryBuilder->createNamedParameter($row['uid'], PDO::PARAM_INT) + ) + )->set($this->fieldToMigrate, $i)->execute(); + + } + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function getTitle(): string + { + return $this->title; + } + + public function getDescription(): string + { + return $this->description; + } + + /** + * @throws Exception + */ + public function executeUpdate(): bool + { + // storage with uid 1 is hopefully the fileadmin storage + $this->storage = GeneralUtility::makeInstance(StorageRepository::class)->findByUid(1); + + $customMessage = ''; + $records = $this->getRecordsFromTable(); + foreach ($records as $record) { + $this->migrateField($record, $customMessage); + } + return true; + } + + public function updateNecessary(): bool + { + $records = $this->getRecordsFromTable(); + if (empty($records)) { + return false; + } + return true; + } + + public function getPrerequisites(): array + { + return [ + DatabaseUpdatedPrerequisite::class + ]; + } +} \ No newline at end of file diff --git a/Classes/ViewHelpers/AddJsFooterInlineCodeViewHelper.php b/Classes/ViewHelpers/AddJsFooterInlineCodeViewHelper.php index 62c0768..ff2ecf8 100644 --- a/Classes/ViewHelpers/AddJsFooterInlineCodeViewHelper.php +++ b/Classes/ViewHelpers/AddJsFooterInlineCodeViewHelper.php @@ -2,7 +2,7 @@ namespace Comsolit\OwlSlider\ViewHelpers; -class AddJsFooterInlineCodeViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper +class AddJsFooterInlineCodeViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper { /** * diff --git a/Configuration/FlexForms/flexform_owlslider.xml b/Configuration/FlexForms/flexform_owlslider.xml index f82f4fc..b7da843 100644 --- a/Configuration/FlexForms/flexform_owlslider.xml +++ b/Configuration/FlexForms/flexform_owlslider.xml @@ -14,7 +14,7 @@ - select + selectSingle Simple Owl @@ -40,7 +40,7 @@ - select + selectSingle tx_owlslider_addFieldsToFlexForm->addFields diff --git a/Configuration/TCA/tx_owlslider_domain_model_item.php b/Configuration/TCA/tx_owlslider_domain_model_item.php index cfd9c82..8a76e9e 100755 --- a/Configuration/TCA/tx_owlslider_domain_model_item.php +++ b/Configuration/TCA/tx_owlslider_domain_model_item.php @@ -12,7 +12,6 @@ 'versioningWS' => TRUE, 'origUid' => 't3_origuid', 'languageField' => 'sys_language_uid', - 'transOrigPointerField' => 'l10n_parent', 'transOrigDiffSourceField' => 'l10n_diffsource', 'delete' => 'deleted', 'enablecolumns' => array( @@ -23,9 +22,6 @@ 'searchFields' => 'itemname,itemimage,itemlink,', 'iconfile' => 'EXT:owl_slider/Resources/Public/Icons/tx_owlslider_domain_model_item.png' ), - 'interface' => array( - 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, itemname, itemimage, itemlink, itemcontent' - ), 'types' => array( '1' => array( 'showitem' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, itemname, itemimage, itemlink, itemcontent, column_offset,--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access,starttime, endtime', @@ -134,20 +130,49 @@ 'eval' => 'trim,required' ) ), - 'itemimage' => array( - 'exclude' => 0, +// 'itemimage' => array( +// 'exclude' => 0, +// 'label' => 'LLL:EXT:owl_slider/Resources/Private/Language/locallang_db.xlf:tx_owlslider_domain_model_item.itemimage', +// 'config' => array( +// 'type' => 'inline', +// 'internal_type' => 'file', +// 'uploadfolder' => 'uploads/tx_owlslider', +// 'minitems' => 1, +// 'size' => 1, +// 'maxitems' => 1, +// 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], +// 'disallowed' => '' +// ) +// ), + 'itemimage' => [ 'label' => 'LLL:EXT:owl_slider/Resources/Private/Language/locallang_db.xlf:tx_owlslider_domain_model_item.itemimage', - 'config' => array( - 'type' => 'group', - 'internal_type' => 'file', - 'uploadfolder' => 'uploads/tx_owlslider', - 'minitems' => 1, - 'size' => 1, - 'maxitems' => 1, - 'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], - 'disallowed' => '' - ) - ), + 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( + 'itemimage', + [ + 'appearance' => [ + 'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference', + + ], + // custom configuration for displaying fields in the overlay/reference table + // to use the image overlay palette instead of the basic overlay palette + 'overrideChildTca' => [ + 'types' => [ + '0' => [ + 'showitem' => ' + --palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, + --palette--;;filePalette' + ], + \TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [ + 'showitem' => ' + --palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette, + --palette--;;filePalette' + ], + ], + ], + ], + $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] + ), + ], 'itemlink' => array( 'exclude' => 0, 'label' => 'LLL:EXT:owl_slider/Resources/Private/Language/locallang_db.xlf:tx_owlslider_domain_model_item.itemlink', diff --git a/Resources/Private/Partials/SimpleOwl.html b/Resources/Private/Partials/SimpleOwl.html index cafcc37..53b8b29 100644 --- a/Resources/Private/Partials/SimpleOwl.html +++ b/Resources/Private/Partials/SimpleOwl.html @@ -9,12 +9,12 @@ - + - + diff --git a/Resources/Private/Partials/SyncedOwls.html b/Resources/Private/Partials/SyncedOwls.html index 795eede..45e3db7 100644 --- a/Resources/Private/Partials/SyncedOwls.html +++ b/Resources/Private/Partials/SyncedOwls.html @@ -8,12 +8,12 @@ - + - + diff --git a/ext_localconf.php b/ext_localconf.php index 907f37b..09dbe06 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -4,7 +4,7 @@ } \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( - 'Comsolit.' . $_EXTKEY, + 'Comsolit.owl_slider', 'Owlslider', array( 'Item' => 'list, show' @@ -14,3 +14,6 @@ 'Item' => '' ) ); + +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['owlSliderItemImage'] + = \Comsolit\OwlSlider\Updates\ItemImageUpdateWizard::class; \ No newline at end of file diff --git a/ext_tables.php b/ext_tables.php index 95af681..94397fa 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -13,4 +13,4 @@ 'tx_owlslider_domain_model_item' ); -include_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'Classes/PHP/tx_owlslider_addFieldsToFlexForm.php'); +include_once(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('owl_slider') . 'Classes/PHP/tx_owlslider_addFieldsToFlexForm.php');