-
-
Save grappler/867ec6f1f207cff5d0ad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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᾿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᾿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