How can I save file from external url Laravel public directory - php

I wanted to save a file from External Url which would have any kind of file like say "jpg, png, mp4 etc"
I want to save it in the public directory of Laravel App. How could I do that? Any help will be highly appreciated.
I tried the following thing, but it's saving file in my storage folder:
Storage::put($name, $contents);
Thanks

create an img folder in public path and :
$image = file_get_contents("https://logos-download.com/wp-content/uploads/2016/09/Laravel_logo.png");
file_put_contents(public_path('img/a.png'), $image);

use File like below
use Illuminate\Support\Facades\File;
and then
File::put(public_path( 'ANY FILE YOU WANT' ));
example:
File::put( public_path( 'js/a.js'), ' CONTENT ');

Download files from external URL after authentication.
public function file_get_contents_curl( $url ) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public function downloadFile( $imgName, $url, $path )
{
$data = $this->file_get_contents_curl( $url );
file_put_contents( $path.$imgName, $data );
echo "File downloaded!";
}
Code for creating a new folder based on the date.
public function imgBackupFolder( $currentShop ) {
$folderName = 'export'.DS.str_replace( '.', '_', $currentShop->shopify_domain ).DS.'images'.DS.date( 'Y_m_d' ).DS;
return $this->createFolder( $folderName );
}
/*
* Create folder based on the store,date,export type
*/
private function createFolder( $folderName ) {
try {
$path = public_path( $folderName );
if( !File::isDirectory( $path ) ){
File::makeDirectory( $path, 0777, true, true );
}
return $path;
} catch (Exception $ex) {
Log::error( $ex->getMessage() );
}
}

Related

PHP Script Not Downloading A Zipped Product Feed From URL - Download works fine when visited on browser

I have a simple bit of PHP code which copies a zip file from a remote url to the server, and then extracts it into another folder.
function extract_remote_zip($new_file_loc, $tmp_file_loc, $zip_url) {
echo 'Copying Zip to local....<br>';
//copy file to local
if (!copy($zip_url, $tmp_file_loc)) {
echo "failed to copy zip from".$zip_url."...";
}
//unzip
$zip = new ZipArchive;
$res = $zip->open($tmp_file_loc);
if ($res === TRUE) {
echo 'Extracting Zip....<br>';
if(! $zip->extractTo($new_file_loc)){
echo 'Couldnt extract!<br>';
}
$zip->close();
echo 'Deleting local copy....<br>';
unlink($tmp_file_loc);
return 1;
} else {
echo 'Failed to open tmp zip!<br>';
return 0;
}
}
It works perfectly with one URL from Awin and downloads and extracts the correct 600kb zip, but with another from Webgains it just downloads a Zip file with size 0 bytes. I'm guessing the download is getting corrupted somewhere?
When I visit the URL on my browser it downloads the zip perfectly (the size is about 3mb). I just can't get it to download with PHP.
Please help!
Since you didn't provide the problem URL, I can't say for sure, but you are likely encountering an issue with the method copy uses to read the file. Doing a direct curl call should resolve this.
Try the below:
function file_get_contents_curl( $url ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );
$data = curl_exec( $ch );
if ( curl_errno( $ch ) <> FALSE ) {
echo "ERROR at line " . __LINE__ . " in file_get_contents_curl: error number: " . curl_errno( $ch ) . ' error : ' . curl_error( $ch ) . " url: $url";
return FALSE;
}
curl_close( $ch );
return $data;
}
function extract_remote_zip($new_file_loc, $tmp_file_loc, $zip_url) {
echo 'Copying Zip to local....<br>';
// read the zip
if ( $zip_str = file_get_contents_curl( $zip_url ) ) {
// write the zip to local
if ( !file_put_contents( $tmp_file_loc, $zip_str ) ) {
echo "failed to write the zip to: " . $zip_url;
return FALSE;
}
} else {
echo "failed to read the zip from: " . $zip_url;
return FALSE;
}
//unzip
$zip = new ZipArchive;
$res = $zip->open($tmp_file_loc);
if ($res === TRUE) {
echo 'Extracting Zip....<br>';
if(! $zip->extractTo($new_file_loc)){
echo 'Couldnt extract!<br>';
}
$zip->close();
echo 'Deleting local copy....<br>';
unlink($tmp_file_loc);
return 1;
} else {
echo 'Failed to open tmp zip!<br>';
return 0;
}
}

