<?php
/**
 * Define My Calendar post types.
 *
 * @category Posts
 * @package  My Calendar
 * @author   Joe Dolson
 * @license  GPLv2 or later
 * @link     https://www.joedolson.com/my-calendar/
 */

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

/**
 * Add custom fields to permalinks settings page.
 */
function mc_load_permalinks() {
	if ( isset( $_POST['mc_cpt_base'] ) ) {
		mc_update_option( 'cpt_base', sanitize_key( $_POST['mc_cpt_base'] ) );
	}
	$opts = array( 'label_for' => 'mc_cpt_base' );
	// Add a settings field to the permalink page.
	add_settings_field( 'mc_cpt_base', __( 'My Calendar Events base', 'my-calendar' ), 'mc_field_callback', 'permalink', 'optional', $opts );

	if ( isset( $_POST['mc_location_cpt_base'] ) ) {
		mc_update_option( 'location_cpt_base', sanitize_key( $_POST['mc_location_cpt_base'] ) );
	}
	$opts = array( 'label_for' => 'mc_location_cpt_base' );
	// Add a settings field to the permalink page.
	add_settings_field( 'mc_location_cpt_base', __( 'My Calendar Locations base', 'my-calendar' ), 'mc_location_field_callback', 'permalink', 'optional', $opts );
}
add_action( 'load-options-permalink.php', 'mc_load_permalinks' );

/**
 * Custom field callback for permalinks settings
 */
function mc_field_callback() {
	$value = ( '' !== mc_get_option( 'cpt_base' ) ) ? mc_get_option( 'cpt_base' ) : 'mc-events';
	echo '<input type="text" value="' . esc_attr( $value ) . '" name="mc_cpt_base" id="mc_cpt_base" class="regular-text" placeholder="mc-events" />';
}

/**
 * Custom field callback for permalinks settings
 */
function mc_location_field_callback() {
	$value = ( '' !== mc_get_option( 'location_cpt_base' ) ) ? mc_get_option( 'location_cpt_base' ) : 'mc-locations';
	echo '<input type="text" value="' . esc_attr( $value ) . '" name="mc_location_cpt_base" id="mc_location_cpt_base" class="regular-text" placeholder="mc-locations" />';
}

/**
 * Generate arguments for My Calendar post type.
 */
function mc_post_type() {
	$arguments = array(
		'public'              => apply_filters( 'mc_event_posts_public', true ),
		'publicly_queryable'  => true,
		/**
		 * Should My Calendar post types be excluded from search. Default false.
		 * Allowing the event post type to be searchable will not provide a true event search, especially with respect to recurring events.
		 * It will not search recurring events by date, only the post content from each event. See https://github.com/joedolson/my-calendar/issues/23.
		 *
		 * @hook mc_event_exclude_from_search
		 *
		 * @param {bool} $show True to exclude from search.
		 *
		 * @return {bool}
		 */
		'exclude_from_search' => apply_filters( 'mc_event_exclude_from_search', true ),
		'show_ui'             => true,
		/**
		 * Should My Calendar post types be shown in admin menus. Default false.
		 *
		 * @hook mc_show_custom_posts_in_menu
		 *
		 * @param {bool} $show True to show in menus.
		 *
		 * @return {bool}
		 */
		'show_in_menu'        => apply_filters( 'mc_show_custom_posts_in_menu', false ),
		'menu_icon'           => null,
		'supports'            => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields' ),
	);

	$loc_arguments             = $arguments;
	$loc_arguments['supports'] = array( 'title', 'custom-fields', 'thumbnail' );
	/**
	 * Should location posts be excluded from search? Default true.
	 *
	 * @hook mc_location_exclude_from_search
	 *
	 * @param {bool} $exclude True to exclude.
	 *
	 * @return {bool}
	 */
	$loc_arguments['exclude_from_search'] = apply_filters( 'mc_location_exclude_from_search', true );

	$types = array(
		'mc-events'    => array(
			__( 'event', 'my-calendar' ),
			__( 'events', 'my-calendar' ),
			__( 'Event', 'my-calendar' ),
			__( 'Events', 'my-calendar' ),
			$arguments,
		),
		'mc-locations' => array(
			__( 'location', 'my-calendar' ),
			__( 'locations', 'my-calendar' ),
			__( 'Location', 'my-calendar' ),
			__( 'Locations', 'my-calendar' ),
			$loc_arguments,
		),
	);

	return $types;
}
/**
 * Register custom post types for events
 */
function mc_posttypes() {
	$types   = mc_post_type();
	$enabled = array( 'mc-events', 'mc-locations' );
	if ( is_array( $enabled ) ) {
		foreach ( $enabled as $key ) {
			$value  =& $types[ $key ];
			$labels = array(
				'name'               => $value[3],
				'singular_name'      => $value[2],
				'add_new'            => _x( 'Add New', 'Add new event', 'my-calendar' ),
				'add_new_item'       => __( 'Create New Event', 'my-calendar' ),
				'edit_item'          => __( 'Modify Event', 'my-calendar' ),
				'new_item'           => __( 'New Event', 'my-calendar' ),
				'view_item'          => __( 'View Event', 'my-calendar' ),
				'search_items'       => __( 'Search Events', 'my-calendar' ),
				'not_found'          => __( 'No event found', 'my-calendar' ),
				'not_found_in_trash' => __( 'No events found in Trash', 'my-calendar' ),
				'parent_item_colon'  => '',
			);
			$raw    = $value[4];
			$args   = array(
				'labels'              => $labels,
				'public'              => $raw['public'],
				'publicly_queryable'  => $raw['publicly_queryable'],
				'exclude_from_search' => $raw['exclude_from_search'],
				'show_ui'             => $raw['show_ui'],
				'show_in_menu'        => $raw['show_in_menu'],
				'menu_icon'           => ( null === $raw['menu_icon'] ) ? plugins_url( 'images', __FILE__ ) . '/icon.png' : $raw['menu_icon'],
				'query_var'           => true,
				'rewrite'             => array(
					'with_front' => false,
					/**
					 * Filter default calendar post type slugs. Default 'mc-events' for events and 'mc-locations' for locations.
					 *
					 * @hook mc_event_slug
					 *
					 * @param {string} $key Slug.
					 *
					 * @return {string}
					 */
					'slug'       => apply_filters( 'mc_event_slug', $key ),
					/**
					 * Enable feeds for My Calendar post types.
					 *
					 * @hook mc_has_feeds
					 *
					 * @param {bool}   $enabled Default false.
					 * @param {string} $key Post type name.
					 *
					 * @return {bool}
					 */
					'feeds'      => apply_filters( 'mc_has_feeds', false, $key ),
				),
				'hierarchical'        => false,
				'menu_position'       => 20,
				'supports'            => $raw['supports'],
			);
			register_post_type( $key, $args );
		}
	}
}

/**
 * Replace the slug with saved option.
 *
 * @param string $slug Base post type name.
 *
 * @return string New permalink base.
 */
function mc_filter_posttype_slug( $slug ) {
	if ( 'mc-events' === $slug ) {
		$slug = ( '' !== mc_get_option( 'cpt_base' ) ) ? mc_get_option( 'cpt_base' ) : $slug;
	}
	if ( 'mc-locations' === $slug ) {
		$slug = ( '' !== mc_get_option( 'location_cpt_base' ) ) ? mc_get_option( 'location_cpt_base' ) : $slug;
	}

	return $slug;
}
add_filter( 'mc_event_slug', 'mc_filter_posttype_slug' );

add_filter( 'the_posts', 'mc_close_comments' );
/**
 * Most people don't want comments open on events. This will automatically close them.
 *
 * @param array $posts Array of WP Post objects.
 *
 * @return array $posts
 */
