/lib/Molinos/Base/XML.php
PHP | 646 lines | 447 code | 51 blank | 148 comment | 31 complexity | 29254f47caa007f05c254e8742dc9c4c MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0
- <?php
- /**
- * ??????????? ????? ??? ???????????? XML ????.
- *
- * @package Molinos_CMS
- * @subpackage base
- * @author Justin Forest <justin.forest@gmail.com>
- * @copyright 2006-2009 molinos.ru
- * @license http://www.gnu.org/copyleft/gpl.html GPL
- */
- class Molinos_Base_XML
- {
- /**
- * ???????????? ??? ????? ?????? ? simple().
- *
- * @var string
- */
- protected static $xml_errors;
- /**
- * Renders an HTML element.
- *
- * Returns the HTML representation of an element described by
- * input parameters which are: element name, an array of attributes,
- * and the content. Except for the first parameter, all is optional.
- *
- * @param string $em ??? ???????????? ????????.
- * @param array $attrs ????????.
- * @param string $content ??????????.
- * @return string ??????? XML ???.
- */
- public static function em()
- {
- if (func_num_args() == 0 or func_num_args() > 3)
- throw new InvalidArgumentException('Molinos_Base_XML::em() expects 1 to 3 arguments.');
- else {
- $args = func_get_args();
- $name = array_shift($args);
- if (empty($name))
- throw new InvalidArgumentException('Attempting to create an XML element without a name.');
- $parts = array();
- $content = null;
- if (is_array($tmp = array_shift($args)))
- $parts = $tmp;
- else
- $content = $tmp;
- if (!empty($args))
- $content = array_shift($args);
- }
- if (array_key_exists('#cdata', $parts)) {
- $content = self::cdata($parts['#cdata']);
- unset($parts['#cdata']);
- } elseif (array_key_exists('#text', $parts)) {
- $content = $parts['#text'];
- unset($parts['#text']);
- }
- $name = str_replace('_', '-', $name);
- $output = '<'. $name;
- if (('td' == $name or 'th' == $name) and empty($content))
- $content = ' ';
- if (empty($parts))
- $parts = array();
- $fixmap = array(
- 'a' => 'href',
- 'form' => 'action',
- );
- $output .= self::attrs($parts);
- if (null === $content and !in_array($name, array('a', 'script', 'div', 'textarea', 'span', 'base'))) {
- $output .= '/>';
- } else {
- $output .= '>'. $content .'</'. $name .'>';
- }
- return $output;
- }
- /**
- * ?????????????? ?????????.
- *
- * ???????????? ????? ????????? (????? ???????), ??????? ?? ? ???????
- * ???????? ? ??????? ???????? ????????. ???????? true ???????? ?? "yes",
- * ?????? ???????? ?? ?????????.
- *
- * @param array $attrs ???????? ??? ??????????????.
- * @return string ?????? ? ?????????? XML ????????.
- */
- public static function attrs(array $attrs)
- {
- $result = '';
- ksort($attrs);
- foreach ($attrs as $k => $v) {
- if (!ctype_alpha(substr($k, 0, 1)))
- continue;
- if ('class' == $k) {
- if (!is_array($v))
- $v = preg_split('/\s+/', $v, -1, PREG_SPLIT_NO_EMPTY);
- $v = join(' ', array_unique($v));
- }
- if (empty($v) or is_array($v))
- continue;
- if (strlen($v)) {
- if (true === $v)
- $v = 'yes';
- else
- $v = Molinos_Base_XML::plain($v, false);
- $result .= ' '.self::attrname($k).'=\''. $v .'\'';
- } elseif ($k == 'value') {
- $result .= " value=''";
- }
- }
- return $result;
- }
- /**
- * ??????? ???????????? HTML ??????.
- *
- * ?????????? ?????????????????? ????????? <li>, ?????? ?? ??????? ????????
- * ???? ???????? ?? ???????, ?????????????? ? ??????? htmlspecialchars().
- * ????? ??????? ????????????. ??? ?????? (<ul> ??? <ol>) ?? ???????????.
- *
- * @param array $elements ???????? ??????. ????? ????????????.
- * @return string ?????????????????? ????????? <li>.
- */
- public static function simpleList(array $elements)
- {
- $result = '';
- foreach ($elements as $em)
- $result .= self::em('li', htmlspecialchars($em));
- return $result;
- }
- /**
- * ???????????? ?????? ????????.
- *
- * ????? ??????? ????????? ? ??????? value ????????, ???????? ? ?????,
- * ??? ???? (??? ?????????????).
- *
- * @param array $elements ????????????? ?????? ????????.
- * @param string $emName ??? ????????? ?? ??????????.
- * @param string $wrapperName ??? ????????, ? ??????? ??????????????
- * ?????????, ???? ?????? ?? ????.
- * @return string XML ???.
- */
- public static function simpleOptions(array $elements, $emName = 'option', $wrapperName = null)
- {
- $output = '';
- foreach ($elements as $k => $v)
- $output .= Molinos_Base_XML::em($emName, array(
- 'value' => $k,
- ), $v);
- if (null !== $wrapperName and !empty($output))
- return Molinos_Base_XML::em($wrapperName, $output);
- return $output;
- }
- /**
- * ????????????? ?????? ? CDATA, ???? ?????.
- *
- * @param string $data ?????????????? ??????.
- * @return string ???????? ??????, ???? ?? ???????? ????????????, ??? ???
- * ??, ?????????? ? CDATA, ???? ???????? ???? ?? ????????: "<>&".
- */
- public static function cdata($data)
- {
- if (empty($data))
- return null;
- if (is_array($data) or is_object($data))
- return null;
- if (strlen($data) != strcspn($data, '<>&'))
- return '<![CDATA[' . $data . ']]>';
- else
- return $data;
- }
- /**
- * ?????????????? ????????????.
- *
- * @return string ?????????????????? ????????? <link> ? <script>.
- *
- * @deprecated ?????? ?? ????????????, ??????????.
- * @todo ???????.
- */
- public static function formatExtras(array $extras)
- {
- $output = '';
- foreach ($extras as $item) {
- switch ($item[0]) {
- case 'style':
- $output .= Molinos_Base_XML::em('link', array(
- 'rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => Molinos_Core_Utils::webpath($item[1]),
- ));
- break;
- case 'script':
- $output .= Molinos_Base_XML::em('script', array(
- 'type' => 'text/javascript',
- 'src' => Molinos_Core_Utils::webpath($item[1]),
- ));
- break;
- }
- }
- return $output;
- }
- /**
- * ?????????? ??????????? HTML, ??????????? ?????? ?? ?????.
- *
- * @param string $text ??????????? ?????.
- * @param bool $strip true, ???? ????? ??????? ????.
- * @return string ?????????????? ?????.
- */
- public static function plain($text, $strip = true)
- {
- if (is_object($text) or is_array($text))
- throw new InvalidArgumentException('Molinos_Base_XML::plain() expects a string.');
- if ($strip)
- $text = strip_tags($text);
- return str_replace(array('&quot;'), array('"'), htmlspecialchars($text, ENT_QUOTES));
- }
- /**
- * ????????? ??????.
- *
- * @param string $href ????? ??????.
- * @param string $text ????? ??????.
- * @param array $options ?????????????? ????????.
- * @return string ????????????????? ??????.
- *
- * @deprecated ??????? ???????????? {@link em()}.
- * @todo ???????.
- */
- public static function link($href, $text, array $options = array())
- {
- $options['href'] = $href;
- return Molinos_Base_XML::em('a', $options, $text);
- }
- /**
- * ????????????? ????????? ??????????? ? ???????.
- *
- * @param string $em ??? ????????-???????.
- * @param string $content ????????????? ??????????.
- * @param array $options ?????????????? ????????.
- * @return string ?????????? $content, ?????????? ? ??????? $em. ????
- * ? $content ?????, ?????????? NULL.
- */
- public static function wrap($em, $content, $options = null)
- {
- return empty($content)
- ? null
- : Molinos_Base_XML::em($em, $options, $content);
- }
- /**
- * ????????? ????? ????????.
- *
- * @param string $string ??? ????????.
- * @return string ??? ????????, ?? ???????? ??????? ??? ???????, ?????
- * ????????? ????, ???? ? ???????, ? ????? ? ???????? ???????? ????????.
- */
- public static function attrname($string)
- {
- return preg_replace('/[^a-z0-9-]/i', '', str_replace(array('_', '.'), array('-', '-'), $string));
- }
- /**
- * ?????????? ???????? ??????, ????????? ??? ????????????? ? ?????????.
- *
- * ??????? ??? ???? ? ??????? ? ????? ????? 0x20, ??? ????????? ?????????
- * ? ????? ??????????.
- *
- * @param string $html ???????? ?????.
- * @param integer $length ?????, ? ????????.
- * @return string ????????? ???????? ?????? ?????? ?????.
- */
- public static function snippet($html, $length = 200)
- {
- $snippet = mb_strimwidth(strip_tags(html_entity_decode($html)), 0, $length, '
', 'utf-8');
- $snippet = preg_replace('/[\x01-\x20]+/', ' ', $snippet);
- return trim($snippet);
- }
- /**
- * ?????????? SimpleXMLElement.
- *
- * ????? ???????? ?????????? ????????? ???????? ??????, ??????? ??????????,
- * ????????? ? ???, ????? ????????? ??????????.
- *
- * @param string $xml ???, ??????? ????? ??????????.
- * @return SimpleXMLElement ????????? ???????.
- */
- public static function simple($xml)
- {
- $xml = self::decode_entities($xml);
- self::$xml_errors = '';
- set_error_handler(array(__CLASS__, 'simple_error'), -1);
- try {
- $em = new SimpleXMLElement($xml);
- restore_error_handler();
- } catch (Exception $e) {
- restore_error_handler();
- $logger = Molinos_Core_Logger::getInstance();
- $logger->error(self::$xml_errors . "The full XML document follows.\n" . $xml);
- throw new RuntimeException(t('Could not process the XML document, see the log file for details.'));
- }
- return $em;
- }
- public static function simple_error($errno, $errstr, $errfile, $errline)
- {
- self::$xml_errors .= trim($errstr) . "\n";
- }
- /**
- * ?????? HTML ????????? ?? ?????????? ?????????????.
- *
- * ?????? ???????? ???????? HTML ? ??????? SimpleXML (issue 2155).
- *
- * @param string $xml ???????? ?????.
- * @return string ????? ? ???????? ?????? ????? ?????????.
- */
- public static function decode_entities($xml)
- {
- return str_replace(array_keys(self::$entity_map), array_values(self::$entity_map), $xml);
- }
- /**
- * ?????????? ????? ?????????.
- *
- * ????? ?? ????????????. ??? ???????? ?? ?????? ??????.
- */
- public static function build_entity_map()
- {
- // Resources used:
- // http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
- // http://www.intuitive.com/coolweb/entities.html
- // $base_url = './';
- $base_url = 'http://www.w3.org/TR/html4/';
- $fileNames = array('HTMLlat1.ent', 'HTMLspecial.ent', 'HTMLsymbol.ent');
- $result = array();
- foreach ($fileNames as $fileName) {
- $contents = file_get_contents($base_url . $fileName);
- if (preg_match_all('/<!ENTITY\s+(\S+)\s+CDATA\s+"([^"]+)"/', $contents, $m))
- foreach ($m[1] as $idx => $src) {
- if (!in_array($src, array('quot', 'apos', 'amp', 'lt', 'gt'))) {
- $dst = $m[2][$idx];
- $dst = html_entity_decode($dst, ENT_QUOTES, 'utf-8');
- $result['&' . $src . ';'] = $dst;
- }
- }
- }
- ksort($result);
- file_put_contents('entities.php', '<?php return ' . var_export($result, true) . ';');
- }
- /**
- * ????? ?????????, ????????? ? ??????? build_entity_map().
- *
- * @var array
- */
- protected static $entity_map = array(
- 'Æ' => 'Ć',
- 'Á' => 'Á',
- 'Â' => 'Â',
- 'À' => 'Ŕ',
- 'Α' => '?',
- 'Å' => 'Ĺ',
- 'Ã' => 'Ă',
- 'Ä' => 'Ä',
- 'Β' => '?',
- 'Ç' => 'Ç',
- 'Χ' => '?',
- '‡' => '',
- 'Δ' => '?',
- 'Ð' => 'Đ',
- 'É' => 'É',
- 'Ê' => 'Ę',
- 'È' => 'Č',
- 'Ε' => '?',
- 'Η' => '?',
- 'Ë' => 'Ë',
- 'Γ' => '?',
- 'Í' => 'Í',
- 'Î' => 'Î',
- 'Ì' => 'Ě',
- 'Ι' => '?',
- 'Ï' => 'Ď',
- 'Κ' => '?',
- 'Λ' => '?',
- 'Μ' => '?',
- 'Ñ' => 'Ń',
- 'Ν' => '?',
- 'Œ' => '',
- 'Ó' => 'Ó',
- 'Ô' => 'Ô',
- 'Ò' => 'Ň',
- 'Ω' => '?',
- 'Ο' => '?',
- 'Ø' => 'Ř',
- 'Õ' => 'Ő',
- 'Ö' => 'Ö',
- 'Φ' => '?',
- 'Π' => '?',
- '″' => '?',
- 'Ψ' => '?',
- 'Ρ' => '?',
- 'Š' => '',
- 'Σ' => '?',
- 'Þ' => 'Ţ',
- 'Τ' => '?',
- 'Θ' => '?',
- 'Ú' => 'Ú',
- 'Û' => 'Ű',
- 'Ù' => 'Ů',
- 'Υ' => '?',
- 'Ü' => 'Ü',
- 'Ξ' => '?',
- 'Ý' => 'Ý',
- 'Ÿ' => '',
- 'Ζ' => '?',
- 'á' => 'á',
- 'â' => 'â',
- '´' => '´',
- 'æ' => 'ć',
- 'à' => 'ŕ',
- 'ℵ' => '?',
- 'α' => '?',
- '∧' => '?',
- '∠' => '?',
- 'å' => 'ĺ',
- '≈' => '?',
- 'ã' => 'ă',
- 'ä' => 'ä',
- '„' => '',
- 'β' => '?',
- '¦' => 'Ś',
- '•' => '',
- '∩' => '?',
- 'ç' => 'ç',
- '¸' => '¸',
- '¢' => '˘',
- 'χ' => '?',
- 'ˆ' => '',
- '♣' => '?',
- '≅' => '?',
- '©' => 'Š',
- '↵' => '?',
- '∪' => '?',
- '¤' => '¤',
- '⇓' => '?',
- '†' => '',
- '↓' => '?',
- '°' => '°',
- 'δ' => '?',
- '♦' => '?',
- '÷' => '÷',
- 'é' => 'é',
- 'ê' => 'ę',
- 'è' => 'č',
- '∅' => '?',
- ' ' => '?',
- ' ' => '?',
- 'ε' => '?',
- '≡' => '?',
- 'η' => '?',
- 'ð' => 'đ',
- 'ë' => 'ë',
- '€' => '',
- '∃' => '?',
- 'ƒ' => '',
- '∀' => '?',
- '½' => '˝',
- '¼' => 'ź',
- '¾' => 'ž',
- '⁄' => '?',
- 'γ' => '?',
- '≥' => '?',
- '⇔' => '?',
- '↔' => '?',
- '♥' => '?',
- '…' => '
',
- 'í' => 'í',
- 'î' => 'î',
- '¡' => 'Ą',
- 'ì' => 'ě',
- 'ℑ' => '?',
- '∞' => '?',
- '∫' => '?',
- 'ι' => '?',
- '¿' => 'ż',
- '∈' => '?',
- 'ï' => 'ď',
- 'κ' => '?',
- '⇐' => '?',
- 'λ' => '?',
- '⟨' => '?',
- '«' => 'Ť',
- '←' => '?',
- '⌈' => '?',
- '“' => '',
- '≤' => '?',
- '⌊' => '?',
- '∗' => '?',
- '◊' => '?',
- '‎' => '?',
- '‹' => '',
- '‘' => '',
- '¯' => 'Ż',
- '—' => '',
- 'µ' => 'ľ',
- '·' => 'ˇ',
- '−' => '?',
- 'μ' => '?',
- '∇' => '?',
- ' ' => ' ',
- '–' => '',
- '≠' => '?',
- '∋' => '?',
- '¬' => 'Ź',
- '∉' => '?',
- '⊄' => '?',
- 'ñ' => 'ń',
- 'ν' => '?',
- 'ó' => 'ó',
- 'ô' => 'ô',
- 'œ' => '',
- 'ò' => 'ň',
- '‾' => '?',
- 'ω' => '?',
- 'ο' => '?',
- '⊕' => '?',
- '∨' => '?',
- 'ª' => 'Ş',
- 'º' => 'ş',
- 'ø' => 'ř',
- 'õ' => 'ő',
- '⊗' => '?',
- 'ö' => 'ö',
- '¶' => 'ś',
- '∂' => '?',
- '‰' => '',
- '⊥' => '?',
- 'φ' => '?',
- 'π' => '?',
- 'ϖ' => '?',
- '±' => 'ą',
- '£' => 'Ł',
- '′' => '?',
- '∏' => '?',
- '∝' => '?',
- 'ψ' => '?',
- '⇒' => '?',
- '√' => '?',
- '⟩' => '?',
- '»' => 'ť',
- '→' => '?',
- '⌉' => '?',
- '”' => '',
- 'ℜ' => '?',
- '®' => 'Ž',
- '⌋' => '?',
- 'ρ' => '?',
- '‏' => '?',
- '›' => '',
- '’' => '',
- '‚' => '',
- 'š' => '',
- '⋅' => '?',
- '§' => '§',
- '­' => '',
- 'σ' => '?',
- 'ς' => '?',
- '∼' => '?',
- '♠' => '?',
- '⊂' => '?',
- '⊆' => '?',
- '∑' => '?',
- '¹' => 'š',
- '²' => '˛',
- '³' => 'ł',
- '⊃' => '?',
- '⊇' => '?',
- 'ß' => 'ß',
- 'τ' => '?',
- '∴' => '?',
- 'θ' => '?',
- 'ϑ' => '?',
- ' ' => '?',
- 'þ' => 'ţ',
- '˜' => '',
- '×' => '×',
- '™' => '',
- '⇑' => '?',
- 'ú' => 'ú',
- '↑' => '?',
- 'û' => 'ű',
- 'ù' => 'ů',
- '¨' => '¨',
- 'ϒ' => '?',
- 'υ' => '?',
- 'ü' => 'ü',
- '℘' => '?',
- 'ξ' => '?',
- 'ý' => 'ý',
- '¥' => 'Ľ',
- 'ÿ' => '˙',
- 'ζ' => '?',
- '‍' => '?',
- '‌' => '?',
- );
- }