[BUGFIX] FAL Upgrade Wizards do not set pid 30/19130/3
authorBenjamin Mack <benni@typo3.org>
Thu, 21 Mar 2013 14:46:49 +0000 (15:46 +0100)
committerBenjamin Mack <benni@typo3.org>
Sat, 23 Mar 2013 14:02:32 +0000 (15:02 +0100)
The sys_file_reference records are originally set to
be placed on rootLevel, the upgrade wizard does
exactly that.

However, the concept in this case is flawed
- When creating new sys_file_reference records via IRRE,
   the sys_file_reference is stored on the page
- When copying moving e.g. a tt_content record, all its
   child elements are placed on that new page as
   well (so this works)
- rootLevel restriction is not needed in this case

The patch does the following:
- Modify the existing upgrade wizard to place the
   sys_file_references on the pages of the foreign
   tables (tt_content pid)
- the rootLevel flag for sys_file_reference is removed
- Add a new upgrade wizard is added to ensure the
integrity of the sys-file-reference pids

Releases: 6.1, 6.0
Resolves: #46497
Change-Id: I2ee435907c6381becd29664e901b1bd8fd62174a
Reviewed-on: https://review.typo3.org/19130
Reviewed-by: Henrik Ziegenhain
Reviewed-by: Simon Schick
Reviewed-by: Michael Staatz
Tested-by: Michael Staatz
Tested-by: Henrik Ziegenhain
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
typo3/sysext/core/Configuration/TCA/sys_file_reference.php
typo3/sysext/install/Classes/Updates/ReferenceIntegrityUpdateWizard.php [new file with mode: 0644]
typo3/sysext/install/Classes/Updates/TceformsUpdateWizard.php
typo3/sysext/install/Classes/Updates/TtContentUploadsUpdateWizard.php
typo3/sysext/install/ext_localconf.php

index 5863bbc..45fcf4a 100644 (file)
@@ -8,7 +8,6 @@ return array(
                'cruser_id' => 'cruser_id',
                'type' => 'uid_local:type',
                'hideTable' => TRUE,
-               'rootLevel' => TRUE,
                'sortby' => 'sorting',
                'delete' => 'deleted',
                'versioningWS' => TRUE,
@@ -257,4 +256,4 @@ return array(
                )
        )
 );
