Gorilla.php
changeset 0 cac93de16379
child 1 f2ceea4fabe8
equal deleted inserted replaced
-1:000000000000 0:cac93de16379
       
     1 <?php
       
     2 /**!info**
       
     3 {
       
     4   "Plugin Name"  : "Gorilla Paste",
       
     5   "Plugin URI"   : "http://enanocms.org/plugin/gorilla",
       
     6   "Description"  : "For The Toughest Pasting Jobs On Earth.&trade; The pastebin, Enano style. <a href=\"http://enanocms.org/plugin/geshi\" onclick=\"window.open(this.href); return false;\">GeSHi plugin</a> highly recommended.",
       
     7   "Author"       : "Dan Fuhry",
       
     8   "Version"      : "0.1",
       
     9   "Author URI"   : "http://enanocms.org/"
       
    10 }
       
    11 **!*/
       
    12 
       
    13 // Register namespace and ACLs
       
    14 $plugins->attachHook('acl_rule_init', 'gorilla_setupcore($this, $session);');
       
    15 // Add our special page
       
    16 $plugins->attachHook('session_started', 'register_special_page(\'NewPaste\', \'gorilla_page_create\', true);');
       
    17 
       
    18 // constants
       
    19 define('PASTE_PRIVATE', 1);
       
    20 
       
    21 function gorilla_setupcore(&$paths, &$session)
       
    22 {
       
    23   // register our paste namespace
       
    24   $nssep = substr($paths->nslist['Special'], -1);
       
    25   $paths->create_namespace('Paste', 'Paste' . $nssep);
       
    26   
       
    27   // create our ACLs
       
    28   /**
       
    29    * @param string $acl_type An identifier for this field
       
    30    * @param int $default_perm Whether permission should be granted or not if it's not specified in the ACLs.
       
    31    * @param string $desc A human readable name for the permission type
       
    32    * @param array $deps The list of dependencies - this should be an array of ACL types
       
    33    * @param string $scope Which namespaces this field should apply to. This should be either a pipe-delimited list of namespace IDs or just "All".
       
    34    */
       
    35    
       
    36   $session->acl_extend_scope('read', 'Paste', $paths);
       
    37   $session->acl_extend_scope('post_comments', 'Paste', $paths);
       
    38   $session->acl_extend_scope('edit_comments', 'Paste', $paths);
       
    39   $session->acl_extend_scope('mod_comments', 'Paste', $paths);
       
    40   $session->acl_extend_scope('create_page', 'Paste', $paths);
       
    41   $session->acl_extend_scope('mod_misc', 'Paste', $paths);
       
    42   
       
    43   $session->register_acl_type('delete_paste_own', AUTH_ALLOW, 'gorilla_acl_delete_paste_own', array(), 'Paste');
       
    44   $session->register_acl_type('delete_paste_others', AUTH_DISALLOW, 'gorilla_acl_delete_paste_others', array(), 'Paste');
       
    45 }
       
    46 
       
    47 // Our paste creation page
       
    48 function page_Special_NewPaste()
       
    49 {
       
    50   global $db, $session, $paths, $template, $plugins; // Common objects
       
    51   global $lang, $output;
       
    52   
       
    53   $have_geshi = isset($GLOBALS['geshi_supported_formats']);
       
    54   $perms = $session->fetch_page_acl('0', 'Paste');
       
    55   $have_permission = $perms->get_permissions('create_page');
       
    56   
       
    57   if ( $paths->getParam(0) === 'ajaxsubmit' )
       
    58   {
       
    59     header('Content-type: text/plain');
       
    60     echo gorilla_process_post($have_geshi, $have_permission, true);
       
    61     return true;
       
    62   }
       
    63   
       
    64   $private = false;
       
    65   $highlight = isset($_COOKIE['g_highlight']) ? $_COOKIE['g_highlight'] : 'plaintext';
       
    66   $text = '';
       
    67   $title = '';
       
    68   $ttl = 3600;
       
    69   $copy_from = false;
       
    70   
       
    71   if ( preg_match('/^Copy=([0-9]+)$/', $paths->getParam(0), $match) )
       
    72   {
       
    73     $paste_id = intval($match[1]);
       
    74     $q = $db->sql_query('SELECT paste_flags, paste_language, paste_text, paste_title, paste_ttl FROM ' . table_prefix . "pastes WHERE paste_id = $paste_id;");
       
    75     if ( !$q )
       
    76       $db->_die();
       
    77     
       
    78     list($flags, $highlight, $text, $title, $ttl) = $db->fetchrow_num();
       
    79     $db->free_result();
       
    80     $private = $flags & PASTE_PRIVATE ? true : false;
       
    81     $copy_from = $paste_id;
       
    82   }
       
    83   
       
    84   $output->header();
       
    85   
       
    86   ?>
       
    87   <script type="text/javascript">
       
    88   var gorilla_have_permission = <?php echo $have_permission ? 'true' : 'false'; ?>;
       
    89   function gorilla_create_submit()
       
    90   {
       
    91     if ( !window.gorilla_have_permission && user_level < USER_LEVEL_MEMBER )
       
    92     {
       
    93       load_component('login');
       
    94       
       
    95       ajaxLogonInit(function(k, response)
       
    96         {
       
    97           window.gorilla_have_permission = true;
       
    98           document.forms['gorilla_create'].submit();
       
    99         }, USER_LEVEL_MEMBER);
       
   100       return false;
       
   101     }
       
   102     
       
   103     try
       
   104     {
       
   105       load_component(['jquery', 'jquery-ui']);
       
   106       $('#gorilla_submit_result').empty().hide();
       
   107       
       
   108       var whitey = whiteOutElement(document.forms['gorilla_create']);
       
   109       
       
   110       var json_packet = {
       
   111         highlight: $('#gorilla_highlight').val(),
       
   112         text: $('#gorilla_create_text').val(),
       
   113         is_private: $('#gorilla_private:checked').val() ? true : false,
       
   114         nick: $('#gorilla_nick').val(),
       
   115         title: $('#gorilla_title').val(),
       
   116         ttl: parseInt($('.gorilla_ttl:checked').val())
       
   117       };
       
   118       json_packet = ajaxEscape(toJSONString(json_packet));
       
   119       ajaxPost(makeUrlNS('Special', 'NewPaste/ajaxsubmit'), 'r=' + json_packet, function(ajax)
       
   120         {
       
   121           if ( ajax.readyState == 4 && ajax.status == 200 )
       
   122           {
       
   123             var failed = parseInt((String(ajax.responseText)).substr(0, 1));
       
   124             if ( failed == 1 )
       
   125               whiteOutReportFailure(whitey);
       
   126             else
       
   127               whiteOutReportSuccess(whitey);
       
   128               
       
   129             var response = (String(ajax.responseText)).substr(2);
       
   130             
       
   131             setTimeout(function()
       
   132               {
       
   133                 window.scroll(0, 0);
       
   134                 $('#gorilla_submit_result').html(response).show('blind', 150);
       
   135               }, 1250);
       
   136           }
       
   137         });
       
   138       return false;
       
   139     }
       
   140     catch(e)
       
   141     {}
       
   142     
       
   143     return true;
       
   144   }
       
   145   addOnloadHook(function()
       
   146     {
       
   147       load_component('expander');
       
   148     });
       
   149   </script>
       
   150   <div id="gorilla_submit_result">
       
   151   <?php
       
   152     echo substr(gorilla_process_post($have_geshi, $have_permission), 2);
       
   153   ?>
       
   154   </div>
       
   155   
       
   156   <form action="<?php echo makeUrlNS('Special', 'NewPaste'); ?>" method="post" name="gorilla_create" onsubmit="return gorilla_create_submit();">
       
   157   
       
   158     <?php
       
   159     if ( $copy_from )
       
   160     {
       
   161       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>';
       
   162     }
       
   163     ?>
       
   164   
       
   165     <!-- private -->
       
   166     <div style="float: right; margin: 10px 1%;">
       
   167       <label title="<?php echo $lang->get('gorilla_lbl_private_hint'); ?>">
       
   168         <input type="checkbox" name="is_private" id="gorilla_private" <?php if ( $private ) echo 'checked="checked"'; ?> />
       
   169         <img alt="<?php echo $lang->get('gorilla_lbl_private'); ?>" src="<?php echo cdnPath; ?>/images/lock16.png" />
       
   170       </label>
       
   171     </div>
       
   172     
       
   173     <!-- highlighting -->
       
   174     <div style="float: right; margin: 10px;">
       
   175     
       
   176     <?php echo $lang->get('gorilla_lbl_highlight'); ?>
       
   177     <?php if ( $have_geshi ): ?>
       
   178       <select name="highlight" id="gorilla_highlight">
       
   179         <?php
       
   180         // print out options for each GeSHi format
       
   181         global $geshi_supported_formats;
       
   182         $formats = array_merge(array('plaintext'), $geshi_supported_formats);
       
   183         foreach ( $formats as $format )
       
   184         {
       
   185           // $string = str_replace('-', '_', "geshi_lang_$format");
       
   186           // if ( ($_ = $lang->get($string)) !== $string )
       
   187           //   $string = $_;
       
   188           // else
       
   189             $string = $format;
       
   190             
       
   191           $sel = ( $format == $highlight ) ? ' selected="selected"' : '';
       
   192           echo '<option value="' . $format . '"' . $sel . '>' . $string . '</option>' . "\n          ";
       
   193         }
       
   194         ?>
       
   195       </select>
       
   196     <?php else: ?>
       
   197       <span style="color: #808080;"><?php echo $lang->get('gorilla_msg_no_geshi'); ?></span>
       
   198       <input type="hidden" name="highlight_type" id="gorilla_highlight" value="plaintext" />
       
   199     <?php endif; ?>
       
   200                    
       
   201     </div>
       
   202   
       
   203     <!-- text box -->
       
   204     
       
   205     <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>
       
   206     
       
   207     <fieldset enano:expand="closed" style="margin-bottom: 10px;">
       
   208       <legend><?php echo $lang->get('gorilla_btn_advanced_options'); ?></legend>
       
   209       <div>
       
   210       
       
   211       <!-- title -->
       
   212       <p>
       
   213         <?php echo $lang->get('gorilla_lbl_title'); ?>
       
   214         <input type="text" name="title" id="gorilla_title" size="40" value="<?php echo htmlspecialchars($title); ?>" />
       
   215       </p>
       
   216       
       
   217       <!-- nick -->
       
   218       <p>
       
   219         <?php echo $lang->get('gorilla_lbl_nick'); ?>
       
   220         <?php
       
   221         if ( !$have_permission && !$session->user_logged_in )
       
   222         {
       
   223           echo '<em>' . $lang->get('gorilla_msg_using_login_nick') . '</em>';
       
   224           echo '<input type="hidden" name="nick" id="gorilla_nick" value="" />';
       
   225         }
       
   226         else if ( $session->user_logged_in )
       
   227         {
       
   228           $rankinfo = $session->get_user_rank($session->user_id);
       
   229           echo '<em>' . $lang->get('gorilla_msg_using_logged_in_nick') . '</em> ';
       
   230           echo '<span style="' . $rankinfo['rank_style'] . '">' . $session->username . '</span>';
       
   231           echo '<input type="hidden" name="nick" id="gorilla_nick" value="" />';
       
   232         }
       
   233         else
       
   234         {
       
   235           echo '<input type="text" name="nick" id="gorilla_nick" value="' . $lang->get('gorilla_nick_anonymous') . '" />';
       
   236         }
       
   237         ?>
       
   238       </p>
       
   239       
       
   240       <!-- ttl -->
       
   241       <p>
       
   242         <?php echo $lang->get('gorilla_lbl_ttl'); ?>
       
   243         <em>
       
   244         <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>
       
   245         <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>
       
   246         <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>
       
   247         <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>
       
   248         </em>
       
   249       </p>
       
   250       
       
   251       </div>
       
   252     </fieldset>
       
   253   
       
   254     <!-- login notice -->
       
   255   
       
   256     <?php if ( !$have_permission && !$session->user_logged_in ): ?>
       
   257     <div class="info-box-mini">
       
   258       <?php echo $lang->get('gorilla_msg_will_prompt_for_login'); ?>
       
   259     </div>
       
   260     <?php endif; ?>
       
   261     
       
   262     <!-- submit -->
       
   263   
       
   264     <input type="submit" style="font-size: x-large;" value="<?php echo $lang->get('gorilla_btn_submit'); ?>" />
       
   265   </form>
       
   266   <?php
       
   267   
       
   268   $output->footer();
       
   269 }
       
   270 
       
   271 // actual processing for submitted pastes
       
   272 function gorilla_process_post($have_geshi, $have_permission, $is_ajax = false)
       
   273 {
       
   274   global $db, $session, $paths, $template, $plugins; // Common objects
       
   275   global $lang;
       
   276   
       
   277   $fields = array(
       
   278       'highlight' => 'string',
       
   279       'text' => 'string',
       
   280       'is_private' => 'boolean',
       
   281       'nick' => 'string',
       
   282       'title' => 'string',
       
   283       'ttl' => 'integer'
       
   284     );
       
   285   
       
   286   $info = array();
       
   287   
       
   288   if ( $is_ajax )
       
   289   {
       
   290     try
       
   291     {
       
   292       $request = enano_json_decode(@$_POST['r']);
       
   293     }
       
   294     catch ( Exception $e )
       
   295     {
       
   296       return '1;No JSON request given';
       
   297     }
       
   298     foreach ( $fields as $field => $type )
       
   299     {
       
   300       if ( !isset($request[$field]) )
       
   301         return "1;Field \"$field\" not provided";
       
   302       if ( ($ftype = gettype($request[$field])) !== $type )
       
   303         return "1;Field \"$field\": expected $type, got $ftype";
       
   304       
       
   305       $info[$field] = $request[$field];
       
   306     }
       
   307   }
       
   308   else
       
   309   {
       
   310     foreach ( $fields as $field => $type )
       
   311     {
       
   312       if ( !isset($_POST[$field]) && $field != 'is_private' )
       
   313         return '';
       
   314     }
       
   315     $info = array(
       
   316         'highlight' => $_POST['highlight'],
       
   317         'text' => $_POST['text'],
       
   318         'is_private' => isset($_POST['is_private']),
       
   319         'nick' => $_POST['nick'],
       
   320         'title' => $_POST['title'],
       
   321         'ttl' => intval($_POST['ttl'])
       
   322       );
       
   323   }
       
   324   
       
   325   if ( !$have_permission )
       
   326   {
       
   327     return '1;<div class="error-box-mini">' . $lang->get('etc_access_denied') . '</div>';
       
   328   }
       
   329   
       
   330   // validate highlight scheme
       
   331   global $geshi_supported_formats;
       
   332   if ( is_array($geshi_supported_formats) )
       
   333   {
       
   334     if ( !in_array($info['highlight'], $geshi_supported_formats) )
       
   335       $info['highlight'] = 'plaintext';
       
   336   }
       
   337   else
       
   338   {
       
   339     $info['highlight'] = 'plaintext';
       
   340   }
       
   341   
       
   342   setcookie('g_highlight', $info['highlight'], time() + 365 * 24 * 60 * 60);
       
   343   
       
   344   $info_db = $info;
       
   345   foreach ( $info_db as &$item )
       
   346   {
       
   347     if ( is_string($item) )
       
   348       $item = "'" . $db->escape($item) . "'";
       
   349     else if ( is_bool($item) )
       
   350       $item = $item ? '1' : '0';
       
   351     else if ( is_int($item) )
       
   352       $item = strval($item);
       
   353     else
       
   354       $item = "''";
       
   355   }
       
   356   
       
   357   $now = time();
       
   358   $flags = 0;
       
   359   if ( $info['is_private'] )
       
   360     $flags |= PASTE_PRIVATE;
       
   361   
       
   362   $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"
       
   363        . "  ( {$info_db['title']}, {$info_db['text']}, $session->user_id, {$info_db['nick']}, '{$_SERVER['REMOTE_ADDR']}', {$info_db['highlight']}, $now, {$info_db['ttl']}, $flags );";
       
   364        
       
   365   if ( !$db->sql_query($sql) )
       
   366     ( $is_ajax ) ? $db->die_json() : $db->_die();
       
   367   
       
   368   // avoid insert_id
       
   369   $q = $db->sql_query('SELECT paste_id FROM ' . table_prefix . "pastes WHERE paste_timestamp = $now ORDER BY paste_id DESC LIMIT 1;");
       
   370   if ( !$q )
       
   371     ( $is_ajax ) ? $db->die_json() : $db->_die();
       
   372   list($paste_id) = $db->fetchrow_num();
       
   373   $db->free_result();
       
   374   
       
   375   $params = false;
       
   376   if ( $flags & PASTE_PRIVATE )
       
   377     $params = 'hash=' . hmac_sha1($paste_id, sha1($info['text']));
       
   378   
       
   379   $paste_url = makeUrlComplete('Paste', $paste_id, $params, true);
       
   380   
       
   381   return '0;'
       
   382            . '<div class="info-box-mini">' . $lang->get('gorilla_msg_created') . '</div>'
       
   383            . '<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>';
       
   384 }
       
   385 
       
   386 ###############################################################################
       
   387 ## PASTE DISPLAY
       
   388 ###############################################################################
       
   389 
       
   390 class Namespace_Paste extends Namespace_Default
       
   391 {
       
   392   protected $paste_data = false;
       
   393   
       
   394   public function __construct($page_id, $namespace, $revid = 0)
       
   395   {
       
   396     $this->page_id = $page_id;
       
   397     $this->namespace = $namespace;
       
   398     $this->revision_id = 0;
       
   399     
       
   400     $this->build_cdata();
       
   401   }
       
   402   
       
   403   public function build_cdata()
       
   404   {
       
   405     global $db, $session, $paths, $template, $plugins; // Common objects
       
   406     global $lang;
       
   407   
       
   408     $this->exists = false;
       
   409     if ( ctype_digit($this->page_id) )
       
   410     {
       
   411       $q = $db->sql_query('SELECT p.*, u.username FROM ' . table_prefix . "pastes AS p\n"
       
   412                         . "  LEFT JOIN " . table_prefix . "users AS u\n"
       
   413                         . "    ON ( u.user_id = p.paste_author )\n"
       
   414                         . "  WHERE p.paste_id = $this->page_id;");
       
   415       if ( $db->numrows() > 0 )
       
   416       {
       
   417         $this->exists = true;
       
   418         $this->paste_data = $db->fetchrow();
       
   419       }
       
   420       $db->free_result();
       
   421     }
       
   422     if ( $this->exists )
       
   423     {
       
   424       $this->cdata = array(
       
   425         'name' => empty($this->paste_data['paste_title']) ? $lang->get('gorilla_untitled_paste') : $this->paste_data['paste_title'],
       
   426         'urlname' => $this->page_id,
       
   427         'namespace' => $this->namespace,
       
   428         'special' => 0,
       
   429         'visible' => 0,
       
   430         'comments_on' => 1,
       
   431         'protected' => 0,
       
   432         'delvotes' => 0,
       
   433         'delvote_ips' => '',
       
   434         'wiki_mode' => 2,
       
   435         'page_exists' => true,
       
   436         'page_format' => getConfig('default_page_format', 'wikitext')
       
   437       );
       
   438     }
       
   439     else
       
   440     {
       
   441       $this->cdata = array(
       
   442         'name' => $lang->get('gorilla_title_404'),
       
   443         'urlname' => $this->page_id,
       
   444         'namespace' => $this->namespace,
       
   445         'special' => 0,
       
   446         'visible' => 0,
       
   447         'comments_on' => 0,
       
   448         'protected' => 0,
       
   449         'delvotes' => 0,
       
   450         'delvote_ips' => '',
       
   451         'wiki_mode' => 2,
       
   452         'page_exists' => false,
       
   453         'page_format' => getConfig('default_page_format', 'wikitext')
       
   454       );
       
   455     }
       
   456     $this->cdata = Namespace_Default::bake_cdata($this->cdata);
       
   457   }
       
   458   
       
   459   public function send()
       
   460   {
       
   461     global $db, $session, $paths, $template, $plugins; // Common objects
       
   462     global $output, $lang;
       
   463     
       
   464     $plugins->attachHook('page_type_string_set', '$this->namespace_string = $lang->get(\'gorilla_template_ns_string\');');
       
   465     $template->add_header('<style type="text/css">
       
   466       .geshi_highlighted a {
       
   467         background-image: none !important;
       
   468         padding-right: 0 !important;
       
   469       }
       
   470       </style>
       
   471       ');
       
   472     
       
   473     if ( $this->exists )
       
   474     {
       
   475       gorilla_display_paste($this->paste_data);
       
   476     }
       
   477     else
       
   478     {
       
   479       $output->header();
       
   480       $this->error_404();
       
   481       $output->footer();
       
   482     }
       
   483   }
       
   484   
       
   485   public function error_404()
       
   486   {
       
   487     global $lang;
       
   488     echo '<p>' . $lang->get('gorilla_msg_paste_not_found', array('create_link' => makeUrlNS('Special', 'NewPaste'))) . '</p>';
       
   489   }
       
   490 }
       
   491 
       
   492 function gorilla_display_paste($data)
       
   493 {
       
   494   global $db, $session, $paths, $template, $plugins; // Common objects
       
   495   global $lang;
       
   496   global $output;
       
   497   
       
   498   extract($data);
       
   499   $perms = $session->fetch_page_acl($paste_id, 'Paste');
       
   500   
       
   501   if ( isset($_GET['format']) )
       
   502   {
       
   503     switch($_GET['format'])
       
   504     {
       
   505       case 'text':
       
   506       case 'plain':
       
   507         header('Content-type: text/plain');
       
   508         echo $paste_text;
       
   509         return true;
       
   510         break;
       
   511       case 'download':
       
   512         header('Content-type: text/plain');
       
   513         header('Content-disposition: attachment; filename="paste' . $paste_id . '.txt"');
       
   514         header('Content-length: ' . strlen($paste_text));
       
   515         echo $paste_text;
       
   516         return true;
       
   517         break;
       
   518     }
       
   519   }
       
   520   
       
   521   if ( $paste_flags & PASTE_PRIVATE || isset($_GET['delete']) )
       
   522   {
       
   523     if ( @$_GET['hash'] !== hmac_sha1($paste_id, sha1($paste_text)) )
       
   524     {
       
   525       die_friendly($lang->get('etc_access_denied_short'), '<p>' . $lang->get('gorilla_msg_wrong_hash') . '</p>');
       
   526     }
       
   527   }
       
   528   
       
   529   $output->header();
       
   530   
       
   531   $perm = $paste_author == $session->user_id ? 'delete_paste_own' : 'delete_paste_others';
       
   532   if ( isset($_GET['delete']) && !isset($_POST['cancel']) )
       
   533   {
       
   534     if ( isset($_POST['delete_confirm']) )
       
   535     {
       
   536       $q = $db->sql_query('DELETE FROM ' . table_prefix . "pastes WHERE paste_id = $paste_id;");
       
   537       if ( !$q )
       
   538         $db->_die();
       
   539       
       
   540       echo '<p>' . $lang->get('gorilla_msg_paste_deleted') . '</p>';
       
   541     }
       
   542     else
       
   543     {
       
   544       $submit_url = makeUrlNS('Paste', $paste_id, 'delete&hash=' . hmac_sha1($paste_id, sha1($paste_text)), true);
       
   545       ?>
       
   546       <form action="<?php echo $submit_url; ?>" method="post">
       
   547         <p><?php echo $lang->get('gorilla_msg_delete_confirm'); ?></p>
       
   548         <p>
       
   549           <input type="submit" value="<?php echo $lang->get('gorilla_btn_delete_confirm'); ?>" name="delete_confirm" style="font-weight: bold;" />
       
   550           <input type="submit" value="<?php echo $lang->get('etc_cancel'); ?>" name="cancel" />
       
   551         </p>
       
   552       </form>
       
   553       <?php
       
   554     }
       
   555     $output->footer();
       
   556     return true;
       
   557   }
       
   558   
       
   559   if ( $paste_author > 1 )
       
   560   {
       
   561     // logged-in user
       
   562     $rank_info = $session->get_user_rank($paste_author);
       
   563     $user_link = '<a href="' . makeUrlNS('User', $username, false, true) . '" style="' . $rank_info['rank_style'] . '">' . htmlspecialchars($username) . '</a>';
       
   564   }
       
   565   else
       
   566   {
       
   567     // anonymous
       
   568     $user_link = '<b>' . htmlspecialchars($paste_author_name) . '</b>';
       
   569   }
       
   570   $date = enano_date('D, j M Y H:i:s', $paste_timestamp);
       
   571   $pasteinfo = $lang->get('gorilla_msg_paste_info', array('user_link' => $user_link, 'date' => $date));
       
   572   
       
   573   echo '<div class="mdg-infobox" style="margin: 10px 0;">';
       
   574   echo '<div style="float: right;">
       
   575           ' . $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))) . '
       
   576           /
       
   577           <a title="' . $lang->get('gorilla_tip_new_paste') . '" href="' . makeUrlNS('Special', 'NewPaste') . '">' . $lang->get('gorilla_btn_new_paste') . '</a>
       
   578           /
       
   579           <a title="' . $lang->get('gorilla_tip_copy_from_this') . '" href="' . makeUrlNS('Special', 'NewPaste/Copy=' . $paste_id) . '">' . $lang->get('gorilla_btn_copy_from_this') . '</a>';
       
   580           
       
   581   if ( $perms->get_permissions($perm) && $session->user_logged_in )
       
   582   {
       
   583     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>';
       
   584   }
       
   585   if ( $perms->get_permissions('mod_misc') )
       
   586   {
       
   587     echo ' / <span title="' . $lang->get('gorilla_tip_paste_ip') . '">' . $paste_author_ip . '</span>';
       
   588   }
       
   589   
       
   590   echo '</div>';
       
   591   echo $pasteinfo;
       
   592   echo '</div>';
       
   593   
       
   594   if ( preg_match('/^## /m', $paste_text) )
       
   595   {
       
   596     gorilla_show_text_multi($paste_text, $paste_language);
       
   597   }
       
   598   else
       
   599   {
       
   600     gorilla_show_text($paste_text, $paste_language);
       
   601   }
       
   602   
       
   603   $output->footer();
       
   604 }
       
   605 
       
   606 function gorilla_show_text($text, $lang)
       
   607 {
       
   608   $have_geshi = isset($GLOBALS['geshi_supported_formats']);
       
   609   
       
   610   if ( $have_geshi )
       
   611   {
       
   612     if ( $lang == 'plaintext' )
       
   613       $lang = 'text';
       
   614     
       
   615     if ( !defined('GESHI_ROOT') )
       
   616     define('GESHI_ROOT', ENANO_ROOT . '/plugins/geshi/');
       
   617   
       
   618     require_once ( GESHI_ROOT . 'base.php' );
       
   619     
       
   620     $geshi = new GeSHi($text, $lang, null);
       
   621     $geshi->set_header_type(GESHI_HEADER_DIV);
       
   622     $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 2);
       
   623     $geshi->set_overall_class('geshi_highlighted');
       
   624     $parsed = $geshi->parse_code();
       
   625     
       
   626     echo $parsed;
       
   627   }
       
   628   else
       
   629   {
       
   630     echo '<h3>FIXME: WRITE REAL PLAINTEXT FORMATTER</h3>';
       
   631     echo '<pre>' . htmlspecialchars($text) . '</pre>';
       
   632   }
       
   633 }
       
   634 
       
   635 function gorilla_show_text_multi($text, $lang)
       
   636 {
       
   637   $sections = preg_split('/^## .*$/m', $text);
       
   638   $headingcount = preg_match_all('/^## (.+?)(?: \[([a-z_-]+)\])? *$/m', $text, $matches);
       
   639   
       
   640   // if we have one heading less than the number of sections, print the first section
       
   641   while ( count($sections) > $headingcount )
       
   642   {
       
   643     gorilla_show_text(trim($sections[0], "\r\n"), $lang);
       
   644     
       
   645     unset($sections[0]);
       
   646     $sections = array_values($sections);
       
   647   }
       
   648   
       
   649   foreach ( $matches[0] as $i => $_ )
       
   650   {
       
   651     $clang = !empty($matches[2][$i]) ? $matches[2][$i] : $lang;
       
   652     echo '<h2>' . htmlspecialchars(trim($matches[1][$i])) . '</h2>';
       
   653     gorilla_show_text(trim($sections[$i], "\r\n"), $clang);
       
   654   }
       
   655 }
       
   656 
       
   657 // make sure pastes are pruned on a regular basis
       
   658 function gorilla_prune_expired()
       
   659 {
       
   660   global $db, $session, $paths, $template, $plugins; // Common objects
       
   661   
       
   662   $now = time();
       
   663   $q = $db->sql_query('DELETE FROM ' . table_prefix . "pastes WHERE paste_timestamp + paste_ttl < $now AND paste_ttl > 0;");
       
   664 }
       
   665 
       
   666 register_cron_task('gorilla_prune_expired', 1);
       
   667 
       
   668 /**!install dbms="mysql"; **
       
   669 CREATE TABLE {{TABLE_PREFIX}}pastes(
       
   670   paste_id int(18) NOT NULL auto_increment,
       
   671   paste_title text DEFAULT NULL,
       
   672   paste_text text NOT NULL DEFAULT '',
       
   673   paste_author int(12) NOT NULL DEFAULT 1,
       
   674   paste_author_name varchar(255) NOT NULL DEFAULT 'Anonymous',
       
   675   paste_author_ip varchar(39) NOT NULL,
       
   676   paste_language varchar(32) NOT NULL DEFAULT 'plaintext',
       
   677   paste_timestamp int(12) NOT NULL DEFAULT 0,
       
   678   paste_ttl int(12) NOT NULL DEFAULT 86400,
       
   679   paste_flags int(8) NOT NULL DEFAULT 0,
       
   680   PRIMARY KEY ( paste_id )
       
   681 ) ENGINE=`MyISAM` CHARSET=`UTF8` COLLATE=`utf8_bin`;
       
   682 
       
   683 **!*/
       
   684 
       
   685 /**!uninstall **
       
   686 DROP TABLE {{TABLE_PREFIX}}pastes;
       
   687 **!*/
       
   688 
       
   689 /**!language**
       
   690 <code>
       
   691 {
       
   692   eng: {
       
   693     categories: ['meta', 'gorilla'],
       
   694     strings: {
       
   695       meta: {
       
   696         gorilla: 'Gorilla',
       
   697       },
       
   698       gorilla: {
       
   699         acl_delete_paste_own: 'Delete own pastes',
       
   700         acl_delete_paste_others: 'Delete others\' pastes',
       
   701         
       
   702         page_create: 'Create paste',
       
   703         msg_copying_from: 'Copying from <a href="%paste_url%">paste #%paste_id%</a>.',
       
   704         lbl_highlight: 'Language:',
       
   705         msg_no_geshi: 'Not supported',
       
   706         btn_advanced_options: 'Advanced options',
       
   707         lbl_private: 'Private paste',
       
   708         lbl_private_hint: 'Don\'t list this paste or allow it to be included in searches',
       
   709         lbl_title: 'Title:',
       
   710         lbl_nick: 'Nickname:',
       
   711         nick_anonymous: 'Anonymous',
       
   712         msg_using_login_nick: 'Using username provided during login',
       
   713         msg_using_logged_in_nick: 'Logged in; using nickname:',
       
   714         lbl_ttl: 'Keep it for:',
       
   715         lbl_ttl_hour: '1 hour',
       
   716         lbl_ttl_day: '1 day',
       
   717         lbl_ttl_month: '1 month',
       
   718         lbl_ttl_forever: 'forever',
       
   719         msg_will_prompt_for_login: 'You are not logged in. You will be asked to log in when you click the submit button below.',
       
   720         btn_submit: 'Paste it!',
       
   721         
       
   722         msg_created: 'Paste created.',
       
   723         msg_paste_url: 'Share this paste using the following URL:',
       
   724         
       
   725         untitled_paste: 'Untitled paste',
       
   726         title_404: 'Paste not found',
       
   727         msg_paste_not_found: 'This paste cannot be found or has been deleted. <a href="%create_link%">Create a new paste</a>',
       
   728         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.',
       
   729         
       
   730         msg_paste_info: 'By %user_link%, pasted on %date%',
       
   731         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>',
       
   732         btn_new_paste: 'new',
       
   733         tip_new_paste: 'Create a new paste',
       
   734         btn_copy_from_this: 'cp',
       
   735         tip_copy_from_this: 'Create a new paste, copying this one into the form',
       
   736         btn_delete: 'rm',
       
   737         tip_delete: 'Delete this paste',
       
   738         tip_paste_ip: 'IP address of paste author',
       
   739         template_ns_string: 'paste',
       
   740         
       
   741         msg_paste_deleted: 'Paste deleted.',
       
   742         msg_delete_confirm: 'Really delete this paste?',
       
   743         btn_delete_confirm: 'Delete',
       
   744       }
       
   745     }
       
   746   }
       
   747 }
       
   748 </code>
       
   749 **!*/