期末課題でチャレンジすると面白そうなことを掲載しておく。
参考:
【CakePHP入門】スタイルシート(CSS)を読み込む方法
cakePHP3で、自作したcssファイルを読み込むにはどうしたらいいのでしょうか?
CSSファイルを設置するディレクトリ
webroot\css
CSSを読み込むファイルとコードの場所(ヘッダー部分)
templates\layout\default.php
<?= $this->Html->css('base.css') ?>
<?= $this->Html->css('style.css') ?>
base.cssを独自のCSSファイルに差し替えることで完全に自作のCSSに交換できる。
webroot\css\base.cssを書き換えて部分的に独自のCSSを組み込んでもOK。
※各ビューの上記コードを修正すればビューごとに異なる個別のCSSファイルを読み込ませることが出来る。
※※ブラウザのキャッシュを消去してリロード(Chromeの場合、Shift+リロードボタン)しないとCSSの変更が反映されない
Foundation for Sites by ZURB * Version 5
修正例
カテゴリー選択ボックスの表示範囲の調整してみよう。
CakePHPで生成されたビュー(template)のデザインをCSSで微調整する。
ChromeでCakePHPの画面を表示している場合、
Ctrl + Shift + I で開発者モードに切り替え、
CSSで調整したいエレメントのクラスやIDを調べ、
CakePHPのwebroot フォルダのcssフォルダのcake.css にCSSを記述する。
CSS修正の確認のため、ブラウザのキャッシュを無効にしてリロードする。→ Ctrl+ブラウザのリロードボタンをクリック
作業例)
Google Chrome の 開発者ツールで選択フォーム(select)のCSSのIDを調べている様子
選択ボックスのIDが categories-ids であることが分かる
cake.cssファイルを編集してデザインを修正するIDについて記述を加える
#categories-ids
を選択項目の高さに合わせて調整した例)
CakePHPの 国際化と地域化 機能を利用する。英語版から日本語版に切り替えるための辞書ファイルを作成する。
参考サイト: CakePHP3:メッセージを日本語化する(2021年度から演習ではCakePHP4.0に移行した。記述内容が食い違っている場合がある。要注意。)
vs code でフォルダ作成と設定ファイル編集作業
システムが利用する多言語対応辞書ファイルを配置するフォルダを準備する。
resourcesフォルダの下にlocalesフォルダを作成する。
resources/locales/
フォルダを新規作成して以下のように各言語用のフォルダを作成する。
/resources
/locales
/en_US
default.po
/en_GB
default.po
validation.po
上記の例は米国(en_US)と英国(en_GB)が設定されている例。
今回はen_USとen_GBは用意せずに日本語用の
ja_JP
フォルダを作成する。
config/app.php 53行目
en_US をja_JP に修正
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja_JP'),
辞書ファイルの生成
参照:I18Nシェル
XAMPP controlからShellを開いて作業する。
cd htdocs\3122333boardgame_rental
続けて以下のコマンドで I18Nシェルを起動する。(シェル:設定ツール)
bin\cake i18n extract
vs code で作業
resources/locales フォルダの default.pot ファイルとcake.potを resources/locales/ja_JP フォルダに移動する。
default.pot ファイルを default.po に名前を変更する。
cake.pot ファイルを cake.po に名前を変更する。
default.po を編集する。
msid "英語のメッセージ"
msgstr "日本語のメッセージ追加"
例)
msid "New Game"
msgstr "ゲーム登録"
日本語化したい項目を検索して msgstr を登録(一部だけでOK)しておく。
(もし存在していれば)キャッシュを削除する。
tmp/cache/persistent/myapp_cake_core_translations.default.ja_j_p
を削除する。
ファイルが見つからない場合は、vs code の再読み込みボタンを押して再度確認する。
TOPページを再読み込み。→日本語に変換されていることを確認。
翻訳データを追加編集する場合はキャッシュの削除が必要となる。
公式ドキュメントより: 翻訳はキャッシュされています。翻訳を変更した後は、必ずキャッシュをクリアしてください。 キャッシュツール を使って、例えば bin/cake cache clear _cake_core_ を実行するか、手動で tmp/cache/persistent フォルダをクリアすることができます (ファイルベースのキャッシュを使用している場合)。
部分的翻訳の例
2025 日本語化でエラーの事例あり
再表示したら回復した。原因不明。
ICU (International Components for Unicode)はPHPのロケールに応じた日付のフォーマットやパースを行うための機能
参照: Form
CakePHP3のタイムゾーンを協定世界時UTCから日本標準時間JSTにずれを変更する方法
PHPの date関数を Form->control のオプション default の値に使用する。書式を MySQLのDATETIME型に合わせる。
コードの例) date("Y-m-d H:i:s")
add.phpの修正例)
echo $this->Form->control('date', ['default' => date("Y-m-d H:i:s")]);
php のタイムゾーンを修正する
D:\xampp\php\php\php.ini の956行目付近を以下のように修正する。
date.timezone = Asia/Tokyo
Webサーバ(Apache)を再起動する。
CakePHPのタイムゾーンを修正する
config\app.php の54行目付近を以下のように修正する。
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Asia/Tokyo'),
config\app_local.php の273行目付近を以下のように修正する。
'timezone' => '+09:00',
※+09:00は暫定処置。正しくは Asia/Tokyo を設定して、MySQLにタイムゾーンを追加する作業を行う必要がある。
参照: FormHelper 日付のセレクトボックスの日本語化 (CakePHP3)
上述のメニューの日本語化と同様の手順を進める。
vs code で作業
src/Locale/ja_JP フォルダの作成
src フォルダに Locale フォルダを作成し、さらにその中に ja_JP フォルダを作成する。
config/app_local.php 53行目
en_US をja_JP に修正
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja_JP'),
辞書ファイルの作成または編集
src/Locale/ja_JP/default.po を新規作成する。
メニューを日本語化するために辞書ファイルが作成済みの場合は default.po を編集する。
以下の内容を記述。
※辞書ファイルの末尾に追記。
※※辞書ファイルに既に msgid "January" などがある場合は追記せずに修正する。
msgid "January"
msgstr "1月"
msgid "February"
msgstr "2月"
msgid "March"
msgstr "3月"
msgid "April"
msgstr "4月"
msgid "May"
msgstr "5月"
msgid "June"
msgstr "6月"
msgid "July"
msgstr "7月"
msgid "August"
msgstr "8月"
msgid "September"
msgstr "9月"
msgid "October"
msgstr "10月"
msgid "November"
msgstr "11月"
msgid "December"
msgstr "12月"
カテゴリー別登録数の集計
第14回の作業内容を参考にして次のようなビューテーブルを期末課題に組み込む。
create view category_groups as
select c.name,count(g.id) s from games g inner join categories c on g.category_id=c.id
group by category_id order by s
表示項目を制限
gamesテーブルの表示で、id name description の3項目の表示を id name だけの表示に制限する。
create view game2s as
SELECT `games`.`id`, `games`.`name`
FROM `games`
ORDER BY `games`.`name` ASC
第10回のcmsチュートリアルの後半の作業を参考にして作成する。
gamesテーブルにURLを記録するtext型のフィールド url を追加する。
ALTER TABLE games ADD url text
templates\Games\view.php を編集する。画像urlをテキスト表示からimgタグ表示に修正する。
↓下のコードを変更する。
<?= $this->Text->autoParagraph(h($game->url)); ?>
変更例)画像のサイズ指定は省略している。
<img src="<?= h($game->url); ?>" />
※urlで表示する画像の取り扱いに注意。詳細画面で画像を表示する際に、外部サイトの画像であることが分かるように工夫が必要。
※Webプログラミングの応用 index.phpを編集してゲーム一覧表示に縮小画像を表示してみよう。
参照:
CakePHP3でファイルのアップロード処理を自作・解説付き・その1 サムネイル画像なし・画像処理ライブラリ不要
※以下にボードゲーム貸し出しデータベースへの組み込みについて記載する。
CakePHP3の画像、ファイルアップロードプラグインUpload Plugin 3.0の設置解説・その1 サムネイル画像あり・要プラグイン&画像処理ライブラリ
※記事を参考に作業を進めてください。
例)ボードゲーム貸し出しデータベースにゲームの画像をアップロードして表示する機能を追加する(サムネイル画像なし)
gamesテーブルにファイル名を記録するtext型のフィールド file_name を追加する。
ALTER TABLE games ADD file_name text
gamesテーブルを bake all する。
ゲーム登録ビューにファイルアップロードフォームを追加する。
template\Games\add.php を編集する。Formクラスのcreateヘルパー関数の引数に以下のオプションを追加。
['enctype' => 'multipart/form-data']
例)
<?= $this->Form->create($game, ['enctype' => 'multipart/form-data']) ?>
アップロードボダンのタグ用コードを追加する。submittedfileはアップロードファイルの情報管理用変数名。
echo $this->Form->file('submittedfile');
webrootにアップロード画像用フォルダを新規作成する。
webroot\upload_img
アップロードしたファイルをサーバに保存するコードを追加する。
src\Controller\GamesController.php
先頭付近にファイル操作関連のクラス利用の宣言を追加する。
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;
use RuntimeException;
さらに、
public function add()
に以下を追記する。追加する場所は、
$game = $this->Games->patchEntity($game, $this->request->getData());
と
if ($this->Games->save($game)) {
の間。
$dir = realpath(WWW_ROOT . "/upload_img");
$limitFileSize = 1024 * 1024;
try {
$game['file_name'] = $this->file_upload($this->request->data['submittedfile'], $dir, $limitFileSize);
} catch (RuntimeException $e){
$this->Flash->error(__('ファイルのアップロードができませんでした.'));
$this->Flash->error(__($e->getMessage()));
}
※アップロードする画像のサイズの上限を必要に応じて変更する。
さらに
src\Controller\GamesController.php に、以下の file_upload() 関数を追記する。
例)
public function file_upload ($file = null,$dir = null, $limitFileSize = 1024 * 1024){
try {
$fileInfo = new File($file["tmp_name"]);
// ファイルサイズのチェック
if ($fileInfo->size() > $limitFileSize) {
throw new RuntimeException('Exceeded filesize limit.');
}
// ファイルタイプをチェックして拡張子を取得
if (false === $ext = array_search($fileInfo->mime(),
['jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',],
true)){
throw new RuntimeException('Invalid file format.');
}
// ファイルのデータからハッシュを計算して保存用ファイル名に使う。→同じ内容のファイルは同じファイル名になる。
$uploadFile = sha1_file($file["tmp_name"]) . "." . $ext;
// ファイルの移動
if (!@move_uploaded_file($file["tmp_name"], $dir . "/" . $uploadFile)){
throw new RuntimeException('Failed to move uploaded file.');
}
} catch (RuntimeException $e) {
throw $e;
}
return $uploadFile;
}
※エラー処理は省略した。アップロードできる画像のタイプは、jpg png gif です。
template\Games\view.php を編集して画像を表示する様に変更する。
<?= $this->Text->autoParagraph(h($game->file_name)); ?>
↑上を↓下の様に変更
<?= $this->Html->image("../upload_img/" . h($game->file_name)); ?>
※ゲームデータの編集と削除の際に、サーバにアップした画像ファイルの更新や削除が必要となる。また、同じ画像は同一ファイルに纏められているため、画像を削除する際には他のゲーム画像として利用されていないかチェックが必要。
※※ edit.php や delete.php や index.php の修正については各自で工夫するものとする。
任意の形式のファイルをアップロードして表示
参考:
中間テーブルに値を記録するコードを書く
モデル(テーブル)どうしを繋いで多対多の値を記録する場合、中間テーブルを belongToManyアソシエーションの throughオプションで指定する方法がある。
集計などのビューは基本的に表示専用である。レコードの追加や修正、削除などのActionは不要。そこでBakeのカスタムテンプレートを作成してビューを表示専用のMVCとしてBakeする。