WordPress 4.9 から最新版へ画面操作のみでアプデできるのか

WordPress 4.9 から最新へ画面操作だけで上がる。PHP 5.6 経由なら4回、PHP 7.4 からなら2回で最新へ。PHP 7.0〜7.3 に切り替えると更新ボタンが出ず行き止まり

約 18,037 字 · 読むのに 30 分ほど

WordPress 4.9 のサイトは、管理画面の更新ボタンと、サーバーの PHP の切り替えだけで最新版まで上げられるのか。実際のレンタルサーバーで確かめました。

答え:できる。ただし切り替える PHP を選ぶ

WordPress 4.9 から最新の 7.1 まで、管理画面の「更新」ボタンと PHP の切り替えだけで上げられました。FTP も SSH もいりません。ただし、途中で切り替える PHP のバージョンを間違えると、更新ボタンが出なくなったり、サイトが止まったりします。

覚えることは2つだけです。

  • WordPress 4.9 の間は、PHP 5.6 か 7.4 のどちらかにする
  • PHP 8 系にするのは、WordPress を最新にして、プラグインも更新してから

ただし、4.9.26 以前のまま長く放置したサイトは、更新ボタンを押してもダウンロードに失敗します。先に「放置サイトは先に証明書を直す」の手順で直してください(2026年9月30日 追記)。

放置サイトは先に証明書を直す(4.9.26 以前)

長く更新していない 4.9 のサイトでは、管理画面の更新ボタンは出るのに、押すと「ダウンロードに失敗しました。: cURL error 60」で止まります。プラグインのインストールも同じ理由で失敗します。

更新を押すと cURL error 60 でダウンロードに失敗する(WordPress 4.9.8)
WordPress 4.9.8 で「今すぐ更新」を押したところ

当てはまる版

系列当てはまる版(その版以前)
4.94.9.26
5.05.0.22
5.15.1.19
5.25.2.21
5.3 以降なし

4.9 から最新まで全 406 版の証明書を調べた結果です。4.9.27・5.0.23・5.1.20・5.2.22(2025年8月5日)で証明書が新しくなりました。自分の版は、ダッシュボードの「概要」か、管理画面の右下で確かめられます。この記事の検証で使った 4.9.33 は新しい証明書入りだったので、この問題に当たりませんでした。

原因

WordPress は、wordpress.org に接続するとき、自分に同梱している証明書(wp-includes/certificates/ca-bundle.crt)で相手を確かめます。古い版の証明書は 2015 年のもので、今の wordpress.org の証明書の発行元(Let’s Encrypt の ISRG Root X1)が入っていません。WordPress が同梱の証明書を指定して接続するので、サーバーの cURL が新しくても直りません(最新の cURL 8.21 でも失敗しました)。

画面操作だけで直す(証明書の一時修正プラグイン)

証明書を貼り付けるだけの小さなプラグインを作りました。プラグインには証明書を入れていません。証明書は公式サイトから自分で取ってきて貼ります。ダウンロードとソースは記事の最後にあります。

  1. 「プラグイン」→「新規追加」→「プラグインのアップロード」で zip を入れて有効化する(管理画面からのプラグインのインストールは失敗するので、アップロードで入れる)
  2. 「ツール」→「証明書の一時修正」を開き、ISRG Root X1 の -----BEGIN CERTIFICATE----- から -----END CERTIFICATE----- までを貼り付ける。取ってくる場所は WordPress 公式(GitHub、1118〜1146 行目)か Let’s Encrypt 公式。スマホなら GitHub のほうが表示できる
  3. 「自分で確認しました」にチェックを入れて保存し、表示された指紋(SHA-256)が 96:BC:EC:06:…:BD:DF:08:C6 と同じか確かめる
  4. 「接続テスト」で api.wordpress.org・downloads.wordpress.org が OK になるのを確かめる
  5. いつもどおり「更新」→「今すぐ更新」を押す
  6. 更新が終わったら、プラグインを無効化・削除する(保存した証明書も一緒に消える)
証明書の一時修正プラグインの画面。ISRG Root X1 を貼り付け、指紋と接続テストを確認
貼り付けて保存すると、証明書の名前・期限・指紋と、接続テストの結果が出る
プラグインを入れたあと、更新ボタンで WordPress 6.2.13 に上がった
PHP 5.6 のまま「今すぐ更新」を押すと 6.2.13 に上がった