-?>
\ No newline at end of file
+?>
diff --git a/typo3/sysext/install/Classes/Updates/ReferenceIntegrityUpdateWizard.php b/typo3/sysext/install/Classes/Updates/ReferenceIntegrityUpdateWizard.php
new file mode 100644 (file)
index 0000000..01e145c
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+namespace TYPO3\CMS\Install\Updates;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Benni Mack <benni@typo3.org>
+ *  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 3 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.
+ *
+ *  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!
+ ***************************************************************/
+/**
+ * Performs certain DB updates in order to ensure that the DB fields
+ * are set properly. Currently this is used for ensuring that there
+ * are no sys_file_reference records with PID=0 where the connected
+ * parent records (e.g. a tt_content record) are not on PID=0
+ *
+ * @author Benni Mack <benni@typo3.org>
+ * @license http://www.gnu.org/copyleft/gpl.html
+ */
+class ReferenceIntegrityUpdateWizard extends \TYPO3\CMS\Install\Updates\AbstractUpdate {
+
+       /**
+        * @var string
+        */
+       protected $title = 'Ensures the database integrity for File Abstraction records';
+
+       /**
+        * Checks if an update is needed
+        *
+        * @param       string          &$description: The description for the update
+        * @return      boolean         TRUE if an update is needed, FALSE otherwise
+        */
+       public function checkForUpdate(&$description) {
+               $description = 'Checks if there are file references that are on the root level. This could have happened due to a misconfigured previous migration.';
+               return count($this->getRequiredUpdates()) > 0;
+       }
+
+       /**
+        * Performs the database update.
+        *
+        * @param       array           &$dbQueries: queries done in this update
+        * @param       mixed           &$customMessages: custom messages
+        * @return      boolean         TRUE on success, FALSE on error
+        */
+       public function performUpdate(array &$dbQueries, &$customMessages) {
+               $updates = $this->getRequiredUpdates();
+               if (isset($updates['inproperConnectedFileReferences'])) {
+                       foreach ($updates['inproperConnectedFileReferences'] as $fileReferenceRecord) {
+                               if ($fileReferenceRecord['newpid'] > 0) {
+                                       $updateQuery = $GLOBALS['TYPO3_DB']->UPDATEquery(
+                                               'sys_file_reference',
+                                               'uid=' . intval($fileReferenceRecord['uid']),
+                                               array('pid' => $fileReferenceRecord['newpid'])
+                                       );
+                                       $GLOBALS['TYPO3_DB']->sql_query($updateQuery);
+                                       $dbQueries[] = $updateQuery;
+                               }
+                       }
+               }
+               return TRUE;
+       }
+
+       /**
+        * Determine all DB updates that need to be done
+        *
+        * @return array
+        */
+       protected function getRequiredUpdates() {
+               $requiredUpdates = array();
+               $inproperConnectedFileReferences = $this->getInproperConnectedFileReferences();
+               if (count($inproperConnectedFileReferences) > 0) {
+                       $requiredUpdates['inproperConnectedFileReferences'] = $inproperConnectedFileReferences;
+               }
+               return $requiredUpdates;
+       }
+
+       /**
+        * fetches a list of all sys_file_references that have PID=0
+        *
+        * @return mixed
+        */
+       protected function getFileReferencesOnRootlevel() {
+               return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+                       'uid, pid, uid_local AS fileuid, uid_foreign AS targetuid, tablenames AS targettable',
+                       'sys_file_reference',
+                       'pid=0 AND deleted=0'
+               );
+       }
+
+       /**
+        * fetches all sys_file_reference records that are on PID=0 BUT their counter parts (the target record)
+        * is NOT on pid=0
+        *
+        * @return array
+        */
+       protected function getInproperConnectedFileReferences() {
+               $inproperConnectedReferences = array();
+               // fetch all references on root level
+               $sysFileReferences = $this->getFileReferencesOnRootlevel();
+               foreach ($sysFileReferences as $fileReferenceRecord) {
+                       // if the target table is pages (e.g. when adding a file reference to the pages->media
+                       // record, then the
+                       $whereClause = 'uid=' . intval($fileReferenceRecord['targetuid']);
+                       if ($fileReferenceRecord['targettable'] === 'pages') {
+                               $isPageReference = TRUE;
+                       } else {
+                               $isPageReference = FALSE;
+                               $whereClause .= ' AND pid<>0';
+                       }
+                       // check the target table, if the target record is NOT on the rootlevel
+                       $targetRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+                               'uid, pid',
+                               $fileReferenceRecord['targettable'],
+                               $whereClause
+                       );
+                       // only add the file reference if the target record is not on PID=0
+                       if ($targetRecord !== NULL) {
+                               $fileReferenceRecord['newpid'] = ($isPageReference ? $targetRecord['uid'] : $targetRecord['pid']);
+                               $inproperConnectedReferences[] = $fileReferenceRecord;
+                       }
+               }
+               return $inproperConnectedReferences;
+       }
+}
+
+
+?>
\ No newline at end of file
index 42acd04..a68ca0d 100644 (file)
@@ -247,6 +247,9 @@ class TceformsUpdateWizard extends \TYPO3\CMS\Install\Updates\AbstractUpdate {
                                        // TODO add sorting/sorting_foreign
                                        'fieldname' => $fieldname,
                                        'table_local' => 'sys_file',
+                                       // the sys_file_reference record should always placed on the same page
+                                       // as the record to link to, see issue #46497
+                                       'pid' => ($table === 'pages' ? $row['uid'] : $row['pid']),
                                        'uid_foreign' => $row['uid'],
                                        'uid_local' => $file->getUid(),
                                        'tablenames' => $table,
index 8b32b9d..4c49986 100644 (file)
@@ -165,6 +165,9 @@ class TtContentUploadsUpdateWizard extends \TYPO3\CMS\Install\Updates\AbstractUp
                                        'uid_local' => $fileObject->getUid(),
                                        'tablenames' => 'tt_content',
                                        'uid_foreign' => $record['uid'],
+                                       // the sys_file_reference record should always placed on the same page
+                                       // as the record to link to, see issue #46497
+                                       'pid' => $record['pid'],
                                        'fieldname' => 'media',
                                        'sorting_foreign' => $i
                                );
index f059a3d..c7456a9 100644 (file)
@@ -42,6 +42,8 @@ $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['imagelink'] = 'TYPO3\\C
 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['sysext_file_init'] = 'TYPO3\\CMS\\Install\\Updates\\InitUpdateWizard';
 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['sysext_file_images'] = 'TYPO3\\CMS\\Install\\Updates\\TceformsUpdateWizard';
 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['sysext_file_uploads'] = 'TYPO3\\CMS\\Install\\Updates\\TtContentUploadsUpdateWizard';
+$TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['referenceIntegrity'] = 'TYPO3\\CMS\\Install\\Updates\\ReferenceIntegrityUpdateWizard';
+
 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['sysext_file_filemounts'] = 'TYPO3\\CMS\\Install\\Updates\\FilemountUpdateWizard';
 // Version 4.7: Migrate the flexforms of MediaElement
 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['mediaElementFlexform'] = 'TYPO3\\CMS\\Install\\CoreUpdates\\MediaFlexformUpdate';