PortableInfobox/includes/services/Parser/XmlParser.php

81 lines
2 KiB
PHP
Raw Normal View History

<?php
2022-03-11 20:35:51 +00:00
namespace PortableInfobox\Parser;
2022-03-11 20:35:51 +00:00
use Exception;
use MediaWiki\Logger\LoggerFactory;
2022-03-11 20:35:51 +00:00
use SimpleXMLElement;
class XmlParser {
protected static $contentTags = [ 'default', 'label', 'format', 'navigation', 'header' ];
2015-05-29 13:04:04 +00:00
/**
* @param string $xmlString XML to parse
*
2018-08-16 09:25:53 +00:00
* @param array &$errors this array will be filled with errors if any found
*
2022-03-11 20:35:51 +00:00
* @return SimpleXMLElement
2015-05-29 13:04:04 +00:00
* @throws XmlMarkupParseErrorException
*/
2018-08-16 09:25:53 +00:00
public static function parseXmlString( $xmlString, &$errors = [] ) {
2015-05-29 13:04:04 +00:00
$global_libxml_setting = libxml_use_internal_errors();
libxml_use_internal_errors( true );
// support for html entities and single & char
$xml = simplexml_load_string( self::prepareXml( $xmlString ) );
2015-05-29 13:04:04 +00:00
$errors = libxml_get_errors();
libxml_use_internal_errors( $global_libxml_setting );
if ( $xml === false ) {
foreach ( $errors as $xmlerror ) {
self::logXmlParseError( $xmlerror->level, $xmlerror->code, trim( $xmlerror->message ) );
2015-05-29 13:04:04 +00:00
}
libxml_clear_errors();
throw new XmlMarkupParseErrorException( $errors );
2015-05-29 13:04:04 +00:00
}
2015-05-29 13:04:04 +00:00
return $xml;
}
protected static function logXmlParseError( $level, $code, $message ) {
2018-10-02 07:41:19 +00:00
LoggerFactory::getInstance( 'PortableInfobox' )->info( 'PortableInfobox XML Parser problem', [
'level' => $level,
'code' => $code,
'message' => $message
] );
}
/**
* @param string $xmlString
*
* @return mixed
*/
protected static function prepareXml( $xmlString ) {
foreach ( self::$contentTags as $tag ) {
// wrap content in CDATA for content tags
2018-10-02 07:41:19 +00:00
$xmlString = preg_replace(
'|(<' . $tag . '.*>)(.*)(</' . $tag . '>)|sU', '$1<![CDATA[$2]]>$3',
$xmlString
);
}
$decoded = str_replace( '&', '&amp;', html_entity_decode( $xmlString ) );
return $decoded;
}
}
2015-05-08 12:04:18 +00:00
2018-10-02 07:41:19 +00:00
// phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound
2022-03-11 20:35:51 +00:00
class XmlMarkupParseErrorException extends Exception {
2015-06-10 12:51:07 +00:00
private $errors;
public function __construct( $errors ) {
$this->errors = $errors;
2021-09-10 02:52:19 +00:00
parent::__construct();
2015-06-10 12:51:07 +00:00
}
public function getErrors() {
return $this->errors;
}
2015-05-21 18:38:33 +00:00
}