<?php

// Include the WP_List_Table class
if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
/**
 * List Table API: WP_Posts_List_Table class
 *
 * @package    WordPress
 * @subpackage Administration
 * @since      3.1.0
 */

/**
 * Class that extends WP_List_Table for displaying a list of Downloads.
 * This is a modified copy of the WP_Posts_List_Table class.
 *
 * @since 5.0.0
 *
 * @see   WP_List_Table
 */
class DLM_Admin_List_Table extends WP_List_Table {

	/**
	 * Whether the items should be displayed hierarchically or linearly.
	 *
	 * @since 5.0.0
	 * @var bool
	 */
	protected $hierarchical_display;

	/**
	 * Holds the number of pending comments for each post.
	 *
	 * @since 5.0.0
	 * @var array
	 */
	protected $comment_pending_count;

	/**
	 * Holds the number of posts for this user.
	 *
	 * @since 5.0.0
	 * @var int
	 */
	private $user_posts_count;

	/**
	 * Holds the number of posts which are sticky.
	 *
	 * @since 5.0.0
	 * @var int
	 */
	private $sticky_posts_count = 0;

	private $is_trash;

	/**
	 * Current level for output.
	 *
	 * @since 5.0.0
	 * @var int
	 */
	protected $current_level = 0;

	/**
	 * Holds the Downloads.
	 *
	 * @var array
	 */
	private $downloads = array();

