<?php

/**
 * Custom Post type class.
 *
 * @author     Time.ly Network Inc.
 * @since      2.0
 *
 * @package    AI1EC
 * @subpackage AI1EC.Post
 */
class Ai1ec_Post_Custom_Type extends Ai1ec_Base {

    /**
     * Registers the custom post type.
     *
     * @wp-hook init
     */
    public function register() {
        $settings = $this->_registry->get( 'model.settings' );

        // ===============================
        // = labels for custom post type =
        // ===============================
        $labels = array(
            'name'               => Ai1ec_I18n::_x( 'Events', 'Custom post type name' ),
            'singular_name'      => Ai1ec_I18n::_x( 'Event', 'Custom post type name (singular)' ),
            'add_new'            => Ai1ec_I18n::__( 'Add New' ),
            'add_new_item'       => Ai1ec_I18n::__( 'Add New Event' ),
            'edit_item'          => Ai1ec_I18n::__( 'Edit Event' ),
            'new_item'           => Ai1ec_I18n::__( 'New Event' ),
            'view_item'          => Ai1ec_I18n::__( 'View Event' ),
            'search_items'       => Ai1ec_I18n::__( 'Search Events' ),
            'not_found'          => Ai1ec_I18n::__( 'No Events found' ),
            'not_found_in_trash' => Ai1ec_I18n::__( 'No Events found in Trash' ),
            'parent_item_colon'  => Ai1ec_I18n::__( 'Parent Event' ),
            'menu_name'          => Ai1ec_I18n::__( 'Events' ),
            'all_items'          => $this->get_all_items_name(),
        );


        // ================================
        // = support for custom post type =
        // ================================
        $supports = array( 'title', 'editor', 'comments', 'custom-fields', 'thumbnail', 'author' );

        // =============================
        // = args for custom post type =
        // =============================
        $page_base = false;
        if ( $settings->get( 'calendar_page_id' ) ) {
            $page_base = get_page_uri( $settings->get( 'calendar_page_id' ) );
        }

        $rewrite     = array( 'slug' => Ai1ec_I18n::__( 'event' ) );
        $has_archive = true;
        if (
            $settings->get( 'calendar_base_url_for_permalinks' ) &&
            $page_base
        ) {
            $rewrite     =  array( 'slug' => $page_base );
            $has_archive = AI1EC_ALTERNATIVE_ARCHIVE_URL;
        }
        $args = array(
            'labels'              => $labels,
            'public'              => true,
            'publicly_queryable'  => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'query_var'           => true,
            'rewrite'             => $rewrite,
            'map_meta_cap'        => true,
            'capability_type'     => 'ai1ec_event',
            'has_archive'         => $has_archive,
            'hierarchical'        => false,
            'menu_position'       => 5,
            'supports'            => $supports,
            'exclude_from_search' => $settings->get( 'exclude_from_search' ),
        );

        // ========================================
        // = labels for event categories taxonomy =
        // ========================================
        $events_categories_labels = array(
            'name'          => Ai1ec_I18n::_x( 'Categories', 'Event categories taxonomy' ),
            'singular_name' => Ai1ec_I18n::_x( 'Category', 'Event categories taxonomy (singular)' ),
            'menu_name'     => Ai1ec_I18n::_x( 'Organize', 'Event categories menu item' ),
        );

        // ==================================
        // = labels for event tags taxonomy =
        // ==================================
        $events_tags_labels = array(
            'name'          => Ai1ec_I18n::_x( 'Tags', 'Event tags taxonomy' ),
            'singular_name' => Ai1ec_I18n::_x( 'Tag', 'Event tags taxonomy (singular)' )
        );

        // ==================================
        // = labels for event feeds taxonomy =
        // ==================================
        $events_feeds_labels = array(
            'name'          => Ai1ec_I18n::_x( 'Event Feeds', 'Event feeds taxonomy' ),
            'singular_name' => Ai1ec_I18n::_x( 'Event Feed', 'Event feed taxonomy (singular)' )
        );

        // ======================================
        // = args for event categories taxonomy =
        // ======================================
        $events_categories_args = array(
            'labels'       => $events_categories_labels,
            'hierarchical' => true,
            'rewrite'      => array( 'slug' => 'events_categories' ),
            'capabilities' => array(
                'manage_terms' => 'manage_events_categories',
                'edit_terms'   => 'manage_events_categories',
                'delete_terms' => 'manage_events_categories',
                'assign_terms' => 'edit_ai1ec_events'
            ),
        );

        // ================================
        // = args for event tags taxonomy =
        // ================================
        $events_tags_args = array(
            'labels'       => $events_tags_labels,
            'hierarchical' => false,
            'rewrite'      => array( 'slug' => 'events_tags' ),
            'show_ui'      => true,
            'capabilities' => array(
                'manage_terms' => 'manage_events_categories',
                'edit_terms'   => 'manage_events_categories',
                'delete_terms' => 'manage_events_categories',
                'assign_terms' => 'edit_ai1ec_events'
            ),
        );

        // ================================
        // = args for event feeds taxonomy =
        // ================================
        $events_feeds_args = array(
            'labels'       => $events_feeds_labels,
            'hierarchical' => false,
            'rewrite'      => array( 'slug' => 'events_feeds' ),
            'capabilities' => array(
                'manage_terms' => 'manage_events_categories',
                'edit_terms'   => 'manage_events_categories',
                'delete_terms' => 'manage_events_categories',
                'assign_terms' => 'edit_ai1ec_events'
            ),
            'public'        => false // don't show taxonomy in admin UI
        );

        // ======================================
        // = register event categories taxonomy =
        // ======================================
        register_taxonomy(
            'events_categories',
            array( AI1EC_POST_TYPE ),
            $events_categories_args
        );

        // ================================
        // = register event tags taxonomy =
        // ================================
        register_taxonomy(
            'events_tags',
            array( AI1EC_POST_TYPE ),
            $events_tags_args
        );

        // ================================
        // = register event tags taxonomy =
        // ================================
        register_taxonomy(
            'events_feeds',
            array( AI1EC_POST_TYPE ),
            $events_feeds_args
        );

        // ========================================
        // = register custom post type for events =
        // ========================================
        register_post_type( AI1EC_POST_TYPE, $args );

        // get event contributor if saved in the db
        $contributor = get_role( 'ai1ec_event_assistant' );
        // if it's present and has the wrong capability delete it.
        if (
            $contributor instanceOf WP_Role &&
            (
                $contributor->has_cap( 'publish_ai1ec_events' ) ||
                ! $contributor->has_cap( 'edit_published_ai1ec_events' ) ||
                ! $contributor->has_cap( 'delete_published_ai1ec_events' )
            )
        ) {
            remove_role( 'ai1ec_event_assistant' );
            $contributor = false;
        }
        // Create event contributor role with the same capabilities
        // as subscriber role, plus event managing capabilities
        // if we have not created it yet.
        if ( ! $contributor ) {
            $caps = get_role( 'subscriber' )->capabilities;
            $role = add_role(
                'ai1ec_event_assistant',
                'Event Contributor',
                $caps
            );
            $role->add_cap( 'edit_ai1ec_events' );
            $role->add_cap( 'read_ai1ec_events' );
            $role->add_cap( 'delete_ai1ec_events' );
            $role->add_cap( 'edit_published_ai1ec_events' );
            $role->add_cap( 'delete_published_ai1ec_events' );
            $role->add_cap( 'read' );
            unset( $caps, $role );
        }

        // Add event managing capabilities to administrator, editor, author.
        // The last created capability is "manage_ai1ec_feeds", so check for
        // that one.
        $role = get_role( 'administrator' );
        if ( is_object( $role ) && ! $role->has_cap( 'manage_ai1ec_feeds' ) ) {
            $role_list = array( 'administrator', 'editor', 'author' );
            foreach ( $role_list as $role_name ) {
                $role = get_role( $role_name );
                if ( null === $role || ! ( $role instanceof WP_Role ) ) {
                    continue;
                }
                // Read events.
                $role->add_cap( 'read_ai1ec_event' );
                // Edit events.
                $role->add_cap( 'edit_ai1ec_event' );
                $role->add_cap( 'edit_ai1ec_events' );
                $role->add_cap( 'edit_private_ai1ec_events' );
                $role->add_cap( 'edit_published_ai1ec_events' );
                // Delete events.
                $role->add_cap( 'delete_ai1ec_event' );
                $role->add_cap( 'delete_ai1ec_events' );
                $role->add_cap( 'delete_published_ai1ec_events' );
                $role->add_cap( 'delete_private_ai1ec_events' );
                // Publish events.
                $role->add_cap( 'publish_ai1ec_events' );
                // Read private events.
                $role->add_cap( 'read_private_ai1ec_events' );
                // Manage categories & tags.
                $role->add_cap( 'manage_events_categories' );
                // Manage calendar feeds.
                $role->add_cap( 'manage_ai1ec_feeds' );
                if ( 'administrator' === $role_name ) {
                    // Change calendar themes & manage calendar options.
                    $role->add_cap( 'switch_ai1ec_themes' );
                    $role->add_cap( 'manage_ai1ec_options' );
                }
                // Add additional roles for administrator and editor
                if ( 'author' !== $role_name ) {
                    $role->add_cap( 'edit_others_ai1ec_events' );
                    $role->add_cap( 'delete_others_ai1ec_events' );
                }
            }
        }

    }

    /**
     * Appending pending items number to the menu name.
     *
     * If current user can publish events and there
     * is at least 1 event pending, append the pending
     * events number to the menu
     *
     * @return string
     */
    public function get_all_items_name() {
        // if current user can publish events
        if ( current_user_can( 'publish_ai1ec_events' ) ) {
            // get all pending events
            $query = array (
                'post_type'      => AI1EC_POST_TYPE,
                'post_status'    => 'pending',
                'posts_per_page' => -1,
            );
            $query = new WP_Query( $query );

            // at least 1 pending event?
            if ( $query->post_count > 0 ) {
                // append the pending events number to the menu
                return sprintf(
                    Ai1ec_I18n::__(
                        'All Events <span class="update-plugins count-%d" title="%d Pending Events"><span class="update-count">%d</span></span>'
                    ),
                    $query->post_count,
                    $query->post_count,
                    $query->post_count
                );
            }
        }

        // no pending events, or the user doesn't have sufficient capabilities
        return Ai1ec_I18n::__( 'All Events' );
    }

}
