Merge pull request #5998 from sminnee/remove-bbcode

This commit is contained in:
Daniel Hensby 2016-09-23 15:28:30 +01:00
commit 004bb8f03a
No known key found for this signature in database
GPG Key ID: B00D1E9767F0B06E
23 changed files with 3 additions and 2302 deletions

View File

@ -9,7 +9,6 @@ use SilverStripe\Forms\TextareaField;
use SilverStripe\Forms\NullableField;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DB;
use SilverStripe\View\Parsers\TextParser;
use InvalidArgumentException;
/**
@ -233,24 +232,6 @@ class DBText extends DBString {
return $summary;
}
/**
* Allows a sub-class of TextParser to be rendered.
*
* @see TextParser for implementation details.
* @param string $parser Class name of parser (Must extend {@see TextParser})
* @return DBField Parsed value in the appropriate type
*/
public function Parse($parser) {
$reflection = new \ReflectionClass($parser);
if($reflection->isAbstract() || !$reflection->isSubclassOf('SilverStripe\\View\\Parsers\\TextParser')) {
throw new InvalidArgumentException("Invalid parser {$parser}");
}
/** @var TextParser $obj */
$obj = Injector::inst()->createWithArgs($parser, [$this->forTemplate()]);
return $obj->parse();
}
public function scaffoldFormField($title = null, $params = null) {
if(!$this->nullifyEmpty) {
// Allow the user to select if it's null instead of automatically assuming empty string is

View File

@ -1,24 +0,0 @@
[SSHTMLBBCodeParser]
; possible values: single|double
; use single or double quotes for attributes
quotestyle = "double"
; possible values: all|nothing|strings
; quote all attribute values, none, or only the strings
quotewhat = "all"
; the closing tag character
close = "]"
; the opening tag character
open = "["
; 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,Email,Images,Links,Lists"

View File

@ -1,152 +0,0 @@
<?php
namespace SilverStripe\View\Parsers;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\View\ArrayData;
use HTML_BBCodeParser2;
/**
* BBCode parser object.
* Use on a text field in a template with $Content.Parse(BBCodeParser).
*/
class BBCodeParser extends TextParser {
/**
* @config
* @var Boolean Set whether phrases starting with http:// or www. are automatically linked
*/
private static $autolink_urls = true;
/**
* @config
* @var Boolean Set whether similies :), :(, :P are converted to images
*/
private static $allow_similies = false;
/**
* Set the location of the smiles folder. By default use the ones in framework
* but this can be overridden by setting this via config API
*
* @config
* @var string
*/
private static $smilies_location = null;
public static function usable_tags() {
/** @skipUpgrade */
return new ArrayList(
array(
new ArrayData(array(
"Title" => _t('BBCodeParser.BOLD', 'Bold Text'),
"Example" => '[b]<b>'._t('BBCodeParser.BOLDEXAMPLE', 'Bold').'</b>[/b]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.ITALIC', 'Italic Text'),
"Example" => '[i]<i>'._t('BBCodeParser.ITALICEXAMPLE', 'Italics').'</i>[/i]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.UNDERLINE', 'Underlined Text'),
"Example" => '[u]<u>'._t('BBCodeParser.UNDERLINEEXAMPLE', 'Underlined').'</u>[/u]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.STRUCK', 'Struck-out Text'),
"Example" => '[s]<s>'._t('BBCodeParser.STRUCKEXAMPLE', 'Struck-out').'</s>[/s]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.COLORED', 'Colored text'),
"Example" => '[color=blue]'._t('BBCodeParser.COLOREDEXAMPLE', 'blue text').'[/color]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.ALIGNEMENT', 'Alignment'),
"Example" => '[align=right]'._t('BBCodeParser.ALIGNEMENTEXAMPLE', 'right aligned').'[/align]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.CODE', 'Code Block'),
"Description" => _t('BBCodeParser.CODEDESCRIPTION', 'Unformatted code block'),
"Example" => '[code]'._t('BBCodeParser.CODEEXAMPLE', 'Code block').'[/code]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.EMAILLINK', 'Email link'),
"Description" => _t('BBCodeParser.EMAILLINKDESCRIPTION', 'Create link to an email address'),
"Example" => "[email]you@yoursite.com[/email]"
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.EMAILLINK', 'Email link'),
"Description" => _t('BBCodeParser.EMAILLINKDESCRIPTION', 'Create link to an email address'),
"Example" => "[email=you@yoursite.com]Email[/email]"
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.UNORDERED', 'Unordered list'),
"Description" => _t('BBCodeParser.UNORDEREDDESCRIPTION', 'Unordered list'),
"Example" => '[ulist][*]'._t('BBCodeParser.UNORDEREDEXAMPLE1', 'unordered item 1').'[/ulist]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.IMAGE', 'Image'),
"Description" => _t('BBCodeParser.IMAGEDESCRIPTION', 'Show an image in your post'),
"Example" => "[img]http://www.website.com/image.jpg[/img]"
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.LINK', 'Website link'),
"Description" => _t('BBCodeParser.LINKDESCRIPTION', 'Link to another website or URL'),
"Example" => '[url]http://www.website.com/[/url]'
)),
new ArrayData(array(
"Title" => _t('BBCodeParser.LINK', 'Website link'),
"Description" => _t('BBCodeParser.LINKDESCRIPTION', 'Link to another website or URL'),
"Example" => "[url=http://www.website.com/]Website[/url]"
))
)
);
}
public function useable_tagsHTML() {
$useabletags = "<ul class='bbcodeExamples'>";
foreach($this->usable_tags()->toArray() as $tag){
$useabletags = $useabletags."<li><span>".$tag->Example."</span></li>";
}
return $useabletags."</ul>";
}
/**
* Main BBCode parser method. This takes plain jane content and
* runs it through so many filters
*
* @return DBField
*/
public function parse() {
// Convert content to plain text
/** @var DBHTMLText $fragment */
$fragment = DBField::create_field('HTMLFragment', $this->content);
$this->content = $fragment->Plain();
// Get options
$config = parse_ini_file('BBCodeParser.ini', true);
$options = $config['SSHTMLBBCodeParser'];
$p = new HTML_BBCodeParser2($options);
$this->content = $p->qparse($this->content);
unset($p);
if($this->config()->allow_smilies) {
$smiliesLocation = $this->config()->get('smilies_location');
$smilies = array(
'#(?<!\w):D(?!\w)#i' => " <img src='{$smiliesLocation}/grin.gif'> ", // :D
'#(?<!\w):\)(?!\w)#i' => " <img src='{$smiliesLocation}/smile.gif'> ", // :)
'#(?<!\w):-\)(?!\w)#i' => " <img src='{$smiliesLocation}/smile.gif'> ", // :-)
'#(?<!\w):\((?!\w)#i' => " <img src='{$smiliesLocation}/sad.gif'> ", // :(
'#(?<!\w):-\((?!\w)#i' => " <img src='{$smiliesLocation}/sad.gif'> ", // :-(
'#(?<!\w):p(?!\w)#i' => " <img src='{$smiliesLocation}/tongue.gif'> ", // :p
'#(?<!\w)8-\)(?!\w)#i' => " <img src='{$smiliesLocation}/cool.gif'> ", // 8-)
'#(?<!\w):\^\)(?!\w)#i' => " <img src='{$smiliesLocation}/confused.gif'> " // :^)
);
$this->content = preg_replace(array_keys($smilies), array_values($smilies), $this->content);
}
// Ensure to return cast value
return DBField::create_field('HTMLFragment', $this->content);
}
}

