Fix typo in avatar condition in UserRebuildDataWorker
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / worker / UserRebuildDataWorker.class.php
index 009fb72a184f55747676c766487f85aa770b695c..f55276b0ce9b403cdbd3332cb16de09e075e5acb 100644 (file)
@@ -1,5 +1,7 @@
 <?php
+
 namespace wcf\system\worker;
+
 use wcf\data\reaction\type\ReactionTypeCache;
 use wcf\data\user\avatar\UserAvatar;
 use wcf\data\user\avatar\UserAvatarEditor;
@@ -17,219 +19,266 @@ use wcf\system\WCF;
 
 /**
  * Worker implementation for updating users.
- * 
- * @author     Marcel Werk
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\System\Worker
- * 
- * @method     UserList        getObjectList()
+ *
+ * @author  Marcel Werk
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Worker
+ *
+ * @method  UserList    getObjectList()
  */
-class UserRebuildDataWorker extends AbstractRebuildDataWorker {
-       /**
-        * @inheritDoc
-        */
-       protected $objectListClassName = UserList::class;
-       
-       /**
-        * @inheritDoc
-        */
-       protected $limit = 50;
-       
-       /**
-        * @inheritDoc
-        */
-       protected function initObjectList() {
-               parent::initObjectList();
-               
-               $this->objectList->sqlSelects = 'user_option_value.userOption' . User::getUserOptionID('aboutMe') . ' AS aboutMe';
-               $this->objectList->sqlJoins = "LEFT JOIN wcf".WCF_N."_user_option_value user_option_value ON (user_option_value.userID = user_table.userID)";
-               $this->objectList->sqlOrderBy = 'user_table.userID';
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function execute() {
-               parent::execute();
-               
-               $users = $userIDs = [];
-               foreach ($this->getObjectList() as $user) {
-                       $users[] = new UserEditor($user);
-                       $userIDs[] = $user->userID;
-               }
-               
-               // update user ranks
-               if (!empty($users)) {
-                       $action = new UserProfileAction($users, 'updateUserOnlineMarking');
-                       $action->executeAction();
-               }
-               
-               if (!empty($userIDs)) {
-                       // update article counter
-                       $conditionBuilder = new PreparedStatementConditionBuilder();
-                       $conditionBuilder->add('user_table.userID IN (?)', [$userIDs]);
-                       $sql = "UPDATE  wcf".WCF_N."_user user_table
-                               SET     articles = (
-                                               SELECT  COUNT(*)
-                                               FROM    wcf".WCF_N."_article
-                                               WHERE   userID = user_table.userID
-                                       )
-                               ".$conditionBuilder;
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       $statement->execute($conditionBuilder->getParameters());
-                       
-                       // update like counter
-                       if (MODULE_LIKE) {
-                               $sql = "UPDATE  wcf".WCF_N."_user user_table SET";
-                               
-                               $reactionTypeIDs = array_keys(ReactionTypeCache::getInstance()->getReactionTypes());
-                               if (!empty($reactionTypeIDs)) {
-                                       $sql .= " likesReceived = (
-                                                       SELECT  COUNT(*)
-                                                       FROM    wcf".WCF_N."_like
-                                                       WHERE   objectUserID = user_table.userID
-                                                               AND reactionTypeID IN (". implode(',', $reactionTypeIDs) .")
-                                               )";
-                               }
-                               else {
-                                       $sql .= " likesReceived = 0";
-                               }
-                               
-                               $sql .= " ".$conditionBuilder;
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute($conditionBuilder->getParameters());
-                       }
-                       
-                       // update trophy points
-                       if (MODULE_TROPHY) {
-                               $sql = "UPDATE  wcf".WCF_N."_user user_table
-                                       SET     trophyPoints = (
-                                                       SELECT          COUNT(*)
-                                                       FROM            wcf".WCF_N."_user_trophy user_trophy
-                                                       LEFT JOIN       wcf".WCF_N."_trophy trophy ON user_trophy.trophyID = trophy.trophyID
-                                                       LEFT JOIN       wcf".WCF_N."_category trophy_category ON trophy.categoryID = trophy_category.categoryID
-                                                       WHERE           user_trophy.userID = user_table.userID
-                                                                       AND trophy.isDisabled = 0
-                                                                       AND trophy_category.isDisabled = 0
-                                               )
-                                       ".$conditionBuilder;
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute($conditionBuilder->getParameters());
-                       }
-                       
-                       // update signatures and about me
-                       $sql = "UPDATE  wcf".WCF_N."_user_option_value
-                               SET     userOption" . User::getUserOptionID('aboutMe') . " = ?
-                               WHERE   userID = ?";
-                       $statement = WCF::getDB()->prepareStatement($sql);
-                       
-                       // retrieve permissions
-                       $userIDs = [];
-                       foreach ($users as $user) {
-                               $userIDs[] = $user->userID;
-                       }
-                       $userPermissions = $this->getBulkUserPermissions($userIDs, ['user.message.disallowedBBCodes', 'user.signature.disallowedBBCodes']);
-                       
-                       $htmlInputProcessor = new HtmlInputProcessor();
-                       WCF::getDB()->beginTransaction();
-                       /** @var UserEditor $user */
-                       foreach ($users as $user) {
-                               BBCodeHandler::getInstance()->setDisallowedBBCodes(explode(',', $this->getBulkUserPermissionValue($userPermissions, $user->userID, 'user.signature.disallowedBBCodes')));
-                               
-                               if (!$user->signatureEnableHtml) {
-                                       $htmlInputProcessor->process($user->signature, 'com.woltlab.wcf.user.signature', $user->userID, true);
-                                       
-                                       $user->update([
-                                               'signature' => $htmlInputProcessor->getHtml(),
-                                               'signatureEnableHtml' => 1
-                                       ]);
-                               }
-                               else {
-                                       $htmlInputProcessor->reprocess($user->signature, 'com.woltlab.wcf.user.signature', $user->userID);
-                                       $user->update(['signature' => $htmlInputProcessor->getHtml()]);
-                               }
-                               
-                               if ($user->aboutMe) {
-                                       BBCodeHandler::getInstance()->setDisallowedBBCodes(explode(',', $this->getBulkUserPermissionValue($userPermissions, $user->userID, 'user.message.disallowedBBCodes')));
-                                       
-                                       if (!$user->signatureEnableHtml) {
-                                               $htmlInputProcessor->process($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID, true);
-                                       }
-                                       else {
-                                               $htmlInputProcessor->reprocess($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID);
-                                       }
-                                       
-                                       $html = $htmlInputProcessor->getHtml();
-                                       // MySQL's TEXT type allows for 65,535 bytes, hence we need to count
-                                       // the bytes rather than the actual amount of characters
-                                       if (strlen($html) > 65535) {
-                                               // content does not fit the available space, and any
-                                               // attempts to truncate it will yield awkward results
-                                               $html = '';
-                                       }
-                                       
-                                       $statement->execute([$html, $user->userID]);
-                               }
-                       }
-                       WCF::getDB()->commitTransaction();
-                       
-                       // update old/imported avatars
-                       $avatarList = new UserAvatarList();
-                       $avatarList->getConditionBuilder()->add('user_avatar.userID IN (?)', [$userIDs]);
-                       $avatarList->getConditionBuilder()->add('(user_avatar.width <> ? OR user_avatar.height <> ?)', [UserAvatar::AVATAR_SIZE, UserAvatar::AVATAR_SIZE]);
-                       $avatarList->readObjects();
-                       foreach ($avatarList as $avatar) {
-                               $editor = new UserAvatarEditor($avatar);
-                               if (!file_exists($avatar->getLocation()) || @getimagesize($avatar->getLocation()) === false) {
-                                       // delete avatars that are missing or broken
-                                       $editor->delete();
-                                       continue;
-                               }
-                               
-                               $width = $avatar->width;
-                               $height = $avatar->height;
-                               if ($width != $height) {
-                                       // make avatar quadratic
-                                       $width = $height = min($width, $height, UserAvatar::AVATAR_SIZE);
-                                       $adapter = ImageHandler::getInstance()->getAdapter();
-                                       
-                                       try {
-                                               $adapter->loadFile($avatar->getLocation());
-                                       }
-                                       catch (SystemException $e) {
-                                               // broken image
-                                               $editor->delete();
-                                               continue;
-                                       }
-                                       
-                                       $thumbnail = $adapter->createThumbnail($width, $height, false);
-                                       $adapter->writeImage($thumbnail, $avatar->getLocation());
-                               }
-                               
-                               if ($width != UserAvatar::AVATAR_SIZE || $height != UserAvatar::AVATAR_SIZE) {
-                                       // resize avatar
-                                       $adapter = ImageHandler::getInstance()->getAdapter();
-                                       
-                                       try {
-                                               $adapter->loadFile($avatar->getLocation());
-                                       }
-                                       catch (SystemException $e) {
-                                               // broken image
-                                               $editor->delete();
-                                               continue;
-                                       }
-                                       
-                                       $adapter->resize(0, 0, $width, $height, UserAvatar::AVATAR_SIZE, UserAvatar::AVATAR_SIZE);
-                                       $adapter->writeImage($adapter->getImage(), $avatar->getLocation());
-                                       $width = $height = UserAvatar::AVATAR_SIZE;
-                               }
-                               
-                               $editor->update([
-                                       'width' => $width,
-                                       'height' => $height
-                               ]);
-                       }
-               }
-       }
+class UserRebuildDataWorker extends AbstractRebuildDataWorker
+{
+    /**
+     * @inheritDoc
+     */
+    protected $objectListClassName = UserList::class;
+
+    /**
+     * @inheritDoc
+     */
+    protected $limit = 50;
+
+    /**
+     * @inheritDoc
+     */
+    protected function initObjectList()
+    {
+        parent::initObjectList();
+
+        $this->objectList->sqlSelects = 'user_option_value.userOption' . User::getUserOptionID('aboutMe') . ' AS aboutMe';
+        $this->objectList->sqlJoins = "
+            LEFT JOIN   wcf" . WCF_N . "_user_option_value user_option_value
+            ON          user_option_value.userID = user_table.userID";
+        $this->objectList->sqlOrderBy = 'user_table.userID';
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function execute()
+    {
+        parent::execute();
+
+        $users = $userIDs = [];
+        foreach ($this->getObjectList() as $user) {
+            $users[] = new UserEditor($user);
+            $userIDs[] = $user->userID;
+        }
+
+        // update user ranks
+        if (!empty($users)) {
+            $action = new UserProfileAction($users, 'updateUserOnlineMarking');
+            $action->executeAction();
+        }
+
+        if (!empty($userIDs)) {
+            // update article counter
+            $conditionBuilder = new PreparedStatementConditionBuilder();
+            $conditionBuilder->add('user_table.userID IN (?)', [$userIDs]);
+            $sql = "UPDATE  wcf" . WCF_N . "_user user_table
+                    SET     articles = (
+                                SELECT  COUNT(*)
+                                FROM    wcf" . WCF_N . "_article
+                                WHERE   userID = user_table.userID
+                            )
+                    " . $conditionBuilder;
+            $statement = WCF::getDB()->prepareStatement($sql);
+            $statement->execute($conditionBuilder->getParameters());
+
+            // update like counter
+            if (MODULE_LIKE) {
+                $sql = "UPDATE  wcf" . WCF_N . "_user user_table
+                        SET";
+
+                $reactionTypeIDs = \array_keys(ReactionTypeCache::getInstance()->getReactionTypes());
+                if (!empty($reactionTypeIDs)) {
+                    $sql .= "
+                        likesReceived = (
+                            SELECT  COUNT(*)
+                            FROM    wcf" . WCF_N . "_like
+                            WHERE   objectUserID = user_table.userID
+                                AND reactionTypeID IN (" . \implode(',', $reactionTypeIDs) . ")
+                        )";
+                } else {
+                    $sql .= " likesReceived = 0";
+                }
+
+                $sql .= " " . $conditionBuilder;
+                $statement = WCF::getDB()->prepareStatement($sql);
+                $statement->execute($conditionBuilder->getParameters());
+            }
+
+            // update trophy points
+            if (MODULE_TROPHY) {
+                $sql = "UPDATE  wcf" . WCF_N . "_user user_table
+                        SET     trophyPoints = (
+                                    SELECT      COUNT(*)
+                                    FROM        wcf" . WCF_N . "_user_trophy user_trophy
+                                    LEFT JOIN   wcf" . WCF_N . "_trophy trophy
+                                    ON          user_trophy.trophyID = trophy.trophyID
+                                    LEFT JOIN   wcf" . WCF_N . "_category trophy_category
+                                    ON          trophy.categoryID = trophy_category.categoryID
+                                    WHERE           user_trophy.userID = user_table.userID
+                                                AND trophy.isDisabled = 0
+                                                AND trophy_category.isDisabled = 0
+                                )
+                        " . $conditionBuilder;
+                $statement = WCF::getDB()->prepareStatement($sql);
+                $statement->execute($conditionBuilder->getParameters());
+            }
+
+            // update signatures and about me
+            $sql = "UPDATE  wcf" . WCF_N . "_user_option_value
+                    SET     userOption" . User::getUserOptionID('aboutMe') . " = ?
+                    WHERE   userID = ?";
+            $statement = WCF::getDB()->prepareStatement($sql);
+
+            // retrieve permissions
+            $userIDs = [];
+            foreach ($users as $user) {
+                $userIDs[] = $user->userID;
+            }
+            $userPermissions = $this->getBulkUserPermissions(
+                $userIDs,
+                ['user.message.disallowedBBCodes', 'user.signature.disallowedBBCodes']
+            );
+
+            $htmlInputProcessor = new HtmlInputProcessor();
+            WCF::getDB()->beginTransaction();
+            /** @var UserEditor $user */
+            foreach ($users as $user) {
+                BBCodeHandler::getInstance()->setDisallowedBBCodes(\explode(
+                    ',',
+                    $this->getBulkUserPermissionValue(
+                        $userPermissions,
+                        $user->userID,
+                        'user.signature.disallowedBBCodes'
+                    )
+                ));
+
+                if (!$user->signatureEnableHtml) {
+                    $htmlInputProcessor->process(
+                        $user->signature,
+                        'com.woltlab.wcf.user.signature',
+                        $user->userID,
+                        true
+                    );
+
+                    $user->update([
+                        'signature' => $htmlInputProcessor->getHtml(),
+                        'signatureEnableHtml' => 1,
+                    ]);
+                } else {
+                    $htmlInputProcessor->reprocess($user->signature, 'com.woltlab.wcf.user.signature', $user->userID);
+                    $user->update(['signature' => $htmlInputProcessor->getHtml()]);
+                }
+
+                if ($user->aboutMe) {
+                    BBCodeHandler::getInstance()->setDisallowedBBCodes(\explode(
+                        ',',
+                        $this->getBulkUserPermissionValue(
+                            $userPermissions,
+                            $user->userID,
+                            'user.message.disallowedBBCodes'
+                        )
+                    ));
+
+                    if (!$user->signatureEnableHtml) {
+                        $htmlInputProcessor->process(
+                            $user->aboutMe,
+                            'com.woltlab.wcf.user.aboutMe',
+                            $user->userID,
+                            true
+                        );
+                    } else {
+                        $htmlInputProcessor->reprocess($user->aboutMe, 'com.woltlab.wcf.user.aboutMe', $user->userID);
+                    }
+
+                    $html = $htmlInputProcessor->getHtml();
+                    // MySQL's TEXT type allows for 65,535 bytes, hence we need to count
+                    // the bytes rather than the actual amount of characters
+                    if (\strlen($html) > 65535) {
+                        // content does not fit the available space, and any
+                        // attempts to truncate it will yield awkward results
+                        $html = '';
+                    }
+
+                    $statement->execute([$html, $user->userID]);
+                }
+            }
+            WCF::getDB()->commitTransaction();
+
+            // update old/imported avatars
+            $avatarList = new UserAvatarList();
+            $avatarList->getConditionBuilder()->add('user_avatar.userID IN (?)', [$userIDs]);
+            $avatarList->getConditionBuilder()->add(
+                '(
+                    (user_avatar.width <> ? OR user_avatar.height <> ?)
+                    OR (user_avatar.hasWebP = ? AND user_avatar.avatarExtension <> ?)
+                )',
+                [
+                    UserAvatar::AVATAR_SIZE,
+                    UserAvatar::AVATAR_SIZE,
+                    0,
+                    "gif",
+                ]
+            );
+            $avatarList->readObjects();
+            foreach ($avatarList as $avatar) {
+                $editor = new UserAvatarEditor($avatar);
+                if (!\file_exists($avatar->getLocation()) || @\getimagesize($avatar->getLocation()) === false) {
+                    // delete avatars that are missing or broken
+                    $editor->delete();
+                    continue;
+                }
+
+                $width = $avatar->width;
+                $height = $avatar->height;
+                if ($width != $height) {
+                    // make avatar quadratic
+                    $width = $height = \min($width, $height, UserAvatar::AVATAR_SIZE);
+                    $adapter = ImageHandler::getInstance()->getAdapter();
+
+                    try {
+                        $adapter->loadFile($avatar->getLocation());
+                    } catch (SystemException $e) {
+                        // broken image
+                        $editor->delete();
+                        continue;
+                    }
+
+                    $thumbnail = $adapter->createThumbnail($width, $height, false);
+                    $adapter->writeImage($thumbnail, $avatar->getLocation());
+                    // Clear thumbnail as soon as possible to free up the memory.
+                    $thumbnail = null;
+                }
+
+                if ($width != UserAvatar::AVATAR_SIZE || $height != UserAvatar::AVATAR_SIZE) {
+                    // resize avatar
+                    $adapter = ImageHandler::getInstance()->getAdapter();
+
+                    try {
+                        $adapter->loadFile($avatar->getLocation());
+                    } catch (SystemException $e) {
+                        // broken image
+                        $editor->delete();
+                        continue;
+                    }
+
+                    $adapter->resize(0, 0, $width, $height, UserAvatar::AVATAR_SIZE, UserAvatar::AVATAR_SIZE);
+                    $adapter->writeImage($adapter->getImage(), $avatar->getLocation());
+                    $width = $height = UserAvatar::AVATAR_SIZE;
+                }
+
+                $editor->deleteLegacyThumbnails();
+                $editor->createAvatarVariant();
+
+                $editor->update([
+                    'width' => $width,
+                    'height' => $height,
+                ]);
+            }
+        }
+    }
 }