Posts tagged tag

CakePHP 携帯専用サイトを作成する

6

CakePHP で携帯用のページを作成する際に CakePHP 携帯用ビューを表示する | Shin x blog のページが大変参考になります。

しかし、/m/ のような URL ではなく携帯専用サイトにしたかったので下記のような方法で実装しました。なお、PC でアクセスしたときには /pc.html という静的なページを表示するようにしてあります。
また、PC、携帯の振り分けはユーザエージェントで行っています。

携帯用コンポーネント

app/controller/component/mobile.php を作成し、PEAR の Net_UserAgent_Mobile を使用しています。このコンポーネントでユーザエージェントを判定して PC だったら pc.html へリダイレクトします。

PEAR の Net_UserAgent_Mobile はサーバにインストールしてもいいのですが、今回は app/vendors/ ディレクトリに入れました。また、app/vendors/ に include_path を通すために、CakePHPガイドブック を参考に include_path_vendors.php を作成しました。

app/controller/component/mobile.php

vendor("include_path_vendors");
vendor("Net/UserAgent/Mobile");
class MobileComponent extends Object {
    function startup(&$controller) {
        $this->controller = $controller;
        $mobile = &Net_UserAgent_Mobile::factory();
        if ($mobile->isNonMobile()) {
            $this->controller->redirect("/pc.html");
        }
    }
}

今回は簡単に PC か携帯でアクセス振り分けているだけですが、画面の大きさやキャリアなどによって色々な処理の振り分けが考えられます。

携帯用ヘルパー

app/views/helper/mobile.php を作成して HTML 出力時に文字コードを Shift-JIS へ変換します。ヘルパーの afterRender メソッドを使用しています。

class MobileHelper extends Helper {
    function afterRender() {
        $out = ob_get_clean();
        $out = mb_convert_kana($out, "rak", "UTF-8");
        $out = mb_convert_encoding($out, "SJIS", "UTF-8");
        ob_start();
        echo $out;
    }
}

コントローラで携帯用コンポーネント、ヘルパーを使用する

app/app_controller.php で携帯用コンポーネントと携帯用ヘルパーを使用します。

var $components = array('Mobile');
var $helpers = array('Mobile');

app_controller.php で設定しておけば全てのコントローラで共通に読み込むので各コントローラにその都度書く必要がなくなります。DB の管理画面など PC 用のコントローラが必要な場合は各コントローラに書いた方がいいでしょう。今回は完全に携帯用にしています。PC 用の管理画面もあるのですが、サブドメインを変えて app ディレクトリも違うものを使用しています。

また、各コントローラ内で設定するタイトルの文字コードを変換しないといけないので、app_controller.php の beforeRenderメソッドでタイトルの文字コードを変換します。

function beforeRender() {
    $this->pageTitle = mb_convert_encoding($this->pageTitle, "SJIS", "UTF-8");
    parent::beforeRender();
}

以上で携帯専用のサイトが CakePHP で作成できました。

コントローラの afterFilter で文字コードを変換する方法

コントローラの afterFilter で文字コードを変換することもできます。

app/controller.php

function afterFilter() {
    parent::afterFilter();
    $out = ob_get_clean();
    $out = mb_convert_kana($out, "rak", "UTF-8");
    $out = mb_convert_encoding($out, "SJIS", "UTF-8");
    ob_start();
    echo $out;
}

この場合は、beforeRender でのタイトルの文字コード変換の処理が必要ないのと、携帯用ヘルパーは必要ありません。
PC 用のコントローラも作りたいときは携帯用コンポーネント、携帯用ヘルパーを使用する方法がよいかと思います。

12月に読んだ本

0

先月、宣言(11月に読んだ本 )したように少し小説を読みました。
2冊のみですが、どちらも文庫本で700ページ前後なので読み応えはありました。「幻夜」は「白夜行 」の続編のようで白夜行に迫る面白さで読むのが止まりませんでした。

