Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Thu, Jun 19, 5:24 AM

in-portal

Index: branches/5.2.x/core/units/helpers/xml_helper.php
===================================================================
--- branches/5.2.x/core/units/helpers/xml_helper.php (revision 14606)
+++ branches/5.2.x/core/units/helpers/xml_helper.php (revision 14607)
@@ -1,572 +1,606 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kXMLHelper extends kHelper {
/**
* Normal mode for XMLHelper
*
*/
const XML_NO_TEXT_NODES = 1;
/**
* Will create text nodes for every char-data (used in kPDFHelper)
*
*/
const XML_WITH_TEXT_NODES = 2;
- var $RootElement = null;
+ /**
+ * Root node after parsing xml document
+ *
+ * @var kXMLNode
+ * @access protected
+ */
+ protected $RootElement = null;
/**
- * Enter description here...
+ * Xml node, that is currently being processed
*
* @var kXMLNode
+ * @access protected
*/
- var $CurrentElement = null;
+ protected $CurrentElement = null;
var $Mode;
var $XMLNodeClassName = 'kXMLNode';
public function __construct()
{
parent::__construct();
if ( version_compare(PHP_VERSION, '5.0.0') === 1 ) {
$this->XMLNodeClassName = 'kXMLNode5';
kUtil::includeOnce( dirname(__FILE__) . DIRECTORY_SEPARATOR . 'xml_helper5.php' );
}
}
/**
* Parses XML data specified and returns root node
*
* @param string $xml
* @param int $mode
* @param bool $no_case_folding
* @return kXMLNode
+ * @access public
*/
- function &Parse($xml = null, $mode = self::XML_NO_TEXT_NODES, $no_case_folding = false)
+ public function &Parse($xml = null, $mode = self::XML_NO_TEXT_NODES, $no_case_folding = false)
{
$xml = trim($xml);
$this->Mode = !isset($mode) ? self::XML_NO_TEXT_NODES : $mode;
$this->Clear(); // in case if Parse method is called more then one time
$xml_parser = xml_parser_create();
- if ($no_case_folding) {
+ if ( $no_case_folding ) {
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
}
- xml_set_element_handler( $xml_parser, Array(&$this, 'startElement'), Array(&$this, 'endElement') );
- xml_set_character_data_handler( $xml_parser, Array(&$this, 'characterData') );
+ xml_set_element_handler($xml_parser, Array (&$this, 'startElement'), Array (&$this, 'endElement'));
+ xml_set_character_data_handler($xml_parser, Array (&$this, 'characterData'));
if ( !xml_parse($xml_parser, $xml, 1) ) {
$class_name = $this->XMLNodeClassName;
$byte = xml_get_current_byte_index($xml_parser);
- $extract = '...' . mb_substr($xml, $byte-50, 50) . ' !!![' . mb_substr($xml, $byte, 1) . ']!!! '.mb_substr($xml, $byte+1, 50) . '...';
+ $extract = '...' . mb_substr($xml, $byte - 50, 50) . ' !!![' . mb_substr($xml, $byte, 1) . ']!!! ' . mb_substr($xml, $byte + 1, 50) . '...';
$message = sprintf(
'XML error number %s: %s at line %d col %d, byte %d, extract: %s',
xml_get_error_code($xml_parser),
- xml_error_string(xml_get_error_code($xml_parser)),
+ xml_error_string( xml_get_error_code($xml_parser) ),
xml_get_current_line_number($xml_parser),
xml_get_current_column_number($xml_parser),
xml_get_current_byte_index($xml_parser),
$extract
);
- $this->RootElement =& new $class_name(
- 'ERROR',
- array(
- 'code' => xml_get_error_code($xml_parser),
- 'message' => $message
- )
- );
+ $this->RootElement =& new $class_name('ERROR', array ('code' => xml_get_error_code($xml_parser), 'message' => $message));
- trigger_error($message, E_USER_WARNING);
+ trigger_error($message, E_USER_WARNING);
}
xml_parser_free($xml_parser);
$root_copy = $this->RootElement;
+ /* @var $root_copy kXMLNode */
+
unset($this->RootElement);
unset($this->CurrentElement);
return $root_copy;
}
function ConvertHTMLEntities($s)
{
//build first an assoc. array with the entities we want to match
$table1 = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES);
$patterns = array();
$replacements = array();
//now build another assoc. array with the entities we want to replace (numeric entities)
foreach ($table1 as $k=>$v){
$patterns[] = "/$v/";
// $c = htmlentities($k,ENT_QUOTES,"UTF-8");
$replacements[] = "&#".ord($k).";";
}
//now perform a replacement using preg_replace
//each matched value in array 1 will be replaced with the corresponding value in array 2
$s = preg_replace($patterns,$replacements,$s);
return $s;
}
function startElement(&$Parser, &$Elem, $Attrs)
{
$parent =& $this->CurrentElement; // 1. $parent is now reference to $this->CurrentElement
$class_name = $this->XMLNodeClassName;
$this->CurrentElement =& new $class_name($Elem, $Attrs); // 2. =& ensures, that new object won't be assigned to $parent as well (don't remove)
if (!isset($this->RootElement) || is_null($this->RootElement)) {
$this->RootElement =& $this->CurrentElement;
}
if (!is_null($parent)) {
$parent->AddChild($this->CurrentElement);
}
}
function characterData($Parser, $Line)
{
if ($this->Mode == self::XML_WITH_TEXT_NODES) {
$class_name = $this->XMLNodeClassName;
$text_node = new $class_name('_TEXT_');
+ /* @var $text_node kXMLNode */
+
$text_node->AppendData($Line);
$this->CurrentElement->AddChild( $text_node );
}
else {
$this->CurrentElement->AppendData($Line);
}
}
function endElement($Parser, $Elem)
{
if ($this->Mode == self::XML_WITH_TEXT_NODES) {
/*if (count($this->CurrentElement->Children) == 1 && $this->CurrentElement->firstChild->Name == '_TEXT_') {
$this->CurrentElement->Children = array();
}*/
}
if ($this->CurrentElement->Parent != null) {
$this->CurrentElement =& $this->CurrentElement->Parent;
}
}
function Clear()
{
unset($this->RootElement);
unset($this->CurrentElement);
}
function &CreateNode($name, $value=null, $attributes=array())
{
$class_name = $this->XMLNodeClassName;
$node = new $class_name($name, $attributes);
/* @var $node kXMLNode */
if ($value) {
$node->SetData($value);
}
return $node;
}
+
+ /**
+ * Checks, that there is no error during XML document parsing
+ *
+ * @param kXMLNode $root_node
+ * @param string $root_node_name
+ * @return bool
+ * @access public
+ */
+ public function isError(&$root_node, $root_node_name)
+ {
+ if ( !is_object($root_node) || !preg_match('/^kxmlnode/i', get_class($root_node)) || ($root_node->Name == 'ERROR') || ($root_node->Name != $root_node_name) ) {
+ return true;
+ }
+
+ return false;
+ }
}
class kXMLNode {
/**
* Casefolded name of this node
*
* @var string
*/
var $Name = null;
/**
* Original name of this node
*
* @var string
*/
var $OriginalName = null;
/**
* Casefolded attributes of this node
*
* @var Array
*/
var $Attributes = array();
/**
* Original attributes of this node
*
* @var Array
*/
var $OriginalAttributes = array();
/**
- * List of node childnodes
+ * List of node child nodes
*
* @var Array
+ * @access public
*/
- var $Children = array();
+ public $Children = Array ();
/**
* Node content (usually text)
*
* @var string
*/
var $Data = null;
/**
* Reference to first child
*
* @var kXMLNode
*/
var $firstChild = null;
/**
* Last child of this node
*
* @var kXMLNode
*/
var $lastChild = null;
/**
* Parent node
*
* @var kXMLNode
*/
var $Parent = null;
/**
* Node position relative to other nodes of it's parent
*
* @var int
*/
var $Position = 0;
/**
* Node identifier
*
* @var int
*/
var $CRC = null;
- function kXMLNode($name, $attrs = array())
+ function __construct($name, $attributes = Array())
{
$this->Name = strtoupper($name);
$this->OriginalName = $name;
- $this->OriginalAttributes = $attrs;
+ $this->OriginalAttributes = $attributes;
- foreach ($attrs as $attr => $value) {
- $this->Attributes[ strtoupper($attr) ] = $value;
+ foreach ($attributes as $attr => $value) {
+ $this->Attributes[strtoupper($attr)] = $value;
}
- $this->CRC = crc32($this->Name.join(array_keys($this->Attributes)).join(array_values($this->Attributes)));
+ $this->CRC = crc32($this->Name . implode('', array_keys($this->Attributes)) . implode('', array_values($this->Attributes)));
}
/**
* Returns attribute value, first checking it casesensitively, then caseinsensitively
* If attribute is not set returns default value (if passed), or false otherwise
*
* @param string $name
* @param mixed $default
* @return string
*/
function GetAttribute($name, $default=false)
{
if (isset($this->OriginalAttributes[$name])) {
return $this->OriginalAttributes[$name];
}
return isset($this->Attributes[strtoupper($name)]) ? $this->Attributes[strtoupper($name)] : $default;
}
function SetParent(&$elem)
{
$this->Parent =& $elem;
}
/**
* Adds new child to current node
*
* @param kXMLNode $a_child
*/
function AddChild(&$a_child)
{
$node_count = count($this->Children);
$a_child->Position = $node_count;
if ($node_count == 0) {
$this->firstChild =& $a_child;
$this->lastChild =& $a_child;
}
else {
$this->lastChild =& $a_child;
}
$this->Children[] =& $a_child;
$a_child->SetParent($this);
}
/**
* Appends data to current node
*
* @param string $data
*/
function AppendData($data)
{
$this->Data .= $data;
}
/**
* Returns child node by given path
*
* @param string $path
* @return kXMLNode
*/
function &GetChild($path)
{
$entries = explode('/', strtoupper($path));
$cur = array_shift($entries);
if ($cur == $this->Name) $cur = array_shift($entries);
if (!$cur) return $this;
if (!isset($this->Children[$cur])) return false;
$left = implode('/', $entries);
if (!$left) return $this->Children[$cur];
return $this->Children[$cur]->GetChild($left);
}
function &GetFirstChild()
{
return $this->firstChild;
}
/**
* Returns node value by given path
*
* @param string $path
* @return string
*/
function GetChildValue($path)
{
$child =& $this->GetChild($path);
- if ($child !== false) {
- return $child->Data;
- }
+
+ return $child !== false ? $child->Data : '';
}
/**
* Returns child node by given position among it siblings
*
* @param int $position
* @return kXMLNode
*/
function &GetChildByPosition($position)
{
if ($position < count($this->Children) ) {
return $this->Children[$position];
}
else {
$false = false;
return $false;
}
}
/**
* Recursively searches for child with given name under current node
*
* @param string $name
* @return kXMLNode
*/
function &FindChild($name)
{
$name = strtoupper($name);
- if ($this->Name == $name) return $this;
- // if (isset($this->Children[$name])) return $this->Children[$name];
- // $children = array_keys($this->Children);
- foreach ($this->Children as $elem)
- {
+ if ( $this->Name == $name ) {
+ return $this;
+ }
+
+ /*if ( isset($this->Children[$name]) ) {
+ return $this->Children[$name];
+ }
+
+ $children = array_keys($this->Children);*/
+
+ foreach ($this->Children as $elem) {
+ /* @var $elem kXMLNode */
+
$child =& $elem->FindChild($name);
- if ($child !== false)
- {
+ if ( $child !== false ) {
return $child;
}
}
- if (isset($child) && is_object($child)) {
+ if ( isset($child) && is_object($child) ) {
$child->_destruct();
}
+
unset($child);
$false = false;
return $false;
}
/**
- * Retruns value of given child or value of it's attribute
+ * Returns value of given child or value of it's attribute
*
* @param string $name
* @param string $attr
* @return string
+ * @access public
*/
- function FindChildValue($name, $attr=null)
+ public function FindChildValue($name, $attr = null)
{
$child =& $this->FindChild($name);
- if ($child !== false) {
- if (isset($attr)) {
- return $child->Attributes[strtoupper($attr)];
+ if ( $child !== false ) {
+ if ( isset($attr) ) {
+ return $child->Attributes[ strtoupper($attr) ];
}
return $child->Data;
}
+
+ return '';
}
/**
* Returns next node to this, false in case of end list
*
* @return kXMLNode
*/
function &PrevSibling()
{
if (!is_null($this->Parent) && $this->Position > 0) {
$pos = $this->Position - 1;
do {
$ret =& $this->Parent->GetChildByPosition($pos--);
} while ($ret->Name == '_TEXT_' && $pos >= 0);
if ($ret->Name == '_TEXT_') $ret = false;
return $ret;
}
else {
$false = false;
return $false;
}
}
/**
* Returns next node to this, false in case of end list
*
* @return kXMLNode
*/
function &NextSibling()
{
if (!is_null($this->Parent)) {
$pos = $this->Position + 1;
do {
$ret =& $this->Parent->GetChildByPosition($pos++);
} while ($pos < count($this->Parent->Children) && ($ret->Name == '_TEXT_'));
if (is_object($ret) && ($ret->Name == '_TEXT_')) {
$ret = false;
}
return $ret;
}
else {
$false = false;
return $false;
}
}
/**
* Reconstructs XML of the node and subnodes
*
* $param bool $content_only
*/
function GetXML($content_only = false)
{
$xml = '';
$single = (!$this->Data && count($this->Children) == 0);
if (!$content_only) {
$xml = '<'.$this->OriginalName;
if (count($this->OriginalAttributes)) {
$xml .= ' ';
$att_contents = array();
foreach ($this->OriginalAttributes as $name => $value) {
$att_contents[] = $name.'="'.htmlspecialchars($value).'"';
}
$xml .= implode(' ', $att_contents);
}
$xml .= $single ? '/>' : '>';
}
if (!$single) {
if ($content_only) {
$xml .= $this->Data;
}
else {
$xml .= preg_match('/&|</', $this->Data) ? '<![CDATA['.$this->Data.']]>' : $this->Data;
}
foreach ($this->Children as $node) {
/* @var $node kXMLNode */
$xml .= $node->GetXML($node->Name == '_TEXT_' ? true : false);
}
if (!$content_only) {
$xml .= '</'.$this->OriginalName.'>';
}
}
return $xml;
}
function RemoveChild($name)
{
$child =& $this->FindChild($name);
$parent =& $child->Parent;
$pos = $child->Position;
array_splice($parent->Children, $pos, 1);
for ($i=$pos; $i < count($parent->Children); $i++) {
$parent->Children[$i]->Position = $i;
}
$parent->firstChild =& $parent->Children[0];
$parent->lastChild =& $parent->Children[count($parent->Children)-1];
}
function ReplaceChild($name, &$replacement)
{
$child =& $this->FindChild($name);
$parent =& $child->Parent;
$pos = $child->Position;
array_splice($parent->Children, $pos, 1, array($replacement));
$replacement->Parent =& $parent;
$replacement->Position = $pos;
$parent->firstChild =& $parent->Children[0];
$parent->lastChild =& $parent->Children[count($parent->Children)-1];
}
function SetName($name)
{
$this->Name = strtoupper($name);
$this->OriginalName = $name;
}
function SetData($data)
{
$this->Data = $data;
}
function SetAttribute($name, $value)
{
$this->Attributes[strtoupper($name)] = $value;
$this->OriginalAttributes[$name] = $value;
}
}
\ No newline at end of file

Event Timeline