how to move temp file in a case of just knowing its path?

I just can get the temp file path,like D:\XAMPP\tmp\phpE185.tmp...But the $_FILE array is null,because I do a transport from a url to another url.So how to move this temp file?
here is my code:
class UserController extends Controller
{
public function getRank(){
echo "waht";
}
public function uploadTrans(Request $request){
$image = $request->image;
$name = $request->name;
$image = urlencode($image);
$curlPost = "name=$name&image=$image";
$uploadApi = "http://mdx.ittun.com/authprac/public/upload";
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$uploadApi);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$curlPost);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
}
public function upload (Request $request){
$fileTempName = $request->image;
print_r($fileTempName);
// here I just can get the temp file path..$_FILES array is null
}
}
PHP has a move_uploaded_file() function for this purpose.
Since you've tagged your question with laravel, see their docs regarding uploaded files:
$request->file('photo')->move($destinationPath);

PHP thread can't unlink files?

When creating a new PHP child thread it becomes unable to delete files using unlink(). is there a good reason for that limitation or I'm forgetting something?
I get a worning:
Warning: unlink(downloads/1e6f6fa1c0552a1af9058f10216b40e8): No such
file or directory
although the file is created in the destination folder, and when I run the same command outside the thread function it deletes the file as it should.
//multithreading class
<?php
class download extends Thread {
public $i;
public $res;
public function __construct($s){
$this->i = $s;
}
public function run() {
try{
$url = "http://my.link.com/{$this->i}";
set_time_limit(0);
$id = md5(uniqid());
$tempName = md5($id.time());
$tmp = "downloads/{$tempName}";
$fp = fopen (dirname(__FILE__) . '/'.$tmp, 'w+');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
require('scanner.php');
$results = scanfiles($tmp);
unlink($tmp);
$this->res = $results;
}catch(Exception $e){
$this->res = '0';
}}} ?>
Into fopen you're passing absolute path (dirname(__FILE__) . "/{$tmp}") while into unlink relative path, just use abslute everywhere and it should work. Btw you can use just __DIR__ instead dirname(__FILE__) since PHP 5.3.

CakePHP downloading file doesn't work when function is called by another function

In my Controller I have a function called get which sends the client a file. When a user clicks a link which calls the get function it works properly.
I have another function called get_veeva which first downloads the file from veeva to the server, then calls the get function to send the file to the user. This does not work properly. get_veeva downloads the file correctly, calls get, but the user doesn't receive the file, instead I just get a blank page. I know the file permissions and ownership are not the problem as I've tested by hardcoding the veeva files to the media class params in get and hitting get directly using the first method. Neither function has a View. Here are the two functions:
function get($name, $ext, $original_name, $mime)
{
$this->viewClass = 'Media';
$params = array(
'id' => sprintf("%s.%s", $name, $ext),
'name' => basename($original_name, '.' . $ext),
'download' => true,
'ext' => $ext,
'mimeType' => $mime,
'path' => APP . "webroot/uploads" . DS
);
$this->set($params);
}
public function get_veeva($id = null)
{
$this->autoRender = false;
$asset = $this->Asset->findById($id);
$vault = $asset['VeevaVault'];
App::import('Vendor', 'phpVeeva', array('file' => 'veeva' . DS . 'veeva.php'));
$veeva = new phpVeeva();
$file = $veeva->getVeevaAsset($vault['veeva_id'], $vault['title']);
$filename = $file['filename'];
$ext = $filename['ext'];
$mime = $filename['mime'];
$this->get($filename, $ext, $filename, $mime);
}
Here is the getVeevaAsset function which downloads the file:
public function getVeevaAsset($id, $filename)
{
$this->Auth();
$url = self::VVURL . "/objects/documents/" . $id . "/file";
set_time_limit(0);
$path = APP . 'webroot/uploads/';
$info = $this->getInfo($id);
$mime = $info['format__v'];
$ext = $this->extensions[$mime];
$fullFilename = $filename . "." . $ext;
$uri = $path . $fullFilename;
$fp = fopen($uri, 'w+');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/json;charset=UTF-8", "Authorization: ".$this->sessID));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$json_response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($status != 200)
{
die('Error: call to URL $url failed with status "' . $status .'", response "' . $json_response. '", curl_error "' . curl_error($curl) . '", curl_errno "' . curl_errno($curl). '"');
}
curl_close($ch);
fclose($fp);
chmod($uri, 0777);
$file['path'] = $path;
$file['filename'] = $filename;
$file['ext'] = $ext;
$file['mime'] = $mime;
return $file;
}
I'm thinking either there's something happening in the getVeevaAsset function which doesn't let the get run properly (The download script is interfering with the mediaclass transfer?). Or the get function only runs properly if it is called directly by a user and not by another function. But these are just guesses. I can't use CakeResponse because I'm running Cake version 2.2.5.
I need to get this working for my client really soon so if anybody can help I'd really appreciate it.
When disabling auto-rendering ($this->autoRender = false;) you have to call Controller::render() at some point.
public function get_veeva($id = null)
{
$this->autoRender = false;
// ...
$this->get($filename, $ext, $filename, $mime);
$this->render();
}

