[WordPressコアを読む]プラグインのバージョンチェック

はじめに

WordPressのコアを読んで勉強しています。

一覧はWordPress Core Readingにありますので、こちらもどうぞ。

この投稿はWordPress4.3のコアを読んで作成されています。

極力バージョンアップの際には記事を更新するようにしますが、投稿作成時のコアバージョンにはご注意下さい。


 

WordPressのプラグインバージョンのチェック

WordPressのプラグインは、機能追加や修正などがあった際にはアップデートをする必要があります。

新しいバージョンのプラグインがリリースされると、管理画面のインストールされているプラグインの一覧で該当するプラグインの下に次のようなリンクが表示されます。

「新しいバージョンの [プラグイン名] が利用可能です。バージョン [新しいバージョン番号] の詳細を見るか、今すぐ更新して下さい。 」

スクリーンショット 2015-08-23 23.12.35


どのような仕組みでプラグインのバージョンをチェックしているのか?

WordPress本体がバージョンチェックを行うのは公式ディレクトリに掲載されているプラグインのみとなります。

wordpress.org より掲載申請を行い、専用のSubversionにコミットすることで公開されます。

では、どのようにしてバージョンのチェックを行っているのか見ていくことにします。


 

まずは、更新メッセージを表示している箇所を探す

スクリーンショット 2015-08-23 23.12.35

一覧用のテーブル

インストールされているプラグインの一覧は

wp-admin/includes/class-wp-plugins-list-table.php

に定義されているclass WP_Plugins_List_Tableで出力されています。

更新メッセージ部のHTML

 <tr class="plugin-update-tr active" id="hello-dolly-update" data-slug="hello-dolly" data-plugin="hello.php">...</tr>

プラグインの情報を表示するテーブル行(tr)が出力された後に、更新の必要があるプラグインに関してはplugin-update-trというcssクラスがついたテーブル行が足されていることが分かりました。

更新メッセージを出力しているのはどこか?

単純に、plugin-update-trというcssクラスで検索してもヒットしませんでした。

そこで先ほどの、class WP_Plugins_List_Tableを読み進めていくと、各行(各プラグイン)を出力するためのsingle_rowメソッドが以下のように定義されていることが分かりました。

