<?php
/**
 * List events manageable from the front-end.
 *
 * @category Submissions
 * @package  My Calendar Pro
 * @author   Joe Dolson
 * @license  GPLv3
 * @link     https://www.joedolson.com/my-calendar-pro/
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Render My Calendar event editor on configured page.
 *
 * @param string $content Post content.
 *
 * @return string
 */
function mcs_render_editing( $content ) {
	$mcs_edit_id = get_option( 'mcs_edit_id' );
	if ( is_singular() && get_queried_object_id() === (int) $mcs_edit_id ) {
		if ( ! has_shortcode( $content, 'submitted_events' ) ) {
			$content .= mcs_submitted_events( array(), '' );
		}
	}

	return $content;
}
add_filter( 'the_content', 'mcs_render_editing' );

/**
 * Show a user's submitted events with links to edit
 *
 * @param array  $atts Shortcode attributes.
 * @param string $content contained content.
 *
 * @return user event list.
 */
function mcs_submitted_events( $atts, $content ) {
	// Shortcode arguments.
	$args    = shortcode_atts(
		array(
			'orderby'        => 'default',
			'order'          => 'default',
			'items_per_page' => 50,
			'show_past'      => 'true',
		),
		$atts,
		'submitted_events'
	);
	$page_id = get_option( 'mcs_edit_id', '' );
	if ( ! $page_id && is_singular() ) {
		global $post;
		update_option( 'mcs_edit_id', $post->ID );
	}

	return ( ! is_user_logged_in() ) ? $content : mcs_user_events( $args );
}
add_shortcode( 'submitted_events', 'mcs_submitted_events' );

/**
 * Get events for admin list.
 *
 * @param array $params Sorting and filtering of admin order for front-end management.
 *
 * @return array
 */
