ContextErrorException in Symfony 3 - image

I am trying to upload images in SF3, and I have this error when I upload:
Missing argument 2 for Symfony\Component\HttpFoundation\File\UploadedFile::__construct().
This is the part of my entity where is the error is located (line 9 here):
public function preUpload()
{
// if there is no file (optional field)
if (null === $this->image) {
return;
}
// $file = new File($this->getUploadRootDir() . '/' . $this->image);
$file = new File($this->getUploadRootDir() .'/' . $this->image);
$uploadedfile = new UploadedFile($this->getUploadRootDir() .'/' . $this->image);
// the name of the file is its id, one should just store also its extension
// to make clean, we should rename this attribute to "extension" rather than "url"
$this->url = $file->guessExtension();
// and we generate the alt attribute of the <img> tag,
// the value of the file name on the user's PC
$this->alt = $uploadedfile->getClientOriginalName();
}
Then my controller :
public function mediaEditAction(Request $request)
{
$media = new Media();
$form = $this->createForm(MediaType::class, $media);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$file = $media->getImage();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move(
$this->getParameter('images_directory'),
$fileName
);
$media->setImage($fileName);
$em = $this->getDoctrine()->getManager();
$em->persist($media);
$em->flush();
$request->getSession()->getFlashBag()->add('Notice', 'Photo added with success');
// redirection
$url = $this->generateUrl('medecin_parametre');
// permanent redirection with the status http 301
return $this->redirect($url, 301);
} else {
return $this->render('DoctixMedecinBundle:Medecin:mediaedit.html.twig', array(
'form' => $form->createView()
));
}
}

It seems like you are doing unnecessary work and making this a little more complicated than it probably needs to be. Have you followed this Symfony guide for How to Upload Files?
In the meantime, it seems like the image name is what is in $this->image so you can just pass that as the 2nd constructor argument.
$uploadedfile = new UploadedFile($this->getUploadRootDir().'/'.$this->image, $this->image);
However, UploadedFile should probably only come from the form submission, and in your entity you would want to use File instead - like so:
use Symfony\Component\HttpFoundation\File\File;
$uploadedfile = new File($this->getUploadRootDir() .'/' . $this->image);

Related

How to save Base64 string as Image in laravel

