XoopsModules25x/xoopstube

View on GitHub
class/MediaUploader.php

Summary

Maintainability
C
1 day
Test Coverage
<?php

namespace XoopsModules\Xoopstube;

/**
 * Module: XoopsTube
 *
 * You may not change or alter any portion of this comment or credits
 * of supporting developers from this source code or any supporting source code
 * which is considered copyrighted (c) material of the original comment or credit authors.
 *
 * PHP version 5
 *
 * @category        Module
 * @package         Xoopstube
 * @author          XOOPS Development Team
 * @copyright       2001-2016 XOOPS Project (https://xoops.org)
 * @license         GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
 * @link            https://xoops.org/
 * @since           1.0.6
 */

use XoopsModules\Xoopstube;

/**
 * Class MediaUploader
 */
class MediaUploader
{
    public $mediaName;
    public $mediaType;
    public $mediaSize;
    public $mediaTmpName;
    public $mediaError;
    public $uploadDir        = '';
    public $allowedMimeTypes = [];
    public $maxFileSize      = 0;
    public $maxWidth;
    public $maxHeight;
    public $targetFileName;
    public $prefix;
    public $ext;
    public $dimension;
    public $errors           = [];
    public $savedDestination;
    public $savedFileName;
    /**
     * No admin check for uploads
     */
    public $noAdminSizeCheck;

    /**
     * Constructor
     *
     * @param string    $uploadDir
     * @param array|int $allowedMimeTypes
     * @param int       $maxFileSize
     * @param int       $maxWidth
     * @param int       $maxHeight
     *
     * @internal param int $cmodvalue
     */
    public function __construct($uploadDir, $allowedMimeTypes, $maxFileSize, $maxWidth = 0, $maxHeight = 0)
    {
        if (\is_array($allowedMimeTypes)) {
            $this->allowedMimeTypes = &$allowedMimeTypes;
        }
        $this->uploadDir   = $uploadDir;
        $this->maxFileSize = (int)$maxFileSize;
        if (isset($maxWidth)) {
            $this->maxWidth = (int)$maxWidth;
        }
        if (isset($maxHeight)) {
            $this->maxHeight = (int)$maxHeight;
        }
    }

    /**
     * @param $value
     */
    public function noAdminSizeCheck($value)
    {
        $this->noAdminSizeCheck = $value;
    }

