admin_url( 'admin-ajax.php' ),
'working' => __( 'Refreshing...', 'yopingme' ),
)
);
}
/**
* Register the widget for administrators only.
*/
public static function register() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
wp_add_dashboard_widget( 'yopingme_dashboard', __( 'YoPingMe Uptime', 'yopingme' ), array( __CLASS__, 'render' ) );
}
/**
* Render the widget body.
*/
public static function render() {
echo '
';
self::render_body( Yopingme_Cache::get_monitors() );
echo '
';
}
/**
* Forced refresh from the widget's own link.
*/
public static function handle_refresh() {
check_ajax_referer( 'yopingme_refresh' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( array( 'message' => __( 'You are not allowed to do that.', 'yopingme' ) ), 403 );
}
ob_start();
self::render_body( Yopingme_Cache::get_monitors( true ) );
wp_send_json_success( array( 'html' => ob_get_clean() ) );
}
/**
* Everything inside the widget container.
*
* @param array $state Result from Yopingme_Cache::get_monitors().
*/
private static function render_body( $state ) {
$error = $state['error'];
if ( $error && 'no_key' === $error['code'] ) {
self::render_setup_prompt();
return;
}
if ( $error ) {
self::render_error_notice( $error, $state );
}
// This widget is about this site, not the whole account. Everything
// else on the account belongs in YoPingMe itself, and a WordPress
// admin has no reason to see the other properties here.
$monitor = Yopingme_Cache::monitor_for( $state, home_url( '/' ) );
if ( $monitor ) {
self::render_site( $monitor );
} elseif ( ! $error ) {
self::render_unwatched();
}
self::render_footer( $state );
}
/**
* This site's own status.
*
* @param array $monitor The monitor watching this site.
*/
private static function render_site( $monitor ) {
$paused = ! empty( $monitor['paused'] );
$status = $paused ? 'paused' : ( isset( $monitor['current_status'] ) ? (string) $monitor['current_status'] : 'unknown' );
?>
—
" plus the refresh link.
*
* @param array $state Cache state.
*/
private static function render_footer( $state ) {
echo '';
if ( $state['fetched_at'] ) {
printf(
/* translators: %s: local date and time the data was fetched. */
esc_html__( 'As of %s.', 'yopingme' ),
esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $state['fetched_at'] ) )
);
echo ' ';
}
if ( ! empty( $state['throttled'] ) ) {
echo esc_html__( 'Just refreshed.', 'yopingme' ) . ' ';
}
printf(
'%s',
esc_attr( wp_create_nonce( 'yopingme_refresh' ) ),
esc_html__( 'Refresh', 'yopingme' )
);
echo '
';
}
/**
* Error banner. Sits above stale data when there is any.
*
* @param array $error Error array.
* @param array $state Cache state.
*/
private static function render_error_notice( $error, $state ) {
$message = self::error_message( $error );
if ( $state['data'] && ! empty( $state['data']['monitors'] ) && $state['fetched_at'] ) {
$message .= ' ' . esc_html__( 'Showing the last data we have.', 'yopingme' );
}
printf(
'',
wp_kses( $message, array( 'a' => array( 'href' => array() ) ) )
);
}
/**
* Human-readable text for an error, shared with the settings page.
*
* @param array $error Error array.
* @return string HTML-escaped, may contain a link.
*/
public static function error_message( $error ) {
$code = isset( $error['code'] ) ? (string) $error['code'] : '';
switch ( $code ) {
case 'no_key':
return esc_html__( 'No API key is configured.', 'yopingme' );
case 'auth':
return sprintf(
/* translators: %s: link to the plugin settings page. */
esc_html__( 'YoPingMe did not accept the API key. It may have been revoked. %s', 'yopingme' ),
'' . esc_html__( 'Check the key', 'yopingme' ) . ''
);
case 'rate_limited':
if ( ! empty( $error['resets_at'] ) ) {
$resets = strtotime( $error['resets_at'] );
if ( $resets ) {
return sprintf(
/* translators: %s: local date and time the daily quota resets. */
esc_html__( 'Daily query limit reached. Fresh data resumes after %s.', 'yopingme' ),
esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $resets ) )
);
}
}
return esc_html__( 'Daily query limit reached. Fresh data resumes tomorrow.', 'yopingme' );
case 'plan_limited':
return esc_html__( 'Your plan does not cover that request.', 'yopingme' );
case 'network':
return esc_html__( 'Could not reach YoPingMe.', 'yopingme' );
default:
if ( 0 === strpos( $code, 'http_' ) ) {
return esc_html__( 'YoPingMe returned an error.', 'yopingme' );
}
return ! empty( $error['message'] )
? esc_html( $error['message'] )
: esc_html__( 'Something went wrong talking to YoPingMe.', 'yopingme' );
}
}
/**
* @param float|null $pct Uptime percentage, 0-100.
* @return string
*/
public static function format_pct( $pct ) {
if ( null === $pct || '' === $pct ) {
return __( 'n/a', 'yopingme' );
}
return number_format_i18n( (float) $pct, 2 ) . '%';
}
/**
* @param string $status Monitor status.
* @return string
*/
public static function status_color( $status ) {
switch ( $status ) {
case 'up':
return '#00a32a';
case 'down':
return '#d63638';
case 'confirming':
return '#dba617';
default:
return '#8c8f94';
}
}
/**
* @param string $status Monitor status.
* @return string
*/
public static function status_label( $status ) {
switch ( $status ) {
case 'up':
return __( 'Up', 'yopingme' );
case 'down':
return __( 'Down', 'yopingme' );
case 'confirming':
return __( 'Confirming', 'yopingme' );
case 'paused':
return __( 'Paused', 'yopingme' );
default:
return __( 'Unknown', 'yopingme' );
}
}
}