daily pastebin goal
7%
SHARE
TWEET

frooyoyahoocom

a guest Jan 13th, 2010 361 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  /*
  3. Plugin Name: Login-Free Posting
  4. Plugin URI:
  5. Description: Allows bbPress users to post without logging in, much like WordPress comments.
  6. Version: .9
  7. Author: Austin Matzko
  8. Author URI: http://ilfilosofo.com/
  9.  */
  10.  
  11. /*
  12.  * Class for handling posting by non-logged-in users
  13.  */
  14. class LoginLess_Posting
  15. {
  16.         protected $_anon_user_id = 0; // the user ID we're using for the anonymous user in certain situations
  17.         protected $_user_login_base = 'anonymousloginlessuser';
  18.  
  19.         public $allow_new_topics = false; // whether to allow non-logged-in users to post new topics
  20.         public $allow_new_posts = false; // whether to allow non-logged-in users to post new posts
  21.  
  22.         public function __construct()
  23.         {
  24.                 $this->attach_events();
  25.  
  26.                 $this->_anon_user_id = bb_get_option('loginless-anon-id');
  27.         }
  28.  
  29.         /**
  30.          * Check for permission to do things.  The purpose of this method is to centralize permission issues, basically imitating bb_current_user_can() for all but those not logged in.
  31.          * @param string $cap The capability to check for the current user.
  32.          * @param array $args The array of optional arguments to more finely tune the permissions situation.
  33.          * @return bool Whether the current user has the capability.
  34.          */
  35.         private function _current_user_can($cap = '', $args = array())
  36.         {
  37.                 global $bb_current_user;
  38.  
  39.                 $retvalue = false;
  40.  
  41.                 // if a logged-in user, then we'll do what bb_current_user_can() would do
  42.                 if ( ! empty($bb_current_user) ) {
  43.                         $retvalue = call_user_func_array(array(&$bb_current_user, 'has_cap'), array_merge(array($cap), $args));
  44.                 // not logged in, which is what we're interested in
  45.                 } else {
  46.                         // let's whitelist capabilities of an anonymous user
  47.                         switch( $cap ) {
  48.                                 case 'write_post' :
  49.                                 case 'write_posts' :
  50.                                 case 'write_topic' :
  51.                                 case 'write_topics' :
  52.                                         $retvalue = true;
  53.                                         break;
  54.                         }
  55.                 }
  56.  
  57.                 return $retvalue;
  58.         }
  59.  
  60.         /**
  61.          * Extend the bbPress global $wp_users_object so that its user search methods work with non-logged-in posting.
  62.          */
  63.         private function _extend_wp_users_object()
  64.         {
  65.                 global $bbdb, $wp_auth_object, $wp_users_object;
  66.                 $cookies = $wp_auth_object->cookies;
  67.                 $wp_users_object = new LoginLess_WP_Users($bbdb);
  68.                 $wp_users_object->_anon_user_id = $this->_anon_user_id;
  69.                 $wp_auth_object = new LoginLess_WP_Auth( $bbdb, $wp_users_object, $cookies );
  70.                 $GLOBALS['bb_current_user'] =& $wp_auth_object->current;
  71.         }
  72.  
  73.         /**
  74.          * Attach action events and filters.
  75.          */
  76.         public function attach_events()
  77.         {
  78.                 add_action('bb_admin_menu_generator', array(&$this, 'event_bb_admin_menu_generator') );
  79.                 add_action('bb_got_roles', array(&$this, 'event_bb_got_roles'), 5);
  80.                 add_action('bb_new_post', array(&$this, 'event_bb_new_post'));
  81.                 add_action('bb_new_topic', array(&$this, 'event_bb_new_topic'), 99, 3);
  82.                 add_action('get_post_author', array(&$this, 'event_get_post_author'), 99, 2);  
  83.                 add_action('pre_post_form', array(&$this, 'event_pre_post_form'));
  84.                 add_action('post_post_form', array(&$this, 'event_post_post_form'));
  85.                
  86.                 add_filter('bb_current_user_can', array(&$this, 'bb_current_user_can_callback'), 99, 3);
  87.                 add_filter('bb_get_user_email', array(&$this, 'filter_bb_get_user_email'), 99);
  88.                 add_filter('bb_get_user_link', array(&$this, 'filter_bb_get_user_link'), 99);
  89.                 add_filter('get_topic_author', array(&$this, 'filter_get_topic_author'), 99, 2);
  90.                 add_filter('get_topic_last_poster', array(&$this, 'filter_get_topic_last_poster'), 99, 2);
  91.  
  92.                 bb_register_plugin_activation_hook(__FILE__, array(&$this, 'event_plugin_activation'));
  93.         }
  94.  
  95.         /**
  96.          * This method is meant to act as a callback on the bb_current_user_can filter, in order to modify the behavior of bb_current_user_can() to parallel this->_current_user_can.
  97.          * @param bool $return Whether bb_current_user_can() thinks the current user can do the capability.
  98.          * @param string $cap The capability for which we're checking the current user's permissions.
  99.          * @param array $args Additional arguments to pass to the current user object has_cap method.
  100.          * @return bool Whether the user has permission to do something.
  101.          */
  102.         public function bb_current_user_can_callback($return = false, $cap = '', $args = array())
  103.         {
  104.                 // bb_current_user_can is more strict, so if it says a user can do something, we'll believe it
  105.                 if ( true == $return ) {
  106.                         return $return;
  107.                 } else {
  108.                         return $this->_current_user_can($cap, $args);
  109.                 }
  110.         }
  111.  
  112.         /**
  113.          * Generate a nonce, based on the dummy user's ID
  114.          * @param string $action The action for the nonce.
  115.          * @return string The nonce.
  116.          */
  117.         public function get_nonce($action = '')
  118.         {
  119.                 if ( ! bb_is_user_logged_in() ) {
  120.                         $uid = $this->_anon_user_id;   
  121.                         $i = bb_nonce_tick();
  122.                         return substr(bb_hash($i . $action . $uid, 'nonce'), -12, 10);
  123.                 } else {
  124.                         return bb_create_nonce($action);
  125.                 }
  126.         }
  127.  
  128.         /**
  129.          * Callback to set up the admin configuration page.
  130.          */
  131.         public function event_bb_admin_menu_generator()
  132.         {
  133.                 bb_admin_add_submenu(__('Loginless Posting', 'loginless-posting'), 'administrate', 'loginless_posting_options_page', 'options-general.php');
  134.         }
  135.  
  136.         /**
  137.          * Handle events on the get_post_author action hook.
  138.          * @param string $name The username.
  139.          * @param int $user_id The user's id.
  140.          */
  141.         public function event_get_post_author($name = '', $user_id = 0)
  142.         {
  143.                 if ( $this->_anon_user_id == $user_id ) {
  144.                         $post = bb_get_post(get_post_id());
  145.                         $post = bb_append_meta($post, 'post');
  146.  
  147.                         // can't use bb_get_postmeta for now thanks to a bug.  See trac #1077.
  148.                         // $_name = bb_get_postmeta( get_post_id(), '_anon_user_name' );
  149.                         $_name = $post->_anon_user_name;
  150.  
  151.                         if ( ! empty( $_name ) ) {
  152.                                 $name = $_name;
  153.                         }
  154.                 }
  155.                 return $name;  
  156.         }
  157.  
  158.         /**
  159.          * Handle events on the 'bb_got_roles' action hook
  160.          */
  161.         public function event_bb_got_roles()
  162.         {
  163.                 if ( ! bb_is_admin() ) {
  164.                         $this->_extend_wp_users_object();
  165.                 }
  166.         }
  167.        
  168.         /**
  169.          * Callback function for bb_new_post action.
  170.          * @param int $post_id The id of the new post.
  171.          */
  172.         public function event_bb_new_post($post_id = 0)
  173.         {
  174.                 global $bb;
  175.                 $post = bb_get_post( $post_id );
  176.  
  177.                 // if the "author" is the anonymous id, then let's save the name in the post meta
  178.                 if ( $this->_anon_user_id == $post->poster_id ) {
  179.                         $email = wp_specialchars(filter_var($_POST['email'], FILTER_SANITIZE_EMAIL));
  180.                         $name = wp_specialchars(filter_var($_POST['author'], FILTER_SANITIZE_STRING));
  181.                         $url = filter_var($_POST['url'], FILTER_SANITIZE_URL);
  182.  
  183.                         $cookiehash = md5(bb_get_option( 'uri' ));
  184.                         $comment_cookie_lifetime = apply_filters('comment_cookie_lifetime', 30000000);
  185.                         setcookie('comment_author_' . $cookiehash, $name, time() + $comment_cookie_lifetime, $bb->cookiepath, $bb->cookiedomain);
  186.                         setcookie('comment_author_email_' . $cookiehash, $email, time() + $comment_cookie_lifetime, $bb->cookiepath, $bb->cookiedomain);
  187.                         setcookie('comment_author_url_' . $cookiehash, esc_url($url), time() + $comment_cookie_lifetime, $bb->cookiepath, $bb->cookiedomain);
  188.        
  189.                         // associate the user of this post with correct username / email
  190.                         bb_update_postmeta( $post_id, '_anon_user_name', $name );
  191.                         bb_update_postmeta( $post_id, '_anon_user_email', $email );
  192.                         bb_update_postmeta( $post_id, '_anon_user_url', $url );
  193.                 }
  194.         }
  195.  
  196.         /**
  197.          * Callback function for bb_new_topic action.
  198.          * @param int $topic_id The id of the new / updated topic.
  199.          */
  200.         public function event_bb_new_topic($topic_id = 0)
  201.         {
  202.                 $topic = get_topic( $topic_id, false ); // false for no caching
  203.  
  204.                 // if using the anonymous user id, then let's save the name in the meta table
  205.                 if ( $this->_anon_user_id == $topic->topic_poster ) {
  206.                         $email = wp_specialchars(filter_var($_POST['email'], FILTER_SANITIZE_EMAIL));
  207.                         $name = wp_specialchars(filter_var($_POST['author'], FILTER_SANITIZE_STRING));
  208.                        
  209.                         // let's associate that email address with the posted user's name
  210.                         bb_update_topicmeta( $topic_id, '_anon_user_name-' . $email, $name );
  211.                 }
  212.         }
  213.  
  214.         public function event_plugin_activation()
  215.         {
  216.                 // get the anonymous user, if it exists
  217.                 $anon_id = bb_get_option('loginless-anon-id');
  218.                 if ( empty( $anon_id ) ) {
  219.                         $sitename = strtolower( $_SERVER['SERVER_NAME'] );
  220.                         if ( substr( $sitename, 0, 4 ) == 'www.' ) {
  221.                                 $sitename = substr( $sitename, 4 );
  222.                         }
  223.                         $user_id = bb_new_user( $this->_user_login_base, $this->_user_login_base . '@' . $sitename, bb_get_option('url'));     
  224.                         if ( ! is_wp_error($user_id) && ! empty($user_id) ) {
  225.                                 $this->_anon_user_id = intval($user_id);
  226.                                 return bb_update_option('loginless-anon-id', intval($user_id));
  227.                         }
  228.                 }
  229.         }
  230.  
  231.         public function event_pre_post_form()
  232.         {
  233.                 $req = intval(bb_get_option('require_name_email'));
  234.  
  235.                 $cookiehash = md5(bb_get_option( 'uri' ));
  236.                 $comment_author = isset($_COOKIE['comment_author_'.$cookiehash]) ? $_COOKIE['comment_author_'.$cookiehash] : '';
  237.                 $comment_author_email = isset($_COOKIE['comment_author_email_'.$cookiehash]) ? $_COOKIE['comment_author_email_'.$cookiehash] : '';
  238.                 $comment_author_url = isset($_COOKIE['comment_author_url_'.$cookiehash]) ? $_COOKIE['comment_author_url_'.$cookiehash] : '';
  239.  
  240.                 $plugin_options = (array) bb_get_option('loginless_posting_settings');
  241.  
  242.                 ob_start(); // we have to use output buffering to replace the post form nonce. yay!
  243.                 if ( empty( $plugin_options['disable-auto-fields'] ) ) :
  244.                        
  245.                         if ( ! bb_is_user_logged_in() ) {
  246.                         ?>
  247.  
  248.                         <p>
  249.                                 <input type="text" name="author" id="author" value="<?php echo esc_attr($comment_author); ?>" size="22" <?php if ($req) echo "aria-required='true'"; ?> />
  250.                                 <label for="author"><small><?php
  251.                                         printf(
  252.                                                 __('Name %s', 'loginless-posting'),
  253.                                                 ( $req ? '(required)' : '' )
  254.                                         );
  255.                                 ?></small></label>
  256.                         </p>
  257.  
  258.                         <p>
  259.                                 <input type="text" name="email" id="email" value="<?php echo esc_attr($comment_author_email); ?>" size="22" <?php if ($req) echo "aria-required='true'"; ?> />
  260.                                 <label for="email"><small><?php
  261.                                         printf(
  262.                                                 __('Mail (will not be published) %s', 'loginless-posting'),
  263.                                                 ( $req ? '(required)' : '' )
  264.                                         );
  265.                                 ?></small></label>
  266.                         </p>
  267.                        
  268.                                                
  269.                         <?php
  270.                         /*      // don't display the website field for anonymous login's
  271.                         <p>
  272.                                 <input type="text" name="url" id="url" value="<?php echo esc_attr($comment_author_url); ?>" size="22" />
  273.                                 <label for="url"><small><?php _e('Website', 'loginless-posting'); ?></small></label>
  274.                         </p>
  275.                         */
  276.                        
  277.                        
  278.                         }       // endif for the bb_is_user_logged_in
  279.                        
  280.                 endif; // if we haven't disabled automatic name, email, url fields
  281.         }
  282.  
  283.         public function event_post_post_form()
  284.         {
  285.                 $content = ob_get_clean();
  286.                 if ( ! bb_is_user_logged_in() ) {
  287.                         // need to move "<form..>" to the beginning of $content
  288.                         if ( preg_match('#(<form[^>]*>)#s', $content, $matches) ) {
  289.                                 $content = str_replace($matches[0], '', $content);
  290.                                 $content = $matches[0] . "\n" . '<input type="hidden" name="loginless-form-submission" id="loginless-form-submission" value="1" />' . "\n" . $content;
  291.                         }
  292.                         if ( bb_is_topic() ) {
  293.                                 $new_field = $this->get_nonce('create-post_' . get_topic_id());
  294.                         } else {
  295.                                 $new_field = $this->get_nonce('create-topic');
  296.                         }
  297.                         if ( ! empty( $new_field ) ) {
  298.                                 $content = preg_replace('#(_wpnonce[^>]*value=")([^"]*)#', '${1}' . $new_field, $content);
  299.                         }
  300.                 }
  301.                 echo $content;
  302.         }
  303.         /**
  304.          * Callback method on the get_topic_author filter.
  305.          * @param string $name The name
  306.          * @param int $user_id The id of the user.
  307.          * @return string The name of the user.
  308.          */
  309.         public function filter_get_topic_author($name = '', $user_id = 0)
  310.         {
  311.                 if ( $this->_anon_user_id == $user_id ) {
  312.                         $topic = get_topic(get_topic_id());                    
  313.                         $_name = bb_get_topicmeta( $topic->topic_id, '_anon_user_name-' . $topic->topic_poster_name );
  314.                         if ( ! empty( $_name ) ) {
  315.                                 $name = $_name;
  316.                         }
  317.                 }
  318.                 return $name;
  319.         }
  320.  
  321.         /**
  322.          * Callback method on the 'get_topic_last_poster' filter.
  323.          * @param string $name The name.
  324.          * @param int $uesr_id The id of the user.
  325.          * @return string The name of the user.
  326.          */
  327.         public function filter_get_topic_last_poster($name = '', $user_id = 0)
  328.         {
  329.                 if ( $this->_anon_user_id == $user_id ) {
  330.                         $topic = get_topic(get_topic_id());                    
  331.                         $_name = bb_get_postmeta( $topic->topic_last_post_id, '_anon_user_name' );
  332.                         if ( ! empty( $_name ) ) {
  333.                                 $name = $_name;
  334.                         }
  335.                 }
  336.                 return $name;
  337.         }
  338.  
  339.         /**
  340.          * Callback filter for bb_get_user_email
  341.          * @param string $email The email of the user
  342.          * @param int $user_id The id of the user
  343.          * @return string The email of the user.
  344.          */
  345.         public function filter_bb_get_user_email($email = '', $user_id = 0)
  346.         {
  347.                 // let's try to get the posted email
  348.                 $post_id = get_post_id();
  349.                 if ( ! empty( $post_id ) ) {
  350.                         $_email = bb_get_post_meta( '_anon_user_email', $post_id );
  351.                         if ( ! empty( $_email ) ) {
  352.                                 $email = $_email;
  353.                         }
  354.                 }
  355.                 return $email;
  356.         }
  357.  
  358.         /**
  359.          * Callback filter for bb_get_user_link
  360.          * @param string $link The link of the user
  361.          * @param int $user_id The id of the user
  362.          * @return string The link of the user.
  363.          */
  364.         public function filter_bb_get_user_link($link = '', $user_id = 0)
  365.         {
  366.                 // let's try to get the posted link
  367.                 $post_id = get_post_id();
  368.                 if ( ! empty( $post_id ) ) {
  369.                         $_link = bb_get_post_meta( '_anon_user_url', $post_id );
  370.                         if ( ! empty( $_link ) ) {
  371.                                 $link = $_link;
  372.                         }
  373.                 }
  374.                 return $link;
  375.         }
  376.  
  377.         /**
  378.          * Prints the admin options page
  379.          */
  380.         public function print_options_page()
  381.         {
  382.                 $plugin_options = (array) bb_get_option('loginless_posting_settings');
  383.                 if ( ! empty( $_POST['loginless-posting-update'] ) ) {
  384.                         bb_check_admin_referer( 'loginless-posting-update' );
  385.                         $disabled = intval($_POST['disable-auto-fields']);
  386.                         $plugin_options['disable-auto-fields'] = $disabled;
  387.                         if ( bb_update_option('loginless_posting_settings', $plugin_options) ) :
  388.                                 bb_admin_notice(__('Settings updated', 'loginless-posting'));
  389.                         else :
  390.                                 bb_admin_notice(__('Settings not changed', 'loginless-posting'));
  391.                         endif;
  392.                 }
  393.  
  394.                 ?>
  395.                 <h2><?php _e('Loginless Posting Settings', 'loginless-posting'); ?></h2>
  396.                 <?php do_action( 'bb_admin_notices' ); ?>
  397.  
  398.                 <form class="settings" method="post" action="<?php bb_uri( 'bb-admin/admin-base.php', array( 'plugin' => 'loginless_posting_options_page'), BB_URI_CONTEXT_FORM_ACTION + BB_URI_CONTEXT_BB_ADMIN ); ?>">
  399.                         <input type="hidden" name="loginless-posting-update" value="1" />
  400.  
  401.                         <fieldset>
  402.                                 <div id="option-disable-auto-fields">
  403.                                         <div class="label">
  404.                                                 <?php _e('Disable Automatic Form Fields', 'loginless-posting'); ?>
  405.                                         </div>
  406.  
  407.                                         <div class="inputs">
  408.                                                 <label class="checkboxs">
  409.                                                         <?php $disabled_check = ( isset($plugin_options['disable-auto-fields']) && 1 == $plugin_options['disable-auto-fields'] ) ? ' checked="checked"' : '';
  410.                                                         ?>
  411.                                                         <input <?php echo $disabled_check; ?> type="checkbox" value="1" id="disable-auto-fields" name="disable-auto-fields" class="checkbox"/> <?php _e('Don&rsquo;t automatically add the author, email, and URL fields to the post form.  Checking this allows you to use your own markup for those fields in the <code>post-form.php</code> template file.'); ?>
  412.                                                 </label>
  413.                                         </div>
  414.                                 </div>
  415.  
  416.                         </fieldset>
  417.  
  418.                         <fieldset class="submit">
  419.                                 <?php bb_nonce_field( 'loginless-posting-update' ); ?>
  420.                                 <input type="hidden" name="action" value="update-akismet-settings" />
  421.                                 <input class="submit" type="submit" name="submit" value="<?php _e('Save Changes') ?>" />
  422.                         </fieldset>
  423.                 </form>
  424.                 <?php
  425.         }
  426. }
  427.  
  428. class LoginLess_WP_Users extends WP_Users {
  429.         /**
  430.          * Get a user.  Use parent method except for anonymous users.
  431.          * @param mixed $user_id Something identifying the user, such as username or ID, as specified in the $args.
  432.          * @param array $args Arguments
  433.          */
  434.         public function get_user( $user_id = 0, $args = null )
  435.         {
  436.                 // only mess around with this in the situation of a non-logged-in user posting a topic or post
  437.                 if ( ! empty($_POST['loginless-form-submission']) && in_array($user_id, array(0, $this->_anon_user_id)) ) {
  438.                         $email = wp_specialchars($_POST['email']);
  439.                         $name = wp_specialchars($_POST['author']);
  440.                         if ( empty( $email ) || empty( $name ) || ! is_email( $email ) ) {
  441.                                 bb_die( __('Error: please fill the required fields (name, email).') );
  442.                         }
  443.                         $user = parent::get_user($this->_anon_user_id);
  444.                         $user->user_login = $email;
  445.                         return $user;
  446.                 // or if somebody's requesting the anonymous user, let's try getting it by post instead
  447.                 } elseif ( $user_id == $this->_anon_user_id ) {
  448.                         $post_id = get_post_id();
  449.                         if ( ! empty( $post_id ) ) {
  450.                                 $user = parent::get_user($this->_anon_user_id);
  451.                                 $user->user_url = bb_get_post_meta( '_anon_user_url', $post_id );
  452.                                 return $user;
  453.                         }
  454.                 }
  455.                 return parent::get_user($user_id, $args);
  456.         }
  457.        
  458. }
  459.  
  460. class LoginLess_WP_Auth extends WP_Auth {
  461.         public function validate_auth_cookie( $cookie = null, $scheme = 'auth' )
  462.         {
  463.                 // only mess around with this in the situation of a non-logged-in user posting a topic or post
  464.                 if ( ! empty($_POST['loginless-form-submission'])
  465.                         && empty( $cookie )
  466.                         && 'logged_in' == $scheme
  467.                         && ( $_db = loginless_posting_get_backtrace_functions() )
  468.                         && in_array('bb_auth', array_keys($_db) )
  469.                         && false !== strpos($_db['bb_auth']['file'], 'bb-post.php' ) ) {
  470.                                 return true;
  471.                 } else {
  472.                         return parent::validate_auth_cookie($cookie, $scheme);
  473.                 }
  474.         }
  475. }
  476.  
  477. function loginless_posting_get_backtrace_functions()
  478. {
  479.         $_db_funcs = array();
  480.         foreach( (array) debug_backtrace() as $bt ) {
  481.                 if ( ! empty( $bt['function'] ) ) {
  482.                         $_db_funcs[$bt['function']] = $bt;
  483.                 }
  484.         }
  485.         return $_db_funcs;
  486. }
  487.  
  488. $loginless_posting_factory = new LoginLess_Posting;
  489.  
  490. function loginless_posting_options_page()
  491. {
  492.         global $loginless_posting_factory;
  493.         return $loginless_posting_factory->print_options_page();
  494. }
  495. ?>
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top