function mcs_get_admin_events( $params ) {
	global $wpdb;
	$direction      = $params['direction'];
	$by             = $params['orderby'];
	$status         = $params['status'];
	$restrict       = $params['restrict'];
	$current        = (int) $params['current'];
	$items_per_page = (int) $params['items'];
	$user           = wp_get_current_user();
	if ( current_user_can( 'mc_manage_events' ) ) {
		$author = 'all';
	} else {
		$author = $user;
	}

	if ( empty( $by ) ) {
		$sortbyvalue = 'event_begin';
	} else {
		switch ( $by ) {
			case 1:
				$sortbyvalue = 'event_ID';
				break;
			case 2:
				$sortbyvalue = 'event_title';
				break;
			case 4:
				$sortbyvalue = "event_begin $direction, event_time";
				break;
			case 6:
				$sortbyvalue = 'event_category';
				break;
			case 7:
				$sortbyvalue = 'event_location';
				break;
			default:
				$sortbyvalue = "event_begin $direction, event_time";
		}
	}

	switch ( $status ) {
		case 'all':
			$limit = '';
			break;
		case 'draft':
			$limit = 'WHERE event_approved <> 1';
			break;
		case 'published':
			$limit = 'WHERE event_approved = 1';
			break;
		case 'trashed':
			$limit = 'WHERE event_approved = 2';
			break;
		default:
			$limit = 'WHERE event_approved != 2';
	}

	switch ( $restrict ) {
		case 'all':
			$filter = '';
			break;
		case 'where':
			$filter   = ( isset( $_GET['filter'] ) ) ? absint( $_GET['filter'] ) : '';
			$restrict = 'event_location';
			break;
		case 'category':
			$filter   = ( isset( $_GET['filter'] ) ) ? absint( $_GET['filter'] ) : '';
			$restrict = 'event_category';
			break;
		default:
			$filter = '';
	}

	$filter = esc_sql( urldecode( $filter ) );
	if ( '' === $limit && '' !== $filter ) {
		$limit = " WHERE $restrict = $filter";
	} elseif ( '' !== $limit && '' !== $filter ) {
		$limit .= " AND $restrict = $filter";
	}

	// default limits.
	if ( '' === $limit ) {
		$limit .= ( 'event_flagged' !== $restrict ) ? ' WHERE event_flagged = 0' : '';
	} else {
		$limit .= ( 'event_flagged' !== $restrict ) ? ' AND event_flagged = 0' : '';
	}

	if ( 'all' !== $author ) {
		$limit .= " AND event_author = $author->ID";
	}
	$limit .= ( 'archived' !== $restrict ) ? ' AND event_status = 1' : ' AND event_status = 0';
	$now    = current_time( 'Y-m-d H:i:s' );
	$date   = ( 'false' === $params['show_past'] ) ? " AND DATE(events.event_begin) > CAST('$now' as DATE)" : '';

	if ( 'event_category' !== $sortbyvalue ) {
		$events     = $wpdb->get_results( 'SELECT events.event_id FROM ' . my_calendar_table() . " AS events $limit $date ORDER BY $sortbyvalue $direction LIMIT " . ( ( $current - 1 ) * $items_per_page ) . ', ' . $items_per_page ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
		$found_rows = $wpdb->get_col( 'SELECT count(*) FROM ' . my_calendar_table() . " AS events $limit $date ORDER BY $sortbyvalue $direction" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
	} else {
		$limit      = str_replace( array( 'WHERE ' ), '', $limit );
		$limit      = ( 0 === strpos( $limit, 'AND' ) ) ? $limit : 'AND ' . $limit;
		$events     = $wpdb->get_results( 'SELECT DISTINCT events.event_id FROM ' . my_calendar_table() . ' AS events JOIN ' . my_calendar_categories_table() . " AS categories WHERE events.event_category = categories.category_id $limit $date ORDER BY categories.category_name $direction LIMIT " . ( ( $current - 1 ) * $items_per_page ) . ', ' . $items_per_page ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
		$found_rows = $wpdb->get_col( 'SELECT count(*) FROM ' . my_calendar_table() . ' AS events JOIN ' . my_calendar_categories_table() . " AS categories WHERE events.event_category = categories.category_id $limit $date ORDER BY categories.category_name $direction" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
	}
	$items = $found_rows[0];

	return array(
		'events' => $events,
		'items'  => $items,
	);
}

/**
 * Map a string ordering type to the integer used internally.
 *
 * @param string $order_type Ordering term.
 *
 * @return int
 */
function mcs_map_order( $order_type ) {
	if ( is_numeric( $order_type ) ) {
		return (int) $order_type;
	}
	switch ( $order_type ) {
		case 'id':
			$return = 1;
			break;
		case 'title':
			$return = 2;
			break;
		case 'date':
			$return = 3;
			break;
		case 'category':
			$return = 6;
			break;
		case 'location':
			$return = 7;
			break;
		default:
			$return = 3;
	}

	return $return;
}

/**
 * Front-end admin page to display a list of events by the logged-in user
 *
 * @param array $args Ordering and display arguments.
 *
 * @return string.
 */
function mcs_user_events( $args ) {
	$return = '<div class="mc-submissions mc-user-events">';
	$page   = get_permalink();

	if ( current_user_can( 'mc_approve_events' ) || current_user_can( 'mc_manage_events' ) || current_user_can( 'mc_add_events' ) ) {

		if ( isset( $_GET['order'] ) ) {
			$sortdir = ( isset( $_GET['order'] ) && 'ASC' === $_GET['order'] ) ? 'ASC' : $args['order'];
			$sortdir = ( isset( $_GET['order'] ) && 'DESC' === $_GET['order'] ) ? 'DESC' : $sortdir;
		} else {
			$sortdir = $args['order'];
		}

		$default_direction = ( '' === get_option( 'mc_default_direction', '' ) ) ? 'ASC' : get_option( 'mc_default_direction' );
		$sortbydirection   = ( 'default' === $sortdir ) ? $default_direction : $sortdir;
		$newsort           = ( 'ASC' === $sortbydirection ) ? 'DESC' : 'ASC';

		$default_sort = ( 'default' === $args['orderby'] ) ? (int) get_option( 'mc_default_sort' ) : mcs_map_order( $args['orderby'] );
		$sortby       = ( isset( $_GET['sort'] ) ) ? absint( $_GET['sort'] ) : $default_sort;
		$sortby       = ( 3 === $sortby ) ? 2 : $sortby;
		$status       = ( isset( $_GET['limit'] ) ) ? sanitize_text_field( wp_unslash( $_GET['limit'] ) ) : '';
		$restrict     = ( isset( $_GET['restrict'] ) ) ? sanitize_text_field( wp_unslash( $_GET['restrict'] ) ) : 'all';

		$current        = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
		$items_per_page = $args['items_per_page'];

		$params = array(
			'direction' => $sortbydirection,
			'orderby'   => $sortby,
			'status'    => $status,
			'restrict'  => $restrict,
			'current'   => $current,
			'items'     => $items_per_page,
			'show_past' => $args['show_past'],
		);

		$event_data = mcs_get_admin_events( $params );
		$items      = $event_data['items'];
		$events     = $event_data['events'];

		$num_pages = ceil( $items / $items_per_page );
		if ( $num_pages > 1 ) {
			$page_links = paginate_links(
				array(
					'base'      => add_query_arg( 'paged', '%#%' ),
					'format'    => '',
					'prev_text' => __( '&laquo; Previous<span class="screen-reader-text"> Events</span>', 'my-calendar-pro' ),
					'next_text' => __( 'Next<span class="screen-reader-text"> Events</span> &raquo;', 'my-calendar-pro' ),
					'total'     => $num_pages,
					'current'   => $current,
					'mid_size'  => 1,
				)
			);
			$nav_label  = esc_attr( __( 'Events Pagination', 'my-calendar-pro' ) );
			$return    .= sprintf( "<nav class='tablenav' aria-label='$nav_label'><div class='tablenav-pages'>%s</div></nav>", $page_links );
		}

		if ( isset( $_GET['filter'] ) ) {
			$return .= "<p><span class='dashicons dashicons-no' aria-hidden='true'></span><a href='$page'>" . __( 'Clear filters', 'my-calendar-pro' ) . '</a></p>';
		}

		$dash           = ( 'ASC' === $newsort ) ? 'arrow-down-alt' : 'arrow-up-alt';
		$sort_direction = ( 'ASC' === $newsort ) ? 'ascending' : 'descending';
		// Translators: Sort direction text.
		$sort_text = "<span class='dashicons dashicons-$dash' aria-label='" . sprintf( __( 'Sort %s', 'my-calendar-pro' ), $sort_direction ) . "'></span>";
		if ( isset( $_GET['sort'] ) ) {
			$sort    = absint( $_GET['sort'] );
			$sorted1 = ( 1 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
			$sorted2 = ( 2 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
			$sorted7 = ( 7 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
			$sorted4 = ( 4 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
			$sorted6 = ( 6 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
			$sorted5 = ( 5 === $sort ) ? "<span class='dashicons dashicons-$dash' aria-hidden='true'></span>" : '';
		} else {
			$sorted1 = ''; // ID.
			$sorted2 = ''; // Title.
			$sorted7 = ''; // Location.
			$sorted4 = ''; // Begin date.
			$sorted6 = ''; // Category.
			$sorted5 = ''; // Author.
			switch ( $sortby ) {
				case 1:
					$sorted1 = $sort_text;
					break;
				case 2:
					$sorted2 = $sort_text;
					break;
				case 7:
					$sorted7 = $sort_text;
					break;
				case 4:
					$sorted4 = $sort_text;
					break;
				case 5:
					$sorted5 = $sort_text;
					break;
				case 6:
					$sorted6 = $sort_text;
					break;
			}
		}

		if ( ! empty( $events ) ) {
			$sort1 = add_query_arg(
				array(
					'sort'  => '1',
					'order' => $newsort,
				),
				$page
			);
			$sort2 = add_query_arg(
				array(
					'sort'  => '2',
					'order' => $newsort,
				),
				$page
			);
			$sort7 = add_query_arg(
				array(
					'sort'  => '7',
					'order' => $newsort,
				),
				$page
			);
			$sort4 = add_query_arg(
				array(
					'sort'  => '4',
					'order' => $newsort,
				),
				$page
			);
			$sort5 = add_query_arg(
				array(
					'sort'  => '5',
					'order' => $newsort,
				),
				$page
			);
			$sort6 = add_query_arg(
				array(
					'sort'  => '6',
					'order' => $newsort,
				),
				$page
			);

			$sort_by_author = '';
			if ( current_user_can( 'mc_manage_events' ) ) {
				$sort_by_author = "	<th scope='col'><a href='" . esc_url( $sort5 ) . "'>" . __( 'Author', 'my-calendar-pro' ) . " $sorted5</a></th>";
			}

			$return .= "
			<table class='widefat wp-list-table' id='my-calendar-admin-table'>
				<thead>
				<tr>
					<th scope='col'> <a href='" . esc_url( $sort1 ) . "'>" . __( 'ID', 'my-calendar-pro' ) . " $sorted1</a></th>
					<th scope='col'><a href='" . esc_url( $sort2 ) . "'>" . __( 'Title', 'my-calendar-pro' ) . " $sorted2</a></th>
					<th scope='col'><a href='" . esc_url( $sort7 ) . "'>" . __( 'Location', 'my-calendar-pro' ) . " $sorted7</a></th>
					<th scope='col'><a href='" . esc_url( $sort4 ) . "'>" . __( 'Date/Time', 'my-calendar-pro' ) . " $sorted4</a></th>
					$sort_by_author
					<th scope='col'><a href='" . esc_url( $sort6 ) . "'>" . __( 'Category', 'my-calendar-pro' ) . " $sorted6</a></th>
				</tr>
				</thead>";

			$class = '';
			foreach ( array_keys( $events ) as $key ) {
				$e        =& $events[ $key ];
				$event    = mc_get_first_event( $e->event_id );
				$can_edit = mc_can_edit_event( $event->event_id );
				if ( ! is_object( $event ) ) {
					continue;
				}
				$class   = ( 'alternate' === $class ) ? 'even' : 'alternate';
				$pending = ( 0 === (int) $event->event_approved ) ? 'pending' : '';

				if ( 1 === (int) $event->event_flagged ) {
					$spam       = 'spam';
					$pending    = '';
					$spam_label = '<strong>' . __( 'Possible spam', 'my-calendar-pro' ) . ':</strong> ';
				} else {
					$spam       = '';
					$spam_label = '';
				}
				$edit_url   = mcs_submit_url( $event->event_id, $event );
				$view_url   = mc_get_details_link( $event );
				$delete_url = mcs_delete_url( $event->event_id );
				$check      = mc_test_occurrence_overlap( $event, true );
				$problem    = ( '' !== $check ) ? 'problem' : '';

				if ( current_user_can( 'mc_manage_events' ) || current_user_can( 'mc_approve_events' ) || $can_edit ) {
					$classes = trim( "$class $spam $pending $problem" );
					$return .= "
					<tr class='$classes'>
						<th scope='row'>$event->event_id</th>
						<td><strong>";
					if ( $can_edit ) {
						$return .= "<span class='dashicons dashicons-edit' aria-hidden='true'></span><a href='" . esc_url( $edit_url ) . "' class='edit'>";
					}
					$return .= $spam_label;
					$return .= wp_strip_all_tags( stripslashes( $event->event_title ) );

					if ( $can_edit ) {
						$return .= '</a>';
						if ( '' !== $check ) {
							// Translators: Edit URL.
							$return .= '<br /><strong class="error">' . sprintf( __( 'There is a problem with this event. <a href="%s">Edit</a>', 'my-calendar-pro' ), esc_url( $edit_url ) ) . '</strong>';
						}
					}
					$return .= "</strong>

					<div class='row-actions'>";
					if ( mc_event_published( $event ) && $view_url ) {
						$return .= "<a href='" . esc_url( $view_url ) . "' class='view'>" . __( 'View', 'my-calendar-pro' ) . '</a> | ';
					}
					if ( $can_edit && $delete_url ) {
						$return .= "<a href='" . esc_url( $delete_url ) . "' class='delete'>" . __( 'Delete', 'my-calendar-pro' ) . '</a>';
					} else {
						$return .= __( 'Not editable.', 'my-calendar-pro' );
					}

					$return .= '</div>
					</td>
					<td>';
					if ( '' !== $event->event_location ) {
						$elabel = '';
						if ( property_exists( $event, 'location' ) && is_object( $event->location ) ) {
							$elabel     = $event->location->location_label;
							$filter_url = add_query_arg(
								array(
									'filter'   => $event->event_location,
									'restrict' => 'where',
								),
								$page
							);
						}

						$return .= ( $elabel ) ? "<a class='mc_filter' href='" . esc_url( $filter_url ) . "'><span class='screen-reader-text'>" . __( 'Show only: ', 'my-calendar-pro' ) . '</span> ' . wp_strip_all_tags( stripslashes( $elabel ) ) . '</a>' : '';
					}
					$return .= '</td>
					<td>';
					if ( '23:59:59' !== $event->event_endtime ) {
						$event_time = date_i18n( get_option( 'mc_time_format' ), mc_strtotime( $event->event_time ) );
					} else {
						$event_time = mc_notime_label( $event );
					}
					$date_format = mc_date_format();
					$begin       = date_i18n( $date_format, mc_strtotime( $event->event_begin ) );
					$return     .= esc_html( "$begin, $event_time" );
					$recur       = mc_recur_string( $event );
					if ( $recur ) {
						$return .= "<div class='recurs'><strong>" . __( 'Recurs', 'my-calendar-pro' ) . ':</strong> ' . $recur . '</div>';
					}
					$return .= '</td>';
					if ( current_user_can( 'mc_manage_events' ) ) {
						$author     = ( 0 !== (int) $event->event_author ) ? get_userdata( $event->event_author ) : 'Public Submitter';
						$auth       = ( is_object( $author ) ) ? $author->ID : 0;
						$filter_url = add_query_arg(
							array(
								'filter'   => $auth,
								'restrict' => 'author',
							),
							$page
						);
						$author     = ( is_object( $author ) ? $author->display_name : $author );
						$return    .= "<td>
							<a class='mc_filter' href='" . esc_url( $filter_url ) . "'>
							<span class='screen-reader-text'>" . esc_html__( 'Show only: ', 'my-calendar-pro' ) . '</span>' . esc_html( $author ) . '</a>
						</td>';
					}
					$return .= '
					<td>
						<div class="mcs-category-list">' . mc_admin_category_list( $event ) . '</div>
					</td>
				</tr>';
				}
			}
			$return .= '</table>';
		} else {
			if ( isset( $_GET['restrict'] ) ) {
				$return .= "<p class='mc-none'>" . __( 'You have not submitted any events that match these filters.', 'my-calendar-pro' ) . '</p>';
			} else {
				$url = mcs_submit_url();
				// translators: URL to submit events.
				$return .= "<p class='mc-none'>" . sprintf( __( 'You have not yet submitted any events. <a href="%s">Submit an Event</a>', 'my-calendar-pro' ), $url ) . '</p>';
			}
		}
	}
	$return .= '</div>';

	return $return;
}
