<?php
/**
 * AG WP Plugin Install Manager — Bulk Installer View。
 *
 * Bulk_Plugin_Upgrader_Skin を拡張し、複数プラグインの
 * まとめてインストール・更新時の画面出力を制御する。
 *
 * @package AG_WP_Plugin_Install_Manager
 */

// WordPress 外からの直接アクセスを禁止。
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// 依存クラスを読み込む。
if ( ! class_exists( 'Bulk_Plugin_Upgrader_Skin' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
}

if ( ! class_exists( 'AG_WP_Bulk_Installer_View' ) ) {

	/**
	 * 複数プラグインのまとめてインストール・更新時の画面出力を制御するクラス。
	 *
	 * @since 1.0.0
	 * @see Bulk_Plugin_Upgrader_Skin
	 */
	class AG_WP_Bulk_Installer_View extends Bulk_Plugin_Upgrader_Skin {

		/**
		 * 全処理完了後のリダイレクト先URL。
		 *
		 * @since 1.0.0
		 * @var string
		 */
		public $redirect_url = '';

		/**
		 * 処理対象のプラグインスラッグ一覧。
		 *
		 * @since 1.0.0
		 * @var string[]
		 */
		public $plugin_slugs = array();

		/**
		 * 処理済みプラグイン数。
		 *
		 * @since 1.0.0
		 * @var int
		 */
		protected $processed_count = 0;

		/**
		 * このスキンに対応するマネージャーの管理メニュースラッグ。
		 *
		 * @since 1.0.0
		 * @var string
		 */
		public $menu_slug = '';

		/**
		 * アクションの種別。
		 *
		 * 'install-activate' を指定すると完了メッセージにインストール・有効化を示す文言が使われる。
		 *
		 * @since 1.1.0
		 * @var string
		 */
		protected $action_type = '';

		/**
		 * コンストラクタ。
		 *
		 * @since 1.0.0
		 *
		 * @param array $args {
		 *     オプション。
		 *
		 *     @type string   $redirect_url リダイレクト先URL。
		 *     @type string[] $plugin_slugs 処理対象のスラッグ一覧。
		 *     @type string   $url          アップグレード処理のURL（親クラス用）。
		 *     @type string   $nonce        ノンス（親クラス用）。
		 * }
		 */
		public function __construct( $args = array() ) {
			$defaults = array(
				'redirect_url' => '',
				'plugin_slugs' => array(),
				'menu_slug'    => '',
				'action_type'  => '',
				'url'          => '',
				'nonce'        => '',
			);

			$args = wp_parse_args( $args, $defaults );

			$this->redirect_url = $args['redirect_url'];
			$this->plugin_slugs = (array) $args['plugin_slugs'];
			$this->menu_slug    = $args['menu_slug'];
			$this->action_type  = $args['action_type'];

			parent::__construct( $args );
		}

		/**
		 * 1件のインストール開始前に呼ばれる。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function before( $title = '' ) {
			$this->processed_count++;

			$total = count( $this->plugin_slugs );

			echo '<h4 class="ag-wpim-bulk-progress">'
				. sprintf(
					/* translators: 1: 現在の件数, 2: 合計件数, 3: プラグイン名 */
					esc_html__( '（%1$d / %2$d）%3$s', AG_WPIM_TEXTDOMAIN ),
					(int) $this->processed_count,
					(int) $total,
					esc_html( $title )
				)
				. '</h4>';
		}

		/**
		 * 1件のインストール完了後に呼ばれる。
		 *
		 * force_activation が有効なプラグインは自動有効化する。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function after( $title = '' ) {
			// エラーがある場合は次へ進む（バルク処理は続行）。
			if ( $this->upgrader->result instanceof WP_Error ) {
				echo '<p class="ag-wpim-error">'
					. esc_html__( 'インストールに失敗しました。次のプラグインへ進みます。', AG_WPIM_TEXTDOMAIN )
					. '</p>';
				return;
			}

			$success_msg = ( 'install-activate' === $this->action_type )
				? __( 'インストール・有効化完了。', AG_WPIM_TEXTDOMAIN )
				: __( 'インストール完了。', AG_WPIM_TEXTDOMAIN );
			echo '<p class="ag-wpim-success">' . esc_html( $success_msg ) . '</p>';

			// force_activation が有効なプラグインは自動有効化する。
			$this->maybe_activate_plugin_by_title( $title );
		}

		/**
		 * 全件完了後に呼ばれる。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function bulk_header() {
			echo '<div class="ag-wpim-bulk-wrap">';
		}

		/**
		 * 全件完了のフッターを出力し、リダイレクトする。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function bulk_footer() {
			echo '</div>';

			$done_msg = ( 'install-activate' === $this->action_type )
				? __( 'すべてのインストール・有効化処理が完了しました。', AG_WPIM_TEXTDOMAIN )
				: __( 'すべてのインストール処理が完了しました。', AG_WPIM_TEXTDOMAIN );
			echo '<p class="ag-wpim-bulk-done">' . esc_html( $done_msg ) . '</p>';

			if ( ! empty( $this->redirect_url ) ) {
				echo '<p><a href="' . esc_url( $this->redirect_url ) . '" class="button button-primary">'
					. esc_html__( 'プラグイン管理画面に戻る', AG_WPIM_TEXTDOMAIN )
					. '</a></p>';
			}
		}

		/**
		 * エラーメッセージを出力する。
		 *
		 * @since 1.0.0
		 *
		 * @param string|WP_Error $errors エラーメッセージまたは WP_Error オブジェクト。
		 * @return void
		 */
		public function error( $errors ) {
			if ( is_string( $errors ) ) {
				echo '<p class="ag-wpim-error">' . esc_html( $errors ) . '</p>';
			} elseif ( $errors instanceof WP_Error ) {
				foreach ( $errors->get_error_messages() as $message ) {
					echo '<p class="ag-wpim-error">' . esc_html( $message ) . '</p>';
				}
			}
		}

		// =========================================================
		// 内部ヘルパー
		// =========================================================

		/**
		 * プラグイン名からスラッグを推定し、force_activation なら有効化する。
		 *
		 * @since 1.0.0
		 *
		 * @param string $title インストールしたプラグインの表示名。
		 * @return void
		 */
		protected function maybe_activate_plugin_by_title( $title ) {
			$manager = AG_WP_Plugin_Install_Manager::get_instance( $this->menu_slug );
			$plugins = $manager->get_plugins();

			foreach ( $plugins as $slug => $plugin ) {
				if ( $plugin['name'] !== $title ) {
					continue;
				}

				if ( empty( $plugin['force_activation'] ) ) {
					break;
				}

				if ( ! function_exists( 'get_plugins' ) ) {
					require_once ABSPATH . 'wp-admin/includes/plugin.php';
				}

				foreach ( get_plugins() as $plugin_file => $plugin_data ) {
					if ( 0 === strpos( $plugin_file, $slug . '/' ) ) {
						activate_plugin( $plugin_file );
						break;
					}
				}

				break;
			}
		}
	}
}
