<?php
/**
 * Main Plugin Class
 *
 * This class is the main class for the plugin.
 * This is where all core components will be hooked.
 *
 * @package WP Awesome Support
 * @since 2.0.0
 * @author Julien Liabeuf <julien.liabeuf@n2clic.com>
 */
class WP_Awesome_Support {
	
	public function __construct() {

		$this->cpt_slug 	  = $this->getPostTypeSlug();
		$this->taxonomies 	  = array();
		$this->customFields   = array();
		$this->fineuploader   = 'fineuploader-4.1.0';
		$this->alert_endpoint = 'http://support.themeavenue.net/wpas-notification/';
		$this->redirect_login = apply_filters( 'wpas_redirect_after_login', true );

		if( wpas_get_option('force_cache_clear') == 'yes' ) {

			/**
			 * The correct hook would be send_headers, but I need
			 * the WP object in order to force cache to clear
			 * only on pages related to the plugin. Otherwise
			 * it would slow down the whole site.
			 */
			add_action( 'wp', array( $this, 'forceClearCache' ) );
		}
		
		add_action( 'wp', array( $this, 'ticketsPurge' ) );								// Auto close tickets hook registration
		add_action( 'wp', array( $this, 'ticketCreateRedirect' ) );						// Redirect agents to backend for ticket creation
		add_action( 'init', array( $this, 'loadTranslation' ), 1 );						// Load translation files
		add_action( 'init', array( $this, 'registerPostType' ) );						// Register CPT
		add_action( 'init', array( $this, 'registerStatusTaxonomy' ) );					// Register mendatory taxonomy
		add_action( 'init', array( $this, 'registerDefaultTaxonomies' ) );				// Register mendatory taxonomy
		add_action( 'init', array( $this, 'registerTaxonomies' ) );						// Register dynamic taxonomies
		add_action( 'init', array( $this, 'UserCustomFields' ) );						// Add custom user profile fields
		add_action( 'init', array( $this, 'LoggedOutRedirect' ) );						// Modify logout URL
		add_action( 'init', array( $this, 'deleteTicketReply' ) );						// Modify tickets replies (edit, delete)
		add_action( 'init', array( $this, 'dismissAlert' ) );
		add_action( 'admin_init', array( $this, 'preventAdminAccess' ) );				// Prevent admin access from subscribers
		add_action( 'admin_init', array( $this, 'upgradePlugin' ), 10 );				// Execute required actions after plugin upgrade
		add_action( 'admin_init', array( $this, 'installPlugin' ), 11 );				// Setup assistant
		add_action( 'pre_get_posts', array( $this, 'RedirectArchive' ) );				// Redirect tickets archive to ticket list page
		add_action( 'pre_get_posts', array( $this, 'limitLiveSearch' ) );				
		add_action( 'wp_head', array( $this, 'customCss' ) );							// Custom CSS
		add_action( 'template_redirect', array( $this, 'singleTemplate' ) );			// Get the template for ticket details
		add_action( 'template_redirect', array( $this, 'liveSearch' ) );				// Get the template for ticket details
		add_action( 'admin_bar_menu', array( $this, 'RemoveAdminBarItems' ), 999 );		// Remove admin bar items
		add_action( 'admin_bar_menu', array( $this, 'CustomizeAdminBar' ), 999 );		// Add plugin related admin bar items
		add_action( 'wp_footer', array( $this, 'modalPlaceholders' ), 100 );			// Modal placeholders
		add_action( 'wp_footer', array( $this, 'snapengage' ) );						// Snapengage script

		/* Load custom update messages */
		add_filter( 'post_updated_messages', array( $this, 'customizeUpdateMessages' ) );

		/* Register menus */
		add_action( 'admin_menu', array( $this, 'registerMenus' ) );
		add_action( 'admin_menu' , array( $this, 'removeTaxonomiesMetaboxes' ) );
		add_action( 'admin_menu', array( $this, 'modifyPostTypeMenuItemLink' ) );
		add_action( 'admin_menu', array( $this, 'AddTicketsCount' ) );
		add_action( 'admin_notices', array( $this, 'adminNotices' ) );
		add_action( 'admin_notices', array( $this, 'pluginSetup' ) );
		// add_action( 'admin_notices', array( $this, 'clientAlert' ) );

		/* Load resources */
		add_action( 'admin_print_scripts', array( $this, 'loadAdminScripts' ) );
		add_action( 'admin_print_styles', array( $this, 'loadAdminStyles' ) );
		add_action( 'wp_print_styles', array( $this, 'loadStyles' ) );
		add_action( 'wp_print_scripts', array( $this, 'loadScripts' ) );
		add_action( 'wp_footer', array( $this, 'fineUploaderScript' ) );
		add_action( 'admin_footer', array( $this, 'fineUploaderScript' ) );

		add_filter( 'login_redirect', array( $this, 'redirectAfterLogin' ) );
		add_filter( 'gettext', array( $this, 'changePublishButtonLabel' ), 10, 2 );
		add_filter( 'logout_url', array( $this, 'LogoutRedirectUrl' ), 10, 2 );

		/* Print the jQuery object in the site's header */
		add_action( 'wp_print_scripts', array( $this, 'jQueryObject' ) );

		if( is_admin() && ( isset( $_GET['post_type'] ) && 'tickets' == $_GET['post_type'] ) )
			add_filter( 'admin_footer_text', array( $this, 'versionInFooter' ) );

		if( !function_exists( 'tav_add_code_tag' ) )
			add_filter( 'tiny_mce_before_init', array( $this, 'addWysiwygCodeTag' ) );

	}

	/**
	 * Redirect agents to backend for ticket creation
	 *
	 * @since 2.0.0
	 */
	public function ticketCreateRedirect() {

		/* Only apply this on the front-end */
		if( is_admin() )
			return;

		global $post;

		$list = wpas_get_option( 'ticket_submit', false );

		if( $list && '' != $list && isset( $post ) && is_object( $post ) && $post->ID == $list && current_user_can( 'edit_ticket' ) ) {
			wp_redirect( admin_url( 'post-new.php?post_type=tickets' ) );
		}

	}

