539 lines
23 KiB
PHP
539 lines
23 KiB
PHP
<?php
|
|
/*
|
|
* jQuery File Upload Plugin PHP Example 5.14
|
|
* https://github.com/blueimp/jQuery-File-Upload
|
|
*
|
|
* Copyright 2010, Sebastian Tschan
|
|
* https://blueimp.net
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/MIT
|
|
*/
|
|
|
|
use BRSystems\Core\App\pubUsers\inc\pubUsersController;
|
|
use BRSystems\Core\Library\cCore\cCore;
|
|
use BRSystems\Core\Library\cDb\cDb;
|
|
use BRSystems\Core\Library\cDefuseCrypto\cDefuseCrypto;
|
|
use BRSystems\Core\Library\cImage\cImage;
|
|
use BRSystems\Core\Library\cINI\cINI;
|
|
use BRSystems\Core\Library\cJSON\cJSON;
|
|
use BRSystems\Core\Sys\sysUsers\inc\sysUsersController;
|
|
|
|
class fileUpload
|
|
{
|
|
public $db;
|
|
public $oUser;
|
|
public $is_cms;
|
|
|
|
private $file;
|
|
private $config;
|
|
private $encrypt;
|
|
|
|
public function __construct()
|
|
{
|
|
// Increase memory limit
|
|
if (!isset($GLOBALS['coverage_tests_running'])) {
|
|
ini_set('memory_limit', '64M');
|
|
}
|
|
|
|
/*** Include autoload & the init.php file ***/
|
|
include './../../../../vendor/autoload.php';
|
|
|
|
// Create directory file path
|
|
$path_ch = explode('/', str_replace('\\', '/', dirname(__FILE__)));
|
|
array_splice($path_ch, count($path_ch) - 3);
|
|
|
|
if (!defined('__MDIR__')) {
|
|
define('__MDIR__', implode('/', $path_ch) . '/');
|
|
}
|
|
|
|
// Require site structure configuration
|
|
require_once __MDIR__ . "system-brs-core/config/constants.php";
|
|
require_once __MDIR__ . "system-brs-core/functions/com.funct.php";
|
|
|
|
// Load file upload handler class
|
|
//require_once "UploadHandler.php";
|
|
|
|
// Set handler functions
|
|
set_error_handler('errorHandler');
|
|
|
|
|
|
// Load site configuration file
|
|
$oCfg = new cINI(__CFG__ . 'init.cfg.ini');
|
|
$oCfg->loadSystemConstants();
|
|
|
|
// Set time zone
|
|
if ($sZone = $oCfg->getV('system', 'DATE_TIMEZONE')) {
|
|
ini_set('date.timezone', $sZone);
|
|
date_default_timezone_set($sZone);
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
// Set developer configuration
|
|
//-------------------------------------------------------------
|
|
$debug_mode = false;
|
|
if ($oCfg->getV('system', 'DEBUG_MODE')) {
|
|
$vExcludeIp = $oCfg->getV('system_update', 'EXCLUDE_IP');
|
|
$debug_mode = (in_array($_SERVER['REMOTE_ADDR'], (!!$vExcludeIp ? $vExcludeIp : array())) || $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR']);
|
|
}
|
|
|
|
if (!defined('DB_DEBUG')) define('DB_DEBUG', $debug_mode);
|
|
if (!defined('DEBUG_MODE')) define('DEBUG_MODE', $debug_mode);
|
|
if (!defined('DEBUG_QUERIES')) define('DEBUG_QUERIES', $debug_mode);
|
|
|
|
|
|
// Session ID check & init
|
|
if ($key = getP('dxcheck')) {
|
|
$this->encrypt = new cDefuseCrypto();
|
|
$key = $this->encrypt->decrypt($key);
|
|
session_id($key);
|
|
|
|
$staticConfigFunction = $this->encrypt->decrypt(getP('upload'));
|
|
if (is_callable($staticConfigFunction)) {
|
|
|
|
startSessionSameSite(60 * 60 * 24);
|
|
$this->config = call_user_func($staticConfigFunction, getP('type'));
|
|
|
|
// Load libraries
|
|
$this->db = cDb::getInstance();
|
|
$this->core = new cCore();
|
|
|
|
$this->is_cms = $this->config['cms'];
|
|
if ($this->is_cms) {
|
|
$this->oUser = new sysUsersController(false);
|
|
} else {
|
|
$this->oUser = new pubUsersController(false);
|
|
}
|
|
} else {
|
|
throw new Exception('No session config found!');
|
|
}
|
|
} else {
|
|
throw new Exception('No key found!');
|
|
}
|
|
}
|
|
|
|
public function chkUploadFiles()
|
|
{
|
|
// Check user has logged in & user permission to upload files
|
|
if ($this->oUser->isLoggedIn()) {
|
|
if (!$this->is_cms || $this->is_cms && $this->oUser->chkPermission('UPLOADIFY_PLUGIN', false, false)) {
|
|
|
|
// Reconstruct files array for easier usage
|
|
$_FILES = $this->reconstructFilesArray($_FILES);
|
|
|
|
if (!empty($_FILES)) {
|
|
foreach ($_FILES['files'] as $fileValue) {
|
|
|
|
// $fn = "";
|
|
$fname = $fileValue['name'];
|
|
$tempFile = $fileValue['tmp_name'];
|
|
$serverFolder = $this->config['folder'] . '/';
|
|
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $serverFolder;
|
|
//$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
|
|
|
|
$typesArray = explode('|', $this->config['fileExt']);
|
|
//$typesArray = explode(';',"png;gif;jpg;jepg");
|
|
$fileParts = pathinfo($fileValue['name']);
|
|
|
|
|
|
if (in_array(strtolower($fileParts['extension']), $typesArray)) {
|
|
|
|
// Create separation folder structure
|
|
if (!empty($this->config['separate']) && $this->config['separate']) {
|
|
$targetPath .= date('Y-m') . '/';
|
|
$serverFolder .= date('Y-m') . '/';
|
|
}
|
|
|
|
//Uncomment the following line if you want to make the directory if it doesn't exist
|
|
if (!file_exists(str_replace('//', '/', $targetPath)))
|
|
mkdir(str_replace('//', '/', $targetPath), 0755, true);
|
|
|
|
// if(isset($this->config['saveFileName']) && $this->config['saveFileName'])
|
|
// $fn = $fileParts['filename'];
|
|
// Check file size - if above 3k send error
|
|
list($w, $h) = getimagesize($tempFile);
|
|
if ($w > 2500 || $h > 2000) cJSON::sendError(array('crop_needed' => 1, 'msg' => 'Image too large for process!'));
|
|
|
|
|
|
if (isset($this->config['preserveNames']) && $this->config['preserveNames']) {
|
|
$fname = strtolower($fname);
|
|
} else {
|
|
$fname = sha1_file($tempFile) . "." . $fileParts['extension'];
|
|
}
|
|
|
|
$fileValue['name'] = $fname;
|
|
$targetFile = str_replace('//', '/', $targetPath) . $fname;
|
|
move_uploaded_file($tempFile, $targetFile);
|
|
|
|
// Reconstruct image based on sample image using sample image type & size
|
|
if (isset($this->config['reconstruct_base']) && $this->config['reconstruct_base']) {
|
|
$vBaseCfgData = $this->config['reconstruct_base'];
|
|
$targetFile = $this->createSampleImgAdv(
|
|
$targetPath, $fileValue['name'], false, $vBaseCfgData['dimensions'],
|
|
false,
|
|
(!empty($vBaseCfgData) ? $vBaseCfgData : false),
|
|
(!empty($vBaseCfgData['scale2fit']) ? $vBaseCfgData['scale2fit'] : false),
|
|
(!empty($vBaseCfgData['delete_base_file']) ? $vBaseCfgData['delete_base_file'] : false)
|
|
);
|
|
|
|
$fileValue['name'] = basename($targetFile);
|
|
$fileParts = pathinfo($fileValue['name']);
|
|
}
|
|
|
|
if (isset($this->config['preview_dir']) && isset($this->config['preview_size'])
|
|
&& (!isset($this->config['preview_extensions']) || isset($this->config['preview_extensions']) && in_array($fileParts['extension'], $this->config['preview_extensions'])))
|
|
$this->createSampleImgAdv($targetPath, $fileValue['name'], $this->config['preview_dir'], $this->config['preview_size']);
|
|
if (isset($this->config['onUploadStatic']) && is_callable($this->config['onUploadStatic']))
|
|
call_user_func($this->config['onUploadStatic'], array('file' => $fname, 'file_name' => $fileParts['basename'], 'path' => $serverFolder, 'user' => $this->oUser->getUser(), 'userInst' => &$this->oUser));
|
|
|
|
|
|
// Slice image in smaller portions based on type-specific cuts.
|
|
$slices = $this->getConfiguredSlices((int)(getP('type_id') ?: getP('type')));
|
|
foreach ($slices as $kk => $vv) {
|
|
if (is_string($kk)) {
|
|
$this->createSampleImgAdv(
|
|
$targetPath,
|
|
$fileValue['name'],
|
|
$kk,
|
|
$vv,
|
|
(!empty($this->config['watermark'][$kk]) ? $this->config['watermark'][$kk] : false),
|
|
(!empty($this->config['container_base'][$kk]) ? $this->config['container_base'][$kk] : false),
|
|
(!empty($this->config['container_base'][$kk]['scale2fit']) ? $this->config['container_base'][$kk]['scale2fit'] : false)
|
|
);
|
|
}
|
|
}
|
|
|
|
// Check no return flag
|
|
if (isset($this->config['noFileReturn']) && $this->config['noFileReturn']) {
|
|
cJSON::sendOk();
|
|
}
|
|
|
|
$vResponse = array(
|
|
'file_name' => $fileParts['filename'],
|
|
'file_ext' => $fileParts['extension'],
|
|
'file' => $fileValue['name'],
|
|
'path' => (!!$serverFolder ? $serverFolder : ""),
|
|
'v' => filemtime("{$targetPath}{$fileValue['name']}")
|
|
);
|
|
|
|
if (isset($this->config['preview_dir'])) {
|
|
$vResponse['dir'] = $this->config['preview_dir'];
|
|
}
|
|
|
|
if (isset($this->config['getExtension']) && $this->config['getExtension']) {
|
|
$vResponse['ext'] = $fileParts['extension'];
|
|
}
|
|
|
|
if (!empty($this->config['cryptFileUrl'])) {
|
|
$vResponse['cryptFileUrl'] = $this->encrypt->encrypt(
|
|
"{$vResponse['path']}{$vResponse['file']}"
|
|
);
|
|
}
|
|
|
|
if (getP('type')) {
|
|
$vResponse['type'] = getP('type');
|
|
}
|
|
|
|
cJSON::sendOk($vResponse);
|
|
} else {
|
|
cJSON::sendError(array('crop_needed' => 1, 'msg' => 'Invalid file type!'));
|
|
}
|
|
}
|
|
} else {
|
|
throw new Exception('No files selected!');
|
|
}
|
|
} else {
|
|
throw new Exception('No access rights!');
|
|
}
|
|
} else {
|
|
throw new Exception('Please login!');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve which slices should be generated for the current upload type.
|
|
*
|
|
* If a type has explicit cuts, use those cuts. If a referenced cut is missing,
|
|
* fall back to preview when available. If no type cuts are configured at all,
|
|
* keep the original behavior and generate all slices.
|
|
*/
|
|
private function getConfiguredSlices(int $typeId): array
|
|
{
|
|
$slices = $this->config['slices'] ?? [];
|
|
if (empty($slices) || !is_array($slices)) {
|
|
return [];
|
|
}
|
|
|
|
$typeCuts = $this->config['type_cuts'] ?? [];
|
|
if (empty($typeCuts) || !is_array($typeCuts)) {
|
|
return $slices;
|
|
}
|
|
|
|
$previewSlice = [];
|
|
if (isset($slices['preview'])) {
|
|
$previewSlice['preview'] = $slices['preview'];
|
|
}
|
|
|
|
if (empty($typeId) || empty($typeCuts[$typeId]) || !is_array($typeCuts[$typeId])) {
|
|
return $previewSlice ?: $slices;
|
|
}
|
|
|
|
$selected = [];
|
|
foreach ($typeCuts[$typeId] as $cutName) {
|
|
if (isset($slices[$cutName])) {
|
|
$selected[$cutName] = $slices[$cutName];
|
|
} elseif (isset($previewSlice['preview'])) {
|
|
$selected['preview'] = $previewSlice['preview'];
|
|
}
|
|
}
|
|
|
|
return $selected ?: ($previewSlice ?: $slices);
|
|
}
|
|
|
|
/**
|
|
* Function to prepare images for display
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category cmsCatProducts Controller
|
|
* @param string $base_dir - dir path
|
|
* @param string $file - file path
|
|
* @param bool $dir - dir name inside the path
|
|
* @param bool $size - img size
|
|
* @param bool $fixedWH - indicates if needs to have fixed width / height
|
|
* @param bool $watermark - generate image with watermark
|
|
* @return array of data
|
|
*/
|
|
public static function createSampleImg($base_dir, $file, $dir = false, $size = false, $fixedWH = true, $watermark = false)
|
|
{
|
|
$size = explode('x', $size);
|
|
if ($dir && count($size) > 1) {
|
|
|
|
//$log = new logger('uplodify');
|
|
// Get sample dir
|
|
$sample_file = str_replace('//', '/', $base_dir . '/' . $dir . '/' . $file);
|
|
$base_file = str_replace('//', '/', $base_dir . '/' . $file);
|
|
|
|
if (!file_exists(dirname($sample_file))) {
|
|
mkdir(dirname($sample_file), 0755, true);
|
|
}
|
|
|
|
$img = '';
|
|
$image = new cImage($base_file);
|
|
|
|
|
|
if ($fixedWH) {
|
|
list($width, $height) = getimagesize($base_file);
|
|
|
|
if ($width > $height && !$watermark) {
|
|
$width = null;
|
|
$height = $size[1];
|
|
} else {
|
|
$width = $size[0];
|
|
$height = null;
|
|
}
|
|
// Check if watermark needs to be added
|
|
if ($watermark) {
|
|
$image->resize($width, $height)->crop($size[0], $size[1])->watermark($img = new cImage(__IMG__ . $watermark['file']), $watermark['offset_x'], $watermark['offset_y'])->save($sample_file);
|
|
} else {
|
|
$image->resize($width, $height)->crop($size[0], $size[1])->save($sample_file);
|
|
}
|
|
//$img->resizeImg($base_file, $sample_file, $size[0], $size[1], IR_CROP | IR_TOUCH_FROM_OUTSIDE | IR_CONST_WIDTH | IR_CONST_HEIGHT | IR_FORCE_IF_EXISTS);
|
|
} else {
|
|
$image->resize($size[0], $size[1])->save($sample_file);
|
|
//$img->resizeImg($base_file, $sample_file, $size[0], $size[1], IR_CROP | IR_TOUCH_FROM_INSIDE | IR_CONST_WIDTH | IR_FORCE_IF_EXISTS);
|
|
}
|
|
|
|
unset($image, $img);
|
|
//$log->end();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to prepare images for display
|
|
*
|
|
* @author Mareks Zukovskis <mareks.zukovskis@gmail.com>
|
|
* @category cmsCatProducts Controller
|
|
* @param string $base_dir - dir path
|
|
* @param string $file - file path
|
|
* @param bool $dir - dir name inside the path
|
|
* @param bool $size - img size
|
|
* @param bool $watermark - generate image with watermark
|
|
* @param bool $vBaseImage - generate image based on sample layout
|
|
* @param bool $bScale2fit - scale image to fit dimensions
|
|
* @return mixed
|
|
*/
|
|
public static function createSampleImgAdv($base_dir, $file, $dir = false, $size = false, $watermark = false, $vBaseImage = false, $bScale2fit = false, $bOverwriteExistingFile = false)
|
|
{
|
|
// // TESTS!!!!
|
|
//
|
|
// $w = 200; $h = 150;
|
|
// $data = array(
|
|
// "article/2018-05/badf3af13649d583b5976433ab7caada137b98f6.JPG",
|
|
// "article/2018-05/d31f41d37796138f09e0ad059872ac5d0cc95b53.jpg",
|
|
// "article/2018-05/7202742c9f96705bb4933d7085a57ccec6d04e45.jpg",
|
|
// );
|
|
// if(!!$vBaseImage){
|
|
// foreach($data as $base_file){
|
|
//
|
|
// if(!file_exists(__FILES__ . $base_file))
|
|
// continue;
|
|
//
|
|
// $oImage = new Image(__FILES__ . $base_file);
|
|
// list($width, $height) = getimagesize(__FILES__ . $base_file);
|
|
// // pr('w > ' . $width, 'h > ' . $height);
|
|
//
|
|
// if($bScale2fit){
|
|
// if($width > $height)
|
|
// $oImage = $oImage->resize(null, $h)->crop($w, $h);
|
|
// else
|
|
// $oImage = $oImage->resize($w, null)->crop($w, $h);
|
|
//
|
|
// }else{
|
|
// $height2be = $height * $w / $width;
|
|
// // Normal resizing
|
|
// if($height2be > $h){
|
|
// $oImage = $oImage->resize($w, null);
|
|
// // Opposite resize
|
|
// }else{
|
|
// $oImage = $oImage->resize(null, $h);
|
|
// }
|
|
// }
|
|
//
|
|
// $new_file_url = "http://local.latefekts.lv/files/" . str_replace(array('.JPG', '.jpg'), array('_2.png', '_2.png'), $base_file);
|
|
// $new_file = str_replace(array('.JPG', '.jpg'), array('_2.png', '_2.png'), __FILES__ . $base_file);
|
|
//
|
|
// //$oImage->resize($width, $height)->crop($size[0], $size[1])->save($new_file);
|
|
// //$oImage->save($new_file);
|
|
//
|
|
// pr('bimage >>> ' . "\n", $vBaseImage, "\n");
|
|
// if(!!$vBaseImage){
|
|
// $oImg = new Image(__IMG__ . $vBaseImage['file']);
|
|
// //$oImg->save($new_file);
|
|
// pr($new_file, "\n");
|
|
// $sNewExt = pathinfo($vBaseImage['file'], PATHINFO_EXTENSION);
|
|
// $oImg->watermark($oImage, $vBaseImage['offset_x'], $vBaseImage['offset_y'])->save($new_file);
|
|
// }
|
|
//
|
|
// echo "<img style='border:1px solid gray;' src='{$new_file_url}'/>";
|
|
// }
|
|
// }
|
|
// //************************************************************************************
|
|
// //************************************************************************************
|
|
// //************************************************************************************
|
|
|
|
|
|
$size = explode('x', $size);
|
|
if (($bOverwriteExistingFile || $dir) && count($size) > 1) {
|
|
|
|
$w = $size[0];
|
|
$h = $size[1];
|
|
|
|
//$log = new logger('uplodify');
|
|
// Get sample dir
|
|
$sample_file = str_replace('//', '/', $base_dir . ($dir ? '/' . $dir : '') . '/' . $file);
|
|
$base_file = str_replace('//', '/', $base_dir . '/' . $file);
|
|
|
|
if (!file_exists(dirname($sample_file))) {
|
|
mkdir(dirname($sample_file), 0755, true);
|
|
}
|
|
|
|
$img = '';
|
|
$oImage = new cImage($base_file);
|
|
|
|
|
|
list($width, $height) = getimagesize($base_file);
|
|
// Scale to crop & fit
|
|
if ($bScale2fit) {
|
|
if ($width > $height)
|
|
$oImage = $oImage->resize($w, null)->crop($w, $h);
|
|
else
|
|
$oImage = $oImage->resize(null, $h)->crop($w, $h);
|
|
|
|
// Fit whole img without cropping
|
|
} elseif (!empty($vBaseImage['scale2preserveImg'])) {
|
|
$height2be = $height * $w / $width;
|
|
// Normal resizing
|
|
if ($height2be > $h) {
|
|
$oImage = $oImage->resize(null, $h);
|
|
// Opposite resize
|
|
} else {
|
|
$oImage = $oImage->resize($w, null);
|
|
}
|
|
|
|
// Fit entire img - while cropping part off
|
|
} else {
|
|
$height2be = $height * $w / $width;
|
|
// Normal resizing
|
|
if ($height2be > $h) {
|
|
$oImage = $oImage->resize($w, null);
|
|
// Opposite resize
|
|
} else {
|
|
$oImage = $oImage->resize(null, $h);
|
|
}
|
|
}
|
|
|
|
// Check if watermark needs to be added
|
|
if ($watermark) {
|
|
$oImage->crop($w, $h, 0, 0)->watermark($img = new cImage(__IMG__ . $watermark['file']), $watermark['offset_x'], $watermark['offset_y'])->save($sample_file);
|
|
} elseif (!!$vBaseImage) {
|
|
if (file_exists(__IMG__ . $vBaseImage['file'])) {
|
|
$oImg = new cImage(__IMG__ . $vBaseImage['file']);
|
|
$sNewExt = pathinfo($vBaseImage['file'], PATHINFO_EXTENSION);
|
|
$file_path = pathinfo($sample_file);
|
|
|
|
// Unlik old file when needed
|
|
if ($bOverwriteExistingFile) unlink($base_file);
|
|
|
|
$sample_file = "{$file_path['dirname']}/{$file_path['filename']}.{$sNewExt}";
|
|
$oImg->watermark($oImage, $vBaseImage['offset_x'], $vBaseImage['offset_y'])->save($sample_file);
|
|
}
|
|
} else {
|
|
$oImage->crop($w, $h, 0, 0)->save($sample_file);
|
|
}
|
|
|
|
unset($image, $img);
|
|
return $sample_file;
|
|
}
|
|
}
|
|
|
|
public function reconstructFilesArray(array $_files, $top = true)
|
|
{
|
|
$files = array();
|
|
foreach ($_files as $name => $file) {
|
|
if ($top) $sub_name = $file['name'];
|
|
else $sub_name = $name;
|
|
|
|
if (is_array($sub_name)) {
|
|
foreach (array_keys($sub_name) as $key) {
|
|
$files[$name][$key] = array(
|
|
'name' => $file['name'][$key],
|
|
'type' => $file['type'][$key],
|
|
'tmp_name' => $file['tmp_name'][$key],
|
|
'error' => $file['error'][$key],
|
|
'size' => $file['size'][$key],
|
|
);
|
|
$files[$name] = $this->reconstructFilesArray($files[$name], FALSE);
|
|
}
|
|
} else {
|
|
$files[$name] = $file;
|
|
}
|
|
}
|
|
return $files;
|
|
}
|
|
}
|
|
|
|
try {
|
|
|
|
// Initialize class & check for files
|
|
$upload = new fileUpload();
|
|
$upload->chkUploadFiles();
|
|
|
|
} catch (Exception $e) {
|
|
if (isset($GLOBALS['coverage_tests_running'])) {
|
|
return;
|
|
}
|
|
|
|
die($e->getMessage());
|
|
}
|