CakePHPでBlogを作る
某社の課題でBlogを作る。
基本設計編
次にデータベースの選択
・Mysql(ローカルにインストール済)
・PostgreSQL(ローカルに未インストール)
・Sqlite(環境が変わってもファイルなんで手軽)
ローカル環境なので何も考えずにMysqlで作ることにした。
ローカル環境編
ホストの設定
hostsファイルにローカルアクセスできるように以下を記述する。
sudo vi /etc/hosts 127.0.0.1 blog.localhost
Apacheの設定
バーチャルホストの設定する。
sudo vi /opt/local/apache2/conf/extra/httpd-vhosts.conf <VirtualHost *:80> DocumentRoot "/Users/kazuya/home/blog/app/webroot/" ServerName blog.localhost </VirtualHost>
サーバー再起動
sudo apachectl restart
データベース作成
本当ならユーザーも作成すべきだけどローカル環境なのでrootで全てやっちゃう。
mysql -u root -p # (パスワード入力) mysql > CREATE DATABASE `blog` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CakePHPのインストール
http://cakephp.jp/ より最新版をゲットして/Users/kazuya/home/blogに設置する。
CakePHPの設定
データベースアクセスの設定
app/Config/databese.phpを作成する。
ファイル内容はこんな感じ。(パスワードとユーザー名は適宜変えてね)
またMacportsでインストールしたMysqlだとソケットを指定しないと動かないので注意する。
public $default = array( 'datasource' => 'Database/Mysql', 'persistent' => false, 'host' => 'localhost', 'login' => 'root', 'password' => 'XXXXXXXXX', 'database' => 'blog', 'prefix' => '', 'encoding' => 'utf8', 'unix_socket' => '/opt/local/var/run/mysql5/mysqld.sock' );
書き込みの権限を付与
キャッシュとかセッションを保存する一時フォルダーに書き込み権限をつける。
chmod -Rf 0777 app/tmp
http://blog.localhost/ にアクセスして問題なく動作していることを確認。
アプリケーション設計
データベース設計
データベースはERMasterで作った。
Blogで最低限記事とタグ付けが出来ればいいとの課題なので、
記事とタグと関連付けテーブル。あと認証を使いたいのでユーザーテーブルを作成する。
ER図はこんな感じ。
ERMasterでSQLをエクスポートしてコマンドラインからテーブルを作成する。
> mysql -u root -p blog < blog.sql
Bakeでモデル、コントローラー、ビューを作成する
CakePHPにはBakeっていうインタラクティブなコマンドラインツールがあるんだけど、
2.2で久しぶりに使ってみたらかなり使えるツールになってた。
php -f ./app/Console/cake.php bake --------------------------------------------------------------- Interactive Bake Shell --------------------------------------------------------------- [D]atabase Configuration [M]odel [V]iew [C]ontroller [P]roject [F]ixture [T]est case [Q]uit What would you like to Bake? (D/M/V/C/P/F/T/Q)
と表示されるのでMを選択してModelを作成する。
Use Database Config: (default/test) [default] > Possible Models based on your current database: 1. ArticleTag 2. Article 3. Tag 4. User
と4テーブル分のモデルをチュートリアルに従って作成する。
バリデーターとかも事細かにそれぞれのフィールドごとに指定できる。
ここで大切なのは
ArticleとTagはArticleTagにhasAndBelongsToManyであり、
ArticleTagはArticleとTagにbelongsToしていると関連付けしておく。
ControllerとViewも同様にして作成する。
アプリケーション実装
ルーティング処理
articlesのindexがblog.localhostにアクセスした際にデフォルトの表示になるように
app/Config/routes.phpに以下を記述する。
Router::connect('/', array('controller' => 'articles', 'action' => 'index'));
またコントローラーのadmin_の関数を有効化する為に
app/Config/core.phpに以下を記述
Configure::write('Routing.prefixes', array('admin'));
ページング処理
ArticlesControllerにページング処理の設定。
記事の公開日時順に並び替えたいのとデフォルトで5件表示に変更。
クラス変数に以下を追記
public $paginate = array( 'Article' => array( 'maxLimit' => 5, 'order' => array('published' => 'desc'), ));
あとはタグIDが指定されている場合にそのタグの記事だけが表示されるように、
ArticlesControllerのページング処理に絞込みの条件を指定。
function index ()内に以下を追記した。
if(isset($this->params['named']['tag'])){ $cond = "ArticleTag.tag_id = {$this->params['named']['tag']} and "; $this->paginate['Article']['joins'] = array(array('type' => 'LEFT', 'alias' => 'ArticleTag', 'table' => 'article_tags','conditions' => 'Article.id = ArticleTag.article_id')); }
ログイン処理
LoginControllerとAppControllerにadminのログイン処理を記述。
今回はAuthコンポーネントを使って処理する。
AppControllerにコンポーネントの有効化を記述することにより、
基本すべてのコントローラーがAppControllerを継承しているので全てに反映される。
クラス変数に以下を追記
public $components = array( 'Session', 'Auth' => array( 'loginRedirect' => Array('controller' => 'admin', 'action' => 'articles'), 'logoutRedirect' => Array('controller' => 'login', 'action' => 'index'), 'loginAction' => Array('controller' => 'login', 'action' => 'index')), );
ただ、Blogのトップと記事詳細はログインしてなくてもアクセスできるように、
AppControllerのbeforeFilterに以下を記述。
function beforeFilter() { $this->Auth->authError = __('Login Error'); $this->Auth->allow('article','index'); $this->Auth->allow('article','view'); }
日本語化対応
デフォルトでエラーメッセージやデータベースのカラムとかは全て英語表示。
一応日本語化しておく。
コマンドで全ファイル内の文字出力関数__()内の翻訳ファイルを作る。
php -f ./app/Console/cake.php i18n
これでapp/Locale/以下にdefault.potファイルが出来る。
mkdir -R app/Locale/jpn/LC_MESSAGES/ cp app/Locale/default.pot app/Locale/jpn/LC_MESSAGES/default.po
日本語の翻訳メッセージを入力しておく。
デフォルトで英語環境で使っているので日本語のFirefoxをインストールして確認した。
こんな感じで最低限ひと通りの機能は完成。