Symfony2.2 #Assert\Image not working - validation

Completely misses any files.
If I use Assert \ File works, but then does not take minWidth, minHeight
Purpose:
1) The file must be an image.
2) Make a limit on the resolution of the image
My Entity:
/**
* #Assert\Image(
* minWidth = 150,
* maxWidth = 150,
* minHeight = 190,
* maxHeight = 190
* )
* #Assert\NotBlank(message="Додайте будь ласка фотографію")
*/
protected $file;
/**
* Sets file.
*
* #param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
}
/**
* Get file.
*
* #return UploadedFile
*/
public function getFile()
{
return $this->file;
}
Generate form:
$builder
->add('file', 'file', array(
'label' => 'Ваша фотографія (Обов`язковий розмір: 150*190)',
'required' => true,))

Related

Laravel 9: AWS S3 retreiving a Video to Stream

After updating to Laravel 9.14 with PHP 8.1.4 then streaming has broke that was based on this answer https://stackoverflow.com/a/52598361/6825499.
I can see that it is because of a
Call to undefined method League\Flysystem\AwsS3V3\AwsS3V3Adapter::getClient()
So it seems to have been removed in the newest version from league/flysystem-aws-s3-v3 (3.0.13)
I did find a reference to this SO post which tries to explain there is a workaround now: Get S3Client from storage facade in Laravel 9
This is though too complex for me to understand.
Does anyone know what can be done?
You need to update the PHP version on your server to the latest one. It sounds like the server is still on the PHP 7.x version and that's the issue.
After researching quite a bit I realized that the issue came down to updates described in Laravel document page about upgrading.
I ended up altering the code a bit where I use environment variables to fill out what was before provieded by the adapter in the code.
In the latest version of the flysystem,there is no longer access to the client via the adapter. Due to mentioned reason, the service has been broken.
For a fully working class then you can use below code for laravel version 9
<?php
namespace App\Http;
use Exception;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use League\Flysystem\Filesystem;
use Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class S3FileStream
{
/**
* Name of adapter
*
* #var string
*/
private $adapterName;
/**
* Storage disk
*
* #var FilesystemAdapter
*/
private $disk;
/**
* #var int file end byte
*/
private $end;
/**
* #var string
*/
private $filePath;
/**
* Human-known filename
*
* #var string|null
*/
private $humanName;
/**
* #var bool storing if request is a range (or a full file)
*/
private $isRange = false;
/**
* #var int|null length of bytes requested
*/
private $length = null;
/**
* #var array
*/
private $returnHeaders = [];
/**
* #var int file size
*/
private $size;
/**
* #var string bucket name
*/
private $bucket;
/**
* #var int start byte
*/
private $start;
/**
* S3FileStream constructor.
* #param string $filePath
* #param string $adapter
* #param string $humanName
*/
public function __construct(string $filePath, string $adapter = 's3', ?string $humanName = null)
{
$options = [
'region' => env("AWS_DEFAULT_REGION"),
'version' => 'latest'
];
$this->filePath = $filePath;
$this->adapterName = $adapter;
$this->disk = Storage::disk($this->adapterName);
$this->client = new \Aws\S3\S3Client($options);
$this->humanName = $humanName;
$this->bucket = env("AWS_BUCKET");
//Set to zero until setHeadersAndStream is called
$this->start = 0;
$this->size = 0;
$this->end = 0;
}
/**
* Output file to client.
*/
public function output()
{
return $this->setHeadersAndStream();
}
/**
* Output headers to client.
* #return Response|StreamedResponse
*/
protected function setHeadersAndStream()
{
if (!$this->disk->exists($this->filePath)) {
report(new Exception('S3 File Not Found in S3FileStream - ' . $this->adapterName . ' - ' . $this->disk->path($this->filePath)));
return response('File Not Found', 404);
}
$this->start = 0;
$this->size = $this->disk->size($this->filePath);
$this->end = $this->size - 1;
$this->length = $this->size;
$this->isRange = false;
//Set headers
$this->returnHeaders = [
'Last-Modified' => $this->disk->lastModified($this->filePath),
'Accept-Ranges' => 'bytes',
'Content-Type' => $this->disk->mimeType($this->filePath),
'Content-Disposition' => 'inline; filename=' . ($this->humanName ?? basename($this->filePath) . '.' . Arr::last(explode('.', $this->filePath))),
'Content-Length' => $this->length,
];
//Handle ranges here
if (!is_null(request()->server('HTTP_RANGE'))) {
$cStart = $this->start;
$cEnd = $this->end;
$range = Str::after(request()->server('HTTP_RANGE'), '=');
if (strpos($range, ',') !== false) {
return response('416 Requested Range Not Satisfiable', 416, [
'Content-Range' => 'bytes */' . $this->size,
]);
}
if (substr($range, 0, 1) == '-') {
$cStart = $this->size - intval(substr($range, 1)) - 1;
} else {
$range = explode('-', $range);
$cStart = intval($range[0]);
$cEnd = (isset($range[1]) && is_numeric($range[1])) ? intval($range[1]) : $cEnd;
}
$cEnd = min($cEnd, $this->size - 1);
if ($cStart > $cEnd || $cStart > $this->size - 1) {
return response('416 Requested Range Not Satisfiable', 416, [
'Content-Range' => 'bytes */' . $this->size,
]);
}
$this->start = intval($cStart);
$this->end = intval($cEnd);
$this->length = min($this->end - $this->start + 1, $this->size);
$this->returnHeaders['Content-Length'] = $this->length;
$this->returnHeaders['Content-Range'] = 'bytes ' . $this->start . '-' . $this->end . '/' . $this->size;
$this->isRange = true;
}
return $this->stream();
}
/**
* Stream file to client.
* #throws Exception
* #return StreamedResponse
*/
protected function stream(): StreamedResponse
{
$this->client->registerStreamWrapper();
// Create a stream context to allow seeking
$context = stream_context_create([
's3' => [
'seekable' => true,
],
]);
// Open a stream in read-only mode
if (!($stream = fopen("s3://{$this->bucket}/{$this->filePath}", 'rb', false, $context))) {
throw new Exception('Could not open stream for reading export [' . $this->filePath . ']');
}
if (isset($this->start) && $this->start > 0) {
fseek($stream, $this->start, SEEK_SET);
}
$remainingBytes = $this->length ?? $this->size;
$chunkSize = 100;
$video = response()->stream(
function () use ($stream, $remainingBytes, $chunkSize) {
while (!feof($stream) && $remainingBytes > 0) {
$toGrab = min($chunkSize, $remainingBytes);
echo fread($stream, $toGrab);
$remainingBytes -= $toGrab;
flush();
}
fclose($stream);
},
($this->isRange ? 206 : 200),
$this->returnHeaders
);
return $video;
}
}

Convert Codeigniter's Excel class from PHPExcel to PhpSpreadsheet

I'm about to migrate the PhpExcel to PhpSpreadsheet using Codeigniter 3.1.11
Previously I use a PHP class file named Excel.php which helps to generate Excel using PhpExcel but now I want to connect it using PhpSpreadsheet.
The code is as follow
class Excel extends PHPExcel{
public $alphabet;
/**
* Constructor
*
* Responsible for initializing library class
*
* #access public
* #return void
*/
public function __construct() {
parent::__construct();
$this->alphabet = range('A', 'Z');
$this->alphabet[26] = 'AA';
$this->alphabet[27] = 'AB';
$this->alphabet[28] = 'AC';
$this->alphabet[29] = 'AD';
$this->alphabet[30] = 'AE';
$this->alphabet[31] = 'AF';
$this->alphabet[32] = 'AG';
$this->alphabet[33] = 'AH';
$this->alphabet[34] = 'AI';
$this->alphabet[35] = 'AJ';
$this->alphabet[36] = 'AK';
$this->alphabet[37] = 'AL';
$this->alphabet[38] = 'AM';
}
/**
* Responsible for generating excel
*
* Column_format array is use as a column name having
* number => '#,##0.00'
* number => '0.00'
* number => '0'
*
* #access public
* #param array, array, array, array, Boolean
* #return void
*/
private function generate_excel_sheet($header_data, $content_data, $column_width = NULL, $column_format = NULL, $border = FALSE){
//make 2st row become bold
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].'2')->getFont()->setBold(true);
//Wraping text
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].'2')->getAlignment()->setWrapText(true);
//Setting column width
if(!empty($column_width)){
foreach($column_width as $column => $size){
$this->getActiveSheet()->getColumnDimension($column)->setWidth($size);
}
}
//Merger table header and content
$excel_data[0] = $header_data;
if(!empty($content_data))
$excel_data = array_merge($excel_data,$content_data);
$this->getActiveSheet()->fromArray($excel_data, null, 'A2'); //Adding table data from A2 cell
//Setting column formate as Number
if(!empty($column_format)){
$last_row = $this->getActiveSheet()->getHighestRow();
foreach($column_format as $column => $format){
if(isset($format[0]) && $format[0] == 'Number')
$this->getActiveSheet()->getStyle($column)->getNumberFormat()->setFormatCode($format[1]);
if(isset($format[0]) && $format[0] == 'Date')
$this->getActiveSheet()->getStyle($column.'3:'.$column.$last_row)->getNumberFormat()->setFormatCode($format[1]);
}
}
//Creating Border if $border = TRUE
if($border){
$styleArray = array( 'borders' => array(
'allborders' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN
)
)
);
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].(count($excel_data)+1))->applyFromArray($styleArray);
}
}//end function generate_excel(...)
/**
* This is the main class to create excel we pass the Excel name, Table data, Sheet Name and Sheet Heading
* Where Table data is a multidimensional associative array detials are as follow
* Sheet
* $table_data[0][table_heading]= array();
* $table_data[0][contant_data] = array();
* $table_data[0][column_width] = array() (by default NULL);
* $table_data[0][column_format]= array() (by default NULL);
* $table_data[0][table_border] = Boolean (by default FALSE);
*
* $sheet_name[0] = 'sheet1';
* $sheet_heading[0] = 'This is a testing heading'
*
* #access public
* #param string, array, array, array
* #return void
*/
public function create_excel($excel_name = 'new_excel', $table_data = NULL, $sheet_name = NULL, $sheet_heading = NULL){
foreach($table_data as $key => $row){
//Create a new worksheet, after the default sheet
if($key > 0) $this->createSheet();
//Set Active Sheet
$this->setActiveSheetIndex($key);
//name the worksheet
$sheet = $this->getActiveSheet();
$sheet->setTitle($sheet_name[$key]);
//Getting last column name
$last_column = $this->alphabet[count($table_data[$key]['table_heading'])-1];
//heading worksheet
$sheet->setCellValue('A1', $sheet_heading[$key]);
$sheet->mergeCells('A1:'.$last_column.'1'); //Need to make it dynamic
$sheet->getStyle('A1:'.$last_column.'1')->getFont()->setSize(20);
$sheet->getStyle('A1:'.$last_column.'1')->getFont()->setBold(true);
$sheet->getStyle('A1:'.$last_column.'1')->getAlignment()->applyFromArray(array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER));
$header_data = NULL;
$content_data = NULL;
$column_width = NULL;
$column_format = NULL;
$border = FALSE;
if(!empty($table_data[$key]['table_heading']))
$header_data = $table_data[$key]['table_heading'];
if(!empty($table_data[$key]['content_data']))
$content_data = $table_data[$key]['content_data'];
if(!empty($table_data[$key]['column_width']))
$column_width = $table_data[$key]['column_width'];
if(!empty($table_data[$key]['column_format']))
$column_format = $table_data[$key]['column_format'];
$table_border = $table_data[$key]['table_border'];
$this->generate_excel_sheet($header_data, $content_data, $column_width, $column_format, $table_border);
}//end foreach($table_data as $key => $value)
//Print excel here;
$this->print_excel($excel_name);
}//end function create_excel(...)
/**
*
*/
public function print_excel($excel_name){
//Creating header
header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename='.$excel_name.'.xlsx');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($this, 'Excel2007');
$objWriter->save('php://output');
}
}// END Excel CLASS
/* End of file Excel.php */
/* Location: ./application/libraries/Excel.php */
I called the above code using following function
/**
* Download Excel file
*
* #access private
* #param array
* #return void
*/
private function download_excel($excel_data){
$excel_name = $this->controller_name.'_'.date('Y-m-d');
$sheet_name = array('Report Salary');
$sheet_heading = array('Report Salary');
$header_data = array( 'S. No.', 'Title', 'First Name', 'Last Name', 'salary');
$content_data = array();
//Setting content data
$i =0;
foreach($excel_data as $row){
$i++;
$row_content = array();
$row_content[] = $i;
$row_content[] = $row->title;
$row_content[] = html_entity_decode($row->first_name, ENT_QUOTES, "UTF-8");
$row_content[] = html_entity_decode($row->last_name, ENT_QUOTES, "UTF-8");
$row_content[] = html_entity_decode($row->salary, ENT_QUOTES, "UTF-8");
$content_data[] = $row_content;
}
//Set number format
//$column_format = NULL;
$column_format = array('E' => array('Number','#,##0'));
//Set excel column width
$column_width = array( 'A' => 10, 'B' => 6, 'C' => 30, 'D' => 30, 'E' => 8);
$table_data[0]['table_heading']= $header_data;
$table_data[0]['content_data'] = $content_data;
$table_data[0]['column_width'] = $column_width;
$table_data[0]['column_format']= $column_format;
$table_data[0]['table_border'] = TRUE;
//Generate excel
$this->excel->create_excel($excel_name, $table_data, $sheet_name, $sheet_heading);
}//end function download()
Could any one help to convert it?
Thanks
Finally, I solve it myself. I hope it helps others too.
Just to update here Excel.php file is written by me which helps to make it easier to use the PhpSpreadsheet library. And I used to put the Excel.php file in Library Directory in the Codeigniter table structured.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* An open source application development framework for PHP 7.3 or newer
*
* #author Sameer Naqvi
* #since Version 2.0
* #filesource
*/
// ------------------------------------------------------------------------
/**
* Excel Class
*
* This library holds the functions which helps to generate the Excel in (xlsx formate)
*
* #package Libraries
* #subpackage -
* #category Library
* #author Sameer Naqvi
*/
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
//use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class Excel extends Spreadsheet{
public $alphabet;
/**
* Constructor
*
* Responsible for initializing library class
*
* #access public
* #return void
*/
public function __construct() {
parent::__construct();
$this->alphabet = range('A', 'Z');
$this->alphabet[26] = 'AA';
$this->alphabet[27] = 'AB';
$this->alphabet[28] = 'AC';
$this->alphabet[29] = 'AD';
$this->alphabet[30] = 'AE';
$this->alphabet[31] = 'AF';
$this->alphabet[32] = 'AG';
$this->alphabet[33] = 'AH';
$this->alphabet[34] = 'AI';
$this->alphabet[35] = 'AJ';
$this->alphabet[36] = 'AK';
$this->alphabet[37] = 'AL';
$this->alphabet[38] = 'AM';
}
/**
* Responsible for generating excel sheet
*
* Column_format array is use as a column name having
* Number => '#,##0.00'
* Number => '0.00'
* Number => '0'
* Date => 'yyyy-mm-dd'
*
* #access public
* #param array, array, array, array, Boolean
* #return void
*/
private function generate_excel_sheet($header_data, $content_data, $column_width = NULL, $column_format = NULL, $border = FALSE){
//make 2st row become bold
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].'2')->getFont()->setBold(true);
//Wraping text
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].'2')->getAlignment()->setWrapText(true);
//Alignment = Vertical_center
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].'2')->getAlignment()->applyFromArray(array('vertical' => Alignment::VERTICAL_CENTER));
//Setting column width
if(!empty($column_width)){
foreach($column_width as $column => $size){
$this->getActiveSheet()->getColumnDimension($column)->setWidth($size);
}
}
//Merger table header and content
$excel_data[0] = $header_data;
if(!empty($content_data))
$excel_data = array_merge($excel_data,$content_data);
$this->getActiveSheet()->fromArray($excel_data, null, 'A2'); //Adding table data from A2 cell
//Setting column formate as Number or Date
if(!empty($column_format)){
$last_row = $this->getActiveSheet()->getHighestRow();
foreach($column_format as $column => $format){
if(isset($format[0]) && $format[0] == 'Number')
$this->getActiveSheet()->getStyle($column)->getNumberFormat()->setFormatCode($format[1]);
if(isset($format[0]) && $format[0] == 'Date')
$this->getActiveSheet()->getStyle($column.'3:'.$column.$last_row)->getNumberFormat()->setFormatCode($format[1]);
//$this->getActiveSheet()->getStyle($column.'3:'.$column.$last_row)->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDD);
}
}
//Creating Border if $border = TRUE
if($border){
$styleArray = array(
'borders' => array(
'allBorders' => array(
'borderStyle' => Border::BORDER_THIN,
'color' => array('argb' => '000000'),
),
),
);
$this->getActiveSheet()->getStyle('A2:'.$this->alphabet[count($header_data)-1].(count($excel_data)+1))->applyFromArray($styleArray);
}
}//end function generate_excel(...)
/**
* This is the main class to create excel we pass the Excel name, Table data, Sheet Name and Sheet Heading
* Where Table data is a multidimensional associative array detials are as follow
* Sheet
* $table_data[0][table_heading]= array();
* $table_data[0][contant_data] = array();
* $table_data[0][column_width] = array() (by default NULL);
* $table_data[0][column_format]= array() (by default NULL);
* $table_data[0][table_border] = Boolean (by default FALSE);
*
* $sheet_name[0] = 'sheet1';
* $sheet_heading[0] = 'This is a testing heading'
*
* #access public
* #param string, array, array, array
* #return void
*/
public function create_excel($excel_name = 'new_excel', $table_data = NULL, $sheet_name = NULL, $sheet_heading = NULL){
foreach($table_data as $key => $row){
//Create a new worksheet, after the default sheet
if($key > 0) $this->getActiveSheet();
//Set Active Sheet
$this->setActiveSheetIndex($key);
//name the worksheet
$sheet = $this->getActiveSheet();
$sheet->setTitle($sheet_name[$key]);
//Getting last column name
$last_column = $this->alphabet[count($table_data[$key]['table_heading'])-1];
//heading worksheet
$sheet->setCellValue('A1', $sheet_heading[$key]);
$sheet->mergeCells('A1:'.$last_column.'1'); //Need to make it dynamic
$sheet->getStyle('A1:'.$last_column.'1')->getFont()->setSize(20);
$sheet->getStyle('A1:'.$last_column.'1')->getFont()->setBold(true);
$sheet->getStyle('A1:'.$last_column.'1')->getAlignment()->applyFromArray(array('horizontal' => Alignment::HORIZONTAL_CENTER));
$header_data = NULL;
$content_data = NULL;
$column_width = NULL;
$column_format = NULL;
$border = FALSE;
if(!empty($table_data[$key]['table_heading']))
$header_data = $table_data[$key]['table_heading'];
if(!empty($table_data[$key]['content_data']))
$content_data = $table_data[$key]['content_data'];
if(!empty($table_data[$key]['column_width']))
$column_width = $table_data[$key]['column_width'];
if(!empty($table_data[$key]['column_format']))
$column_format = $table_data[$key]['column_format'];
$table_border = $table_data[$key]['table_border'];
$this->generate_excel_sheet($header_data, $content_data, $column_width, $column_format, $table_border);
}//end foreach($table_data as $key => $value)
//Print excel here;
$this->print_excel($excel_name);
}//end function create_excel(...)
/**
* This function helps to print or downlaod excel
*/
public function print_excel($excel_name){
//Creating header
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename='.$excel_name.'.xlsx');
header('Cache-Control: max-age=0');
$writer = new Xlsx($this);
ob_end_clean();
$writer->save('php://output');
exit;
}
/**
* This function is responsible to convert php date into excel date
* Then we can apply excel formating on date field
*
* #access public
* #param data (yyyy-mm-dd)
* #return int (excel number e.g. 2008-12-31 to 39813)
*/
public function convert_date_php_2_excel($php_date){
if(isset($php_date) && trim($php_date)!= "")
return intval(25569 + strtotime($php_date) / 86400);
return NULL;
}
}// END Excel CLASS
/* End of file Excel.php */
/* Location: ./application/libraries/Excel.php */

