* @since 1.48.2
*/
namespace AdvancedAds\Admin;
defined( 'ABSPATH' ) || exit;
use AdvancedAds\Options;
use AdvancedAds\Constants;
use AdvancedAds\Abstracts\Ad;
use AdvancedAds\Abstracts\Admin_List_Table;
use AdvancedAds\Framework\Utilities\Params;
defined( 'ABSPATH' ) || exit;
/**
* Admin Ad List Table.
*/
class Ad_List_Table extends Admin_List_Table {
/**
* Object being shown on the row.
*
* @var Ad|null
*/
protected $object = null;
/**
* Object type.
*
* @var string
*/
protected $object_type = 'ad';
/**
* Post type.
*
* @var string
*/
protected $list_table_type = Constants::POST_TYPE_AD;
/**
* Hook into WordPress.
*
* @return void
*/
public function hooks(): void {
parent::hooks();
add_filter( 'pre_get_posts', [ $this, 'posts_ordering' ] );
add_action( 'manage_posts_extra_tablenav', [ $this, 'display_views' ] );
add_filter( 'views_edit-' . $this->list_table_type, [ $this, 'add_views' ] );
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
*
* @return array
*/
public function define_columns( $columns ): array {
// Remove the group taxonomy column as we have custom 'Used' column.
unset( $columns[ 'taxonomy-' . Constants::TAXONOMY_GROUP ] );
$new_columns = [];
foreach ( $columns as $key => $value ) {
$new_columns[ $key ] = $value;
if ( 'cb' === $key ) {
$new_columns['ad_type'] = __( 'Type', 'advanced-ads' );
continue;
}
if ( 'title' === $key ) {
$new_columns['title'] = __( 'Name', 'advanced-ads' );
$new_columns['ad_size'] = __( 'Size', 'advanced-ads' );
$new_columns['ad_timing'] = __( 'Ad Planning', 'advanced-ads' );
$new_columns['ad_shortcode'] = __( 'Ad Shortcode', 'advanced-ads' );
$new_columns['ad_adsense_id'] = __( 'AdSense ID', 'advanced-ads' );
$new_columns['ad_date'] = __( 'Date', 'advanced-ads' );
$new_columns['ad_description'] = __( 'Notes', 'advanced-ads' );
$new_columns['ad_preview'] = __( 'Preview', 'advanced-ads' );
$new_columns['ad_used'] = __( 'Used', 'advanced-ads' );
$new_columns['ad_debugmode'] = __( 'Debug Mode', 'advanced-ads' );
// show only when privacy setting is enabled.
if ( Options::instance()->get( 'privacy.enabled' ) ) {
$new_columns['ad_privacyignore'] = __( 'Privacy Ignore', 'advanced-ads' );
}
}
}
unset( $new_columns['date'] );
return apply_filters( 'advanced-ads-ad-columns', $new_columns );
}
/**
* Define which columns are sortable.
*
* @param array $columns Existing columns.
*
* @return array
*/
public function define_sortable_columns( $columns ): array {
$columns['ad_date'] = 'ad_date';
return $columns;
}
/**
* Define hidden columns.
*
* @return array
*/
protected function define_hidden_columns(): array {
$hidden[] = 'ad_description';
$hidden[] = 'author';
$hidden[] = 'ad_size';
$hidden[] = 'ad_shortcode';
$hidden[] = 'ad_date';
$hidden[] = 'ad_preview';
$hidden[] = 'ad_adsense_id';
$hidden[] = 'ad_debugmode';
$hidden[] = 'ad_privacyignore';
return $hidden;
}
/**
* Render any custom filters and search inputs for the list table.
*
* @return void
*/
protected function render_filters(): void {
$addate = Params::get( 'addate' );
if ( ! empty( $addate ) ) {
printf( '', esc_attr( $addate ) );
}
include ADVADS_ABSPATH . 'views/admin/tables/ads/filters.php';
}
/**
* Add expiring and expired ads view.
*
* @param array $views Available list table views.
*
* @return array
*/
public function add_views( $views ): array {
$counts = wp_count_posts( $this->list_table_type, 'readable' );
$expired = $counts->{Constants::AD_STATUS_EXPIRED};
$expiring = $counts->{Constants::AD_STATUS_EXPIRING};
if ( $expiring > 0 ) {
$views[ Constants::AD_STATUS_EXPIRING ] = sprintf(
'%s (%d)',
add_query_arg(
[
'post_type' => Constants::POST_TYPE_AD,
'addate' => 'advads-filter-expiring',
'orderby' => 'expiry_date',
'order' => 'ASC',
],
'edit.php'
),
'advads-filter-expiring' === Params::request( 'addate' ) ? 'class="current" aria-current="page"' : '',
esc_attr_x( 'Expiring', 'Post list header for ads expiring in the future.', 'advanced-ads' ),
$expiring
);
}
if ( $expired > 0 ) {
$views[ Constants::AD_STATUS_EXPIRED ] = sprintf(
'%s (%d)',
add_query_arg(
[
'post_type' => Constants::POST_TYPE_AD,
'addate' => 'advads-filter-expired',
'orderby' => 'expiry_date',
'order' => 'DESC',
],
'edit.php'
),
'advads-filter-expired' === Params::request( 'addate' ) ? 'class="current" aria-current="page"' : '',
esc_attr_x( 'Expired', 'Post list header for expired ads.', 'advanced-ads' ),
$expired
);
}
return $views;
}
/**
* Displays the list of views available for Ads.
*
* @param string $which The location of the extra table nav markup.
*
* @return void
*/
public function display_views( $which ): void {
global $wp_list_table;
if ( 'top' !== $which ) {
return;
}
$views = $wp_list_table->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.
*/
$views = apply_filters( "views_{$wp_list_table->screen->id}", $views );
if ( empty( $views ) ) {
return;
}
$wp_list_table->screen->render_screen_reader_content( 'heading_views' );
$is_all = count(
array_diff_key(
$_GET, // phpcs:ignore WordPress.Security.NonceVerification.Recommended
[
'post_type' => Constants::POST_TYPE_AD,
'orderby' => '',
'order' => '',
'paged' => '',
'mode' => '',
]
)
) === 0;
$show_trash_delete_button = 'trash' === Params::get( 'post_status', false ) && have_posts() && current_user_can( get_post_type_object( $wp_list_table->screen->post_type )->cap->edit_others_posts );
include ADVADS_ABSPATH . 'views/admin/tables/ads/view-list.php';
}
/**
* Query filters.
*
* @param array $query_vars Query vars.
*
* @return array
*/
protected function query_filters( $query_vars ): array {
// Early bail!!
if ( wp_doing_ajax() ) {
return $query_vars;
}
if ( 'expiry_date' === $query_vars['orderby'] ) {
$query_vars['orderby'] = 'meta_value';
$query_vars['meta_key'] = Constants::AD_META_EXPIRATION_TIME; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
$query_vars['order'] = strtoupper( $query_vars['order'] ) === 'DESC' ? 'DESC' : 'ASC';
if ( 'advads-filter-expired' === Params::get( 'addate' ) ) {
$query_vars['post_status'] = Constants::AD_STATUS_EXPIRED;
}
}
$filter_author = Params::get( 'ad_author' );
if ( $filter_author ) {
$query_vars['author'] = $filter_author;
}
return $query_vars;
}
/**
* Modify the post listing order in the admin panel for a specific custom post type.
*
* @param WP_Query $query The WP_Query object.
*
* @return void
*/
public function posts_ordering( $query ): void {
global $typenow;
// Early bail!!
if ( ! $query->is_main_query() ) {
return;
}
if ( $this->list_table_type === $typenow ) {
$orderby = Params::get( 'orderby', 'title' );
$order = strtoupper( Params::get( 'order', 'ASC' ) );
if ( 'ad_date' === $orderby ) {
$orderby = 'post_modified';
}
$query->set( 'orderby', $orderby );
$query->set( 'order', $order );
}
}
/**
* Pre-fetch any data for the row each column has access to it.
*
* @param int $post_id Post ID being shown.
*
* @return void
*/
protected function prepare_row_data( $post_id ): void {
if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) {
$this->object = wp_advads_get_ad( $post_id );
}
}
/**
* Display the ad type icon in the ads list.
*
* @return void
*/
protected function render_ad_type_column(): void {
$ad = $this->object;
$size_string = $this->get_ad_size_string();
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-type.php';
}
/**
* Display the ad description in the ads list
*
* @return void
*/
protected function render_ad_description_column(): void {
$description = wp_trim_words( $this->object->get_description(), 50 );
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-description.php';
}
/**
* Display an ad preview in ads list.
*
* @return void
*/
protected function render_ad_preview_column(): void {
$type_object = $this->object->get_type_object();
// Early bail!!
if ( ! $type_object ) {
return;
}
if ( is_callable( [ $type_object, 'render_preview' ] ) ) {
$type_object->render_preview( $this->object );
}
do_action( 'advanced-ads-ad-list-details-column-after', $this->object, $type_object );
}
/**
* Display the ad size in the ads list
*
* @return void
*/
protected function render_ad_size_column(): void {
$size = $this->get_ad_size_string();
// Early bail!!
if ( empty( $size ) ) {
return;
}
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-size.php';
}
/**
* Display ad timing in ads list
*
* @return void
*/
protected function render_ad_timing_column(): void {
list(
'status_strings' => $status_strings,
'html_classes' => $html_classes,
) = $this->object->get_ad_schedule_details();
ob_start();
do_action_ref_array(
'advanced-ads-ad-list-timing-column-after',
[
$this->object,
&$html_classes,
]
);
$content_after = ob_get_clean();
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-timing.php';
}
/**
* Display ad shortcode in ads list
*
* @return void
*/
protected function render_ad_shortcode_column(): void {
$ad_id = $this->object->get_id();
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-shortcode.php';
}
/**
* Display an ad date in ads list.
*
* @return void
*/
protected function render_ad_date_column(): void {
$id = $this->object->get_id();
if ( ! $id ) {
return;
}
$datetime_regex = get_option( 'date_format' ) . ' \\a\\t ' . get_option( 'time_format' );
$published_date = get_the_date( $datetime_regex, $id );
$modified_date = get_the_modified_date( $datetime_regex, $id );
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-date.php';
}
/**
* Display the adsense id.
*
* @return void
*/
protected function render_ad_adsense_id_column(): void {
if ( null === $this->object->get_content() ) {
return;
}
$content = json_decode( $this->object->get_content() );
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$slotid = $content->slotId ?? null;
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-adsense.php';
}
/**
* Display ad usage in groups & placements.
*
* @return void
*/
protected function render_ad_used_column(): void {
$ad_id = $this->object->get_id();
if ( ! $ad_id ) {
return;
}
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-used.php';
}
/**
* Display the debug mode in the ads list.
*
* @return void
*/
protected function render_ad_debugmode_column(): void {
$debug_mode = $this->object->is_debug_mode();
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-debug.php';
}
/**
* Display the privacy ignore status in the ads list.
*
* @return void
*/
protected function render_ad_privacyignore_column(): void {
$privacyignore = $this->object->get_prop( 'privacy.ignore-consent' ) ?? false;
include ADVADS_ABSPATH . 'views/admin/tables/ads/column-privacyignore.php';
}
/**
* Get the ad size string to display in post list.
*
* @return string
*/
private function get_ad_size_string(): string {
$size = '';
if ( ! empty( $this->object->get_width() ) || ! empty( $this->object->get_height() ) ) {
$size = sprintf( '%d × %d', $this->object->get_width(), $this->object->get_height() );
}
/**
* Filter the ad size string to display in the ads post list.
*
* @param string $size Size string.
* @param Ad $ad Ad instance.
*/
return (string) apply_filters( 'advanced-ads-list-ad-size', $size, $this->object );
}
}