document.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 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. /* $Id$ */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "php.h"
  24. #if HAVE_LIBXML && HAVE_DOM
  25. #include "php_dom.h"
  26. #include <libxml/SAX.h>
  27. #ifdef LIBXML_SCHEMAS_ENABLED
  28. #include <libxml/relaxng.h>
  29. #include <libxml/xmlschemas.h>
  30. #endif
  31. typedef struct _idsIterator idsIterator;
  32. struct _idsIterator {
  33. xmlChar *elementId;
  34. xmlNode *element;
  35. };
  36. #define DOM_LOAD_STRING 0
  37. #define DOM_LOAD_FILE 1
  38. /* {{{ arginfo */
  39. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1)
  40. ZEND_ARG_INFO(0, tagName)
  41. ZEND_ARG_INFO(0, value)
  42. ZEND_END_ARG_INFO();
  43. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0)
  44. ZEND_END_ARG_INFO();
  45. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1)
  46. ZEND_ARG_INFO(0, data)
  47. ZEND_END_ARG_INFO();
  48. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1)
  49. ZEND_ARG_INFO(0, data)
  50. ZEND_END_ARG_INFO();
  51. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1)
  52. ZEND_ARG_INFO(0, data)
  53. ZEND_END_ARG_INFO();
  54. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2)
  55. ZEND_ARG_INFO(0, target)
  56. ZEND_ARG_INFO(0, data)
  57. ZEND_END_ARG_INFO();
  58. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1)
  59. ZEND_ARG_INFO(0, name)
  60. ZEND_END_ARG_INFO();
  61. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1)
  62. ZEND_ARG_INFO(0, name)
  63. ZEND_END_ARG_INFO();
  64. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1)
  65. ZEND_ARG_INFO(0, tagName)
  66. ZEND_END_ARG_INFO();
  67. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2)
  68. ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0)
  69. ZEND_ARG_INFO(0, deep)
  70. ZEND_END_ARG_INFO();
  71. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2)
  72. ZEND_ARG_INFO(0, namespaceURI)
  73. ZEND_ARG_INFO(0, qualifiedName)
  74. ZEND_ARG_INFO(0, value)
  75. ZEND_END_ARG_INFO();
  76. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2)
  77. ZEND_ARG_INFO(0, namespaceURI)
  78. ZEND_ARG_INFO(0, qualifiedName)
  79. ZEND_END_ARG_INFO();
  80. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2)
  81. ZEND_ARG_INFO(0, namespaceURI)
  82. ZEND_ARG_INFO(0, localName)
  83. ZEND_END_ARG_INFO();
  84. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1)
  85. ZEND_ARG_INFO(0, elementId)
  86. ZEND_END_ARG_INFO();
  87. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1)
  88. ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0)
  89. ZEND_END_ARG_INFO();
  90. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0)
  91. ZEND_END_ARG_INFO();
  92. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3)
  93. ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
  94. ZEND_ARG_INFO(0, namespaceURI)
  95. ZEND_ARG_INFO(0, qualifiedName)
  96. ZEND_END_ARG_INFO();
  97. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1)
  98. ZEND_ARG_INFO(0, source)
  99. ZEND_ARG_INFO(0, options)
  100. ZEND_END_ARG_INFO();
  101. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1)
  102. ZEND_ARG_INFO(0, file)
  103. ZEND_END_ARG_INFO();
  104. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1)
  105. ZEND_ARG_INFO(0, source)
  106. ZEND_ARG_INFO(0, options)
  107. ZEND_END_ARG_INFO();
  108. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0)
  109. ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1)
  110. ZEND_END_ARG_INFO();
  111. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0)
  112. ZEND_ARG_INFO(0, version)
  113. ZEND_ARG_INFO(0, encoding)
  114. ZEND_END_ARG_INFO();
  115. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0)
  116. ZEND_END_ARG_INFO();
  117. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0)
  118. ZEND_ARG_INFO(0, options)
  119. ZEND_END_ARG_INFO();
  120. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1)
  121. ZEND_ARG_INFO(0, source)
  122. ZEND_ARG_INFO(0, options)
  123. ZEND_END_ARG_INFO();
  124. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1)
  125. ZEND_ARG_INFO(0, source)
  126. ZEND_ARG_INFO(0, options)
  127. ZEND_END_ARG_INFO();
  128. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0)
  129. ZEND_END_ARG_INFO();
  130. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1)
  131. ZEND_ARG_INFO(0, file)
  132. ZEND_END_ARG_INFO();
  133. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1)
  134. ZEND_ARG_INFO(0, filename)
  135. ZEND_END_ARG_INFO();
  136. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1)
  137. ZEND_ARG_INFO(0, source)
  138. ZEND_END_ARG_INFO();
  139. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1)
  140. ZEND_ARG_INFO(0, filename)
  141. ZEND_END_ARG_INFO();
  142. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1)
  143. ZEND_ARG_INFO(0, source)
  144. ZEND_END_ARG_INFO();
  145. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
  146. ZEND_ARG_INFO(0, baseClass)
  147. ZEND_ARG_INFO(0, extendedClass)
  148. ZEND_END_ARG_INFO();
  149. /* }}} */
  150. /*
  151. * class DOMDocument extends DOMNode
  152. *
  153. * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document
  154. * Since:
  155. */
  156. const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
  157. PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element)
  158. PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment)
  159. PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node)
  160. PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment)
  161. PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection)
  162. PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction)
  163. PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute)
  164. PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference)
  165. PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name)
  166. PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node)
  167. PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns)
  168. PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns)
  169. PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns)
  170. PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id)
  171. PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node)
  172. PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document)
  173. PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node)
  174. PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
  175. PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save)
  176. PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
  177. PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml)
  178. PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
  179. PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate)
  180. PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude)
  181. #if defined(LIBXML_HTML_ENABLED)
  182. PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
  183. PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
  184. PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml)
  185. PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile)
  186. #endif /* defined(LIBXML_HTML_ENABLED) */
  187. #if defined(LIBXML_SCHEMAS_ENABLED)
  188. PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file)
  189. PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml)
  190. PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file)
  191. PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
  192. #endif
  193. PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
  194. PHP_FE_END
  195. };
  196. /* }}} */
  197. /* {{{ docType DOMDocumentType
  198. readonly=yes
  199. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31
  200. Since:
  201. */
  202. int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC)
  203. {
  204. xmlDoc *docp;
  205. xmlDtdPtr dtdptr;
  206. int ret;
  207. docp = (xmlDocPtr) dom_object_get_node(obj);
  208. if (docp == NULL) {
  209. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  210. return FAILURE;
  211. }
  212. ALLOC_ZVAL(*retval);
  213. dtdptr = xmlGetIntSubset(docp);
  214. if (!dtdptr) {
  215. ZVAL_NULL(*retval);
  216. return SUCCESS;
  217. }
  218. if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, *retval, obj TSRMLS_CC))) {
  219. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  220. return FAILURE;
  221. }
  222. return SUCCESS;
  223. }
  224. /* }}} */
  225. /* {{{ implementation DOMImplementation
  226. readonly=yes
  227. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA
  228. Since:
  229. */
  230. int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC)
  231. {
  232. ALLOC_ZVAL(*retval);
  233. php_dom_create_implementation(retval TSRMLS_CC);
  234. return SUCCESS;
  235. }
  236. /* }}} */
  237. /* {{{ documentElement DOMElement
  238. readonly=yes
  239. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092
  240. Since:
  241. */
  242. int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC)
  243. {
  244. xmlDoc *docp;
  245. xmlNode *root;
  246. int ret;
  247. docp = (xmlDocPtr) dom_object_get_node(obj);
  248. if (docp == NULL) {
  249. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  250. return FAILURE;
  251. }
  252. ALLOC_ZVAL(*retval);
  253. root = xmlDocGetRootElement(docp);
  254. if (!root) {
  255. ZVAL_NULL(*retval);
  256. return SUCCESS;
  257. }
  258. if (NULL == (*retval = php_dom_create_object(root, &ret, *retval, obj TSRMLS_CC))) {
  259. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  260. return FAILURE;
  261. }
  262. return SUCCESS;
  263. }
  264. /* }}} */
  265. /* {{{ encoding string
  266. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding
  267. Since: DOM Level 3
  268. */
  269. int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
  270. {
  271. xmlDoc *docp;
  272. char *encoding;
  273. docp = (xmlDocPtr) dom_object_get_node(obj);
  274. if (docp == NULL) {
  275. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  276. return FAILURE;
  277. }
  278. encoding = (char *) docp->encoding;
  279. ALLOC_ZVAL(*retval);
  280. if (encoding != NULL) {
  281. ZVAL_STRING(*retval, encoding, 1);
  282. } else {
  283. ZVAL_NULL(*retval);
  284. }
  285. return SUCCESS;
  286. }
  287. int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
  288. {
  289. zval value_copy;
  290. xmlDoc *docp;
  291. xmlCharEncodingHandlerPtr handler;
  292. docp = (xmlDocPtr) dom_object_get_node(obj);
  293. if (docp == NULL) {
  294. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  295. return FAILURE;
  296. }
  297. convert_to_string_copy(newval, value_copy);
  298. handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
  299. if (handler != NULL) {
  300. xmlCharEncCloseFunc(handler);
  301. if (docp->encoding != NULL) {
  302. xmlFree((xmlChar *)docp->encoding);
  303. }
  304. docp->encoding = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
  305. } else {
  306. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document Encoding");
  307. }
  308. if (newval == &value_copy) {
  309. zval_dtor(newval);
  310. }
  311. return SUCCESS;
  312. }
  313. /* }}} */
  314. /* {{{ standalone boolean
  315. readonly=no
  316. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone
  317. Since: DOM Level 3
  318. */
  319. int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC)
  320. {
  321. xmlDoc *docp;
  322. int standalone;
  323. docp = (xmlDocPtr) dom_object_get_node(obj);
  324. if (docp == NULL) {
  325. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  326. return FAILURE;
  327. }
  328. ALLOC_ZVAL(*retval);
  329. standalone = docp->standalone;
  330. ZVAL_BOOL(*retval, standalone);
  331. return SUCCESS;
  332. }
  333. int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
  334. {
  335. zval value_copy;
  336. xmlDoc *docp;
  337. int standalone;
  338. docp = (xmlDocPtr) dom_object_get_node(obj);
  339. if (docp == NULL) {
  340. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  341. return FAILURE;
  342. }
  343. convert_to_long_copy(newval, value_copy);
  344. standalone = Z_LVAL_P(newval);
  345. if (standalone > 0) {
  346. docp->standalone = 1;
  347. }
  348. else if (standalone < 0) {
  349. docp->standalone = -1;
  350. }
  351. else {
  352. docp->standalone = 0;
  353. }
  354. if (newval == &value_copy) {
  355. zval_dtor(newval);
  356. }
  357. return SUCCESS;
  358. }
  359. /* }}} */
  360. /* {{{ version string
  361. readonly=no
  362. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version
  363. Since: DOM Level 3
  364. */
  365. int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC)
  366. {
  367. xmlDoc *docp;
  368. char *version;
  369. docp = (xmlDocPtr) dom_object_get_node(obj);
  370. if (docp == NULL) {
  371. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  372. return FAILURE;
  373. }
  374. version = (char *) docp->version;
  375. ALLOC_ZVAL(*retval);
  376. if (version != NULL) {
  377. ZVAL_STRING(*retval, version, 1);
  378. } else {
  379. ZVAL_NULL(*retval);
  380. }
  381. return SUCCESS;
  382. }
  383. int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
  384. {
  385. zval value_copy;
  386. xmlDoc *docp;
  387. docp = (xmlDocPtr) dom_object_get_node(obj);
  388. if (docp == NULL) {
  389. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  390. return FAILURE;
  391. }
  392. if (docp->version != NULL) {
  393. xmlFree((xmlChar *) docp->version );
  394. }
  395. convert_to_string_copy(newval, value_copy);
  396. docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
  397. if (newval == &value_copy) {
  398. zval_dtor(newval);
  399. }
  400. return SUCCESS;
  401. }
  402. /* }}} */
  403. /* {{{ strictErrorChecking boolean
  404. readonly=no
  405. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking
  406. Since: DOM Level 3
  407. */
  408. int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC)
  409. {
  410. dom_doc_propsptr doc_prop;
  411. ALLOC_ZVAL(*retval);
  412. if (obj->document) {
  413. doc_prop = dom_get_doc_props(obj->document);
  414. ZVAL_BOOL(*retval, doc_prop->stricterror);
  415. } else {
  416. ZVAL_FALSE(*retval);
  417. }
  418. return SUCCESS;
  419. }
  420. int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC)
  421. {
  422. zval value_copy;
  423. dom_doc_propsptr doc_prop;
  424. convert_to_boolean_copy(newval, value_copy);
  425. if (obj->document) {
  426. doc_prop = dom_get_doc_props(obj->document);
  427. doc_prop->stricterror = Z_LVAL_P(newval);
  428. }
  429. if (newval == &value_copy) {
  430. zval_dtor(newval);
  431. }
  432. return SUCCESS;
  433. }
  434. /* }}} */
  435. /* {{{ formatOutput boolean
  436. readonly=no
  437. */
  438. int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
  439. {
  440. dom_doc_propsptr doc_prop;
  441. ALLOC_ZVAL(*retval);
  442. if (obj->document) {
  443. doc_prop = dom_get_doc_props(obj->document);
  444. ZVAL_BOOL(*retval, doc_prop->formatoutput);
  445. } else {
  446. ZVAL_FALSE(*retval);
  447. }
  448. return SUCCESS;
  449. }
  450. int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC)
  451. {
  452. zval value_copy;
  453. dom_doc_propsptr doc_prop;
  454. convert_to_boolean_copy(newval, value_copy);
  455. if (obj->document) {
  456. doc_prop = dom_get_doc_props(obj->document);
  457. doc_prop->formatoutput = Z_LVAL_P(newval);
  458. }
  459. if (newval == &value_copy) {
  460. zval_dtor(newval);
  461. }
  462. return SUCCESS;
  463. }
  464. /* }}} */
  465. /* {{{ validateOnParse boolean
  466. readonly=no
  467. */
  468. int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC)
  469. {
  470. dom_doc_propsptr doc_prop;
  471. ALLOC_ZVAL(*retval);
  472. if (obj->document) {
  473. doc_prop = dom_get_doc_props(obj->document);
  474. ZVAL_BOOL(*retval, doc_prop->validateonparse);
  475. } else {
  476. ZVAL_FALSE(*retval);
  477. }
  478. return SUCCESS;
  479. }
  480. int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC)
  481. {
  482. zval value_copy;
  483. dom_doc_propsptr doc_prop;
  484. convert_to_boolean_copy(newval, value_copy);
  485. if (obj->document) {
  486. doc_prop = dom_get_doc_props(obj->document);
  487. doc_prop->validateonparse = Z_LVAL_P(newval);
  488. }
  489. if (newval == &value_copy) {
  490. zval_dtor(newval);
  491. }
  492. return SUCCESS;
  493. }
  494. /* }}} */
  495. /* {{{ resolveExternals boolean
  496. readonly=no
  497. */
  498. int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC)
  499. {
  500. dom_doc_propsptr doc_prop;
  501. ALLOC_ZVAL(*retval);
  502. if (obj->document) {
  503. doc_prop = dom_get_doc_props(obj->document);
  504. ZVAL_BOOL(*retval, doc_prop->resolveexternals);
  505. } else {
  506. ZVAL_FALSE(*retval);
  507. }
  508. return SUCCESS;
  509. }
  510. int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC)
  511. {
  512. zval value_copy;
  513. dom_doc_propsptr doc_prop;
  514. convert_to_boolean_copy(newval, value_copy);
  515. if (obj->document) {
  516. doc_prop = dom_get_doc_props(obj->document);
  517. doc_prop->resolveexternals = Z_LVAL_P(newval);
  518. }
  519. if (newval == &value_copy) {
  520. zval_dtor(newval);
  521. }
  522. return SUCCESS;
  523. }
  524. /* }}} */
  525. /* {{{ preserveWhiteSpace boolean
  526. readonly=no
  527. */
  528. int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC)
  529. {
  530. dom_doc_propsptr doc_prop;
  531. ALLOC_ZVAL(*retval);
  532. if (obj->document) {
  533. doc_prop = dom_get_doc_props(obj->document);
  534. ZVAL_BOOL(*retval, doc_prop->preservewhitespace);
  535. } else {
  536. ZVAL_FALSE(*retval);
  537. }
  538. return SUCCESS;
  539. }
  540. int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC)
  541. {
  542. zval value_copy;
  543. dom_doc_propsptr doc_prop;
  544. convert_to_boolean_copy(newval, value_copy);
  545. if (obj->document) {
  546. doc_prop = dom_get_doc_props(obj->document);
  547. doc_prop->preservewhitespace = Z_LVAL_P(newval);
  548. }
  549. if (newval == &value_copy) {
  550. zval_dtor(newval);
  551. }
  552. return SUCCESS;
  553. }
  554. /* }}} */
  555. /* {{{ recover boolean
  556. readonly=no
  557. */
  558. int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
  559. {
  560. dom_doc_propsptr doc_prop;
  561. ALLOC_ZVAL(*retval);
  562. if (obj->document) {
  563. doc_prop = dom_get_doc_props(obj->document);
  564. ZVAL_BOOL(*retval, doc_prop->recover);
  565. } else {
  566. ZVAL_FALSE(*retval);
  567. }
  568. return SUCCESS;
  569. }
  570. int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
  571. {
  572. zval value_copy;
  573. dom_doc_propsptr doc_prop;
  574. convert_to_boolean_copy(newval, value_copy);
  575. if (obj->document) {
  576. doc_prop = dom_get_doc_props(obj->document);
  577. doc_prop->recover = Z_LVAL_P(newval);
  578. }
  579. if (newval == &value_copy) {
  580. zval_dtor(newval);
  581. }
  582. return SUCCESS;
  583. }
  584. /* }}} */
  585. /* {{{ substituteEntities boolean
  586. readonly=no
  587. */
  588. int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
  589. {
  590. dom_doc_propsptr doc_prop;
  591. ALLOC_ZVAL(*retval);
  592. if (obj->document) {
  593. doc_prop = dom_get_doc_props(obj->document);
  594. ZVAL_BOOL(*retval, doc_prop->substituteentities);
  595. } else {
  596. ZVAL_FALSE(*retval);
  597. }
  598. return SUCCESS;
  599. }
  600. int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC)
  601. {
  602. zval value_copy;
  603. dom_doc_propsptr doc_prop;
  604. convert_to_boolean_copy(newval, value_copy);
  605. if (obj->document) {
  606. doc_prop = dom_get_doc_props(obj->document);
  607. doc_prop->substituteentities = Z_LVAL_P(newval);
  608. }
  609. if (newval == &value_copy) {
  610. zval_dtor(newval);
  611. }
  612. return SUCCESS;
  613. }
  614. /* }}} */
  615. /* {{{ documentURI string
  616. readonly=no
  617. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI
  618. Since: DOM Level 3
  619. */
  620. int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
  621. {
  622. xmlDoc *docp;
  623. char *url;
  624. docp = (xmlDocPtr) dom_object_get_node(obj);
  625. if (docp == NULL) {
  626. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  627. return FAILURE;
  628. }
  629. ALLOC_ZVAL(*retval);
  630. url = (char *) docp->URL;
  631. if (url != NULL) {
  632. ZVAL_STRING(*retval, url, 1);
  633. } else {
  634. ZVAL_NULL(*retval);
  635. }
  636. return SUCCESS;
  637. }
  638. int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
  639. {
  640. zval value_copy;
  641. xmlDoc *docp;
  642. docp = (xmlDocPtr) dom_object_get_node(obj);
  643. if (docp == NULL) {
  644. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  645. return FAILURE;
  646. }
  647. if (docp->URL != NULL) {
  648. xmlFree((xmlChar *) docp->URL);
  649. }
  650. convert_to_string_copy(newval, value_copy);
  651. docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
  652. if (newval == &value_copy) {
  653. zval_dtor(newval);
  654. }
  655. return SUCCESS;
  656. }
  657. /* }}} */
  658. /* {{{ config DOMConfiguration
  659. readonly=yes
  660. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config
  661. Since: DOM Level 3
  662. */
  663. int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC)
  664. {
  665. ALLOC_ZVAL(*retval);
  666. ZVAL_NULL(*retval);
  667. return SUCCESS;
  668. }
  669. /* }}} */
  670. /* {{{ proto DOMElement dom_document_create_element(string tagName [, string value]);
  671. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
  672. Since:
  673. */
  674. PHP_FUNCTION(dom_document_create_element)
  675. {
  676. zval *id;
  677. xmlNode *node;
  678. xmlDocPtr docp;
  679. dom_object *intern;
  680. int ret, name_len, value_len;
  681. char *name, *value = NULL;
  682. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
  683. return;
  684. }
  685. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  686. if (xmlValidateName((xmlChar *) name, 0) != 0) {
  687. php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  688. RETURN_FALSE;
  689. }
  690. node = xmlNewDocNode(docp, NULL, name, value);
  691. if (!node) {
  692. RETURN_FALSE;
  693. }
  694. DOM_RET_OBJ(node, &ret, intern);
  695. }
  696. /* }}} end dom_document_create_element */
  697. /* {{{ proto DOMDocumentFragment dom_document_create_document_fragment();
  698. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
  699. Since:
  700. */
  701. PHP_FUNCTION(dom_document_create_document_fragment)
  702. {
  703. zval *id;
  704. xmlNode *node;
  705. xmlDocPtr docp;
  706. dom_object *intern;
  707. int ret;
  708. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
  709. return;
  710. }
  711. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  712. node = xmlNewDocFragment(docp);
  713. if (!node) {
  714. RETURN_FALSE;
  715. }
  716. DOM_RET_OBJ(node, &ret, intern);
  717. }
  718. /* }}} end dom_document_create_document_fragment */
  719. /* {{{ proto DOMText dom_document_create_text_node(string data);
  720. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
  721. Since:
  722. */
  723. PHP_FUNCTION(dom_document_create_text_node)
  724. {
  725. zval *id;
  726. xmlNode *node;
  727. xmlDocPtr docp;
  728. int ret, value_len;
  729. dom_object *intern;
  730. char *value;
  731. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
  732. return;
  733. }
  734. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  735. node = xmlNewDocText(docp, (xmlChar *) value);
  736. if (!node) {
  737. RETURN_FALSE;
  738. }
  739. DOM_RET_OBJ(node, &ret, intern);
  740. }
  741. /* }}} end dom_document_create_text_node */
  742. /* {{{ proto DOMComment dom_document_create_comment(string data);
  743. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
  744. Since:
  745. */
  746. PHP_FUNCTION(dom_document_create_comment)
  747. {
  748. zval *id;
  749. xmlNode *node;
  750. xmlDocPtr docp;
  751. int ret, value_len;
  752. dom_object *intern;
  753. char *value;
  754. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
  755. return;
  756. }
  757. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  758. node = xmlNewDocComment(docp, (xmlChar *) value);
  759. if (!node) {
  760. RETURN_FALSE;
  761. }
  762. DOM_RET_OBJ(node, &ret, intern);
  763. }
  764. /* }}} end dom_document_create_comment */
  765. /* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data);
  766. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
  767. Since:
  768. */
  769. PHP_FUNCTION(dom_document_create_cdatasection)
  770. {
  771. zval *id;
  772. xmlNode *node;
  773. xmlDocPtr docp;
  774. int ret, value_len;
  775. dom_object *intern;
  776. char *value;
  777. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
  778. return;
  779. }
  780. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  781. node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
  782. if (!node) {
  783. RETURN_FALSE;
  784. }
  785. DOM_RET_OBJ(node, &ret, intern);
  786. }
  787. /* }}} end dom_document_create_cdatasection */
  788. /* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data);
  789. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
  790. Since:
  791. */
  792. PHP_FUNCTION(dom_document_create_processing_instruction)
  793. {
  794. zval *id;
  795. xmlNode *node;
  796. xmlDocPtr docp;
  797. int ret, value_len, name_len = 0;
  798. dom_object *intern;
  799. char *name, *value = NULL;
  800. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
  801. return;
  802. }
  803. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  804. if (xmlValidateName((xmlChar *) name, 0) != 0) {
  805. php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  806. RETURN_FALSE;
  807. }
  808. node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
  809. if (!node) {
  810. RETURN_FALSE;
  811. }
  812. node->doc = docp;
  813. DOM_RET_OBJ(node, &ret, intern);
  814. }
  815. /* }}} end dom_document_create_processing_instruction */
  816. /* {{{ proto DOMAttr dom_document_create_attribute(string name);
  817. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
  818. Since:
  819. */
  820. PHP_FUNCTION(dom_document_create_attribute)
  821. {
  822. zval *id;
  823. xmlAttrPtr node;
  824. xmlDocPtr docp;
  825. int ret, name_len;
  826. dom_object *intern;
  827. char *name;
  828. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
  829. return;
  830. }
  831. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  832. if (xmlValidateName((xmlChar *) name, 0) != 0) {
  833. php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  834. RETURN_FALSE;
  835. }
  836. node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
  837. if (!node) {
  838. RETURN_FALSE;
  839. }
  840. DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
  841. }
  842. /* }}} end dom_document_create_attribute */
  843. /* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name);
  844. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE
  845. Since:
  846. */
  847. PHP_FUNCTION(dom_document_create_entity_reference)
  848. {
  849. zval *id;
  850. xmlNode *node;
  851. xmlDocPtr docp = NULL;
  852. dom_object *intern;
  853. int ret, name_len;
  854. char *name;
  855. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
  856. return;
  857. }
  858. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  859. if (xmlValidateName((xmlChar *) name, 0) != 0) {
  860. php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  861. RETURN_FALSE;
  862. }
  863. node = xmlNewReference(docp, name);
  864. if (!node) {
  865. RETURN_FALSE;
  866. }
  867. DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
  868. }
  869. /* }}} end dom_document_create_entity_reference */
  870. /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname);
  871. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
  872. Since:
  873. */
  874. PHP_FUNCTION(dom_document_get_elements_by_tag_name)
  875. {
  876. zval *id;
  877. xmlDocPtr docp;
  878. int name_len;
  879. dom_object *intern, *namednode;
  880. char *name;
  881. xmlChar *local;
  882. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
  883. return;
  884. }
  885. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  886. php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
  887. namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
  888. local = xmlCharStrndup(name, name_len);
  889. dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
  890. }
  891. /* }}} end dom_document_get_elements_by_tag_name */
  892. /* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep);
  893. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
  894. Since: DOM Level 2
  895. */
  896. PHP_FUNCTION(dom_document_import_node)
  897. {
  898. zval *id, *node;
  899. xmlDocPtr docp;
  900. xmlNodePtr nodep, retnodep;
  901. dom_object *intern, *nodeobj;
  902. int ret;
  903. long recursive = 0;
  904. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &id, dom_document_class_entry, &node, dom_node_class_entry, &recursive) == FAILURE) {
  905. return;
  906. }
  907. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  908. DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
  909. if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
  910. || nodep->type == XML_DOCUMENT_TYPE_NODE) {
  911. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot import: Node Type Not Supported");
  912. RETURN_FALSE;
  913. }
  914. if (nodep->doc == docp) {
  915. retnodep = nodep;
  916. } else {
  917. if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) {
  918. recursive = 2;
  919. }
  920. retnodep = xmlDocCopyNode(nodep, docp, recursive);
  921. if (!retnodep) {
  922. RETURN_FALSE;
  923. }
  924. if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
  925. xmlNsPtr nsptr = NULL;
  926. xmlNodePtr root = xmlDocGetRootElement(docp);
  927. nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href);
  928. if (nsptr == NULL) {
  929. int errorcode;
  930. nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix);
  931. }
  932. xmlSetNs(retnodep, nsptr);
  933. }
  934. }
  935. DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern);
  936. }
  937. /* }}} end dom_document_import_node */
  938. /* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value]);
  939. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
  940. Since: DOM Level 2
  941. */
  942. PHP_FUNCTION(dom_document_create_element_ns)
  943. {
  944. zval *id;
  945. xmlDocPtr docp;
  946. xmlNodePtr nodep = NULL;
  947. xmlNsPtr nsptr = NULL;
  948. int ret, uri_len = 0, name_len = 0, value_len = 0;
  949. char *uri, *name, *value = NULL;
  950. char *localname = NULL, *prefix = NULL;
  951. int errorcode;
  952. dom_object *intern;
  953. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
  954. return;
  955. }
  956. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  957. errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
  958. if (errorcode == 0) {
  959. if (xmlValidateName((xmlChar *) localname, 0) == 0) {
  960. nodep = xmlNewDocNode (docp, NULL, localname, value);
  961. if (nodep != NULL && uri != NULL) {
  962. nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri);
  963. if (nsptr == NULL) {
  964. nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
  965. }
  966. xmlSetNs(nodep, nsptr);
  967. }
  968. } else {
  969. errorcode = INVALID_CHARACTER_ERR;
  970. }
  971. }
  972. xmlFree(localname);
  973. if (prefix != NULL) {
  974. xmlFree(prefix);
  975. }
  976. if (errorcode != 0) {
  977. if (nodep != NULL) {
  978. xmlFreeNode(nodep);
  979. }
  980. php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
  981. RETURN_FALSE;
  982. }
  983. if (nodep == NULL) {
  984. RETURN_FALSE;
  985. }
  986. nodep->ns = nsptr;
  987. DOM_RET_OBJ(nodep, &ret, intern);
  988. }
  989. /* }}} end dom_document_create_element_ns */
  990. /* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName);
  991. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
  992. Since: DOM Level 2
  993. */
  994. PHP_FUNCTION(dom_document_create_attribute_ns)
  995. {
  996. zval *id;
  997. xmlDocPtr docp;
  998. xmlNodePtr nodep = NULL, root;
  999. xmlNsPtr nsptr;
  1000. int ret, uri_len = 0, name_len = 0;
  1001. char *uri, *name;
  1002. char *localname = NULL, *prefix = NULL;
  1003. dom_object *intern;
  1004. int errorcode;
  1005. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  1006. return;
  1007. }
  1008. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1009. root = xmlDocGetRootElement(docp);
  1010. if (root != NULL) {
  1011. errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
  1012. if (errorcode == 0) {
  1013. if (xmlValidateName((xmlChar *) localname, 0) == 0) {
  1014. nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
  1015. if (nodep != NULL && uri_len > 0) {
  1016. nsptr = xmlSearchNsByHref (nodep->doc, root, uri);
  1017. if (nsptr == NULL) {
  1018. nsptr = dom_get_ns(root, uri, &errorcode, prefix);
  1019. }
  1020. xmlSetNs(nodep, nsptr);
  1021. }
  1022. } else {
  1023. errorcode = INVALID_CHARACTER_ERR;
  1024. }
  1025. }
  1026. } else {
  1027. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element");
  1028. RETURN_FALSE;
  1029. }
  1030. xmlFree(localname);
  1031. if (prefix != NULL) {
  1032. xmlFree(prefix);
  1033. }
  1034. if (errorcode != 0) {
  1035. if (nodep != NULL) {
  1036. xmlFreeProp((xmlAttrPtr) nodep);
  1037. }
  1038. php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
  1039. RETURN_FALSE;
  1040. }
  1041. if (nodep == NULL) {
  1042. RETURN_FALSE;
  1043. }
  1044. DOM_RET_OBJ(nodep, &ret, intern);
  1045. }
  1046. /* }}} end dom_document_create_attribute_ns */
  1047. /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName);
  1048. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
  1049. Since: DOM Level 2
  1050. */
  1051. PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
  1052. {
  1053. zval *id;
  1054. xmlDocPtr docp;
  1055. int uri_len, name_len;
  1056. dom_object *intern, *namednode;
  1057. char *uri, *name;
  1058. xmlChar *local, *nsuri;
  1059. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  1060. return;
  1061. }
  1062. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1063. php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
  1064. namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
  1065. local = xmlCharStrndup(name, name_len);
  1066. nsuri = xmlCharStrndup(uri, uri_len);
  1067. dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
  1068. }
  1069. /* }}} end dom_document_get_elements_by_tag_name_ns */
  1070. /* {{{ proto DOMElement dom_document_get_element_by_id(string elementId);
  1071. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
  1072. Since: DOM Level 2
  1073. */
  1074. PHP_FUNCTION(dom_document_get_element_by_id)
  1075. {
  1076. zval *id;
  1077. xmlDocPtr docp;
  1078. xmlAttrPtr attrp;
  1079. int ret, idname_len;
  1080. dom_object *intern;
  1081. char *idname;
  1082. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) {
  1083. return;
  1084. }
  1085. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1086. attrp = xmlGetID(docp, (xmlChar *) idname);
  1087. if (attrp && attrp->parent) {
  1088. DOM_RET_OBJ((xmlNodePtr) attrp->parent, &ret, intern);
  1089. } else {
  1090. RETVAL_NULL();
  1091. }
  1092. }
  1093. /* }}} end dom_document_get_element_by_id */
  1094. /* {{{ proto DOMNode dom_document_adopt_node(DOMNode source);
  1095. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode
  1096. Since: DOM Level 3
  1097. */
  1098. PHP_FUNCTION(dom_document_adopt_node)
  1099. {
  1100. DOM_NOT_IMPLEMENTED();
  1101. }
  1102. /* }}} end dom_document_adopt_node */
  1103. /* {{{ proto void dom_document_normalize_document();
  1104. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
  1105. Since: DOM Level 3
  1106. */
  1107. PHP_FUNCTION(dom_document_normalize_document)
  1108. {
  1109. zval *id;
  1110. xmlDocPtr docp;
  1111. dom_object *intern;
  1112. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
  1113. return;
  1114. }
  1115. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1116. dom_normalize((xmlNodePtr) docp TSRMLS_CC);
  1117. }
  1118. /* }}} end dom_document_normalize_document */
  1119. /* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);
  1120. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode
  1121. Since: DOM Level 3
  1122. */
  1123. PHP_FUNCTION(dom_document_rename_node)
  1124. {
  1125. DOM_NOT_IMPLEMENTED();
  1126. }
  1127. /* }}} end dom_document_rename_node */
  1128. /* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */
  1129. PHP_METHOD(domdocument, __construct)
  1130. {
  1131. zval *id;
  1132. xmlDoc *docp = NULL, *olddoc;
  1133. dom_object *intern;
  1134. char *encoding, *version = NULL;
  1135. int encoding_len = 0, version_len = 0, refcount;
  1136. zend_error_handling error_handling;
  1137. zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
  1138. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) {
  1139. zend_restore_error_handling(&error_handling TSRMLS_CC);
  1140. return;
  1141. }
  1142. zend_restore_error_handling(&error_handling TSRMLS_CC);
  1143. docp = xmlNewDoc(version);
  1144. if (!docp) {
  1145. php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
  1146. RETURN_FALSE;
  1147. }
  1148. if (encoding_len > 0) {
  1149. docp->encoding = (const xmlChar*)xmlStrdup(encoding);
  1150. }
  1151. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  1152. if (intern != NULL) {
  1153. olddoc = (xmlDocPtr) dom_object_get_node(intern);
  1154. if (olddoc != NULL) {
  1155. php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
  1156. refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
  1157. if (refcount != 0) {
  1158. olddoc->_private = NULL;
  1159. }
  1160. }
  1161. intern->document = NULL;
  1162. if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC) == -1) {
  1163. RETURN_FALSE;
  1164. }
  1165. php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC);
  1166. }
  1167. }
  1168. /* }}} end DOMDocument::__construct */
  1169. char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) /* {{{ */
  1170. {
  1171. xmlURI *uri;
  1172. xmlChar *escsource;
  1173. char *file_dest;
  1174. int isFileUri = 0;
  1175. uri = xmlCreateURI();
  1176. escsource = xmlURIEscapeStr(source, ":");
  1177. xmlParseURIReference(uri, escsource);
  1178. xmlFree(escsource);
  1179. if (uri->scheme != NULL) {
  1180. /* absolute file uris - libxml only supports localhost or empty host */
  1181. #ifdef PHP_WIN32
  1182. if (strncasecmp(source, "file://",7) == 0 && ':' == source[8]) {
  1183. isFileUri = 1;
  1184. source += 7;
  1185. } else
  1186. #endif
  1187. if (strncasecmp(source, "file:///",8) == 0) {
  1188. isFileUri = 1;
  1189. #ifdef PHP_WIN32
  1190. source += 8;
  1191. #else
  1192. source += 7;
  1193. #endif
  1194. } else if (strncasecmp(source, "file://localhost/",17) == 0) {
  1195. isFileUri = 1;
  1196. #ifdef PHP_WIN32
  1197. source += 17;
  1198. #else
  1199. source += 16;
  1200. #endif
  1201. }
  1202. }
  1203. file_dest = source;
  1204. if ((uri->scheme == NULL || isFileUri)) {
  1205. /* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */
  1206. if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
  1207. xmlFreeURI(uri);
  1208. return NULL;
  1209. }
  1210. file_dest = resolved_path;
  1211. }
  1212. xmlFreeURI(uri);
  1213. return file_dest;
  1214. }
  1215. /* }}} */
  1216. static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int source_len, int options TSRMLS_DC) /* {{{ */
  1217. {
  1218. xmlDocPtr ret;
  1219. xmlParserCtxtPtr ctxt = NULL;
  1220. dom_doc_propsptr doc_props;
  1221. dom_object *intern;
  1222. php_libxml_ref_obj *document = NULL;
  1223. int validate, recover, resolve_externals, keep_blanks, substitute_ent;
  1224. int resolved_path_len;
  1225. int old_error_reporting = 0;
  1226. char *directory=NULL, resolved_path[MAXPATHLEN];
  1227. if (id != NULL) {
  1228. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  1229. document = intern->document;
  1230. }
  1231. doc_props = dom_get_doc_props(document);
  1232. validate = doc_props->validateonparse;
  1233. resolve_externals = doc_props->resolveexternals;
  1234. keep_blanks = doc_props->preservewhitespace;
  1235. substitute_ent = doc_props->substituteentities;
  1236. recover = doc_props->recover;
  1237. if (document == NULL) {
  1238. efree(doc_props);
  1239. }
  1240. xmlInitParser();
  1241. if (mode == DOM_LOAD_FILE) {
  1242. char *file_dest;
  1243. if (CHECK_NULL_PATH(source, source_len)) {
  1244. return NULL;
  1245. }
  1246. file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
  1247. if (file_dest) {
  1248. ctxt = xmlCreateFileParserCtxt(file_dest);
  1249. }
  1250. } else {
  1251. ctxt = xmlCreateMemoryParserCtxt(source, source_len);
  1252. }
  1253. if (ctxt == NULL) {
  1254. return(NULL);
  1255. }
  1256. /* If loading from memory, we need to set the base directory for the document */
  1257. if (mode != DOM_LOAD_FILE) {
  1258. #if HAVE_GETCWD
  1259. directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
  1260. #elif HAVE_GETWD
  1261. directory = VCWD_GETWD(resolved_path);
  1262. #endif
  1263. if (directory) {
  1264. if(ctxt->directory != NULL) {
  1265. xmlFree((char *) ctxt->directory);
  1266. }
  1267. resolved_path_len = strlen(resolved_path);
  1268. if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
  1269. resolved_path[resolved_path_len] = DEFAULT_SLASH;
  1270. resolved_path[++resolved_path_len] = '\0';
  1271. }
  1272. ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
  1273. }
  1274. }
  1275. ctxt->vctxt.error = php_libxml_ctx_error;
  1276. ctxt->vctxt.warning = php_libxml_ctx_warning;
  1277. if (ctxt->sax != NULL) {
  1278. ctxt->sax->error = php_libxml_ctx_error;
  1279. ctxt->sax->warning = php_libxml_ctx_warning;
  1280. }
  1281. if (validate && ! (options & XML_PARSE_DTDVALID)) {
  1282. options |= XML_PARSE_DTDVALID;
  1283. }
  1284. if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) {
  1285. options |= XML_PARSE_DTDATTR;
  1286. }
  1287. if (substitute_ent && ! (options & XML_PARSE_NOENT)) {
  1288. options |= XML_PARSE_NOENT;
  1289. }
  1290. if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) {
  1291. options |= XML_PARSE_NOBLANKS;
  1292. }
  1293. xmlCtxtUseOptions(ctxt, options);
  1294. ctxt->recovery = recover;
  1295. if (recover) {
  1296. old_error_reporting = EG(error_reporting);
  1297. EG(error_reporting) = old_error_reporting | E_WARNING;
  1298. }
  1299. xmlParseDocument(ctxt);
  1300. if (ctxt->wellFormed || recover) {
  1301. ret = ctxt->myDoc;
  1302. if (ctxt->recovery) {
  1303. EG(error_reporting) = old_error_reporting;
  1304. }
  1305. /* If loading from memory, set the base reference uri for the document */
  1306. if (ret && ret->URL == NULL && ctxt->directory != NULL) {
  1307. ret->URL = xmlStrdup(ctxt->directory);
  1308. }
  1309. } else {
  1310. ret = NULL;
  1311. xmlFreeDoc(ctxt->myDoc);
  1312. ctxt->myDoc = NULL;
  1313. }
  1314. xmlFreeParserCtxt(ctxt);
  1315. return(ret);
  1316. }
  1317. /* }}} */
  1318. /* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */
  1319. static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
  1320. zval *id;
  1321. xmlDoc *docp = NULL, *newdoc;
  1322. dom_doc_propsptr doc_prop;
  1323. dom_object *intern;
  1324. char *source;
  1325. int source_len, refcount, ret;
  1326. long options = 0;
  1327. id = getThis();
  1328. if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
  1329. id = NULL;
  1330. }
  1331. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
  1332. return;
  1333. }
  1334. if (!source_len) {
  1335. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
  1336. RETURN_FALSE;
  1337. }
  1338. newdoc = dom_document_parser(id, mode, source, source_len, options TSRMLS_CC);
  1339. if (!newdoc)
  1340. RETURN_FALSE;
  1341. if (id != NULL) {
  1342. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  1343. if (intern != NULL) {
  1344. docp = (xmlDocPtr) dom_object_get_node(intern);
  1345. doc_prop = NULL;
  1346. if (docp != NULL) {
  1347. php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
  1348. doc_prop = intern->document->doc_props;
  1349. intern->document->doc_props = NULL;
  1350. refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
  1351. if (refcount != 0) {
  1352. docp->_private = NULL;
  1353. }
  1354. }
  1355. intern->document = NULL;
  1356. if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
  1357. RETURN_FALSE;
  1358. }
  1359. intern->document->doc_props = doc_prop;
  1360. }
  1361. php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
  1362. RETURN_TRUE;
  1363. } else {
  1364. DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
  1365. }
  1366. }
  1367. /* }}} end dom_parser_document */
  1368. /* {{{ proto DOMNode dom_document_load(string source [, int options]);
  1369. URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load
  1370. Since: DOM Level 3
  1371. */
  1372. PHP_METHOD(domdocument, load)
  1373. {
  1374. dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
  1375. }
  1376. /* }}} end dom_document_load */
  1377. /* {{{ proto DOMNode dom_document_loadxml(string source [, int options]);
  1378. URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML
  1379. Since: DOM Level 3
  1380. */
  1381. PHP_METHOD(domdocument, loadXML)
  1382. {
  1383. dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
  1384. }
  1385. /* }}} end dom_document_loadxml */
  1386. /* {{{ proto int dom_document_save(string file);
  1387. Convenience method to save to file
  1388. */
  1389. PHP_FUNCTION(dom_document_save)
  1390. {
  1391. zval *id;
  1392. xmlDoc *docp;
  1393. int file_len = 0, bytes, format, saveempty = 0;
  1394. dom_object *intern;
  1395. dom_doc_propsptr doc_props;
  1396. char *file;
  1397. long options = 0;
  1398. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
  1399. return;
  1400. }
  1401. if (file_len == 0) {
  1402. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
  1403. RETURN_FALSE;
  1404. }
  1405. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1406. /* encoding handled by property on doc */
  1407. doc_props = dom_get_doc_props(intern->document);
  1408. format = doc_props->formatoutput;
  1409. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1410. saveempty = xmlSaveNoEmptyTags;
  1411. xmlSaveNoEmptyTags = 1;
  1412. }
  1413. bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
  1414. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1415. xmlSaveNoEmptyTags = saveempty;
  1416. }
  1417. if (bytes == -1) {
  1418. RETURN_FALSE;
  1419. }
  1420. RETURN_LONG(bytes);
  1421. }
  1422. /* }}} end dom_document_save */
  1423. /* {{{ proto string dom_document_savexml([node n]);
  1424. URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
  1425. Since: DOM Level 3
  1426. */
  1427. PHP_FUNCTION(dom_document_savexml)
  1428. {
  1429. zval *id, *nodep = NULL;
  1430. xmlDoc *docp;
  1431. xmlNode *node;
  1432. xmlBufferPtr buf;
  1433. xmlChar *mem;
  1434. dom_object *intern, *nodeobj;
  1435. dom_doc_propsptr doc_props;
  1436. int size, format, saveempty = 0;
  1437. long options = 0;
  1438. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, &options) == FAILURE) {
  1439. return;
  1440. }
  1441. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1442. doc_props = dom_get_doc_props(intern->document);
  1443. format = doc_props->formatoutput;
  1444. if (nodep != NULL) {
  1445. /* Dump contents of Node */
  1446. DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
  1447. if (node->doc != docp) {
  1448. php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1449. RETURN_FALSE;
  1450. }
  1451. buf = xmlBufferCreate();
  1452. if (!buf) {
  1453. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
  1454. RETURN_FALSE;
  1455. }
  1456. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1457. saveempty = xmlSaveNoEmptyTags;
  1458. xmlSaveNoEmptyTags = 1;
  1459. }
  1460. xmlNodeDump(buf, docp, node, 0, format);
  1461. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1462. xmlSaveNoEmptyTags = saveempty;
  1463. }
  1464. mem = (xmlChar*) xmlBufferContent(buf);
  1465. if (!mem) {
  1466. xmlBufferFree(buf);
  1467. RETURN_FALSE;
  1468. }
  1469. RETVAL_STRING(mem, 1);
  1470. xmlBufferFree(buf);
  1471. } else {
  1472. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1473. saveempty = xmlSaveNoEmptyTags;
  1474. xmlSaveNoEmptyTags = 1;
  1475. }
  1476. /* Encoding is handled from the encoding property set on the document */
  1477. xmlDocDumpFormatMemory(docp, &mem, &size, format);
  1478. if (options & LIBXML_SAVE_NOEMPTYTAG) {
  1479. xmlSaveNoEmptyTags = saveempty;
  1480. }
  1481. if (!size || !mem) {
  1482. RETURN_FALSE;
  1483. }
  1484. RETVAL_STRINGL(mem, size, 1);
  1485. xmlFree(mem);
  1486. }
  1487. }
  1488. /* }}} end dom_document_savexml */
  1489. static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) /* {{{ */
  1490. {
  1491. xmlNodePtr xincnode;
  1492. xincnode = cur;
  1493. cur = cur->next;
  1494. xmlUnlinkNode(xincnode);
  1495. php_libxml_node_free_resource(xincnode TSRMLS_CC);
  1496. return cur;
  1497. }
  1498. /* }}} */
  1499. static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) /* {{{ */
  1500. {
  1501. while(cur) {
  1502. if (cur->type == XML_XINCLUDE_START) {
  1503. cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
  1504. /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
  1505. while(cur && cur->type != XML_XINCLUDE_END) {
  1506. /* remove xinclude processing nodes from recursive xincludes */
  1507. if (cur->type == XML_ELEMENT_NODE) {
  1508. php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
  1509. }
  1510. cur = cur->next;
  1511. }
  1512. if (cur && cur->type == XML_XINCLUDE_END) {
  1513. cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
  1514. }
  1515. } else {
  1516. if (cur->type == XML_ELEMENT_NODE) {
  1517. php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
  1518. }
  1519. cur = cur->next;
  1520. }
  1521. }
  1522. }
  1523. /* }}} */
  1524. /* {{{ proto int dom_document_xinclude([int options])
  1525. Substitutues xincludes in a DomDocument */
  1526. PHP_FUNCTION(dom_document_xinclude)
  1527. {
  1528. zval *id;
  1529. xmlDoc *docp;
  1530. xmlNodePtr root;
  1531. long flags = 0;
  1532. int err;
  1533. dom_object *intern;
  1534. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) {
  1535. return;
  1536. }
  1537. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1538. err = xmlXIncludeProcessFlags(docp, flags);
  1539. /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
  1540. are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
  1541. but are not wanted in resulting document - must be done even if err as it could fail after
  1542. having processed some xincludes */
  1543. root = (xmlNodePtr) docp->children;
  1544. while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) {
  1545. root = root->next;
  1546. }
  1547. if (root) {
  1548. php_dom_remove_xinclude_nodes(root TSRMLS_CC);
  1549. }
  1550. if (err) {
  1551. RETVAL_LONG(err);
  1552. } else {
  1553. RETVAL_FALSE;
  1554. }
  1555. }
  1556. /* }}} */
  1557. /* {{{ proto boolean dom_document_validate();
  1558. Since: DOM extended
  1559. */
  1560. PHP_FUNCTION(dom_document_validate)
  1561. {
  1562. zval *id;
  1563. xmlDoc *docp;
  1564. dom_object *intern;
  1565. xmlValidCtxt *cvp;
  1566. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
  1567. return;
  1568. }
  1569. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1570. cvp = xmlNewValidCtxt();
  1571. cvp->userData = NULL;
  1572. cvp->error = (xmlValidityErrorFunc) php_libxml_error_handler;
  1573. cvp->warning = (xmlValidityErrorFunc) php_libxml_error_handler;
  1574. if (xmlValidateDocument(cvp, docp)) {
  1575. RETVAL_TRUE;
  1576. } else {
  1577. RETVAL_FALSE;
  1578. }
  1579. xmlFreeValidCtxt(cvp);
  1580. }
  1581. /* }}} */
  1582. #if defined(LIBXML_SCHEMAS_ENABLED)
  1583. static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
  1584. {
  1585. zval *id;
  1586. xmlDoc *docp;
  1587. dom_object *intern;
  1588. char *source = NULL, *valid_file = NULL;
  1589. int source_len = 0, valid_opts = 0;
  1590. long flags = 0;
  1591. xmlSchemaParserCtxtPtr parser;
  1592. xmlSchemaPtr sptr;
  1593. xmlSchemaValidCtxtPtr vptr;
  1594. int is_valid;
  1595. char resolved_path[MAXPATHLEN + 1];
  1596. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &source, &source_len, &flags) == FAILURE) {
  1597. return;
  1598. }
  1599. if (source_len == 0) {
  1600. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
  1601. RETURN_FALSE;
  1602. }
  1603. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1604. switch (type) {
  1605. case DOM_LOAD_FILE:
  1606. if (CHECK_NULL_PATH(source, source_len)) {
  1607. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
  1608. RETURN_FALSE;
  1609. }
  1610. valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
  1611. if (!valid_file) {
  1612. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
  1613. RETURN_FALSE;
  1614. }
  1615. parser = xmlSchemaNewParserCtxt(valid_file);
  1616. break;
  1617. case DOM_LOAD_STRING:
  1618. parser = xmlSchemaNewMemParserCtxt(source, source_len);
  1619. /* If loading from memory, we need to set the base directory for the document
  1620. but it is not apparent how to do that for schema's */
  1621. break;
  1622. default:
  1623. return;
  1624. }
  1625. xmlSchemaSetParserErrors(parser,
  1626. (xmlSchemaValidityErrorFunc) php_libxml_error_handler,
  1627. (xmlSchemaValidityWarningFunc) php_libxml_error_handler,
  1628. parser);
  1629. sptr = xmlSchemaParse(parser);
  1630. xmlSchemaFreeParserCtxt(parser);
  1631. if (!sptr) {
  1632. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema");
  1633. RETURN_FALSE;
  1634. }
  1635. docp = (xmlDocPtr) dom_object_get_node(intern);
  1636. vptr = xmlSchemaNewValidCtxt(sptr);
  1637. if (!vptr) {
  1638. xmlSchemaFree(sptr);
  1639. php_error(E_ERROR, "Invalid Schema Validation Context");
  1640. RETURN_FALSE;
  1641. }
  1642. #if LIBXML_VERSION >= 20614
  1643. if (flags & XML_SCHEMA_VAL_VC_I_CREATE) {
  1644. valid_opts |= XML_SCHEMA_VAL_VC_I_CREATE;
  1645. }
  1646. #endif
  1647. xmlSchemaSetValidOptions(vptr, valid_opts);
  1648. xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
  1649. is_valid = xmlSchemaValidateDoc(vptr, docp);
  1650. xmlSchemaFree(sptr);
  1651. xmlSchemaFreeValidCtxt(vptr);
  1652. if (is_valid == 0) {
  1653. RETURN_TRUE;
  1654. } else {
  1655. RETURN_FALSE;
  1656. }
  1657. }
  1658. /* }}} */
  1659. /* {{{ proto boolean dom_document_schema_validate_file(string filename, int flags); */
  1660. PHP_FUNCTION(dom_document_schema_validate_file)
  1661. {
  1662. _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
  1663. }
  1664. /* }}} end dom_document_schema_validate_file */
  1665. /* {{{ proto boolean dom_document_schema_validate(string source, int flags); */
  1666. PHP_FUNCTION(dom_document_schema_validate_xml)
  1667. {
  1668. _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
  1669. }
  1670. /* }}} end dom_document_schema_validate */
  1671. static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
  1672. {
  1673. zval *id;
  1674. xmlDoc *docp;
  1675. dom_object *intern;
  1676. char *source = NULL, *valid_file = NULL;
  1677. int source_len = 0;
  1678. xmlRelaxNGParserCtxtPtr parser;
  1679. xmlRelaxNGPtr sptr;
  1680. xmlRelaxNGValidCtxtPtr vptr;
  1681. int is_valid;
  1682. char resolved_path[MAXPATHLEN + 1];
  1683. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
  1684. return;
  1685. }
  1686. if (source_len == 0) {
  1687. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
  1688. RETURN_FALSE;
  1689. }
  1690. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1691. switch (type) {
  1692. case DOM_LOAD_FILE:
  1693. if (CHECK_NULL_PATH(source, source_len)) {
  1694. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
  1695. RETURN_FALSE;
  1696. }
  1697. valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
  1698. if (!valid_file) {
  1699. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
  1700. RETURN_FALSE;
  1701. }
  1702. parser = xmlRelaxNGNewParserCtxt(valid_file);
  1703. break;
  1704. case DOM_LOAD_STRING:
  1705. parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
  1706. /* If loading from memory, we need to set the base directory for the document
  1707. but it is not apparent how to do that for schema's */
  1708. break;
  1709. default:
  1710. return;
  1711. }
  1712. xmlRelaxNGSetParserErrors(parser,
  1713. (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
  1714. (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
  1715. parser);
  1716. sptr = xmlRelaxNGParse(parser);
  1717. xmlRelaxNGFreeParserCtxt(parser);
  1718. if (!sptr) {
  1719. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG");
  1720. RETURN_FALSE;
  1721. }
  1722. docp = (xmlDocPtr) dom_object_get_node(intern);
  1723. vptr = xmlRelaxNGNewValidCtxt(sptr);
  1724. if (!vptr) {
  1725. xmlRelaxNGFree(sptr);
  1726. php_error(E_ERROR, "Invalid RelaxNG Validation Context");
  1727. RETURN_FALSE;
  1728. }
  1729. xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
  1730. is_valid = xmlRelaxNGValidateDoc(vptr, docp);
  1731. xmlRelaxNGFree(sptr);
  1732. xmlRelaxNGFreeValidCtxt(vptr);
  1733. if (is_valid == 0) {
  1734. RETURN_TRUE;
  1735. } else {
  1736. RETURN_FALSE;
  1737. }
  1738. }
  1739. /* }}} */
  1740. /* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */
  1741. PHP_FUNCTION(dom_document_relaxNG_validate_file)
  1742. {
  1743. _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
  1744. }
  1745. /* }}} end dom_document_relaxNG_validate_file */
  1746. /* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */
  1747. PHP_FUNCTION(dom_document_relaxNG_validate_xml)
  1748. {
  1749. _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
  1750. }
  1751. /* }}} end dom_document_relaxNG_validate_xml */
  1752. #endif
  1753. #if defined(LIBXML_HTML_ENABLED)
  1754. static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
  1755. {
  1756. zval *id;
  1757. xmlDoc *docp = NULL, *newdoc;
  1758. dom_object *intern;
  1759. dom_doc_propsptr doc_prop;
  1760. char *source;
  1761. int source_len, refcount, ret;
  1762. long options = 0;
  1763. htmlParserCtxtPtr ctxt;
  1764. id = getThis();
  1765. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
  1766. return;
  1767. }
  1768. if (!source_len) {
  1769. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
  1770. RETURN_FALSE;
  1771. }
  1772. if (mode == DOM_LOAD_FILE) {
  1773. if (CHECK_NULL_PATH(source, source_len)) {
  1774. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid file source");
  1775. RETURN_FALSE;
  1776. }
  1777. ctxt = htmlCreateFileParserCtxt(source, NULL);
  1778. } else {
  1779. source_len = xmlStrlen(source);
  1780. ctxt = htmlCreateMemoryParserCtxt(source, source_len);
  1781. }
  1782. if (!ctxt) {
  1783. RETURN_FALSE;
  1784. }
  1785. if (options) {
  1786. htmlCtxtUseOptions(ctxt, options);
  1787. }
  1788. ctxt->vctxt.error = php_libxml_ctx_error;
  1789. ctxt->vctxt.warning = php_libxml_ctx_warning;
  1790. if (ctxt->sax != NULL) {
  1791. ctxt->sax->error = php_libxml_ctx_error;
  1792. ctxt->sax->warning = php_libxml_ctx_warning;
  1793. }
  1794. htmlParseDocument(ctxt);
  1795. newdoc = ctxt->myDoc;
  1796. htmlFreeParserCtxt(ctxt);
  1797. if (!newdoc)
  1798. RETURN_FALSE;
  1799. if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
  1800. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  1801. if (intern != NULL) {
  1802. docp = (xmlDocPtr) dom_object_get_node(intern);
  1803. doc_prop = NULL;
  1804. if (docp != NULL) {
  1805. php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
  1806. doc_prop = intern->document->doc_props;
  1807. intern->document->doc_props = NULL;
  1808. refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
  1809. if (refcount != 0) {
  1810. docp->_private = NULL;
  1811. }
  1812. }
  1813. intern->document = NULL;
  1814. if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
  1815. RETURN_FALSE;
  1816. }
  1817. intern->document->doc_props = doc_prop;
  1818. }
  1819. php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
  1820. RETURN_TRUE;
  1821. } else {
  1822. DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
  1823. }
  1824. }
  1825. /* }}} */
  1826. /* {{{ proto DOMNode dom_document_load_html_file(string source);
  1827. Since: DOM extended
  1828. */
  1829. PHP_METHOD(domdocument, loadHTMLFile)
  1830. {
  1831. dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
  1832. }
  1833. /* }}} end dom_document_load_html_file */
  1834. /* {{{ proto DOMNode dom_document_load_html(string source);
  1835. Since: DOM extended
  1836. */
  1837. PHP_METHOD(domdocument, loadHTML)
  1838. {
  1839. dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
  1840. }
  1841. /* }}} end dom_document_load_html */
  1842. /* {{{ proto int dom_document_save_html_file(string file);
  1843. Convenience method to save to file as html
  1844. */
  1845. PHP_FUNCTION(dom_document_save_html_file)
  1846. {
  1847. zval *id;
  1848. xmlDoc *docp;
  1849. int file_len, bytes, format;
  1850. dom_object *intern;
  1851. dom_doc_propsptr doc_props;
  1852. char *file;
  1853. const char *encoding;
  1854. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
  1855. return;
  1856. }
  1857. if (file_len == 0) {
  1858. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
  1859. RETURN_FALSE;
  1860. }
  1861. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1862. encoding = (const char *) htmlGetMetaEncoding(docp);
  1863. doc_props = dom_get_doc_props(intern->document);
  1864. format = doc_props->formatoutput;
  1865. bytes = htmlSaveFileFormat(file, docp, encoding, format);
  1866. if (bytes == -1) {
  1867. RETURN_FALSE;
  1868. }
  1869. RETURN_LONG(bytes);
  1870. }
  1871. /* }}} end dom_document_save_html_file */
  1872. /* {{{ proto string dom_document_save_html();
  1873. Convenience method to output as html
  1874. */
  1875. PHP_FUNCTION(dom_document_save_html)
  1876. {
  1877. zval *id, *nodep = NULL;
  1878. xmlDoc *docp;
  1879. xmlNode *node;
  1880. xmlBufferPtr buf;
  1881. dom_object *intern, *nodeobj;
  1882. xmlChar *mem = NULL;
  1883. int size = 0, format;
  1884. dom_doc_propsptr doc_props;
  1885. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
  1886. "O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry)
  1887. == FAILURE) {
  1888. return;
  1889. }
  1890. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1891. doc_props = dom_get_doc_props(intern->document);
  1892. format = doc_props->formatoutput;
  1893. if (nodep != NULL) {
  1894. /* Dump contents of Node */
  1895. DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
  1896. if (node->doc != docp) {
  1897. php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1898. RETURN_FALSE;
  1899. }
  1900. buf = xmlBufferCreate();
  1901. if (!buf) {
  1902. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
  1903. RETURN_FALSE;
  1904. }
  1905. if (node->type == XML_DOCUMENT_FRAG_NODE) {
  1906. int one_size;
  1907. for (node = node->children; node; node = node->next) {
  1908. one_size = htmlNodeDump(buf, docp, node);
  1909. if (one_size >= 0) {
  1910. size += one_size;
  1911. } else {
  1912. size = -1;
  1913. break;
  1914. }
  1915. }
  1916. } else {
  1917. size = htmlNodeDump(buf, docp, node);
  1918. }
  1919. if (size >= 0) {
  1920. mem = (xmlChar*) xmlBufferContent(buf);
  1921. if (!mem) {
  1922. RETVAL_FALSE;
  1923. } else {
  1924. RETVAL_STRINGL((const char*) mem, size, 1);
  1925. }
  1926. } else {
  1927. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error dumping HTML node");
  1928. RETVAL_FALSE;
  1929. }
  1930. xmlBufferFree(buf);
  1931. } else {
  1932. #if LIBXML_VERSION >= 20623
  1933. htmlDocDumpMemoryFormat(docp, &mem, &size, format);
  1934. #else
  1935. htmlDocDumpMemory(docp, &mem, &size);
  1936. #endif
  1937. if (!size || !mem) {
  1938. RETVAL_FALSE;
  1939. } else {
  1940. RETVAL_STRINGL((const char*) mem, size, 1);
  1941. }
  1942. if (mem)
  1943. xmlFree(mem);
  1944. }
  1945. }
  1946. /* }}} end dom_document_save_html */
  1947. #endif /* defined(LIBXML_HTML_ENABLED) */
  1948. /* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass);
  1949. Register extended class used to create base node type */
  1950. PHP_METHOD(domdocument, registerNodeClass)
  1951. {
  1952. zval *id;
  1953. xmlDoc *docp;
  1954. char *baseclass = NULL, *extendedclass = NULL;
  1955. int baseclass_len = 0, extendedclass_len = 0;
  1956. zend_class_entry *basece = NULL, *ce = NULL;
  1957. dom_object *intern;
  1958. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, dom_document_class_entry, &baseclass, &baseclass_len, &extendedclass, &extendedclass_len) == FAILURE) {
  1959. return;
  1960. }
  1961. if (baseclass_len) {
  1962. zend_class_entry **pce;
  1963. if (zend_lookup_class(baseclass, baseclass_len, &pce TSRMLS_CC) == FAILURE) {
  1964. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", baseclass);
  1965. return;
  1966. }
  1967. basece = *pce;
  1968. }
  1969. if (basece == NULL || ! instanceof_function(basece, dom_node_class_entry TSRMLS_CC)) {
  1970. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from DOMNode.", baseclass);
  1971. return;
  1972. }
  1973. if (extendedclass_len) {
  1974. zend_class_entry **pce;
  1975. if (zend_lookup_class(extendedclass, extendedclass_len, &pce TSRMLS_CC) == FAILURE) {
  1976. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", extendedclass);
  1977. }
  1978. ce = *pce;
  1979. }
  1980. if (ce == NULL || instanceof_function(ce, basece TSRMLS_CC)) {
  1981. DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
  1982. if (dom_set_doc_classmap(intern->document, basece, ce TSRMLS_CC) == FAILURE) {
  1983. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be registered.", extendedclass);
  1984. }
  1985. RETURN_TRUE;
  1986. } else {
  1987. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from %s.", extendedclass, baseclass);
  1988. }
  1989. RETURN_FALSE;
  1990. }
  1991. /* }}} */
  1992. #endif /* HAVE_LIBXML && HAVE_DOM */
  1993. /*
  1994. * Local variables:
  1995. * tab-width: 4
  1996. * c-basic-offset: 4
  1997. * End:
  1998. * vim600: noet sw=4 ts=4 fdm=marker
  1999. * vim<600: noet sw=4 ts=4
  2000. */