Laravel S3 retreiving a Video to Stream

I'm storing videos to Amazon S3 via my Laravel app. That works great. But I can't "stream" them.
This is the URL for example: https://website.com/video/342.qt?api_token=a5a18c9f-f5f6-5d66-85e3-aaaaaaa, what should return this movie from S3 called '212.DdsqoK1PlL.qt'
It returns this output when calling the URL:
That's the video, but I was expecting it to run directly in the browser, like this video does: https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4
The route calls this function, retrieving the non-public file from the S3-disk:
public function document(Document $document)
{
return Storage::disk('s3')->get($document->path);
}
The only difference between the example URL that works and mine is that the example is MP4 and mine .QT, but I tried MP4 also and go the same output in the browser; so no autoplaying video.
I guess the movie that plays directly is streaming the video?..
My website is running on Ubuntu and installed also sudo apt-get install vlc.
I personally am opposed to the idea of redirecting to an S3 URL. I mask all my URLs through a Laravel php wrapper server-side. This is the code I use to do so if anyone else encounters similar issues. This code is written for streaming a video from S3 with Laravel 5.6 (and includes HTTP_RANGE support so it works on iOS too).
I use the class below, placed at App/Http/Responses. To use this class, create a method that does this (this is like a getFile method):
$filestream = new \App\Http\Responses\S3FileStream('file_path_and_name_within_bucket', 'disk_bucket_name', 'output_file_name_when_downloaded');
return $filestream->output();
With any luck, you should be streaming in no time (without revealing an S3 URL)!
S3FileStream.php:
<?php
namespace Http\Responses;
use Exception;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class S3FileStream
{
/**
* #var \League\Flysystem\AwsS3v3\AwsS3Adapter
*/
private $adapter;
/**
* Name of adapter
*
* #var string
*/
private $adapterName;
/**
* Storage disk
*
* #var FilesystemAdapter
*/
private $disk;
/**
* #var int file end byte
*/
private $end;
/**
* #var string
*/
private $filePath;
/**
* Human-known filename
*
* #var string|null
*/
private $humanName;
/**
* #var bool storing if request is a range (or a full file)
*/
private $isRange = false;
/**
* #var int|null length of bytes requested
*/
private $length = null;
/**
* #var array
*/
private $returnHeaders = [];
/**
* #var int file size
*/
private $size;
/**
* #var int start byte
*/
private $start;
/**
* S3FileStream constructor.
* #param string $filePath
* #param string $adapter
* #param string $humanName
*/
public function __construct(string $filePath, string $adapter = 's3', ?string $humanName = null)
{
$this->filePath = $filePath;
$this->adapterName = $adapter;
$this->disk = Storage::disk($this->adapterName);
$this->adapter = $this->disk->getAdapter();
$this->humanName = $humanName;
//Set to zero until setHeadersAndStream is called
$this->start = 0;
$this->size = 0;
$this->end = 0;
}
/**
* Output file to client.
*/
public function output()
{
return $this->setHeadersAndStream();
}
/**
* Output headers to client.
* #return Response|StreamedResponse
*/
protected function setHeadersAndStream()
{
if (!$this->disk->exists($this->filePath)) {
report(new Exception('S3 File Not Found in S3FileStream - ' . $this->adapterName . ' - ' . $this->disk->path($this->filePath)));
return response('File Not Found', 404);
}
$this->start = 0;
$this->size = $this->disk->size($this->filePath);
$this->end = $this->size - 1;
$this->length = $this->size;
$this->isRange = false;
//Set headers
$this->returnHeaders = [
'Last-Modified' => $this->disk->lastModified($this->filePath),
'Accept-Ranges' => 'bytes',
'Content-Type' => $this->disk->mimeType($this->filePath),
'Content-Disposition' => 'inline; filename=' . ($this->humanName ?? basename($this->filePath) . '.' . Arr::last(explode('.', $this->filePath))),
'Content-Length' => $this->length,
];
//Handle ranges here
if (!is_null(request()->server('HTTP_RANGE'))) {
$cStart = $this->start;
$cEnd = $this->end;
$range = Str::after(request()->server('HTTP_RANGE'), '=');
if (strpos($range, ',') !== false) {
return response('416 Requested Range Not Satisfiable', 416, [
'Content-Range' => 'bytes */' . $this->size,
]);
}
if (substr($range, 0, 1) == '-') {
$cStart = $this->size - intval(substr($range, 1)) - 1;
} else {
$range = explode('-', $range);
$cStart = intval($range[0]);
$cEnd = (isset($range[1]) && is_numeric($range[1])) ? intval($range[1]) : $cEnd;
}
$cEnd = min($cEnd, $this->size - 1);
if ($cStart > $cEnd || $cStart > $this->size - 1) {
return response('416 Requested Range Not Satisfiable', 416, [
'Content-Range' => 'bytes */' . $this->size,
]);
}
$this->start = intval($cStart);
$this->end = intval($cEnd);
$this->length = min($this->end - $this->start + 1, $this->size);
$this->returnHeaders['Content-Length'] = $this->length;
$this->returnHeaders['Content-Range'] = 'bytes ' . $this->start . '-' . $this->end . '/' . $this->size;
$this->isRange = true;
}
return $this->stream();
}
/**
* Stream file to client.
* #throws Exception
* #return StreamedResponse
*/
protected function stream(): StreamedResponse
{
$this->adapter->getClient()->registerStreamWrapper();
// Create a stream context to allow seeking
$context = stream_context_create([
's3' => [
'seekable' => true,
],
]);
// Open a stream in read-only mode
if (!($stream = fopen("s3://{$this->adapter->getBucket()}/{$this->filePath}", 'rb', false, $context))) {
throw new Exception('Could not open stream for reading export [' . $this->filePath . ']');
}
if (isset($this->start) && $this->start > 0) {
fseek($stream, $this->start, SEEK_SET);
}
$remainingBytes = $this->length ?? $this->size;
$chunkSize = 100;
$video = response()->stream(
function () use ($stream, $remainingBytes, $chunkSize) {
while (!feof($stream) && $remainingBytes > 0) {
$toGrab = min($chunkSize, $remainingBytes);
echo fread($stream, $toGrab);
$remainingBytes -= $toGrab;
flush();
}
fclose($stream);
},
($this->isRange ? 206 : 200),
$this->returnHeaders
);
return $video;
}
}
Like I said on the comments section. I think you should use S3 url (temporary, or public).
You have some options here:
Use laravel temporary url;
Set your file as public + get url;
For more information:
https://laravel.com/docs/5.5/filesystem#storing-files
To set your file visibility as public:
Storage::setVisibility('file.jpg', 'public')
Temporary URL:
$url = Storage::temporaryUrl(
'file1.jpg', Carbon::now()->addMinutes(5)
);
If your file is public, you can use:
Storage::url('file1.jpg');

