Is it possible to customize the chunk configuration in Filepond such that the chunk information is provided to the upload server:
as query parameters instead of headers
with custom query parameter names instead of Upload-Length, Upload-Name, and Upload-Offset
I am trying to fit Filepond's chunk implementation to a third party upload endpoint that I don't have control over.
I have found the Advanced configuration where you provide a process function which I've played with a little bit to see what comes through the options param -- however that appears (I think) to make the chunking calculations my responsibility. My original thought was to manipulate the options.chunkServer.url to include the query params I need but I don't believe this processes individual chunks.
In case it makes a difference, this is being done in React using the react-filepond package.
I made and implementation in Laravel 6 using Traits and some "bad practices" (I didn't have time because ... release in prod) to join chunks into a file
Basically:
post to get unique id folder to storage
get chunks and join together
profit!
Here's the full code:
<?php
namespace App\Http\Traits\Upload;
use Closure;
use Faker\Factory as Faker;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
trait Uploadeable
{
public function uploadFileInStorage(Request $request, Closure $closure)
{
// get the nex offset for next chunk send
if (($request->isMethod('options') || $request->isMethod('head')) && $request->has('patch')) {
//get the temp dir
$dir = $request->patch . DIRECTORY_SEPARATOR;
// reead all chunks in directory
$patch = collect(Storage::files($dir))
->sortBy(function ($file) {
return Storage::lastModified($file);
});
// read offsets for calculate
$offsets = array();
$size = 0;
$last_offset = 0;
foreach ($patch as $filename) {
$size = Storage::size($filename);
list($dir, $offset) = explode('file.patch.', $filename, 2);
array_push($offsets, $offset);
if ($offset > 0 && !in_array($offset - $size, $offsets)) {
$last_offset = $offset - $size;
break;
}
// last offset is at least next offset
$last_offset = $offset + $size;
}
// return offset
return response($last_offset, 200)
->header('Upload-Offset', $last_offset);
}
// chunks
if ($request->isMethod('patch') && $request->has('patch')) {
// get the temp dir
$dir = $request->patch . DIRECTORY_SEPARATOR;
// read headers
$offset = $request->header('upload-offset');
$length = $request->header('upload-length');
// should be numeric values, else exit
if (!is_numeric($offset) || !is_numeric($length)) {
return response('', 400);
}
// get the file name
$name = $request->header('Upload-Name');
// sleep server for get a diference between file created to sort
usleep(500000);
// storage the chunk with name + offset
Storage::put($dir . 'file.patch.' . $offset, $request->getContent());
// calculate total size of patches
$size = 0;
$patch = Storage::files($dir);
foreach ($patch as $filename) {
$size += Storage::size($filename);
}
// make the final file
if ($size == $length) {
// read all chunks in directory
$files = collect(Storage::files($dir))
->sortBy(function ($file) {
return Storage::lastModified($file);
});
// create output file
//Log::info(storage_path('app'));
$new_file_name = $final_name = trim(storage_path('app') . DIRECTORY_SEPARATOR . $dir . $name);
$file_handle = fopen($new_file_name, 'w');
// write patches to file
foreach ($files as $filename) {
// get offset from filename
list($dir, $offset) = explode('.patch.', $filename, 2);
// read chunk
$patch_handle = fopen(storage_path('app') . DIRECTORY_SEPARATOR . trim($filename), 'r');
$patch_contents = fread($patch_handle, filesize(storage_path('app') . DIRECTORY_SEPARATOR . trim($filename)));
fclose($patch_handle);
// apply patch
fseek($file_handle, $offset);
fwrite($file_handle, $patch_contents);
}
// done with file
fclose($file_handle);
// file permission (prefered 0755)
chmod($final_name, 0777);
// remove patches
foreach ($patch as $filename) {
$new_file_name = storage_path('app') . DIRECTORY_SEPARATOR . trim($filename);
unlink($new_file_name);
}
// simple class (no time to explain)
$file = new UploadedFile(
$final_name,
basename($final_name),
mime_content_type($final_name),
filesize($final_name),
false
);
$dir = $request->patch . DIRECTORY_SEPARATOR;
$object = new \stdClass();
$object->full_path = (string)$file->getPathname();
$object->directory = (string)($dir);
$object->path = (string)($dir . basename($final_name));
$object->name = (string)$file->getClientOriginalName();
$object->mime_type = (string)$file->getClientMimeType();
$object->extension = (string)$file->getExtension();
$object->size = (string)$this->formatSizeUnits($file->getSize());
// exec closure
$closure($file, (object)$object, $request);
}
// response
return response()->json([
'message' => 'Archivo subido correctamente.',
'filename' => $name
], 200);
}
// get dir unique id folder temp
if ($request->isMethod('post')) {
$faker = Faker::create();
$unique_id = $faker->uuid . '-' . time();
$unique_folder_path = $unique_id;
// create directory
Storage::makeDirectory($unique_folder_path);
// permisos directorio
chmod(storage_path('app') . DIRECTORY_SEPARATOR . $unique_folder_path . DIRECTORY_SEPARATOR, 0777);
// response with folder
return response($unique_id, 200)
->header('Content-Type', 'text/plain');
}
}
private function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824) {
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
$bytes = number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
$bytes = number_format($bytes / 1024, 2) . ' KB';
} elseif ($bytes > 1) {
$bytes = $bytes . ' bytes';
} elseif ($bytes == 1) {
$bytes = $bytes . ' byte';
} else {
$bytes = '0 bytes';
}
return $bytes;
}
}
ยดยดยด
Related
I need the last 7 days' storage logs to move a new folder. But, I can't move them and got this error.
rename(/var/www/html/eMarketing/storage/logs/old-log-2020-02-27,/var/www/html/eMarketing/storage/logs/laravel-2020-02-27.log): Not a directory
My Code is here
public function logs()
{
$today = \Carbon\Carbon::today()->format('Y-m-d');
$days = \Carbon\Carbon::today()->subDays(7)->format('Y-m-d');
$newDirectoryPath = storage_path('logs/old-log-'.$days);
if (!\File::isDirectory($newDirectoryPath)) {
\File::makeDirectory($newDirectoryPath);
}
$path = storage_path('logs/');
$allFiles = \File::allFiles($path);
foreach($allFiles as $files) {
$file = pathinfo($files);
$logDay = str_replace('laravel-','', $file['filename']);
if ($logDay >= $days && $logDay < $today) {
\File::move($newDirectoryPath, $path.$file['basename']);
}
}
}
Problem
The problem is, you don't have files to move.
$newDirectoryPath = storage_path('logs/old-log-' . $days);
if (!\File::isDirectory($newDirectoryPath)) {
\File::makeDirectory($newDirectoryPath);
}
The move() method may be used to rename or move an existing file to a new location. But
$newDirectoryPath is a folder not a file.
Solution
You need to change :
\File::move(
$path . $file['basename'], // old file
$newDirectoryPath . '/' . $file['basename'] // new file
);
public function logs()
{
$today = \Carbon\Carbon::today()->format('Y-m-d');
$days = \Carbon\Carbon::today()->subDays(7)->format('Y-m-d');
$newDirectoryPath = storage_path('logs/old-log-' . $days);
if (!\File::isDirectory($newDirectoryPath)) {
\File::makeDirectory($newDirectoryPath);
}
$path = storage_path('logs/');
$allFiles = \File::allFiles($path);
foreach ($allFiles as $files) {
$file = pathinfo($files);
$logDay = str_replace('laravel-', '', $file['filename']);
if ($logDay >= $days && $logDay < $today) {
\File::move($path . $file['basename'], $newDirectoryPath . '/' . $file['basename']);
}
}
}
I am trying to unlink files that were created the day before
I have a custom application > core > MY_Log.php file and it creates a log for each error level. For easier reading.
logs > DEBUG-04-08-2016.php
logs > ERROR-04-08-2016.php
logs > INFO-04-08-2016.php
logs > DEBUG-03-08-2016.php
logs > ERROR-03-08-2016.php
logs > INFO-03-08-2016.php
Question how am I able to modify the write_log so could delete / unlink files that were created the day before?
<?php
class MY_Log extends CI_Log {
public function write_log($level, $msg)
{
if ($this->_enabled === FALSE)
{
return FALSE;
}
$level = strtoupper($level);
if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
&& ! isset($this->_threshold_array[$this->_levels[$level]]))
{
return FALSE;
}
$filepath = $this->_log_path . $level .'-'. date('d-m-Y').'.'.$this->_file_ext;
$message = '';
if ( ! file_exists($filepath))
{
$newfile = TRUE;
// Only add protection to php files
if ($this->_file_ext === 'php')
{
$message .= "";
}
}
if ( ! $fp = #fopen($filepath, 'ab'))
{
return FALSE;
}
flock($fp, LOCK_EX);
// Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
if (strpos($this->_date_fmt, 'u') !== FALSE)
{
$microtime_full = microtime(TRUE);
$microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
$date = new DateTime(date('d-m-Y H:i:s.'.$microtime_short, $microtime_full));
$date = $date->format($this->_date_fmt);
}
else
{
$date = date($this->_date_fmt);
}
$message .= $this->_format_line($level, $date, $msg);
for ($written = 0, $length = strlen($message); $written < $length; $written += $result)
{
if (($result = fwrite($fp, substr($message, $written))) === FALSE)
{
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
if (isset($newfile) && $newfile === TRUE)
{
chmod($filepath, $this->_file_permissions);
}
return is_int($result);
}
}
First of use
$config['log_threshold'] = 1;
For only error message, so there will be less number of files
Add below code just before $filepath; to delete previous date logs
$unlink_date = date('Y-m-d',strtotime("-1 days"));
$filepath_unlink = $this->_log_path . $level .'-'. $unlink_date.'.'.$this->_file_ext;
if ( file_exists($filepath_unlink))
{
unlink($filepath_unlink);
}
I am using image extension for image re sizing but they are not resized according to the parameters which i gave. Here is my code.Is there any mistake in my code or what. Images which are resized have dimension equal to "800*533"
but not exactly equals to 800*600.
public function actionCreate()
{
$model=new Business;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Business']))
{
$rnd = rand(0, 9999); // generate random number between 0-9999
$model->attributes = $_POST['Business'];
$uploadedFile = CUploadedFile::getInstance($model, 'image');
$fileName = "{$rnd}-{$uploadedFile}"; // random number + file name
$model->image = $fileName;
if ($model->save()) {
if(!empty($uploadedFile)) // check if uploaded file is set or not
{
//$uploadedFile->saveAs(Yii::getPathOfAlias('webroot')."/img".$filename);
$uploadedFile->saveAs(Yii::app()->basePath . '/../img/' . $fileName);
$image = Yii::app()->image->load(Yii::app()->basePath . '/../img/' . $fileName);
$image->resize(800, 600);
$image->save(Yii::app()->basePath . '/../img/' . $fileName);
}
$this->redirect(array('view', 'id' => $model->id));
}
}
$this->render('create', array(
'model' => $model,
));
}
First advise. Don't store not resized image you can use
tempName property of CUploadedFile
$image = Yii::app()->image->load($uploadedFile->tempName );
$image->resize(800, 600);
$image->save(Yii::app()->basePath . '/../img/' . $fileName);
About resize i think you have to calculate size of resized picture.
Here is my code
protected static function getImgBox($img,$width,$height,$bySide,$boxType){
$img_width=$img->getSize()->getWidth();
$img_height=$img->getSize()->getHeight();
$newWidth =0;
$newHeight=0;
switch($boxType){
case self::BOX_TYPE_FILL:
{
$newWidth=$width;
$newHeight=$height;
}
break;
case self::BOX_TYPE_WO:{
if($bySide==self::BY_SIDE_WIDTH) {
$newWidth = $width;
$newHeight = $img_height * $newWidth / $img_width;
}
if($bySide==self::BY_SIDE_HEIGHT){
$newHeight=$height;
$newWidth = $img_width*$newHeight/$img_height;
}
}
break;
case self::BOX_TYPE_INSIDE:{
$newWidth = $width;
$newHeight = $img_height * $newWidth / $img_width;
if($newHeight>=$height){
$newHeight=$height;
$newWidth = $img_width*$newHeight/$img_height;
}
}
}
if($newHeight!=0 && $newWidth!=0){
return new Box(ceil($newWidth),ceil($newHeight));
}
else
return null;
}
I don't know witch extension you use. I use Imagine Extension for Yii 2
$imgpathlogo = App::param("upload_path").'outletlogo'. DIRECTORY_SEPARATOR;
$imgpathlogothumb100 = App::param("upload_path")."outletlogo". DIRECTORY_SEPARATOR."thumb100". DIRECTORY_SEPARATOR;
$imgpathlogothumb200 = App::param("upload_path")."outletlogo". DIRECTORY_SEPARATOR."thumb200". DIRECTORY_SEPARATOR;
///////////////////Chek Outlet New Logo Images////////////////
if ($_FILES['OutletMaster']['name']['outlet_logo'] != "") {
$imagelogo=$files['OutletMaster']['name']['outlet_logo'];
$logofilename=explode(".", $imagelogo);
$logofileext = $logofilename[count($logofilename) - 1];
$newlogofilename = uniqid(). "." . $logofileext;
$model->outlet_logo = $newlogofilename;
move_uploaded_file($_FILES['OutletMaster']['tmp_name']['outlet_logo'],$imgpathlogo.$newlogofilename);
//////////////////Creating Thumbnail For Outlet Logo///////////////////////////
$ext = explode(".", strtolower($newlogofilename))[1];
$src = $imgpathlogo.$newlogofilename;
if ($ext == 'gif')
$resource = imagecreatefromgif($src);
else if ($ext == 'png')
$resource = imagecreatefrompng($src);
else if ($ext == 'PNG')
$resource = imagecreatefrompng($src);
else if ($ext == 'jpg' || $ext == 'jpeg')
$resource = imagecreatefromjpeg($src);
$width = imagesx($resource);
$height = imagesy($resource);
$thumbWidth100 = 100;
$desired_width100 = $thumbWidth100;
$desired_height100 = floor( $height * ( $thumbWidth100 / $width ) );
$virtual_image = imagecreatetruecolor($desired_width100,$desired_height100);
imagecopyresized($virtual_image,$resource,0,0,0,0,$desired_width100,$desired_height100,$width,$height);
imagejpeg( $virtual_image, "{$imgpathlogothumb100}{$newlogofilename}" );
$thumbWidth200 = 200;
$desired_width200 = $thumbWidth200;
$desired_height200 = floor( $height * ( $thumbWidth200 / $width ) );
$virtual_image = imagecreatetruecolor($desired_width200,$desired_height200);
imagecopyresized($virtual_image,$resource,0,0,0,0,$desired_width200,$desired_height200,$width,$height);
imagejpeg( $virtual_image, "{$imgpathlogothumb200}{$newlogofilename}" );
}
I am trying to create several thumbs of different sizes using a foreach loop on a resize method.
$sizes = array(
'thumb' => Configure::read('Shop.image_thumb_dimensions'),
'medium' => Configure::read('Shop.image_medium_dimensions'),
'large' => Configure::read('Shop.image_large_dimensions')
);
foreach($sizes as $folder => $size) {
$destFolder = WWW_ROOT. $this->upload_dir . DS . $folder;
if (!file_exists($destFolder)) {
#mkdir($destFolder);
}
$dimensionsArray = explode(',', $size);
$newWidth = $dimensionsArray[0];
$newHeight = $dimensionsArray[1];
$destFile = $destFolder . DS . $fileName;
$resize = $this->__resize($filePath, $destFile, $newWidth, $newHeight);
}
and then the resize function which uses some methods from a component goes like this:
private function __resize($src, $destFile, $newWidth, $newHeight) {
$this->Watimage->setImage($src);
$this->Watimage->resize(array('type' => 'resizecrop', 'size' => array($newWidth, $newHeight)));
if ( !$this->Watimage->generate($destFile) ) {
// handle errors...
return $this->Watimage->errors;
}
else {
return true;
}
}
So this works great for the first image size (the thumb) but thereafter I get the error:
b>Notice</b> (8)</a>: Indirect modification of overloaded property WatimageComponent::$file has no effect [<b>APP/Plugin/Gallery/Controller/Component/WatimageComponent.php</b>, line <b>114</b>
I don't understand what I am doing wrong?? Have spent hours trying to figure this out.
Any illumination on the matter will be greatly appreciated.
This is the method from the component class:
public function setImage($file) {
// Remove possible errors...
$this->errors = array();
try
{
if ( is_array($file) && isset($file['file']) )
{
if ( isset($file['quality']) )
$this->setQuality($file['quality']);
$file = $file['file'];
}
elseif ( empty($file) || (is_array($file) && !isset($file['file'])) )
{
throw new Exception('Empty file');
}
if ( file_exists($file) )
$this->file['image'] = $file;
else
throw new Exception('File "' . $file . '" does not exist');
// Obtain extension
$this->extension['image'] = $this->getFileExtension($this->file['image']);
// Obtain file sizes
$this->getSizes();
// Create image boundary
$this->image = $this->createImage($this->file['image']);
$this->handleTransparentImage();
}
catch ( Exception $e )
{
$this->error($e);
return false;
}
return true;
}
There you go, the initial problem is most probably the unsetting of the WaitmageComponent::$file property
unset($this->file);
https://github.com/elboletaire/Watimage/blob/b72e7ac17ad30bfc47ae4d0f31c4ad6795c8f8d2/watimage.php#L706
After doing so, the magic property accessor Component::__get() will kick in when trying to access the now unexistent WaitmageComponent::$file property, and consequently this results in the warning you are receiving.
Instead of unsetting the variable, it should be reinitialized:
$this->file = array();
And of course it should also be initialized properly:
private $file = array();
You should initialize the property on your class, i think what is going on is you are trying to do something like:
$this->file = $var;
But you need to tell your class what is the $file property is:
class WaitmageComponent extends Component {
public $file = array();
}
I try use this:
$image = new JImage();
$image->loadFile($item->logo);
$image->resize('208', '125');
$properties = JImage::getImageFileProperties($item->logo);
echo $image->toFile(JPATH_CACHE . DS . $item->logo, $properties->type);
But not work =\ any idea?
Try this out:
// Set the path to the file
$file = '/Absolute/Path/To/File';
// Instantiate our JImage object
$image = new JImage($file);
// Get the file's properties
$properties = JImage::getImageFileProperties($file);
// Declare the size of our new image
$width = 100;
$height = 100;
// Resize the file as a new object
$resizedImage = $image->resize($width, $height, true);
// Determine the MIME of the original file to get the proper type for output
$mime = $properties->mime;
if ($mime == 'image/jpeg')
{
$type = IMAGETYPE_JPEG;
}
elseif ($mime == 'image/png')
{
$type = IMAGETYPE_PNG;
}
elseif ($mime == 'image/gif')
{
$type = IMAGETYPE_GIF;
}
// Store the resized image to a new file
$resizedImage->toFile('/Absolute/Path/To/New/File', $type);