1<?php 2/* 3 * Gallery - a web based photo album viewer and editor 4 * Copyright (C) 2000-2008 Bharat Mediratta 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or (at 9 * your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21/* 22 * Smarty plugin 23 * ------------------------------------------------------------- 24 * Type: modifier 25 * Name: markup 26 * Purpose: Format embedded markup in the given string according 27 * to settings specified in site admin (no markup, bbcode or 28 * raw html) 29 * ------------------------------------------------------------- 30 */ 31function smarty_modifier_markup($text) { 32 static $parsers = array(); 33 static $cacheKey = 'smarty_modifier_markup'; 34 35 $stripTags = false; 36 $args = func_get_args(); 37 array_shift($args); 38 foreach ($args as $arg) { 39 if ($arg == 'strip') { 40 $stripTags = true; 41 } else { 42 $markupType = $arg; 43 } 44 } 45 if (!isset($markupType)) { 46 if (!GalleryDataCache::containsKey($cacheKey)) { 47 list ($ret, $defaultMarkupType) = 48 GalleryCoreApi::getPluginParameter('module', 'core', 'misc.markup'); 49 if ($ret) { 50 /* This code is used by the UI -- we can't return an error. Choose something safe */ 51 $defaultMarkupType = 'none'; 52 } 53 GalleryDataCache::put($cacheKey, $defaultMarkupType); 54 } 55 56 $markupType = GalleryDataCache::get($cacheKey); 57 } 58 59 if (!isset($parsers[$markupType])) { 60 switch($markupType) { 61 case 'bbcode': 62 $parsers[$markupType] = new GalleryBbcodeMarkupParser(); 63 break; 64 65 case 'html': 66 $parsers[$markupType] = new GalleryHtmlMarkupParser(); 67 break; 68 69 case 'none': 70 default: 71 $parsers[$markupType] = new GalleryNoMarkupParser(); 72 } 73 } 74 75 $text = $parsers[$markupType]->parse($text); 76 return $stripTags ? strip_tags($text) : $text; 77} 78 79class GalleryNoMarkupParser { 80 function parse($text) { 81 return $text; 82 } 83} 84 85class GalleryHtmlMarkupParser { 86 function parse($text) { 87 /* http://bugs.php.net/bug.php?id=22014 - TODO: remove empty check when min php is 4.3.2+ */ 88 return empty($text) ? $text : GalleryUtilities::htmlSafe(html_entity_decode($text)); 89 } 90} 91 92class GalleryBbcodeMarkupParser { 93 var $_bbcode; 94 95 function GalleryBbcodeMarkupParser() { 96 if (!class_exists('StringParser_BBCode')) { 97 GalleryCoreApi::requireOnce('lib/bbcode/stringparser_bbcode.class.php'); 98 } 99 100 $this->_bbcode = new StringParser_BBCode(); 101 $this->_bbcode->setGlobalCaseSensitive(false); 102 103 /* Convert line breaks everywhere */ 104 $this->_bbcode->addParser(array('block', 'inline', 'link', 'listitem', 'list'), 105 array($this, 'convertLineBreaks')); 106 107 /* 108 * Escape all characters everywhere 109 * We don't need to do this 'cause G2 doesn't allow raw entities into the database 110 * $this->_bbcode->addParser('htmlspecialchars', 111 * array('block', 'inline', 'link', 'listitem')); 112 */ 113 114 /* Convert line endings */ 115 $this->_bbcode->addParser(array('block', 'inline', 'link', 'listitem'), 'nl2br'); 116 117 /* Strip last line break in list items */ 118 $this->_bbcode->addParser(array('listitem'), array($this, 'stripLastLineBreak')); 119 120 /* Strip contents in list elements */ 121 $this->_bbcode->addParser(array('list'), array($this, 'stripContents')); 122 123 /* [b], [i] */ 124 $this->_bbcode->addCode('b', 'simple_replace', null, 125 array('start_tag' => '<b>', 'end_tag' => '</b>'), 126 'inline', array('listitem', 'block', 'inline', 'link'), array()); 127 128 $this->_bbcode->addCode('i', 'simple_replace', null, 129 array('start_tag' => '<i>', 'end_tag' => '</i>'), 130 'inline', array('listitem', 'block', 'inline', 'link'), array()); 131 132 /* [url]http://...[/url], [url=http://...]Text[/url] */ 133 $this->_bbcode->addCode('url', 'usecontent?', array($this, 'url'), 134 array('usecontent_param' => 'default'), 135 'link', array('listitem', 'block', 'inline'), array('link')); 136 137 /* [color=...]Text[/color] */ 138 $this->_bbcode->addCode('color', 'callback_replace', array($this, 'color'), 139 array('usecontent_param' => 'default'), 140 'inline', array('listitem', 'block', 'inline', 'link'), array()); 141 142 /* [img]http://...[/img] */ 143 $this->_bbcode->addCode('img', 'usecontent', array($this, 'image'), array(), 144 'image', array('listitem', 'block', 'inline', 'link'), array()); 145 146 /* [list] [*]Element [/list] */ 147 $this->_bbcode->addCode('list', 'simple_replace', null, 148 array('start_tag' => '<ul>', 'end_tag' => '</ul>'), 149 'list', array('block', 'listitem'), array()); 150 $this->_bbcode->addCode('*', 'simple_replace', null, 151 array('start_tag' => '<li>', 'end_tag' => "</li>\n"), 152 'listitem', array('list'), array()); 153 $this->_bbcode->setCodeFlag('*', 'closetag', BBCODE_CLOSETAG_OPTIONAL); 154 } 155 156 function parse($text) { 157 return $this->_bbcode->parse($text); 158 } 159 160 function url($action, $attributes, $content, $params, &$node_object) { 161 if ($action == 'validate') { 162 /* The code is like [url]http://.../[/url] */ 163 if (!isset($attributes['default'])) { 164 return preg_match('#^(https?|ftp|mailto):|^/#', $content); 165 } else { 166 /* The code is like [url=http://.../]Text[/url] */ 167 return preg_match('#^(https?|ftp|mailto):|^/#', $attributes['default']); 168 } 169 } else { 170 /* Output of HTML. */ 171 /* The code is like [url]http://.../[/url] */ 172 if (!isset($attributes['default'])) { 173 return '<a href="' . $content . '" rel="nofollow">' . $content . '</a>'; 174 } else { 175 /* The code is like [url=http://.../]Text[/url] */ 176 return '<a href="' . $attributes['default'] . '" rel="nofollow">' 177 . $content . '</a>'; 178 } 179 } 180 } 181 182 function image($action, $attrs, $content, $params, &$node_object) { 183 if ($action == 'validate') { 184 return preg_match('#^(https?|ftp|mailto):|^/#', $content); 185 } else { 186 /* Output of HTML. */ 187 $size = (isset($attrs['width']) ? ' width="' . (int)$attrs['width'] . '"' : '') 188 . (isset($attrs['height']) ? ' height="' . (int)$attrs['height'] . '"' : ''); 189 /* Input should have entities already, so no htmlspecialchars here */ 190 return sprintf('<img src="%s" alt=""%s/>', $content, $size); 191 } 192 } 193 194 function color($action, $attrs, $content, $params, &$node_object) { 195 if ($action == 'validate') { 196 return !empty($attrs['default']); 197 } else { 198 /* Output of HTML. */ 199 $color = empty($attrs) ? 'bummer' : $attrs['default']; 200 return sprintf('<font color="%s">%s</font>', $color, $content); 201 } 202 } 203 204 function convertLineBreaks($text) { 205 return preg_replace("/\015\012|\015|\012/", "\n", $text); 206 } 207 208 function stripContents($text) { 209 return preg_replace("/[^\n]/", '', $text); 210 } 211 212 function stripLastLineBreak ($text) { 213 return preg_replace("/\n( +)?$/", '$1', $text); 214 } 215} 216?> 217