CodeIgniter4のシステムメッセージを日本語にする

この記事は CodeIgniter Advent Calendar 2020 - Qiita の5日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

CodeIgniter4のシステムメッセージはデフォルトでは英語なので、日本語に変更します。

デフォルトのシステムメッセージ

例えば、バリデーションエラーは以下のように英語で表示されます。

codeigniter4/translations のインストール

CodeIgniter4 は Composer でインストールしたことを前提とします。

システムメッセージの翻訳は公式の Composer パッケージがありますので、それをインストールします。

CodeIgniter プロジェクトのルートフォルダで、以下のコマンドを実行します。

$ composer require codeigniter4/translations:dev-develop

注意:現在の codeigniter4/translations のリリースバージョン 4.0.2 にはまだ日本語が含まれていませんので develop ブランチをインストールしました。

defaultLocale の設定

設定ファイル app/Config/App.php を開き、$defaultLocaleja に変更します。

--- a/app/Config/App.php
+++ b/app/Config/App.php
@@ -63,7 +63,7 @@ class App extends BaseConfig
        | should run under for this request.
        |
        */
-       public $defaultLocale = 'en';
+       public $defaultLocale = 'ja';

        /*
        |--------------------------------------------------------------------------

これで、システムメッセージが日本語になりました。

少し日本語訳が変ですね。

(2021-02-23 追記) 日本語訳は修正しました。

参考

Tags: codeigniter, codeigniter4

CodeIgniter4の公式チュートリアルをやってみる (3)

(2021-12-05 追記) この記事は古くなっています。 「CodeIgniter4入門 公式チュートリアル (1)静的ページの表示」 を参照してください。

この記事は CodeIgniter Advent Calendar 2020 - Qiita の4日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

CodeIgniter 4 の公式ドキュメントにあるチュートリアルを続けます。

CodeIgniter4の公式チュートリアルをやってみる (2) の続きです。

データベースへの書き込みを実装します。

Form の作成

記事を書き込むためのビューファイル app/Views/news/create.php を作成します。

<h2><?= esc($title); ?></h2>

<?= \Config\Services::validation()->listErrors(); ?>

<form action="/news/create" method="post">
    <?= csrf_field() ?>

    <label for="title">Title</label>
    <input type="input" name="title" /><br />

    <label for="body">Text</label>
    <textarea name="body"></textarea><br />

    <input type="submit" name="submit" value="Create news item" />
</form>

\Config\Services クラスは CodeIgniter4 のサービスロケータです。 CodeIgniter4 では、フレームワークのクラスはサービスとして、サービスロケータから取得できます。

\Config\Services::validation() メソッドは、CodeIgniter4 の Validation クラスを返します。

Form を受け取るためのコントローラメソッドの追加

News コントローラに Form を受け取るための create() メソッドを追加します。

--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -40,4 +40,30 @@ class News extends Controller
         echo view('news/view', $data);
         echo view('templates/footer', $data);
     }
+
+    public function create()
+    {
+        $model = new NewsModel();
+
+        if ($this->request->getMethod() === 'post' && $this->validate([
+                'title' => 'required|min_length[3]|max_length[255]',
+                'body'  => 'required',
+            ]))
+        {
+            $model->save([
+                 'title' => $this->request->getPost('title'),
+                 'slug'  => url_title($this->request->getPost('title'), '-', TRUE),
+                 'body'  => $this->request->getPost('body'),
+            ]);
+
+            echo view('news/success');
+
+        }
+        else
+        {
+            echo view('templates/header', ['title' => 'Create a news item']);
+            echo view('news/create');
+            echo view('templates/footer');
+        }
+    }
 }

コントローラの $this->validate() メソッドは、リクエストのデータを検証するための便利なメソッドです。

Model クラスの save() メソッドは、データを挿入または更新するメソッドです。今回は、プライマリキーの指定がないため全て挿入処理になります。

書き込み成功時のビューの追加

書き込みが成功した旨のメッセージを表示するための app/Views/news/success.php を追加します。

News item created successfully.

NewsModel の変更

NewsModel がデータを保存できるように、$allowedFields プロパティに変更可能なカラムを設定します。

--- a/app/Models/NewsModel.php
+++ b/app/Models/NewsModel.php
@@ -7,6 +7,8 @@ class NewsModel extends Model
 {
     protected $table = 'news';

+    protected $allowedFields = ['title', 'slug', 'body'];
+
     public function getNews($slug = false)
     {
         if ($slug === false)

ルーティングの追加

News コントローラの create() メソッドへのルーティングを追加します。

--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -32,6 +32,7 @@ $routes->setAutoRoute(true);
 // route since we don't have to scan directories.
 $routes->get('/', 'Home::index');

+$routes->match(['get', 'post'], 'news/create', 'News::create');
 $routes->get('news/(:segment)', 'News::view/$1');
 $routes->get('news', 'News::index');
 $routes->get('(:any)', 'Pages::view/$1');

news/create に GET または POST でアクセスされた場合に、News::create() メソッドを呼び出します。

記事の追加

では、http://localhost:8080/news/create にアクセスしてみましょう。

記事を入力して、「Create news item」ボタンを押します。

書き込みに成功しました。

プロファイラでデータベースクエリを確認してみます。

一覧を表示してみます。

一番下に追加した記事が表示されています。

以上で公式チュートリアルの内容は完了しました。データベースからの読み込みと書き込み処理までが含まれています。

News コントローラと NewsModel

コントローラとモデルのコードは以下のようになっています。

app/Controllers/News.php

<?php
namespace App\Controllers;

use App\Models\NewsModel;
use CodeIgniter\Controller;
use CodeIgniter\Exceptions\PageNotFoundException;

class News extends Controller
{
    public function index()
    {
        $model = new NewsModel();

        $data = [
            'news'  => $model->getNews(),
            'title' => 'News archive',
        ];
//        dd($data);

        echo view('templates/header', $data);
        echo view('news/overview', $data);
        echo view('templates/footer', $data);
    }

    public function view($slug = null)
    {
        $model = new NewsModel();

        $data['news'] = $model->getNews($slug);

        if (empty($data['news']))
        {
            throw new PageNotFoundException('Cannot find the news item: '. $slug);
        }

        $data['title'] = $data['news']['title'];
//        dd($data);

        echo view('templates/header', $data);
        echo view('news/view', $data);
        echo view('templates/footer', $data);
    }

    public function create()
    {
        $model = new NewsModel();

        if ($this->request->getMethod() === 'post' && $this->validate([
                'title' => 'required|min_length[3]|max_length[255]',
                'body'  => 'required',
            ]))
        {
            $model->save([
                 'title' => $this->request->getPost('title'),
                 'slug'  => url_title($this->request->getPost('title'), '-', TRUE),
                 'body'  => $this->request->getPost('body'),
            ]);

            echo view('news/success');

        }
        else
        {
            echo view('templates/header', ['title' => 'Create a news item']);
            echo view('news/create');
            echo view('templates/footer');
        }
    }
}

app/Models/NewsModel.php

<?php
namespace App\Models;

use CodeIgniter\Model;

class NewsModel extends Model
{
    protected $table = 'news';

    protected $allowedFields = ['title', 'slug', 'body'];

    public function getNews($slug = false)
    {
        if ($slug === false)
        {
            return $this->findAll();
        }

        return $this->asArray()
            ->where(['slug' => $slug])
            ->first();
    }
}

CodeIgniter3 と比べて、変わった?あまり変わらない?どうでしょうか?

このチュートリアルは CodeIgniter3 のチュートリアルとほぼ同一なのですが、実は XSS 対策が追加されています。

この記事は CodeIgniter Advent Calendar 2020 - Qiita の4日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

参考

Tags: codeigniter, codeigniter4, database

CodeIgniter4の公式チュートリアルをやってみる (2)

(2021-12-05 追記) この記事は古くなっています。 「CodeIgniter4入門 公式チュートリアル (1)静的ページの表示」 を参照してください。

この記事は CodeIgniter Advent Calendar 2020 - Qiita の3日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

CodeIgniter 4 の公式ドキュメントにあるチュートリアルを続けます。

CodeIgniter4の公式チュートリアルをやってみる (1) の続きです。

データベースを使います。

MySQLでのデータベースの準備

チュートリアル用のデータベースとユーザを作成します。

$ mysql -uroot -p

データベース ci4tutorial を作成します。

CREATE DATABASE ci4tutorial DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

ユーザ dbuser を作成します。

GRANT ALL PRIVILEGES ON ci4tutorial.* TO dbuser@localhost IDENTIFIED BY 'dbpassword';

テーブルを作成します。作成したユーザで MySQL にログインします。

$ mysql -u dbuser -p ci4tutorial
Enter password: 

news テーブルを作成します。

CREATE TABLE news (
    id int(11) NOT NULL AUTO_INCREMENT,
    title varchar(128) NOT NULL,
    slug varchar(128) NOT NULL,
    body text NOT NULL,
    PRIMARY KEY (id),
    KEY slug (slug)
);

初期データを挿入します。

INSERT INTO news VALUES
(1,'Elvis sighted','elvis-sighted','Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.'),
(2,'Say it isn\'t so!','say-it-isnt-so','Scientists conclude that some programmers have a sense of humor.'),
(3,'Caffeination, Yes!','caffeination-yes','World\'s largest coffee shop open onsite nested coffee shop for staff only.');

確認します。

mysql> select * from news \G
*************************** 1. row ***************************
   id: 1
title: Elvis sighted
 slug: elvis-sighted
 body: Elvis was sighted at the Podunk internet cafe. It looked like he was writing a CodeIgniter app.
*************************** 2. row ***************************
   id: 2
title: Say it isn't so!
 slug: say-it-isnt-so
 body: Scientists conclude that some programmers have a sense of humor.
*************************** 3. row ***************************
   id: 3
title: Caffeination, Yes!
 slug: caffeination-yes
 body: World's largest coffee shop open onsite nested coffee shop for staff only.
3 rows in set (0.00 sec)

CodeIgniter4 のデータベース設定

.env ファイルにデータベース接続情報を設定します。

--- env 2020-07-16 12:44:28.000000000 +0900
+++ .env    2020-12-02 10:08:24.000000000 +0900
@@ -49,11 +49,11 @@
 # DATABASE
 #--------------------------------------------------------------------

-# database.default.hostname = localhost
-# database.default.database = ci4
-# database.default.username = root
-# database.default.password = root
-# database.default.DBDriver = MySQLi
+database.default.hostname = localhost
+database.default.database = ci4tutorial
+database.default.username = dbuser
+database.default.password = dbpassword
+database.default.DBDriver = MySQLi

 # database.tests.hostname = localhost
 # database.tests.database = ci4

NewsModel の作成

news テーブルにアクセスする NewsModel を作成します。

app/Models/NewsModel.php

<?php
namespace App\Models;

use CodeIgniter\Model;

class NewsModel extends Model
{
    protected $table = 'news';

    public function getNews($slug = false)
    {
        if ($slug === false)
        {
            return $this->findAll();
        }

        return $this->asArray()
            ->where(['slug' => $slug])
            ->first();
    }
}

CodeIgniter\ModelfindAll() メソッドと first() メソッドを使い、news テーブルを検索します。

News コントローラの作成

News コントローラを作成します。

app/Controllers/News.php

<?php
namespace App\Controllers;

use App\Models\NewsModel;
use CodeIgniter\Controller;
use CodeIgniter\Exceptions\PageNotFoundException;

class News extends Controller
{
    public function index()
    {
        $model = new NewsModel();

        $data = [
            'news'  => $model->getNews(),
            'title' => 'News archive',
        ];
        dd($data);

        echo view('templates/header', $data);
        echo view('news/overview', $data);
        echo view('templates/footer', $data);
    }

    public function view($slug = null)
    {
        $model = new NewsModel();

        $data['news'] = $model->getNews($slug);

        if (empty($data['news']))
        {
            throw new PageNotFoundException('Cannot find the news item: '. $slug);
        }

        $data['title'] = $data['news']['title'];
        dd($data);

        echo view('templates/header', $data);
        echo view('news/view', $data);
        echo view('templates/footer', $data);
    }
}

CodeIgniter4 の dd() 関数で $data の値を表示して確認できるようにしました。

ルーティング設定

前回、全てのルートを Pages コントローラで処理するように、ルーティング設定をしたため、現状だと News コントローラにアクセスできません。

そこで、News コントローラにアクセスするためのルーティングを追加します。

app/Config/Routes.php

--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -32,6 +32,8 @@ $routes->setAutoRoute(true);
 // route since we don't have to scan directories.
 $routes->get('/', 'Home::index');

+$routes->get('news/(:segment)', 'News::view/$1');
+$routes->get('news', 'News::index');
 $routes->get('(:any)', 'Pages::view/$1');

 /**

http://localhost:8080/news にアクセスすると、CodeIgniter4 の dd() メソッドで $data の値が表示されます。

データベースに登録したレコードの値が取得できていることがわかります。

データベースとのやりとりを確認できたら、デバッグ用の dd() 関数を無効にしておきます。

--- a/app/Controllers/News.php
+++ b/app/Controllers/News.php
@@ -15,7 +15,7 @@ class News extends Controller
             'news'  => $model->getNews(),
             'title' => 'News archive',
         ];
-        dd($data);
+//        dd($data);

         echo view('templates/header', $data);
         echo view('news/overview', $data);
@@ -34,7 +34,7 @@ class News extends Controller
         }

         $data['title'] = $data['news']['title'];
-        dd($data);
+//        dd($data);

         echo view('templates/header', $data);
         echo view('news/view', $data);

View ファイルの作成

一覧ページ用の app/Views/news/overview.php を追加します。

<h2><?= esc($title); ?></h2>

<?php if (! empty($news) && is_array($news)) : ?>

    <?php foreach ($news as $news_item): ?>

        <h3><?= esc($news_item['title']); ?></h3>

        <div class="main">
            <?= esc($news_item['body']); ?>
        </div>
        <p><a href="/news/<?= esc($news_item['slug'], 'url'); ?>">View article</a></p>

    <?php endforeach; ?>

<?php else : ?>

    <h3>No News</h3>

    <p>Unable to find any news for you.</p>

<?php endif ?>

個別記事ページ用の app/Views/news/view.php を追加します。

<h2><?= esc($news['title']); ?></h2>
<p><?= esc($news['body']); ?></p>

これで、ビューファイルが全て用意できました。

http://localhost:8080/news にアクセスしてみます。

記事の一覧が表示されました。

「View article」をクリックして、http://localhost:8080/news/elvis-sighted にアクセスします。

個別の記事も表示されています。

CodeIgniter4の公式チュートリアルをやってみる (3) へ続きます。

この記事は CodeIgniter Advent Calendar 2020 - Qiita の3日目です。まだ、空きがありますので、興味のある方は気軽に参加してください。

参考

Tags: codeigniter, codeigniter4, database