File: /home/axxoncom/domains/ogundem.xyz/public_html/wp-content/themes/spectra-one/inc/utilities/dom.php
<?php
/**
* Target DOM Elements
*
* @package Spectra One
* @author Brainstorm Force
* @since 0.0.1
*/
declare( strict_types=1 );
namespace Swt;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use function bin2hex;
use function current;
use DOMDocument;
use DOMElement;
use function iconv;
use function is_a;
use function libxml_clear_errors;
use function libxml_use_internal_errors;
use function ltrim;
use function preg_replace_callback;
use function sprintf;
use function strtoupper;
/**
* Formatted DOMDocument object from string.
*
* @since 0.0.1
*
* @param string $html HTML string to convert to DOM.
*
* @return \DOMDocument
*/
function dom( string $html ): DOMDocument {
$dom = new DOMDocument();
if ( ! $html ) {
return $dom;
}
$libxml_previous_state = libxml_use_internal_errors( true );
$dom->preserveWhiteSpace = true;
if ( defined( 'LIBXML_HTML_NOIMPLIED' ) && defined( 'LIBXML_HTML_NODEFDTD' ) ) {
$options = LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD;
} elseif ( defined( 'LIBXML_HTML_NOIMPLIED' ) ) {
$options = LIBXML_HTML_NOIMPLIED;
} elseif ( defined( 'LIBXML_HTML_NODEFDTD' ) ) {
$options = LIBXML_HTML_NODEFDTD;
} else {
$options = 0;
}
$html = preg_replace_callback(
'/[\x{80}-\x{10FFFF}]/u',
static fn( array $matches ): string => sprintf(
'&#x%s;',
ltrim(
strtoupper(
bin2hex(
iconv(
'UTF-8',
'UCS-4',
current( $matches )
)
)
),
'0'
)
),
$html
);
if ( ! empty( $html ) ) {
$dom->loadHTML( $html, $options );
}
$dom->formatOutput = true;
libxml_clear_errors();
libxml_use_internal_errors( $libxml_previous_state );
return $dom;
}
/**
* Formatted DOMElement object from a DOMDocument object.
*
* @since 0.0.1
*
* @param string $tag HTML tag.
* @param mixed $dom_or_element DOMDocument.
* @param int $index Index of element to return.
*
* @return \DOMElement|null
*/
function get_dom_element( string $tag, $dom_or_element, int $index = 0 ) {
if ( ! is_a( $dom_or_element, DOMDocument::class ) && ! is_a( $dom_or_element, DOMElement::class ) ) {
return null;
}
$element = $dom_or_element->getElementsByTagName( $tag )->item( $index );
if ( ! $element ) {
return null;
}
return dom_element( $element );
}
/**
* DOMNode to a DOMElement.
*
* @since 0.0.1
*
* @param mixed $node DOMNode.
*
* @return \DOMElement|null
*/
function dom_element( $node ) {
if ( $node->nodeType === XML_ELEMENT_NODE ) {
return $node;
}
return null;
}
/**
* Change html tag name.
*
* @since 0.0.1
*
* @param \DOMElement $element DOM Element.
* @param string $name Tag name.
*
* @return \DOMElement
*/
function change_tag_name( DOMElement $element, string $name ): DOMElement {
if ( ! $element->ownerDocument ) {
return new DOMElement( $name );
}
$child_nodes = array();
foreach ( $element->childNodes as $child ) {
$child_nodes[] = $child;
}
$new_element = $element->ownerDocument->createElement( $name );
foreach ( $child_nodes as $child ) {
$child2 = $element->ownerDocument->importNode( $child, true );
$new_element->appendChild( $child2 );
}
foreach ( $element->attributes as $attr_node ) {
$attr_name = $attr_node->nodeName;
$attr_value = $attr_node->nodeValue;
if ( $attr_value !== null ) {
$new_element->setAttribute( $attr_name, $attr_value );
}
}
if ( $element->parentNode ) {
$element->parentNode->replaceChild( $new_element, $element );
}
return $new_element;
}
/**
* Returns dom elements by class name as array.
*
* @since 0.0.1
*
* @param \DOMDocument|\DOMElement $dom DOM document.
* @param string $class_name class name.
* @param string $tag tag name.
*
* @return array
*/
function get_elements_by_class_name( $dom, string $class_name, string $tag = '*' ): array {
$elements = array();
foreach ( $dom->getElementsByTagName( $tag ) as $element ) {
if ( $element->hasAttribute( 'class' ) ) {
$classes = explode( ' ', $element->getAttribute( 'class' ) );
if ( in_array( $class_name, $classes, true ) ) {
$elements[] = $element;
}
}
}
return $elements;
}