Add update script for style cleanup
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 4 Aug 2020 13:07:31 +0000 (15:07 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 4 Aug 2020 13:08:08 +0000 (15:08 +0200)
Resolves #3468

com.woltlab.wcf/package.xml
wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php [new file with mode: 0644]

index dec2c8c9bdcce2354c47c7dc5085451fe7351592..0ed0160dee53cbe3f68d7259c13b0aaf13909a01 100644 (file)
@@ -53,6 +53,7 @@
        <instructions type="update" fromversion="5.2.*">
                <!-- Delete wcfsetup/install/files/lib/form/MailForm.class.php during the upgrade to make it 100% non-functional. -->
                <!-- Remove useGoogleFont style variable. -->
+               <!-- Run update_com.woltlab.wcf_5.3_style.php -->
        </instructions>
 
        <instructions type="update" fromversion="3.1.*">
diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.3_style.php
new file mode 100644 (file)
index 0000000..95a2bcb
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+require('global.php');
+
+use wcf\data\style\StyleEditor;
+use wcf\data\style\StyleList;
+use wcf\util\FileUtil;
+
+/**
+ * @author     Tim Duesterhus
+ * @copyright  2001-2020 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    WoltLabSuite\Core
+ */
+
+$styleList = new StyleList();
+$styleList->readObjects();
+
+foreach ($styleList as $style) {
+       $style->loadVariables();
+       $variables = $style->getVariables();
+       $styleEditor = new StyleEditor($style);
+       
+       
+       // 1) Move existing asset path folder out of the way.
+       // It's unlikely that one exists, but having an existing folder will create a small mess.
+       if (file_exists($style->getAssetPath())) {
+               rename($style->getAssetPath(), FileUtil::removeTrailingSlash($style->getAssetPath()) . '.old53/');
+       }
+       
+       // 2) Create asset folder.
+       FileUtil::makePath($style->getAssetPath());
+       
+       // 3) If the file had a custom image folder we need to copy all files into the asset folder.
+       // Moving the files is unsafe, because multiple styles can share a single image folder.
+       if ($style->imagePath != 'images/') {
+               $srcPath = FileUtil::addTrailingSlash(WCF_DIR.$style->imagePath);
+               if ($srcPath == $style->getAssetPath()) {
+                       $srcPath = FileUtil::removeTrailingSlash($style->getAssetPath()) . '.old53/';
+               }
+               
+               $iterator = new \RecursiveIteratorIterator(
+                       new \RecursiveDirectoryIterator(
+                               $srcPath,
+                               \FilesystemIterator::SKIP_DOTS
+                       ), 
+                       \RecursiveIteratorIterator::SELF_FIRST
+               );
+               foreach ($iterator as $file) {
+                       /** @var \SplFileInfo $file */
+                       if (!$file->isFile()) continue;
+                       
+                       $relative = FileUtil::getRelativePath($srcPath, $file->getPath());
+                       FileUtil::makePath($style->getAssetPath() . $relative);
+                       copy($file->getPathname(), $style->getAssetPath() . $relative . $file->getBasename());
+               }
+       }
+       $styleEditor->update([
+               'imagePath' => 'images/style-' . $style->styleID . '/',
+       ]);
+       
+       // 4) Copy style previews into the asset folder.
+       // Moving *should* be safe here, unless the admin manually edited the style, but better play safe.
+       if ($style->image && file_exists(WCF_DIR . 'images/' . $style->image)) {
+               $extension = pathinfo($style->image, PATHINFO_EXTENSION);
+               copy(
+                       WCF_DIR . 'images/' . $style->image,
+                       $style->getAssetPath() . 'stylePreview.' . $extension
+               );
+               $styleEditor->update([
+                       'image' => 'stylePreview.' . $extension,
+               ]);
+       }
+
+       if ($style->image2x && file_exists(WCF_DIR . 'images/' . $style->image2x)) {
+               $extension = pathinfo($style->image2x, PATHINFO_EXTENSION);
+               copy(
+                       WCF_DIR . 'images/' . $style->image2x,
+                       $style->getAssetPath() . 'stylePreview@2x.' . $extension
+               );
+               $styleEditor->update([
+                       'image2x' => 'stylePreview@2x.' . $extension,
+               ]);
+       }
+       
+       // 5) Copy coverPhotos into the asset folder.
+       // Moving is safe here, but for consistency we are copying.
+       if (file_exists(WCF_DIR . 'images/coverPhotos/' . $style->styleID . '.' . $style->coverPhotoExtension)) {
+               copy(
+                       WCF_DIR . 'images/coverPhotos/' . $style->styleID . '.' . $style->coverPhotoExtension,
+                       $style->getAssetPath() . 'coverPhoto.' . $style->coverPhotoExtension
+               );
+       }
+       
+       // 6) Copy favicon related files into the asset folder.
+       // Moving is safe here, but for consistency we are copying.
+       foreach ([
+               'android-chrome-192x192.png',
+               'android-chrome-256x256.png',
+               'apple-touch-icon.png',
+               'browserconfig.xml',
+               'favicon.ico',
+               'favicon-template.png',
+               'manifest.json',
+               'mstile-150x150.png',
+       ] as $filename) {
+               if (file_exists(WCF_DIR . 'images/favicon/' . $style->styleID . '.' . $filename)) {
+                       copy(
+                               WCF_DIR . 'images/favicon/' . $style->styleID . '.' . $filename,
+                               $style->getAssetPath() . $filename
+                       );
+               }
+       }
+       
+       // 7) Copy styleLogo.
+       // Moving is unsafe, we cannot even guarantee that the logo is a file on the local filesystem.
+       foreach (['pageLogo', 'pageLogoMobile'] as $type) {
+               if (empty($variables[$type])) continue;
+               $srcPath = WCF_DIR . 'images/' . $variables[$type];
+               if (!file_exists($srcPath)) {
+                       $srcPath = WCF_DIR . $style->imagePath . '/' . $style->getVariable($type);
+                       if (!file_exists($srcPath)) {
+                               continue;
+                       }
+               }
+               copy(
+                       $srcPath,
+                       $style->getAssetPath() . basename($srcPath)
+               );
+               $variables[$type] = basename($srcPath);
+       }
+       $styleEditor->setVariables($variables);
+}