	/**
	 * Install plugin default configuration
	 *
	 * @since 2.0.0
	 */
	public function installPlugin() {

		if( isset( $_GET['install'] ) && 'true' == $_GET['install'] ) {

			/* Update the options */
			$options = get_option( WPAS_PREFIX . 'plugin_options' );

			/* Insert required pages */
			$list   = wp_insert_post( array( 'post_content' => '[tickets]', 'post_title' => __( 'My Tickets', 'wpas' ), 'post_type' => 'page', 'post_status' => 'publish', 'comment_status' => 'closed' ) );				// Tickets list
			$submit = wp_insert_post( array( 'post_content' => '[submit-ticket]', 'post_title' => __( 'Submit Ticket', 'wpas' ), 'post_type' => 'page', 'post_status' => 'publish', 'comment_status' => 'closed' ) );		// Ticket submit

			$options['ticket_submit'] = $submit;
			$options['ticket_list']   = $list;

			/* Default priorites */
			wp_insert_term( __( 'Blocker', 'wpas' ), 'priority' );
			wp_insert_term( __( 'Critical', 'wpas' ), 'priority' );
			wp_insert_term( __( 'Major', 'wpas' ), 'priority' );
			wp_insert_term( __( 'Minor', 'wpas' ), 'priority' );
			wp_insert_term( __( 'Trivial', 'wpas' ), 'priority' );
			
			/* Default states */
			$new = wp_insert_term( __( 'New', 'wpas' ), 'state' );
			wp_insert_term( __( 'In Progress', 'wpas' ), 'state' );
			$hold = wp_insert_term( __( 'Hold', 'wpas' ), 'state' );

			/* Default types */
			wp_insert_term( __( 'Commercial', 'wpas' ), 'type' );
			wp_insert_term( __( 'Technical', 'wpas' ), 'type' );

			/* Sat "Hold" as the exclude from auto close status */
			if( !is_wp_error( $hold ) ) {

				/* Get term slug */
				$hold_id 		 = $hold['term_id'];
				$hold_term 		 = get_term_by( 'id', $hold_id, 'state' );
				$default_exclude = $hold_term->slug;

				$options['auto_close_exclude_state'] = $default_exclude;

			}

			/* Sat "New" as the default state for new tickets */
			if( !is_wp_error( $new ) ) {

				/* Get term slug */
				$new_id 		 = $new['term_id'];
				$new_term 		 = get_term_by( 'id', $new_id, 'state' );
				$default_state   = $new_term->slug;

				$options['default_state'] = $default_state;

			}

			/* Set current user as defautlassignee */
			$options['default_assignee'] = get_current_user_id();

			/* Update plugin options */
			update_option( WPAS_PREFIX . 'plugin_options', $options );

			/* Mark setup as done */
			update_option( 'wpas_setup_status', 'done' );

			/* Redirect to tickets edit screen */
			wp_redirect( admin_url( 'edit.php?post_type=tickets' ) );
			exit;

		}

		if( isset( $_GET['skip_install'] ) && 'true' == $_GET['skip_install'] ) {

			/* Mark setup as skipped */
			update_option( 'wpas_setup_status', 'skipped' );

			wp_redirect( admin_url( 'edit.php?post_type=tickets' ) );
			exit;

		}

	}

	/**
	 * Execute required upgrade functions
	 *
	 * By default, this will update the plugin version saved in DB
	 *
	 * @since 2.0.0
	 */
	public function upgradePlugin() {

		$version = get_option( WPAS_PREFIX . 'version', false );

		/* Load the upgrade functions */
		if( $version )
			require_once( WPAS_PATH . 'functions/upgrade.php' );

		/* Update from versions below 2.0.0 to v2 */
		if( $version && version_compare( $version, '2.0.0', '<' ) )
			wpas_upgrade_to_2_0_0();

		/* Finally, update the version number in DB */
		if( $version )
			update_option( WPAS_PREFIX . 'version', WPAS_VERSION );

	}

	/**
	 * Register custom fields in user profile
	 *
	 * We need to hook those function in a separate function
	 * as user_can cannot be loaded too early. We have to call
	 * this function on the init hook for it to work.
	 */
	public function UserCustomFields() {

		if( isset( $_GET['user_id'] ) && current_user_can( 'administrator' ) ) {

			add_action( 'show_user_profile', array( $this, 'UserProfileFields' ) );
			add_action( 'edit_user_profile', array( $this, 'UserProfileFields' ) );

		}

		add_action( 'profile_personal_options', array( $this, 'UserProfileFields' ) );
		add_action( 'personal_options_update', array( $this, 'SaveUserProfileFields' ) );
		add_action( 'edit_user_profile_update', array( $this, 'SaveUserProfileFields' ) );

	}

	/**
	 * Prepare the translation
	 */
	public function loadTranslation() {
	 	load_plugin_textdomain( 'wpas', false, dirname( WPAS_BASENAME ) . '/languages/' );
	}

