]> granicus.if.org Git - php/commitdiff
new test
authorGreg Beaver <cellog@php.net>
Thu, 13 Dec 2007 05:22:06 +0000 (05:22 +0000)
committerGreg Beaver <cellog@php.net>
Thu, 13 Dec 2007 05:22:06 +0000 (05:22 +0000)
now, SplDirectoryIterator can be used directly with Phar->buildFromIterator() in order to populate the
files in a phar archive.  When combined with a RegexIterator and other filters, it becomes very easy to create
a phar archive with 1 line of code
[DOC]

ext/phar/phar_object.c
ext/phar/tests/phar_buildfromiterator8.phpt [new file with mode: 0644]

index a9980f252efe52187aa93a760a997eb0b7f8e3b2..4ac637dcf7ce4dd2f910bada943438e7b29c33fb 100755 (executable)
@@ -310,6 +310,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
 {
        zval **value;
        zend_uchar key_type;
+       zend_bool is_splfileinfo = 0;
        ulong int_key;
        struct _t {
                phar_archive_object *p;
@@ -318,11 +319,11 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
                uint l;
                zval *ret;
        } *p_obj = (struct _t*) puser;
-       uint str_key_len, base_len = p_obj->l;
+       uint str_key_len, base_len = p_obj->l, fname_len;
        phar_entry_data *data;
        php_stream *fp;
        long contents_len;
-       char *fname, *error, *str_key, *base = p_obj->b, *opened, *save;
+       char *fname, *error, *str_key, *base = p_obj->b, *opened, *save = NULL;
        zend_class_entry *ce = p_obj->c;
        phar_archive_object *phar_obj = p_obj->p;
 
@@ -334,27 +335,70 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
                /* failure in get_current_data */
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned no value", ce->name);
        }
-       if (Z_TYPE_PP(value) != IS_STRING) {
-               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned an invalid value (must return a string)", ce->name);
-               return ZEND_HASH_APPLY_STOP;
+       switch (Z_TYPE_PP(value)) {
+               case IS_STRING :
+                       break;
+               case IS_OBJECT :
+                       if (instanceof_function(Z_OBJCE_PP(value), spl_ce_SplFileInfo)) {
+                               char *test;
+                               zval dummy;
+                               spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(*value TSRMLS_CC);
+
+                               if (!base_len) {
+                                       zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator %s returns an SplFileInfo object, so base directory must be specified", ce->name);
+                                       return ZEND_HASH_APPLY_STOP;
+                               }
+                               switch (intern->type) {
+                                       case SPL_FS_DIR:
+                                               fname_len = spprintf(&fname, 0, "%s%c%s", intern->path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
+                                               php_stat(fname, fname_len, FS_IS_DIR, &dummy TSRMLS_CC);
+                                               if (Z_BVAL(dummy)) {
+                                                       /* ignore directories */
+                                                       efree(fname);
+                                                       return ZEND_HASH_APPLY_KEEP;
+                                               }
+                                               test = expand_filepath(fname, test TSRMLS_CC);
+                                               if (test) {
+                                                       efree(fname);
+                                                       fname = test;
+                                                       fname_len = strlen(fname);
+                                               }
+                                               save = fname;
+                                               is_splfileinfo = 1;
+                                               goto phar_spl_fileinfo;
+                                       case SPL_FS_INFO:
+                                       case SPL_FS_FILE:
+                                               return ZEND_HASH_APPLY_KEEP;
+                               }
+                       }
+                       /* fall-through */
+               default :
+                       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned an invalid value (must return a string)", ce->name);
+                       return ZEND_HASH_APPLY_STOP;
        }
 
        fname = Z_STRVAL_PP(value);
+       fname_len = Z_STRLEN_PP(value);
 
+phar_spl_fileinfo:
        if (base_len) {
                if (strstr(fname, base)) {
-                       str_key_len = Z_STRLEN_PP(value) - base_len;
+                       str_key_len = fname_len - base_len;
                        if (str_key_len <= 0) {
-                               efree(save);
+                               if (save) {
+                                       efree(save);
+                               }
                                return ZEND_HASH_APPLY_KEEP;
                        }
                        str_key = fname + base_len;
                } else {
                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that is not in the base directory \"%s\"", ce->name, fname, base);
-                       efree(save);
+                       if (save) {
+                               efree(save);
+                       }
                        return ZEND_HASH_APPLY_STOP;
                }
-       } else  {
+       } else {
                if (iter->funcs->get_current_key) {
                        key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
                        if (EG(exception)) {
@@ -374,14 +418,18 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
 #if PHP_MAJOR_VERSION < 6
        if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that safe mode prevents opening", ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 #endif
 
        if (php_check_open_basedir(fname TSRMLS_CC)) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a path \"%s\" that open_basedir prevents opening", ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 
@@ -389,14 +437,18 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
        fp = php_stream_open_wrapper(fname, "rb", STREAM_MUST_SEEK|0, &opened);
        if (!fp) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %s returned a file that could not be opened \"%s\"", ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 
        if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", &error TSRMLS_CC))) {
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s cannot be created: %s", str_key, error);
                efree(error);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                php_stream_close(fp);
                return ZEND_HASH_APPLY_STOP;
        } else {
@@ -408,7 +460,9 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
        php_stream_close(fp);
 
        add_assoc_string(p_obj->ret, str_key, opened, 0);
-       efree(save);
+       if (save) {
+               efree(save);
+       }
 
        data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
        phar_entry_delref(data TSRMLS_CC);
diff --git a/ext/phar/tests/phar_buildfromiterator8.phpt b/ext/phar/tests/phar_buildfromiterator8.phpt
new file mode 100644 (file)
index 0000000..a48b040
--- /dev/null
@@ -0,0 +1,94 @@
+--TEST--
+Phar::buildFromIterator() iterator, SplFileInfo as current
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip"; ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+try {
+       chdir(dirname(__FILE__));
+       $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar');
+       var_dump($phar->buildFromIterator(new RegexIterator(new DirectoryIterator('.'), '/^\d{0,3}\.phpt\\z|^\.\\z|^\.\.\\z/'), dirname(__FILE__) . DIRECTORY_SEPARATOR));
+} catch (Exception $e) {
+       var_dump(get_class($e));
+       echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/buildfromiterator.phar');
+__HALT_COMPILER();
+?>
+--EXPECT--
+array(33) {
+  ["001.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/001.phpt"
+  ["002.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/002.phpt"
+  ["003.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/003.phpt"
+  ["004.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/004.phpt"
+  ["005.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/005.phpt"
+  ["006.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/006.phpt"
+  ["007.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/007.phpt"
+  ["008.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/008.phpt"
+  ["009.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/009.phpt"
+  ["010.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/010.phpt"
+  ["011.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/011.phpt"
+  ["012.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/012.phpt"
+  ["013.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/013.phpt"
+  ["014.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/014.phpt"
+  ["015.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/015.phpt"
+  ["016.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/016.phpt"
+  ["017.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/017.phpt"
+  ["018.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/018.phpt"
+  ["019.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/019.phpt"
+  ["020.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/020.phpt"
+  ["021.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/021.phpt"
+  ["022.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/022.phpt"
+  ["023.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/023.phpt"
+  ["024.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/024.phpt"
+  ["025.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/025.phpt"
+  ["026.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/026.phpt"
+  ["027.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/027.phpt"
+  ["028.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/028.phpt"
+  ["029.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/029.phpt"
+  ["030.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/030.phpt"
+  ["031.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/031.phpt"
+  ["032.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/032.phpt"
+  ["033.phpt"]=>
+  string(51) "/home/cellog/workspace/php5/ext/phar/tests/033.phpt"
+}
+===DONE===