From 7f5dde7bad13c12b9180718000325643bf33b2c3 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 4 Jan 2019 03:25:05 +0300 Subject: [PATCH] Entries Manager: Media Manager - improvements - Flextype Core: Glide/Intervention Image Implementation #61 - Upload method as a part of Entries Manager - Upload max file updated to 17000000 - Show error on upload error - Pretty names for uploaded images --- site/plugins/admin/classes/EntriesManager.php | 160 +++++++++++++++++- 1 file changed, 157 insertions(+), 3 deletions(-) diff --git a/site/plugins/admin/classes/EntriesManager.php b/site/plugins/admin/classes/EntriesManager.php index 8172d733..ca33482d 100644 --- a/site/plugins/admin/classes/EntriesManager.php +++ b/site/plugins/admin/classes/EntriesManager.php @@ -460,12 +460,166 @@ class EntriesManager if (Http::post('upload_file')) { if (Token::check(Http::post('token'))) { - Filesystem::uploadFile($_FILES['file'], $files_directory, Registry::get('settings.accept_file_types'), 7000000); - Notification::set('success', __('admin_message_entry_file_uploaded')); - Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true'); + $file = EntriesManager::uploadFile($_FILES['file'], $files_directory, Registry::get('settings.accept_file_types'), 17000000); + + if($file !== false) { + Notification::set('success', __('admin_message_entry_file_uploaded')); + Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true'); + } else { + Notification::set('error', __('admin_message_entry_file_not_uploaded')); + Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true'); + } + } else { die('Request was denied because it contained an invalid security token. Please refresh the entry and try again.'); } } } + + /** + * Upload files on the Server with several type of Validations! + * + * Entries::uploadFile($_FILES['file'], $files_directory); + * + * @param array $file Uploaded file data + * @param string $upload_directory Upload directory + * @param array $allowed Allowed file extensions + * @param int $max_size Max file size in bytes + * @param string $filename New filename + * @param bool $remove_spaces Remove spaces from the filename + * @param int $max_width Maximum width of image + * @param int $max_height Maximum height of image + * @param bool $exact Match width and height exactly? + * @param int $chmod Chmod mask + * @return string on success, full path to new file + * @return false on failure + */ + public static function uploadFile( + array $file, + string $upload_directory, + array $allowed = ['jpeg', 'png', 'gif', 'jpg'], + int $max_size = 3000000, + string $filename = null, + bool $remove_spaces = true, + int $max_width = null, + int $max_height = null, + bool $exact = false, + int $chmod = 0644 + ) { + // + // Tests if a successful upload has been made. + // + if (isset($file['error']) + and isset($file['tmp_name']) + and $file['error'] === UPLOAD_ERR_OK + and is_uploaded_file($file['tmp_name'])) { + + // + // Tests if upload data is valid, even if no file was uploaded. + // + if (isset($file['error']) + and isset($file['name']) + and isset($file['type']) + and isset($file['tmp_name']) + and isset($file['size'])) { + + // + // Test if an uploaded file is an allowed file type, by extension. + // + if (in_array(strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)), $allowed)) { + + // + // Validation rule to test if an uploaded file is allowed by file size. + // + if (($file['error'] != UPLOAD_ERR_INI_SIZE) + and ($file['error'] == UPLOAD_ERR_OK) + and ($file['size'] <= $max_size)) { + + // + // Validation rule to test if an upload is an image and, optionally, is the correct size. + // + if (in_array(mime_content_type($file['tmp_name']), ['image/jpeg', 'image/jpg', 'image/png','image/gif'])) { + function validateImage($file, $max_width, $max_height, $exact) + { + try { + // Get the width and height from the uploaded image + list($width, $height) = getimagesize($file['tmp_name']); + } catch (ErrorException $e) { + // Ignore read errors + } + + if (empty($width) or empty($height)) { + // Cannot get image size, cannot validate + return false; + } + + if (! $max_width) { + // No limit, use the image width + $max_width = $width; + } + + if (! $max_height) { + // No limit, use the image height + $max_height = $height; + } + + if ($exact) { + // Check if dimensions match exactly + return ($width === $max_width and $height === $max_height); + } else { + // Check if size is within maximum dimensions + return ($width <= $max_width and $height <= $max_height); + } + + return false; + } + + if (validateImage($file, $max_width, $max_height, $exact) === false) { + return false; + } + } + + if (! isset($file['tmp_name']) or ! is_uploaded_file($file['tmp_name'])) { + + // Ignore corrupted uploads + return false; + } + + if ($filename === null) { + + // Use the default filename, with a timestamp pre-pended + $filename = uniqid().'-'.$file['name']; + } + + if ($remove_spaces === true) { + + // Remove spaces from the filename + $filename = Text::safeString(pathinfo($filename)['filename'], '-', true) . '.' . pathinfo($filename)['extension']; + } + + if (! is_dir($upload_directory) or ! is_writable(realpath($upload_directory))) { + throw new \RuntimeException("Directory {$upload_directory} must be writable"); + } + + // Make the filename into a complete path + $filename = realpath($upload_directory).DIRECTORY_SEPARATOR.$filename; + + if (move_uploaded_file($file['tmp_name'], $filename)) { + + if ($chmod !== false) { + // Set permissions on filename + chmod($filename, $chmod); + } + + // Return new file path + return $filename; + } + } + } + } + } + + return false; + } + }