HtmlHelper

Posted by muchag | CakePHP 3.x | 2018-02-26 (月) 15:11:27

Html ラグ生成ヘルパー。
公式:Html

【環境】
CakePHP: 3.5.11
php: 7.1.5
リンク

動画や音声ファイルへのリンクは media メソッドが別にあるみたいなので、
a タグ用メソッドってことかしらね。

公式:Html リンクの作成

/vendor/cakephp/cakephp/src/View/Helper/HtmlHelper.php

public function link($title, $url = null, array $options = [])

第1引数:表示文字列
第2引数:URL。省略可
第3引数:オプション。省略可
上記処理を見ればわかるけど、内部的には UrlHelper::build メソッドを呼んでいる。

URL
書式

上記公式を見る限り、下記のようになっているので、それぞれの書き方が可能っぽい。

  • ‘/pages/home’,
  • “recipes/view/6”,
  • [‘controller’ => ‘Recipes’, ‘action’ => ‘delete’, 6],
パラメータ

['controller' => 'Recipes', 'action' => 'delete', 6],

この書式を用いたときの 6 がパラメータ。
これで、/recipes/view/6 となる。


['controller' => 'Recipes', 'action' => 'delete', 'id' => 6],

このような書き方もあるみたいだけど、これだとリンク文字列は


となり


public function view($id = null)

としているコントローラ側では、$id = null となってしまう。

ちと不思議。。。


echo $this->Url->build([
    "controller" => "Posts",
    "action" => "search",
    "?" => ["foo" => "bar"],
    "#" => "first",
]);

こうすると


こうなるらしい。

名前付きルート

なんていうのも載っていたけど、これはほぼルーティングの話なので
今回はパス!

絶対 URL

['controller' => 'Dashboards', 'action' => 'index', '_full' => true]

このように _full を指定してやることで、絶対 URL になるとのこと。


‘_full’ => は、省略可能?。

拡張子つき

echo $this->Url->build([
    "controller" => "Posts",
    "action" => "list",
    "_ext" => "rss",
]);

オプション
  • class
  • confirm
    • JavaScript の confirm() ダイアログを表示
  • escape
    • $title の HTML 特殊文字は HTML エンティティーに変換
    • リンクの属性のエスケープも無効
    • デフォルトは true
  • escapeTitle
    • 属性ではなくタイトルのエスケープだけを無効
  • fullBase
    • デフォルトは false
  • target
  • title
  • その他不明
CakePHP 3.x | 2018-02-26 (月) 15:11:27 |

プラグイン開発 -> Template

Posted by muchag | CakePHP 3.x | 2018-02-25 (日) 21:45:15


公式:ビュー ビューテンプレート

【環境】
CakePHP: 3.5.11
php: 7.1.5
概要

View クラスから利用される実際の HTML 部、という理解で合っているのかしらね~。

また定義はよくわかっていないけど、要はフロント部分を格納する場所。

種類
  • テンプレート: テンプレートは実行中のアクション固有のページの一部分です。 アプリケーションの応答の中心となります。
  • エレメント: 小さな、再利用可能なちょっとしたコードです。エレメントは通常、 ビューの中で描画されます。
  • レイアウト: アプリケーションの多くのインターフェイスをくるむ表示コードを入れる テンプレートファイルです。ほとんどのビューはレイアウトの中に描画されます。
  • ヘルパー: これらのクラスはビューレイヤーの様々な場所で必要とされるロジックを カプセル化します。とりわけ、CakePHP のヘルパーはフォームの構築や AJAX 機能の構築、 モデルデータのページ切替、RSS フィードの提供などの手助けをしてくれます。
  • cells: これらのクラスは、自己完結型のUI部品を作成する 小さなコントローラー風の機能を提供します。 より詳しい情報は ビューセル を参照してください。

公式には、これだけの情報が載っているけど
プラス Bake で吐き出されるファイルのテンプレートも存在する。

ファイル配置

コントローラ名と同一のディレクトリ内に
アクション名の .ctp ファイルを配置することで
自動的に読み込んでくれる。


src
 ┣ Controller
 ┃  ┣ AdminController
 ┃  ┗ FrontController
 ┗ Template
   ┣ Admin
   ┃  ┣ index.ctp
   ┃  ┗ view.ctp
   ┗ Front
     ┣ index.ctp
     ┗ view.ctp

カスタマイズ

Controller 参照。

変数の受け渡し

Controller 参照。

継承

公式:ビュー ビューの継承
公式では「ビューの継承」となっている。

これもいいね~♪

CakePHP 3.x | 2018-02-25 (日) 21:45:15 |

