<?php
/*
 Plugin Name: WP Extend Toolbar
 Plugin URI: https://piece-web.jp/plugins/wp-extend-toolbar/
 Description: Adds a page information window overlay on the frontend for logged-in users.
 Author: Piece
 Version: 3.1.0
 Author URI: https://piece-web.jp/
 Domain Path: /language
 Text Domain: wp-extend-toolbar
 */

class WP_Extend_Toolbar {

	/**
	 * Settings_Managerのインスタンス
	 */
	private $settings_manager;

	function __construct() {
		// Settings_Managerのインスタンスを作成
		$this->settings_manager = new WP_Extend_Toolbar_Settings();
		
		// 既存のアクションフックを維持
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ), 100 );
		add_action( 'wp_footer', array( $this, 'output_window_info' ), 100 );
	}

	function output_window_info() {
		// 設定を読み込む
		$settings = WP_Extend_Toolbar_Settings::get_settings();
		$required_capability = isset( $settings['user_role'] ) ? $settings['user_role'] : 'edit_user';
		
		if ( is_admin() || !is_user_logged_in() || !current_user_can( $required_capability ) ) {
			return;
		}
		global $template;

		// 既存項目のデータを取得
		$theme       = get_template();
		$template_f  = basename( $template );
		
		// 新規項目のデータを取得
		$post_type = WP_Extend_Toolbar_Data_Provider::get_post_type();
		$post_id   = WP_Extend_Toolbar_Data_Provider::get_post_id();
		$taxonomy  = WP_Extend_Toolbar_Data_Provider::get_taxonomy();
		$term      = WP_Extend_Toolbar_Data_Provider::get_term();

		$close_btn = esc_url( $this->get_plugins_url('/img/btn-close.png') );
		$open_btn  = esc_url( $this->get_plugins_url('/img/btn-open.png') );

		ob_start();
		?>
		<div id="wp-extend-toolbar-window">
			<div class="window-info-inner">
				<button id="wp-extend-toolbar-window__close" type="button" title="<?php echo esc_attr( __( 'Close', 'wp-extend-toolbar' ) ); ?>"><img src="<?php echo esc_url( $close_btn ); ?>" alt="×" /></button>
				<ul id="wp-extend-toolbar-window__list">
					<?php if ( $settings['theme'] ) : ?>
					<li id="wp-extend-toolbar-window__theme" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('テーマ　　　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $theme ); ?></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['template'] ) : ?>
					<li id="wp-extend-toolbar-window__template" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('テンプレート', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $template_f ); ?></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['title'] ) : ?>
					<li id="wp-extend-toolbar-window__title" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('タイトル　　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['description'] ) : ?>
					<li id="wp-extend-toolbar-window__desc" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('説明　　　　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['keyword'] ) : ?>
					<li id="wp-extend-toolbar-window__keyword" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('キーワード　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['post_type'] ) : ?>
					<li id="wp-extend-toolbar-window__post-type" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('投稿タイプ　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $post_type ); ?></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['post_id'] ) : ?>
					<li id="wp-extend-toolbar-window__post-id" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('投稿ID　　　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $post_id ); ?></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['taxonomy'] ) : ?>
					<li id="wp-extend-toolbar-window__taxonomy" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('タクソノミー', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $taxonomy ); ?></span>
					</li>
					<?php endif; ?>
					
					<?php if ( $settings['term'] ) : ?>
					<li id="wp-extend-toolbar-window__term" class="wp-extend-toolbar-window__item">
						<span class="title"><?php echo esc_html( __('ターム　　　', 'wp-extend-toolbar') ); ?> : </span>
						<span class="value"><?php echo esc_html( $term ); ?></span>
					</li>
					<?php endif; ?>
				</ul>
			</div>
		</div>
		<button id="wp-extend-toolbar-window__reopen" type="button" title="<?php echo esc_attr( __( 'Show Toolbar', 'wp-extend-toolbar' ) ); ?>" style=""><img src="<?php echo esc_url( $open_btn ); ?>" alt="×" /></button>
		<?php
		echo ob_get_clean();
	}

	function enqueue() {
		$settings = WP_Extend_Toolbar_Settings::get_settings();
		$required_capability = isset( $settings['user_role'] ) ? $settings['user_role'] : 'edit_user';
		
		if ( is_admin() || !is_user_logged_in() || !current_user_can( $required_capability ) ) {
			return;
		}

		wp_enqueue_style( 'wp-extend-toolbar',  $this->get_plugins_url( "/css/wp-extend-toolbar.css" ), array() );
		wp_enqueue_script( 'wp-extend-toolbar', $this->get_plugins_url( "/js/wp-extend-toolbar.js" ),   array( 'jquery' ), null, true );

	}

	function get_plugins_url( $path = '' ) {
		return plugins_url( $path, __FILE__ );
	}
}


class WP_Extend_Toolbar_Settings {
	
	/**
	 * 設定のオプション名
	 */
	const OPTION_NAME = 'wp_extend_toolbar_display_settings';
	
	/**
	 * デフォルト設定
	 */
	const DEFAULT_SETTINGS = array(
		'theme'       => true,
		'template'    => true,
		'title'       => true,
		'description' => true,
		'keyword'     => true,
		'post_type'   => false,
		'post_id'     => false,
		'taxonomy'    => false,
		'term'        => false,
		'user_role'   => 'edit_user'  // デフォルト: 管理者+編集者
	);
	
	/**
	 * キャッシュされた設定（1リクエストにつき1回のみDB読み込み）
	 */
	private static $cached_settings = null;
	
	/**
	 * 表示項目の定義
	 */
	const DISPLAY_ITEMS = array(
		'theme' => array(
			'id'          => 'wp-extend-toolbar-window__theme',
			'label'       => 'テーマ',
			'data_source' => 'php',
			'default'     => true
		),
		'template' => array(
			'id'          => 'wp-extend-toolbar-window__template',
			'label'       => 'テンプレート',
			'data_source' => 'php',
			'default'     => true
		),
		'title' => array(
			'id'          => 'wp-extend-toolbar-window__title',
			'label'       => 'タイトル',
			'data_source' => 'javascript',
			'default'     => true
		),
		'description' => array(
			'id'          => 'wp-extend-toolbar-window__desc',
			'label'       => '説明',
			'data_source' => 'javascript',
			'default'     => true
		),
		'keyword' => array(
			'id'          => 'wp-extend-toolbar-window__keyword',
			'label'       => 'キーワード',
			'data_source' => 'javascript',
			'default'     => true
		),
		'post_type' => array(
			'id'          => 'wp-extend-toolbar-window__post-type',
			'label'       => '投稿タイプ',
			'data_source' => 'php',
			'default'     => false
		),
		'post_id' => array(
			'id'          => 'wp-extend-toolbar-window__post-id',
			'label'       => '投稿ID',
			'data_source' => 'php',
			'default'     => false
		),
		'taxonomy' => array(
			'id'          => 'wp-extend-toolbar-window__taxonomy',
			'label'       => 'タクソノミー',
			'data_source' => 'php',
			'default'     => false
		),
		'term' => array(
			'id'          => 'wp-extend-toolbar-window__term',
			'label'       => 'ターム',
			'data_source' => 'php',
			'default'     => false
		)
	);
	
	/**
	 * コンストラクタ
	 */
	public function __construct() {
		add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_filter( 'pre_update_option_' . self::OPTION_NAME, array( $this, 'pre_update_settings' ), 10, 3 );
	}
	
	/**
	 * 管理メニューを追加
	 */
	public function add_admin_menu() {
		add_options_page(
			__( 'WP Extend Toolbar 設定', 'wp-extend-toolbar' ),  // ページタイトル
			__( 'WP Extend Toolbar', 'wp-extend-toolbar' ),       // メニュータイトル
			'edit_user',                                           // 必要な権限
			'wp-extend-toolbar',                                   // メニュースラッグ
			array( $this, 'render_settings_page' )                // コールバック関数
		);
	}
	
	/**
	 * 設定を登録
	 */
	public function register_settings() {
		register_setting(
			'wp_extend_toolbar_settings_group',  // オプショングループ
			self::OPTION_NAME,                    // オプション名
			array(
				'sanitize_callback' => array( $this, 'sanitize_settings' ),
				'default'           => self::DEFAULT_SETTINGS
			)
		);
	}
	
	/**
	 * 設定ページを表示
	 */
	public function render_settings_page() {
		// 権限チェックを強化
		// edit_user権限を持つユーザーのみがアクセス可能
		if ( ! current_user_can( 'edit_user' ) ) {
			wp_die(
				__( 'このページにアクセスする権限がありません。', 'wp-extend-toolbar' ),
				__( '権限エラー', 'wp-extend-toolbar' ),
				array( 'response' => 403 )
			);
		}
		
		// 現在の設定を取得
		$settings = get_option( self::OPTION_NAME, self::DEFAULT_SETTINGS );
		$settings = array_merge( self::DEFAULT_SETTINGS, $settings );
		
		?>
		<div class="wrap">
			<h1><?php echo esc_html( __( 'WP Extend Toolbar 設定', 'wp-extend-toolbar' ) ); ?></h1>
			
			<?php
			// 設定エラー・成功メッセージを表示
			settings_errors( self::OPTION_NAME );
			?>
			
			<form method="post" action="options.php">
				<?php settings_fields( 'wp_extend_toolbar_settings_group' ); ?>
				<?php do_settings_sections( 'wp-extend-toolbar' ); ?>
				
				<table class="form-table">
					<tr>
						<th scope="row"><?php echo esc_html( __( '表示項目', 'wp-extend-toolbar' ) ); ?></th>
						<td>
							<fieldset>
								<legend class="screen-reader-text">
									<span><?php echo esc_html( __( '表示項目の選択', 'wp-extend-toolbar' ) ); ?></span>
								</legend>
								
								<?php foreach ( self::DISPLAY_ITEMS as $key => $item ) : ?>
									<label>
										<input 
											type="checkbox" 
											name="<?php echo esc_attr( self::OPTION_NAME . '[' . $key . ']' ); ?>" 
											value="1" 
											<?php checked( isset( $settings[ $key ] ) && $settings[ $key ], true ); ?>
										/>
										<?php echo esc_html( __( $item['label'], 'wp-extend-toolbar' ) ); ?>
									</label><br>
								<?php endforeach; ?>
							</fieldset>
						</td>
					</tr>
					<tr>
						<th scope="row"><?php echo esc_html( __( '表示対象ユーザー', 'wp-extend-toolbar' ) ); ?></th>
						<td>
							<fieldset>
								<legend class="screen-reader-text">
									<span><?php echo esc_html( __( '表示対象ユーザーの選択', 'wp-extend-toolbar' ) ); ?></span>
								</legend>
								
								<label>
									<input 
										type="radio" 
										name="<?php echo esc_attr( self::OPTION_NAME . '[user_role]' ); ?>" 
										value="manage_options" 
										<?php checked( isset( $settings['user_role'] ) ? $settings['user_role'] : 'edit_user', 'manage_options' ); ?>
									/>
									<?php echo esc_html( __( '管理者のみ', 'wp-extend-toolbar' ) ); ?>
								</label><br>
								
								<label>
									<input 
										type="radio" 
										name="<?php echo esc_attr( self::OPTION_NAME . '[user_role]' ); ?>" 
										value="edit_user" 
										<?php checked( isset( $settings['user_role'] ) ? $settings['user_role'] : 'edit_user', 'edit_user' ); ?>
									/>
									<?php echo esc_html( __( '管理者 + 編集者', 'wp-extend-toolbar' ) ); ?>
								</label>
								
								<p class="description">
									<?php echo esc_html( __( 'フロントエンドでページ情報ウィンドウを表示できるユーザーを選択します。', 'wp-extend-toolbar' ) ); ?>
								</p>
							</fieldset>
						</td>
					</tr>
				</table>
				
				<?php submit_button(); ?>
			</form>
		</div>
		<?php
	}
	
	/**
	 * 設定を取得（デフォルト値とマージ）
	 * 
	 * キャッシング機能により、1リクエストにつき1回のみDB読み込みを行う
	 * 
	 * @return array 設定の配列
	 */
	public static function get_settings() {
		// キャッシュが存在する場合はそれを返す
		if ( self::$cached_settings !== null ) {
			return self::$cached_settings;
		}
		
		// データベースから設定を読み込む
		$settings = get_option( self::OPTION_NAME, self::DEFAULT_SETTINGS );
		
		// デフォルト設定とマージ（新しい項目が追加された場合に対応）
		self::$cached_settings = array_merge( self::DEFAULT_SETTINGS, $settings );
		
		return self::$cached_settings;
	}
	
	/**
	 * 設定をサニタイズ
	 * 
	 * 権限チェックを含む入力のサニタイゼーション処理
	 * 全ての入力を検証し、不正な値を除外する
	 * 
	 * @param array $input 入力された設定値
	 * @return array サニタイズされた設定値
	 */
	public function sanitize_settings( $input ) {
		// 権限チェック - 設定保存時にも権限を確認
		if ( ! current_user_can( 'edit_user' ) ) {
			add_settings_error(
				self::OPTION_NAME,
				'permission_denied',
				__( '設定を保存する権限がありません。', 'wp-extend-toolbar' ),
				'error'
			);
			// 権限がない場合は現在の設定を返す（変更を適用しない）
			return get_option( self::OPTION_NAME, self::DEFAULT_SETTINGS );
		}
		
		// 入力が配列でない場合はデフォルト設定を返す
		if ( ! is_array( $input ) ) {
			add_settings_error(
				self::OPTION_NAME,
				'invalid_input_type',
				__( '不正な入力形式です。', 'wp-extend-toolbar' ),
				'error'
			);
			return self::DEFAULT_SETTINGS;
		}
		
		$sanitized = array();
		
		// 各設定項目について、チェックボックスの値を真偽値に変換
		foreach ( self::DEFAULT_SETTINGS as $key => $default ) {
			// 有効なキーのみを処理（不正なキーを除外）
			if ( ! array_key_exists( $key, self::DEFAULT_SETTINGS ) ) {
				continue;
			}
			
			// user_roleの場合は特別処理
			if ( $key === 'user_role' ) {
				// manage_options または edit_user のみ許可
				if ( isset( $input[ $key ] ) && in_array( $input[ $key ], array( 'manage_options', 'edit_user' ), true ) ) {
					$sanitized[ $key ] = $input[ $key ];
				} else {
					$sanitized[ $key ] = 'edit_user'; // デフォルト値
				}
				continue;
			}
			
			// 入力値が存在する場合
			if ( isset( $input[ $key ] ) ) {
				// 値が文字列 '1' の場合のみ true、それ以外は false
				// これにより、不正な値（配列、オブジェクト、その他の文字列など）を除外
				$sanitized[ $key ] = ( $input[ $key ] === '1' || $input[ $key ] === 1 || $input[ $key ] === true );
			} else {
				// チェックボックスがオフの場合は送信されないため false
				$sanitized[ $key ] = false;
			}
		}
		
		// 入力に不正なキーが含まれていた場合は警告を記録
		$invalid_keys = array_diff( array_keys( $input ), array_keys( self::DEFAULT_SETTINGS ) );
		if ( ! empty( $invalid_keys ) ) {
			error_log( 'WP Extend Toolbar: Invalid settings keys detected: ' . implode( ', ', $invalid_keys ) );
		}
		
		return $sanitized;
	}
	
	/**
	 * 設定更新前のフィルター
	 * 
	 * update_option()が実行される前に呼ばれる
	 * データベースエラーなどの例外をキャッチする
	 * 
	 * @param mixed $value 新しい設定値
	 * @param mixed $old_value 古い設定値
	 * @param string $option オプション名
	 * @return mixed 設定値（変更なし）
	 */
	public function pre_update_settings( $value, $old_value, $option ) {
		try {
			// 値の検証
			if ( ! is_array( $value ) ) {
				add_settings_error(
					self::OPTION_NAME,
					'invalid_value',
					__( '設定の保存に失敗しました。不正な値です。', 'wp-extend-toolbar' ),
					'error'
				);
				// 古い値を返して更新を防ぐ
				return $old_value;
			}
			
			// データベース接続の確認
			global $wpdb;
			if ( ! empty( $wpdb->last_error ) ) {
				add_settings_error(
					self::OPTION_NAME,
					'database_error',
					__( '設定の保存に失敗しました。データベースエラーが発生しました。', 'wp-extend-toolbar' ),
					'error'
				);
				error_log( 'WP Extend Toolbar: Database error during settings save: ' . $wpdb->last_error );
				return $old_value;
			}
			
			return $value;
			
		} catch ( Exception $e ) {
			add_settings_error(
				self::OPTION_NAME,
				'save_exception',
				__( '予期しないエラーが発生しました。', 'wp-extend-toolbar' ),
				'error'
			);
			error_log( 'WP Extend Toolbar: Exception during settings save: ' . $e->getMessage() );
			return $old_value;
		}
	}
}


class WP_Extend_Toolbar_Data_Provider {
	
	/**
	 * 投稿タイプを取得
	 * 
	 * 現在のページが投稿またはカスタム投稿タイプの場合、その投稿タイプを返す
	 * データ取得に失敗した場合は「N/A」を返す
	 * 
	 * @return string 投稿タイプ名または「N/A」
	 */
	public static function get_post_type() {
		try {
			if ( is_singular() ) {
				$post_type = get_post_type();
				return $post_type ? esc_html( $post_type ) : 'N/A';
			}
			return 'N/A';
		} catch ( Exception $e ) {
			error_log( 'WP Extend Toolbar: ' . $e->getMessage() );
			return 'N/A';
		}
	}
	
	/**
	 * 投稿IDを取得
	 * 
	 * 現在のページが投稿またはカスタム投稿タイプの場合、その投稿IDを返す
	 * データ取得に失敗した場合は「N/A」を返す
	 * 
	 * @return string 投稿IDまたは「N/A」
	 */
	public static function get_post_id() {
		try {
			if ( is_singular() ) {
				$post_id = get_the_ID();
				return $post_id ? esc_html( (string) $post_id ) : 'N/A';
			}
			return 'N/A';
		} catch ( Exception $e ) {
			error_log( 'WP Extend Toolbar: ' . $e->getMessage() );
			return 'N/A';
		}
	}
	
	/**
	 * タクソノミーを取得
	 * 
	 * 現在のページがタクソノミーアーカイブの場合、そのタクソノミー名を返す
	 * データ取得に失敗した場合は「N/A」を返す
	 * 
	 * @return string タクソノミー名または「N/A」
	 */
	public static function get_taxonomy() {
		try {
			if ( is_tax() || is_category() || is_tag() ) {
				$queried_object = get_queried_object();
				if ( $queried_object && isset( $queried_object->taxonomy ) ) {
					return esc_html( $queried_object->taxonomy );
				}
			}
			return 'N/A';
		} catch ( Exception $e ) {
			error_log( 'WP Extend Toolbar: ' . $e->getMessage() );
			return 'N/A';
		}
	}
	
	/**
	 * タームを取得
	 * 
	 * 現在のページがタームアーカイブの場合、そのターム名を返す
	 * データ取得に失敗した場合は「N/A」を返す
	 * 
	 * @return string ターム名または「N/A」
	 */
	public static function get_term() {
		try {
			if ( is_tax() || is_category() || is_tag() ) {
				$queried_object = get_queried_object();
				if ( $queried_object && isset( $queried_object->name ) ) {
					return esc_html( $queried_object->name );
				}
			}
			return 'N/A';
		} catch ( Exception $e ) {
			error_log( 'WP Extend Toolbar: ' . $e->getMessage() );
			return 'N/A';
		}
	}
}

function wp_extend_toolbar_load_plugin_textdomain() {
    load_plugin_textdomain( 'wp-extend-toolbar', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'wp_extend_toolbar_load_plugin_textdomain' );

/**
 * プラグイン一覧に設定リンクを追加
 * 
 * @param array $links 既存のリンク配列
 * @return array 設定リンクを追加したリンク配列
 */
function wp_extend_toolbar_add_settings_link( $links ) {
	$settings_link = '<a href="' . admin_url( 'options-general.php?page=wp-extend-toolbar' ) . '">' . __( '設定', 'wp-extend-toolbar' ) . '</a>';
	array_unshift( $links, $settings_link );
	return $links;
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wp_extend_toolbar_add_settings_link' );

/**
 * アンインストール時の処理
 * 
 * プラグインがアンインストールされる際に、データベースから設定を削除する
 * register_uninstall_hook()を使用して登録
 */
function wp_extend_toolbar_uninstall() {
	// 設定オプションを削除
	delete_option( 'wp_extend_toolbar_display_settings' );
}

// アンインストールフックを登録
register_uninstall_hook( __FILE__, 'wp_extend_toolbar_uninstall' );

$GLOBALS['wp_extend_toolbar'] = new WP_Extend_Toolbar();