<?php
/*
 * License: GPLv3
 * License URI: http://www.gnu.org/licenses/gpl.txt
 * Copyright 2012-2016 Jean-Sebastien Morisset (http://surniaulula.com/)
 */

if ( ! defined( 'ABSPATH' ) ) 
	die( 'These aren\'t the droids you\'re looking for...' );

if ( ! class_exists( 'NgfbTaxonomy' ) ) {

	/*
	 * This class is extended by gpl/util/taxonomy.php or pro/util/taxonomy.php
	 * and the class object is created as $this->p->m['util']['taxonomy'].
	 */
	class NgfbTaxonomy extends NgfbMeta {

		protected $tax_slug = false;
		protected $tax_obj = false;
		protected $term_id = false;

		protected function add_actions() {
			if ( is_admin() ) {
				/**
				 * Hook a minimum number of admin actions to maximize performance.
				 * The taxonomy and tag_ID arguments are always present when we're
				 * editing a category and/or tag page, so return immediately if
				 * they're not present.
				 */
				if ( ( $this->tax_slug = SucomUtil::get_req_val( 'taxonomy' ) ) === '' )
					return;

				$this->tax_obj = get_taxonomy( $this->tax_slug );
				if ( ! $this->tax_obj->public )
					return;

				if ( ! empty( $this->p->options['plugin_columns_taxonomy'] ) ) {

					add_filter( 'manage_edit-'.$this->tax_slug.'_columns', 
						array( $this, 'add_column_headings' ), 10, 1 );
					add_filter( 'manage_'.$this->tax_slug.'_custom_column', 
						array( $this, 'get_taxonomy_column_content' ), 10, 3 );
	
					$this->p->util->add_plugin_filters( $this, array( 
						'og_image_taxonomy_column_content' => 4,
						'og_desc_taxonomy_column_content' => 4,
					) );
				}

				if ( ( $this->term_id = SucomUtil::get_req_val( 'tag_ID' ) ) === '' )
					return;

				if ( $this->p->debug->enabled )
					$this->p->debug->log( 'tax_slug/term_id values: '.
						$this->tax_slug.'/'.$this->term_id );

				/**
				 * Available term and taxonomy actions:
				 *
				 * do_action( "create_term",       $term_id, $tt_id, $taxonomy );
				 * do_action( "created_term",      $term_id, $tt_id, $taxonomy );
				 * do_action( "edited_term",       $term_id, $tt_id, $taxonomy );
				 * do_action( 'delete_term',       $term_id, $tt_id, $taxonomy, $deleted_term );
				 * do_action( "create_$taxonomy",  $term_id, $tt_id );
				 * do_action( "created_$taxonomy", $term_id, $tt_id );
				 * do_action( "edited_$taxonomy",  $term_id, $tt_id );
				 * do_action( "delete_$taxonomy",  $term_id, $tt_id, $deleted_term );
				 */

				add_action( 'admin_init', array( &$this, 'add_metaboxes' ) );
				// load_meta_page() priorities: 100 post, 200 user, 300 taxonomy
				add_action( 'current_screen', array( &$this, 'load_meta_page' ), 300, 1 );
				add_action( $this->tax_slug.'_edit_form', array( &$this, 'show_metaboxes' ), 100, 1 );
				add_action( 'created_'.$this->tax_slug, array( &$this, 'save_options' ), NGFB_META_SAVE_PRIORITY, 2 );
				add_action( 'created_'.$this->tax_slug, array( &$this, 'clear_cache' ), NGFB_META_CACHE_PRIORITY, 2 );
				add_action( 'edited_'.$this->tax_slug, array( &$this, 'save_options' ), NGFB_META_SAVE_PRIORITY, 2 );
				add_action( 'edited_'.$this->tax_slug, array( &$this, 'clear_cache' ), NGFB_META_CACHE_PRIORITY, 2 );
				add_action( 'delete_'.$this->tax_slug, array( &$this, 'delete_options' ), NGFB_META_SAVE_PRIORITY, 2 );
				add_action( 'delete_'.$this->tax_slug, array( &$this, 'clear_cache' ), NGFB_META_CACHE_PRIORITY, 2 );
			}
		}

		public function get_taxonomy_column_content( $value, $column_name, $id ) {
			return $this->get_mod_column_content( $value, $column_name, $id, 'taxonomy' );
		}

		public function filter_og_image_taxonomy_column_content( $value, $column_name, $id, $mod_name ) {

			if ( ! empty( $value ) )
				return $value;

			// use the open graph image dimensions to reject images that are too small
			$size_name = $this->p->cf['lca'].'-opengraph';
			$check_dupes = false;	// using first image we find, so dupe checking is useless
			$force_regen = false;
			$md_pre = 'og';
			$og_image = array();

			if ( empty( $og_image ) )
				$og_image = $this->get_og_video_preview_image( $id, $mod_name, $check_dupes, $md_pre );

			// get_og_images() also provides filter hooks for additional image ids and urls
			if ( empty( $og_image ) )
				$og_image = $this->get_og_image( 1, $size_name, $id, $check_dupes, $force_regen, $md_pre );

			if ( empty( $og_image ) )
				$og_image = $this->p->media->get_default_image( 1, $size_name, $check_dupes, $force_regen );

			if ( ! empty( $og_image ) && is_array( $og_image ) ) {
				$image = reset( $og_image );
				if ( ! empty( $image['og:image'] ) )
					$value = $this->get_og_image_column_html( $image );
			}

			return $value;
		}

		public function filter_og_desc_taxonomy_column_content( $desc, $column_name, $id, $mod_name ) {
			if ( ! empty( $desc ) )
				return $desc;

			$term_obj = get_term_by( 'id', $id, $this->tax_slug, OBJECT, 'raw' );
			if ( empty( $term_obj->term_id ) )
				return $desc;

			$desc = $this->p->util->get_mod_options( 'taxonomy', $term_obj->term_id, 'og_desc' );

			if ( $this->p->debug->enabled ) {
				if ( empty( $desc ) )
					$this->p->debug->log( 'no custom description found' );
				else $this->p->debug->log( 'custom description = "'.$desc.'"' );
			}

			if ( empty( $desc ) ) {
				if ( is_tag( $term_obj->term_id ) ) {
					if ( ! $desc = tag_description( $term_obj->term_id ) )
						$desc = sprintf( 'Tagged with %s', $term_obj->name );
	
				} elseif ( is_category( $term_obj->term_id ) ) { 
					if ( ! $desc = category_description( $term_obj->term_id ) )
						$desc = sprintf( '%s Category', $term_obj->name ); 
	
				} else {
					if ( ! empty( $term_obj->description ) )
						$desc = $term_obj->description;
					elseif ( ! empty( $term_obj->name ) )
						$desc = $term_obj->name.' Archives';
				}
			}

			return $desc;
		}

		// hooked into the current_screen action
		public function load_meta_page( $screen = false ) {

			if ( $this->p->debug->enabled )
				$this->p->debug->mark();

			// all meta modules set this property, so use it to optimize code execution
			if ( ! empty( NgfbMeta::$head_meta_tags ) 
				|| ! isset( $screen->id ) )
					return;

			if ( $this->p->debug->enabled )
				$this->p->debug->log( 'screen id: '.$screen->id );

			$lca = $this->p->cf['lca'];
			switch ( $screen->id ) {
				case 'edit-'.$this->tax_slug:
					break;
				default:
					return;
					break;
			}

			$add_metabox = empty( $this->p->options[ 'plugin_add_to_taxonomy' ] ) ? false : true;

			if ( apply_filters( $this->p->cf['lca'].'_add_metabox_taxonomy', 
				$add_metabox, $this->term_id, $screen->id ) === true ) {

				do_action( $this->p->cf['lca'].'_admin_taxonomy_header', $this->term_id, $screen->id );

				// use_post is false since this isn't a post
				// read_cache is false to generate notices etc.
				NgfbMeta::$head_meta_tags = $this->p->head->get_header_array( false );
				NgfbMeta::$head_meta_info = $this->p->head->extract_head_info( NgfbMeta::$head_meta_tags );

				if ( empty( NgfbMeta::$head_meta_info['og:image'] ) )
					// check for missing open graph image and issue warning
					$this->p->notice->err( $this->p->msgs->get( 'notice-missing-og-image' ) );
			}

			$action_query = $lca.'-action';
			if ( ! empty( $_GET[$action_query] ) ) {
				$action_name = SucomUtil::sanitize_hookname( $_GET[$action_query] );
				if ( $this->p->debug->enabled )
					$this->p->debug->log( 'found action query: '.$action_name );
				if ( empty( $_GET[ NGFB_NONCE ] ) ) {	// NGFB_NONCE is an md5() string
					if ( $this->p->debug->enabled )
						$this->p->debug->log( 'nonce token query field missing' );
				} elseif ( ! wp_verify_nonce( $_GET[ NGFB_NONCE ], NgfbAdmin::get_nonce() ) ) {
					$this->p->notice->err( sprintf( __( 'Nonce token validation failed for %1$s action "%2$s".',
						'nextgen-facebook' ), 'taxonomy', $action_name ) );
				} else {
					$_SERVER['REQUEST_URI'] = remove_query_arg( array( $action_query, NGFB_NONCE ) );
					switch ( $action_name ) {
						default: 
							do_action( $lca.'_load_meta_page_taxonomy_'.$action_name, $this->term_id );
							break;
					}
				}
			}
		}

		public function add_metaboxes() {
			if ( ! current_user_can( $this->tax_obj->cap->edit_terms ) ) {
				if ( $this->p->debug->enabled )
					$this->p->debug->log( 'insufficient privileges to add metabox for taxonomy '.$this->tax_slug );
				return;
			}
			$add_metabox = empty( $this->p->options[ 'plugin_add_to_taxonomy' ] ) ? false : true;
			if ( apply_filters( $this->p->cf['lca'].'_add_metabox_taxonomy', $add_metabox ) === true )
				add_meta_box( NGFB_META_NAME, _x( 'Social Settings', 'metabox title', 'nextgen-facebook' ),
					array( &$this, 'show_metabox_taxonomy' ), 'taxonomy', 'normal', 'low' );
		}

		public function show_metaboxes( $term ) {
			if ( ! current_user_can( $this->tax_obj->cap->edit_terms ) )
				return;
			echo '<div id="poststuff">';
			do_meta_boxes( 'taxonomy', 'normal', $term );
			echo '</div>';
		}

		public function show_metabox_taxonomy( $term ) {
			$opts = $this->get_options( $term->term_id );
			$def_opts = $this->get_defaults( false, 'taxonomy' );
			$this->form = new SucomForm( $this->p, NGFB_META_NAME, $opts, $def_opts );
			wp_nonce_field( NgfbAdmin::get_nonce(), NGFB_NONCE );	// NGFB_NONCE is an md5() string

			// save additional info about the term
			NgfbMeta::$head_meta_info['term_id'] = $term->term_id;			// term id

			$metabox = 'taxonomy';
			$tabs = apply_filters( $this->p->cf['lca'].'_social_settings_taxonomy_tabs',
				$this->get_default_tabs(), $term );
			if ( empty( $this->p->is_avail['mt'] ) )
				unset( $tabs['tags'] );

			$rows = array();
			foreach ( $tabs as $key => $title )
				$rows[$key] = array_merge( $this->get_rows( $metabox, $key, NgfbMeta::$head_meta_info ), 
					apply_filters( $this->p->cf['lca'].'_'.$metabox.'_'.$key.'_rows', 
						array(), $this->form, NgfbMeta::$head_meta_info ) );
			$this->p->util->do_tabs( $metabox, $tabs, $rows );
		}

		public function clear_cache( $term_id, $term_tax_id = false ) {
			$post_id = 0;
			$lca = $this->p->cf['lca'];
			$lang = SucomUtil::get_locale();
			$sharing_url = $this->p->util->get_sharing_url( false );
			$transients = array(
				'NgfbHead::get_header_array' => array( 
					'lang:'.$lang.'_post:'.$post_id.'_url:'.$sharing_url,
					'lang:'.$lang.'_post:'.$post_id.'_url:'.$sharing_url.'_crawler:pinterest',
				),
				'NgfbMeta::get_mod_column_content' => array( 
					'lang:'.$lang.'_id:'.$term_id.'_mod:taxonomy_column:'.$lca.'_og_image',
				),
			);
			$transients = apply_filters( $this->p->cf['lca'].'_taxonomy_cache_transients', 
				$transients, $term_id, $lang, $sharing_url );

			$deleted = $this->p->util->clear_cache_objects( $transients );

			if ( ! empty( $this->p->options['plugin_cache_info'] ) && $deleted > 0 )
				$this->p->notice->inf( $deleted.' items removed from the WordPress object and transient caches.', true );

			return $term_id;
		}

		public static function get_public_terms( $tax_name = false, $fields = 'ids' ) {
			$ret = array();
			$tax_filter = array(
				'public' => 1,
			);
			if ( $tax_name !== false )
				$tax_filter['name'] = $tax_name;
			$term_args = array(
				'fields' => $fields,
			);
			$oper = 'and';
			foreach ( get_taxonomies( $tax_filter, 'names' ) as $tax_name ) {
				foreach ( get_terms( $tax_name, $term_args, $oper ) as $term_val ) {
					$ret[] = $term_val;
				}
			}
			sort( $ret );
			return $ret;
		}

		public static function get_term_meta( $term_id, $options_name, $single ) {
			$options_name .= '_term_'.$term_id;
			/**
			 * re-create the return value of get_post_meta() and get_user_meta():
			 *
			 * If the meta value does not exist and $single is true the function will return an empty string.
			 * If $single is false an empty array is returned.
			 */
			return get_option( $options_name, ( $single === false ? array() : '' ) );
		}

		public static function update_term_meta( $term_id, $options_name, $opts ) {
			$options_name .= '_term_'.$term_id;
			return update_option( $options_name, $opts );
		}

		public static function delete_term_meta( $term_id, $options_name ) {
			$options_name .= '_term_'.$term_id;
			return delete_option( $options_name );
		}
	}
}

?>
