1fd46b569d42ad8329891c2b976e905d44b91f53
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / RteMagicImagesUpdateWizard.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2013 Benjamin 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 /**
28 * Upgrade wizard that moves all RTE magic images (usually in uploads/)
29 * that have the prefix RTEmagicC_* to the default storage (usually fileadmin/_migrated/RTE/)
30 * and also updates the according fields (e.g. tt_content:123:bodytext) with the new string, and updates
31 * the softreference index
32 *
33 * @author Benjamin Mack <benni@typo3.org>
34 */
35 class RteMagicImagesUpdateWizard extends AbstractUpdate {
36
37 /**
38 * Title of the update wizard
39 * @var string
40 */
41 protected $title = 'Migrate all RTE magic images from uploads/RTEmagicC_* to fileadmin/_migrated/RTE/';
42
43 /**
44 * The default storage
45 * @var \TYPO3\CMS\Core\Resource\ResourceStorage
46 */
47 protected $storage;
48
49 /**
50 * The old location of the file name, e.g. "uploads/RTEmagicC_"
51 * @var string
52 */
53 protected $oldPrefix = NULL;
54
55 /**
56 * @var \TYPO3\CMS\Core\Log\Logger
57 */
58 protected $logger;
59
60 /**
61 * Constructor
62 */
63 public function __construct() {
64 /** @var $logManager \TYPO3\CMS\Core\Log\LogManager */
65 $logManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Log\\LogManager');
66 $this->logger = $logManager->getLogger(__CLASS__);
67
68 // Set it to uploads/RTEmagicC_*
69 if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'])) {
70 $this->oldPrefix = $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'] . 'RTEmagicC_';
71 }
72 }
73
74 /**
75 * Initialize the storage repository.
76 *
77 * @return void
78 */
79 public function init() {
80 /** @var $storageRepository \TYPO3\CMS\Core\Resource\StorageRepository */
81 $storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
82 $storages = $storageRepository->findAll();
83 $this->storage = $storages[0];
84 }
85
86 /**
87 * Checks if an update is needed
88 *
89 * @param string $description The description for the update
90 * @return boolean TRUE if an update is needed, FALSE otherwise
91 */
92 public function checkForUpdate(&$description) {
93 $description = 'This update wizard goes through all magic images, located in "' . htmlspecialchars($this->oldPrefix) . '", and moves the files to fileadmin/_migrated/RTE/.';
94 $description .= '<br />It also moves the files from uploads/ to the fileadmin/_migrated/ path.';
95 // Issue warning about sys_refindex needing to be up to date
96 /** @var \TYPO3\CMS\Core\Messaging\FlashMessage $message */
97 $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
98 'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
99 'This script bases itself on the references contained in the general reference index (sys_refindex). It is strongly advised to update it before running this wizard.',
100 'Updating the reference index',
101 \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING
102 );
103 $description .= $message->render();
104
105 // Wizard is only available if oldPrefix set
106 if ($this->oldPrefix) {
107 $oldRecords = $this->findMagicImagesInOldLocation();
108 if (count($oldRecords) > 0) {
109 $description .= '<br />There are currently <strong>' . count($oldRecords) . '</strong> magic images in the old directory.<br />';
110 return TRUE;
111 }
112 }
113
114 // Disable the update wizard if there are no old RTE magic images
115 return FALSE;
116 }
117
118 /**
119 * Performs the database update.
120 *
121 * @param array $dbQueries queries done in this update
122 * @param mixed $customMessages custom messages
123 * @return boolean TRUE on success, FALSE on error
124 */
125 public function performUpdate(array &$dbQueries, &$customMessages) {
126 $this->init();
127
128 if (!PATH_site) {
129 throw new \Exception('PATH_site was undefined.');
130 }
131
132 $fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/');
133 $targetDirectory = '/_migrated/RTE/';
134 $fullTargetDirectory = PATH_site . $fileadminDirectory . $targetDirectory;
135
136 // Create the directory, if necessary
137 if (!is_dir($fullTargetDirectory)) {
138 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($fullTargetDirectory);
139 }
140
141
142 $oldRecords = $this->findMagicImagesInOldLocation();
143 foreach ($oldRecords as $refRecord) {
144
145 // Is usually uploads/RTE_magicC_123423324.png.png
146 $sourceFileName = $refRecord['ref_string'];
147 // Absolute path/filename
148 $fullSourceFileName = PATH_site . $refRecord['ref_string'];
149 $targetFileName = $targetDirectory . \TYPO3\CMS\Core\Utility\PathUtility::basename($refRecord['ref_string']);
150 // Full directory
151 $fullTargetFileName = $fullTargetDirectory . \TYPO3\CMS\Core\Utility\PathUtility::basename($refRecord['ref_string']);
152
153 // maybe the file has been moved previously
154 if (!file_exists($fullTargetFileName)) {
155 // If the source file does not exist, we should just continue, but leave a message in the docs;
156 // ideally, the user would be informed after the update as well.
157 if (!file_exists(PATH_site . $sourceFileName)) {
158 $this->logger->notice('File ' . $sourceFileName . ' does not exist. Reference was not migrated.', array());
159
160 $format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
161 $message = sprintf($format, $sourceFileName, $refRecord['tablename'], $refRecord['recuid'], $refRecord['field']);
162 $customMessages .= PHP_EOL . $message;
163
164 continue;
165 }
166
167 rename($fullSourceFileName, $fullTargetFileName);
168 }
169
170 // Get the File object
171 $file = $this->storage->getFile($targetFileName);
172 if ($file instanceof \TYPO3\CMS\Core\Resource\File) {
173 // And now update the referencing field
174 $targetFieldName = $refRecord['field'];
175 $targetRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
176 'uid, ' . $targetFieldName,
177 $refRecord['tablename'],
178 'uid=' . (int)$refRecord['recuid']
179 );
180 if ($targetRecord) {
181 // Replace the old filename with the new one, and add data-* attributes used by the RTE
182 $searchString = 'src="' . $sourceFileName . '"';
183 $replacementString = 'src="' . $fileadminDirectory . $targetFileName . '"';
184 $replacementString .= ' data-htmlarea-file-uid="' . $file->getUid() . '"';
185 $replacementString .= ' data-htmlarea-file-table="sys_file"';
186 $targetRecord[$targetFieldName] = str_replace(
187 $searchString,
188 $replacementString,
189 $targetRecord[$targetFieldName]
190 );
191 // Update the record
192 $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
193 $refRecord['tablename'],
194 'uid=' . (int)$refRecord['recuid'],
195 array($targetFieldName => $targetRecord[$targetFieldName])
196 );
197 $queries[] = str_replace(LF, ' ', $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery);
198
199 // Finally, update the sys_refindex table as well
200 $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
201 'sys_refindex',
202 'hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($refRecord['hash'], 'sys_refindex'),
203 array(
204 'ref_table' => 'sys_file',
205 'softref_key' => 'rtehtmlarea_images',
206 'ref_uid' => $file->getUid(),
207 'ref_string' => $fileadminDirectory . $targetFileName
208 )
209 );
210 $queries[] = str_replace(LF, ' ', $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery);
211 }
212
213 }
214 }
215
216 return TRUE;
217 }
218
219 /**
220 * Go through the soft refindex and find all occurences where the old filename
221 * is still written in the ref_string
222 *
223 * @return array Entries from sys_refindex
224 */
225 protected function findMagicImagesInOldLocation() {
226 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
227 'hash, tablename, recuid, field, ref_table, ref_uid, ref_string',
228 'sys_refindex',
229 'ref_string LIKE "' . $GLOBALS['TYPO3_DB']->escapeStrForLike($this->oldPrefix, 'sys_refindex') . '%"',
230 '',
231 'ref_string ASC'
232 );
233 return $records;
234 }
235
236 }