PHP 5.6 で試すと 6.2.13 に、PHP 7.4 で試すと最新の 7.1.2 に上がりました。いちど上がれば WordPress 本体の証明書が新しくなるので、プラグインはもう要りません。

このプラグインがしていること

  • 貼り付けた証明書を、同梱の証明書に足したファイルを作り、wordpress.org への接続にだけ使う。ほかのサイトへの接続は元のまま
  • 貼り付けた内容がルート証明書でない・期限切れ・途中が欠けている場合は保存しない
  • 保存したあとでファイルが書き換えられていたら、使わない
  • 無効化・削除すると、保存した証明書と作ったファイルを消す

中心は次の部分です(全文は記事の最後)。

/** wordpress.org への接続だけ、貼り付けた証明書を足したファイルで検証する */
function ocpf_http_args( $args, $url ) {
	$host = strtolower( (string) parse_url( $url, PHP_URL_HOST ) );
	if ( 'wordpress.org' !== $host && '.wordpress.org' !== substr( $host, -14 ) ) {
		return $args;
	}
	$st = get_option( OCPF_OPTION );
	// 保存したときから中身が変わっていたら使わない
	if ( is_array( $st ) && ! empty( $st['file'] ) && is_readable( $st['file'] ) && hash_file( 'sha256', $st['file'] ) === $st['hash'] ) {
		$args['sslcertificates'] = $st['file'];
	}
	return $args;
}

自己責任について

  • 貼り付ける証明書は、公式サイトから自分で取ってくる。指紋を必ず見比べる
  • サイトがすでに乗っ取られている場合、攻撃者はファイルも WordPress 本体も書き換えられるので、このプラグインでは守れない
  • 更新が終わったら、すぐにプラグインを削除する
  • 利用は自己責任でお願いします

ほかの方法

  • SSH が使えるなら、WP-CLI の wp core update はそのまま通る(WP-CLI は自分の証明書でダウンロードするため)
  • サーバーのファイル管理画面で wp-includes/certificates/ca-bundle.crt を最新版に差し替えてもよい(ファイル管理の画面そのものは未検証)
  • 強制アップデート系のプラグイン(WP Downgrade など)だけでは直らない。ダウンロードで同じエラーになる
  • エックスサーバーでは、一度プラグインで接続したあと、しばらくはプラグインなしでも接続できることがある(サーバーが証明書を一時的に覚えるため)。WordPress を上げれば本体の証明書が新しくなるので、気にしなくてよい

管理画面だけで上げる手順

おすすめ:PHP 5.6 を経由する(4回)

手順やること終わったとき
04.9.26 以前なら、先に証明書を直す—
1サーバーで PHP を 5.6 にする(すでに 5.6 なら不要)WP 4.9 × PHP 5.6
2管理画面の更新ボタンで 6.2 へWP 6.2 × PHP 5.6
3サーバーで PHP を 7.4 にする → 管理画面でプラグインを更新 → 更新ボタンで最新へ → プラグインとテーマを更新WP 7.1 × PHP 7.4
4サーバーで PHP を 8.3 以上にする → もう一度プラグインを更新WP 7.1 × PHP 8.3〜8.5

どの段階も、WordPress が正式に対応している組み合わせだけを通ります。定番プラグイン16個を入れた状態で試し、すべての段階でエラーなく通りました。

なお、PHP 5.6 で出る 6.2 は英語版(6.2.13–en_US)だけです。サイトの言語の設定によっては、上げたあと管理画面が英語になります。そのときは「Settings」→「General」→「Site Language」を日本語にして保存すると戻ります。

近道:PHP 7.4 から一気に(2回)

手順やること終わったとき
04.9.26 以前なら、先に証明書を直す—
1サーバーで PHP を 7.4 にし、すぐに管理画面の更新ボタンで最新へ → プラグインとテーマを更新WP 7.1 × PHP 7.4
2サーバーで PHP を 8.3 以上にする → もう一度プラグインを更新WP 7.1 × PHP 8.3〜8.5

サーバーに PHP 5.6 が用意されていない場合はこちらです。こちらも16個のプラグイン入りで最後まで通りました。ただし、WordPress 4.9 は PHP 7.4 に正式対応していないので、手順1の途中はエラーログに警告が大量に出て(約1,300件)、管理画面の一部が開かないことがありました。PHP を切り替えたら、間を置かずに更新してください。