値の取得

Posted by muchag | CakePHP 3.x | 2018-02-25 (日) 19:22:39

Synfony のときにも作ったけど
こちらでも、各値の取得方法一覧。

【環境】
CakePHP: 3.5.11
php: 7.1.5
定数
コア定義定数

公式:定数および関数 コア定義定数

APP アプリケーションディレクトリーへの絶対パス。末尾にスラッシュが付きます。
APP_DIR あなたのアプリケーションのディレクトリー名。app かも知れません。
CACHE キャッシュファイルディレクトリーへのパス。 複数サーバーをセットアップした際のホスト間で共有できます。
CAKE cake ディレクトリーへのパス。
CAKE_CORE_INCLUDE_PATH ルートの lib ディレクトリーへのパス。
CONFIG config ディレクトリーへのパス。
CORE_PATH ルートディレクトリーへの、末尾にディレクトリースラッシュを付加したパス。
DS PHP の DIRECTORY_SEPARATOR (Linux の場合は / Windows の場合は \) のショートカット。
LOGS ログディレクトリーへのパス。
ROOT ルートディレクトリーへのパス。
TESTS テストディレクトリーへのパス。
TMP 一時ファイルディレクトリーへのパス。
WWW_ROOT ウェブルートへのフルパス。
時間定義定数

公式:定数および関数 時間定義定数

TIME_START アプリケーションが開始された時点の、浮動小数点マイクロ秒での UNIX タイムスタンプ。
SECOND 1 と等しい
MINUTE 60 と等しい
HOUR 3600 と等しい
DAY 86400 と等しい
WEEK 604800 と等しい
MONTH 2592000 と等しい
YEAR 31536000 と等しい
名称

// プラグイン名
// Controller:OK
$this->plugin

// クラス名
$this->name
$request->params

リクエストパラメータに情報が含まれているので
そこから取り出せる。


debug($this->request->params);

[
	'controller' => 'Users',
	'pass' => [],
	'action' => 'index',
	'plugin' => 'MyPlugin',
	'prefix' => 'admin',
	'_matchedRoute' => '/admin/:controller',
	'_ext' => null,
	'isAjax' => false
]
取得

$this->request->getParam('controller');

// または
$this->request->params['controller'];

// または
$this->request->controller;
リファラ(アクセス元 URL)

未試行。


$this->referer()
CakePHP 3.x | 2018-02-25 (日) 19:22:39 |

プラグインに認証を配置したら、ログインできない

Posted by muchag | CakePHP 3.x | 2018-02-25 (日) 18:24:56

せっかく認証機能を乗っけたのに
認証を必要とするページへアクセスできない。 😥

【環境】
CakePHP: 3.5.11
php: 7.1.5
経緯

認証を機能をプラグインの中に実装した。

プレフィックスルーティングを利用している。

その他、原因がハッキリとはしていなので、何を書くべきかがわからない。

エラー

認証機能を実装できたので
喜び勇んでログインしてみたところ
下記のようなエラーが出た。

Error: A route matching “array ( ‘controller’ => ‘Users’, ‘action’ => ‘login’, ‘plugin’ => NULL, ‘prefix’ => ‘admin’, ‘_ext’ => NULL, )” could not be found.
原因

ハッキリとしていないけど、後述試行錯誤の結果
エラーメッセージにある plugin が NULL だからな気がする。

解決

AuthComponent のオプションに loginAction を設定したら動いた。

BackController.php

$this->loadComponent('Auth', [
  'authenticate' => [
    'Form' => [
      'fields' => [
        'username' => 'email',
        'password' => 'password',
      ],
      'userModel' => $model,
    ]
  ],
  'loginAction' => [
    'plugin' => $this->plugin,
    'prefix' => $this->request->getParam('prefix'),
    'controller' => 'Users',
    'action' => 'login',
  ],
  'loginRedirect' => [
    'action' => 'index',
  ],
  'logoutRedirect' => [
    'action' => 'login',
  ],
  'authError' => 'ログインできませんでした。ログインしてください。'
]);
試行錯誤
エラー箇所

スタックを追っかけると、認証処理中にログインアクションかどうかを判定する箇所があって
そこで、loginAction で指定された URL と、リクエストの URL が一致しない、というエラーが出ていた。

ここで考えたのは、
loginAction で指定された URL と、リクエストの URL なんて一致するわけがない!
なんだけど・・・もっと細かく処理を見ればわかるんだろうね~。

プラグイン

エラー内容を見てみると、plugin のところが null になっていたので
試しに、デフォルトの loginAction ではなく、
プラグイン名を足した設定を追加してみた。

するとなんと~!
無事に認証が必要なページを表示できた。 8-P

確認
/vendor/cakephp/cakephp/src/Routing/RouteCollection.php

public function match($url, $context)
{
    // Named routes support optimization.
    if (isset($url['_name'])) {
        $name = $url['_name'];
        unset($url['_name']);
        if (isset($this->_named[$name])) {
            $route = $this->_named[$name];
            $out = $route->match($url + $route->defaults, $context);
            if ($out) {
                return $out;
            }
            throw new MissingRouteException([
                'url' => $name,
                'context' => $context,
                'message' => 'A named route was found for "%s", but matching failed.',
            ]);
        }
        throw new MissingRouteException(['url' => $name, 'context' => $context]);
    }
    if ($url['action'] == 'login') {

      debug($url);
      exit;
    }

    foreach ($this->_getNames($url) as $name) {
        if (empty($this->_routeTable[$name])) {
            continue;
        }
        /* @var \Cake\Routing\Route\Route $route */
        foreach ($this->_routeTable[$name] as $route) {
            $match = $route->match($url, $context);
            if ($match) {
                return strlen($match) > 1 ? trim($match, '/') : $match;
            }
        }
    }
    throw new MissingRouteException(['url' => var_export($url, true), 'context' => $context]);
}

上記のようにデバッグコードを仕込んで見てみると


/src/Routing/RouteCollection.php (line 330)
[
	'plugin' => null,
	'prefix' => 'admin',
	'controller' => 'Users',
	'action' => 'login',
	'_ext' => null
]

/src/Routing/RouteCollection.php (line 330)
[
	'plugin' => 'MyPlugin',
	'prefix' => 'admin',
	'controller' => 'Users',
	'action' => 'login',
	'_ext' => null
]

当たり前だけど、違いはプラグインのところだけ。

CakePHP 3.x | 2018-02-25 (日) 18:24:56 |

Timestamp ビヘイビア

Posted by muchag | CakePHP 3.x | 2018-02-24 (土) 23:14:53

データに更新日付情報を追加してくれるビヘイビア。

公式:Timestamp

【環境】
CakePHP: 3.5.11
php: 7.1.5
設定

Table::initialize にて設定。


class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Timestamp');
    }
}

このように記述するだけで、下記のように動作する。

  • created:新規登録時のみ日付を追加
  • modified:常に日付を追加

メッチャ便利!

デフォルト

なぜ、上記のようになるのかというと、
デフォルトの設定が下記のようになっているから。

/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php

protected $_defaultConfig = [
    'implementedFinders' => [],
    'implementedMethods' => [
        'timestamp' => 'timestamp',
        'touch' => 'touch'
    ],
    'events' => [
        'Model.beforeSave' => [
            'created' => 'new',
            'modified' => 'always'
        ]
    ],
    'refreshTimestamp' => true
];
カスタマイズ

設定内容をカスタマイズしたければ、ビヘイビア登録時にオプションとして設定する。


$this->addBehavior('Timestamp', [
    'events' => [
        'Model.beforeSave' => [
            'created_at' => 'new',
            'updated_at' => 'always',
        ],
        'Orders.completed' => [
            'completed_at' => 'always'
        ]
    ]
]);
  • created, modified カラム名
  • created, modified の挙動
    • new:新規登録のときのみ日付を追加
    • existing:更新のときのみ日付を追加
    • always:常に日付を追加
  • 任意カラムへ更新日時を登録

このようなことが可能。

touch

データの更新はないけど、タイムスタンプだけ更新したいときのメソッド。


// Model.beforeSave イベントに基づいて touch します
$articles->touch($article);

// 指定したイベントに基づいて touch します
$orders->touch($order, 'Orders.completed');
dirty

touch とは逆に、タイムスタンプを更新したくないときのメソッド。


// modified カラムを dirty としてマークして、更新時に現在の値がセットされるようにします。
$order->setDirty('modified', true);

// 3.4.0 より前
$order->dirty('modified', true);
参考サイト

あかつきのお宿:CakePHP3を触ってみました 〜あれ、updatedは?〜(2015-11-14)
→挙動の部分を参考にさせていただいた

Qiita:cakephp3 modified のみ変更 touch(2017-02-04)
→touch についての記事。まだ読んでいない

CakePHP 3.x | 2018-02-24 (土) 23:14:53 |

プラグイン開発 -> 基本

Posted by muchag | CakePHP 3.x | 2018-02-24 (土) 23:08:24


公式:プラグイン

【環境】
CakePHP: 3.5.11
php: 7.1.5
プラグイン名

