[TASK] Introduce Hooks to create DB fields and keys dynamically
authorThomas Maroschik <tmaroschik@dfau.de>
Fri, 9 Sep 2011 09:56:34 +0000 (11:56 +0200)
committerXavier Perseguers <xavier@typo3.org>
Fri, 7 Oct 2011 13:25:31 +0000 (15:25 +0200)
For the purpose of modifying the database schema upon extension
installation and database compare in install tool I implemented hooks
to append sql create statements dynamically.

Hooks are registered via:

$TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']
['checkDBupdates'] for changes in the extension manager and has to
implement tx_em_Index_CheckDatabaseUpdatesHook interface

$TYPO3_CONF_VARS['SC_OPTIONS']['ext/install/mod/class.tx_install.php']
['checkTheDatabase'] for changes in the install tool and has to
implement tx_em_Index_CheckDatabaseUpdatesHook interface

Change-Id: I66ff195ae8f656961f5251d7722a16a554aca219
Resolves: #29594
Releases: 4.6
Reviewed-on: http://review.typo3.org/4870
Reviewed-by: Fabien Udriot
Tested-by: Fabien Udriot
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
typo3/sysext/em/classes/install/class.tx_em_install.php
typo3/sysext/em/interfaces/interface.tx_em_index_checkdatabaseupdateshook.php
typo3/sysext/install/Classes/Interfaces/CheckTheDatabaseHook.php [new file with mode: 0644]
typo3/sysext/install/ext_autoload.php
typo3/sysext/install/mod/class.tx_install.php

index 0ce4be6..d2a50ba 100644 (file)
@@ -820,6 +820,18 @@ class tx_em_Install {
 
                $dbStatus = array();
                $content = '';
+               $hookObjects = array();
+
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/mod/tools/em/index.php']['checkDBupdates'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/mod/tools/em/index.php']['checkDBupdates'] as $classData) {
+                               /** @var $hookObject tx_em_Index_CheckDatabaseUpdatesHook **/
+                               $hookObject = t3lib_div::getUserObj($classData);
+                               if (!($hookObject instanceof tx_em_Index_CheckDatabaseUpdatesHook)) {
+                                       throw new UnexpectedValueException('$hookObject must implement interface em_index_checkDatabaseUpdatesHook', 1288418476);
+                               }
+                               $hookObjects[] = $hookObject;
+                       }
+               }
 
                // Updating tables and fields?
                $showUpdateStatements = TRUE;