I have been searching for the past 2 days now trying to get a solution that decodes base64 in all file type extensions(.png or jpg). All I found was a base64 decoder that only allow one type of extensions.
My Controller:
public function updatepicture(Request $request){
$user = User::find($request->id);
if($user == null){
return response()->json(['statusCode'=>'5', 'statusMessage' => "user account doesn't exists", 'data' => []]);
}
$image = $request->avatar; // your base64 encoded
$decoded_file = base64_decode($image); // decode the file
$mime_type = finfo_buffer(finfo_open(), $decoded_file, FILEINFO_MIME_TYPE); // extract mime type
$extension = $this->mime2ext($mime_type); // extract extension from mime type
$image = str_replace('data:image/'.$extension.';base64,', '', $image);
$image = str_replace(' ', '+', $image);
$filename = str::random(10).'.'.$extension;
//$image = $request->file('avatar');
//$filename = time().'.'.$image->getClientOriginalExtension();
$filePath = 'avatars/'.$filename;
$disk = Storage::disk('gcs')->put($filePath, file_get_contents(base64_decode($image)));
$gcs = Storage::disk('gcs');
$url = $gcs->url('avatars'. "/" . $filename);
$user->avatar = $url;
$user->save();
return response()->json(['statusCode'=>'0', 'statusMessage' => 'Successful','data' => $user], 200);
}
/*
to take mime type as a parameter and return the equivalent extension
*/
public function mime2ext($mime){
$all_mimes = '{"png":["image\/png","image\/x-png"],"bmp":["image\/bmp","image\/x-bmp",
"image\/x-bitmap","image\/x-xbitmap","image\/x-win-bitmap","image\/x-windows-bmp",
"image\/ms-bmp","image\/x-ms-bmp","application\/bmp","application\/x-bmp",
"application\/x-win-bitmap"],"gif":["image\/gif"],"jpeg":["image\/jpeg",
"image\/pjpeg"],"xspf":["application\/xspf+xml"],"vlc":["application\/videolan"],
"wmv":["video\/x-ms-wmv","video\/x-ms-asf"],"au":["audio\/x-au"],
"ac3":["audio\/ac3"],"flac":["audio\/x-flac"],"ogg":["audio\/ogg",
"video\/ogg","application\/ogg"],"kmz":["application\/vnd.google-earth.kmz"],
"kml":["application\/vnd.google-earth.kml+xml"],"rtx":["text\/richtext"],
"rtf":["text\/rtf"],"jar":["application\/java-archive","application\/x-java-application",
"application\/x-jar"],"zip":["application\/x-zip","application\/zip",
"application\/x-zip-compressed","application\/s-compressed","multipart\/x-zip"],
"7zip":["application\/x-compressed"],"xml":["application\/xml","text\/xml"],
"svg":["image\/svg+xml"],"3g2":["video\/3gpp2"],"3gp":["video\/3gp","video\/3gpp"],
"mp4":["video\/mp4"],"m4a":["audio\/x-m4a"],"f4v":["video\/x-f4v"],"flv":["video\/x-flv"],
"webm":["video\/webm"],"aac":["audio\/x-acc"],"m4u":["application\/vnd.mpegurl"],
"pdf":["application\/pdf","application\/octet-stream"],
"pptx":["application\/vnd.openxmlformats-officedocument.presentationml.presentation"],
"ppt":["application\/powerpoint","application\/vnd.ms-powerpoint","application\/vnd.ms-office",
"application\/msword"],"docx":["application\/vnd.openxmlformats-officedocument.wordprocessingml.document"],
"xlsx":["application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application\/vnd.ms-excel"],
"xl":["application\/excel"],"xls":["application\/msexcel","application\/x-msexcel","application\/x-ms-excel",
"application\/x-excel","application\/x-dos_ms_excel","application\/xls","application\/x-xls"],
"xsl":["text\/xsl"],"mpeg":["video\/mpeg"],"mov":["video\/quicktime"],"avi":["video\/x-msvideo",
"video\/msvideo","video\/avi","application\/x-troff-msvideo"],"movie":["video\/x-sgi-movie"],
"log":["text\/x-log"],"txt":["text\/plain"],"css":["text\/css"],"html":["text\/html"],
"wav":["audio\/x-wav","audio\/wave","audio\/wav"],"xhtml":["application\/xhtml+xml"],
"tar":["application\/x-tar"],"tgz":["application\/x-gzip-compressed"],"psd":["application\/x-photoshop",
"image\/vnd.adobe.photoshop"],"exe":["application\/x-msdownload"],"js":["application\/x-javascript"],
"mp3":["audio\/mpeg","audio\/mpg","audio\/mpeg3","audio\/mp3"],"rar":["application\/x-rar","application\/rar",
"application\/x-rar-compressed"],"gzip":["application\/x-gzip"],"hqx":["application\/mac-binhex40",
"application\/mac-binhex","application\/x-binhex40","application\/x-mac-binhex40"],
"cpt":["application\/mac-compactpro"],"bin":["application\/macbinary","application\/mac-binary",
"application\/x-binary","application\/x-macbinary"],"oda":["application\/oda"],
"ai":["application\/postscript"],"smil":["application\/smil"],"mif":["application\/vnd.mif"],
"wbxml":["application\/wbxml"],"wmlc":["application\/wmlc"],"dcr":["application\/x-director"],
"dvi":["application\/x-dvi"],"gtar":["application\/x-gtar"],"php":["application\/x-httpd-php",
"application\/php","application\/x-php","text\/php","text\/x-php","application\/x-httpd-php-source"],
"swf":["application\/x-shockwave-flash"],"sit":["application\/x-stuffit"],"z":["application\/x-compress"],
"mid":["audio\/midi"],"aif":["audio\/x-aiff","audio\/aiff"],"ram":["audio\/x-pn-realaudio"],
"rpm":["audio\/x-pn-realaudio-plugin"],"ra":["audio\/x-realaudio"],"rv":["video\/vnd.rn-realvideo"],
"jp2":["image\/jp2","video\/mj2","image\/jpx","image\/jpm"],"tiff":["image\/tiff"],
"eml":["message\/rfc822"],"pem":["application\/x-x509-user-cert","application\/x-pem-file"],
"p10":["application\/x-pkcs10","application\/pkcs10"],"p12":["application\/x-pkcs12"],
"p7a":["application\/x-pkcs7-signature"],"p7c":["application\/pkcs7-mime","application\/x-pkcs7-mime"],"p7r":["application\/x-pkcs7-certreqresp"],"p7s":["application\/pkcs7-signature"],"crt":["application\/x-x509-ca-cert","application\/pkix-cert"],"crl":["application\/pkix-crl","application\/pkcs-crl"],"pgp":["application\/pgp"],"gpg":["application\/gpg-keys"],"rsa":["application\/x-pkcs7"],"ics":["text\/calendar"],"zsh":["text\/x-scriptzsh"],"cdr":["application\/cdr","application\/coreldraw","application\/x-cdr","application\/x-coreldraw","image\/cdr","image\/x-cdr","zz-application\/zz-winassoc-cdr"],"wma":["audio\/x-ms-wma"],"vcf":["text\/x-vcard"],"srt":["text\/srt"],"vtt":["text\/vtt"],"ico":["image\/x-icon","image\/x-ico","image\/vnd.microsoft.icon"],"csv":["text\/x-comma-separated-values","text\/comma-separated-values","application\/vnd.msexcel"],"json":["application\/json","text\/json"]}';
$all_mimes = json_decode($all_mimes,true);
foreach ($all_mimes as $key => $value) {
if(array_search($mime,$value) !== false) return $key;
}
return false;
}
Please help me align this piece of code, the error massage m getting is as follow:
ErrorException: file_get_contents() expects parameter 1 to be a valid path, string given in file
You don't need to use file_get_contents() function while using put method because you are already converting string to image using base64_decode method.
$disk = Storage::disk('gcs')->put($filePath, base64_decode($image));
Please try like this. It should work.

