config = $config; $this->workflow = $workflow; } /** * Register hooks. * * @return void */ public function register_hooks() { add_action( 'admin_bar_menu', array( $this, 'admin_bar' ), 80 ); add_action( 'wp_dashboard_setup', array( $this, 'dashboard_widget' ) ); } /** * The statuses the given user is an approver for (across all workflows). * * @param \WP_User $user User. * @return string[] */ private function statuses_for_user( $user ) { $out = array(); // Someone who may approve on every step sees every approval step. Without // this the queue disagrees with Workflow::allowed_actions(), and an // administrator who can approve is shown nothing to approve. $is_global = $this->workflow->is_global_approver( $user ); foreach ( $this->config->all() as $workflow ) { if ( empty( $workflow['steps'] ) ) { continue; } foreach ( $workflow['steps'] as $step ) { if ( ! isset( $step['approver_roles'], $step['status'] ) ) { continue; } if ( $is_global || array_intersect( (array) $step['approver_roles'], (array) $user->roles ) ) { $out[] = $step['status']; } } } return array_values( array_unique( $out ) ); } /** * Posts awaiting the current user. * * @param int $limit Max items. * @return \WP_Post[] */ public function queue( $limit = 50 ) { $user = wp_get_current_user(); if ( ! $user || ! $user->ID ) { return array(); } $statuses = $this->statuses_for_user( $user ); if ( empty( $statuses ) ) { return array(); } return get_posts( array( 'post_type' => $this->config->managed_post_types(), 'post_status' => $statuses, 'numberposts' => $limit, 'orderby' => 'modified', 'order' => 'ASC', ) ); } /** * Cached count for the current user (short TTL keeps it cheap + fresh enough). * * @return int */ public function count() { $user = wp_get_current_user(); if ( ! $user || ! $user->ID ) { return 0; } $key = 'ostew_qcount_' . $user->ID; $cached = get_transient( $key ); if ( false !== $cached ) { return (int) $cached; } $count = count( $this->queue( 200 ) ); set_transient( $key, $count, 2 * MINUTE_IN_SECONDS ); return $count; } /** * Admin-bar node showing the pending count. * * @param \WP_Admin_Bar $bar Admin bar. * @return void */ public function admin_bar( $bar ) { if ( ! is_user_logged_in() ) { return; } $count = $this->count(); if ( $count < 1 ) { return; } $bar->add_node( array( 'id' => 'ostew-reviews', 'title' => sprintf( /* translators: %d: number of items awaiting review. */ _n( 'Reviews (%d)', 'Reviews (%d)', $count, 'ost-editorial-workflow' ), $count ), 'href' => admin_url( 'index.php#ostew_review_queue' ), 'meta' => array( 'title' => __( 'Items awaiting your review', 'ost-editorial-workflow' ) ), ) ); } /** * Register the dashboard widget. * * @return void */ public function dashboard_widget() { if ( empty( $this->statuses_for_user( wp_get_current_user() ) ) ) { return; } wp_add_dashboard_widget( 'ostew_review_queue', __( 'Awaiting your review', 'ost-editorial-workflow' ), array( $this, 'render_widget' ) ); } /** * Render the dashboard widget contents. * * @return void */ public function render_widget() { $items = $this->queue( 25 ); echo '
' . esc_html__( 'Nothing is waiting on you right now.', 'ost-editorial-workflow' ) . '