0 ) { update_user_meta( $user_id, self::META, array( 'id' => (int) $id, 'status' => $status, ) ); } } /** * Show the finished notice once (not on our own page, which shows its own). */ public static function finished_notice() { if ( ! Plugin::user_can() ) { return; } $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; $data = get_user_meta( get_current_user_id(), self::META, true ); if ( ! is_array( $data ) || empty( $data['id'] ) ) { return; } if ( $screen && false !== strpos( (string) $screen->id, Plugin::SLUG ) ) { delete_user_meta( get_current_user_id(), self::META ); return; } delete_user_meta( get_current_user_id(), self::META ); $manifest = Storage::find( (int) $data['id'] ); if ( ! $manifest ) { return; } $page = Plugin::page_url(); if ( 'ready' === $manifest['status'] ) { printf( '

%s %s · %s

', /* translators: %s: backup size */ esc_html( sprintf( __( 'Your database backup is ready (%s).', 'database-export-genie' ), Admin_Page::size( (int) $manifest['zip_bytes'] ) ) ), esc_url( Downloader::url( (int) $manifest['id'] ) ), esc_html__( 'Download', 'database-export-genie' ), esc_url( $page ), esc_html__( 'View backups', 'database-export-genie' ) ); } elseif ( 'failed' === $manifest['status'] ) { printf( '

%s %s %s

', esc_html__( 'Your database backup failed.', 'database-export-genie' ), esc_html( isset( $manifest['error']['message'] ) ? $manifest['error']['message'] : '' ), esc_url( $page ), esc_html__( 'View details', 'database-export-genie' ) ); } } /** * Admin-bar item "DB backup 42%" for the current user's running backup. * * @param \WP_Admin_Bar $bar Admin bar. */ public static function admin_bar( $bar ) { if ( ! is_admin() || ! Plugin::user_can() ) { return; } $job = Job::load(); if ( ! $job || ! $job->is_active() || (int) $job->s['created_by'] !== get_current_user_id() ) { return; } $pct = max( (int) $job->s['percent_shown'], $job->percent() ); $bar->add_node( array( 'id' => 'dbmg-progress', 'title' => '' . esc_html( 'stalled' === $job->s['stage'] ? __( 'DB backup paused', 'database-export-genie' ) /* translators: %d: percent */ : sprintf( __( 'DB backup %d%%', 'database-export-genie' ), $pct ) ) . '', 'href' => Plugin::page_url(), 'meta' => array( 'title' => __( 'Database backup in progress — open Database Backups', 'database-export-genie' ) ), ) ); } /** * While a job runs, every admin page helps it along through Heartbeat (§8.2 C). */ public static function enqueue_assist() { if ( ! Plugin::user_can() ) { return; } $job = Job::load(); if ( ! $job || ! $job->is_active() ) { return; } wp_enqueue_script( 'heartbeat' ); /* translators: %d: percent */ $fmt = esc_js( str_replace( '%%', '%', __( 'DB backup %d%%', 'database-export-genie' ) ) ); wp_add_inline_script( 'heartbeat', "(function(\$){\$(document).on('heartbeat-send',function(e,d){d.dbmg_nudge=1;}).on('heartbeat-tick',function(e,d){if(!d||!d.dbmg)return;var l=document.querySelector('#wp-admin-bar-dbmg-progress .ab-label');if(!l)return;if(d.dbmg.active){l.textContent='{$fmt}'.replace('%d',d.dbmg.percent);}else{l.closest('li').remove();}});})(jQuery);" ); } /** * Heartbeat handler: nudge + report progress. * * @param array $response Response. * @param array $data Data from the browser. * @return array */ public static function heartbeat( $response, $data ) { if ( empty( $data['dbmg_nudge'] ) || ! Plugin::user_can() ) { return $response; } // WordPress checks the heartbeat nonce before this filter runs; checked again here because a nudge can start // work (D75). if ( ! check_ajax_referer( 'heartbeat-nonce', '_nonce', false ) ) { return $response; } Runner::nudge( 'heartbeat' ); $job = Job::load(); $response['dbmg'] = array( 'active' => $job && $job->is_active(), 'percent' => $job ? max( (int) $job->s['percent_shown'], $job->percent() ) : 100, ); return $response; } }