<?php defined( 'ABSPATH' ) OR die( 'This script cannot be accessed directly.' );

/**
 * Post List
 */

// Never output a 'loop' element inside other 'loop' elements
if ( us_in_the_loop() ) {
	return;
}

if ( $post_author == 'current_user' AND ! is_user_logged_in() ) {
	return;
}

// Required checks, when this template is loaded via ajax
$filled_atts = $filled_atts ?? $vars;
$paged = $paged ?? 1;

// Force "Numbered" pagination for AMP version to avoid AMP ajax developing
if ( us_amp() AND $pagination != 'none' ) {
	$pagination = 'numbered';
}
global $us_ajax_list_pagination;
if (
	$pagination == 'numbered'
	OR $pagination == 'numbered_ajax'
	OR $us_ajax_list_pagination
) {
	// Fix for get_query_var() that is empty on AMP frontpage
	$request_paged = ( is_front_page() AND ! us_amp() ) ? 'page' : 'paged';

	if ( get_query_var( $request_paged ) ) {
		$paged = get_query_var( $request_paged );
	}
}

// Get the ID of the current object (post, term, user)
$current_object_id = us_get_current_id();

/*
 * Generate query for WP_Query
 */
$query_args = array(
	'ignore_sticky_posts' => (bool) $ignore_sticky_posts,
	'post__not_in' => array(),
	'tax_query' => array(),
	'meta_query' => array(),
	'posts_per_page' => $show_all ? 999 : (int) $quantity,
	'paged' => $paged,

	// When TRUE, allows the current list be triggered by List Filter, List Order, List Search elements
	'apply_list_url_params' => ( $apply_url_params OR $source == 'current_wp_query' ) AND $shortcode_base != 'us_post_carousel',
);

if ( $source == 'current_wp_query' ) {

	// Live Builder can't show the current query, so we need to immitate the output
	if ( usb_is_preview() ) {

		$query_args['posts_per_page'] = $posts_per_archive_page ?: get_option( 'posts_per_page', 10 );

		// Get global query vars and append them to the list query
	} else {
		global $wp_query;
		$query_args += $wp_query->query_vars;
		$query_args['posts_per_page'] = $wp_query->posts_per_page;

		if ( $posts_per_archive_page ) {
			$query_args['posts_per_archive_page'] = (int) $posts_per_archive_page;
		}
	}

} else {
	$query_args['post_type'] = 'any'; // required because the 'post' is used when 'post_type' is not set
}

// If there is no pagination, then disable page count
if ( $pagination == 'none' ) {
	$query_args['no_found_rows'] = TRUE; // speeds up the query
}

// Post status is required, because ajax actions can show draft posts
if ( function_exists( 'wp_get_current_user' ) AND current_user_can( 'read_private_posts' ) ) {
	$query_args['post_status'] = array( 'publish', 'private' );
} else {
	$query_args['post_status'] = 'publish';
}

if ( $post_type AND $source != 'current_wp_query' ) {
	$query_args['post_type'] = explode( ',', $post_type );
}

// Exclude child posts
if ( $exclude_children ) {
	$query_args['post_parent'] = '0';
}