View File

@ -1,66 +0,0 @@
<?php
namespace SilverStripe\View\Parsers;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Core\Object;
/**
* Parses text in a variety of ways.
*
* Called from a template by $Content.Parse(SubClassName), similar to $Content.XML.
* This will work on any Text database field (Or a sub-class, such as HTMLText,
* although it's usefulness in this situation is more limited).
*
* Any sub-classes of TextParser must implement a parse() method.
* This should take $this->content and parse it however you want. For an example
* of the implementation, @see BBCodeParser.
*
* Your sub-class will be initialized with a string of text, then parse() will be called.
* parse() should (after processing) return the formatted string.
*
* Note: $this->content will have NO conversions applied to it.
* You should run Covert::raw2xml or whatever is appropriate before using it.
*
* Optionally (but recommended), is creating a static usable_tags method,
* which will return a SS_List of all the usable tags that can be parsed.
* This will (mostly) be used to create helper blocks - telling users what things will be parsed.
* Again, @see BBCodeParser for an example of the syntax
*
* @todo Define a proper syntax for (or refactor) usable_tags that can be extended as needed.
*/
abstract class TextParser extends Object {
/**
* @var string
*/
protected $content;
/**
* Creates a new TextParser object.
*
* @param string $content The contents of the dbfield
*/
public function __construct($content = "") {
parent::__construct();
$this->content = $content;
parent::__construct();
}
/**
* Convenience method, shouldn't really be used, but it's here if you want it
*
* @param string $content
*/
public function setContent($content = "") {
$this->content = $content;
}
/**
* Define your own parse method to parse $this->content appropriately.
* See the class doc-block for more implementation details.
*
* @return DBField
*/
abstract public function parse();
}

