さくらのVPS を改めて使いはじめる 11 – Git、Gitolite、GitHub その 2

2012年6月24日 4 開発 , , , , , ,

さくらのVPS(v3) 2GB プランへの環境構築メモ 11。今回は Git 関連の続き。Gitolite と GitHub の push をフックする方法などについて書く。

もくじ

Gitolite への push をフックする

前回 Gitolite をセットアップして、そのリポジトリを Redmine へ表示するところまで書いた。しかしそのままでは Gitolite の push がミラーリングされたリポジトリに反映されず内容は古いままとなる。この問題への対処方法は 2 通りある。

  1. ミラーリングされたリポジトリ上で git fetch を定期実行
  2. Gitolite 上で push を検知して、ミラーリング先リポジトリに対して git push –mirror を実行

方法 1 なら crontab を利用することになるだろう。たとえば 10 分間隔ぐらいで git fetch させるなど。しかし push が全くないときでも無駄なコマンド実行が発生するうえ実行されるまで push が反映されないためイマイチ。

そのため今回は方法 2 で検討する。話の前提として前回の記事により以下のような環境が構築されているものとする。

リポジトリ ユーザー:グループ 説明
/home/gituser/repositories/testing.git gituser:gituser Gitolite のテスト用リポジトリ。
/var/lib/git/testing.git XXXX:XXXX Gitolite のテスト用リポジトリに対するミラーリング リポジトリ。

XXXX というのは普段 SSH 接続でログインしているユーザーとグループになる。例えば test というユーザーとグループなら、test:test のようになる。

ミラーリング リポジトリの設定

ミラーリングされたリポジトリを参照したいユーザーを XXXX とした場合、gpasswd コマンドで gituser グループに追加する。所属しているグループは id コマンドで確認する。

リポジトリを Redmine 上のプロジェクトに関連づけるなら、Redmine の稼働ユーザーを指定すること。このシリーズにならって環境構築していた場合、SSH 接続でログインしているユーザーと一緒のはず。

$ sudo gpasswd -a XXXX gituser
Adding user XXXX to group gituser
$ id XXXX
uid=500(XXXX) gid=500(XXXX) 所属グループ=500(XXXX),10(wheel),501(gituser)

ミラーリングしたリポジトリの所有者とグループを gituser、権限を 755 ( グループに読み取りを許可 ) に変更する。

$ sudo chown -R gituser:gituser /var/lib/git/testing.git/
$ sudo chmod -R 755 /var/lib/git/testing.git/

この時点で gituser グループに所属するユーザー全員が /var/lib/git/testing.git/ 以下の内容を読み取れるようになる。

このリポジトリを Redmine プロジェクトに関連づけているなら、そちらの表示も確認すること。もしリポジトリ画面で 404 になる場合はグループやパーミッションの設定が Redmine の稼働ユーザーからアクセス不能になった可能性がある。

ミラーリング元からこのリポジトリに対して git push --mirror が実行された場合、testing.git/objects などにディレクトリが追加されるのだがパーミッションは 700 になる。つまり所有者しかアクセスできない。というわけで以下の記事を参考に、config ファイルの設定を変更する。

ミラーリング リポジトリ直下に移動して git config コマンドで core セクションの sharedRepository に group を指定する。

$ cd /var/lib/git/testing.git
$ sudo git config core.sharedRepository group

設定が反映されたことを確認する。

