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( '

%s

', 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' ); } } }