最悪」は奥田英郎の最初の頃の作品なので、イラブ先生シリーズやサウスバウンドなどにはかないませんが、引き込まれる作品でした。

幻夜

幻夜

最悪 (講談社文庫)

最悪 (講談社文庫)

あなたが年収1000万円稼げない理由。―給料氷河期を勝ち残るキャリア・デザイン (幻冬舎新書 た 3-1)

あなたが年収1000万円稼げない理由。―給料氷河期を勝ち残るキャリア・デザイン (幻冬舎新書 た 3-1)

【超】WORK HACKS!

【超】WORK HACKS!

起業家2.0―次世代ベンチャー9組の物語

起業家2.0―次世代ベンチャー9組の物語

効率が10倍アップする新・知的生産術―自分をグーグル化する方法

効率が10倍アップする新・知的生産術―自分をグーグル化する方法
勝間さんの本はどれもはずれがなくていいですね。読んでいるだけでやる気が出てきます。(それだけで実践しないと意味ないですが)巻末のお勧め本がかなりいいです。これからの読書の参考にしていきます。早速、今月は「非常識な成功法則―お金と自由をもたらす8つの習慣」をリストを参考に読んでみました。

読みならがメモしたことをいくつかリストアップしておきます。

  • 情報こそが現代の通貨である
  • 資本主義の本質は賢くない人から賢い人へお金が移動する仕組み
  • 情報の発信者になれば情報がラクに収集できるようになる
  • 自分が得意なことに集中する
  • Not To Do List を作成する
  • まずは見返りを求めずに情報を発信し続ける

金融商品にだまされるな!

金融商品にだまされるな!

金持ちの床屋さん

金持ちの床屋さん

非常識な成功法則―お金と自由をもたらす8つの習慣

非常識な成功法則―お金と自由をもたらす8つの習慣

レバレッジ人脈術

レバレッジ人脈術

チーズはどこへ消えた?

チーズはどこへ消えた?

ザ・マインドマップ

ザ・マインドマップ

WEB+DB PRESS Vol.42

WEB+DB PRESS Vol.42

人を出し抜く速読術―要領よく生きてるヤツは知っている (凄ビジ・シリーズ 3)

人を出し抜く速読術―要領よく生きてるヤツは知っている (凄ビジ・シリーズ 3)

キラー・リーディング 「仕事脳」が劇的に回り出す最強の読書法 (JBシリーズ)

キラー・リーディング  「仕事脳」が劇的に回り出す最強の読書法 (JBシリーズ)

CakePHP JQuery ヘルパー

3

JQuery helper for CakePHP ( PQuery port ) at NGCoders
CakePHP から JQuery を簡単に使うことができます。

正確には PQuery ヘルパーかもしれません。PQuery は JQuery を PHP から簡単に使用するライブラリで PQuery ヘルパーと同じ開発者が開発しています。
参考:PQuery – PHP and JQuery at NGCoders

インストール

JQuery helper for CakePHP ( PQuery port ) at NGCoders から JQuery ヘルパーをダウンロードし、解凍した pquery.php を /app/views/helpers にコピーします。
そのほかに jquery.js ファイルも必要になります。こちらもダウンロードして /app/webroot/js にコピーします。

コントローラ

Pquery ヘルパーと Javascritp ヘルパーを使用します
var $helpers = array('Pquery', 'Javascript');

ビュー

jquery.js の読み込み
<?php echo $javascript->link('jquery.js'); ?>

使用例

トグルボタン

<div id='msg'>Message...</div>
<?php echo $pquery->link_to_function('toggle', $pquery->toggle('#msg'));?>

フォームで送信された内容により HTML を更新
入力したテキストを /controller/action/ に GET で送信し、id=idtoupdate に受け取った HTML を表示する

