EC-CUBEのカテゴリ・コンテンツプラグインをカスタマイズする

EC-CUBEのカテゴリ・コンテンツプラグインは大変に便利なプラグインなのだけれど、その掲載位置をh2タイトルの下に変更する必要が出てきた。プラグインパッケージを解凍して「CategoryContents.php」を読んでみると次のようにある。

//変更前(L150付近)
$objTransform->select('h2.title')->insertBefore(file_get_contents($template_dir . 'categorycontents_products_list_add.tpl'));

この部分を下記修正する。

//変更後
$objTransform->select('h2.title')->insertAfter(file_get_contents($template_dir . 'categorycontents_products_list_add.tpl'));

その後、改変したファイルを元と同じようにtar.gz圧縮してからプラグインアップデート(もしくは一旦削除して再インストール)すると望み通りの形が実現できた。

MySQLのInnoDBに対してAUTOCOMMITが無効であるのにも関わらずCOMMITするのを忘れていた。

MySQLのInnoDBに対してAUTOCOMMIT = 0の状態でsqlを発行しCOMMITしなかった(するのを忘れた)場合、次のようになった(idはAUTO_INCREMENT)。

a. スクリプト実行前

id, value
1 taro
2 jiro
3 saburo

b. スクリプト実行中(shiroを追加するsqlを発行/COMMITせずにスクリプト終了)

id, value
1 taro
2 jiro
3 saburo
4 shiro

c. スクリプト実行後

id, value
1 taro
2 jiro
3 saburo

d. 同じsqlを再度発行し、きちんとCOMMITした場合。

id, value
1 taro
2 jiro
3 saburo
5 shiro

そもそもの原因は、「sqlをphpスクリプト上で発行してもDBに反映されないが、同sqlをphpMyAdminから直接発行すると正常に反映される」という現象が発生し、ついでに対象となるテーブルのid(AUTO_INCREMENT)がなぜか飛び番号になってしまったこと。いろいろと調べた結果、原因は単純にAUTOCOMMITの設定値の問題だった。

MySQLでInnoDBテーブルを利用していた場合、トランザクション時の挙動はAUTOCOMMITの値によって異なる。AUTOCOMMIT = 1の場合は、ユーザーが明示的にmysql_query(“BEGIN”)としなくともトランザクションを自動的に設定してコミットまで行ってくれる。AUTOCOMMIT = 0の場合は、ユーザーがmysql_query(“BEGIN”)とすることが前提となっており、またコミットには同じく明示的にmysql_query(“COMMIT”)が必要となる(もしくはmysql_query(“ROLLBACK”)とすることで反映をキャンセルする)。

参照:13.5.10.2. InnoDB と AUTOCOMMIT

DBの更新については通常であれば次のように常にAUTOCOMMIT = 0として明示的にBEGINおよびCOMMIT/ROLLBACKを行うようにしていたが、今回は例外的に下記を通さずにsqlを個別に発行しなければならない状況になり、かつ、その発行の直前にAUTOCOMMIT = 0を発行していることを忘れていたためにいくらか悩んでしまった。

$dbHandle = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Could not connect: ' . mysql_error());
mysql_select_db("TEST");

$sql = "INSERT INTO table_name ...";

mysql_query("SET AUTOCOMMIT = 0");
mysql_query("BEGIN");

try {
	$result = mysql_query($sql);	
	if (!$result) {
		throw new Exception('exception : ' . mysql_error()) ;
	}	
	mysql_query("COMMIT");

} catch(Exception $e) {
	echo $e->getMessage;	
	mysql_query("ROLLBACK");
}

if (!$dbHandle) {
    mysql_close($dbHandle) ;
}

ちなみにAUTOCOMMITの値は下記sqlによって取得する

SELECT @@autocommit;

なお上記のテーブルの履歴で、dにおいて追加されたshiroのidが5となっているのは次の理由からだと思われる。

1. bにおいて発行されたsqlによってidが一つ使用(予約?)される。
2. cにおいてCOMMITなしに接続が切れることによるROLLBACKでレコードは元に戻されるがidは元に戻らない。
3. よってdの段階においては一旦使用されたidを飛ばしてその次の5が使用される。

参照:13.5.10.9. 暗黙的なトランザクション コミットとロールバック

もし自動コミット モードがオフで、最後のトランザクションを明示的にコミットせずに接続を閉じると、MySQL はそのトランザクションをロールバックします。

simplehtmldomを利用してCOOKPADのレシピを取得する

COOKPADのレシピを大量に取得する必要にせまられ簡単なスクリプトを組む。取得すべきレシピのIDがあらかじめ分かっていたために仕組みは非常に単純で、レシピ詳細ページのHTMLを丸ごと引っ張ってきて、該当の要素、ID、CLASS名を頼りにテキストを抽出するだけの内容。

当初、HTMLからの要素の抽出は正規表現の利用を考えていたのだけれど、予想に反して手間がかかりそうだったので「HTMLを扱うならjqueryのように出来ないかな」とスクリプトを探していたところPHP Simple HTML DOM Parserを見つけた。これはphpからHTMLをjqueryのように扱うためのライブラリで、書き方もjqueryに似ていてとても使いやすい。

“simplehtmldomを利用してCOOKPADのレシピを取得する” の続きを読む

Smartyで日付のdate_format時に「月」の表示を一桁で行う