Yootheme Zoo Image Watermark

I have use the yootheme zoo applications. I need to add watermark to zoo images.
This is zoo image progress file:
<?php
/**
* #package com_zoo
* #author YOOtheme http://www.yootheme.com
* #copyright Copyright (C) YOOtheme GmbH
* #license http://www.gnu.org/licenses/gpl.html GNU/GPL
*/
/**
* Image thumbnail helper class.
*
* #package Component.Helpers
* #since 2.0
*/
class ImageThumbnailHelper extends AppHelper {
/**
* Creates an AppImageThumbnail instance
*
* #param string $file The filepath
*
* #return AppImageThumbnail
*
* #since 2.0
*/
public function create($file) {
return $this->app->object->create('AppImageThumbnail', array($file));
}
/**
* Checks for the required php functions
*
* #return boolean
*
* #since 2.0
*/
public function check() {
$gd_functions = array(
'getimagesize',
'imagecreatefromgif',
'imagecreatefromjpeg',
'imagecreatefrompng',
'imagecreatetruecolor',
'imagecopyresized',
'imagecopy',
'imagegif',
'imagejpeg',
'imagepng'
);
foreach ($gd_functions as $name) {
if (!function_exists($name)) return false;
}
return true;
}
}
/**
* Image thumbnail class.
*
* #package Component.Helpers
* #since 2.0
*/
class AppImageThumbnail {
/**
* App instance
*
* #var App
* #since 2.0
*/
public $app;
/**
* The image file path
* #var string
*/
public $img_file;
/**
* The image format
* #var string
*/
public $img_format;
/**
* The image source
* #var resource
*/
public $img_source;
/**
* The image width
* #var string
*/
public $img_width;
/**
* The image height
* #var string
*/
public $img_height;
/**
* The thumb width
* #var string
*/
public $thumb_width;
/**
* The thumb height
* #var string
*/
public $thumb_height;
/**
* The thumb resize
* #var boolean
*/
public $thumb_resize;
/**
* The thumb quality
* #var int
*/
public $thumb_quality;
/**
* Class constructor
*
* #param string $file The file path.
* #since 2.0
*/
public function __construct($file) {
$this->img_file = $file;
$this->thumb_resize = true;
$this->thumb_quality = 90;
// get image info
list($width, $height, $type, $attr) = #getimagesize($this->img_file, $info);
// set image dimensions and type
if (is_array($info)) {
$this->img_width = $width;
$this->img_height = $height;
$this->thumb_width = $width;
$this->thumb_height = $height;
switch ($type) {
case 1:
$this->img_format = 'gif';
$this->img_source = imagecreatefromgif($this->img_file);
break;
case 2:
$this->img_format = 'jpeg';
$this->img_source = imagecreatefromjpeg($this->img_file);
break;
case 3:
$this->img_format = 'png';
$this->img_source = imagecreatefrompng($this->img_file);
break;
default:
$this->img_format = null;
$this->img_source = null;
break;
}
}
}
/**
* Set resize
*
* #param boolean $resize Resize value
*
* #return void
* #since 2.0
*/
public function setResize($resize) {
$this->thumb_resize = $resize;
}
/**
* Set thumb dimensions
*
* #param int $width
* #param int $height
*
* #return void
* #since 2.0
*/
public function setSize($width, $height) {
$this->thumb_width = $width;
$this->thumb_height = $height;
}
/**
* Size thumb width
*
* #param int $width
*
* #return void
* #since 2.0
*/
public function sizeWidth($width) {
$this->thumb_width = $width;
$this->thumb_height = #($width / $this->img_width) * $this->img_height;
}
/**
* Size thumb height
*
* #param int $height
*
* #return void
* #since 2.0
*/
public function sizeHeight($height) {
$this->thumb_width = #($height / $this->img_height) * $this->img_width;
$this->thumb_height = $height;
}
/**
* Save file
*
* #param string $file the file to save
*
* #return boolean true on success
* #since 2.0
*/
public function save($file) {
$return = false;
if ($this->img_format) {
$src = $this->img_source;
$src_x = 0;
$src_y = 0;
// smart resize thumbnail image
if ($this->thumb_resize) {
$resized_width = #($this->thumb_height / $this->img_height) * $this->img_width;
$resized_height = #($this->thumb_width / $this->img_width) * $this->img_height;
if ($this->thumb_width <= $resized_width) {
$width = $resized_width;
$height = $this->thumb_height;
$src_x = intval(($resized_width - $this->thumb_width) / 2);
} else {
$width = $this->thumb_width;
$height = $resized_height;
$src_y = intval(($resized_height - $this->thumb_height) / 2);
}
$src = imagecreatetruecolor($width, $height);
// save transparent colors
if ($this->img_format == 'png') {
imagecolortransparent($src, imagecolorallocate($src, 0, 0, 0));
imagealphablending($src, false);
imagesavealpha($src, true);
}
// get and reallocate transparency-color for gif
if ($this->img_format == 'gif') {
imagealphablending($src, false);
$transindex = imagecolortransparent($this->img_source) <= imagecolorstotal($src) ? imagecolortransparent($this->img_source) : imagecolorstotal($src);
if ($transindex >= 0) {
$transcol = imagecolorsforindex($this->img_source, $transindex);
$transindex = imagecolorallocatealpha($src, $transcol['red'], $transcol['green'], $transcol['blue'], 127);
imagefill($src, 0, 0, $transindex);
}
}
if (function_exists('imagecopyresampled')) {
#imagecopyresampled($src, $this->img_source, 0, 0, 0, 0, $width, $height, $this->img_width, $this->img_height);
} else {
#imagecopyresized($src, $this->img_source, 0, 0, 0, 0, $width, $height, $this->img_width, $this->img_height);
}
// restore transparency for gif
if ($this->img_format == 'gif') {
if ($transindex >= 0) {
imagecolortransparent($src, $transindex);
for ($y=0; $y < imagesy($src); ++$y) {
for ($x=0; $x < imagesx($src); ++$x) {
if (((imagecolorat($src, $x, $y)>>24) & 0x7F) >= 100) {
imagesetpixel($src, $x, $y, $transindex);
}
}
}
}
}
}
// create thumbnail image
$thumbnail = imagecreatetruecolor($this->thumb_width, $this->thumb_height);
// save transparent colors for png
if ($this->img_format == 'png') {
imagecolortransparent($thumbnail, imagecolorallocate($src, 0, 0, 0));
imagealphablending($thumbnail, false);
imagesavealpha($thumbnail, true);
}
// get and reallocate transparency-color for gif
if ($this->img_format == 'gif') {
imagealphablending($thumbnail, false);
$transindex = imagecolortransparent($src);
if ($transindex >= 0) {
$transcol = imagecolorsforindex($src, $transindex);
$transindex = imagecolorallocatealpha($thumbnail, $transcol['red'], $transcol['green'], $transcol['blue'], 127);
imagefill($thumbnail, 0, 0, $transindex);
}
}
#imagecopy($thumbnail, $src, 0, 0, $src_x, $src_y, $this->thumb_width, $this->thumb_height);
// restore transparency for gif
if ($this->img_format == 'gif') {
if ($transindex >= 0) {
imagecolortransparent($thumbnail, $transindex);
for ($y=0; $y < imagesy($thumbnail); ++$y) {
for ($x=0; $x < imagesx($thumbnail); ++$x) {
if (((imagecolorat($thumbnail, $x, $y)>>24) & 0x7F) >= 100) {
imagesetpixel($thumbnail, $x, $y, $transindex);
}
}
}
}
}
// save thumbnail to file
ob_start();
switch ($this->img_format) {
case 'gif':
$return = imagegif($thumbnail);
break;
case 'jpeg':
$return = imagejpeg($thumbnail, null, $this->thumb_quality);
break;
case 'png':
$return = imagepng($thumbnail);
break;
}
$output = ob_get_contents();
ob_end_clean();
JFile::write($file, $output);
// free memory resources
imagedestroy($thumbnail);
imagedestroy($src);
}
return $return;
}
}
And I find this code:
#imagecopy($thumbnail, $src, 0, 0, $src_x, $src_y, $this->thumb_width, $this->thumb_height);
Now how can I add watermark to this file?
You can use a 3rd Party Joomla plugin like Supermarks Pro. Works on all images except those fired inside lightboxes.

