Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions ext/dom/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ PHP_METHOD(DOMDocument, getElementById)
char *idname;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STRING(idname, idname_len)
Z_PARAM_PATH(idname, idname_len)
ZEND_PARSE_PARAMETERS_END();

DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
Expand All @@ -1051,20 +1051,10 @@ PHP_METHOD(DOMDocument, getElementById)
* the element the ID is actually removed by libxml2. Since libxml2 has such behaviour deeply
* ingrained in the library, and uses the cache for various purposes, it seems like a bad
* idea and lost cause to fight it. */

const xmlNode *base = (const xmlNode *) docp;
const xmlNode *node = base->children;
while (node != NULL) {
if (node->type == XML_ELEMENT_NODE) {
for (const xmlAttr *attr = node->properties; attr != NULL; attr = attr->next) {
if (attr->atype == XML_ATTRIBUTE_ID && dom_compare_value(attr, BAD_CAST idname)) {
DOM_RET_OBJ((xmlNodePtr) node, intern);
return;
}
}
}

node = php_dom_next_in_tree_order(node, base);
xmlNodePtr node = dom_scan_id(base, BAD_CAST idname);
if (node) {
DOM_RET_OBJ(node, intern);
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions ext/dom/documentfragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,23 @@ PHP_METHOD(DOMDocumentFragment, appendXML) {
}
/* }}} */

PHP_METHOD(Dom_DocumentFragment, getElementById)
{
xmlNodePtr base;
size_t idname_len;
dom_object *intern;
char *idname;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(idname, idname_len)
ZEND_PARSE_PARAMETERS_END();

DOM_GET_OBJ(base, ZEND_THIS, xmlNodePtr, intern);

xmlNodePtr node = dom_scan_id(base, BAD_CAST idname);
if (node) {
DOM_RET_OBJ(node, intern);
}
}

#endif
18 changes: 18 additions & 0 deletions ext/dom/php_dom.c
Original file line number Diff line number Diff line change
Expand Up @@ -2720,4 +2720,22 @@ xmlDocPtr php_dom_create_html_doc(void)
return lxml_doc;
}

xmlNodePtr dom_scan_id(const xmlNode *base, const xmlChar *idname)
{
xmlNodePtr node = base->children;
while (node != NULL) {
if (node->type == XML_ELEMENT_NODE) {
for (const xmlAttr *attr = node->properties; attr != NULL; attr = attr->next) {
if (attr->atype == XML_ATTRIBUTE_ID && dom_compare_value(attr, BAD_CAST idname)) {
return node;
}
}
}

node = php_dom_next_in_tree_order(node, base);
}

return NULL;
}

#endif /* HAVE_DOM */
1 change: 1 addition & 0 deletions ext/dom/php_dom.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ bool php_dom_create_nullable_object(xmlNodePtr obj, zval *return_value, dom_obje
xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive);
void dom_set_document_ref_pointers(xmlNodePtr node, php_libxml_ref_obj *document);
void dom_set_document_ref_pointers_attr(xmlAttrPtr attr, php_libxml_ref_obj *document);
xmlNodePtr dom_scan_id(const xmlNode *base, const xmlChar *idname);

/* Prop getters by offset */
zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name);
Expand Down
2 changes: 2 additions & 0 deletions ext/dom/php_dom.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,8 @@ public function replaceChildren(Node|string ...$nodes): void {}
public function querySelector(string $selectors): ?Element {}
/** @implementation-alias Dom\Element::querySelectorAll */
public function querySelectorAll(string $selectors): NodeList {}

public function getElementById(string $elementId): ?Element {}
}

class Entity extends Node
Expand Down
12 changes: 8 additions & 4 deletions ext/dom/php_dom_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading