Add upload for custom style assets
authorTim Düsterhus <duesterhus@woltlab.com>
Wed, 5 Aug 2020 13:34:58 +0000 (15:34 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Wed, 5 Aug 2020 13:34:58 +0000 (15:34 +0200)
Resolves #3364

wcfsetup/install/files/acp/templates/styleAdd.tpl
wcfsetup/install/files/lib/acp/form/StyleAddForm.class.php
wcfsetup/install/files/lib/acp/form/StyleEditForm.class.php
wcfsetup/install/files/lib/data/style/StyleAction.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 58e682c54b96a67a144e6663fa43f522299ab124..6c1663876c2a3a4c6589b6b9772d22313c4feb77 100644 (file)
                                        </dl>
                                {/if}
                                
+                               <dl{if $errorField == 'customAssets'} class="formError"{/if}>
+                                       <dt><label for="customAssets">{lang}wcf.acp.style.customAssets{/lang}</label></dt>
+                                       <dd>
+                                               {@$__wcf->getUploadHandler()->renderField('customAssets')}
+                                               {if $errorField == 'customAssets'}
+                                                       <small class="innerError">
+                                                               {if $errorType == 'empty'}
+                                                                       {lang}wcf.global.form.error.empty{/lang}
+                                                               {else}
+                                                                       {lang}wcf.acp.style.customAssets.error.{$errorType}{/lang}
+                                                               {/if}
+                                                       </small>
+                                               {/if}
+                                               <small>{lang}wcf.acp.style.customAssets.description{/lang}</small>
+                                       </dd>
+                               </dl>
+                               
                                {event name='fileFields'}
                        </section>
                        
index d29a6a73279ca7aec4d417436d4750ab753e4e29..5fc9d0275801a87b05f2a729cc4e77617e73e2c3 100644 (file)
@@ -206,11 +206,17 @@ class StyleAddForm extends AbstractForm {
        public $scrollOffsets = [];
        
        /**
-        * @var mixed[]
+        * @var (null|UploadFile)[]
         * @since 5.3
         */
        public $uploads = [];
        
+       /**
+        * @var UploadFile[]
+        * @since 5.3
+        */
+       public $customAssets = [];
+       
        /**
         * @inheritDoc
         */
@@ -297,6 +303,13 @@ class StyleAddForm extends AbstractForm {
                        $field->maxFiles = 1;
                        $handler->registerUploadField($field);
                }
+               
+               // This field is special cased, because it may contain arbitrary data.
+               $field = new UploadField('customAssets');
+               $field->setImageOnly(true);
+               $field->setAllowSvgImage(true);
+               $field->maxFiles = null;
+               $handler->registerUploadField($field);
        }
        
        /**
@@ -372,6 +385,12 @@ class StyleAddForm extends AbstractForm {
                                $this->uploads[$field] = $files[0];
                        }
                }
+               
+               $this->customAssets = [
+                       'removed' => UploadHandler::getInstance()->getRemovedFiledByFieldId('customAssets'),
+                       'added' => UploadHandler::getInstance()->getFilesByFieldId('customAssets'),
+               ];
+               
        }
        
        /**
@@ -754,8 +773,9 @@ class StyleAddForm extends AbstractForm {
                                'apiVersion' => $this->apiVersion
                        ]),
                        'uploads' => $this->uploads,
+                       'customAssets' => $this->customAssets,
                        'tmpHash' => $this->tmpHash,
-                       'variables' => $this->variables
+                       'variables' => $this->variables,
                ]);
                $returnValues = $this->objectAction->executeAction();
                $style = $returnValues['returnValues'];
index 8e262b0afc6b8da7f519261131d8f4ce1c9fa026..ba45bbc34d0f679727b8ff7911ed692fb7aa9d9d 100644 (file)
@@ -181,8 +181,11 @@ class StyleEditForm extends StyleAddForm {
                                                break;
                                        }
                                }
-                               
                        }
+                       
+                       UploadHandler::getInstance()->registerFilesByField('customAssets', array_map(function ($filename) {
+                               return new UploadFile($filename, basename($filename), false, true, true);
+                       }, glob($this->style->getAssetPath().'custom/*')));
                }
        }
        
@@ -217,8 +220,9 @@ class StyleEditForm extends StyleAddForm {
                                'apiVersion' => $this->apiVersion
                        ]),
                        'uploads' => $this->uploads,
+                       'customAssets' => $this->customAssets,
                        'tmpHash' => $this->tmpHash,
-                       'variables' => $this->variables
+                       'variables' => $this->variables,
                ]);
                $this->objectAction->executeAction();
                
index ec0878bdd84fab240a3d3c0543cb096fde8fa610..0d7915767ad8e4729051d98467cde7cf43e1c01d 100644 (file)
@@ -86,7 +86,10 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction
                
                // handle the cover photo
                $this->updateCoverPhoto($style);
-
+                       
+               // handle custom assets
+               $this->updateCustomAssets($style);
+               
                return $style;
        }
        
@@ -109,6 +112,9 @@ class StyleAction extends AbstractDatabaseObjectAction implements IToggleAction
                        // handle the cover photo
                        $this->updateCoverPhoto($style->getDecoratedObject());
                        
+                       // handle custom assets
+                       $this->updateCustomAssets($style->getDecoratedObject());
+                       
                        // reset stylesheet
                        StyleHandler::getInstance()->resetStylesheet($style->getDecoratedObject());
                }
@@ -443,6 +449,31 @@ BROWSERCONFIG;
                }
        }
        
+       /**
+        * @since       5.2
+        */
+       protected function updateCustomAssets(Style $style) {
+               $customAssetPath = $style->getAssetPath().'custom/';
+               
+               if (!empty($this->parameters['customAssets']['removed'])) {
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       foreach ($this->parameters['customAssets']['removed'] as $file) {
+                               unlink($file->getLocation());
+                       }
+               }
+               if (!empty($this->parameters['customAssets']['added'])) {
+                       if (!is_dir($customAssetPath)) {
+                               FileUtil::makePath($customAssetPath);
+                       }
+                       
+                       /** @var \wcf\system\file\upload\UploadFile $file */
+                       foreach ($this->parameters['customAssets']['added'] as $file) {
+                               rename($file->getLocation(), $customAssetPath.$file->getFilename());
+                               $file->setProcessed($customAssetPath.$file->getFilename());
+                       }
+               }
+       }
+       
        /**
         * Validates parameters to assign a new default style.
         */
index 7dabd27ccf196a9b461cdc8051ae86a89e92e7e3..0a8d7485fe026871f7d16b7dc57273a0d1a35ca8 100644 (file)
@@ -2878,6 +2878,8 @@ Kein Abschnitt darf leer sein und alle Abschnitten dürfen nur folgende Zeichen
                <item name="wcf.acp.style.coverPhoto"><![CDATA[Standard-Titelbild]]></item>
                <item name="wcf.acp.style.coverPhoto.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} das Standard-Titelbild dieses Stils wirklich löschen? Nach dem Löschen wird das allgemeine, Stil-unabhängige Standard-Titelbild verwendet.]]></item>
                <item name="wcf.acp.style.coverPhoto.description"><![CDATA[Das Bild muss mindestens {$coverPhotoMinWidth}×{$coverPhotoMinHeight} Pixel groß sein, als Bildformate sind GIF, JPG, JPEG und PNG zulässig.]]></item>
+               <item name="wcf.acp.style.customAssets"><![CDATA[Zusätzliche Bilder]]></item>
+               <item name="wcf.acp.style.customAssets.description"><![CDATA[{literal}Die hochgeladenen Bilder werden im <kbd>custom/</kbd>-Ordner innerhalb des <kbd>#{$style_image_path}</kbd> gespeichert.{/literal}]]></item>
                <item name="wcf.acp.style.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Stil <span class="confirmationObject">{$style->styleName}</span> wirklich löschen?]]></item>
                <item name="wcf.acp.style.edit"><![CDATA[Stil bearbeiten]]></item>
                <item name="wcf.acp.style.exportAsPackage"><![CDATA[Als Paket exportieren]]></item>
index d45d82840826adca593c6996227d3fe1be617cfc..9ab54b07a0f29f5a95cd647952a0cc28c4d93cd9 100644 (file)
@@ -2805,6 +2805,8 @@ If you have <strong>already bought the licenses for the listed apps</strong>, th
                <item name="wcf.acp.style.coverPhoto"><![CDATA[Default Cover Photo]]></item>
                <item name="wcf.acp.style.coverPhoto.delete.confirmMessage"><![CDATA[Do you really want to delete the default cover photo? Once deleted, the global default photo will be used instead.]]></item>
                <item name="wcf.acp.style.coverPhoto.description"><![CDATA[The image must be at least {$coverPhotoMinWidth}×{$coverPhotoMinHeight} pixels large, acceptable image types are GIF, JPG, JPEG and PNG.]]></item>
+               <item name="wcf.acp.style.customAssets"><![CDATA[Additional Images]]></item>
+               <item name="wcf.acp.style.customAssets.description"><![CDATA[{literal}The uploaded images will be stored within the <kbd>custom/</kbd> folder within the <kbd>#{$style_image_path}</kbd>.{/literal}]]></item>
                <item name="wcf.acp.style.delete.confirmMessage"><![CDATA[Do you really want to delete the style <span class="confirmationObject">{$style->styleName}</span>?]]></item>
                <item name="wcf.acp.style.edit"><![CDATA[Edit Style]]></item>
                <item name="wcf.acp.style.exportAsPackage"><![CDATA[Export as package]]></item>