Skip to content

Instantly share code, notes, and snippets.

@grappler
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grappler/867ec6f1f207cff5d0ad to your computer and use it in GitHub Desktop.
Save grappler/867ec6f1f207cff5d0ad to your computer and use it in GitHub Desktop.
<?php
class Dotorg_Theme_Review_Assigner {
protected $trac;
function __construct() {
add_action( 'widgets_init', array( $this, 'widgets_init' ) );
add_action( 'init', array( $this, 'shortcode_init' ) );
add_action( 'admin_post_assign_theme_review', array( $this, 'admin_post' ) );
}
function require_trac() {
require_once ABSPATH . WPINC . '/class-IXR.php';
require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
require_once WPORGPATH . 'bb-theme/themes/lib/class-trac.php';
$this->trac = new Trac( 'themetracbot', THEME_TRACBOT_PASSWORD, 'https://themes.trac.wordpress.org/login/xmlrpc' );
}
function widgets_init() {
register_widget( 'Dotorg_Theme_Review_Widget' );
}
function shortcode_init() {
add_shortcode( 'assign-theme-review', array( $this, 'assign_button' ) );
}
function assign_button() {
$action = isset( $_GET['theme-assign'] ) ? $_GET['theme-assign'] : false;
if ( $action && $_GET['now'] < time() - 10 ) {
// If the page was refreshed > 10 seconds later, ignore the action and show the button again.
$action = false;
}
if ( 'existing' === $action ) {
$button = sprintf( '<p><strong>You have reviews <a href="%s">assigned to you</a> that you need to complete first.</strong></p>',
esc_url( 'https://themes.trac.wordpress.org/query?status=!closed&owner=$USER' ) );
} elseif ( 'none' === $action ) {
$button = '<p><strong>There are no themes in the review queue to assign right now. Check back soon.</strong></p>';
} elseif ( 'failed' === $action ) {
$button = '<p><strong>Something went wrong; the system can&#8127;t assign you a review right now.</strong></p>';
} elseif ( is_user_logged_in() ) {
$url = add_query_arg( '_wp_get_referer', $_SERVER['REQUEST_URI'], admin_url( 'admin-post.php?action=assign_theme_review' ) );
$url = wp_nonce_url( $url, 'assign-theme-review' );
$button = sprintf( '<p><form method="post" action="%s"><button>Request a theme to review</button></form></p>', esc_url( $url ) );
} else {
$button = sprintf( '<p>Please <a href="%s">log in</a> first to review.</em></p>', esc_url( wp_login_url( $_SERVER['REQUEST_URI'] ) ) );
}
return $button;
}
function admin_post() {
check_admin_referer( 'assign-theme-review' );
$this->require_trac();
$assignments = $this->get_current_assignments();
if ( is_wp_error( $assignments ) ) {
$result = 'failed';
} elseif ( $assignments ) {
$result = 'existing';
} else {
$ticket = $this->assign_next_theme();
if ( is_wp_error( $ticket ) ) {
$result = 'failed';
} elseif ( $ticket ) {
$result = $ticket;
} else {
$result = 'none';
}
}
if ( is_int( $result ) ) {
wp_redirect( 'https://themes.trac.wordpress.org/ticket/' . $result );
exit;
}
$redirect = add_query_arg( array( 'theme-assign' => $result, 'now' => time() ), wp_get_referer() );
wp_safe_redirect( $redirect );
exit;
}
function get_current_assignments() {
$username = wp_get_current_user()->user_login;
$assigned = $this->trac->ticket_query( sprintf( 'owner=%s&status=reviewing', $username ) );
if ( $assigned ) {
return $assigned;
} elseif ( $assigned === array() ) {
return false;
} else {
// RPC failure condition ($assigned is false here)
return new WP_Error;
}
}
function assign_next_theme() {
$username = wp_get_current_user()->user_login;
$assigned = false;
$i = 0;
do {
if ( ++$i > 10 ) {
// Safeguard.
return new WP_Error;
}
$next_ticket = $this->trac->ticket_query( 'priority=new theme&priority=previously reviewed&status=new&keywords=!~buddypress&order=time&max=1&owner=' );
if ( $next_ticket === array() ) {
return false;
} elseif ( $next_ticket === false ) {
return new WP_Error;
}
$ticket = $this->trac->ticket_get( $next_ticket[0] );
// Avoid race condition: Maybe someone was just assigned this one between query and get.
if ( $ticket['owner'] || $ticket['status'] !== 'new' ) {
continue;
}
// Assign the ticket using the proper workflow actions.
$attributes = array( 'action' => 'review_other', 'action_review_other_reassign_owner' => $username );
// Set _ts (changetime) so the update will fail if the ticket was updated since our fetch.
$attributes['_ts'] = $ticket['_ts'];
// No comment, yes notify. User is 'themetracbot'.
$updated = $this->trac->ticket_update( $ticket['id'], '', $attributes, true );
if ( ! $updated ) {
// Update failed. Try another ticket.
continue;
}
$assigned = (int) $ticket['id'];
} while ( ! $assigned );
return $assigned;
}
}
// Hack so this can sit in a mu-plugin (included before widgets are)
add_action( 'widgets_init', function() {
class Dotorg_Theme_Review_Widget extends WP_Widget_Text {
function __construct() {
$widget_ops = array( 'classname' => 'dotorg_theme_review_widget', 'description' => 'Widget for theme reviewers to self-assign themselves themes.' );
$control_ops = array( 'width' => 400, 'height' => 350 );
WP_Widget::__construct('dotorg_theme_review', __('Theme Review Self-Assign'), $widget_ops, $control_ops );
}
function widget( $args, $instance ) {
ob_start();
echo '<style>
.dotorg_theme_review_widget .textwidget { font-size: 14px; color: #333 }
.dotorg_theme_review_widget .textwidget p { margin: 1em 0; }
.dotorg_theme_review_widget button { font-size: 13px; }
</style>';
$action = isset( $_GET['theme-assign'] ) ? $_GET['theme-assign'] : false;
if ( $action && $_GET['now'] < time() - 10 ) {
// If the page was refreshed > 10 seconds later, ignore the action and show the button again.
$action = false;
}
if ( 'existing' === $action ) {
printf( '<p><strong>You have reviews <a href="%s">assigned to you</a> that you need to complete first.</strong></p>',
esc_url( 'https://themes.trac.wordpress.org/query?status=!closed&owner=$USER' ) );
} elseif ( 'none' === $action ) {
echo '<p><strong>There are no themes in the review queue to assign right now. Check back soon.</strong></p>';
} elseif ( 'failed' === $action ) {
echo '<p><strong>Something went wrong; the system can&#8127;t assign you a review right now.</strong></p>';
} elseif ( is_user_logged_in() ) {
$url = add_query_arg( '_wp_get_referer', $_SERVER['REQUEST_URI'], admin_url( 'admin-post.php?action=assign_theme_review' ) );
$url = wp_nonce_url( $url, 'assign-theme-review' );
printf( '<p><form method="post" action="%s"><button>Request a theme to review</button></form></p>', esc_url( $url ) );
} else {
printf( '<p>Please <a href="%s">log in</a> first to review.</em></p>', esc_url( wp_login_url( $_SERVER['REQUEST_URI'] ) ) );
}
$instance['text'] .= ob_get_clean();
parent::widget( $args, $instance );
}
}
}, 9 );
new Dotorg_Theme_Review_Assigner( $themes_trac );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment