I am trying to script some code that will search a specified folder on the server for the latest file with a specific file extension (in my case .zip) and transfer that file to Rackspace's Cloud Files. The code below is as far i got and i keep getting the error:
Fatal error: Uncaught exception 'IOException' with message 'Could not open file for reading: Resource id #8' in /home/test/public_html/cloudapi/cloudfiles.php:1952 Stack trace: #0 /home/test/public_html/final.php(60): CF_Object->load_from_filename(Resource id #8) #1 {main} thrown in /home/test/public_html/cloudapi/cloudfiles.php on line 1952
The code that i'm using below was originally done for uploading content via an html upload form & i'm trying to adapt the same code to use a local server file instead of an uploaded file. You will see commented code with was previously for an upload script to show you how the upload script had worked.
<?php
// include the Cloud API.
require('cloudapi/cloudfiles.php');
// START - Script to find recent file with the extension .zip in current folder
$show = 2; // Leave as 0 for all
$dir = ''; // Leave as blank for current
if($dir) chdir($dir);
$files = glob( '*.zip');
usort( $files, 'filemtime_compare' );
function filemtime_compare( $a, $b )
{
return filemtime( $b ) - filemtime( $a );
}
$i = 0;
foreach ( $files as $file )
{
++$i;
if ( $i == $show ) break;
$value = $file; //Variable $value contains the filename of the recent file to be used in Cloud Files API
}
// END - Script to find recent file with the extension .zip in current folder
// START - Rackspace API code to upload content to cloud files container
// Rackspace Connection Details;
$username = "randomusername"; // put username here
$key = "234887347r93289f28h3ru283h2fuh23093402398"; // api key
// Connect to Rackspace
$auth = new CF_Authentication($username, $key);
$auth->authenticate();
$conn = new CF_Connection($auth);
//Set the Container you want to use
$container = $conn->get_container('Backups');
//Temp store the file
//$localfile = $_FILES['uploadfile']['tmp_name'];
//$filename = $_FILES['uploadfile']['name'];
$localfile = fopen($value, "r");
$filename = $value;
//Uploading to Rackspace Cloud
$object = $container->create_object($filename);
$object->load_from_filename($localfile);
echo "Your file has been uploaded";
// END - Rackspace API code to upload content to cloud files container
?>
I know this is an old thread. But for the benefit of people who may land at this page while searching for a solution...
The problem with your code is:
The following statement opens the file for reading
$localfile = fopen($value, "r");
However when you place the load_from_filename call, the routine again tries to open the same file and fails because you already have it open in $localfile.
So comment out the previous command and you should be able to run the script successfully.
Error's being thrown in because content type not defined from read file.
Related
I'm struggling around with a simple PHP functionality: Creating a ZIP Archive with some files in.
The problem is, it does not create only one file called filename.zip but two files called filename.zip.a07600 and filename.zip.b07600. Pls. see the following screenshot:
The two files are perfect in size and I even can rename each of them to filename.zip and extract it without any problems.
Can anybody tell me what is going wrong???
function zipFilesAndDownload_Defect($archive_file_name, $archiveDir, $file_path = array(), $files_array = array()) {
// Archive File Name
$archive_file = $archiveDir."/".$archive_file_name;
// Time-to-live
$archiveTTL = 86400; // 1 day
// Delete old zip file
#unlink($archive_file);
// Create the object
$zip = new ZipArchive();
// Create the file and throw the error if unsuccessful
if ($zip->open($archive_file, ZIPARCHIVE::CREATE) !== TRUE) {
$response->res = "Cannot open '$archive_file'";
return $response;
}
// Add each file of $file_name array to archive
$i = 0;
foreach($files_array as $value){
$expl = explode("/", $value);
$file = $expl[(count($expl)-1)];
$path_file = $file_path[$i] . "/" . $file;
$size = round((filesize ($path_file) / 1024), 0);
if(file_exists($path_file)){
$zip->addFile($path_file, $file);
}
$i++;
}
$zip->close();
// Then send the headers to redirect to the ZIP file
header("HTTP/1.1 303 See Other"); // 303 is technically correct for this type of redirect
header("Location: $archive_file");
exit;
}
The code which calls the function is a file with a switch-case... it is called itself by an ajax-call:
case "zdl":
$files_array = array();
$file_path = array();
foreach ($dbh->query("select GUID, DIRECTORY, BASENAME, ELEMENTID from SMDMS where ELEMENTID = ".$osguid." and PROJECTID = ".$osproject.";") as $subrow) {
$archive_file_name = $subrow['ELEMENTID'].".zip";
$archiveDir = "../".$subrow['DIRECTORY'];
$files_array[] = $archiveDir.DIR_SEPARATOR.$subrow['BASENAME'];
$file_path[] = $archiveDir;
}
zipFilesAndDownload_Defect($archive_file_name, $archiveDir, $file_path, $files_array);
break;
One more code... I tried to rename the latest 123456.zip.a01234 file to 123456.zip and then unlink the old 123456.zip.a01234 (and all prior added .a01234 files) with this function:
function zip_file_exists($pathfile){
$arr = array();
$dir = dirname($pathfile);
$renamed = 0;
foreach(glob($pathfile.'.*') as $file) {
$path_parts = pathinfo($file);
$dirname = $path_parts['dirname'];
$basename = $path_parts['basename'];
$extension = $path_parts['extension'];
$filename = $path_parts['filename'];
if($renamed == 0){
$old_name = $file;
$new_name = str_replace(".".$extension, "", $file);
#copy($old_name, $new_name);
#unlink($old_name);
$renamed = 1;
//file_put_contents($dir."/test.txt", "old_name: ".$old_name." - new_name: ".$new_name." - dirname: ".$dirname." - basename: ".$basename." - extension: ".$extension." - filename: ".$filename." - test: ".$test);
}else{
#unlink($file);
}
}
}
In short: copy works, rename didn't work and "unlink"-doesn't work at all... I'm out of ideas now... :(
ONE MORE TRY: I placed the output of $zip->getStatusString() in a variable and wrote it to a log file... the log entry it produced is: Renaming temporary file failed: No such file or directory.
But as you can see in the graphic above the file 43051221.zip.a07200 is located in the directory where the zip-lib opens it temporarily.
Thank you in advance for your help!
So, after struggling around for days... It was so simple:
Actually I work ONLY on *nix Servers so in my scripts I created the folders dynamically with 0777 Perms. I didn't know that IIS doesn't accept this permissions format at all!
So I remoted to the server, right clicked on the folder Documents (the hierarchically most upper folder of all dynamically added files and folders) and gave full control to all users I found.
Now it works perfect!!! The only thing that would be interesting now is: is this dangerous of any reason???
Thanks for your good will answers...
My suspicion is that your script is hitting the PHP script timeout. PHP zip creates a temporary file to zip in to where the filename is yourfilename.zip.some_random_number. This file is renamed to yourfilename.zip when the zip file is closed. If the script times out it will probably just get left there.
Try reducing the number of files to zip, or increasing the script timeout with set_time_limit()
http://php.net/manual/en/function.set-time-limit.php
I am using google drive sdk for uploading files and also I think i can possibly create pdf file on it - so I tweak the code. So in my code, I generate HTML text format to be used as content for the PDF to be created in google drive.
this is a snip-it of my code.
$subcontent = "<h1>Hello World</h1><p>some text here</p>";
$file = new Google_DriveFile();
....
$mkFile = $this->_service->files->insert($file, array('data' => $subcontent));
$createdFile = $fileupload->nextChunk($mkFile, $subcontent); // I got error on this line
$this->_service->files->trash( $createdFile['id'] );
...
when I run the code I got an error based the comment I put in my code above:
Catchable fatal error: Argument 1 passed to Google_MediaFileUpload::nextChunk() must be an instance of Google_HttpRequest, array given, called in /home/site/public_html/mywp/wp-content/plugins/mycustomplugin/functions.php on line 689 and defined in /home/site/public_html/mywp/wp-content/plugins/mycustomplugin/gdwpm-api/service/Google_MediaFileUpload.php on line 212
I have no idea what should be the value in the 2nd parameter in nextChunk, in the original code it goes like this:
.....
$handle = fopen($path, "rb");
while (!$status && !feof($handle)) {
$max = false;
for ($i=1; $i<=$max_retries; $i++) {
$chunked = fread($handle, $chunkSize);
if ($chunked) {
$createdFile = $fileupload->nextChunk($mkFile, $chunked);
break;
}elseif($i == $max_retries){
$max = true;
}
}
.....
my question is that, how can I deal with this error? and how can I successfully create pdf file in google drive by tweaking this code? because I need the created file ID of the file to be linked in my post.
Thanks in advance...
You shouldn't be passing $mkFile to nextChunk. Have a read though the resumable uploads section in the documentation.
You have more fundamental issues than that though. For instance, the insert call you do already sets the data for the file. There is no need to do anything with nextChunk unless you are doing resumable uploads. Follow the "Multipart File Upload" section of the above doc to fix your insert statement and just remove the nextChunk line.
While User uploads the files, the folder should be automatically created in the dropbox with the username as folder name. and then after the files that were uploaded by the user should be saved in that folder.
Error thrown:
"
Error: Resource at uri: https://api.dropbox.com/1/metadata/dropbox/sweety could not be found."
The code is
// Upload
$wpschunks = explode("/",$wpsdbTmpFile);
for($i = 0; $i < count($wpschunks); $i++) {
$c = $i;
}
global $current_user;
$wpuserid = $current_user->data->ID;
$wpusername = $current_user->data->user_login;
$newfoldername = $wpusername;
// echo trim($wpsdb_path,'/').' //\\ ';
$folderMetadata = $dropbox->getMetaData(trim($wpsdb_path, '/') . '/' . $newfoldername, true);
if (!$folderMetadata['is_dir']) {
$dropbox->CreateFolder(trim($wpsdb_path, '/') . '/' . $newfoldername, "dropbox");
if ( !$dropbox->putFile(trim($wpsdb_path,'/').'/'.$newfoldername.'/'.$wpschunks[$c], $wpstmpFile,"dropbox") ) {
throw new Exception(__('ERROR! Upload Failed.','simpleDbUpload'));
}
if($wpsdb_delete_file == "True") {
if (isset($wpsdbTmpFile) && file_exists($wpsdbTmpFile)) {
unlink($wpsdbTmpFile);
}
}
}
Note:
When we create the blank folder manually in dropbox and then delete it and then if we try to upload the files the folder is create automatically(using this code) and the files also get uploaded.
I have no idea what "api version of 2010" means. :-) I don't know what library the Wordpress plugin is based on, but it looks like in this one, an error is raised when you request the metadata of a path that doesn't exist. I don't see why this is a problem... just handle the error and continue?
As an alternative, you could just not create the folder at all. Folders are implicitly created in Dropbox when you upload files into them. So you could just go straight to the $dropbox->putFile() call and skip checking for the folder and creating it if it doesn't already exist.
I am trying to add Document to Sugar object (client) from PHP script. I have a directory of files (on the same server where sugarCRM is installed) and xls with sugar objec ID and filename). PHP Script should add correct filename to specific sugar object (identified with ID). I can read XLS this is no problem, I can also get instance of sugar object (retrieve by ID), but I have no idea how can I assign the file to sugar. I was trying with Document, and upload_file.php, but those seem to be usable with uploading single file with html Form.
How can I automate this task, copy files with correct filename to cache\upload and create Document related to my Customer from PHP Script? I would prefer not to use SOAP if it's not necesarry...
Edit:
I was able to save document and revision, but something is wrong, and file can't be downloaded from browser ("incorrect call to file")
My Code so far is:
require_once('include/upload_file.php');
$upload_file = new UploadFile('uploadfile');
$document->filename = 'robots.txt';
$document->document_name = 'robots.txt';
$document->save();
$contents = file_get_contents ($document->filename);
$revision = new DocumentRevision;
$revision->document_id = $document->id;
$revision->file = base64_encode($contents);
$revision->filename = $document->filename;
$revision->revision = 1;
$revision->doc_type = 'Sugar';
$revision->file_mime_type = 'text/plain';
$revision->save();
$document->revision_id = $revision->id;
$document->save();
$destination = clean_path($upload_file->get_upload_path($document->id));
$fp = sugar_fopen($destination, 'wb');
if( !fwrite($fp, $contents) ){
die("ERROR: can't save file to $destination");
}
fclose($fp);
WORKS! I Hope this will help someone
I have corrected 3 lines from code abowe:
//$document->revision_id = $revision->id;
//$document->save();
$destination = clean_path($upload_file->get_upload_path($revision->id));
I am working on a piece of code that I am wanting to "spice" up with jQuery but I can't think of a way to actually make it work. I am sure its simple, I just need a little advice to get me going.
I am wanting to create a piece of code that makes an Ajax request out to start a big loop that will download files and then upload them to an S3 bucket of mine. The place where I am stuck is I am wanting to send back a request back to the browser everytime a file is uploaded and output a string of text to the screen upon completion.
I don't have any of the frontend code working... just trying to get my head wrapped around the logic first... any ideas?
PHP Backend Code:
<?php
public function photos($city) {
if(isset($city))
$this->city_name = "{$city}";
// grab data array from Dropbox folder
$postcard_assets = $this->conn->getPostcardDirContent("{$this->city_name}", "Photos", TRUE);
$data = array();
foreach($postcard_assets['contents'] as $asset) {
//only grab contents in root folder... do not traverse into sub folders && make sure the folder is not empty
if(!$asset['is_dir'] && $asset['bytes'] > 0) {
// get information on file
$file = pathinfo($asset['path']);
// download file from Dropbox
$original_file = $this->conn->downloadFile(str_replace(" ", "%20", $asset['path']));
// create file name
$file_name = $this->cleanFileName($file['basename']);
// write photo to TMP_DIR ("/tmp/photos/") for manipulation
$fh = fopen(self::TMP_DIR . $file_name, 'w');
fwrite($fh, $original_file);
fclose($fh);
// Resize photo
$this->resize_photo($file_name);
// hash file name
$raw_file = sha1($file_name);
// create S3 hashed name
$s3_file_name = "1_{$raw_file}.{$file['extension']}";
// Upload manipulated file to S3
$this->s3->putObject($s3_file_name, file_get_contents(self::TMP_DIR . $file_name), $this->photo_s3_bucket, 'public-read');
// check to see if file exists in S3 bucket
$s3_check = $this->s3->getObjectInfo($s3_file_name, $this->photo_s3_bucket);
// if the file uploaded successully to S3, load into DB
if($s3_check['content-length'] > 0) {
$data['src'] = $s3_file_name;
$data['width'] = $this->width;
$data['height'] = $this->height;
Photo::create_postcard_photo($data, "{$this->city_name}");
// Now that the photo has been uploaded to S3 and saved in the DB, remove local file for cleanup
unlink(self::TMP_DIR . $file_name);
echo "{$file_name} uploaded to S3 and resized!<br />";
}
}
}
// after loop is complete, kill script or nasty PHP header warnings will appear
exit();
}
?>
The main problem is that with PHP, the output is buffered so it won't return a line at a time. You can try and force the flush but it's not always reliable.
You could add an entry to the DB for each file that is exchanged and create a seperate API to get the details of what has completed.
Generally, Jquery will wait till the request has finished before it allows you to manipulate data from a HTTP request.