diff --git a/Classes/Controller/DamMigrationCommandController.php b/Classes/Controller/DamMigrationCommandController.php index 89eba7c..60947cb 100644 --- a/Classes/Controller/DamMigrationCommandController.php +++ b/Classes/Controller/DamMigrationCommandController.php @@ -464,19 +464,53 @@ public function updateReferenceIndexCommand() { * Migrate relations to DAM records * Migrate relations to dam records that dam_ttcontent and dam_uploads introduced. * + * The way image captions, title and alt attributes apply varies wildly across + * TYPO3 installations, mainly depending on whether you used the static + * include that came with dam_ttcontent and how you configured it. Please + * read the documentation for more information. To support all + * configurations, you can specify a chain for each image caption, title and + * alt text which defines the priority of each field. Each chain consists + * of one or more of the following options, separated by commas, earliest + * non-empty field takes precedence over later ones: + * + * contentTitle title line from content element + * contentAlt alt text line from content element + * contentCaption caption text line from content element + * metaTitle title from DAM meta data + * metaAlt alt text from DAM meta data + * metaCaption caption text from DAM meta data + * metaDescription description from DAM meta data + * empty ends chain with an empty string if nothing applied + * (overriding FAL metadata with no output) + * default ends chain without overriding FAL metadata if nothing + * applied (using central FAL metadata without copy) + * + * meta options cause DAM/FAL meta data to be copied to the content element, + * so they override values entered later on central FAL record. Thus they + * freeze input to the state at the time of migration, so later edits of + * central metadata won't have any effect on migrated content element + * references. Omit meta options and instead add default to the end of your + * chain if you want FAL edits to have an effect on migrated content. + * * It is highly recommended to update the ref index afterwards. * * @param string $tablename The tablename to migrate relations for + * @param string $imageCaption Chain of fields to determine image captions. (Default: metaDescription,default) + * @param string $imageTitle Chain of fields to determine image title. (Default: contentCaption,metaTitle,empty) + * @param string $imageAlt Chain of fields to determine image alt texts. (Default: metaAlt,empty) * @param string $uploadsLayout The layout ID to set on migrated CType uploads ("file links") content elements. 1 shows file type icons (like dam_filelinks did), 2 shows a thumbnail preview instead, 0 shows nothing but link & caption. Set to 'null' if no action should be taken. Default: 1 * * @return void */ - public function migrateRelationsCommand($tablename = '', $uploadsLayout = '1') { + public function migrateRelationsCommand($tablename = '', $imageCaption = 'metaDescription,default', $imageTitle = 'contentCaption,metaTitle,empty', $imageAlt = 'metaAlt,empty', $uploadsLayout = '1') { $tablename = preg_replace('/[^a-zA-Z0-9_-]/', '', $tablename); /** @var Service\MigrateRelationsService $service */ $service = $this->objectManager->get('TYPO3\\CMS\\DamFalmigration\\Service\\MigrateRelationsService', $this); $service->setTablename($tablename); + $service->setChainImageCaption($imageCaption); + $service->setChainImageTitle($imageTitle); + $service->setChainImageAlt($imageAlt); $service->setUploadsLayout($uploadsLayout); $this->outputMessage($service->execute()); } diff --git a/Classes/Service/MigrateRelationsService.php b/Classes/Service/MigrateRelationsService.php index 43552c3..86748bd 100644 --- a/Classes/Service/MigrateRelationsService.php +++ b/Classes/Service/MigrateRelationsService.php @@ -27,6 +27,7 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ use TYPO3\CMS\Core\Messaging\FlashMessage; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; /** @@ -47,7 +48,7 @@ class MigrateRelationsService extends AbstractService { * @var string */ protected $tablename = ''; - + /** * Layout to set on migrated content elements of CType "uploads". * Layout 1 matches dam_filelinks behaviour (file type icon before links). @@ -55,6 +56,54 @@ class MigrateRelationsService extends AbstractService { */ protected $uploadsLayout = 1; + /** + * Chain defining priority and handling of fields for image captions. + * @var array + */ + protected $chainImageCaption = array(); + + /** + * Chain defining priority and handling of fields for image titles. + * @var array + */ + protected $chainImageTitle = array(); + + /** + * Chain defining priority and handling of fields for image alt texts. + * @var array + */ + protected $chainImageAlt = array(); + + /* constants for parsed chain options + * may not be the same as parser input, so do not use outside this class + */ + const CHAIN_CONTENT_TITLE = 'contentTitle'; + const CHAIN_CONTENT_ALT = 'contentAlt'; + const CHAIN_CONTENT_CAPTION = 'contentCaption'; + const CHAIN_META_TITLE = 'metaTitle'; + const CHAIN_META_ALT = 'metaAlt'; + const CHAIN_META_CAPTION = 'metaCaption'; + const CHAIN_META_DESCRIPTION = 'metaDescription'; + const CHAIN_EMPTY = 'empty'; + const CHAIN_DEFAULT = 'default'; + + /** + * Chain options parser mapping. Used to verify valid options and associate + * them to above constants. + * @var array + */ + protected $chainOptionsMap = array( + 'contentTitle' => self::CHAIN_CONTENT_TITLE, + 'contentAlt' => self::CHAIN_CONTENT_ALT, + 'contentCaption' => self::CHAIN_CONTENT_CAPTION, + 'metaTitle' => self::CHAIN_META_TITLE, + 'metaAlt' => self::CHAIN_META_ALT, + 'metaCaption' => self::CHAIN_META_CAPTION, + 'metaDescription' => self::CHAIN_META_DESCRIPTION, + 'empty' => self::CHAIN_EMPTY, + 'default' => self::CHAIN_DEFAULT, + ); + /** * main function * @@ -117,32 +166,9 @@ public function execute() { $newRelationsRecordUid = $this->database->sql_insert_id(); $this->updateReferenceIndex($newRelationsRecordUid); - // update layout of CType uploads - if (($damRelation['tablenames'] === 'tt_content') && ($insertData['fieldname'] == 'media')) { - // check if content element actually has CType uploads - $contentElement = $this->database->exec_SELECTgetSingleRow( - 'CType', - 'tt_content', - 'uid = ' . $damRelation['uid_foreign'] - ); - - $shouldSetLayout = (($this->uploadsLayout !== NULL) && ($contentElement !== NULL) && is_array($contentElement) && ($contentElement['CType'] == 'uploads')); - - if ($shouldSetLayout) { - $this->database->exec_UPDATEquery( - 'tt_content', - 'uid = ' . $damRelation['uid_foreign'], - array( - 'layout' => $this->uploadsLayout - ) - ); - } - } - - if ($damRelation['tablenames'] === 'tt_content' || - $damRelation['tablenames'] === 'pages' || - $damRelation['tablenames'] === 'pages_language_overlay' - ) { + $isTablePagesOrOverlay = (($damRelation['tablenames'] === 'pages') || ($damRelation['tablenames'] === 'pages_language_overlay')); + $isTableTTContent = ($damRelation['tablenames'] === 'tt_content'); + if ($isTableTTContent || $isTablePagesOrOverlay) { // when using IRRE (should be default for image & media?) we // need to supply the actual number of images referenced // by the content element @@ -163,61 +189,100 @@ public function execute() { } } - if ($insertData['fieldname'] === 'image') { - // migrate image_links from tt_content. - $linkFromContentRecord = $this->database->exec_SELECTgetSingleRow( - 'image_link,imagecaption', + if ($isTableTTContent && ($insertData['fieldname'] === 'image')) { + // get image-related settings saved on content element + $ttContentFields = $this->database->exec_SELECTgetSingleRow( + 'image_link, imagecaption, titleText, altText', 'tt_content', 'uid = ' . $damRelation['uid_foreign'] ); - if (!empty($linkFromContentRecord)) { - $imageLinks = explode(chr(10), $linkFromContentRecord['image_link']); - $imageCaptions = explode(chr(10), $linkFromContentRecord['imagecaption']); - $update = array(); - // only update if image explode result has some content - if ($imageLinks[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]) { + // prepare content element data to apply via chain + $contentElementRelationIndex = ($numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1); + $chainFieldArray = $this->compileChainFieldArray($damRelation, $ttContentFields, $contentElementRelationIndex); + + // process configurable image field chains + $update = array(); + $update['title'] = $this->applyChain($this->chainImageTitle, $chainFieldArray); + $update['alternative'] = $this->applyChain($this->chainImageAlt, $chainFieldArray); + $update['description'] = $this->applyChain($this->chainImageCaption, $chainFieldArray); + + // copy link if content element has got any + if (!empty($ttContentFields)) { + $imageLinks = explode(chr(10), $ttContentFields['image_link']); + + if ($imageLinks[$contentElementRelationIndex]) { $update['link'] = $imageLinks[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]; } - // only update title if caption explode has some content - if ($imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]) { - $update['title'] = $imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]; - } - if (count($update)) { - $this->database->exec_UPDATEquery( - 'sys_file_reference', - 'uid = ' . $newRelationsRecordUid, - $update - ); - } } + + // save to database + $this->database->exec_UPDATEquery( + 'sys_file_reference', + 'uid = ' . $newRelationsRecordUid, + $update + ); } elseif ($insertData['fieldname'] === 'media') { + // "media" is processed for both tt_content and pages + // (see getColForFieldName for applicable mappings) + + // QUESTION: The way this is handled for pages and page + // language overlays does not appear to make + // any sense (introduced for dam_pages): + // Do we really query tt_content using a page + // ID for a content UID? This should not yield + // any valid results and may require testing. + // (we believe tt_content should be + // $damRelation['tablenames'] instead) + // see GitHub issue #73 + // migrate captions from tt_content upload elements - $linkFromContentRecord = $this->database->exec_SELECTgetSingleRow( + $ttContentFields = $this->database->exec_SELECTgetSingleRow( 'imagecaption', 'tt_content', 'uid = ' . $damRelation['uid_foreign'] ); - if (!empty($linkFromContentRecord)) { - $imageCaptions = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(chr(10), $linkFromContentRecord['imagecaption']); + if (!empty($ttContentFields)) { + $imageCaptions = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(chr(10), $ttContentFields['imagecaption']); $update = array(); - // only update title if caption explode has some content + // only update description (new caption field) if caption explode has some content if ($imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]) { - $update['title'] = $imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]; + $update['description'] = $imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1]; } if (count($update)) { $this->database->exec_UPDATEquery( 'sys_file_reference', 'uid = ' . $newRelationsRecordUid, + $update + ); + } + } + + // update layout of CType uploads + if ($isTableTTContent) { + // check if content element actually has CType uploads + $contentElement = $this->database->exec_SELECTgetSingleRow( + 'CType', + 'tt_content', + 'uid = ' . $damRelation['uid_foreign'] + ); + + $shouldSetLayout = (($this->uploadsLayout !== NULL) && ($contentElement !== NULL) && is_array($contentElement) && ($contentElement['CType'] == 'uploads')); + + if ($shouldSetLayout) { + $this->database->exec_UPDATEquery( + 'tt_content', + 'uid = ' . $damRelation['uid_foreign'], array( - 'title' => $imageCaptions[$numberImportedRelationsByContentElement[$insertData['uid_foreign']] - 1] + 'layout' => $this->uploadsLayout ) ); } } } } + $this->controller->message(number_format(100 * ($counter / $total), 1) . '% of ' . $total . ' id: ' . $damRelation['uid_local'] . ' table: ' . $damRelation['tablenames'] . @@ -266,6 +331,7 @@ protected function execSelectDamReferencesWhereSysFileExists() { sys_file_metadata.title, sys_file_metadata.description, sys_file_metadata.alternative, + sys_file_metadata.caption, sys_file.uid as sys_file_uid', 'tx_dam_mm_ref JOIN sys_file ON @@ -330,6 +396,155 @@ public function setTablename($tablename) { } /** + * Compiles all chain-relevant content required for applyChain method into + * an array per given file relation including all options to end chains. + * + * @param array $damRelation fields from DAM/FAL (as used in execute()) + * @param array $ttContentFields fields from tt_content (as used in execute()) + * @param int $contentElementRelationIndex array index of current file in tt_content multi-line string fields + * + * @return array all content required for applyChain method + */ + protected function compileChainFieldArray($damRelation, $ttContentFields, $contentElementRelationIndex) { + // pre-defined values to end chain + $out = array( + self::CHAIN_EMPTY => '', + self::CHAIN_DEFAULT => NULL + ); + + // split tt_content fields by line + $hasTTContentFields = !empty($ttContentFields); + $contentCaptions = $hasTTContentFields ? explode(chr(10), $ttContentFields['imagecaption']) : array(); + $contentTitles = $hasTTContentFields ? explode(chr(10), $ttContentFields['titleText']) : array(); + $contentAlts = $hasTTContentFields ? explode(chr(10), $ttContentFields['altText']) : array(); + + // assign tt_content fields + $out[self::CHAIN_CONTENT_CAPTION] = (count($contentCaptions) > $contentElementRelationIndex) ? $contentCaptions[$contentElementRelationIndex] : ''; + $out[self::CHAIN_CONTENT_TITLE] = (count($contentTitles) > $contentElementRelationIndex) ? $contentTitles[$contentElementRelationIndex] : ''; + $out[self::CHAIN_CONTENT_ALT] = (count($contentAlts) > $contentElementRelationIndex) ? $contentAlts[$contentElementRelationIndex] : ''; + + // assign DAM meta data fields + // fields are actually coming from migrated sys_file_metadata + $out[self::CHAIN_META_ALT] = $damRelation['alternative']; + $out[self::CHAIN_META_CAPTION] = $damRelation['caption']; + $out[self::CHAIN_META_DESCRIPTION] = $damRelation['description']; + $out[self::CHAIN_META_TITLE] = $damRelation['title']; + + return $out; + } + + /** + * Parses the given chain string to an array of chain option constants. + * Prints an error message and terminates program on unknown options. + * + * @param string $chain comma-separated list of chain option names as documented (not necessarily matching constants!) + * + * @return array array of chain option constants + */ + protected function parseChain($chain) { + $parsed = array(); + + $chainSplit = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $chain); + foreach ($chainSplit as $elem) { + if (array_key_exists($elem, $this->chainOptionsMap)) { + $parsed[] = $this->chainOptionsMap[$elem]; + } else { + $this->controller->errorMessage('invalid chain option: ' . $elem); + exit(); + } + } + + return $parsed; + } + + /** + * Determines and returns the value to set according to given chain. + * + * @param array $chain chain as an array of chain option constants (use parseChain) + * @param array $chainFieldArray all content of current file reference for chain options (use compileChainFieldArray) + * + * @return mixed field value of first "non-empty" chain option or last chain option given; may be empty string (overriding FAL record data on content element), null (the opposite, not overriding central FAL record metadata) or anything else $chainFieldArray may have yielded + */ + protected function applyChain($chain, $chainFieldArray) { + $out = null; + + // replace $out by all specified fields in order + foreach ($chain as $chainOption) { + $out = $chainFieldArray[$chainOption]; + + // we stop on first "non-empty" (not null) field + // NOTE: empty($s) is false for strings consisting only of + // white-space. This appears to be what TYPO3 checks for FE + // rendering, it does not appear to check empty(trim($s)). + if (!empty($out)) { + break; + } + } + + return $out; + } + + /** + * Sets the chain used to determine image caption content. See documentation + * on what values are supported and why they should be set. + * May terminate program on invalid input. + * + * @param string $chainImageCaption options by documented names (not class constants), separated by commas + * + * @return \TYPO3\CMS\DamFalmigration\Service\MigrateRelationsService for chaining + */ + public function setChainImageCaption($chainImageCaption) { + $this->chainImageCaption = $this->parseChain($chainImageCaption); + + if (count($this->chainImageCaption) === 0) { + $this->controller->errorMessage('image caption chain cannot be empty'); + exit; + } + + return $this; + } + + /** + * Sets the chain used to determine image title content. See documentation + * on what values are supported and why they should be set. + * May terminate program on invalid input. + * + * @param string $chainImageTitle options by documented names (not class constants), separated by commas + * + * @return \TYPO3\CMS\DamFalmigration\Service\MigrateRelationsService for chaining + */ + public function setChainImageTitle($chainImageTitle) { + $this->chainImageTitle = $this->parseChain($chainImageTitle); + + if (count($this->chainImageTitle) === 0) { + $this->controller->errorMessage('image title chain cannot be empty'); + exit; + } + + return $this; + } + + /** + * Sets the chain used to determine image alternative text content. See + * documentation on what values are supported and why they should be set. + * May terminate program on invalid input. + * + * @param string $chainImageAlt options by documented names (not class constants), separated by commas + * + * @return \TYPO3\CMS\DamFalmigration\Service\MigrateRelationsService for chaining + */ + public function setChainImageAlt($chainImageAlt) { + $this->chainImageAlt = $this->parseChain($chainImageAlt); + + if (count($this->chainImageAlt) === 0) { + $this->controller->errorMessage('image alt text chain cannot be empty'); + exit; + } + + return $this; + } + + /* * Sets the layout ID to update "uploads" content elements with upon migration. * @param mixed $uploadsLayout layout ID to set, NULL or 'null' to disable * @return $this to allow for chaining @@ -340,7 +555,5 @@ public function setUploadsLayout($uploadsLayout) { } else { $this->uploadsLayout = (int)$uploadsLayout; } - - return $this; } } diff --git a/Documentation/CommandReference/Index.rst b/Documentation/CommandReference/Index.rst index 1afe93a..82362eb 100644 --- a/Documentation/CommandReference/Index.rst +++ b/Documentation/CommandReference/Index.rst @@ -252,6 +252,44 @@ dam_falmigration:dammigration:migraterelations Migrate relations to dam records that dam_ttcontent and dam_uploads introduced. +The way image captions, title and alt attributes apply varies wildly across +TYPO3 installations, mainly depending on whether you used the static +include that came with dam_ttcontent and how you configured it. Please +read the documentation of :ref:`Chain Options` for more information. To support all +configurations, you can specify a chain for each image caption, title and +alt text which defines the priority of each field. Each chain consists +of one or more of the following options, separated by commas, earliest +non-empty field takes precedence over later ones: + ++---------------------+-------------------------------------------------------+ +| ``contentTitle`` | title line from content element | ++---------------------+-------------------------------------------------------+ +| ``contentAlt`` | alt text line from content element | ++---------------------+-------------------------------------------------------+ +| ``contentCaption`` | caption text line from content element | ++---------------------+-------------------------------------------------------+ +| ``metaTitle`` | title from DAM meta data | ++---------------------+-------------------------------------------------------+ +| ``metaAlt`` | alt text from DAM meta data | ++---------------------+-------------------------------------------------------+ +| ``metaCaption`` | caption text from DAM meta data | ++---------------------+-------------------------------------------------------+ +| ``metaDescription`` | description from DAM meta data | ++---------------------+-------------------------------------------------------+ +| ``empty`` | ends chain with an empty string if nothing applied | +| | (overriding FAL metadata with no output) | ++---------------------+-------------------------------------------------------+ +| ``default`` | ends chain without overriding FAL metadata if nothing | +| | applied (using central FAL metadata without copy) | ++---------------------+-------------------------------------------------------+ + +meta options cause DAM/FAL meta data to be copied to the content element, +so they override values entered later on central FAL record. Thus they +freeze input to the state at the time of migration, so later edits of +central metadata won't have any effect on migrated content element +references. Omit meta options and instead add default to the end of your +chain if you want FAL edits to have an effect on migrated content. + It is highly recommended to update the ref index afterwards. @@ -261,6 +299,12 @@ Options ``--tablename`` The tablename to migrate relations for +``--image-caption`` + Chain of fields to determine image captions. (Default: `metaDescription,default`) +``--image-title`` + Chain of fields to determine image title. (Default: `contentCaption,metaTitle,empty`) +``--image-alt`` + Chain of fields to determine image alt texts. (Default: `metaAlt,empty`) ``--uploads-layout`` The layout ID to set on migrated CType uploads ("file links") content elements. 1 shows file type icons (like dam_filelinks did), 2 shows a thumbnail preview instead, 0 shows nothing but link & caption. Set to 'null' if no action should be taken. Default: 1 diff --git a/Documentation/UserManual/Index.rst b/Documentation/UserManual/Index.rst index ac4a1aa..3364a27 100644 --- a/Documentation/UserManual/Index.rst +++ b/Documentation/UserManual/Index.rst @@ -81,4 +81,4 @@ The available migration tasks can be found under the *extbase* cliKey: Please see the :ref:`Command Reference` for an explanation of the commands. -In general you will want to execute the commands 'migratedamrecords' and 'migratedammetadata' first, then migrate any links using 'migratelinks'. After that you may wish to migrate the tx_dam_mm_ref table to sys_file_reference by running the 'migraterelations' command. +In general you will want to execute the commands 'migratedamrecords' and 'migratedammetadata' first, then migrate any links using 'migratelinks'. After that you may wish to migrate the tx_dam_mm_ref table to sys_file_reference by running the 'migraterelations' command which will, among others, migrate images and files linked into content elements. Unfortunately, the way images were handled with DAM wasn't uniform, so you may need to figure out the correct field order to pass to 'migraterelations' via additional parameters, see :ref:`Command Reference` and :ref:`Chain Options` for details. diff --git a/Documentation/UserManual/MigrateRelationsChainOptions.rst b/Documentation/UserManual/MigrateRelationsChainOptions.rst new file mode 100644 index 0000000..d190d54 --- /dev/null +++ b/Documentation/UserManual/MigrateRelationsChainOptions.rst @@ -0,0 +1,256 @@ +.. ================================================== +.. FOR YOUR INFORMATION +.. -------------------------------------------------- +.. -*- coding: utf-8 -*- with BOM. Check: ÄÖÜäöüß + +.. include:: ../Includes.txt + +.. _Chain Options: + +Chain options for use with migraterelations command +=================================================== + +Why is this needed, what does it do? +------------------------------------ + +Unfortunately, the way image captions, title attributes and alt texts are +rendered on frontend varied wildly with DAM and thus depends on the exact +setup of each individual TYPO3 installation. Basically, you had two options +where to enter data with DAM; either in the content element displaying your +image or on central DAM metadata. The latter option allowed you to change +e.g. the image caption right on the file and it would have updated on all +content elements referencing that image upon clearing the cache. However, +whether this was possible or not depended on your template setup, specifically +``tt_content.image.20``, so your website may or may not have used either central +meta data or texts entered on content elements. If you didn't change image +rendering via your own TypoScript code, the way images were displayed will +mainly depend on whether you added the static include for dam_ttcontent or if +you omitted it. + +With FAL (by default) you will get a clean simple logic: If your content element +defines its own texts for caption/description, title or alt text that "override +value" will be used. Otherwise, central metadata will be used. If don't want to +show either, you can check the "override" option for each text field on your +content element and simply leave the text box empty. + +When running ``migraterelations`` command, all image texts entered on content +elements will be migrated to the new "override" fields. As those override fields +will determine what's actually rendered on frontend, you have to provide the +priority of fields to be used for your image texts and whether you want FAL +metadata copied (frozen at the time of migration), be used centrally (disabling +"override" option) or not used at all (enabling "override" option with an empty +text field). As this defines how fields are being linked together, we call this +a chain. A different chain can be entered for caption, title and alt text. If +you don't provide the correct chains, your images will still be migrated but +they may show up with wrong or missing captions, titles and alt texts. + + +Special considerations +---------------------- + +`migratedammetadata` must have been run before `migraterelations`, otherwise +metadata may be missing (database is queried for migrated FAL, not original +DAM fields). + +With the introduction of FAL, TYPO3 renamed the caption field to description. +DAM provided both a caption and a description field. When migrating from DAM to +FAL using this extension, the DAM description field will be mapped to FAL +description. DAM caption will be mapped to ``filemetadata``'s additional +caption field in FAL - which will not be used for frontend rendering by default, +so you may want to check and maybe modify ``tt_content.image`` to use the +correct data when using FAL metadata fallback (``default`` chain option below). + +If you have used multiple templates for the same TYPO3 installation or switched +``tt_content.image`` rendering depending on conditions - you would have to find +a compromise as (at the time of writing) you can only migrate with one generic +set of chains and not per page ID. + + +Chain options +------------- + +Options are given by optional parameters ``--image-caption``, ``--image-title`` +and ``--image-alt`` when running ``migraterelations``. Each option/field you +entered will be checked for being empty (strings containing white-space are not +considered empty). If it is not empty, it will be used for the "override" text +field on the migrated content element. Multiple options can be given separated +by commas. If an option yielded an empty result, the next option will be +checked. If all checked fields were empty, the last option's value will be used, +allowing you to decide with ``empty`` or ``default`` whether to use central FAL +metadata. + +Fields from content elements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``contentTitle``, ``contentAlt`` and ``contentCaption`` can be specified to +use the individual field of the content element a file was previously used in. +Use these options if, using DAM, texts entered on the content element were +printed on frontend. + +Fields from central DAM metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``metaTitle``, ``metaAlt``, ``metaDescription`` and ``metaCaption`` can be +specified to use the individual field from central DAM metadata. Use these +options if, using DAM, texts entered on file properties were printed on +frontend. + +Note that using these options will statically copy the field's value to the +"override" fields of your content element, thus freezing it to what your metadata +contained while running the migration - they will not be updated automatically +when editing the central FAL metadata! + +Fallback options (use at end of chain) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When no fields matched, you may want to specify whether central FAL metadata +shall be used (now & in future) or if you want to override FAL metadata with an +empty string instead, so no central metadata will be used. + +Adding ``empty`` to the end of your chain allows you to disable fallback to FAL +metadata by "checking the override option while leaving the text field empty" on +your content elements. + +Adding ``default`` instead will cause that "override" checkbox to be left +unchecked. What's actually shown for your content elements is being determined +by ``tt_content.image``. By default, your images will use central FAL metadata +in that case, allowing central updates to take an immediate effect on all +content elements upon clearing the cache (as was a common use-case with DAM). + + +Common setups and matching chains +--------------------------------- + +Read below orders as: "if 1. is empty, use 2." + +All options given here are derived from observed behaviour and may not match +your exact TYPO3 installation. Please always verify the migration result. +We recommend to create a backup just before performing DAM migration to +be able to quickly reset and retry migration if you notice any errors. + +with dam_ttcontent static include and styles.content.imgtext.captionEach enabled +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++----------------------+--------------------+ +| **Caption** | 1. DAM Caption | +| | 2. DAM Description | ++----------------------+--------------------+ +| **Title** | 1. DAM Title | ++----------------------+--------------------+ +| **Alternative text** | 1. DAM Alt | +| | 2. Content Alt | ++----------------------+--------------------+ + +Note that content fields were not used for title or caption. + +Options to freeze texts at time of migration:: + + --image-caption metaCaption,metaDescription,empty + --image-title metaTitle,empty + --image-alt metaAlt,contentAlt,empty + +Options to fall back to FAL metadata instead:: + + --image-caption metaCaption,default + --image-title default + --image-alt metaAlt,contentAlt,default + +with dam_ttcontent static include and styles.content.imgtext.captionEach disabled +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++----------------------+--------------------+ +| **Caption** | 1. Content Caption | ++----------------------+--------------------+ +| **Title** | 1. DAM Title | ++----------------------+--------------------+ +| **Alternative text** | 1. DAM Alt | +| | 2. Content Alt | ++----------------------+--------------------+ + +Note that content title field was not used. + +Options to freeze texts at time of migration:: + + --image-caption contentCaption,empty + --image-title metaTitle,empty + --image-alt metaAlt,contentAlt,empty + +Options to fall back to FAL metadata instead (note that we still freeze +caption as it may not match the unmigrated website otherwise and also alt text +if available at time of migration as we cannot use content alt text otherwise):: + + --image-caption contentCaption,empty + --image-title default + --image-alt metaAlt,contentAlt,default + + +TYPO3 4.5 default without dam_ttcontent static include +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++----------------------+--------------------+ +| **Caption** | 1. Content Caption | ++----------------------+--------------------+ +| **Title** | 1. Content Title | ++----------------------+--------------------+ +| **Alternative text** | 1. Content Alt | ++----------------------+--------------------+ + +Note that no DAM metadata was used, so it does not make much sense to fall back +to FAL metadata, you will instead want to set migrated file references to an +empty override field. + +Options to freeze texts at time of migration:: + + --image-caption contentCaption,empty + --image-title contentTitle,empty + --image-alt contentAlt,empty + +TYPO3 6.2 default (just for comparison) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++----------------------+------------------------+ +| **Caption** | 1. Content Description | +| | 2. FAL Description | ++----------------------+------------------------+ +| **Title** | 1. Content Title | +| | 2. FAL Title | ++----------------------+------------------------+ +| **Alternative text** | 1. Content Alt | +| | 2. FAL Alt | ++----------------------+------------------------+ + +Running migration without options (same as before introduction of configurable chains) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++----------------------+------------------------+ +| **Caption** | 1. DAM Description | ++----------------------+------------------------+ +| **Title** | 1. Content Title | +| | 2. DAM Title | ++----------------------+------------------------+ +| **Alternative text** | 1. DAM Alt | ++----------------------+------------------------+ + +This is mainly provided for backwards-compatibility so default behaviour won't +change compared to previous versions of this extension if called without +specifying chains. If you want this behaviour, you can just omit the parameters +listed below:: + + --image-caption metaDescription,default + --image-title contentCaption,metaTitle,empty + --image-alt metaAlt,empty + + +Examples +-------- + +Assuming default ``tt_content.image`` setup from CSS Styled Content static includes: + +``php typo3/cli_dispatch.phpsh extbase dammigration:migraterelations --image-caption metaCaption,default --image-title default --image-alt metaAlt,contentAlt,default`` + Image caption (new field name: "description") on content elements will be set to the DAM/FAL "caption" (not "description") field as-is at the time of running the migration. If no caption was available, "override" option will be unchecked, allowing central FAL metadata to be used (updating automatically in the future). The field used for captions from FAL metadata is "description" (not "caption"). Image title will always come from FAL (no override) while the alternative text will be copied (frozen) from DAM/FAL metadata if available at migration. If it's not available, content alt text will be copied instead. And if that's missing, FAL metadata will determine what's shown (updating automatically). + +``php typo3/cli_dispatch.phpsh extbase dammigration:migraterelations --image-caption contentCaption,empty --image-title contentTitle,empty --image-alt contentAlt,empty`` + Caption, title and alternative texts are only used from content element texts. If they are unavailable at the time of migration, central FAL metadata will be disabled by an empty "override" text field. This prevents FAL/DAM to have any effect on migrated content element file references. + +``php typo3/cli_dispatch.phpsh extbase dammigration:migraterelations --image-caption metaDescription,default --image-title contentCaption,metaTitle,empty -image-alt metaAlt,empty`` (default) + Caption will be copied from old DAM description field, freezing it to the text at time of migration. If it was missing on migration, central FAL field "description" will be used instead. Title is copied from content element caption if set, else DAM title is being copied (frozen). Empty is just provided for a clean end of chain just in case - as DAM titles were mandatory, you are unlikely to encounter any empty file title. Alternative text is copied (frozen) from DAM/FAL alternative text field.