CakePHPサイト引っ越しの際の注意点。
CakePHPで作成したサイトのサーバ引っ越しは比較的簡単に行えます。
基本的にはファイル一式とデータベースを新サーバにコピーして、データベース情報を「app/Config/database.php」にて、新しい情報に書き換えます。
上記の作業のみでおおむね引っ越しは完了ですが、注意点としては「app/tmp/~」内のキャッシュファイルなどが影響して表示がおかしくなる場合があるので、このディレクトリ内の不要ファイルを削除しておいた方が安心です。
CakePHPで作成したサイトのサーバ引っ越しは比較的簡単に行えます。
基本的にはファイル一式とデータベースを新サーバにコピーして、データベース情報を「app/Config/database.php」にて、新しい情報に書き換えます。
上記の作業のみでおおむね引っ越しは完了ですが、注意点としては「app/tmp/~」内のキャッシュファイルなどが影響して表示がおかしくなる場合があるので、このディレクトリ内の不要ファイルを削除しておいた方が安心です。
PHPではPEARなどのライブラリを利用すると簡単にカレンダーを作成できますが、CakePHPなどフレームワークをベースに開発している場合、あまり他のライブラリを利用したくないこともあります。
また祝日情報を含むイベント情報を簡単に組み込めるカレンダーとして、シンプルなカレンダーを作成してみました。
サンプルはこちら
機能としては指定月のカレンダーを生成し、イベント情報を配列として渡すことで、該当日にイベント内容を表示することができます。
祝日情報の取得の関数「getHolidays()」については、「Googleカレンダーから祝日情報を取得。」をご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
<?php //カレンダーと祝日情報の生成用に年月日の変数を作成 $year = date('Y'); $month = date('n'); $day = 1; //祝日情報の配列(「label」はクラス名として利用します) $holidays = getHolidays($year); $holidays['label'] = 'holiday'; //テストイベント情報の配列 $tests = array('label' => 'test', date('Ymd') => '本日です(イベントのテスト)'); //祝日情報とテストイベント情報を連想配列にまとめます $events = array($holidays, $tests); //カレンダーの出力 echo getCalendar($year, $month, $day, $events); //指定月のカレンダーを生成 function getCalendar($year, $month, $day, $events) { //ヘッダー部分の曜日表示 $days = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); //本日を取得(20120512) $today = date('Ymd'); //1行ごとの順番(1〜7)と、月全体の順番(1〜31(最大)) $num_row = 1; $num_day = 1; //月の始まる曜日から、前月の空白分を取得 $num_blank = date('w', mktime(0, 0, 0, $month, 1, $year)); //月の合計日 $total = $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31); //カレンダーのヘッダー部分 $calendar = '<table class="calendar">'; $calendar .= '<thead><tr>'; while ($num_row <= count($days)) { $calendar .= '<th>'.$days[$num_row-1].'</th>'; $num_row++; } $calendar .= '</tr></thead>'; //カレンダーの本体部分 $calendar .= '<tbody><tr>'; $num_row = 1; //前月の空白分のセルを生成 while ($num_blank > 0) { $label = ''; $label = ($num_row == 1) ? $label.' sun' : $label; $calendar .= '<td class="'.$label.'"></td>'; $num_blank--; $num_row++; } //1日〜31日(最大)までのセルを生成 while ($num_day <= $total) { //「$label」は要素のクラス名として、「$content」は祝日などのイベント内容 $label = ''; $content = ''; //イベントの配列を走査するためのキーとして、「20120512」の形式で文字列を生成 $key = $year.sprintf('%02d', $month).sprintf('%02d', $num_day); //左端なら日曜日、右端なら土曜日のためのラベル(クラス)を付加 $label = ($num_row == 1) ? $label.' sun' : $label; $label = ($num_row == 7) ? $label.' sat' : $label; //本日の場合もクラスを付加 $label = ($key == $today) ? $label.' today' : $label; //イベントの配列があれば、配列を走査 if (isset($events)) { //連想配列になっているイベントの配列($event)の中の、各イベント配列ごとに処理 for ($i = 0; $i < count($events); $i++) { $label_event = (isset($events[$i]['label'])) ? $events[$i]['label'] : ''; //イベントの配列に一致するキー(20120512など)があれば、要素を付加 if (array_key_exists($key, $events[$i])) { $label .= ' '.$label_event; $content .= '<div class="'.$label_event.'">'.$events[$i][$key].'</div>'; } } } $calendar .= '<td class="'.$label.'">'; $calendar .= '<div class="day">'.$num_day.'</div>'; $calendar .= $content; $calendar .= '</td>'; $num_day++; $num_row++; //1行の終わり(7日目)ごとに、新しい行を開始 if ($num_row > 7) { $calendar .= '</tr><tr>'; $num_row = 1; } } //月の最終日以降の空白分のセルを生成 while ($num_row > 1 && $num_row <= 7) { $label = ''; $label = ($num_row == 7) ? $label.' sat' : $label; $calendar .= '<td class="'.$label.'"></td>'; $num_row++; } //カレンダーの終了 $calendar .= '</tr></tbody></table>'; //文字列として生成したカレンダーを返す return $calendar; } ?> |
CakePHPで利用する場合には、コンポーネントとして登録しておくと使い勝手が良いかもしれません。
CakePHPでファイルをアップロードするための基本機能のみフォームのサンプルです。使用しているCakePHPのバージョンは2.1.2です。
データベースには「uploads」というテーブルを作り、ファイル名を保存するために「file_name」のカラムを設けています。
1 2 3 4 5 6 |
CREATE TABLE uploads ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, file_name VARCHAR(50), created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL ); |
コントローラーの「UploadsController.php」には、アップロードされたファイル名の一覧のための「index」と、ファイルをアップロードするための「add」アクションを作ります。
(bakeで焼いたものをもとに、手を加えて作成してあります)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php App::uses('AppController', 'Controller'); /** * Uploads Controller * * @property Upload $Upload */ class UploadsController extends AppController { public function index() { $this->Upload->recursive = 0; $this->set('uploads', $this->paginate()); } public function add() { if ($this->request->is('post')) { $tmp = $this->request->data['Upload']['file']['tmp_name']; if(is_uploaded_file($tmp)) { $file_name = basename($this->request->data['Upload']['file']['name']); $file = WWW_ROOT.'files'.DS.$file_name; if (move_uploaded_file($tmp, $file)) { $this->Upload->create(); $this->request->data['Upload']['file_name'] = $file_name; if ($this->Upload->save($this->request->data)) { $this->Session->setFlash(__('The upload has been saved')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('The upload could not be saved. Please, try again.')); } } } } } } |
ファイルのアップロード処理自体はCakePHP特有のものではなく、通常のPHPの処理になります。途中の「WWW_ROOT」「DS」はCakePHPで用意されている定数で、詳しくはドキュメントページで確認できます。
ここではアップロードされたファイル名のみ、データベースに登録するようにしています。
ファイル名一覧のためのビュー「index.php」です。これもbakeで書き出されたものを、さらに簡略化しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<div class="uploads index"> <h2><?php echo __('Uploads'); ?></h2> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo __('id'); ?></th> <th><?php echo __('file_name'); ?></th> <th><?php echo __('created'); ?></th> </tr> <?php foreach ($uploads as $upload) : ?> <tr> <td><?php echo h($upload['Upload']['id']); ?></td> <td><?php echo h($upload['Upload']['file_name']); ?></td> <td><?php echo h($upload['Upload']['created']); ?></td> </tr> <?php endforeach; ?> </table> </div><!-- index --> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('New Upload'), array('action' => 'add')); ?></li> </ul> </div><!-- actions --> |
ファイルをアップロードするためのビュー「add.php」では、フォームのタイプをファイル対応にして、アップロードのためのフォームパーツを出力しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<div class="uploads form"> <?php echo $this->Form->create('Upload', array('action' => 'add', 'type' => 'file')); ?> <fieldset> <legend><?php echo __('Add Upload'); ?></legend> <?php echo $this->Form->file('file'); ?> </fieldset> <?php echo $this->Form->end(__('Submit'));?> </div><!-- form --> <div class="actions"> <h3><?php echo __('Actions'); ?></h3> <ul> <li><?php echo $this->Html->link(__('List Uploads'), array('action' => 'index'));?></li> </ul> </div><!-- actions --> |
モデルの「Upload.php」では、今回は特に処理を行っていません。
1 2 3 4 5 6 7 8 |
<?php App::uses('AppModel', 'Model'); /** * Upload Model * */ class Upload extends AppModel { } |
上記以外では、「AppController.php」の中で、「Html」と「Form」ヘルパーを読み込んできます。
1 |
public $helpers = array('Html', 'Form'); |
以上、シンプルなファイルのアップロードフォームの作り方でした。
CakePHP 2.0 RC3でブログのサンプル、ACLを設定した後に、各コントローラーでアクセス権限をViewのテンプレートファイル内(View/Posts/index.ctpなど)でチェックするためのコードメモです。
ブログのサンプル、ACLについてはCakePHPマニュアルページの中にあるチュートリアルを参考に設定してみました。(ACLチュートリアルの説明は難解ですね。かなり苦戦しました・・・。)
CakePHPブログチュートリアル(英語)
ACL を制御するシンプルなアプリケーション(英語)
チュートリアルで作成したブログのコントローラ「PostsController.php」のbeforeFilter()の中に下記のコードを記述することで、閲覧しているユーザーのアクセス権限をチェックし、「create」「read」「update」「delete」の各アクションの権限の有無を配列にして、Viewへ渡すデータにセットするようにしています。
1 2 3 4 5 6 7 8 |
function beforeFilter() { $acl = array(); $action = array('create', 'read', 'update', 'delete'); foreach ($action as $value) { $acl[$value] = $this->Acl->check($this->Auth->user('username'), 'posts', $value); } $this->set('acl', $acl); } |
Viewのテンプレート上では次のように利用できます。
1 2 3 |
if ($acl['create']) { echo $this->Html->link('Add Post', array('action' => 'add')); } |
ユーザーの権限によって、編集や削除のリンクを、表示/非表示にしたい場合などに使えるかなと思います。
他にもっと良い方法があるかもしれませんが・・・。
CakePHPでトップページの表示を変更するには「app/views/pages/home.ctp」を書き換えることで可能です。
この場合レイアウトは、自動的に「app/views/layouts/default.ctp」を利用します。
通常レイアウトの変更には、コントローラーのアクションに「$this->layout = ‘default’;」といった感じで、任意に変更ができるのですが、もともとコントローラーを作成しないトップページの場合では、簡単にレイアウトの変更ができません。
そのための解決方法として、トップページの表示を担うコントローラーをCakePHPコアのライブラリからコピーして、一部修正することにします。
はじめに、コアに含まれるライブラリ「cake/libs/controller/pages_controller.php」を、「app/controllers」にコピーします。
「pages_controller.php」内のdisplayアクションは次のようになっています。(バージョン1.3.8)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function display() { $path = func_get_args(); $count = count($path); if (!$count) { $this->redirect('/'); } $page = $subpage = $title_for_layout = null; if (!empty($path[0])) { $page = $path[0]; } if (!empty($path[1])) { $subpage = $path[1]; } if (!empty($path[$count - 1])) { $title_for_layout = Inflector::humanize($path[$count - 1]); } $this->set(compact('page', 'subpage', 'title_for_layout')); $this->render(implode('/', $path)); } |
このdisplayアクションに、レイアウトを指定する記述を追加することで、トップページ用のレイアウトを変更できます。
1 2 3 4 5 6 7 8 9 10 11 12 |
function display() { $path = func_get_args(); //ここから if ($path[0] == 'home') { $this->layout = 'home'; } //ここまで ... } |
上記の例では、ページのパスが「home(トップページ)」の場合に、「home」レイアウトを利用するようにしています。
後は「app/views/layouts」フォルダに、テンプレート「home.ctp」を作成すればレイアウトの変更が可能になります。