PHP 7.0〜7.3に切り替えてはいけない

今の WordPress避ける PHP実際に起きたこと
4.97.0 / 7.1 / 7.2 / 7.3サイトは動くが、管理画面に更新ボタンが出ない。「WordPress 7.1.2 は PHP 7.4 以降を必要とするため、更新を実行できません」と出るだけで、行き止まりになる
4.98.0 以上全ページが HTTP 500。管理画面にも入れない
6.2(プラグインは古いまま)8.0 以上公開ページは正常に見えるが、投稿の編集画面が「重大なエラー」で記事が書けない(古い SEO プラグインが原因)
7.17.3 以下WordPress が起動しない(「PHP 7.4 以上が必要」)

いちばん気をつけたいのが1行目です。PHP 7.0〜7.3 はどれも「新しい PHP にしたから大丈夫」と思いやすいのですが、WordPress 4.9 のまま 7.0〜7.3 にすると、管理画面から先に進めなくなります。いま PHP 7.0〜7.3 で動いている 4.9 のサイトは、PHP を 7.4 に上げるか、5.6 に下げてから、上の手順に入ってください。

なぜ PHP 7.0〜7.3 だとボタンが出ないのか

管理画面の更新ボタンは、WordPress.org が「このサイトはこの版に上げてよい」と返した版に対して出ます。PHP ごとに返ってくる版を調べると、次のとおりでした。

サイトの PHP更新ボタンが出る版
5.2〜5.6.195.1 系(この PHP で動く最終版)
5.6.20 以上の 5.66.2 系(この PHP で動く最終版)
7.0〜7.3なし(最新の 7.1 は PHP 7.4 以上が必要なため押せない)
7.4 以上最新版

PHP 5 系には「その PHP で動く最終版」が代わりに用意されていますが、PHP 7.0〜7.3 向けには用意されていません。互換表の上では PHP 7.0 でも WordPress 6.5 まで動くのですが、そこへ上げるボタンが出ないのです。ボタンがない状態で更新のリクエストを直接送ってみても、WordPress は更新しませんでした。

では、なぜ非対応の PHP 7.4 なら通れるのか

更新ボタンを出すかどうかは、「更新先の版が今の PHP で動くか」だけで決まります。「今の WordPress が今の PHP に対応しているか」は見ていません。PHP 7.4 なら、更新先の 7.1 の条件(PHP 7.4 以上)を満たすので、4.9 が 7.4 に非対応でもボタンが出ます。

そのうえで、4.9 が PHP 7.4 で実際に動いたことが効いています。4.9 が使っている get_magic_quotes_gpc() は、PHP 7.4 では「非推奨」になっただけで、削除されたのは PHP 8.0 です。7.4 では警告を出しながらも動くので、更新の処理まで走り切れました。4.9 × PHP 7.4 で出た約1,300件の警告は、ほぼすべて(1,282件)この関数の非推奨警告でした。

PHP4.9 の公式対応管理画面から先に進めるか
7.0〜7.37.2 までは対応進めない(更新ボタンが出ない)
7.4非対応進める(ボタン1回で最新へ)
8.0 以上非対応進めない(サイトが止まる)

正式に対応している PHP のほうが行き止まりで、非対応の 7.4 のほうが通れる、という逆転が起きています。PHP 7.4 は、古い書き方が「非推奨」になっただけで、まだ削除はされていない段階です。そのため 4.9 がぎりぎり動き、しかも最新版の最低要件も満たす、ちょうどの隙間になっています。近道の手順が成り立つのは、この隙間があるからです。

なお、PHP 5.4 のサイトでは 5.1 系のボタンが出たので、「5.1 系へ → PHP 5.6 → 6.2 系へ」と、ボタンを1回多く押すだけで同じ経路に乗れました。

途中でやること

  • 段階ごとにバックアップを取る(ファイルと DB の両方)
  • PHP を切り替えるたびに、プラグインの更新画面を開く。管理画面は今の PHP で動かないプラグインの更新を出さないので、PHP を上げるたびに少しずつ出てきます(16個で試すと、PHP 5.6 では0個、7.4 で10個、WordPress 7.1 で4個、PHP 8.3 で2個)
  • WordPress を上げたら、テーマも更新する
  • 公開ページだけでなく、投稿の編集画面を開く(壊れるのは管理画面のことがある)
  • 問い合わせフォームは送信まで試す

エックスサーバーの場合

PHP 5.6 に切り替えようとすると「Xアクセラレータ Ver.2が有効なため、PHP 5.6に変更できません。」と断られます。PHP 5.6 を使う間は、Xアクセラレータを Ver.1 か OFF にしてください。PHP 7.4 に上げたら Ver.2 に戻して問題ありませんでした。また、PHP のバージョンはドメイン単位なので、同じドメインの他の WordPress もまとめて切り替わります。

管理画面を使わない場合の注意(WP-CLI・FTP)

  • 古い PHP のまま wp plugin update --all を使わない。WordPress 6.2 × PHP 5.6 で実行すると、WP-CLI は PHP 7.4 用のプラグインを11個入れてしまい、ログイン画面まで HTTP 500 になりました。管理画面なら、この更新は出てきません。落としてしまったら wp plugin deactivate <名前> --skip-plugins で止めれば戻ります。
  • PHP 7.0〜7.3 のまま上げたい場合は、FTP で wp-admin と wp-includes を「その PHP で動く最終版」(7.0・7.1 なら 6.5 系、7.2・7.3 なら 6.9 系)に入れ替えて管理画面を開くと、「データベースの更新」ボタンで上がりました。WP-CLI なら wp core update --version=6.5.12 のように版を指定します。
  • wp core update --version=latest は 6.2 系で止まることがあります。版を数字で指定するか、何も付けずに実行してください。

検証した環境

  • サーバー:エックスサーバー
  • 出発点:WordPress 4.9.33(日本語版)× PHP 5.4 / 5.6 / 7.0 / 7.1 / 7.2 / 7.3(4.9.33 は新しい証明書入り)
  • 放置サイトの再現:WordPress 4.9.8(日本語版、2015 年の証明書、自動更新オフ)× PHP 5.6 / 7.4 で、証明書の問題と直し方を確認(2026年9月30日)
  • 到達点:WordPress 7.1.2 × PHP 7.4 / 8.3 / 8.4 / 8.5
  • 各段階で確認したこと:公開ページ、ログイン後の管理画面(ダッシュボード、投稿一覧、投稿の編集、プラグイン、メディア、更新)、画像のアップロード、問い合わせフォームの送信、エラーログ
  • テーマ:Twenty Seventeen
  • プラグイン(2018年ごろの版から開始):Contact Form 7、Advanced Custom Fields、All in One SEO Pack、All-in-One WP Migration、BackWPup、Breadcrumb NavXT、Classic Editor、Custom Post Type UI、Duplicate Post、EWWW Image Optimizer、Google XML Sitemaps、Pz-LinkCard、Table of Contents Plus、WP Multibyte Patch、WP-PageNavi、YARPP

有料テーマや独自テーマ、ページビルダー、WooCommerce、キャッシュ系プラグイン、マルチサイトは試していません。手順はそのまま使えても、各段階の確認は自分のサイトで必ず行ってください。

まとめ

  • WordPress 4.9 から最新まで、管理画面と PHP の切り替えだけで上げられる
  • 4.9.26 以前のまま放置したサイトは、先に証明書を直す(貼り付け式のプラグインで画面操作だけで直せる)
  • 4.9 の間は PHP 5.6 か 7.4。7.0〜7.3 と 8 系は避ける
  • おすすめは PHP 5.6 → WordPress 6.2 → PHP 7.4 → WordPress 最新 → PHP 8.3 以上
  • PHP 5.6 がないなら、PHP 7.4 にしてすぐ最新へ
  • PHP を切り替えるたびに、プラグインの更新画面を開く

付録:証明書の一時修正プラグイン

  • ダウンロード:old-ca-paste-fix-1.2.0-0e49bca6.zip(4.7KB、PHP 1 ファイル)
  • MD5:0e49bca6fd768fd5801e9073ab1effd3
  • SHA-256:f6e3f5389f870b70367425516cb384f8cec246e8390a044b8b35eff641cf16ae
  • 動作を確かめた環境:WordPress 4.9.8 × PHP 5.6 / 7.4(エックスサーバー)。PHP 5.3 でも読み込めることを確認
  • 証明書は入っていません。zip を使いたくない場合は、下のソースを old-ca-paste-fix.php という名前で保存し、フォルダーに入れて zip にしてもアップロードできます

この記事のサイトがすでに乗っ取られていた場合、配布しているプラグインが正しくない場合があります。ソースの内容を確認して、手元に保管しておくことをおすすめします。

ソースを表示(old-ca-paste-fix.php)
<?php
/*
Plugin Name: 証明書の一時修正(貼り付け式)
Description: WordPress 4.9〜5.2 の古い版は、同梱の証明書が古く wordpress.org から更新をダウンロードできない(cURL error 60)。公式サイトから取ってきたルート証明書を「ツール」画面に貼り付けると、wordpress.org への接続にだけ使う。証明書は同梱していない。更新が終わったら削除する。自己責任で使うこと。
Version: 1.2.0
*/

// WordPress 4.9 は PHP 5.2 でも動くので、無名関数や [] は使わない

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

define( 'OCPF_OPTION', 'ocpf_state' ); // array( 'certs' => 情報の一覧, 'file' => 作ったファイル, 'hash' => その SHA-256 )

add_filter( 'http_request_args', 'ocpf_http_args', 10, 2 );
add_action( 'admin_menu', 'ocpf_menu' );
add_action( 'admin_notices', 'ocpf_notice' );
register_deactivation_hook( __FILE__, 'ocpf_clear' );

/** wordpress.org への接続だけ、貼り付けた証明書を足したファイルで検証する */
function ocpf_http_args( $args, $url ) {
	$host = strtolower( (string) parse_url( $url, PHP_URL_HOST ) );
	if ( 'wordpress.org' !== $host && '.wordpress.org' !== substr( $host, -14 ) ) {
		return $args;
	}
	$st = get_option( OCPF_OPTION );
	// 保存したときから中身が変わっていたら使わない
	if ( is_array( $st ) && ! empty( $st['file'] ) && is_readable( $st['file'] ) && hash_file( 'sha256', $st['file'] ) === $st['hash'] ) {
		$args['sslcertificates'] = $st['file'];
	}
	return $args;
}

function ocpf_menu() {
	add_management_page( '証明書の一時修正', '証明書の一時修正', 'update_core', 'ocpf', 'ocpf_page' );
}

function ocpf_notice() {
	$st = get_option( OCPF_OPTION );
	if ( is_array( $st ) && ! empty( $st['file'] ) ) {
		echo '<div class="notice notice-warning"><p>「証明書の一時修正」が有効です。WordPress の更新が終わったら、このプラグインを削除してください。</p></div>';
	}
}

/** 保存した証明書と作ったファイルを消す(無効化・削除のときにも呼ぶ) */
function ocpf_clear() {
	$st = get_option( OCPF_OPTION );
	if ( is_array( $st ) && ! empty( $st['file'] ) && file_exists( $st['file'] ) ) {
		@unlink( $st['file'] );
	}
	// 設定が消えて行方が分からなくなったファイルも残さない
	$up    = wp_upload_dir();
	$found = empty( $up['error'] ) ? glob( trailingslashit( $up['basedir'] ) . 'ocpf-*.crt' ) : array();
	foreach ( (array) $found as $f ) {
		@unlink( $f );
	}
	delete_option( OCPF_OPTION );
}

/** 貼り付けた文字から証明書を取り出して調べる。問題があればエラーの文を返す */
function ocpf_parse( $text, &$certs ) {
	$certs = array();
	if ( strlen( $text ) > 20000 ) {
		return '長すぎます。ルート証明書だけを貼り付けてください。';
	}
	if ( ! preg_match_all( '/-----BEGIN CERTIFICATE-----\s*([A-Za-z0-9+\/=\s]+?)\s*-----END CERTIFICATE-----/', $text, $m ) ) {
		return '証明書(-----BEGIN CERTIFICATE----- から -----END CERTIFICATE----- まで)が見つかりません。';
	}
	if ( count( $m[1] ) > 3 ) {
		return '証明書は 3 つまでにしてください。';
	}
	if ( ! function_exists( 'openssl_x509_parse' ) ) {
		return 'このサーバーの PHP では証明書を読めません(OpenSSL 拡張がありません)。';
	}
	foreach ( $m[1] as $body ) {
		$b64 = preg_replace( '/\s+/', '', $body );
		$der = base64_decode( $b64, true );
		$pem = "-----BEGIN CERTIFICATE-----\n" . chunk_split( $b64, 64, "\n" ) . "-----END CERTIFICATE-----\n";
		$x   = false === $der ? false : openssl_x509_parse( $pem );
		if ( ! $x ) {
			return '証明書として読めない部分があります。途中が欠けていないか確かめてください。';
		}
		$ca = isset( $x['extensions']['basicConstraints'] ) && false !== strpos( $x['extensions']['basicConstraints'], 'CA:TRUE' );
		if ( ! $ca ) {
			return '「' . ocpf_name( $x ) . '」はルート証明書(認証局の証明書)ではありません。';
		}
		if ( $x['validTo_time_t'] < time() ) {
			return '「' . ocpf_name( $x ) . '」は有効期限が切れています。';
		}
		$certs[] = array(
			'name'   => ocpf_name( $x ),
			'org'    => isset( $x['subject']['O'] ) ? $x['subject']['O'] : '',
			'to'     => gmdate( 'Y-m-d', $x['validTo_time_t'] ),
			'sha256' => strtoupper( implode( ':', str_split( hash( 'sha256', $der ), 2 ) ) ),
			'pem'    => $pem,
		);
	}
	return '';
}

function ocpf_name( $x ) {
	return isset( $x['subject']['CN'] ) ? $x['subject']['CN'] : '(名前なし)';
}

/** 同梱の証明書に貼り付けた証明書を足したファイルを、アップロード用のフォルダーに作る */
function ocpf_write( $certs ) {
	$up = wp_upload_dir();
	if ( ! empty( $up['error'] ) || ! wp_mkdir_p( $up['basedir'] ) ) {
		return false;
	}
	$file = trailingslashit( $up['basedir'] ) . 'ocpf-' . wp_generate_password( 16, false ) . '.crt';
	$data = (string) @file_get_contents( ABSPATH . WPINC . '/certificates/ca-bundle.crt' );
	foreach ( $certs as $c ) {
		$data .= "\n" . $c['name'] . "(証明書の一時修正で追加)\n" . $c['pem'];
	}
	if ( false === @file_put_contents( $file, $data ) ) {
		return false;
	}
	return array( 'file' => $file, 'hash' => hash_file( 'sha256', $file ) );
}

function ocpf_test() {
	$out  = array();
	$urls = array( 'https://api.wordpress.org/core/version-check/1.7/', 'https://downloads.wordpress.org/release/wordpress-latest.zip' );
	foreach ( $urls as $u ) {
		$r     = wp_remote_head( $u, array( 'timeout' => 20, 'redirection' => 0 ) );
		$out[] = array( parse_url( $u, PHP_URL_HOST ), is_wp_error( $r ) ? 'NG:' . $r->get_error_message() : 'OK(HTTP ' . wp_remote_retrieve_response_code( $r ) . ')' );
	}
	return $out;
}

