CakePHP1.2でKtai Library利用時に、組み込まれているテストケースでエラーになる

CakePHP1.2でKtai Library for CakePHP1.2をインストールした後に最初から組み込まれているテストケース「All Core Tests」を実行するとエラーになる。
エラーメッセージはこんな感じ。
# Failed
Identical expectation [Array: 3 items] fails with [Array: 3 items] as key list [0, param, param2] does not match key list [0, 1, 2] at [/var/www/html/project/cake/tests/cases/dispatcher.test.php line 1254]
/var/www/html/project/cake/tests/cases/dispatcher.test.php -> DispatcherTest -> testDispatch

とにかくだーっといくつかエラー発生。

んで、いろいろ調べてみたらKtai Libraryをインストールした際にapp/config/routes.phpへ追加した以下の一文が悪さしている模様。
Router::connectNamed(array(), array('argSeparator' => '~'));

がこれをコメント化したらちゃんと動いた。

まあ、わざわざテストケース書くのもなあと思うので、コレで良しとしよう。
ちゃんとしたい人は、パラメータを渡す時のセパレータをコロンからチルダに変えてあげれば上手く行くはずなんだけど、cakeディレクトリに入っているテストケースを触ることになるので、ちょっと嫌だなー。

CakePHP1.2のバリデーションでurlがチルダをエラーにしてしまう

ということで、タイトル通り。

http://hogehoge.com/~foo

みたいなチルダが入っている値だと、入力エラーになる。

調べてみると、ちらほら同じような人が見つかる。
CakePHPのvalidateで、チルダが入っているとURLとして認識してくれない « 15Pub
CakePHP-ja tumblr - Validation::url() が URL の ~ に反応する件への

けど、具体的な解決策が見つからなかったので、コードを晒しておく。
# app/app_model.php

function url($data, $strict = false) {
	$check = is_array($data) ? array_shift($data) : $data;

	$_this =& Validation::getInstance();
	$_this->check = $check;
	$validChars = '([' . preg_quote('~!"$&\'()*+,-.@_:;=') . '\/0-9a-z]|(%[0-9a-f]{2}))';         // 「~」を追加
	$_this->regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . ife($strict, '', '?') .
		'(?:' . $_this->__pattern['ip'] . '|' . $_this->__pattern['hostname'] . ')(?::[1-9][0-9]{0,3})?' .
		'(?:\/?|\/' . $validChars . '*)?' .
		'(?:\?' . $validChars . '*)?' .
		'(?:#' . $validChars . '*)?$/i';
	return $_this->_check();
}


参考サイトを真似してvalidCharsにチルダを追加しておいた。
cake/libs/validation.phpに手を入れるのは嫌なので、app/app_model.phpに上記を追加。

んー、チルダをURLに含むべきではないってのはそうかもしれないんだけど、柔軟に対応して欲しいところだね。

CakePHP1.2+Ktai LibraryでcakeErrorを使いたい

CakePHP1.2にてKtai Libraryを使って携帯サイトを開発中に躓いた。
僕の場合、モバイル用のviewのlayout.ctpの一行目がこんな感じ。
<?xml version="1.0" encoding="<?php echo $ktai->options['output_encoding']; ?>"?>

いきなりKtai Library用のHelper呼んでるんだよね。
んで、
Notice (8): Undefined variable: ktai 

なんてオシャレなエラーメッセージを出してくれます。
「$ktaiなんて無いよ、バカ」と言われても、こちらとしては、
「Controllerに設定しているだろ、バカ」ということになるんですが、cakeError()のソースコードを追ってみたら、Error用に独自にController用意されているみたいで、こりゃダメだわと。

んで、ネットで検索してたどりついたのがこちら。
CakePHPを本気で勉強: cakeError:ErrorHandlerで独自ヘルパーを使用する

それをちょっとカスタマイズして出来たのがコレ。
# app/app_error.php

/**
 * error 
 * 
 * @param mixed $params 
 * @access public
 * @return void
 */
function error($params){
    $this->controller->helpers[] = 'ktai';
    return parent::error($params);
}
/**
 * error404 
 * 
 * @param mixed $params 
 * @access public
 * @return void
 */
function error404($params){
    $this->controller->helpers[] = 'ktai';
    return parent::error404($params);
}

error404()もついでにやっておいた。

つうか、ネット上にこういった情報が皆無なのにビックリ。
Ktai Libraryってメジャーでしょ?
みんなエラー処理どうしてんの?
謎だわー。

CakePHP1.2でKtai LibraryとQdmailを使う時の注意メモ

気を抜くと技術ネタが皆無になり、漫画と音楽だけのブログになりそうなので、簡単だけどメモを。

CakePHPで携帯サイトを作る時に便利なのが、Ktai Library。
Works Blog | Ktai Library for CakePHP1.2

CakePHPで日本語メールを送る時に便利なのが、Qdmail。
PHP高機能日本語メール送信ライブラリ・文字化けフリー - Qdmail - PHP::Mail Library , Quick and Detailed for Multibyte

