--- /dev/null
+<?php
+
+/**
+ * Updates the database layout during the update from 6.1 to 6.2.
+ *
+ * @author Olaf Braun
+ * @copyright 2001-2024 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+
+use wcf\system\database\table\column\IntDatabaseTableColumn;
+use wcf\system\database\table\index\DatabaseTableForeignKey;
+use wcf\system\database\table\PartialDatabaseTable;
+
+return [
+ PartialDatabaseTable::create('wcf1_user')
+ ->columns([
+ IntDatabaseTableColumn::create('avatarFileID')
+ ->length(10)
+ ->defaultValue(null),
+ ])
+ ->foreignKeys([
+ DatabaseTableForeignKey::create()
+ ->columns(['avatarFileID'])
+ ->referencedTable('wcf1_file')
+ ->referencedColumns(['fileID'])
+ ->onDelete('SET NULL'),
+ ]),
+];
namespace wcf\system\file\processor;
use wcf\data\file\File;
-use wcf\data\file\thumbnail\FileThumbnail;
use wcf\data\user\avatar\UserAvatar;
use wcf\data\user\User;
+use wcf\data\user\UserEditor;
use wcf\system\cache\runtime\UserRuntimeCache;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\UserInputException;
+use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;
+use wcf\util\FileUtil;
/**
* @author Olaf Braun
#[\Override]
public function canAdopt(File $file, array $context): bool
{
- // TODO
- return true;
+ $userFromContext = $this->getUser($context);
+ $userFromCoreFile = $this->getUserByFile($file);
+
+ if ($userFromContext === null) {
+ return true;
+ }
+
+ if ($userFromContext->userID === $userFromCoreFile->userID) {
+ return true;
+ }
+
+ return false;
}
#[\Override]
public function adopt(File $file, array $context): void
{
- // TODO
+ $user = $this->getUser($context);
+ if ($user === null) {
+ return;
+ }
+
+ (new UserEditor($user))->update([
+ 'avatarFileID' => $file->fileID,
+ ]);
+ // reset user storage
+ UserStorageHandler::getInstance()->reset([$user->userID], 'avatar');
}
#[\Override]
public function acceptUpload(string $filename, int $fileSize, array $context): FileProcessorPreflightResult
{
- // TODO
+ $user = $this->getUser($context);
+
+ if ($user === null) {
+ return FileProcessorPreflightResult::InvalidContext;
+ }
+
+ if (!$this->canEditAvatar($user)) {
+ return FileProcessorPreflightResult::InsufficientPermissions;
+ }
+
+ if ($fileSize > $this->getMaximumSize($context)) {
+ return FileProcessorPreflightResult::FileSizeTooLarge;
+ }
+
+ if (!FileUtil::endsWithAllowedExtension($filename, $this->getAllowedFileExtensions($context))) {
+ return FileProcessorPreflightResult::FileExtensionNotPermitted;
+ }
+
return FileProcessorPreflightResult::Passed;
}
#[\Override]
- public function canDelete(File $file): bool
+ public function validateUpload(File $file): void
{
- // TODO
- return true;
+ $imageData = @\getimagesize($file->getPathname());
+ if ($imageData === false) {
+ throw new UserInputException('file', 'noImage');
+ }
+
+ if ($imageData[0] !== $imageData[1]) {
+ throw new UserInputException('file', 'notSquare');
+ }
+
+ if ($imageData[0] != UserAvatar::AVATAR_SIZE && $imageData[0] != UserAvatar::AVATAR_SIZE_2X) {
+ throw new UserInputException('file', 'wrongSize');
+ }
}
#[\Override]
- public function canDownload(File $file): bool
+ public function canDelete(File $file): bool
{
- // TODO
- return true;
+ $user = $this->getUserByFile($file);
+ if ($user === null) {
+ return false;
+ }
+
+ return $this->canEditAvatar($user);
}
#[\Override]
- public function getMaximumCount(array $context): ?int
+ public function canDownload(File $file): bool
{
- // TODO
- return null;
+ return true;
}
#[\Override]
];
}
- #[\Override]
- public function adoptThumbnail(FileThumbnail $thumbnail): void
- {
- // TODO
- }
-
#[\Override]
public function delete(array $fileIDs, array $thumbnailIDs): void
{
- // TODO
+ $conditionBuilder = new PreparedStatementConditionBuilder();
+ $conditionBuilder->add('avatarFileID IN (?)', [$fileIDs]);
+
+ $sql = "UPDATE wcf1_user
+ SET avatarFileID = ?
+ " . $conditionBuilder;
+ $statement = WCF::getDB()->prepare($sql);
+ $statement->execute([null, ...$conditionBuilder->getParameters()]);
}
#[\Override]
public function countExistingFiles(array $context): ?int
{
- // TODO
+ $user = $this->getUser($context);
+ if ($user === null) {
+ return null;
+ }
+
+ return $user->avatarFileID === null ? 0 : 1;
}
#[\Override]
return UserRuntimeCache::getInstance()->getObject($userID);
}
+
+ private function getUserByFile(File $file): ?User
+ {
+ $sql = "SELECT *
+ FROM wcf1_user
+ WHERE avatarFileID = ?";
+ $statement = WCF::getDB()->prepare($sql);
+ $statement->execute([$file->fileID]);
+
+ return $statement->fetchObject(User::class);
+ }
+
+ private function canEditAvatar(User $user): bool
+ {
+ if (WCF::getSession()->getPermission('admin.user.canEditUser')) {
+ return true;
+ }
+
+ if ($user->userID !== WCF::getUser()->userID) {
+ return false;
+ }
+
+ if (WCF::getUser()->disableAvatar) {
+ return false;
+ }
+
+ return WCF::getSession()->getPermission('user.profile.avatar.canUploadAvatar');
+ }
}