Updating an image in laravel does not save to DB, only saves when adding new record

I have the form of a service where a name, description, and photo is required. When adding a new service the form works fine, everything is saved in the database.
Problem is when I want to change the photo and upload a new one its not working.
**Here is my controller method **, for both adding and updating service
public function post(ServiceRequest $request, Service $service)
{
$service = Service::firstOrNew(['id' => $request->get('id')]);
$service->id = $request->get('id');
$service->name = $request->get('name');
$service->description = $request->get('description');
$image = $request->file('photo')->store('services/');
$service->photo = $image;
if ($request->hasFile('photo')) {
$image = $request->file('photo');
$name = time() . $service->name . '.' . $image->getClientOriginalExtension();
$destinationPath = public_path('/images/services');
$image->move($destinationPath, $name);
}
if ($request->has('photo')) {
$image = $request->file('photo');
}
$service->save();
Alert::success('Service Saved');
return redirect()->back();
// dd($service);
}
I need some assistance with updating the image and removing an old one that was added on update record.

Creating zip of multiple files and download in laravel

i am using the following codes to make zip and allow user to download the zip
but its not working.it shows the error as ZipArchive::close(): Read error: Bad file descriptor.What might be the problem?i am working with laravel.
public function downloadposts(int $id)
{
$post = Post::find($id);
// Define Dir Folder
$public_dir = public_path() . DIRECTORY_SEPARATOR . 'uploads/post/zip';
$file_path = public_path() . DIRECTORY_SEPARATOR . 'uploads/post';
// Zip File Name
$zipFileName = $post->post_title . '.zip';
// Create ZipArchive Obj
$zip = new ZipArchive();
if ($zip->open($public_dir . DIRECTORY_SEPARATOR . $zipFileName, ZipArchive::CREATE) === TRUE) {
// Add File in ZipArchive
foreach ($post->PostDetails as $postdetails) {
$zip->addFile($file_path, $postdetails->file_name);
}
// Close ZipArchive
$zip->close();
}
// Set Header
$headers = [
'Content-Type' => 'application/octet-stream',
];
$filetopath = $public_dir . '/' . $zipFileName;
dd($filetopath);
// Create Download Response
if (file_exists($filetopath)) {
return response()->download($filetopath, $zipFileName, $headers);
}
return redirect()->back();
}
For Laravel 7.29.3 PHP 7.4.11
Create a GET route in api.php
Route::get('/downloadZip','ZipController#download')->name('download');
Create controller ZipController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use File;
class ZipController extends Controller
{
public function download(Request $request)
{
$zip = new \ZipArchive();
$fileName = 'zipFile.zip';
if ($zip->open(public_path($fileName), \ZipArchive::CREATE)== TRUE)
{
$files = File::files(public_path('myFiles'));
foreach ($files as $key => $value){
$relativeName = basename($value);
$zip->addFile($value, $relativeName);
}
$zip->close();
}
return response()->download(public_path($fileName));
}
}
In the public folder make sure you have a folder myFiles. This snippet will get every file within the folder, create a new zip file and put within the public folder, then when route is called it returns the zip file created.
Only pure php code.
public function makeZipWithFiles(string $zipPathAndName, array $filesAndPaths): void {
$zip = new ZipArchive();
$tempFile = tmpfile();
$tempFileUri = stream_get_meta_data($tempFile)['uri'];
if ($zip->open($tempFileUri, ZipArchive::CREATE) !== TRUE) {
echo 'Could not open ZIP file.';
return;
}
// Add File in ZipArchive
foreach($filesAndPaths as $file)
{
if (! $zip->addFile($file, basename($file))) {
echo 'Could not add file to ZIP: ' . $file;
}
}
// Close ZipArchive
$zip->close();
echo 'Path:' . $zipPathAndName;
rename($tempFileUri, $zipPathAndName);
}
I will suggest you to use Zipper package
Try below code for creating zip of multiple files :
public function downloadZip($id)
{
$headers = ["Content-Type"=>"application/zip"];
$fileName = $id.".zip"; // name of zip
Zipper::make(public_path('/documents/'.$id.'.zip')) //file path for zip file
->add(public_path()."/documents/".$id.'/')->close(); //files to be zipped
return response()
->download(public_path('/documents/'.$fileName),$fileName, $headers);
}
you can use the following code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\ImgUpload;
use ZipArchive;
use File;
class UserController extends Controller
{
/**
* Function to get all images from DB
*/
public function downloadZip()
{
$data = ImgUpload::all();
foreach($data as $key => $value)
{
$imgarr[] = "storage/image". '/' . $value->image;
}
$ziplink = $this->converToZip($imgarr);
return $ziplink;
}
/**
* Function to covert all DB files to Zip
*/
public function converToZip($imgarr)
{
$zip = new ZipArchive;
$storage_path = 'storage/image';
$timeName = time();
$zipFileName = $storage_path . '/' . $timeName . '.zip';
$zipPath = asset($zipFileName);
if ($zip->open(($zipFileName), ZipArchive::CREATE) === true) {
foreach ($imgarr as $relativName) {
$zip->addFile($relativName,"/".$timeName."/".basename($relativName));
}
$zip->close();
if ($zip->open($zipFileName) === true) {
return $zipPath;
} else {
return false;
}
}
}
}
you can refer this link for more information
The question got answer, but I am posting this solution for those who wants to download dynamically zip some (based on id) files from the same folder, I hope it might help them that how to create dynamic zip file of multiple files/images affiliated with some id.
I would be taking example of multiple images. You can do the same for files.
Assuming the above table the autos_id is foreign key and based on the autos_id, there are multiple images store in the database.
To make zip file of it I will do the following:
public function downloadZip($id)
{
$data = AutoImage::where('autos_id',$id)->get();
$imgarr=[];
foreach($data as $data){
$file = storage_path() . '/app/public/autoImages/'.$data->image_name;
if(\File::exists(public_path('storage/autoImages/'.$data->image_name))){
$imgarr[]= public_path('storage/autoImages/'.$data->image_name);
}
}
$zip = new ZipArchive;
$fileName = 'AutoImages.zip';
/*OVERWRITE will not make a different zip file on server but it will
replace the one which is in the server, this approach will help you to not
make multiple zip files, if you want to creat new you can do it with unique
name of the zip file and adding CREATE instead of OVERWRITE.*/
if ($zip->open(public_path($fileName), ZipArchive::OVERWRITE) === TRUE)
{
$files = $imgarr; //passing the above array
foreach ($files as $key => $value) {
$relativeNameInZipFile = basename($value);
$zip->addFile($value, $relativeNameInZipFile);
}
$zip->close();
}
return response()->download(public_path($fileName));
}
Note: for file storage I used storage and then made a link symlink for storing files.
For further info of file storage: https://laravel.com/docs/9.x/filesystem
This works for me, multiple files zip and download.
public function download_attachment($ticket_no)
{
$zip = new \ZipArchive();
$fileName = $ticket_no.'.zip';
if ($zip->open(public_path($fileName), \ZipArchive::CREATE)== TRUE)
{
$files = File::files(public_path('uploads/tickets/' . $ticket_no));
foreach ($files as $key => $value){
$relativeName = basename($value);
$zip->addFile($value, $relativeName);
}
$zip->close();
}
return response()->download(public_path($fileName));
}

Use Dropbox API with CodeIgniter

Trying to reuse the following Dropbox API code within CodeIgniter. The issue is getting it to work within the constraints of class methods & constuctors:
require_once('../dropbox-sdk-1.1.4/Dropbox/autoload.php');
use \Dropbox as dbx;
$accessToken = 'DROPBOX_ACCESSTOKEN';
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
Needs to be something like the following, but doesn't like the 'use \Dropbox as dbx' line, amongst others:
class Controller_name extends CI_Controller
{
public function __construct()
{
parent::__construct();
require_once('../dropbox-sdk-1.1.4/Dropbox/autoload.php');
use \Dropbox as dbx;
}
public function access_dropbox()
{
$accessToken = 'DROPBOX_ACCESSTOKEN';
$dbxClient = new dbx\Client($accessToken, "PHP-Example/1.0");
$file = 'file.txt';
$f = fopen( $file, "rb" );
$result = $dbxClient->uploadFile( "/$file", dbx\WriteMode::add(), $f);
fclose($f);
}
}
Using the code below I'm getting the following error message:
An uncaught Exception was encountered
Type: Kunnu\Dropbox\Exceptions\DropboxClientException
Message: Error in call to API function "files/upload": HTTP header
"Dropbox-API-Arg": path: 'db_backup' did not match pattern
'(/(.|[\r\n]))|(ns:[0-9]+(/.)?)|(id:.*)'
Filename:
/opt/lampp/htdocs/codeig-smythes/vendor/kunalvarma05/dropbox-php-sdk/src/Dropbox/Http/Clients/DropboxGuzzleHttpClient.php
Line Number: 59
$file_path = 'public/sql_backup/db_backup_' .date("Y-m-d"). '.sql';
require_once('../vendor/autoload.php');
$app = new Kunnu\Dropbox\DropboxApp(
'APP_KEY',
'APP_SECRET',
'ACCESS_TOKEN'
);
$dropbox = new Kunnu\Dropbox\Dropbox($app);
$dropboxFile = new Kunnu\Dropbox\DropboxFile(realpath($file_path));
$file = $dropbox->upload(
$dropboxFile, basename($file_path), array('autorename' => TRUE)
);
Working with the dropbox API is pretty easy. I use a package found on github:
https://github.com/kunalvarma05/dropbox-php-sdk
I am not using CodeIgniter 3's composer autoload feature. Also, my vendor directory is located at FCPATH.
Since it looks like you want to upload a file, I'll show you that example:
$appKey = '77fgftsb77joj77';
$appSecret = 'fw77777tspam5y';
$accessToken = 'PMP7777777AAAAAAADFC_6JI7777777hY8xYhO7777777MJkpCKbBv';
if( is_file( $file_path ) )
{
$file_path = realpath( $file_path );
$file_name = basename( $file_path );
require FCPATH . 'vendor/autoload.php';
$app = new Kunnu\Dropbox\DropboxApp(
$appKey,
$appSecret,
$accessToken
);
$dropbox = new Kunnu\Dropbox\Dropbox($app);
$dropboxFile = new Kunnu\Dropbox\DropboxFile(
$file_path
);
$file = $dropbox->upload(
$dropboxFile,
'/backups/website/' . $file_name,
[
'autorename' => TRUE
]
);
}