で、二つを同時に使う時に気をつけなくちゃいけないのが
メールを使う時は、Ktai Libraryを無効化した方が良い
っつうこと。

携帯用のメールとPC用のメールって何か変更しなくちゃいけないかなと考えたんだけど、半角カタカナにしたら面倒なことになりそうだし、文字コードも一緒だし。
なので、メールを送信する箇所だけ外したいわけ。

僕の場合は、前提としてAppControllerで以下の様な設定をしております。

# app/app_controller.php
function beforeFilter() {

~ 略~

	if (in_array('Ktai', $this->components)) {
		if($this->Ktai->is_ktai()){
		
			Configure::write('Ktai', array(
				'use_img_emoji'   => true,			//画像絵文字を使用
				'input_encoding'  => KTAI_ENCODING_UTF8, 	//入力をUTF-8に変更
				'output_encoding' => KTAI_ENCODING_SJIS, 	//出力をShift-JISに変更
				'output_convert_kana' => 'knr',			//半角変換
				'output_auto_encoding' => true,                 //自動変換
			));
		
			$config = Configure::getInstance();
			array_unshift($config->viewPaths, ROOT.DS.APP_DIR.DS.'views_mobile'.DS);
		
			// SJIS -> UTF8
			if(!empty($this->data)) {
				mb_convert_variables( 'UTF-8', 'SJIS-win' ,$this->data);
			}
		}
	}

~ 略~

}

簡単にいうと
1)携帯だったら、画像絵文字を使っちゃって!
2)携帯だったら、文字コードの変換(UTF-8→Shift-JIS)を自動でやっちゃって!
3)携帯だったら、文字を半角にしちゃって!
4)携帯だったら、viewのディレクトリ変えちゃって!
5)携帯だったら、フォームの内容とか文字コード変えちゃって!

っつうことなんだけど、いろいろ余分なものも含まれているので、view側で再設定してあげる。
例えばこんな感じ。
# app/view_mobile/layouts/email/text/default.ctp

<?php $ktai->options['use_img_emoji'] = false; ?>
<?php $ktai->options['output_convert_kana'] = false; ?>
<?php $ktai->options['output_auto_encoding'] = false; ?>


各controllerのactionで切り分けてもいいと思うんだけど、ぶっちゃけメール送信部分だけoptionを変更するのが面倒なので。
まあ、MVC的にはアレですが。

CakePHP1.2で管理者用の静的ページを作る(認証付き)

言わんとしていることがわかるかなー。

CakePHP1.2だと静的ページを表示したい時ってPagesController使って表示出来るんだけど、管理者用のページも作りたい訳。

つうことで以下のページを参考に実装してみた。
"プレフィックスルーティング時のpages_controllerの挙動" フォーラム - CakePHP Users in Japan
actionshrimp.com ≫ CakePHP: PagesController with Admin Routing

まずはPagesControllerを継承したコントローラを作る。
# app/controllers/pages_ex_controller.php

<?php
App::import('Controller', 'Pages');

class PagesExController extends PagesController {

	var $components = array('Auth');

	function beforeFilter(){
		if(Configure::read('Routing.admin') && empty($this->params[Configure::read('Routing.admin')])){
			$this->Auth->allow();
		}
	}

	function admin_display() {
		$path = func_get_args();
		if ($path[0] != 'admin') {
			//This adds admin to the beginning of the path so the pages controller will look in the 'admin' folder in pages directory
			$path = array_merge((array)'admin', $path);
		} else {
			//This removes admin from the beginning if it's there already, and sends the request round again so we end up with URLs that look like app/admin/pages/x
			//when app/admin/pages/admin/x is requested somehow.
			$path = array_slice($path, 1);
			$this->redirect(array_merge(array('controller' => 'pagesEx', 'action' => 'display', 'admin' => true), $path));
		}
		call_user_func_array(array($this, 'parent::display'), $path);
	}
}
?>

一応
/admin/pages/*

ってパスでアクセスして来ても認証されるようにAuthコンポーネント読み込んでる。
まあ、この辺は通常のControllerクラスと一緒なので、お好みで。

ルーティングを設定してやる
# app/config/routes.php

/**
 * admin.
 */
	Router::connect('/admin', array('controller' => 'pagesEx', 'action' => 'display', 'admin' => true, 'home'));
	Router::connect('/admin/pages/*', array('controller' => 'pages', 'action' => 'display', 'admin' => true));

この設定だと
/admin

で管理者用のページ(app/views/pages/admin/home.ctp)へアクセスできるようになる

あんまりネット上に情報が無かったけど、みんないらんのかな。
僕なんかは、管理者のトップページなんかは静的ページ欲しかったりするんだけど。
1 | 2 | 3 | 4 次のページ ≫ 1 of 4

アーカイブ

2010

  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12

2009

2008

2007

コンタクト

longkey1[at]gmail[dot]com