Articleプラグインでは、既存のモデルに対して擬似フィールドを追加して記事を登録します。
今回は記事を登録するためのビヘイビアを作成します。
Articleビヘイビアを作成する
今回作成したファイルはこちら
CakePHP-Article-Plugin/Model/Behavior/ArticleBehavior.php
順を追って解説します。
セットアップ
public function setup(Model $model, $settings = array()) { if (isset($this->settings[$model->alias])) return; $this->settings[$model->alias] = array(); // Set fields if (empty($settings['fields'])) { return; } foreach ($settings['fields'] as $field => $options) { if (!isset($this->settings[$model->alias][$field])) { if (empty($options)) { $options = array(); } $this->settings[$model->alias][$field] = $options; } } // Set runtime App::uses('Model', $this->attacheModel); $this->runtime[$model->alias] =& ClassRegistry::init($this->attacheModel); }
ここではアタッチ元のモデルから渡された$settingsから記事データのフィールド名を取得して、$this->settingに追加しています。
アタッチ元モデルのActsAsでは次のようなパラメータを想定しています。
public $actsAs = array( 'Article.Article' => array( 'fields' => array( 'post' => array( // 将来的にオプションなどを設定 ), ), ), );
$this->setting[$model->alias]にオプションを保存しておくことで、フィールドごとに異なるオプションをセット出来るようにしています。
Set runtimesの箇所では、フィールドごとに記事を格納するモデルオブジェクトを渡しています。
すべて共通のモデルで処理していい場合は$this->runtime[$model->alias]ではなくて$this->runtimeでいいのだと思いますが、フィールドごとに別のテーブルに格納したいケースを想定してこのようにしました。*1
記事の参照や、追加、編集、削除は$this->runtime[$model->alias]で行います。
記事の保存処理
public function afterSave(Model $model, $created) { // setupで設定したフィールドごとに処理 foreach ($this->settings[$model->alias] as $field => $options) { // 擬似フィールドがemptyならループを進める if (empty($model->data[$model->alias][$field])) { continue; } // Whether or not to publish articles // 記事の表示を制御できるように$publishedというパラメータをもたせる // フォームはヘルパーで提供する予定 $published = false; if (!empty($model->data[$model->alias][$field.'_published'])) { $published = true; } // Create the data to be saved article // 保存する記事のデータを作成 $article[$this->attacheModel] = array( 'model' => $model->alias, // アタッチ元のモデル 'model_id' => $model->id, // アタッチ元モデルのid 'model_field' => $field, // 擬似フィールド名 'content' => $model->data[$model->alias][$field], // 記事本文 'published' => $published, // 公開フラグ(まだ使わない) 'posted' => date('Y-m-d H:i:s'), // 投稿日時(もしかしたら削るかも) ); // 保存処理 $this->runtime[$model->alias]->create(); if (!$this->runtime[$model->alias]->save($article)) { return false; } } }
まだこの時点では新規追加にしか対応していません。
あとはここに、更新や削除の機能を追加したり、オプションを追加したりする予定です。
動作をテスト
動作をテストしてみます。
GitHubからソースをプラグインフォルダにクローン(DLして設置でも大丈夫です)してください。
cd /Cakeアプリのパス/Plugin git clone -b master git://github.com/happyquality/CakePHP-Article-Plugin.git Article
ディレクトリ名はArticleにします。
/app/Config/bootstrap.phpでプラグインをロードします。
CakePlugin::loadAll(array( // Articleプラグインを追加 'Article', ));
適当なモデルにActsAsしましょう。
テストするために登録フォームのあるモデルがいいと思います。なければBakeしましょう。
public $actsAs = array( 'Article.Article' => array( 'fields' => array( // 配列のキーが記事を格納する擬似フィールド名になります 'post' => array(), ), ), );
登録フォームに擬似フィールドのinputを追加します。
ここは後々ヘルパーで提供する予定です。
add.ctpなど
省略 <?PHP echo $this->Form->input('post', array('type' => 'textarea')); ?> 省略
アタッチ元モデルの保存処理を行うタイミングで、Articleに記事が追加されるはずです。
あとがき
まだ色々追加しなければならない処理はありますが、擬似フィールドに入力した記事をArticleに追加することができました。意外と簡単でしたね。
長くなってしまったので、編集や削除の処理は次回にします。
- あんまり無さそうだけど、参考にさせていただいたFileBinderビヘイビアに習ってそうしてみました [↩]