how to encode image decoded by base64_decode, symfony

I have a image decode by base64_decode.
I have a entity Image. This is entity consist : id and path to the file. File of image load to server by this guide http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html.
How encode this string and upload file to server and upload path to database in controller.
my controller
public function updateattachmentAction()
{
$em = $this->getDoctrine()->getManager();
$photo = $em->getRepository('MyPluginBundle:Photo')->findOneById(4);
$str="";
$request = $this->container->get('request');
$image = $request->query->get('image');
// file_put_contents($photo, base64_decode($data));
// $photo->upload();
// $em->persist($photo);
// $em->flush();
$response = array("code" => 100,"success" => true);
//you can return result as JSON
return new Response(json_encode($response));
}
it should help DataUriNormalizer
https://symfony.com/blog/new-in-symfony-3-1-data-uri-normalizer## Heading ##
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
$normalizer = new DataUriNormalizer();
$avatar = $normalizer->denormalize('data:image/gif;base64,R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs=', 'SplFileObject');
// $avatar is a SplFileObject with the GIF image contents
and this https://github.com/hshn/base64-encoded-file
use Hshn\Base64EncodedFile\HttpFoundation\File\Base64EncodedFile;
$file = new Base64EncodedFile(base64_encode($data));
$file->getPathname(); // "/path/to/file"
$file instanceof Symfony\Component\HttpFoundation\File\File; // true

Resources