View File

@ -49,15 +49,11 @@
"SilverStripe\\Security\\": "Security/",
"SilverStripe\\View\\": "View/"
},
"psr-0": {
"HTML_": "thirdparty/HTML_BBCodeParser2"
},
"files": ["Core/Constants.php"],
"classmap": ["tests/behat/features/bootstrap"]
},
"include-path": [
"thirdparty/",
"thirdparty/HTML_BBCodeParser2/"
"thirdparty/"
],
"min-stability": "dev",
"prefer-stable": true

View File

@ -837,6 +837,8 @@ specific functions.
* `RestfulService` has been removed. Use Guzzle instead. See Upgrading notes.
* Our self-maintained `Oembed` implementation has been removed, in favour of introducing
[oscarotero/Embed](https://github.com/oscarotero/Embed) as a dependency.
* Removed TextParser and BBCodeParser. These are available in an archived module,
[silverstripe-archive/bbcodeparser](https://github.com/silverstripe-archive/silverstripe-bbcodeparser)
#### <a name="overview-general-deprecated"></a>General and Core Deprecated API

View File

@ -411,21 +411,6 @@ class DBHTMLTextTest extends SapphireTest {
);
}
public function testParse() {
// Test parse
/** @var DBHTMLText $obj */
$obj = DBField::create_field(
'HTMLText',
'<p>[b]Some content[/b] [test_shortcode] with shortcode</p>'
);
// BBCode strips HTML and applies own formatting
$this->assertEquals(
'<strong>Some content</strong> shortcode content with shortcode',
$obj->Parse('SilverStripe\\View\\Parsers\\BBCodeParser')->forTemplate()
);
}
function testExists() {
$h = new DBHTMLText();
$h->setValue("");

View File

@ -1,4 +0,0 @@
# composer related
composer.lock
composer.phar
vendor

View File

@ -1,865 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @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_BBCodeParser2($options = array(...));
* $parser->setText('normal [b]bold[/b] and normal again');
* $parser->parse();
* echo $parser->getParsed();
* or:
* $parser = new HTML_BBCodeParser2($options = array(...));
* echo $parser->qparse('normal [b]bold[/b] and normal again');
* or:
* echo HTML_BBCodeParser2::staticQparse('normal [b]bold[/b] and normal again');
*
*
* Setting the options from the ini file:
* $config = parse_ini_file('BBCodeParser.ini', true);
* $options = $config['HTML_BBCodeParser2'];
*
* 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'
* => (...)
* )
*/
class HTML_BBCodeParser2
{
/**
* 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 options to properly escape the tag
* characters in preg_replace() etc.
*
* 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 __construct($options = array())
{
// 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_BBCodeParser2_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_BBCodeParser2_Filter_'.$filter;
@include_once 'HTML/BBCodeParser2/Filter/'.$filter.'.php';
if (!class_exists($class)) {
throw new InvalidArgumentException("Failed to load filter $filter");
}
$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_BBCodeParser2')) {
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&#058;", $v);
$v = htmlspecialchars($v);
$v = str_replace('&amp;amp;', '&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_BBCodeParser2();
$str = $p->qparse($str);
unset($p);
return $str;
}
}
?>

View File

@ -1,9 +0,0 @@
<?php
require_once 'HTML/BBCodeParser2.php';
/**
* Dummy class that filters need to extend from.
*/
class HTML_BBCodeParser2_Filter extends HTML_BBCodeParser2
{
}

View File

@ -1,68 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
class HTML_BBCodeParser2_Filter_Basic extends HTML_BBCodeParser2_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())
);
}

View File

