Newer
Older
tonitalia-pluginsoci / admin / class-registration-list-table.php
<?php
/**
 * Admin list table for registrations.
 *
 * @package TonItaliaRegistration
 */

defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

/**
 * Class TON_Reg_Registration_List_Table
 */
class TON_Reg_Registration_List_Table extends WP_List_Table {

	/**
	 * @var array<int,string>
	 */
	private $renewal_statuses = array();

	/**
	 * @var int
	 */
	private $renewal_year = 0;

	/**
	 * @var string
	 */
	private $list_status = '';

	/**
	 * @var string
	 */
	private $list_search = '';

	/**
	 * @var bool
	 */
	private $list_renewal_unpaid = false;

	/**
	 * @var string
	 */
	private $list_orderby = 'created_at';

	/**
	 * @var string
	 */
	private $list_order = 'DESC';

	/**
	 * Constructor.
	 */
	public function __construct() {
		parent::__construct(
			array(
				'singular' => 'registration',
				'plural'   => 'registrations',
				'ajax'     => false,
			)
		);
	}

	/**
	 * @return array<string,string>
	 */
	public function get_columns() {
		return array(
			'id'         => __( 'ID', 'ton-italia-registration' ),
			'cognome'    => __( 'Cognome', 'ton-italia-registration' ),
			'nome'       => __( 'Nome', 'ton-italia-registration' ),
			'email'      => __( 'Email', 'ton-italia-registration' ),
			'status'     => __( 'Stato', 'ton-italia-registration' ),
			'renewal'    => __( 'Rinnovo', 'ton-italia-registration' ),
			'created_at' => __( 'Data', 'ton-italia-registration' ),
		);
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_id( $item ) {
		return (string) (int) $item->id;
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_cognome( $item ) {
		$view_url = $this->build_detail_url( (int) $item->id );
		$name     = trim( ( $item->cognome ?? '' ) . ' ' . ( $item->nome ?? '' ) );
		$actions  = array(
			'view' => '<a href="' . esc_url( $view_url ) . '">' . esc_html__( 'Dettaglio', 'ton-italia-registration' ) . '</a>',
		);

		return '<strong><a class="row-title" href="' . esc_url( $view_url ) . '">' . esc_html( $name ) . '</a></strong>' . $this->row_actions( $actions );
	}

	/**
	 * @param int $id Registration ID.
	 * @return string
	 */
	private function build_detail_url( $id ) {
		return TON_Reg_Admin::detail_url( $id, $this->get_list_context() );
	}

	/**
	 * @return array<string,mixed>
	 */
	public function get_list_context() {
		return array(
			'status'         => $this->list_status,
			'search'         => $this->list_search,
			'renewal_unpaid' => $this->list_renewal_unpaid,
			'renewal_year'   => $this->renewal_year,
			'orderby'        => $this->list_orderby,
			'order'          => $this->list_order,
		);
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_email( $item ) {
		$email = $item->email ?? '';
		if ( ! $email ) {
			return '';
		}

		return '<a href="mailto:' . esc_attr( $email ) . '">' . esc_html( $email ) . '</a>';
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_created_at( $item ) {
		$value = $item->created_at ?? '';
		if ( ! $value ) {
			return '';
		}

		$timestamp = strtotime( $value );
		if ( ! $timestamp ) {
			return esc_html( $value );
		}

		return esc_html( wp_date( 'd/m/Y H:i', $timestamp ) );
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_status( $item ) {
		$labels = array(
			'pending'  => __( 'In attesa', 'ton-italia-registration' ),
			'admitted' => __( 'Ammesso', 'ton-italia-registration' ),
			'rejected' => __( 'Non ammesso', 'ton-italia-registration' ),
		);
		$status = $item->status ?? '';
		$label  = $labels[ $status ] ?? $status;
		$class  = 'ton-reg-status ton-reg-status--' . sanitize_html_class( $status );

		if ( $item->anonymized_at ) {
			$label .= ' (' . __( 'anonimizzato', 'ton-italia-registration' ) . ')';
			$class .= ' ton-reg-status--anonymized';
		}

		return '<span class="' . esc_attr( $class ) . '">' . esc_html( $label ) . '</span>';
	}

	/**
	 * @param object $item Item.
	 * @return string
	 */
	public function column_renewal( $item ) {
		if ( 'admitted' !== ( $item->status ?? '' ) || ! empty( $item->anonymized_at ) ) {
			return '<span class="ton-reg-renewal ton-reg-renewal--na">&mdash;</span>';
		}

		$id     = (int) $item->id;
		$status = $this->renewal_statuses[ $id ] ?? TON_Reg_Membership_Renewals::STATUS_PENDING;
		$badge  = TON_Reg_Membership_Renewals::display_badge( $status, $this->renewal_year );

		return '<span class="ton-reg-renewal ' . esc_attr( $badge['class'] ) . '">' . esc_html( $badge['label'] ) . '</span>';
	}

	/**
	 * @param object $item        Item.
	 * @param string $column_name Column.
	 * @return string
	 */
	public function column_default( $item, $column_name ) {
		return esc_html( $item->$column_name ?? '' );
	}

	/**
	 * @return string
	 */
	protected function get_primary_column_name() {
		return 'cognome';
	}

	/**
	 * @return array<string,bool>
	 */
	protected function get_sortable_columns() {
		return array(
			'cognome'    => array( 'cognome', false ),
			'created_at' => array( 'created_at', true ),
			'status'     => array( 'status', false ),
		);
	}

	/**
	 * Prepare items.
	 */
	public function prepare_items() {
		$per_page       = 20;
		$status         = isset( $_REQUEST['status'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status'] ) ) : '';
		$search         = isset( $_REQUEST['s'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ) : '';
		$renewal_unpaid = ! empty( $_REQUEST['renewal_unpaid'] );
		$this->renewal_year      = TON_Reg_Membership_Renewals::current_year();
		$this->list_status       = $status;
		$this->list_search       = $search;
		$this->list_renewal_unpaid = $renewal_unpaid;

		$orderby = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'created_at';
		$order   = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'DESC';
		$allowed_orderby         = array( 'id', 'created_at', 'cognome', 'nome', 'email', 'status' );
		$this->list_orderby      = in_array( $orderby, $allowed_orderby, true ) ? $orderby : 'created_at';
		$this->list_order        = 'ASC' === strtoupper( $order ) ? 'ASC' : 'DESC';

		$query_args = array(
			'status'         => $status,
			'search'         => $search,
			'renewal_unpaid' => $renewal_unpaid,
			'renewal_year'   => $this->renewal_year,
			'orderby'        => $this->list_orderby,
			'order'          => $this->list_order,
		);

		$total = TON_Reg_Database::count( $query_args );

		$total_pages = max( 1, (int) ceil( $total / $per_page ) );
		$page        = max( 1, min( $this->get_pagenum(), $total_pages ) );

		$this->items = TON_Reg_Database::query(
			array_merge(
				$query_args,
				array(
					'limit'  => $per_page,
					'offset' => ( $page - 1 ) * $per_page,
				)
			)
		);

		$ids = array_map(
			static function ( $item ) {
				return (int) $item->id;
			},
			$this->items
		);
		$this->renewal_statuses = TON_Reg_Membership_Renewals::get_statuses_for_registrations( $ids, $this->renewal_year );

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

		$columns  = $this->get_columns();
		$hidden   = array();
		$sortable = $this->get_sortable_columns();
		$this->_column_headers = array( $columns, $hidden, $sortable );
	}

	/**
	 * @return string
	 */
	public function no_items() {
		esc_html_e( 'Nessuna iscrizione trovata.', 'ton-italia-registration' );
	}
}