@@ -832,6 +844,14 @@ class tx_em_Install {
                        if ($showCachingTables) {
                                $fileContent .= t3lib_cache::getDatabaseTableDefinitions();
                        }
+                       foreach ($hookObjects as $hookObject) {
+                               /** @var $hookObject tx_em_Index_CheckDatabaseUpdatesHook **/
+                               $appendableTableDefinitions = $hookObject->appendTableDefinitions($extKey, $extInfo, $fileContent, $this->install, $this->installerSql, $this);
+                               if ($appendableTableDefinitions) {
+                                       $fileContent .= $appendableTableDefinitions;
+                                       break;
+                               }
+                       }
 
                        $FDfile = $this->installerSql->getFieldDefinitions_fileContent($fileContent);
                        if (count($FDfile)) {
@@ -848,21 +868,17 @@ class tx_em_Install {
                                        $this->installerSql->performUpdateQueries($update_statements['change'], $this->install->INSTALL['database_update']);
                                        $this->installerSql->performUpdateQueries($update_statements['create_table'], $this->install->INSTALL['database_update']);
                                } else {
-                                       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/mod/tools/em/index.php']['checkDBupdates'])) {
-                                               foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/mod/tools/em/index.php']['checkDBupdates'] as $classData) {
-                                                       $hookObject = t3lib_div::getUserObj($classData);
-
-                                                       if (!($hookObject instanceof tx_em_Index_CheckDatabaseUpdatesHook)) {
-                                                               throw new UnexpectedValueException('$hookObject must implement interface tx_em_Index_CheckDatabaseUpdatesHook', 1288418476);
-                                                       }
-
-                                                       /* @var $hookObject tx_em_Index_CheckDatabaseUpdatesHook */
-                                                       $preprocessContent = $hookObject->preProcessDatabaseUpdates($extKey, $extInfo, $diff, $this->install, $this);
-                                                       if ($preprocessContent) {
-                                                               $content .= $preprocessContent;
-                                                               $showUpdateStatements = FALSE;
-                                                               break;
-                                                       }
+                                       foreach ($hookObjects as $hookObject) {
+                                               /** @var $hookObject tx_em_Index_CheckDatabaseUpdatesHook **/
+                                                       // Hook that allows pre-processing of database structure modifications.
+                                                       // The hook implementation may return a user form that will temporarily
+                                                       // replace the standard database update form. This allows additional
+                                                       // operations to be performed before the database structure gets updated.
+                                               $preprocessContent = $hookObject->preProcessDatabaseUpdates($extKey, $extInfo, $diff, $this->install, $this);
+                                               if ($preprocessContent) {
+                                                       $content .= $preprocessContent;
+                                                       $showUpdateStatements = FALSE;
+                                                       break;
                                                }
                                        }
                                        if ($showUpdateStatements) {
index c98d5fe..75ea733 100644 (file)
  * Interface for hook in tx_em_Install::checkDBupdates.
  *
  * @author Xavier Perseguers <xavier@typo3.org>
+ * @author Thomas Maroschik <tmaroschik@dfau.de>
  * @package TYPO3
  * @subpackage em
  */
 interface tx_em_Index_CheckDatabaseUpdatesHook {
 
        /**
+        * Hook that allows to dynamically extend the table definitions for e.g. custom caches.
+        * The hook implementation may return table create strings that will be respected by
+        * the extension manager during installation of an extension.
+        *
+        * @param string $extKey: Extension key
+        * @param array $extInfo: Extension information array
+        * @param string $fileContent: Content of the current extension sql file
+        * @param t3lib_install $instObj: Instance of the installer
+        * @param t3lib_install_Sql $instSqlObj: Instance of the installer sql object
+        * @param tx_em_Install $parent: The calling parent object
+        * @return string Either empty string or table create strings
+        */
+       public function appendTableDefinitions($extKey, array $extInfo, $fileContent, t3lib_install $instObj, t3lib_install_Sql $instSqlObj, tx_em_Install $parent);
+
+       /**
         * Hook that allows pre-processing of database structure modifications.
         * The hook implementation may return a user form that will temporarily
         * replace the standard database update form. This allows additional
diff --git a/typo3/sysext/install/Classes/Interfaces/CheckTheDatabaseHook.php b/typo3/sysext/install/Classes/Interfaces/CheckTheDatabaseHook.php
new file mode 100644 (file)
index 0000000..842fca0
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2011 Thomas Maroschik <tmaroschik@dfau.de>
+*  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 2 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.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  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!
+***************************************************************/
+
+/**
+ * Interface for hook in tx_install::checkTheDatabase
+ *
+ * @author Thomas Maroschik <tmaroschik@dfau.de>
+ * @package TYPO3
+ * @subpackage install
+ */
+interface Tx_Install_Interfaces_CheckTheDatabaseHook {
+
+       /**
+        * Hook that allows to dynamically extend the table definitions on a per extension base
+        * for e.g. custom caches. The hook implementation may return table create strings that
+        * will be respected by the install tool.
+        *
+        * @param string $extKey: Extension key
+        * @param array $loadedExtConf: The extension's configuration from $GLOBALS['TYPO3_LOADED_EXT']
+        * @param string $extensionSqlContent: The content of the extensions ext_tables.sql
+        * @param t3lib_install_Sql $instSqlObj: Instance of the installer sql object
+        * @param tx_em_Install $parent: The calling parent object
+        * @return string Either empty string or table create strings
+        */
+       public function appendExtensionTableDefinitions($extKey, array $loadedExtConf, $extensionSqlContent, t3lib_install_Sql $instSqlObj, tx_install $parent);
+
+       /**
+        * Hook that allows to dynamically extend the table definitions for the whole system
+        * for e.g. custom caches. The hook implementation may return table create strings that
+        * will be respected by the install tool.
+        *
+        * @param string $allSqlContent: The content of all relevant sql files
+        * @param t3lib_install_Sql $instSqlObj: Instance of the installer sql object
+        * @param tx_em_Install $parent: The calling parent object
+        * @return string Either empty string or table create strings
+        */
+       public function appendGlobalTableDefinitions($allSqlContent, t3lib_install_Sql $instSqlObj, tx_install $parent);
+
+}
+
+?>
\ No newline at end of file
index a1d0f38..c76b6cc 100644 (file)
@@ -7,7 +7,8 @@ $extPath = t3lib_extMgm::extPath('install');
 return array(
        'tx_install_report_installstatus' => $extPath . 'report/class.tx_install_report_installstatus.php',
        'tx_install_service_basicservice' => $extPath . 'Classes/Service/BasicService.php',
-       'tx_install_updates_base' => $extPath . 'Classes/Updates/Base.php'
+       'tx_install_updates_base' => $extPath . 'Classes/Updates/Base.php',
+       'tx_install_interfaces_checkthedatabasehook' => $extPath . 'Classes/Interfaces/CheckTheDatabaseHook.php'
 );
 
 ?>
\ No newline at end of file
index 3a756ff..3784a32 100644 (file)
@@ -5518,17 +5518,53 @@ REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndp
                        switch($actionParts[0]) {
                                case 'cmpFile':
                                        $tblFileContent='';
+                                       $hookObjects = array();
+
+                                       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['checkTheDatabase'])) {
+                                               foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['checkTheDatabase'] as $classData) {
+                                                       /** @var $hookObject Tx_Install_Interfaces_CheckTheDatabaseHook **/
+                                                       $hookObject = t3lib_div::getUserObj($classData);
+
+                                                       if (!($hookObject instanceof Tx_Install_Interfaces_CheckTheDatabaseHook)) {
+                                                               throw new UnexpectedValueException('$hookObject must implement interface Tx_Install_Interfaces_CheckTheDatabaseHook', 1315554770);
+                                                       }
+
+                                                       $hookObjects[] = $hookObject;
+                                               }
+                                       }
+
                                        if (!strcmp($actionParts[1],'CURRENT_TABLES')) {
                                                $tblFileContent = t3lib_div::getUrl(PATH_t3lib.'stddb/tables.sql');
 
-                                               foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $loadedExtConf) {
+                                               foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $extKey => $loadedExtConf) {
                                                        if (is_array($loadedExtConf) && $loadedExtConf['ext_tables.sql']) {
-                                                               $tblFileContent .= LF . LF . LF . LF . t3lib_div::getUrl($loadedExtConf['ext_tables.sql']);
+                                                               $extensionSqlContent = t3lib_div::getUrl($loadedExtConf['ext_tables.sql']);
+                                                               $tblFileContent .= LF . LF . LF . LF . $extensionSqlContent;
+
+                                                               foreach ($hookObjects as $hookObject) {
+                                                                       /** @var $hookObject Tx_Install_Interfaces_CheckTheDatabaseHook **/
+                                                                       $appendableTableDefinitions = $hookObject->appendExtensionTableDefinitions($extKey, $loadedExtConf, $extensionSqlContent, $this->sqlHandler, $this);
+                                                                       if ($appendableTableDefinitions) {
+                                                                               $tblFileContent .= $appendableTableDefinitions;
+                                                                               break;
+                                                                       }
+                                                               }
                                                        }
                                                }
+
                                        } elseif (@is_file($actionParts[1])) {
                                                $tblFileContent = t3lib_div::getUrl($actionParts[1]);
                                        }
+
+
+                                       foreach ($hookObjects as $hookObject) {
+                                               /** @var $hookObject Tx_Install_Interfaces_CheckTheDatabaseHook **/
+                                               $appendableTableDefinitions = $hookObject->appendGlobalTableDefinitions($tblFileContent, $this->sqlHandler,  $this);
+                                               if ($appendableTableDefinitions) {
+                                                       $tblFileContent .= $appendableTableDefinitions;
+                                                       break;
+                                               }
+                                       }
                                        $tblFileContent .= t3lib_cache::getDatabaseTableDefinitions();
                                        if ($tblFileContent) {
                                                $fileContent = implode(