Use Dropbox API with CodeIgniter - 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
]
);
}

Related

Laravel 5.4 file uploading error - fileName not uploaded due to an unknown error

Im trying to upload multiple images to via below code in laravel. In my form there are 3 types of images to be selected to upload. When user select all the images and then submit the form. I need to upload all the images to same folder . First images get uploaded in to the folder. But then it gives me below error.
The file "1575738164-main-slider2.webp" was not uploaded due to an unknown error.
Controller
if ($request->hasFile('image') && $request->hasFile('image_575') && $request->hasFile('image_768')){
$file = $request->image;
$file_575 = $request->image_575;
$file_768 = $request->image_768;
$name = time().'-'.$file->getClientOriginalName();
$name_575 = time().'-'.$file_575->getClientOriginalName();
$name_768 = time().'-'.$file_768->getClientOriginalName();
$names = [ $name , $name_575 , $name_768];
foreach ( $names as $n){
$file->move('uploads/banners/',$n);
}
$banner = new Banner();
$banner->name = $name;
$banner->name_575 = $name_575;
$banner->name_768 = $name_768;
$banner -> side_color = $request -> side_color ;
$banner->type = $request->type;
$banner->save();
}
Please note that I have almost gone through below questions.
Laravel: The file was not uploaded due to an unknown error
First only using time() method won't work to generate unique file name for all three images all the time and when a concurrent request occurs.
Second:
$names = [ $name , $name_575 , $name_768];
foreach ( $names as $n){
$file->move('uploads/banners/',$n);
}
What you are looping is totally wrong. You are trying to move the same image, $file for three times.
You have to move all the three images inside the loop:
`
$file = $request->image;
$file_575 = $request->image_575;
$file_768 = $request->image_768;
`
So, you should probably do:
$filesToMoves = [$name=> $file, $name_575 => $file2 , $name_768 => $file3];
foreach($filesToMoves as $fileName => $fileToMove){
$fileToMove->move('uploads/banners/',$fileName);
}
I will add my code for future references that I used to solve this issue
public function store(Request $request)
{
$this -> validate ( request () , [
'image' => 'required|mimes:webp|dimensions:max_width=1200,max_height=380|max:50' ,
'image_575' => 'required|mimes:jpeg,png,jpg|dimensions:max_width=575,max_height=380|max:80' ,
'image_768' => 'required|mimes:jpeg,png,jpg|dimensions:max_width=768,max_height=380|max:80' ,
] ) ;
if ($request->hasFile('image') && $request->hasFile('image_575') && $request->hasFile('image_768')){
$fils = [$request->image, $request->image_575, $request->image_768];
$formats = ['webp' , '575','768'];
$fileNames = [];
$i = 0;
foreach($fils as $file){
$name = time().'_'.$formats[$i].'.'.$file->getClientOriginalExtension();
$file->move('uploads/banners/', $name);
array_push($fileNames, $name);
$i++;
}
$a= new X();
$a->name = $fileNames[0];
$a->image_575 = $fileNames[1];
$a->image_768 = $fileNames[2];
$a->save();
}
This is just for information.

How do grant rw access to public folder in laravel

I get this error after i migrated my project from windows to mac.
The "/private/var/folders/6w/zypn4xb120l6x6f1kjx9_nxw0000gn/T/phpwroBVT" file does not exist or is not readable.
here is my code
if($request->hasFile('image')){
$image = $request->file('image');
$image_name = $image->getClientOriginalName();
$destinationPath = public_path('/images/services');
$image->move($destinationPath, $image_name);
$summary = $request->summary;
$body = $request->body;
$title = $request->title;
$service = Service::create([
'title'=> $title,
'summary'=>$summary,
'body'=>$body,
'image'=> $image
]
);
if($service){
return redirect()->back()->with('success','services added');
}
}
the images goes into the public/images/services folder but i get the above error
I faced the similar error and I found out that i was accessing the global variable declared in the controller without "this" pointer reference. For example
class BlogController extends Controller
{
public $attachment_folder_name = "/blogs/";
}
You should access this variable with following syntax.
echo $this->attachment_folder_name
And not like this
echo $attachment_folder_name

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));
}

ContextErrorException in Symfony 3

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);

Download File doesnt work

Im trying to create a download file functionality, but it doesnt work, it gives me a error of:
"The file "/storage/app/candidates/cvs/3/1493594353.pdf" does not exist", but im just looking at the file, and is there.
Am i missing something?
Note: im using laravel 5.4
File structure:
storage
- app
-- candidates
---cvs
----3
-----1493594353.pdf
- public
Route:
Route::post('candidate/cv/download-cv/','CurriculumVitaeController#downloadCV');
Controller:
public function downloadCV()
{
$candidate = Candidate::where('user_id',Auth::user()->id)->first();
$candidateCv = CandidateCv::where('candidate_id',$candidate->id)->first();
$path = Storage::url('app/candidates/cvs/'.$candidate->id.'/'.$candidateCv->cv);
$headers = ['Content-Type: application/pdf'];
$newName = 'cv-'.time().'.pdf';
return response()->download($path, $newName, $headers);
}
Change your controller download method to this:
public function downloadCV()
{
$candidate = Candidate::where('user_id',Auth::user()->id)->first();
$candidateCv = CandidateCv::where('candidate_id',$candidate->id)->first();
$path = storage_path().'/app/candidates/cvs/'.$candidate->id.'/'.$candidateCv->cv;
$headers = ['Content-Type: application/pdf'];
$newName = 'cv-'.time().'.pdf';
return response()->download($path, $newName, $headers);
}
Also, to make things more dynamic, you could assign the Content-type and the returned file name extension on the fly, like this:
public function downloadCV()
{
$candidate = Candidate::where('user_id',Auth::user()->id)->first();
$candidateCv = CandidateCv::where('candidate_id',$candidate->id)->first();
$path = storage_path().'/app/candidates/cvs/'.$candidate->id.'/'.$candidateCv->cv;
$headers = ['Content-Type: '.Storage::mimeType('/app/candidates/cvs/'.$candidate->id.'/'.$candidateCv->cv)];
$newName = 'cv-'.time().'.'.pathinfo($path, PATHINFO_EXTENSION);
return response()->download($path, $newName, $headers);
}

Resources