cellog Thu Dec 13 05:22:05 2007 UTC
Added files:
/pecl/phar/tests phar_buildfromiterator8.phpt
Modified files:
/pecl/phar phar_object.c
Log:
new test
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]
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.74&r2=1.75&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.74 pecl/phar/phar_object.c:1.75
--- pecl/phar/phar_object.c:1.74 Thu Dec 13 01:16:55 2007
+++ pecl/phar/phar_object.c Thu Dec 13 05:22:05 2007
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar_object.c,v 1.74 2007/12/13 01:16:55 cellog Exp $ */
+/* $Id: phar_object.c,v 1.75 2007/12/13 05:22:05 cellog Exp $ */
#include "phar_internal.h"
@@ -310,6 +310,7 @@
{
zval **value;
zend_uchar key_type;
+ zend_bool is_splfileinfo = 0;
ulong int_key;
struct _t {
phar_archive_object *p;
@@ -318,11 +319,11 @@
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 @@
/* 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 @@
#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 @@
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 @@
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);
http://cvs.php.net/viewvc.cgi/pecl/phar/tests/phar_buildfromiterator8.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/phar_buildfromiterator8.phpt
+++ pecl/phar/tests/phar_buildfromiterator8.phpt
--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===