1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459:
<?php
class ContentSecondParser extends AbstractParser
{
const MAX_CODE_LENGTH = 40000;
public function __construct()
{
parent::__construct();
}
public function parse()
{
$this->content = preg_replace_callback('`(src|href)="/([A-Za-z0-9#+-_\./]+)"`suU', array($this, 'callbackrelative_url'), $this->content);
if (TextHelper::strpos($this->content, '[[CODE') !== false)
{
$this->content = preg_replace_callback('`\[\[CODE(?:=([^,\s]+))?(?:,(0|1)(?:,(0|1))?)?\]\](.+)\[\[/CODE\]\]`suU', array($this, 'callbackhighlight_code'), $this->content);
}
if (stripos($this->content, '[[MEMBER]]') !== false)
{
$this->content = preg_replace_callback('`\[\[MEMBER\]\](.+)\[\[/MEMBER\]\]`suU', array($this, 'callback_member_tag'), $this->content);
}
if (stripos($this->content, '[[MODERATOR]]') !== false)
{
$this->content = preg_replace_callback('`\[\[MODERATOR\]\](.+)\[\[/MODERATOR\]\]`suU', array($this, 'callback_moderator_tag'), $this->content);
}
if (TextHelper::strpos($this->content, '[[MEDIA]]') !== false)
{
$this->process_media_insertion();
}
if (TextHelper::strpos($this->content, '[[MATH]]') !== false)
{
$server_config = new ServerConfiguration();
if ($server_config->has_gd_library())
{
require_once PATH_TO_ROOT . '/kernel/lib/php/mathpublisher/mathpublisher.php';
$this->content = preg_replace_callback('`\[\[MATH\]\](.+)\[\[/MATH\]\]`suU', array($this, 'math_code'), $this->content);
}
}
$this->parse_feed_tag();
}
public static function export_html_text($html_content)
{
$html_content = preg_replace('`<a href="([^"]+)" style="display:block;margin:auto;width:([0-9]+)px;height:([0-9]+)px;" id="movie_[0-9]+"></a><br /><script><!--\s*insertMoviePlayer\(\'movie_[0-9]+\'\);\s*--></script>`isU',
'<object type="application/x-shockwave-flash" width="$2" height="$3">
<param name="FlashVars" value="flv=$1&width=$2&height=$3" />
<param name="allowScriptAccess" value="never" />
<param name="play" value="true" />
<param name="movie" value="$1" />
<param name="menu" value="false" />
<param name="quality" value="high" />
<param name="scalemode" value="noborder" />
<param name="wmode" value="transparent" />
<param name="bgcolor" value="#FFFFFF" />
</object>',
$html_content);
return Url::html_convert_root_relative2absolute($html_content);
}
private static function highlight_code($contents, $language, $line_number, $inline_code)
{
$contents = TextHelper::htmlspecialchars_decode($contents);
if (TextHelper::strtolower($language) == 'bbcode')
{
$bbcode_highlighter = new BBCodeHighlighter();
$bbcode_highlighter->set_content($contents);
$bbcode_highlighter->parse($inline_code);
$contents = $bbcode_highlighter->get_content();
}
elseif (TextHelper::strtolower($language) == 'tpl' || TextHelper::strtolower($language) == 'template')
{
require_once(PATH_TO_ROOT . '/kernel/lib/php/geshi/geshi.php');
$template_highlighter = new TemplateHighlighter();
$template_highlighter->set_content($contents);
$template_highlighter->parse($line_number ? GESHI_NORMAL_LINE_NUMBERS : GESHI_NO_LINE_NUMBERS, $inline_code);
$contents = $template_highlighter->get_content();
}
elseif ( TextHelper::strtolower($language) == 'plain')
{
$plain_code_highlighter = new PlainCodeHighlighter();
$plain_code_highlighter->set_content($contents);
$plain_code_highlighter->parse();
$contents = $plain_code_highlighter->get_content();
}
elseif ($language != '')
{
require_once(PATH_TO_ROOT . '/kernel/lib/php/geshi/geshi.php');
$Geshi = new GeSHi($contents, $language);
if ($line_number)
{
$Geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
}
if ($inline_code)
{
$Geshi->set_header_type(GESHI_HEADER_NONE);
}
$contents = '<pre style="display:inline;">' . $Geshi->parse_code() . '</pre>';
}
else
{
$highlight = highlight_string($contents, true);
$font_replace = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $highlight);
$contents = preg_replace('`color="(.*?)"`', 'style="color:$1"', $font_replace);
}
return $contents;
}
private function callbackrelative_url($matches)
{
return $matches[1] . '="' . Url::to_rel('/' . $matches[2]) . '"';
}
private function callbackhighlight_code($matches)
{
$extension = "";
$line_number = !empty($matches[2]);
$inline_code = !empty($matches[3]);
$content_to_highlight = $matches[4];
if (TextHelper::strlen($content_to_highlight) > self::MAX_CODE_LENGTH)
{
return '<div class="message-helper error">' . LangLoader::get_message('code_too_long_error', 'editor-common') . '</div>';
}
if (!empty($matches[1])) {
$info = new SplFileInfo($matches[1]);
$extension = $info->getExtension();
$extension = TextHelper::strtolower($extension);
if ($extension == 'js' || $extension == 'jquery')
{
$extension = "javascript";
}
else if ($extension && TextHelper::strtolower($extension)!='tpl')
{
require_once(PATH_TO_ROOT . '/kernel/lib/php/geshi/geshi.php');
$Geshi = new GeSHi();
$Geshi->set_language($extension);
if ($Geshi->error())
{
$extension = "text";
}
}
}
if ($extension != "")
{
$typecode = TextHelper::strtoupper($extension);
$title = $matches[1] .' : ';
}
else
{
$typecode = TextHelper::strtoupper($matches[1]);
$title = sprintf(LangLoader::get_message('code_langage', 'main'), TextHelper::strtoupper($matches[1]));
}
$contents = $this->highlight_code($content_to_highlight, $typecode, $line_number, $inline_code);
if (!$inline_code && !empty($matches[1]))
{
$contents = '<div class="formatter-container formatter-code code-' . $typecode . '"><span class="formatter-title">' . $title . '</span><div class="formatter-content">' . $contents .'</div></div>';
}
else if (!$inline_code && empty($matches[1]))
{
$contents = '<div class="formatter-container formatter-code"><span class="formatter-title">' . LangLoader::get_message('code_tag', 'main') . '</span><div class="formatter-content">' . $contents . '</div></div>';
}
return $contents;
}
private function callback_member_tag($matches)
{
if (AppContext::get_current_user()->check_level(User::MEMBER_LEVEL))
{
return $matches[1];
}
return MessageHelper::display(LangLoader::get_message('bbcode_member', 'status-messages-common'), MessageHelper::MEMBER_ONLY)->render();
}
private function callback_moderator_tag($matches)
{
if (AppContext::get_current_user()->check_level(User::MODERATOR_LEVEL))
{
return $matches[1];
}
return MessageHelper::display(LangLoader::get_message('bbcode_moderator', 'status-messages-common'), MessageHelper::MODERATOR_ONLY)->render();
}
private function math_code($matches)
{
$matches[1] = str_replace('<br />', '', $matches[1]);
$code = mathimage($matches[1], 12, '/images/maths/');
return $code;
}
private function process_media_insertion()
{
$this->content = preg_replace_callback('`\[\[MEDIA\]\]insertSwfPlayer\(\'([^\']+)\', ([0-9]+), ([0-9]+)\);\[\[/MEDIA\]\]`isuU', array('ContentSecondParser', 'process_swf_tag'), $this->content);
$this->content = preg_replace_callback('`\[\[MEDIA\]\]insertMoviePlayer\(\'([^\']+)\', ([0-9]+), ([0-9]+)\);\[\[/MEDIA\]\]`isuU', array('ContentSecondParser', 'process_movie_tag'), $this->content);
$this->content = preg_replace_callback('`\[\[MEDIA\]\]insertMoviePlayer\(\'([^\']+)\', ([0-9]+), ([0-9]+), \'([^\']+)\'\);\[\[/MEDIA\]\]`isuU', array('ContentSecondParser', 'process_movie_tag'), $this->content);
$this->content = preg_replace_callback('`\[\[MEDIA\]\]insertSoundPlayer\(\'([^\']+)\'\);\[\[/MEDIA\]\]`isuU', array('ContentSecondParser', 'process_sound_tag'), $this->content);
$this->content = preg_replace_callback('`\[\[MEDIA\]\]insertYoutubePlayer\(\'([^\']+)\', ([0-9]+), ([0-9]+)\);\[\[/MEDIA\]\]`isuU', array('ContentSecondParser', 'process_youtube_tag'), $this->content);
}
private static function process_swf_tag($matches)
{
if (pathinfo($matches[1], PATHINFO_EXTENSION) == 'flv')
{
$id = 'movie_' . AppContext::get_uid();
return '<div class="media-content"><a class="video-player" href="' . Url::to_rel($matches[1]) . '" style="display:block;margin:auto;width:' . $matches[2] . 'px;height:' . $matches[3] . 'px;" id="' . $id . '"></a></div><br />' .
'<script><!--' . "\n" .
'insertMoviePlayer(\'' . $id . '\');' .
"\n" . '--></script>';
}
else
{
return "<div class=\"media-content\"><object type=\"application/x-shockwave-flash\" data=\"" . $matches[1] . "\" width=\"" . $matches[2] . "\" height=\"" . $matches[3] . "\">" .
"<param name=\"allowScriptAccess\" value=\"never\" />" .
"<param name=\"play\" value=\"true\" />" .
"<param name=\"movie\" value=\"" . Url::to_rel($matches[1]) . "\" />" .
"<param name=\"menu\" value=\"false\" />" .
"<param name=\"quality\" value=\"high\" />" .
"<param name=\"scalemode\" value=\"noborder\" />" .
"<param name=\"wmode\" value=\"transparent\" />" .
"<param name=\"bgcolor\" value=\"#000000\" />" .
"</object></div>";
}
}
private static function process_movie_tag($matches)
{
$sources = '';
$video_files = explode(',', $matches[1]);
if (pathinfo($video_files[0], PATHINFO_EXTENSION) == 'flv')
{
$id = 'movie_' . AppContext::get_uid();
return '<div class="media-content"><a class="video-player" href="' . Url::to_rel($matches[1]) . '" style="display:block;margin:auto;width:' . $matches[2] . 'px;height:' . $matches[3] . 'px;" id="' . $id . '"></a></div><br />' .
'<script><!--' . "\n" .
'insertMoviePlayer(\'' . $id . '\');' .
"\n" . '--></script>';
}
else
{
$poster = '';
if (!empty($matches[4]))
{
$poster_type = new FileType(new File($matches[4]));
$poster = $poster_type->is_picture() ? ' poster="' . Url::to_rel($matches[4]) . '"' : '';
}
foreach ($video_files as $video)
{
$video_file = new File($video);
$type = new FileType($video_file);
if ($type->is_video())
$sources .= '<source src="' . Url::to_rel($video) . '" type="video/' . pathinfo($video, PATHINFO_EXTENSION) . '" />';
}
return '<div class="media-content"><video class="video-player" width="' . $matches[2] . '" height="' . $matches[3] . '"' . $poster . ' controls>' . $sources . '</video></div>';
}
}
private static function process_sound_tag($matches)
{
return '<audio class="audio-player" controls><source src="' . Url::to_rel($matches[1]) . '" /></audio>';
}
private static function process_youtube_tag($matches)
{
preg_match('#(?<=docid=)[a-zA-Z0-9-]+(?=&)|(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+(?=\?)|(?<=e\/)[^&\n]+(?=\?)|(?<=embed/)[^&\n]+|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#', $matches[1], $url_matches);
$video_id = isset($url_matches[0]) ? $url_matches[0] : '';
return $video_id ? '<div class="media-content"><iframe class="youtube-player" type="text/html" width="' . $matches[2] . '" height="' . $matches[3] . '" src="https://www.youtube.com/embed/' . $video_id . '" frameborder="0" allowfullscreen></iframe></div>' : '';
}
private function parse_feed_tag()
{
$this->content = preg_replace_callback('`\[\[FEED((?: [a-z]+="[^"]+")*)\]\]([a-z]+)\[\[/FEED\]\]`uU', array(__CLASS__, 'inject_feed'), $this->content);
}
private static function inject_feed(array $matches)
{
$module = $matches[2];
$args = self::parse_feed_tag_args($matches[1]);
$name = !empty($args['name']) ? $args['name'] : Feed::DEFAULT_FEED_NAME;
$cat = !empty($args['cat']) ? $args['cat'] : 0;
$tpl = false;
$number = !empty($args['number']) ? $args['number'] : 10;
$result = '';
try
{
$result = Feed::get_parsed($module, $name, $cat, $tpl, $number);
}
catch (Exception $e)
{
}
if (!empty($result))
{
return $result;
}
else
{
$error = StringVars::replace_vars(LangLoader::get_message('feed_tag_error', 'editor-common'), array('module' => $module));
return '<div class="message-helper error">' . $error . '</div>';
}
}
private static function parse_feed_tag_args($matches)
{
$args = explode(' ', trim($matches));
$result = array();
foreach ($args as $arg)
{
$param = array();
if (!preg_match('`([a-z]+)="([^"]+)"`uU', $arg, $param))
{
break;
}
$name = $param[1];
$value = $param[2];
if (in_array($name, array('name', 'cat', 'number')))
{
$result[$name] = $value;
}
}
return $result;
}
}
?>