[BUGFIX] RTE Image Wizard
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / ImageHandler / EditImageHandler.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea\ImageHandler;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Http\Message\ServerRequestInterface;
18 use TYPO3\CMS\Core\Page\PageRenderer;
19 use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
20 use TYPO3\CMS\Core\Resource\FileInterface;
21 use TYPO3\CMS\Core\Resource\ResourceFactory;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Lang\LanguageService;
24 use TYPO3\CMS\Recordlist\Controller\AbstractLinkBrowserController;
25 use TYPO3\CMS\Recordlist\LinkHandler\LinkHandlerInterface;
26 use TYPO3\CMS\Recordlist\Tree\View\LinkParameterProviderInterface;
27 use TYPO3\CMS\Rtehtmlarea\Controller\SelectImageController;
28
29 class EditImageHandler implements LinkHandlerInterface, LinkParameterProviderInterface
30 {
31 /**
32 * @var SelectImageController
33 */
34 protected $selectImageController;
35
36 /**
37 * @var FileInterface
38 */
39 protected $currentFile;
40
41 /**
42 * Initialize the handler
43 *
44 * @param AbstractLinkBrowserController $linkBrowser
45 * @param string $identifier
46 * @param array $configuration Page TSconfig
47 *
48 * @return void
49 */
50 public function initialize(AbstractLinkBrowserController $linkBrowser, $identifier, array $configuration)
51 {
52 if (!$linkBrowser instanceof SelectImageController) {
53 throw new \InvalidArgumentException('The given $linkBrowser must be of type SelectImageController."', 1455499721);
54 }
55 $this->selectImageController = $linkBrowser;
56 }
57
58 /**
59 * Checks if this is the handler for the given link
60 *
61 * The handler may store this information locally for later usage.
62 *
63 * @param array $linkParts Link parts as returned from TypoLinkCodecService
64 *
65 * @return bool
66 */
67 public function canHandleLink(array $linkParts)
68 {
69 if (!empty($linkParts['currentImage'])) {
70 try {
71 $this->currentFile = ResourceFactory::getInstance()->getFileObject($linkParts['currentImage']);
72 return true;
73 } catch (FileDoesNotExistException $e) {
74 }
75 }
76 return false;
77 }
78
79 /**
80 * Format the current link for HTML output
81 *
82 * @return string
83 */
84 public function formatCurrentUrl()
85 {
86 return $this->currentFile->getStorage()->getName() . ': ' . $this->currentFile->getIdentifier();
87 }
88
89 /**
90 * Disallow this handler if no image is there to edit
91 *
92 * @param array $allowedItems
93 * @return array
94 */
95 public function modifyAllowedItems($allowedItems, $linkParts)
96 {
97 $selfPosition = array_search('image', $allowedItems, true);
98 if (empty($linkParts['currentImage']) && $selfPosition !== false) {
99 unset($allowedItems[$selfPosition]);
100 }
101 return $allowedItems;
102 }
103
104 /**
105 * Render the link handler
106 *
107 * @param ServerRequestInterface $request
108 *
109 * @return string
110 */
111 public function render(ServerRequestInterface $request)
112 {
113 GeneralUtility::makeInstance(PageRenderer::class)->loadRequireJsModule('TYPO3/CMS/Rtehtmlarea/EditImage');
114
115 $buttonConfig = $this->selectImageController->getButtonConfiguration();
116 $removedProperties = array();
117 if (is_array($buttonConfig['properties.'])) {
118 if ($buttonConfig['properties.']['removeItems']) {
119 $removedProperties = GeneralUtility::trimExplode(',', $buttonConfig['properties.']['removeItems'], true);
120 }
121 }
122
123 $rteProperties = $this->selectImageController->getRteProperties();
124
125 $lockPlainWidth = false;
126 $lockPlainHeight = false;
127 if (isset($rteProperties['default.']['proc.']['plainImageMode'])) {
128 $plainImageMode = $rteProperties['default.']['proc.']['plainImageMode'];
129 $lockPlainWidth = $plainImageMode === 'lockDimensions';
130 $lockPlainHeight = $lockPlainWidth || $plainImageMode === 'lockRatio' || $plainImageMode === 'lockRatioWhenSmaller';
131 }
132
133 $lang = $this->getLanguageService();
134
135 $content = '<div><form name="imageData" class="t3js-editForm"><table class="htmlarea-window-table">';
136
137 if (!in_array('class', $removedProperties, true) && !empty($buttonConfig['properties.']['class.']['allowedClasses'])) {
138 $classesImageArray = GeneralUtility::trimExplode(',', $buttonConfig['properties.']['class.']['allowedClasses'], true);
139 $classesImageJSOptions = '<option value=""></option>';
140 foreach ($classesImageArray as $class) {
141 $classesImageJSOptions .= '<option value="' . $class . '">' . $class . '</option>';
142 }
143 $content .= '<tr><td><label for="iClass">' . $lang->getLL('class') . ': </label></td><td>
144 <select id="t3js-iClass" name="iClass" style="width:140px;">' . $classesImageJSOptions . '
145 </select></td></tr>';
146 }
147 if (!in_array('width', $removedProperties, true) && !($this->currentFile && $lockPlainWidth /* && check if it is a RTE magic image (no clue how to do that now with FAL)*/)) {
148 $content .= '<tr><td><label for="iWidth">' . $lang->getLL('width') . ': </label></td><td>
149 <input type="text" id="t3js-iWidth" name="iWidth" value="" style="width: 39px;" maxlength="4" /></td></tr>';
150 }
151 if (!in_array('height', $removedProperties, true) && !($this->currentFile && $lockPlainHeight /* && check if it is a RTE magic image (no clue how to do that now with FAL)*/)) {
152 $content .= '<tr><td><label for="iHeight">' . $lang->getLL('height') . ': </label></td><td>
153 <input type="text" id="t3js-iHeight" name="iHeight" value="" style="width: 39px;" maxlength="4" /></td></tr>';
154 }
155 if (!in_array('border', $removedProperties, true)) {
156 $content .= '<tr><td><label for="iBorder">' . $lang->getLL('border') . ': </label></td><td>
157 <input type="checkbox" id="t3js-iBorder" name="iBorder" value="1" /></td></tr>';
158 }
159 if (!in_array('float', $removedProperties, true)) {
160 $content .= '<tr><td><label for="iFloat">' . $lang->getLL('float') . ': </label></td><td>
161 <select id="t3js-iFloat" name="iFloat">'
162 . '<option value="">' . $lang->getLL('notSet') . '</option>'
163 . '<option value="none">' . $lang->getLL('nonFloating') . '</option>'
164 . '<option value="left">' . $lang->getLL('left') . '</option>'
165 . '<option value="right">' . $lang->getLL('right') . '</option>'
166 . '</select>
167 </td></tr>';
168 }
169 if (!in_array('paddingTop', $removedProperties, true)) {
170 $content .= '<tr><td><label for="iPaddingTop">' . $lang->getLL('padding_top') . ': </label></td><td><input type="text" id="t3js-iPaddingTop" name="iPaddingTop" value="" style="width: 39px;" maxlength="4" /></td></tr>';
171 }
172 if (!in_array('paddingRight', $removedProperties, true)) {
173 $content .= '<tr><td><label for="iPaddingRight">' . $lang->getLL('padding_right') . ': </label></td><td><input type="text" id="t3js-iPaddingRight" name="iPaddingRight" value="" style="width: 39px;" maxlength="4" /></td></tr>';
174 }
175 if (!in_array('paddingBottom', $removedProperties, true)) {
176 $content .= '<tr><td><label for="iPaddingBottom">' . $lang->getLL('padding_bottom') . ': </label></td><td><input type="text" id="t3js-iPaddingBottom" name="iPaddingBottom" value="" style="width: 39px;" maxlength="4" /></td></tr>';
177 }
178 if (!in_array('paddingLeft', $removedProperties, true)) {
179 $content .= '<tr><td><label for="iPaddingLeft">' . $lang->getLL('padding_left') . ': </label></td><td><input type="text" id="t3js-iPaddingLeft" name="iPaddingLeft" value="" style="width: 39px;" maxlength="4" /></td></tr>';
180 }
181 if (!in_array('title', $removedProperties, true)) {
182 $content .= '<tr><td><label for="iTitle">' . $lang->getLL('title') . ': </label></td><td><input type="text" id="t3js-iTitle" name="iTitle" style="width:192px;" maxlength="256" /></td></tr>';
183 }
184 if (!in_array('alt', $removedProperties, true)) {
185 $content .= '<tr><td><label for="iAlt">' . $lang->getLL('alt') . ': </label></td><td><input type="text" id="t3js-iAlt" name="iAlt" style="width:192px;" maxlength="256" /></td></tr>';
186 }
187 if (!in_array('lang', $removedProperties, true)) {
188 $content .= '<tr id="t3js-languageSetting"><td><label for="iLang"></label></td><td><select id="t3js-iLang" name="iLang">###lang_selector###</select></td></tr>';
189 }
190 if (!in_array('data-htmlarea-clickenlarge', $removedProperties, true) && !in_array('clickenlarge', $removedProperties, true)) {
191 $content .= '<tr><td><label for="iClickEnlarge">' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:image_zoom') . ': </label></td><td><input type="checkbox" name="iClickEnlarge" id="t3js-iClickEnlarge" value="0" /></td></tr>';
192 }
193 $content .= '<tr><td></td><td><input class="btn btn-default" type="submit" value="' . $lang->getLL('update') . '"></td></tr></table></form>';
194
195 return $content;
196 }
197
198 /**
199 * Return TRUE if the handler supports to update a link.
200 *
201 * This is useful for file or page links, when only attributes are changed.
202 *
203 * @return bool
204 */
205 public function isUpdateSupported()
206 {
207 return false;
208 }
209
210 /**
211 * @return string[] Array of body-tag attributes
212 */
213 public function getBodyTagAttributes()
214 {
215 return [
216 'data-classes-image' => $this->selectImageController->getButtonConfiguration()['properties.']['class.']['allowedClasses'] || $this->selectImageController->getRteProperties()['default.']['classesImage']
217 ];
218 }
219
220 /**
221 * Returns the URL of the current script
222 *
223 * @return string
224 */
225 public function getScriptUrl()
226 {
227 return $this->selectImageController->getScriptUrl();
228 }
229
230 /**
231 * Provides an array or GET parameters for URL generation
232 *
233 * @param array $values Array of values to include into the parameters or which might influence the parameters
234 *
235 * @return string[] Array of parameters which have to be added to URLs
236 */
237 public function getUrlParameters(array $values)
238 {
239 return [];
240 }
241
242 /**
243 * Check if given value is currently the selected item
244 *
245 * This method is only used in the page tree.
246 *
247 * @param array $values Values to be checked
248 *
249 * @return bool Returns TRUE if the given values match the currently selected item
250 */
251 public function isCurrentlySelectedItem(array $values)
252 {
253 return false;
254 }
255
256 /**
257 * @return array
258 */
259 public function getLinkAttributes()
260 {
261 return [];
262 }
263
264 /**
265 * @param string[] $fieldDefinitions Array of link attribute field definitions
266 * @return string[]
267 */
268 public function modifyLinkAttributes(array $fieldDefinitions)
269 {
270 return $fieldDefinitions;
271 }
272
273 /**
274 * @return LanguageService
275 */
276 protected function getLanguageService()
277 {
278 return $GLOBALS['LANG'];
279 }
280 }