1/*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2014 The PHP Group                                |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Authors: Christian Stocker <chregu@php.net>                          |
16   |          Rob Richards <rrichards@php.net>                            |
17   +----------------------------------------------------------------------+
18*/
19
20/* $Id$ */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include "php.h"
27
28#if HAVE_LIBXML && HAVE_DOM
29
30#include "php_dom.h"
31
32/* {{{ arginfo */
33ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_is_id, 0, 0, 0)
34ZEND_END_ARG_INFO();
35
36ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_construct, 0, 0, 1)
37    ZEND_ARG_INFO(0, name)
38    ZEND_ARG_INFO(0, value)
39ZEND_END_ARG_INFO();
40/* }}} */
41
42/*
43* class DOMAttr extends DOMNode
44*
45* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-637646024
46* Since:
47*/
48
49const zend_function_entry php_dom_attr_class_functions[] = {
50    PHP_FALIAS(isId, dom_attr_is_id, arginfo_dom_attr_is_id)
51    PHP_ME(domattr, __construct, arginfo_dom_attr_construct, ZEND_ACC_PUBLIC)
52    PHP_FE_END
53};
54
55/* {{{ proto void DOMAttr::__construct(string name, [string value]); */
56PHP_METHOD(domattr, __construct)
57{
58
59    zval *id;
60    xmlAttrPtr nodep = NULL;
61    xmlNodePtr oldnode = NULL;
62    dom_object *intern;
63    char *name, *value = NULL;
64    int name_len, value_len, name_valid;
65    zend_error_handling error_handling;
66
67    zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
68    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_attr_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
69        zend_restore_error_handling(&error_handling TSRMLS_CC);
70        return;
71    }
72
73    zend_restore_error_handling(&error_handling TSRMLS_CC);
74    intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
75
76    name_valid = xmlValidateName((xmlChar *) name, 0);
77    if (name_valid != 0) {
78        php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
79        RETURN_FALSE;
80    }
81
82    nodep = xmlNewProp(NULL, (xmlChar *) name, value);
83
84    if (!nodep) {
85        php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
86        RETURN_FALSE;
87    }
88
89    if (intern != NULL) {
90        oldnode = dom_object_get_node(intern);
91        if (oldnode != NULL) {
92            php_libxml_node_free_resource(oldnode  TSRMLS_CC);
93        }
94        php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC);
95    }
96}
97
98/* }}} end DOMAttr::__construct */
99
100/* {{{ name string
101readonly=yes
102URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1112119403
103Since:
104*/
105int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC)
106{
107    xmlAttrPtr attrp;
108
109    attrp = (xmlAttrPtr) dom_object_get_node(obj);
110
111    if (attrp == NULL) {
112        php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
113        return FAILURE;
114    }
115
116    ALLOC_ZVAL(*retval);
117    ZVAL_STRING(*retval, (char *) (attrp->name), 1);
118
119    return SUCCESS;
120}
121
122/* }}} */
123
124/* {{{ specified    boolean
125readonly=yes
126URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-862529273
127Since:
128*/
129int dom_attr_specified_read(dom_object *obj, zval **retval TSRMLS_DC)
130{
131    /* TODO */
132    ALLOC_ZVAL(*retval);
133    ZVAL_TRUE(*retval);
134    return SUCCESS;
135}
136
137/* }}} */
138
139/* {{{ value    string
140readonly=no
141URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-221662474
142Since:
143*/
144int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC)
145{
146    xmlAttrPtr attrp;
147    xmlChar *content;
148
149    attrp = (xmlAttrPtr) dom_object_get_node(obj);
150
151    if (attrp == NULL) {
152        php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
153        return FAILURE;
154    }
155
156    ALLOC_ZVAL(*retval);
157
158
159    if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) {
160        ZVAL_STRING(*retval, content, 1);
161        xmlFree(content);
162    } else {
163        ZVAL_EMPTY_STRING(*retval);
164    }
165
166    return SUCCESS;
167
168}
169
170int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC)
171{
172    zval value_copy;
173    xmlAttrPtr attrp;
174
175    attrp = (xmlAttrPtr) dom_object_get_node(obj);
176
177    if (attrp == NULL) {
178        php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
179        return FAILURE;
180    }
181
182    if (attrp->children) {
183        node_list_unlink(attrp->children TSRMLS_CC);
184    }
185
186    if (newval->type != IS_STRING) {
187        if(Z_REFCOUNT_P(newval) > 1) {
188            value_copy = *newval;
189            zval_copy_ctor(&value_copy);
190            newval = &value_copy;
191        }
192        convert_to_string(newval);
193    }
194
195    xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
196
197    if (newval == &value_copy) {
198        zval_dtor(newval);
199    }
200
201    return SUCCESS;
202}
203
204/* }}} */
205
206/* {{{ ownerElement DOMElement
207readonly=yes
208URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-ownerElement
209Since: DOM Level 2
210*/
211int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC)
212{
213    xmlNodePtr nodep, nodeparent;
214    int ret;
215
216    nodep = dom_object_get_node(obj);
217
218    if (nodep == NULL) {
219        php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
220        return FAILURE;
221    }
222
223    ALLOC_ZVAL(*retval);
224
225    nodeparent = nodep->parent;
226    if (!nodeparent) {
227        ZVAL_NULL(*retval);
228        return SUCCESS;
229    }
230
231    if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) {
232        php_error_docref(NULL TSRMLS_CC, E_WARNING,  "Cannot create required DOM object");
233        return FAILURE;
234    }
235    return SUCCESS;
236
237}
238
239/* }}} */
240
241/* {{{ schemaTypeInfo   DOMTypeInfo
242readonly=yes
243URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-schemaTypeInfo
244Since: DOM Level 3
245*/
246int dom_attr_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC)
247{
248    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented");
249    ALLOC_ZVAL(*retval);
250    ZVAL_NULL(*retval);
251    return SUCCESS;
252}
253
254/* }}} */
255
256/* {{{ proto boolean dom_attr_is_id();
257URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId
258Since: DOM Level 3
259*/
260PHP_FUNCTION(dom_attr_is_id)
261{
262    zval *id;
263    dom_object *intern;
264    xmlAttrPtr attrp;
265
266    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_attr_class_entry) == FAILURE) {
267        return;
268    }
269
270    DOM_GET_OBJ(attrp, id, xmlAttrPtr, intern);
271
272    if (attrp->atype == XML_ATTRIBUTE_ID) {
273        RETURN_TRUE;
274    } else {
275        RETURN_FALSE;
276    }
277}
278/* }}} end dom_attr_is_id */
279
280#endif
281
282/*
283 * Local variables:
284 * tab-width: 4
285 * c-basic-offset: 4
286 * End:
287 * vim600: noet sw=4 ts=4 fdm=marker
288 * vim<600: noet sw=4 ts=4
289 */
290