// Selected posts
if ( $source == 'post__in' ) {
	$query_args['post__in'] = explode( ',', $ids );

	// Exclude selected posts
} elseif ( $source == 'post__not_in' ) {
	$query_args['post__not_in'] = explode( ',', $ids );

	// Child posts of the current one
} elseif ( $source == 'child_posts_of_current' AND ! usb_is_template_preview() ) {
	$query_args['post_parent'] = $current_object_id;
	$query_args['post_type'] = 'any';

	// Child posts of selected posts
} elseif ( $source == 'child_posts_of_selected' ) {
	$query_args['post_parent__in'] = explode( ',', $ids );

	// Favorites of the current user
} elseif ( $source == 'user_favorite_ids' AND ! usb_is_preview() ) {
	$user_favorite_ids = us_get_user_favorite_post_ids();

	// Use the non-existing id to get no results, because empty 'post__in' is ignored by query
	if ( ! $user_favorite_ids ) {
		$user_favorite_ids = array( 0 );
	}

	$query_args['post__in'] = (array) $user_favorite_ids;

	// Media (attachment)
} elseif ( $source == 'media' ) {
	$query_args['post_type'] = 'attachment';
	$query_args['post_status'] = 'inherit';
	$query_args['post_mime_type'] = 'image';

	if ( ! empty( $attachment_ids ) ) {

		$attachment_ids = us_replace_dynamic_value( $attachment_ids, /* acf_format */ FALSE );

		// Prepend the featured image ID
		if ( $include_post_thumbnail AND $post_thumbnail_id = get_post_thumbnail_id() ) {
			$attachment_ids = $post_thumbnail_id . ',' . $attachment_ids;
		}

		$query_args['post__in'] = explode( ',', $attachment_ids );

		// Fix while get_post_thumbnail_id() and us_replace_dynamic_value() can't work on ajax
		if ( ! wp_doing_ajax() ) {
			$filled_atts['attachment_ids'] = $attachment_ids;
		}
	}
}

// Exclude the current post from the query
if (
	$exclude_current_post
	AND $current_object_id
	AND $source != 'current_wp_query'
) {
	// Separate conditions because 'post__in' and 'post__not_in' can't work together
	if ( ! empty( $query_args['post__in'] ) ) {
		$_post_ids = array_diff( $query_args['post__in'], array( $current_object_id ) );
		$query_args['post__in'] = $_post_ids ?: array( 0 );
	} else {
		$query_args['post__not_in'] = array_merge( $query_args['post__not_in'], array( $current_object_id ) );
	}
}

$list_end_vars = array();

// Exclude posts of previous lists
if ( $exclude_prev_posts ) {
	global $us_post_ids_shown_by_grid;
	if ( $us_post_ids_shown_by_grid ) {
		$list_end_vars['us_post_ids_shown_by_grid'] = $query_args['post__not_in'] = array_merge( $query_args['post__not_in'], $us_post_ids_shown_by_grid );
	}
}

// Exclude posts by the given quantity from the beginning of output
if ( $enable_items_offset AND $items_offset ) {
	global $us_list_query_offset;
	$us_list_query_offset = absint( $items_offset );
	$query_args['_id'] = 'us_list_with_offset';
	add_action( 'pre_get_posts', 'us_list_query_offset', 1 );
	add_filter( 'found_posts', 'us_list_adjust_offset_pagination', 1, 2 );
}

// Post Author
if ( $post_author == 'include' ) {
	$query_args['author__in'] = explode( ',', $post_author_ids );
} elseif ( $post_author == 'exclude' ) {
	$query_args['author__not_in'] = explode( ',', $post_author_ids );
} elseif ( $post_author == 'current_author' ) {
	$query_args['author'] = get_the_author_meta( 'ID' );
} elseif ( $post_author == 'current_user' ) {
	$query_args['author'] = get_current_user_id();
}

// Tax Query
if ( is_string( $tax_query ) ) {
	$tax_query = json_decode( urldecode( $tax_query ), TRUE );
}
if ( ! is_array( $tax_query ) ) {
	$tax_query = array();
}
if ( $tax_query_relation != 'none' AND ! empty( $tax_query ) ) {
	foreach ( $tax_query as &$_tax ) {

		// Explode terms IDs to array
		if ( ! empty( $_tax['terms'] ) ) {
			$_tax['terms'] = explode( ',', $_tax['terms'] );
		}

		$operator_initial_value = $_tax['operator'];
		// Get terms of the current post
		if ( $_tax['operator'] == 'CURRENT' AND ! usb_is_template_preview() ) {
			$_tax['terms'] = wp_get_object_terms( $current_object_id, $_tax['taxonomy'], array( 'fields' => 'ids' ) );
			$_tax['operator'] = 'IN';
		}

		// Check #4124 issue for explanation
		if ( empty( $_tax['terms'] ) AND $operator_initial_value !== 'CURRENT' ) {
			$_tax['operator'] = ( $_tax['operator'] == 'NOT IN' ) ? 'NOT EXISTS' : 'EXISTS';
		}

		// Transfer to bool var type
		$_tax['include_children'] = (bool) $_tax['include_children'];
	}
	unset( $_tax );
	$tax_query['relation'] = $tax_query_relation;
	$query_args['tax_query'] = $tax_query;
}

// Meta Query
if ( is_string( $meta_query ) ) {
	$meta_query = json_decode( urldecode( $meta_query ), TRUE );
}
if ( ! is_array( $meta_query ) ) {
	$meta_query = array();
}
if ( $meta_query_relation != 'none' AND ! empty( $meta_query ) ) {
	foreach ( $meta_query as &$_meta ) {

		// Set the NUMERIC type for specific "compare" values
		if ( in_array( $_meta['compare'], array( '>', '>=', '<', '<=' ) ) ) {
			$_meta['type'] = 'NUMERIC';
		}

		if ( isset( $_meta['value'] ) ) {
			// Force date/time type if the relevant dynamic value is set
			if ( $_meta['value'] == '{{today_now}}' OR ( strpos( $_meta['value'], '{{date|') !== FALSE AND $_meta['value'] !== '{{date|U}}' ) ) {
				$_meta['type'] = 'DATETIME';
			} elseif ( $_meta['value'] == '{{today}}' ) {
				$_meta['type'] = 'DATE';
			} elseif ( $_meta['value'] == '{{now}}' ) {
				$_meta['type'] = 'TIME';
			}

			// Unset the field value for specific "compare" values
			if ( in_array( $_meta['compare'], array( 'EXISTS', 'NOT EXISTS' ) ) ) {
				unset( $_meta['value'] );
			} else {
				$_meta['value'] = us_replace_dynamic_value( $_meta['value'] );
			}
		} elseif ( $_meta['compare'] == 'EXISTS' AND isset( $_meta['key'] ) ) {
			$_meta = array(
				'relation' => 'AND',
				array(
					'key' => $_meta['key'],
					'compare' => 'EXISTS',
				),
				array(
					'key' => $_meta['key'],
					'value' => '',
					'compare' => '!=',
				),
			);
		} elseif ( $_meta['compare'] == 'NOT EXISTS' AND isset( $_meta['key'] ) ) {
			$_meta = array(
				'relation' => 'OR',
				array(
					'key' => $_meta['key'],
					'compare' => 'NOT EXISTS',
				),
				array(
					'key' => $_meta['key'],
					'value' => '',
					'compare' => '=',
				),
			);
		}
	}
	unset( $_meta );
	$meta_query['relation'] = $meta_query_relation;
	$query_args['meta_query'] = $meta_query;
}

// Get search query from List Search element (provided by ajax request)
if ( isset( $list_search ) ) {
	$query_args['s'] = sanitize_text_field( $list_search );
}

// Save arguments for faceted filtering before applying the orderby and filter params.
// Ordering by custom field may change the amount of results (like in Post Views Counter)
$query_args_unfiltered = apply_filters( 'us_post_list_query_args_unfiltered', $query_args, $filled_atts );

// Get orderby params from the List Order element (provided by ajax request)
if ( isset( $list_order ) ) {
	$_orderby_params = $list_order;

	// in other case combine orderby params from settings
} else {
	$_orderby_params = $orderby;

	if ( $orderby == 'custom' ) {
		$_orderby_params = $orderby_custom_field;

		if ( $orderby_custom_type ) {
			$_orderby_params .= ',num';
		}
	}

	if ( $order_invert ) {
		$_orderby_params .= ',asc';
	}
}

// Random orderby needs the same seed to avoid duplications with enabled pagination
if ( strpos( $_orderby_params, 'rand' ) === 0 ) {

	// Use the current date as seed for numbered pagination (since it doesn't have ajax)
	if ( $pagination == 'numbered' ) {
		$orderby_random_seed = date( 'Ymd' );

	} else {
		$orderby_random_seed = $orderby_random_seed // check if the var is passed from us_ajax_post_list()
			?? filter_input( INPUT_POST, 'orderby_random_seed' ) // ..if not, get from POST request (used on archives with current_wp_query)
			?: mt_rand(); // ..if not, generate new seed
	}

	$_orderby_params = 'RAND(' . (int) $orderby_random_seed . ')';
}