/**
 * @global string $status
 * @global int $page
 * @global string $s
 * @global array $totals
 *
 * @param array $item
 */
 public function single_row( $item ) {

そして、当該メソッドでプラグイン情報を出力後にafter_plugin_row_[プラグインファイル]アクションフックが実行されていることを確認しました。

 /**
 * Fires after each specific row in the Plugins list table.
 *
 * The dynamic portion of the hook name, `$plugin_file`, refers to the path
 * to the plugin file, relative to the plugins directory.
 *
 * @since 2.7.0
 *
 * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
 * @param array $plugin_data An array of plugin data.
 * @param string $status Status of the plugin. Defaults are 'All', 'Active',
 * 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
 * 'Drop-ins', 'Search'.
 */
 do_action( "after_plugin_row_$plugin_file", $plugin_file, $plugin_data, $status );

after_plugin_row_[プラグインファイル]アクションフックはどこからフックされているか?

インストールされているプラグインの一覧で、各プラグインの情報出力後に実行されるafter_plugin_row_[プラグインファイル]アクションをフックしている箇所は

wp-admin/includes/update.php

に定義されているwp_plugin_update_rowsメソッドでした。

当該メソッド内でのみadd_actionが登録されています。

 /**
 * @since 2.9.0
 */
 function wp_plugin_update_rows() {
 if ( !current_user_can('update_plugins' ) )
 return;

$plugins = get_site_transient( 'update_plugins' );
 if ( isset($plugins->response) && is_array($plugins->response) ) {
 $plugins = array_keys( $plugins->response );
 foreach( $plugins as $plugin_file ) {
 add_action( "after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2 );
 }
 }
 }

まずはログインしているユーザーがプラグインを更新する権限を持っているかをチェックしていますね。

次にTransients APIより、update_pluginsというキーで値を取得しています。

この値を表示すると次のような感じになりました。

※Akismet、Hello Dolly がインストールされていて、Hello Dollyに更新がある場合

 stdClass Object
 (
 [last_checked] => 1440341492
 [checked] => Array
 (
 [akismet/akismet.php] => 3.1.3
 [hello.php] => 1.5
 )

[response] => Array
 (
 [hello.php] => stdClass Object
 (
 [id] => 3564
 [slug] => hello-dolly
 [plugin] => hello.php
 [new_version] => 1.6
 [url] => https://wordpress.org/plugins/hello-dolly/
 [package] => https://downloads.wordpress.org/plugin/hello-dolly.1.6.zip
 )

)

[translations] => Array
 (
 )

[no_update] => Array
 (
 [akismet/akismet.php] => stdClass Object
 (
 [id] => 15
 [slug] => akismet
 [plugin] => akismet/akismet.php
 [new_version] => 3.1.3
 [url] => https://wordpress.org/plugins/akismet/
 [package] => https://downloads.wordpress.org/plugin/akismet.3.1.3.zip
 )

)

)

[response]プロパティに更新対象のプラグインが配列でセットされているようです。

どこで、Transientsに、update_pluginsというキーで情報をセットしているのか?

 

set_site_transient( 'update_plugins', [値] );

 

のようにして保存いるはずなので探してみると

 

/wp-includes/update.php

に定義されているwp_update_pluginsメソッドの中であることが分かりました。

ここでインストールされている各WordPressプラグインのバージョンを何らかの方法で公式ディレクトリと比較しているはず。

読み進めていくと以下のような箇所を見つけました。

 $url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
 if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
 $url = set_url_scheme( $url, 'https' );

$raw_response = wp_remote_post( $url, $options );

 

api.wordpress.orgに、プラグインアップデートチェック用のAPIがあった

ということが分かりました。

パラメータは以下のように渡していました。

 $options = array(
 'timeout' => $timeout,
 'body' => array(
 'plugins' => wp_json_encode( $to_send ),
 'translations' => wp_json_encode( $translations ),
 'locale' => wp_json_encode( $locales ),
 'all' => wp_json_encode( true ),
 ),
 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
 );

 

APIにPOSTしてみる

次のようなパラメータを先ほどのAPIに渡してみました。

 $timeout = 30;
 $to_send = array(
 "plugins"=> array(
 "akismet/akismet.php" => array(
 "Name" => "Akismet",
 "PluginURI" => "http://akismet.com/",
 "Version" => "3.1.3",
 "Description" => 'Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from comment and trackback spam</strong>. It keeps your site protected from spam even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) <a href="http://akismet.com/get/">Sign up for an Akismet API key</a>, and 3) Go to your Akismet configuration page, and save your API key.',
 "Author" => "Automattic",
 "AuthorURI" => "http://automattic.com/wordpress-plugins/",
 "TextDomain" => "akismet",
 "DomainPath" => "",
 "Network" => false,
 "Title" =>"Akismet",
 "AuthorName" =>"Automattic",
 ),
 "hello.php" => array(
 "Name" => "Hello Dolly",
 "PluginURI" => "http://wordpress.org/plugins/hello-dolly/",
 "Version" => "1.5",
 "Description" => 'This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.',
 "Author" => "Matt Mullenweg",
 "AuthorURI" => "http://ma.tt/",
 "TextDomain" => "",
 "DomainPath" => "",
 "Network" => false,
 "Title" => "Hello Dolly",
 "AuthorName" => "Matt Mullenweg",
 ),
 ),
 "active" => array(
 "hello.php"
 ),
 );

$translations = array(
 "akismet" => array (
 "ja" => array (
 "POT-Creation-Date" => "",
 "PO-Revision-Date" => "2015-08-01 15:50:07+0000",
 "Project-Id-Version" => "Stable (latest release)",
 "X-Generator" => "GlotPress/1.0-alpha-1100",
 )
 )
 );

$locales = array( "ja" );

$options = array(
 'timeout' => $timeout,
 'body' => array(
 'plugins' => wp_json_encode( $to_send ),
 'translations' => wp_json_encode( $translations ),
 'locale' => wp_json_encode( $locales ),
 'all' => wp_json_encode( true ),
 ),
 'user-agent' => 'WordPress/4.3; ' . get_bloginfo( 'url' )
 );

次のように結果をパースしてみました。※エラーチェックしていません

 $url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
 $raw_response = wp_remote_post( $url, $options );
 var_dump(json_decode(wp_remote_retrieve_body($raw_response)));

結果は、更新の必要があるものはpluginsに、更新の必要がないものはno_updateにセットされていることが分かりました。
そして、この結果をTransients APIで記憶しています。

 object(stdClass)#202 (3) {
 ["plugins"]=> object(stdClass)#203 (1) {
 ["hello.php"]=> object(stdClass)#204 (6) {
 ["id"]=> string(4) "3564"
 ["slug"]=> string(11) "hello-dolly"
 ["plugin"]=> string(9) "hello.php"
 ["new_version"]=> string(3) "1.6"
 ["url"]=> string(42) "https://wordpress.org/plugins/hello-dolly/"
 ["package"]=> string(58) "https://downloads.wordpress.org/plugin/hello-dolly.1.6.zip" } }
 ["translations"]=> array(0) { }
 ["no_update"]=> object(stdClass)#205 (1) {
 ["akismet/akismet.php"]=> object(stdClass)#206 (6) {
 ["id"]=> string(2) "15"
 ["slug"]=> string(7) "akismet"
 ["plugin"]=> string(19) "akismet/akismet.php"
 ["new_version"]=> string(5) "3.1.3"
 ["url"]=> string(38) "https://wordpress.org/plugins/akismet/"
 ["package"]=> string(56) "https://downloads.wordpress.org/plugin/akismet.3.1.3.zip" } } }


まとめ

  • api.wordpress.orgに現在インストールされているプラグイン情報を通知して更新の必要があるかを問い合わせる
  • API問い合わせ結果に基づいて、プラグイン一覧で更新の必要があるかを表示する

FC2ブログからWordPressへ引っ越しするときに便利なプラグインを作りました

FC2ブログからWordPressへ

WordPressからFC2ブログに引っ越す手順は、次のようになるかと思います。


 

記事、カテゴリーはいい感じに引っ越しできます

上記プラグインで、記事・カテゴリーはいい感じに移行できます。

なんて言ったって公式に出してくれているプラグインですからね。

大量に記事がある場合は、wp-contentフォルダの下に、「mt-export.txt」という名前でFTP等でアップすることでphpのファイルアップロード上限とかを気にしなくても大丈夫な作りになってます。


 

コメントだけがちょっと残念なことになる

FC2ブログからWordPressへ引っ越したらコメント文が変?でも書いたのですが

記事へのコメントについても移行できるのですが、ちょっとだけ問題があります。

“管理者にだけ表示を許可する”という秘密のコメントがFC2ブログにあり、この機能が少し引っ越しの際に障害になります。

コメントについては、次のような形で取り込まれてしまいます。

“管理者だけに表示を許可する:チェックOFF”

SECRET: 0
PASS: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

この記事、とてもよいですね。
参考になりました。
ありがとうございます。

“管理者だけに表示を許可する:チェックON”

SECRET: 1
PASS: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

この前は、ありがとうございました。
例の件、大きな声では言えませんが、この秘密のコメントでだけ書いておきますね。

■■■さんが▲▲▲さんと●●●してました


 

全部出てしまう。それが秘密かどうかに関わらず。

これは、WordPress・Movable Type and TypePad Importerに問題があるわけではありません。

FC2ブログのエクスポート形式の問題です。

このままだと、普通にコメント書いてくれた人・秘密のコメントを書いてくれた人どちらのコメントにも「SECRET」とか「PASS」という文字が入って公開されてしまいます。

しかも、秘密のコメントに至っては公開されてしまいます。

(パスワードはハッシュ値のようなので、漏洩は大丈夫そう)


 

Mt8 Import Comments Adjuster

そんなときに使うプラグインを作りました。

GitHubよりダウンロードしてインストール・有効化して下さい。

※Movable Type and TypePad Importerでインポートを実行する前にインストール・有効化して下さい。


 

プラグインの動作

Movable Type and TypePad Importerの投稿・コメント保存時にフックして、コメントデータを以下のように編集します。

  • SECRET: 1で始まるコメントの場合、”承認待ち”にする。
  • SECRETセクション・PASSセクションをコメント本文から削除する。

 

今後の課題

  • インポート時に画像も保存してメディアに登録・アイキャッチ設定するのもプラグインでできれば、一発で引っ越しできる?

 

その他、プルリクもお待ちしております。

mt8/mt8-fc2-import-comments-adjuster | GitHub


 

WordPressのカテゴリ編集画面で親カテゴリで一覧を絞り込めるプラグインを作りました。

WordPressでカテゴリが増えていくと大変

WordPressでたくさんカテゴリを作ると、管理画面上でツリービューになって欲しいところですが、投稿と同様に一覧表示なのでカテゴリをたくさん作っていくと管理が大変になっていきます。

また、カテゴリ一覧などの表示順をクライアント様でも並び替えできるように「Intuitive Custom Post Order」をインストールすることが多いので、親カテゴリで絞り込んだ上でドラッグ&ドロップしたいと思いました。

(表示オプションで表示件数を増やすのも手ですが、親カテゴリ絞り込んだ上で並び替えできたほうが便利かと考えました。)


 

Mt8 Parent Category Filter

作ってみました。ダウンロードはGitHubから。

スクリーンショットのように、絞り込み用のドロップダウンが表示されます。

この絞り込み用ドロップダウンには「子カテゴリを最上位の親カテゴリ」のみ表示されます。

スクリーンショット 2015-08-13 10.02.30

選択すると、絞り込まれます

