/* nodelist properties */
int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+xmlNodePtr dom_nodelist_xml_item(dom_nnodemap_object *objmap, long index);
+xmlNodePtr dom_nodelist_baseobj_item(dom_nnodemap_object *objmap, long index);
/* notation properties */
int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC);
/* }}} */
+xmlNodePtr dom_nodelist_xml_item(dom_nnodemap_object *objmap, long index) /* {{{ */
+{
+ xmlNodePtr itemnode = NULL;
+
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+ } else {
+ itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+ }
+
+ return itemnode;
+} /* }}} end dom_nodelist_xml_item */
+
+xmlNodePtr dom_nodelist_baseobj_item(dom_nnodemap_object *objmap, long index) /* {{{ */
+{
+ xmlNodePtr itemnode = NULL;
+ xmlNodePtr nodep, curnode;
+ int count = 0;
+
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+ curnode = nodep->children;
+ while (count < index && curnode != NULL) {
+ count++;
+ curnode = curnode->next;
+ }
+ itemnode = curnode;
+ } else {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+ } else {
+ nodep = nodep->children;
+ }
+ itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, (char *) objmap->ns, (char *) objmap->local, &count, index);
+ }
+ }
+
+ return itemnode;
+} /* }}} end dom_nodelist_baseobj_item */
+
/* {{{ proto DOMNode dom_nodelist_item(int index);
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
Since:
xmlNodePtr itemnode = NULL;
dom_nnodemap_object *objmap;
- xmlNodePtr nodep, curnode;
- int count = 0;
HashTable *nodeht;
zval **entry;
objmap = (dom_nnodemap_object *)intern->ptr;
if (objmap != NULL) {
if (objmap->ht) {
- if (objmap->nodetype == XML_ENTITY_NODE) {
- itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
- } else {
- itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
- }
+ itemnode = dom_nodelist_xml_item(objmap, index);
} else {
if (objmap->nodetype == DOM_NODESET) {
nodeht = HASH_OF(objmap->baseobjptr);
if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
- *return_value = **entry;
- zval_copy_ctor(return_value);
+ MAKE_COPY_ZVAL(entry, return_value);
return;
}
} else if (objmap->baseobj) {
- nodep = dom_object_get_node(objmap->baseobj);
- if (nodep) {
- if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
- curnode = nodep->children;
- while (count < index && curnode != NULL) {
- count++;
- curnode = curnode->next;
- }
- itemnode = curnode;
- } else {
- if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
- nodep = xmlDocGetRootElement((xmlDoc *) nodep);
- } else {
- nodep = nodep->children;
- }
- itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
- }
- }
+ itemnode = dom_nodelist_baseobj_item(objmap, index);
}
}
}
/* }}} */
zend_object_handlers dom_object_handlers;
+zend_object_handlers dom_nnodemap_object_handlers;
static HashTable classes;
/* {{{ prop handler tables */
dom_object_handlers.has_property = dom_property_exists;
dom_object_handlers.get_debug_info = dom_get_debug_info;
+ memcpy(&dom_nnodemap_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
+ dom_nnodemap_object_handlers.read_dimension = dom_nodelist_read_dimension;
+ dom_nnodemap_object_handlers.has_dimension = dom_nodelist_has_dimension;
+
zend_hash_init(&classes, 0, NULL, NULL, 1);
INIT_CLASS_ENTRY(ce, "DOMException", php_dom_domexception_class_functions);
retval.handle = zend_objects_store_put(intern, dom_nnodemap_object_dtor, (zend_objects_free_object_storage_t)dom_nnodemap_objects_free_storage, dom_objects_clone TSRMLS_CC);
intern->handle = retval.handle;
- retval.handlers = dom_get_obj_handlers(TSRMLS_C);
+ retval.handlers = &dom_nnodemap_object_handlers;
return retval;
}
}
/* }}} end dom_get_nsdecl */
+static int dom_nodelist_fetch_dimension(xmlNodePtr *itemnode, zval *offset, dom_nnodemap_object *objmap, zval *rv TSRMLS_DC) /* {{{ */
+{
+ convert_to_long(offset);
+ long index = Z_LVAL_P(offset);
+ HashTable *nodeht;
+ zval **entry;
+ int ret = 0;
+
+ if (objmap->ht) {
+ *itemnode = dom_nodelist_xml_item(objmap, index);
+ } else {
+ if (objmap->nodetype == DOM_NODESET) {
+ nodeht = HASH_OF(objmap->baseobjptr);
+ if (zend_hash_index_find(nodeht, index, (void **) &entry) == SUCCESS) {
+ if (itemnode != NULL && rv != NULL) {
+ /* Passed by read_dimension */
+ MAKE_COPY_ZVAL(entry, rv);
+ }
+ ret = 1;
+ }
+ } else if (objmap->baseobj) {
+ if (itemnode == NULL && rv == NULL) {
+ /* Passed by has_dimension */
+ if (dom_nodelist_baseobj_item(objmap, index)) {
+ ret = 1;
+ }
+ } else {
+ *itemnode = dom_nodelist_baseobj_item(objmap, index);
+ }
+ }
+ }
+
+ if (rv != NULL && itemnode != NULL) {
+ if (*itemnode) {
+ ret = 1;
+ }
+ }
+
+ return ret;
+} /* }}} end dom_nodelist_fetch_dimension */
+
+zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */
+{
+ dom_object *intern;
+ xmlNodePtr itemnode = NULL;
+ dom_nnodemap_object *objmap;
+ zval *rv;
+ int found;
+
+ ALLOC_INIT_ZVAL(rv);
+
+ intern = (dom_object *) zend_object_store_get_object(object TSRMLS_CC);
+
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ if (dom_nodelist_fetch_dimension(&itemnode, offset, objmap, rv TSRMLS_CC)) {
+ if (itemnode) {
+ php_dom_create_object(itemnode, &found, rv, objmap->baseobj TSRMLS_CC);
+ }
+ }
+
+ Z_DELREF_P(rv);
+
+ return rv;
+} /* }}} end dom_nodelist_read_dimension */
+
+int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC)
+{
+ dom_object *intern;
+ dom_nnodemap_object *objmap;
+
+ intern = (dom_object *) zend_object_store_get_object(object TSRMLS_CC);
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ return dom_nodelist_fetch_dimension(NULL, member, objmap, NULL TSRMLS_CC);
+} /* }}} end dom_nodelist_has_dimension */
+
#endif /* HAVE_DOM */
/*
xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index);
zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC);
+zval *dom_nodelist_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
+int dom_nodelist_has_dimension(zval *object, zval *member, int check_empty TSRMLS_DC);
+static int dom_nodelist_fetch_dimension(xmlNodePtr *itemnode, zval *offset, dom_nnodemap_object *objmap, zval *rv TSRMLS_DC);
#define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
INIT_CLASS_ENTRY(ce, name, funcs); \
--- /dev/null
+--TEST--
+Bug #67949: DOMNodeList elements should be accessible through array notation
+--FILE--
+<?php
+
+$html = <<<HTML
+<div>data</div>
+HTML;
+$doc = new DOMDocument;
+$doc->loadHTML($html);
+var_dump($doc->getElementsByTagName('div')[0]->textContent);
+var_dump($doc->getElementsByTagName('div')['test']->textContent); // testing that weak casting works
+var_dump(isset($doc->getElementsByTagName('div')[0]));
+var_dump(isset($doc->getElementsByTagName('div')[1]));
+
+--EXPECT--
+string(4) "data"
+string(4) "data"
+bool(true)
+bool(false)