@ -1,82 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
class HTML_BBCodeParser2_Filter_Email extends HTML_BBCodeParser2_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 = $this->_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);
}
}

View File

@ -1,95 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
class HTML_BBCodeParser2_Filter_Extended extends HTML_BBCodeParser2_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())
);
}

View File

@ -1,79 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
class HTML_BBCodeParser2_Filter_Images extends HTML_BBCodeParser2_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 = $this->_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\" alt=\"\"\$1".$c.$o."/img".$c,
$this->_text);
}
}

View File

@ -1,202 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
/**
*
*/
class HTML_BBCodeParser2_Filter_Links extends HTML_BBCodeParser2_Filter
{
/**
* List of allowed schemes
*
* @access private
* @var array
*/
var $_allowedSchemes = array('http', 'https', 'ftp', 'irc');
/**
* 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',
't' => 'target=%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 = $this->_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)
{
$options = $this->_options;
$o = $options['open'];
$c = $options['close'];
$oe = $options['open_esc'];
$ce = $options['close_esc'];
//If we have an intro tag that is [url], then skip this match
if (preg_match("/".$oe."url(=[^\s()\[\]=]+)?".$ce."/i", $matches[1])) {
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 = $this->_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];
}
}
?>

View File

@ -1,105 +0,0 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5 |
// +----------------------------------------------------------------------+
// | 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$
//
/**
* @package HTML_BBCodeParser2
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
require_once 'HTML/BBCodeParser2/Filter.php';
/**
*
*/
class HTML_BBCodeParser2_Filter_Lists extends HTML_BBCodeParser2_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 = $this->_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);
}
}

View File

@ -1,19 +0,0 @@
This package is http://pear.php.net/package/HTML_BBCodeParser2
Please report all new issues via the PEAR bug tracker.
If this package is marked as unmaintained and you have fixes, please submit your pull requests and start discussion on the pear-qa mailing list.
To test, run either
$ phpunit tests/
or
$ pear run-tests -r
To build, simply
$ pear package
To install from scratch
$ pear install package.xml
To upgrade
$ pear upgrade -f package.xml

View File

@ -1,14 +0,0 @@
TODO
- fix bugs reported through http://pear.php.net/bugs/ (373, 512)
- think about custom runtime tag loading (Stan Lemon was busy with this)
- make sure <li> is embedded in <ul> of <ol>
- add a nl2br option
- maybe add default value for attributes (target in url)
- try to fix recursive lists (only occurs with [*] shorthand)
- make it possible to use spaces in argument values with quotes
DONE
- fix urls with strange characters (#, &, spaces)
- add more advanced text filter (color, size, quote, code, etc)
- check for notice errors (undefined offset)
- fixed bugs 484, 486, 518, 508, 462

View File

@ -1,33 +0,0 @@
{
"authors": [
{
"email": "sjr@gmx.co.uk",
"name": "Stijn de Reede",
"role": "Lead"
},
{
"email": "clockwerx@php.net",
"name": "Daniel O'Connor",
"role": "Lead"
}
],
"autoload": {
"psr-0": {
"HTML": "./"
}
},
"description": "A PHP5 replacement for HTML_BBCodeParser",
"include-path": [
"./"
],
"license": "PHP License",
"name": "pear/html_bbcodeparser2",
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=HTML_BBCodeParser2",
"source": "https://github.com/pear/HTML_BBCodeParser2"
},
"type": "library",
"require-dev": {
"phpunit/phpunit": "*"
}
}

View File

@ -1,23 +0,0 @@
[HTML_BBCodeParser2]
; 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,Images,Links,Lists,Email

View File