$ git config --list
core.repositoryformatversion=0
core.filemode=true
core.bare=true
core.sharedrepository=group
remote.origin.fetch=+refs/*:refs/*
remote.origin.mirror=true
remote.origin.url=/home/gituser/repositories/testing.git

ハイライトした部分が追加した設定。ばっちり反映されている。これで Gitolite からの push を受け入れる体制が整った。

Gitolite の push をフックしてミラーに push

Git のフック機能を利用して Gitolite 上のリポジトリに push がおこなわれた時、ミラーリング リポジトリ側にも反映されるようにする。

はじめに hook 時のパーミッション設定を変更する。gituser の HOME にある .gitolite.rc の REPO_UMASK を編集する。gituser になってからファイルを開く。

$ sudo su gituser
$ cd
$ vi .gitolite.rc

REPO_UMASK を設定している部分を探す。デフォルトのパーミッションは 0077 になっているので元をコメントアウト、 0027 の設定を追加してからファイルを保存する。この作業は一度だけ実施すればよい。

#$REPO_UMASK = 0077;
$REPO_UMASK = 0027;

gituser の状態で testing.git 内の hooks ディレクトリに post-receive というファイルを新規作成する。

$ sudo su - gituser
$ cd repositories/testing.git/hooks
$ vi post-receive

このファイルにはリポジトリに対する操作に応じた処理をシェル スクリプトとして記述できる。今回はミラーリング リポジトリとなる /var/lib/git/testing.git に変更を git push --mirror する処理を書いて保存。

#!/bin/sh
/usr/bin/git push --mirror /var/lib/git/testing.git

スクリプト ファイルなので、実行属性を付ける。

$ chmod 700 post-receive

正しく設定できているなら以降、testing.git へ push が行われるたびにミラー側へも変更が反映されるはず。

GitHub への push をフックして VPS に送信

GitHub 上のリポジトリに変更がおこなわれた場合、Post-Receive Hooks でハンドリングできる。今回はこの機能を利用してリポジトリへの push 時に VPS へ更新を通知してみる。

GitHub のクローン リポジトリ

前回は GitHub から clone したリポジトリに対して Redmine の動作ユーザー ( = SSH ログインしているユーザー ) を所有者に設定した。今回は Gitolite 用のミラーリング リポジトリの設定でこのユーザーを gituser に所属させる。

今後は Git 系の操作を gituser または gituser グループに統一。GitHub に Test というリポジトリがあると仮定して、以下のようにクローンする。

$ cd /var/lib/git
$ sudo git clone --mirror git://github.com/akabekobeko/Test.git
$ sudo chown -R gituser:gituser Test.git
$ sudo chmod -R 755 Test.git/

これで gituser グループに所属するユーザーでもリポジトリを読めるようになる。ただし git fetch などの更新系は gituser のみに許可する。

PHP 実行ユーザーに sudo を許可

今回 GitHub からの更新通知による VPS 上のリポジトリ反映は PHP スクリプトでおこなう予定である。反映は git fetch コマンドで実行するのだが、これを PHP から呼び出す方法としては以下が考えられる。

  1. suEXEC を有効にしてスクリプトの実行ユーザーを git 操作可能なユーザーにする
  2. PHP の実行ユーザーに sudo を許可し、その -u オプションでユーザー指定する

前者は設定が面倒なうえスクリプトや CGI 全体の実行にかかわってくるので後者を採用する。

本シリーズのsudo と SSH ポート変更の回で取り上げた visudo コマンドを実行する。

$ sudo visudo

すると vi で sudoers ファイルが開かれるので Defaults requiretty の行をコメントアウトする。これが有効だとシェル ログインできないユーザーは sudo を利用出来ない。PHP 実行ユーザーとなる apache はこれに該当するので設定を無効にする。

セキュリティ的には好ましくないのだが VPS 全体として SSH ログインを必須にし、かつそのユーザーを限定しているのでよしとしておく。

#
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
#Defaults    requiretty

次に apache ユーザーへ sudo を許可する。といっても代替ユーザーは gituser、実行可能なコマンドは git に限定しておく。この設定は wheel グループの後ろあたりに記述。

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL

apache   ALL=(gituser)    NOPASSWD: /usr/bin/git

設定できたらファイルを保存して編集を終了。

更新通知時に実行するスクリプト

GitHub の clone リポジトリと、PHP の実行環境が整ったので、GitHub からの更新通知を処理するスクリプトを書く。GitHub からの変更通知は POST 形式で送信されるので、これを VPS 上で受信したときにスクリプトが実行されるように設定する。

Git リポジトリ ルート直下に scripts というディレクトリを作成、この中にスクリプトを置く。スクリプトの言語は何でもよいのだが今回は PHP を選んでみた。ファイル名は github-post-receive.php としておく。

$ cd /var/lib/git/
$ sudo mkdir scripts
$ sudo chown gituser:gituser scripts
$ cd scripts
$ vi github-post-receive.php

ファイルを以下のように記述して保存する。

<?php
$githubIPs   = array( "207.97.227.253", "50.57.128.197", "108.171.174.178" );
$errorStatus = "HTTP/1.1 500 Internal Server Error";
if( !in_array( $_SERVER[ "REMOTE_ADDR" ], $githubIPs ) )
{
    header( $errorStatus );
    die;
}

$payload = json_decode( $_REQUEST[ "payload" ] );
if( $payload == NULL )
{
    header( $errorStatus );
    die;
}

if( !chdir( "/var/lib/git/" . $payload->repository->name . ".git" ) )
{
    header( $errorStatus );
    die;
}

shell_exec( "sudo -u gituser git fetch" );
?>

GitHub からのアクセスであることをチェックする。GitHub が POST に使用する IP アドレスは固定なのでそれを判定。IP アドレスは GitHub リポジトリの WebHook URLs 設定画面に記載されているものを指定すること。

json_decode により POST のリクエストボディに含まれる payload パラメータの JSON をデコード。この中には push 時の様々な情報 ( ユーザー、リポジトリ名、…etc ) が格納されている。続けて JSON 内のリポジトリ名を元に clone 先へ移動し、gituser として git fetch を実行している。

スクリプトが完成したら所有者とグループを apache にして Web に公開する。いたずらにアクセスされると厄介なので、シンボリックリンクには UUID を指定し URL を類推されにくくしておく。

$ sudo chown apache:apache github-post-receive.php
$ sudo chmod 644 github-post-receive.php
$ uuidgen
a2267948-9f75-46ba-85df-058199cdfb7d
$ sudo ln -s /var/lib/git/scripts /var/www/html/a2267948-9f75-46ba-85df-058199cdfb7d

UUID は uuidgen コマンドで生成。コマンドを実行すると UUID が出力されるので、それをコピーしてリンク名に使用する。この例の場合、スクリプトへの URL は以下のようになる。

http://ホスト名/a2267948-9f75-46ba-85df-058199cdfb7d/github-post-receive.php

Web ブラウザからアクセスすると真っ白なページが表示される。Firebug などで HTTP ステータスを確認すると 500 エラーになるはず。

GitHub リポジトリの設定

スクリプトが用意できたので GitHub 側から呼び出せる用にする。

GitHub にログインして push をフックしたいリポジトリの設定画面を開く。そして上段にある Admin ボタンを押す。

Admin ボタン

左側のメニューから「Service Hooks」→「WebHook URLs」を選択。

Service Hooks

画面右側に URL の入力欄があるので push 時に呼び出すものを指定。URL を入力したら、Update Settings ボタンを押して設定を保存する。

WebHook URLs

保存に成功すると、以下のような画面が表示される。

設定成功

スクリプトが正しく実行されることを確認するため GitHub リポジトリへ何度か push してみる。以下はスクリプトによって更新された VPS 上のリポジトリを Redmine で表示してみたところ。

Redmine のリポジトリ表示

…今回はここまで。次回は phpMyAdmin あたりを取り上げるかもしれない。

さくらのVPS を使いはじめる 9 – phpMyAdmin 導入と Redmine 更新

2010年12月5日 14 開発 , , ,

さくらのVPS への作業メモ 9。

Redmine をアップデートするためにデータベースのバックアップを取ろうと思った。このブログのバックアップに使用している phpMyAdmin が便利だったので、これを導入しつつ Redmine 更新をおこなってみる。

もくじ

phpMyAdmin とは?

phpMyAdmin とは、Web ベースの MySQL 管理ツールである。ブラウザからアクセスしてデータベースの操作をおこなえる。

MySQL の状態がグラフィカルに表示されるので、コマンドラインツールに比べて分かりやすい。GUI から操作をおこなうと、それに応じた SQL が自動実行される。もちろん任意の SQL も指定できる。

なんだかいいことずくめだが、Web ベースゆえにアクセスが容易という欠点がある。Redmine などと異なり、MySQL は広範に利用されるシステムなので、侵入されたときのリスクは段違いに高い。

PHP 関連のインストール

phpMyAdmin の動作には PHP 関連のモジュールと MySQL が必要となる。最新の 3.x 系は PHP 5.2 & MySQL 5 以上、旧系列の 2.x は PHP 4 & MySQL 3 以上となる。

さくらのVPS 上で稼働している CentOS の場合、現時点の yum 標準リポジトリで入手できる PHP は 5.1.6、MySQL は 5.0.77 となっているので、この環境に phpMyAdmin を導入するなら 2.x 系を選ぶ必要がある。

当初、標準外のリポジトリ ( Remi など ) から最新の PHP を入手して 3.x 系の導入を試みたのだけど、PHP や MySQL の依存解決が面倒になったのでやめた。単に私の知識不足なのだが、現行の PHP & MySQL を全削除して最新を入れ直してもうまくゆかなかった。

というわけで標準リポジトリからインストールをおこなう。php-pear と php-gd は不要なのだけど、PHP でなにか作りたくなったときのために、ついでに入れてみた。

$ sudo yum -y install php php-mbstring php-mcrypt php-mysql php-pear php-gd
... 中略 ...
Complete!

PHP のバージョンを確認してみる。

$ php -v
PHP 5.1.6 (cli) (built: Mar 31 2010 02:39:17)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies

MySQL のほうも確認しておく。

$ mysqladmin version
mysqladmin  Ver 8.41 Distrib 5.0.77, for redhat-linux-gnu on x86_64
Copyright (C) 2000-2006 MySQL AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Server version          5.0.77
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/lib/mysql/mysql.sock
Uptime:                 62 days 21 hours 38 min 38 sec

Threads: 1  Questions: 23815  Slow queries: 0  Opens: 678  Flush tables: 1  Open tables: 64  Queries per second avg: 0.004

PHP が 5.1.6MySQL は 5.0.77 なので phpMyAdmin 2.x 系の動作要件を満たしている。

phpMyAdmin のインストール

準備が整ったので phpMyAdmin をインストールする。まず公式サイトで最新のリリース URL を調べる。

2.x 系の最新は 2.11.11.1 となっている。いくつかファイルのリンクが並んでいるが、これらの中から末尾が all-languages.tar.gz になっているものを選ぶ。リンクの URL をブラウザでコピーすると、一部のスラッシュが %2F にエスケープされ、末尾にも余計な文字列がついているので、wget コマンドに指定する場合は直しておく。

実行するコマンドは以下のようになる。インストール先は Redmin と同様に /var/libとした。/var/www/html に置かない理由は後述する。なお、cd コマンドの引数を空にして実行するとユーザー ホームに移動してくれて便利。

この記事を下書きしていた時の最新版は 2.11.11 だったが、いつの間にか 2.11.11.1 がリリースされていたので、URL などを最新のものに直しておく。

$ cd
$ wget http://sourceforge.net/projects/phpmyadmin/files/phpMyAdmin/2.11.11.1/phpMyAdmin-2.11.11.1-all-languages.tar.gz
$ tar zxvf phpMyAdmin-2.11.11.1-all-languages.tar.gz
$ rm -rf phpMyAdmin-2.11.11.1-all-languages.tar.gz
$ sudo mv phpMyAdmin-2.11.11.1-all-languages /var/lib/phpmyadmin

次はセットアップをおこなう。config.sample.inc.php という設定ファイルのサンプルが用意されているので、それを config.inc.php という名前にコピーして編集を開始する。

$ cd /var/lib/phpmyadmin
$ sudo cp config.sample.inc.php config.inc.php
$ sudo vi config.inc.php

開いたファイルの内容を以下のように変更する。

<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
 * phpMyAdmin sample configuration, you can use it as base for
 * manual configuration. For easier setup you can use scripts/setup.php
 *
 * All directives are explained in Documentation.html and on phpMyAdmin
 * wiki <http://wiki.phpmyadmin.net>.
 *
 * @version $Id$
 */

