CakePHP Shells内でAuth Componentを使ってUserを追加

前回のブログでCakePHP Shellを作成しましたが、そのシェルの中でAuth Componentを利用する際にはまったので書いて見ます。

ご存知、Componentを読み込む場合はコントローラーのメンバ変数として

	var $components = array('Auth');

のように書くだけですが、Shellの場合はこうやってもComponentを読み込んでくれません。

Shellでコンポーネントを利用する場合は以下のように関数内で呼び出してやることで解決できました。

function main(){
    App::import('Component','Auth'); 
    $this->Auth = new AuthComponent(null); 

}

さて、なぜAuth ComponentをShell内で使いたかったかというと、自分の場合、Auth->password() 関数を利用してパスワードをハッシュさせた後、ユーザーを追加したかったからです。

以下、Shell内でのユーザー作成に使ったコードです。

$username = [NEW_USERNAME];
$password = $this->Auth->password([NEW_PASSWORD]);

$retData = $this->User->findByUsername($username);
if(empty($retData['User']) ){
    $data = array("User" => array(
                           "username" => $username,
                           "password" => $password,
                           )
                       );
    $this->User->save($data);
}

最後に、以下参考になったサイトです。

Cookbook 認証 - http://book.cakephp.org/ja/view/172/%E8%AA%8D%E8%A8%BC

CakePHP: Creating a Custom Shell for Adding Users for Use With AuthComponent - http://www.springenwerk.com/2008/07/cakephp-creating-custom-shell-for.html


CakePHP Shellsを使ってスクリプトをDreamhost上のCron Jobsで動かす方法

今回は、CakePHPを使って自作プログラムをCron Jobで動かす方法について書きます。 今回はサーバーにDreamhostを使ったのでDreamhostでCron Jobを動かす特有の方法も説明していきます。

まず、CakePHPでコマンドラインスクリプトを書く必要がありますが、CakePHPではShellという機能を使って簡単に実現することができます。

