I have to send a file to an API. The API documentation provides an example of how to do this through a file upload script ($_FILES). But, I have the files on the same machine, so would like to skip this step and just read in the file directly to save time.
How can I read in the file (a video) so that it will work with this code snippet?
I understand that FILES is an array, but I could set the other parts of it (the filename) seperately, I just really need the data part of it to be read in the same format to work with this code (do I use fread? file get contents?)
<?php
# Include & Instantiate
require('../echove.php');
$bc = new Echove(
'z9Jp-c3-KhWc4fqNf1JWz6SkLDlbO0m8UAwOjDBUSt0.',
'z9Jp-c3-KhWdkasdf74kaisaDaIK7239skaoKWUAwOjDBUSt0..'
);
# Create new metadata
$metaData = array(
'name' => $_POST['title'],
'shortDescription' => $_POST['shortDescription']
);
# Rename the video file
$file = $_FILES['video'];
rename($file['tmp_name'], '/tmp/' . $file['name']);
$file_location = '/tmp/' . $file['name'];
# Send video to Brightcove
$id = $bc->createVideo($file_location, $metaData);
?>
Thanks in advance for any help!
Er - all you'd need to do is feed the location, not a file handle or anything, no?
$files = $_FILES['video'];
$filename = $files['name'];
$file_location = '/home/username/' . $filename; // maybe append the extension
$id = $bc->createVideo($file_location, $metaData);
Or more simply
$id = $bc->createVideo( '/foo/bar/baz.txt', $metaData );
Looks like you don't need to do anything except point at the file on your local disk. What about:
<?php
# Include & Instantiate
require('../echove.php');
$bc = new Echove(
'z9Jp-c3-KhWc4fqNf1JWz6SkLDlbO0m8UAwOjDBUSt0.',
'z9Jp-c3-KhWdkasdf74kaisaDaIK7239skaoKWUAwOjDBUSt0..'
);
# Create new metadata
$metaData = array(
'name' => $_POST['title'],
'shortDescription' => $_POST['shortDescription']
);
# point at some file already on disk
$file_location = '/path/to/my/file.dat'; // <== if the file is already on the box, just set $file_location with the pathname and bob's yer uncle
# Send video to Brightcove
$id = $bc->createVideo($file_location, $metaData);
Related
The site is the CAISO OASIS and they use an old way of querying and returning datasets. 30 days at a time, zip file with enclosed *.csv files. I have tried for 4 days coming up with a way to automate this download first of the zip file but i cant even get past there.
If I populate the url string I want and enter it myself in the address bar a zip file will start downloading, I cannot for the life of me get it to do the same through code.
I need to use php to accomplish this task.
I have tried, fopen, file_get_contents, file_put_contents, cURL, ziparchive class. I have tried changing all sorts of things. The best I get is a download of a corrupt zip file that is empty.
Ideally i would love to extract the *.csv or xml file but I cannot even do the first basic step.
The following variable I populate, $url_caiso_qry, if you take the echo string and past in the browser and enter the zip file will start downloading, but I cannot download it automatically.
http://oasis.caiso.com/oasisapi/SingleZip?startdatetime=20220109T7:00-0000&enddatetime=20220207T7:00-0000&resultformat=6&queryname=SLD_FCST&market_run_id=ACTUAL&version=1
<?php
$public_end = strpos($_SERVER['SCRIPT_NAME'], '/public') + 13;
$doc_root = substr($_SERVER['SCRIPT_NAME'], 0, $public_end);
define("WWW_ROOT", $doc_root);
// creates data array for precio de carga SIN
// function create_dataarrayp_chrt($zona) {
$ayer = date("Ymd\T7:00-0000", strtotime('now - 1 day'));
$mespasado = date("Ymd\T7:00-0000",strtotime('-30 days'));
$sdate = $mespasado; //startdatetime=
$edate = $ayer; //enddatetime=
$resultformat = '6';
$queryname='SLD_FCST';
$version='1';
$marketrunid='ACTUAL';
$fields = [
'startdatetime' => $sdate,
'enddatetime' => $edate,
'resultformat' => $resultformat,
'queryname' => $queryname,
'market_run_id' => $marketrunid,
'version' => $version,
];
//post fields
$postparam = urldecode(http_build_query($fields));
//PRECIOS url base string
$urlcaiso = 'http://oasis.caiso.com/oasisapi/SingleZip?';
//$urlcaiso = 'http://oasis.caiso.com/oasisapi/SingleZip?resultformat=6&queryname=SLD_FCST&version=1&market_run_id=ACTUAL&startdatetime=' . $sdate . 'T07:00-0000&enddatetime=' . $edate . 'T07:00-0000';
$url_caiso_qry = $urlcaiso . $postparam;
$caisofile = file_get_contents($url_caiso_qry, "rb");
//attempt to write file to destination path, but no file is written. Instead the following warning
//Warning: file_put_contents(/name1/name2/private/test/):
// failed to open stream: No such file or directory in C:\xampp\htdocs\name1\name2\private\test.php on line 94
$destination_path = WWW_ROOT . 'name2/private/test/';
$newfile = file_put_contents($destination_path, $caisofile);
echo $newfile . '<br><br>';
?>
The second parameter you pass to file_get_contents describes the use_include_path according to the php documentation.
I tried this simple example to get the file and save it:
<?php
$content = file_get_contents('http://oasis.caiso.com/oasisapi/SingleZip?startdatetime=20220109T7:00-0000&enddatetime=20220207T7:00-0000&resultformat=6&queryname=SLD_FCST&market_run_id=ACTUAL&version=1');
file_put_contents('example.zip', $content);
Running file example.zip gives the following output:
example.zip: Zip archive data, at least v2.0 to extract which indicates success.
So essentially your final code could look something like this:
<?php
// Build url here
$url = 'http://oasis.caiso.com/...';
// Download file
$zipFile = file_get_contents($url);
$public_end = strpos($_SERVER['SCRIPT_NAME'], '/public') + 13;
$doc_root = substr($_SERVER['SCRIPT_NAME'], 0, $public_end);
define("WWW_ROOT", $doc_root);
$targetPath = WWW_ROOT . 'proj3-ampenergy/private/test/'; // This could be any other path where your file should be stored
// Write contents to file
file_put_contents($targetPath, $zipFile);
// Write extraction logic here
Clean & tested code. Your csv file will be extracted to your script's directory.
<?php
define('PATH_ZIP', __DIR__ . '/archive.zip');
$url = 'http://oasis.caiso.com/oasisapi/SingleZip?' . http_build_query
([
'startdatetime' => '20220109T7:00-0000',
'enddatetime' => '20220207T7:00-0000',
'resultformat' => '6',
'queryname' => 'SLD_FCST',
'market_run_id' => 'ACTUAL',
'version' => '1',
]);
$data = file_get_contents($url);
file_put_contents(PATH_ZIP, $data);
$zip = new ZipArchive;
if ($zip->open(PATH_ZIP) === true)
{
$zip->extractTo(__DIR__);
$zip->close();
}
I'm using Laravel 5.4.*. I've this simple code in a helper file to upload images/gif in S3 bucket under a folder named say "instant_gifs/". The code is below:
if ( !function_exists('uploadFile') ) {
function uploadFile($fileContent, $fileName, $size='full', $disk='s3')
{
$rv = '';
if( empty($fileContent) ) {
return $rv;
}
if($size == 'full') {
dump($fileName);
$path = Storage::disk($disk)->put(
$fileName,
$fileContent,
'public'
);
}
if ( $path ) {
$rv = $fileName;
}
return $rv;
}
}
From the controller, I'm calling the helper method as below:
$file = $request->gif;
$file_name = 'instant_gifs/' . $user_id . '_' . time() . '_' . $file->getClientOriginalName();
$result = uploadFile($file, $file_name);
In the the $fileName parameter of the helper method, I'm providing the fileName as for example in this format:
"instant_gifs/83_1518596022_giphy.gif"
but after the upload, I see that the file gets stored under this folder
"vvstorage/instant_gifs/83_1518596022_giphy.gif/CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif"
with a random file name
CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif
Whereas, according to the code, it should get stored in this path:
"vvstorage/instant_gifs/83_1518596022_giphy.gif"
Doesn't get any explanation why this is happening. Any clue will be appreciated.
BucketName = vvstorage
Folder I'm mimicking = instant_gifs
After some research & testing, found the issue. put() method expects the 2nd parameter as the file contents or stream not the file object. In my code, I was sending the file as $file = $request->gif; or $file = $request->file('gif'); hoping that Storage class will implicitly get the file contents. But to get the expected result, I needed to call the helper method from the controller as below. Notice the file_get_contents() part.
$file = $request->gif;
$file_name = 'instant_gifs/' . $user_id . '_' . time() . '_' . $file>getClientOriginalName();
$result = uploadFile( file_get_contents($file), $file_name );
Now, I got the image correctly stored under the correct path for example in /instant_gifs/9_1518633281_IMG_7491.jpg.
Now, let me compare/summarize the available methods for achieving the same result:
1) put():
$path = Storage::disk('s3')->put(
'/instant_gifs/9_1518633281_IMG_7491.jpg', #$path
file_get_contents($request->file('gif')), #$fileContent
'public' #$visibility
Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg
2) putFileAs(): To achieve the same thing withputFileAs(), I needed to write it as below. 1st parameter expects the directory name, I left it blank as I'm mimicking the directory name in s3 through the filename.
$path = Storage::disk('s3')->putFileAs(
'', ## 1st parameter expects directory name, I left it blank as I'm mimicking the directory name through the filename
'/instant_gifs/9_1518633281_IMG_7491.jpg',
$request->file('gif'), ## 3rd parameter file resource
['visibility' => 'public'] #$options
);
Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg
3) storeAs():
$path = $request->file('gif')->storeAs(
'', #$path
'/instant_gifs/9_1518633281_IMG_7491.jpg', #$fileName
['disk'=>'s3', 'visibility'=>'public'] #$options
);
Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg
Extras::
4) For storing Thumbnails through put(). Example of stream() ...
$imgThumb = Image::make($request->file('image'))->resize(300, 300)->stream(); ##create thumbnail
$path = Storage::disk('s3')->put(
'profilethumbs/' . $imgName,
$imgThumb->__toString(),
'public'
);
Hope that it helps someone.
1.) Why is there vvstorage in the url?
It is appending that route because your root folder inside of your configuration for S3 is set as vvstorage, so whenever you upload to S3 all files will be prepended with vvstorage.
2.) Why random name even when you passed the name of the file?
Because when using put the file will get a unique ID generated and set as it's file name so no matter what you pass, it won't save the file under the name you wanted. But if you use putFileAs then you can override the default behaviour of put and pass a name of the file.
Hope this clarifies it
I need to download all the attachments on a Podio app. I can get all the files id and their url, etc.. i just can't make the download. I've tried many possible solutions (get_raw(), file_get_contents, etc..).
Lets say i have this file that i want to save:
$items = PodioFile::get_for_app(APP_ID, array(
'sort_by' => 'name',
'sort_desc' => 'false',
'limit' => 1
));
(...)
$item->file_id = '123456789'
$item->link = 'https://files.podio.com/111222333';
$path_to_save = 'backup/';
How can i save it?
There's an example ready for copy+paste at: http://podio.github.io/podio-php/api-requests/
// Get the file object. Only necessary if you don't already have it!
$file = PodioFile::get($file_id);
// Download the file. This might take a while...
$file_content = $file->get_raw();
// Store the file on local disk
file_put_contents($path_to_file, $file_content);
mkdirs("downloads");
foreach ($podio_item->fields['images']->values as $key => $podio_file) {
$file = PodioFile::get($podio_file->file_id);
$file_content = $file->get_raw();
file_put_contents("downloads/$podio_image->name", $file_content);
}
I have found this script http://d.danylevskyi.com/node/7 which I have used as a starter for the below code.
The goal is to be able to save a user picture:
<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$uid = 99;
$account = user_load($uid);
// get image information
$image_path = 'public://avatars/upload/b8f1e69e83aa12cdd3d2babfbcd1fe27_4.gif';
$image_info = image_get_info($image_path);
// create file object
$file = new StdClass();
$file->uid = $uid;
$file->uri = $image_path;
$file->filemime = $image_info['mime_type'];
$file->status = 0; // Yes! Set status to 0 in order to save temporary file.
$file->filesize = $image_info['file_size'];
// standard Drupal validators for user pictures
$validators = array(
'file_validate_is_image' => array(),
'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')),
'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024),
);
// here all the magic :)
$errors = file_validate($file, $validators);
if (empty($errors)) {
file_save($file);
$edit['picture'] = $file;
user_save($account, $edit);
}
?>
A picture is created in sites/default/files/pictures/ with the name picture-99-1362753611.gif
Everything seems correct in the file_managed table except that:
the filename field is empty
the uri field shows public://avatars/upload/b8f1e69e83aa12cdd3d2babfbcd1fe27_4.gif
the status field is set to 0 (temporary)
The picture field in the users table gets updated with the fid of the above mentioned entry.
I would guess that the file_managed table should store the final file (in sites/default/pictures) instead of the original file info and that the users table should link to the one too.
Any idea how I can achieve that? I am quite new to the Drupal API. Thank you.
Edit:
I understand that I am giving the original file to the file_save and user_save functions. But which one actually creates the file in sites/default/pictures/ ?
Try adding the following to your code:
$file->filename = drupal_basename($image_path);
$file->status = FILE_STATUS_PERMANENT;
$file = file_save($file); // Use this instead of your current file_save
Does that help?
------------------ EDIT ------------------
If you want to save a copy of the file in a new location, you can replace the third line above with something like
// Save the file to the root of the files directory.
$file = file_copy($file, 'public://');
I've got this PHP script I'm working on to import pay-stubs into Drupal. It's doing everything the way I want except the script is not attaching the uploaded PDF file to the node.
A few notes; Drupal's filesystem is set to private, not sure if this makes a difference or not. Second, the pdf files are already in the correct location 'paystubs/[uid]/paystub_1.pdf' so I think my problem is that the file is not being associated to the node correctly.
Here is the code
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2) {
$sourcePDF = "/var/www/html/mgldev.************.com/burst_pdfs/pdfs/" . $file2;
$destinationPDF = '/paystubs/' . $drupalUid . '/' . $file2;
$destination = '/paystubs/' . $drupalUid . '/';
if (!file_check_directory($destination, TRUE)){
echo "Failed to check dir, does it exist?";
mkdir($destination);
echo "trying to drupal mkdir...";
}
// Copy the file to the Drupal files directory
if (file_exists($sourcePDF)) {
if(!rename($sourcePDF, $destinationPDF)) {
echo "Failed to move file\n";
}
}
//Create node and attach file uplaod
$file_drupal_path = "paystubs/" . $drupalUid . "/" . $file2;
$mime = 'pdf/application';
$file = new stdClass();
$file->filename = $file2;
$file->filepath = $file_drupal_path;
$file->filemime = $mime;
$file->filesize = filesize($file_drupal_path);
$file->uid = $drupalUid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$node = new StdClass();
$node->type = 'paystub';
$node->body = $employeeID;
$node->title = $employeeDate;
$node->field_paystub_upload = array(
array(
'fid' => $file->fid,
'title' => $file2,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'data' => array(
'description' => $file2,
),
'list' => 1,
),
);
$node->uid = $drupalUid;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);
}
The node is created and the title and body of the node have the right values. When I look at the node using Devel module I can see that the 'field_paystub_upload' array is null. So for some reason its doing everything right except attaching the file to the node and that is what I've been banging my head on for days. Best response gets on free internet?
Drupal's file.inc file_save_upload uses $_FILES, which is a global, magically set by PHP. Drupal expects an uploaded file, not a file that exists locally.
You best just call a custom file-saver method, to process local files. Make sure its path up in the files database-table too. file_save_upload will be valuable for creating such a helper method.
Big thanks to berkes for helping me solve this problem. Turns out that since the files were already on the drupal webserver and not being uploaded to PHP $_FILES global variable, I was unable to programmatically upload the file correctly.
This was causing every other way I've tried to fail. I tried using Drupals defualt upload module and I also tried using CCK's fielfield module both were not working. Thanks to berkes suggestion I found a function that comes with CCK's filefield widget to save uploaded files that are already on the server. Hopefully this helps someone else.
This is the function I found that can save a file thats already on the web-server.
Here is the working code I used to create the node and attach the file after calling field_file_save_file.
function create_drupal_node($employeeID, $employeeDate, $drupalUid, $file2){
$file_remove_html_extention = substr($file2, 0, -7);
$file_pdf = $file_remove_html_extention . '.pdf';
$node = new stdClass();
$node->type = 'paystub';
$node->status = 1;
$node->uid = $drupalUid;
$node->title = $employeeDate . ' - eStub';
$node->body = $employeeID;
$node->created = time();
$node->changed = $node->created;
$node->promote = 1;
$node->sticky = 0;
$node->format = 1;
$node->language = 'en';
$file = '/var/www/html/mgldev.foobar.com/burst_pdfs/pdfs/' . $file_pdf;
// Get the path to your Drupal site's files directory
$dest_folder = '/paystubs/' . $drupalUid;
$dest = 'paystubs/' . $drupalUid . '/' . $file_pdf;
if (!file_check_directory($dest_folder, TRUE)){
mkdir($dest_folder);
}
// Load the CCK field
$field = content_fields('field_paystub_upload', 'paystub');
// Load the appropriate validators
$validators = array_merge(filefield_widget_upload_validators($field));
// Create the file object
$file = field_file_save_file($file, $validators, $dest_folder);
// Apply the file to the field, this sets the first file only, could be looped
// if there were more files
$node->field_paystub_upload = array(0 => $file);
// The file has been copied in the appropriate directory, so it can be
// removed from the import directory
unlink($file);
// change file status to permanent
file_set_status($file,1);
node_save($node);
}
</pre></code>
Thanks again berkes