<?php
if ( ! class_exists( 'NISHIKI_PRO_BREADCRUMBS' ) ) {
	/**
	 * Create Code.
	 */
	class NISHIKI_PRO_BREADCRUMBS extends NISHIKI_PRO_GENERAL_UTILITY {

		/**
		 * Constructor.
		 */
		public function __construct() {
			// フォーム追加
			add_action( 'admin_init', array( $this, 'nishiki_pro_register_settings' ), 20 );
			add_action(
				'template_redirect',
				function() {
					$this->output();
				}
			);

			// add_filter( 'nishiki_before_site_footer', array( $this, 'output' ), 30 );
		}

		/**
		 * フォーム追加
		 */
		public function nishiki_pro_register_settings() {
			$page_name = $this->plugin_name . '_breadcrumbs';

			register_setting(
				$page_name,
				$page_name,
				array( $this, 'sanitize' )
			);

			add_settings_section(
				$page_name,
				'',
				array( $this, 'nishiki_pro_general_cb' ),
				$page_name
			);

			add_settings_field(
				'enable',
				__( 'パンくずリストを表示する', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_checkbox_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '有効化',
					'label'       => 'enable',
					'page_name'   => $page_name,
					'description' => '有効にする場合はチェックを入れてください。',
				)
			);

			add_settings_field(
				'display',
				__( '表示箇所', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_checkbox_multiple_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '',
					'label'       => 'display',
					'page_name'   => $page_name,
					'description' => '表示する箇所にチェックを入れてください。',
					'script'      => array(
						'header' => 'ヘッダー',
						'footer' => 'フッター',
					),
					'display_key' => true,
				)
			);

			add_settings_field(
				'post_type',
				__( '表示する投稿・固定ページ', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_checkbox_multiple_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '',
					'label'       => 'post_type',
					'page_name'   => $page_name,
					'description' => '有効にする場合はチェックを入れてください。',
					'script'      => $this->post_types(),
					'display_key' => true,
				)
			);

			add_settings_field(
				'archive',
				__( '表示するアーカイブページ', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_checkbox_multiple_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '',
					'label'       => 'archive',
					'page_name'   => $page_name,
					'description' => '有効にする場合はチェックを入れてください。「年」「月」「日」のアーカイブページでパンくずリストを表示する場合は、パーマリンク設定を「基本」以外に設定してください。',
					'script'      => $this->archives(),
					'display_key' => true,
				)
			);

			add_settings_field(
				'other',
				__( 'その他のページ', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_checkbox_multiple_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '',
					'label'       => 'other',
					'page_name'   => $page_name,
					'description' => '有効にする場合はチェックを入れてください。',
					'script'      => $this->other(),
					'display_key' => true,
				)
			);

			add_settings_field(
				'home_text',
				__( 'トップページのリンクテキスト', 'nishiki_pro' ),
				array( $this, 'nishiki_pro_text_cb' ),
				$page_name,
				$page_name,
				array(
					'title'       => '',
					'label'       => 'home_text',
					'page_name'   => $page_name,
					'placeholder' => __( 'Home' ),
					'description' => '空欄の場合は「' . __( 'Home' ) . '」と表示されます',
				)
			);
		}

		/**
		 * 投稿タイプの配列取得
		 */
		public function post_types() {
			$pt_args  = array(
				'public' => true,
			);
			$output   = 'objects';
			$operator = 'and';
			$pts      = get_post_types( $pt_args, $output, $operator );

			$pt_array = array();

			foreach ( $pts as $pt ) {
				if ( 'attachment' !== $pt->name ) {
					$pt_array[ $pt->name ] = $pt->label;
				}
			}

			return $pt_array;
		}


		/**
		 * タクソノミーの配列取得
		 */
		public function taxonomy_archives() {
			$args       = array(
				'public' => true,
			);
			$output     = 'objects';
			$operator   = 'and';
			$taxonomies = get_taxonomies( $args, $output, $operator );

			$tax_array = array();

			foreach ( $taxonomies as $taxonomy ) {
				if ( 'post_format' !== $taxonomy->name ) {
					$tax_array[ $taxonomy->name ] = $taxonomy->label;
				}
			}

			return $tax_array;
		}

		/**
		 * 投稿タイプのアーカイブページ
		 */
		public function post_type_archives() {
			$args = array(
				'public'   => true,
				'_builtin' => false,
			);

			$output   = 'objects';
			$operator = 'and';

			$post_types = get_post_types( $args, $output, $operator );

			$post_types_array = array();

			foreach ( $post_types as $post_type ) {
				$post_types_array[ $post_type->name ] = $post_type->label;
			}

			return $post_types_array;
		}

		/**
		 * その他のアーカイブページ
		 */
		public function other_archives() {
			$archive_array = array(
				'author' => '著者',
				'paged'  => '複数ページ',
				'year'   => '年',
				'month'  => '月',
				'day'    => '日',
			);

			return $archive_array;
		}

		/**
		 * アーカイブページの配列
		 */
		public function archives() {
			$taxonomy_archives  = $this->taxonomy_archives();
			$post_type_archives = $this->post_type_archives();
			$other_archives     = $this->other_archives();

			$archives = array_merge( $taxonomy_archives, $post_type_archives );
			$archives = array_merge( $archives, $other_archives );

			return $archives;
		}

		/**
		 * その他のページ配列取得
		 */
		public function other() {
			$other_array = array(
				'404'    => '404',
				'search' => '検索',
			);

			return $other_array;
		}

		/**
		 * 出力
		 */
		public function output() {
			$page_name = $this->plugin_name . '_breadcrumbs';
			$options   = get_option( $page_name );

			if ( isset( $options['enable'] ) ) {
				// Header
				self::breadcrumbs_header( $options );

				// Footer
				self::breadcrumbs_footer( $options );				
			}

		}

		/**
		 * Meta position 生成
		 *
		 * @param integer $num 数値
		 * @return string
		 */
		public function meta_position( $num = 1 ) {
			return '<meta itemprop="position" content="' . $num . '" />';
		}

		/**
		 * ヘッダーの出力
		 */
		public function breadcrumbs_header( $options ){
			if ( isset( $options['display']['header'] ) ) {

				$output = self::create_breadcrumbs( $options, ' nishiki-pro-breadcrumbs-header' );

				if ( is_singular() && ! is_front_page() ) {
					$queried_object = get_queried_object();
					$post_type = $queried_object->post_type;
					$post_id   = $queried_object->ID;


					if ( isset( $options['post_type'][ $post_type ] ) ) {
						if ( get_post_meta( $post_id, '_nishiki_pro_meta_box_breadcrumbs_disable_' . get_post_type(), true ) ) {
							return;
						}

						add_filter(
							'nishiki_pro_before_singular_container',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				}

				if ( is_search() ) {
					if ( isset( $options['other']['search'] ) ) {
						add_filter(
							'nishiki_pro_before_search_container',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				} elseif ( is_archive() ) {
					$term_object = get_queried_object();

					if ( is_category() || is_tag() || is_tax() ) {
						$taxonomy = $term_object->taxonomy;

						if ( isset( $options['archive'][ $taxonomy ] ) ) {
							add_filter(
								'nishiki_pro_before_archive_container',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}

					if ( is_post_type_archive() ) {
						$post_type_archive = $term_object->name;

						if ( isset( $options['archive'][ $post_type_archive ] ) ) {
							add_filter(
								'nishiki_pro_before_archive_container',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}

					if ( is_date() ) {
						$permalink_structure = get_option( 'permalink_structure' );

						if ( isset( $permalink_structure ) && '' !== $permalink_structure ) {
							if ( is_year() ) {
								if ( isset( $options['archive']['year'] ) ) {
									add_filter(
										'nishiki_pro_before_archive_container',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
							if ( is_month() ) {
								if ( isset( $options['archive']['month'] ) ) {
									add_filter(
										'nishiki_pro_before_archive_container',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
							if ( is_day() ) {
								if ( isset( $options['archive']['day'] ) ) {
									add_filter(
										'nishiki_pro_before_archive_container',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
						}
					}

					if ( is_author() ) {
						if ( isset( $options['archive']['author'] ) ) {
							add_filter(
								'nishiki_pro_before_archive_container',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}
				}

				if ( is_404() ) {
					if ( isset( $options['other']['404'] ) ) {
						add_filter(
							'nishiki_pro_before_404_container',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				}

				if ( is_home() ) {
					if ( is_front_page() ) {
						if ( is_paged() ) {
							if ( isset( $options['archive']['paged'] ) ) {
								add_filter(
									'nishiki_pro_before_index_container',
									function() use ( $options, $output ) {
										echo wp_kses_post( $output );
									},
									10
								);
							}
						}
					} else {
						if ( isset( $options['archive']['paged'] ) ) {
							add_filter(
								'nishiki_pro_before_index_container',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}
				}
			}
		}

		/**
		 * フッターの出力
		 */
		public function breadcrumbs_footer( $options ){
			if ( isset( $options['display']['footer'] ) ) {

				$output = self::create_breadcrumbs( $options, ' nishiki-pro-breadcrumbs-footer' );

				if ( is_singular() && ! is_front_page() ) {
					
					$queried_object = get_queried_object();
					$post_type = $queried_object->post_type;
					$post_id   = $queried_object->ID;

					if ( isset( $options['post_type'][ $post_type ] ) ) {
						if ( get_post_meta( $post_id, '_nishiki_pro_meta_box_breadcrumbs_disable_' . get_post_type(), true ) ) {
							return;
						}

						add_filter(
							'nishiki_pro_after_content',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				}

				if ( is_archive() ) {
					$term_object = get_queried_object();

					if ( is_category() || is_tag() || is_tax() ) {
						$taxonomy = $term_object->taxonomy;

						if ( isset( $options['archive'][ $taxonomy ] ) ) {
							add_filter(
								'nishiki_pro_after_content',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}

					if ( is_post_type_archive() ) {
						$post_type_archive = $term_object->name;

						if ( isset( $options['archive'][ $post_type_archive ] ) ) {
							add_filter(
								'nishiki_pro_after_content',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}

					if ( is_date() ) {
						$permalink_structure = get_option( 'permalink_structure' );

						if ( isset( $permalink_structure ) && '' !== $permalink_structure ) {
							if ( is_year() ) {
								if ( isset( $options['archive']['year'] ) ) {
									add_filter(
										'nishiki_pro_after_content',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
							if ( is_month() ) {
								if ( isset( $options['archive']['month'] ) ) {
									add_filter(
										'nishiki_pro_after_content',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
							if ( is_day() ) {
								if ( isset( $options['archive']['day'] ) ) {
									add_filter(
										'nishiki_pro_after_content',
										function() use ( $options, $output ) {
											echo wp_kses_post( $output );
										},
										10
									);
								}
							}
						}
					}

					if ( is_author() ) {
						if ( isset( $options['archive']['author'] ) ) {
							add_filter(
								'nishiki_pro_after_content',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}
				}

				if ( is_404() ) {
					if ( isset( $options['other']['404'] ) ) {
						add_filter(
							'nishiki_pro_after_content',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				}

				if ( is_search() ) {
					if ( isset( $options['other']['search'] ) ) {
						add_filter(
							'nishiki_pro_after_content',
							function() use ( $options, $output ) {
								echo wp_kses_post( $output );
							},
							10
						);
					}
				}

				if ( is_front_page() || is_home() ) {
					if ( is_paged() ) {
						if ( isset( $options['archive']['paged'] ) ) {
							add_filter(
								'nishiki_pro_after_content',
								function() use ( $options, $output ) {
									echo wp_kses_post( $output );
								},
								10
							);
						}
					}
				}
			}
		}

		/**
		 * パンくずリスト作成
		 *
		 * @param array $options 設定
		 * @return boolean
		 */
		public function create_breadcrumbs( $options, $position = '' ) {

			global $wp_query;

			$queried_object = get_queried_object();
			$home_link      = get_bloginfo( 'url' );
			if ( ! empty( $options['home_text'] ) ) {
				$home_text = apply_filters( 'nishiki_pro_breadcrumbs_home_text', $options['home_text'] );
			} else {
				$home_text = apply_filters( 'nishiki_pro_breadcrumbs_home_text', __( 'Home' ) );
			}
			$current = '';

			// パンくずを入れる配列
			$bread_array = array();

			// 投稿＆固定ページ
			if ( is_singular() && ! is_front_page() ) {
				$post_type = $queried_object->post_type;
				$post_id   = $queried_object->ID;
				$parent    = $queried_object->post_parent;

				// 現在のページ
				$current = wp_kses_post( get_the_title() );

				// 固定ページ＆親ページがある場合
				if ( 0 !== $parent ) {

					// 親ページがなくなるまでループ
					while ( $parent ) {
						$post_parent = get_post( $parent );

						$bread_array[] = array(
							'permalink' => get_permalink( $post_parent->ID ),
							'title'     => get_the_title( $post_parent->ID ),
						);

						$parent = $post_parent->post_parent;
					}
				}

				// カスタム投稿タイプの場合
				if ( $this->is_custom_post_type() ) {
					$post_type_object = get_post_type_object( $post_type );
					$post_type_link   = get_post_type_archive_link( $post_type );
					$taxonomies       = get_post_taxonomies( $post_id );
					$flag             = false;

					if ( $taxonomies ) {
						foreach ( $taxonomies as $taxonomy ) {
							// 非公開タクソノミーは除外
					        $taxonomy_object = get_taxonomy( $taxonomy );
							if ( ! $taxonomy_object || ! $taxonomy_object->public ) {
								continue;
							}
			
							$terms = get_the_terms( $post_id, $taxonomy );

							if( 'product_type' == $taxonomy && function_exists('wc_get_product') ){
								continue;
							}

							if ( $terms && ! is_wp_error( $terms ) ) {
								foreach ( $terms as $term ) {
									// var_dump( $terms );
									if ( $term->count > 0 && false === $flag ) {
										$flag = true;
										// 親タームを取得
										$term_parent = $term->parent;

										$bread_array[] = array(
											'permalink' => esc_url( get_term_link( $term->term_id ) ),
											'title'     => $term->name,
										);

										// 親のアーカイブがある場合
										if ( 0 !== $term_parent ) {
											// 親アーカイブがあるまでループして配列に入れる
											while ( $term_parent ) {
												$term = get_term( $term_parent, $taxonomy );

												$bread_array[] = array(
													'permalink' => get_term_link( $term ),
													'title' => $term->name,
												);

												$term_parent = $term->parent;
											}
										}

										// 最初に見つかったタームで処理を終わらせる
										break;
									}
								}
							}
						}

						// 投稿タイプのアーカイブ
						if ( $post_type_link ) {
							$bread_array[] = array(
								'permalink' => esc_url( $post_type_link ),
								'title'     => $post_type_object->label,
							);
						}
					}

					/*
					$bread_array[] = array(
						'permalink' => esc_url( $post_type_link ),
						'title'     => esc_html( $post_type_object->label ),
					);
					*/

					// 通常の投稿の場合
				} elseif ( 'post' === $post_type ) {
					$categories = get_the_terms( $post_id, 'category' );

					if( false !== $categories ){
						$bread_array[] = array(
							'permalink' => esc_url( get_term_link( $categories[0]->term_id ) ),
							'title'     => esc_html( $categories[0]->name ),
						);
					}
				}
			}

			if ( is_search() ) {
				$current = '検索結果';
			} elseif ( is_archive() ) {
				$term_object = get_queried_object();

				// 投稿タイプのアーカイブページ
				if ( is_post_type_archive() ) {
					$current = esc_html( $term_object->labels->singular_name );
				}

				// カテゴリー、タグ、タクソノミーのアーカイブページ
				if ( is_category() || is_tag() || is_tax() ) {
					// Set the variables for this section
					$term_object     = get_term( $queried_object );
					$taxonomy        = $term_object->taxonomy;
					$term_name       = $term_object->name;
					$term_parent     = $term_object->parent;
					$taxonomy_object = get_taxonomy( $taxonomy );
					$taxonomy_name   = $taxonomy_object->label;

					// 親のアーカイブがある場合
					if ( 0 !== $term_parent ) {
						// 親アーカイブがあるまでループして配列に入れる
						while ( $term_parent ) {
							$term = get_term( $term_parent, $taxonomy );

							$bread_array[] = array(
								'permalink' => get_term_link( $term ),
								'title'     => $term->name,
							);

							$term_parent = $term->parent;
						}
					}

					$current = $term_name;
				}

				// 日付のアーカイブページ
				if ( is_date() ) {
					$year  = $wp_query->query_vars['year'];
					$month = $wp_query->query_vars['monthnum'];
					$day   = $wp_query->query_vars['day'];

					// 年
					if ( is_year() ) {

						$current = $year . __( 'Year' );
						// 月
					} elseif ( is_month() ) {

						// 年
						$bread_array[] = array(
							'permalink' => esc_url( get_year_link( $year ) ),
							'title'     => $year . __( 'Year' ),
						);

						$current = $month . __( 'Month' );

						// 日
					} elseif ( is_day() ) {
						// 年,月,日を入れる

						// 月
						$bread_array[] = array(
							'permalink' => esc_url( get_month_link( $year, $month ) ),
							'title'     => $month . __( 'Month' ),
						);

						// 年
						$bread_array[] = array(
							'permalink' => esc_url( get_year_link( $year ) ),
							'title'     => $year . __( 'Year' ),
						);

						$current = $day . __( 'Day' );
					}
				}

				if ( is_author() ) {
					$current = esc_html( $queried_object->data->display_name );
				}
			}

			if ( is_404() ) {
				$current = __( 'Page Not Found.', 'nishiki-pro' );
			}

			if ( is_home() ) {
				if ( is_front_page() ) {
					if ( is_paged() ) {
						$current_page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );

						/* translators: %s: page num */
						$current = sprintf( __( 'Page %s' ), number_format_i18n( $current_page ) );
					}
				} else {
					if ( get_option( 'page_on_front' ) ) {
						if ( is_paged() ) {
							$bread_array[] = array(
								'permalink' => esc_url( get_permalink( $queried_object->ID ) ),
								'title'     => $queried_object->post_title,
							);

							$current_page = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' );

							/* translators: %s: page num */
							$current = sprintf( __( 'Page %s' ), number_format_i18n( $current_page ) );
						} else {
							// 投稿ページ
							$current = $queried_object->post_title;
						}
					}
				}
			}

			// 出力
			// 最後にhomeを入れる
			$bread_array[] = array(
				'permalink' => $home_link,
				'title'     => $home_text,
			);

			// 入れ替える
			$bread_array = array_reverse( $bread_array );

			// パーマリンクとテキストを変更するフィルター
			$bread_array = apply_filters( 'nishiki_pro_breadcrumbs_links', $bread_array );

			if ( empty( $bread_array ) ) {
				return false;
			}

			$bread_content_num = 1;
			$output            = '<div class="nishiki-pro-breadcrumbs' . $position . '"><ol itemscope itemtype="http://schema.org/BreadcrumbList" class="container">';
			foreach ( $bread_array as $bread ) {
				$output .= '<li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a itemprop="item" href="' . $bread['permalink'] . '"><span itemprop="name">' . $bread['title'] . '</span></a><meta itemprop="position" content="' . $bread_content_num . '"/></li>';

				++$bread_content_num;
			}

			$current_page = apply_filters( 'nishiki_pro_breadcrumbs_current_page_text', $current );

			if ( $current_page ) {
				$output .= apply_filters( 'nishiki_pro_breadcrumbs_current_page', '<li><span class="current">' . $current_page . '</span></li>' );
			}
			$output .= '</ol></div>';

			return $output;
		}

	}
}

$output = new NISHIKI_PRO_BREADCRUMBS();