作成手順はCakePHPのリファレンス Cookbook (http://book.cakephp.org/#!/view/1106/The-CakePHP-Console) にある通りです。

まず最初にShellクラスを継承したクラスファイルを自分のAppフォルダの中 (CAKEPHP/myapp/vendors/shells/)の中に作成します。
自分はTwitter.phpというクラスファイルを作成、以下のようにつくりました。

class TwitterShell extends Shell {

  function main() {
      $this->out("TEST Task Run! n");

  }

}

これだけです。超シンプル!

では早速これをまずマニュアルで実行してみます。

SSHでDreamhostにログイン後、以下のようにコマンドを実行します。

/home/YOUR_ACCOUNT/DOMAIN.COM/cake/console/cake -app /home/YOUR_ACCOUNT/DOMAIN.COM/myapp/ twitter

ここで -appパラメータを使ってフルパスで自分のアプリケーションフォルダ(この場合myapp)をしてやらないと、CakePHPは常にappフォルダをみに行ってしまいます。

上手くいけば、

Welcome to CakePHP v1.3.7 Console
---------------------------------------------------------------
App : myapp
Path: /home/YOUR_ACCOUNT/DOMAIN.COM/myapp
---------------------------------------------------------------
TEST Task Run!

のように表示されます。

プログラムが正常に動くことを確認出来たので、次にDreamhostからCronjobに登録します。

Dreamhostのコントロールパネルにログイン後、「Goodies」の中の「Cron Jobs」を選択します。

「Add New Cron Job」ボタンをクリックしてCommand to runフィールドに先ほどの

/home/YOUR_ACCOUNT/DOMAIN.COM/cake/console/cake -app /home/YOUR_ACCOUNT/DOMAIN.COM/myapp/ twitter

を入力します。

最初は実行確認のために、Email output toフィールドにEmailを記入しておくことをお薦めします。

Cron Jobエントリーを保存して後は実行されるのを待つばかり、、、と思いきや、残念ながらDreamhostではさらにすこしばかり変更を加えてやらないと上手くスクリプトが走りません。

実際、問題は実行結果をEmailで受け取るとわかるのですが、

/home/YOUR_ACCOUNT/DOMAIN.COM/cake/console/cake: line 24: exec: php: not found

のようにエラーが帰ってきてしまいます。

これは/cake/console/cakeファイルがphpコマンドを実行できないというエラーなので、Dreamhost用にcakeファイルを以下のように書き換えてやる必要があります。

まず、一行目の

LIB=${0/%cake/}
APP='pwd'

の下に

TERM=linux
export TERM

を追加しておきます。これは必須ではないようですが、追加しておくことでサーバーメンテナンス等でエラーが起きたときに助けになるようです。

次に

exec php -q ${LIB}cake.php -working "${APP}" "$@"

のラインを

exec /usr/local/php5/bin/php -q ${LIB}cake.php -working "${APP}" "$@"

のように書き換えます。 これはphp5コマンドを明示的に呼び出しています。

以上で、Cron Jobのスクリプトが正常に実行されました。

余談ですが、DreamhostのCron Jobは最短で10分間隔でしか実行できないみたいです。 何個もCron Jobを登録したらもっと短い間隔で実行できるかもしれませんが、試してません。

これで、自分は今流行(?)のOAuthを使ったTwitter BOTの作成をしてみたのですが、それはまた次回のブログで説明するようにします。

最後に、

参考になったサイト

CakePHP Shells, and Cron Jobs -  http://www.utoxin.name/2009/07/cakephp-shells-and-cron-jobs/

Running a cakePHP shell script as cronjob on Dreamhost - http://www.pixelastic.com/blog/242:running-cakephp-shell-script-cronjob-dreamhost

Setting up cron jobs with Cake shells - http://planetcakephp.org/aggregator/items/4632-setting-up-cron-jobs-with-cake-shells


[CakePHP] JSON出力時にstring型をint型に戻す

久々のブログ、今回はCakePHPでJSON出力をするときにInteger型、String型に型変換して出力する方法について書きます。 (あ、今回も他力本願、満載)

まず、CakePHPでJSON出力をする為には

Controllerで

$yourJsonObect= $this->YourModel->find('all');
$this->set('yourJsonObect', $yourJsonObect);

としてやり

Viewで

<?php echo $javascript->object($yourJsonObect); ?>

としてやれば簡単に実現できます。

出力されるコードは以下のようになります。

[{"YourModel":{"id":"10060","foreign_id":"1","short_description":"Short Desc Test.","long_description":"Long Desc Test"},
{}
.....
)]

これで、殆ど場合は問題ないのですが、データベース上でIntegerで持っているスキーマ(id, foreign_idなど)も全てString型として出力されます。

もし、JSONデータを受け取る側が厳密にInteger型、String型を区別して受け取りたい場合などに以下の方法でスマートに解決できたので紹介します。

余談ですが、自分の場合は、iPhone開発において、JSONデータをウェブサーバーから受け取り、Core DataにInsertする時に、iPhone側で型チェックや型変換をさせたくなかったので、サーバー側で吸収してしまおうという経緯がありました。

参考にしたサイトはこちらです。

CakePHPのmodelの結果配列でstring型をint型に戻す。

CakePHPでmodel::findなどの関数で結果配列を取得したときに、データベースではint型の値string型として返って来ます。

今回は、flashにjson出力でデータを渡したかったので、別に文字列型のまま渡しても問題ないのかもしれないけど、なんか気持ち悪い。

それに例えばよくある、intの0,1をフラグと扱って if (flag) {.... }なんて書いたらマズいんじゃないかと思うので、settypeで型変換を行う方法。

引用元: CakePHPのmodelの結果配列でstring型をint型に戻す。: ろーにーの日記.

モデルの親クラスで、Findで取得したデータ(デフォルトは全てString)をデータベースのTypeを参照して、型変換を行っています。

app_model.phpにafterFind()オーバーライド関数を追加してやるだけ。

class AppModel extends Model{
	public function afterFind($results, $primary = false) {
		parent::afterFind($results, $primary);
		$columnTypes = $this->getColumnTypes();
		foreach($results as $index => $result) {
			foreach($columnTypes as $field => $columnType) {
				if($columnType == 'integer') {
					if(isset($results[$index][$this->name][$field])) {
						settype($results[$index][$this->name][$field], 'integer');
					}
				}
			}
		}
		return $results;
	}
}

これで全てのモデルが自動変換されるようになりました。 感激~

変換後のJSON出力を見ると以下のようになります。

[{"YourModel":{"id":10060,"foreign_id":1,"short_description":"Short Desc Test.","long_description":"Long Desc Test"},
{}
.....
)]

Integer型の数字の部分からダブルクォーテーションが消えました。

めでたしめでたし。

http://app.cocolog-nifty.com/t/trackback/120702/48427427

CakePHPで携帯サイト構築(Ktai Library)の場合のGPLライセンスについて

以下のサイトでCakePHPで携帯サイト構築をするためのヘルパー・コンポーネントを公開されています。 ありがたく、今度試させてもらおうと思います。

携帯サイトを構築する場合の、各キャリア対応をサポートするライブラリと、それをCakePHPで利用するためのヘルパー・コンポーネントを公開いたします。ライブラリ本体はCakePHPだけでなく他の環境でも使用することが出来ます。

引用元: ECWorks Blog | Ktai Library for CakePHP1.2.

なお、ライセンス形態はGPLライセンスのようです。

GPLライセンスといえば「コピーレフト」。「コピーレフト」といえばGPLライセンス、と切っても切れない関係で、その「コピーレフト」の感染力がしばしば話題になりますが、

ここで、疑問。

ヘルパー・コンポーネントとしてGPLライセンスを使った場合、自分の成果物もGPLライセンスにしなければいけないのか?

想定されるライセンス形態は以下のような感じです。

  • MITのCakePHP
  • 自分の成果物(Appフォルダの中)
  • GPLライセンスのKtai Library/ヘルパー・コンポーネント

 

いろいろ調べた結果、自分のなかでは「自分の成果物もGPLライセンスにしなければいけない」のではないか、という考えです。 ただ間違っている可能性大です。

理由としては以下のとおりです。

CakePHPではないですが、
以下にWordPressのテーマはすべてGPLライセンスにしなければならないか?といった内容の記事があります。GPL の専門のソフトウェア・フリーダム・ロー・センターの回答ということで、大変興味深い内容になっています。その中で、

CSS ファイルや “default” テーマの画像ディレクトリに含まれるものは、WordPress コードとは分離しているといえるでしょう。一方、WordPress のコードと混じり合い、影響を受ける PHP や HTML コードは、WordPress の派生物といえます。

[中略]

結論として、提示された WordPress テーマは WordPress の著作権の元にあるコードの派生物を含んでいます。それぞれ独自の作品である画像、CSS、PHP ファイルをまとめたこれらのテーマは、全体的を GPL ライセンスにする必要はありません。むしろ、PHP ファイルは GPL ライセンスの要件に制約されるが、画像や CSS はそうではないと言えます。サードパーティのテーマ開発者は、希望するなら制限付きの著作権を適用することができます。

最後に、WordPress の著作権に制限されない合法な WordPress テーマを作成することも可能ということを言っておきます。しかしそのようなテーマはこのソフトを有益なものにしている WordPress 関数をまったく使わないものである必要があります。

引用元:http://www.my-standard.co.jp/932.html

と結んでいます。

WordpressのWordPress関数はGPLなのでそのコードを呼び出したり、混じり合い、影響を受けるPHPはWordpressの派生物である(画像、CSSは混じり合ってないのでそうでない)

ということらしいです。すると、

Ktai Libraryはコンポーネントなので、自分のコードから読出したり、影響を受けたりするわけだから、「コピーレフト」の影響をうける。よって、自分の成果物もGPLライセンスにしなければならない。

であろう、という考えにいたりました。

間違っていたら是非指摘して下さい。


すでにあるPHPのサイトからSSOでWordpressにもログインさせる方法

自分の会員制のサイトで利用者にブログを提供できるオプショナルサービスを考えていてSSO(Single Sign On)をどうしたものかと思い調べてみました。

すでにあるPHPのサイトからSSOでWordpressにもログインさせる方法として、以下のサイトのコードが流用できそうなのでブックマーク。。。

In my setup, the main site has role-based permissions and the WordPress setup only has one account for each role (i.e. admin, editor, user etc…). The plugin first checks the role of the user logged in to the main site and then simulates a WordPress login anytime the user navigates to the blog. You should be able to customize this method for your own needs.

引用元: WordPress Auto-Login | Leon's Weblog.

まぁ~、うちのサイトではまだまだ対応はあとになるだろうけど・・・


CakePHPでreCAPTCHAによる画像認証

自作のポータルサイトシステムのお問い合わせにCAPTCHA機能の認証を付ける際に参考にさせてもらいました。

GWからCakePHPでつくりはじめたWebサービスで、画像認証を実装したいと思って、以前から気になっていたreCAPTCHAを導入した。びっくりするくらい簡単だったけど、意外とreCAPTCHA実装の記事が少ないので、丁寧に解説します。

引用元: CakePHPでreCAPTCHAによる画像認証を実装するまで – 情報と音楽.

実際、reCAPTCHAのようなWEBサービスは開発者にとってかなりの時間の削減になるので、これからもいいサービスがあれば積極的に導入していきたいです。


CakePHP リンク連打や読み込み中に再アクセスするとセッションが切れる問題

CakePHPを使ったプロジェクトでデザイナーの友達から「管理画面を使っていたらよくログアウトしてしまう。」という指摘を受けたので調べてみたら以下のフォーラムで解決策が載っていました。

CAKE_SECURITYを"high"で運用中に勝手にログアウトされる現象が多発!リンク連打等、読み込み中に再アクセスするとセッションが切れる様子。いろいろと原因を探してると、ここの記事にたどり着きました。現在は、CAKE_SECURITYを"medium"で運用しています。アクセス毎session_idを書き換えてセキュリティを高める目的なんでしょうかね?しかし、毎回読み込みが完了するまで、ユーザに触らせないようにしないと使えないですね。

引用元: "cake1.1.18にversionアップしたらSessionが使えない?" フォーラム - CakePHP Users in Japan.

実際に、ページの読み込み中に他のリンクを押すと十中八九再現が可能だったので、セッカチな人はログアウトしまくってしまうみたいです。

CakePHPのデフォルトセキュリティでは、セッションハイジャックを防ぐなどの意味で、こういう対応になっているみたいなのですが、一般ユーザに公開するようなサイトだと、これはちょっと実用的ではないので、CAKE_SECURITYを"medium"で運営するか、読み込み中はリンクを押させないような工夫が必要になってくるのではないかと思います。


【CakePHP】CakeFestで発表された「Media Plugin for CakePHP」のスライドを翻訳してみました | ECWorks Blog

ヴァージョン管理、Webroot以外でのアップロードファイルを保存というところに激しく興味を覚えたので、時間があるときに試してみたいと思い、とりあえずブックマーク。

【CakePHP】CakeFestで発表された「Media Plugin for CakePHP」のスライドを翻訳してみました | ECWorks Blog.


mod_rewrite サンプル集のメモのメモ

使いこなせばスイス製のアーミーナイフのような切れ味を発揮すると説明されている、apacheのmod_rewrite。

わかっちゃいるけど、正規表現と同じで、いつも必要なところだけサラッとかっさらって、いつまでも使い方をちゃんと理解していない。 いつか腰をすえて習得しないといけないなぁ~と思ってはいるんだけど・・・

ってことで、サンプルのメモ

mod_rewrite サンプル集

mod_rewrite はすげー色んなことができて楽しい。

でもけっこう難しい。

そこで、オイラ用メモで簡単なサンプル集をば。

引用元: mod_rewrite サンプル集/楽.


CakePHPでWordpressにアクセス

If you’re like me, you’ve fallen in love with CakePHP. It’s a tight bit of code that’s easy to use and once you have your application using it, easy to maintain and add new features. For my recent redesign of my freelance site www.systemsevendesigns.com I wanted to be able to display my 3 most recent blog posts on the homepage. Both sites run off of different databases, so how do we do it with Cake? (This post assumes you know a little bit about Cake, but is not too terribly complex. Cake newbies welcome!)

引用元: WebDevKungfu » Blog Archive » Accessing WordPress with CakePHP | Web Development, Web Design, Coldfusion, Rails, Ruby on Rails, PHP blog.

仕事の合間に、ふと思いたってググッてみた。

やっぱみんな考えることは同じだなぁ~。

ちょっと前にWordpressで動くフリーマケットとか購入したし、これからどんどんインテグレートしていこう。

最近、CakePHP用の掲示板をPluginとして取り入れたばかりだけど、ちゃちゃっと別システムを取り入れれるCakePHPの柔軟性がステキすぎです。(といってもCakePHPのACL周りで結構書き換えに工夫が必要だったけど)

ってことで、今回も自分用メモ。。。 あしからず。