<?php echo $pquery->form_remote_tag(array('url'=>'/controller/action/','update'=>'#idtoupdate'));?>
<input type='text' name='field' />
<input type='submit' />

<div id='idtoupdate'></div>

pquery.php を見ると色々なメソッドがあります。使い方はソースを見ればすぐに分かると思います。

scriptaculous.js を使ってマトリックス状に配置した要素を並び替える

1

scriptaculous.js を使って並び替えを行う を応用して格子状に並んだ要素を並び替える例です。基本的な部分はリスト形式の並び替えと同じですので省略します。
最初にデモ、その後にコードを紹介します。

デモ


#sortarea { width: 350px; } #sortarea div { float: left; width: 100px; height: 70px; border: 1px solid #000; margin: 5px; text-align: center; padding-top: 30px; cursor: default; }

A1
A2
A3
A4
A5
A6
A7
A8
A9

ソートする要素

前回は li タグで要素を定義しましたが、今回は div タグで定義しました。
CSS で格子状に並ぶようにしています。

<style>
#sortarea {
width: 350px;
}

#sortarea div {
float: left;
width: 100px;
height: 70px;
border: 1px solid #000;
margin: 5px;
text-align: center;
padding-top: 30px;
cursor: default;
}
</style>

<div id="sortarea">
<div id="drag_1">A1</div>
<div id="drag_2">A2</div>
<div id="drag_3">A3</div>
<div id="drag_4">A4</div>
<div id="drag_5">A5</div>
<div id="drag_6">A6</div>
<div id="drag_7">A7</div>
<div id="drag_8">A8</div>
<div id="drag_9">A9</div>
</div>

ソートする JavaScript コード

Sortable.create の option に overlap:’horizontal’ を指定しなくても並び替えはできますが、少しぎこちない感じになりますので、指定しておいたほうがいいでしょう。

<script type="text/javascript" language="javascript">
// <![CDATA[
Sortable.create("sortarea",{
    tag:'div',overlap:'horizontal',constraint: false,
});
// ]]>
</script>

WordPress の Simple Tagging プラグインで表示する関連エントリのはてブ数を表示する方法

1

このブログは Simple Tagging というプラグインを使用して各エントリにタグをつけています。このプラグインを使用するとタグから各エントリの関連エントリを自動的に表示することができます。詳しくは下記エントリをご覧ください。
WordPress でタグを使えるようにしてみた

今回はこの関連エントリのはてなブックマーク数を表示するようにする方法です。
こんなイメージです。
関連エントリにはてブ数を表示

関連エントリを表示するタグ

<?php STP_RelatedPosts(); ?>
この STP_RelatedPosts 関数の第1引数は表示フォーマットを指定するので、そこにはてブ数を表示するようなフォーマットを指定します。
<?php STP_RelatedPosts('<li><a href="%permalink%" title="%title% (%date%)">%title%</a> <a href="http://b.hatena.ne.jp/entry/%permalink%"><img src="http://b.hatena.ne.jp/entry/image/%permalink%" alt="" /></a>'); ?>

これで関連エントリにはてブ数が表示されるようになりました。

CakePHP Security コンポーネントのまとめ

1

CakePHP の Security コンポーネント の動作を調べたのでまとめておきます。
この Security コンポーネントをうまく使用すればクロスサイトリクエストフォージェリ(CSRF) を防ぐことができるでしょう。

トークンの使用

フォームにワンタイムトークンを実装する方法です。

コントローラの beforeFilter メソッドでトークンをチェックするアクションを指定
function beforeFilter() {
    $this->Security->requireAuth('login');
}
ビューのフォーム内にトークンを設定

<?php echo $html->formTag(); ?>
トークンが hidden 属性で生成される

トークンが一致しない場合

requireAuth で指定したアクションに POST でアクセスがあるとセションに保存したトークンとフォームから送られてきたトークンが一致するかチェックします。またそのほかにトークンの有効期間もチェックします。有効期間は CAKE_SECURITY の設定により違います。

