--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Gorilla.php Sat May 30 02:52:13 2009 -0400
@@ -0,0 +1,749 @@
+<?php
+/**!info**
+{
+ "Plugin Name" : "Gorilla Paste",
+ "Plugin URI" : "http://enanocms.org/plugin/gorilla",
+ "Description" : "For The Toughest Pasting Jobs On Earth.™ The pastebin, Enano style. <a href=\"http://enanocms.org/plugin/geshi\" onclick=\"window.open(this.href); return false;\">GeSHi plugin</a> highly recommended.",
+ "Author" : "Dan Fuhry",
+ "Version" : "0.1",
+ "Author URI" : "http://enanocms.org/"
+}
+**!*/
+
+// Register namespace and ACLs
+$plugins->attachHook('acl_rule_init', 'gorilla_setupcore($this, $session);');
+// Add our special page
+$plugins->attachHook('session_started', 'register_special_page(\'NewPaste\', \'gorilla_page_create\', true);');
+
+// constants
+define('PASTE_PRIVATE', 1);
+
+function gorilla_setupcore(&$paths, &$session)
+{
+ // register our paste namespace
+ $nssep = substr($paths->nslist['Special'], -1);
+ $paths->create_namespace('Paste', 'Paste' . $nssep);
+
+ // create our ACLs
+ /**
+ * @param string $acl_type An identifier for this field
+ * @param int $default_perm Whether permission should be granted or not if it's not specified in the ACLs.
+ * @param string $desc A human readable name for the permission type
+ * @param array $deps The list of dependencies - this should be an array of ACL types
+ * @param string $scope Which namespaces this field should apply to. This should be either a pipe-delimited list of namespace IDs or just "All".
+ */
+
+ $session->acl_extend_scope('read', 'Paste', $paths);
+ $session->acl_extend_scope('post_comments', 'Paste', $paths);
+ $session->acl_extend_scope('edit_comments', 'Paste', $paths);
+ $session->acl_extend_scope('mod_comments', 'Paste', $paths);
+ $session->acl_extend_scope('create_page', 'Paste', $paths);
+ $session->acl_extend_scope('mod_misc', 'Paste', $paths);
+
+ $session->register_acl_type('delete_paste_own', AUTH_ALLOW, 'gorilla_acl_delete_paste_own', array(), 'Paste');
+ $session->register_acl_type('delete_paste_others', AUTH_DISALLOW, 'gorilla_acl_delete_paste_others', array(), 'Paste');
+}
+
+// Our paste creation page
+function page_Special_NewPaste()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang, $output;
+
+ $have_geshi = isset($GLOBALS['geshi_supported_formats']);
+ $perms = $session->fetch_page_acl('0', 'Paste');
+ $have_permission = $perms->get_permissions('create_page');
+
+ if ( $paths->getParam(0) === 'ajaxsubmit' )
+ {
+ header('Content-type: text/plain');
+ echo gorilla_process_post($have_geshi, $have_permission, true);
+ return true;
+ }
+
+ $private = false;
+ $highlight = isset($_COOKIE['g_highlight']) ? $_COOKIE['g_highlight'] : 'plaintext';
+ $text = '';
+ $title = '';
+ $ttl = 3600;
+ $copy_from = false;
+
+ if ( preg_match('/^Copy=([0-9]+)$/', $paths->getParam(0), $match) )
+ {
+ $paste_id = intval($match[1]);
+ $q = $db->sql_query('SELECT paste_flags, paste_language, paste_text, paste_title, paste_ttl FROM ' . table_prefix . "pastes WHERE paste_id = $paste_id;");
+ if ( !$q )
+ $db->_die();
+
+ list($flags, $highlight, $text, $title, $ttl) = $db->fetchrow_num();
+ $db->free_result();
+ $private = $flags & PASTE_PRIVATE ? true : false;
+ $copy_from = $paste_id;
+ }
+
+ $output->header();
+
+ ?>
+ <script type="text/javascript">
+ var gorilla_have_permission = <?php echo $have_permission ? 'true' : 'false'; ?>;
+ function gorilla_create_submit()
+ {
+ if ( !window.gorilla_have_permission && user_level < USER_LEVEL_MEMBER )
+ {
+ load_component('login');
+
+ ajaxLogonInit(function(k, response)
+ {
+ window.gorilla_have_permission = true;
+ document.forms['gorilla_create'].submit();
+ }, USER_LEVEL_MEMBER);
+ return false;
+ }
+
+ try
+ {
+ load_component(['jquery', 'jquery-ui']);
+ $('#gorilla_submit_result').empty().hide();
+
+ var whitey = whiteOutElement(document.forms['gorilla_create']);
+
+ var json_packet = {
+ highlight: $('#gorilla_highlight').val(),
+ text: $('#gorilla_create_text').val(),
+ is_private: $('#gorilla_private:checked').val() ? true : false,
+ nick: $('#gorilla_nick').val(),
+ title: $('#gorilla_title').val(),
+ ttl: parseInt($('.gorilla_ttl:checked').val())
+ };
+ json_packet = ajaxEscape(toJSONString(json_packet));
+ ajaxPost(makeUrlNS('Special', 'NewPaste/ajaxsubmit'), 'r=' + json_packet, function(ajax)
+ {
+ if ( ajax.readyState == 4 && ajax.status == 200 )
+ {
+ var failed = parseInt((String(ajax.responseText)).substr(0, 1));
+ if ( failed == 1 )
+ whiteOutReportFailure(whitey);
+ else
+ whiteOutReportSuccess(whitey);
+
+ var response = (String(ajax.responseText)).substr(2);
+
+ setTimeout(function()
+ {
+ window.scroll(0, 0);
+ $('#gorilla_submit_result').html(response).show('blind', 150);
+ }, 1250);
+ }
+ });
+ return false;
+ }
+ catch(e)
+ {}
+
+ return true;
+ }
+ addOnloadHook(function()
+ {
+ load_component('expander');
+ });
+ </script>
+ <div id="gorilla_submit_result">
+ <?php
+ echo substr(gorilla_process_post($have_geshi, $have_permission), 2);
+ ?>
+ </div>
+
+ <form action="<?php echo makeUrlNS('Special', 'NewPaste'); ?>" method="post" name="gorilla_create" onsubmit="return gorilla_create_submit();">
+
+ <?php
+ if ( $copy_from )
+ {
+ echo '<p style="float: left;">' . $lang->get('gorilla_msg_copying_from', array('paste_id' => $copy_from, 'paste_url' => makeUrlNS('Paste', $copy_from, false, true))) . '</p>';
+ }
+ ?>
+
+ <!-- private -->
+ <div style="float: right; margin: 10px 1%;">
+ <label title="<?php echo $lang->get('gorilla_lbl_private_hint'); ?>">
+ <input type="checkbox" name="is_private" id="gorilla_private" <?php if ( $private ) echo 'checked="checked"'; ?> />
+ <img alt="<?php echo $lang->get('gorilla_lbl_private'); ?>" src="<?php echo cdnPath; ?>/images/lock16.png" />
+ </label>
+ </div>
+
+ <!-- highlighting -->
+ <div style="float: right; margin: 10px;">
+
+ <?php echo $lang->get('gorilla_lbl_highlight'); ?>
+ <?php if ( $have_geshi ): ?>
+ <select name="highlight" id="gorilla_highlight">
+ <?php
+ // print out options for each GeSHi format
+ global $geshi_supported_formats;
+ $formats = array_merge(array('plaintext'), $geshi_supported_formats);
+ foreach ( $formats as $format )
+ {
+ // $string = str_replace('-', '_', "geshi_lang_$format");
+ // if ( ($_ = $lang->get($string)) !== $string )
+ // $string = $_;
+ // else
+ $string = $format;
+
+ $sel = ( $format == $highlight ) ? ' selected="selected"' : '';
+ echo '<option value="' . $format . '"' . $sel . '>' . $string . '</option>' . "\n ";
+ }
+ ?>
+ </select>
+ <?php else: ?>
+ <span style="color: #808080;"><?php echo $lang->get('gorilla_msg_no_geshi'); ?></span>
+ <input type="hidden" name="highlight_type" id="gorilla_highlight" value="plaintext" />
+ <?php endif; ?>
+
+ </div>
+
+ <!-- text box -->
+
+ <textarea id="gorilla_create_text" name="text" rows="30" cols="80" style="width: 98%; display: block; margin: 10px auto; clear: both;"><?php echo htmlspecialchars($text); ?></textarea>
+
+ <fieldset enano:expand="closed" style="margin-bottom: 10px;">
+ <legend><?php echo $lang->get('gorilla_btn_advanced_options'); ?></legend>
+ <div>
+
+ <!-- title -->
+ <p>
+ <?php echo $lang->get('gorilla_lbl_title'); ?>
+ <input type="text" name="title" id="gorilla_title" size="40" value="<?php echo htmlspecialchars($title); ?>" />
+ </p>
+
+ <!-- nick -->
+ <p>
+ <?php echo $lang->get('gorilla_lbl_nick'); ?>
+ <?php
+ if ( !$have_permission && !$session->user_logged_in )
+ {
+ echo '<em>' . $lang->get('gorilla_msg_using_login_nick') . '</em>';
+ echo '<input type="hidden" name="nick" id="gorilla_nick" value="" />';
+ }
+ else if ( $session->user_logged_in )
+ {
+ $rankinfo = $session->get_user_rank($session->user_id);
+ echo '<em>' . $lang->get('gorilla_msg_using_logged_in_nick') . '</em> ';
+ echo '<span style="' . $rankinfo['rank_style'] . '">' . $session->username . '</span>';
+ echo '<input type="hidden" name="nick" id="gorilla_nick" value="" />';
+ }
+ else
+ {
+ echo '<input type="text" name="nick" id="gorilla_nick" value="' . $lang->get('gorilla_nick_anonymous') . '" />';
+ }
+ ?>
+ </p>
+
+ <!-- ttl -->
+ <p>
+ <?php echo $lang->get('gorilla_lbl_ttl'); ?>
+ <em>
+ <label><input<?php if ( !in_array($ttl, array(0, 86400, 2592000)) ) echo ' checked="checked"'; ?> class="gorilla_ttl" type="radio" name="ttl" value="3600" /> <?php echo $lang->get('gorilla_lbl_ttl_hour'); ?></label>
+ <label><input<?php if ( $ttl == 86400 ) echo ' checked="checked"'; ?> class="gorilla_ttl" type="radio" name="ttl" value="86400" /> <?php echo $lang->get('gorilla_lbl_ttl_day'); ?></label>
+ <label><input<?php if ( $ttl == 2592000 ) echo ' checked="checked"'; ?> class="gorilla_ttl" type="radio" name="ttl" value="2592000" /> <?php echo $lang->get('gorilla_lbl_ttl_month'); ?></label>
+ <label><input<?php if ( $ttl == 0 ) echo ' checked="checked"'; ?> class="gorilla_ttl" type="radio" name="ttl" value="0" /> <?php echo $lang->get('gorilla_lbl_ttl_forever'); ?></label>
+ </em>
+ </p>
+
+ </div>
+ </fieldset>
+
+ <!-- login notice -->
+
+ <?php if ( !$have_permission && !$session->user_logged_in ): ?>
+ <div class="info-box-mini">
+ <?php echo $lang->get('gorilla_msg_will_prompt_for_login'); ?>
+ </div>
+ <?php endif; ?>
+
+ <!-- submit -->
+
+ <input type="submit" style="font-size: x-large;" value="<?php echo $lang->get('gorilla_btn_submit'); ?>" />
+ </form>
+ <?php
+
+ $output->footer();
+}
+
+// actual processing for submitted pastes
+function gorilla_process_post($have_geshi, $have_permission, $is_ajax = false)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+
+ $fields = array(
+ 'highlight' => 'string',
+ 'text' => 'string',
+ 'is_private' => 'boolean',
+ 'nick' => 'string',
+ 'title' => 'string',
+ 'ttl' => 'integer'
+ );
+
+ $info = array();
+
+ if ( $is_ajax )
+ {
+ try
+ {
+ $request = enano_json_decode(@$_POST['r']);
+ }
+ catch ( Exception $e )
+ {
+ return '1;No JSON request given';
+ }
+ foreach ( $fields as $field => $type )
+ {
+ if ( !isset($request[$field]) )
+ return "1;Field \"$field\" not provided";
+ if ( ($ftype = gettype($request[$field])) !== $type )
+ return "1;Field \"$field\": expected $type, got $ftype";
+
+ $info[$field] = $request[$field];
+ }
+ }
+ else
+ {
+ foreach ( $fields as $field => $type )
+ {
+ if ( !isset($_POST[$field]) && $field != 'is_private' )
+ return '';
+ }
+ $info = array(
+ 'highlight' => $_POST['highlight'],
+ 'text' => $_POST['text'],
+ 'is_private' => isset($_POST['is_private']),
+ 'nick' => $_POST['nick'],
+ 'title' => $_POST['title'],
+ 'ttl' => intval($_POST['ttl'])
+ );
+ }
+
+ if ( !$have_permission )
+ {
+ return '1;<div class="error-box-mini">' . $lang->get('etc_access_denied') . '</div>';
+ }
+
+ // validate highlight scheme
+ global $geshi_supported_formats;
+ if ( is_array($geshi_supported_formats) )
+ {
+ if ( !in_array($info['highlight'], $geshi_supported_formats) )
+ $info['highlight'] = 'plaintext';
+ }
+ else
+ {
+ $info['highlight'] = 'plaintext';
+ }
+
+ setcookie('g_highlight', $info['highlight'], time() + 365 * 24 * 60 * 60);
+
+ $info_db = $info;
+ foreach ( $info_db as &$item )
+ {
+ if ( is_string($item) )
+ $item = "'" . $db->escape($item) . "'";
+ else if ( is_bool($item) )
+ $item = $item ? '1' : '0';
+ else if ( is_int($item) )
+ $item = strval($item);
+ else
+ $item = "''";
+ }
+
+ $now = time();
+ $flags = 0;
+ if ( $info['is_private'] )
+ $flags |= PASTE_PRIVATE;
+
+ $sql = 'INSERT INTO ' . table_prefix . "pastes( paste_title, paste_text, paste_author, paste_author_name, paste_author_ip, paste_language, paste_timestamp, paste_ttl, paste_flags ) VALUES\n"
+ . " ( {$info_db['title']}, {$info_db['text']}, $session->user_id, {$info_db['nick']}, '{$_SERVER['REMOTE_ADDR']}', {$info_db['highlight']}, $now, {$info_db['ttl']}, $flags );";
+
+ if ( !$db->sql_query($sql) )
+ ( $is_ajax ) ? $db->die_json() : $db->_die();
+
+ // avoid insert_id
+ $q = $db->sql_query('SELECT paste_id FROM ' . table_prefix . "pastes WHERE paste_timestamp = $now ORDER BY paste_id DESC LIMIT 1;");
+ if ( !$q )
+ ( $is_ajax ) ? $db->die_json() : $db->_die();
+ list($paste_id) = $db->fetchrow_num();
+ $db->free_result();
+
+ $params = false;
+ if ( $flags & PASTE_PRIVATE )
+ $params = 'hash=' . hmac_sha1($paste_id, sha1($info['text']));
+
+ $paste_url = makeUrlComplete('Paste', $paste_id, $params, true);
+
+ return '0;'
+ . '<div class="info-box-mini">' . $lang->get('gorilla_msg_created') . '</div>'
+ . '<div style="font-size: larger; text-align: center; margin: 30px 0;">' . $lang->get('gorilla_msg_paste_url') . '<br /><input onfocus="this.select()" readonly="readonly" type="text" size="50" style="font-size: larger; text-align: center;" value="' . $paste_url . '" /></div>';
+}
+
+###############################################################################
+## PASTE DISPLAY
+###############################################################################
+
+class Namespace_Paste extends Namespace_Default
+{
+ protected $paste_data = false;
+
+ public function __construct($page_id, $namespace, $revid = 0)
+ {
+ $this->page_id = $page_id;
+ $this->namespace = $namespace;
+ $this->revision_id = 0;
+
+ $this->build_cdata();
+ }
+
+ public function build_cdata()
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+
+ $this->exists = false;
+ if ( ctype_digit($this->page_id) )
+ {
+ $q = $db->sql_query('SELECT p.*, u.username FROM ' . table_prefix . "pastes AS p\n"
+ . " LEFT JOIN " . table_prefix . "users AS u\n"
+ . " ON ( u.user_id = p.paste_author )\n"
+ . " WHERE p.paste_id = $this->page_id;");
+ if ( $db->numrows() > 0 )
+ {
+ $this->exists = true;
+ $this->paste_data = $db->fetchrow();
+ }
+ $db->free_result();
+ }
+ if ( $this->exists )
+ {
+ $this->cdata = array(
+ 'name' => empty($this->paste_data['paste_title']) ? $lang->get('gorilla_untitled_paste') : $this->paste_data['paste_title'],
+ 'urlname' => $this->page_id,
+ 'namespace' => $this->namespace,
+ 'special' => 0,
+ 'visible' => 0,
+ 'comments_on' => 1,
+ 'protected' => 0,
+ 'delvotes' => 0,
+ 'delvote_ips' => '',
+ 'wiki_mode' => 2,
+ 'page_exists' => true,
+ 'page_format' => getConfig('default_page_format', 'wikitext')
+ );
+ }
+ else
+ {
+ $this->cdata = array(
+ 'name' => $lang->get('gorilla_title_404'),
+ 'urlname' => $this->page_id,
+ 'namespace' => $this->namespace,
+ 'special' => 0,
+ 'visible' => 0,
+ 'comments_on' => 0,
+ 'protected' => 0,
+ 'delvotes' => 0,
+ 'delvote_ips' => '',
+ 'wiki_mode' => 2,
+ 'page_exists' => false,
+ 'page_format' => getConfig('default_page_format', 'wikitext')
+ );
+ }
+ $this->cdata = Namespace_Default::bake_cdata($this->cdata);
+ }
+
+ public function send()
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $output, $lang;
+
+ $plugins->attachHook('page_type_string_set', '$this->namespace_string = $lang->get(\'gorilla_template_ns_string\');');
+ $template->add_header('<style type="text/css">
+ .geshi_highlighted a {
+ background-image: none !important;
+ padding-right: 0 !important;
+ }
+ </style>
+ ');
+
+ if ( $this->exists )
+ {
+ gorilla_display_paste($this->paste_data);
+ }
+ else
+ {
+ $output->header();
+ $this->error_404();
+ $output->footer();
+ }
+ }
+
+ public function error_404()
+ {
+ global $lang;
+ echo '<p>' . $lang->get('gorilla_msg_paste_not_found', array('create_link' => makeUrlNS('Special', 'NewPaste'))) . '</p>';
+ }
+}
+
+function gorilla_display_paste($data)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $lang;
+ global $output;
+
+ extract($data);
+ $perms = $session->fetch_page_acl($paste_id, 'Paste');
+
+ if ( isset($_GET['format']) )
+ {
+ switch($_GET['format'])
+ {
+ case 'text':
+ case 'plain':
+ header('Content-type: text/plain');
+ echo $paste_text;
+ return true;
+ break;
+ case 'download':
+ header('Content-type: text/plain');
+ header('Content-disposition: attachment; filename="paste' . $paste_id . '.txt"');
+ header('Content-length: ' . strlen($paste_text));
+ echo $paste_text;
+ return true;
+ break;
+ }
+ }
+
+ if ( $paste_flags & PASTE_PRIVATE || isset($_GET['delete']) )
+ {
+ if ( @$_GET['hash'] !== hmac_sha1($paste_id, sha1($paste_text)) )
+ {
+ die_friendly($lang->get('etc_access_denied_short'), '<p>' . $lang->get('gorilla_msg_wrong_hash') . '</p>');
+ }
+ }
+
+ $output->header();
+
+ $perm = $paste_author == $session->user_id ? 'delete_paste_own' : 'delete_paste_others';
+ if ( isset($_GET['delete']) && !isset($_POST['cancel']) )
+ {
+ if ( isset($_POST['delete_confirm']) )
+ {
+ $q = $db->sql_query('DELETE FROM ' . table_prefix . "pastes WHERE paste_id = $paste_id;");
+ if ( !$q )
+ $db->_die();
+
+ echo '<p>' . $lang->get('gorilla_msg_paste_deleted') . '</p>';
+ }
+ else
+ {
+ $submit_url = makeUrlNS('Paste', $paste_id, 'delete&hash=' . hmac_sha1($paste_id, sha1($paste_text)), true);
+ ?>
+ <form action="<?php echo $submit_url; ?>" method="post">
+ <p><?php echo $lang->get('gorilla_msg_delete_confirm'); ?></p>
+ <p>
+ <input type="submit" value="<?php echo $lang->get('gorilla_btn_delete_confirm'); ?>" name="delete_confirm" style="font-weight: bold;" />
+ <input type="submit" value="<?php echo $lang->get('etc_cancel'); ?>" name="cancel" />
+ </p>
+ </form>
+ <?php
+ }
+ $output->footer();
+ return true;
+ }
+
+ if ( $paste_author > 1 )
+ {
+ // logged-in user
+ $rank_info = $session->get_user_rank($paste_author);
+ $user_link = '<a href="' . makeUrlNS('User', $username, false, true) . '" style="' . $rank_info['rank_style'] . '">' . htmlspecialchars($username) . '</a>';
+ }
+ else
+ {
+ // anonymous
+ $user_link = '<b>' . htmlspecialchars($paste_author_name) . '</b>';
+ }
+ $date = enano_date('D, j M Y H:i:s', $paste_timestamp);
+ $pasteinfo = $lang->get('gorilla_msg_paste_info', array('user_link' => $user_link, 'date' => $date));
+
+ echo '<div class="mdg-infobox" style="margin: 10px 0;">';
+ echo '<div style="float: right;">
+ ' . $lang->get('gorilla_msg_other_formats', array('plain_link' => makeUrlNS('Paste', $paste_id, 'format=text', true), 'download_link' => makeUrlNS('Paste', $paste_id, 'format=download', true))) . '
+ /
+ <a title="' . $lang->get('gorilla_tip_new_paste') . '" href="' . makeUrlNS('Special', 'NewPaste') . '">' . $lang->get('gorilla_btn_new_paste') . '</a>
+ /
+ <a title="' . $lang->get('gorilla_tip_copy_from_this') . '" href="' . makeUrlNS('Special', 'NewPaste/Copy=' . $paste_id) . '">' . $lang->get('gorilla_btn_copy_from_this') . '</a>';
+
+ if ( $perms->get_permissions($perm) && $session->user_logged_in )
+ {
+ echo ' / <a title="' . $lang->get('gorilla_tip_delete') . '" href="' . makeUrlNS('Paste', $paste_id, 'delete&hash=' . hmac_sha1($paste_id, sha1($paste_text)), true) . '">' . $lang->get('gorilla_btn_delete') . '</a>';
+ }
+ if ( $perms->get_permissions('mod_misc') )
+ {
+ echo ' / <span title="' . $lang->get('gorilla_tip_paste_ip') . '">' . $paste_author_ip . '</span>';
+ }
+
+ echo '</div>';
+ echo $pasteinfo;
+ echo '</div>';
+
+ if ( preg_match('/^## /m', $paste_text) )
+ {
+ gorilla_show_text_multi($paste_text, $paste_language);
+ }
+ else
+ {
+ gorilla_show_text($paste_text, $paste_language);
+ }
+
+ $output->footer();
+}
+
+function gorilla_show_text($text, $lang)
+{
+ $have_geshi = isset($GLOBALS['geshi_supported_formats']);
+
+ if ( $have_geshi )
+ {
+ if ( $lang == 'plaintext' )
+ $lang = 'text';
+
+ if ( !defined('GESHI_ROOT') )
+ define('GESHI_ROOT', ENANO_ROOT . '/plugins/geshi/');
+
+ require_once ( GESHI_ROOT . 'base.php' );
+
+ $geshi = new GeSHi($text, $lang, null);
+ $geshi->set_header_type(GESHI_HEADER_DIV);
+ $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 2);
+ $geshi->set_overall_class('geshi_highlighted');
+ $parsed = $geshi->parse_code();
+
+ echo $parsed;
+ }
+ else
+ {
+ echo '<h3>FIXME: WRITE REAL PLAINTEXT FORMATTER</h3>';
+ echo '<pre>' . htmlspecialchars($text) . '</pre>';
+ }
+}
+
+function gorilla_show_text_multi($text, $lang)
+{
+ $sections = preg_split('/^## .*$/m', $text);
+ $headingcount = preg_match_all('/^## (.+?)(?: \[([a-z_-]+)\])? *$/m', $text, $matches);
+
+ // if we have one heading less than the number of sections, print the first section
+ while ( count($sections) > $headingcount )
+ {
+ gorilla_show_text(trim($sections[0], "\r\n"), $lang);
+
+ unset($sections[0]);
+ $sections = array_values($sections);
+ }
+
+ foreach ( $matches[0] as $i => $_ )
+ {
+ $clang = !empty($matches[2][$i]) ? $matches[2][$i] : $lang;
+ echo '<h2>' . htmlspecialchars(trim($matches[1][$i])) . '</h2>';
+ gorilla_show_text(trim($sections[$i], "\r\n"), $clang);
+ }
+}
+
+// make sure pastes are pruned on a regular basis
+function gorilla_prune_expired()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ $now = time();
+ $q = $db->sql_query('DELETE FROM ' . table_prefix . "pastes WHERE paste_timestamp + paste_ttl < $now AND paste_ttl > 0;");
+}
+
+register_cron_task('gorilla_prune_expired', 1);
+
+/**!install dbms="mysql"; **
+CREATE TABLE {{TABLE_PREFIX}}pastes(
+ paste_id int(18) NOT NULL auto_increment,
+ paste_title text DEFAULT NULL,
+ paste_text text NOT NULL DEFAULT '',
+ paste_author int(12) NOT NULL DEFAULT 1,
+ paste_author_name varchar(255) NOT NULL DEFAULT 'Anonymous',
+ paste_author_ip varchar(39) NOT NULL,
+ paste_language varchar(32) NOT NULL DEFAULT 'plaintext',
+ paste_timestamp int(12) NOT NULL DEFAULT 0,
+ paste_ttl int(12) NOT NULL DEFAULT 86400,
+ paste_flags int(8) NOT NULL DEFAULT 0,
+ PRIMARY KEY ( paste_id )
+) ENGINE=`MyISAM` CHARSET=`UTF8` COLLATE=`utf8_bin`;
+
+**!*/
+
+/**!uninstall **
+DROP TABLE {{TABLE_PREFIX}}pastes;
+**!*/
+
+/**!language**
+<code>
+{
+ eng: {
+ categories: ['meta', 'gorilla'],
+ strings: {
+ meta: {
+ gorilla: 'Gorilla',
+ },
+ gorilla: {
+ acl_delete_paste_own: 'Delete own pastes',
+ acl_delete_paste_others: 'Delete others\' pastes',
+
+ page_create: 'Create paste',
+ msg_copying_from: 'Copying from <a href="%paste_url%">paste #%paste_id%</a>.',
+ lbl_highlight: 'Language:',
+ msg_no_geshi: 'Not supported',
+ btn_advanced_options: 'Advanced options',
+ lbl_private: 'Private paste',
+ lbl_private_hint: 'Don\'t list this paste or allow it to be included in searches',
+ lbl_title: 'Title:',
+ lbl_nick: 'Nickname:',
+ nick_anonymous: 'Anonymous',
+ msg_using_login_nick: 'Using username provided during login',
+ msg_using_logged_in_nick: 'Logged in; using nickname:',
+ lbl_ttl: 'Keep it for:',
+ lbl_ttl_hour: '1 hour',
+ lbl_ttl_day: '1 day',
+ lbl_ttl_month: '1 month',
+ lbl_ttl_forever: 'forever',
+ msg_will_prompt_for_login: 'You are not logged in. You will be asked to log in when you click the submit button below.',
+ btn_submit: 'Paste it!',
+
+ msg_created: 'Paste created.',
+ msg_paste_url: 'Share this paste using the following URL:',
+
+ untitled_paste: 'Untitled paste',
+ title_404: 'Paste not found',
+ msg_paste_not_found: 'This paste cannot be found or has been deleted. <a href="%create_link%">Create a new paste</a>',
+ msg_wrong_hash: 'Either you are trying to view a private paste which requires a hash in the URL or you were linked to this page from an outside source and the CSRF protection kicked in.',
+
+ msg_paste_info: 'By %user_link%, pasted on %date%',
+ msg_other_formats: '<a title="View as plain text" href="%plain_link%" onclick="window.open(this.href, \'gorillaplaintext\', \'address=no,status=no,toolbar=no,menus=no,scroll=yes,width=640,height=480\'); return false;">raw</a> / <a title="Download paste" href="%download_link%">dl</a>',
+ btn_new_paste: 'new',
+ tip_new_paste: 'Create a new paste',
+ btn_copy_from_this: 'cp',
+ tip_copy_from_this: 'Create a new paste, copying this one into the form',
+ btn_delete: 'rm',
+ tip_delete: 'Delete this paste',
+ tip_paste_ip: 'IP address of paste author',
+ template_ns_string: 'paste',
+
+ msg_paste_deleted: 'Paste deleted.',
+ msg_delete_confirm: 'Really delete this paste?',
+ btn_delete_confirm: 'Delete',
+ }
+ }
+ }
+}
+</code>
+**!*/