so1o, mdawaffe and SamBauers' Support Forum plugin. Version: 0.2.1 Author: so1o, mdawaffe, SamBauers, mr_pelle Author URI: http://scr.im/mrpelle */ /** * @license CC-GNU-GPL http://creativecommons.org/licenses/GPL/2.0/ * @license Copyright (C) 2007 Aditya Naik (http://www.adityanaik.com/) * @license Copyright (C) 2007 Sam Bauers (http://unlettered.org/) */ /** * Define constants */ define( 'SUPPORT_FORUMS_ID', 'support-forums' ); define( 'SUPPORT_FORUMS_NAME', 'Support Forums' ); define( 'SUPPORT_FORUMS_ICONS_URI', bb_get_plugin_uri( bb_plugin_basename( __FILE__ ) ) . 'icons/' ); define( 'SUPPORT_FORUMS_ACTIVE_TEMPLATE_IMAGES_URI', bb_get_active_theme_uri() . 'images/' ); define( 'SUPPORT_FORUMS_VIEWS_IGNORE_STICKIES_PRIORITY', false ); // Set this to true to make support views override stickies priority order // Create text domain for translations bb_load_plugin_textdomain( SUPPORT_FORUMS_ID, dirname( __FILE__ ) . '/languages' ); /** * Wrapper class for plugin settings */ class Support_Forums_Settings { /** * List of support forums ids * * @var array */ var $forums; /** * New support topics default status * * @var string */ var $defaultStatus; /** * List of pairs (support statuses, their display statements) * * @var array */ var $statuses; /** * List of enabled support views * * @var array */ var $views; /** * List of enabled icons and their directory (if different from the default one) * * @var array */ var $icons; /** * Whether or not users can set topic support status on creation * * @var boolean **/ var $posterSetable; /** * Whether or not support topic poster can change its status at anytime * * @var boolean */ var $posterChangeable; /** * Class constructor */ function Support_Forums_Settings() { $settings = bb_get_option( 'support_forums_settings' ); // Define support statuses whether or not plugin is enabled $this->statuses = array( 'not_support' => __( 'not a support question', SUPPORT_FORUMS_ID ), 'not_resolved' => __( 'not resolved', SUPPORT_FORUMS_ID ), 'resolved' => __( 'resolved', SUPPORT_FORUMS_ID ) ); if ( !is_array( $settings ) ) { // Plugin is disabled $this->forums = false; } else { // Get plugin settings $this->forums = ( is_array( $settings['forums'] ) ) ? // Get support forums ids list $settings['forums'] : false; $this->defaultStatus = (string) $settings['default_status']; if ( empty( $this->defaultStatus ) ) // Should never happen $this->defaultStatus = 'not_support'; $this->views = ( is_array( $settings['views'] ) ) ? // Get views list $settings['views'] : false; $this->icons = ( is_array( $settings['icons'] ) ) ? // Get icons list and directory $settings['icons'] : false; $this->posterSetable = (bool) $settings['poster_setable']; $this->posterChangeable = (bool) $settings['poster_changeable']; } } /** * Functions */ /** * Whether or not plugin is enabled * * @return boolean */ function isEnabled() { return is_array( $this->forums ); } /** * Whether or not views are enabled * * @return boolean */ function areViewsEnabled() { return is_array( $this->views ); } /** * Whether or not icons are enabled * * @return boolean */ function areIconsEnabled() { return is_array( $this->icons ); } /** * Whether or not users can set topic support status on creation * * @return boolean */ function isStatusSetable() { if ( !$this->isEnabled() ) return false; return $this->posterSetable; } /** * Whether or not current user can change topic support status * * @global $topic * * @uses bb_current_user_can() * @uses bb_get_current_user_info() * @uses apply_filters() * * @return boolean */ function isStatusChangeable() { if ( !$this->isEnabled() ) return false; if ( !is_topic() ) return false; global $topic; if ( bb_current_user_can( 'edit_others_topics', $topic->topic_id ) ) // Super-users override plugin settings return true; if ( $topic->topic_poster != bb_get_current_user_info( 'id' ) ) // Current user is not topic poster return false; if ( !$this->isStatusSetable() ) // We did not want users to set topic support status on creation, neither do we want them to change it afterwards return false; return (bool) apply_filters( 'support_forums_poster_changeable', $this->posterChangeable, $topic->topic_id ); } /** * Return topic support status * * @global $topic * * @return string */ function getTopicStatus() { if ( !$this->isEnabled() ) return; global $topic; if ( !in_array( $topic->forum_id, $this->forums ) ) // Topic parent forum is not a support forum return; return ( !empty( $topic->topic_support_status ) ) ? $topic->topic_support_status : $this->defaultStatus; } /** * Echo support topic additional meta * * @global $topic * * @return void */ function supportTopicMeta() { if ( !$this->isEnabled() ) return; global $topic; if ( $this->areIconsEnabled() ) { // Add closed and sticky statements if icons are enabled $icons_uri = ( array_key_exists( 'dir', $this->icons ) ) ? SUPPORT_FORUMS_ACTIVE_TEMPLATE_IMAGES_URI . $this->icons['dir'] : SUPPORT_FORUMS_ICONS_URI; if ( $topic->topic_sticky && in_array( 'sticky', $this->icons ) ) // Add sticky statement $meta .= sprintf( '
%4$s
%4$s
',
$icons_uri . SUPPORT_FORUMS_ID,
str_replace( '_', '-', $topic_status ),
$this->statuses[$topic_status]
);
}
$statement .= $this->statuses[$topic_status];
echo $statement;
}
/**
* Echo support statuses dropdown menu
*
* @global $topic
*
* @uses get_topic_link()
* @uses bb_nonce_field()
*
* @return void
*/
function statusesDropdown() {
if ( !$this->isEnabled() )
return;
global $topic;
if ( !$topic_status = $this->getTopicStatus() ) // Topic is not a support topic
return;
if ( $this->areIconsEnabled() ) // Add icons, if enabled
if ( in_array( 'status', $this->icons ) ) { // Add status icon if enabled
$icons_uri = ( array_key_exists( 'dir', $this->icons ) ) ? SUPPORT_FORUMS_ACTIVE_TEMPLATE_IMAGES_URI . $this->icons['dir'] : SUPPORT_FORUMS_ICONS_URI;
$menu .= sprintf(
'
',
$icons_uri . SUPPORT_FORUMS_ID,
str_replace( '_', '-', $topic_status ),
$this->statuses[$topic_status]
);
}
$menu .= '' . "\n";
// Echo new $menu
echo $menu;
}
/**
* Process support statuses dropdown menu
*
* @global $topic
*
* @uses bb_check_admin_referer()
* @uses remove_query_arg()
* @uses add_query_arg()
* @uses bb_safe_redirect()
*
* @return void
*/
function statusesDropdownProcess() {
if ( !$this->isEnabled() )
return;
if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && !empty( $_POST['action'] ) && 'update-support-forums-topic-status' == $_POST['action'] && is_topic() ) {
global $topic;
bb_verify_nonce( 'support-forums-update-status-topic-' . $topic->topic_id );
$goback = remove_query_arg( array( 'message' ), wp_get_referer() );
if ( $this->isStatusChangeable() && !empty( $_POST['support_forums_statuses_dropdown'] ) )
$goback = ( $this->setTopicStatus( $topic->topic_id, $_POST['support_forums_statuses_dropdown'] ) ) ?
add_query_arg( 'message', 'support-forums-topic-status-updated', $goback ) :
add_query_arg( 'message', 'update-support-forums-topic-status-error', $goback );
bb_safe_redirect( $goback );
exit;
}
}
/**
* Add jQuery library to page head, if not yet included
*
* @uses is_front()
* @uses is_bb_tag()
* @uses wp_script_is()
* @uses wp_enqueue_script()
*
* @return void
*/
function addJQuery() {
if ( !$this->isEnabled() )
return;
if ( $this->isStatusSetable() && ( ( is_front() && !empty( $_GET['new'] ) ) || is_bb_tag() ) ) { // Script is necessary only when users can select topic destination forum
if ( wp_script_is( 'jquery' ) ) // Nothing to do, since jQuery is already included in page head
return;
wp_enqueue_script( 'jquery' );
}
}
/**
* Echo a jQuery script for support statuses dropdown menu visibility
*
* Call jQuery using a special handler to avoid namespace difficulties
*
* @link http://api.jquery.com/ready/ - "Aliasing the jQuery Namespace"
*
* @uses is_front()
* @uses is_bb_tag()
*
* @return void
*/
function newTopicStatusesDropdownJQuery() {
if ( !$this->isEnabled() )
return;
if ( $this->isStatusSetable() && ( ( is_front() && !empty( $_GET['new'] ) ) || is_bb_tag() ) ) { // Script is necessary only when user can select topic destination forum
$script = <<'; $menu .= sprintf( '
' . "\n"; echo $menu; } } } /** * Process new topic support statuses dropdown menu * * @param int $post_id Post id * * @uses bb_get_post() * * @return boolean */ function newTopicStatusesDropdownProcess( $post_id ) { if ( !$this->isEnabled() ) return false; if ( $this->isStatusSetable() && !empty( $_POST['support_status'] ) ) { $topic_id = bb_get_post( $post_id )->topic_id; return $this->setTopicStatus( $topic_id, $_POST['support_status'] ); } } /** * Whether or not topic support status change was successful * * @param int $topic_id Support topic id * @param string $status Topic new support status * * @uses apply_filters() * @uses bb_update_topicmeta() * * @return boolean */ function setTopicStatus( $topic_id = 0, $status ) { if ( !$this->isEnabled() ) return false; if ( empty( $topic_id ) ) return false; // Apply filters, if any $status = apply_filters( 'support_forums_set_topic_status', $status, $topic_id ); if ( !array_key_exists( $status, $this->statuses ) ) return false; return bb_update_topicmeta( $topic_id, 'topic_support_status', $status ); } /** * Whether or not views register was successful * * @uses bb_register_view() * * @return boolean */ function registerSupportViews() { if ( !$this->isEnabled() ) return false; if ( !$this->areViewsEnabled() ) return false; // Temporary var for error reporting $processing_error = false; foreach ( $this->views as $view ) { $additional_meta_value = ( $this->defaultStatus == $view ) ? // Default support status view ',NULL' : // Include topics with no Support Forums meta key set. No space between the comma and NULL! ''; $query = array( 'sticky' => ( (bool) SUPPORT_FORUMS_VIEWS_IGNORE_STICKIES_PRIORITY ) ? 'all' : NULL, 'meta_key' => 'topic_support_status', 'meta_value'=> $view . $additional_meta_value, 'forum_id' => join( ',', $this->forums ) // View must include support forums only ); $title = __( 'Support topics that are %s', SUPPORT_FORUMS_ID ); if ( 'not_resolved' == $view ) { // Filter not resolved support topics by age $delay = 7200; // Minimum support topic age (in seconds) $query['started'] = '<' . gmdate( 'YmdH', time() - $delay ); $title .= sprintf( __( ', at least %d hours old', SUPPORT_FORUMS_ID ), $delay / 3600 ); } // A view registration error turns $processing_error true $processing_error = ( $processing_error || !(bool) bb_register_view( 'support-forums-' . str_replace( '_', '-', $view ), sprintf( $title, $this->statuses[$view] ), $query ) ); } return !$processing_error; } /** * Prepend support, sticky and closed icons or statements to all topics labels * * @param string $label Topic current label * * @global $topic * * @return string */ function modifyTopicLabel( $label ) { if ( !$this->isEnabled() ) return $label; if ( !$this->areIconsEnabled() ) // Icons are disabled return $label; global $topic; $icons_uri = ( array_key_exists( 'dir', $this->icons ) ) ? SUPPORT_FORUMS_ACTIVE_TEMPLATE_IMAGES_URI . $this->icons['dir'] : SUPPORT_FORUMS_ICONS_URI; // Prepend labels in reverse order if ( $topic_status = $this->getTopicStatus() ) // Topic is a support topic $label = ( in_array( 'status', $this->icons ) ) ? // Support icons are enabled sprintf( '
',
$icons_uri . SUPPORT_FORUMS_ID,
str_replace( '_', '-', $topic_status ),
$this->statuses[$topic_status]
) . $label :
'[' . $this->statuses[$topic_status] . '] ' . $label;
if ( !$topic->topic_open ) // Topic is closed
$label = ( in_array( 'closed', $this->icons ) ) ? // Closed icon is enabled
sprintf(
'
',
$icons_uri . SUPPORT_FORUMS_ID,
'closed',
__( 'closed', SUPPORT_FORUMS_ID )
) . $label :
'[' . __( 'closed', SUPPORT_FORUMS_ID ) . '] ' . $label;
if ( $topic->topic_sticky ) // Topic is sticky
$label = ( in_array( 'sticky', $this->icons ) ) ? // Sticky icon is enabled
sprintf(
'
',
$icons_uri . SUPPORT_FORUMS_ID,
'sticky',
__( 'sticky', SUPPORT_FORUMS_ID )
) . $label :
'[' . __( 'sticky', SUPPORT_FORUMS_ID ) . '] ' . $label;
return $label;
}
/**
* Add a class to support topics
*
* @param array $class Topic current classes list
*
* @global $topic
*
* @return array
*/
function addSupportTopicClass( $class ) {
if ( !$this->isEnabled() )
return $class;
global $topic;
if ( in_array( $topic->forum_id, $this->forums ) && !empty( $topic->topic_support_status ) && $this->defaultStatus != $topic->topic_support_status ) // Do not add default support status class to topics
$class[] = $topic->topic_support_status;
return $class;
}
}
// Initialize the class
$support_forums_settings = new Support_Forums_Settings();
if ( bb_is_admin() ) // Load admin.php if on admin area
require_once( 'includes/admin.php' );
if ( $support_forums_settings->isEnabled() ) { // Load plugin core if plugin is enabled
// Add plugin actions
add_action( 'topicmeta', array( $support_forums_settings, 'supportTopicMeta' ) ); // This function includes statusesDropdown()
add_action( 'bb_topic.php_pre_db', array( $support_forums_settings, 'statusesDropdownProcess' ) );
if ( $support_forums_settings->isStatusSetable() ) { // Add new topics support statuses dropdown menu &co. if status is setable
add_action( 'bb_init', array( $support_forums_settings, 'addJQuery' ) );
add_action( 'bb_head', array( $support_forums_settings, 'newTopicStatusesDropdownJQuery' ), 100 );
add_action( 'post_form_pre_post', array( $support_forums_settings, 'newTopicStatusesDropdown' ) );
add_action( 'bb-post.php', array( $support_forums_settings, 'newTopicStatusesDropdownProcess' ) );
}
if ( $support_forums_settings->areViewsEnabled() ) // Add views registration if views are enabled
add_action( 'bb_init', array( $support_forums_settings, 'registerSupportViews' ) );
if ( $support_forums_settings->areIconsEnabled() ) { // Add icons filters if icons are enabled
// Remove closed and sticky topic label filters
remove_filter( 'bb_topic_labels', 'bb_closed_label', 10 );
remove_filter( 'bb_topic_labels', 'bb_sticky_label', 20 );
add_filter( 'bb_topic_labels', array( $support_forums_settings, 'modifyTopicLabel' ), 30, 1 );
}
// Add plugin filters
add_filter( 'topic_class', array( $support_forums_settings, 'addSupportTopicClass' ), 10, 1 );
}