cellog          Wed Dec 12 18:01:39 2007 UTC

  Modified files:              
    /pecl/phar  TODO package.php package.xml phar.phar phar_object.c 
  Log:
  implement Phar::buildFromIterator()
  first argument is an iterator that returns as values paths to files to add to 
the phar archive
  the key should be the path that the file should be saved as within the phar 
archive
  if the optional second parameter is passed, then the key is ignored and 
substr(value, strlen(base_directory)) is
  used as the save path within the phar archive
  [DOC]
  
http://cvs.php.net/viewvc.cgi/pecl/phar/TODO?r1=1.44&r2=1.45&diff_format=u
Index: pecl/phar/TODO
diff -u pecl/phar/TODO:1.44 pecl/phar/TODO:1.45
--- pecl/phar/TODO:1.44 Sat Aug 25 01:32:34 2007
+++ pecl/phar/TODO      Wed Dec 12 18:01:39 2007
@@ -70,8 +70,7 @@
    or foreach ($p->match('mime-type', 'image/jpeg') as $file)
  * Phar::copy($from, $to);
  X Phar::delete($what) [Greg]
- * Phar::buildFromIterator($filename, Iterator $it, array $addinfo = null);
-   $addinfo = array('alias','flags','metadata','stub'...)
+ X Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
  * Layout: Option to compress all content rather than single files.
    That excludes stub and manifest haeder.
  * stream context option for cleaning crap paths like 
phar://blah.phar/file//to\\here.php
http://cvs.php.net/viewvc.cgi/pecl/phar/package.php?r1=1.23&r2=1.24&diff_format=u
Index: pecl/phar/package.php
diff -u pecl/phar/package.php:1.23 pecl/phar/package.php:1.24
--- pecl/phar/package.php:1.23  Tue Dec 11 03:12:41 2007
+++ pecl/phar/package.php       Wed Dec 12 18:01:39 2007
@@ -1,6 +1,7 @@
 <?php
 
 $notes = '
+ * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) 
[Greg]
  * add mapping of include/require from within a phar to location within phar 
[Greg]
    solves the include_path issue without code munging
  * add Phar::delete() [Greg]
http://cvs.php.net/viewvc.cgi/pecl/phar/package.xml?r1=1.39&r2=1.40&diff_format=u
Index: pecl/phar/package.xml
diff -u pecl/phar/package.xml:1.39 pecl/phar/package.xml:1.40
--- pecl/phar/package.xml:1.39  Tue Nov 20 15:55:36 2007
+++ pecl/phar/package.xml       Wed Dec 12 18:01:39 2007
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.6.2" version="2.0" 
xmlns="http://pear.php.net/dtd/package-2.0"; 
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 
http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 
http://pear.php.net/dtd/package-2.0.xsd";>
+<package packagerversion="1.7.0RC1" version="2.0" 
xmlns="http://pear.php.net/dtd/package-2.0"; 
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 
http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 
http://pear.php.net/dtd/package-2.0.xsd";>
  <name>phar</name>
  <channel>pecl.php.net</channel>
  <summary>allows running of complete applications out of .phar files (like 
Java .jar files)</summary>
@@ -29,10 +29,10 @@
   <email>[EMAIL PROTECTED]</email>
   <active>yes</active>
  </lead>
- <date>2007-08-24</date>
- <time>20:06:43</time>
+ <date>2007-12-12</date>
+ <time>11:56:58</time>
  <version>
-  <release>1.2.1</release>
+  <release>1.3.0</release>
   <api>1.1.0</api>
  </version>
  <stability>
@@ -42,18 +42,10 @@
  <license uri="http://www.php.net/license";>PHP License</license>
  <notes>
 
- * add Phar::setAlias() [Greg]
- * fix too many open file handles issue [Greg]
- * fix rename [Greg]
- * add Phar::getAlias() [Marcus]
- * Made -a optional in pack subcommand of phar.phar [Marcus]
- * Fix issue with apache module and extracted archives [Marcus]
- * Send all error messages to stderr in phar.phar [Marcus]
- * Added new subcommands add and delete to phar.phar [Marcus]
- * Made Phar::loadPhar() and Phar::mapPhar() ignore extracted archives [Marcus]
- * Fix issue with compressed entries and uncompressing entries [Marcus]
- * Verify stubs before writing [Marcus]
- * Always use longest stub end to avoid issues with length field [Marcus]
+ * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) 
[Greg]
+ * add mapping of include/require from within a phar to location within phar 
[Greg]
+   solves the include_path issue without code munging
+ * add Phar::delete() [Greg]
 
  </notes>
  <contents>