Magento: Load/Use Image Base URL instead of Cached URL

Does anybody know how to get Magento to use the actual base URL of images instead of the cached ones?
Using Magento Community V 1.6.2.0
If I look at the URL of a product image you get something like this…
/media/catalog/product/cache/1/image/390x/5e06319eda06f020e43594a9c230972d/1/1/1101012001-J-1Front-Man/.jpg
I need for it to be more like:
/media/catalog/product/1101012001-J-1Front-Man/.jpg
Reason is that I'm using the M2EPro extension which allows you to sync products for sale/sold in Magento with eBay/Amazon. Problem is that eBay does not allow image URLs that are longer that 150 characters. The MD5 hash and other mixed in variables (that I believe originate at /app/code/core/Mage/Catalog/Helper/Image.php) make the URL too long for it to be usable for many of my images.
When M2EPro runs it pulls the cached image (because that is what Magento designates as the main image). I believe that I need to have only the absolute URL referenced and have not been able to put this all together yet.
I have seen lots and lots of similar questions that span years with no definite answer on this one. If I find the answer first I will post here, but any help is really, really appreciated!
Current code from Image.php file mentioned above:
$this->_baseFile = $baseFile;
// build new filename (most important params)
$path = array(
Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath(),
Mage::app()->getStore()->getId(),
$path[] = $this->getDestinationSubdir()
);
if((!empty($this->_width)) || (!empty($this->_height)))
$path[] = "{$this->_width}x{$this->_height}";
// add misk params as a hash
$miscParams = array(
($this->_keepAspectRatio ? '' : 'non') . 'proportional',
($this->_keepFrame ? '' : 'no') . 'frame',
($this->_keepTransparency ? '' : 'no') . 'transparency',
($this->_constrainOnly ? 'do' : 'not') . 'constrainonly',
$this->_rgbToString($this->_backgroundColor),
'angle' . $this->_angle,
'quality' . $this->_quality
);
// if has watermark add watermark params to hash
if ($this->getWatermarkFile()) {
$miscParams[] = $this->getWatermarkFile();
$miscParams[] = $this->getWatermarkImageOpacity();
$miscParams[] = $this->getWatermarkPosition();
$miscParams[] = $this->getWatermarkWidth();
$miscParams[] = $this->getWatermarkHeigth();
}
$path[] = md5(implode('_', $miscParams));
// append prepared filename
$this->_newFile = implode('/', $path) . $file; // the $file contains heading slash
return $this;
}
public function getBaseFile()
{
return $this->_baseFile;
}
public function getNewFile()
{
return $this->_newFile;
}
/**
* #return Mage_Catalog_Model_Product_Image
*/
public function setImageProcessor($processor)
{
$this->_processor = $processor;
return $this;
}
/**
* #return Varien_Image
*/
public function getImageProcessor()
{
if( !$this->_processor ) {
// var_dump($this->_checkMemory());
// if (!$this->_checkMemory()) {
// $this->_baseFile = null;
// }
$this->_processor = new Varien_Image($this->getBaseFile());
}
$this->_processor->keepAspectRatio($this->_keepAspectRatio);
$this->_processor->keepFrame($this->_keepFrame);
$this->_processor->keepTransparency($this->_keepTransparency);
$this->_processor->constrainOnly($this->_constrainOnly);
$this->_processor->backgroundColor($this->_backgroundColor);
$this->_processor->quality($this->_quality);
return $this->_processor;
}
/**
* #see Varien_Image_Adapter_Abstract
* #return Mage_Catalog_Model_Product_Image
*/
public function resize()
{
if (is_null($this->getWidth()) && is_null($this->getHeight())) {
return $this;
}
$this->getImageProcessor()->resize($this->_width, $this->_height);
return $this;
}
/**
* #return Mage_Catalog_Model_Product_Image
*/
public function rotate($angle)
{
$angle = intval($angle);
$this->getImageProcessor()->rotate($angle);
return $this;
}
/**
* Set angle for rotating
*
* This func actually affects only the cache filename.
*
* #param int $angle
* #return Mage_Catalog_Model_Product_Image
*/
public function setAngle($angle)
{
$this->_angle = $angle;
return $this;
}
/**
* Add watermark to image
* size param in format 100x200
*
* #param string $file
* #param string $position
* #param string $size
* #param int $width
* #param int $heigth
* #param int $imageOpacity
* #return Mage_Catalog_Model_Product_Image
*/
public function setWatermark($file, $position=null, $size=null, $width=null, $heigth=null, $imageOpacity=null)
{
if ($this->_isBaseFilePlaceholder)
{
return $this;
}
if ($file) {
$this->setWatermarkFile($file);
} else {
return $this;
}
if ($position)
$this->setWatermarkPosition($position);
if ($size)
$this->setWatermarkSize($size);
if ($width)
$this->setWatermarkWidth($width);
if ($heigth)
$this->setWatermarkHeigth($heigth);
if ($imageOpacity)
$this->setImageOpacity($imageOpacity);
$filePath = $this->_getWatermarkFilePath();
if($filePath) {
$this->getImageProcessor()
->setWatermarkPosition( $this->getWatermarkPosition() )
->setWatermarkImageOpacity( $this->getWatermarkImageOpacity() )
->setWatermarkWidth( $this->getWatermarkWidth() )
->setWatermarkHeigth( $this->getWatermarkHeigth() )
->watermark($filePath);
}
return $this;
}
/**
* #return Mage_Catalog_Model_Product_Image
*/
public function saveFile()
{
$filename = $this->getNewFile();
$this->getImageProcessor()->save($filename);
Mage::helper('core/file_storage_database')->saveFile($filename);
return $this;
}
/**
* #return string
*/
public function getUrl()
{
$baseDir = Mage::getBaseDir('media');
$path = str_replace($baseDir . DS, "", $this->_newFile);
return Mage::getBaseUrl('media') . str_replace(DS, '/', $path);
}
public function push()
{
$this->getImageProcessor()->display();
}
/**
* #return Mage_Catalog_Model_Product_Image
*/
public function setDestinationSubdir($dir)
{
$this->_destinationSubdir = $dir;
return $this;
}
/**
* #return string
*/
public function getDestinationSubdir()
{
return $this->_destinationSubdir;
}
public function isCached()
{
return $this->_fileExists($this->_newFile);
}
/**
* Set watermark file name
*
* #param string $file
* #return Mage_Catalog_Model_Product_Image
*/
public function setWatermarkFile($file)
{
$this->_watermarkFile = $file;
return $this;
}
/**
* Get watermark file name
*
* #return string
*/
public function getWatermarkFile()
{
return $this->_watermarkFile;
}
/**
* Get relative watermark file path
* or false if file not found
*
* #return string | bool
*/
protected function _getWatermarkFilePath()
{
$filePath = false;
if (!$file = $this->getWatermarkFile())
{
return $filePath;
}
$baseDir = Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath();
if( $this->_fileExists($baseDir . '/watermark/stores/' . Mage::app()->getStore()->getId() . $file) ) {
$filePath = $baseDir . '/watermark/stores/' . Mage::app()->getStore()->getId() . $file;
} elseif ( $this->_fileExists($baseDir . '/watermark/websites/' . Mage::app()->getWebsite()->getId() . $file) ) {
$filePath = $baseDir . '/watermark/websites/' . Mage::app()->getWebsite()->getId() . $file;
} elseif ( $this->_fileExists($baseDir . '/watermark/default/' . $file) ) {
$filePath = $baseDir . '/watermark/default/' . $file;
} elseif ( $this->_fileExists($baseDir . '/watermark/' . $file) ) {
$filePath = $baseDir . '/watermark/' . $file;
} else {
$baseDir = Mage::getDesign()->getSkinBaseDir();
if( $this->_fileExists($baseDir . $file) ) {
$filePath = $baseDir . $file;
}
}
return $filePath;
}
I guess you can use
echo Mage::getModel('catalog/product_media_config')
->getMediaUrl( $product->getImage() );
You can also use getSmallImage() or getThumbnail() methods instead.
What version of M2e Pro are you using, my current version is 6 and it has an option to use base image as opposed to gallery. Works great in my magento 1.6.2.0 if you have your base image at least 500 pixals

Resources