/*
 * This is needed for cookie based authentication to encrypt password in
 * cookie
 */
$cfg['blowfish_secret'] = '';

/*
 * Servers configuration
 */
$i = 0;

/*
 * First server
 */
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'http';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysql';
/* User for advanced features */
// $cfg['Servers'][$i]['controluser'] = 'pma';
// $cfg['Servers'][$i]['controlpass'] = 'pmapass';
/* Advanced phpMyAdmin features */
// $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
// $cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';
// $cfg['Servers'][$i]['relation'] = 'pma_relation';
// $cfg['Servers'][$i]['table_info'] = 'pma_table_info';
// $cfg['Servers'][$i]['table_coords'] = 'pma_table_coords';
// $cfg['Servers'][$i]['pdf_pages'] = 'pma_pdf_pages';
// $cfg['Servers'][$i]['column_info'] = 'pma_column_info';
// $cfg['Servers'][$i]['history'] = 'pma_history';
// $cfg['Servers'][$i]['designer_coords'] = 'pma_designer_coords';

$cfg['Lang'] = 'ja-utf-8';

/*
 * End of servers configuration
 */

/*
 * Directories for saving/loading files from server
 */
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';

?>

auth_type認証方法となる。デフォルトでは cookie が指定されているのでこれを http に変更する。こうすると phpMyAdmin のページへのアクセス時に HTTP 認証され、ブラウザからユーザーとパスワード入力を求めるダイアログ ボックスが表示される。