Smartyで下記のようにdate_formatを行うと、「月」がゼロパディングされて二桁表示になってしまう。

<{$date|date_format:'%m'}>

これを一桁で表示するのにプラグインを作成する(探す?)のが面倒くさかったので正規表現で対応してみる。

<{$date|date_format:'%m'|regex_replace:'/0([0-9])/':'$1'}>

・・・と、思ってちょっと調べていたら下記のようなオプションを見つける(参照:Smartyのdate_formatのゼロパディングを無くす)。mの前に「-」付ければ解決らしい。sprintfのアラインメント修飾子とかそのあたりのオプションかなあ。

<{$row|date_format:'%-m'}

GeoHash備忘録

GeoHashを利用したいと思い、いくつかのサイトをチェック。その個人的備忘録。

Geohash Wikipedia
Wikipedia
Geohash Wikipedia(日本語)
Wikipedia
Geohashの概略(サンプルプログラム有り)
@masuidrive blog
Geohashエンコード、デコード関数(近隣メッシュ取得関数有り)
とりあえずPHP
Geohashエンコード、デコード関数
LordElph’s Ramblings
Geohashのアルゴリズムについて
ゆろよろ日記
Geohashの分解能について
Relevant, Timely, and Accurate

Dreamweaverで文字コードが勝手にSJISに変更される

DW4でphpファイルやjsファイルを開くと、文字コードをもともとUTF-8で作っていたつもりのファイルでも勝手にShift-JISに変更してくれる。それが発生する場合としない場合があるので、まあいいかと思っていたが最近どうも気になるので少し調べてみたところ、発生する条件はほぼ下記の通りになった。

変更されない(UTF-8で保存/日本語有り)

/*日本語コメント*/
<?php
echo "こんにちは世界!";
?>

変更される(UTF-8で保存/日本語なし)

/*japanese comment*/
<?php
echo "hello world!";
?>

つまり、ファイルの保存時に日本語(2バイト文字?)がどのような形であれ含まれていないと、次回開いたときに文字コードがShift-JISになってしまうらしい。

原因が分かったところで、解決方法を探してみると次のサイトが見つかった。

1.ファイルの先頭に文字コードを書き込む

DreamWeaverでPHPファイルのエンコードを勝手に変えちゃうの何とかした

それによると各ファイルの先頭に文字コードの設定を書き込み、DWに強制的に文字コードを認識させるというもの。jsを除き、確かに動作はするけれど、なんだかまどろっこしい。cssはまだ良くてもphpはちょっと。。

phpの場合

<?php /* <meta content="charset=UTF-8"?> */ ?>

jsの場合(どうもうまくいかない)

/* @charset "UTF-8"; */

cssの場合

@charset "UTF-8";

2.UTFで保存するときにBOMを書き込む

Adobe Forums

UTF-8保存時にBOMを書き込むことでUTF-8として認識させることはできるけれども、肝心のphpファイルを実行したときにheader()関連でエラーが出てしまうので実用的ではない。そして日本語windowsの場合、OSデフォルトの文字コードがShift-JISのため、DWは編集対象のファイルの文字コードが明示的に示されていない場合にはShift-JISに変えるみたい。以下原文。

~省略~
> When I save the document with BOM
> signature, forcing it to be UTF8 -no mater what-, the problem has solved.
Be careful using the BOM with PHP files. PHP interprets the BOM as
output, causing problems with the header() function and sessions.
> Probably DW is thinking "Hey! this guy's system is Japanese, so I should
> ignore the DW settings and set this to SJIS".
Bingo! If you're using a Japanese operating system that defaults to
Shift_JIS, that's what Dreamweaver will use in files that don't have a
way of indicating their encoding. The UTF-8 setting applies only to
files that have a meta tag or other method of declaring their encoding.

関係ないけど、このくだりには笑った。いじめられてる。。

> Probably DW is thinking "Hey! this guy's system is Japanese, so I should
> ignore the DW settings and set this to SJIS".

3.Dreamweaverの初期設定を変更する

Dreamweaver8の文字コード

「編集」->「環境設定」->「新規ドキュメント」の中にある「エンコーディングが指定されていない既存ファイルを開くときに仕様」のチェックをはずす、という記述もあったけれど、CS4では効かないみたい。やりかたが悪いのかな。

結局のところ1の方法か、各ファイルに日本語でコメントを入れておくのが実用的なのかな。それにしても、余計な機能はいらないからこういった細かい部分をしっかり作り込んで欲しい。

CakePHPでcake.phpを直接呼び出す

どうも忘れがちなのでメモ。

bashスクリプトが入っているがどうも正常に動かないようで、その中身を見ると同ディレクトリのcake.phpを直接呼び出している様子。コマンドから次のようにしてみると無事に動作した。

> php ./cake.php -app /path/to/app bake
Welcome to CakePHP v1.3.3 Console
---------------------------------------------------------------
App : app
Path: /path/to/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q)

ZEN PHOTO

オープンソースの画像ギャラリー生成モジュール。

  • 見た目にシンプルなギャラリー(自由度はきっと高い)
  • 画像ギャラリーとしての一通り(以上?)の機能は揃っている
  • Extensionsによる機能拡張が可能

と、なかなか使いやすそう。今度、何かの際には導入してみよう。
デモページを見ると、気持ち重いような気もするけれど、サーバーのせいかな?