Fixed bug #16225: Disable draft workspace and migrate it to a real workspace (Thanks...
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / updates / class.tx_coreupdates_migrateworkspaces.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010 Tolleiv Nietsch <info@tolleiv.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28
29 /**
30 * Migrates workspaces from TYPO3 versions below 4.5.
31 *
32 * @author Tolleiv Nietsch <info@tolleiv.de>
33 * @version $Id$
34 */
35 class tx_coreupdates_migrateworkspaces extends tx_coreupdates_installsysexts {
36 public $versionNumber; // version number coming from t3lib_div::int_from_ver()
37
38 /**
39 * parent object
40 *
41 * @var tx_install
42 */
43 public $pObj;
44 public $userInput; // user input
45 public $sqlQueries;
46
47 /**
48 * Checks if an update is needed
49 *
50 * @param string &$description: The description for the update, which will be updated with a description of the script's purpose
51 * @return boolean whether an update is needed (true) or not (false)
52 */
53 public function checkForUpdate(&$description) {
54 $result = FALSE;
55 $description = 'Migrates the old hardcoded draft workspace to be a real workspace element';
56
57 // TYPO3 version 4.5 and above
58 if ($this->versionNumber >= 4005000) {
59 $this->includeTCA();
60 $result = $this->isDraftWorkspaceUsed();
61 }
62
63 return $result;
64 }
65
66 /**
67 * If there's any user-input which we'd love to process, this method allows to specify what
68 * kind of input we need.
69 *
70 * Since we don't need input this is left empty. It's still here to avoid that this is inherited.
71 *
72 * @param string $inputPrefix
73 * @return void
74 */
75 public function getUserInput($inputPrefix) {
76 return;
77 }
78
79 /**
80 * Performs the database update. Changes existing workspaces to use the new custom workspaces
81 *
82 * @param array &$databaseQueries: queries done in this update
83 * @param mixed &$customMessages: custom messages
84 * @return boolean whether it worked (true) or not (false)
85 */
86 public function performUpdate(array &$databaseQueries, &$customMessages) {
87 $result = TRUE;
88
89 // TYPO3 version below 4.5
90 if ($this->versionNumber < 4005000) {
91 return FALSE;
92 }
93
94 // There's no TCA available yet
95 $this->includeTCA();
96
97 // install version extension (especially when updating from very old TYPO3 versions
98 $this->installExtensions(array('version'));
99
100 // create a new dedicated "Draft" workspace and move all records to that new workspace
101 if ($this->isDraftWorkspaceUsed()) {
102 $draftWorkspaceId = $this->createWorkspace();
103 if (is_integer($draftWorkspaceId)) {
104 $this->migrateDraftWorkspaceRecordsToWorkspace($draftWorkspaceId);
105 }
106 }
107
108 if (is_array($this->sqlQueries) && is_array($databaseQueries)) {
109 $databaseQueries = array_merge($databaseQueries, $this->sqlQueries);
110 }
111
112 return $result;
113 }
114
115 /**
116 * Install a extensions
117 *
118 * @param array List of extension keys
119 * @return boolean Determines whether this was successful or not
120 */
121 protected function installExtensions($extensionKeys) {
122 if (!is_array($extensionKeys)) {
123 return FALSE;
124 }
125
126 $result = FALSE;
127 $extList = $this->addExtToList($extensionKeys);
128 if ($extList) {
129 $this->writeNewExtensionList($extList);
130 $result = TRUE;
131 }
132 return $result;
133 }
134
135 /**
136 * Check if any table contains draft-workspace records
137 *
138 * @return bool
139 */
140 protected function isDraftWorkspaceUsed() {
141 $foundDraftRecords = FALSE;
142
143 $tables = array_keys($GLOBALS['TCA']);
144 foreach ($tables as $table) {
145 $versioningVer = t3lib_div::intInRange($GLOBALS['TCA'][$table]['ctrl']['versioningWS'], 0, 2, 0);
146 if ($versioningVer > 0) {
147 if ($this->hasElementsOnWorkspace($table, -1)) {
148 $foundDraftRecords = TRUE;
149 break;
150 }
151 }
152 }
153
154 return $foundDraftRecords;
155 }
156
157 /**
158 * Create a real workspace named "Draft"
159 *
160 * @return integer
161 */
162 protected function createWorkspace() {
163 // @todo who are the reviewers and owners for this workspace?
164 // In previous versions this was defined in be_groups/be_users with the setting "Edit in Draft"
165 $data = array(
166 'title' => 'Draft'
167 );
168 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_workspace', $data);
169 $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;
170 return $GLOBALS['TYPO3_DB']->sql_insert_id();
171 }
172
173 /**
174 * Migrates all elements from the old draft workspace to the new one.
175 *
176 * @param integer $wsId
177 * @return void
178 */
179 protected function migrateDraftWorkspaceRecordsToWorkspace($wsId) {
180 $tables = array_keys($GLOBALS['TCA']);
181 $where = 't3ver_wsid=-1';
182 $values = array(
183 't3ver_wsid' => intval($wsId)
184 );
185 foreach($tables as $table) {
186 $versioningVer = t3lib_div::intInRange($GLOBALS['TCA'][$table]['ctrl']['versioningWS'], 0, 2, 0);
187 if ($versioningVer > 0 && $this->hasElementsOnWorkspace($table, -1)) {
188 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, $where, $values);
189 $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;
190 }
191 }
192 }
193
194 /**
195 * Includes the TCA definition of installed extensions.
196 *
197 * This method is used because usually the TCA is included within the init.php script, this doesn't happen
198 * if the install-tool is used, therefore this has to be done by hand.
199 *
200 * @return void
201 */
202 protected function includeTCA() {
203 global $TCA; // this is relevant because it's used within the included ext_tables.php files - do NOT remove it
204
205 include_once(TYPO3_tables_script ? PATH_typo3conf . TYPO3_tables_script : PATH_t3lib . 'stddb/tables.php');
206 // Extension additions
207 if ($GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE']) {
208 include_once(PATH_typo3conf . $GLOBALS['TYPO3_LOADED_EXT']['_CACHEFILE'] . '_ext_tables.php');
209 } else {
210 include_once(PATH_t3lib . 'stddb/load_ext_tables.php');
211 }
212 }
213
214 /**
215 * Determines whether a table has elements in a particular workspace.
216 *
217 * @param string $table Name of the table
218 * @param integer $workspaceId Id of the workspace
219 * @return boolean
220 */
221 protected function hasElementsOnWorkspace($table, $workspaceId) {
222 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
223 'uid',
224 $table,
225 't3ver_wsid=' . intval($workspaceId)
226 );
227
228 $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;
229
230 return ($count > 0);
231 }
232 }
233 ?>