<?php
/*!
 * Provides the functionality for displaying authors in an admin table in WordPress.
 *
 * This file defines the logic for listing authors in a WordPress-like admin table, including the fallback mechanism for
 * ensuring compatibility with WordPress core's WP_List_Table class.
 *
 * @author     Molongui
 * @package    Authorship
 * @subpackage includes/admin
 * @since      4.5.0
 */

namespace Molongui\Authorship\Admin;

use Molongui\Authorship\Author;
use Molongui\Authorship\Authors;
use Molongui\Authorship\Common\Utils\Debug;
use Molongui\Authorship\Settings;
use Molongui\Authorship\Social;

defined( 'ABSPATH' ) or exit; // Exit if accessed directly
if ( class_exists( \Molongui\Authorship\Common\Libraries\WP_List_Table::class ) )
{
    class Base_Author_List_Table extends \Molongui\Authorship\Common\Libraries\WP_List_Table {};
}
else
{
    if ( !class_exists( \WP_List_Table::class ) )
    {
        require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
    }
    class Base_Author_List_Table extends \WP_List_Table {};
}
class Author_List_Table extends Base_Author_List_Table
{
    protected function extra_tablenav( $which )
    {
        if ( 'top' === $which )
        {
            ?><div class="alignleft actions"><?php

                if ( current_user_can( 'list_users' ) )
                {
                    ?><a href="users.php" class="button"><?php _e( "Edit Users", 'molongui-authorship' ); ?></a>&ensp;<?php
                }
                if ( Settings::get( 'guest_author_enabled', true ) and current_user_can( 'edit_posts' ) )
                {
                    ?><a href="<?php echo admin_url( 'edit.php?post_type=guest_author' ); ?>" class="button"><?php _e( "Edit Guests", 'molongui-authorship' ); ?></a>&ensp;<?php
                }
            ?></div><?php
            ?><div class="alignleft actions">

            <?php $type = isset( $_GET['type'] ) ? sanitize_text_field( $_GET['type'] ) : 'all'; ?>
            <label class="screen-reader-text" for="filter-by-type"><?php _ex( "Filter authors by type", 'Screen reader hint', 'molongui-authorship' ); ?></label>
            <select name="type" id="filter-by-type">
                <option value="all" <?php selected( $type, 'all' ); ?>><?php _ex( "All types", 'Filter option', 'molongui-authorship' ); ?></option>
                <option value="users" <?php selected( $type, 'users' ); ?>><?php _ex( "Registered WP User", 'Filter option', 'molongui-authorship' ); ?></option>
                <option value="guests" <?php selected( $type, 'guests' ); ?>><?php _ex( "Guest Author", 'Filter option', 'molongui-authorship' ); ?></option>
            </select>

            <?php $role = isset( $_GET['role'] ) ? sanitize_text_field( $_GET['role'] ) : 'all'; ?>
            <label class="screen-reader-text" for="filter-by-role"><?php _ex( "Filter authors by role", 'Screen reader hint', 'molongui-authorship' ); ?></label>
            <select name="role" id="filter-by-role">
                <option value="all" <?php selected( $role, 'all' ); ?>><?php _ex( "All roles", 'Filter option', 'molongui-authorship' ); ?></option>
                <?php wp_dropdown_roles( $role ); ?>
                <option value="guest"><?php _ex( "Guest Author", 'Filter option', 'molongui-authorship' ); ?></option>
            </select>

            <?php submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );

            ?></div><?php
        }
    }
    public function get_columns()
    {
        $table_columns = array
        (
            'avatar'          => _x( "Avatar", 'column name', 'molongui-authorship' ),
            'name'            => _x( "Display Name", 'column name', 'molongui-authorship' ),
            'type'            => _x( "Type", 'column name', 'molongui-authorship' ),
            'user_roles'      => _x( "Roles", 'column name', 'molongui-authorship' ),
            'post_count'      => _x( "Entries", 'column name', 'molongui-authorship' ),
            'email'           => _x( "Email", 'column name', 'molongui-authorship' ),
            'description'     => _x( "Bio", 'column name', 'molongui-authorship' ),
            'social_profiles' => _x( "Social", 'column name', 'molongui-authorship' ),
            'box'             => _x( "Author Box", 'column name', 'molongui-authorship' ),
            'archived'        => '<span class="dashicons dashicons-archive"></span>',
            'id'              => __( "ID", 'molongui-authorship' ),
        );
        if ( !Settings::is_enabled( 'author-box' ) )
        {
            unset( $table_columns['box'] );
        }
        if ( !Settings::get( 'social_profiles_enabled' ) )
        {
            unset( $table_columns['social_profiles'] );
        }

        return $table_columns;
    }
    public function get_sortable_columns()
    {
        return array
        (
            'name'       => array( 'name', false ),
            'type'       => array( 'type', false ),
            'user_roles' => array( 'user_roles', false ),
            'post_count' => array( 'post_count', false ),
            'email'      => array( 'email', false ),
            'id'         => array( 'id', false ),
        );
    }
    public function prepare_items()
    {
        $columns               = $this->get_columns();
        $sortable              = $this->get_sortable_columns();
        $hidden                = array();
        $primary               = 'name';
        $this->_column_headers = array( $columns, $hidden, $sortable, $primary );

        $orderby = ( isset( $_GET['orderby'] ) ) ? esc_sql( $_GET['orderby'] ) : 'name';
        $order   = ( isset( $_GET['order'] ) )   ? esc_sql( $_GET['order'] )   : 'ASC';
        $search_key = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : '';
        $type_filter = isset( $_REQUEST['type'] ) ? wp_unslash( trim( $_REQUEST['type'] ) ) : 'all';
        $role_filter = isset( $_REQUEST['role'] ) ? wp_unslash( trim( $_REQUEST['role'] ) ) : 'all';
        $type = 'authors';
        switch ( $role_filter )
        {
            case 'all':

                switch ( $type_filter )
                {
                    case 'all':
                        $type = 'authors';
                    break;

                    case 'users':
                        $type = 'users';
                    break;

                    case 'guests':
                        $type = 'guests';
                    break;
                }

            break;
            case 'guest':

                switch ( $type_filter )
                {
                    case 'all':
                    case 'guests':
                        $type = 'guests';
                    break;

                    case 'users':
                        $data = array();
                    break;
                }

            break;
            default:

                switch ( $type_filter )
                {
                    case 'all':
                    case 'users':
                        $type = 'users';
                    break;

                    case 'guests':
                        $data = array();
                    break;
                }

            break;
        }

        if ( !isset( $data ) )
        {
            add_filter( 'molongui_authorship/get_author_data_fields', array( $this, 'author_fields' ) );
            add_filter( 'authorship/get_avatar/size', array( $this, 'avatar_size' ) );
            add_filter( 'authorship/get_avatar/context', array( $this, 'avatar_context' ) );
            $args = array
            (
                'type'     => $type,
                'order'    => $order,
                'orderby'  => $orderby,
                'prefetch' => array
                (
                    'core' => array( 'display_name', 'post_title' ),
                    'meta' => array(),
                ),
            );
            $data = Authors::get_authors( $args );

            if ( !in_array( $role_filter, array( 'all', 'guests' ) ) )
            {
                $data = $this->filter_table_data( $data, $role_filter, array( 'user_roles' ) );
            }
        }
        if ( $search_key )
        {
            $search_in = array
            (
                'id',
                'name',
                'display_name',
                'first_name',
                'last_name',
                'email',
            );

            $data = $this->filter_table_data( $data, $search_key, $search_in );
        }
        $items_per_page = $this->get_items_per_page( 'authors_per_page' );
        $table_page     = $this->get_pagenum();
        $this->items    = array_slice( $data, ( ( $table_page - 1 ) * $items_per_page ), $items_per_page );
        $total_authors = count( $data );
        $this->set_pagination_args( array
        (
            'total_items' => $total_authors,
            'per_page'    => $items_per_page,
            'total_pages' => ceil( $total_authors / $items_per_page ),
        ));
    }
    public function author_fields( $default )
    {
        return array
        (
            'id',
            'type',
            'name',
            'email',
            'archive_url',
            'avatar',
            'description',
            'post_counts',
            'user_roles',
            'user_login',
            'box_display',
            'archived',
            'social_profiles',
        );
    }
    public function avatar_size( $default )
    {
        return array( 60, 60 );
    }
    public function avatar_context( $default )
    {
        return 'screen';
    }
    private function filter_table_data( $table_data, $search_key, $search_in )
    {
        $search_key = trim( (string) $search_key );
        if ( $search_key === '' || empty( $table_data ) || empty( $search_in ) )
        {
            return $table_data;
        }
        $needle = strtolower( $search_key );
        $fields = array();
        foreach ( (array) $search_in as $field )
        {
            $field = (string) $field;
            if ( $field !== '' )
            {
                $fields[ $field ] = true;
            }
        }
        if ( empty( $fields ) )
        {
            return $table_data;
        }
        $fields = array_keys( $fields );

        $filtered = array();

        foreach ( (array) $table_data as $row )
        {
            if ( $row instanceof Author )
            {
                foreach ( $fields as $field )
                {
                    $value = '';

                    switch ( $field )
                    {
                        case 'id':
                            $value = (string) $row->get_id();
                            break;

                        case 'name':
                        case 'display_name':
                            $value = (string) $row->get_display_name();
                            break;

                        case 'first_name':
                            $value = (string) $row->get_first_name();
                            break;

                        case 'last_name':
                            $value = (string) $row->get_last_name();
                            break;

                        case 'email':
                            $value = (string) $row->get_email();
                            break;

                        default:
                            $value = (string) $row->get_meta( $field );
                            break;
                    }

                    if ( $value !== '' && strpos( strtolower( $value ), $needle ) !== false )
                    {
                        $filtered[] = $row;
                        break;
                    }
                }

                continue;
            }
            if ( is_array( $row ) )
            {
                foreach ( $fields as $field )
                {
                    if ( ! isset( $row[ $field ] ) )
                    {
                        continue;
                    }

                    $val = $row[ $field ];
                    if ( is_array( $val ) )
                    {
                        $val = implode( ', ', $val );
                    }

                    if ( $val !== '' && strpos( strtolower( (string) $val ), $needle ) !== false )
                    {
                        $filtered[] = $row;
                        break;
                    }
                }
            }
        }

        return $filtered;
    }
    public function no_items()
    {
        _e( "No authors available.", 'molongui-authorship' );
    }
    public function column_default( $item, $column_name )
    {
        $result    = '';
        $author_id = absint( $item->get_id() );

        switch ( $column_name )
        {
            case 'avatar':
                $result = $item->get_avatar();
                break;

            case 'name':
                switch ( $item->get_type() )
                {
                    case 'user':

                        $super_admin = '';

                        if ( is_multisite() and current_user_can( 'manage_network_users' ) )
                        {
                            if ( in_array( $item->get_meta( 'user_login' ), get_super_admins(), true ) )
                            {
                                $super_admin = ' &mdash; ' . __( 'Super Admin' );
                            }
                        }
                        if ( current_user_can( 'list_users' ) )
                        {
                            if ( current_user_can( 'edit_user', $author_id ) )
                            {
                                $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $author_id ) ) );
                                $result    = "<strong><a href=\"{$edit_link}\">{$item->get_display_name()}</a>{$super_admin}</strong><br />";
                            }
                            else
                            {
                                $result = "<strong>{$item->get_display_name()}{$super_admin}</strong><br />";
                            }

                        }
                        else
                        {
                            $result = "<strong>{$item->get_display_name()}{$super_admin}</strong>";
                        }
                        break;

                    case 'guest':

                        if ( current_user_can( 'edit_others_pages' ) or current_user_can( 'edit_others_posts' ) )
                        {
                            $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_post_link( $author_id ) ) );
                            $result    = "<strong><a href=\"{$edit_link}\">{$item->get_display_name()}</a></strong><br />";
                        }
                        else
                        {
                            $result = "<strong>{$item->get_display_name()}</strong>";
                        }
                        break;
                }
                break;

            case 'type':
                $result = ucfirst( $item->get_type() );
                break;

            case 'user_roles':
                global $wp_roles;
                $ur = $item->get_user_roles();
                $user_roles = array();
                foreach ( $ur as $user_role )
                {
                    if ( 'Guest Author' === $user_role )
                    {
                        $user_roles[] = 'Guest Author';
                    }
                    else
                    {
                        $user_roles[] = translate_user_role( $wp_roles->roles[$user_role]['name'] );
                    }
                }
                $result = ucwords( implode( ", ", $user_roles ) );
                break;

            case 'post_count':

                $result =  '';
                foreach ( Settings::enabled_post_types( 'all', 'object' ) as $post_type )
                {
                    $type = 'user' === $item->get_type() ? 'author' : 'guest';
                    $link = admin_url( 'edit.php?post_type='.$post_type['id'].'&'.$type.'='.$author_id );
                    $post_counts = $item->get_post_counts();
                    if ( isset( $post_counts[$post_type['id']] ) and $post_counts[$post_type['id']] > 0 )
                    {
                        $result .= '<div><a href="'.$link.'">'.$post_counts[$post_type['id']].' '.$post_type['label'].'</a></div>';
                    }
                }
                if ( !$result )
                {
                    $result = __( 'None' );
                }
                break;

            case 'description':
                if ( !empty( $item->get_description() ) )
                {
                    $result  = '<div class="m-tooltip">';
                    $result .= '<span class="dashicons dashicons-yes"></span>';
                    $result .= '<span class="m-tooltip__text m-tooltip__top m-tooltip__w400">'.esc_html( $item->get_description() ).'</span>';
                    $result .= '</div>';
                }
                break;

            case 'social_profiles':
                foreach ( Social::get( 'enabled' ) as $network => $data )
                {
                    if ( !empty( $item->get_meta( $network ) ) )
                    {
                        $result  = '<div class="m-tooltip">';
                        $result .= '<span class="dashicons dashicons-yes"></span>';
                        $result .= '<span class="m-tooltip__text m-tooltip__top m-tooltip__w50">'.__( "Has social profiles defined", 'molongui-authorship' ).'</span>';
                        $result .= '</div>';
                        break;
                    }
                }
                break;

            case 'box':
                switch ( $item->get_meta( 'box_display' ) )
                {
                    case 'show':
                        $icon = 'visibility';
                        $tip  = __( "Visible", 'molongui-authorship' );
                        break;

                    case 'hide':
                        $icon = 'hidden';
                        $tip  = __( "Hidden", 'molongui-authorship' );
                        break;

                    default:
                        $icon = 'admin-generic';
                        $tip  = __( "Visibility depends on global plugin settings", 'molongui-authorship' );
                        break;
                }

                $result  = '<div class="m-tooltip">';
                $result .= '<span class="dashicons dashicons-'.$icon.'"></span>';
                $result .= '<span class="m-tooltip__text m-tooltip__top m-tooltip__w100">'.$tip.'</span>';
                $result .= '</div>';
                break;

            case 'archived':
                if ( $item->is_archived() )
                {
                    $tip     = __( "Archived author", 'molongui-authorship' );

                    $result  = '<div class="m-tooltip">';
                    $result .= '<span class="dashicons dashicons-yes"></span>';
                    $result .= '<span class="m-tooltip__text m-tooltip__top m-tooltip__w50">'.$tip.'</span>';
                    $result .= '</div>';
                }
                break;

            case 'id':
                $result = $item->get_id() . '<br>' . '<span style="font-family: \'Courier New\', Courier, monospace; font-size: 81%; color: #a2a2a2;" >' . $item->get_type() . '</span>';
                break;

            default:
                $result = $item->get_meta( $column_name );
                break;
        }

        return $result;
    }
    protected function handle_row_actions( $item, $column_name, $primary )
    {
        if ( $primary !== $column_name )
        {
            return '';
        }

        $actions   = array();
        $author_id = absint( $item->get_id() );

        switch ( $item->get_type() )
        {
            case 'user':
                $url = 'users.php?';
                if ( current_user_can( 'list_users' ) )
                {
                    $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $author_id ) ) );

                    if ( current_user_can( 'edit_user', $author_id ) )
                    {
                        $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
                    }

                    if ( !is_multisite() and get_current_user_id() != $author_id and current_user_can( 'delete_user', $author_id ) )
                    {
                        $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&amp;user=$author_id", 'bulk-users' ) . "'>" . __( 'Delete' ) . '</a>';
                    }
                    if ( is_multisite() and current_user_can( 'remove_user', $author_id ) )
                    {
                        $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url . "action=remove&amp;user=$author_id", 'bulk-users' ) . "'>" . __( 'Remove' ) . '</a>';
                    }
                    $author_posts_url = get_author_posts_url( $author_id );
                    if ( $author_posts_url )
                    {
                        $actions['view'] = sprintf(
                            '<a href="%s" aria-label="%s">%s</a>',
                            esc_url( $author_posts_url ),
                            esc_attr( sprintf( __( 'View posts by %s' ), $item->get_display_name() ) ),
                            __( 'View' )
                        );
                    }

                }

            break;

            case 'guest':
                if ( current_user_can( 'edit_others_pages' ) or current_user_can( 'edit_others_posts' ) )
                {
                    $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_post_link( $author_id ) ) );
                    $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
                }

                if ( current_user_can( 'delete_others_pages' ) or current_user_can( 'delete_others_posts' ) )
                {
                    $actions['trash'] = sprintf(
                        '<a href="%s" class="submitdelete" aria-label="%s">%s</a>',
                        get_delete_post_link( $author_id ),
                        esc_attr( sprintf( __( 'Move &#8220;%s&#8221; to the Trash' ), $item->get_display_name() ) ),
                        _x( 'Trash', 'verb' )
                    );
                }

                if ( '#molongui-disabled-link' !== $item->get_meta( 'archive_url' ) )
                {
                    $actions['view'] = sprintf(
                        '<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
                        $item->get_meta( 'archive_url' ),
                        esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $item->get_display_name() ) ),
                        __( 'View' )
                    );
                }

            break;
        }
        $actions = apply_filters( 'molongui_authorship/author_row_actions', $actions, $item );

        return $this->row_actions( $actions );
    }
}
