11月
20
2009
0

[Cakephp]Inflectorのメソッドって何があったっけ?なメモ
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

クラスのメソッド :: Inflector :: 実用的な各種の組み込みライブラリ :: マニュアル :: 1.2 Collection :: The Cookbook

よく使うのに、いつも忘れるInflector。
単語を複数形にしたり単数形にしたり、キャメル記法にしたり、人間に読みやすい切り分けをしてくれたり?とにかく便利なInflectorですが、いっつもクラス名を忘れてしまって、検索することすらできない有様。最後には、じゃあ仕方ねーかとCakePHPのマニュアルページを見る羽目になるのでございます。

……毎度大変なので、自前でメモ。

以下、マニュアルから転載

  入力 出力
pluralize Apple, Orange, Person Apples, Oranges, People
singularize Apples, Oranges, People Apple, Orange, Person
camelize Apple_pie, orange_pekoe, people_person ApplePie, OrangePekoe, PeoplePerson
underscore アンダースコアが含まれるように変換されるのは、キャメル記法で書かれた単語のみ(たとえば「camelCase」というようなもの)であることに注意してください。スペースを含むものは小文字に変換はされますが、アンダースコアは含みません。
applePie, orangePekoe apple_pie, orange_pekoe
humanize apple_pie, orange_pekoe, people_person Apple Pie, Orange Pekoe, People Person
tableize Apples, OrangePekoe, people_person apples, orange_pekoe, people_people
classify apples, orange_pekoes, people_people Apple, OrangePekoe, PeoplePerson
variable apples, orange_pekoes, people_people apples, orangePekoes, peoplePeople
slug Slug は特殊な文字を同等なラテン文字に変換し、同等のラテン文字が無いものとスペースはアンダースコアに変換します。また、 slug メソッドはエンコーディングが UTF-8 であることを期待します。
puree puree

使い方

コントローラ、モデル、ビューのどこでも使えます。(多分)
使い方はいたって簡単。

Inflector::camelize(orange_pekoe);
// ⇒ OrangePekoe

って感じで使えます。

Written by suzukenn in: 記事 | タグ:
11月
19
2009
0

[CakePHP]htmlヘルパーを<link rel=”canonical” />に対応させる
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

SEO的な事情で<link href=”URL” rel=”canonical” />を特定のページに入れる必要があったのでそのメモ。

html->cssの引数にrelがあったのでViewで$html->css(”URL”, “canonical”, array(), false));でできるかなーと思ってやったら、残念。
type=”text/css”が出てしまって、思うようにできませんでした。

なので、#6309 (Canonical meta tag in HTML Helper) – CakePHP : The Rapid Development Framework for PHP – Tracこちらのようにhtmlヘルパーを変更し*1 、該当アクションのViewで、

echo $html->meta("canonical", "URL", array(), false);

しました。

以上、メモでした。

200911201447
半角で<link rel=”canonical” />書いたら表示されていなかったので修正

  1. もちろん/app/views/helpersにコピーして []
Written by suzukenn in: メモ | タグ:
11月
18
2009
0

[CakePHP][cron][さくら]うまくいかない原因が環境変数って・・・
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

このたび、生涯で初めてcronを使ったのですが、なぜかうまくいかず散々悩んだ挙句がCakePHPに仕込んでいた「環境変数による判定」が原因だったというお話。2度と同じ轍を踏まないようメモしておきます。

サーバはさくらインターネットのレンタルサーバ・ビジネスプロを使ってます。

CakePHPのアクションを用意する

ZiSTA Cake: XREAのCronでCakePHPのシェルを実行する
こちらのようにコマンドラインから実行できるシェル形式にする方法もあるようですが、よくわからんので、今回は
CakePHPでcronを使う方法 – ElectricBrain Standard
こちらにある、Cakeのアクションをcronで実行するやり方でチャレンジしました。

