[!!!][FEATURE] Introduce migration wizard for changed flexform fields 50/60450/24
authorJan Stockfisch <typo3@jan-stockfisch.de>
Thu, 11 Apr 2019 17:25:30 +0000 (19:25 +0200)
committerDaniel Goerz <daniel.goerz@posteo.de>
Tue, 2 Jul 2019 18:04:07 +0000 (20:04 +0200)
Rename ext:felogin's flexform fields. Add prefix `settings.` to all of
them. This is for the later extbase change to easily access the flexform
values via $this->settings in the extbase controllers.

An update wizard is provided to migrate all existing felogin plugins
which are stored in the database.

Resolves: #88129
Releases: master
Change-Id: I76158d8c73d5510fc537fcd5d5bbb376b156c1e7
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60450
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
typo3/sysext/core/Documentation/Changelog/master/Breaking-88129-RenameFeloginFlexformFields.rst [new file with mode: 0644]
typo3/sysext/felogin/Classes/Controller/FrontendLoginController.php
typo3/sysext/felogin/Classes/Updates/MigrateFeloginPlugins.php [new file with mode: 0644]
typo3/sysext/felogin/Configuration/FlexForms/Login.xml
typo3/sysext/felogin/ext_localconf.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-88129-RenameFeloginFlexformFields.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-88129-RenameFeloginFlexformFields.rst
new file mode 100644 (file)
index 0000000..8720256
--- /dev/null
@@ -0,0 +1,40 @@
+.. include:: ../../Includes.txt
+
+==================================================
+Breaking: #88129 - Renamed felogin flexform fields
+==================================================
+
+See :issue:`88129`
+
+Description
+===========
+
+In preparation to :issue:`84262` the felogin flexform field definition has been changed
+and all field names are now prefixed with `settings.`. This has been done to easily access all
+of the flexform values in the later extbase controller via :php:`$this->settings['foo']` and also in
+the fluid templates via :html:`{settings.foo}`.
+
+
+Impact
+======
+
+Any PageTsConfig that overrides felogin flexform fields will be ignored.
+
+
+Affected Installations
+======================
+
+All installations with a felogin plugin need to migrate their flexform database values.
+PageTsConfig needs to be adjusted, that overrides the flexform.
+
+
+Migration
+=========
+
+An update wizard is provided to easily update all used felogin plugins. To migrate the flexform values, execute
+`Migrate felogin plugins to use prefixed flexform keys`.
+
+All PageTsConfig that overrides felogin flexform fields e.g. :typoscript:`TCEFORM.tt_content.pi_flexform.login.sDEF.showForgotPassword.disabled = 1` needs to add the `settings.` prefix to the keys.
+Note the escaping backslash! :typoscript:`TCEFORM.tt_content.pi_flexform.login.sDEF.settings\.showForgotPassword.disabled = 1`.
+
+.. index:: FlexForm, NotScanned, ext:felogin
index 1ec3fc4..490ae83 100644 (file)
@@ -910,7 +910,7 @@ class FrontendLoginController extends AbstractPlugin
      */
     protected function flexFormValue($var, $sheet)
     {
-        return $this->pi_getFFvalue($this->cObj->data['pi_flexform'], $var, $sheet);
+        return $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'settings.' . $var, $sheet);
     }
 
     /**
diff --git a/typo3/sysext/felogin/Classes/Updates/MigrateFeloginPlugins.php b/typo3/sysext/felogin/Classes/Updates/MigrateFeloginPlugins.php
new file mode 100644 (file)
index 0000000..c9d1310
--- /dev/null
@@ -0,0 +1,205 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Felogin\Updates;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
+use TYPO3\CMS\Core\Database\Query\QueryBuilder;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
+use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
+
+/**
+ * Class MigrateFeloginPlugins
+ * @internal
+ */
+class MigrateFeloginPlugins implements UpgradeWizardInterface
+{
+    /**
+     * @var array Flexform fields which we are interested in updating
+     */
+    protected static $flexFormFields = [
+        'showForgotPassword',
+        'showPermaLogin',
+        'showLogoutFormAfterLogin',
+        'pages',
+        'recursive',
+        'redirectMode',
+        'redirectFirstMethod',
+        'redirectPageLogin',
+        'redirectPageLoginError',
+        'redirectPageLogout',
+        'redirectDisable',
+        'welcome_header',
+        'welcome_message',
+        'success_header',
+        'success_message',
+        'error_header',
+        'error_message',
+        'status_header',
+        'status_message',
+        'logout_header',
+        'logout_message',
+        'forgot_reset_message'
+    ];
+
+    /**
+     * Return the identifier for this wizard
+     * This should be the same string as used in the ext_localconf class registration
+     *
+     * @return string
+     */
+    public function getIdentifier(): string
+    {
+        return self::class;
+    }
+
+    /**
+     * Return the speaking name of this wizard
+     *
+     * @return string
+     */
+    public function getTitle(): string
+    {
+        return 'Migrate felogin plugins to use prefixed flexform keys';
+    }
+
+    /**
+     * Return the description for this wizard
+     *
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return 'This wizard migrates existing front end plugins of the extension felogin to' .
+            ' make use of the streamlined flexform keys. Therefore it updates the field values' .
+            ' "pi_flexform" within the tt_content table';
+    }
+
+    /**
+     * Execute the update
+     *
+     * Called when a wizard reports that an update is necessary
+     *
+     * @return bool
+     */
+    public function executeUpdate(): bool
+    {
+        // Get all tt_content data for login plugins and update their flexforms settings
+        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
+
+        /** @var QueryBuilder $queryBuilder */
+        $queryBuilder = $connection->createQueryBuilder();
+        $statement = $queryBuilder->select('uid')
+            ->addSelect('pi_flexform')
+            ->from('tt_content')
+            ->where(
+                $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('login'))
+            )
+            ->execute();
+
+        // Update the found record sets
+        while ($record = $statement->fetch()) {
+            $queryBuilder = $connection->createQueryBuilder();
+            $updateResult = $queryBuilder->update('tt_content')
+                ->where(
+                    $queryBuilder->expr()->eq(
+                        'uid',
+                        $queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
+                    )
+                )
+                ->set('pi_flexform', $this->migrateFlexformSettings($record['pi_flexform']))
+                ->execute();
+
+            //exit if at least one update statement is not successful
+            if (!((bool)$updateResult)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Is an update necessary?
+     *
+     * Looks for fe plugins in tt_content table to be migrated
+     *
+     * @return bool
+     */
+    public function updateNecessary(): bool
+    {
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+            ->getConnectionForTable('tt_content')
+            ->createQueryBuilder();
+
+        $queryBuilder->select('pi_flexform')
+            ->from('tt_content')
+            ->where(
+                $queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('login')),
+                $this->getFlexformConstraints($queryBuilder)
+            );
+
+        return (bool)$queryBuilder->execute()->fetchColumn();
+    }
+
+    /**
+     * Returns an array of class names of Prerequisite classes
+     *
+     * This way a wizard can define dependencies like "database up-to-date" or
+     * "reference index updated"
+     *
+     * @return string[]
+     */
+    public function getPrerequisites(): array
+    {
+        return [
+            DatabaseUpdatedPrerequisite::class
+        ];
+    }
+
+    /**
+     * @param string $oldValue
+     * @return string
+     */
+    protected function migrateFlexformSettings(string $oldValue): string
+    {
+        $fieldNames = implode('|', static::$flexFormFields);
+        $pattern = '/<field index="(' . $fieldNames . ')">/';
+        $replacement = '<field index="settings.$1">';
+
+        return preg_replace($pattern, $replacement, $oldValue);
+    }
+
+    /**
+     * Creates a "like" statement for every flexform fields
+     *
+     * @param QueryBuilder $queryBuilder
+     * @return CompositeExpression
+     */
+    protected function getFlexformConstraints(QueryBuilder $queryBuilder): CompositeExpression
+    {
+        $constraints = [];
+
+        foreach (static::$flexFormFields as $flexFormField) {
+            $value = '%<field index="' . $flexFormField . '">%';
+            $constraints[] = $queryBuilder->expr()->like('pi_flexform', $queryBuilder->createNamedParameter($value));
+        }
+
+        return $queryBuilder->expr()->orX(...$constraints);
+    }
+}
index 4fa2b6b..7a50da5 100644 (file)
@@ -7,7 +7,7 @@
                                </TCEforms>
                                <type>array</type>
                                <el>
-                                       <showForgotPassword>
+                                       <settings.showForgotPassword>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.show_forgot_password</label>
                                                        <config>
@@ -20,8 +20,8 @@
                                                                </items>
                                                        </config>
                                                </TCEforms>
-                                       </showForgotPassword>
-                                       <showPermaLogin>
+                                       </settings.showForgotPassword>
+                                       <settings.showPermaLogin>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.show_permalogin</label>
                                                        <config>
@@ -35,8 +35,8 @@
                                                                </items>
                                                        </config>
                                                </TCEforms>
-                                       </showPermaLogin>
-                                       <showLogoutFormAfterLogin>
+                                       </settings.showPermaLogin>
+                                       <settings.showLogoutFormAfterLogin>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.show_logoutFormAfterLogin</label>
                                                        <config>
@@ -50,8 +50,8 @@
                                                                </items>
                                                        </config>
                                                </TCEforms>
-                                       </showLogoutFormAfterLogin>
-                                       <pages>
+                                       </settings.showLogoutFormAfterLogin>
+                                       <settings.pages>
                                                <TCEforms>
                                                        <exclude>1</exclude>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.user_storage</label>
@@ -64,9 +64,9 @@
                                                                <minitems>0</minitems>
                                                        </config>
                                                </TCEforms>
-                                       </pages>
+                                       </settings.pages>
 
-                                       <recursive>
+                                       <settings.recursive>
                                                <TCEforms>
                                                        <label>LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.recursive</label>
                                                        <config>
                                                                <size>1</size>
                                                        </config>
                                                </TCEforms>
-                                       </recursive>
+                                       </settings.recursive>
                                </el>
                        </ROOT>
                </sDEF>
                                </TCEforms>
                                <type>array</type>
                                <el>
-                                       <redirectMode>
+                                       <settings.redirectMode>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectMode</label>
                                                        <config>
                                                                <maxitems>8</maxitems>
                                                        </config>
                                                </TCEforms>
-                                       </redirectMode>
-                                       <redirectFirstMethod>
+                                       </settings.redirectMode>
+                                       <settings.redirectFirstMethod>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectFirstMethod</label>
                                                        <config>
                                                                </items>
                                                        </config>
                                                </TCEforms>
-                                       </redirectFirstMethod>
-                                       <redirectPageLogin>
+                                       </settings.redirectFirstMethod>
+                                       <settings.redirectPageLogin>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectPageLogin</label>
                                                        <config>
                                                                <minitems>0</minitems>
                                                        </config>
                                                </TCEforms>
-                                       </redirectPageLogin>
-                                       <redirectPageLoginError>
+                                       </settings.redirectPageLogin>
+                                       <settings.redirectPageLoginError>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectPageLoginError</label>
                                                        <config>
                                                                <minitems>0</minitems>
                                                        </config>
                                                </TCEforms>
-                                       </redirectPageLoginError>
-                                       <redirectPageLogout>
+                                       </settings.redirectPageLoginError>
+                                       <settings.redirectPageLogout>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectPageLogout</label>
                                                        <config>
                                                                <minitems>0</minitems>
                                                        </config>
                                                </TCEforms>
-                                       </redirectPageLogout>
-                                       <redirectDisable>
+                                       </settings.redirectPageLogout>
+                                       <settings.redirectDisable>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.redirectDisable</label>
                                                        <config>
                                                                </items>
                                                        </config>
                                                </TCEforms>
-                                       </redirectDisable>
+                                       </settings.redirectDisable>
                                </el>
                        </ROOT>
                </s_redirect>
                                </TCEforms>
                                <type>array</type>
                                <el>
-                                       <welcome_header>
+                                       <settings.welcome_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.welcome_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </welcome_header>
-                                       <welcome_message>
+                                       </settings.welcome_header>
+                                       <settings.welcome_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.welcome_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </welcome_message>
-                                       <success_header>
+                                       </settings.welcome_message>
+                                       <settings.success_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.success_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </success_header>
-                                       <success_message>
+                                       </settings.success_header>
+                                       <settings.success_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.success_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </success_message>
-                                       <error_header>
+                                       </settings.success_message>
+                                       <settings.error_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.error_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </error_header>
-                                       <error_message>
+                                       </settings.error_header>
+                                       <settings.error_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.error_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </error_message>
-                                       <status_header>
+                                       </settings.error_message>
+                                       <settings.status_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.status_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </status_header>
-                                       <status_message>
+                                       </settings.status_header>
+                                       <settings.status_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.status_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </status_message>
-                                       <logout_header>
+                                       </settings.status_message>
+                                       <settings.logout_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.logout_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </logout_header>
-                                       <logout_message>
+                                       </settings.logout_header>
+                                       <settings.logout_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.logout_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </logout_message>
-                                       <forgot_header>
+                                       </settings.logout_message>
+                                       <settings.forgot_header>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.forgot_header</label>
                                                        <config>
                                                                <size>30</size>
                                                        </config>
                                                </TCEforms>
-                                       </forgot_header>
-                                       <forgot_reset_message>
+                                       </settings.forgot_header>
+                                       <settings.forgot_reset_message>
                                                <TCEforms>
                                                        <label>LLL:EXT:felogin/Resources/Private/Language/Database.xlf:tt_content.pi_flexform.forgot_message</label>
                                                        <config>
                                                                <rows>5</rows>
                                                        </config>
                                                </TCEforms>
-                                       </forgot_reset_message>
+                                       </settings.forgot_reset_message>
                                </el>
                        </ROOT>
                </s_messages>
index 0cebdb5..773ce26 100644 (file)
@@ -16,3 +16,7 @@ defined('TYPO3_MODE') or die();
 
 // Page module hook
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['felogin'] = \TYPO3\CMS\Felogin\Hooks\CmsLayout::class;
+
+// Add migration wizard
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\TYPO3\CMS\Felogin\Updates\MigrateFeloginPlugins::class]
+    = \TYPO3\CMS\Felogin\Updates\MigrateFeloginPlugins::class;