このアカウントは MySQL のものとなる。root にパスワードを設定していないと非常に危険なので注意する。未設定の場合は、以前の記事でおこなっているように、SSH でログインして先に設定しておいたほうがよい。

Lang言語と文字コードの指定となる。初期状態では存在しないため、追記が必要。この指定の場合、日本語で UTF-8 となる。

これで動作するようになったので、Web に公開してみる。以下のコマンドを実行し、/var/www/html に phpmyadmin というシンボリックリンクを作成する。

$ sudo ln -s /var/lib/phpmyadmin /var/www/html/phpmyadmin

このようにすると、http://サーバーの URL/phpmyadmin/ へアクセスしたとき、/var/lib/phpmyadmin が開かれる。/var/www/html にディレクトリを置かず、シンボリックリンクにしておくとメンテナンスが楽になる。

公開をやめたくなった場合はリンクを消すだけで済む。バージョンを更新する場合も、最新版を現行と同じディレクトリに phpmyadmin-new のような名前で配置し、ひととおり設定が終わったところで入れ替えればよい。作業の間はリンクを消しておくのもよいだろう。

なお、シンボリックリンクの削除は以下のようにおこなう。単なるファイルなので、rm コマンドを利用する。

$ sudo rm /var/www/html/phpmyadmin

シンボリックリンクを作成したら、さっそくアクセスしてみよう。前述のようにユーザー認証があるので入力し、それが正しければ以下のような画面が表示される。