複数のECサイトの売上を集計して、1日1回メールで売上日報を送信します。
ソースは割愛しますが、ブラウザからそのURLを開くと日報メールが送信されることを確認しました。

cronに設定してみる

[000742]CRONや.mailfilterに記述したプログラムが動作しません。
こちらにあるとおり、

cd /home/アカウント名/www/app/webroot ; /usr/local/bin/php send_report.php

てなかんじでコマンドを入力して、とりあえずテストのため実行時間を5分後くらいにセットして実行してみたのですが…
メールがこない。。。なんで?

あれこれ試してみたのですが一向にうまくいかない。
じゃあ、そのコマンドを直接コンソールから実行してみよう!というわけでやってみたところ、原因がわかりました。

リターンされてきたデータを見ると、データベースの接続に失敗している模様。
ブラウザからはうまくいくのに、なんで?と思いながらも/app/core/database.phpを見てみたら、環境変数を条件にローカルの開発環境と本番環境を振り分けしてました(笑)

結論・まとめ

ローカルの開発環境と本番環境では使うデータベースが違うので、database.phpで以下のように振り分けを行っていました。
/app/core/database.php

if (strpos($_SERVER['SERVER_NAME'],"サイトURLの一部") === false) {
    // ローカル開発環境のDB設定
} else {
    // 本番環境のDB設定
}

cronが実行するときにはSERVER_NAMEなんてとれないんですね。
というわけで、以下のように修正しました。

// さくらの場合/home/アカウント名/www....というフルパスになるので、それで判定する。
// ローカル環境にも同じようにアカウント名が含まれていれば使えないけど、いかようにもなりますね。
if (strpos(dirname(__FILE__), "アカウント名") === false) {
    // ローカル環境のDB設定
} else {
    // 本番環境のDB設定
}

その後コンソールからもcronからも無事にメールが送信されました^^

僕の知識の外のトラブルだったので解決に少してこずりましたが、何とかなってよかった :-)
今日から毎晩0:05に、売上報告が届く予定なので楽しみです♪

Written by suzukenn in: メモ | タグ: ,
9月
12
2009
0

[CakePHP]paginateでbindModel
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

これはみんなは知ってることなんだろうなぁと思いつつPOST。
僕は少々気付くのに時間がかかりました。

問題

paginateでbindModelしてもうまくいきません (><)

回答

paginateでbindModelを使うときはbindModelの引数にfalseを渡しましょう

		$this->Model->bindModel($bind, false);
		$this->paginate = array(
			"Model" => array(
				"conditions" => $conditions,
				"limit" => 30,
				"order" => array("Model.created" => "ASC"),
			),
		);
		$lists = $this->paginate("Model");

解説

bindModelの第2引数はクエリを投げた後にbindをリセットするかどうかのフラグで、デフォルトはtrueになっています。
paginateでデータを取得する場合、最初にデータ数をカウントするクエリを投げるので*1 カウントではbindされているのですが、2度目のデータ取得ではbindが外れてしまうことが原因でした。
bindModelの第2引数にfalseを渡すと、その処理においてはbindの設定が持続しますのでカウントした後のデータ取得でもちゃんとアソシエーションが維持されると言うわけです。

  1. データ数/limitでページ数を算出したりするためでしょう。 []
Written by suzukenn in: メモ | タグ: ,
8月
10
2009
0

[CakePHP]Cakeで初めてSSLを使ったメモ
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

明後日リリースするecサイトのプロジェクトで、CakePHPwithSSLを初めて経験したのでメモ。

注文フロー(カート内と呼称)や、問い合わせフォーム、マイページなど、個人情報に関する入力フォームのあるactionはhttps(SSL)のアクセスとする。

事前準備

特定のコントローラ、アクションに対してSSLアクセス必須の定義をするために、
/app/app_controller.phpでSecurityコンポーネントを追加

そのアクセスがSSLかどうかを判定するisSSLを使うために、
/app/app_controller.phpでRequestHandlerコンポーネントを追加

