[TASK] Remove closing PHP tags
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / TceformsUpdateWizard.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2011-2013 Ingmar Schlecht <ingmar@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 use TYPO3\CMS\Core\Utility\GeneralUtility;
28
29 /**
30 * Upgrade wizard which goes through all files referenced in the tt_content.image filed
31 * and creates sys_file records as well as sys_file_reference records for the individual usages.
32 *
33 * @author Ingmar Schlecht <ingmar@typo3.org>
34 */
35 class TceformsUpdateWizard extends AbstractUpdate {
36
37 /**
38 * @var string
39 */
40 protected $title = 'Migrate all file relations from tt_content.image and pages.media';
41
42 /**
43 * @var \TYPO3\CMS\Core\Resource\ResourceStorage
44 */
45 protected $storage;
46
47 /**
48 * @var \TYPO3\CMS\Core\Log\Logger
49 */
50 protected $logger;
51
52 /**
53 * Constructor
54 */
55 public function __construct() {
56 /** @var $logManager \TYPO3\CMS\Core\Log\LogManager */
57 $logManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Log\\LogManager');
58 $this->logger = $logManager->getLogger(__CLASS__);
59 }
60
61 /**
62 * Initialize the storage repository.
63 */
64 public function init() {
65 /** @var $storageRepository \TYPO3\CMS\Core\Resource\StorageRepository */
66 $storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
67 $storages = $storageRepository->findAll();
68 $this->storage = $storages[0];
69 }
70
71 /**
72 * Checks if an update is needed
73 *
74 * @param string &$description The description for the update
75 * @return boolean TRUE if an update is needed, FALSE otherwise
76 */
77 public function checkForUpdate(&$description) {
78 $description = 'This update wizard goes through all files that are referenced in the tt_content.image and pages.media / pages_language_overlay.media filed and adds the files to the new File Index.<br />It also moves the files from uploads/ to the fileadmin/_migrated/ path.<br /><br />This update wizard can be called multiple times in case it didn\'t finish after running once.';
79 // Make this wizard always available
80 return TRUE;
81 }
82
83 /**
84 * Performs the database update.
85 *
86 * @param array &$dbQueries Queries done in this update
87 * @param mixed &$customMessages Custom messages
88 * @return boolean TRUE on success, FALSE on error
89 */
90 public function performUpdate(array &$dbQueries, &$customMessages) {
91 $this->init();
92 $tables = array(
93 'tt_content' => array(
94 'image' => array(
95 'sourcePath' => 'uploads/pics/',
96 // Relative to fileadmin
97 'targetPath' => '_migrated/pics/',
98 'titleTexts' => 'titleText',
99 'captions' => 'imagecaption',
100 'links' => 'image_link',
101 'alternativeTexts' => 'altText'
102 )
103 ),
104 'pages' => array(
105 'media' => array(
106 'sourcePath' => 'uploads/media/',
107 // Relative to fileadmin
108 'targetPath' => '_migrated/media/'
109 )
110 ),
111 'pages_language_overlay' => array(
112 'media' => array(
113 'sourcePath' => 'uploads/media/',
114 // Relative to fileadmin
115 'targetPath' => '_migrated/media/'
116 )
117 )
118 );
119 // We write down the fields that were migrated. Like this: tt_content:media
120 // so you can check whether a field was already migrated
121 if (isset($GLOBALS['TYPO3_CONF_VARS']['INSTALL']['wizardDone']['Tx_Install_Updates_File_TceformsUpdateWizard'])) {
122 $finishedFields = explode(',', $GLOBALS['TYPO3_CONF_VARS']['INSTALL']['wizardDone']['Tx_Install_Updates_File_TceformsUpdateWizard']);
123 } else {
124 $finishedFields = array();
125 }
126 $result = TRUE;
127 if ($this->versionNumber >= 6000000) {
128 // @todo
129 // - for each table:
130 // - get records from table
131 // - for each record:
132 // - for each field:
133 // - migrate field
134 foreach ($tables as $table => $tableConfiguration) {
135 $fieldsToMigrate = array_keys($tableConfiguration);
136 $fieldsToGet = array();
137 // find all additional fields we should get from the database
138 foreach ($tableConfiguration as $field => $fieldConfiguration) {
139 $fieldKey = $table . ':' . $field;
140 if (array_search($fieldKey, $finishedFields) !== FALSE) {
141 // this field was already migrated
142 continue;
143 } else {
144 $finishedFields[] = $fieldKey;
145 }
146 $fieldsToGet[] = $field;
147 if (isset($fieldConfiguration['titleTexts'])) {
148 $fieldsToGet[] = $fieldConfiguration['titleTexts'];
149 }
150 if (isset($fieldConfiguration['alternativeTexts'])) {
151 $fieldsToGet[] = $fieldConfiguration['alternativeTexts'];
152 }
153 if (isset($fieldConfiguration['captions'])) {
154 $fieldsToGet[] = $fieldConfiguration['captions'];
155 }
156 if (isset($fieldConfiguration['links'])) {
157 $fieldsToGet[] = $fieldConfiguration['links'];
158 }
159 }
160 $records = $this->getRecordsFromTable($table, $fieldsToGet);
161 foreach ($records as $record) {
162 foreach ($fieldsToMigrate as $field) {
163 $dbQueries = array_merge($this->migrateField($table, $record, $field, $tableConfiguration[$field], $customMessages));
164 }
165 }
166 }
167 }
168 $finishedFields = implode(',', $finishedFields);
169 $this->markWizardAsDone($finishedFields);
170 return $result;
171 }
172
173 /**
174 * Get records from table
175 *
176 * @param string $table
177 * @param array $relationFields
178 * @return array
179 */
180 protected function getRecordsFromTable($table, $relationFields) {
181 $fields = implode(',', array_merge($relationFields, array('uid', 'pid')));
182 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows($fields, $table, '');
183 return $records;
184 }
185
186 /**
187 * Migrates a single field.
188 *
189 * @param string $table
190 * @param array $row
191 * @param string $fieldname
192 * @param array $fieldConfiguration
193 * @param string $customMessages
194 * @return array A list of performed database queries
195 * @throws \Exception
196 */
197 protected function migrateField($table, $row, $fieldname, $fieldConfiguration, &$customMessages) {
198 $fieldItems = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $row[$fieldname], TRUE);
199 if (empty($fieldItems) || is_numeric($row[$fieldname])) {
200 return array();
201 }
202 if (isset($fieldConfiguration['titleTexts'])) {
203 $titleTextField = $fieldConfiguration['titleTexts'];
204 $titleTextContents = explode(LF, $row[$titleTextField]);
205 }
206 if (isset($fieldConfiguration['alternativeTexts'])) {
207 $alternativeTextField = $fieldConfiguration['alternativeTexts'];
208 $alternativeTextContents = explode(LF, $row[$alternativeTextField]);
209 }
210 if (isset($fieldConfiguration['captions'])) {
211 $captionField = $fieldConfiguration['captions'];
212 $captionContents = explode(LF, $row[$captionField]);
213 }
214 if (isset($fieldConfiguration['links'])) {
215 $linkField = $fieldConfiguration['links'];
216 $linkContents = explode(LF, $row[$linkField]);
217 }
218 $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/';
219 $queries = array();
220 $i = 0;
221 foreach ($fieldItems as $item) {
222 if (!PATH_site) {
223 throw new \Exception('PATH_site was undefined.');
224 }
225
226 $sourcePath = PATH_site . $fieldConfiguration['sourcePath'] . $item;
227 $targetPath = PATH_site . $fileadminDirectory . $fieldConfiguration['targetPath'] . $item;
228
229 // if the source file does not exist, we should just continue, but leave a message in the docs;
230 // ideally, the user would be informed after the update as well.
231 if (!file_exists($sourcePath)) {
232 $this->logger->notice('File ' . $fieldConfiguration['sourcePath'] . $item . ' does not exist. Reference was not migrated.', array('table' => $table, 'record' => $row, 'field' => $fieldname));
233
234 $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
235 $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('\TYPO3\CMS\Core\Messaging\FlashMessage',
236 sprintf($format, $fieldConfiguration['sourcePath'] . $item, $table, $row['uid'], $fieldname),
237 '', \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
238 );
239 /** @var \TYPO3\CMS\Core\Messaging\FlashMessage $message */
240 $customMessages .= '<br />' . $message->render();
241
242 continue;
243 }
244
245 if (!is_dir(dirname($targetPath))) {
246 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep(dirname($targetPath));
247 }
248 rename($sourcePath, $targetPath);
249 // get the File object
250 $file = $this->storage->getFile($fieldConfiguration['targetPath'] . $item);
251 if ($file instanceof \TYPO3\CMS\Core\Resource\File) {
252 $fields = array(
253 // TODO add sorting/sorting_foreign
254 'fieldname' => $fieldname,
255 'table_local' => 'sys_file',
256 // the sys_file_reference record should always placed on the same page
257 // as the record to link to, see issue #46497
258 'pid' => ($table === 'pages' ? $row['uid'] : $row['pid']),
259 'uid_foreign' => $row['uid'],
260 'uid_local' => $file->getUid(),
261 'tablenames' => $table,
262 'crdate' => time(),
263 'tstamp' => time()
264 );
265 if (isset($titleTextField)) {
266 $fields['title'] = trim($titleTextContents[$i]);
267 }
268 if (isset($alternativeTextField)) {
269 $fields['alternative'] = trim($alternativeTextContents[$i]);
270 }
271 if (isset($captionField)) {
272 $fields['description'] = trim($captionContents[$i]);
273 }
274 if (isset($linkField)) {
275 $fields['link'] = trim($linkContents[$i]);
276 }
277 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_file_reference', $fields);
278 $queries[] = str_replace(LF, ' ', $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery);
279 ++$i;
280 }
281 }
282 // Update referencing table's original field to now contain the count of references.
283 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . $row['uid'], array($fieldname => $i));
284 $queries[] = str_replace(LF, ' ', $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery);
285 return $queries;
286 }
287
288 }