<file>lib/system/template/plugin/TemplatePluginPrefilterIcon.class.php</file>
<file>lib/system/template/plugin/TemplatePluginPrefilterLang.class.php</file>
<file>lib/system/template/plugin/WordwrapModifierTemplatePlugin.class.php</file>
+ <file>lib/system/upload/AvatarUploadFileSaveStrategy.class.php</file>
+ <file>lib/system/upload/AvatarUploadFileValidationStrategy.class.php</file>
<file>lib/system/user/UserCollapsibleContentHandler.class.php</file>
<file>lib/system/user/activity/point/AbstractUserActivityPointObjectProcessor.class.php</file>
<file>lib/system/user/activity/point/DefaultUserActivityPointObjectProcessor.class.php</file>
namespace wcf\data\user;
use wcf\data\object\type\ObjectTypeCache;
-use wcf\data\user\avatar\UserAvatar;
-use wcf\data\user\avatar\UserAvatarAction;
-use wcf\data\user\avatar\UserAvatarEditor;
use wcf\data\user\group\UserGroup;
use wcf\system\bbcode\BBCodeHandler;
use wcf\system\cache\runtime\UserProfileRuntimeCache;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;
use wcf\util\ArrayUtil;
-use wcf\util\FileUtil;
-use wcf\util\ImageUtil;
use wcf\util\MessageUtil;
use wcf\util\StringUtil;
}
}
- /**
- * Sets an avatar for a given user. The given file will be renamed and is gone after this method call.
- *
- * @throws UserInputException If none or more than one user is given.
- * @throws \InvalidArgumentException If the given file is not an image or is incorrectly sized.
- * @since 5.5
- */
- public function setAvatar(): array
- {
- $user = $this->getSingleObject();
-
- $imageData = \getimagesize($this->parameters['fileLocation']);
-
- if (!$imageData) {
- throw new \InvalidArgumentException("The given file is not an image.");
- }
-
- if (
- ($imageData[0] != UserAvatar::AVATAR_SIZE || $imageData[1] != UserAvatar::AVATAR_SIZE)
- && ($imageData[0] != UserAvatar::AVATAR_SIZE_2X || $imageData[1] != UserAvatar::AVATAR_SIZE_2X)
- ) {
- throw new \InvalidArgumentException(
- \sprintf(
- "The given file does not have the size of %dx%d",
- UserAvatar::AVATAR_SIZE,
- UserAvatar::AVATAR_SIZE
- )
- );
- }
-
- $data = [
- 'avatarName' => $this->parameters['filename'] ?? \basename($this->parameters['fileLocation']),
- 'avatarExtension' => ImageUtil::getExtensionByMimeType($imageData['mime']),
- 'width' => $imageData[0],
- 'height' => $imageData[1],
- 'userID' => $user->userID,
- 'fileHash' => \sha1_file($this->parameters['fileLocation']),
- ];
-
- // create avatar
- $avatar = UserAvatarEditor::create($data);
-
- try {
- // check avatar directory
- // and create subdirectory if necessary
- $dir = \dirname($avatar->getLocation(null, false));
- if (!\file_exists($dir)) {
- FileUtil::makePath($dir);
- }
-
- \rename($this->parameters['fileLocation'], $avatar->getLocation(null, false));
-
- // Fix the permissions of the file in case the source file was created with restricted
- // permissions (e.g. 0600 instead of 0644). Without this the file might not be readable
- // for the web server if it runs with a different system user.
- FileUtil::makeWritable($avatar->getLocation(null, false));
-
- // Create the WebP variant or the JPEG fallback of the avatar.
- $avatarEditor = new UserAvatarEditor($avatar);
- if ($avatarEditor->createAvatarVariant()) {
- $avatar = new UserAvatar($avatar->avatarID);
- }
-
- // update user
- $userEditor = new UserEditor($user->getDecoratedObject());
- $userEditor->update([
- 'avatarID' => $avatar->avatarID,
- ]);
- } catch (\Exception $e) {
- $editor = new UserAvatarEditor($avatar);
- $editor->delete();
-
- throw $e;
- }
-
- // delete old avatar
- if ($user->avatarID) {
- (new UserAvatarAction([$user->avatarID], 'delete'))->executeAction();
- }
-
- // reset user storage
- UserStorageHandler::getInstance()->reset([$user->userID], 'avatar');
-
- return [
- 'avatar' => $avatar,
- ];
- }
-
/**
* Validates the 'uploadCoverPhoto' method.
*
* @property-read int|null $userID id of the user to which the user avatar belongs or null
* @property-read string $fileHash SHA1 hash of the original avatar file
* @property-read int $hasWebP `1` if there is a WebP variant, else `0`
+ *
+ * @deprecated 6.2
*/
class UserAvatar extends DatabaseObject implements IUserAvatar, ISafeFormatAvatar
{
* @method UserAvatar create()
* @method UserAvatarEditor[] getObjects()
* @method UserAvatarEditor getSingleObject()
+ *
+ * @deprecated 6.2
*/
class UserAvatarAction extends AbstractDatabaseObjectAction
{
* @method static UserAvatar create(array $parameters = [])
* @method UserAvatar getDecoratedObject()
* @mixin UserAvatar
+ *
+ * @deprecated 6.2
*/
class UserAvatarEditor extends DatabaseObjectEditor
{
* @method UserAvatar|null getSingleObject()
* @method UserAvatar|null search($objectID)
* @property UserAvatar[] $objects
+ *
+ * @deprecated 6.2
*/
class UserAvatarList extends DatabaseObjectList
{
+++ /dev/null
-<?php
-
-namespace wcf\system\upload;
-
-use RuntimeException;
-use wcf\data\user\avatar\UserAvatar;
-use wcf\data\user\User;
-use wcf\data\user\UserProfileAction;
-use wcf\system\exception\SystemException;
-use wcf\system\WCF;
-use wcf\util\ImageUtil;
-
-/**
- * Save strategy for avatar uploads.
- *
- * @author Marcel Werk
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @since 5.2
- */
-class AvatarUploadFileSaveStrategy implements IUploadFileSaveStrategy
-{
- /**
- * @var int
- */
- protected $userID = 0;
-
- /**
- * @var User
- */
- protected $user;
-
- /**
- * @var UserAvatar
- */
- protected $avatar;
-
- /**
- * Reject the file if it is larger than 750 kB after resizing. A worst-case
- * completely-random 128x128 PNG is around 35 kB and JPEG is around 50 kB.
- *
- * Animated GIFs can be much larger depending on the length of animation,
- * 750 kB seems to be a reasonable upper bound for anything that can be
- * considered reasonable with regard to "distraction" and mobile data
- * volume.
- */
- private const MAXIMUM_FILESIZE = 750_000;
-
- /**
- * Creates a new instance of AvatarUploadFileSaveStrategy.
- *
- * @param int $userID
- */
- public function __construct($userID = null)
- {
- $this->userID = ($userID ?: WCF::getUser()->userID);
- $this->user = ($this->userID != WCF::getUser()->userID ? new User($userID) : WCF::getUser());
- }
-
- /**
- * @return UserAvatar
- */
- public function getAvatar()
- {
- return $this->avatar;
- }
-
- /**
- * @inheritDoc
- */
- public function save(UploadFile $uploadFile)
- {
- if (!$uploadFile->getValidationErrorType()) {
- // rotate avatar if necessary
- /** @noinspection PhpUnusedLocalVariableInspection */
- $fileLocation = ImageUtil::fixOrientation($uploadFile->getLocation());
-
- // shrink avatar if necessary
- try {
- $newWidth = $newHeight = UserAvatar::AVATAR_SIZE;
-
- // Save HiDPI version if possible.
- $imageData = \getimagesize($fileLocation);
- if ($imageData[0] >= UserAvatar::AVATAR_SIZE_2X && $imageData[1] >= UserAvatar::AVATAR_SIZE_2X) {
- $newWidth = $newHeight = UserAvatar::AVATAR_SIZE_2X;
- }
-
- $fileLocation = ImageUtil::enforceDimensions(
- $fileLocation,
- $newWidth,
- $newHeight,
- false
- );
- }
- /** @noinspection PhpRedundantCatchClauseInspection */
- catch (SystemException $e) {
- $uploadFile->setValidationErrorType('tooLarge');
-
- return;
- }
-
- if (\filesize($fileLocation) > self::MAXIMUM_FILESIZE) {
- $uploadFile->setValidationErrorType('tooLarge');
-
- return;
- }
-
- try {
- $returnValues = (new UserProfileAction([$this->userID], 'setAvatar', [
- 'fileLocation' => $fileLocation,
- 'filename' => $uploadFile->getFilename(),
- 'extension' => $uploadFile->getFileExtension(),
- ]))->executeAction();
-
- $this->avatar = $returnValues['returnValues']['avatar'];
- } catch (RuntimeException $e) {
- $uploadFile->setValidationErrorType('uploadFailed');
- }
- }
- }
-}
+++ /dev/null
-<?php
-
-namespace wcf\system\upload;
-
-use wcf\data\user\avatar\UserAvatar;
-use wcf\system\exception\SystemException;
-
-/**
- * Validation strategy for avatar uploads.
- *
- * @author Marcel Werk
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- */
-class AvatarUploadFileValidationStrategy extends DefaultUploadFileValidationStrategy
-{
- /**
- * @inheritDoc
- */
- public function validate(UploadFile $uploadFile)
- {
- if (!parent::validate($uploadFile)) {
- return false;
- }
-
- // check image size
- try {
- $imageData = \getimagesize($uploadFile->getLocation());
- if ($imageData === false) {
- $uploadFile->setValidationErrorType('badImage');
-
- return false;
- }
-
- if ($imageData[0] < UserAvatar::AVATAR_SIZE || $imageData[1] < UserAvatar::AVATAR_SIZE) {
- $uploadFile->setValidationErrorType('tooSmall');
-
- return false;
- } else {
- // Validate the mime type against the list of allowed extensions.
- //
- // We usually don't care about the extension, restricting allowed file extensions
- // primarily exists to prevent users from uploaded clickable '.exe'. The software
- // itself only ever uses the mime type.
- //
- // In the case of avatars, though, the administrator might want to disallow uploading
- // GIF files to prevent the most common case of animated avatar, thus we specifically
- // validate the mime type against the extension.
- $extension = \image_type_to_extension($imageData[2], false);
- if (!\in_array($extension, $this->fileExtensions)) {
- $uploadFile->setValidationErrorType('invalidExtension');
-
- return false;
- }
- }
- } catch (SystemException $e) {
- if (ENABLE_DEBUG_MODE) {
- throw $e;
- }
-
- $uploadFile->setValidationErrorType('badImage');
-
- return false;
- }
-
- return true;
- }
-}