phpMyAdmin

コマンドライン ツールに比べるとかなり見やすい。簡単なレコード修正ならテキストフィールドからおこなえる。もちろん SQL も実行できる。

Redmine のバックアップ

まずは Redmine のデータベース管理画面へ移動する。phpMyAdmin の画面左にデータベース一覧があるので、Redmin 用に使用しているものをクリックする。

画面右にデータベースの管理画面が表示されたら、上段のメニューからエクスポートをクリックする。そしてエクスポート欄ですべてのテーブルを選択した状態で出力形式のラジオボタンから SQL を選ぶ。

次に画面下段のファイルに保存するをチェックし、最後に実行するボタンを押す。設定については、下記の画面を参照のこと。

バックアップの実行

成功するとファイルのダウンロードが始まり、ローカルに SQL の書かれたテキストファイルが保存される。これで Redmine のデータベースをバックアップできた。リストアするときはインポートでこのファイルを取り込めばよい。

次に Redmine へアップロードしたファイルをバックアップする。サーバーへ SSH でログインし、以下のコマンドを実行する。

$ cd
$ cp -r /var/lib/redmine/files redmine-files

これでホームディレクトリの redmine-files へ添付ファイルなどがコピーされた。この場所に置くことをバックアップとしてもよいし、心配なら WinSCP などでローカルにもコピーする。

前述の SQL ファイルとこれが Redmine 上のユーザー データになる。

Redmine の更新

まずは最新版を取得する。Redmine をインストールしたときと同様に、RubyForge からリリース版の URL をコピーしておく。

そして SSH でサーバーにログインし、以下のコマンドを実行する。

$ cd
$ wget http://rubyforge.org/frs/download.php/73457/redmine-1.0.4.tar.gz
$ tar zxvf redmine-1.0.4.tar.gz
$ sudo mv redmine-1.0.4 /var/lib/redmine-new
$ rm -rf redmine-1.0.4.tar.gz

これで /var/lib 以下に現行の redmine と最新の redmine-new が格納された状態になったので、以下のコマンドで設定を引き継ぐ。

$ cd /var/lib
$ cp redmine/config/database.yml redmine-new/config/database.yml
$ cp -r redmine/config/email.yml redmine-new/config/email.yml
$ cp -r redmine/files/ redmine-new/

2 行目 = データベース、3 行目 = メール設定、4 行目 = 添付ファイルとなる。メール機能を利用していないなら email.yml は存在しない。

もしプラグインを追加インストールしていたならば、Redmine 以下の vendor/plugin もコピーしておく。重複するものが多いので、plugin ディレクトリではなく、その中のプラグインを個別でコピーしたほうが、古いもので上書きする危険がなくて安全だと思う。

引き継ぎが完了したら、ディレクトリ名を以下のように変更する。

$ cd /var/lib
$ sudo mv redmine redmine-old
$ sudo mv redmine-new redmine

これで現行のものが redmine-old、最新が redmine になった。最後の手順として、データベースなどをマイグレートするために以下のコマンドを実行する。

$ cd /var/lib/redmine
$ rake config/initializers/session_store.rb
$ rake db:migrate RAILS_ENV="production"
$ rake db:migrate:upgrade_plugin_migrations RAILS_ENV=production
$ rake db:migrate_plugins RAILS_ENV=production
$ rake tmp:cache:clear
$ rake tmp:sessions:clear
$ sudo service httpd restart

2 行目の実行を忘れると、3、4 行目のコマンドが以下のエラーになるので注意すること。

rake aborted!
A key is required to write a cookie containing the session data. Use config.action_controller.session = { :key => "_myapp_session", :secret => "some secret phrase" } in config/environment.rb

6、7 行目は Redmine のキャッシュとセッション情報の消去となる。8 行目で Apache の再起動をおこなう。なくても更新は成功するけれど、念のため。

コマンドを実行し終えたら、さっそく Redmine にアクセスしてみよう。管理者でログインし、ページ最上段から「管理」→「情報」と選択してゆき、バージョン情報を表示してみる。

バージョン情報

無事にアップデートされたようだ。めでたしめでたし。

WordPress プラグインでエディタにボタンを追加する 2

2009年12月16日 1 開発 , , , , ,

WordPress プラグインでエディタにボタンを追加する方法の覚え書き。今回はビジュアル エディタのツールバー ボタンを追加してみる。

WP-Nicodo でこのボタンをサポートする時は以下の記事を参考にした。非常に丁寧に書かれているので、こちらの方が参考になるかもしれない。

目次

MCE ボタンとは?

MCE ボタンは、編集画面のエディタがビジュアル モードになっている時のツールバーに表示されるボタンで、リストやテーブルなどの挿入や編集の補助を行う。

