mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merging 2.1 blog into trunk
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@42892 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
45ff73d72e
commit
e0ddba6ab8
24
parsers/BBCodeParser.ini
Normal file
24
parsers/BBCodeParser.ini
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[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,EmailLinks,Images,Links,Lists"
|
||||||
|
|
112
parsers/BBCodeParser.php
Normal file
112
parsers/BBCodeParser.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
require_once('HTML/HTMLBBCodeParser.php');
|
||||||
|
/*Seting up the PEAR bbcode parser*/
|
||||||
|
$config = parse_ini_file('BBCodeParser.ini', true);
|
||||||
|
$options = &SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser', '_options');
|
||||||
|
$options = $config['SSHTMLBBCodeParser'];
|
||||||
|
//Debug::show($options);
|
||||||
|
unset($options);
|
||||||
|
|
||||||
|
|
||||||
|
class BBCodeParser extends TextParser {
|
||||||
|
|
||||||
|
protected static $autolinkUrls = true;
|
||||||
|
|
||||||
|
static function autolinkUrls() {
|
||||||
|
return (self::$autolinkUrls != null) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function disable_autolink_urls($autolink = false) {
|
||||||
|
BBCodeParser::$autolinkUrls = $autolink;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function usable_tags() {
|
||||||
|
return new DataObjectSet(
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Bold Text",
|
||||||
|
"Example" => "[b]<b>Bold</b>[/b]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Italic Text",
|
||||||
|
"Example" => "[i]<i>Italics</i>[/i]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Underlined Text",
|
||||||
|
"Example" => "[u]<u>Underlined</u>[/u]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Struck-out Text",
|
||||||
|
"Example" => "[s]<s>Struck-out</s>[/s]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Colored text",
|
||||||
|
"Example" => "[color=blue]blue text[/color]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Alignment",
|
||||||
|
"Example" => "[align=right]right aligned[/align]"
|
||||||
|
)),
|
||||||
|
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Website link",
|
||||||
|
"Description" => "Link to another website or URL",
|
||||||
|
"Example" => "[url]http://www.website.com/[/url]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Website link",
|
||||||
|
"Description" => "Link to another website or URL",
|
||||||
|
"Example" => "[url=http://www.website.com/]Some website[/url]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Email link",
|
||||||
|
"Description" => "Create link to an email address",
|
||||||
|
"Example" => "[email]you@yoursite.com[/email]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Email link",
|
||||||
|
"Description" => "Create link to an email address",
|
||||||
|
"Example" => "[email=you@yoursite.com]email me[/email]"
|
||||||
|
)),
|
||||||
|
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Image",
|
||||||
|
"Description" => "Show an image in your post",
|
||||||
|
"Example" => "[img]http://www.website.com/image.jpg[/img]"
|
||||||
|
)),
|
||||||
|
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Code Block",
|
||||||
|
"Description" => "Unformatted code block",
|
||||||
|
"Example" => "[code]Code block[/code]"
|
||||||
|
)),
|
||||||
|
new ArrayData(array(
|
||||||
|
"Title" => "Unordered list",
|
||||||
|
"Description" => "Unordered list",
|
||||||
|
"Example" => "[ulist][*]unordered item 1[*]unordered item 2[/ulist]"
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse() {
|
||||||
|
$this->content = str_replace(array('&', '<', '>'), array('&', '<', '>'), $this->content);
|
||||||
|
$this->content = SSHTMLBBCodeParser::staticQparse($this->content);
|
||||||
|
$this->content = "<p>".$this->content."</p>";
|
||||||
|
$this->content = str_replace("\n\n", "</p><p>", $this->content);
|
||||||
|
$this->content = str_replace("\n", "<br />", $this->content);
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
10
parsers/HTML/BBCodeParser/Filter.php
Normal file
10
parsers/HTML/BBCodeParser/Filter.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'HTML/HTMLBBCodeParser.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dummy class that filters need to extend from.
|
||||||
|
*/
|
||||||
|
class SSHTMLBBCodeParser_Filter extends SSHTMLBBCodeParser
|
||||||
|
{
|
||||||
|
}
|
||||||
|
?>
|
71
parsers/HTML/BBCodeParser/Filter/Basic.php
Normal file
71
parsers/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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SSHTMLBBCodeParser_Filter_Basic extends SSHTMLBBCodeParser_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
parsers/HTML/BBCodeParser/Filter/EmailLinks.php
Normal file
85
parsers/HTML/BBCodeParser/Filter/EmailLinks.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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SSHTMLBBCodeParser_Filter_EmailLinks extends SSHTMLBBCodeParser_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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser','_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
parsers/HTML/BBCodeParser/Filter/Extended.php
Normal file
97
parsers/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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SSHTMLBBCodeParser_Filter_Extended extends SSHTMLBBCodeParser_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' => 'pre',
|
||||||
|
'htmlclose' => 'pre',
|
||||||
|
'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
parsers/HTML/BBCodeParser/Filter/Images.php
Normal file
79
parsers/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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
class SSHTMLBBCodeParser_Filter_Images extends SSHTMLBBCodeParser_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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser','_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);
|
||||||
|
}
|
||||||
|
}
|
205
parsers/HTML/BBCodeParser/Filter/Links.php
Normal file
205
parsers/HTML/BBCodeParser/Filter/Links.php
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<?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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SSHTMLBBCodeParser_Filter_Links extends SSHTMLBBCodeParser_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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser', '_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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser','_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];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!BBCodeParser::autolinkUrls()){
|
||||||
|
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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser','_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
parsers/HTML/BBCodeParser/Filter/Lists.php
Normal file
108
parsers/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 SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'HTML/BBCodeParser/Filter.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SSHTMLBBCodeParser_Filter_Lists extends SSHTMLBBCodeParser_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 = SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser','_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
873
parsers/HTML/HTMLBBCodeParser.php
Normal file
873
parsers/HTML/HTMLBBCodeParser.php
Normal file
@ -0,0 +1,873 @@
|
|||||||
|
<?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 $
|
||||||
|
//
|
||||||
|
// Modified by SilverStripe www.silverstripe.com
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package SSHTMLBBCodeParser
|
||||||
|
* @author Stijn de Reede <sjr@gmx.co.uk> , SilverStripe
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 SSHTMLBBCodeParser();
|
||||||
|
* $parser->setText('normal [b]bold[/b] and normal again');
|
||||||
|
* $parser->parse();
|
||||||
|
* echo $parser->getParsed();
|
||||||
|
* or:
|
||||||
|
* $parser = new SSHTMLBBCodeParser();
|
||||||
|
* echo $parser->qparse('normal [b]bold[/b] and normal again');
|
||||||
|
* or:
|
||||||
|
* echo SSHTMLBBCodeParser::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('SSHTMLBBCodeParser', '_options');
|
||||||
|
* $options = $config['SSHTMLBBCodeParser'];
|
||||||
|
* unset($options);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SSHTMLBBCodeParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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 SSHTMLBBCodeParser($options = array())
|
||||||
|
{
|
||||||
|
// set the already set options
|
||||||
|
$baseoptions = &SSHTMLBBCodeParser::getStaticProperty('SSHTMLBBCodeParser', '_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, 'SSHTMLBBCodeParser_Filter')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the definedTags from subclasses */
|
||||||
|
$this->addFilters($this->_options['filters']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = 'SSHTMLBBCodeParser_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, 'SSHTMLBBCodeParser')) {
|
||||||
|
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 SSHTMLBBCodeParser();
|
||||||
|
$str = $p->qparse($str);
|
||||||
|
unset($p);
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
51
parsers/TextParser.php
Normal file
51
parsers/TextParser.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* 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 DataObjectSet 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 {
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new TextParser object.
|
||||||
|
*
|
||||||
|
* @param string $content The contents of the dbfield
|
||||||
|
*/
|
||||||
|
function __construct($content = "") {
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method, shouldn't really be used, but it's here if you want it
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
abstract function parse();
|
||||||
|
}
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user