My script is not working to make zip file. - php

$files is an array to store file names.
createZipFile function is to make zip file. addFiles function returns true as Boolean value.
I am not sure where I am going wrong with the code.
<?php
$files[] = 'test.php';
$files[] = 'test1.php';
$files[] = 'test2.php';
createZipFile ( 'backup.zip', $files);
function createZipFile($pathtosave, $filestozip) {
// create zip file
$zip = new ZipArchive ();
if ($zip->open ( $pathtosave, ZipArchive::CREATE ) != true)
{
throw new Exception( 'Cannot create or open the zip file' );
}
else
{
foreach ( $filestozip as $zipfiles )
{
$zip->addFile($zipfiles);
}
}
// save it
$zip->close();
}
?>

The code works correctly from the command line. This is possibly a permission issue. If you are executing this through a web server, make sure the user account that the web server runs under has write permissions to the directory in which you wish to create the zip file. In this case it's the same directory as the script. You can also set global write permissions with:
chmod 777 {web directory}
But this is a security risk. It will allow any user account on the system to modify, create or delete files in the directory.

Related

How to achieve the following file structure when archiving a directory in PHP using ZipArchive();

I'm writing a PHP script that archives a selected directory and all its sub-folders. The code works fine, however, I'm running into a small problem with the structure of my archived file.
Imagine the script is located in var/app/current/example/two/ and that it wants to backup everything plus its sub directories starting at var/app/current
When I run the script it creates an archive with the following structure:
/var/app/current/index.html
/var/app/current/assets/test.css
/var/app/current/example/file.php
/var/app/current/example/two/script.php
Now I was wondering how:
a) How can I remove the /var/app/current/ folders so that the root directory of the archive starts beyond the folder current, creating the following structure:
index.html
assets/test.css
example/file.php
example/two/script.php
b) Why & how can I get rid of the "/" before the folder var?
//Create ZIP file
$zip = new ZipArchive();
$tmpzip = realpath(dirname(__FILE__))."/".substr(md5(TIME_NOW), 0, 10).random_str(54).".zip";
//If ZIP failed
if($zip->open($tmpzip,ZIPARCHIVE::CREATE)!== TRUE)
{
$status = "0";
}
else
{
//Fetch all files from directory
$basepath = getcwd(); // var/app/current/example/two
$basepath = str_replace("/example/two", "", $basepath); // var/app/current
$dir = new RecursiveDirectoryIterator($basepath);
//Loop through each file
foreach(new RecursiveIteratorIterator($dir) as $files => $file)
{
if(($file->getBasename() !== ".") && ($file->getBasename() !== ".."))
{
$zip->addFile(realpath($file), $file);
}
}
$zip->close();
You should try with:
$zip->addFile(realpath($file), str_replace("/var/app/current/","",$file));
I've never used the ZipArchive class before but with most archiver application it works if you change the directory and use relative path.
So you can try to use chdir to the folder you want to zip up.

Create diectory (ftp_mkdir) only if files exist

I currently have a program that connects to an ftp directory, if it finds csv files, runs a script, then after the script has run on the files, it creates a back up folder with the date and moves the csv files to this newly created back up folder in the ftp directory.
However, if there are no csv files in the root directory, I do not want a backup folder to be created, as there are no files to move. I know the solution is probably really simple but I cannot seem to figure it out!
logMessage("Creating backups");
$ftp_connection = #ftp_connect($ftp_url, $ftp_port, 6000);
if(!#ftp_login($ftp_connection, $ftp_username, $ftp_password )) {
logMessage("Could not connect to FTP: [$ftp_url], with Username: [$ftp_username], and Password: [$ftp_password]");
die();
}
$date = date('Y_m_d_(His)');
$newBackup = $ftp_root."/".$ftp_backup."backup_$date";
if (ftp_mkdir($ftp_connection, $newBackup)) {
logMessage ("Successfully created [$newBackup\n]");
foreach($filesToProcess as $file){
$pathData = pathinfo($file);
if(isset($pathData['extension']) && $pathData['extension'] == 'csv'){
if(!#ftp_rename($ftp_connection,
$ftp_root.'/'.$file,
$newBackup."/".$file)
){
logMessage("Unable to move file: $file")
}
}
}
}
You have used, foreach($filesToProcess as $file) ,so in $filesToProcess it's array of files. you can use, count($filesToProcess) first count number of files, then if count>0 execute code.
// $csv = your checks for string ending to .csv
$ftp_files = ftp_nlist($ftp_connection, ".");
foreach ($ftp_files = $files) {
if ($files = $csv) {
// makedir
maybe something like this in very basic syntax. ftp_nlist returns an array of all files in a particular directory.

Improve my Unzip & Move function - PHP

I'm a PHP novice and so looking for some advice on a PHP function i have created to use within a Wordpress installation.
As you can see from the code below, it runs when one of the admin's press 'Publish' on a pending post.
It takes a Zip file that has been uploaded by a user via Gravity Forms, then unzips ONLY .mp3 extensions. Re-zips and moves all the files to a new folder in our Amazon S3 directory.
The code is pieced together from my limited knowledge and some help along the way with questions on here.
So, here's what i ended up with:
add_action('pending_to_publish', 'unzip_to_s3');
function unzip_to_s3() {
global $post;
global $wpdb;
// Only run function if post is portfolio post type
if ('portfolio' == $post->post_type) {
// Set temp path
$temp_path = '../wp-content/uploads/gravity_forms/1-9e5dc27086c8b2fd2e48678e1f54f98c/2013/02/tmp/';
// Get filename from Zip file
$file = get_post_meta($post->ID, 'file_url', true);
$zip_file = basename($file);
// Create full Zip file path
$zip_file_path = $temp_path.$zip_file;
// Generate unique name for temp sub_folder for unzipped files
$temp_unzip_folder = uniqid('temp_TMS_', true);
// Create full temp sub_folder path
$temp_unzip_path = $temp_path.$temp_unzip_folder;
// Make the new temp sub_folder for unzipped files
if (!mkdir($temp_unzip_path, 0755, true)) {
die('Error: Could not create path: '.$temp_unzip_path);
}
// Unzip files to temp unzip folder, ignoring anything that is not a .mp3 extension
$zip = new ZipArchive();
$filename = $zip_file_path;
if ($zip->open($filename)!==TRUE) {
exit("cannot open <$filename>\n");
}
for ($i=0; $i<$zip->numFiles;$i++) {
$info = $zip->statIndex($i);
$file = pathinfo($info['name']);
if(strtolower($file['extension']) == "mp3") {
file_put_contents($temp_unzip_path.'/'.basename($info['name']), $zip->getFromIndex($i));
} else {
$zip->deleteIndex($i);
}
}
$zip->close();
// Re-zip the unzipped mp3's and store new zip file in temp folder created earlier
$temp_unzip_path = $temp_unzip_path.'/';
$zip = new ZipArchive();
$dirArray = array();
$new_zip_file = $temp_unzip_path.$zip_file;
$new = $zip->open($new_zip_file, ZIPARCHIVE::CREATE);
if ($new === true) {
$handle = opendir($temp_unzip_path);
while (false !== ($entry = readdir($handle))) {
if(!in_array($entry,array('.','..')))
{
$dirArray[] = $entry;
$zip->addFile($temp_unzip_path.$entry,$entry);
}
}
closedir($handle);
} else {
echo 'Failed to create Zip';
}
$zip->close();
// Set Media bucket dir
$bucket_path = '../wp-content/uploads/gravity_forms/1-9e5dc27086c8b2fd2e48678e1f54f98c/2013/02/mixtape2/';
// Generate unique name for sub_bucket
$sub_bucket = uniqid('TMS_', true);
// Create full sub_bucket path
$sub_bucket_path = $bucket_path.$sub_bucket;
// Make the new sub_bucket
if (!mkdir($sub_bucket_path, 0755, true)) {
die('Error: Could not create path: '.$sub_bucket_path);
}
// Move mp3's to new sub_bucket
// Get array of all source files
$files = scandir($temp_unzip_path);
// Identify directories
$source = $temp_unzip_path;
$destination = $sub_bucket_path.'/';
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// if move files is successful delete the original temp folder
if (rename($source.$file, $destination.$file)) {
rmdir($temp_unzip_path);
}
}
// Delete original Zip file
unlink($temp_path.$zip_file);
// Update Custom field for new Zip file location
update_post_meta($post->ID, 'file_url', 'http://themixtapesite.com/wp-content/uploads/gravity_forms/1-9e5dc27086c8b2fd2e48678e1f54f98c/2013/02/mixtape2/'.$sub_bucket.'/'.$zip_file);
}
}
Whilst this function does work, we're dealing with large files and so it does take a while to process...
What is happening is when the admin presses publish it triggers this function but the page just sits there until it's finished this function and then will continue. This function can take upto around 5 minutes to run.
I'm looking to optimise this function (in terms of code) but also see if there's a way i can run this in the background so that the admin can carry on with other things and not have to sit there waiting around.
Any help appreciated.
You may want to try to WP cron and schedule the task at that point so that it runs in the background. Here is some resources for that. the basic concept would go something like this.
if ( ! wp_next_scheduled( 'pending_to_publish' ) ) {
wp_schedule_single_event($timestamp,'pending_to_publish');
}
add_action('pending_to_publish', 'unzip_to_s3');
http://wpengineer.com/1908/use-wordpress-cron/
http://codex.wordpress.org/Category%3aWP-Cron_Functions
https://wordpress.stackexchange.com/questions/42694/run-a-cron-job-or-similar-in-the-background-of-wp-after-post-update-create

PHPs ZipArchive drops empty directories

Problem
I am building an online file manager, for downloading a whole directory structure I am generating a zip file of all subdirectories and files (recursively), therefore I use the RecursiveDirectoryIterator.
It all works well, but empty directories are not in the generated zip file, although the dir is handled correctly. This is what i am currently using:
<?php
$dirlist = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$filelist = new RecursiveIteratorIterator($dirlist, RecursiveIteratorIterator::SELF_FIRST);
$zip = new ZipArchive();
if ($zip->open($tmpName, ZipArchive::CREATE) !== TRUE) {
die();
}
foreach ($filelist as $key=>$value) {
$result = false;
if (is_dir($key)) {
$result = $zip->addEmptyDir($key);
//this message is correctly generated!
DeWorx_Logger::debug('added dir '.$key .'('.$this->clearRelativePath($key).')');
}
else {
$result = $zip->addFile($key, $key);
}
}
$zip->close();
If I ommit the FilesystemIterator::SKIP_DOTS I end up having a . file in all directories.
Conclusion
The iterator works, the addEmptyDir call gets executed (the result is checked too!) correctly, creating a zip file with various zip tools works with empty directories as intendet.
Is this a bug in phps ZipArchive (php.net lib or am I missing something? I don't want to end up creating dummy files just to keep the directory structure intact.

Remote Zip Extraction > Can't seem to get this to the finish line

The purpose of this code is to grab an update.zip file from a remote server, unzip it and save it to a local directory, updating, overwriting or creating the updated files.
I've almost got a non cURL version of this working, but I'd rather use this version. The first problem I have is that the path to the tmp folder is incorrect. I need a better method of sniffing that out (temporarily hardcoded)...
The 2nd problem is that the code's not working, but its not throwing an error. Its executing the $x branch but no zip extraction is taking place.
require('../../../wp-blog-header.php'); //enables wp security check and ABSPATH
$payload = file_get_contents('http://myserver.com/upgrade.zip'); //grab the file from the remote server
$target = ABSPATH .'wp-content/themes/mytheme/'; // this is the destination for the unzipped files
openZip($payload);
function openZip($file_to_open, $debug = false) {
global $target;
$file = ABSPATH . '/tmp/'.md5($file_to_open).'.zip'; //this should be home/myfolder/tmp but ABSPATH is giving the wrong path to the tmp directory.
$client = curl_init($file_to_open);
curl_setopt($client, CURLOPT_RETURNTRANSFER, 1);
$fileData = curl_exec($client);
file_put_contents($file, $fileData);
$zip = new ZipArchive();
$x = $zip->open($file);
if($x === true) { //this is true, but no zip extraction?
$zip->extractTo($target);
$zip->close();
unlink($file);
} else {
if($debug !== true) {
unlink($file);
}
die("There was a problem. Please try again!");
}
}
The most likely cause here is that you're not actually writing the zip file data in your file_put_contents() call inside openZip. If you pass a zero-length file to $zip->open(), it will happily go about its way returning (bool)true, even though you obviously will not be able to extract anything from it. See this example.

Categories