Advertisement
Guest User

frooyoyahoocom

a guest
Jan 13th, 2010
731
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.59 KB | None | 0 0
  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. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement