2016年5月27日金曜日

cakephp3 admin prefix routingの罠

PHP Ver 5.6.27
CakePHP Ver 3.1.9


cakephp admin prefix routingの罠
・管理画面を作成する場合などControllerをネストする場合は注意!

http://xxx.com/admin/ はsrc/Controller/{dirName}/xxxxController.phpというような
Controllerを作成するが、この{dirName}が曲者。。。

例えば 'Admin' というような名前でディレクトリを作成した場合
XAMPPを利用した場合等、Windows環境では正しく認識されるが、Linux環境では
ディレクトリ名が小文字の 'admin' としないと動作しない
原因は調べられていないが、ディレクトリ名はすべて小文字にしないといけないらしい

MissingControllerエラーが発生するのだが、そのエラーメッセージでは
src/Controller/Admin/xxxxController.phpを作成しろと言われる
しかし、ディレクトリ名が小文字でないと動作しない
バグなのかな?

相当、はまった・・・

cakephp3 how to add intl module

PHP Ver 5.6.27
CakePHP Ver 3.1.9


ディレクトリ作成
$ mkdir -p local/src
ICUインストール
intlインストール時に必要

$ cd local/src/
$ wget http://download.icu-project.org/files/icu4c/54.1/icu4c-54_1-src.tgz
$ tar xzvf icu4c-54_1-src.tgz
$ cd icu/source/
$ ./configure --prefix=$HOME/local
$ gmake
$ gmake install
intlインストール
$ wget http://pecl.php.net/get/intl-3.0.0.tgz
$ tar xzvf intl-3.0.0.tgz
$ cd intl-3.0.0
$ phpize
$ ./configure --with-icu-dir=$HOME/local
$ make
$ cd ~/local/
$ mkdir php
$ mkdir php/extension
$ cd php/extension/
$ cp ~/local/src/intl-3.0.0/modules/intl.so .
$ php -i | grep intl

make install した方が良いと思う

2016年5月5日木曜日

cakephp mysql tinyintの罠

PHP Ver 5.6.27
CakePHP Ver 3.1.9


cakephp mysql tinyintの罠

・cakephpでmysqlのtinyint型を利用するときは要注意!
tinyint(1)と設定した項目はbool型として認識される。

$this->request->dataでは正しくPOSTされてくる、
しかし、patchEntityをするとbool型になる。
何をやっても結果は一緒・・・

これはbugではないのか?とcakephp側のコードを追う
散々調べた結果、cakephpでのtinyint(1)はvarchar型などのbyteと違い、bitと認識されるらしい
相当、はまった・・・
とりあえず、tableをcreateするときに指定なしでtinyintとすることにした

2016年4月24日日曜日

cakephp3 ページネーション -- Pagination method --

PHP Ver 5.6.27
CakePHP Ver 3.1.9



cakephp3 ページネーション (Cake\View\Helper\PaginatorHelper)


利用できるメソッド一覧

基本的には以下のように利用する。
$this->Paginator->{methodName}

・templates($templates = null)
    $templates = [
        'nextActive' => '< li class="next">< a rel="next" href="{{url}}">{{text}}< /a>< /li>',
        'nextDisabled' => '< li class="next disabled">< a href="" onclick="return false;">{{text}}< /a>< /li>',
        'prevActive' => '< li class="prev">< a rel="prev" href="{{url}}">{{text}}< /a>< /li>',
        'prevDisabled' => '< li class="prev disabled">< a href="" onclick="return false;">{{text}}< /a>< /li>',
        'counterRange' => '{{start}} - {{end}} of {{count}}',
        'counterPages' => '{{page}} of {{pages}}',
        'first' => '< li class="first">< a href="{{url}}">{{text}}< /a>< /li>',
        'last' => '< li class="last">< a href="{{url}}">{{text}}< /a>< /li>',
        'number' => '< li>< a href="{{url}}">{{text}}< /a>< /li>',
        'current' => '< li class="active">< a href="">{{text}}< /a>< /li>',
        'ellipsis' => '< li class="ellipsis">...< /li>',
        'sort' => '< a href="{{url}}">{{text}}< /a>',
        'sortAsc' => '< a class="asc" href="{{url}}">{{text}}< /a>',
        'sortDesc' => '< a class="desc" href="{{url}}">{{text}}< /a>',
        'sortAscLocked' => '< a class="asc locked" href="{{url}}">{{text}}< /a>',
        'sortDescLocked' => '< a class="desc locked" href="{{url}}">{{text}}< /a>',
    ];

・sort($key, $title = null, array $options = [])
    $key(string)
    $title(string)
    $options = [
        'url' => [],
        'model' => 'defaultModel',
        'escape' => true,
    ];

・sortDir($model = null, array $options = [])
    $model = {modelName}
    $options = [
        'url' => [
            'sort' => 'email',
            'direction' => 'desc',
            'page' => 6,
            'lang' => 'en',
        ]
    ];

