xref: /PHP-8.3/ext/dom/attr.c (revision 08c4db7f)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Christian Stocker <chregu@php.net>                          |
14    |          Rob Richards <rrichards@php.net>                            |
15    +----------------------------------------------------------------------+
16 */
17 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "php.h"
23 
24 #if defined(HAVE_LIBXML) && defined(HAVE_DOM)
25 
26 #include "php_dom.h"
27 
28 /*
29 * class DOMAttr extends DOMNode
30 *
31 * URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-637646024
32 * Since:
33 */
34 
35 /* {{{ */
PHP_METHOD(DOMAttr,__construct)36 PHP_METHOD(DOMAttr, __construct)
37 {
38 	xmlAttrPtr nodep = NULL;
39 	xmlNodePtr oldnode = NULL;
40 	dom_object *intern;
41 	char *name, *value = NULL;
42 	size_t name_len, value_len, name_valid;
43 
44 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &name, &name_len, &value, &value_len) == FAILURE) {
45 		RETURN_THROWS();
46 	}
47 
48 	intern = Z_DOMOBJ_P(ZEND_THIS);
49 
50 	name_valid = xmlValidateName((xmlChar *) name, 0);
51 	if (name_valid != 0) {
52 		php_dom_throw_error(INVALID_CHARACTER_ERR, 1);
53 		RETURN_THROWS();
54 	}
55 
56 	nodep = xmlNewProp(NULL, (xmlChar *) name, (xmlChar *) value);
57 
58 	if (!nodep) {
59 		php_dom_throw_error(INVALID_STATE_ERR, 1);
60 		RETURN_THROWS();
61 	}
62 
63 	oldnode = dom_object_get_node(intern);
64 	if (oldnode != NULL) {
65 		php_libxml_node_decrement_resource((php_libxml_node_object *)intern);
66 	}
67 	php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern);
68 }
69 
70 /* }}} end DOMAttr::__construct */
71 
72 /* {{{ name	string
73 readonly=yes
74 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1112119403
75 Since:
76 */
dom_attr_name_read(dom_object * obj,zval * retval)77 int dom_attr_name_read(dom_object *obj, zval *retval)
78 {
79 	xmlAttrPtr attrp;
80 
81 	attrp = (xmlAttrPtr) dom_object_get_node(obj);
82 
83 	if (attrp == NULL) {
84 		php_dom_throw_error(INVALID_STATE_ERR, 1);
85 		return FAILURE;
86 	}
87 
88 	ZVAL_STRING(retval, (char *) attrp->name);
89 
90 	return SUCCESS;
91 }
92 
93 /* }}} */
94 
95 /* {{{ specified	boolean
96 readonly=yes
97 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-862529273
98 Since:
99 */
dom_attr_specified_read(dom_object * obj,zval * retval)100 int dom_attr_specified_read(dom_object *obj, zval *retval)
101 {
102 	/* TODO */
103 	ZVAL_TRUE(retval);
104 	return SUCCESS;
105 }
106 
107 /* }}} */
108 
109 /* {{{ value	string
110 readonly=no
111 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-221662474
112 Since:
113 */
dom_attr_value_read(dom_object * obj,zval * retval)114 int dom_attr_value_read(dom_object *obj, zval *retval)
115 {
116 	xmlAttrPtr attrp = (xmlAttrPtr) dom_object_get_node(obj);
117 	xmlChar *content;
118 
119 	if (attrp == NULL) {
120 		php_dom_throw_error(INVALID_STATE_ERR, 1);
121 		return FAILURE;
122 	}
123 
124 	/* Can't avoid a content copy because it's an attribute node */
125 	if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) {
126 		ZVAL_STRING(retval, (char *) content);
127 		xmlFree(content);
128 	} else {
129 		ZVAL_EMPTY_STRING(retval);
130 	}
131 
132 	return SUCCESS;
133 
134 }
135 
dom_attr_value_write(dom_object * obj,zval * newval)136 int dom_attr_value_write(dom_object *obj, zval *newval)
137 {
138 	xmlAttrPtr attrp = (xmlAttrPtr) dom_object_get_node(obj);
139 
140 	if (attrp == NULL) {
141 		php_dom_throw_error(INVALID_STATE_ERR, 1);
142 		return FAILURE;
143 	}
144 
145 	/* Typed property, this is already a string */
146 	ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING);
147 	zend_string *str = Z_STR_P(newval);
148 
149 	dom_remove_all_children((xmlNodePtr) attrp);
150 	xmlNodeSetContentLen((xmlNodePtr) attrp, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str));
151 
152 	return SUCCESS;
153 }
154 
155 /* }}} */
156 
157 /* {{{ ownerElement	DOMElement
158 readonly=yes
159 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-ownerElement
160 Since: DOM Level 2
161 */
dom_attr_owner_element_read(dom_object * obj,zval * retval)162 int dom_attr_owner_element_read(dom_object *obj, zval *retval)
163 {
164 	xmlNodePtr nodep, nodeparent;
165 
166 	nodep = dom_object_get_node(obj);
167 
168 	if (nodep == NULL) {
169 		php_dom_throw_error(INVALID_STATE_ERR, 1);
170 		return FAILURE;
171 	}
172 
173 	nodeparent = nodep->parent;
174 	if (!nodeparent) {
175 		ZVAL_NULL(retval);
176 		return SUCCESS;
177 	}
178 
179 	php_dom_create_object(nodeparent, retval, obj);
180 	return SUCCESS;
181 
182 }
183 
184 /* }}} */
185 
186 /* {{{ schemaTypeInfo	DOMTypeInfo
187 readonly=yes
188 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-schemaTypeInfo
189 Since: DOM Level 3
190 */
dom_attr_schema_type_info_read(dom_object * obj,zval * retval)191 int dom_attr_schema_type_info_read(dom_object *obj, zval *retval)
192 {
193 	/* TODO */
194 	ZVAL_NULL(retval);
195 	return SUCCESS;
196 }
197 
198 /* }}} */
199 
200 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId
201 Since: DOM Level 3
202 */
PHP_METHOD(DOMAttr,isId)203 PHP_METHOD(DOMAttr, isId)
204 {
205 	zval *id;
206 	dom_object *intern;
207 	xmlAttrPtr attrp;
208 
209 	id = ZEND_THIS;
210 	if (zend_parse_parameters_none() == FAILURE) {
211 		RETURN_THROWS();
212 	}
213 
214 	DOM_GET_OBJ(attrp, id, xmlAttrPtr, intern);
215 
216 	if (attrp->atype == XML_ATTRIBUTE_ID) {
217 		RETURN_TRUE;
218 	} else {
219 		RETURN_FALSE;
220 	}
221 }
222 /* }}} end dom_attr_is_id */
223 
224 #endif
225