@@ -66,7 +58,6 @@
     <file name="phar.inc" role="src" />
     <file name="phar.php" role="src" />
     <file name="pharcommand.inc" role="src" />
-    <file name="phar.phar" role="php" />
    </dir> <!-- /phar -->
    <dir name="tests">
     <file name="001.phpt" role="test" />
@@ -113,6 +104,7 @@
     <file name="create_new_phar_b.phpt" role="test" />
     <file name="create_new_phar_c.phpt" role="test" />
     <file name="create_path_error.phpt" role="test" />
+    <file name="delete.phpt" role="test" />
     <file name="delete_in_phar.phpt" role="test" />
     <file name="delete_in_phar_b.phpt" role="test" />
     <file name="delete_in_phar_confirm.phpt" role="test" />
@@ -120,6 +112,7 @@
     <file name="extracted_001.phpt" role="test" />
     <file name="ini_set.phpt" role="test" />
     <file name="ini_set_off.phpt" role="test" />
+    <file name="md5.phar" role="test" />
     <file name="metadata_read.phpt" role="test" />
     <file name="metadata_write.phpt" role="test" />
     <file name="metadata_write_commit.phpt" role="test" />
@@ -133,6 +126,11 @@
     <file name="phar_commitwrite.phpt" role="test" />
     <file name="phar_create_in_cwd.phpt" role="test" />
     <file name="phar_ctx_001.phpt" role="test" />
+    <file name="phar_dir_iterate.phpt" role="test" />
+    <file name="phar_get_supportedcomp1.phpt" role="test" />
+    <file name="phar_get_supportedcomp2.phpt" role="test" />
+    <file name="phar_get_supportedcomp3.phpt" role="test" />
+    <file name="phar_get_supportedcomp4.phpt" role="test" />
     <file name="phar_get_suppoted_signatures_001.phpt" role="test" />
     <file name="phar_get_suppoted_signatures_002.phpt" role="test" />
     <file name="phar_metadata_read.phpt" role="test" />
@@ -159,6 +157,8 @@
     <file name="phar_oo_compressed_001b.phpt" role="test" />
     <file name="phar_oo_compressed_002.phpt" role="test" />
     <file name="phar_oo_compressed_002b.phpt" role="test" />
+    <file name="phar_oo_getmodified.phpt" role="test" />
+    <file name="phar_oo_nosig.phpt" role="test" />
     <file name="phar_oo_test.inc" role="test" />
     <file name="phar_oo_uncompressall.phpt" role="test" />
     <file name="phar_setalias.phpt" role="test" />
@@ -171,7 +171,12 @@
     <file name="phar_stub_write_file.phpt" role="test" />
     <file name="phar_test.inc" role="test" />
     <file name="refcount1.phpt" role="test" />
+    <file name="refcount1_5_2.phpt" role="test" />
     <file name="rename.phpt" role="test" />
+    <file name="sha1.phar" role="test" />
+    <file name="sha256.phar" role="test" />
+    <file name="sha512.phar" role="test" />
+    <file name="test_signaturealgos.phpt" role="test" />
    </dir> <!-- /tests -->
    <file name="build_precommand.php" role="php" />
    <file name="config.m4" role="src" />
@@ -181,7 +186,7 @@
    <file name="LICENSE" role="doc" />
    <file name="Makefile.frag" role="src" />
    <file name="phar.c" role="src" />
-   <file name="phar.phar" role="data" />
+   <file name="phar.phar" role="script" />
    <file name="phar_internal.h" role="src" />
    <file name="phar_object.c" role="src" />
    <file name="phar_path_check.c" role="src" />
@@ -223,34 +228,50 @@
  <changelog>
   <release>
    <version>
-    <release>1.2.1</release>
+    <release>1.3.0</release>
     <api>1.1.0</api>
    </version>
    <stability>
     <release>stable</release>
     <api>stable</api>
    </stability>