	/**
	 * Checks if the current page belongs to the plugin
	 * 
	 * @param  (boolean) $post Current post ID
	 * @return (boolean) True if the post belongs to the plugin
	 */
	public function isPluginPage( $post = false ) {

		/* If the PT is identified in a GET var no need to go further */
		if( isset($_GET['post_type']) && ( $_GET['post_type'] == 'tickets' || $_GET['post_type'] == 'quick-reply' ) )
			return true;

		/* Let's try to get the post ID */
		if( !$post )
			global $post;

		/* If we're in the admin, the post ID should be passed as GET var */
		if( !isset($post) && isset($_GET['post']) )
			$post = $_GET['post'];

		/* Sorry but I can't find the current post ID */
		if( !isset($post) )
			return false;

		/* If we only get the post ID, we look for the object */
		if( is_numeric($post) ) {
			$post = get_post( $post );
		}

		/* If we can't get the post object, abort the function and return false */
		if( !is_object($post) )
			return false;

		/* Post ID */
		$pid = $post->ID;

		/* Post type */
		$cpt = $post->post_type;

		/* Get ticket submission page ID */
		$submit = wpas_get_option( 'ticket_submit' );

		/* Get tickets listing ID */
		$list = wpas_get_option( 'ticket_list' );

		/* If the current ID matched the ticket submit or list page, or if the post type is tickets, we return true */
		if( $pid == $submit || $pid == $list || $cpt == 'tickets' || $cpt == 'quick-reply' ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Gets the post type slug
	 * 
	 * @return (string) The post type slug
	 */
	public static function getPostTypeSlug() {

		/* Return the filtered slug */
		return 'tickets';
	}
	
	/**
	 * Register menus
	 */
	public function registerMenus() {

		/* The E-Mail Settings */
		add_submenu_page( 'edit.php?post_type=tickets', __('WP Awesome Support E-Mail Settings', 'wpas'), __('E-Mail Settings', 'wpas'), 'settings_tickets', 'wpas-email', 'wpas_email_settings' );
	}

	/**
	 * Prints jQuery Object
	 *
	 * This functions will output some of the
	 * main plugin options in the site's header
	 * as a JS object so that jQuery scripts can
	 * easily get plugin parameters.
	 * 
	 * @return (string) jQuery Object
	 */
	public function jQueryObject() {

		global $wp_version;

		/* General vars */
		$global = array(
			'global' => array(
				'wpasUrl' 		=> WPAS_URL,
				'wpasPrefix' 	=> WPAS_PREFIX,
				'baseUrl' 		=> site_url(),
				'version' 		=> WPAS_VERSION,
				'wordpress_version' => $wp_version,
				'current_theme' => get_stylesheet(),
				'locale' 		=> str_replace( '_', '-', WPLANG )
			),
		);

		/* File upoad related vars */
		if( wpas_can_attach_files() ) {

			$global['attachments'] = array(
				'allowedExtensions' => explode( ',', wpas_get_option( 'allowed_filetypes' ) ),
				'maxFiles' 			=> wpas_get_option( 'files_number', 2 ),
				'maxSize' 			=> wpas_get_upload_max_size() * 1024 * 1024,
			);

			/* Ink Filepicker specific vars */
			if( 'filepicker' == wpas_get_option( 'upload_script', 'fineuploader' ) ) {

				$services = wpas_get_option( 'filepicker_services', array() );
				$secret   = wpas_get_option( 'filepicker_secret', false );

				$global['attachments']['fpApiKey'] = wpas_get_option( 'filepicker_api', false );

				if( !empty( $services ) )
					$global['attachments']['allowedServices'] = $services;

				if( $secret ) {

					$delay = is_admin() ? '+60 minutes' : '+20 minutes';

					$global['attachments']['fpPolicy'] = base64_encode( json_encode( array( 'maxsize' => $global['attachments']['maxSize'], 'path' => 'tmp/', 'expiry' => strtotime( $delay ), 'call' => array( 'store', 'pick', 'read' ) ) ) );
					$global['attachments']['fpSignature'] = hash_hmac( 'sha256', $global['attachments']['fpPolicy'], $secret );

				}

			}
		}

		if( is_admin() ) {

			if( 'filepicker' == wpas_get_option( 'upload_script', 'fineuploader' ) )
				wp_localize_script( 'wpas-js-filepicker-init', 'wpas', json_encode( apply_filters( 'wpas_jquery_object', $global ) ) );

			elseif( 'fineuploader' == wpas_get_option( 'upload_script', 'fineuploader' ) )
				wp_localize_script( 'wpas-js-fineuploader-init', 'wpas', json_encode( apply_filters( 'wpas_jquery_object', $global ) ) );

		} else {

			wp_localize_script( 'wpas-js-main', 'wpas', json_encode( apply_filters( 'wpas_jquery_object', $global ) ) );

		}
	}

	/**
	 * Register ticket custom post type
	 *
	 * This post type is the core of the plugin as tickets
	 * are handeled as a custom post type.
	 */
	public function registerPostType() {

		/* Available taxonomies */
		$taxo = array();

		/* We check if th user wants to use tags */
		if( wpas_get_option('use_tags', 'no') == 'yes' )
			array_push($taxo, 'post_tag');

		// Labels
		$labels = array(
			'name' 					=> _x('Tickets', 'post type general name', 'wpas'),
			'singular_name' 		=> _x('Ticket', 'post type singular name', 'wpas'),
			'add_new' 				=> __('Add New Ticket', 'wpas'),
			'add_new_item' 			=> __('Add A Ticket', 'wpas'),
			'edit_item' 			=> __('Reply to Ticket', 'wpas'),
			'new_item' 				=> __('New Ticket', 'wpas'),
			'all_items' 			=> __('All Tickets', 'wpas'),
			'view_item' 			=> __('View Ticket', 'wpas'),
			'search_items' 			=> __('Find A Ticket', 'wpas'),
			'not_found' 			=>  __('You have no tickets assigned', 'wpas'),
			'not_found_in_trash' 	=> __('No Ticket In The Trash', 'wpas'), 
			'parent_item_colon' 	=> '',
			'menu_name' 			=> __('Tickets', 'wpas')
		);
	  
		$args = array(
			'labels' 				=> $labels,
			'public' 				=> true,
			'exclude_from_search' 	=> true,
			'publicly_queryable' 	=> true,
			'show_ui' 				=> true, 
			'show_in_menu' 			=> true, 
			'query_var' 			=> true,
			'rewrite' 				=> array(
				'slug' 					=> $this->cpt_slug,
				'with_front'			=> false
			),
			'capability_type' 		=> 'view_ticket',
			'capabilities' 			=> array(
				'read'					 => 'view_ticket',
				'read_post'				 => 'view_ticket',
				'read_private_posts' 	 => 'view_ticket',
				'edit_post'				 => 'edit_ticket',
				'edit_posts'			 => 'edit_ticket',
				'edit_others_posts' 	 => 'edit_ticket',
				'edit_private_posts' 	 => 'edit_ticket',
				'edit_published_posts' 	 => 'edit_ticket',
				'publish_posts'			 => 'create_ticket',
				'delete_post'			 => 'delete_ticket',
				'delete_posts'			 => 'delete_ticket',
				'delete_private_posts' 	 => 'delete_ticket',
				'delete_published_posts' => 'delete_ticket',
				'delete_others_posts' 	 => 'delete_ticket' ,
			),
			'has_archive' 			=> true, 
			'hierarchical' 			=> false,
			// 'menu_position' 		=> 100,
			'supports' 				=> array('title', 'editor', 'tags', 'author'),
			'taxonomies' 			=> $taxo,
			'menu_icon' 			=> WPAS_URL . 'images/icon-tickets.png'
		);

		register_post_type( 'tickets', $args );
	}

	public function customizeUpdateMessages( $messages ) {

		global $post, $post_ID;

		$messages['tickets'] = array(
			0 => '', // Unused. Messages start at index 1.
			1 => sprintf( __( 'Ticket updated. <a href="%s">View ticket</a>', 'wpas' ), esc_url( get_permalink($post_ID) ) ),
			2 => __( 'Custom field updated.', 'wpas' ),
			3 => __( 'Custom field deleted.', 'wpas' ),
			4 => __( 'Ticket updated.', 'wpas' ),
			/* translators: %s: date and time of the revision */
			5 => isset($_GET['revision']) ? sprintf( __( 'Ticket restored to version %s', 'wpas' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
			6 => sprintf( __( 'Ticket published. <a href="%s">View ticket</a>', 'wpas' ), esc_url( get_permalink( $post_ID ) ) ),
			7 => __( 'Ticket saved.', 'wpas' ),
			8 => sprintf( __( 'Ticket saved. <a target="_blank" href="%s">View ticket</a>', 'wpas' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
			9 => sprintf( __( 'Ticket scheduled for : <strong>%1$s</strong>. <a target="_blank" href="%2$s">View ticket</a>', 'wpas' ),
			  // translators: Publish box date format, see http://php.net/date
				date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
			10 => sprintf( __( 'Ticket draft updated. <a target="_blank" href="%s">Preview ticket</a>', 'wpas' ), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
		);

		return $messages;

	}

	/**
	 * Add a new taxonomy
	 * 
	 * @param (array) $taxo Contains the taxonomy information as follows array( 'singular' => 'singular name', 'plural' => 'plural name', 'label' => 'menu label' )
	 * @since 2.0.0
	 */
	public function addTaxonomy( $taxo ) {

		if( !is_array( $taxo ) || !isset( $taxo['singular'] ) || !isset( $taxo['id'] ) )
			return;

		$singular 	= $taxo['singular'];
		$plural 	= isset( $taxo['plural'] ) ? $taxo['plural'] : $singular;
		$label 		= isset( $taxo['label'] ) ? $taxo['label'] : $plural;
		$required	= isset( $taxo['required'] ) ? $taxo['required'] : false;
		$id			= isset( $taxo['id'] ) ? $taxo['id'] : false;

		$new = array(
			'singular' 	=> $singular,
			'plural' 	=> $plural,
			'label' 	=> $label,
			'required' 	=> $required,
			'id' 		=> $id
		);

		$this->taxonomies[] = $new;

	}

	/**
	 * Add custom field to submission form
	 * 
	 * @param (array) $args List of arguments
	 * @since 2.0.0
	 */
	public function addCustomField( $name = false, $args ) {

		if( !$name )
			return;

		$name = sanitize_text_field( $name );

		$field = array(
			'name' 	=> $name,
			'id' 	=> isset( $args['id'] ) ? sanitize_text_field( $args['id'] ) : $name,
			'label' => isset( $args['label'] ) ? sanitize_text_field( $args['label'] ) : $name,
		);

		if( isset( $args['class'] ) )
			$field['class'] = sanitize_text_field( $args['class'] );

		if( isset( $args['callback'] ) )
			$field['callback'] = sanitize_text_field( $args['callback'] );

		if( isset( $args['required'] ) )
			$field['required'] = true;

		$this->customFields[] = $field;
	}

	public function getCustomFields() {
		return $this->customFields;
	}

	/**
	 * Get all the taxonomies
	 *
	 * This function will mix the default taxonomies and the custom ones, either added through the class WP_Awesome_Support::addTaxonomy() or through the admin (saved in the database).
	 *
	 * @since 2.0.0
	 */
	public function getTaxonomies() {

		/**
		 * TODO
		 *
		 * Get custom taxonomies from DB then iterate
		 * and call WP_Awesome_Support::addTaxonomy()
		 * for each. Finally add it to $this->taxonomies
		 */
		$custom = array();

		return $this->taxonomies;

	}

	/**
	 * Register the "status" taxonomy
	 *
	 * This taxonomy is mendatory for the plugin to
	 * work properly. Hence, there is no choice here and
	 * we register it directly with appropriate settings.
	 */
	public static function registerStatusTaxonomy() {

		$status_labels = array(
			'name'                => _x( 'Status', 'taxonomy general name', 'wpas' ),
			'singular_name'       => _x( 'Status', 'taxonomy singular name', 'wpas' ),
			'search_items'        => __( 'Search Statuses', 'wpas' ),
			'all_items'           => __( 'All Statuses', 'wpas' ),
			'parent_item'         => __( 'Parent Status', 'wpas' ),
			'parent_item_colon'   => __( 'Parent Status:', 'wpas' ),
			'edit_item'           => __( 'Edit Status', 'wpas' ), 
			'update_item'         => __( 'Update Status', 'wpas' ),
			'add_new_item'        => __( 'Add New Status', 'wpas' ),
			'new_item_name'       => __( 'New Status Name', 'wpas' ),
			'menu_name'           => __( 'Status', 'wpas' )
		); 	

		$status_args = array(
			'hierarchical'        => true,
			'labels'              => $status_labels,
			'show_ui'             => false,
			'show_admin_column'   => true,
			'query_var'           => true,
			'rewrite'             => array( 'slug' => 'status' ),
			'capabilities' 		  => array(
				'manage_terms' 		=> 'cannot_do',
				'edit_terms' 		=> 'cannot_do',
				'delete_terms' 		=> 'cannot_do',
				'assign_terms' 		=> 'close_ticket'
			),
		);

		register_taxonomy( 'status', 'tickets', $status_args );

	}

	/**
	 * Register plugin default taxonomies
	 */
	public function registerDefaultTaxonomies() {

		/* Register the default taxonomies */
		$this->addTaxonomy( array( 'singular' => __( 'Types', 'wpas' ), 'plural' => __( 'Types', 'wpas' ), 'label' => __( 'Types', 'wpas' ), 'id' => 'type', 'required' => true ) );
		$this->addTaxonomy( array( 'singular' => __( 'Priorities', 'wpas' ), 'plural' => __( 'Priorities', 'wpas' ), 'label' => __( 'Priorities', 'wpas' ), 'id' => 'priority', 'required' => true ) );
		$this->addTaxonomy( array( 'singular' => __( 'States', 'wpas' ), 'plural' => __( 'States', 'wpas' ), 'label' => __( 'State', 'wpas' ), 'id' => 'state', 'required' => true ) );

	}

	/**
	 * Register all taxonomies
	 *
	 * This function will get all the taxonomies (built-in
	 * and custom) and register them as hierarchical taxonomies
	 * for the tickets post type.
	 * 
	 * @since 2.0.0
	 */
	public function registerTaxonomies() {

		$taxonomies = $this->getTaxonomies();

		foreach( $taxonomies as $key => $taxo ) {

			$slug 		= sanitize_title( $taxo['singular'] );
			$singular 	= ucwords( sanitize_title( $taxo['singular'] ) );
			$plural 	= ucwords( sanitize_title( $taxo['plural'] ) );
			$label 		= sanitize_title( $taxo['label'] );
			$id 		= sanitize_title( $taxo['id'] );

			$labels = array(
				'name'                => ucwords( $plural ),
				'singular_name'       => ucwords( $singular ),
				'search_items'        => sprintf( __( 'Search %s', 'wpas' ), $plural ),
				'all_items'           => sprintf( __( 'All %s', 'wpas' ), $plural ),
				'parent_item'         => sprintf( __( 'Parent %s', 'wpas' ), $singular ),
				'parent_item_colon'   => sprintf( __( 'Parent %s:', 'wpas' ), $singular ),
				'edit_item'           => sprintf( __( 'Edit %s', 'wpas' ), $singular ),
				'update_item'         => sprintf( __( 'Update %s', 'wpas' ), $singular ),
				'add_new_item'        => sprintf( __( 'Add New %s', 'wpas' ), $singular ),
				'new_item_name'       => sprintf( __( 'New %s Name', 'wpas' ), $singular ),
				'menu_name'           => $plural
			);

			$args = array(
				'hierarchical'        => true,
				'labels'              => $labels,
				'show_ui'             => true,
				'show_admin_column'   => true,
				'query_var'           => true,
				'rewrite'             => array( 'slug' => $label ),
				'capabilities' 		  => array(
					'manage_terms' 		=> 'ticket_taxonomy',
					'edit_terms' 		=> 'ticket_taxonomy',
					'delete_terms' 		=> 'ticket_taxonomy',
					'assign_terms' 		=> 'ticket_taxonomy'
				)
			);
		
			register_taxonomy( $id, 'tickets', $args );

		}
	}

	/**
	 * We remove the custom taxonomies metaboxes
	 * as we prefer managing them with custom fields
	 * in order to avoid having two different
	 * values for a taxonomy.
	 */
	public function removeTaxonomiesMetaboxes() {

		$taxonomies = $this->getTaxonomies();

		foreach( $taxonomies as $key => $taxo ) {

			remove_meta_box( $taxo['id'] . 'div', 'tickets', 'side' );

		}
	}

	/**
	 * Modify the default CPT menu link
	 * 
	 * Look for our CPT item in the menu and
	 * then alter the URL to add the open status
	 * ID in the link.
	 */
	function modifyPostTypeMenuItemLink() {

		/* First of all we check if the user
		 * wants to only show opened tickets
		 * when listing all the tickets */
		$show = wpas_get_option( 'only_list_open', 'no' );

		/* If the user doesn't use this feature, we abort the function */
		if( 'no' == $show )
			return;

		/* Get the submenu list */
		global $submenu;

		/* Check if the CPT menu item is in the array */
		if( is_array( $submenu ) && array_key_exists( "edit.php?post_type=tickets", $submenu ) ) {

			/* We loop through the menu items looking for our CPT */
			foreach( $submenu["edit.php?post_type=tickets"] as $key => $item ) {

				/* If this item is the CPT */
				if( "edit.php?post_type=tickets" == $item[2] ) {

					/* Get the open term ID */
					$term = get_term_by( 'slug', 'wpas-open', 'status' );

					/* Open term ID */
					$term_id = $term->term_id;

					/* We add the status parameter to the link */
					$submenu["edit.php?post_type=tickets"][$key][2] = $item[2] . '&status=' . $term_id;
				}
			}
		}
	}

	/**
	 * This function will count the number of open tickets
	 * an agent sees in his dashboard and add the number in
	 * the "Tickets" item of the admin menu.
	 */
	function AddTicketsCount() {

		global $menu, $current_user;
		$count = 0;

		$args = array(
			'posts_per_page' => -1,
			'post_type' 	 => 'tickets'
		);

		if( !current_user_can( 'administrator' ) || wpas_get_option('admins_see_all', 'no') == 'no' ) {
			$args['meta_key']   = WPAS_PREFIX.'assignee';
			$args['meta_value'] = $current_user->data->ID;
		}

		$tickets = get_posts( $args );

		foreach( $tickets as $ticket ) {
			/* Get ticket status */
			$status  = get_the_terms( $ticket->ID, 'status' );
			if( $status ) {
				foreach($status as $s) {
					if( $s->slug == 'wpas-open' )
						$count++;
				}
			}
		}

		if( $count == 0 )
			return;

		foreach ( $menu as $key => $value ) {
			if ( $menu[$key][2] == 'edit.php?post_type=tickets' ) {
				$menu[$key][0] .= ' <span class="awaiting-mod count-'.$count.'"><span class="pending-count">' . $count . '</span></span>';
				return;
			}
		}

	}

	public function loadAdminScripts() {
		
		/* We make sure the current page belongs to the plugin */
		if( !$this->isPluginPage() )
			return;

		wp_enqueue_script( 'wpas-main-admin', WPAS_URL.'js/admin/main.js', '', WPAS_VERSION, true );

		/* Translate text strings contained in JS file */
		wp_localize_script( 'wpas-main-admin', 'wpasL10n', array(
			'alertDelete' 		=> __( 'Warning: This action can not be undone.\n\nClick OK to confirm deletion.', 'wpas' ),
			'alertQuickReplies' => __( 'Quick replies only works in the Visual Editor.\nDo you want to use it now?', 'wpas' ),
			)
		);

		wp_enqueue_script( 'wp-color-picker' );

		/* If file attachment is enabled we call the script */
		if( wpas_can_attach_files() ) {

			global $post;

			/* Only load uploader script if we're on a ticket edit screen */
			if( isset( $_GET['action'] ) && 'edit' == $_GET['action'] && 'tickets' == $post->post_type ) {

				if( 'fineuploader' == wpas_get_option( 'upload_script', 'fineuploader' ) ) {

					wp_enqueue_script( 'wpas-js-fineuploader', WPAS_URL . 'plugins/jquery.' . $this->fineuploader . '/jquery.' . $this->fineuploader . '.min.js', '', false, true );
					wp_enqueue_script( 'wpas-js-fineuploader-init', WPAS_URL . 'js/admin/wpas-fineuploader.js', '', false, true );

				} elseif( 'filepicker' == wpas_get_option( 'upload_script', 'fineuploader' ) ) {

					wp_enqueue_script( 'wpas-js-filepicker', '//api.filepicker.io/v1/filepicker.js', '', false, true );
					wp_enqueue_script( 'wpas-js-filepicker-init', WPAS_URL . 'js/admin/wpas-filepicker.js', '', false, true );

				}

			}

		}
	}

	public function loadAdminStyles() {

		wp_enqueue_style( 'wpas-notifier', WPAS_URL . 'css/admin/wpas-notifier.css', '', false, 'screen' );

		/* We make sure the current page belongs to the plugin */
		if( !$this->isPluginPage() )
			return;

		wp_enqueue_style( 'wp-color-picker' );
		wp_enqueue_style( 'wpas-css', WPAS_URL.'css/admin/wpas.css', '', false, 'screen' );
		wp_enqueue_style( 'wpas-buttons', WPAS_URL.'css/admin/buttons.min.css', '', false, 'screen' );

		/* If file attachment is enabled we call the style */
		if( wpas_can_attach_files() && 'fineuploader' == wpas_get_option( 'upload_script', 'fineuploader' ) ) {
			wp_enqueue_style( 'wpas-css-fineuploader', WPAS_URL.'plugins/jquery.' . $this->fineuploader . '/' . $this->fineuploader . '.css', '', '4.1.0', 'screen' );
		}
	}

	public function loadStyles() {

		/* We make sure the current page belongs to the plugin */
		if( !$this->isPluginPage() )
			return;

		/* Get the style type the user needs */
		$style = wpas_get_option( 'plugin_style' );

		/* We make sure we're not in the admin */
		if( is_admin() )
			return;

		/* We don't load the styles if the user disabled all plugin styling */
		if( $style != 'disable' && $style != 'no_forms' ) {

			/* Default Bootstrap style (light color) */
			wp_enqueue_style( 'wpas-css-bootstrap', WPAS_URL.'css/bootstrap-wpas.min.css', '', false, 'screen' );

			/* Load the dark style */
			if( 'dark' == $style ) {
				wp_enqueue_style( 'wpas-css-bootstrap-dark', WPAS_URL . 'css/dark.css', '', false, 'screen' );
			}

			wp_enqueue_style( 'wpas-css-bootstrap-tagmanager', WPAS_URL.'css/bootstrap-tagmanager.css', '', false, 'screen' );

			/* wysihtml5 */
			if( wpas_get_option( 'frontend_wysiwyg_editor' ) == 'yes' ) {
				wp_enqueue_style( 'wpas-css-bootstrap-wysihtml5', WPAS_URL.'plugins/bootstrap3-wysihtml5/bootstrap3-wysihtml5.min.css', '', false, 'screen' );
			}

			/* Plugin main style */
			wp_enqueue_style( 'wpas-css-main', WPAS_URL.'css/main.css', '', false, 'screen' );
		}

		/**
		 * This CSS is required even if user doesn't want plugin styling
		 */
		if( wpas_can_attach_files() && 'fineuploader' == wpas_get_option( 'upload_script', 'fineuploader' ) ) {
			wp_enqueue_style( 'wpas-css-fineuploader', WPAS_URL.'plugins/jquery.' . $this->fineuploader . '/' . $this->fineuploader . '.css', '4.1.0', false, 'screen' );
		}

		wp_enqueue_style( 'wpas-mendatory', WPAS_URL.'css/mandatory.css', '', WPAS_VERSION, 'screen' );
	}

	public function loadScripts() {

		/* We make sure the current page belongs to the plugin */
		if( !$this->isPluginPage() )
			return;

		/* We only load those resources in frontend */
		if( !is_admin() ) {

			wp_enqueue_script( 'wpas-js-bootstrap', WPAS_URL.'js/bootstrap.min.js', array( 'jquery' ), NULL, true );
			wp_enqueue_script( 'wpas-js-bootstrap-tagmanager', WPAS_URL.'js/bootstrap-tagmanager.js', array( 'jquery' ), NULL, true );
			wp_enqueue_script( 'wpas-js-easyModal', WPAS_URL.'js/jquery.easyModal.min.js', array( 'jquery' ), NULL, true );

			/* wysihtml5 */
			if( wpas_get_option( 'frontend_wysiwyg_editor' ) == 'yes' ) {

				$locale = str_replace( '_', '-', WPLANG );

				wp_enqueue_script( 'wpas-wysihtml5-js', WPAS_URL.'plugins/bootstrap3-wysihtml5/bootstrap3-wysihtml5.all.min.js', '', false, true );

				/* Load translation for wysihtml5 */
				if( file_exists( WPAS_PATH . "plugins/bootstrap3-wysihtml5/locales/bootstrap-wysihtml5.$locale.js" ) ) {

					wp_enqueue_script( 'wpas-bootstrap-wysihtml5-locales', WPAS_URL . "plugins/bootstrap3-wysihtml5/locales/bootstrap-wysihtml5.$locale.js", '', false, true );

				}

			}

			/* If file attachment is enabled we call the script */
			if( wpas_can_attach_files() ) {

				if( 'fineuploader' == wpas_get_option( 'upload_script', 'fineuploader' ) )
					wp_enqueue_script( 'wpas-js-fineuploader', WPAS_URL.'plugins/jquery.' . $this->fineuploader . '/jquery.' . $this->fineuploader . '.min.js', '', false, true );

				elseif( 'filepicker' == wpas_get_option( 'upload_script', 'fineuploader' ) )
					wp_enqueue_script( 'wpas-js-filepicker', '//api.filepicker.io/v1/filepicker.js', '', false, true );

			}

			if( 'yes' == wpas_get_option( 'live_search', 'no' ) )
				wp_enqueue_script( 'wpas-searchbox', WPAS_URL.'js/searchbox.js', '', false, true );

			wp_enqueue_script( 'wpas-placeholder', WPAS_URL.'js/jquery.placeholder.min.js', '', false, true );
			wp_enqueue_script( 'wpas-sisyphus', WPAS_URL.'js/sisyphus.min.js', '', false, true );
			wp_enqueue_script( 'wpas-restable', WPAS_URL.'plugins/jquery.restable/jquery.restable.min.js', '', false, true );
			wp_enqueue_script( 'wpas-js-main', WPAS_URL.'js/main.js', '', WPAS_VERSION, true );

			/* Translate text strings contained in JS file */
			wp_localize_script( 'wpas-js-main', 'wpasL10n', array(
				'uploadAddMore' => __( 'Add more files', 'wpas' ),
				'uploadIssue' 	=> sprintf( __( '<strong>Oh snap!</strong> We were unabled to load the uploader script. Please %srefresh the page%s if you want to attach files.', 'wpas' ), '<a href="#" onClick="window.location.reload()">', '</a>' ),
				)
			);
		}
	}

	/**
	 * Script for FineUploader
	 */
	public function fineUploaderScript() {

		global $post;

		/* Make sure Fineuploader is in use */
		if( 'fineuploader' != wpas_get_option( 'upload_script', 'fineuploader' ) )
			return;

		if( isset( $post ) && is_object( $post ) && ( wpas_get_option( 'ticket_submit' ) == $post->ID || is_single() && 'tickets' == $post->post_type || is_admin() && 'tickets' == $post->post_type ) ): ?>

		<script type="text/template" id="wpas-qq-template">
			<div class="qq-uploader-selector qq-uploader">
				<div class="qq-upload-drop-area-selector wpas-dz" qq-hide-dropzone>
					<span aria-hidden="true" class="glyphicon glyphicon-cloud-upload"></span>
					<span><?php _e( 'Drop files here to upload', 'wpas' ); ?></span>
				</div>
				<div class="qq-upload-button-selector wpas-btn-upload btn btn-default btn-block">
					<?php _e( 'Browse files or Drop files here', 'wpas' ); ?>
				</div>
				<span class="qq-drop-processing-selector">
					<span><?php _e( 'Processing dropped files...', 'wpas' ); ?></span>
				</span>
				<ul class="qq-upload-list-selector qq-upload-list">
					<li>
						<div class="qq-progress-bar-container-selector progress">
							<div class="qq-progress-bar-selector progress-bar"></div>
						</div>
						<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
						<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
						<span class="qq-upload-file-selector qq-upload-file"></span>
						<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
						<span class="qq-upload-size-selector qq-upload-size"></span>
						<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">لغو</a>
						<a class="qq-upload-retry-selector qq-upload-retry" href="#">دوباره</a>
						<a class="qq-upload-delete-selector qq-upload-delete" href="#">حذف</a>
						<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
					</li>
				</ul>
			</div>
		</script>
		<?php
		endif;
	}

	/**
	 * Add version number in footer
	 */
	public function versionInFooter() {

		printf( __( WPAS_NAME . ' version ' . WPAS_VERSION . ' by <a href="%s">' . WPAS_AUTHOR . '</a>.', 'gtsp' ), esc_url( WPAS_URI ) );

	}

	/**
	 * Adds admin notices for updates
	 * 
	 * @return (string) Echoes the notice
	 */
	public function adminNotices() {

		if( !isset($_GET['page']) || $_GET['page'] != 'wpas-templates' || $_GET['page'] != 'wpas-settings' )
			return;

		if( isset( $_GET['settings-updated'] ) )
			echo '<div id="message" class="updated fade">' . __('Settings updated.', 'wpas') . '</div>';
	}

	/**
	 * Simple setup assistant
	 *
	 * This assistant will ask the use if he wants to setup the required pages. By clicking yes, the user lets the plugin
	 * create the sicket submission and tickets list pages. Those pages will be saved as "special pages" and the appropriate
	 * shortcodes will be inserted in the pages 
	 *
	 * @since 2.0.0
	 */
	public function pluginSetup() {

		if( ( 'skipped' || 'done' ) == get_option( 'wpas_setup_status', false ) )
			return;

		?>
		<div id="message" class="updated wpas-message wpas-setup">
			<h4>شما تقریبا آماده هستید که تیکت ها رو با قدرت تمام پاسخ بدی! فقط قبلش باید صفحات پیشفرض رو ایجاد کنی</h4>
			<p class="submit">
				<a href="<?php echo add_query_arg( array( 'install' => 'true' ), admin_url( 'edit.php?post_type=tickets' ) ); ?>" class="button-primary"><?php _e( 'Install Support Pages', 'wpas' ); ?></a>
				<a class="skip button-primary" href="<?php echo add_query_arg( array( 'skip_install' => 'true' ), admin_url( 'edit.php?post_type=tickets' ) ); ?>">بی خیال اصلا!</a>
			</p>
		</div>
		<?php

	}

	/**
	 * Redirects to submit page after login
	 * 
	 * @return (string) The redirect URL
	 */
	public function redirectAfterLogin() {

		if( !$this->redirect_login )
			return;

		global $current_user;
		
		$role 	= get_option( 'default_role', 'subscriber' );
		$submit = wpas_get_option( 'ticket_submit' );
		$link 	= get_permalink( $submit );

		if( is_object( $current_user ) && isset( $current_user->data->roles ) && $current_user->data->roles[0] == $role )
			return $link;

		else
			return admin_url();
	}
	
	/**
	 * Add the <code> tag to TinyMCE
	 */
	function addWysiwygCodeTag( $settings ) {

		$style_formats = array(
			array(
				'title' 	=> 'Code',
				'inline' 	=> 'code',
				'classes' 	=> '',
				'wrapper' 	=> false
			),
			array(
				'title' 	=> 'Keyboard',
				'inline' 	=> 'kbd',
				'classes' 	=> '',
				'wrapper' 	=> false
			),
		);

		$settings['style_formats'] = json_encode( $style_formats );

		return $settings;
	}

	/**
	 * Change publish button label in ticket edit screen
	 */
	function changePublishButtonLabel( $translation, $text ) {
		global $typenow;

		if( $text == 'Update' && $typenow == 'tickets' && isset($_GET['post']) )
		    return __('Update Ticket', 'wpas');

		return $translation;
	}

	/**
	 * If the admin doesn't want the users to be
	 * able to reach the WordPress admin, this function
	 * will redirect users with the base role to
	 * the tickets list.
	 */
	public function preventAdminAccess() {

		/**
		 * This is no good. Could lead to security issues.
		 * I need to find a better way to stop the function execution
		 * in certain cases.
		 */
		if( defined('DOING_AJAX') && DOING_AJAX )
			return;

		global $current_user;

		$prevent = wpas_get_option( 'prevent_admin_access' );
		$role 	 = get_option( 'default_role', 'subscriber' );

		if( is_admin() && in_array( $role, $current_user->roles ) && $prevent == 'yes' ) {

			/**
			 * wpas_before_prevent_admin_access hook
			 */
			do_action( 'wpas_before_prevent_admin_access' );

			$redirect = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : wpas_get_option( 'ticket_list' );

			if( $redirect ) {
				wp_redirect( get_permalink( $redirect ), 302 );
			} else {
				wp_redirect( home_url(), 302 );
			}
		}
	}

	/**
	 * Add the group selection to the user profile
	 */
	public function UserProfileFields( $user ) {

		$val 	= get_user_meta( $user->ID, 'wpas_user_group', true );
		$groups = get_terms( 'type', array('hide_empty' => 0) );
		?>

		<h3><?php _e( 'Agent Support Group', 'wpas' ); ?></h3>
		<table class="form-table">
			<tr>
				<th>
					<label for="wpas_user_group"><?php _e('Agent\'s Group', 'wpas'); ?></label>
				</th>
				<td>
					<select name="wpas_user_group" id="wpas_user_group">
						<option value="" <?php if( $val == '' ) { echo ' selected="selected"'; } ?> disabled="disabled"><?php _e('None', 'wpas'); ?></option>
						<?php
						foreach( $groups as $group => $vars ) {
							?><option value="<?php echo $vars->slug; ?>" <?php if( $val == $vars->slug ) echo ' selected="selected"'; ?>><?php echo $vars->name; ?></option><?php
						}
						?>
					</select>
				</td>
			</tr>
		</table>
	<?php }

	/**
	 * Save the custom user profile fields
	 */
	public function SaveUserProfileFields( $user_id ) {

		if ( !current_user_can( 'edit_user', $user_id ) )
			return false;

		update_user_meta( $user_id, 'wpas_user_group', $_POST['wpas_user_group'] );
	}

	/**
	 * We don't use the standard WordPress archive for
	 * the tickets as it's gonna look ugly in most
	 * cases. Better redirect on the user's tickets list.
	 */
	public function RedirectArchive( $query ) {

		if( is_admin() )
			return;

		if ( is_post_type_archive( 'tickets' ) ) {

			$list = wpas_get_option( 'ticket_list' );

			wp_redirect( get_permalink( $list ), 301 );

		}
	}

	/**
	 * Redirect user to homepage after logout
	 *
	 * @param (string) Current logout URL
	 * @return (string) New logout URL
	 */
	public function LogoutRedirectUrl( $logouturl ) {
		return $logouturl . '&amp;redirect_to=' . urlencode( home_url() );
	}

	/**
	 * Alternative function for logout redirect
	 * if user loggs out without using a link generated
	 * by the WordPress function
	 */
	public function LoggedOutRedirect() {
		if( isset($_GET['loggedout']) && $_GET['loggedout'] == 'true' ) {
			wp_redirect( home_url() );
			exit;
		}
	}

	/**
	 * Removes some of the default admin bar items
	 */
	public function RemoveAdminBarItems() {

		global $wp_admin_bar;

		if( !current_user_can('administrator') ) {

			if( 'yes' == wpas_get_option( 'prevent_admin_access' ) ) {

				$wp_admin_bar->remove_node( 'site-name' );
				$wp_admin_bar->remove_menu( 'edit-profile' );
				$wp_admin_bar->remove_menu( 'user-info' );

			}

		}

		$wp_admin_bar->remove_menu('wporg');
		$wp_admin_bar->remove_menu('documentation');
		$wp_admin_bar->remove_menu('support-forums');
		$wp_admin_bar->remove_menu('feedback');

	}

	/**
	 * Customize the admin bar and add the plugin
	 * specific links.
	 */
	public function CustomizeAdminBar() {

		global $wp_admin_bar, $current_user, $post;

		$submit 	  = wpas_get_option( 'ticket_submit' );
		$tickets_page = wpas_get_option( 'ticket_list' );

		/* Does the user want to see all states? */
		$show = wpas_get_option( 'only_list_open', 'no' );

		/* Get CPT slug */
		$slug = $this->getPostTypeSlug();

		if( 'yes' == $show ) {

			/* Get the open term ID */
			$term = get_term_by( 'slug', 'wpas-open', 'status' );

			/* Open term ID */
			$term_id = $term->term_id;

			/* Prepare URL */
			$url = add_query_arg( array( 'status' => $term_id ), admin_url( 'edit.php?post_type=' . $slug ) );

		} else {
			$url = admin_url( 'edit.php?post_type=' . $slug );
		}
			
		if( !current_user_can( 'edit_ticket' ) ) {

			$wp_admin_bar->add_menu( array(
				'id' 	=> 'new-ticket',
				'title' => __( 'Submit Ticket', 'wpas' ),
				'href' 	=> __( get_permalink($submit) )
			) );

			$wp_admin_bar->add_menu( array(
				'id' 	=> 'my-tickets',
				'title' => __( 'My Tickets', 'wpas' ),
				'href' 	=> get_permalink( $tickets_page )
			) );

		}

		if( current_user_can( 'edit_ticket' ) ) {

			$wp_admin_bar->add_menu( array(
				'id' 	=> 'all-tickets',
				'title' => __( 'My Tickets', 'wpas' ),
				'href' 	=> __( $url )
			) );

			if( isset( $_GET['action'] ) && 'edit' == $_GET['action'] && 'tickets' == $post->post_type )

			$wp_admin_bar->add_menu( array(
				'id' 	=> 'wpas-private-note',
				'title' => __( 'Add Note', 'wpas' ),
				'href' 	=> '#TB_inline?height=400&amp;width=700&amp;inlineId=wpas-note-modal',
				'meta'  => array( 'class' => 'wpas-add-note thickbox', 'title' => __( 'Add a private note to this ticket', 'wpas' ) )
			) );

		}

		$wp_admin_bar->add_menu( array(
			'id' 	=> 'about-wpas',
			'parent' => 'wp-logo',
			'title' => __( 'About WP Awesome Support', 'wpas' ),
			'href' 	=> 'http://bit.ly/1hYx4Tw'
		) );

	}

	/**
	 *	If the current page belongs to the plugin front-end we load the
	 * modal placeholders in the footer.
	 */
	public function modalPlaceholders() {
		global $post;

		/* If the current page is a 404 we don't load the content */
		if( is_404() )
			return;

		/* Ticket submit page ID  */
		$submit = wpas_get_option('ticket_submit');

		/* Tickets list page ID */
		$list   = wpas_get_option('ticket_list');

		/* Check if the current page belongs to the plugin */
		if( $post->ID == $submit || $post->ID == $list || $post->post_type == 'tickets' ): ?>

		<div class="wpas">
			<div class="wpas-modal" id="wpas-modalterms" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
				<div class="modal-content">
					<div class="modal-header">
						<h4 class="modal-title"><?php _e('Terms &amp; Conditions', 'wpas'); ?></h4>
					</div>
					<div class="modal-body">
						<?php echo wpas_get_option('terms'); ?>
					</div>
				</div>
			</div>

			<div class="wpas-modal" id="wpas-modalenvato" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
				<div class="modal-content">
					<div class="modal-header">
						<h4 class="modal-title"><?php _e('Get My Purchase Code', 'wpas'); ?></h4>
					</div>
					<div class="modal-body">
						<img class="wpas-youtube" id="Ii2V4mj7X_o" src="<?php echo WPAS_URL; ?>images/envato-purchasecode.jpg" alt="<?php _e('Get Envato Purchase Code', 'wpas'); ?>" width="700" height="525">
					</div>
				</div>
			</div>

			<div class="wpas-modal" id="wpas-modalupload" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;">
				<div class="modal-content">
					<div class="modal-header">
						<h4 class="modal-title"><?php _e('There was some errors', 'wpas'); ?></h4>
					</div>
					<div class="modal-body"></div>
				</div>
			</div>
		</div>
		<?php endif;
	}

	/**
	 * Add Snapengage script to the site's footer
	 * @return [type] [description]
	 */
	public function snapengage() {
		$code = wpas_get_option('snapengage_code');
		if( $code )
			echo $code;
	}

	/**
	 * If a built-in cache system messes up with the login process
	 */
	public function forceClearCache() {
		global $post;
		$submit = wpas_get_option('ticket_submit');
		$list   = wpas_get_option('ticket_list');
		$styles = wpas_get_option('disable_plugin_style');

		if( $post->ID == $submit || $post->ID == $list || $post->post_type == 'tickets' ) {
			header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
			header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
			header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
			header("Cache-Control: post-check=0, pre-check=0", false);
			header("Pragma: no-cache");
		}
	}

	/**
	 * Add custom CSS to site's header
	 */
	public function customCss() {
		global $post;
		$submit = wpas_get_option('ticket_submit');
		$list   = wpas_get_option('ticket_list');

		if( isset( $post ) && is_object( $post ) && ( $post->ID == $submit || $post->ID == $list || $post->post_type == 'tickets' ) ):
			$extra = wpas_get_option('extra_css');
		echo '<!-- This is your custom CSS -->';
			echo '<style>'.$extra.'</style>';
		endif;
	}

	/**
	 * The WordPress SEO plugin is messing up
	 * with the content filter through the 
	 * opengraph class. Hence, we remove the
	 * description method from this class.
	 */
	public function wpas_wordpress_seo_fix() {

		include_once( ABSPATH . 'wp-admin/includes/plugin.php' );

		if( is_plugin_active( 'wordpress-seo/wp-seo.php' ) ) {
			global $wpseo_og;
			remove_action( 'wpseo_opengraph', array( $wpseo_og, 'description' ), 11 );
			remove_filter( 'fb_meta_tags', array( $wpseo_og, 'facebook_filter' ), 10 );
		}
	}

	/**
	 * Modify ticket replies
	 */
	public function deleteTicketReply() {

		if( isset( $_GET['rid'] ) && is_numeric( $_GET['rid'] ) && isset( $_GET['_wpnonce'] ) ) {

			$rid = intval( $_GET['rid'] );

			/* If the nonce is incorrect we just go back to the edit screen */
			if( !wp_verify_nonce( $_GET['_wpnonce'], 'delete_reply_' . $rid  ) ) {

				wp_redirect( add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit' ), admin_url( 'post.php' ) ) );
				exit;

			}

			/* Otherwise we delete and redirect */
			wp_update_post( array( 'ID' => $rid, 'post_content' => __( 'This reply has been deleted by the agent.', 'wpas' ), 'post_status' => 'trash' ) );

			wp_redirect( add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit' ), admin_url( 'post.php' ) ) . '#wpas-post-' . $rid );
			exit;

		}

	}

	/**
	 * Get the single ticket template for front-end
	 */
	public function singleTemplate() {

		global $post;

		/* Get theme name */
		$theme = get_stylesheet();

		$custom = STYLESHEETPATH . '/single-tickets.php'; // Custom template filename
		$ready 	= WPAS_PATH . 'templates/' . $theme . '/single-tickets.php'; // Pre-build template filename

		/* Test if a custom template exists */
		if( is_single() && 'tickets' == $post->post_type ) {

			/* Otherwise we load the default template */
			if( file_exists( $custom ) ) {

				include( $custom );
				exit();

			} elseif( file_exists( $ready ) ) {

				include( $ready );
				exit();

			} else {

				include( WPAS_PATH . '/templates/single-tickets.php' );
				exit();

			}

		}
	}

	/**
	 * Register the hook to automatically close ticket to the WordPress cron
	 *
	 * @since 2.0.0
	 */
	public function ticketsPurge() {

		$clean = wpas_get_option( 'automatically_close' );

		if( 'yes' == $clean && !wp_next_scheduled( 'wpas_tickets_purge' ) ) {

			wp_schedule_event( time(), 'twicedaily', 'wpas_tickets_purge');

		} elseif( 'no' == $clean && wp_next_scheduled( 'wpas_tickets_purge' ) ) {

			wp_clear_scheduled_hook( 'wpas_tickets_purge' );

		}

	}

	/**
	 * Live search
	 *
	 * This is used to perform live search in the database to avoid clients submitting tickets
	 * when there is already an answer in the FAQ.
	 *
	 * @since 2.0.0
	 */
	public function liveSearch() {

		if( is_search() && isset( $_GET['wpas_search'] ) && 'true' == sanitize_text_field( $_GET['wpas_search'] ) ) {
			include( WPAS_PATH . '/templates/template-live-search.php' );
			exit;
		}

	}

	public function limitLiveSearch( $query ) {

		$live_search   = wpas_get_option( 'live_search', 'no' );
		$search_places = wpas_get_option( 'live_search_where', array() );

		if( 'no' == $live_search )
			return $query;

		if( $query->is_search() && !is_admin() && isset( $_GET['wpas_search'] ) )
			$query->set( 'post_type', $search_places );

		return $query;
	}

	/**
	 * Client notifications
	 *
	 * Get push notifications from the server
	 *
	 * @since 2.0.1
	 */
	public function clientAlert() {

		/* Retrieve message from DB if available */
		$notification = get_transient( 'wpas_notification' );

		/* If not, go for a request */
		if( !$notification ) {

			/* Endpoint URL */
			$endpoint = $this->alert_endpoint;

			/* Get the content */
			$raw = wp_remote_get( $endpoint );

			/* Check request header */
			if( isset( $raw['response']['code'] ) && 200 == $raw['response']['code'] ) {

				/* Get body */
				$notification = wp_remote_retrieve_body( $raw );

				/* Make sure body is not empty */
				if( '' != $notification ) {

					/* Set transient to avoid too many requests */
					set_transient( 'wpas_notification', $notification, 60 * 60 * 1 );

				}

			}

		}

		if( $notification ) {

			$alert = json_decode( $notification );

			/* Make sure the notification is in JSON format */
			if( version_compare( phpversion(), '5.3.0', '>=' ) ) {

				if( ! ( json_last_error() == JSON_ERROR_NONE ) )
					return;

			} else {
				
				if( $alert == NULL )
					return;

			}

			$screen 	= get_current_screen();
			$dismissed  = get_option( 'wpas_dismissed_alerts', array() );
			$dismiss 	= add_query_arg( array( 'action' => 'wpas-dismiss', 'alert' => $alert->slug ), admin_url( $screen->parent_file ) );

			if( is_array( $dismissed ) && in_array( $alert->slug, $dismissed ) )
				return;

			if( isset( $alert->title ) && isset( $alert->message ) ) {
				?>
				<div id="<?php echo $alert->slug; ?>" class="updated wpas-message">
					<h4><?php echo $alert->title; ?></h4>
					<p class="wpas-message-body">
						<?php echo $alert->message; ?>
					</p>
					<a href="<?php echo $dismiss; ?>" class="wpas-dismiss dashicons dashicons-xit" title="<?php _e( 'Dismiss', 'wpas' ); ?>">&#10005;</a>
				</div>
				<?php

			}

		}

	}

	/**
	 * Dismiss client notifications
	 *
	 * @since 2.0.1
	 */
	public function dismissAlert() {

		if( isset( $_GET['action'] ) && isset( $_GET['alert'] ) && 'wpas-dismiss' == $_GET['action'] ) {

			$dismissed = get_option( 'wpas_dismissed_alerts', array() );

			if( !is_array( $dismissed ) )
				$dismissed = array();

			array_push( $dismissed, $_GET['alert'] );

			update_option( 'wpas_dismissed_alerts', $dismissed );

		}

	}
	
}

$wpas = new WP_Awesome_Support();