CAKE_SECURITY 有効期間
high 10分
medium 100分
low 300分

トークンが一致しないと SecurityComponent の blackHole メソッドが実行されます。このメソッドでは
header('HTTP/1.0 404 Not Found');
を出力して exit します。(画面は空白)

任意の処理を実行したい場合は blackHoleCallback でコールバック関数を指定します。
設定できるのは同じコントローラ内のアクションのみになります。

function beforeFilter() {
    $this->Security->blackHoleCallback = "securityError";
    $this->Security->requireAuth('login');
}

function securityError() {
	die("security error!");
}
トークンチェックをするアクションを複数指定するときはカンマでつなげる

$this->requireAuth('login', 'delete');

特定のコントローラからのポストのみ許可する

$this->Security->allowedControllers = array("users");
これを指定するとたとえトークンが一致しても許可のないコントローラからのポストの場合は blackHole メソッドを実行します。

特定のアクションからのポストのみ許可する

$this->Security->allowedActions = array("action");
これを指定するとトークンが一致しても許可のないアクションからのポストの場合は blackHole メソッドを実行します。

ポストのみ受け付けるようにする

$this->requirePost('login');
これはトークンとは違い、POST のみ許可して GET でのアクセスを不可にします。
/users/login/ のような URL でのアクセスも GET なので不可になります。
POST の処理だけを実行したいようなアクションに使用します。

11月に読んだ本

2

最近は仕事関係の本や自己啓発関係の本が多い。特に今年は小説を読んでないので、今月は少し小説を読もうと思っています。

決算書がスラスラわかる 財務3表一体理解法 (朝日新書 44) (朝日新書 44)

決算書がスラスラわかる 財務3表一体理解法 (朝日新書 44) (朝日新書 44)

あたりまえだけどなかなかできない仕事のルール (アスカビジネス)

あたりまえだけどなかなかできない仕事のルール (アスカビジネス)

ウェブ時代をゆく ─いかに働き、いかに学ぶか (ちくま新書 687)

ウェブ時代をゆく ─いかに働き、いかに学ぶか (ちくま新書 687)

なぜ、エグゼクティブはゴルフをするのか?

なぜ、エグゼクティブはゴルフをするのか?

ちょいデキ! (文春新書 591)

ちょいデキ! (文春新書 591)

すごい「実行力」

すごい「実行力」

なぜ、エグゼクティブはゴルフをするのか?

なぜ、エグゼクティブはゴルフをするのか?

仕事に活かす!本200%活用ブック

仕事に活かす!本200%活用ブック

WEB+DB PRESS Vol.41

WEB+DB PRESS Vol.41

お金は銀行に預けるな 金融リテラシーの基本と実践 (光文社新書)

お金は銀行に預けるな   金融リテラシーの基本と実践 (光文社新書)

プログラミングPHP 第2版

プログラミングPHP 第2版

CakePHPガイドブック

CakePHPガイドブック

忙しいパパのための子育てハッピーアドバイス

忙しいパパのための子育てハッピーアドバイス

ケータイ業界52人が語る「戦略」の裏側

ケータイ業界52人が語る「戦略」の裏側

カリスマ・コンサルタントの稼ぐ超思考法 ~仕事と人生に効く「問題解決力」が身につく20の方法~

カリスマ・コンサルタントの稼ぐ超思考法 ~仕事と人生に効く「問題解決力」が身につく20の方法~

自転車生活の愉しみ

自転車生活の愉しみ

CakePHP モデルの validation の拡張 同じ項目で違うメッセージを出す

1

CakePHP のモデルの validation の拡張のメモの続きです。

同じフォームの項目で違うエラーメッセージを出したいときがあります。
例えばユーザ登録フォームでユーザID がフォーマットエラーなのか、既に使用されているのかなどです。

models/users.php

var $validate = array(
        'loginid' => '/^[0-9a-zA-Z]{8}$/',
    );

