3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * Utilities for working with zip files
24 * Given a zip file which contains a single root directory, determine the root's name.
26 * @param ZipArchive $zip
29 * FALSE if #root level items !=1; otherwise, the name of base dir
31 public static function findBaseDirName(ZipArchive
$zip) {
32 $cnt = $zip->numFiles
;
37 for ($i = 0; $i < $cnt; $i++
) {
38 $filename = $zip->getNameIndex($i);
39 if ($base === FALSE) {
40 if (preg_match('/^[^\/]+\/$/', $filename) && $filename != './' && $filename != '../') {
42 $baselen = strlen($filename);
48 elseif (0 != substr_compare($base, $filename, 0, $baselen)) {
57 * Given a zip file, find all directory names in the root
59 * @param ZipArchive $zip
61 * @return array(string)
64 public static function findBaseDirs(ZipArchive
$zip) {
65 $cnt = $zip->numFiles
;
68 for ($i = 0; $i < $cnt; $i++
) {
69 $filename = $zip->getNameIndex($i);
70 // hypothetically, ./ or ../ would not be legit here
71 if (preg_match('/^[^\/]+\/$/', $filename) && $filename != './' && $filename != '../') {
72 $basedirs[] = rtrim($filename, '/');
80 * Determine the name of the folder within a zip.
82 * @param ZipArchive $zip
86 * Return string or FALSE
88 public static function guessBasedir(ZipArchive
$zip, $expected) {
90 $basedirs = CRM_Utils_Zip
::findBaseDirs($zip);
91 if (in_array($expected, $basedirs)) {
92 $candidate = $expected;
94 elseif (count($basedirs) == 1) {
95 $candidate = array_shift($basedirs);
97 if ($candidate !== FALSE && preg_match('/^[a-zA-Z0-9]/', $candidate)) {
106 * An inefficient helper for creating a ZIP file from data in memory.
107 * This is only intended for building temp files for unit-testing.
109 * @param string $zipName
112 * Array, list of directory paths.
113 * @param array $files
114 * Array, keys are file names and values are file contents.
117 public static function createTestZip($zipName, $dirs, $files) {
118 $zip = new ZipArchive();
119 $res = $zip->open($zipName, ZipArchive
::CREATE
);
121 foreach ($dirs as $dir) {
122 if (!$zip->addEmptyDir($dir)) {
126 foreach ($files as $fileName => $fileData) {
127 if (!$zip->addFromString($fileName, $fileData)) {