スクリーンショット 2015-08-13 10.03.43


 

カスタムタクソノミーにも対応

mt8-parent-category-filter-allow-taxonomies

このプラグインで処理するタクソノミーを指定できるフィルターを実装しておきました。(デフォルトはcategoryのみ)

テーマとかで次のように記述すればOKです。(例は”items”というスラッグのタクソノミー)

 if ( ! function_exists( 'my_mt8pcf_taxonomies' ) ) :
     function my_mt8pcf_taxonomies( $allow_taxonomies ) {
         $allow_taxonomies[] = 'items';
         return $allow_taxonomies;
     }
     add_filter( 'mt8-parent-category-filter-allow-taxonomies', 'my_mt8pcf_taxonomies' );
 endif;


GitHubで公開してます

“get_terms_args”フィルターをこねくり回してます。

/wp-admin/edit-tags.php(タクソノミー編集画面)では

  • 新規カテゴリ用の親選択用のドロップダウン
  • 一覧表示の件数
  • 一覧データ

で”get_terms_args”が呼ばれることになり、その上、各々考え方が違うのでパラメータを変えなければうまく実現できませんでした。

かなり力技となっておりますので、いい方法があれば教えて欲しいです。

協力してください!

https://github.com/mt8/mt8-parent-category-filter

WordPressで管理者だけが見れる秘密のコメントを書けるプラグインを作りました

何故かここにきてFC2ブログからの引越しが多くなっています。

参考リンク?

http://www.sankei.com/affairs/news/150803/afr1508030032-n1.html


 

FC2ブログからWordPress移行で問題が

FC2ブログからWordPressへの引越しは、FC2ブログからエクポート(MT形式)して、WordPressのインポートツールはMovable Type and TypePad Importerになるかと思います。

基本的にコンテンツ・カテゴリ等はこれでOKなのですが、コメントだけちょっと注意が必要です。

以前、FC2ブログからWordPressへ引っ越したらコメント文が変?でも書いたのですが、非公開コメントがうまく移行できません。というか公開されてしまいます。

非公開コメントで何かやりとりしていた内容とかはこれだと公開されちゃいます。

移行方法は先述のブログを参考にしてもらって、実際に秘密のコメントをWordPressで運用する方法はないか、と探してみました。

似たようなことがWordPressで出来ないかなと探したのですが、古いプラグインが見つかったもののそれらしいものは見つかりませんでした。

(似たようなやつがあったら教えてください)


Mt8 Secret Comments

WordPress › Mt8 Secret Comments « WordPress Plugins

有効化すると、コメントフォームの下に「管理者だけに表示」というチェックボックスが表示されます。

スクリーンショット 2015-08-12 13.09.20

これをチェックしてコメントを書くと管理者以外には「このコメントは管理者だけが見ることができます」と表示されます。

スクリーンショット 2015-08-12 13.13.07

書いた本人、管理者はコメント編集で表示状態を変更することもができます。

スクリーンショット 2015-08-12 13.15.18

あと、コメント一覧に「管理者だけに表示」という列も足します。(表示オプションで切り替え可能)

スクリーンショット 2015-08-12 13.16.40


GitHubで公開してます

RSSとか、考慮が足りない気が・・・。

協力してください!

https://github.com/mt8/mt8-secret-comments

リブライズの書籍データをWordPressで表示するプラグインを作りました

すべての本棚を図書館に

リブライズの書籍データを公開されているAPIで取得してリスト表示するWordPressプラグインを作りました。

 


 GitHubでWordPressプラグイン公開してます

Mt8 librize Book Listです。リブライズAPIの詳細ドキュメントが見つからなく、この先も使えるかが怪しいので公式ディレクトリへの掲載は保留しています。

 


 インストール方法

GitHubからダウンロードしてWordPressプラグインとしてインストール、有効化するとショートコードでリスト表示が可能になります。

スタイルはCSSでいい感じに調整してください。

 


ショートコード例

※例はOpen Space DEP. Motomachi Kobeブックスポットです。

[librize-book-list id=1239]

idにリブライズの場所IDを設定します。

 

※リブライズの場所IDの調べ方は、ブックスポットの設定編集時のURLから分かります。DEP.の場合以下のようになっています。

https://librize.com/places/1239/edit

 


その他のパラメータ

パラメータ名 内容 初期値 必須
id 場所ID
limit 取得件数 5
wrap ラップするタグ div
wrap_class ラップするタグのCSSクラス mt8lbl_book_list
no_title タイトルを表示しない false
random ランダム表示 false
link リブライズにリンクする true
image_size 画像サイズ(横) 75

 

WordPressの書籍を執筆しました。

WordPressの書籍を執筆しました。