function validates($data=array()) {
        if(empty($data)) {
            $data = $this->data;
        }

        parent::validates($data);

        // loginid のユニークチェック
        if ($this->findByLoginid($data["User"]["loginid"])) {
            $this->invalidate("loginid_unique");
        }

        if (count($this->validationErrors)>0) {
            return false;
        } else {
            return true;
        }
}

既にloginid が登録済みの場合は
$this->invalidate('loginid_unique');
としています。
invalidate に指定するのは実際に存在しないものでも大丈夫なのでそれを使用して view でエラーメッセージを分けて表示します。

views/users/regist.thtml

ID:< ?php echo $html->password('User/loginid'); ?>
< ?php echo $html->tagErrorMsg("User/loginid", "IDは英数字8文字で入力してください"); ?>
< ?php echo $html->tagErrorMsg("User/loginid_unique", "IDは既に使用されています。他のID を指定してください"); ?>

CakePHP モデルの validation の拡張

1

CakePHP のモデルの validation の拡張のメモです。

ユーザ登録フォームなどでパスワードの再確認のバリデーションを行うときの方法です。

views/users/regist.thtml

パスワード:< ?php echo $html->password('User/password'); ?>
確認用パスワード:< ?php echo $html->password('User/password2'); ?>
< ?php echo $html->tagErrorMsg('User/password2', 'パスワードが一致しません');

※users テーブルにpassword2 のカラムはなくてかまいません。

models/users.php

function validates($data=array()) {
        if(empty($data)) {
            $data = $this->data;
        }

        parent::validates($data);

        if ($data["User"]["password"]!==$data["User"]["password2"]) {
            $this->invalidate("password2");
        }

        if (count($this->validationErrors)>0) {
            return false;
        } else {
            return true;
        }
}

AppModel クラスの validation メソッドも実行する必要があるので、必ず
parent::validates($data);
を書かないといけません。

10月に読んだ本

1

先月少なかった分、今月は結構読めました。

なぜ、週4時間働くだけでお金持ちになれるのか?

なぜ、週4時間働くだけでお金持ちになれるのか?

ダメなら、さっさとやめなさい! ~No.1になるための成功法則~

ダメなら、さっさとやめなさい! ~No.1になるための成功法則~

レバレッジ勉強法

レバレッジ勉強法

スタバではグランデを買え! ―価格と生活の経済学

スタバではグランデを買え! ―価格と生活の経済学

佐藤可士和の超整理術

佐藤可士和の超整理術

パーソナルブランディング 最強のビジネスツール「自分ブランド」を作り出す

パーソナルブランディング 最強のビジネスツール「自分ブランド」を作り出す

SAMURAI佐藤可士和のつくり方

SAMURAI佐藤可士和のつくり方

無理なく続けられる年収10倍アップ時間投資法

無理なく続けられる年収10倍アップ時間投資法

勝手サイト 先駆者が明かすケータイビジネスの新機軸 (ソフトバンク新書 52) (ソフトバンク新書 52)

勝手サイト 先駆者が明かすケータイビジネスの新機軸 (ソフトバンク新書 52) (ソフトバンク新書 52)

プログラマー現役続行 (技評SE新書 12)

プログラマー現役続行 (技評SE新書 12)

月に100万稼げるドロップシッピング

月に100万稼げるドロップシッピング

図解 SEO対策がわかる (知りたい!テクノロジー)

図解 SEO対策がわかる (知りたい!テクノロジー)

ネット未来地図 ポスト・グーグル時代 20の論点 (文春新書 595)

ネット未来地図 ポスト・グーグル時代 20の論点 (文春新書 595)

ケータイハックス-いつでもどこでも仕事術 [マイコミ新書] (マイコミ新書)

ケータイハックス-いつでもどこでも仕事術 [マイコミ新書] (マイコミ新書)

Go to Top