@ -1,107 +0,0 @@
<?php
require_once('HTML/BBCodeParser2.php');
/* get options from the ini file */
$config = parse_ini_file('BBCodeParser2.ini', true);
$options = $config['HTML_BBCodeParser2'];
/* do yer stuff! */
$parser = new HTML_BBCodeParser2($options);
$parser->setText($_GET['string']);
$parser->parse();
$parsed = $parser->getParsed();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>HTML_BBCodeParser2 (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>

View File

@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.4" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>HTML_BBCodeParser2</name>
<channel>pear.php.net</channel>
<summary>This is a parser to replace UBB style tags with their html equivalents.</summary>
<description>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.</description>
<lead>
<name>Stijn de Reede</name>
<user>sjr</user>
<email>sjr@gmx.co.uk</email>
<active>no</active>
</lead>
<lead>
<name>Daniel O'Connor</name>
<user>doconnor</user>
<email>clockwerx@php.net</email>
<active>yes</active>
</lead>
<date>2012-11-03</date>
<time>14:00:34</time>
<version>
<release>0.1.0</release>
<api>0.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Forked from HTML_BBCodeParser
</notes>
<contents>
<dir baseinstalldir="/" name="/">
<file baseinstalldir="/" md5sum="4b21a26a5458a24d954318736ff557dc" name="example/BBCodeParser2.ini" role="data" />
<file baseinstalldir="/" md5sum="cae173b47c741333a07f2d719ffb733a" name="example/parser.php" role="php" />
<file baseinstalldir="/" md5sum="1b10fb033f10f196a93eace0b62b0ec0" name="HTML/BBCodeParser2.php" role="php" />
<file baseinstalldir="/" md5sum="b9768d4b7d62c9ac8850e440263557b4" name="HTML/BBCodeParser2/Filter.php" role="php" />
<file baseinstalldir="/" md5sum="a0180072b1ab1d5305e45740cbb1d5a2" name="HTML/BBCodeParser2/Filter/Basic.php" role="php" />
<file baseinstalldir="/" md5sum="97067ea67ae9aba7aa2c844b101b3c68" name="HTML/BBCodeParser2/Filter/Email.php" role="php" />
<file baseinstalldir="/" md5sum="e7dbe406fc7a7a9e7b2cd82d9e6a573e" name="HTML/BBCodeParser2/Filter/Extended.php" role="php" />
<file baseinstalldir="/" md5sum="a5d20d794e183cdd12282894a5e62aee" name="HTML/BBCodeParser2/Filter/Images.php" role="php" />
<file baseinstalldir="/" md5sum="c17ce7ba2f009e6760e701e0bcd03433" name="HTML/BBCodeParser2/Filter/Links.php" role="php" />
<file baseinstalldir="/" md5sum="6f70562067180a891e2c61425b6cdb15" name="HTML/BBCodeParser2/Filter/Lists.php" role="php" />
<file baseinstalldir="/" md5sum="d65933ef1613c22ddfc5276a5200236d" name="tests/HTML_BBCodeParser2Test.php" role="test" />
<file baseinstalldir="/" md5sum="53595c19c98669add7fdf564a3216b85" name="README" role="data" />
<file baseinstalldir="/" md5sum="a5a36f5ec0b094c93b39cf3bae5b51ca" name="TODO" role="data" />
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.0.0</min>
</php>
<pearinstaller>
<min>1.5.4</min>
</pearinstaller>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<version>
<release>0.1.0</release>
<api>0.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2012-11-03</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Forked from HTML_BBCodeParser
</notes>
</release>
</changelog>
</package>

View File

@ -1,237 +0,0 @@
<?php
require_once "PHPUnit/Framework/TestCase.php";
require_once 'HTML/BBCodeParser2.php';
class HTML_BBCodeParser2Test extends PHPUnit_Framework_TestCase
{
function testFilters()
{
$bbc = new HTML_BBCodeParser2(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_BBCodeParser2(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" alt="Enthalpy Wheel" width="100" height="99" />', $bbc->$funcNam('[img w=100 h=99 alt=Enthalpy Wheel]/images/Enthalpy Wheel.png[/img]'));
$this->assertEquals('<img src="img.jpg" alt="" />', $bbc->$funcNam('[img]img.jpg[/img]'));
$this->assertEquals('<img src="http://www.server.org/image.jpg" alt="" 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" target="new">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&amp;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&amp;j=2">linked text</a>',
$bbc->$funcNam('[url=http://domain.com/index.php?i=1&amp;j=2]linked text[/URL]'));
//Bug #5609: BBCodeParser allows XSS
$this->assertEquals(
'<a href="javascript&amp;#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&quot;&gt;&lt;script&gt;alert(\'JavaScript_Enabled\');&lt;/script&gt;"></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_BBCodeParser2(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_BBCodeParser2(array('filters' => ''));
$bbc->addFilter('Images');
$this->assertEquals('<img src="admin.php?fs=image" alt="" />',
$bbc->qparse("[img]admin.php?fs=image[/img]")
);
}
}