-   <date>2007-08-24</date>
+   <date>2007-12-12</date>
    <license uri="http://www.php.net/license";>PHP License</license>
    <notes>
 
- * add Phar::setAlias() [Greg]
- * fix too many open file handles issue [Greg]
- * fix rename [Greg]
- * add Phar::getAlias() [Marcus]
- * Made -a optional in pack subcommand of phar.phar [Marcus]
- * Fix issue with apache module and extracted archives [Marcus]
- * Send all error messages to stderr in phar.phar [Marcus]
- * Added new subcommands add and delete to phar.phar [Marcus]
- * Made Phar::loadPhar() and Phar::mapPhar() ignore extracted archives [Marcus]
- * Fix issue with compressed entries and uncompressing entries [Marcus]
- * Verify stubs before writing [Marcus]
- * Always use longest stub end to avoid issues with length field [Marcus]
+ * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) 
[Greg]
+ * add mapping of include/require from within a phar to location within phar 
[Greg]
+   solves the include_path issue without code munging
+ * add Phar::delete() [Greg]
 
    </notes>
   </release>
   <release>
    <version>
+    <release>1.2.1</release>
+    <api>1.1.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2007-08-24</date>
+   <license uri="http://www.php.net/license";>PHP License</license>
+   <notes>* add Phar::setAlias() [Greg]
+* fix too many open file handles issue [Greg]
+* fix rename [Greg]
+* add Phar::getAlias() [Marcus]
+* Made -a optional in pack subcommand of phar.phar [Marcus]
+* Fix issue with apache module and extracted archives [Marcus]
+* Send all error messages to stderr in phar.phar [Marcus]
+* Added new subcommands add and delete to phar.phar [Marcus]
+* Made Phar::loadPhar() and Phar::mapPhar() ignore extracted archives [Marcus]
+* Fix issue with compressed entries and uncompressing entries [Marcus]
+* Verify stubs before writing [Marcus]
+* Always use longest stub end to avoid issues with length field 
[Marcus]</notes>
+  </release>
+  <release>
+   <version>
     <release>1.2.0</release>
     <api>1.1.0</api>
    </version>
http://cvs.php.net/viewvc.cgi/pecl/phar/phar.phar?r1=1.4&r2=1.5&diff_format=u
Index: pecl/phar/phar.phar
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.69&r2=1.70&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.69 pecl/phar/phar_object.c:1.70
--- pecl/phar/phar_object.c:1.69        Sun Nov 25 05:04:39 2007
+++ pecl/phar/phar_object.c     Wed Dec 12 18:01:39 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_object.c,v 1.69 2007/11/25 05:04:39 cellog Exp $ */
+/* $Id: phar_object.c,v 1.70 2007/12/12 18:01:39 cellog Exp $ */
 
 #include "phar_internal.h"
 
@@ -306,6 +306,156 @@
                return; \
        }
 