How do I temporarily store facebook profile picture?

Hey guys i'm trying to build a little app that pulls in the users profile picture, allows them to manipulate the image and then publish the modified image to their profile pictures album (ideally set as their profile pic, but i don't think this is possible???).
The problem I'm having is that the javascript i'm using to alter the image will not work unless the image is local
i.e. <img src="http://profile.ak.fbcdn.net/hprofile-ak-snc4/[some_user_id].jpg" /> will not work, but <img src="img/image.jpg" /> will...
Is there any way of achieving this?
The method I am using to get hold of the user picture is this:
To connect to facebook:
<?php
require_once 'library/facebook.php';
$app_id = "###";
$app_secret = "###";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
if(is_null($facebook->getUser()))
{
header("Location:{$facebook->getLoginUrl(array('req_perms' => 'user_status,publish_stream,user_photos'))}");
exit;
}
Then to display the image:
<?php
$aResponse = $facebook->api('/me', array(
'fields' => 'picture',
'type' => 'large'
));
echo "<img src='".$aResponse["picture"]."' />";
?>
Many thanks!
Write yourself a proxy image server which which takes the the image you want to manipulate as a query parameter and just outputs the image content. It's a little slower than directly accessing the user's picture, but if you get creative you could cache that image locally to make subsequent loads faster.
a simple way to do this would be something like this:
front end:
<img src="image_server.php?img=<?= urlencode($aResponse['picture']); ?>">
back end:
<?php
if (!empty($_GET['img']))
{
//make sure this is a file on the facebook content delivery network
//and not our /etc/passwd or database connection config, or something
//else completely malicious.
if (preg_match("#^https?://profile\.ak\.fbcdn\.net/#i", $_GET['img']))
{
$img_path = $_GET['img'];
}
else
{
//do something with someone that entered a bad image, probably just
//display a "no image" image.
die('bad user. bad.');
}
readfile($img_path);
exit;
}
else
{
//no image was specified. output an anonymous/no image image.
die('an image file must be specified.');
}
You might want to get a little more complex than that...but that's the basic gist.
note: The php code assumes you have fopen wrappers enabled in your php.ini (so you can include web urls).
Thanks Jim for your response, I had seen someone doing something very similar to that, but again (just my luck) I was having problems with it. Anyway the way I managed to solve it was:
function save_image($inPath,$outPath)
{ //Download images from remote server
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
// This is just pulling the user id to use for the filename
$id = $get_id['id'];
save_image($aResponse['picture'],'tmp/'.$id.'.jpg');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
#list($header, $data) = #explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = #parse_url(trim(array_pop($matches)));
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (#$url['query']?'?'.$url['query']:'');
return $new_url;
} else {
$curl_loops=0;
return $data;
}
}
function get_right_url($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
return curl_redir_exec($curl);
}
$url = 'http://graph.facebook.com/' . $fbid . '/picture?type=large';
$file_handler = fopen('/img/avatar/'.$fbid.'.jpg', 'w');
$curl = curl_init(get_right_url($url));
curl_setopt($curl, CURLOPT_FILE, $file_handler);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($file_handler);
// Happy Coding

Categories