$this->plugin

コントローラ内で取得できることは確認済み。

CakePHP 3.x | 2018-02-24 (土) 23:08:24 |

プレフィックスルーティング

Posted by muchag | CakePHP 3.x | 2018-02-23 (金) 15:10:12


公式:ルーティング プレフィックスルーティング

【環境】
CakePHP: 3.5.8
php: 7.1.5
概要

最初は URL にプレフィクスを付けるのかと思ったけど
どうやらディレクトリ構成のプレフィクスらしい。

ディレクトリ構成

通常は、下記のようなディレクトリ構成。
Controller の例。


src
 ┗ Controller
   ┣ AdminController
   ┗ FrontController

これをプレフィックスルーティングを用いることで、下記のようなディレクトリ構成を実現できる。


src
 ┗ Controller
   ┣ Admin
   ┃  ┗ AdminController
   ┗ Front
      ┗ FrontController
メリット

この例だと意味不明だけど、これができれば下記のようなメリットがある気がする。
これから試すので予想!

URL と処理との関係

/admin/* という URL で管理系処理をまとめたい場合、
ノーマルルーティングだと AdminController にアクションを全て集約しなければならなくなるけど
プレフィックスルーティングだと、コントローラをわかりやすくファイル分割できる。

ファイル整理

ノーマルルーティングでコントローラファイルを分割しようとすると、
何系の処理かわかりにくい、または、クラス名にプレフィックスを付けることになるけど
プレフィックスルーティングなら、ディレクトリ毎にまとめられるので、見やすい♪

書式
個別指定

connect メソッドにて個別指定する手法。


$routes->connect('/admin', ['plugin' => 'MyPlugin', 'controller' => 'Users', 'action' => 'index', 'prefix' => 'admin']);
一括指定

prefix メソッドにて一括指定する手法。


Router::prefix('admin', function ($routes) {
  
  $routes->fallbacks(DashedRoute::class);
});
プラグイン

プレフィックスに対して、全てのルーティングを同一プラグインに割り当てる手法。


Router::prefix('admin', ['plugin' => 'MyPlugin'], function ($routes) {
  
  $routes->fallbacks(DashedRoute::class);
});
階層化

プレフィックスを2段階にしたい場合。


Router::prefix('manager', function ($routes) {
    $routes->prefix('admin', function ($routes) {
        $routes->connect('/:controller');
    });
});

上記のコードは、 /manager/admin/:controller のようなルートテンプレートを生成します。
接続されたルートは prefix というルート要素を manager/admin に設定します。

コントローラ

コントローラ Bake コマンド。
–prefix オプションを用いる。


bin/cake bake controller --plugin MyPlugin --prefix admin administrators

これにて下記のようなディレクトリ構成となる。


src
 ┗ Controller
   ┗ Admin
     ┗ AdministratorsController
取得

現在のプレフィックスをリクエストから取得するには、コントローラで下記のように取得。


$prefix = $this->request->getParam('prefix');

// または
$prefix = $this->request->params['prefix'];
番外編

本来のプレフィックスルーティングとは異なるけど
結果的に似たようなことをできる設定方法を見つけたのでメモ。
Qiita:CakePHPのコントローラを階層化する(2016-01-31)
ここの追記部分。


Router::connect('/:dir/:controller/', array('action' => 'index'));

とかでも動くんですね(bootstrap.phpは書かなきゃいけない様子)。
知らなかったとはいえ拙いことを書いて申し訳ありませんでした。
/:dirであるとか/:langであるとか、好きな名前で書いてやると今度はリンクを貼るときに
array(‘dir’=>’hoge’,’controller’=>’fuga’)とかで動いてくれて便利です。名前付きパラメータで取れますし。

ディレクトリとか言語とかでURLがごちゃごちゃになってきたら第三引数に正規表現書いて判断させます。

ちょっと読んだだけでは、よく意味がわからなかったけど
いつかわかるようになりたい。

参考サイト

Qiita:CakePHP3でフロントとバックエンドでControllerとTemplateをフォルダ分けするための設定(2017-01-20)
→ほぼほぼこちらの記事を参考にさせていただいた

あなたとあなたの会社にあったITを提供するエンジニア:CakePHP3で管理画面を作る、その1(2017-04-07)
→プレフィックスルーティングのコマンドを参考にさせていただいた

stack overflow:CakePHP 3.x: all routes to the plugin(2015-04-01)
→プラグイン一括指定方法を参考にさせていただいた

CakePHP 3.x | 2018-02-23 (金) 15:10:12 |

ルートクラス

Posted by muchag | CakePHP 3.x | 2018-02-23 (金) 15:04:46

ルーティングルールを設定するクラス。
公式:ルーティング

【環境】
CakePHP: 3.5.8
php: 7.1.5
既存
/vendor/cakephp/cakephp/src/Routing/Route

この中にしまわれており、デフォルトで下記4クラスが存在する模様。

  1. DashedRoute
    1. 単語を -(ハイフン、ダッシュ)で連結
    2. URL:/my-controller/my-action
    3. 対応アクション:MyController::myAction
  2. InflectedRoute
    1. 単語を _(アンダースコア)で連結
    2. URL:/my_controller/my_action
    3. 対応アクション:MyController::myAction
  3. PluginShortRoute
  4. RedirectRoute
    1. 個別の URL に対してリダイレクトを設定
    2. パラメータを渡すことも可能
    3. 公式:ルーティング リダイレクトルーティング
カスタム

公式:ルーティング カスタムルートクラス
ここを見ると、自前のルートクラスを作成、設定可能みたい。

デフォルト

公式:ルーティング デフォルトルートクラス

デフォルトのルートクラスは、下記のように設定するみたい。

/config/routes.php

Router::defaultRouteClass(InflectedRoute::class);

実際に当該ファイルを覗いてみると、最初に記述されている。

フォールバックメソッド

公式:ルーティング フォールバックメソッド


$routes->fallbacks(DashedRoute::class);

// こんな書き方もある
$routes->fallbacks('DashedRoute');

このような記述を見かけるけど、上記公式の記事にも書いてあり
route.php にも記述されているように、
設定されていないルーティングに対する
デフォルトのルーティング設定を記述するショートカットメソッドとのこと。

実体

実際には、下記のように記述しているのと同じだそうな。


$routes->connect('/:controller', ['action' => 'index'], ['routeClass' => DashedRoute::class]);
$routes->connect('/:controller/:action/*', [], ['routeClass' => DashedRoute::class]);
デフォルト
/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php

protected $_routeClass = 'Cake\Routing\Route\Route';

public function fallbacks($routeClass = null)
{
    $routeClass = $routeClass ?: $this->_routeClass;
    $this->connect('/:controller', ['action' => 'index'], compact('routeClass'));
    $this->connect('/:controller/:action/*', [], compact('routeClass'));
}

ということなので、デフォルトは Route クラスなのね~。

って、どういうことなのか。。。いずれのお楽しみ。。。

参考サイト

sakutarou’s blog:CakePHP3のRouteクラス3種(2016-12-05)

CakePHP 3.x | 2018-02-23 (金) 15:04:46 |

Localkit が起動しない!

Posted by muchag | Monaca | 2018-02-18 (日) 21:59:11

【環境】
Monaca LocalKit: 2.5.0? → 2.5.1
経緯

ある日突然 Localkit が起動しなくなった。

アプリアイコンをクリックして、処理中のグルグルが断続的に2,3回出たものの
サッパリ起動しない。

Localkit をアンインストールして、再インストールしてもダメ。

原因

不明。

解決

teratail:Monaca LocalKitが起動されません(2017-12-11)
こちらの記事のおかげで解決。

記事にある通り、下記手順にて無事に起動するようになった。

  1. Localkit(おそらく 2.5.0)をアンインストール
  2. 下記2ディレクトリを削除
    1. ローカルディスク(c)/Users/(ユーザ名)/.cordova
    2. ローカルディスク(c)/Users/(ユーザ名)/AppData/Roaming/Monaca Localkit
  3. Localkit 2.5.1 を再インストール

私が戸惑っている数ヶ月の間に、解決記事がアップされていて助かりました。
ありがとうございました。

プロジェクト追加

プロジェクトが綺麗サッパリなくなっていたので

  1. 左ペイン「プロジェクト一覧」右にある+ボタンから
  2. [インポート]-[Cordova プロジェクトをインポート]
  3. 「既存の Cordova プロジェクトをインポート」
    1. 作業ディレクトリ:[参照] からローカルリポジトリ(ディレクトリ)を選択
    2. プロジェクト名:任意
    3. [インポート]
Monaca | 2018-02-18 (日) 21:59:11 |

構成設定

Posted by muchag | CakePHP 3.x | 2018-02-14 (水) 13:12:41


公式:構成設定

【環境】
CakePHP: 3.5.8
php: 7.1.5
参考サイト

新人Webエンジニアの記録。:CakePHP3のConfigureクラスに関して調べました(2015-01-18)

CakePHP 3.x | 2018-02-14 (水) 13:12:41 |
次ページへ »