function mc_close_comments( $posts ) {
	if ( is_admin() || ! is_single() || empty( $posts ) ) {
		return $posts;
	}

	if ( 'mc-events' === get_post_type( $posts[0]->ID ) ) {
		/**
		 * Filter whether event posts should automatically close comments. Default 'true'.
		 *
		 * @hook mc_autoclose_comments
		 *
		 * @param {bool} $close 'true' to close comments.
		 *
		 * @return {bool}
		 */
		if ( apply_filters( 'mc_autoclose_comments', true ) && 'closed' !== $posts[0]->comment_status ) {
			$posts[0]->comment_status = 'closed';
			$posts[0]->ping_status    = 'closed';
			wp_update_post( $posts[0] );
		}
	}

	return $posts;
}

add_filter( 'default_content', 'mc_posttypes_defaults', 10, 2 );
/**
 * By default, disable comments on event posts on save
 *
 * @param string $post_content unused.
 * @param object $post WP Post object.
 *
 * @return string $post_content;
 */
function mc_posttypes_defaults( $post_content, $post ) {
	if ( $post->post_type ) {
		switch ( $post->post_type ) {
			case 'mc-events':
				$post->comment_status = 'closed';
				break;
		}
	}

	return $post_content;
}

/**
 * Register taxonomies on My Calendar custom post types
 */
function mc_taxonomies() {
	$types   = mc_post_type();
	$enabled = array( 'mc-events' );
	if ( is_array( $enabled ) ) {
		foreach ( $enabled as $key ) {
			$value = $types[ $key ];
			/**
			 * Filter event category taxonomy slug. Default 'mc-event-category'.
			 *
			 * @hook mc_event_category_slug
			 *
			 * @param {string} $slug Default slug.
			 *
			 * @return {string}
			 */
			$slug = apply_filters( 'mc_event_category_slug', 'mc-event-category' );
			register_taxonomy(
				'mc-event-category',
				// Internal name = machine-readable taxonomy name.
				array( $key ),
				array(
					'hierarchical' => true,
					'label'        => __( 'Event Categories', 'my-calendar' ),
					'query_var'    => true,
					'rewrite'      => array( 'slug' => $slug ),
				)
			);
		}
	}
}

/**
 * Custom post type strings
 *
 * @param array $messages default text.
 *
 * @return array Modified messages array.
 */
function mc_posttypes_messages( $messages ) {
	global $post, $post_ID;
	$types   = mc_post_type();
	$enabled = array( 'mc-events', 'mc-locations' );
	if ( is_array( $enabled ) ) {
		foreach ( $enabled as $key ) {
			$value            = $types[ $key ];
			$messages[ $key ] = array(
				0  => '', // Unused. Messages start at index 1.
				// Translators: URL to view event.
				1  => sprintf( __( 'Event updated. <a href="%s">View Event</a>', 'my-calendar' ), esc_url( get_permalink( $post_ID ) ) ),
				2  => __( 'Custom field updated.', 'my-calendar' ),
				3  => __( 'Custom field deleted.', 'my-calendar' ),
				4  => __( 'Event updated.', 'my-calendar' ),
				// Translators: %s: date and time of the revision.
				5  => isset( $_GET['revision'] ) ? sprintf( __( 'Event restored to revision from %s', 'my-calendar' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
				// Translators: URL to view event.
				6  => sprintf( __( 'Event published. <a href="%s">View event</a>', 'my-calendar' ), esc_url( get_permalink( $post_ID ) ) ),
				7  => sprintf( __( 'Event saved.', 'my-calendar' ) ),
				// Translators: URL to preview event.
				8  => sprintf( __( 'Event submitted. <a target="_blank" href="%s">Preview event</a>', 'my-calendar' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
				// Translators: Date event scheduled to be published, URL to preview event.
				9  => sprintf( __( 'Event scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview event</a>', 'my-calendar' ), date_i18n( __( 'M j, Y @ G:i', 'my-calendar' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ) ),
				// Translators: URL to preview event.
				10 => sprintf( __( 'Event draft updated. <a target="_blank" href="%s">Preview event</a>', 'my-calendar' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
			);
		}
	}

	return $messages;
}
