add simplexml_import_dom
This is needed for Symphony. I copied the zend implementation and then cargocult programmed the rest from the other 2 functions in the file. Closes #789
Esse commit está contido em:
+161
-11
@@ -3311,6 +3311,161 @@ class DirectoryIterator extends SplFileInfo implements Traversable,
|
||||
}
|
||||
|
||||
// This doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/class.filesystemiterator.php )
|
||||
*
|
||||
* The Filesystem iterator
|
||||
*
|
||||
*/
|
||||
class FilesystemIterator extends DirectoryIterator
|
||||
implements SeekableIterator, Traversable, Iterator {
|
||||
|
||||
const CURRENT_AS_PATHNAME = 32;
|
||||
const CURRENT_AS_FILEINFO = 0;
|
||||
const CURRENT_AS_SELF = 16;
|
||||
const CURRENT_MODE_MASK = 240;
|
||||
const KEY_AS_PATHNAME = 0;
|
||||
const KEY_AS_FILENAME = 256;
|
||||
const FOLLOW_SYMLINKS = 512;
|
||||
const KEY_MODE_MASK = 3840;
|
||||
const NEW_CURRENT_AND_KEY = 256;
|
||||
const SKIP_DOTS = 4096;
|
||||
const UNIX_PATHS = 8192;
|
||||
|
||||
private $flags;
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.construct.php
|
||||
* )
|
||||
*
|
||||
* Constructs a new filesystem iterator from the path.
|
||||
*
|
||||
* @path mixed The path of the filesystem item to be iterated over.
|
||||
* @flags mixed Flags may be provided which will affect the behavior
|
||||
* of some methods. A list of the flags can found under
|
||||
* FilesystemIterator predefined constants. They can
|
||||
* also be set later with
|
||||
* FilesystemIterator::setFlags()
|
||||
*
|
||||
* @return mixed No value is returned.
|
||||
*/
|
||||
public function __construct(string $path, int $flags = null) {
|
||||
parent::__construct($path);
|
||||
if ($flags === null) {
|
||||
$flags = FilesystemIterator::KEY_AS_PATHNAME |
|
||||
FilesystemIterator::CURRENT_AS_FILEINFO |
|
||||
FilesystemIterator::SKIP_DOTS;
|
||||
}
|
||||
$this->flags = $flags;
|
||||
$this->goPastDotsIfNeeded();
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.current.php )
|
||||
*
|
||||
* Get file information of the current element.
|
||||
*
|
||||
* @return mixed The filename, file information, or $this depending
|
||||
* on the set flags. See the FilesystemIterator
|
||||
* constants.
|
||||
*/
|
||||
public function current() {
|
||||
$f = parent::current();
|
||||
if ($this->flags & FilesystemIterator::CURRENT_AS_PATHNAME) {
|
||||
return $f->getPathname();
|
||||
} else if ($this->flags & FilesystemIterator::CURRENT_AS_SELF) {
|
||||
return $this;
|
||||
}
|
||||
// FilesystemIterator::CURRENT_AS_FILEINFO == 0
|
||||
return $f;
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.getflags.php
|
||||
* )
|
||||
*
|
||||
* Gets the handling flags, as set in FilesystemIterator::__construct() or
|
||||
* FilesystemIterator::setFlags().
|
||||
*
|
||||
* @return mixed The integer value of the set flags.
|
||||
*/
|
||||
public function getFlags() {
|
||||
return $this->flags;
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.key.php )
|
||||
*
|
||||
*
|
||||
* @return mixed Returns the pathname or filename depending on the
|
||||
* set flags. See the FilesystemIterator constants.
|
||||
*/
|
||||
public function key() {
|
||||
if ($this->flags & FilesystemIterator::KEY_AS_FILENAME) {
|
||||
return parent::current()->getFileName();
|
||||
}
|
||||
// FilesystemIterator::KEY_AS_PATHNAME == 0
|
||||
return parent::current()->getPathName();
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.next.php )
|
||||
*
|
||||
* Move to the next file.
|
||||
*
|
||||
* @return mixed No value is returned.
|
||||
*/
|
||||
public function next() {
|
||||
parent::next();
|
||||
$this->goPastDotsIfNeeded();
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.rewind.php )
|
||||
*
|
||||
* Rewinds the directory back to the start.
|
||||
*
|
||||
* @return mixed No value is returned.
|
||||
*/
|
||||
public function rewind() {
|
||||
parent::rewind();
|
||||
$this->goPastDotsIfNeeded();
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from http://php.net/manual/en/filesystemiterator.setflags.php
|
||||
* )
|
||||
*
|
||||
* Sets handling flags.
|
||||
*
|
||||
* @flags mixed The handling flags to set. See the
|
||||
* FilesystemIterator constants.
|
||||
*
|
||||
* @return mixed No value is returned.
|
||||
*/
|
||||
public function setFlags(int $flags) {
|
||||
$this->flags = $flags;
|
||||
}
|
||||
|
||||
private function goPastDotsIfNeeded() {
|
||||
if ($this->flags & FilesystemIterator::SKIP_DOTS) {
|
||||
$f = parent::current();
|
||||
while ($f && $f->isDot()) {
|
||||
parent::next();
|
||||
$f = parent::current();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do NOT modifiy this doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
* ( excerpt from
|
||||
* http://php.net/manual/en/class.recursivedirectoryiterator.php )
|
||||
@@ -3319,15 +3474,8 @@ class DirectoryIterator extends SplFileInfo implements Traversable,
|
||||
* recursively over filesystem directories.
|
||||
*
|
||||
*/
|
||||
class RecursiveDirectoryIterator extends DirectoryIterator
|
||||
class RecursiveDirectoryIterator extends FilesystemIterator
|
||||
implements RecursiveIterator {
|
||||
|
||||
const CURRENT_AS_SELF = 0x0;
|
||||
const CURRENT_AS_FILEINFO = 0x00000010;
|
||||
const CURRENT_AS_PATHNAME = 0x00000020;
|
||||
const KEY_AS_PATHNAME = 0x0;
|
||||
const KEY_AS_FILENAME = 0x00000100;
|
||||
const NEW_CURRENT_AND_KEY = 0x00000110;
|
||||
|
||||
// This doc comment block generated by idl/sysdoc.php
|
||||
/**
|
||||
@@ -3346,8 +3494,11 @@ class RecursiveDirectoryIterator extends DirectoryIterator
|
||||
* @return mixed Returns the newly created
|
||||
* RecursiveDirectoryIterator.
|
||||
*/
|
||||
function __construct($path,
|
||||
$flags = RecursiveDirectoryIterator::CURRENT_AS_FILEINFO) {
|
||||
function __construct($path, $flags = null) {
|
||||
if ($flags === null) {
|
||||
$flags = FilesystemIterator::KEY_AS_PATHNAME |
|
||||
FilesystemIterator::CURRENT_AS_FILEINFO;
|
||||
}
|
||||
if (!hphp_recursivedirectoryiterator___construct($this, $path, $flags)) {
|
||||
throw new UnexpectedValueException(
|
||||
"RecursiveDirectoryIterator::__construct($path): failed to open dir");
|
||||
@@ -3462,7 +3613,6 @@ class RecursiveDirectoryIterator extends DirectoryIterator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helpers
|
||||
|
||||
|
||||
@@ -83,6 +83,30 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "simplexml_import_dom",
|
||||
"desc": "This function takes a node of a DOM document and makes it into a SimpleXML node. This new object can then be used as a native SimpleXML element.",
|
||||
"flags": [
|
||||
"HasDocComment"
|
||||
],
|
||||
"return": {
|
||||
"type": "Variant",
|
||||
"desc": "Returns a SimpleXMLElement or FALSE on failure."
|
||||
},
|
||||
"args": [
|
||||
{
|
||||
"name": "node",
|
||||
"type": "Variant",
|
||||
"desc": "A DOM Element node"
|
||||
},
|
||||
{
|
||||
"name": "class_name",
|
||||
"type": "Variant",
|
||||
"value": "\"SimpleXMLElement\"",
|
||||
"desc": "You may use this optional parameter so that simplexml_load_file() will return an object of the specified class. That class should extend the SimpleXMLElement class."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "libxml_get_errors",
|
||||
"desc": "Retrieve array of errors.",
|
||||
@@ -699,4 +723,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#include "hphp/runtime/ext/ext_simplexml.h"
|
||||
#include "hphp/runtime/ext/ext_file.h"
|
||||
#include "hphp/runtime/ext/ext_class.h"
|
||||
#include "hphp/runtime/ext/ext_domdocument.h"
|
||||
#include "hphp/runtime/base/class_info.h"
|
||||
#include "hphp/runtime/base/util/request_local.h"
|
||||
|
||||
#include "hphp/system/lib/systemlib.h"
|
||||
|
||||
#ifndef LIBXML2_NEW_BUFFER
|
||||
@@ -42,13 +42,19 @@ public:
|
||||
// overriding ResourceData
|
||||
virtual CStrRef o_getClassNameHook() const { return s_class_name; }
|
||||
|
||||
XmlDocWrapper(xmlDocPtr doc, CStrRef cls)
|
||||
: m_doc(doc), m_cls(cls) { }
|
||||
XmlDocWrapper(xmlDocPtr doc, CStrRef cls, Object domNode = nullptr)
|
||||
: m_doc(doc), m_cls(cls), m_domNode(domNode) {
|
||||
if (!domNode.isNull()) {
|
||||
DEBUG_ONLY c_DOMNode *domnode = domNode.getTyped<c_DOMNode>();
|
||||
assert(!domnode || domnode->m_node == (xmlNodePtr) doc);
|
||||
}
|
||||
}
|
||||
|
||||
CStrRef getClass() { return m_cls; }
|
||||
|
||||
void sweep() {
|
||||
if (m_doc) {
|
||||
// if m_domNode isn't null, then he owns the m_doc. Otherwise, I own it
|
||||
if (m_doc && m_domNode.isNull()) {
|
||||
xmlFreeDoc(m_doc);
|
||||
}
|
||||
}
|
||||
@@ -56,6 +62,8 @@ public:
|
||||
private:
|
||||
xmlDocPtr m_doc;
|
||||
String m_cls;
|
||||
// Hold onto the original owner of the doc so it doesn't get free()d.
|
||||
Object m_domNode;
|
||||
};
|
||||
IMPLEMENT_OBJECT_ALLOCATION_NO_DEFAULT_SWEEP(XmlDocWrapper)
|
||||
|
||||
@@ -236,6 +244,45 @@ static void add_registered_namespaces(Array &out, xmlNodePtr node,
|
||||
|
||||
static StaticString s_SimpleXMLElement("SimpleXMLElement");
|
||||
|
||||
Variant f_simplexml_import_dom(CVarRef node,
|
||||
CVarRef class_name /* = "SimpleXMLElement" */) {
|
||||
|
||||
if (!node.isObject()) {
|
||||
raise_warning(
|
||||
"simplexml_import_dom() expects parameter 1 to be object"
|
||||
);
|
||||
return uninit_null();
|
||||
}
|
||||
if (!class_name.isString()) {
|
||||
raise_warning(
|
||||
"simplexml_import_dom() expects parameter 2 to be string"
|
||||
);
|
||||
return uninit_null();
|
||||
}
|
||||
|
||||
c_DOMNode *domnode = node.asCObjRef().getTyped<c_DOMNode>();
|
||||
xmlNodePtr nodep = domnode->m_node;
|
||||
|
||||
if (nodep) {
|
||||
if (nodep->doc == nullptr) {
|
||||
raise_warning("Imported Node must have associated Document");
|
||||
return uninit_null();
|
||||
}
|
||||
if (nodep->type == XML_DOCUMENT_NODE ||
|
||||
nodep->type == XML_HTML_DOCUMENT_NODE) {
|
||||
nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodep && nodep->type == XML_ELEMENT_NODE) {
|
||||
Object obj = Object(NEWOBJ(XmlDocWrapper)(nodep->doc, class_name, node));
|
||||
return create_element(obj, nodep, String(), false);
|
||||
} else {
|
||||
raise_warning("Invalid Nodetype to import");
|
||||
return uninit_null();
|
||||
}
|
||||
}
|
||||
|
||||
Variant f_simplexml_load_string(CStrRef data,
|
||||
CStrRef class_name /* = "SimpleXMLElement" */,
|
||||
int64_t options /* = 0 */,
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Variant f_simplexml_import_dom(CVarRef node,
|
||||
CVarRef class_name = "SimpleXMLElement");
|
||||
Variant f_simplexml_load_string(CStrRef data, CStrRef class_name = "SimpleXMLElement", int64_t options = 0, CStrRef ns = "", bool is_prefix = false);
|
||||
Variant f_simplexml_load_file(CStrRef filename, CStrRef class_name = "SimpleXMLElement", int64_t options = 0, CStrRef ns = "", bool is_prefix = false);
|
||||
Variant f_libxml_get_errors();
|
||||
|
||||
@@ -5901,6 +5901,13 @@ const char *g_class_map[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(const char *)0x10006040, "simplexml_import_dom", "", (const char*)0, (const char*)0,
|
||||
"/**\n * ( excerpt from\n * http://php.net/manual/en/function.simplexml-import-dom.php )\n *\n * This function takes a node of a DOM document and makes it into a\n * SimpleXML node. This new object can then be used as a native SimpleXML\n * element.\n *\n * @node mixed A DOM Element node\n * @class_name mixed You may use this optional parameter so that\n * simplexml_load_file() will return an object of the\n * specified class. That class should extend the\n * SimpleXMLElement class.\n *\n * @return mixed Returns a SimpleXMLElement or FALSE on failure.\n */",
|
||||
(const char *)0xffffffff /* KindOfUnknown: $t: Variant */, (const char *)0x2000, "node", "", (const char *)0xffffffff /* KindOfUnknown: $t: Variant */, "", (const char *)0, "", (const char *)0, NULL,
|
||||
(const char *)0x2000, "class_name", "", (const char *)0xffffffff /* KindOfUnknown: $t: Variant */, "s:16:\"SimpleXMLElement\";", (const char *)24, "\"SimpleXMLElement\"", (const char *)18, NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(const char *)0x10006040, "libxml_get_errors", "", (const char*)0, (const char*)0,
|
||||
"/**\n * ( excerpt from http://php.net/manual/en/function.libxml-get-errors.php )\n *\n * Retrieve array of errors.\n *\n * @return mixed Returns an array with LibXMLError objects if there\n * are any errors in the buffer, or an empty array\n * otherwise.\n */",
|
||||
(const char *)0xffffffff /* KindOfUnknown: $t: Variant */, NULL,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
$string = <<<EOT
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entry xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:other="http://other.w3.org/other" >
|
||||
<id>uYG7-sPwjFg</id>
|
||||
<published>2009-05-17T18:29:31.000Z</published>
|
||||
</entry>
|
||||
EOT;
|
||||
|
||||
$doc = new DOMDocument;
|
||||
$doc->loadXML($string);
|
||||
|
||||
$xml = simplexml_import_dom($doc);
|
||||
$xml->registerXPathNamespace('atom', "http://www.w3.org/2005/Atom");
|
||||
$nodes = $xml->xpath('//atom:entry/atom:published/text()');
|
||||
foreach ($nodes as $node) {
|
||||
print $node;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
2009-05-17T18:29:31.000Z
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
function main() {
|
||||
$dom = new domDocument;
|
||||
$string = <<<END
|
||||
<a>
|
||||
<b>c</b>
|
||||
</a>
|
||||
END;
|
||||
|
||||
$dom->loadXML($string);
|
||||
$s = simplexml_import_dom($dom);
|
||||
$dom = null;
|
||||
var_dump((string) $s->b);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1 @@
|
||||
string(1) "c"
|
||||
@@ -0,0 +1,10 @@
|
||||
<books>
|
||||
<book>
|
||||
<title>The Grapes of Wrath</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
<book>
|
||||
<title>The Pearl</title>
|
||||
<author>John Steinbeck</author>
|
||||
</book>
|
||||
</books>
|
||||
Referência em uma Nova Issue
Bloquear um usuário