    /**
     * Fetch the uploaded file
     *
     * @param string  $media_name Name of the file field
     * @param int     $index      Index of the file (if more than one uploaded under that name)
     *
     * @return bool
     * @global        $HTTP_POST_FILES
     */
    public function fetchMedia($media_name, $index = null)
    {
        global $_FILES;

        if (!isset($_FILES[$media_name])) {
            $this->setErrors(\_AM_XOOPSTUBE_READWRITEERROR);

            return false;
        }

        if (\is_array($_FILES[$media_name]['name']) && isset($index)) {
            $index              = (int)$index;
            $this->mediaName    = $_FILES[$media_name]['name'][$index];
            $this->mediaType    = $_FILES[$media_name]['type'][$index];
            $this->mediaSize    = $_FILES[$media_name]['size'][$index];
            $this->mediaTmpName = $_FILES[$media_name]['tmp_name'][$index];
            $this->mediaError   = !empty($_FILES[$media_name]['error'][$index]) ? $_FILES[$media_name]['error'][$index] : 0;
        } else {
            $media_name         = @$_FILES[$media_name];
            $this->mediaName    = $media_name['name'];
            $this->mediaType    = $media_name['type'];
            $this->mediaSize    = $media_name['size'];
            $this->mediaTmpName = $media_name['tmp_name'];
            $this->mediaError   = !empty($media_name['error']) ? $media_name['error'] : 0;
        }
        $this->dimension = \getimagesize($this->mediaTmpName);

        $this->errors = [];

        if ((int)$this->mediaSize < 0) {
            $this->setErrors(\_AM_XOOPSTUBE_INVALIDFILESIZE);

            return false;
        }
        if ('' === $this->mediaName) {
            $this->setErrors(\_AM_XOOPSTUBE_FILENAMEEMPTY);

            return false;
        }

        if ('none' === $this->mediaTmpName) {
            $this->setErrors(\_AM_XOOPSTUBE_NOFILEUPLOAD);

            return false;
        }

        if (!\is_uploaded_file($this->mediaTmpName)) {
            switch ($this->mediaError) {
                case 0: // no error; possible file attack!
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORZERO);
                    break;
                case 1: // uploaded file exceeds the upload_max_filesize directive in php.ini
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORONE);
                    break;
                case 2: // uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORTWO);
                    break;
                case 3: // uploaded file was only partially uploaded
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORTHREE);
                    break;
                case 4: // no file was uploaded
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORFOUR);
                    break;
                default: // a default error, just in case!  :)
                    $this->setErrors(\_AM_XOOPSTUBE_UPLOADERRORFIVE);
                    break;
            }

            return false;
        }

        return true;
    }

    /**
     * Set the target filename
     *
     * @param string $value
     */
    public function setTargetFileName($value)
    {
        $this->targetFileName = \trim($value);
    }

    /**
     * Set the prefix
     *
     * @param string $value
     */
    public function setPrefix($value)
    {
        $this->prefix = \trim($value);
    }

    /**
     * Get the uploaded filename
     *
     * @return string
     */
    public function getMediaName()
    {
        return $this->mediaName;
    }

    /**
     * Get the type of the uploaded file
     *
     * @return string
     */
    public function getMediaType()
    {
        return $this->mediaType;
    }

    /**
     * Get the size of the uploaded file
     *
     * @return int
     */
    public function getMediaSize()
    {
        return $this->mediaSize;
    }

    /**
     * Get the temporary name that the uploaded file was stored under
     *
     * @return string
     */
    public function getMediaTmpName()
    {
        return $this->mediaTmpName;
    }

    /**
     * Get the saved filename
     *
     * @return string
     */
    public function getSavedFileName()
    {
        return $this->savedFileName;
    }

    /**
     * Get the destination the file is saved to
     *
     * @return string
     */
    public function getSavedDestination()
    {
        return $this->savedDestination;
    }

    /**
     * Check the file and copy it to the destination
     *
     * @param int $chmod
     *
     * @return bool
     */
    public function upload($chmod = 0644)
    {
        if ('' === $this->uploadDir) {
            $this->setErrors(\_AM_XOOPSTUBE_NOUPLOADDIR);

            return false;
        }

        if (!\is_dir($this->uploadDir)) {
            $this->setErrors(\_AM_XOOPSTUBE_FAILOPENDIR . $this->uploadDir);
        }

        if (!\is_writable($this->uploadDir)) {
            $this->setErrors(\_AM_XOOPSTUBE_FAILOPENDIRWRITEPERM . $this->uploadDir);
        }

        if (!$this->checkMaxFileSize()) {
            $this->setErrors(\sprintf(\_AM_XOOPSTUBE_FILESIZEMAXSIZE, $this->mediaSize, $this->maxFileSize));
        }

        if (\is_array($this->dimension)) {
            if (!$this->checkMaxWidth($this->dimension[0])) {
                $this->setErrors(\sprintf(\_AM_XOOPSTUBE_FILESIZEMAXWIDTH, $this->dimension[0], $this->maxWidth));
            }
            if (!$this->checkMaxHeight($this->dimension[1])) {
                $this->setErrors(\sprintf(\_AM_XOOPSTUBE_FILESIZEMAXHEIGHT, $this->dimension[1], $this->maxHeight));
            }
        }

        if (!$this->checkMimeType()) {
            $this->setErrors(\_AM_XOOPSTUBE_MIMENOTALLOW . $this->mediaType);
        }

        if (!$this->_copyFile($chmod)) {
            $this->setErrors(\_AM_XOOPSTUBE_FAILEDUPLOADING . $this->mediaName);
        }

        if (\count($this->errors) > 0) {
            return false;
        }

        return true;
    }

    /**
     * Copy the file to its destination
     *
     * @param $chmod
     *
     * @return bool
     */
    public function _copyFile($chmod)
    {
        $matched = [];
        if (!\preg_match('/\.([a-zA-Z0-9]+)$/', $this->mediaName, $matched)) {
            return false;
        }
        if (isset($this->targetFileName)) {
            $this->savedFileName = $this->targetFileName;
        } elseif (isset($this->prefix)) {
            $this->savedFileName = \uniqid($this->prefix, true) . '.' . mb_strtolower($matched[1]);
        } else {
            $this->savedFileName = mb_strtolower($this->mediaName);
        }
        $this->savedFileName    = \preg_replace('!\s+!', '_', $this->savedFileName);
        $this->savedDestination = $this->uploadDir . $this->savedFileName;
        if (\is_file($this->savedDestination) && !!\is_dir($this->savedDestination)) {
            $this->setErrors(\_AM_XOOPSTUBE_FILE . $this->mediaName . \_AM_XOOPSTUBE_ALREADYEXISTTRYAGAIN);

            return false;
        }
        if (!\move_uploaded_file($this->mediaTmpName, $this->savedDestination)) {
            return false;
        }
        @\chmod($this->savedDestination, $chmod);

        return true;
    }

    /**
     * Is the file the right size?
     *
     * @return bool
     */
    public function checkMaxFileSize()
    {
        if ($this->noAdminSizeCheck) {
            return true;
        }
        if ($this->mediaSize > $this->maxFileSize) {
            return false;
        }

        return true;
    }

    /**
     * Is the picture the right width?
     *
     * @param $dimension
     *
     * @return bool
     */
    public function checkMaxWidth($dimension)
    {
        if (!isset($this->maxWidth)) {
            return true;
        }
        if ($dimension > $this->maxWidth) {
            return false;
        }

        return true;
    }

    /**
     * Is the picture the right height?
     *
     * @param $dimension
     *
     * @return bool
     */
    public function checkMaxHeight($dimension)
    {
        if (!isset($this->maxHeight)) {
            return true;
        }
        if ($dimension > $this->maxWidth) {
            return false;
        }

        return true;
    }

    /**
     * Is the file the right Mime type
     *
     * (is there a right type of mime? ;-)
     *
     * @return bool
     */
    public function checkMimeType()
    {
        if (\count($this->allowedMimeTypes) > 0 && !\in_array($this->mediaType, $this->allowedMimeTypes)) {
            return false;
        }

        return true;
    }

    /**
     * Add an error
     *
     * @param string $error
     */
    public function setErrors($error)
    {
        $this->errors[] = \trim($error);
    }

    /**
     * Get generated errors
     *
     * @param bool $ashtml Format using HTML?
     *
     * @return array |string    Array of array messages OR HTML string
     */
    public function &getErrors($ashtml = true)
    {
        if (!$ashtml) {
            return $this->errors;
        }
        $ret = '';
        if (\count($this->errors) > 0) {
            $ret = \_AM_XOOPSTUBE_ERRORSRETURNUPLOAD;
            foreach ($this->errors as $error) {
                $ret .= $error . '<br>';
            }
        }

        return $ret;
    }
}