# HG changeset patch # User Dan # Date 1243666333 14400 # Node ID cac93de16379573a0aa53e39bad9f07edaab1a05 First commit. Works great. TODO: add ability to reply to other pastes and provide some primitive threaded structure. diff -r 000000000000 -r cac93de16379 Gorilla.php --- /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 @@ +GeSHi plugin 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(); + + ?> + +
' . $lang->get('gorilla_msg_paste_not_found', array('create_link' => makeUrlNS('Special', 'NewPaste'))) . '
'; + } +} + +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'), '' . $lang->get('gorilla_msg_wrong_hash') . '
'); + } + } + + $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 '' . $lang->get('gorilla_msg_paste_deleted') . '
'; + } + else + { + $submit_url = makeUrlNS('Paste', $paste_id, 'delete&hash=' . hmac_sha1($paste_id, sha1($paste_text)), true); + ?> + + footer(); + return true; + } + + if ( $paste_author > 1 ) + { + // logged-in user + $rank_info = $session->get_user_rank($paste_author); + $user_link = '' . htmlspecialchars($username) . ''; + } + else + { + // anonymous + $user_link = '' . htmlspecialchars($paste_author_name) . ''; + } + $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 '' . htmlspecialchars($text) . ''; + } +} + +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 '
+{
+ 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 paste #%paste_id%.',
+ 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. Create a new paste',
+ 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: 'raw / dl',
+ 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',
+ }
+ }
+ }
+}
+
+**!*/