Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 8 Feb 2017 */ namespace IPS\Text; /* To prevent PHP errors (extending class does not exist) revealing path */ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * DOM Parser */ class _DOMParser { /** * @brief Callback to parse a DOMElement object */ protected $elementParser; /** * @brief Callback to parse a DOMText object */ protected $textParser; /** * Parse * * @param string $value Contents to parse * @param callback $elementParser Callback to parse a DOMElement object. Is expected to call $parent->appendChild( $element ) after doing any parsing and call $parser->_parseDomNodeList(). function ( \DOMElement $element, \DOMNode $parent, \IPS\Text\DOMParser $parser ) * @param callback|NULL $textParser Callback to parse a DOMText object. Is expected to call $parent->appendChild( $element ) after doing any parsing. function ( \DOMText $textNode, \DOMNode $parent, \IPS\Text\DOMParser $parser ) * @retrun string */ public static function parse( $value, $elementParser, $textParser = NULL ) { return static::getDocumentBodyContents( ( new static( $elementParser, $textParser ) )->parseValueIntoDocument( $value ) ); } /** * Constructor * * @param string $value * @param callback $elementParser Callback to parse a DOMElement object. Is expected to call $parent->appendChild( $element ) after doing any parsing and call $parser->_parseDomNodeList(). function ( \DOMElement $element, \DOMNode $parent, \IPS\Text\DOMParser $parser ) * @param callback|NULL $textParser Callback to parse a DOMText object. Is expected to call $parent->appendChild( $element ) after doing any parsing. function ( \DOMText $textNode, \DOMNode $parent, \IPS\Text\DOMParser $parser ) * @retrun string */ public function __construct( $elementParser, $textParser = NULL ) { $this->elementParser = $elementParser; $this->textParser = $textParser; } /** * Parse Value into DOMDocument * * @param string $value Contents to parse * @return \DOMDocument */ public function parseValueIntoDocument( $value ) { /* Load the value into a DOMDocument */ $source = new \IPS\Xml\DOMDocument( '1.0', 'UTF-8' ); $source->loadHTML( \IPS\Xml\DOMDocument::wrapHtml( $value ) ); /* Create a new DOMDocument which we will move nodes into */ $document = new \IPS\Xml\DOMDocument( '1.0', 'UTF-8' ); /* Parse */ $this->_parseDomNode( $source, $document ); /* Return */ return $document; } /** * Parse DOMNode * * @param \DOMNode $node The node from the source document to parse * @param \DOMNode $parent The node from the new document which will be this node's parent * @return void */ public function _parseDomNode( \DOMNode $node, \DOMNode &$parent ) { switch ( $node->nodeType ) { /* This is the main DOMDocument object and it contains HTML. We just need to loop children */ case XML_HTML_DOCUMENT_NODE: $this->_parseDomNodeList( $node->childNodes, $parent ); break; /* This is a HTML element (e.g. ,