us_apply_orderby_to_list_query(	$query_args, $_orderby_params );

// Get params from List Filter element (provided by ajax request)
if ( isset( $list_filter ) ) {
	us_apply_filtering_to_list_query( $query_args, $list_filter );
}

$query_args = apply_filters( 'us_post_list_query_args', $query_args, $filled_atts );

$post_list_query = new WP_Query( $query_args );
unset( $query_args );

// Override global $wp_query for correct pagination on non-archive pages
// It must be reseted in the end of the output
if ( $source != 'current_wp_query' ) {
	global $wp_query;
	$wp_query = $post_list_query;
}

$no_results = $post_list_query->have_posts() ? FALSE : TRUE;

$grid_layout_settings = us_get_grid_layout_settings( $items_layout, /* default_template */ 'blog_1' );

$list_start_vars = array(
	'shortcode_base' => $shortcode_base,
	'classes' => $classes ?? '',
	'grid_elm_id' => ! empty( $el_id ) ? $el_id : sprintf( 'us_post_list_%s', us_uniqid() ),
	'grid_layout_settings' => $grid_layout_settings,
	'no_results' => $no_results,
);

// Needed for Ajax pagination
if ( $source == 'current_wp_query' ) {
	$list_start_vars['classes'] .= ' for_current_wp_query';
}

if ( $apply_url_params OR $source == 'current_wp_query' ) {
	$list_start_vars['classes'] .= ' apply_url_params';
}

// Override 'type' param for Post Carousel
if ( $shortcode_base == 'us_post_carousel' ) {
	$list_start_vars['type'] = 'carousel';
}

us_load_template( 'templates/loop/start', $list_start_vars + $filled_atts );

// Design settings of Post Content inner elements
global $us_post_content_design_css;
if ( ! $us_post_content_design_css ) {
	$us_post_content_design_css = array();
}

$is_enabled_full_content = FALSE;
if ( ! empty( $grid_layout_settings ) AND is_array( $grid_layout_settings ) ) {
	$is_enabled_full_content = strpos( json_encode( $grid_layout_settings ), '"full_content"' ) !== FALSE;
}

if ( ! $no_results ) {

	$list_post_vars = array(
		'columns' => $columns,
		'grid_layout_settings' => $grid_layout_settings,
		'type' => $type,
		'ignore_items_size' => $ignore_items_size,
		'load_animation' => $load_animation,
		'overriding_link' => $overriding_link,
		'current_page_id' => $exclude_current_post ? 0 : $current_object_id,
	);

	while ( $post_list_query->have_posts() ) {
		$post_list_query->the_post();

		// Collect Design settings of content elements inside every post
		if (
			$is_enabled_full_content
			AND $elm_design_settings = get_post_meta( get_the_ID(), '_us_jsoncss_data', TRUE )
			AND is_array( $elm_design_settings )
		) {

			foreach ( $elm_design_settings as $_elm_settings ) {
				us_append_elm_design_settings( $_elm_settings, $us_post_content_design_css );
			}
		}

		us_load_template( 'templates/loop/item-post', $list_post_vars );
	}
}

$list_end_vars += array(
	'shortcode_base' => $shortcode_base,
	'paged' => $paged,
	'query_args_unfiltered' => $query_args_unfiltered,
	'max_num_pages' => $post_list_query->max_num_pages,
	'no_results' => $no_results,
	'us_post_content_design_css' => $us_post_content_design_css,
	'found_posts' => $post_list_query->found_posts, // Needed for List Result Counter
	'per_page' => $post_list_query->query_vars['posts_per_page'], // Needed for List Result Counter
	'items_count' => $post_list_query->post_count,
	'orderby_random_seed' => $orderby_random_seed ?? NULL, // Needed for random ordering with ajax pagination
);

us_load_template( 'templates/loop/end', $list_end_vars + $filled_atts );
