Example #1
0
 /**
  *	extract()
  *
  *	Extracts the contents of a zip file to the specified directory using the best unzip methods possible.
  *
  *	@param	string		$zip_file					Full path & filename of ZIP file to extract from.
  *	@param	string		$destination_directory		Full directory path to extract into.
  *	@return	bool									true on success, false otherwise
  */
 public function extract($zip_file, $destination_directory = '')
 {
     $result = false;
     $za = NULL;
     $stat = array();
     // This should give us a new archive object, of not catch it and bail out
     try {
         $za = new pluginbuddy_ZipArchive();
         $result = true;
     } catch (Exception $e) {
         // Something fishy - the methods indicated ziparchive but we couldn't find the class
         $error_string = $e->getMessage();
         pb_backupbuddy::status('details', sprintf(__('ziparchive indicated as available method but error reported: %1$s', 'it-l10n-backupbuddy'), $error_string));
         $result = false;
     }
     // Only continue if we have a valid archive object
     if (true === $result) {
         $result = $za->open($zip_file);
         // Make sure we opened the zip ok
         if (true === $result) {
             // How many files - could be 0 if we had an empty zip file
             $file_count = $za->numFiles;
             // Only returns true for success or false for failure - no indication of why failed
             $result = $za->extractTo($destination_directory);
             // Currently we can only distinguish between success and failure but no finer grain
             if (true === $result) {
                 pb_backupbuddy::status('details', sprintf(__('ziparchive extracted file contents (%1$s to %2$s)', 'it-l10n-backupbuddy'), $zip_file, $destination_directory));
             } else {
                 $error_string = $za->errorInfo();
                 pb_backupbuddy::status('details', sprintf(__('ziparchive failed to extract file contents (%1$s to %2$s) - Error Info: %3$s.', 'it-l10n-backupbuddy'), $zip_file, $destination_directory, $error_string));
                 // May seem redundant but belt'n'braces
                 $result = false;
             }
             $this->log_archive_file_stats($zip_file);
         } else {
             // Couldn't open archive - will return for maybe another method to try
             $error_string = $za->errorInfo($result);
             pb_backupbuddy::status('details', sprintf(__('ZipArchive failed to open file to extract contents (%1$s to %2$s) - Error Info: %3$s.', 'it-l10n-backupbuddy'), $zip_file, $destination_directory, $error_string));
             // Return an error code and a description - this needs to be handled more generically
             //$result = array( 1, "Unable to get archive contents" );
             // Currently as we are returning an array as a valid result we just return false on failure
             $result = false;
         }
         $za->close();
     }
     if (NULL != $za) {
         unset($za);
     }
     return $result;
 }
 /**
  *	extract_generic_selected()
  *
  *	Extracts the contents of a zip file to the specified directory using the best unzip methods possible.
  *
  *	@param	string		$zip_file					Full path & filename of ZIP file to extract from.
  *	@param	string		$destination_directory		Full directory path to extract into.
  *	@param	array		$items						Mapping of what to extract and to what
  *	@return	bool									true on success (all extractions successful), false otherwise
  */
 protected function extract_generic_selected($zip_file, $destination_directory = '', $items)
 {
     $result = false;
     $za = NULL;
     // This should give us a new archive object, if not catch it and bail out
     try {
         $za = new pluginbuddy_ZipArchive();
         $result = true;
     } catch (Exception $e) {
         // Something fishy - the methods indicated ziparchive but we couldn't find the class
         $error_string = $e->getMessage();
         $this->log('details', sprintf(__('ziparchive indicated as available method but error reported: %1$s', 'it-l10n-backupbuddy'), $error_string));
         $result = false;
     }
     // Only continue if we have a valid archive object
     if (true === $result) {
         $result = $za->open($zip_file);
         // Make sure we opened the zip ok
         if (true === $result) {
             // Now we need to take each item and run an unzip for it - unfortunately there is no easy way of combining
             // arbitrary extractions into a single command if some might be to a
             foreach ($items as $what => $where) {
                 $rename_required = false;
                 $result = false;
                 // Decide how to extract based on where
                 if (empty($where)) {
                     // First we'll extract and then junk the path
                     $result = $za->extractTo($destination_directory, $what);
                     // Unlike exec zip we have to effectively junk the path after the extraction
                     // Do this by renaming the file to the destination directory and then getting rid of any directory
                     // structure it was under. If dirname is not . then we know there is a directry path and not
                     // just a simple file name (remember that $what should _not_ have any leading slash whether
                     // it is a filepath or a simple filename)
                     if ("." != dirname($what)) {
                         rename($destination_directory . DIRECTORY_SEPARATOR . $what, $destination_directory . DIRECTORY_SEPARATOR . basename($what));
                         // Get the path component of $what - note that dirname() adds a leading slash
                         // even if none was present originally. We must get the first directory component only
                         // so we can do a recursive delete on it. This is a bit klunky but functional.
                         $whatpath = $what;
                         do {
                             $whatpath = dirname($whatpath);
                         } while (1 < strlen(dirname($whatpath)));
                         // Now we can do the recursive delete from that top level component
                         $this->delete_directory_recursive($destination_directory . $whatpath);
                     }
                 } elseif (!empty($where)) {
                     if ($what === $where) {
                         // Check for wildcard directory extraction like dir/* => dir/*
                         if ("*" == substr(trim($what), -1)) {
                             // Get our path match string (just clip off the wildcard)
                             $whatroot = substr(trim($what), 0, -1);
                             $file_count = $za->numFiles;
                             // Crikey, it's a directory tree extraction - don't panic
                             // We need to go through the whole zip and extract each file that matches
                             for ($i = 0; $i < $file_count; $i++) {
                                 // Get the filename by index and see if it's in the tree
                                 $filename = $za->getNameIndex($i);
                                 if (0 === strpos($filename, $whatroot)) {
                                     // $what matched the root of this filename so extract it
                                     $result = $za->extractTo($destination_directory, $filename);
                                     if (false === $result) {
                                         // An extraction failed so bail out here - this should just
                                         // drop us through to the post-processing of $result which on
                                         // a false should then drop us out of the foreach loop
                                         break;
                                     }
                                 }
                             }
                         } else {
                             // It's just a single file extraction - breath a sign of relief
                             // Extract to same directory structure - don't junk path, no need to add where to destnation as automatic
                             $result = $za->extractTo($destination_directory, $what);
                         }
                     } else {
                         // First we'll extract and then junk the path
                         $result = $za->extractTo($destination_directory, $what);
                         // Unlike exec zip we have to effectively junk the path after the extraction
                         // Do this by renaming the file to the destination directory and then getting rid of any directory
                         // structure it was under. If dirname is not . then we know there is a directry path and not
                         // just a simple file name (remember that $what should _not_ have any leading slash whether
                         // it is a filepath or a simple filename)
                         if ("." != dirname($what)) {
                             rename($destination_directory . DIRECTORY_SEPARATOR . $what, $destination_directory . DIRECTORY_SEPARATOR . basename($what));
                             // Get the path component of $what - note that dirname() adds a leading slash
                             // even if none was present originally. We must get the first directory component only
                             // so we can do a recursive delete on it. This is a bit klunky but functional.
                             $whatpath = $what;
                             do {
                                 $whatpath = dirname($whatpath);
                             } while (1 < strlen(dirname($whatpath)));
                             // Now we can do the recursive delete from that top level component
                             $this->delete_directory_recursive($destination_directory . $whatpath);
                         }
                         // Will need to rename if the extract is ok
                         $rename_required = true;
                     }
                 }
                 // Note: we don't open the file and then do stuff but it's all done in one action
                 // so we need to interpret the return code to dedide what to do
                 // Currently we can only distinguish between success and failure but no finer grain
                 if (true === $result) {
                     $this->log('details', sprintf(__('ziparchive extracted file contents (%1$s from %2$s to %3$s%4$s)', 'it-l10n-backupbuddy'), $what, $zip_file, $destination_directory, $where));
                     // Rename if we have to
                     if (true === $rename_required) {
                         // Note: we junked the path on the extraction so just the filename of $what is the source but
                         // $where could be a simple file name or a file path
                         $result = $result && rename($destination_directory . DIRECTORY_SEPARATOR . basename($what), $destination_directory . DIRECTORY_SEPARATOR . $where);
                     }
                 } else {
                     // For now let's just print the error code and drop through
                     $error_string = $za->errorInfo();
                     $this->log('details', sprintf(__('ziparchive failed to open/process file to extract file contents (%1$s from %2$s to %3$s%4$s) - Error Info: %5$s.', 'it-l10n-backupbuddy'), $what, $zip_file, $destination_directory, $where, $error_string));
                     // May seem redundant but belt'n'braces
                     $result = false;
                 }
                 // If the extraction failed (or rename after extraction) then break out of the foreach and simply return false
                 if (false === $result) {
                     break;
                 }
             }
         } else {
             // Couldn't open archive - will return for maybe another method to try
             $error_string = $za->errorInfo($result);
             $this->log('details', sprintf(__('ZipArchive failed to open file to extract contents (%1$s to %2$s) - Error Info: %3$s.', 'it-l10n-backupbuddy'), $zip_file, $destination_directory, $error_string));
             // Return an error code and a description - this needs to be handled more generically
             //$result = array( 1, "Unable to get archive contents" );
             // Currently as we are returning an array as a valid result we just return false on failure
             $result = false;
         }
         $za->close();
     }
     if (NULL != $za) {
         unset($za);
     }
     return $result;
 }