ブログチュートリアル Part.1
CakePHP4のブログチュートリアルを進める。 book.cakephp.org
インストール
Composerでローカルにインストールする。
composer self-update && composer create-project --prefer-dist cakephp/app:4.* blog
初期設定
chown -R www-data tmp chown -R www-data logs
データベースの設定を行う。今回はSQLiteを使用する。 Aritclesテーブルを作成するために下記SQLを実行。
sqlite> CREATE TABLE articles ( ...> id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, ...> title VARCHAR(50), ...> body TEXT, ...> created DATETIME DEFAULT NULL, ...> modified DATETIME DEFAULT NULL ...> ); sqlite> sqlite> ;
config/app.php にデータベースの設定を追加する。
<?php 'Datasources' => [ 'default' => [ 'driver' => Sqlite::class, 'database' => ROOT . DS . 'db', ], ]
Article モデルの作成
モデルクラスを作成します。 モデルクラスは、データベースと直接やりとりを行う場所で、基本的なCRUD操作の役割を担います。
下記コマンドでArticlesTable モデルを作成する。
bin/cake bake model Articles
Articles コントローラーの作成
コントローラーを作成します。 コントローラーは、処理対象を操作するロジック全てが発生する場所で、モデルクラスに命令を与えるのもコントローラーの役割です。
下記コマンドでArticlesController クラスを作成する。
bin/cake bake controller Articles
Article ビューの作成
ビューを作成します。 ビューは、クライアントへ表示する画面の構成を担います。 コントローラーからセットされたビュー変数で画面をレンダリングします。
下記コマンドでArticle ビューを作成する。
bin/cake bake template all Articles
データのバリデーション
デフォルトのバリデーションロジックを ArticlesTable クラスに実装します。
<?php namespace App\Model\Table; use Cake\ORM\Table; use Cake\Validation\Validator; class ArticlesTable extends Table { public function initialize(array $config): void { $this->addBehavior('Timestamp'); } public function validationDefault(Validator $validator): Validator { $validator ->notEmptyString('title') ->requirePresence('title', 'create') ->notEmptyString('body') ->requirePresence('body', 'create'); return $validator; } }
ルーティング
config/routes.php を修正し、トップ画面にArticlesのindexページを表示するように修正します。
<?php $builder->connect('/', ['controller' => 'Articles', 'action' => 'index']);
ツリーカテゴリーの作成
投稿記事をカテゴリ作成のために Tree behavior を使用します。
Migrations プラグイン
migrations プラグイン をインストールするため、下記コマンドを実行します。
composer require cakephp/migrations:~1.0
articles テーブルを作成するマイグレーションファイルを作成します。 下記コマンドでマイグレーションファイルを生成します。
bin/cake bake migration CreateArticles title:string body:text category_id:integer created modified
次に、categories テーブルのマイグレーションファイルを作成します。 下記コマンドでマイグレーションファイルを生成します。
bin/cake bake migration CreateCategories parent_id:integer lft:integer[10] rght:integer[10] name:string[100] description:string created modified
最後に、マイグレーションコマンドを実行し、データベース内にテーブルを作成します。
bin/cake migrations migrate
テーブルの編集
Articles と Categories テーブルとを結びつけるため、ArticlesTable に下記のようにアソシエーションの設定を追加します。
<?php $this->addBehavior('Timestamp'); // Just add the belongsTo relation with CategoriesTable $this->belongsTo('Categories', [ 'foreignKey' => 'category_id', ]);
Categories のスケルトンコードを作成する
bake コマンドで、Categoriesのコードを作成します。
bin/cake bake model Categories bin/cake bake controller Categories bin/cake bake template Categories
templateのカテゴリのオプションの修正を行います。
<?php echo $this->Form->control('parent_id', [ 'options' => $parentCategories, 'empty' => 'No parent category' ]);
CategoriesController.php のindexアクションを編集して、ツリーでカテゴリーを並べ替えるために moveUp() および moveDown() メソッドを追加する。
<?php class CategoriesController extends AppController { public function index() { $categories = $this->Categories->find() ->order(['lft' => 'ASC']) ->all(); $this->set(compact('categories')); $this->viewBuilder()->setOption('serialize', ['categories']); } public function moveUp($id = null) { $this->request->allowMethod(['post', 'put']); $category = $this->Categories->get($id); if ($this->Categories->moveUp($category)) { $this->Flash->success('The category has been moved Up.'); } else { $this->Flash->error('The category could not be moved up. Please, try again.'); } return $this->redirect($this->referer(['action' => 'index'])); } public function moveDown($id = null) { $this->request->allowMethod(['post', 'put']); $category = $this->Categories->get($id); if ($this->Categories->moveDown($category)) { $this->Flash->success('The category has been moved down.'); } else { $this->Flash->error('The category could not be moved down. Please, try again.'); } return $this->redirect($this->referer(['action' => 'index'])); } }
templates/Categories/index.php を下記のように変更する。
<?php <div class="actions large-2 medium-3 columns"> <h3><?= __('Actions') ?></h3> <ul class="side-nav"> <li><?= $this->Html->link(__('New Category'), ['action' => 'add']) ?></li> </ul> </div> <div class="categories index large-10 medium-9 columns"> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th>Id</th> <th>Parent Id</th> <th>Lft</th> <th>Rght</th> <th>Name</th> <th>Description</th> <th>Created</th> <th class="actions"><?= __('Actions') ?></th> </tr> </thead> <tbody> <?php foreach ($categories as $category): ?> <tr> <td><?= $category->id ?></td> <td><?= $category->parent_id ?></td> <td><?= $category->lft ?></td> <td><?= $category->rght ?></td> <td><?= h($category->name) ?></td> <td><?= h($category->description) ?></td> <td><?= h($category->created) ?></td> <td class="actions"> <?= $this->Html->link(__('View'), ['action' => 'view', $category->id]) ?> <?= $this->Html->link(__('Edit'), ['action' => 'edit', $category->id]) ?> <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $category->id], ['confirm' => __('Are you sure you want to delete # {0}?', $category->id)]) ?> <?= $this->Form->postLink(__('Move down'), ['action' => 'moveDown', $category->id], ['confirm' => __('Are you sure you want to move down # {0}?', $category->id)]) ?> <?= $this->Form->postLink(__('Move up'), ['action' => 'moveUp', $category->id], ['confirm' => __('Are you sure you want to move up # {0}?', $category->id)]) ?> </td> </tr> <?php endforeach; ?> </tbody> </table> </div>
こちらで、/yoursite/categories/add へアクセスすることで、カテゴリー一覧に遷移することでできる。