1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: domimplementation.c 272374 2008-12-31 11:17:49Z sebastian $ */
21 :
22 : #ifdef HAVE_CONFIG_H
23 : #include "config.h"
24 : #endif
25 :
26 : #include "php.h"
27 : #if HAVE_LIBXML && HAVE_DOM
28 : #include "php_dom.h"
29 :
30 : /* {{{ arginfo */
31 : static
32 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_get_feature, 0, 0, 2)
33 : ZEND_ARG_INFO(0, feature)
34 : ZEND_ARG_INFO(0, version)
35 : ZEND_END_ARG_INFO();
36 :
37 : static
38 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_has_feature, 0, 0, 0)
39 : ZEND_END_ARG_INFO();
40 :
41 : static
42 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_documenttype, 0, 0, 3)
43 : ZEND_ARG_INFO(0, qualifiedName)
44 : ZEND_ARG_INFO(0, publicId)
45 : ZEND_ARG_INFO(0, systemId)
46 : ZEND_END_ARG_INFO();
47 :
48 : static
49 : ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_document, 0, 0, 3)
50 : ZEND_ARG_INFO(0, namespaceURI)
51 : ZEND_ARG_INFO(0, qualifiedName)
52 : ZEND_ARG_OBJ_INFO(0, docType, DOMDocumentType, 0)
53 : ZEND_END_ARG_INFO();
54 : /* }}} */
55 :
56 : /*
57 : * class DOMImplementation
58 : *
59 : * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-102161490
60 : * Since:
61 : */
62 :
63 : zend_function_entry php_dom_domimplementation_class_functions[] = {
64 : PHP_ME(domimplementation, getFeature, arginfo_dom_implementation_get_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
65 : PHP_ME(domimplementation, hasFeature, arginfo_dom_implementation_has_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
66 : PHP_ME(domimplementation, createDocumentType, arginfo_dom_implementation_create_documenttype, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
67 : PHP_ME(domimplementation, createDocument, arginfo_dom_implementation_create_document, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
68 : {NULL, NULL, NULL}
69 : };
70 :
71 : /* {{{ proto boolean dom_domimplementation_has_feature(string feature, string version);
72 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7
73 : Since:
74 : */
75 : PHP_METHOD(domimplementation, hasFeature)
76 0 : {
77 : int feature_len, version_len;
78 : char *feature, *version;
79 :
80 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &feature, &feature_len, &version, &version_len) == FAILURE) {
81 0 : return;
82 : }
83 :
84 0 : if (dom_has_feature(feature, version)) {
85 0 : RETURN_TRUE;
86 : } else {
87 0 : RETURN_FALSE;
88 : }
89 : }
90 : /* }}} end dom_domimplementation_has_feature */
91 :
92 :
93 : /* {{{ proto DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId);
94 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType
95 : Since: DOM Level 2
96 : */
97 : PHP_METHOD(domimplementation, createDocumentType)
98 0 : {
99 0 : zval *rv = NULL;
100 : xmlDtd *doctype;
101 0 : int ret, name_len = 0, publicid_len = 0, systemid_len = 0;
102 : char *name, *publicid, *systemid;
103 0 : xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL;
104 : xmlURIPtr uri;
105 :
106 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) == FAILURE) {
107 0 : return;
108 : }
109 :
110 0 : if (name_len == 0) {
111 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "qualifiedName is required");
112 0 : RETURN_FALSE;
113 : }
114 :
115 0 : if (publicid_len > 0)
116 0 : pch1 = publicid;
117 0 : if (systemid_len > 0)
118 0 : pch2 = systemid;
119 :
120 0 : uri = xmlParseURI(name);
121 0 : if (uri != NULL && uri->opaque != NULL) {
122 0 : localname = xmlStrdup(uri->opaque);
123 0 : if (xmlStrchr(localname, (xmlChar) ':') != NULL) {
124 0 : php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
125 0 : xmlFreeURI(uri);
126 0 : xmlFree(localname);
127 0 : RETURN_FALSE;
128 : }
129 : } else {
130 0 : localname = xmlStrdup(name);
131 : }
132 :
133 : /* TODO: Test that localname has no invalid chars
134 : php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC);
135 : */
136 :
137 0 : if (uri) {
138 0 : xmlFreeURI(uri);
139 : }
140 :
141 0 : doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2);
142 0 : xmlFree(localname);
143 :
144 0 : if (doctype == NULL) {
145 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create DocumentType");
146 0 : RETURN_FALSE;
147 : }
148 :
149 0 : DOM_RET_OBJ(rv, (xmlNodePtr) doctype, &ret, NULL);
150 : }
151 : /* }}} end dom_domimplementation_create_document_type */
152 :
153 :
154 : /* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);
155 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
156 : Since: DOM Level 2
157 : */
158 : PHP_METHOD(domimplementation, createDocument)
159 0 : {
160 0 : zval *node = NULL, *rv = NULL;
161 : xmlDoc *docp;
162 : xmlNode *nodep;
163 0 : xmlDtdPtr doctype = NULL;
164 0 : xmlNsPtr nsptr = NULL;
165 0 : int ret, uri_len = 0, name_len = 0, errorcode = 0;
166 : char *uri, *name;
167 0 : char *prefix = NULL, *localname = NULL;
168 : dom_object *doctobj;
169 :
170 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) {
171 0 : return;
172 : }
173 :
174 0 : if (node != NULL) {
175 0 : DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj);
176 0 : if (doctype->type == XML_DOCUMENT_TYPE_NODE) {
177 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object");
178 0 : RETURN_FALSE;
179 : }
180 0 : if (doctype->doc != NULL) {
181 0 : php_dom_throw_error(WRONG_DOCUMENT_ERR, 1 TSRMLS_CC);
182 0 : RETURN_FALSE;
183 : }
184 : } else {
185 0 : doctobj = NULL;
186 : }
187 :
188 0 : if (name_len > 0) {
189 0 : errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len);
190 0 : if (errorcode == 0 && uri_len > 0 && ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL)) {
191 0 : errorcode = NAMESPACE_ERR;
192 : }
193 : }
194 :
195 0 : if (prefix != NULL) {
196 0 : xmlFree(prefix);
197 : }
198 :
199 0 : if (errorcode != 0) {
200 0 : if (localname != NULL) {
201 0 : xmlFree(localname);
202 : }
203 0 : php_dom_throw_error(errorcode, 1 TSRMLS_CC);
204 0 : RETURN_FALSE;
205 : }
206 :
207 : /* currently letting libxml2 set the version string */
208 0 : docp = xmlNewDoc(NULL);
209 0 : if (!docp) {
210 0 : if (localname != NULL) {
211 0 : xmlFree(localname);
212 : }
213 0 : RETURN_FALSE;
214 : }
215 :
216 0 : if (doctype != NULL) {
217 0 : docp->intSubset = doctype;
218 0 : doctype->parent = docp;
219 0 : doctype->doc = docp;
220 0 : docp->children = (xmlNodePtr) doctype;
221 0 : docp->last = (xmlNodePtr) doctype;
222 : }
223 :
224 0 : if (localname != NULL) {
225 0 : nodep = xmlNewDocNode (docp, nsptr, localname, NULL);
226 0 : if (!nodep) {
227 0 : if (doctype != NULL) {
228 0 : docp->intSubset = NULL;
229 0 : doctype->parent = NULL;
230 0 : doctype->doc = NULL;
231 0 : docp->children = NULL;
232 0 : docp->last = NULL;
233 : }
234 0 : xmlFreeDoc(docp);
235 0 : xmlFree(localname);
236 : /* Need some type of error here */
237 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected Error");
238 0 : RETURN_FALSE;
239 : }
240 :
241 0 : nodep->nsDef = nsptr;
242 :
243 0 : xmlDocSetRootElement(docp, nodep);
244 0 : xmlFree(localname);
245 : }
246 :
247 0 : DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL);
248 :
249 0 : if (doctobj != NULL) {
250 0 : doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
251 0 : php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC);
252 : }
253 : }
254 : /* }}} end dom_domimplementation_create_document */
255 :
256 :
257 : /* {{{ proto DOMNode dom_domimplementation_get_feature(string feature, string version);
258 : URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature
259 : Since: DOM Level 3
260 : */
261 : PHP_METHOD(domimplementation, getFeature)
262 0 : {
263 0 : DOM_NOT_IMPLEMENTED();
264 : }
265 : /* }}} end dom_domimplementation_get_feature */
266 : #endif
|