Your IP : 216.73.216.85


Current Path : /home/smartconb/www/armencom33/libraries/sobi/ThirdParty/HTMLFilter/
Upload File :
Current File : /home/smartconb/www/armencom33/libraries/sobi/ThirdParty/HTMLFilter/HTMLFilter.php

<?php

namespace AthosHun\HTMLFilter;


class HTMLFilter
{
	private $config;
	private $original_dom;
	private $filtered_dom;
	private $libxml_used_internal_errors;

	public function __construct()
	{
	}

	public function filter( Configuration $config, $html_text )
	{
		$this->libxml_used_internal_errors = libxml_use_internal_errors( true );

		try {
			$this->initialize( $config, $html_text );
			$this->copyAllowedNodes();
			$filtered_html = htmlspecialchars_decode( $this->fetchFilteredHTML(), ENT_HTML5 );
		}
		catch ( \Exception $error ) {
			$this->cleanup();
			throw $error;
		}

		$this->cleanup();

		return $filtered_html;
	}

	private function initialize( Configuration $config, $html_text )
	{
		$this->config = $config;
		$html_text = mb_convert_encoding( $html_text, "UTF-8", "UTF-8" );
		$this->original_dom = $this->createDOMDocument( $html_text );
		$this->filtered_dom = $this->createDOMDocument( "" );
	}

	private function createDOMDocument( $html_text )
	{
		$dom_document = new \DOMDocument( "1.0", "UTF-8" );
		$dom_document->loadHTML(
			"<?xml encoding=\"UTF-8\"><html><body>$html_text</body></html>"
		);

		return $dom_document;
	}

	private function copyAllowedNodes()
	{
		$original_body = $this->findBodyNode( $this->original_dom );
		$filtered_body = $this->findBodyNode( $this->filtered_dom );
		$this->copyAllowedChildNodes( $original_body, $filtered_body );
	}

	private function findBodyNode( \DOMDocument $dom_document )
	{
		return $dom_document->getElementsByTagName( "body" )->item( 0 );
	}

	private function copyAllowedChildNodes(
		\DOMNode $source,
		\DOMNode $destination
	)
	{
		if ( !$source->hasChildNodes() ) {
			return;
		}

		for ( $i = 0, $l = $source->childNodes->length; $i != $l; ++$i ) {
			$node = $source->childNodes->item( $i );

			if ( $this->isAllowedNode( $node ) ) {
				$this->copyNode( $node, $destination );
			}
			else {
				$this->copyAllowedChildNodes( $node, $destination );
			}
		}
	}

	private function isAllowedNode( \DOMNode $node )
	{
		return ( $node instanceof \DOMText )
			|| ( $node instanceof \DOMComment )
			|| ( $this->config->isAllowedTag( $node->nodeName ) );
	}

	private function copyNode( \DOMNode $node, \DOMNode $destination )
	{
		if ( $node instanceof \DOMText ) {
			$this->copyTextNode( $node, $destination );
		}
		else {
			if ( $node instanceof \DOMElement ) {
				$this->copyDOMElement( $node, $destination );
			}
			else {
				if ( $node instanceof \DOMComment ) {
					$this->copyDOMComment( $node, $destination );
				}
			}
		}
	}

	private function copyTextNode( \DOMText $text_node, \DOMNode $destination )
	{
		$destination->appendChild(
			$destination->ownerDocument->createTextNode( $text_node->data )
		);
	}

	private function copyDOMElement(
		\DOMElement $element,
		\DOMNode $destination
	)
	{
		$copied_element = $destination->ownerDocument
			->createElement( $element->nodeName );
		$destination->appendChild( $copied_element );
		$this->copyAllowedAttributes( $element, $copied_element );
		$this->copyAllowedChildNodes( $element, $copied_element );
	}

	private function copyAllowedAttributes(
		\DOMElement $source,
		\DOMElement $destination
	)
	{
		for ( $i = 0, $l = $source->attributes->length; $i != $l; ++$i ) {
			$attribute = $source->attributes->item( $i );

			if ( $this->isAllowedAttribute( $attribute ) ) {
				$this->copyAttribute( $attribute, $destination );
			}
		}
	}

	private function isAllowedAttribute( \DOMAttr $attribute )
	{
		return $this->config->isAllowedAttribute(
			$attribute->ownerElement->nodeName,
			$attribute->name,
			$attribute->value
		);
	}

	private function copyAttribute(
		\DOMAttr $attribute,
		\DOMElement $destination
	)
	{
		$copied_attribute = $destination->ownerDocument
			->createAttribute( $attribute->name );
		$copied_attribute->value = htmlspecialchars(
			$attribute->value,
			ENT_QUOTES,
			"UTF-8"
		);
		$destination->appendChild( $copied_attribute );
	}

	private function copyDOMComment( \DOMComment $comment, \DOMNode $destination )
	{
		$destination->appendChild(
			$destination->ownerDocument->createComment( $comment->data )
		);
	}

	private function fetchFilteredHTML()
	{
		$filtered_html = $this->filtered_dom->saveHTML(
			$this->findBodyNode( $this->filtered_dom )
		);

		return $this->trimBodyTags( $filtered_html );
	}

	private function trimBodyTags( $html_text )
	{
		if ( $html_text === "<body/>" ) {
			return "";
		}

		if ( substr( $html_text, 0, 6 ) === "<body>" ) {
			$html_text = substr( $html_text, 6 );
		}

		if ( substr( $html_text, -7, 7 ) === "</body>" ) {
			$html_text = substr( $html_text, 0, strlen( $html_text ) - 7 );
		}

		return $html_text;
	}

	private function cleanup()
	{
		$this->config = null;
		$this->original_dom = null;
		$this->filtered_dom = null;
		libxml_use_internal_errors( $this->libxml_used_internal_errors );
	}
}