Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/User/ProfileBanner.php
<?php

namespace XF\Service\User;

use
XF\Entity\User;

use function
count, in_array;

class
ProfileBanner extends \XF\Service\AbstractService
{
   
/**
     * @var User
     */
   
protected $user;

    protected
$logIp = true;
    protected
$logChange = true;

    protected
$fileName;

    protected
$type;

    protected
$error = null;

    protected
$allowedTypes = [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG];

    protected
$sizeMap;

    protected
$throwErrors = true;

    public function
__construct(\XF\App $app, User $user)
    {
       
parent::__construct($app);
       
$this->setUser($user);

       
$this->sizeMap = $this->app->container('profileBannerSizeMap');
    }

    protected function
setUser(User $user)
    {
        if (
$user->user_id)
        {
           
$this->user = $user;
        }
        else
        {
            throw new \
LogicException("User must be saved");
        }
    }

    public function
logIp($logIp)
    {
       
$this->logIp = $logIp;
    }

    public function
logChange($logChange)
    {
       
$this->logChange = $logChange;
    }

    public function
getError()
    {
        return
$this->error;
    }

    public function
silentRunning($runSilent)
    {
       
$this->throwErrors = !$runSilent;
    }

    public function
setImage($fileName)
    {
        if (!
$this->validateImageAsBanner($fileName, $error))
        {
           
$this->error = $error;
           
$this->fileName = null;
            return
false;
        }

       
$this->fileName = $fileName;
        return
true;
    }

    public function
setImageFromUpload(\XF\Http\Upload $upload)
    {
       
$upload->requireImage();

        if (!
$upload->isValid($errors))
        {
           
$this->error = reset($errors);
            return
false;
        }

        return
$this->setImage($upload->getTempFile());
    }

    public function
validateImageAsBanner($fileName, &$error = null)
    {
       
$error = null;

        if (!
file_exists($fileName))
        {
            return
$this->throwException(new \InvalidArgumentException("Invalid file '$fileName' passed to banner service"));
        }
        if (!
is_readable($fileName))
        {
            return
$this->throwException(new \InvalidArgumentException("'$fileName' passed to banner service is not readable"));
        }

       
$imageInfo = filesize($fileName) ? @getimagesize($fileName) : false;
        if (!
$imageInfo)
        {
           
$error = \XF::phrase('provided_file_is_not_valid_image');
            return
false;
        }

       
$type = $imageInfo[2];
        if (!
in_array($type, $this->allowedTypes))
        {
           
$error = \XF::phrase('provided_file_is_not_valid_image');
            return
false;
        }

       
$width = $imageInfo[0];
       
$height = $imageInfo[1];

        if (!
$this->app->imageManager()->canResize($width, $height))
        {
           
$error = \XF::phrase('uploaded_image_is_too_big');
            return
false;
        }

       
$this->type = $type;

        return
true;
    }

    public function
updateBanner()
    {
        if (!
$this->fileName)
        {
            return
$this->throwException(new \LogicException("No source file for banner set"));
        }
        if (!
$this->user->exists())
        {
            return
$this->throwException(new \LogicException("User does not exist, cannot update banner"));
        }

       
$imageManager = $this->app->imageManager();

       
$outputFiles = [];

        foreach (
$this->sizeMap AS $size => $width)
        {
           
$image = $imageManager->imageFromFile($this->fileName);
            if (!
$image)
            {
                continue;
            }

           
$image->resizeWidth($width, true);

           
$newTempFile = \XF\Util\File::getTempFile();
            if (
$newTempFile && $image->save($newTempFile, null, 95))
            {
               
$outputFiles[$size] = $newTempFile;
            }
            unset(
$image);
        }

        if (
count($outputFiles) != count($this->sizeMap))
        {
            return
$this->throwException(new \RuntimeException("Failed to save image to temporary file; image may be corrupt or check internal_data/data permissions"));
        }

        foreach (
$outputFiles AS $code => $file)
        {
           
$dataFile = $this->user->Profile->getAbstractedBannerPath($code);
            \
XF\Util\File::copyFileToAbstractedPath($file, $dataFile);
        }

       
$profile = $this->user->Profile;
       
$profile->bulkSet([
           
'banner_date' => \XF::$time,
           
'banner_position_y' => 50
       
]);

        if (
$this->logChange == false)
        {
           
$profile->getBehavior('XF:ChangeLoggable')->setOption('enabled', false);
        }

       
$profile->save();

        if (
$this->logIp)
        {
           
$ip = ($this->logIp === true ? $this->app->request()->getIp() : $this->logIp);
           
$this->writeIpLog('update', $ip);
        }

        return
true;
    }

    public function
setPosition($y)
    {
       
$profile = $this->user->Profile;
       
$profile->bulkSet([
           
'banner_position_y' => $y
       
]);

       
$profile->save();

        return
true;
    }

    public function
deleteBanner()
    {
       
$this->deleteBannerFiles();

       
$profile = $this->user->Profile;
       
$profile->bulkSet([
           
'banner_date' => 0,
           
'banner_position_y' => null
       
]);

       
$profile->save();

        if (
$this->logIp)
        {
           
$ip = ($this->logIp === true ? $this->app->request()->getIp() : $this->logIp);
           
$this->writeIpLog('delete', $ip);
        }

        return
true;
    }

    public function
deleteBannerForUserDelete()
    {
       
$this->deleteBannerFiles();

        return
true;
    }

    protected function
deleteBannerFiles()
    {
        if (
$this->user->Profile->banner_date)
        {
            foreach (
$this->sizeMap AS $code => $size)
            {
                \
XF\Util\File::deleteFromAbstractedPath($this->user->Profile->getAbstractedBannerPath($code));
            }
        }
    }

    protected function
writeIpLog($action, $ip)
    {
       
$user = $this->user;

       
/** @var \XF\Repository\Ip $ipRepo */
       
$ipRepo = $this->repository('XF:Ip');
       
$ipRepo->logIp(\XF::visitor()->user_id, $ip, 'user', $user->user_id, 'profile_banner_' . $action);
    }

   
/**
     * @param \Exception $error
     *
     * @return bool
     * @throws \Exception
     */
   
protected function throwException(\Exception $error)
    {
        if (
$this->throwErrors)
        {
            throw
$error;
        }
        else
        {
            return
false;
        }
    }
}