Created
November 14, 2009 18:08
-
-
Save laszlokorte/234666 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Secure | |
{ | |
private static $charset = 'utf-8'; | |
/* | |
* | |
* Alle HTML-Befehlszeichen aus einem String in HTML-Entities umwandeln | |
* | |
*/ | |
public static function html($string) | |
{ | |
return htmlentities($string, ENT_QUOTES, self::$charset); | |
} | |
/* | |
* | |
* Nach allen 50 Zeichen ohne Zeilenumbruch einen solchen einfügen | |
* | |
*/ | |
public static function linebreak($string) | |
{ | |
return $replace = preg_replace("=([^\s*?]{50})(?![^<]+>|[^&]*;)=","\\0 ", $string); | |
} | |
/* | |
* | |
* HTML-Entities wieder echtes HTML machen | |
* | |
*/ | |
public static function rebuild_html($string) | |
{ | |
return html_entity_decode($string, ENT_QUOTES, self::$charset); | |
} | |
} | |
/* | |
* | |
* Pattern Klasse | |
* | |
*/ | |
class Pattern | |
{ | |
const SIMPLE_STRING_TYPE = 0; | |
const PREG_STRING_TYPE = 1; | |
const PREG_CALLBACK_TYPE = 2; | |
private $pattern; | |
private $action; | |
private $type; | |
private $recursive; | |
public $level; | |
public function __construct($pattern, $action, $recursive = FALSE, $level = 0, $regex = TRUE) | |
{ | |
$this->pattern = $pattern; | |
$this->action = $action; | |
$this->recursive = $recursive; | |
$this->level = $level; | |
if(is_object($action)) | |
{ | |
$this->type = self::PREG_CALLBACK_TYPE; | |
} | |
elseif(is_string($action)) | |
{ | |
if(substr ($action, -2) === '()') | |
{ | |
$this->type = self::PREG_CALLBACK_TYPE; | |
$this->action = substr ($action, 0, -2); | |
} | |
else | |
{ | |
if($regex===FALSE) | |
{ | |
$this->type = self::SIMPLE_STRING_TYPE; | |
} | |
else | |
{ | |
$this->type = self::PREG_STRING_TYPE; | |
} | |
} | |
} | |
if($regex!==TRUE) | |
{ | |
$this->type *= -1; | |
} | |
} | |
public function apply($string) | |
{ | |
do | |
{ | |
switch($this->type) | |
{ | |
case self::PREG_STRING_TYPE: | |
$string = preg_replace($this->pattern, $this->action, $string); | |
break; | |
case self::SIMPLE_STRING_TYPE: | |
$string = str_replace($this->pattern, $this->action, $string); | |
break; | |
case self::PREG_CALLBACK_TYPE: | |
$string = preg_replace_callback($this->pattern, $this->action, $string); | |
} | |
} | |
while($this->recursive && preg_match($this->pattern, $string)); | |
return $string; | |
} | |
public function filter($string) | |
{ | |
do | |
{ | |
switch($this->type) | |
{ | |
case self::PREG_CALLBACK_TYPE: | |
case self::PREG_STRING_TYPE: | |
$string = preg_replace_callback($this->pattern, "end", $string); | |
break; | |
} | |
} | |
while($this->recursive && preg_match($this->pattern, $string)); | |
return $string; | |
} | |
} | |
/* | |
* | |
* BbcodeInterface | |
* | |
* Jeder Bbcode muss eine replace(), eine clear() und eine load() Methode haben | |
* | |
*/ | |
interface BbcodeInterface | |
{ | |
public static function replace($string, $level = 0); | |
public static function clear($string, $level = FALSE); | |
public static function load(); | |
public static function extend(Pattern $pattern, $start_pos = FALSE); | |
} | |
/* | |
* | |
* Bbcode Klasse | |
* | |
* Gefällt mir eigentlich nicht so gut, aber man könnte sie benutzen um hier alle Bbcode-Addons zu registrieren | |
* evtl könnte auch diese Klasse eine extend() Methode bekommen (siehe ClansphereBbcode) mit der man alle registrierten Bbcode-Addons um ein Pattern erweitern kann. | |
* oder auch eine replace() oder clear() Methode mit der man die Patterns aller Bbcode-Addons auf einen String anwendet oder entfernt | |
* | |
*/ | |
/* | |
* | |
* Clansphere Bbcode | |
* | |
* Implementiert das BbcodeInterface | |
* | |
* hat also eine replace() clear() und load() Methode | |
* die 3 Methoden von einer Klasse zu Erben wäre besser, aber geht nicht, weil auf statische Eigenschaften zurückgegriffen werden muss | |
* | |
*/ | |
class ClansphereBbcode implements BbcodeInterface | |
{ | |
private static $patterns = array(); | |
private static $cache = array(); | |
public static function extend(Pattern $pattern, $start_pos = FALSE) | |
{ | |
if($start_pos===TRUE) | |
{ | |
array_unshift(self::$patterns, $pattern); | |
} | |
else | |
{ | |
array_push(self::$patterns, $pattern); | |
} | |
} | |
public static function replace($string, $level = 0) | |
{ | |
$patterns_count = count(self::$patterns); | |
for($i=0; $i<$patterns_count; $i++) | |
{ | |
if(self::$patterns[$i]->level <= $level) | |
{ | |
$string = self::$patterns[$i]->apply($string); | |
} | |
} | |
return $string; | |
} | |
public static function clear($string, $level = FALSE) | |
{ | |
$patterns_count = count(self::$patterns); | |
for($i=0; $i<$patterns_count; $i++) | |
{ | |
if($level===FALSE || self::$patterns[$i]->level <= $level) | |
{ | |
$string = self::$patterns[$i]->filter($string); | |
} | |
} | |
return $string; | |
} | |
public static function load() | |
{ | |
self::extend(new Pattern("/\[b\](.*?)\[\/b\]/si","<strong>$1</strong>")); | |
self::extend(new Pattern("/\[i\](.*?)\[\/i\]/si","<em>$1</em>")); | |
self::extend(new Pattern("/\[u\](.*?)\[\/u\]/si","<span class=\"underlined\">$1</span>")); | |
self::extend(new Pattern("/\[s\](.*?)\[\/s\]/si","<del>$1</del>")); | |
self::extend(new Pattern("/\[img\](.*?)\[\/img\](.{0})/si","<img src=\"$1\" alt=\"\" />")); | |
self::extend(new Pattern("/\[url\=(.*?)\]\[img width\=(.*?) height\=(.*?)\](.*?)\[\/img\]\[\/url\]/si","ClansphereBbcode::url_image()")); | |
self::extend(new Pattern("/\[img width\=([\d]*?) height\=([\d]*?)\](.*?)\[\/img\]/si","ClansphereBbcode::image()")); | |
self::extend(new Pattern("/\[mail\](.+)\[\/mail]/si","ClansphereBbcode::mail()")); | |
self::extend(new Pattern("/([^\s]{3,})@([^\s]*?)\.([^\s]{2,7})(?![^<]+>|[^&]*;)/si","ClansphereBbcode::mail()")); | |
self::extend(new Pattern("/\[size\=([1-3]?\d)\]\[color\=(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6}|red|green|blue|yellow|black|white|grey|purple)\](.+)\[\/color\]\[\/size\]/si","<span style=\"font-size: $1px; color: $2\">$3</span>")); | |
self::extend(new Pattern("/\[color\=(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6}|red|green|blue|yellow|black|white|grey|purple)\]\[size\=([1-3]?\d)\](.+)\[\/size\]\[\/color\]/si","<span style=\"font-size: $1px; color: $2\">$3</span>")); | |
self::extend(new Pattern("/\[color\=(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6}|red|green|blue|yellow|black|white|grey|purple)\](.+)\[\/color\]/si","<span style=\"color: $1\">$2</span>")); | |
self::extend(new Pattern("/\[size\=([1-3]?\d)\](.+)\[\/size\]/si","<span style=\"font-size: $1px\">$2</span>")); | |
self::extend(new Pattern("/\[(?P<align>left|center|right|justify)\](.+)\[\/(?P=align)]/si","<p style=\"text-align: $1;\">$2</p>")); | |
self::extend(new Pattern("/\[list\=([a-z_-]+?)\](.+?)\[\/list\]/si","ClansphereBbcode::unordered_list()")); | |
self::extend(new Pattern("/\[list\](.+?)\[\/list\]/si","ClansphereBbcode::unordered_list()")); | |
self::extend(new Pattern("/\[url\=(.+)\](.+)\[\/url]/si","ClansphereBbcode::url()")); | |
self::extend(new Pattern("/\[url\](.+)\[\/url]/si","ClansphereBbcode::url()")); | |
self::extend(new Pattern("/(www\.|http:\/\/|ftp:\/\/)([^\s,]+)\.([^\s]+)(?![^<]+>|[^&]*;)/si", 'ClansphereBbcode::url_auto()')); | |
self::extend(new Pattern("/\[flag\=([A-Za-z]{2})\]/si","ClansphereBbcode::flag()")); | |
self::extend(new Pattern("/\[indent\=([\d]+)\](.+)\[\/indent\]/siU","<div style=\"padding-left: $1em\">$2</div>",TRUE)); | |
self::extend(new Pattern("/\[threadid\=([\d]+)\](.+)\[\/threadid\]/si","ClansphereBbcode::thread_link()")); | |
self::extend(new Pattern("/\[h\=([1-7])\](.+)\[\/h\]/si","<h$1>$2</h$1>")); | |
self::extend(new Pattern("/\[hr\]/","<hr>")); | |
self::extend(new Pattern("/\[quote\](.*)\[\/quote\]/siU","<div style=\"padding: 5px;\">$1</div>", TRUE)); | |
self::extend(new Pattern("/\[clip=(.+)\](.*)\[\/clip\]/siU","<div class=\"bbcode_clip\"><h4 class=\"clip_title\">$1</h4><div class=\"clip_body\">$2</div></div>", TRUE)); | |
self::extend(new Pattern("/\[code=(.+)\](.*)\[\/code\]/si","ClansphereBbcode::extract_code()"), TRUE); | |
self::extend(new Pattern("/\[code\](.*)\[\/code\]/si","ClansphereBbcode::extract_code()"), TRUE); | |
self::extend(new Pattern("/\[code=(\d+)\/\]/si","ClansphereBbcode::insert_cached()")); | |
self::extend(new Pattern("/\[html\](.*)\[\/html\]/si","ClansphereBbcode::extract_html()", FALSE, 2), TRUE); | |
self::extend(new Pattern("/\[html=(\d+)\/\]/si","ClansphereBbcode::insert_cached()", FALSE, 2)); | |
self::extend(new Pattern("/\[filter\](.*)\[\/filter\]/si","ClansphereBbcode::extract_filter()"), TRUE); | |
self::extend(new Pattern("/\[filter=(\d+)\/\]/si","ClansphereBbcode::insert_cached()")); | |
self::extend(new Pattern("/\[phpcode\](.*)\[\/phpcode\]/si","ClansphereBbcode::extract_phpcode()", FALSE, 3), TRUE); | |
self::extend(new Pattern("/\[phpcode=(\d+)\/\]/si","ClansphereBbcode::insert_cached()", FALSE, 3)); | |
self::extend(new Pattern("/[\n]/i", "<br/>\n",false,0),TRUE); | |
} | |
public static function thread_link($matches) | |
{ | |
return "<a href=\"?mod=board&action=thread&id={$matches[1]}\">{$matches[2]}</a>"; | |
} | |
//TODO: Rework: url(), url_auto(), url_image(), image(), mail() | |
public static function url($matches) { | |
$java = substr($matches[1],0,10); | |
if($java != 'javascript') { | |
if(empty($matches[2])) { | |
$matches[2] = $matches[1]; | |
} | |
$matches[1] = strpos($matches[1],'www.') === 0 ? 'http://' . $matches[1] : $matches[1]; | |
return cs_html_link($matches[1],$matches[2],1); | |
} else { | |
return cs_bbcode_i(array(0,'Javascript Links are not allowed')); | |
} | |
} | |
public static function url_auto($matches) { | |
if (strpos($matches[0],'</a>') !== FALSE || strpos($matches[0],'[/threadid]') !== FALSE) | |
return $matches[0]; | |
$after = ''; | |
if (substr($matches[0],-1) == ',') { $matches[0] = substr($matches[0],0,-1); $after = ','; } | |
$url = substr($matches[0],0,4) == 'www.' ? 'http://' . $matches[0] : $matches[0]; | |
return '<a href="' . $url . '">' . $matches[0] . '</a>' . $after; | |
} | |
public static function url_image($matches) { | |
} | |
public static function image($matches) { | |
if ($matches[0]{4} == ']') { | |
return '<img src="' . $matches[1] . '" alt="" />'; | |
} else { | |
return '<a href="' . $matches[3] . '"<img src="' . $matches[1] . '" style="width: ' . $matches[1] . 'px; height: ' . $matches[1] . 'px" alt="" /></a>'; | |
} | |
} | |
public static function mail($matches) { | |
$mail = $matches[1]; | |
if (strpos($matches[0],'</a>') !== FALSE) | |
return $matches[0]; | |
if ($matches[0]{0} != '[') | |
$mail = $matches[0]; | |
return '<a href="mailto:' . $mail . '">' . $mail . '</a>'; | |
} | |
public static function flag($matches) | |
{ | |
$short = $matches[1]; | |
$country = $short . ': not included'; | |
return '<img src="symbols/countries/' . $short . '.png" alt="' . $country . '" />'; | |
} | |
public static function unordered_list($matches) | |
{ | |
$list_types = array('none', 'circle', 'square', 'disc', 'decimal', 'lower-roman', 'upper-roman', 'decimal-leading-zero', 'lower-greek', 'lower-latin', 'upper-latin', 'armenian', 'georgian'); | |
$type = (isset($matches[2]) && in_array($matches[1], $list_types)) ? $matches[1] : 'disc'; | |
if(preg_match_all("/\[\*\]([\w\d\s]+)/si",end($matches),$items)>0) | |
{ | |
$items = end($items); | |
$list = '<ul style="list-style: ' . $type . ';">'; | |
foreach($items AS $item) | |
{ | |
$list .= '<li>' . $item . '</li>'; | |
} | |
$content; | |
$list .= '</ul>'; | |
return $list; | |
} | |
return $matches[0]; | |
} | |
public static function extract_code($matches) | |
{ | |
$lang = isset($matches[2]) ? $matches[1] : 'text'; | |
$code = isset($matches[2]) ? $matches[2] : $matches[1]; | |
$code = preg_replace("/<br(.*?)>/si",'',$code); | |
$line_count = substr_count ( $code, "\n" ) + 1; | |
$line_numbers = ''; | |
for($i=1;$i<=$line_count;$i++) | |
{ | |
$line_numbers .= ($i.'<br/>'); | |
} | |
$code = '<table class="code"><tr><td class="lines"><pre>' . $line_numbers . '</pre></td><td class=\"code\"><pre><code class="' . $lang . '">' . $code . '</code></pre></td></tr></table>'; | |
$index = self::set_cache($code); | |
return '[code=' . $index .'/]'; | |
} | |
public static function extract_html($matches) | |
{ | |
$html = Secure::rebuild_html($matches[1]); | |
$index = self::set_cache($html); | |
return '[html=' . $index .'/]'; | |
} | |
public static function extract_filter($matches) | |
{ | |
$index = self::set_cache($matches[1]); | |
return '[filter=' . $index .'/]'; | |
} | |
public static function extract_phpcode($matches) | |
{ | |
ob_start(); | |
eval($matches[1]); | |
$eval = ob_get_contents(); | |
ob_end_clean(); | |
$eval; | |
$index = self::set_cache($eval); | |
return '[phpcode=' . $index .'/]'; | |
} | |
public static function insert_cached($matches) | |
{ | |
$cached = self::get_cache($matches[1]); | |
if($cached !== FALSE) | |
{ | |
return $cached; | |
} | |
return $matches[0]; | |
} | |
private static function set_cache($content) { | |
array_push(self::$cache, $content); | |
return (count(self::$cache)-1); | |
} | |
private static function get_cache($index) { | |
if(isset(self::$cache[$index])) | |
{ | |
$result = self::$cache[$index]; | |
unset(self::$cache[$index]); | |
return $result; | |
} | |
return FALSE; | |
} | |
} | |
/* Ruft die ClansphereBbcode::load() Methode auf um die patterns zu erstellen */ | |
ClansphereBbcode::load(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment