Skip to content

Commit 275ae3c

Browse files
committed
Add Dom\DocumentFragment::getElementById()
1 parent 7455f6a commit 275ae3c

File tree

6 files changed

+52
-18
lines changed

6 files changed

+52
-18
lines changed

ext/dom/document.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ PHP_METHOD(DOMDocument, getElementById)
10321032
char *idname;
10331033

10341034
ZEND_PARSE_PARAMETERS_START(1, 1)
1035-
Z_PARAM_STRING(idname, idname_len)
1035+
Z_PARAM_PATH(idname, idname_len)
10361036
ZEND_PARSE_PARAMETERS_END();
10371037

10381038
DOM_GET_OBJ(docp, ZEND_THIS, xmlDocPtr, intern);
@@ -1051,20 +1051,10 @@ PHP_METHOD(DOMDocument, getElementById)
10511051
* the element the ID is actually removed by libxml2. Since libxml2 has such behaviour deeply
10521052
* ingrained in the library, and uses the cache for various purposes, it seems like a bad
10531053
* idea and lost cause to fight it. */
1054-
10551054
const xmlNode *base = (const xmlNode *) docp;
1056-
const xmlNode *node = base->children;
1057-
while (node != NULL) {
1058-
if (node->type == XML_ELEMENT_NODE) {
1059-
for (const xmlAttr *attr = node->properties; attr != NULL; attr = attr->next) {
1060-
if (attr->atype == XML_ATTRIBUTE_ID && dom_compare_value(attr, BAD_CAST idname)) {
1061-
DOM_RET_OBJ((xmlNodePtr) node, intern);
1062-
return;
1063-
}
1064-
}
1065-
}
1066-
1067-
node = php_dom_next_in_tree_order(node, base);
1055+
xmlNodePtr node = dom_scan_id(base, BAD_CAST idname);
1056+
if (node) {
1057+
DOM_RET_OBJ(node, intern);
10681058
}
10691059
}
10701060
}

ext/dom/documentfragment.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,23 @@ PHP_METHOD(DOMDocumentFragment, appendXML) {
9393
}
9494
/* }}} */
9595

96+
PHP_METHOD(Dom_DocumentFragment, getElementById)
97+
{
98+
xmlNodePtr base;
99+
size_t idname_len;
100+
dom_object *intern;
101+
char *idname;
102+
103+
ZEND_PARSE_PARAMETERS_START(1, 1)
104+
Z_PARAM_PATH(idname, idname_len)
105+
ZEND_PARSE_PARAMETERS_END();
106+
107+
DOM_GET_OBJ(base, ZEND_THIS, xmlNodePtr, intern);
108+
109+
xmlNodePtr node = dom_scan_id(base, BAD_CAST idname);
110+
if (node) {
111+
DOM_RET_OBJ(node, intern);
112+
}
113+
}
114+
96115
#endif

ext/dom/php_dom.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,4 +2720,22 @@ xmlDocPtr php_dom_create_html_doc(void)
27202720
return lxml_doc;
27212721
}
27222722

2723+
xmlNodePtr dom_scan_id(const xmlNode *base, const xmlChar *idname)
2724+
{
2725+
xmlNodePtr node = base->children;
2726+
while (node != NULL) {
2727+
if (node->type == XML_ELEMENT_NODE) {
2728+
for (const xmlAttr *attr = node->properties; attr != NULL; attr = attr->next) {
2729+
if (attr->atype == XML_ATTRIBUTE_ID && dom_compare_value(attr, BAD_CAST idname)) {
2730+
return node;
2731+
}
2732+
}
2733+
}
2734+
2735+
node = php_dom_next_in_tree_order(node, base);
2736+
}
2737+
2738+
return NULL;
2739+
}
2740+
27232741
#endif /* HAVE_DOM */

ext/dom/php_dom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ bool php_dom_create_nullable_object(xmlNodePtr obj, zval *return_value, dom_obje
158158
xmlNodePtr dom_clone_node(php_dom_libxml_ns_mapper *ns_mapper, xmlNodePtr node, xmlDocPtr doc, bool recursive);
159159
void dom_set_document_ref_pointers(xmlNodePtr node, php_libxml_ref_obj *document);
160160
void dom_set_document_ref_pointers_attr(xmlAttrPtr attr, php_libxml_ref_obj *document);
161+
xmlNodePtr dom_scan_id(const xmlNode *base, const xmlChar *idname);
161162

162163
/* Prop getters by offset */
163164
zval *dom_get_prop_checked_offset(dom_object *obj, uint32_t offset, const char *name);

ext/dom/php_dom.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,8 @@ public function replaceChildren(Node|string ...$nodes): void {}
18991899
public function querySelector(string $selectors): ?Element {}
19001900
/** @implementation-alias Dom\Element::querySelectorAll */
19011901
public function querySelectorAll(string $selectors): NodeList {}
1902+
1903+
public function getElementById(string $elementId): ?Element {}
19021904
}
19031905

19041906
class Entity extends Node

ext/dom/php_dom_arginfo.h

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)