diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h index 231d8402d89e1..6f1035a577316 100644 --- a/ext/dom/dom_fe.h +++ b/ext/dom/dom_fe.h @@ -172,6 +172,7 @@ PHP_METHOD(domnode, getLineNo); /* domnodelist methods */ PHP_FUNCTION(dom_nodelist_item); +PHP_FUNCTION(dom_nodelist_count); /* domnamednodemap methods */ PHP_FUNCTION(dom_namednodemap_get_named_item); @@ -181,6 +182,7 @@ PHP_FUNCTION(dom_namednodemap_item); PHP_FUNCTION(dom_namednodemap_get_named_item_ns); PHP_FUNCTION(dom_namednodemap_set_named_item_ns); PHP_FUNCTION(dom_namednodemap_remove_named_item_ns); +PHP_FUNCTION(dom_namednodemap_count); /* domcharacterdata methods */ PHP_FUNCTION(dom_characterdata_substring_data); diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c index 4dea7be28a91b..cfae5a920ecb9 100644 --- a/ext/dom/namednodemap.c +++ b/ext/dom/namednodemap.c @@ -57,6 +57,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0) ZEND_ARG_INFO(0, namespaceURI) ZEND_ARG_INFO(0, localName) ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_count, 0, 0, 0) +ZEND_END_ARG_INFO(); /* }}} */ /* @@ -74,6 +77,7 @@ const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */ PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns) PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns) PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns) + PHP_FALIAS(count, dom_namednodemap_count, arginfo_dom_namednodemap_count) PHP_FE_END }; /* }}} */ @@ -332,6 +336,27 @@ PHP_FUNCTION(dom_namednodemap_remove_named_item_ns) } /* }}} end dom_namednodemap_remove_named_item_ns */ +/* {{{ proto int|bool dom_namednodemap_count(); +*/ +PHP_FUNCTION(dom_namednodemap_count) +{ + zval *id; + dom_object *intern; + zval *count; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_namednodemap_class_entry) == FAILURE) { + return; + } + + intern = Z_DOMOBJ_P(id); + if(dom_namednodemap_length_read(intern, &count)) { + RETURN_FALSE; + } + + RETURN_LONG(count); +} +/* }}} end dom_namednodemap_count */ + #endif /* diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index d469467f48a95..86e5d2f082d3c 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -34,6 +34,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1) ZEND_END_ARG_INFO(); /* }}} */ +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_count, 0, 0, 0) +ZEND_END_ARG_INFO(); +/* }}} */ + /* * class DOMNodeList * @@ -43,9 +48,11 @@ ZEND_END_ARG_INFO(); const zend_function_entry php_dom_nodelist_class_functions[] = { PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item) + PHP_FALIAS(count, dom_nodelist_count, arginfo_dom_nodelist_count) PHP_FE_END }; + /* {{{ length int readonly=yes URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337 @@ -96,6 +103,27 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval) return SUCCESS; } + +/* {{{ proto int|bool dom_nodelist_count(); +*/ +PHP_FUNCTION(dom_nodelist_count) +{ + zval *id; + dom_object *intern; + zval *count; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) { + return; + } + + intern = Z_DOMOBJ_P(id); + if(dom_nodelist_length_read(intern, &count)) { + RETURN_FALSE; + } + RETURN_LONG(count); +} +/* }}} end dom_nodelist_count */ + /* }}} */ /* {{{ proto DOMNode dom_nodelist_item(int index); @@ -170,6 +198,7 @@ PHP_FUNCTION(dom_nodelist_item) } /* }}} end dom_nodelist_item */ + #endif /* diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6b844ab33304d..0b0f48080419c 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -707,6 +707,7 @@ PHP_MINIT_FUNCTION(dom) dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_nodelist_class_entry->get_iterator = php_dom_get_iterator; zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable); + zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_countable); zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", sizeof("length")-1, dom_nodelist_length_read, NULL); @@ -717,6 +718,7 @@ PHP_MINIT_FUNCTION(dom) dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator; zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable); + zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_countable); zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL); diff --git a/ext/dom/tests/DOMNamedNodeMap_count.phpt b/ext/dom/tests/DOMNamedNodeMap_count.phpt new file mode 100644 index 0000000000000..656dd4859efc9 --- /dev/null +++ b/ext/dom/tests/DOMNamedNodeMap_count.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test count nodes in DOMNamedNodeMap +--CREDITS-- +Andreas Treichel +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); +for($i = 0; $i < 5; $i++) { + $root->setAttribute('attribute-' . $i, 'value-' . $i); +} +for($i = 0; $i < 7; $i++) { + $item = $document->createElement('item'); + $root->appendChild($item); +} +var_dump($root->attributes->length); +var_dump($root->attributes->count()); +var_dump(count($root->attributes)); + +?> +--EXPECTF-- +int(5) +int(5) +int(5) diff --git a/ext/dom/tests/DomNodeList_count.phpt b/ext/dom/tests/DomNodeList_count.phpt new file mode 100644 index 0000000000000..3ebf4ae7d2ea1 --- /dev/null +++ b/ext/dom/tests/DomNodeList_count.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test count nodes in DOMNodeList +--CREDITS-- +Andreas Treichel +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); +for($i = 0; $i < 5; $i++) { + $root->setAttribute('attribute-' . $i, 'value-' . $i); +} +for($i = 0; $i < 7; $i++) { + $item = $document->createElement('item'); + $root->appendChild($item); +} +var_dump($root->childNodes->length); +var_dump($root->childNodes->count()); +var_dump(count($root->childNodes)); + +?> +--EXPECTF-- +int(7) +int(7) +int(7) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 499a8b40b2079..6b2941fe9ab0f 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1056,6 +1056,75 @@ ftp_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *inst } /* }}} */ + +/* {{{ ftp_append + */ +int +ftp_append(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *instream, ftptype_t type) +{ + databuf_t *data = NULL; + zend_long size; + char *ptr; + int ch; + char arg[11]; + + if (ftp == NULL) { + return 0; + } + if (!ftp_type(ftp, type)) { + goto bail; + } + if ((data = ftp_getdata(ftp)) == NULL) { + goto bail; + } + ftp->data = data; + + if (!ftp_putcmd(ftp, "APPE", sizeof("APPE")-1, path, path_len)) { + goto bail; + } + if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { + goto bail; + } + if ((data = data_accept(data, ftp)) == NULL) { + goto bail; + } + + size = 0; + ptr = data->buf; + while (!php_stream_eof(instream) && (ch = php_stream_getc(instream))!=EOF) { + /* flush if necessary */ + if (FTP_BUFSIZE - size < 2) { + if (my_send(ftp, data->fd, data->buf, size) != size) { + goto bail; + } + ptr = data->buf; + size = 0; + } + + if (ch == '\n' && type == FTPTYPE_ASCII) { + *ptr++ = '\r'; + size++; + } + + *ptr++ = ch; + size++; + } + + if (size && my_send(ftp, data->fd, data->buf, size) != size) { + goto bail; + } + ftp->data = data = data_close(ftp, data); + + if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250 && ftp->resp != 200)) { + goto bail; + } + return 1; +bail: + ftp->data = data_close(ftp, data); + return 0; +} +/* }}} */ + /* {{{ ftp_size */ zend_long diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h index d1576f0a8aac9..38e34acfe2e24 100644 --- a/ext/ftp/ftp.h +++ b/ext/ftp/ftp.h @@ -190,6 +190,11 @@ int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const size_ */ int ftp_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *instream, ftptype_t type, zend_long startpos); +/* append the data from a file, socket, or process as a file on the remote server + * returns true on success, false on error + */ +int ftp_append(ftpbuf_t *ftp, const char *path, const size_t path_len, php_stream *instream, ftptype_t type); + /* returns the size of the given file, or -1 on error */ zend_long ftp_size(ftpbuf_t *ftp, const char *path, const size_t path_len); diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index bad56900393c9..94cf59b77d3cd 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -191,6 +191,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_put, 0, 0, 4) ZEND_ARG_INFO(0, startpos) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_append, 0, 0, 3) + ZEND_ARG_INFO(0, ftp) + ZEND_ARG_INFO(0, remote_file) + ZEND_ARG_INFO(0, local_file) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_ftp_nb_put, 0, 0, 4) ZEND_ARG_INFO(0, ftp) ZEND_ARG_INFO(0, remote_file) @@ -265,6 +272,7 @@ const zend_function_entry php_ftp_functions[] = { PHP_FE(ftp_get, arginfo_ftp_get) PHP_FE(ftp_fget, arginfo_ftp_fget) PHP_FE(ftp_put, arginfo_ftp_put) + PHP_FE(ftp_append, arginfo_ftp_append) PHP_FE(ftp_fput, arginfo_ftp_fput) PHP_FE(ftp_size, arginfo_ftp_size) PHP_FE(ftp_mdtm, arginfo_ftp_mdtm) @@ -1272,6 +1280,41 @@ PHP_FUNCTION(ftp_put) } /* }}} */ +/* {{{ proto bool ftp_append(resource stream, string remote_file, string local_file, int mode) + Append content of a file a another file on the FTP server */ +PHP_FUNCTION(ftp_append) +{ + zval *z_ftp; + ftpbuf_t *ftp; + ftptype_t xtype; + char *remote, *local; + size_t remote_len, local_len; + zend_long mode; + php_stream *instream; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rppl", &z_ftp, &remote, &remote_len, &local, &local_len, &mode) == FAILURE) { + return; + } + + if ((ftp = (ftpbuf_t *)zend_fetch_resource(Z_RES_P(z_ftp), le_ftpbuf_name, le_ftpbuf)) == NULL) { + RETURN_FALSE; + } + XTYPE(xtype, mode); + + if (!(instream = php_stream_open_wrapper(local, mode == FTPTYPE_ASCII ? "rt" : "rb", REPORT_ERRORS, NULL))) { + RETURN_FALSE; + } + + if (!ftp_append(ftp, remote, remote_len, instream, xtype)) { + php_stream_close(instream); + php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf); + RETURN_FALSE; + } + php_stream_close(instream); + + RETURN_TRUE; +} +/* }}} */ /* {{{ proto int ftp_nb_put(resource stream, string remote_file, string local_file, int mode[, int startpos]) Stores a file on the FTP server */ diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h index 37b75f6b9b2a3..3927738306f0a 100644 --- a/ext/ftp/php_ftp.h +++ b/ext/ftp/php_ftp.h @@ -60,6 +60,7 @@ PHP_FUNCTION(ftp_pasv); PHP_FUNCTION(ftp_get); PHP_FUNCTION(ftp_fget); PHP_FUNCTION(ftp_put); +PHP_FUNCTION(ftp_append); PHP_FUNCTION(ftp_fput); PHP_FUNCTION(ftp_size); PHP_FUNCTION(ftp_mdtm); diff --git a/ext/ftp/tests/ftp_append.phpt b/ext/ftp/tests/ftp_append.phpt new file mode 100644 index 0000000000000..5f52ac923c0e5 --- /dev/null +++ b/ext/ftp/tests/ftp_append.phpt @@ -0,0 +1,32 @@ +--TEST-- +ftp_append() create new file and append something +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) +bool(true) +bool(true) +string(6) "foobar" diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 5f003cc04d00e..a1bf074f90c05 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -267,7 +267,28 @@ if ($pid) { } } - } elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) { + } elseif (preg_match("~^APPE ([\w/.-]+)\r\n$~", $buf, $m)) { + fputs($s, "150 File status okay; about to open data connection\r\n"); + + if(empty($pasv)) + { + if (!$fs = stream_socket_client("tcp://$host:$port")) { + fputs($s, "425 Can't open data connection\r\n"); + continue; + } + + $data = stream_get_contents($fs); + file_put_contents(__DIR__.'/'.$m[1], $data, FILE_APPEND); + fputs($s, "226 Closing data Connection.\r\n"); + fclose($fs); + }else{ + $data = stream_get_contents($fs); + file_put_contents(__DIR__.'/'.$m[1], $data, FILE_APPEND); + fputs($s, "226 Closing data Connection.\r\n"); + fclose($fs); + } + + }elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) { change_dir($m[1]); fputs($s, "250 CWD command successful.\r\n");