Commit | Line | Data |
---|---|---|
6c80f0df AE |
1 | <?php |
2 | namespace wcf\acp\form; | |
3 | use wcf\data\package\Package; | |
811f5a93 | 4 | use wcf\data\style\Style; |
6c80f0df | 5 | use wcf\data\style\StyleAction; |
bcb9c1bf | 6 | use wcf\data\style\StyleEditor; |
7a23a706 | 7 | use wcf\data\template\group\TemplateGroup; |
6c80f0df | 8 | use wcf\data\template\group\TemplateGroupList; |
9a9b5ed5 | 9 | use wcf\form\AbstractForm; |
6c80f0df AE |
10 | use wcf\system\event\EventHandler; |
11 | use wcf\system\exception\SystemException; | |
12 | use wcf\system\exception\UserInputException; | |
aa5fecb3 | 13 | use wcf\system\language\I18nHandler; |
6c80f0df AE |
14 | use wcf\system\Regex; |
15 | use wcf\system\WCF; | |
16 | use wcf\util\DateUtil; | |
17 | use wcf\util\FileUtil; | |
18 | use wcf\util\StringUtil; | |
19 | ||
20 | /** | |
21 | * Shows the style add form. | |
22 | * | |
23 | * @author Alexander Ebert | |
c839bd49 | 24 | * @copyright 2001-2018 WoltLab GmbH |
6c80f0df | 25 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
e71525e4 | 26 | * @package WoltLabSuite\Core\Acp\Form |
6c80f0df | 27 | */ |
9a9b5ed5 | 28 | class StyleAddForm extends AbstractForm { |
6c80f0df | 29 | /** |
0fcfe5f6 | 30 | * @inheritDoc |
6c80f0df AE |
31 | */ |
32 | public $activeMenuItem = 'wcf.acp.menu.link.style.add'; | |
33 | ||
34 | /** | |
35 | * author's name | |
36 | * @var string | |
37 | */ | |
38 | public $authorName = ''; | |
39 | ||
40 | /** | |
41 | * author's URL | |
42 | * @var string | |
43 | */ | |
44 | public $authorURL = ''; | |
45 | ||
811f5a93 AE |
46 | /** |
47 | * style api version | |
48 | * @var string | |
49 | */ | |
50 | public $apiVersion = Style::API_VERSION; | |
51 | ||
6c80f0df AE |
52 | /** |
53 | * list of available font families | |
7a23a706 | 54 | * @var string[] |
6c80f0df | 55 | */ |
954d51cf | 56 | public $availableFontFamilies = [ |
6c80f0df AE |
57 | 'Arial, Helvetica, sans-serif' => 'Arial', |
58 | 'Chicago, Impact, Compacta, sans-serif' => 'Chicago', | |
59 | '"Comic Sans MS", sans-serif' => 'Comic Sans', | |
60 | '"Courier New", Courier, monospace' => 'Courier New', | |
61 | 'Geneva, Arial, Helvetica, sans-serif' => 'Geneva', | |
62 | 'Georgia, "Times New Roman", Times, serif' => 'Georgia', | |
63 | 'Helvetica, Verdana, sans-serif' => 'Helvetica', | |
64 | 'Impact, Compacta, Chicago, sans-serif' => 'Impact', | |
65 | '"Lucida Sans", "Lucida Grande", Monaco, Geneva, sans-serif' => 'Lucida', | |
8da4f05f | 66 | '"Segoe UI", "DejaVu Sans", "Lucida Grande", Helvetica, sans-serif' => 'Segoe UI', |
6c80f0df AE |
67 | 'Tahoma, Arial, Helvetica, sans-serif' => 'Tahoma', |
68 | '"Times New Roman", Times, Georgia, serif' => 'Times New Roman', | |
69 | '"Trebuchet MS", Arial, sans-serif' => 'Trebuchet MS', | |
70 | 'Verdana, Helvetica, sans-serif' => 'Verdana' | |
954d51cf | 71 | ]; |
6c80f0df AE |
72 | |
73 | /** | |
74 | * list of available template groups | |
7a23a706 | 75 | * @var TemplateGroup[] |
6c80f0df | 76 | */ |
954d51cf | 77 | public $availableTemplateGroups = []; |
6c80f0df AE |
78 | |
79 | /** | |
80 | * list of available units | |
7a23a706 | 81 | * @var string[] |
6c80f0df | 82 | */ |
0347920c | 83 | public $availableUnits = ['px', 'pt', 'rem', 'em', '%']; |
6c80f0df | 84 | |
640a8bea MW |
85 | /** |
86 | * @var array | |
87 | */ | |
f2b50825 AE |
88 | public $colorCategories = []; |
89 | ||
6c80f0df AE |
90 | /** |
91 | * list of color variables | |
5fffbcb8 | 92 | * @var string[][] |
6c80f0df | 93 | */ |
954d51cf | 94 | public $colors = []; |
6c80f0df AE |
95 | |
96 | /** | |
97 | * copyright message | |
98 | * @var string | |
99 | */ | |
100 | public $copyright = ''; | |
101 | ||
6c80f0df AE |
102 | /** |
103 | * list of global variables | |
104 | * @var array | |
105 | */ | |
954d51cf | 106 | public $globals = []; |
6c80f0df | 107 | |
6c80f0df AE |
108 | /** |
109 | * image path | |
110 | * @var string | |
111 | */ | |
112 | public $imagePath = 'images/'; | |
113 | ||
90b4b964 AE |
114 | /** |
115 | * tainted style | |
116 | * @var boolean | |
117 | */ | |
118 | public $isTainted = true; | |
119 | ||
6c80f0df AE |
120 | /** |
121 | * license name | |
122 | * @var string | |
123 | */ | |
124 | public $license = ''; | |
125 | ||
126 | /** | |
0fcfe5f6 | 127 | * @inheritDoc |
6c80f0df | 128 | */ |
954d51cf | 129 | public $neededPermissions = ['admin.style.canManageStyle']; |
6c80f0df | 130 | |
811f5a93 AE |
131 | /** |
132 | * list of variables that were added after 3.0 | |
133 | * @var string[] | |
134 | */ | |
135 | public $newVariables = [ | |
136 | // 3.1 | |
137 | 'wcfContentContainerBackground' => '3.1', | |
138 | 'wcfContentContainerBorder' => '3.1', | |
139 | 'wcfEditorButtonBackground' => '3.1', | |
140 | 'wcfEditorButtonBackgroundActive' => '3.1', | |
141 | 'wcfEditorButtonText' => '3.1', | |
142 | 'wcfEditorButtonTextActive' => '3.1', | |
143 | 'wcfEditorButtonTextDisabled' => '3.1' | |
144 | ]; | |
145 | ||
90b4b964 AE |
146 | /** |
147 | * style package name | |
148 | * @var string | |
149 | */ | |
150 | public $packageName = ''; | |
151 | ||
6c80f0df AE |
152 | /** |
153 | * last change date | |
154 | * @var string | |
155 | */ | |
156 | public $styleDate = '0000-00-00'; | |
157 | ||
158 | /** | |
159 | * description | |
160 | * @var string | |
161 | */ | |
162 | public $styleDescription = ''; | |
163 | ||
164 | /** | |
165 | * style name | |
166 | * @var string | |
167 | */ | |
168 | public $styleName = ''; | |
169 | ||
170 | /** | |
171 | * version number | |
172 | * @var string | |
173 | */ | |
174 | public $styleVersion = ''; | |
175 | ||
176 | /** | |
177 | * template group id | |
178 | * @var integer | |
179 | */ | |
180 | public $templateGroupID = 0; | |
181 | ||
182 | /** | |
183 | * temporary image hash | |
184 | * @var string | |
185 | */ | |
186 | public $tmpHash = ''; | |
187 | ||
188 | /** | |
189 | * list of variables and their value | |
7a23a706 | 190 | * @var string[] |
6c80f0df | 191 | */ |
954d51cf | 192 | public $variables = []; |
6c80f0df AE |
193 | |
194 | /** | |
195 | * list of specialized variables | |
7a23a706 | 196 | * @var string[] |
6c80f0df | 197 | */ |
954d51cf | 198 | public $specialVariables = []; |
6c80f0df AE |
199 | |
200 | /** | |
0fcfe5f6 | 201 | * @inheritDoc |
6c80f0df AE |
202 | */ |
203 | public function readParameters() { | |
204 | parent::readParameters(); | |
205 | ||
aa5fecb3 AE |
206 | I18nHandler::getInstance()->register('styleDescription'); |
207 | ||
6c80f0df | 208 | $this->setVariables(); |
393e18c5 MS |
209 | if (empty($_POST)) { |
210 | $this->readStyleVariables(); | |
211 | } | |
6c80f0df AE |
212 | |
213 | $templateGroupList = new TemplateGroupList(); | |
cd1fcbfa | 214 | $templateGroupList->sqlOrderBy = "templateGroupName"; |
3c33452f | 215 | $templateGroupList->getConditionBuilder()->add('templateGroupFolderName <> ?', ['_wcf_email/']); |
6c80f0df AE |
216 | $templateGroupList->readObjects(); |
217 | $this->availableTemplateGroups = $templateGroupList->getObjects(); | |
218 | ||
219 | if (isset($_REQUEST['tmpHash'])) { | |
220 | $this->tmpHash = StringUtil::trim($_REQUEST['tmpHash']); | |
221 | } | |
222 | if (empty($this->tmpHash)) { | |
223 | $this->tmpHash = StringUtil::getRandomID(); | |
224 | } | |
225 | } | |
226 | ||
227 | /** | |
0fcfe5f6 | 228 | * @inheritDoc |
6c80f0df AE |
229 | */ |
230 | public function readFormParameters() { | |
231 | parent::readFormParameters(); | |
232 | ||
aa5fecb3 AE |
233 | I18nHandler::getInstance()->readValues(); |
234 | ||
954d51cf | 235 | $colors = []; |
f2b50825 AE |
236 | foreach ($this->colors as $categoryName => $variables) { |
237 | foreach ($variables as $variable) { | |
238 | $colors[] = $categoryName . ucfirst($variable); | |
954d51cf AE |
239 | } |
240 | } | |
241 | ||
6c80f0df AE |
242 | // ignore everything except well-formed rgba() |
243 | $regEx = new Regex('rgba\(\d{1,3}, \d{1,3}, \d{1,3}, (1|1\.00?|0|0?\.[0-9]{1,2})\)'); | |
954d51cf | 244 | foreach ($colors as $variableName) { |
6c80f0df AE |
245 | if (isset($_POST[$variableName]) && $regEx->match($_POST[$variableName])) { |
246 | $this->variables[$variableName] = $_POST[$variableName]; | |
247 | } | |
248 | } | |
249 | ||
250 | // read variables with units, e.g. 13px | |
251 | foreach ($this->globals as $variableName) { | |
252 | if (isset($_POST[$variableName]) && is_numeric($_POST[$variableName])) { | |
0f0590c2 | 253 | if (isset($_POST[$variableName.'_unit']) && in_array($_POST[$variableName.'_unit'], $this->availableUnits)) { |
ed5531ea | 254 | $this->variables[$variableName] = abs($_POST[$variableName]).$_POST[$variableName.'_unit']; |
6c80f0df AE |
255 | } |
256 | } | |
79aa2380 MW |
257 | else { |
258 | // set default value | |
259 | $this->variables[$variableName] = '0px'; | |
260 | } | |
6c80f0df AE |
261 | } |
262 | ||
263 | // read specialized variables | |
ed5531ea | 264 | $integerValues = ['pageLogoHeight', 'pageLogoWidth']; |
6c80f0df | 265 | foreach ($this->specialVariables as $variableName) { |
ed5531ea AE |
266 | if (isset($_POST[$variableName])) { |
267 | $this->variables[$variableName] = (in_array($variableName, $integerValues)) ? abs(intval($_POST[$variableName])) : StringUtil::trim($_POST[$variableName]); | |
268 | } | |
6c80f0df | 269 | } |
63b9817b | 270 | $this->variables['useFluidLayout'] = isset($_POST['useFluidLayout']) ? 1 : 0; |
ffeec0e2 | 271 | $this->variables['useGoogleFont'] = isset($_POST['useGoogleFont']) ? 1 : 0; |
6c80f0df AE |
272 | |
273 | // style data | |
274 | if (isset($_POST['authorName'])) $this->authorName = StringUtil::trim($_POST['authorName']); | |
275 | if (isset($_POST['authorURL'])) $this->authorURL = StringUtil::trim($_POST['authorURL']); | |
276 | if (isset($_POST['copyright'])) $this->copyright = StringUtil::trim($_POST['copyright']); | |
6c80f0df AE |
277 | if (isset($_POST['imagePath'])) $this->imagePath = StringUtil::trim($_POST['imagePath']); |
278 | if (isset($_POST['license'])) $this->license = StringUtil::trim($_POST['license']); | |
90b4b964 | 279 | if (isset($_POST['packageName'])) $this->packageName = StringUtil::trim($_POST['packageName']); |
6c80f0df AE |
280 | if (isset($_POST['styleDate'])) $this->styleDate = StringUtil::trim($_POST['styleDate']); |
281 | if (isset($_POST['styleDescription'])) $this->styleDescription = StringUtil::trim($_POST['styleDescription']); | |
282 | if (isset($_POST['styleName'])) $this->styleName = StringUtil::trim($_POST['styleName']); | |
283 | if (isset($_POST['styleVersion'])) $this->styleVersion = StringUtil::trim($_POST['styleVersion']); | |
284 | if (isset($_POST['templateGroupID'])) $this->templateGroupID = intval($_POST['templateGroupID']); | |
811f5a93 | 285 | if (isset($_POST['apiVersion']) && in_array($_POST['apiVersion'], Style::$supportedApiVersions)) $this->apiVersion = $_POST['apiVersion']; |
6c80f0df AE |
286 | } |
287 | ||
288 | /** | |
0fcfe5f6 | 289 | * @inheritDoc |
6c80f0df AE |
290 | */ |
291 | public function validate() { | |
292 | parent::validate(); | |
293 | ||
294 | if (empty($this->authorName)) { | |
295 | throw new UserInputException('authorName'); | |
296 | } | |
297 | ||
6c80f0df AE |
298 | // validate date |
299 | if (empty($this->styleDate)) { | |
300 | throw new UserInputException('styleDate'); | |
301 | } | |
302 | else { | |
303 | try { | |
304 | DateUtil::validateDate($this->styleDate); | |
305 | } | |
306 | catch (SystemException $e) { | |
063bbf46 | 307 | throw new UserInputException('styleDate', 'invalid'); |
6c80f0df AE |
308 | } |
309 | } | |
310 | ||
311 | if (empty($this->styleName)) { | |
312 | throw new UserInputException('styleName'); | |
313 | } | |
314 | ||
315 | // validate version | |
316 | if (empty($this->styleVersion)) { | |
317 | throw new UserInputException('styleVersion'); | |
318 | } | |
319 | else if (!Package::isValidVersion($this->styleVersion)) { | |
063bbf46 | 320 | throw new UserInputException('styleVersion', 'invalid'); |
6c80f0df AE |
321 | } |
322 | ||
90b4b964 AE |
323 | // validate style package name |
324 | if (!empty($this->packageName)) { | |
325 | if (!Package::isValidPackageName($this->packageName)) { | |
063bbf46 | 326 | throw new UserInputException('packageName', 'invalid'); |
90b4b964 AE |
327 | } |
328 | ||
6147a666 | 329 | $this->enforcePackageNameRestriction(); |
90b4b964 AE |
330 | } |
331 | ||
6c80f0df AE |
332 | // validate template group id |
333 | if ($this->templateGroupID) { | |
334 | if (!isset($this->availableTemplateGroups[$this->templateGroupID])) { | |
335 | throw new UserInputException('templateGroupID'); | |
336 | } | |
337 | } | |
338 | ||
6c80f0df AE |
339 | // ensure image path is below WCF_DIR/images/ |
340 | if ($this->imagePath) { | |
f2024036 | 341 | $relativePath = FileUtil::unifyDirSeparator(FileUtil::getRelativePath(WCF_DIR.'images/', WCF_DIR.$this->imagePath)); |
6c80f0df | 342 | if (strpos($relativePath, '../') !== false) { |
063bbf46 | 343 | throw new UserInputException('imagePath', 'invalid'); |
6c80f0df AE |
344 | } |
345 | } | |
346 | ||
97ec0367 | 347 | if (!empty($this->variables['overrideScss'])) { |
6c80f0df AE |
348 | $this->parseOverrides(); |
349 | } | |
811f5a93 AE |
350 | |
351 | $this->validateApiVersion(); | |
6c80f0df AE |
352 | } |
353 | ||
6147a666 | 354 | /** |
811f5a93 | 355 | * Disallow the use of `com.woltlab.*` for package names to avoid accidental collisions. |
6147a666 AE |
356 | * |
357 | * @throws UserInputException | |
358 | */ | |
359 | protected function enforcePackageNameRestriction() { | |
360 | // 3rd party styles may never have com.woltlab.* as name | |
361 | if (strpos($this->packageName, 'com.woltlab.') !== false) { | |
362 | throw new UserInputException('packageName', 'reserved'); | |
363 | } | |
364 | } | |
365 | ||
811f5a93 AE |
366 | /** |
367 | * Validates the style API version. | |
368 | * | |
369 | * @throws UserInputException | |
370 | * @since 3.1 | |
371 | */ | |
372 | protected function validateApiVersion() { | |
373 | if (!in_array($this->apiVersion, Style::$supportedApiVersions)) { | |
374 | throw new UserInputException('apiVersion', 'invalid'); | |
375 | } | |
376 | } | |
377 | ||
6c80f0df AE |
378 | /** |
379 | * Validates LESS-variable overrides. | |
380 | * | |
381 | * If an override is invalid, unknown or matches a variable covered by | |
382 | * the style editor itself, it will be silently discarded. | |
bfbc0267 AE |
383 | * |
384 | * @param string $variableName | |
385 | * @throws UserInputException | |
6c80f0df | 386 | */ |
bfbc0267 AE |
387 | protected function parseOverrides($variableName = 'overrideScss') { |
388 | static $colorNames = null; | |
389 | if ($colorNames === null) { | |
390 | $colorNames = []; | |
391 | foreach ($this->colors as $colorPrefix => $colors) { | |
392 | foreach ($colors as $color) { | |
393 | $colorNames[] = $colorPrefix . ucfirst($color); | |
394 | } | |
395 | } | |
396 | } | |
397 | ||
6c80f0df AE |
398 | // get available variables |
399 | $sql = "SELECT variableName | |
400 | FROM wcf".WCF_N."_style_variable"; | |
401 | $statement = WCF::getDB()->prepareStatement($sql); | |
402 | $statement->execute(); | |
cd975610 | 403 | $variables = $statement->fetchAll(\PDO::FETCH_COLUMN); |
6c80f0df | 404 | |
bfbc0267 AE |
405 | $lines = explode("\n", StringUtil::unifyNewlines($this->variables[$variableName])); |
406 | $regEx = new Regex('^\$([a-zA-Z]+):\s*([@a-zA-Z0-9 ,\.\(\)\%\#-]+);$'); | |
954d51cf | 407 | $errors = []; |
6c80f0df AE |
408 | foreach ($lines as $index => &$line) { |
409 | $line = StringUtil::trim($line); | |
410 | ||
411 | // ignore empty lines | |
412 | if (empty($line)) { | |
413 | unset($lines[$index]); | |
414 | continue; | |
415 | } | |
416 | ||
417 | if ($regEx->match($line)) { | |
418 | $matches = $regEx->getMatches(); | |
419 | ||
420 | // cannot override variables covered by style editor | |
bfbc0267 | 421 | if (in_array($matches[1], $colorNames) || in_array($matches[1], $this->globals) || in_array($matches[1], $this->specialVariables)) { |
954d51cf | 422 | $errors[] = [ |
6c80f0df AE |
423 | 'error' => 'predefined', |
424 | 'text' => $matches[1] | |
954d51cf | 425 | ]; |
6c80f0df AE |
426 | } |
427 | else if (!in_array($matches[1], $variables)) { | |
428 | // unknown style variable | |
954d51cf | 429 | $errors[] = [ |
6c80f0df AE |
430 | 'error' => 'unknown', |
431 | 'text' => $matches[1] | |
954d51cf | 432 | ]; |
6c80f0df | 433 | } |
393e18c5 MS |
434 | else { |
435 | $this->variables[$matches[1]] = $matches[2]; | |
436 | } | |
6c80f0df AE |
437 | } |
438 | else { | |
439 | // not valid | |
954d51cf | 440 | $errors[] = [ |
063bbf46 | 441 | 'error' => 'invalid', |
6c80f0df | 442 | 'text' => $line |
954d51cf | 443 | ]; |
6c80f0df AE |
444 | } |
445 | } | |
446 | ||
bfbc0267 | 447 | $this->variables[$variableName] = implode("\n", $lines); |
6c80f0df AE |
448 | |
449 | if (!empty($errors)) { | |
bfbc0267 | 450 | throw new UserInputException($variableName, $errors); |
6c80f0df AE |
451 | } |
452 | } | |
453 | ||
454 | /** | |
0fcfe5f6 | 455 | * @inheritDoc |
6c80f0df AE |
456 | */ |
457 | public function readData() { | |
458 | parent::readData(); | |
459 | ||
460 | // parse global (unit) variables | |
461 | foreach ($this->globals as $variableName) { | |
0347920c MW |
462 | if (preg_match('/(.*?)(' . implode('|', $this->availableUnits) . ')$/', $this->variables[$variableName], $match)) { |
463 | $this->variables[$variableName] = $match[1]; | |
464 | $this->variables[$variableName.'_unit'] = $match[2]; | |
6c80f0df AE |
465 | } |
466 | } | |
467 | ||
468 | if (empty($_POST)) { | |
ecc35380 | 469 | $this->setDefaultValues(); |
6c80f0df AE |
470 | } |
471 | } | |
472 | ||
473 | /** | |
474 | * Sets available variables | |
475 | */ | |
476 | protected function setVariables() { | |
f2b50825 | 477 | $this->colorCategories = [ |
f6fc939a | 478 | 'wcfHeader' => ['wcfHeader', 'wcfHeaderSearchBox', 'wcfHeaderMenu', 'wcfHeaderMenuDropdown'], |
f2b50825 | 479 | 'wcfNavigation' => 'wcfNavigation', |
1223c43c | 480 | 'wcfSidebar' => ['wcfSidebar', 'wcfSidebarDimmed', 'wcfSidebarHeadline'], |
811f5a93 | 481 | 'wcfContent' => ['wcfContent', 'wcfContentContainer', 'wcfContentDimmed', 'wcfContentHeadline'], |
f2b50825 AE |
482 | 'wcfTabularBox' => 'wcfTabularBox', |
483 | 'wcfInput' => ['wcfInput', 'wcfInputDisabled'], | |
484 | 'wcfButton' => ['wcfButton', 'wcfButtonPrimary', 'wcfButtonDisabled'], | |
aa893dd8 | 485 | 'wcfEditor' =>'wcfEditorButton', |
f2b50825 | 486 | 'wcfDropdown' => 'wcfDropdown', |
1223c43c | 487 | 'wcfStatus' => ['wcfStatusInfo', 'wcfStatusSuccess', 'wcfStatusWarning', 'wcfStatusError'], |
f2b50825 | 488 | 'wcfFooterBox' => ['wcfFooterBox', 'wcfFooterBoxHeadline'], |
a785e6a7 | 489 | 'wcfFooter' => ['wcfFooter', 'wcfFooterHeadline', 'wcfFooterCopyright'] |
954d51cf | 490 | ]; |
f2b50825 | 491 | |
954d51cf | 492 | $this->colors = [ |
55b402a0 | 493 | 'wcfHeader' => ['background', 'text', 'link', 'linkActive'], |
fee45149 | 494 | 'wcfHeaderSearchBox' => ['background', 'text', 'placeholder', 'placeholderActive', 'backgroundActive', 'textActive'], |
0aabd40b | 495 | 'wcfHeaderMenu' => ['background', 'linkBackground', 'linkBackgroundActive', 'link', 'linkActive'], |
5f56200a | 496 | 'wcfHeaderMenuDropdown' => ['background', 'link', 'backgroundActive', 'linkActive'], |
f2b50825 AE |
497 | 'wcfNavigation' => ['background', 'text', 'link', 'linkActive'], |
498 | 'wcfSidebar' => ['background', 'text', 'link', 'linkActive'], | |
1223c43c | 499 | 'wcfSidebarDimmed' => ['text', 'link', 'linkActive'], |
f2b50825 | 500 | 'wcfSidebarHeadline' => ['text', 'link', 'linkActive'], |
1223c43c | 501 | 'wcfContent' => ['background', 'border', 'borderInner', 'text', 'link', 'linkActive'], |
811f5a93 | 502 | 'wcfContentContainer' => ['background', 'border'], |
1223c43c | 503 | 'wcfContentDimmed' => ['text', 'link', 'linkActive'], |
f2b50825 | 504 | 'wcfContentHeadline' => ['border', 'text', 'link', 'linkActive'], |
b3ac08d1 | 505 | 'wcfTabularBox' => ['borderInner', 'headline', 'backgroundActive', 'headlineActive'], |
7a9ba67e | 506 | 'wcfInput' => ['label', 'background', 'border', 'text', 'placeholder', 'placeholderActive', 'backgroundActive', 'borderActive', 'textActive'], |
f2b50825 | 507 | 'wcfInputDisabled' => ['background', 'border', 'text'], |
640a8bea MW |
508 | 'wcfButton' => ['background', 'text', 'backgroundActive', 'textActive'], |
509 | 'wcfButtonPrimary' => ['background', 'text', 'backgroundActive', 'textActive'], | |
510 | 'wcfButtonDisabled' => ['background', 'text'], | |
aa893dd8 | 511 | 'wcfEditorButton' => ['background', 'backgroundActive', 'text', 'textActive', 'textDisabled'], |
640a8bea | 512 | 'wcfDropdown' => ['background', 'borderInner', 'text', 'link', 'backgroundActive', 'linkActive'], |
1223c43c AE |
513 | 'wcfStatusInfo' => ['background', 'border', 'text', 'link', 'linkActive'], |
514 | 'wcfStatusSuccess' => ['background', 'border', 'text', 'link', 'linkActive'], | |
515 | 'wcfStatusWarning' => ['background', 'border', 'text', 'link', 'linkActive'], | |
516 | 'wcfStatusError' => ['background', 'border', 'text', 'link', 'linkActive'], | |
f2b50825 AE |
517 | 'wcfFooterBox' => ['background', 'text', 'link', 'linkActive'], |
518 | 'wcfFooterBoxHeadline' => ['text', 'link', 'linkActive'], | |
a785e6a7 MW |
519 | 'wcfFooter' => ['background', 'text', 'link', 'linkActive'], |
520 | 'wcfFooterHeadline' => ['text', 'link', 'linkActive'], | |
521 | 'wcfFooterCopyright' => ['background', 'text', 'link', 'linkActive'] | |
954d51cf | 522 | ]; |
f2b50825 | 523 | |
6c80f0df | 524 | // set global variables |
954d51cf | 525 | $this->globals = [ |
b3ac08d1 AE |
526 | 'wcfFontSizeSmall', |
527 | 'wcfFontSizeDefault', | |
528 | 'wcfFontSizeHeadline', | |
f6fc939a | 529 | 'wcfFontSizeSection', |
b3ac08d1 AE |
530 | 'wcfFontSizeTitle', |
531 | ||
6c80f0df | 532 | 'wcfLayoutFixedWidth', |
a78137a1 MW |
533 | 'wcfLayoutMinWidth', |
534 | 'wcfLayoutMaxWidth' | |
954d51cf | 535 | ]; |
6c80f0df AE |
536 | |
537 | // set specialized variables | |
954d51cf | 538 | $this->specialVariables = [ |
97ec0367 MW |
539 | 'individualScss', |
540 | 'overrideScss', | |
6c80f0df | 541 | 'pageLogo', |
4a292263 MW |
542 | 'pageLogoWidth', |
543 | 'pageLogoHeight', | |
544 | 'pageLogoMobile', | |
a0fe7466 | 545 | 'useFluidLayout', |
b3ac08d1 AE |
546 | 'useGoogleFont', |
547 | 'wcfFontFamilyGoogle', | |
548 | 'wcfFontFamilyFallback' | |
954d51cf | 549 | ]; |
6c80f0df AE |
550 | |
551 | EventHandler::getInstance()->fireAction($this, 'setVariables'); | |
552 | } | |
553 | ||
554 | /** | |
555 | * Reads style variable values. | |
556 | */ | |
557 | protected function readStyleVariables() { | |
558 | $sql = "SELECT variableName, defaultValue | |
559 | FROM wcf".WCF_N."_style_variable"; | |
560 | $statement = WCF::getDB()->prepareStatement($sql); | |
561 | $statement->execute(); | |
0557bb04 | 562 | $this->variables = $statement->fetchMap('variableName', 'defaultValue'); |
6c80f0df AE |
563 | } |
564 | ||
565 | /** | |
0fcfe5f6 | 566 | * @inheritDoc |
6c80f0df AE |
567 | */ |
568 | public function save() { | |
569 | parent::save(); | |
570 | ||
954d51cf AE |
571 | $this->objectAction = new StyleAction([], 'create', [ |
572 | 'data' => array_merge($this->additionalFields, [ | |
6c80f0df AE |
573 | 'styleName' => $this->styleName, |
574 | 'templateGroupID' => $this->templateGroupID, | |
90b4b964 | 575 | 'packageName' => $this->packageName, |
aa5fecb3 | 576 | 'isDisabled' => 1, // styles are disabled by default |
90b4b964 | 577 | 'isTainted' => 1, |
aa5fecb3 | 578 | 'styleDescription' => '', |
6c80f0df AE |
579 | 'styleVersion' => $this->styleVersion, |
580 | 'styleDate' => $this->styleDate, | |
581 | 'imagePath' => $this->imagePath, | |
582 | 'copyright' => $this->copyright, | |
583 | 'license' => $this->license, | |
584 | 'authorName' => $this->authorName, | |
811f5a93 AE |
585 | 'authorURL' => $this->authorURL, |
586 | 'apiVersion' => $this->apiVersion | |
954d51cf | 587 | ]), |
6c80f0df AE |
588 | 'tmpHash' => $this->tmpHash, |
589 | 'variables' => $this->variables | |
954d51cf | 590 | ]); |
aa5fecb3 AE |
591 | $returnValues = $this->objectAction->executeAction(); |
592 | $style = $returnValues['returnValues']; | |
593 | ||
594 | // save style description | |
595 | I18nHandler::getInstance()->save('styleDescription', 'wcf.style.styleDescription'.$style->styleID, 'wcf.style'); | |
596 | ||
597 | $styleEditor = new StyleEditor($style); | |
954d51cf | 598 | $styleEditor->update([ |
aa5fecb3 | 599 | 'styleDescription' => 'wcf.style.styleDescription'.$style->styleID |
954d51cf | 600 | ]); |
6c80f0df AE |
601 | |
602 | // call saved event | |
603 | $this->saved(); | |
604 | ||
605 | // reset variables | |
4a292263 | 606 | $this->authorName = $this->authorURL = $this->copyright = $this->packageName = ''; |
6c80f0df | 607 | $this->license = $this->styleDate = $this->styleDescription = $this->styleName = $this->styleVersion = ''; |
ecc35380 | 608 | $this->setDefaultValues(); |
6c80f0df | 609 | $this->imagePath = 'images/'; |
90b4b964 | 610 | $this->isTainted = true; |
6c80f0df AE |
611 | $this->templateGroupID = 0; |
612 | ||
d59c86bd AE |
613 | I18nHandler::getInstance()->reset(); |
614 | ||
6c80f0df AE |
615 | // reload variables |
616 | $this->readStyleVariables(); | |
617 | ||
618 | WCF::getTPL()->assign('success', true); | |
619 | } | |
620 | ||
621 | /** | |
0fcfe5f6 | 622 | * @inheritDoc |
6c80f0df AE |
623 | */ |
624 | public function assignVariables() { | |
625 | parent::assignVariables(); | |
626 | ||
aa5fecb3 AE |
627 | I18nHandler::getInstance()->assignVariables(); |
628 | ||
954d51cf | 629 | WCF::getTPL()->assign([ |
6c80f0df | 630 | 'action' => 'add', |
811f5a93 | 631 | 'apiVersion' => $this->apiVersion, |
6c80f0df AE |
632 | 'authorName' => $this->authorName, |
633 | 'authorURL' => $this->authorURL, | |
634 | 'availableFontFamilies' => $this->availableFontFamilies, | |
635 | 'availableTemplateGroups' => $this->availableTemplateGroups, | |
636 | 'availableUnits' => $this->availableUnits, | |
f2b50825 | 637 | 'colorCategories' => $this->colorCategories, |
954d51cf | 638 | 'colors' => $this->colors, |
6c80f0df | 639 | 'copyright' => $this->copyright, |
6c80f0df | 640 | 'imagePath' => $this->imagePath, |
90b4b964 | 641 | 'isTainted' => $this->isTainted, |
6c80f0df | 642 | 'license' => $this->license, |
90b4b964 | 643 | 'packageName' => $this->packageName, |
811f5a93 | 644 | 'recommendedApiVersion' => Style::API_VERSION, |
6c80f0df AE |
645 | 'styleDate' => $this->styleDate, |
646 | 'styleDescription' => $this->styleDescription, | |
647 | 'styleName' => $this->styleName, | |
648 | 'styleVersion' => $this->styleVersion, | |
649 | 'templateGroupID' => $this->templateGroupID, | |
650 | 'tmpHash' => $this->tmpHash, | |
811f5a93 AE |
651 | 'variables' => $this->variables, |
652 | 'supportedApiVersions' => Style::$supportedApiVersions, | |
653 | 'newVariables' => $this->newVariables | |
954d51cf | 654 | ]); |
6c80f0df | 655 | } |
ecc35380 MW |
656 | |
657 | protected function setDefaultValues() { | |
658 | $this->authorName = WCF::getUser()->username; | |
659 | $this->styleDate = gmdate('Y-m-d', TIME_NOW); | |
660 | $this->styleVersion = '1.0.0'; | |
661 | } | |
6c80f0df | 662 | } |