Seditio Source
Root |
./othercms/ips_4.3.4/system/3rd_party/HTMLPurifier/HTMLPurifier/ErrorCollector.php
<?php

/**
 * Error collection class that enables HTML Purifier to report HTML
 * problems back to the user
 */
class HTMLPurifier_ErrorCollector
{

   
/**
     * Identifiers for the returned error array. These are purposely numeric
     * so list() can be used.
     */
   
const LINENO   = 0;
    const
SEVERITY = 1;
    const
MESSAGE  = 2;
    const
CHILDREN = 3;

   
/**
     * @type array
     */
   
protected $errors;

   
/**
     * @type array
     */
   
protected $_current;

   
/**
     * @type array
     */
   
protected $_stacks = array(array());

   
/**
     * @type HTMLPurifier_Language
     */
   
protected $locale;

   
/**
     * @type HTMLPurifier_Generator
     */
   
protected $generator;

   
/**
     * @type HTMLPurifier_Context
     */
   
protected $context;

   
/**
     * @type array
     */
   
protected $lines = array();

   
/**
     * @param HTMLPurifier_Context $context
     */
   
public function __construct($context)
    {
       
$this->locale    =& $context->get('Locale');
       
$this->context   = $context;
       
$this->_current  =& $this->_stacks[0];
       
$this->errors    =& $this->_stacks[0];
    }

   
/**
     * Sends an error message to the collector for later use
     * @param int $severity Error severity, PHP error style (don't use E_USER_)
     * @param string $msg Error message text
     */
   
public function send($severity, $msg)
    {
       
$args = array();
        if (
func_num_args() > 2) {
           
$args = func_get_args();
           
array_shift($args);
            unset(
$args[0]);
        }

       
$token = $this->context->get('CurrentToken', true);
       
$line  = $token ? $token->line : $this->context->get('CurrentLine', true);
       
$col   = $token ? $token->col  : $this->context->get('CurrentCol', true);
       
$attr  = $this->context->get('CurrentAttr', true);

       
// perform special substitutions, also add custom parameters
       
$subst = array();
        if (!
is_null($token)) {
           
$args['CurrentToken'] = $token;
        }
        if (!
is_null($attr)) {
           
$subst['$CurrentAttr.Name'] = $attr;
            if (isset(
$token->attr[$attr])) {
               
$subst['$CurrentAttr.Value'] = $token->attr[$attr];
            }
        }

        if (empty(
$args)) {
           
$msg = $this->locale->getMessage($msg);
        } else {
           
$msg = $this->locale->formatMessage($msg, $args);
        }

        if (!empty(
$subst)) {
           
$msg = strtr($msg, $subst);
        }

       
// (numerically indexed)
       
$error = array(
           
self::LINENO   => $line,
           
self::SEVERITY => $severity,
           
self::MESSAGE  => $msg,
           
self::CHILDREN => array()
        );
       
$this->_current[] = $error;

       
// NEW CODE BELOW ...
        // Top-level errors are either:
        //  TOKEN type, if $value is set appropriately, or
        //  "syntax" type, if $value is null
       
$new_struct = new HTMLPurifier_ErrorStruct();
       
$new_struct->type = HTMLPurifier_ErrorStruct::TOKEN;
        if (
$token) {
           
$new_struct->value = clone $token;
        }
        if (
is_int($line) && is_int($col)) {
            if (isset(
$this->lines[$line][$col])) {
               
$struct = $this->lines[$line][$col];
            } else {
               
$struct = $this->lines[$line][$col] = $new_struct;
            }
           
// These ksorts may present a performance problem
           
ksort($this->lines[$line], SORT_NUMERIC);
        } else {
            if (isset(
$this->lines[-1])) {
               
$struct = $this->lines[-1];
            } else {
               
$struct = $this->lines[-1] = $new_struct;
            }
        }
       
ksort($this->lines, SORT_NUMERIC);

       
// Now, check if we need to operate on a lower structure
       
if (!empty($attr)) {
           
$struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr);
            if (!
$struct->value) {
               
$struct->value = array($attr, 'PUT VALUE HERE');
            }
        }
        if (!empty(
$cssprop)) {
           
$struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop);
            if (!
$struct->value) {
               
// if we tokenize CSS this might be a little more difficult to do
               
$struct->value = array($cssprop, 'PUT VALUE HERE');
            }
        }

       
// Ok, structs are all setup, now time to register the error
       
$struct->addError($severity, $msg);
    }

   
/**
     * Retrieves raw error data for custom formatter to use
     */
   
public function getRaw()
    {
        return
$this->errors;
    }

   
/**
     * Default HTML formatting implementation for error messages
     * @param HTMLPurifier_Config $config Configuration, vital for HTML output nature
     * @param array $errors Errors array to display; used for recursion.
     * @return string
     */
   
public function getHTMLFormatted($config, $errors = null)
    {
       
$ret = array();

       
$this->generator = new HTMLPurifier_Generator($config, $this->context);
        if (
$errors === null) {
           
$errors = $this->errors;
        }

       
// 'At line' message needs to be removed

        // generation code for new structure goes here. It needs to be recursive.
       
foreach ($this->lines as $line => $col_array) {
            if (
$line == -1) {
                continue;
            }
            foreach (
$col_array as $col => $struct) {
               
$this->_renderStruct($ret, $struct, $line, $col);
            }
        }
        if (isset(
$this->lines[-1])) {
           
$this->_renderStruct($ret, $this->lines[-1]);
        }

        if (empty(
$errors)) {
            return
'<p>' . $this->locale->getMessage('ErrorCollector: No errors') . '</p>';
        } else {
            return
'<ul><li>' . implode('</li><li>', $ret) . '</li></ul>';
        }

    }

    private function
_renderStruct(&$ret, $struct, $line = null, $col = null)
    {
       
$stack = array($struct);
       
$context_stack = array(array());
        while (
$current = array_pop($stack)) {
           
$context = array_pop($context_stack);
            foreach (
$current->errors as $error) {
                list(
$severity, $msg) = $error;
               
$string = '';
               
$string .= '<div>';
               
// W3C uses an icon to indicate the severity of the error.
               
$error = $this->locale->getErrorName($severity);
               
$string .= "<span class=\"error e$severity\"><strong>$error</strong></span> ";
                if (!
is_null($line) && !is_null($col)) {
                   
$string .= "<em class=\"location\">Line $line, Column $col: </em> ";
                } else {
                   
$string .= '<em class="location">End of Document: </em> ';
                }
               
$string .= '<strong class="description">' . $this->generator->escape($msg) . '</strong> ';
               
$string .= '</div>';
               
// Here, have a marker for the character on the column appropriate.
                // Be sure to clip extremely long lines.
                //$string .= '<pre>';
                //$string .= '';
                //$string .= '</pre>';
               
$ret[] = $string;
            }
            foreach (
$current->children as $array) {
               
$context[] = $current;
               
$stack = array_merge($stack, array_reverse($array, true));
                for (
$i = count($array); $i > 0; $i--) {
                   
$context_stack[] = $context;
                }
            }
        }
    }
}

// vim: et sw=4 sts=4