Skip to content

Instantly share code, notes, and snippets.

@laszlokorte
Created November 14, 2009 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laszlokorte/234605 to your computer and use it in GitHub Desktop.
Save laszlokorte/234605 to your computer and use it in GitHub Desktop.
<?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;
}
}
/*
*
* AbcodeInterface
*
* Jeder Abcode muss eine replace(), eine clear() und eine load() Methode haben
*
*/
interface AbcodeInterface
{
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);
}
/*
*
* Abcode Klasse
*
* Gefällt mir eigentlich nicht so gut, aber man könnte sie benutzen um hier alle Abcode-Addons zu registrieren
* evtl könnte auch diese Klasse eine extend() Methode bekommen (siehe ClansphereAbcode) mit der man alle registrierten Abcode-Addons um ein Pattern erweitern kann.
* oder auch eine replace() oder clear() Methode mit der man die Patterns aller Abcode-Addons auf einen String anwendet oder entfernt
*
*/
/*
*
* Clansphere Abcode
*
* Implementiert das AbcodeInterface
*
* 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 ClansphereAbcode implements AbcodeInterface
{
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","ClansphereAbcode::url_image()"));
self::extend(new Pattern("/\[img width\=([\d]*?) height\=([\d]*?)\](.*?)\[\/img\]/si","ClansphereAbcode::image()"));
self::extend(new Pattern("/\[mail\](.+)\[\/mail]/si","ClansphereAbcode::mail()"));
self::extend(new Pattern("/([^\s]{3,})@([^\s]*?)\.([^\s]{2,7})(?![^<]+>|[^&]*;)/si","ClansphereAbcode::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","ClansphereAbcode::unordered_list()"));
self::extend(new Pattern("/\[list\](.+?)\[\/list\]/si","ClansphereAbcode::unordered_list()"));
self::extend(new Pattern("/\[url\=(.+)\](.+)\[\/url]/si","ClansphereAbcode::url()"));
self::extend(new Pattern("/\[url\](.+)\[\/url]/si","ClansphereAbcode::url()"));
self::extend(new Pattern("/(www\.|http:\/\/|ftp:\/\/)([^\s,]+)\.([^\s]+)(?![^<]+>|[^&]*;)/si", 'ClansphereAbcode::url_auto()'));
self::extend(new Pattern("/\[flag\=([A-Za-z]{2})\]/si","ClansphereAbcode::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","ClansphereAbcode::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=\"abcode_clip\"><h4 class=\"clip_title\">$1</h4><div class=\"clip_body\">$2</div></div>", TRUE));
self::extend(new Pattern("/\[code=(.+)\](.*)\[\/code\]/si","ClansphereAbcode::extract_code()"), TRUE);
self::extend(new Pattern("/\[code\](.*)\[\/code\]/si","ClansphereAbcode::extract_code()"), TRUE);
self::extend(new Pattern("/\[code=(\d+)\/\]/si","ClansphereAbcode::insert_cached()"));
self::extend(new Pattern("/\[html\](.*)\[\/html\]/si","ClansphereAbcode::extract_html()", FALSE, 2), TRUE);
self::extend(new Pattern("/\[html=(\d+)\/\]/si","ClansphereAbcode::insert_cached()", FALSE, 2));
self::extend(new Pattern("/\[filter\](.*)\[\/filter\]/si","ClansphereAbcode::extract_filter()"), TRUE);
self::extend(new Pattern("/\[filter=(\d+)\/\]/si","ClansphereAbcode::insert_cached()"));
self::extend(new Pattern("/\[phpcode\](.*)\[\/phpcode\]/si","ClansphereAbcode::extract_phpcode()", FALSE, 3), TRUE);
self::extend(new Pattern("/\[phpcode=(\d+)\/\]/si","ClansphereAbcode::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&amp;action=thread&amp;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_abcode_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 ClansphereAbcode::load() Methode auf um die patterns zu erstellen */
ClansphereAbcode::load();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment