mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Created pear directory which includes the PEAR HTML_BBCodeParser-1.2.2 and PEAR.php
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@41270 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
85b45924a2
commit
8055b4b291
882
pear/HTML/BBCodeParser.php
Normal file
882
pear/HTML/BBCodeParser.php
Normal file
@ -0,0 +1,882 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: BBCodeParser.php,v 1.17 2007/07/02 18:46:30 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This is a parser to replace UBB style tags with their html equivalents. It
|
||||||
|
* does not simply do some regex calls, but is complete stack based
|
||||||
|
* parse engine. This ensures that all tags are properly nested, if not,
|
||||||
|
* extra tags are added to maintain the nesting. This parser should only produce
|
||||||
|
* xhtml 1.0 compliant code. All tags are validated and so are all their attributes.
|
||||||
|
* It should be easy to extend this parser with your own tags, see the _definedTags
|
||||||
|
* format description below.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* $parser = new HTML_BBCodeParser();
|
||||||
|
* $parser->setText('normal [b]bold[/b] and normal again');
|
||||||
|
* $parser->parse();
|
||||||
|
* echo $parser->getParsed();
|
||||||
|
* or:
|
||||||
|
* $parser = new HTML_BBCodeParser();
|
||||||
|
* echo $parser->qparse('normal [b]bold[/b] and normal again');
|
||||||
|
* or:
|
||||||
|
* echo HTML_BBCodeParser::staticQparse('normal [b]bold[/b] and normal again');
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Setting the options from the ini file:
|
||||||
|
* $config = parse_ini_file('BBCodeParser.ini', true);
|
||||||
|
* $options = &PEAR::getStaticProperty('HTML_BBCodeParser', '_options');
|
||||||
|
* $options = $config['HTML_BBCodeParser'];
|
||||||
|
* unset($options);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The _definedTags variables should be in this format:
|
||||||
|
* array('tag' // the actual tag used
|
||||||
|
* => array('htmlopen' => 'open', // the opening tag in html
|
||||||
|
* 'htmlclose' => 'close', // the closing tag in html,
|
||||||
|
* can be set to an empty string
|
||||||
|
* if no closing tag is present
|
||||||
|
* in html (like <img>)
|
||||||
|
* 'allowed' => 'allow', // tags that are allowed inside
|
||||||
|
* this tag. Values can be all
|
||||||
|
* or none, or either of these
|
||||||
|
* two, followed by a ^ and then
|
||||||
|
* followed by a comma seperated
|
||||||
|
* list of exceptions on this
|
||||||
|
* 'attributes' => array() // an associative array containing
|
||||||
|
* the tag attributes and their
|
||||||
|
* printf() html equivalents, to
|
||||||
|
* which the first argument is
|
||||||
|
* the value, and the second is
|
||||||
|
* the quote. Default would be
|
||||||
|
* something like this:
|
||||||
|
* 'attr' => 'attr=%2$s%1$s%2$s'
|
||||||
|
* ),
|
||||||
|
* 'etc'
|
||||||
|
* => (...)
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
|
||||||
|
class HTML_BBCodeParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine, should be overwritten by filters
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string containing the input
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_text = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string containing the preparsed input
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_preparsed = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array tags and texts build from the input text
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_tagArray = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A string containing the parsed version of the text
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_parsed = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of options, filled by an ini file or through the contructor
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_options = array(
|
||||||
|
'quotestyle' => 'double',
|
||||||
|
'quotewhat' => 'all',
|
||||||
|
'open' => '[',
|
||||||
|
'close' => ']',
|
||||||
|
'xmlclose' => true,
|
||||||
|
'filters' => 'Basic'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of filters used for parsing
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_filters = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor, initialises the options and filters
|
||||||
|
*
|
||||||
|
* Sets the private variable _options with base options defined with
|
||||||
|
* &PEAR::getStaticProperty(), overwriting them with (if present)
|
||||||
|
* the argument to this method.
|
||||||
|
* Then it sets the extra options to properly escape the tag
|
||||||
|
* characters in preg_replace() etc. The set options are
|
||||||
|
* then stored back with &PEAR::getStaticProperty(), so that the filter
|
||||||
|
* classes can use them.
|
||||||
|
* All the filters in the options are initialised and their defined tags
|
||||||
|
* are copied into the private variable _definedTags.
|
||||||
|
*
|
||||||
|
* @param array options to use, can be left out
|
||||||
|
* @return none
|
||||||
|
* @access public
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function HTML_BBCodeParser($options = array())
|
||||||
|
{
|
||||||
|
// set the already set options
|
||||||
|
$baseoptions = &PEAR::getStaticProperty('HTML_BBCodeParser', '_options');
|
||||||
|
if (is_array($baseoptions)) {
|
||||||
|
foreach ($baseoptions as $k => $v) {
|
||||||
|
$this->_options[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the options passed as an argument
|
||||||
|
foreach ($options as $k => $v ) {
|
||||||
|
$this->_options[$k] = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add escape open and close chars to the options for preg escaping
|
||||||
|
$preg_escape = '\^$.[]|()?*+{}';
|
||||||
|
if ($this->_options['open'] != '' && strpos($preg_escape, $this->_options['open'])) {
|
||||||
|
$this->_options['open_esc'] = "\\".$this->_options['open'];
|
||||||
|
} else {
|
||||||
|
$this->_options['open_esc'] = $this->_options['open'];
|
||||||
|
}
|
||||||
|
if ($this->_options['close'] != '' && strpos($preg_escape, $this->_options['close'])) {
|
||||||
|
$this->_options['close_esc'] = "\\".$this->_options['close'];
|
||||||
|
} else {
|
||||||
|
$this->_options['close_esc'] = $this->_options['close'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the options back so that child classes can use them */
|
||||||
|
$baseoptions = $this->_options;
|
||||||
|
unset($baseoptions);
|
||||||
|
|
||||||
|
// return if this is a subclass
|
||||||
|
if (is_subclass_of($this, 'HTML_BBCodeParser_Filter')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the definedTags from subclasses */
|
||||||
|
$this->addFilters($this->_options['filters']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option setter
|
||||||
|
*
|
||||||
|
* @param string option name
|
||||||
|
* @param mixed option value
|
||||||
|
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||||
|
*/
|
||||||
|
function setOption($name, $value)
|
||||||
|
{
|
||||||
|
$this->_options[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new filter
|
||||||
|
*
|
||||||
|
* @param string filter
|
||||||
|
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||||
|
*/
|
||||||
|
function addFilter($filter)
|
||||||
|
{
|
||||||
|
$filter = ucfirst($filter);
|
||||||
|
if (!array_key_exists($filter, $this->_filters)) {
|
||||||
|
$class = 'HTML_BBCodeParser_Filter_'.$filter;
|
||||||
|
@include_once 'HTML/BBCodeParser/Filter/'.$filter.'.php';
|
||||||
|
if (!class_exists($class)) {
|
||||||
|
PEAR::raiseError("Failed to load filter $filter", null, PEAR_ERROR_DIE);
|
||||||
|
}
|
||||||
|
$this->_filters[$filter] = new $class;
|
||||||
|
$this->_definedTags = array_merge(
|
||||||
|
$this->_definedTags,
|
||||||
|
$this->_filters[$filter]->_definedTags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an existing filter
|
||||||
|
*
|
||||||
|
* @param string $filter
|
||||||
|
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||||
|
*/
|
||||||
|
function removeFilter($filter)
|
||||||
|
{
|
||||||
|
$filter = ucfirst(trim($filter));
|
||||||
|
if (!empty($filter) && array_key_exists($filter, $this->_filters)) {
|
||||||
|
unset($this->_filters[$filter]);
|
||||||
|
}
|
||||||
|
// also remove the related $this->_definedTags for this filter,
|
||||||
|
// preserving the others
|
||||||
|
$this->_definedTags = array();
|
||||||
|
foreach (array_keys($this->_filters) as $filter) {
|
||||||
|
$this->_definedTags = array_merge(
|
||||||
|
$this->_definedTags,
|
||||||
|
$this->_filters[$filter]->_definedTags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new filters
|
||||||
|
*
|
||||||
|
* @param mixed (array or string)
|
||||||
|
* @return boolean true if all ok, false if not.
|
||||||
|
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||||
|
*/
|
||||||
|
function addFilters($filters)
|
||||||
|
{
|
||||||
|
if (is_string($filters)) {
|
||||||
|
//comma-separated list
|
||||||
|
if (strpos($filters, ',') !== false) {
|
||||||
|
$filters = explode(',', $filters);
|
||||||
|
} else {
|
||||||
|
$filters = array($filters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_array($filters)) {
|
||||||
|
//invalid format
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($filters as $filter) {
|
||||||
|
if (trim($filter)){
|
||||||
|
$this->addFilter($filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes statements before the actual array building starts
|
||||||
|
*
|
||||||
|
* This method should be overwritten in a filter if you want to do
|
||||||
|
* something before the parsing process starts. This can be useful to
|
||||||
|
* allow certain short alternative tags which then can be converted into
|
||||||
|
* proper tags with preg_replace() calls.
|
||||||
|
* The main class walks through all the filters and and calls this
|
||||||
|
* method. The filters should modify their private $_preparsed
|
||||||
|
* variable, with input from $_text.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _preparse()
|
||||||
|
{
|
||||||
|
// default: assign _text to _preparsed, to be overwritten by filters
|
||||||
|
$this->_preparsed = $this->_text;
|
||||||
|
|
||||||
|
// return if this is a subclass
|
||||||
|
if (is_subclass_of($this, 'HTML_BBCodeParser')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk through the filters and execute _preparse
|
||||||
|
foreach ($this->_filters as $filter) {
|
||||||
|
$filter->setText($this->_preparsed);
|
||||||
|
$filter->_preparse();
|
||||||
|
$this->_preparsed = $filter->getPreparsed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the tag array from the input string $_text
|
||||||
|
*
|
||||||
|
* An array consisting of tag and text elements is contructed from the
|
||||||
|
* $_preparsed variable. The method uses _buildTag() to check if a tag is
|
||||||
|
* valid and to build the actual tag to be added to the tag array.
|
||||||
|
*
|
||||||
|
* TODO: - rewrite whole method, as this one is old and probably slow
|
||||||
|
* - see if a recursive method would be better than an iterative one
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see _buildTag()
|
||||||
|
* @see $_text
|
||||||
|
* @see $_tagArray
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _buildTagArray()
|
||||||
|
{
|
||||||
|
$this->_tagArray = array();
|
||||||
|
$str = $this->_preparsed;
|
||||||
|
$strPos = 0;
|
||||||
|
$strLength = strlen($str);
|
||||||
|
|
||||||
|
while (($strPos < $strLength)) {
|
||||||
|
$tag = array();
|
||||||
|
$openPos = strpos($str, $this->_options['open'], $strPos);
|
||||||
|
if ($openPos === false) {
|
||||||
|
$openPos = $strLength;
|
||||||
|
$nextOpenPos = $strLength;
|
||||||
|
}
|
||||||
|
if ($openPos + 1 > $strLength) {
|
||||||
|
$nextOpenPos = $strLength;
|
||||||
|
} else {
|
||||||
|
$nextOpenPos = strpos($str, $this->_options['open'], $openPos + 1);
|
||||||
|
if ($nextOpenPos === false) {
|
||||||
|
$nextOpenPos = $strLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$closePos = strpos($str, $this->_options['close'], $strPos);
|
||||||
|
if ($closePos === false) {
|
||||||
|
$closePos = $strLength + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($openPos == $strPos) {
|
||||||
|
if (($nextOpenPos < $closePos)) {
|
||||||
|
// new open tag before closing tag: treat as text
|
||||||
|
$newPos = $nextOpenPos;
|
||||||
|
$tag['text'] = substr($str, $strPos, $nextOpenPos - $strPos);
|
||||||
|
$tag['type'] = 0;
|
||||||
|
} else {
|
||||||
|
// possible valid tag
|
||||||
|
$newPos = $closePos + 1;
|
||||||
|
$newTag = $this->_buildTag(substr($str, $strPos, $closePos - $strPos + 1));
|
||||||
|
if (($newTag !== false)) {
|
||||||
|
$tag = $newTag;
|
||||||
|
} else {
|
||||||
|
// no valid tag after all
|
||||||
|
$tag['text'] = substr($str, $strPos, $closePos - $strPos + 1);
|
||||||
|
$tag['type'] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// just text
|
||||||
|
$newPos = $openPos;
|
||||||
|
$tag['text'] = substr($str, $strPos, $openPos - $strPos);
|
||||||
|
$tag['type'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// join 2 following text elements
|
||||||
|
if ($tag['type'] === 0 && isset($prev) && $prev['type'] === 0) {
|
||||||
|
$tag['text'] = $prev['text'].$tag['text'];
|
||||||
|
array_pop($this->_tagArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_tagArray[] = $tag;
|
||||||
|
$prev = $tag;
|
||||||
|
$strPos = $newPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a tag from the input string
|
||||||
|
*
|
||||||
|
* This method builds a tag array based on the string it got as an
|
||||||
|
* argument. If the tag is invalid, <false> is returned. The tag
|
||||||
|
* attributes are extracted from the string and stored in the tag
|
||||||
|
* array as an associative array.
|
||||||
|
*
|
||||||
|
* @param string string to build tag from
|
||||||
|
* @return array tag in array format
|
||||||
|
* @access private
|
||||||
|
* @see _buildTagArray()
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _buildTag($str)
|
||||||
|
{
|
||||||
|
$tag = array('text' => $str, 'attributes' => array());
|
||||||
|
|
||||||
|
if (substr($str, 1, 1) == '/') { // closing tag
|
||||||
|
|
||||||
|
$tag['tag'] = strtolower(substr($str, 2, strlen($str) - 3));
|
||||||
|
if (!in_array($tag['tag'], array_keys($this->_definedTags))) {
|
||||||
|
return false; // nope, it's not valid
|
||||||
|
} else {
|
||||||
|
$tag['type'] = 2;
|
||||||
|
return $tag;
|
||||||
|
}
|
||||||
|
} else { // opening tag
|
||||||
|
|
||||||
|
$tag['type'] = 1;
|
||||||
|
if (strpos($str, ' ') && (strpos($str, '=') === false)) {
|
||||||
|
return false; // nope, it's not valid
|
||||||
|
}
|
||||||
|
|
||||||
|
// tnx to Onno for the regex
|
||||||
|
// split the tag with arguments and all
|
||||||
|
$oe = $this->_options['open_esc'];
|
||||||
|
$ce = $this->_options['close_esc'];
|
||||||
|
$tagArray = array();
|
||||||
|
if (preg_match("!$oe([a-z0-9]+)[^$ce]*$ce!i", $str, $tagArray) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$tag['tag'] = strtolower($tagArray[1]);
|
||||||
|
if (!in_array($tag['tag'], array_keys($this->_definedTags))) {
|
||||||
|
return false; // nope, it's not valid
|
||||||
|
}
|
||||||
|
|
||||||
|
// tnx to Onno for the regex
|
||||||
|
// validate the arguments
|
||||||
|
$attributeArray = array();
|
||||||
|
$regex = "![\s$oe]([a-z0-9]+)=(\"[^\s$ce]+\"|[^\s$ce]";
|
||||||
|
if ($tag['tag'] != 'url') {
|
||||||
|
$regex .= "[^=]";
|
||||||
|
}
|
||||||
|
$regex .= "+)(?=[\s$ce])!i";
|
||||||
|
preg_match_all($regex, $str, $attributeArray, PREG_SET_ORDER);
|
||||||
|
foreach ($attributeArray as $attribute) {
|
||||||
|
$attNam = strtolower($attribute[1]);
|
||||||
|
if (in_array($attNam, array_keys($this->_definedTags[$tag['tag']]['attributes']))) {
|
||||||
|
if ($attribute[2][0] == '"' && $attribute[2][strlen($attribute[2])-1] == '"') {
|
||||||
|
$tag['attributes'][$attNam] = substr($attribute[2], 1, -1);
|
||||||
|
} else {
|
||||||
|
$tag['attributes'][$attNam] = $attribute[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the tag array, regarding the allowed tags
|
||||||
|
*
|
||||||
|
* While looping through the tag array, two following text tags are
|
||||||
|
* joined, and it is checked that the tag is allowed inside the
|
||||||
|
* last opened tag.
|
||||||
|
* By remembering what tags have been opened it is checked that
|
||||||
|
* there is correct (xml compliant) nesting.
|
||||||
|
* In the end all still opened tags are closed.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see _isAllowed()
|
||||||
|
* @see $_tagArray
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>, Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function _validateTagArray()
|
||||||
|
{
|
||||||
|
$newTagArray = array();
|
||||||
|
$openTags = array();
|
||||||
|
foreach ($this->_tagArray as $tag) {
|
||||||
|
$prevTag = end($newTagArray);
|
||||||
|
switch ($tag['type']) {
|
||||||
|
case 0:
|
||||||
|
if (($child = $this->_childNeeded(end($openTags), 'text')) &&
|
||||||
|
$child !== false &&
|
||||||
|
/*
|
||||||
|
* No idea what to do in this case: A child is needed, but
|
||||||
|
* no valid one is returned. We'll ignore it here and live
|
||||||
|
* with it until someone reports a valid bug.
|
||||||
|
*/
|
||||||
|
$child !== true )
|
||||||
|
{
|
||||||
|
if (trim($tag['text']) == '') {
|
||||||
|
//just an empty indentation or newline without value?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$newTagArray[] = $child;
|
||||||
|
$openTags[] = $child['tag'];
|
||||||
|
}
|
||||||
|
if ($prevTag['type'] === 0) {
|
||||||
|
$tag['text'] = $prevTag['text'].$tag['text'];
|
||||||
|
array_pop($newTagArray);
|
||||||
|
}
|
||||||
|
$newTagArray[] = $tag;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (!$this->_isAllowed(end($openTags), $tag['tag']) ||
|
||||||
|
($parent = $this->_parentNeeded(end($openTags), $tag['tag'])) === true ||
|
||||||
|
($child = $this->_childNeeded(end($openTags), $tag['tag'])) === true) {
|
||||||
|
$tag['type'] = 0;
|
||||||
|
if ($prevTag['type'] === 0) {
|
||||||
|
$tag['text'] = $prevTag['text'].$tag['text'];
|
||||||
|
array_pop($newTagArray);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($parent) {
|
||||||
|
/*
|
||||||
|
* Avoid use of parent if we can help it. If we are
|
||||||
|
* trying to insert a new parent, but the current tag is
|
||||||
|
* the same as the previous tag, then assume that the
|
||||||
|
* previous tag structure is valid, and add this tag as
|
||||||
|
* a sibling. To add as a sibling, we need to close the
|
||||||
|
* current tag.
|
||||||
|
*/
|
||||||
|
if ($tag['tag'] == end($openTags)){
|
||||||
|
$newTagArray[] = $this->_buildTag('[/'.$tag['tag'].']');
|
||||||
|
array_pop($openTags);
|
||||||
|
} else {
|
||||||
|
$newTagArray[] = $parent;
|
||||||
|
$openTags[] = $parent['tag'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($child) {
|
||||||
|
$newTagArray[] = $child;
|
||||||
|
$openTags[] = $child['tag'];
|
||||||
|
}
|
||||||
|
$openTags[] = $tag['tag'];
|
||||||
|
}
|
||||||
|
$newTagArray[] = $tag;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (($tag['tag'] == end($openTags) || $this->_isAllowed(end($openTags), $tag['tag']))) {
|
||||||
|
if (in_array($tag['tag'], $openTags)) {
|
||||||
|
$tmpOpenTags = array();
|
||||||
|
while (end($openTags) != $tag['tag']) {
|
||||||
|
$newTagArray[] = $this->_buildTag('[/'.end($openTags).']');
|
||||||
|
$tmpOpenTags[] = end($openTags);
|
||||||
|
array_pop($openTags);
|
||||||
|
}
|
||||||
|
$newTagArray[] = $tag;
|
||||||
|
array_pop($openTags);
|
||||||
|
/* why is this here? it just seems to break things
|
||||||
|
* (nested lists where closing tags need to be
|
||||||
|
* generated)
|
||||||
|
while (end($tmpOpenTags)) {
|
||||||
|
$tmpTag = $this->_buildTag('['.end($tmpOpenTags).']');
|
||||||
|
$newTagArray[] = $tmpTag;
|
||||||
|
$openTags[] = $tmpTag['tag'];
|
||||||
|
array_pop($tmpOpenTags);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$tag['type'] = 0;
|
||||||
|
if ($prevTag['type'] === 0) {
|
||||||
|
$tag['text'] = $prevTag['text'].$tag['text'];
|
||||||
|
array_pop($newTagArray);
|
||||||
|
}
|
||||||
|
$newTagArray[] = $tag;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (end($openTags)) {
|
||||||
|
$newTagArray[] = $this->_buildTag('[/'.end($openTags).']');
|
||||||
|
array_pop($openTags);
|
||||||
|
}
|
||||||
|
$this->_tagArray = $newTagArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a parent is needed
|
||||||
|
*
|
||||||
|
* Checks to see if the current $in tag has an appropriate parent. If it
|
||||||
|
* does, then it returns false. If a parent is needed, then it returns the
|
||||||
|
* first tag in the list to add to the stack.
|
||||||
|
*
|
||||||
|
* @param array tag that is on the outside
|
||||||
|
* @param array tag that is on the inside
|
||||||
|
* @return boolean false if not needed, tag if needed, true if out
|
||||||
|
* of our minds
|
||||||
|
* @access private
|
||||||
|
* @see _validateTagArray()
|
||||||
|
* @author Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function _parentNeeded($out, $in)
|
||||||
|
{
|
||||||
|
if (!isset($this->_definedTags[$in]['parent']) ||
|
||||||
|
($this->_definedTags[$in]['parent'] == 'all')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ar = explode('^', $this->_definedTags[$in]['parent']);
|
||||||
|
$tags = explode(',', $ar[1]);
|
||||||
|
if ($ar[0] == 'none'){
|
||||||
|
if ($out && in_array($out, $tags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Create a tag from the first one on the list
|
||||||
|
return $this->_buildTag('['.$tags[0].']');
|
||||||
|
}
|
||||||
|
if ($ar[0] == 'all' && $out && !in_array($out, $tags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Tag is needed, we don't know which one. We could make something up,
|
||||||
|
// but it would be so random, I think that it would be worthless.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a child is needed
|
||||||
|
*
|
||||||
|
* Checks to see if the current $out tag has an appropriate child. If it
|
||||||
|
* does, then it returns false. If a child is needed, then it returns the
|
||||||
|
* first tag in the list to add to the stack.
|
||||||
|
*
|
||||||
|
* @param array tag that is on the outside
|
||||||
|
* @param array tag that is on the inside
|
||||||
|
* @return boolean false if not needed, tag if needed, true if out
|
||||||
|
* of our minds
|
||||||
|
* @access private
|
||||||
|
* @see _validateTagArray()
|
||||||
|
* @author Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function _childNeeded($out, $in)
|
||||||
|
{
|
||||||
|
if (!isset($this->_definedTags[$out]['child']) ||
|
||||||
|
($this->_definedTags[$out]['child'] == 'all')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ar = explode('^', $this->_definedTags[$out]['child']);
|
||||||
|
$tags = explode(',', $ar[1]);
|
||||||
|
if ($ar[0] == 'none'){
|
||||||
|
if ($in && in_array($in, $tags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Create a tag from the first one on the list
|
||||||
|
return $this->_buildTag('['.$tags[0].']');
|
||||||
|
}
|
||||||
|
if ($ar[0] == 'all' && $in && !in_array($in, $tags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Tag is needed, we don't know which one. We could make something up,
|
||||||
|
// but it would be so random, I think that it would be worthless.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a tag is allowed inside another tag
|
||||||
|
*
|
||||||
|
* The allowed tags are extracted from the private _definedTags array.
|
||||||
|
*
|
||||||
|
* @param array tag that is on the outside
|
||||||
|
* @param array tag that is on the inside
|
||||||
|
* @return boolean return true if the tag is allowed, false
|
||||||
|
* otherwise
|
||||||
|
* @access private
|
||||||
|
* @see _validateTagArray()
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _isAllowed($out, $in)
|
||||||
|
{
|
||||||
|
if (!$out || ($this->_definedTags[$out]['allowed'] == 'all')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($this->_definedTags[$out]['allowed'] == 'none') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ar = explode('^', $this->_definedTags[$out]['allowed']);
|
||||||
|
$tags = explode(',', $ar[1]);
|
||||||
|
if ($ar[0] == 'none' && in_array($in, $tags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($ar[0] == 'all' && in_array($in, $tags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a parsed string based on the tag array
|
||||||
|
*
|
||||||
|
* The correct html and attribute values are extracted from the private
|
||||||
|
* _definedTags array.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_tagArray
|
||||||
|
* @see $_parsed
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _buildParsedString()
|
||||||
|
{
|
||||||
|
$this->_parsed = '';
|
||||||
|
foreach ($this->_tagArray as $tag) {
|
||||||
|
switch ($tag['type']) {
|
||||||
|
|
||||||
|
// just text
|
||||||
|
case 0:
|
||||||
|
$this->_parsed .= $tag['text'];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// opening tag
|
||||||
|
case 1:
|
||||||
|
$this->_parsed .= '<'.$this->_definedTags[$tag['tag']]['htmlopen'];
|
||||||
|
if ($this->_options['quotestyle'] == 'single') $q = "'";
|
||||||
|
if ($this->_options['quotestyle'] == 'double') $q = '"';
|
||||||
|
foreach ($tag['attributes'] as $a => $v) {
|
||||||
|
//prevent XSS attacks. IMHO this is not enough, though...
|
||||||
|
//@see http://pear.php.net/bugs/bug.php?id=5609
|
||||||
|
$v = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1:", $v);
|
||||||
|
$v = htmlspecialchars($v);
|
||||||
|
$v = str_replace('&amp;', '&', $v);
|
||||||
|
|
||||||
|
if (($this->_options['quotewhat'] == 'nothing') ||
|
||||||
|
(($this->_options['quotewhat'] == 'strings') && is_numeric($v))
|
||||||
|
) {
|
||||||
|
$this->_parsed .= ' '.sprintf($this->_definedTags[$tag['tag']]['attributes'][$a], $v, '');
|
||||||
|
} else {
|
||||||
|
$this->_parsed .= ' '.sprintf($this->_definedTags[$tag['tag']]['attributes'][$a], $v, $q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->_definedTags[$tag['tag']]['htmlclose'] == '' && $this->_options['xmlclose']) {
|
||||||
|
$this->_parsed .= ' /';
|
||||||
|
}
|
||||||
|
$this->_parsed .= '>';
|
||||||
|
break;
|
||||||
|
|
||||||
|
// closing tag
|
||||||
|
case 2:
|
||||||
|
if ($this->_definedTags[$tag['tag']]['htmlclose'] != '') {
|
||||||
|
$this->_parsed .= '</'.$this->_definedTags[$tag['tag']]['htmlclose'].'>';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets text in the object to be parsed
|
||||||
|
*
|
||||||
|
* @param string the text to set in the object
|
||||||
|
* @return none
|
||||||
|
* @access public
|
||||||
|
* @see getText()
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function setText($str)
|
||||||
|
{
|
||||||
|
$this->_text = $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unparsed text from the object
|
||||||
|
*
|
||||||
|
* @return string the text set in the object
|
||||||
|
* @access public
|
||||||
|
* @see setText()
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function getText()
|
||||||
|
{
|
||||||
|
return $this->_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the preparsed text from the object
|
||||||
|
*
|
||||||
|
* @return string the text set in the object
|
||||||
|
* @access public
|
||||||
|
* @see _preparse()
|
||||||
|
* @see $_preparsed
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function getPreparsed()
|
||||||
|
{
|
||||||
|
return $this->_preparsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parsed text from the object
|
||||||
|
*
|
||||||
|
* @return string the parsed text set in the object
|
||||||
|
* @access public
|
||||||
|
* @see parse()
|
||||||
|
* @see $_parsed
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function getParsed()
|
||||||
|
{
|
||||||
|
return $this->_parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the text set in the object
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access public
|
||||||
|
* @see _preparse()
|
||||||
|
* @see _buildTagArray()
|
||||||
|
* @see _validateTagArray()
|
||||||
|
* @see _buildParsedString()
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function parse()
|
||||||
|
{
|
||||||
|
$this->_preparse();
|
||||||
|
$this->_buildTagArray();
|
||||||
|
$this->_validateTagArray();
|
||||||
|
$this->_buildParsedString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick method to do setText(), parse() and getParsed at once
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access public
|
||||||
|
* @see parse()
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function qparse($str)
|
||||||
|
{
|
||||||
|
$this->_text = $str;
|
||||||
|
$this->parse();
|
||||||
|
return $this->_parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick static method to do setText(), parse() and getParsed at once
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access public
|
||||||
|
* @see parse()
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function staticQparse($str)
|
||||||
|
{
|
||||||
|
$p = new HTML_BBCodeParser();
|
||||||
|
$str = $p->qparse($str);
|
||||||
|
unset($p);
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
10
pear/HTML/BBCodeParser/Filter.php
Normal file
10
pear/HTML/BBCodeParser/Filter.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'HTML/BBCodeParser.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy class that filters need to extend from.
|
||||||
|
*/
|
||||||
|
class HTML_BBCodeParser_Filter extends HTML_BBCodeParser
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
71
pear/HTML/BBCodeParser/Filter/Basic.php
Normal file
71
pear/HTML/BBCodeParser/Filter/Basic.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Basic.php,v 1.6 2007/07/02 16:54:25 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HTML_BBCodeParser_Filter_Basic extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array( 'b' => array( 'htmlopen' => 'strong',
|
||||||
|
'htmlclose' => 'strong',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'i' => array( 'htmlopen' => 'em',
|
||||||
|
'htmlclose' => 'em',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'u' => array( 'htmlopen' => 'span style="text-decoration:underline;"',
|
||||||
|
'htmlclose' => 'span',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
's' => array( 'htmlopen' => 'del',
|
||||||
|
'htmlclose' => 'del',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'sub' => array( 'htmlopen' => 'sub',
|
||||||
|
'htmlclose' => 'sub',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'sup' => array( 'htmlopen' => 'sup',
|
||||||
|
'htmlclose' => 'sup',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array())
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
85
pear/HTML/BBCodeParser/Filter/Email.php
Normal file
85
pear/HTML/BBCodeParser/Filter/Email.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Email.php,v 1.5 2007/07/02 16:54:25 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HTML_BBCodeParser_Filter_Email extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array( 'email' => array( 'htmlopen' => 'a',
|
||||||
|
'htmlclose' => 'a',
|
||||||
|
'allowed' => 'none^img',
|
||||||
|
'attributes'=> array('email' =>'href=%2$smailto:%1$s%2$s')
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes statements before the actual array building starts
|
||||||
|
*
|
||||||
|
* This method should be overwritten in a filter if you want to do
|
||||||
|
* something before the parsing process starts. This can be useful to
|
||||||
|
* allow certain short alternative tags which then can be converted into
|
||||||
|
* proper tags with preg_replace() calls.
|
||||||
|
* The main class walks through all the filters and and calls this
|
||||||
|
* method if it exists. The filters should modify their private $_text
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _preparse()
|
||||||
|
{
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser','_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
$oe = $options['open_esc'];
|
||||||
|
$ce = $options['close_esc'];
|
||||||
|
$pattern = array( "!(^|\s)([-a-z0-9_.]+@[-a-z0-9.]+\.[a-z]{2,4})!i",
|
||||||
|
"!".$oe."email(".$ce."|\s.*".$ce.")(.*)".$oe."/email".$ce."!Ui");
|
||||||
|
$replace = array( "\\1".$o."email=\\2".$c."\\2".$o."/email".$c,
|
||||||
|
$o."email=\\2\\1\\2".$o."/email".$c);
|
||||||
|
$this->_preparsed = preg_replace($pattern, $replace, $this->_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
97
pear/HTML/BBCodeParser/Filter/Extended.php
Normal file
97
pear/HTML/BBCodeParser/Filter/Extended.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Extended.php,v 1.3 2007/07/02 16:54:25 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class HTML_BBCodeParser_Filter_Extended extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array(
|
||||||
|
'color' => array( 'htmlopen' => 'span',
|
||||||
|
'htmlclose' => 'span',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array('color' =>'style=%2$scolor:%1$s%2$s')),
|
||||||
|
'size' => array( 'htmlopen' => 'span',
|
||||||
|
'htmlclose' => 'span',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array('size' =>'style=%2$sfont-size:%1$spt%2$s')),
|
||||||
|
'font' => array( 'htmlopen' => 'span',
|
||||||
|
'htmlclose' => 'span',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array('font' =>'style=%2$sfont-family:%1$s%2$s')),
|
||||||
|
'align' => array( 'htmlopen' => 'div',
|
||||||
|
'htmlclose' => 'div',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array('align' =>'style=%2$stext-align:%1$s%2$s')),
|
||||||
|
'quote' => array('htmlopen' => 'q',
|
||||||
|
'htmlclose' => 'q',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array('quote' =>'cite=%2$s%1$s%2$s')),
|
||||||
|
'code' => array('htmlopen' => 'code',
|
||||||
|
'htmlclose' => 'code',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h1' => array('htmlopen' => 'h1',
|
||||||
|
'htmlclose' => 'h1',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h2' => array('htmlopen' => 'h2',
|
||||||
|
'htmlclose' => 'h2',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h3' => array('htmlopen' => 'h3',
|
||||||
|
'htmlclose' => 'h3',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h4' => array('htmlopen' => 'h4',
|
||||||
|
'htmlclose' => 'h4',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h5' => array('htmlopen' => 'h5',
|
||||||
|
'htmlclose' => 'h5',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array()),
|
||||||
|
'h6' => array('htmlopen' => 'h6',
|
||||||
|
'htmlclose' => 'h6',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'attributes'=> array())
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
79
pear/HTML/BBCodeParser/Filter/Images.php
Normal file
79
pear/HTML/BBCodeParser/Filter/Images.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Images.php,v 1.8 2007/07/02 17:44:47 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
class HTML_BBCodeParser_Filter_Images extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array(
|
||||||
|
'img' => array(
|
||||||
|
'htmlopen' => 'img',
|
||||||
|
'htmlclose' => '',
|
||||||
|
'allowed' => 'none',
|
||||||
|
'attributes'=> array(
|
||||||
|
'img' => 'src=%2$s%1$s%2$s',
|
||||||
|
'w' => 'width=%2$s%1$d%2$s',
|
||||||
|
'h' => 'height=%2$s%1$d%2$s',
|
||||||
|
'alt' => 'alt=%2$s%1$s%2$s',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes statements before the actual array building starts
|
||||||
|
*
|
||||||
|
* This method should be overwritten in a filter if you want to do
|
||||||
|
* something before the parsing process starts. This can be useful to
|
||||||
|
* allow certain short alternative tags which then can be converted into
|
||||||
|
* proper tags with preg_replace() calls.
|
||||||
|
* The main class walks through all the filters and and calls this
|
||||||
|
* method if it exists. The filters should modify their private $_text
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
function _preparse()
|
||||||
|
{
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser','_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
$oe = $options['open_esc'];
|
||||||
|
$ce = $options['close_esc'];
|
||||||
|
$this->_preparsed = preg_replace(
|
||||||
|
"!".$oe."img(\s?.*)".$ce."(.*)".$oe."/img".$ce."!Ui",
|
||||||
|
$o."img=\"\$2\"\$1".$c.$o."/img".$c,
|
||||||
|
$this->_text);
|
||||||
|
}
|
||||||
|
}
|
200
pear/HTML/BBCodeParser/Filter/Links.php
Normal file
200
pear/HTML/BBCodeParser/Filter/Links.php
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Links.php,v 1.12 2007/07/02 18:26:17 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class HTML_BBCodeParser_Filter_Links extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* List of allowed schemes
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_allowedSchemes = array('http', 'https', 'ftp');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default scheme
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $_defaultScheme = 'http';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array(
|
||||||
|
'url' => array(
|
||||||
|
'htmlopen' => 'a',
|
||||||
|
'htmlclose' => 'a',
|
||||||
|
'allowed' => 'none^img',
|
||||||
|
'attributes'=> array('url' => 'href=%2$s%1$s%2$s')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes statements before the actual array building starts
|
||||||
|
*
|
||||||
|
* This method should be overwritten in a filter if you want to do
|
||||||
|
* something before the parsing process starts. This can be useful to
|
||||||
|
* allow certain short alternative tags which then can be converted into
|
||||||
|
* proper tags with preg_replace() calls.
|
||||||
|
* The main class walks through all the filters and and calls this
|
||||||
|
* method if it exists. The filters should modify their private $_text
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
* @author Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function _preparse()
|
||||||
|
{
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser', '_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
$oe = $options['open_esc'];
|
||||||
|
$ce = $options['close_esc'];
|
||||||
|
|
||||||
|
$schemes = implode('|', $this->_allowedSchemes);
|
||||||
|
|
||||||
|
$pattern = array( "/(?<![\"'=".$ce."\/])(".$oe."[^".$ce."]*".$ce.")?(((".$schemes."):\/\/|www)[@-a-z0-9.]+\.[a-z]{2,4}[^\s()\[\]]*)/i",
|
||||||
|
"!".$oe."url(".$ce."|\s.*".$ce.")(.*)".$oe."/url".$ce."!iU",
|
||||||
|
"!".$oe."url=((([a-z]*:(//)?)|www)[@-a-z0-9.]+)([^\s\[\]]*)".$ce."(.*)".$oe."/url".$ce."!i");
|
||||||
|
|
||||||
|
$pp = preg_replace_callback($pattern[0], array($this, 'smarterPPLinkExpand'), $this->_text);
|
||||||
|
$pp = preg_replace($pattern[1], $o."url=\$2\$1\$2".$o."/url".$c, $pp);
|
||||||
|
$this->_preparsed = preg_replace_callback($pattern[2], array($this, 'smarterPPLink'), $pp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intelligently expand a URL into a link
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @access private
|
||||||
|
* @author Seth Price <seth@pricepages.org>
|
||||||
|
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||||
|
*/
|
||||||
|
function smarterPPLinkExpand($matches)
|
||||||
|
{
|
||||||
|
//echo '<hr><pre>';var_dump($matches);echo '</pre><hr>';
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser','_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
|
||||||
|
//If we have an intro tag that is [url], then skip this match
|
||||||
|
if ($matches[1] == $o.'url'.$c) {
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$punctuation = '.,;:'; // Links can't end with these chars
|
||||||
|
$trailing = '';
|
||||||
|
// Knock off ending punctuation
|
||||||
|
$last = substr($matches[2], -1);
|
||||||
|
while (strpos($punctuation, $last) !== false) {
|
||||||
|
// Last character is punctuation - remove it from the url
|
||||||
|
$trailing = $last.$trailing;
|
||||||
|
$matches[2] = substr($matches[2], 0, -1);
|
||||||
|
$last = substr($matches[2], -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$off = strpos($matches[2], ':');
|
||||||
|
|
||||||
|
//Is a ":" (therefore a scheme) defined?
|
||||||
|
if ($off === false) {
|
||||||
|
/*
|
||||||
|
* Create a link with the default scheme of http. Notice that the
|
||||||
|
* text that is viewable to the user is unchanged, but the link
|
||||||
|
* itself contains the "http://".
|
||||||
|
*/
|
||||||
|
return $matches[1].$o.'url='.$this->_defaultScheme.'://'.$matches[2].$c.$matches[2].$o.'/url'.$c.$trailing;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scheme = substr($matches[2], 0, $off);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If protocol is in the approved list than allow it. Note that this
|
||||||
|
* check isn't really needed, but the created link will just be deleted
|
||||||
|
* later in smarterPPLink() if we create it now and it isn't on the
|
||||||
|
* scheme list.
|
||||||
|
*/
|
||||||
|
if (in_array($scheme, $this->_allowedSchemes)) {
|
||||||
|
return $matches[1].$o.'url'.$c.$matches[2].$o.'/url'.$c.$trailing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish preparsing URL to clean it up
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @access private
|
||||||
|
* @author Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function smarterPPLink($matches)
|
||||||
|
{
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser','_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
|
||||||
|
$urlServ = $matches[1];
|
||||||
|
$path = $matches[5];
|
||||||
|
|
||||||
|
$off = strpos($urlServ, ':');
|
||||||
|
|
||||||
|
if ($off === false) {
|
||||||
|
//Default to http
|
||||||
|
$urlServ = $this->_defaultScheme.'://'.$urlServ;
|
||||||
|
$off = strpos($urlServ, ':');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add trailing slash if missing (to create a valid URL)
|
||||||
|
if (!$path) {
|
||||||
|
$path = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
$protocol = substr($urlServ, 0, $off);
|
||||||
|
|
||||||
|
if (in_array($protocol, $this->_allowedSchemes)) {
|
||||||
|
//If protocol is in the approved list than allow it
|
||||||
|
return $o.'url='.$urlServ.$path.$c.$matches[6].$o.'/url'.$c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Else remove url tag
|
||||||
|
return $matches[6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
108
pear/HTML/BBCodeParser/Filter/Lists.php
Normal file
108
pear/HTML/BBCodeParser/Filter/Lists.php
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | PHP Version 4 |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Copyright (c) 1997-2003 The PHP Group |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | This source file is subject to version 2.02 of the PHP license, |
|
||||||
|
// | that is bundled with this package in the file LICENSE, and is |
|
||||||
|
// | available at through the world-wide-web at |
|
||||||
|
// | http://www.php.net/license/2_02.txt. |
|
||||||
|
// | If you did not receive a copy of the PHP license and are unable to |
|
||||||
|
// | obtain it through the world-wide-web, please send a note to |
|
||||||
|
// | license@php.net so we can mail you a copy immediately. |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
// | Author: Stijn de Reede <sjr@gmx.co.uk> |
|
||||||
|
// +----------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
// $Id: Lists.php,v 1.5 2007/07/02 16:54:25 cweiske Exp $
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package HTML_BBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class HTML_BBCodeParser_Filter_Lists extends HTML_BBCodeParser_Filter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of tags parsed by the engine
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
var $_definedTags = array( 'list' => array( 'htmlopen' => 'ol',
|
||||||
|
'htmlclose' => 'ol',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'child' => 'none^li',
|
||||||
|
'attributes'=> array('list' => 'style=%2$slist-style-type:%1$s;%2$s')
|
||||||
|
),
|
||||||
|
'ulist' => array( 'htmlopen' => 'ul',
|
||||||
|
'htmlclose' => 'ul',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'child' => 'none^li',
|
||||||
|
'attributes'=> array('list' => 'style=%2$slist-style-type:%1$s;%2$s')
|
||||||
|
),
|
||||||
|
'li' => array( 'htmlopen' => 'li',
|
||||||
|
'htmlclose' => 'li',
|
||||||
|
'allowed' => 'all',
|
||||||
|
'parent' => 'none^ulist,list',
|
||||||
|
'attributes'=> array()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes statements before the actual array building starts
|
||||||
|
*
|
||||||
|
* This method should be overwritten in a filter if you want to do
|
||||||
|
* something before the parsing process starts. This can be useful to
|
||||||
|
* allow certain short alternative tags which then can be converted into
|
||||||
|
* proper tags with preg_replace() calls.
|
||||||
|
* The main class walks through all the filters and and calls this
|
||||||
|
* method if it exists. The filters should modify their private $_text
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
* @access private
|
||||||
|
* @see $_text
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>, Seth Price <seth@pricepages.org>
|
||||||
|
*/
|
||||||
|
function _preparse()
|
||||||
|
{
|
||||||
|
$options = PEAR::getStaticProperty('HTML_BBCodeParser','_options');
|
||||||
|
$o = $options['open'];
|
||||||
|
$c = $options['close'];
|
||||||
|
$oe = $options['open_esc'];
|
||||||
|
$ce = $options['close_esc'];
|
||||||
|
|
||||||
|
$pattern = array( "!".$oe."\*".$ce."!",
|
||||||
|
"!".$oe."(u?)list=(?-i:A)(\s*[^".$ce."]*)".$ce."!i",
|
||||||
|
"!".$oe."(u?)list=(?-i:a)(\s*[^".$ce."]*)".$ce."!i",
|
||||||
|
"!".$oe."(u?)list=(?-i:I)(\s*[^".$ce."]*)".$ce."!i",
|
||||||
|
"!".$oe."(u?)list=(?-i:i)(\s*[^".$ce."]*)".$ce."!i",
|
||||||
|
"!".$oe."(u?)list=(?-i:1)(\s*[^".$ce."]*)".$ce."!i",
|
||||||
|
"!".$oe."(u?)list([^".$ce."]*)".$ce."!i");
|
||||||
|
|
||||||
|
$replace = array( $o."li".$c,
|
||||||
|
$o."\$1list=upper-alpha\$2".$c,
|
||||||
|
$o."\$1list=lower-alpha\$2".$c,
|
||||||
|
$o."\$1list=upper-roman\$2".$c,
|
||||||
|
$o."\$1list=lower-roman\$2".$c,
|
||||||
|
$o."\$1list=decimal\$2".$c,
|
||||||
|
$o."\$1list\$2".$c );
|
||||||
|
|
||||||
|
$this->_preparsed = preg_replace($pattern, $replace, $this->_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
23
pear/HTML/BBCodeParser/example/BBCodeParser.ini
Normal file
23
pear/HTML/BBCodeParser/example/BBCodeParser.ini
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[HTML_BBCodeParser]
|
||||||
|
|
||||||
|
; possible values: single|double
|
||||||
|
; use single or double quotes for attributes
|
||||||
|
quotestyle = single
|
||||||
|
|
||||||
|
; possible values: all|nothing|strings
|
||||||
|
; quote all attribute values, none, or only the strings
|
||||||
|
quotewhat = all
|
||||||
|
|
||||||
|
; the opening tag character
|
||||||
|
open = [
|
||||||
|
|
||||||
|
; the closing tag character
|
||||||
|
close = ]
|
||||||
|
|
||||||
|
; possible values: true|false
|
||||||
|
; use xml style closing tags for single html tags (<img> or <img />)
|
||||||
|
xmlclose = true
|
||||||
|
|
||||||
|
; possible values: a comma seperated list of filters
|
||||||
|
; comma seperated list of filters to use
|
||||||
|
filters = Basic,Extended,Links,Images,Lists,Email
|
118
pear/HTML/BBCodeParser/example/parser.php
Normal file
118
pear/HTML/BBCodeParser/example/parser.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/* adjust include_path to include PEAR */
|
||||||
|
ini_set('include_path', ini_get('include_path').':/usr/share/pear');
|
||||||
|
|
||||||
|
/* all your errors are belong to us */
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
/* require PEAR and the parser */
|
||||||
|
require_once('PEAR.php');
|
||||||
|
require_once('HTML/BBCodeParser.php');
|
||||||
|
|
||||||
|
/* get options from the ini file */
|
||||||
|
$config = parse_ini_file('BBCodeParser.ini', true);
|
||||||
|
$options = &PEAR::getStaticProperty('HTML_BBCodeParser', '_options');
|
||||||
|
$options = $config['HTML_BBCodeParser'];
|
||||||
|
unset($options);
|
||||||
|
|
||||||
|
/* do yer stuff! */
|
||||||
|
$parser = new HTML_BBCodeParser();
|
||||||
|
$parser->setText(@$_GET['string']);
|
||||||
|
$parser->parse();
|
||||||
|
$parsed = $parser->getParsed();
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>HTML_BBCodeParser (by Stijn de Reede)</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form method='get' action='parser.php'>
|
||||||
|
<table border='1' cellpadding='5' cellspacing='0'>
|
||||||
|
<tr><td valign='top'>
|
||||||
|
input:<br/>
|
||||||
|
<textarea cols='45' rows='10' name='string'><?php echo @$_GET['string']?></textarea><br/>
|
||||||
|
<td valign='top'>
|
||||||
|
ouput:<br/>
|
||||||
|
<textarea cols='45' rows='10'><?php echo htmlentities($parsed, ENT_QUOTES)?></textarea><br/>
|
||||||
|
</tr>
|
||||||
|
<tr><td valign='top' colspan='2' align='center'>
|
||||||
|
<input type='submit' value=' parse '><br/>
|
||||||
|
</tr>
|
||||||
|
<tr><td valign='top' colspan='2'>
|
||||||
|
<?php echo $parsed?>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan='2'>
|
||||||
|
possible codes:
|
||||||
|
<pre>
|
||||||
|
[b]bold[/b]
|
||||||
|
[i]italic[/i]
|
||||||
|
[u]underline[/u]
|
||||||
|
[s]strike[/s]
|
||||||
|
[sub]subscript[/sub]
|
||||||
|
[sup]superscript[/sup]
|
||||||
|
|
||||||
|
[color=blue]blue text[/color]
|
||||||
|
[size=18]the size of this text is 18pt[/size]
|
||||||
|
[font=arial]different font type[/font]
|
||||||
|
[align=right]yes, you're right, this isn't on the left[/align]
|
||||||
|
he said: [quote=http://www.server.org/quote.html]i'm tony montana[/quote]
|
||||||
|
[code]x + y = 6;[/code]
|
||||||
|
|
||||||
|
http://www.server.org
|
||||||
|
[url]http://www.server.org[/url]
|
||||||
|
[url=http://www.server.org]server[/url]
|
||||||
|
[url=http://www.server.org t=new]server[/url]
|
||||||
|
|
||||||
|
guest@anonymous.org
|
||||||
|
[email]guest@anonymous.org[/email]
|
||||||
|
[email=guest@anonymous.org]mail me[/email]
|
||||||
|
|
||||||
|
[img]http://www.server.org/image.jpg[/img]
|
||||||
|
[img w=100 h=200]http://www.server.org/image.jpg[/img]
|
||||||
|
|
||||||
|
[ulist]
|
||||||
|
[*]unordered item 1
|
||||||
|
[*]unordered item 2
|
||||||
|
[/ulist]
|
||||||
|
[list]
|
||||||
|
[*]unordered item 1
|
||||||
|
[*]unordered item 2
|
||||||
|
[/list]
|
||||||
|
|
||||||
|
[list=1]
|
||||||
|
[*]ordered item 1
|
||||||
|
[*]ordered item 2
|
||||||
|
[/list]
|
||||||
|
[list=i]
|
||||||
|
[*]ordered item 1 type i
|
||||||
|
[li=4]ordered item 4 type i[/li]
|
||||||
|
[/list]
|
||||||
|
[list=I]
|
||||||
|
[*]ordered item 1 type I
|
||||||
|
[/list]
|
||||||
|
[list=a s=5]
|
||||||
|
[li]ordered item 5 type a[/li]
|
||||||
|
[*]ordered item 6 type a
|
||||||
|
[/list]
|
||||||
|
[list=A]
|
||||||
|
[li]ordered item 1 type A[/li]
|
||||||
|
[li=12]ordered item 12 type A[/li]
|
||||||
|
[/list]
|
||||||
|
|
||||||
|
[list=A s=3]
|
||||||
|
[li]ordered item 1, nested list:
|
||||||
|
[list=I]
|
||||||
|
[li]nested item 1[/li]
|
||||||
|
[li]nested item 2[/li]
|
||||||
|
[/list][/li]
|
||||||
|
[li]ordered item 2[/li]
|
||||||
|
[/list]
|
||||||
|
</pre>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</html>
|
36
pear/HTML/tests/AllTests.php
Normal file
36
pear/HTML/tests/AllTests.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
if (!defined('PHPUnit_MAIN_METHOD')) {
|
||||||
|
define('PHPUnit_MAIN_METHOD', 'AllTests::main');
|
||||||
|
chdir(dirname(__FILE__) . '/../');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!defined('PHPUnit_INSIDE_OWN_TESTSUITE')) {
|
||||||
|
define('PHPUnit_INSIDE_OWN_TESTSUITE', TRUE);
|
||||||
|
}
|
||||||
|
require_once 'PHPUnit/Framework/TestSuite.php';
|
||||||
|
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML_BBCodeParserTest.php';
|
||||||
|
|
||||||
|
|
||||||
|
class AllTests
|
||||||
|
{
|
||||||
|
public static function main()
|
||||||
|
{
|
||||||
|
|
||||||
|
PHPUnit_TextUI_TestRunner::run(self::suite());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function suite()
|
||||||
|
{
|
||||||
|
$suite = new PHPUnit_Framework_TestSuite('HTML_BBCodeParserTest');
|
||||||
|
|
||||||
|
return $suite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PHPUnit_MAIN_METHOD == 'AllTests::main') {
|
||||||
|
AllTests::main();
|
||||||
|
}
|
||||||
|
?>
|
244
pear/HTML/tests/HTML_BBCodeParserTest.php
Normal file
244
pear/HTML/tests/HTML_BBCodeParserTest.php
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'PHPUnit.php';
|
||||||
|
require_once 'HTML/BBCodeParser.php';
|
||||||
|
|
||||||
|
class HTML_BBCodeParserTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
function testFilters()
|
||||||
|
{
|
||||||
|
$bbc = new HTML_BBCodeParser(array('filters' => ''));
|
||||||
|
$bbc->addFilter('Basic');
|
||||||
|
$this->basicBBCode($bbc, 'qparse');
|
||||||
|
$bbc->removeFilter('Basic');
|
||||||
|
$this->assertEquals('[b]txt[/b]', $bbc->qparse('[b]txt[/b]'), 'Basic filters have been removed.');
|
||||||
|
$bbc->addFilters('Basic,Email');
|
||||||
|
$this->basicBBCode($bbc, 'qparse');
|
||||||
|
$this->emailBBCode($bbc, 'qparse');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testQparse()
|
||||||
|
{
|
||||||
|
$bbc = new HTML_BBCodeParser(array('filters' => 'Basic,Email,Extended,Images,Links,Lists'));
|
||||||
|
$this->basicBBCode($bbc, 'qparse');
|
||||||
|
$this->listBBCode($bbc, 'qparse');
|
||||||
|
$this->linkBBCode($bbc, 'qparse');
|
||||||
|
$this->extBBCode($bbc, 'qparse');
|
||||||
|
$this->imgBBCode($bbc, 'qparse');
|
||||||
|
$this->emailBBCode($bbc, 'qparse');
|
||||||
|
}
|
||||||
|
|
||||||
|
function emailBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals('<a href="mailto:guest@anonymous.org">guest@anonymous.org</a>', $bbc->$funcNam('guest@anonymous.org'));
|
||||||
|
$this->assertEquals('<a href="mailto:guest@anonymous.org">mail me</a>', $bbc->$funcNam('[email=guest@anonymous.org]mail me[/email]'));
|
||||||
|
$this->assertEquals('<a href="mailto:guest@anonymous.org">guest@anonymous.org</a>', $bbc->$funcNam('[email]guest@anonymous.org[/email]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function imgBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals('<img src="/images/Enthalpy Wheel.png" width="100" height="99" alt="Enthalpy Wheel" />', $bbc->$funcNam('[img w=100 h=99 alt=Enthalpy Wheel]/images/Enthalpy Wheel.png[/img]'));
|
||||||
|
$this->assertEquals('<img src="img.jpg" />', $bbc->$funcNam('[img]img.jpg[/img]'));
|
||||||
|
$this->assertEquals('<img src="http://www.server.org/image.jpg" width="100" height="200" />', $bbc->$funcNam('[img w=100 h=200]http://www.server.org/image.jpg[/img]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function basicBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals('<strong>txt</strong>', $bbc->$funcNam('[b]txt[/b]'));
|
||||||
|
$this->assertEquals('<strong>txt</strong>', $bbc->$funcNam('[b]txt'));
|
||||||
|
$this->assertEquals('<em>txt</em>', $bbc->$funcNam('[i]txt[/i]'));
|
||||||
|
$this->assertEquals('<em>txt</em>', $bbc->$funcNam('[i]txt[/I]'));
|
||||||
|
$this->assertEquals('<em>txt</em>', $bbc->$funcNam('[I]txt[/i]'));
|
||||||
|
$this->assertEquals('<em>txt</em>', $bbc->$funcNam('[I]txt[/I]'));
|
||||||
|
$this->assertEquals('<del>txt</del>', $bbc->$funcNam('[s]txt[/s]'));
|
||||||
|
$this->assertEquals('<span style="text-decoration:underline;">txt</span>', $bbc->$funcNam('[u]txt[/u]'));
|
||||||
|
$this->assertEquals('<sub>txt</sub>', $bbc->$funcNam('[sub]txt[/sub]'));
|
||||||
|
$this->assertEquals('<sup>txt</sup>', $bbc->$funcNam('[sup]txt[/sup]'));
|
||||||
|
$this->assertEquals('<sup><sub>txt</sub></sup>', $bbc->$funcNam('[sup][sub]txt[/sup][/sub]'));
|
||||||
|
$this->assertEquals('<em><strong>txt</strong></em>', $bbc->$funcNam('[i][b]txt[/i][/b]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function listBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals('<ul><li>txt</li></ul>', $bbc->$funcNam('[*]txt'));
|
||||||
|
$this->assertEquals("<ul><li>txt\n</li></ul>", $bbc->$funcNam("[ulist][*]txt\n[/ulist]"));
|
||||||
|
$this->assertEquals('<ul><li>txt</li></ul>', $bbc->$funcNam('[ulist]txt[/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li><ul><li><ul><li>txt</li></ul></li></ul></li></ul>', $bbc->$funcNam('[ulist][ulist][ulist]txt'));
|
||||||
|
$this->assertEquals('<ul><li>[xxx]txt[/xxx]</li></ul>', $bbc->$funcNam('[ulist][xxx]txt[/xxx][/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li>txt</li></ul>', $bbc->$funcNam('[ulist][li]txt[/li][/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li>txt</li><li>txt</li></ul>', $bbc->$funcNam('[ulist][li]txt[li]txt[/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li>txt</li></ul>', $bbc->$funcNam('[ulist][*]txt[/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li><ol><li>txt</li></ol></li></ul>', $bbc->$funcNam('[ulist][*][list][*]txt[/ulist]'));
|
||||||
|
$this->assertEquals('<ol><li>txt</li></ol>', $bbc->$funcNam('[list][li]txt[/li][/list]'));
|
||||||
|
$this->assertEquals('<ul><li><ol><li>txt</li></ol></li></ul>', $bbc->$funcNam('[li][list][li]txt[/li][/list]'));
|
||||||
|
$this->assertEquals('<ul><li>txt<ul><li>txt</li></ul></li></ul>', $bbc->$funcNam('[*]txt[ulist]txt[/ulist]'));
|
||||||
|
$this->assertEquals('<ul><li><ul><li><ul><li><ul><li>txt</li></ul></li></ul></li></ul></li></ul>', $bbc->$funcNam('[li][ulist][ulist][ulist]txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:upper-alpha;"><li>ordered item 1, nested list:<ol style="list-style-type:upper-roman;"><li>nested item 1</li><li>nested item 2</li></ol></li><li>ordered item 2</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=A s=3][li]ordered item 1, nested list:[list=I][li]nested item 1[/li][li]nested item 2[/li][/list][/li][li]ordered item 2[/li][/list]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:upper-alpha;"><li>ordered item 1 type A</li><li>ordered item 12 type A</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=A][li]ordered item 1 type A[/li][li=12]ordered item 12 type A[/li][/list]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:lower-alpha;"><li>ordered item 5 type a</li><li>ordered item 6 type a</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=a s=5][li]ordered item 5 type a[/li][*]ordered item 6 type a[/list]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:upper-roman;"><li>ordered item 1 type I</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=I][*]ordered item 1 type I[/list]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:lower-roman;"><li>ordered item 1 type i</li><li>ordered item 4 type i</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=i][*]ordered item 1 type i[li=4]ordered item 4 type i[/li][/list]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:decimal;"><li>ordered item 1</li><li>ordered item 2</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=1][*]ordered item 1[*]ordered item 2[/list]'));
|
||||||
|
//Bug #512: [list] in a [list] breaks the first [list]
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol><li> Subject 1<ol><li> First</li><li> Second</li></ol></li><li> Subject 2</li></ol>',
|
||||||
|
$bbc->$funcNam('[list][*] Subject 1[list][*] First[*] Second[/list][*] Subject 2[/list]')
|
||||||
|
);
|
||||||
|
//Bug #1201: [list] output adding extra <li></li>
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol><li>txt</li></ol>',
|
||||||
|
$bbc->$funcNam('[list][*]txt[/list]')
|
||||||
|
);
|
||||||
|
//Bug#6335 Empty item displayed
|
||||||
|
$this->assertEquals(
|
||||||
|
'<ol style="list-style-type:decimal;"><li> Item one</li><li> Item two</li><li> Item three</li></ol>',
|
||||||
|
$bbc->$funcNam('[list=1][*] Item one[*] Item two[*] Item three[/list]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function linkBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://www.test.com/">http://www.test.com/</a>',
|
||||||
|
$bbc->$funcNam('http://www.test.com/'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://www.test.com/">www.test.com</a>',
|
||||||
|
$bbc->$funcNam('[url]www.test.com[/url]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://www.test.com/testurl">http://www.test.com/testurl</a>',
|
||||||
|
$bbc->$funcNam('[url]http://www.test.com/testurl[/url]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://www.test.com/">testurl</a>',
|
||||||
|
$bbc->$funcNam('[url=www.test.com/]testurl[/url]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://www.server.org">server</a>',
|
||||||
|
$bbc->$funcNam('[url=http://www.server.org t=new]server[/url]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <a href="http://www.test.com/">www.test.com</a> txt',
|
||||||
|
$bbc->$funcNam('txt www.test.com txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt (<a href="http://www.test.com/">www.test.com</a>) txt',
|
||||||
|
$bbc->$funcNam('txt (www.test.com) txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <a href="http://www.test.com/test.php?a=1,2">www.test.com/test.php?a=1,2</a>, txt',
|
||||||
|
$bbc->$funcNam('txt www.test.com/test.php?a=1,2, txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <a href="http://www.test.com/">www.test.com</a>, txt',
|
||||||
|
$bbc->$funcNam('txt www.test.com, txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <a href="http://www.test.com/">http://www.test.com</a>: txt',
|
||||||
|
$bbc->$funcNam('txt http://www.test.com: txt'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <a href="http://www.test.com/">www.test.com</a>; txt',
|
||||||
|
$bbc->$funcNam('txt www.test.com; txt'));
|
||||||
|
//Bug #1755: tags around an url -> mess
|
||||||
|
$this->assertEquals(
|
||||||
|
'txt <em><a href="http://www.test.com/">www.test.com</a></em> txt',
|
||||||
|
$bbc->$funcNam('txt [i]www.test.com[/i] txt'));
|
||||||
|
//Bug #1512: URL Tags Allow Javascript injection
|
||||||
|
$this->assertEquals(
|
||||||
|
'Click here',
|
||||||
|
$bbc->$funcNam('[url=javascript:location.replace("bad_link");]Click here[/url]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://domain.com/index.php?i=1&j=2">linked text</a>',
|
||||||
|
$bbc->$funcNam('[url=http://domain.com/index.php?i=1&j=2]linked text[/URL]'));
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="http://domain.com/index.php?i=1&j=2">linked text</a>',
|
||||||
|
$bbc->$funcNam('[url=http://domain.com/index.php?i=1&j=2]linked text[/URL]'));
|
||||||
|
//Bug #5609: BBCodeParser allows XSS
|
||||||
|
$this->assertEquals(
|
||||||
|
'<a href="javascript&#058;//%0ASh=alert(%22CouCou%22);window.close();">Alert box with "CouCou"</a>',
|
||||||
|
$bbc->$funcNam('[url=javascript://%0ASh=alert(%22CouCou%22);window.close();]Alert box with "CouCou"[/url]')
|
||||||
|
);
|
||||||
|
/*
|
||||||
|
//Request #4936: Nested URLs in quotes not handled
|
||||||
|
$this->assertEquals(
|
||||||
|
'<q>Quoted text</q>', //?!?!?
|
||||||
|
$bbc->$funcNam('[quote="[url=http://somewhere.com]URL-Title[/url]"]Quoted text[/quote]')
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function extBBCode($bbc, $funcNam)
|
||||||
|
{
|
||||||
|
$this->assertEquals('<h2>txt</h2>', $bbc->$funcNam('[h2]txt[/h2]'));
|
||||||
|
$this->assertEquals('<span style="color:blue">blue text</span>', $bbc->$funcNam('[color=blue]blue text[/color]'));
|
||||||
|
$this->assertEquals('<span style="font-size:18pt">the size of this text is 18pt</span>', $bbc->$funcNam('[size=18]the size of this text is 18pt[/size]'));
|
||||||
|
$this->assertEquals('<span style="font-family:arial">different font type</span>', $bbc->$funcNam('[font=arial]different font type[/font]'));
|
||||||
|
$this->assertEquals('<div style="text-align:right">yes, you\'re right, this isn\'t on the left</div>', $bbc->$funcNam('[align=right]yes, you\'re right, this isn\'t on the left[/align]'));
|
||||||
|
$this->assertEquals('he said: <q cite="http://www.server.org/quote.html">i\'m tony montana</q>', $bbc->$funcNam('he said: [quote=http://www.server.org/quote.html]i\'m tony montana[/quote]'));
|
||||||
|
$this->assertEquals('<code>x + y = 6;</code>', $bbc->$funcNam('[code]x + y = 6;[/code]'));
|
||||||
|
//Bug #1258: Extra tags rendered with faulty BBCode
|
||||||
|
$this->assertEquals(
|
||||||
|
'<span style="font-family:Verdana"><span style="color:red">my name NeverMind!</span></span>',
|
||||||
|
$bbc->$funcNam('[font=Verdana][color=red]my name NeverMind![/font][/color]')
|
||||||
|
);
|
||||||
|
//Bug #1979: Whitespaces in attribute are breaking it
|
||||||
|
$this->assertEquals(
|
||||||
|
'<span style="font-family:Comic Sans MS">txt</span>',
|
||||||
|
$bbc->$funcNam('[font=Comic Sans MS]txt[/font]')
|
||||||
|
);
|
||||||
|
//Bug #4844: Arbitrary HTML injection
|
||||||
|
$this->assertEquals(
|
||||||
|
'<div style="text-align:foo"><script>alert(\'JavaScript_Enabled\');</script>"></div>',
|
||||||
|
$bbc->$funcNam('[align=foo"><script>alert(\'JavaScript_Enabled\');</script>][/align]')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty <li> had been included for the first space
|
||||||
|
*/
|
||||||
|
function testBug11400()
|
||||||
|
{
|
||||||
|
$bbc = new HTML_BBCodeParser(array('filters' => ''));
|
||||||
|
$bbc->addFilter('Lists');
|
||||||
|
|
||||||
|
//this works
|
||||||
|
$this->assertEquals('<ul><li>one</li><li>two</li></ul>',
|
||||||
|
$bbc->qparse("[ulist][*]one[*]two[/ulist]")
|
||||||
|
);
|
||||||
|
//this not
|
||||||
|
$this->assertEquals('<ul><li>one</li><li>two</li></ul>',
|
||||||
|
$bbc->qparse("[ulist] [*]one[*]two[/ulist]")
|
||||||
|
);
|
||||||
|
//this not
|
||||||
|
$this->assertEquals('<ol><li>one</li><li>two</li></ol>',
|
||||||
|
$bbc->qparse("[list] [*]one[*]two[/list]")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* img tags didn't like = in url
|
||||||
|
*/
|
||||||
|
function testBug11370()
|
||||||
|
{
|
||||||
|
$bbc = new HTML_BBCodeParser(array('filters' => ''));
|
||||||
|
$bbc->addFilter('Images');
|
||||||
|
|
||||||
|
$this->assertEquals('<img src="admin.php?fs=image" />',
|
||||||
|
$bbc->qparse("[img]admin.php?fs=image[/img]")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Run tests if run from the command line
|
||||||
|
if (realpath($_SERVER['PHP_SELF']) == __FILE__){
|
||||||
|
$suite = new PHPUnit_TestSuite('BBCodeParser_TestCase');
|
||||||
|
$result = PHPUnit::run($suite);
|
||||||
|
echo $result->toString();
|
||||||
|
}
|
||||||
|
?>
|
1108
pear/PEAR.php
Normal file
1108
pear/PEAR.php
Normal file
@ -0,0 +1,1108 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR, the PHP Extension and Application Repository
|
||||||
|
*
|
||||||
|
* PEAR class and PEAR_Error class
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||||
|
* that is available through the world-wide-web at the following URI:
|
||||||
|
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||||
|
* the PHP License and are unable to obtain it through the web, please
|
||||||
|
* send a note to license@php.net so we can mail you a copy immediately.
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Sterling Hughes <sterling@php.net>
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||||
|
* @version CVS: $Id: PEAR.php,v 1.101 2006/04/25 02:41:03 cellog Exp $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**#@+
|
||||||
|
* ERROR constants
|
||||||
|
*/
|
||||||
|
define('PEAR_ERROR_RETURN', 1);
|
||||||
|
define('PEAR_ERROR_PRINT', 2);
|
||||||
|
define('PEAR_ERROR_TRIGGER', 4);
|
||||||
|
define('PEAR_ERROR_DIE', 8);
|
||||||
|
define('PEAR_ERROR_CALLBACK', 16);
|
||||||
|
/**
|
||||||
|
* WARNING: obsolete
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
define('PEAR_ERROR_EXCEPTION', 32);
|
||||||
|
/**#@-*/
|
||||||
|
define('PEAR_ZE2', (function_exists('version_compare') &&
|
||||||
|
version_compare(zend_version(), "2-dev", "ge")));
|
||||||
|
|
||||||
|
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||||
|
define('OS_WINDOWS', true);
|
||||||
|
define('OS_UNIX', false);
|
||||||
|
define('PEAR_OS', 'Windows');
|
||||||
|
} else {
|
||||||
|
define('OS_WINDOWS', false);
|
||||||
|
define('OS_UNIX', true);
|
||||||
|
define('PEAR_OS', 'Unix'); // blatant assumption
|
||||||
|
}
|
||||||
|
|
||||||
|
// instant backwards compatibility
|
||||||
|
if (!defined('PATH_SEPARATOR')) {
|
||||||
|
if (OS_WINDOWS) {
|
||||||
|
define('PATH_SEPARATOR', ';');
|
||||||
|
} else {
|
||||||
|
define('PATH_SEPARATOR', ':');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
||||||
|
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
||||||
|
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||||
|
$GLOBALS['_PEAR_shutdown_funcs'] = array();
|
||||||
|
$GLOBALS['_PEAR_error_handler_stack'] = array();
|
||||||
|
|
||||||
|
@ini_set('track_errors', true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for other PEAR classes. Provides rudimentary
|
||||||
|
* emulation of destructors.
|
||||||
|
*
|
||||||
|
* If you want a destructor in your class, inherit PEAR and make a
|
||||||
|
* destructor method called _yourclassname (same name as the
|
||||||
|
* constructor, but with a "_" prefix). Also, in your constructor you
|
||||||
|
* have to call the PEAR constructor: $this->PEAR();.
|
||||||
|
* The destructor method will be called without parameters. Note that
|
||||||
|
* at in some SAPI implementations (such as Apache), any output during
|
||||||
|
* the request shutdown (in which destructors are called) seems to be
|
||||||
|
* discarded. If you need to get any debug information from your
|
||||||
|
* destructor, use error_log(), syslog() or something similar.
|
||||||
|
*
|
||||||
|
* IMPORTANT! To use the emulated destructors you need to create the
|
||||||
|
* objects by reference: $obj =& new PEAR_child;
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||||
|
* @version Release: 1.6.1
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @see PEAR_Error
|
||||||
|
* @since Class available since PHP 4.0.2
|
||||||
|
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
|
||||||
|
*/
|
||||||
|
class PEAR
|
||||||
|
{
|
||||||
|
// {{{ properties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable internal debug messages.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_debug = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default error mode for this object.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_default_error_mode = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default error options used for this object when error mode
|
||||||
|
* is PEAR_ERROR_TRIGGER.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_default_error_options = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default error handler (callback) for this object, if error mode is
|
||||||
|
* PEAR_ERROR_CALLBACK.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_default_error_handler = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which class to use for error objects.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_error_class = 'PEAR_Error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of expected errors.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_expected_errors = array();
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
// {{{ constructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. Registers this object in
|
||||||
|
* $_PEAR_destructor_object_list for destructor emulation if a
|
||||||
|
* destructor object exists.
|
||||||
|
*
|
||||||
|
* @param string $error_class (optional) which class to use for
|
||||||
|
* error objects, defaults to PEAR_Error.
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function PEAR($error_class = null)
|
||||||
|
{
|
||||||
|
$classname = strtolower(get_class($this));
|
||||||
|
if ($this->_debug) {
|
||||||
|
print "PEAR constructor called, class=$classname\n";
|
||||||
|
}
|
||||||
|
if ($error_class !== null) {
|
||||||
|
$this->_error_class = $error_class;
|
||||||
|
}
|
||||||
|
while ($classname && strcasecmp($classname, "pear")) {
|
||||||
|
$destructor = "_$classname";
|
||||||
|
if (method_exists($this, $destructor)) {
|
||||||
|
global $_PEAR_destructor_object_list;
|
||||||
|
$_PEAR_destructor_object_list[] = &$this;
|
||||||
|
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
|
||||||
|
register_shutdown_function("_PEAR_call_destructors");
|
||||||
|
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$classname = get_parent_class($classname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ destructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor (the emulated type of...). Does nothing right now,
|
||||||
|
* but is included for forward compatibility, so subclass
|
||||||
|
* destructors should always call it.
|
||||||
|
*
|
||||||
|
* See the note in the class desciption about output from
|
||||||
|
* destructors.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function _PEAR() {
|
||||||
|
if ($this->_debug) {
|
||||||
|
printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getStaticProperty()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you have a class that's mostly/entirely static, and you need static
|
||||||
|
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||||
|
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
|
||||||
|
* You MUST use a reference, or they will not persist!
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $class The calling classname, to prevent clashes
|
||||||
|
* @param string $var The variable to retrieve.
|
||||||
|
* @return mixed A reference to the variable. If not set it will be
|
||||||
|
* auto initialised to NULL.
|
||||||
|
*/
|
||||||
|
function &getStaticProperty($class, $var)
|
||||||
|
{
|
||||||
|
static $properties;
|
||||||
|
if (!isset($properties[$class])) {
|
||||||
|
$properties[$class] = array();
|
||||||
|
}
|
||||||
|
if (!array_key_exists($var, $properties[$class])) {
|
||||||
|
$properties[$class][$var] = null;
|
||||||
|
}
|
||||||
|
return $properties[$class][$var];
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ registerShutdownFunc()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to register a shutdown method for static
|
||||||
|
* classes.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $func The function name (or array of class/method) to call
|
||||||
|
* @param mixed $args The arguments to pass to the function
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function registerShutdownFunc($func, $args = array())
|
||||||
|
{
|
||||||
|
// if we are called statically, there is a potential
|
||||||
|
// that no shutdown func is registered. Bug #6445
|
||||||
|
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
|
||||||
|
register_shutdown_function("_PEAR_call_destructors");
|
||||||
|
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
|
||||||
|
}
|
||||||
|
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ isError()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell whether a value is a PEAR error.
|
||||||
|
*
|
||||||
|
* @param mixed $data the value to test
|
||||||
|
* @param int $code if $data is an error object, return true
|
||||||
|
* only if $code is a string and
|
||||||
|
* $obj->getMessage() == $code or
|
||||||
|
* $code is an integer and $obj->getCode() == $code
|
||||||
|
* @access public
|
||||||
|
* @return bool true if parameter is an error
|
||||||
|
*/
|
||||||
|
function isError($data, $code = null)
|
||||||
|
{
|
||||||
|
if (is_a($data, 'PEAR_Error')) {
|
||||||
|
if (is_null($code)) {
|
||||||
|
return true;
|
||||||
|
} elseif (is_string($code)) {
|
||||||
|
return $data->getMessage() == $code;
|
||||||
|
} else {
|
||||||
|
return $data->getCode() == $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ setErrorHandling()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets how errors generated by this object should be handled.
|
||||||
|
* Can be invoked both in objects and statically. If called
|
||||||
|
* statically, setErrorHandling sets the default behaviour for all
|
||||||
|
* PEAR objects. If called in an object, setErrorHandling sets
|
||||||
|
* the default behaviour for that object.
|
||||||
|
*
|
||||||
|
* @param int $mode
|
||||||
|
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||||
|
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
|
||||||
|
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
|
||||||
|
*
|
||||||
|
* @param mixed $options
|
||||||
|
* When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
|
||||||
|
* of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
|
||||||
|
*
|
||||||
|
* When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
|
||||||
|
* to be the callback function or method. A callback
|
||||||
|
* function is a string with the name of the function, a
|
||||||
|
* callback method is an array of two elements: the element
|
||||||
|
* at index 0 is the object, and the element at index 1 is
|
||||||
|
* the name of the method to call in the object.
|
||||||
|
*
|
||||||
|
* When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
|
||||||
|
* a printf format string used when printing the error
|
||||||
|
* message.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return void
|
||||||
|
* @see PEAR_ERROR_RETURN
|
||||||
|
* @see PEAR_ERROR_PRINT
|
||||||
|
* @see PEAR_ERROR_TRIGGER
|
||||||
|
* @see PEAR_ERROR_DIE
|
||||||
|
* @see PEAR_ERROR_CALLBACK
|
||||||
|
* @see PEAR_ERROR_EXCEPTION
|
||||||
|
*
|
||||||
|
* @since PHP 4.0.5
|
||||||
|
*/
|
||||||
|
|
||||||
|
function setErrorHandling($mode = null, $options = null)
|
||||||
|
{
|
||||||
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
|
$setmode = &$this->_default_error_mode;
|
||||||
|
$setoptions = &$this->_default_error_options;
|
||||||
|
} else {
|
||||||
|
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||||
|
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($mode) {
|
||||||
|
case PEAR_ERROR_EXCEPTION:
|
||||||
|
case PEAR_ERROR_RETURN:
|
||||||
|
case PEAR_ERROR_PRINT:
|
||||||
|
case PEAR_ERROR_TRIGGER:
|
||||||
|
case PEAR_ERROR_DIE:
|
||||||
|
case null:
|
||||||
|
$setmode = $mode;
|
||||||
|
$setoptions = $options;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEAR_ERROR_CALLBACK:
|
||||||
|
$setmode = $mode;
|
||||||
|
// class/object method callback
|
||||||
|
if (is_callable($options)) {
|
||||||
|
$setoptions = $options;
|
||||||
|
} else {
|
||||||
|
trigger_error("invalid error callback", E_USER_WARNING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
trigger_error("invalid error mode", E_USER_WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ expectError()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to tell which errors you expect to get.
|
||||||
|
* Expected errors are always returned with error mode
|
||||||
|
* PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
|
||||||
|
* and this method pushes a new element onto it. The list of
|
||||||
|
* expected errors are in effect until they are popped off the
|
||||||
|
* stack with the popExpect() method.
|
||||||
|
*
|
||||||
|
* Note that this method can not be called statically
|
||||||
|
*
|
||||||
|
* @param mixed $code a single error code or an array of error codes to expect
|
||||||
|
*
|
||||||
|
* @return int the new depth of the "expected errors" stack
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function expectError($code = '*')
|
||||||
|
{
|
||||||
|
if (is_array($code)) {
|
||||||
|
array_push($this->_expected_errors, $code);
|
||||||
|
} else {
|
||||||
|
array_push($this->_expected_errors, array($code));
|
||||||
|
}
|
||||||
|
return sizeof($this->_expected_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ popExpect()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method pops one element off the expected error codes
|
||||||
|
* stack.
|
||||||
|
*
|
||||||
|
* @return array the list of error codes that were popped
|
||||||
|
*/
|
||||||
|
function popExpect()
|
||||||
|
{
|
||||||
|
return array_pop($this->_expected_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _checkDelExpect()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks unsets an error code if available
|
||||||
|
*
|
||||||
|
* @param mixed error code
|
||||||
|
* @return bool true if the error code was unset, false otherwise
|
||||||
|
* @access private
|
||||||
|
* @since PHP 4.3.0
|
||||||
|
*/
|
||||||
|
function _checkDelExpect($error_code)
|
||||||
|
{
|
||||||
|
$deleted = false;
|
||||||
|
|
||||||
|
foreach ($this->_expected_errors AS $key => $error_array) {
|
||||||
|
if (in_array($error_code, $error_array)) {
|
||||||
|
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
|
||||||
|
$deleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up empty arrays
|
||||||
|
if (0 == count($this->_expected_errors[$key])) {
|
||||||
|
unset($this->_expected_errors[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ delExpect()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method deletes all occurences of the specified element from
|
||||||
|
* the expected error codes stack.
|
||||||
|
*
|
||||||
|
* @param mixed $error_code error code that should be deleted
|
||||||
|
* @return mixed list of error codes that were deleted or error
|
||||||
|
* @access public
|
||||||
|
* @since PHP 4.3.0
|
||||||
|
*/
|
||||||
|
function delExpect($error_code)
|
||||||
|
{
|
||||||
|
$deleted = false;
|
||||||
|
|
||||||
|
if ((is_array($error_code) && (0 != count($error_code)))) {
|
||||||
|
// $error_code is a non-empty array here;
|
||||||
|
// we walk through it trying to unset all
|
||||||
|
// values
|
||||||
|
foreach($error_code as $key => $error) {
|
||||||
|
if ($this->_checkDelExpect($error)) {
|
||||||
|
$deleted = true;
|
||||||
|
} else {
|
||||||
|
$deleted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||||
|
} elseif (!empty($error_code)) {
|
||||||
|
// $error_code comes alone, trying to unset it
|
||||||
|
if ($this->_checkDelExpect($error_code)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// $error_code is empty
|
||||||
|
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ raiseError()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is a wrapper that returns an instance of the
|
||||||
|
* configured error class with this object's default error
|
||||||
|
* handling applied. If the $mode and $options parameters are not
|
||||||
|
* specified, the object's defaults are used.
|
||||||
|
*
|
||||||
|
* @param mixed $message a text error message or a PEAR error object
|
||||||
|
*
|
||||||
|
* @param int $code a numeric error code (it is up to your class
|
||||||
|
* to define these if you want to use codes)
|
||||||
|
*
|
||||||
|
* @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||||
|
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
|
||||||
|
* PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
|
||||||
|
*
|
||||||
|
* @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
|
||||||
|
* specifies the PHP-internal error level (one of
|
||||||
|
* E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
|
||||||
|
* If $mode is PEAR_ERROR_CALLBACK, this
|
||||||
|
* parameter specifies the callback function or
|
||||||
|
* method. In other error modes this parameter
|
||||||
|
* is ignored.
|
||||||
|
*
|
||||||
|
* @param string $userinfo If you need to pass along for example debug
|
||||||
|
* information, this parameter is meant for that.
|
||||||
|
*
|
||||||
|
* @param string $error_class The returned error object will be
|
||||||
|
* instantiated from this class, if specified.
|
||||||
|
*
|
||||||
|
* @param bool $skipmsg If true, raiseError will only pass error codes,
|
||||||
|
* the error message parameter will be dropped.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return object a PEAR error object
|
||||||
|
* @see PEAR::setErrorHandling
|
||||||
|
* @since PHP 4.0.5
|
||||||
|
*/
|
||||||
|
function &raiseError($message = null,
|
||||||
|
$code = null,
|
||||||
|
$mode = null,
|
||||||
|
$options = null,
|
||||||
|
$userinfo = null,
|
||||||
|
$error_class = null,
|
||||||
|
$skipmsg = false)
|
||||||
|
{
|
||||||
|
// The error is yet a PEAR error object
|
||||||
|
if (is_object($message)) {
|
||||||
|
$code = $message->getCode();
|
||||||
|
$userinfo = $message->getUserInfo();
|
||||||
|
$error_class = $message->getType();
|
||||||
|
$message->error_message_prefix = '';
|
||||||
|
$message = $message->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
|
||||||
|
if ($exp[0] == "*" ||
|
||||||
|
(is_int(reset($exp)) && in_array($code, $exp)) ||
|
||||||
|
(is_string(reset($exp)) && in_array($message, $exp))) {
|
||||||
|
$mode = PEAR_ERROR_RETURN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// No mode given, try global ones
|
||||||
|
if ($mode === null) {
|
||||||
|
// Class error handler
|
||||||
|
if (isset($this) && isset($this->_default_error_mode)) {
|
||||||
|
$mode = $this->_default_error_mode;
|
||||||
|
$options = $this->_default_error_options;
|
||||||
|
// Global error handler
|
||||||
|
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
|
||||||
|
$mode = $GLOBALS['_PEAR_default_error_mode'];
|
||||||
|
$options = $GLOBALS['_PEAR_default_error_options'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error_class !== null) {
|
||||||
|
$ec = $error_class;
|
||||||
|
} elseif (isset($this) && isset($this->_error_class)) {
|
||||||
|
$ec = $this->_error_class;
|
||||||
|
} else {
|
||||||
|
$ec = 'PEAR_Error';
|
||||||
|
}
|
||||||
|
if ($skipmsg) {
|
||||||
|
$a = &new $ec($code, $mode, $options, $userinfo);
|
||||||
|
return $a;
|
||||||
|
} else {
|
||||||
|
$a = &new $ec($message, $code, $mode, $options, $userinfo);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ throwError()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simpler form of raiseError with fewer options. In most cases
|
||||||
|
* message, code and userinfo are enough.
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function &throwError($message = null,
|
||||||
|
$code = null,
|
||||||
|
$userinfo = null)
|
||||||
|
{
|
||||||
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
|
$a = &$this->raiseError($message, $code, null, null, $userinfo);
|
||||||
|
return $a;
|
||||||
|
} else {
|
||||||
|
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
function staticPushErrorHandling($mode, $options = null)
|
||||||
|
{
|
||||||
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
|
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||||
|
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||||
|
$stack[] = array($def_mode, $def_options);
|
||||||
|
switch ($mode) {
|
||||||
|
case PEAR_ERROR_EXCEPTION:
|
||||||
|
case PEAR_ERROR_RETURN:
|
||||||
|
case PEAR_ERROR_PRINT:
|
||||||
|
case PEAR_ERROR_TRIGGER:
|
||||||
|
case PEAR_ERROR_DIE:
|
||||||
|
case null:
|
||||||
|
$def_mode = $mode;
|
||||||
|
$def_options = $options;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEAR_ERROR_CALLBACK:
|
||||||
|
$def_mode = $mode;
|
||||||
|
// class/object method callback
|
||||||
|
if (is_callable($options)) {
|
||||||
|
$def_options = $options;
|
||||||
|
} else {
|
||||||
|
trigger_error("invalid error callback", E_USER_WARNING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
trigger_error("invalid error mode", E_USER_WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$stack[] = array($mode, $options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function staticPopErrorHandling()
|
||||||
|
{
|
||||||
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
|
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||||
|
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
|
||||||
|
array_pop($stack);
|
||||||
|
list($mode, $options) = $stack[sizeof($stack) - 1];
|
||||||
|
array_pop($stack);
|
||||||
|
switch ($mode) {
|
||||||
|
case PEAR_ERROR_EXCEPTION:
|
||||||
|
case PEAR_ERROR_RETURN:
|
||||||
|
case PEAR_ERROR_PRINT:
|
||||||
|
case PEAR_ERROR_TRIGGER:
|
||||||
|
case PEAR_ERROR_DIE:
|
||||||
|
case null:
|
||||||
|
$setmode = $mode;
|
||||||
|
$setoptions = $options;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEAR_ERROR_CALLBACK:
|
||||||
|
$setmode = $mode;
|
||||||
|
// class/object method callback
|
||||||
|
if (is_callable($options)) {
|
||||||
|
$setoptions = $options;
|
||||||
|
} else {
|
||||||
|
trigger_error("invalid error callback", E_USER_WARNING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
trigger_error("invalid error mode", E_USER_WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{{ pushErrorHandling()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push a new error handler on top of the error handler options stack. With this
|
||||||
|
* you can easily override the actual error handler for some code and restore
|
||||||
|
* it later with popErrorHandling.
|
||||||
|
*
|
||||||
|
* @param mixed $mode (same as setErrorHandling)
|
||||||
|
* @param mixed $options (same as setErrorHandling)
|
||||||
|
*
|
||||||
|
* @return bool Always true
|
||||||
|
*
|
||||||
|
* @see PEAR::setErrorHandling
|
||||||
|
*/
|
||||||
|
function pushErrorHandling($mode, $options = null)
|
||||||
|
{
|
||||||
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
|
$def_mode = &$this->_default_error_mode;
|
||||||
|
$def_options = &$this->_default_error_options;
|
||||||
|
} else {
|
||||||
|
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||||
|
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||||
|
}
|
||||||
|
$stack[] = array($def_mode, $def_options);
|
||||||
|
|
||||||
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
|
$this->setErrorHandling($mode, $options);
|
||||||
|
} else {
|
||||||
|
PEAR::setErrorHandling($mode, $options);
|
||||||
|
}
|
||||||
|
$stack[] = array($mode, $options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ popErrorHandling()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pop the last error handler used
|
||||||
|
*
|
||||||
|
* @return bool Always true
|
||||||
|
*
|
||||||
|
* @see PEAR::pushErrorHandling
|
||||||
|
*/
|
||||||
|
function popErrorHandling()
|
||||||
|
{
|
||||||
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
|
array_pop($stack);
|
||||||
|
list($mode, $options) = $stack[sizeof($stack) - 1];
|
||||||
|
array_pop($stack);
|
||||||
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
|
$this->setErrorHandling($mode, $options);
|
||||||
|
} else {
|
||||||
|
PEAR::setErrorHandling($mode, $options);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ loadExtension()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OS independant PHP extension load. Remember to take care
|
||||||
|
* on the correct extension name for case sensitive OSes.
|
||||||
|
*
|
||||||
|
* @param string $ext The extension name
|
||||||
|
* @return bool Success or not on the dl() call
|
||||||
|
*/
|
||||||
|
function loadExtension($ext)
|
||||||
|
{
|
||||||
|
if (!extension_loaded($ext)) {
|
||||||
|
// if either returns true dl() will produce a FATAL error, stop that
|
||||||
|
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (OS_WINDOWS) {
|
||||||
|
$suffix = '.dll';
|
||||||
|
} elseif (PHP_OS == 'HP-UX') {
|
||||||
|
$suffix = '.sl';
|
||||||
|
} elseif (PHP_OS == 'AIX') {
|
||||||
|
$suffix = '.a';
|
||||||
|
} elseif (PHP_OS == 'OSX') {
|
||||||
|
$suffix = '.bundle';
|
||||||
|
} else {
|
||||||
|
$suffix = '.so';
|
||||||
|
}
|
||||||
|
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{{ _PEAR_call_destructors()
|
||||||
|
|
||||||
|
function _PEAR_call_destructors()
|
||||||
|
{
|
||||||
|
global $_PEAR_destructor_object_list;
|
||||||
|
if (is_array($_PEAR_destructor_object_list) &&
|
||||||
|
sizeof($_PEAR_destructor_object_list))
|
||||||
|
{
|
||||||
|
reset($_PEAR_destructor_object_list);
|
||||||
|
if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
|
||||||
|
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
|
||||||
|
}
|
||||||
|
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
|
||||||
|
$classname = get_class($objref);
|
||||||
|
while ($classname) {
|
||||||
|
$destructor = "_$classname";
|
||||||
|
if (method_exists($objref, $destructor)) {
|
||||||
|
$objref->$destructor();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$classname = get_parent_class($classname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Empty the object list to ensure that destructors are
|
||||||
|
// not called more than once.
|
||||||
|
$_PEAR_destructor_object_list = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now call the shutdown functions
|
||||||
|
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
|
||||||
|
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
|
||||||
|
call_user_func_array($value[0], $value[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
/**
|
||||||
|
* Standard PEAR error class for PHP 4
|
||||||
|
*
|
||||||
|
* This class is supserseded by {@link PEAR_Exception} in PHP 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||||
|
* @author Gregory Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||||
|
* @version Release: 1.6.1
|
||||||
|
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
|
||||||
|
* @see PEAR::raiseError(), PEAR::throwError()
|
||||||
|
* @since Class available since PHP 4.0.2
|
||||||
|
*/
|
||||||
|
class PEAR_Error
|
||||||
|
{
|
||||||
|
// {{{ properties
|
||||||
|
|
||||||
|
var $error_message_prefix = '';
|
||||||
|
var $mode = PEAR_ERROR_RETURN;
|
||||||
|
var $level = E_USER_NOTICE;
|
||||||
|
var $code = -1;
|
||||||
|
var $message = '';
|
||||||
|
var $userinfo = '';
|
||||||
|
var $backtrace = null;
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ constructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR_Error constructor
|
||||||
|
*
|
||||||
|
* @param string $message message
|
||||||
|
*
|
||||||
|
* @param int $code (optional) error code
|
||||||
|
*
|
||||||
|
* @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
|
||||||
|
* PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
|
||||||
|
* PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
|
||||||
|
*
|
||||||
|
* @param mixed $options (optional) error level, _OR_ in the case of
|
||||||
|
* PEAR_ERROR_CALLBACK, the callback function or object/method
|
||||||
|
* tuple.
|
||||||
|
*
|
||||||
|
* @param string $userinfo (optional) additional user/debug info
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function PEAR_Error($message = 'unknown error', $code = null,
|
||||||
|
$mode = null, $options = null, $userinfo = null)
|
||||||
|
{
|
||||||
|
if ($mode === null) {
|
||||||
|
$mode = PEAR_ERROR_RETURN;
|
||||||
|
}
|
||||||
|
$this->message = $message;
|
||||||
|
$this->code = $code;
|
||||||
|
$this->mode = $mode;
|
||||||
|
$this->userinfo = $userinfo;
|
||||||
|
if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
|
||||||
|
$this->backtrace = debug_backtrace();
|
||||||
|
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
|
||||||
|
unset($this->backtrace[0]['object']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($mode & PEAR_ERROR_CALLBACK) {
|
||||||
|
$this->level = E_USER_NOTICE;
|
||||||
|
$this->callback = $options;
|
||||||
|
} else {
|
||||||
|
if ($options === null) {
|
||||||
|
$options = E_USER_NOTICE;
|
||||||
|
}
|
||||||
|
$this->level = $options;
|
||||||
|
$this->callback = null;
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||||
|
if (is_null($options) || is_int($options)) {
|
||||||
|
$format = "%s";
|
||||||
|
} else {
|
||||||
|
$format = $options;
|
||||||
|
}
|
||||||
|
printf($format, $this->getMessage());
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||||
|
trigger_error($this->getMessage(), $this->level);
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_DIE) {
|
||||||
|
$msg = $this->getMessage();
|
||||||
|
if (is_null($options) || is_int($options)) {
|
||||||
|
$format = "%s";
|
||||||
|
if (substr($msg, -1) != "\n") {
|
||||||
|
$msg .= "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$format = $options;
|
||||||
|
}
|
||||||
|
die(sprintf($format, $msg));
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||||
|
if (is_callable($this->callback)) {
|
||||||
|
call_user_func($this->callback, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_EXCEPTION) {
|
||||||
|
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
|
||||||
|
eval('$e = new Exception($this->message, $this->code);throw($e);');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getMode()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the error mode from an error object.
|
||||||
|
*
|
||||||
|
* @return int error mode
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getMode() {
|
||||||
|
return $this->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getCallback()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the callback function/method from an error object.
|
||||||
|
*
|
||||||
|
* @return mixed callback function or object/method array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getCallback() {
|
||||||
|
return $this->callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getMessage()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the error message from an error object.
|
||||||
|
*
|
||||||
|
* @return string full error message
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getMessage()
|
||||||
|
{
|
||||||
|
return ($this->error_message_prefix . $this->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getCode()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get error code from an error object
|
||||||
|
*
|
||||||
|
* @return int error code
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getCode()
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getType()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of this error/exception.
|
||||||
|
*
|
||||||
|
* @return string error/exception name (type)
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getType()
|
||||||
|
{
|
||||||
|
return get_class($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getUserInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get additional user-supplied information.
|
||||||
|
*
|
||||||
|
* @return string user-supplied information
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getUserInfo()
|
||||||
|
{
|
||||||
|
return $this->userinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getDebugInfo()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get additional debug information supplied by the application.
|
||||||
|
*
|
||||||
|
* @return string debug information
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getDebugInfo()
|
||||||
|
{
|
||||||
|
return $this->getUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ getBacktrace()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the call backtrace from where the error was generated.
|
||||||
|
* Supported with PHP 4.3.0 or newer.
|
||||||
|
*
|
||||||
|
* @param int $frame (optional) what frame to fetch
|
||||||
|
* @return array Backtrace, or NULL if not available.
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getBacktrace($frame = null)
|
||||||
|
{
|
||||||
|
if (defined('PEAR_IGNORE_BACKTRACE')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($frame === null) {
|
||||||
|
return $this->backtrace;
|
||||||
|
}
|
||||||
|
return $this->backtrace[$frame];
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ addUserInfo()
|
||||||
|
|
||||||
|
function addUserInfo($info)
|
||||||
|
{
|
||||||
|
if (empty($this->userinfo)) {
|
||||||
|
$this->userinfo = $info;
|
||||||
|
} else {
|
||||||
|
$this->userinfo .= " ** $info";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ toString()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a string representation of this object.
|
||||||
|
*
|
||||||
|
* @return string a string with an object summary
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function toString() {
|
||||||
|
$modes = array();
|
||||||
|
$levels = array(E_USER_NOTICE => 'notice',
|
||||||
|
E_USER_WARNING => 'warning',
|
||||||
|
E_USER_ERROR => 'error');
|
||||||
|
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||||
|
if (is_array($this->callback)) {
|
||||||
|
$callback = (is_object($this->callback[0]) ?
|
||||||
|
strtolower(get_class($this->callback[0])) :
|
||||||
|
$this->callback[0]) . '::' .
|
||||||
|
$this->callback[1];
|
||||||
|
} else {
|
||||||
|
$callback = $this->callback;
|
||||||
|
}
|
||||||
|
return sprintf('[%s: message="%s" code=%d mode=callback '.
|
||||||
|
'callback=%s prefix="%s" info="%s"]',
|
||||||
|
strtolower(get_class($this)), $this->message, $this->code,
|
||||||
|
$callback, $this->error_message_prefix,
|
||||||
|
$this->userinfo);
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||||
|
$modes[] = 'print';
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||||
|
$modes[] = 'trigger';
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_DIE) {
|
||||||
|
$modes[] = 'die';
|
||||||
|
}
|
||||||
|
if ($this->mode & PEAR_ERROR_RETURN) {
|
||||||
|
$modes[] = 'return';
|
||||||
|
}
|
||||||
|
return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
|
||||||
|
'prefix="%s" info="%s"]',
|
||||||
|
strtolower(get_class($this)), $this->message, $this->code,
|
||||||
|
implode("|", $modes), $levels[$this->level],
|
||||||
|
$this->error_message_prefix,
|
||||||
|
$this->userinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables:
|
||||||
|
* mode: php
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user