/app/app_controller.phpに_sslFailメソッドを追加
参考:CakePHPクッキング – 投稿の詳細: 特定のURLのみSSL接続を必須にする方法
http://cakephp.blog16.jp/index.php/2008/08/08/p50

	// SSL呼出エラー処理
	function _sslFail($err) {

		if ($err === 'secure') {
			// リダイレクト先は$this->paramsからとってるけど、別のパラメータから取得した方がいいのかな?キャメライズされないのでいつもここからとってるんですが^^;
			$this->redirect("https://".BASE_URL."/".$this->params['controller']."/".$this->params['action']);
			exit;
		}

	}

各コントローラのbeforeFIlterで必要に応じてSecurity::requireSecure();とコールバックをセット*1

		$this->Security->blackHoleCallback = '_sslFail';
		$this->Security->requireSecure("index", "preview", "demo", "demo_preview");

http⇒https

各コントローラでblackHoleCallback = _sslFailをセットしてるので、_sslFailメソッドでhttpsのurlにリダイレクトしてます。

https⇒http

各コントローラのbeforeFilterでセットしているSecurity::requireSecureを利用して、requreSecureをセットしていないコントローラでSSLアクセスならばhttpにリダイレクトとい処理を書いています。*2

		// Security::requireSecureをセットしていない"コントローラ"でhttpに戻す(actionを指定しているコントローラでは走らない)
		if (empty($this->Security->requireSecure)) {
			// チェックしたらこの処理じゃSSLページからpages/...を開けなくなってしまう...orzので取り急ぎpagesを回避
			<del datetime="2009-08-10T08:26:31+00:00">if ($this->RequestHandler->isSSL()) {</del>
			if ($this->RequestHandler->isSSL() && $this->params['controller'] !== "pages") {
				$this->redirect("http://".BASE_URL."/".$this->params['controller']."/".$this->params['action']);
			}
		}

Security::requireSecureが!emptyの場合に、array_searchを使えばaction単位で制御できると思いますが、僕の場合はほとんどコントローラ単位の制御なので割愛しました。なんとなくやりすぎかなぁとも思うし。

あと、今追い込みでテストしてますが、もしかしたら支障が出るようなこともあるかも。
例えば、通常ページからSSLのページにポストするとリダイレクトによって$this->dataが飛んじゃうんじゃないか?とか、試してませんしそれなら、その前からSSLアクセスしろよということになりますのであまりないと思いますけど。

ちなみに僕の場合はそれがいいのかどうかはわかりませんが、POSTはすべて元のアクションに返して、if ($this->params['form']['submitのname']) {}で処理、その後次画面にリダイレクトするようにカートを作っているので上記のようなことはありません。
↑こういうのもCakePHPのセオリーから外れた方法なんでしょうかね?CakePHPは素晴らしい先人の方々が作ったソースがいくらでも読み放題なんだから、そこから学べばいいんでしょうが、今の今まで読まずに我流でやってきちゃいました。
正直、CakePHPの規約もあまり守らず好き勝手やってるし、だからというのもあるのですがコンソール?とか、テストもほとんど使ったことが無いんですよね~。
知らないって罪ですよね。ものすごく遠回りしていることがたくさんあるんだろうけど、忙しいからと学ぶことを後回しにしてしまう。
僕にもう少し、余裕が出てきたらCakePHPに関して積極的に活動されている憧れの皆さんの輪の中に、僕も入ってみたいと思っています。 *3

  1. SSLアクセスが必要の無いコントローラなら書かなくてOK []
  2. もっといい方法があると思いますがこんな方法で良いわけありませんが、僕のできる範囲、思いつく範囲ではこれが最善限界…^^;。更によい方法がお分かりになる方教えてくださいm_ _m []
  3. この忙しい最中何を書いてるんだ俺は。。。orz []
Written by suzukenn in: メモ | タグ:

| I have been indebted to Aeros Theme. | Background image owner is NASA.