mirror of
https://github.com/samclarke/SBBCodeParser.git
synced 2026-01-09 14:18:41 +00:00
Cleaned up code
Using a Namespace and a seperate File for each Class in a good structure
This commit is contained in:
1486
SBBCodeParser.php
1486
SBBCodeParser.php
File diff suppressed because it is too large
Load Diff
146
classes/BBCode.php
Normal file
146
classes/BBCode.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class BBCode
|
||||
{
|
||||
/**
|
||||
* The tag this BBCode applies to
|
||||
* @var string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* The BBCodes handler
|
||||
* @var mixed string or function
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
/**
|
||||
* If the tag is a self closing tag
|
||||
* @var bool
|
||||
*/
|
||||
protected $is_self_closing;
|
||||
|
||||
/**
|
||||
* Array of tags which will cause this tag to close
|
||||
* if they are encountered before the end of it.
|
||||
* Used for [*] which may not have a closing tag so
|
||||
* other [*] or [/list] tags will cause it to be closed·
|
||||
* @var array
|
||||
*/
|
||||
protected $closing_tags;
|
||||
|
||||
/**
|
||||
* Valid child nodes for this tag. Tags like list, table,
|
||||
* ect. will only accept li, tr, ect. tags and not text nodes
|
||||
* @var array
|
||||
*/
|
||||
protected $accepted_children;
|
||||
|
||||
/**
|
||||
* Which auto detections this BBCode should be excluded from
|
||||
* @var int
|
||||
*/
|
||||
protected $is_inline;
|
||||
|
||||
const AUTO_DETECT_EXCLUDE_NONE = 0;
|
||||
const AUTO_DETECT_EXCLUDE_URL = 2;
|
||||
const AUTO_DETECT_EXCLUDE_EMAIL = 4;
|
||||
const AUTO_DETECT_EXCLUDE_EMOTICON = 8;
|
||||
const AUTO_DETECT_EXCLUDE_ALL = 15;
|
||||
|
||||
const BLOCK_TAG = false;
|
||||
const INLINE_TAG = true;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new BBCode
|
||||
* @param string $tag Tag this BBCode is for
|
||||
* @param mixed $handler String or function, should return a string
|
||||
* @param bool $is_inline If this tag is an inline tag or a block tag
|
||||
* @param array $is_self_closing If this tag is self closing, I.E. doesn't need [/tag]
|
||||
* @param array $closing_tags Tags which will close this tag
|
||||
* @param int $accepted_children Tags allowed as children of this BBCode. Can also include text_node
|
||||
* @param int $auto_detect_exclude Which auto detections to exclude this BBCode from
|
||||
*/
|
||||
public function __construct($tag,
|
||||
$handler,
|
||||
$is_inline=BBCode::INLINE_TAG,
|
||||
$is_self_closing=false,
|
||||
$closing_tags=array(),
|
||||
$accepted_children=array(),
|
||||
$auto_detect_exclude=BBCode::AUTO_DETECT_EXCLUDE_NONE)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
$this->is_inline = $is_inline;
|
||||
$this->handler = $handler;
|
||||
$this->is_self_closing = $is_self_closing;
|
||||
$this->closing_tags = $closing_tags;
|
||||
$this->accepted_children = $accepted_children;
|
||||
$this->auto_detect_exclude = $auto_detect_exclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag name this BBCode is for
|
||||
* @return string
|
||||
*/
|
||||
public function tag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if this BBCode is inline or if it's block
|
||||
* @return bool
|
||||
*/
|
||||
public function is_inline()
|
||||
{
|
||||
return $this->is_inline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if this BBCode is self closing
|
||||
* @return bool
|
||||
*/
|
||||
public function is_self_closing()
|
||||
{
|
||||
return $this->is_self_closing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format string/handler for this BBCode
|
||||
* @return mixed String or function
|
||||
*/
|
||||
public function handler()
|
||||
{
|
||||
return $this->handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of tags which will cause this tag to be closed
|
||||
* @return array
|
||||
*/
|
||||
public function closing_tags()
|
||||
{
|
||||
return $this->closing_tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of tags which are allowed as children of this tag
|
||||
* @return array
|
||||
*/
|
||||
public function accepted_children()
|
||||
{
|
||||
return $this->accepted_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Which auto detections this BBCode should be excluded from
|
||||
* @return int
|
||||
*/
|
||||
public function auto_detect_exclude()
|
||||
{
|
||||
return $this->auto_detect_exclude;
|
||||
}
|
||||
}
|
||||
7
classes/Exception.php
Normal file
7
classes/Exception.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
7
classes/Exception/InvalidNesting.php
Normal file
7
classes/Exception/InvalidNesting.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class Exception_InvalidNesting extends Exception
|
||||
{
|
||||
}
|
||||
7
classes/Exception/MissingEndTag.php
Normal file
7
classes/Exception/MissingEndTag.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class Exception_MissingEndTag extends Exception
|
||||
{
|
||||
}
|
||||
82
classes/Node.php
Normal file
82
classes/Node.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
abstract class Node
|
||||
{
|
||||
/**
|
||||
* Nodes parent
|
||||
* @var Node_Container
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Nodes root parent
|
||||
* @var Node_Container
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the nodes parent
|
||||
* @param Node $parent
|
||||
*/
|
||||
public function set_parent(Node_Container $parent=null)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
if($parent instanceof Node_Container_Document)
|
||||
$this->root = $parent;
|
||||
else
|
||||
$this->root = $parent->root();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodes parent. Returns null if there
|
||||
* is no parent
|
||||
* @return Node
|
||||
*/
|
||||
public function parent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_html()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodes root node
|
||||
* @return Node
|
||||
*/
|
||||
public function root()
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a parent node of the passed type.
|
||||
* Returns null if none found.
|
||||
* @param string $tag
|
||||
* @return Node_Container_Tag
|
||||
*/
|
||||
public function find_parent_by_tag($tag)
|
||||
{
|
||||
$node = $this->parent();
|
||||
|
||||
while($this->parent() != null
|
||||
&& !$node instanceof Node_Container_Document)
|
||||
{
|
||||
if($node->tag() === $tag)
|
||||
return $node;
|
||||
|
||||
$node = $node->parent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
129
classes/Node/Container.php
Normal file
129
classes/Node/Container.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
abstract class Node_Container extends Node
|
||||
{
|
||||
/**
|
||||
* Array of child nodes
|
||||
* @var array
|
||||
*/
|
||||
protected $children = array();
|
||||
|
||||
|
||||
/**
|
||||
* Adds a Node as a child
|
||||
* of this node.
|
||||
* @param $child The child node to add
|
||||
* @return void
|
||||
*/
|
||||
public function add_child(Node $child)
|
||||
{
|
||||
$this->children[] = $child;
|
||||
$child->set_parent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a child node
|
||||
* @param Node $what
|
||||
* @param mixed $with Node or an array of Node
|
||||
* @return bool
|
||||
*/
|
||||
public function replace_child(Node $what, $with)
|
||||
{
|
||||
$replace_key = array_search($what, $this->children);
|
||||
|
||||
if($replace_key === false)
|
||||
return false;
|
||||
|
||||
if(is_array($with))
|
||||
foreach($with as $child)
|
||||
$child->set_parent($this);
|
||||
|
||||
array_splice($this->children, $replace_key, 1, $with);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a child fromthe node
|
||||
* @param Node $child
|
||||
* @return bool
|
||||
*/
|
||||
public function remove_child(Node $child)
|
||||
{
|
||||
$key = array_search($what, $this->children);
|
||||
|
||||
if($key === false)
|
||||
return false;
|
||||
|
||||
$this->children[$key]->set_parent();
|
||||
unset($this->children[$key]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodes children
|
||||
* @return array
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last child of type Node_Container_Tag.
|
||||
* @return Node_Container_Tag
|
||||
*/
|
||||
public function last_tag_node()
|
||||
{
|
||||
$children_len = count($this->children);
|
||||
|
||||
for($i=$children_len-1; $i >= 0; $i--)
|
||||
if($this->children[$i] instanceof Node_Container_Tag)
|
||||
return $this->children[$i];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a HTML representation of this node
|
||||
* @return string
|
||||
*/
|
||||
public function get_html($nl2br=true)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
foreach($this->children as $child)
|
||||
$html .= $child->get_html($nl2br);
|
||||
|
||||
if($this instanceof Node_Container_Document)
|
||||
return $html;
|
||||
|
||||
$bbcode = $this->root()->get_bbcode($this->tag);
|
||||
|
||||
if(is_callable($bbcode->handler()) && ($func = $bbcode->handler()) !== false)
|
||||
return $func($html, $this->attribs, $this);
|
||||
//return call_user_func($bbcode->handler(), $html, $this->attribs, $this);
|
||||
|
||||
return str_replace('%content%', $html, $bbcode->handler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw text content of this node
|
||||
* and it's children.
|
||||
*
|
||||
* The returned text is UNSAFE and should not
|
||||
* be used without filtering!
|
||||
* @return string
|
||||
*/
|
||||
public function get_text()
|
||||
{
|
||||
$text = '';
|
||||
|
||||
foreach($this->children as $child)
|
||||
$text .= $child->get_text();
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
1051
classes/Node/Container/Document.php
Normal file
1051
classes/Node/Container/Document.php
Normal file
File diff suppressed because it is too large
Load Diff
43
classes/Node/Container/Tag.php
Normal file
43
classes/Node/Container/Tag.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class Node_Container_Tag extends Node_Container
|
||||
{
|
||||
/**
|
||||
* Tag name of this node
|
||||
* @var string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* Assoc array of attributes
|
||||
* @var array
|
||||
*/
|
||||
protected $attribs;
|
||||
|
||||
|
||||
public function __construct($tag, $attribs)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
$this->attribs = $attribs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag of this node
|
||||
* @return string
|
||||
*/
|
||||
public function tag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tags attributes
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return $this->attribs;
|
||||
}
|
||||
}
|
||||
27
classes/Node/Text.php
Normal file
27
classes/Node/Text.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace SBBCodeParser;
|
||||
|
||||
class Node_Text extends Node
|
||||
{
|
||||
protected $text;
|
||||
|
||||
|
||||
public function __construct($text)
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function get_html($nl2br=true)
|
||||
{
|
||||
if(!$nl2br)
|
||||
return str_replace(" ", " ", htmlentities($this->text, ENT_QUOTES | ENT_IGNORE, "UTF-8"));
|
||||
|
||||
return str_replace(" ", " ", nl2br(htmlentities($this->text, ENT_QUOTES | ENT_IGNORE, "UTF-8")));
|
||||
}
|
||||
|
||||
public function get_text()
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
}
|
||||
41
classes/SBBCodeParser.php
Normal file
41
classes/SBBCodeParser.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* SSBBCodeParser
|
||||
*
|
||||
* BBCode parser classes.
|
||||
*
|
||||
* @copyright (C) 2011 Sam Clarke (samclarke.com)
|
||||
* @license http://www.gnu.org/licenses/lgpl.html LGPL version 3 or higher
|
||||
*
|
||||
* @TODO: Add inline/block to tags and forbid adding block elements to inline ones.
|
||||
* Maybe split the inline elemnt and put the block element inbetween?
|
||||
* @TODO: Have options for limiting nesting of tags
|
||||
* @TODO: Have whitespace trimming options for tags
|
||||
*/
|
||||
|
||||
/*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
require('Exception.php');
|
||||
require('Exception/MissingEndTag.php');
|
||||
require('Exception/InvalidNesting.php');
|
||||
|
||||
require('Node.php');
|
||||
require('Node/Text.php');
|
||||
require('Node/Container.php');
|
||||
require('Node/Container/Tag.php');
|
||||
require('Node/Container/Document.php');
|
||||
|
||||
require('BBCode.php');
|
||||
Reference in New Issue
Block a user