EXT:DCE – Upgrade to FAL-based files

Die Dynamic Content Elements (DCE) speichern Datei-Felder nun auch per FAL-Relation, also via File Abstraction Layer von TYPO3. Leider gibt es hierfür keinen Upgrade-Wizard. Man kann sich aber mit ein wenig PHP-Code passende SQL-Befehle generieren, um das Upgrade der Extension durchzuführen und die eigenen Content-Elemente entsprechend anzupassen.

Schritt 1: Notwendige Daten exportieren

Zunächst werden ein paar Daten exportiert, die später per PHP in SQL-Befehle eingebaut werden.
Für jedes definierte DCE werden die UID des Content-Elements sowie (aus dem pi_flexform-Feld) das DCE-Feld mit der Datei abgefragt.

Für das DCE_Element mit UID=2 (CType: dce_dceuid2) würde die Abfrage exemplarisch wie folgt aussehen:

SELECT ExtractValue(pi_flexform, '//field[@index="settings.image"]/value') as filename, `uid`
FROM `tt_content`
WHERE CType='dce_dceuid2' AND ExtractValue(pi_flexform, '//field[@index="settings.image"]/value')!='';

Das Ergebnis wird für die spätere Verarbeitung als CSV exportiert.

Schritt 2: Erstellen bzw. Aktualisieren der Datenbank

Nun geht es daran verschiedene Änderungen in der Datenbank vorzunehmen:

  1. Erstellen der FAL-Relationen
  2. Aktualisierung des Datei-Felde-Inhaltes im pi_flexform-Feld der einzelnen Content-Elemente
  3. Update der Struktur des alten DCE Content-Element-Typs

Für diese Schritte habe ich keinen Upgrade-Wizard geschrieben, sondern eine PHP-funktion, die die nötigen SQL-Queries ausgibt.

function process(string $csv, string $CType, string $fieldName = 'image'): void
{
    foreach (explode(chr(10), $csv) as $line) {
        [$fileName, $uid] = explode(';', $line);
        if ($fileName && $fileName !== '""') {
            $uid = trim($uid);
            echo htmlentities("INSERT INTO sys_file_reference (uid_local, uid_foreign, tablenames, fieldname, table_local) VALUES((SELECT uid FROM sys_file WHERE identifier=\"/_migrated_/pics/" . $fileName . "\"), $uid, 'tt_content', '" . $fieldName . "', 'sys_file');",
                    ENT_QUOTES | ENT_HTML5) . chr(10);
        }
    }
    echo htmlentities('UPDATE tt_content SET pi_flexform=UpdateXML(`pi_flexform`, \'//field[@index="settings.' . $fieldName . '"]/value\', \'<value index=\"vDEF\">1</value>\') WHERE uid=437 AND CType=\'' . $CType . '\' AND ExtractValue(pi_flexform, \'//field[@index="settings.' . $fieldName . '"]/value\')!=\'\';',
            ENT_QUOTES | ENT_HTML5) . chr(10);

    $configuration = '<config>
        <type>inline</type>
        <foreign_table>sys_file_reference</foreign_table>
        <foreign_field>uid_foreign</foreign_field>
        <foreign_sortby>sorting_foreign</foreign_sortby>
        <foreign_table_field>tablenames</foreign_table_field>
        <foreign_match_fields>
            <fieldname>{$variable}</fieldname>
        </foreign_match_fields>
        <foreign_label>uid_local</foreign_label>
        <foreign_selector>uid_local</foreign_selector>
        <overrideChildTca>
            <columns>
                <uid_local>
                    <config>
                        <appearance>
                            <elementBrowserType>file</elementBrowserType>
                            <elementBrowserAllowed>gif,jpg,jpeg,png</elementBrowserAllowed>
                        </appearance>
                    </config>
                </uid_local>
            </columns>
            <types type="array">
                <numIndex index="2">
                    <showitem>--palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,--palette--;;filePalette</showitem>
                </numIndex>
            </types>
        </overrideChildTca>

        <minitems>0</minitems>
        <maxitems>1</maxitems>

        <appearance>
            <useSortable>1</useSortable>
            <headerThumbnail>
                <field>uid_local</field>
                <width>45c</width>
                <height>45</height>
            </headerThumbnail>

            <enabledControls>
                <info>1</info>
                <dragdrop>1</dragdrop>
                <hide>1</hide>
                <new>0</new>
                <sort>0</sort>
                <delete>1</delete>
            </enabledControls>

            <createNewRelationLinkTitle>LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference</createNewRelationLinkTitle>
        </appearance>

        <behaviour>
            <allowLanguageSynchronization>1</allowLanguageSynchronization>
        </behaviour>

        <dce_load_schema>1</dce_load_schema>
        <dce_get_fal_objects>1</dce_get_fal_objects>
    </config>
    ';
    echo 'UPDATE tx_dce_domain_model_dcefield SET configuration=\'' . htmlentities($configuration, ENT_QUOTES | ENT_HTML5) . '\' WHERE variable=\'' . $fieldName . '\' AND parent_dce=' . str_replace('dce_dceuid', '', $CType) . ';' . chr(10);
}

Nun werden die oben exportierten Daten an die Funktion übergeben:

$csv = 'image_1.jpg;82
typo3_box.jpg;904';
process($csv, 'dce_dceuid2', 'image');

Das Ganze nimmt keine Änderung in der Datenbank vor, sondern gibt nur die notwendigen SQL-Queries aus. Diesen können nun nochmals kontrolliert werden und dann ggf. abgefeuert werden.

Schritt 3: Wiederholen für alle DCE-Typen

Jetzt die Schritte 1 + 2 für alle DCE Content-Element-Typen (bzw. weitere Datei-Felder innerhalb eines DCE-Typs) wiederholen.

(Urspünglich von mir veröffentlicht in Englisch auf StackOverflow)

Hinterlasse einen Kommentar.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.