gocodebox/lifterlms

View on GitHub
includes/admin/post-types/post-tables/class.llms.admin.post.table.instructors.php

Summary

Maintainability
A
2 hrs
Test Coverage
F
0%
<?php
/**
 * Post table stuff for courses and memberships who have custom "instructor" stuff * which replaces "Author"
 *
 * @package LifterLMS/Admin/PostTypes/PostTables/Classes
 *
 * @since 3.13.0
 * @version 5.9.0
 */

defined( 'ABSPATH' ) || exit;
/**
 * LLMS_Admin_Post_Table_Instructors class
 *
 * @since 3.13.0
 * @since 3.35.0 Verify nonces and sanitize `$_POST` data.
 */
class LLMS_Admin_Post_Table_Instructors {

    private $post_types = array(
        'course',
        'llms_membership',
    );

    /**
     * Constructor
     *
     * @return  void
     * @since    3.3.0
     * @version  3.13.0
     */
    public function __construct() {

        foreach ( $this->post_types as $post_type ) {
            add_filter( 'manage_' . $post_type . '_posts_columns', array( $this, 'add_columns' ), 10, 1 );
            add_action( 'manage_' . $post_type . '_posts_custom_column', array( $this, 'manage_columns' ), 10, 2 );
            add_filter( 'views_edit-' . $post_type, array( $this, 'get_views' ), 777, 1 );
        }

        add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );

    }

    /**
     * Add Custom Columns
     *
     * @param    array $columns array of default columns
     * @return   array
     * @since    3.13.0
     * @version  3.13.0
     */
    public function add_columns( $columns ) {

        $offset = array_search( 'title', array_keys( $columns ) );

        $add = array(
            'llms-instructors' => __( 'Instructors', 'lifterlms' ),
        );

        return array_slice( $columns, 0, $offset + 1 ) + $add + array_slice( $columns, $offset );

    }

    /**
     * Create a string that can be used in a LIKE query for finding a student's id in the llms_instructors
     * meta field on the usermeta table
     *
     * @param    int $user_id  WP User ID
     * @return   string
     * @since    3.13.0
     * @version  3.13.0
     */
    private function get_serialized_id( $user_id ) {
        $val = serialize(
            array(
                'id' => absint( $user_id ),
            )
        );
        return str_replace( array( 'a:1:{', '}' ), '', $val );
    }

    /**
     * Ensure that the "Mine" view quick link at the top of the table displays the correct number
     * Most of this is based on WordPress core functions found in wp-admin/includes/class-wp-posts-list-table.php
     *
     * @since 3.13.0
     * @since 3.24.0 Unknown.
     * @since 3.35.0 Verify nonces and sanitize `$_POST` data.
     * @since 4.5.1 Use `$_GET` data instead of `$_POST`.
     * @since 5.9.0 Stop using deprecated `FILTER_SANITIZE_STRING`.
     *
     * @param    array $views  array of view link HTML string
     * @return   array
     */
    public function get_views( $views ) {

        $post_type       = llms_filter_input_sanitize_string( INPUT_GET, 'post_type' );
        $current_user_id = get_current_user_id();
        $exclude_states  = get_post_stati(
            array(
                'show_in_admin_all_list' => false,
            )
        );

        global $wpdb;

        // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Statuses are sanitized.

        $count = intval(
            $wpdb->get_var(
                $wpdb->prepare(
                    "
            SELECT COUNT( 1 )
            FROM $wpdb->posts AS p
            JOIN $wpdb->postmeta AS m
              ON p.ID = m.post_id
             AND m.meta_key = '_llms_instructors'
             AND m.meta_value LIKE %s
            WHERE p.post_type = %s
              AND p.post_status NOT IN ( '" . implode( "','", $exclude_states ) . "' )
        ",
                    '%' . $this->get_serialized_id( $current_user_id ) . '%',
                    $post_type
                )
            )
        );

        // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared

        $label = sprintf(
            _nx(
                'Mine <span class="count">(%s)</span>',
                'Mine <span class="count">(%s)</span>',
                $count,
                'posts',
                'lifterlms'
            ),
            number_format_i18n( $count )
        );

        $url = add_query_arg(
            array(
                'post_type' => $post_type,
                'author'    => $current_user_id,
            ),
            'edit.php'
        );

        $class = '';
        if ( isset( $_GET['author'] ) && ( $_GET['author'] == $current_user_id ) ) {
            $class = 'class="current"';
        }

        /**
         * If mine doesn't already exist in views, we need to add it after "All" manually
         * to preserve the user experience.
         */
        if ( ! isset( $views['mine'] ) ) {

            $offset = array_search( 'all', array_keys( $views ) );
            $add    = array(
                'mine' => '',
            );
            $views  = array_slice( $views, 0, $offset + 1 ) + $add + array_slice( $views, $offset + 1 );

        }

        $views['mine'] = sprintf( '<a href="%1$s"%2$s>%3$s</a>', esc_url( $url ), $class, $label );

        return $views;
    }

    /**
     * Manage content of custom columns
     *
     * @param    string $column   column key/name
     * @param    int    $post_id  WP Post ID of the coupon for the row
     * @return   void
     * @since    3.13.0
     * @version  3.23.0
     */
    public function manage_columns( $column, $post_id ) {

        $post = llms_get_post( $post_id );

        switch ( $column ) {

            case 'llms-instructors':
                $instructors = $post->get_instructors();
                $htmls       = array();
                foreach ( $instructors as $user ) {

                    $url = add_query_arg(
                        array(
                            'post_type' => $post->get( 'type' ),
                            'author'    => $user['id'],
                        ),
                        'edit.php'
                    );

                    $instructor = llms_get_instructor( $user['id'] );

                    if ( $instructor ) {
                        $htmls[] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $url ), $instructor->get( 'display_name' ) );
                    }
                }
                echo implode( ', ', $htmls );
                break;

        }

    }

    /**
     * Handle course & membership queries for searching by llms_instructors rather than author
     *
     * @param    obj $query  WP_Query
     * @return   void
     * @since    3.13.0
     * @version  3.13.0
     */
    public function pre_get_posts( $query ) {

        if ( ! is_admin() ) {
            return;
        }

        if ( ! $query->is_main_query() ) {
            return;
        }

        // Don't run duplicates.
        if ( $query->get( 'llms_instructor_query' ) ) {
            return;
        }
        // phpcs:ignore -- commented out code
        // var_dump( $query->query_vars );

        if ( isset( $query->query_vars['post_type'] ) && in_array( $query->query_vars['post_type'], $this->post_types ) && ! empty( $query->query_vars['author'] ) ) {

            // Get the query or a default to work with.
            $meta_query = $query->get( 'meta_query' );
            if ( ! $meta_query ) {
                $meta_query = array();
            }

            /**
             * Set an and relation for our filters
             * if other filters already exist, we'll ensure we obey them as well this way.
             */
            $meta_query['relation'] = 'AND';

            $meta_query[] = array(
                'compare' => 'LIKE',
                'key'     => '_llms_instructors',
                'value'   => $this->get_serialized_id( $query->query_vars['author'] ),
            );

            $query->set( 'meta_query', $meta_query );

            $query->set( 'llms_instructor_query', true );

            $query->set( 'author', '' );

        }

    }

}

return new LLMS_Admin_Post_Table_Instructors();