01e145c43042930c3c264963a1e47754e4068be9
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / ReferenceIntegrityUpdateWizard.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2013 Benni Mack <benni@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * Performs certain DB updates in order to ensure that the DB fields
28 * are set properly. Currently this is used for ensuring that there
29 * are no sys_file_reference records with PID=0 where the connected
30 * parent records (e.g. a tt_content record) are not on PID=0
31 *
32 * @author Benni Mack <benni@typo3.org>
33 * @license http://www.gnu.org/copyleft/gpl.html
34 */
35 class ReferenceIntegrityUpdateWizard extends \TYPO3\CMS\Install\Updates\AbstractUpdate {
36
37 /**
38 * @var string
39 */
40 protected $title = 'Ensures the database integrity for File Abstraction records';
41
42 /**
43 * Checks if an update is needed
44 *
45 * @param string &$description: The description for the update
46 * @return boolean TRUE if an update is needed, FALSE otherwise
47 */
48 public function checkForUpdate(&$description) {
49 $description = 'Checks if there are file references that are on the root level. This could have happened due to a misconfigured previous migration.';
50 return count($this->getRequiredUpdates()) > 0;
51 }
52
53 /**
54 * Performs the database update.
55 *
56 * @param array &$dbQueries: queries done in this update
57 * @param mixed &$customMessages: custom messages
58 * @return boolean TRUE on success, FALSE on error
59 */
60 public function performUpdate(array &$dbQueries, &$customMessages) {
61 $updates = $this->getRequiredUpdates();
62 if (isset($updates['inproperConnectedFileReferences'])) {
63 foreach ($updates['inproperConnectedFileReferences'] as $fileReferenceRecord) {
64 if ($fileReferenceRecord['newpid'] > 0) {
65 $updateQuery = $GLOBALS['TYPO3_DB']->UPDATEquery(
66 'sys_file_reference',
67 'uid=' . intval($fileReferenceRecord['uid']),
68 array('pid' => $fileReferenceRecord['newpid'])
69 );
70 $GLOBALS['TYPO3_DB']->sql_query($updateQuery);
71 $dbQueries[] = $updateQuery;
72 }
73 }
74 }
75 return TRUE;
76 }
77
78 /**
79 * Determine all DB updates that need to be done
80 *
81 * @return array
82 */
83 protected function getRequiredUpdates() {
84 $requiredUpdates = array();
85 $inproperConnectedFileReferences = $this->getInproperConnectedFileReferences();
86 if (count($inproperConnectedFileReferences) > 0) {
87 $requiredUpdates['inproperConnectedFileReferences'] = $inproperConnectedFileReferences;
88 }
89 return $requiredUpdates;
90 }
91
92 /**
93 * fetches a list of all sys_file_references that have PID=0
94 *
95 * @return mixed
96 */
97 protected function getFileReferencesOnRootlevel() {
98 return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
99 'uid, pid, uid_local AS fileuid, uid_foreign AS targetuid, tablenames AS targettable',
100 'sys_file_reference',
101 'pid=0 AND deleted=0'
102 );
103 }
104
105 /**
106 * fetches all sys_file_reference records that are on PID=0 BUT their counter parts (the target record)
107 * is NOT on pid=0
108 *
109 * @return array
110 */
111 protected function getInproperConnectedFileReferences() {
112 $inproperConnectedReferences = array();
113 // fetch all references on root level
114 $sysFileReferences = $this->getFileReferencesOnRootlevel();
115 foreach ($sysFileReferences as $fileReferenceRecord) {
116 // if the target table is pages (e.g. when adding a file reference to the pages->media
117 // record, then the
118 $whereClause = 'uid=' . intval($fileReferenceRecord['targetuid']);
119 if ($fileReferenceRecord['targettable'] === 'pages') {
120 $isPageReference = TRUE;
121 } else {
122 $isPageReference = FALSE;
123 $whereClause .= ' AND pid<>0';
124 }
125 // check the target table, if the target record is NOT on the rootlevel
126 $targetRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
127 'uid, pid',
128 $fileReferenceRecord['targettable'],
129 $whereClause
130 );
131 // only add the file reference if the target record is not on PID=0
132 if ($targetRecord !== NULL) {
133 $fileReferenceRecord['newpid'] = ($isPageReference ? $targetRecord['uid'] : $targetRecord['pid']);
134 $inproperConnectedReferences[] = $fileReferenceRecord;
135 }
136 }
137 return $inproperConnectedReferences;
138 }
139 }
140
141
142 ?>