plugin = $plugin; // Heartbeat live update add_filter( 'heartbeat_received', array( $this, 'heartbeat_received' ), 10, 2 ); // Enable / Disable live update per user add_action( 'wp_ajax_stream_enable_live_update', array( $this, 'enable_live_update' ) ); } /** * Ajax function to enable/disable live update * * @return string Ajax respsonse back in JSON format */ public function enable_live_update() { check_ajax_referer( $this->user_meta_key . '_nonce', 'nonce' ); $input = array( 'checked' => FILTER_SANITIZE_STRING, 'user' => FILTER_SANITIZE_STRING, 'heartbeat' => FILTER_SANITIZE_STRING, ); $input = filter_input_array( INPUT_POST, $input ); if ( false === $input ) { wp_send_json_error( 'Error in live update checkbox' ); } $checked = ( 'checked' === $input['checked'] ) ? 'on' : 'off'; $user = (int) $input['user']; if ( 'false' === $input['heartbeat'] ) { $this->plugin->admin->update_user_meta( $user, $this->user_meta_key, 'off' ); wp_send_json_error( esc_html__( "Live updates could not be enabled because Heartbeat is not loaded.\n\nYour hosting provider or another plugin may have disabled it for performance reasons.", 'stream' ) ); return; } $success = $this->plugin->admin->update_user_meta( $user, $this->user_meta_key, $checked ); if ( $success ) { wp_send_json_success( ( 'on' === $checked ) ? 'Live Updates enabled' : 'Live Updates disabled' ); } else { wp_send_json_error( 'Live Updates checkbox error' ); } } /** * Sends updated actions to the list table view * * @todo Fix reliability issues with sidebar widgets * * @uses gather_updated_items * @uses generate_row * * @param array $response Response to heartbeat * @param array $data Data from heartbeat * * @return array Data sent to heartbeat */ public function live_update( $response, $data ) { unset( $response ); if ( ! isset( $data['wp-stream-heartbeat-last-time'] ) ) { return array(); } $last_time = $data['wp-stream-heartbeat-last-time']; $query = $data['wp-stream-heartbeat-query']; if ( empty( $query ) ) { $query = array(); } // Decode the query $query = json_decode( wp_kses_stripslashes( $query ) ); $updated_items = $this->gather_updated_items( $last_time, (array) $query ); if ( ! empty( $updated_items ) ) { ob_start(); foreach ( $updated_items as $item ) { $this->list_table->single_row( $item ); } $send = ob_get_clean(); } else { $send = ''; } return $send; } /** * Sends Updated Actions to the List Table View * * @param int $last_time Timestamp of last update * @param array $args Query args * * @return array Array of recently updated items */ public function gather_updated_items( $last_time, $args = array() ) { unset( $args ); if ( false === $last_time ) { return ''; } if ( empty( $this->list_table->items ) ) { return ''; } $items = array(); foreach ( $this->list_table->items as $item ) { if ( strtotime( $item->created ) > strtotime( $last_time ) ) { $items[] = $item; } else { break; } } return $items; } /** * Handles live updates for Stream Post List * * @action heartbeat_recieved * * @param array $response Response to be sent to heartbeat tick * @param array $data Data from heartbeat send * * @return array Data sent to heartbeat tick */ public function heartbeat_received( $response, $data ) { // Only fire when Stream is requesting a live update if ( ! isset( $data['wp-stream-heartbeat'] ) ) { return $response; } $enable_stream_update = ( 'off' !== $this->plugin->admin->get_user_meta( get_current_user_id(), $this->user_meta_key ) ); // Register list table $this->list_table = new List_Table( $this->plugin, array( 'screen' => 'toplevel_page_' . $this->plugin->admin->records_page_slug ) ); $this->list_table->prepare_items(); $total_items = isset( $this->list_table->_pagination_args['total_items'] ) ? $this->list_table->_pagination_args['total_items'] : null; $total_pages = isset( $this->list_table->_pagination_args['total_pages'] ) ? $this->list_table->_pagination_args['total_pages'] : null; if ( isset( $data['wp-stream-heartbeat'] ) && isset( $total_items ) ) { $response['total_items'] = $total_items; $response['total_items_i18n'] = sprintf( _n( '%d item', '%d items', $total_items ), number_format_i18n( $total_items ) ); } if ( isset( $data['wp-stream-heartbeat'] ) && 'live-update' === $data['wp-stream-heartbeat'] && $enable_stream_update ) { if ( ! empty( $data['wp-stream-heartbeat'] ) ) { if ( isset( $total_pages ) ) { $response['total_pages'] = $total_pages; $response['total_pages_i18n'] = number_format_i18n( $total_pages ); $query_args = json_decode( $data['wp-stream-heartbeat-query'], true ); $query_args['paged'] = $total_pages; $response['last_page_link'] = add_query_arg( $query_args, admin_url( 'admin.php' ) ); } else { $response['total_pages'] = 0; } } $response['wp-stream-heartbeat'] = $this->live_update( $response, $data ); } else { $response['log'] = 'fail'; } return $response; } }