+/* {{{ proto Phar::buildFromIterator(Iterator iter[, string base_directory])
+ * Construct a phar archive from an iterator.  The iterator must return a 
series of strings
+ * that are full paths to files that should be added to the phar.  The 
iterator key should
+ * be the path that the file will have within the phar archive.
+ *
+ * If base directory is specified, then the key will be ignored, and instead 
the portion of
+ * the current value minus the base directory will be used
+ */
+PHP_METHOD(Phar, buildFromIterator)
+{
+       zend_object_iterator *iter = NULL;
+       zval *obj, **value;
+       char *str_key, *base, *error;
+       uint str_key_len, base_len = 0;
+       zend_uchar key_type;
+       ulong int_key;
+       zend_class_entry *ce;
+       PHAR_ARCHIVE_OBJECT();
+
+
+       if (PHAR_G(readonly)) {
+               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC,
+                       "Cannot write out phar archive, phar is read-only");
+               return;
+       }
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|s", &obj, 
zend_ce_traversable, &base, &base_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       ce = Z_OBJCE_P(obj);
+
+       iter = ce->get_iterator(ce, obj, 0 TSRMLS_CC);
+       if (iter && !EG(exception)) {
+               obj = zend_iterator_wrap(iter TSRMLS_CC);
+       } else {
+               if (!EG(exception)) {
+                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Object 
of type %s did not create an Iterator", ce->name);
+               }
+               return;
+       }
+
+       if (iter) {
+               iter->index = 0;
+               if (iter->funcs->rewind) {
+                       iter->funcs->rewind(iter TSRMLS_CC);
+               }
+               if (FAILURE == iter->funcs->valid(iter TSRMLS_CC)) {
+                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned no values", ce->name);
+                       return;
+               }
+               do {
+                       phar_entry_data *data;
+                       php_stream *fp;
+                       long contents_len;
+                       char *fname;
+                       iter->funcs->get_current_data(iter, &value TSRMLS_CC);
+                       if (EG(exception)) {
+                               break;
+                       }
+                       if (!value) {
+                               /* 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);
+                               break;
+                       }
+                       if (!base_len && 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)) {
+                                       break;
+                               }
+                               if (key_type == HASH_KEY_IS_LONG) {
+                                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid key (must return a string)", ce->name);
+                                       break;
+                               }
+                               if (str_key[str_key_len - 1] == '\0') 
str_key_len--;
+                       } else {
+                               
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid key (must return a string)", ce->name);
+                               break;
+                       }
+
+                       fname = Z_STRVAL_PP(value);
+                       if (base_len) {
+                               if (strstr(fname, base)) {
+                                       str_key_len = Z_STRLEN_PP(value) - 
base_len;
+                                       if (str_key_len <= 0) {
+                                               continue;
+                                       }
+                                       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);
+                                       break;
+                               }
+                       }
+#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);
+                               break;
+                       }
+#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);
+                               break;
+                       }
+
+                       /* try to open source file, then create internal phar 
file and copy contents */
+                       fp = php_stream_open_wrapper(fname, "rb", 
STREAM_MUST_SEEK|0, NULL);
+                       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);
+                               break;
+                       }
+
+                       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);
+                               break;
+                       } else {
+                               if (error) {
+                                       efree(error);
+                               }
+                               contents_len = php_stream_copy_to_stream(fp, 
data->fp, PHP_STREAM_COPY_ALL);
+                       }
+                       data->internal_file->compressed_filesize = 
data->internal_file->uncompressed_filesize = contents_len;
+                       phar_entry_delref(data TSRMLS_CC);
+                       /* This could cause an endless loop if index becomes 
zero again.
+                        * In case that ever happens we need an additional 
flag. */
+                       iter->funcs->move_forward(iter TSRMLS_CC);
+                       if (EG(exception)) {
+                               break;
+                       }
+                       if (iter->funcs->valid(iter TSRMLS_CC) == FAILURE) {
+                               /* reached end of iteration */
+                               break;
+                       }
+               } while (1);
+               if (!EG(exception)) {
+                       phar_flush(phar_obj->arc.archive, 0, 0, &error 
TSRMLS_CC);
+                       if (error) {
+                               zend_throw_exception_ex(phar_ce_PharException, 
0 TSRMLS_CC, error);
+                               efree(error);
+                       }
+               }
+       }
+
+}
+/* }}} */
+
 /* {{{ proto int Phar::count()
  * Returns the number of entries in the Phar archive
  */
@@ -1603,6 +1753,12 @@
        ZEND_ARG_INFO(0, entry)
        ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO();
+
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_build, 0, 0, 1)
+       ZEND_ARG_INFO(0, iterator)
+       ZEND_ARG_INFO(0, base_directory)
+ZEND_END_ARG_INFO();
 #endif
 
 static
@@ -1639,6 +1795,7 @@
        PHP_ME(Phar, offsetSet,             arginfo_phar_offsetSet,    
ZEND_ACC_PUBLIC)
        PHP_ME(Phar, offsetUnset,           arginfo_phar_offsetExists, 
ZEND_ACC_PUBLIC)
        PHP_ME(Phar, uncompressAllFiles,    NULL,                      
ZEND_ACC_PUBLIC)
+       PHP_ME(Phar, buildFromIterator,     arginfo_phar_build,        
ZEND_ACC_PUBLIC)
 #endif
        /* static member functions */
        PHP_ME(Phar, apiVersion,            NULL,                      
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)

Reply via email to