cakePHPでページング(パスの変更)

2007/07/25 | cakePHP

WindowsにXamppをインストールしてウェブアプリの開発をしていたのだが、ファイルをLinux上のサーバにアップしたら、ページング処理が動かなくなってしまった。エラーメッセージを見たら、単にpear内のファイルの呼び出しでエラーがあった。これを以下のような具合で修正した。

require_once(dirname(__FILE__).’/*******’);

無事にこれで動いたのだが、なぜWindows上では大丈夫だったのだろうか。OSも違うし、PHPのバージョンも違うし、原因を探るのはめんどくさいのでやらないけれど。

cakePHPではpearのファイルをvenderディレクトリに設置して使っているが、別にvenderディレクトリにパスを通しているわけではない。そういう意味では、cakePHPでpearを使う場合、使いようによってはpear内部のファイルで多少修正が必要になりそうだ。いちおうメモメモ。

Admin Routingの認証

2007/07/22 | cakePHP

cakePHPは管理者用の機能のことも考えられている。それが「Admin Routing」。
この機能を使うと、閲覧者用のコントローラ内に管理者用の機能を記述することが出来る。単にそれだけだと何のことはないが、コントローラでの記述を正しくおこなうと、URLも自動で「admin」とついたそれらしいものになる(もちろんadminではなくsuperuserやroot等といったURLにすることも出来る)。

コントローラ内のfunction名は「admin_index()」といった具合に「admin_」をつけてやる。「index()」にアクセスするには、

http://hogehoge.com/controller/index

だが、「admin_index()」の場合は、

http://hogehoge.com/admin/controller/index

といった具合。app/config/core.php内の設定で、

define(‘CAKE_ADMIN’, ‘admin’);

上記の記述を、

define(‘CAKE_ADMIN’, ‘superuser’);

等に書き換えるとURLは

http://hogehoge.com/superuser/controller/index

になる(らしい)。同じコントローラ内に処理を書いておけるというのはとてもわかりやすくて好感が持てる。

ただし、これは単にroutingしてやるだけで、認証処理も同時に追加できるわけではなく、「自分で実装してくれ」とマニュアルに書いてある。これ、どうすればいいんだろう、と悩んでたら1×1さんのサイトで書かれていたことを応用すれば出来そう(shinさんお元気ですか?、一度カンファレンスでお会いさせていただきました!)。

1×1さんのサイトでは、管理者用のレイアウトをはめ込む際に、コントローラ内のbeforeRender()で、以下のスクリプトを追加する方法を紹介されている。

function beforeRender() {
  if(defined(‘CAKE_ADMIN’) && !empty($this->params[‘admin’])){
    $this->layout = ‘admin';
  }
}

これを応用して、beforeFilter()でチェックと認証をすればできそうな感じ(そんな関数あったよね、たしか)。

function beforeFilter() {
  if(defined(‘CAKE_ADMIN’) && !empty($this->params[‘admin’])){
    (認証処理)
  }
}

まだ現時点では未検証。近々実装するのでレポートもその際に。

アソシエーション先のテーブルデータの取得で

2007/07/21 | cakePHP

cakePHPのすごいところは、SQLを書かなくてもテーブルからデータを持ってくるところだけど、もっとすごいのは設定さえ書いておけば、リレーション先のテーブルからもデータを持ってきてしまうところ。ここ数日cakePHPをつってCMSを作っているけど、SQLをまったく書かなくていい、というのもすごい話だ。

リレーション先のデータを取得するための設定はcakePHPではアソシエーションというが、これをモデルで設定することは前に書いた。モデル(クラス)内で、

var $hasMany=array();

と記述するのだが・・・、この記述、PHPの約束事で、演算はおこなえないのだ。今回の場合、古いデータは必要ないので当該日以降のデータだけ取得したかった。つまり、アクセスするたびに関数で取得条件が変えたい、というわけだが、演算子が使えないのでモデル内で設定が出来ないのだ。
こんな場合は、コントローラ内で、以下のように記述することで対応できた。

$this->[モデル名]->hasMany[‘関連先モデル名’][‘conditions’]=”条件”;

コントローラ内で、モデルで設定した$hasManyを上書きするのだ。なんとなく「無理やり」の感もあるし、これでいいのかどうかわからないが、うまくデータは取得できている。いい感じ。

慣れると割りと使いやすい、cakePHP。もう少しがんばって、一つサイトを構築してしまおう。

cakePHPでファイルアップロード

2007/07/20 | cakePHP

cakePHPでのCMSネタの続きだが、CMSツールの一つとして、ブラウザからサーバ上のファイル管理(画像とか)機能が必要になる。「ブラウザからファイルをアップロードできて、登録内容を一覧で表示できて、削除とかも出来る」という機能が必要になるわけだが、調べてみてcakePHP用のコンポーネントを公開していらっしゃる方がいた。

http://www.reversefolds.com/

メニューのinfoからFileHandlerを選択。ここで提供されるコンポーネントを使用すれば、簡単にファイルのアップロードが可能になる(一覧表示や削除は自前で実装する)。
ただしこのコンポーネントで使用するテーブルのカラム名が少し気に入らない。file_name、mime_type、file_size、extra_fieldというような、アンダーバー入りのカラム名がやだ。ということで、これをname、mimetype、size、extraと名前を変えることにした。

当然カラム名を変えるだけではダメで、スクリプト側での修正も必要だ。修正した箇所はコンポーネントfile_handler.phpの以下の部分。

・64行目付近($_dbFieldsの記述)
 ここのキーの部分をカラム名にあわせて変更
・392行目付近($this->_dbFieldsの記述)
 ここのキーの部分をカラム名にあわせて変更

これで大丈夫っぽい(サンプルのコントローラでも一部記述の修正が必要)。
このコンポーネント、ちゃんとモデル、コントローラ、ビューのサンプルコードも用意されているので、非常にわかりやすい!。
アップロードのアクション(add)はこれで出来たわけだから、あとはbakeして、Pager組み込めば、画像管理機能の出来上がりだ。

ん〜、ナイスコンポーネント。

cakePHPでページング(Pear_Pager)

2007/07/19 | cakePHP

久しぶりにcakePHPで遊んでいる(もちろん仕事だが)。
「とある業態のウェブサイトでは、必要とされる機能が決まりきっているから、機能を一式作って格安にすれば絶対売れる」とそそのかされたから。mojaviで構築しようか迷ったが、PHP4と5両対応にしたいのでcakePHPにした。
基本機能はなんといってもbake.php!。いやぁ、もうbakeサマ様さま。基本部分をbakeしてしまえば、なんとまぁ早いこと!。入力操作は基本的にウェブサイト管理者しかやらないので、確認画面もなしにした(JavaScriptのアラートくらいは出すかもしれない)。
今回ページング処理を入れたのだが、decorate.phpを使用しなかったのはコードが煩雑になりすぎるから。decorateするとindex()の行数が300行近くになり、これはもう見にくい!。検索機能もとりあえずいらないのでbake.php+Pagerでいくことにした。
これがまぁ簡単。以下が出来上がったスクリプト。

function index($page=null) {
  $perPage=20;
  
  if(!is_numeric($page)){$page=1;}
  $pagerParam=array();
  $pagerParam[‘totalItems’]=$this->[モデル名]->findCount();
  $pagerParam[‘perPage’]=$perPage;
  $pagerParam[‘delta’]=5;
  $pagerParam[‘mode’]=’sliding';
  $pagerParam[‘currentPage’]=$page;
  $pagerParam[‘append’]=false;
  $pagerParam[‘path’]=FULL_BASE_URL . strip_plugin($this->base, $this->plugin) . ‘/[コントローラー名]/index/';
  $pagerParam[‘fileName’]=”%d”;
  $pager=Pager::factory($pagerParam);
  $thisPage=$pager->getCurrentPageID();
  $linkTags=$pager->getLinks();
  $this->set(‘paging’, $linkTags[‘all’]);
  
  $this->[モデル名]->recursive = 0;
  $this->set(‘data’, $this->[モデル名]->findAll(”,”,’id DESC’,$perPage,$thisPage));
}

要点はこんな感じ。
・$pageでページ番号を受け取る。
・findCount()で総レコード数を取得。
・pagerに与えるパラメータでpathとfileNameを与える。
・pathの呼び出し方。

このコード、cakePHPやる人には絶対おすすめ(自画自賛だけどそのくらいスマート!)。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net