・sortKey($model = null, array $options = [])
    $key(string)
    $options = [
        'url' => [
            'sort' => 'email',
            'direction' => 'desc',
            'page' => 6,
            'lang' => 'en',
        ]
    ];

・numbers(array $options = [])
    $options = [
        'before' => {numbers},
        'after' => {numbers},
        'model' => 'defaultModel',
        'modulus' => 8,
        'first' => 'First page',
        'last' => 'Last page',
        'templates' => [
            'active' => 'nextActive',
            'disabled' => 'nextDisabled',
        ],
        'url' => [],
    ];

・prev($title = '<< Previous', array $options = [])
    $title(string)
    $options = [
        'disabledTitle' => {title},         'url' => [],
        'model' => 'defaultModel',
        'escape' => true,
        'templates' => [
            'active' => 'nextActive',
            'disabled' => 'nextDisabled',
        ]
    ];

・next($title = 'Next >>', array $options = [])
    $title(string)
    $options = [
        'disabledTitle' => {title},         'url' => [],
        'model' => 'defaultModel',
        'escape' => true,
        'templates' => [
            'active' => 'nextActive',
            'disabled' => 'nextDisabled',
        ]
    ];

・first($first = '<< first', array $options = [])
    $first(string or int)
    $options = [
        'url' => [],
        'model' => 'defaultModel',
        'escape' => true,
    ];

・last($last = 'last >>', array $options = [])
    $last(string or int)
    $options = [
        'url' => [],
        'model' => 'defaultModel',
        'escape' => true,
    ];

・counter($options = [])
    $options = [
        'model' => 'defaultModel', // デフォルトではPaginatorHelper::defaultModelが呼ばれる
        'format' => 'range' or 'pages' or custom
            custom example: 'Page {{page}} of {{pages}}, showing {{current}} records out of
                {{count}} total, starting on record {{start}}, ending on {{end}}'
        ];

・current($model = null)
    $model = {modelName}

・hasNext($model = null)
    $model = {modelName}

・hasPage($model = null, $page = 1)
    $model = {modelName}
    $page = int
・hasPrev($model = null)
    $model = {modelName}

・options(array $options = [])
    $options = [
        'url' => [
            'sort' => 'email',
            'direction' => 'desc',
            'page' => 6,
            'lang' => 'en',
        ]
    ];

・generateUrl(array $options = [], $model = null, $full = false)
    $options = [
        'page' => null,
        'sort' => null,
        'direction' => null,
        'limit' => null,
    ];
    $model = {modelName}
    $full = boolean

・meta(array $options = [])
    $options = [
        'model' => 'defaultModel', // デフォルトではPaginatorHelper::defaultModelが呼ばれる
        'block' => false or {blockName},
    ];

2016年4月22日金曜日

cakephp3 バリデーション(4)
-- validation of cakephp3 --

PHP Ver 5.6.27
CakePHP Ver 3.1.9


Model

・バリデーションを行いたくない場合

$this->newEntity()、$this->patchEntity()を行うとバリデーションが行われてしまうため、
$this->patchEntity($entity, $this->request->data, ['validate' => false] )とすると
バリデーションを行わない。

但し、これ以外にもバリデーションが行われるメソッドがあるので、そこについては要調査

2016年4月14日木曜日

cakephp3 アクセス時のメソッド呼び出し順

PHP Ver 5.6.27
CakePHP Ver 3.1.9



cakephp3 method 呼び出し順


アクセスした場合、以下のように呼び出される

・Controllerのinitialize()
・ComponentのbeforeFilter()
・ControllerのbeforeFilter()
・Componentのstartup()
・Controllerのaction
・ComponentのbeforeRender()
・ControllerのbeforeRender()
・Componentのshutdown()
・ControllerのafterFilter()



その他(Modelで呼ばれるメソッド)

・Model.initialize
・Model.beforeMarshal
・Model.beforeFind
・Model.buildValidator
・Model.buildRules
・Model.beforeRules
・Model.afterRules
・Model.beforeSave
・Model.afterSave
・Model.afterSaveCommit
・Model.beforeDelete
・Model.afterDelete
・Model.afterDeleteCommit

公式HP:http://book.cakephp.org/3.0/ja/orm/saving-data.html

2016年4月13日水曜日

cakephp3 カスタム HTML ヘルパー -- custom html helper --

PHP Ver 5.6.27
CakePHP Ver 3.1.9



cakephp3 カスタムHTMLヘルパーを使う


設定(src/View/AppView.php)

・ここでは例としてCustomHtmlHelperというクラスを作成
initializeメソッドに追記

----------------------
$this->loadHelper('CustomHtml');
----------------------

ここでHelperが付かないことに注意!



クラス作成(src/View/Helper/CustomHtmlHelper.php)

Cake\View\Helperクラスを継承して作成



利用方法(ctpファイルで利用)

$this->CustomHtml->{MethodName}();
で利用可能