	/**
	 * Constructor.
	 *
	 * @param  array        $args  An associative array of arguments.
	 *
	 * @see   WP_List_Table::__construct() for more information on default arguments.
	 *
	 * @global WP_Post_Type $post_type_object
	 * @global wpdb         $wpdb  WordPress database abstraction object.
	 *
	 * @since 5.0.0
	 *
	 */
	public function __construct( $args = array() ) {
		global $post_type_object, $wpdb;

		parent::__construct(
			array(
				'plural' => 'dlm_downloads',
				'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
			)
		);

		$post_type        = $this->screen->post_type;
		$post_type_object = get_post_type_object( $post_type );

		$exclude_states = get_post_stati(
			array(
				'show_in_admin_all_list' => false,
			)
		);

		$this->user_posts_count = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT( 1 )
				FROM $wpdb->posts
				WHERE post_type = %s
				AND post_status NOT IN ( '" . implode( "','", $exclude_states ) . "' )
				AND post_author = %d",
				$post_type,
				get_current_user_id()
			)
		);

		if ( $this->user_posts_count
		     && ! current_user_can( $post_type_object->cap->edit_others_posts )
		     && empty( $_REQUEST['post_status'] ) && empty( $_REQUEST['all_posts'] )
		     && empty( $_REQUEST['author'] ) && empty( $_REQUEST['show_sticky'] )
		) {
			$_GET['author'] = get_current_user_id();
		}

		$sticky_posts = get_option( 'sticky_posts' );

		if ( 'post' === $post_type && $sticky_posts ) {
			$sticky_posts = implode( ', ', array_map( 'absint', (array) $sticky_posts ) );

			$this->sticky_posts_count = (int) $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT( 1 )
					FROM $wpdb->posts
					WHERE post_type = %s
					AND post_status NOT IN ('trash', 'auto-draft')
					AND ID IN ($sticky_posts)",
					$post_type
				)
			);
		}
	}

	/**
	 * Sets whether the table layout should be hierarchical or not.
	 *
	 * @param  bool  $display  Whether the table layout should be hierarchical.
	 *
	 * @since 5.0.0
	 *
	 */
	public function set_hierarchical_display( $display ) {
		$this->hierarchical_display = $display;
	}

	/**
	 * Check if the current user has permissions to perform the given action.
	 *
	 * @return bool
	 *
	 * @since 5.0.0
	 */
	public function ajax_user_can() {
		return current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_posts );
	}

	/**
	 * Prepare the items for the table to process.
	 *
	 * @global string   $mode     List table view mode.
	 * @global array    $avail_post_stati
	 * @global WP_Query $wp_query WordPress Query object.
	 * @global int      $per_page
	 *
	 * @since 5.0.0
	 */
	public function prepare_items() {
		global $mode, $avail_post_stati, $wp_query, $per_page;

		if ( ! empty( $_REQUEST['mode'] ) ) {
			$mode = 'excerpt' === $_REQUEST['mode'] ? 'excerpt' : 'list';
			set_user_setting( 'posts_list_mode', $mode );
		} else {
			$mode = get_user_setting( 'posts_list_mode', 'list' );
		}

		// Is going to call wp().
		$avail_post_stati = wp_edit_posts_query();

		$this->set_hierarchical_display(
			is_post_type_hierarchical( $this->screen->post_type )
			&& 'menu_order title' === $wp_query->query['orderby']
		);

		$post_type = $this->screen->post_type;
		$per_page  = $this->get_items_per_page( 'edit_' . $post_type . '_per_page' );

		/** This filter is documented in wp-admin/includes/post.php */
		$per_page = apply_filters( 'edit_posts_per_page', $per_page, $post_type );

		if ( $this->hierarchical_display ) {
			$total_items = $wp_query->post_count;
		} elseif ( $wp_query->found_posts || $this->get_pagenum() === 1 ) {
			$total_items = $wp_query->found_posts;
		} else {
			$post_counts = (array) wp_count_posts( $post_type, 'readable' );

			if ( isset( $_REQUEST['post_status'] ) && in_array( $_REQUEST['post_status'], $avail_post_stati, true ) ) {
				$total_items = $post_counts[ $_REQUEST['post_status'] ];
			} elseif ( isset( $_REQUEST['show_sticky'] ) && $_REQUEST['show_sticky'] ) {
				$total_items = $this->sticky_posts_count;
			} elseif ( isset( $_GET['author'] ) && get_current_user_id() === (int) $_GET['author'] ) {
				$total_items = $this->user_posts_count;
			} else {
				$total_items = array_sum( $post_counts );

				// Subtract post types that are not included in the admin all list.
				foreach ( get_post_stati( array( 'show_in_admin_all_list' => false ) ) as $state ) {
					$total_items -= $post_counts[ $state ];
				}
			}
		}

		$this->downloads = download_monitor()->service( 'download_repository' )->create_downloads_from_array( $wp_query->posts );
		$this->is_trash  = isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'];

		$this->set_pagination_args(
			array(
				'total_items' => $total_items,
				'per_page'    => $per_page,
			)
		);
	}

	/**
	 * Check if the current query has items to display.
	 *
	 * @return bool
	 *
	 * @since 5.0.0
	 */
	public function has_items() {
		return have_posts();
	}

	public function has_any_downloads() {
		$statuses = get_post_stati();
		unset( $statuses['auto-draft'], $statuses['inherit'] );

		$query = new WP_Query( array(
			'post_type'      => 'dlm_download',
			'post_status'    => array_keys( $statuses ),
			'posts_per_page' => 1,
			'fields'         => 'ids',
			'no_found_rows'  => true,
		) );

		return ( ! empty( $query->posts ) );
	}

	public function display(){
	
		if( ! $this->has_any_downloads() ) {
			$wp_list_table = new DLM_Empty_Table();
			$wp_list_table->display();
		} else {
			parent::display();
		}
	}

	/**
	 * No items display
	 *
	 * @since 5.0.0
	 */
	public function no_items() {
		global $wp_list_table;
		$wp_list_table = new DLM_Empty_Table();
	}

	/**
	 * Determines if the current view is the "All" view.
	 *
	 * @return bool Whether the current view is the "All" view.
	 * @since 5.0.0
	 *
	 */
	protected function is_base_request() {
		$vars = $_GET;
		unset( $vars['paged'] );

		if ( empty( $vars ) ) {
			return true;
		} elseif ( 1 === count( $vars ) && ! empty( $vars['post_type'] ) ) {
			return $this->screen->post_type === $vars['post_type'];
		}

		return 1 === count( $vars ) && ! empty( $vars['mode'] );
	}

	/**
	 * Creates a link to edit.php with params.
	 *
	 * @param  string[]  $args       Associative array of URL parameters for the link.
	 * @param  string    $link_text  Link text.
	 * @param  string    $css_class  Optional. Class attribute. Default empty string.
	 *
	 * @return string The formatted link string.
	 * @since 5.0.0
	 *
	 */
	protected function get_edit_link( $args, $link_text, $css_class = '' ) {
		$url = add_query_arg( $args, 'edit.php' );

		$class_html   = '';
		$aria_current = '';

		if ( ! empty( $css_class ) ) {
			$class_html = sprintf(
				' class="%s"',
				esc_attr( $css_class )
			);

			if ( 'current' === $css_class ) {
				$aria_current = ' aria-current="page"';
			}
		}

		return sprintf(
			'<a href="%s"%s%s>%s</a>',
			esc_url( $url ),
			$class_html,
			$aria_current,
			$link_text
		);
	}

	/**
	 * Get the views for the posts list table.
	 *
	 * @return array
	 * @global array $avail_post_stati
	 * @global array $locked_post_status This seems to be deprecated.
	 *
	 * @since 5.0.0
	 */
	protected function get_views() {
		global $locked_post_status, $avail_post_stati;

		$post_type = $this->screen->post_type;

		if ( ! empty( $locked_post_status ) ) {
			return array();
		}

		$status_links = array();
		$num_posts    = wp_count_posts( $post_type, 'readable' );
		$total_posts  = array_sum( (array) $num_posts );
		$class        = '';

		$current_user_id = get_current_user_id();
		$all_args        = array( 'post_type' => $post_type );
		$mine            = '';

		// Subtract post types that are not included in the admin all list.
		foreach ( get_post_stati( array( 'show_in_admin_all_list' => false ) ) as $state ) {
			$total_posts -= $num_posts->$state;
		}

		if ( $this->user_posts_count && $this->user_posts_count !== $total_posts ) {
			if ( isset( $_GET['author'] ) && ( $current_user_id === (int) $_GET['author'] ) ) {
				$class = 'current';
			}

			$mine_args = array(
				'post_type' => $post_type,
				'author'    => $current_user_id,
			);

			$mine_inner_html = sprintf(
			/* translators: %s: Number of posts. */
				_nx(
					'Mine <span class="count">(%s)</span>',
					'Mine <span class="count">(%s)</span>',
					$this->user_posts_count,
					'posts'
				),
				number_format_i18n( $this->user_posts_count )
			);

			$mine = array(
				'url'     => esc_url( add_query_arg( $mine_args, 'edit.php' ) ),
				'label'   => $mine_inner_html,
				'current' => isset( $_GET['author'] ) && ( $current_user_id === (int) $_GET['author'] ),
			);

			$all_args['all_posts'] = 1;
			$class                 = '';
		}

		$all_inner_html = sprintf(
		/* translators: %s: Number of posts. */
			_nx(
				'All <span class="count">(%s)</span>',
				'All <span class="count">(%s)</span>',
				$total_posts,
				'posts'
			),
			number_format_i18n( $total_posts )
		);

		$status_links['all'] = array(
			'url'     => esc_url( add_query_arg( $all_args, 'edit.php' ) ),
			'label'   => $all_inner_html,
			'current' => empty( $class ) && ( $this->is_base_request() || isset( $_REQUEST['all_posts'] ) ),
		);

		if ( $mine ) {
			$status_links['mine'] = $mine;
		}

		foreach ( get_post_stati( array( 'show_in_admin_status_list' => true ), 'objects' ) as $status ) {
			$class = '';

			$status_name = $status->name;

			if ( ! in_array( $status_name, $avail_post_stati, true ) || empty( $num_posts->$status_name ) ) {
				continue;
			}

			if ( isset( $_REQUEST['post_status'] ) && $status_name === $_REQUEST['post_status'] ) {
				$class = 'current';
			}

			$status_args = array(
				'post_status' => $status_name,
				'post_type'   => $post_type,
			);

			$status_label = sprintf(
				translate_nooped_plural( $status->label_count, $num_posts->$status_name ),
				number_format_i18n( $num_posts->$status_name )
			);

			$status_links[ $status_name ] = array(
				'url'     => esc_url( add_query_arg( $status_args, 'edit.php' ) ),
				'label'   => $status_label,
				'current' => isset( $_REQUEST['post_status'] ) && $status_name === $_REQUEST['post_status'],
			);
		}

		if ( ! empty( $this->sticky_posts_count ) ) {
			$class = ! empty( $_REQUEST['show_sticky'] ) ? 'current' : '';

			$sticky_args = array(
				'post_type'   => $post_type,
				'show_sticky' => 1,
			);

			$sticky_inner_html = sprintf(
			/* translators: %s: Number of posts. */
				_nx(
					'Sticky <span class="count">(%s)</span>',
					'Sticky <span class="count">(%s)</span>',
					$this->sticky_posts_count,
					'posts'
				),
				number_format_i18n( $this->sticky_posts_count )
			);

			$sticky_link = array(
				'sticky' => array(
					'url'     => esc_url( add_query_arg( $sticky_args, 'edit.php' ) ),
					'label'   => $sticky_inner_html,
					'current' => ! empty( $_REQUEST['show_sticky'] ),
				),
			);

			// Sticky comes after Publish, or if not listed, after All.
			$split        = 1 + array_search( ( isset( $status_links['publish'] ) ? 'publish' : 'all' ), array_keys( $status_links ), true );
			$status_links = array_merge( array_slice( $status_links, 0, $split ), $sticky_link, array_slice( $status_links, $split ) );
		}

		return $this->get_views_links( $status_links );
	}

	/**
	 * Get bulk actions.
	 *
	 * @return array
	 *
	 * @since 5.0.0
	 */
	protected function get_bulk_actions() {
		$actions       = array();
		$post_type_obj = get_post_type_object( $this->screen->post_type );

		if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
			if ( $this->is_trash ) {
				$actions['untrash'] = __( 'Restore' );
			} else {
				$actions['edit'] = __( 'Edit' );
			}
		}

		if ( current_user_can( $post_type_obj->cap->delete_posts ) ) {
			if ( $this->is_trash || ! EMPTY_TRASH_DAYS ) {
				$actions['delete'] = __( 'Delete permanently' );
			} else {
				$actions['trash'] = __( 'Move to Trash' );
			}
		}

		return $actions;
	}

	/**
	 * @param  string  $which
	 */
	protected function extra_tablenav( $which ) {
		?>
		<div class="alignleft actions">
			<?php
			if ( 'top' === $which ) {
				ob_start();

				$this->months_dropdown( $this->screen->post_type );
				/**
				 * Fires before the Filter button on the Posts and Pages list tables.
				 *
				 * The Filter button allows sorting by date and/or category on the
				 * Posts list table, and sorting by date on the Pages list table.
				 *
				 * @param  string  $post_type  The post type slug.
				 * @param  string  $which      The location of the extra table nav markup:
				 *                             'top' or 'bottom' for WP_Posts_List_Table,
				 *                             'bar' for WP_Media_List_Table.
				 *
				 *
				 * @since 5.0.0
				 */
				do_action( 'restrict_manage_posts', $this->screen->post_type, $which );

				$output = ob_get_clean();

				if ( ! empty( $output ) ) {
					echo $output;
					submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
				}
			}

			if ( $this->is_trash && $this->has_items()
			     && current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_others_posts )
			) {
				submit_button( __( 'Empty Trash' ), 'apply', 'delete_all', false );
			}
			?>
		</div>
		<?php
		/**
		 * Fires immediately following the closing "actions" div in the tablenav for the posts
		 * list table.
		 *
		 * @param  string  $which  The location of the extra table nav markup: 'top' or 'bottom'.
		 *
		 * @since 5.0.0
		 *
		 */
		do_action( 'manage_posts_extra_tablenav', $which );
	}

	/**
	 * Get the current action selected from the bulk actions dropdown.
	 *
	 * @return string
	 *
	 * @since 5.0.0
	 */
	public function current_action() {
		if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) ) {
			return 'delete_all';
		}

		return parent::current_action();
	}

	/**
	 * Get the table classes.
	 *
	 * @return array
	 * @global string $mode List table view mode.
	 *
	 * @since 5.0.0
	 */
	protected function get_table_classes() {
		global $mode;

		$mode_class = esc_attr( 'table-view-' . $mode );

		return array(
			'widefat',
			'fixed',
			'striped',
			$mode_class,
			'posts',
		);
	}

	/**
	 * Get columns.
	 *
	 * @return string[] Array of column titles keyed by their column name.
	 *
	 * @since 5.0.0
	 */
	public function get_columns() {
		$post_type = $this->screen->post_type;

		$posts_columns = array();

		$posts_columns['cb']              = '<input type="checkbox" />';
		$posts_columns['download_title']  = __( 'Title', 'download-monitor' );
		$posts_columns['download_cat']    = __( 'Categories', 'download-monitor' );
		$posts_columns['version']         = __( 'Version', 'download-monitor' );
		$posts_columns['shortcode']       = __( 'Shortcode', 'download-monitor' );
		$posts_columns['download_link']   = __( 'Download link', 'download-monitor' );
		$posts_columns['file_location']    = __( 'File Location', 'download-monitor' );
		$posts_columns['file_type']        = __( 'File Type', 'download-monitor' );
		$posts_columns['download_tag']    = __( 'Tags', 'download-monitor' );
		$posts_columns['download_count']  = __( 'Download count', 'download-monitor' );
		$posts_columns['featured']        = __( 'Featured', 'download-monitor' );
		$posts_columns['locked_download'] = __( 'Locked', 'download-monitor' );
		$posts_columns['redirect_only']   = __( 'Redirect only', 'download-monitor' );
		$posts_columns['date']            = __( 'Date posted', 'download-monitor' );

		if ( post_type_supports( $post_type, 'author' ) ) {
			$posts_columns['author'] = __( 'Author' );
		}

		$taxonomies = get_object_taxonomies( $post_type, 'objects' );
		$taxonomies = wp_filter_object_list( $taxonomies, array( 'show_admin_column' => true ), 'and', 'name' );

		/**
		 * Filters the taxonomy columns in the Posts list table.
		 *
		 * The dynamic portion of the hook name, `$post_type`, refers to the post
		 * type slug.
		 *
		 *
		 * @param  string[]  $taxonomies  Array of taxonomy names to show columns for.
		 * @param  string    $post_type   The post type.
		 *
		 * @since 5.0.0
		 *
		 */
		$taxonomies = apply_filters( "manage_taxonomies_for_{$post_type}_columns", $taxonomies, $post_type );
		$taxonomies = array_filter( $taxonomies, 'taxonomy_exists' );

		foreach ( $taxonomies as $taxonomy ) {
			if ( 'dlm_download_category' === $taxonomy ) {
				$column_key = 'dlm_download_category';
			} elseif ( 'post_tag' === $taxonomy ) {
				$column_key = 'tags';
			} else {
				$column_key = 'taxonomy-' . $taxonomy;
			}

			$posts_columns[ $column_key ] = get_taxonomy( $taxonomy )->labels->name;
		}

		$post_status = ! empty( $_REQUEST['post_status'] ) ? $_REQUEST['post_status'] : 'all';

		if ( post_type_supports( $post_type, 'comments' )
		     && ! in_array( $post_status, array( 'pending', 'draft', 'future' ), true )
		) {
			$posts_columns['comments'] = sprintf(
				'<span class="vers comment-grey-bubble" title="%1$s" aria-hidden="true"></span><span class="screen-reader-text">%2$s</span>',
				esc_attr__( 'Comments' ),
				/* translators: Hidden accessibility text. */
				__( 'Comments' )
			);
		}

		/**
		 * Filters the columns displayed in the Posts list table for a specific post type.
		 *
		 * The dynamic portion of the hook name, `$post_type`, refers to the post type slug.
		 *
		 *
		 * @param  string[]  $post_columns  An associative array of column headings.
		 *
		 * @since 5.0.0
		 *
		 */
		return apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );
	}

	/**
	 * Get sortable columns.
	 *
	 * @return array
	 *
	 * @since 5.0.0
	 */
	protected function get_sortable_columns() {
		$columns = array(
			'download_id'     => array( 'ID' ),
			'download_title'  => array( 'title' ),
			'download_count'  => array( 'download_count' ),
			'featured'        => array( 'featured' ),
			'locked_download' => array( 'locked_download' ),
			'redirect_only'   => array( 'redirect_only' ),
		);

		/**
		 * Filters the sortable columns for the DLM downloads list table.
		 *
		 * @param  array  $columns  The sortable columns.
		 *
		 * @since 5.0.0
		 *
		 */
		return apply_filters( 'dlm_admin_page_list_sortable_columns', $columns );
	}

	/**
	 * Display the table.
	 *
	 * @param  array    $posts
	 * @param  int      $level
	 *
	 * @global WP_Query $wp_query WordPress Query object.
	 * @global int      $per_page
	 *
	 * @since 5.0.0
	 */
	public function display_rows( $posts = array(), $level = 0 ) {
		global $wp_query, $per_page;

		if ( empty( $posts ) ) {
			$posts = $wp_query->posts;
		}

		add_filter( 'the_title', 'esc_html' );

		$this->_display_rows( $posts, $level );
	}

	/**
	 * Display the rows.
	 *
	 * @param  array  $posts
	 * @param  int    $level
	 *
	 * @since 5.0.0
	 */
	private function _display_rows( $posts, $level = 0 ) {
		$post_type = $this->screen->post_type;

		// Create array of post IDs.
		$post_ids = array();

		foreach ( $posts as $a_post ) {
			$post_ids[] = $a_post->ID;
		}

		if ( post_type_supports( $post_type, 'comments' ) ) {
			$this->comment_pending_count = get_pending_comments_num( $post_ids );
		}
		update_post_author_caches( $posts );

		foreach ( $posts as $post ) {
			$this->single_row( $post, $level );
		}
	}

	/**
	 * Handles the checkbox column output.
	 *
	 * @param  WP_Post  $item  The current WP_Post object.
	 *
	 *
	 * @since 5.0.0
	 */
	public function column_cb( $item ) {
		// Restores the more descriptive, specific name for use within this method.
		$post = $item;

		$show = current_user_can( 'edit_post', $post->ID );

		/**
		 * Filters whether to show the bulk edit checkbox for a post in its list table.
		 *
		 * By default the checkbox is only shown if the current user can edit the post.
		 *
		 * @param  bool     $show  Whether to show the checkbox.
		 * @param  WP_Post  $post  The current WP_Post object.
		 *
		 * @since 5.0.0
		 *
		 */
		if ( apply_filters( 'wp_list_table_show_post_checkbox', $show, $post ) ) :
			?>
			<input id="cb-select-<?php
			the_ID(); ?>" type="checkbox" name="post[]" value="<?php
			the_ID(); ?>"/>
			<label for="cb-select-<?php
			the_ID(); ?>">
				<span class="screen-reader-text">
				<?php
				/* translators: %s: Post title. */
				printf( __( 'Select %s' ), _draft_or_post_title() );
				?>
				</span>
			</label>
			<div class="locked-indicator">
				<span class="locked-indicator-icon" aria-hidden="true"></span>
				<span class="screen-reader-text">
				<?php
				printf(
				/* translators: Hidden accessibility text. %s: Post title. */
					__( '&#8220;%s&#8221; is locked' ),
					_draft_or_post_title()
				);
				?>
				</span>
			</div>
		<?php
		endif;
	}

	/**
	 * Handles the post date column output.
	 *
	 * @param  WP_Post  $post  The current WP_Post object.
	 *
	 * @global string   $mode  List table view mode.
	 *
	 * @since 5.0.0
	 *
	 */
	public function column_date( $post ) {
		global $mode;

		if ( '0000-00-00 00:00:00' === $post->post_date ) {
			$t_time    = __( 'Unpublished' );
			$time_diff = 0;
		} else {
			$t_time = sprintf(
			/* translators: 1: Post date, 2: Post time. */
				__( '%1$s at %2$s' ),
				/* translators: Post date format. See https://www.php.net/manual/datetime.format.php */
				get_the_time( __( 'Y/m/d' ), $post ),
				/* translators: Post time format. See https://www.php.net/manual/datetime.format.php */
				get_the_time( __( 'g:i a' ), $post )
			);

			$time      = get_post_timestamp( $post );
			$time_diff = time() - $time;
		}

		if ( 'publish' === $post->post_status ) {
			$status = __( 'Published' );
		} elseif ( 'future' === $post->post_status ) {
			if ( $time_diff > 0 ) {
				$status = '<strong class="error-message">' . __( 'Missed schedule' ) . '</strong>';
			} else {
				$status = __( 'Scheduled' );
			}
		} else {
			$status = __( 'Last Modified' );
		}

		/**
		 * Filters the status text of the post.
		 *
		 * @param  string   $status       The status text.
		 * @param  WP_Post  $post         Post object.
		 * @param  string   $column_name  The column name.
		 * @param  string   $mode         The list display mode ('excerpt' or 'list').
		 *
		 * @since 5.0.0
		 *
		 */
		$status = apply_filters( 'post_date_column_status', $status, $post, 'date', $mode );

		if ( $status ) {
			echo $status . '<br />';
		}

		/**
		 * Filters the published, scheduled, or unpublished time of the post.
		 *
		 * @param  string   $t_time       The published time.
		 * @param  WP_Post  $post         Post object.
		 * @param  string   $column_name  The column name.
		 * @param  string   $mode         The list display mode ('excerpt' or 'list').
		 *
		 * @since      5.0.0
		 *
		 */
		echo apply_filters( 'post_date_column_time', $t_time, $post, 'date', $mode );
	}

	/**
	 * Handles the comments column output.
	 *
	 * @param  WP_Post  $post  The current WP_Post object.
	 *
	 * @since 5.0.0
	 *
	 */
	public function column_comments( $post ) {
		?>
		<div class="post-com-count-wrapper">
			<?php
			$pending_comments = isset( $this->comment_pending_count[ $post->ID ] ) ? $this->comment_pending_count[ $post->ID ] : 0;

			$this->comments_bubble( $post->ID, $pending_comments );
			?>
		</div>
		<?php
	}

	/**
	 * Handles the post author column output.
	 *
	 * @param  WP_Post  $post  The current WP_Post object.
	 *
	 * @since 5.0.0
	 *
	 */
	public function column_author( $post ) {
		$args = array(
			'post_type' => $post->post_type,
			'author'    => get_the_author_meta( 'ID' ),
		);
		echo $this->get_edit_link( $args, get_the_author() );
	}

	/**
	 * column_default function.
	 *
	 * @param  WP_Post  $post         The current item
	 * @param  string   $column_name  The current column name
	 *
	 * @since 5.0.0
	 */
	public function column_default( $post, $column_name ) {
		// Set the DLM download object.
		if ( isset( $GLOBALS['dlm_download'] ) && $post->ID === $GLOBALS['dlm_download']->get_id() ) {
			$item = $GLOBALS['dlm_download'];
		} else {
			if ( ! empty( $this->downloads ) && isset( $this->downloads[ $post->ID ] ) ) {
				$item = $this->downloads[ $post->ID ];
			} else {
				$item = download_monitor()->service( 'download_repository' )->retrieve_single( $post->ID );
			}
		}

		switch ( $column_name ) {
			case 'download_title':
				/** @var DLM_Download_Version $file */
				$file = $item->get_version();
				echo '<strong><a class="dlm-file-link row-title" href="' . esc_url( admin_url( 'post.php?post=' . absint( $item->get_id() ) . '&action=edit' ) ) . '">#' . $item->get_id() . ' - ' . esc_html( $item->get_title() ) . '</a></strong>';
				if ( $file->get_filename() ) {
					echo '<a class="dlm-file-link" href="' . esc_url( $item->get_the_download_link() ) . '"><code>' . esc_html( $file->get_filename() );
					if ( $size = $item->get_version()->get_filesize_formatted() ) {
						echo ' &ndash; ' . esc_html( $size );
					}
					echo '</code></a>';
				} else {
					echo '<div class="dlm-listing-no-file"><code>' . esc_html__( 'No file provided', 'download-monitor' ) . '</code></div>';
				}

				/** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
				$quick_edit_enabled = apply_filters( 'quick_edit_enabled_for_post_type', true, $post->post_type );

				if ( $quick_edit_enabled ) {
					get_inline_data( $post );
				}

				break;
			case 'download_cat':
				$links = array();
				if ( ! $terms = get_the_terms( $item->get_id(), 'dlm_download_category' ) ) {
					echo '<span class="na">&ndash;</span>';
				} else {
					foreach ( $terms as $term ) {
						$links[] = '<a href=' . esc_url( add_query_arg( 'dlm_download_category', esc_attr( $term->slug ) ) ) . '>' . esc_html( $term->name ) . '(#' . absint( $term->term_id ) . ')</a> ';
					}
					echo wp_kses_post( implode( ', ', $links ) );
				}
				break;
			case 'download_tag':
				$terms = get_the_terms( $item->get_id(), 'dlm_download_tag' );

				if ( is_wp_error( $terms ) ) {
					echo '<span class="na">&ndash;</span>';
					break;
				}

				if ( empty( $terms ) ) {
					echo '<span class="na">&ndash;</span>';
					break;
				}

				$links = array();
				foreach ( $terms as $term ) {
					$link = get_term_link( $term, 'dlm_download_tag' );
					if ( is_wp_error( $link ) ) {
						continue;
					}
					$links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . esc_html( $term->name ) . '(#' . absint( $term->term_id ) . ')</a>';
				}
				if ( empty( $links ) ) {
					echo '<span class="na">&ndash;</span>';
				} else {
					echo wp_kses_post( implode( ', ', $links ) );
				}
				break;
			case 'featured':
				if ( $item->is_featured() ) {
					echo '<span class="yes">1</span>';
				} else {
					echo '<span class="na">&ndash;</span>';
				}
				break;
			case 'locked_download':
				/**
				 * Filters whether the download is locked or not.
				 *
				 * @param  bool          $is_locked  Whether the download is locked or not using members only. Other extensions tap into this filter to check if the download is locked.
				 * @param  DLM_Download  $item       The download object. Needs to be DLM_Download object.
				 *
				 * @moved 5.0.0 Moved here from CustomColumns.php
				 */
				$is_locked = apply_filters( 'dlm_download_is_locked', $item->is_members_only(), $item );
				if ( $is_locked ) {
					echo '<span class="yes" ' . ( $item->is_members_only() ? 'data-members_only="1"' : '' ) . ' ' . ( DLM_TC_Access_Manager::is_tc_locked( $item->get_id() ) ? 'data-_dlm_tc_locked="1"' : '' ) . '>1</span>';
				} else {
					echo '<span class="na">&ndash;</span>';
				}
				break;
			case 'redirect_only':
				if ( $item->is_redirect_only() ) {
					echo '<span class="yes">1</span>';
				} else {
					echo '<span class="na">&ndash;</span>';
				}
				break;
			case 'version':
				/** @var DLM_Download_Version $file */
				$file = $item->get_version();
				if ( $file && $file->get_version() ) {
					echo esc_html( $file->get_version() );
				} else {
					echo '<span class="na">&ndash;</span>';
				}
				break;

			case 'shortcode':
				echo '<button class="wpchill-tooltip-button copy-dlm-shortcode button button-primary button-compact"><span class="dashicons dashicons-shortcode"></span><div class="wpchill-tooltip-content"><span class="dlm-copy-text">' . esc_html__( 'Copy shortcode', 'download-monitor' ) . '</span><div class="dl-shortcode-copy"><code>[download id="' . absint( $item->get_id() ) . '"]</code><input type="text" readonly value="[download id=\'' . absint( $item->get_id() ) . '\']" class="dlm-copy-shortcode-input"></div></div></button>';
				break;
			case 'download_link':
				echo '<button class="wpchill-tooltip-button copy-dlm-shortcode button button-primary button-compact"><span class="dashicons dashicons-admin-links"></span><div class="wpchill-tooltip-content"><span class="dlm-copy-text">' . esc_html__( 'Copy download link', 'download-monitor' ) . '</span><div class="dl-shortcode-copy">' . esc_url( $item->get_the_download_link() ) . '<input type="text" readonly value="' . esc_url( $item->get_the_download_link() ) . '" class="dlm-copy-shortcode-input"></div></div></button>';
				break;
			case 'download_count':
				echo number_format( $item->get_download_count(), 0, '.', ',' );
				break;
			case 'file_location':
				$file  = $item->get_version();
				$path  = $file->get_url();
				$loc   = __( 'Unknown', 'download-monitor' );
				$class = 'dlm_file_path_unknown';

				if ( null != $path ) {
					$file_manager = new DLM_File_Manager();
					list( $file_path, $remote_file ) = $file_manager->parse_file_path( $path );
					if ( $file_path ) {
						if ( $remote_file ) {
							$loc   = __( 'Remote', 'download-monitor' );
							$class = 'dlm_file_path_remote';
						} else {
							$loc   = __( 'Local', 'download-monitor' );
							$class = 'dlm_file_path_local';
						}
					}
				}

				echo '<span class="' . esc_attr( $class ) . '">' . esc_html( $loc ) . '</span>';
				break;
			case 'file_type':
				$file = $item->get_version();
				$type = $file->get_filetype();
				if ( ! empty( $type ) ) {
					echo '<span class="dlm_file_type_info "><span class="file filetype-icon filetype-' . esc_attr( sanitize_title( $type ) ) . '"></span>' . strtoupper( esc_html( $type ) ) . '</span>';
				}
				break;

			default:
				do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
				break;
		}
	}

	/**
	 * Single row display.
	 *
	 * @param  int|WP_Post  $post
	 * @param  int          $level
	 *
	 * @global WP_Post      $post Global post object.
	 *
	 * @since 5.0.0
	 */
	public function single_row( $post, $level = 0 ) {
		$global_post = get_post();

		$post                = get_post( $post );
		$this->current_level = $level;

		$GLOBALS['post'] = $post;
		setup_postdata( $post );

		$classes = 'iedit author-' . ( get_current_user_id() === (int) $post->post_author ? 'self' : 'other' );

		$lock_holder = wp_check_post_lock( $post->ID );

		if ( $lock_holder ) {
			$classes .= ' wp-locked';
		}

		if ( $post->post_parent ) {
			$count   = count( get_post_ancestors( $post->ID ) );
			$classes .= ' level-' . $count;
		} else {
			$classes .= ' level-0';
		}
		?>
		<tr id="post-<?php
		echo $post->ID; ?>" class="<?php
		echo implode( ' ', get_post_class( $classes, $post->ID ) ); ?>">
			<?php
			$this->single_row_columns( $post ); ?>
		</tr>
		<?php
		// Set the global download object.
		if ( ! empty( $this->downloads ) ) {
			$GLOBALS['dlm_download'] = $this->downloads[ $post->ID ];
		} else {
			$GLOBALS['dlm_download'] = download_monitor()->service( 'download_repository' )->retrieve_single( $post->ID );
		}
		$GLOBALS['post'] = $global_post;
	}

	/**
	 * Gets the name of the default primary column.
	 *
	 * @return string Name of the default primary column, in this case, 'title'.
	 * @since 5.0.0
	 *
	 */
	protected function get_default_primary_column_name() {
		return 'download_title';
	}

	/**
	 * Generates and displays row action links.
	 *
	 * @param  WP_Post  $item         Post being acted upon.
	 * @param  string   $column_name  Current column name.
	 * @param  string   $primary      Primary column name.
	 *
	 * @return string Row actions output for posts, or an empty string
	 *                if the current column is not the primary column.
	 * @since 5.0.0
	 *
	 */
	protected function handle_row_actions( $item, $column_name, $primary ) {
		if ( $primary !== $column_name ) {
			return '';
		}

		// Restores the more descriptive, specific name for use within this method.
		$post = $item;

		$post_type_object = get_post_type_object( $post->post_type );
		$can_edit_post    = current_user_can( 'edit_post', $post->ID );
		$actions          = array();
		$title            = _draft_or_post_title();

		if ( $can_edit_post && 'trash' !== $post->post_status ) {
			$actions['edit'] = sprintf(
				'<a href="%s" aria-label="%s">%s</a>',
				get_edit_post_link( $post->ID ),
				/* translators: %s: Post title. */
				esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ),
				__( 'Edit' )
			);

			/**
			 * Filters whether Quick Edit should be enabled for the given post type.
			 *
			 * @param  bool    $enable     Whether to enable the Quick Edit functionality. Default true.
			 * @param  string  $post_type  Post type name.
			 *
			 * @since 5.0.0
			 *
			 */
			$quick_edit_enabled = apply_filters( 'quick_edit_enabled_for_post_type', true, $post->post_type );

			if ( $quick_edit_enabled && 'wp_block' !== $post->post_type ) {
				$actions['inline hide-if-no-js'] = sprintf(
					'<button type="button" class="button-link editinline" aria-label="%s" aria-expanded="false">%s</button>',
					/* translators: %s: Post title. */
					esc_attr( sprintf( __( 'Quick edit &#8220;%s&#8221; inline' ), $title ) ),
					__( 'Quick&nbsp;Edit' )
				);
			}
		}

		if ( 'trash' !== $post->post_status ) {
			$actions['dlm_duplicate_download'] = '<a href="javascript:;" class="dlm-duplicate-download" rel="' . $post->ID . '" data-value="' . wp_create_nonce( 'dlm_duplicate_download_nonce' ) . '">' . __( 'Duplicate Download', 'download-monitor' ) . '</a>';
		}

		if ( current_user_can( 'delete_post', $post->ID ) ) {
			if ( 'trash' === $post->post_status ) {
				$actions['untrash'] = sprintf(
					'<a href="%s" aria-label="%s">%s</a>',
					wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ),
					/* translators: %s: Post title. */
					esc_attr( sprintf( __( 'Restore &#8220;%s&#8221; from the Trash' ), $title ) ),
					__( 'Restore' )
				);
			} elseif ( EMPTY_TRASH_DAYS ) {
				$actions['trash'] = sprintf(
					'<a href="%s" class="submitdelete" aria-label="%s">%s</a>',
					get_delete_post_link( $post->ID ),
					/* translators: %s: Post title. */
					esc_attr( sprintf( __( 'Move &#8220;%s&#8221; to the Trash' ), $title ) ),
					_x( 'Trash', 'verb' )
				);
			}

			if ( 'trash' === $post->post_status || ! EMPTY_TRASH_DAYS ) {
				$actions['delete'] = sprintf(
					'<a href="%s" class="submitdelete" aria-label="%s">%s</a>',
					get_delete_post_link( $post->ID, '', true ),
					/* translators: %s: Post title. */
					esc_attr( sprintf( __( 'Delete &#8220;%s&#8221; permanently' ), $title ) ),
					__( 'Delete Permanently' )
				);
			}
		}

		if ( is_post_type_viewable( $post_type_object ) ) {
			if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ), true ) ) {
				if ( $can_edit_post ) {
					$preview_link    = get_preview_post_link( $post );
					$actions['view'] = sprintf(
						'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
						esc_url( $preview_link ),
						/* translators: %s: Post title. */
						esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ),
						__( 'Preview' )
					);
				}
			} elseif ( 'trash' !== $post->post_status ) {
				$actions['view'] = sprintf(
					'<a href="%s" rel="bookmark" aria-label="%s">%s</a>',
					get_permalink( $post->ID ),
					/* translators: %s: Post title. */
					esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ),
					__( 'View' )
				);
			}
		}

		if ( 'wp_block' === $post->post_type ) {
			$actions['export'] = sprintf(
				'<button type="button" class="wp-list-reusable-blocks__export button-link" data-id="%s" aria-label="%s">%s</button>',
				$post->ID,
				/* translators: %s: Post title. */
				esc_attr( sprintf( __( 'Export &#8220;%s&#8221; as JSON' ), $title ) ),
				__( 'Export as JSON' )
			);
		}

		/**
		 * Filters the array of row action links on the Posts list table.
		 *
		 * The filter is evaluated only for non-hierarchical post types.
		 *
		 * @param  string[]  $actions  An array of row action links. Defaults are
		 *                             'Edit', 'Quick Edit', 'Restore', 'Trash',
		 *                             'Delete Permanently', 'Preview', and 'View'.
		 * @param  WP_Post   $post     The post object.
		 *
		 * @since 5.0.0
		 *
		 */
		$actions = apply_filters( 'post_row_actions', $actions, $post );

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

	/**
	 * Outputs the hidden row displayed when inline editing
	 *
	 * @since 5.0.0
	 *
	 * @global string $mode List table view mode.
	 */
	public function inline_edit() {
		global $mode;

		$screen = $this->screen;

		$post             = get_default_post_to_edit( $screen->post_type );
		$post_type_object = get_post_type_object( $screen->post_type );

		$taxonomy_names          = get_object_taxonomies( $screen->post_type );
		$hierarchical_taxonomies = array();
		$flat_taxonomies         = array();

		foreach ( $taxonomy_names as $taxonomy_name ) {
			$taxonomy = get_taxonomy( $taxonomy_name );

			$show_in_quick_edit = $taxonomy->show_in_quick_edit;

			/**
			 * Filters whether the current taxonomy should be shown in the Quick Edit panel.
			 *
			 * @param  bool    $show_in_quick_edit  Whether to show the current taxonomy in Quick Edit.
			 * @param  string  $taxonomy_name       Taxonomy name.
			 * @param  string  $post_type           Post type of current Quick Edit post.
			 *
			 * @since 5.0.0
			 *
			 */
			if ( ! apply_filters( 'quick_edit_show_taxonomy', $show_in_quick_edit, $taxonomy_name, $screen->post_type ) ) {
				continue;
			}

			if ( $taxonomy->hierarchical ) {
				$hierarchical_taxonomies[] = $taxonomy;
			} else {
				$flat_taxonomies[] = $taxonomy;
			}
		}

		$m            = ( isset( $mode ) && 'excerpt' === $mode ) ? 'excerpt' : 'list';
		$can_publish  = current_user_can( $post_type_object->cap->publish_posts );
		$core_columns = array(
			'cb'         => true,
			'date'       => true,
			'title'      => true,
			'categories' => true,
			'tags'       => true,
			'comments'   => true,
			'author'     => true,
		);
		?>

		<form method="get">
			<table style="display: none">
				<tbody id="inlineedit">
				<?php
				$hclass              = count( $hierarchical_taxonomies ) ? 'post' : 'page';
				$inline_edit_classes = "inline-edit-row inline-edit-row-$hclass";
				$bulk_edit_classes   = "bulk-edit-row bulk-edit-row-$hclass bulk-edit-{$screen->post_type}";
				$quick_edit_classes  = "quick-edit-row quick-edit-row-$hclass inline-edit-{$screen->post_type}";

				$bulk        = 0;

				while ( $bulk < 2 ) :
					$classes = $inline_edit_classes . ' ';
					$classes .= $bulk ? $bulk_edit_classes : $quick_edit_classes;
					?>
					<tr id="<?php
					echo $bulk ? 'bulk-edit' : 'inline-edit'; ?>" class="<?php
					echo $classes; ?>" style="display: none">
						<td colspan="<?php
						echo $this->get_column_count(); ?>" class="colspanchange">
							<div class="inline-edit-wrapper" role="region" aria-labelledby="<?php
							echo $bulk ? 'bulk' : 'quick'; ?>-edit-legend">
								<fieldset class="inline-edit-col-left">
									<legend class="inline-edit-legend" id="<?php
									echo $bulk ? 'bulk' : 'quick'; ?>-edit-legend"><?php
										echo $bulk ? __( 'Bulk Edit' ) : __( 'Quick Edit' ); ?></legend>
									<div class="inline-edit-col">

										<?php
										if ( post_type_supports( $screen->post_type, 'title' ) ) : ?>

											<?php
											if ( $bulk ) : ?>

												<div id="bulk-title-div">
													<div id="bulk-titles"></div>
												</div>

											<?php
											else : // $bulk
												?>

												<label>
													<span class="title"><?php
														_e( 'Title' ); ?></span>
													<span class="input-text-wrap"><input type="text" name="post_title" class="ptitle" value=""/></span>
												</label>

												<?php
												if ( is_post_type_viewable( $screen->post_type ) ) : ?>

													<label>
														<span class="title"><?php
															_e( 'Slug' ); ?></span>
														<span class="input-text-wrap"><input type="text" name="post_name" value="" autocomplete="off" spellcheck="false"/></span>
													</label>

												<?php
												endif; // is_post_type_viewable()
												?>

											<?php
											endif; // $bulk ?>

										<?php
										endif; // post_type_supports( ... 'title' )
										?>

										<?php
										if ( ! $bulk ) : ?>
											<fieldset class="inline-edit-date">
												<legend>
													<span class="title"><?php
														_e( 'Date' ); ?></span>
												</legend>
												<?php
												touch_time( 1, 1, 0, 1 ); ?>
											</fieldset>
											<br class="clear"/>
										<?php
										endif; // $bulk
										?>

										<?php
										if ( post_type_supports( $screen->post_type, 'author' ) ) {
											$authors_dropdown = '';

											if ( current_user_can( $post_type_object->cap->edit_others_posts ) ) {
												$dropdown_name  = 'post_author';
												$dropdown_class = 'authors';
												if ( wp_is_large_user_count() ) {
													$authors_dropdown = sprintf( '<select name="%s" class="%s hidden"></select>', esc_attr( $dropdown_name ), esc_attr( $dropdown_class ) );
												} else {
													$users_opt = array(
														'hide_if_only_one_author' => false,
														'capability'              => array( $post_type_object->cap->edit_posts ),
														'name'                    => $dropdown_name,
														'class'                   => $dropdown_class,
														'multi'                   => 1,
														'echo'                    => 0,
														'show'                    => 'display_name_with_login',
													);

													if ( $bulk ) {
														$users_opt['show_option_none'] = __( '&mdash; No Change &mdash;' );
													}

													/**
													 * Filters the arguments used to generate the Quick Edit authors drop-down.
													 *
													 * @param  array  $users_opt  An array of arguments passed to wp_dropdown_users().
													 * @param  bool   $bulk       A flag to denote if it's a bulk action.
													 *
													 * @since 5.6.0
													 *
													 * @see   wp_dropdown_users()
													 *
													 */
													$users_opt = apply_filters( 'quick_edit_dropdown_authors_args', $users_opt, $bulk );

													$authors = wp_dropdown_users( $users_opt );

													if ( $authors ) {
														$authors_dropdown = '<label class="inline-edit-author">';
														$authors_dropdown .= '<span class="title">' . __( 'Author' ) . '</span>';
														$authors_dropdown .= $authors;
														$authors_dropdown .= '</label>';
													}
												}
											} // current_user_can( 'edit_others_posts' )

											if ( ! $bulk ) {
												echo $authors_dropdown;
											}
										} // post_type_supports( ... 'author' )
										?>

										<?php
										if ( ! $bulk && $can_publish ) : ?>

											<div class="inline-edit-group wp-clearfix">
												<label class="alignleft">
													<span class="title"><?php
														_e( 'Password' ); ?></span>
													<span class="input-text-wrap"><input type="text" name="post_password" class="inline-edit-password-input" value=""/></span>
												</label>

												<span class="alignleft inline-edit-or">
							<?php
							/* translators: Between password field and private checkbox on post quick edit interface. */
							_e( '&ndash;OR&ndash;' );
							?>
						</span>
												<label class="alignleft inline-edit-private">
													<input type="checkbox" name="keep_private" value="private"/>
													<span class="checkbox-title"><?php
														_e( 'Private' ); ?></span>
												</label>
											</div>

										<?php
										endif; ?>

									</div>
								</fieldset>

								<?php
								if ( count( $hierarchical_taxonomies ) && ! $bulk ) : ?>

									<fieldset class="inline-edit-col-center inline-edit-categories">
										<div class="inline-edit-col">

											<?php
											foreach ( $hierarchical_taxonomies as $taxonomy ) : ?>

												<span class="title inline-edit-categories-label"><?php
													echo esc_html( $taxonomy->labels->name ); ?></span>
												<input type="hidden" name="<?php
												echo ( 'category' === $taxonomy->name ) ? 'post_category[]' : 'tax_input[' . esc_attr( $taxonomy->name ) . '][]'; ?>" value="0"/>
												<ul class="cat-checklist <?php
												echo esc_attr( $taxonomy->name ); ?>-checklist">
													<?php
													wp_terms_checklist( 0, array( 'taxonomy' => $taxonomy->name ) ); ?>
												</ul>

											<?php
											endforeach; // $hierarchical_taxonomies as $taxonomy ?>

										</div>
									</fieldset>

								<?php
								endif; // count( $hierarchical_taxonomies ) && ! $bulk
								?>

								<fieldset class="inline-edit-col-right">
									<div class="inline-edit-col">

										<?php
										if ( post_type_supports( $screen->post_type, 'author' ) && $bulk ) {
											echo $authors_dropdown;
										}
										?>

										<?php
										if ( post_type_supports( $screen->post_type, 'page-attributes' ) ) : ?>

											<?php
											if ( $post_type_object->hierarchical ) : ?>

												<label>
													<span class="title"><?php
														_e( 'Parent' ); ?></span>
													<?php
													$dropdown_args = array(
														'post_type'         => $post_type_object->name,
														'selected'          => $post->post_parent,
														'name'              => 'post_parent',
														'show_option_none'  => __( 'Main Page (no parent)' ),
														'option_none_value' => 0,
														'sort_column'       => 'menu_order, post_title',
													);

													if ( $bulk ) {
														$dropdown_args['show_option_no_change'] = __( '&mdash; No Change &mdash;' );
													}

													/**
													 * Filters the arguments used to generate the Quick Edit page-parent drop-down.
													 *
													 * @param  array  $dropdown_args  An array of arguments passed to wp_dropdown_pages().
													 * @param  bool   $bulk           A flag to denote if it's a bulk action.
													 *
													 * @see   wp_dropdown_pages()
													 *
													 * @since 2.7.0
													 * @since 5.6.0 The `$bulk` parameter was added.
													 *
													 */
													$dropdown_args = apply_filters( 'quick_edit_dropdown_pages_args', $dropdown_args, $bulk );

													wp_dropdown_pages( $dropdown_args );
													?>
												</label>

											<?php
											endif; // hierarchical ?>

											<?php
											if ( ! $bulk ) : ?>

												<label>
													<span class="title"><?php
														_e( 'Order' ); ?></span>
													<span class="input-text-wrap"><input type="text" name="menu_order" class="inline-edit-menu-order-input" value="<?php
														echo $post->menu_order; ?>"/></span>
												</label>

											<?php
											endif; // ! $bulk ?>

										<?php
										endif; // post_type_supports( ... 'page-attributes' )
										?>

										<?php
										if ( 0 < count( get_page_templates( null, $screen->post_type ) ) ) : ?>

											<label>
												<span class="title"><?php
													_e( 'Template' ); ?></span>
												<select name="page_template">
													<?php
													if ( $bulk ) : ?>
														<option value="-1"><?php
															_e( '&mdash; No Change &mdash;' ); ?></option>
													<?php
													endif; // $bulk ?>
													<?php
													/** This filter is documented in wp-admin/includes/meta-boxes.php */
													$default_title = apply_filters( 'default_page_template_title', __( 'Default template' ), 'quick-edit' );
													?>
													<option value="default"><?php
														echo esc_html( $default_title ); ?></option>
													<?php
													page_template_dropdown( '', $screen->post_type ); ?>
												</select>
											</label>

										<?php
										endif; ?>

										<?php
										if ( count( $flat_taxonomies ) && ! $bulk ) : ?>

											<?php
											foreach ( $flat_taxonomies as $taxonomy ) : ?>

												<?php
												if ( current_user_can( $taxonomy->cap->assign_terms ) ) : ?>
													<?php
													$taxonomy_name = esc_attr( $taxonomy->name ); ?>
													<div class="inline-edit-tags-wrap">
														<label class="inline-edit-tags">
															<span class="title"><?php
																echo esc_html( $taxonomy->labels->name ); ?></span>
															<textarea data-wp-taxonomy="<?php
															echo $taxonomy_name; ?>" cols="22" rows="1" name="tax_input[<?php
															echo esc_attr( $taxonomy->name ); ?>]" class="tax_input_<?php
															echo esc_attr( $taxonomy->name ); ?>" aria-describedby="inline-edit-<?php
															echo esc_attr( $taxonomy->name ); ?>-desc"></textarea>
														</label>
														<p class="howto" id="inline-edit-<?php
														echo esc_attr( $taxonomy->name ); ?>-desc"><?php
															echo esc_html( $taxonomy->labels->separate_items_with_commas ); ?></p>
													</div>
												<?php
												endif; // current_user_can( 'assign_terms' ) ?>

											<?php
											endforeach; // $flat_taxonomies as $taxonomy ?>

										<?php
										endif; // count( $flat_taxonomies ) && ! $bulk
										?>

										<?php
										if ( post_type_supports( $screen->post_type, 'comments' ) || post_type_supports( $screen->post_type, 'trackbacks' ) ) : ?>

											<?php
											if ( $bulk ) : ?>

												<div class="inline-edit-group wp-clearfix">

													<?php
													if ( post_type_supports( $screen->post_type, 'comments' ) ) : ?>

														<label class="alignleft">
															<span class="title"><?php
																_e( 'Comments' ); ?></span>
															<select name="comment_status">
																<option value=""><?php
																	_e( '&mdash; No Change &mdash;' ); ?></option>
																<option value="open"><?php
																	_e( 'Allow' ); ?></option>
																<option value="closed"><?php
																	_e( 'Do not allow' ); ?></option>
															</select>
														</label>

													<?php
													endif; ?>

													<?php
													if ( post_type_supports( $screen->post_type, 'trackbacks' ) ) : ?>

														<label class="alignright">
															<span class="title"><?php
																_e( 'Pings' ); ?></span>
															<select name="ping_status">
																<option value=""><?php
																	_e( '&mdash; No Change &mdash;' ); ?></option>
																<option value="open"><?php
																	_e( 'Allow' ); ?></option>
																<option value="closed"><?php
																	_e( 'Do not allow' ); ?></option>
															</select>
														</label>

													<?php
													endif; ?>

												</div>

											<?php
											else : // $bulk
												?>

												<div class="inline-edit-group wp-clearfix">

													<?php
													if ( post_type_supports( $screen->post_type, 'comments' ) ) : ?>

														<label class="alignleft">
															<input type="checkbox" name="comment_status" value="open"/>
															<span class="checkbox-title"><?php
																_e( 'Allow Comments' ); ?></span>
														</label>

													<?php
													endif; ?>

													<?php
													if ( post_type_supports( $screen->post_type, 'trackbacks' ) ) : ?>

														<label class="alignleft">
															<input type="checkbox" name="ping_status" value="open"/>
															<span class="checkbox-title"><?php
																_e( 'Allow Pings' ); ?></span>
														</label>

													<?php
													endif; ?>

												</div>

											<?php
											endif; // $bulk ?>

										<?php
										endif; // post_type_supports( ... comments or pings )
										?>

										<div class="inline-edit-group wp-clearfix">

											<label class="inline-edit-status alignleft">
												<span class="title"><?php
													_e( 'Status' ); ?></span>
												<select name="_status">
													<?php
													if ( $bulk ) : ?>
														<option value="-1"><?php
															_e( '&mdash; No Change &mdash;' ); ?></option>
													<?php
													endif; // $bulk
													?>

													<?php
													if ( $can_publish ) : // Contributors only get "Unpublished" and "Pending Review".
														?>
														<option value="publish"><?php
															_e( 'Published' ); ?></option>
														<option value="future"><?php
															_e( 'Scheduled' ); ?></option>
														<?php
														if ( $bulk ) : ?>
															<option value="private"><?php
																_e( 'Private' ); ?></option>
														<?php
														endif; // $bulk
														?>
													<?php
													endif; ?>

													<option value="pending"><?php
														_e( 'Pending Review' ); ?></option>
													<option value="draft"><?php
														_e( 'Draft' ); ?></option>
												</select>
											</label>

											<?php
											if ( 'post' === $screen->post_type && $can_publish && current_user_can( $post_type_object->cap->edit_others_posts ) ) : ?>

												<?php
												if ( $bulk ) : ?>

													<label class="alignright">
														<span class="title"><?php
															_e( 'Sticky' ); ?></span>
														<select name="sticky">
															<option value="-1"><?php
																_e( '&mdash; No Change &mdash;' ); ?></option>
															<option value="sticky"><?php
																_e( 'Sticky' ); ?></option>
															<option value="unsticky"><?php
																_e( 'Not Sticky' ); ?></option>
														</select>
													</label>

												<?php
												else : // $bulk
													?>

													<label class="alignleft">
														<input type="checkbox" name="sticky" value="sticky"/>
														<span class="checkbox-title"><?php
															_e( 'Make this post sticky' ); ?></span>
													</label>

												<?php
												endif; // $bulk ?>

											<?php
											endif; // 'post' && $can_publish && current_user_can( 'edit_others_posts' )
											?>

										</div>

										<?php
										if ( $bulk && current_theme_supports( 'post-formats' ) && post_type_supports( $screen->post_type, 'post-formats' ) ) : ?>
											<?php
											$post_formats = get_theme_support( 'post-formats' ); ?>

											<label class="alignleft">
												<span class="title"><?php
													_ex( 'Format', 'post format' ); ?></span>
												<select name="post_format">
													<option value="-1"><?php
														_e( '&mdash; No Change &mdash;' ); ?></option>
													<option value="0"><?php
														echo get_post_format_string( 'standard' ); ?></option>
													<?php
													if ( is_array( $post_formats[0] ) ) : ?>
														<?php
														foreach ( $post_formats[0] as $format ) : ?>
															<option value="<?php
															echo esc_attr( $format ); ?>"><?php
																echo esc_html( get_post_format_string( $format ) ); ?></option>
														<?php
														endforeach; ?>
													<?php
													endif; ?>
												</select>
											</label>

										<?php
										endif; ?>

									</div>
								</fieldset>

								<?php
								list( $columns ) = $this->get_column_info();

								foreach ( $columns as $column_name => $column_display_name ) {
									if ( isset( $core_columns[ $column_name ] ) ) {
										continue;
									}

									if ( $bulk ) {
										/**
										 * Fires once for each column in Bulk Edit mode.
										 *
										 * @param  string  $column_name  Name of the column to edit.
										 * @param  string  $post_type    The post type slug.
										 *
										 * @since 5.0.0
										 *
										 */
										do_action( 'bulk_edit_custom_box', $column_name, $screen->post_type );
									} else {
										/**
										 * Fires once for each column in Quick Edit mode.
										 *
										 * @param  string  $column_name  Name of the column to edit.
										 * @param  string  $post_type    The post type slug, or current screen name if this is a taxonomy list table.
										 * @param  string  $taxonomy     The taxonomy name, if any.
										 *
										 * @since 5.0.0
										 *
										 */
										do_action( 'quick_edit_custom_box', $column_name, $screen->post_type, '' );
									}
								}
								?>

								<div class="submit inline-edit-save">
									<?php
									if ( ! $bulk ) : ?>
										<?php
										wp_nonce_field( 'inlineeditnonce', '_inline_edit', false ); ?>
										<button type="button" class="button button-primary save"><?php
											_e( 'Update' ); ?></button>
									<?php
									else : ?>
										<?php
										submit_button( __( 'Update' ), 'primary', 'bulk_edit', false ); ?>
									<?php
									endif; ?>

									<button type="button" class="button cancel"><?php
										_e( 'Cancel' ); ?></button>

									<?php
									if ( ! $bulk ) : ?>
										<span class="spinner"></span>
									<?php
									endif; ?>

									<input type="hidden" name="post_view" value="<?php
									echo esc_attr( $m ); ?>"/>
									<input type="hidden" name="screen" value="<?php
									echo esc_attr( $screen->id ); ?>"/>
									<?php
									if ( ! $bulk && ! post_type_supports( $screen->post_type, 'author' ) ) : ?>
										<input type="hidden" name="post_author" value="<?php
										echo esc_attr( $post->post_author ); ?>"/>
									<?php
									endif; ?>

									<?php
									wp_admin_notice(
										'<p class="error"></p>',
										array(
											'type'               => 'error',
											'additional_classes' => array( 'notice-alt', 'inline', 'hidden' ),
											'paragraph_wrap'     => false,
										)
									);
									?>
								</div>
							</div> <!-- end of .inline-edit-wrapper -->

						</td>
					</tr>

					<?php
					++ $bulk;
				endwhile;
				?>
				</tbody>
			</table>
		</form>
		<?php
	}

	/**
	 * Generates the table navigation above or below the table
	 *
	 * @param  string  $which
	 *
	 * @since 5.0.0
	 */
	protected function display_tablenav( $which ) {
		if ( 'top' === $which ) {
			wp_nonce_field( 'bulk-posts' );
		}

		?>
		<div class="tablenav <?php
		echo esc_attr( $which ); ?>">

			<?php
			if ( $this->has_items() ) : ?>
				<div class="alignleft actions bulkactions">
					<?php
					$this->bulk_actions( $which ); ?>
				</div>
			<?php
			endif;

			if ( 'top' === $which ) {
				$this->extra_tablenav( $which );
			}
			$this->pagination( $which );
			?>

			<br class="clear"/>
		</div>
		<?php
	}

	/**
	 * Display the extension tab.
	 *
	 * @since 5.0.0
	 */
	public function display_extension_tab() {
		?>
		<h2 class="nav-tab-wrapper">
			<?php
			$tabs = array(
				'downloads'       => array(
					'name'     => __( 'Downloads', 'download-monitor' ),
					'url'      => admin_url( 'edit.php?post_type=dlm_download' ),
					'priority' => '1',
				),
			);

			if ( current_user_can( 'install_plugins' ) ) {
				$tabs['extensions'] = array(
					'name'     => esc_html__( 'Extensions',
					                          'download-monitor' ),
					'url'      => esc_url( admin_url( 'edit.php?post_type=dlm_download&page=dlm-extensions' ) ),
					'priority' => '5',
				);
			}

			/**
			 * Hook for DLM CPT table view tabs
			 *
			 * @hooked DLM_Admin_Extensions dlm_cpt_tabs()
			 *
			 * @moved  5.0.0 Moved here from CustomColumns.php
			 */
			$tabs = apply_filters( 'dlm_add_edit_tabs', $tabs );

			uasort( $tabs, array( 'DLM_Admin_Helper', 'sort_data_by_priority' ) );

			DLM_Admin_Helper::dlm_tab_navigation( $tabs, 'downloads' );
			?>
		</h2>
		<br/>
		<?php
	}

	/**
	 * Displays the list of views available on this table.
	 *
	 * @since 5.0.0
	 */
	public function views() {
		// Display the extension tab.
		$this->display_extension_tab();
		// Get the views for the current screen.
		$views = $this->get_views();
		/**
		 * Filters the list of available list table views.
		 *
		 * The dynamic portion of the hook name, `$this->screen->id`, refers
		 * to the ID of the current screen.
		 *
		 * @param  string[]  $views  An array of available list table views.
		 *
		 * @since 5.0.0
		 *
		 */
		$views = apply_filters( "views_{$this->screen->id}", $views );

		if ( empty( $views ) ) {
			return;
		}

		$this->screen->render_screen_reader_content( 'heading_views' );

		echo "<ul class='subsubsub'>\n";
		foreach ( $views as $class => $view ) {
			$views[ $class ] = "\t<li class='$class'>$view";
		}
		echo implode( " |</li>\n", $views ) . "</li>\n";
		echo '</ul>';
	}
}