MCE ボタン

MCE ボタン

ビジュアル モードのエディタは TinyMCE なので、この記事のボタン名も MCE ボタンとしています。もし別の正式名称がある場合はコメントでご指摘いただけると助かります。

ボタンの追加方法は以下のようになる。

  1. TinyMCE へボタンを登録する為の JavaScript を用意する
  2. プラグインに TinyMCE へのボタン登録処理を実装する

JavaScript

JavaScript の実装は以下のようになる。MyPlugin となっている部分はプラグイン名に書き換える。ハイフンなどが入ると問題がおきそうなので、プラグイン名が “WP-Test” なら “Test” にしておく。

ただし 10 行目の longname は単なる名前なので、プラグイン名をそのまま付けても問題はない。その他の部分はコードを見れば理解できると思う。

書き換えが完了したら、mce.js という名前で保存する。保存時の文字コードは UTF-8 にしておく。

/**
 * MCE ツールバーにボタンを追加します。
 */
( function() {
    tinymce.create( "tinymce.plugins.MyPluginButtons", {
        getInfo : function() {
            return { longname:"WP-MyPlugin Button", author: "作者名", authorurl: "作者の URL", infourl: "プラグインページの URL", version: "1.0" };
        },
        init : function( ed, url ) {
            var t = this;
            t.editor = ed;

            var id = "MyPlugin01";

            ed.addCommand( id, function() {
                var str = t._SampleTable();
                ed.execCommand( "mceInsertContent", false, str );
            } );

            ed.addButton( id, { title: "ボタンのツールチップに表示されるテキスト", cmd: id, image : url + "ボタン画像への相対パス" } );
        },
        _SampleTable : function( d, fmt ) {
            str = "[test][/test]";
            return str;
         }
    } );

    tinymce.PluginManager.add( "MyPluginButtons", tinymce.plugins.MyPluginButtons );
} )();

ボタン画像のサイズは 20×20 ピクセルとなる。パスを指定する時は、このスクリプトからの相対パスで指定する。ボタンが押された時は、32 行目で返したテキストが記事に挿入される。このサンプルの場合はショートコードのテンプレートを返している。

プラグインの実装

プラグインの実装は以下のようになる。

/**
 * MCE ツールバーが初期化される時に発生します。
 */
function onMceInitButtons()
{
    // 編集権限のチェック
    if( !current_user_can( "edit_posts" ) && !current_user_can( "edit_pages" ) ) { return; }

    // ビジュアル エディタ時のみ追加
    if( get_user_option( "rich_editing" ) == "true" )
    {
        add_filter( "mce_buttons",          "onMceButtons"         );
        add_filter( "mce_external_plugins", "onMceExternalPlugins" );
    }
}

/**
 * MCE ツールバーにボタンが追加される時に発生します。
 *
 * @param $buttons ボタンのコレクション。
 */
function onMceButtons( $buttons )
{
    array_push( $buttons, "separator", "MyPlugin01" );
    return $buttons;
}

/**
 * MCE ツールバーのボタン処理が登録される時に発生します。
 *
 * @param $plugins ボタンの処理のコレクション。
 */
function onMceExternalPlugins( $plugins )
{
    $pluginDirUrl = WP_PLUGIN_URL . "/" . array_pop( explode( DIRECTORY_SEPARATOR, dirname( __FILE__ ) ) ) . "/"; 
    $plugins[ "MyPluginButtons" ] = "{$pluginDirUrl}js/mce.js";
    return $plugins;
}

// アクションの登録
if( is_admin() )
{
    add_filter( "admin_footer", "onMceInitButtons" );
}

MyPlugin となっている部分は、JavaScript の時と同様にプラグイン名に置き換える。36 行目では mce.js を TinyMCE に登録している。

このサンプルでは、一連の処理をグローバルに実装しているが、プラグインをクラス化しているなら、41 行目~終端までの処理はコンストラクタに実装し、各関数はメンバ関数とする方が好ましい。