function ocpf_page() {
	if ( ! current_user_can( 'update_core' ) ) {
		return;
	}
	$msg   = '';
	$err   = '';
	$test  = array();
	$paste = '';
	if ( isset( $_POST['ocpf_do'] ) ) {
		check_admin_referer( 'ocpf' );
		$do = $_POST['ocpf_do'];
		if ( 'save' === $do ) {
			$paste = wp_unslash( isset( $_POST['ocpf_pem'] ) ? (string) $_POST['ocpf_pem'] : '' );
			$certs = array();
			$err   = ocpf_parse( $paste, $certs );
			if ( ! $err && empty( $_POST['ocpf_ok'] ) ) {
				$err = '「内容を自分で確認しました」にチェックを入れてください。';
			}
			if ( ! $err ) {
				ocpf_clear();
				$w = ocpf_write( $certs );
				if ( ! $w ) {
					$err = 'ファイルを作れませんでした(アップロード用のフォルダーに書き込めません)。';
				} else {
					foreach ( $certs as $i => $c ) {
						unset( $certs[ $i ]['pem'] );
					}
					update_option( OCPF_OPTION, array( 'certs' => $certs, 'file' => $w['file'], 'hash' => $w['hash'] ), false );
					$msg   = '保存しました。下の指紋(SHA-256)を公式の情報と見比べてから、接続テストをしてください。';
					$paste = '';
				}
			}
		} elseif ( 'test' === $do ) {
			$test = ocpf_test();
		} elseif ( 'clear' === $do ) {
			ocpf_clear();
			$msg = '保存した証明書を消しました。';
		}
	}
	$st = get_option( OCPF_OPTION );
	?>
	<div class="wrap">
		<h1>証明書の一時修正</h1>
		<?php if ( $msg ) : ?><div class="notice notice-success"><p><?php echo esc_html( $msg ); ?></p></div><?php endif; ?>
		<?php if ( $err ) : ?><div class="notice notice-error"><p><?php echo esc_html( $err ); ?></p></div><?php endif; ?>
		<p>古い WordPress は、同梱の証明書が古いため wordpress.org から更新をダウンロードできません。公式サイトから取ってきたルート証明書をここに貼り付けると、<strong>wordpress.org への接続にだけ</strong>その証明書を足して使います。</p>
		<p>貼り付けるのは「ISRG Root X1」です。次のどちらかを開いて、<code>-----BEGIN CERTIFICATE-----</code> から <code>-----END CERTIFICATE-----</code> までをコピーします。</p>
		<ul style="list-style:disc;margin-left:1.5em">
			<li>WordPress 公式(GitHub、WordPress 本体に入っている証明書の 1118〜1146 行目):<br><a href="https://github.com/WordPress/WordPress/blob/d2328191fe19d7d22e4755ce422836f9bc2eac5a/wp-includes/certificates/ca-bundle.crt#L1118-L1146" target="_blank" rel="noopener noreferrer">github.com/WordPress/WordPress/…/ca-bundle.crt#L1118-L1146</a>(スマホでも表示されます)</li>
			<li>Let's Encrypt 公式:<br><a href="https://letsencrypt.org/certs/isrgrootx1.pem" target="_blank" rel="noopener noreferrer">letsencrypt.org/certs/isrgrootx1.pem</a>(パソコンで開くと中身が表示されます。スマホではファイルとして保存されます)</li>
		</ul>

		<?php if ( is_array( $st ) && ! empty( $st['certs'] ) ) : ?>
			<h2>使っている証明書</h2>
			<table class="widefat striped" style="max-width:900px">
				<thead><tr><th>名前</th><th>有効期限</th><th>指紋(SHA-256)</th></tr></thead>
				<tbody>
				<?php foreach ( $st['certs'] as $c ) : ?>
					<tr><td><?php echo esc_html( $c['name'] . ( $c['org'] ? '(' . $c['org'] . ')' : '' ) ); ?></td><td><?php echo esc_html( $c['to'] ); ?></td><td><code style="word-break:break-all"><?php echo esc_html( $c['sha256'] ); ?></code></td></tr>
				<?php endforeach; ?>
				</tbody>
			</table>
			<p>指紋は、公式の情報(Let's Encrypt の証明書のページからリンクされている crt.sh など)と 1 文字ずつ同じか確かめてください。</p>
			<form method="post" style="display:flex;gap:8px">
				<?php wp_nonce_field( 'ocpf' ); ?>
				<button class="button button-primary" name="ocpf_do" value="test">接続テスト</button>
				<button class="button" name="ocpf_do" value="clear">保存した証明書を消す</button>
			</form>
			<?php if ( $test ) : ?>
				<ul>
				<?php foreach ( $test as $t ) : ?>
					<li><?php echo esc_html( $t[0] . ':' . $t[1] ); ?></li>
				<?php endforeach; ?>
				</ul>
			<?php endif; ?>
		<?php endif; ?>

		<h2><?php echo is_array( $st ) && ! empty( $st['certs'] ) ? '貼り付けなおす' : '証明書を貼り付ける'; ?></h2>
		<form method="post">
			<?php wp_nonce_field( 'ocpf' ); ?>
			<textarea name="ocpf_pem" rows="12" style="width:100%;max-width:900px;font-family:monospace" placeholder="-----BEGIN CERTIFICATE-----&#10;…&#10;-----END CERTIFICATE-----"><?php echo esc_textarea( $paste ); ?></textarea>
			<p><label><input type="checkbox" name="ocpf_ok" value="1"> 公式サイトから取ってきた証明書であることを、自分で確認しました(自己責任で使います)</label></p>
			<p><button class="button button-primary" name="ocpf_do" value="save">保存する</button></p>
		</form>
		<p>更新が終わったら、このプラグインを無効化・削除してください。保存した証明書と作ったファイルも一緒に消えます。</p>
	</div>
	<?php
}