Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

パスワード変更

phpmyadminから入ってmysqlのパスワードを変更したところアクセスできなくなった。

パスワードの再設定 mysqlのパスワード変更はmysqlから

 SET PASSWORD = PASSWORD('hoge');

で変更できる。

対応してphpMyAdminの設定ファイルを書き換える必要がある。

/Applications/MAMP/bin/phpMyAdmin/config.inc.php

認証 AuthComponent

認証 - 3.x

AuthComponentは三タイプの認証できる。

  1. FormAuthenticate ログインフォーム POSTで (デフォルト)
  2. BasicAuthenticate ベーシック認証
  3. DigestAuthenticate ダイジェストHTTP認証

認証ハンドラの設定

// シンプルな設定
public function initialize()
{
    parent::initialize();
    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'passwd']
            ]
        ]
    ]);
}
>|php|
// 'all' を使って設定を記述
$this->Auth->config('authenticate', [
    AuthComponent::ALL => ['userModel' => 'Members'],
    'Basic',
    'Form'
]);

userModelはデフォルトはUsersとなっているのでそうであれば設定不要。

ログインのサンプル

public function login()
{
    if ($this->request->is('post')) {
        $user = $this->Auth->identify();
        if ($user) {
            $this->Auth->setUser($user);
            return $this->redirect($this->Auth->redirectUrl());
        } else {
            $this->Flash->error(__('Username or password is incorrect'));
        }
    }
}

unauthenticated()は認証されていないユーザがアクセスした際に呼ばれる。

認証関連のフラッシュメッセージの表示

src/Template/Layout/default.ctp の body 部でecho $this->Flash->render();を加える。

ハッシュ化

DefaultPasswordHasher

namespace App\Model\Entity;

use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;

class User extends Entity
{

    // ...

    protected function _setPassword($password)
    {
        if (strlen($password) > 0) {
          return (new DefaultPasswordHasher)->hash($password);
        }
    }

    // ...
}

現在のログインID

$this->Auth->user('id');
で取得できる。

ログアウト

AuthComponent::logout()

public function logout()
{
    return $this->redirect($this->Auth->logout());
}

ユーザ毎のリソース認可

ControllerAuthorize

公開するところ
AuthComponent::allow($actions = null)
公開アクションを拒否
AuthComponent::deny($actions = null)

コントローラのコールバックで

ControllerAuthorize

ビヘイビア群

CounterCacheBehavior

例えばコメント数をエンティティが保存、削除されるたびに更新される。
belongsTo アソシエーションにしか効かない。

class CommentsTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('CounterCache', [
            'Articles' => ['comment_count']
        ]);
    }
}

細かいカスタマイズは以下
CounterCache - 3.x

TimestampBehavior

created や modified を更新してくれる。
Timestamp - 3.x

TranslateBehavior

翻訳

TreeBehavior

ツリー構造
テーブルがnullableなparent_idを持ち、整数、符号付きなlftとrghtを持つこと。

以下はまだ実感が無いので保留。
Tree - 3.x

使い方

class CategoriesTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Tree');
    }
}
で読み込む。
再構築
>|php|
$categories = TableRegistry::get('Categories');
$categories->recover();
$node = $categories->get(1);
echo $categories->childCount($node);
$descendants = $categories->find('children', ['for' => 1]);

foreach ($descendants as $category) {
    echo $category->name . "\n";
}

ビヘイビア

ビヘイビアとはテーブルに追加できる便利部品
以下を参照した。
ビヘイビアー - 3.x

ビヘイビアをテーブルに追加

amespace App\Model\Table;

use Cake\ORM\Table;

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

追加設定

namespace App\Model\Table;

use Cake\ORM\Table;

class HogesTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Timestamp', [
            'events' => [
                'Model.beforeSave' => [
                    'created_at' => 'new',
                    'modified_at' => 'always'
                ]
            ]
        ]);
    }
}

removeBehaviorで削除。

既存のビヘイビア

  1. CounterCache
  2. Timestamp
  3. Translate
  4. Tree

ビヘイビアの作成

namespace App\Model\Behavior;

use Cake\ORM\Behavior;

class HogeBehavior extends Behavior
{
 public function initialize(array $config)
 {
    // 何らかの初期化処理
 }
}

ビヘイビアを追加するとビヘイビアーのパブリックメソッドが、追加されたテーブルオブジェクトに「ミックスイン」メソッドとして追加される。

  1. 複数追加したビヘイビアが同じメソッドを持つと例外発生。
  2. テーブルが同じメソッドを持つとそちらが呼ばれる。

公開したくないビヘイビアのpublicメソッドがあればimplementMethods設定で隠せる。

ビヘイビアでコールバックを実装すればミックスインされるのでイベントを処理できる。

    public function beforeSave(Event $event, EntityInterface $entity)
    {
        $this->slug($entity);
    }

読み込まれたビヘイビアの確認

$table->behaviors()->loaded();
$table->behaviors()->has('CounterCache');
$table->behaviors()->get('CounterCache');

ロードされたビヘイビアの再構成

BehaviorRegistry::getとconfigでできるらしい。

コンポーネント

コントローラで使える部品。
以下を参照した。

設定が必要なコンポーネントを使う際の設定

class HogesController extends AppController
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Auth', [
            'authorize' => 'Controller',
            'loginAction' => ['controller' => 'Users', 'action' => 'login']
        ]);

        $this->loadComponent('Cookie', ['expires' => '1 day']);
    }

}

Controller->beforeFilter()でconfig()を使って設定する方法もあり。
設定は$this->Auth->config('loginAction');でよみ取れる。

コンポーネントの使用

        if ($this->Post->delete($this->request->getData('Post.id')) {

要するに移譲している。

コンポーネントの実装

namespace App\Controller\Component;

use Cake\Controller\Component;

class MathComponent extends Component
{
    public function doComplexOperation($amount1, $amount2)
    {
        return $amount1 + $amount2;
    }
}

コンポーネントから他のコンポーネントを使う。

   public $components = ['Existing'];

これで$this->Existingとなってコンポーネントから色々使える。

コンポーネントからコントローラにアクセス。。orz
$controller = $this->_registry->getController();
$controller = $event->getSubject();
コールバック
  1. beforeFilter(Event $event)
  2. startup(Event $event)
  3. beforeRender(Event $event)
  4. shutdown(Event $event)
  5. beforeRedirect(Event $event, $url, Response $response)

コンポーネント

コントローラで使える部品。

設定が必要なコンポーネントを使う際の設定

class HogesController extends AppController
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('Auth', [
            'authorize' => 'Controller',
            'loginAction' => ['controller' => 'Users', 'action' => 'login']
        ]);

        $this->loadComponent('Cookie', ['expires' => '1 day']);
    }

}

Controller->beforeFilter()でconfig()を使って設定する方法もあり。
設定は$this->Auth->config('loginAction');でよみ取れる。

コンポーネントの使用

        if ($this->Post->delete($this->request->getData('Post.id')) {

要するに移譲している。

コンポーネントの実装

namespace App\Controller\Component;

use Cake\Controller\Component;

class MathComponent extends Component
{
    public function doComplexOperation($amount1, $amount2)
    {
        return $amount1 + $amount2;
    }
}

コンポーネントから他のコンポーネントを使う。

   public $components = ['Existing'];

これで$this->Existingとなってコンポーネントから色々使える。

コンポーネントからコントローラにアクセス。。orz
$controller = $this->_registry->getController();
$controller = $event->getSubject();
コールバック
  1. beforeFilter(Event $event)
  2. startup(Event $event)
  3. beforeRender(Event $event)
  4. shutdown(Event $event)
  5. beforeRedirect(Event $event, $url, Response $response)

イベントシステム

これは
イベントシステム - 3.x
の勉強メモである。


オブザーバーパターンの利用
イベントオブジェクトはすべてのリスナーに行き渡る。
そしてすべてのビュー、コントローラ、テーブルで
$events = $this->eventManager();
がある。。各モデルは独立したイベントマネージャーを持つ。

イベントの通知(dispatch)

// Cart/Model/Table/HogesTable.php
namespace Cart\Model\Table;

use Cake\Event\Event;
use Cake\ORM\Table;

class HogesTable extends Table
{

    public function place($order)
    {
        if ($this->save($order)) {
            $this->Cart->remove($order);
// イベント作成
            $event = new Event('Model.Order.afterPlace', $this, [
                'order' => $order
            ]);
// 通知
            $this->eventManager()->dispatch($event);
            return true;
        }
        return false;
    }
}

グローバルイベントマネージャーはアプリ内で起こる任意のイベントを受け取れる。
Cake\Event\EventManagerのシングルトン

// イベントの前に実行される任意の設定ファイルやコードの一部の中で
use Cake\Event\EventManager;

EventManager::instance()->on(
    'Model.Order.afterPlace',
    $aCallback
);

イベントの追跡

EventManager::instance()->setEventList(new EventList());

これで何を通知していったかわかる。

$eventsFired = EventManager::instance()->getEventList();
$firstEvent = $eventsFired[0];

コアイベント

ORM/Model イベント

テーブルオブジェクト - 3.x

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

コントローラーイベント

コントローラー - 3.x

Controller.initialize
Controller.startup
Controller.beforeRedirect
Controller.beforeRender
Controller.shutdown

ビューイベント

ビュー - 3.x

View.beforeRender
View.beforeRenderFile
View.afterRenderFile
View.afterRender
View.beforeLayout
View.afterLayout

リスナーの追加方法

Cake\Event\EventListenerInterfaceを実装するすなわち
implementedEvents()を実装する。

use Cake\Event\EventListenerInterface;

class Hoge implements EventListenerInterface
{
// イベントごとにどのメソッドを呼ぶか分ける
    public function implementedEvents()
    {
        return [
            'Model.Order.afterPlace' => 'updateBuyStatistic',
        ];
    }
// 各イベントの対処
    public function updateBuyStatistic($event, $order)
    {
        // 統計値を更新するコード
    }
}

// 登録
// Hoge オブジェクトを Order のイベントマネージャーに追加
$hoge = new Hoge();
$this->Orders->eventManager()->on($hoge);
無名リスナーの登録

ブロックで直接登録してしまう。

use Cake\Log\Log;

$this->Orders->eventManager()->on('Model.Order.afterPlace', function ($event) {
    Log::write(
        'info',
        'A new order was placed with id: ' . $event->getSubject()->id
    );
});
リスナーがいるかのチェック

リスナー登録が

// EventManager にリスナーを追加
$this->eventManager()->on('Hoge.Registration', [$this, 'hogeRegistration']);
$this->eventManager()->on('Hoge.Verification', [$this, 'hogeVerification']);
$this->eventManager()->on('Hoge.Authorization', [$this, 'hogeAuthorization']);

として

// アプリケーションのどこか別の場所で
$events = $this->eventManager()->matchingListeners('Verification');
if (!empty($events)) {
    $this->eventManager()->off('Hoge.Verification');
} else {
    // 'Verification' イベントリスナーが存在しない場合のロジックを実行。
}

リスナーには呼び出し順にpriorityをつけることもできる。勉強中

イベントデータ
$this->eventManager()
    ->dispatch(new Event('View.afterRender', $this, ['view' => $viewFileName]));

の場合、afterRenderのコールバックのリスナー(実装メソッドは第2引数で$viewFileNameを受け取る。

function (Event $event, $viewFileName)
イベントの送信
// 第1引数はイベント名
// 第2引数はsubject(イベントに関連づけるオブジェクト(通常自分)
// 第3引数はイベントパラメータで辞書がおすすめ
$event = new Event('Model.Order.afterPlace', $this, [
    'order' => $order
]);
$this->eventManager()->dispatch($event);
イベントの中止(後続のイベントコールバックを防ぐ)

通知を受けたメソッドがfalseをreturnするか
$event->stopPropagation();
を呼べば良い。
ストップすると$event->isStopped()がtrueになる。

イベント結果を返す。
// リスナーコールバック
public function doSomething($event)
{
    // .結果としてalteredDataを作って結果を返す
    $alteredData = $event->getData('order') + $moreData;
    return $alteredData;
}

// 別のリスナーコールバック
public function doSomethingElse($event)
{
    // returnで返す以外にsetResultというのでも返せる。
    $event->setResult(['order' => $alteredData] + $this->result());
}

// イベントを通知してその結果を得る
public function place($order)
{
    $event = new Event('Model.Order.beforePlace', $this, ['order' => $order]);

//  配信
    $this->eventManager()->dispatch($event);

// 配信結果をうけとる
    if (!empty($event->getResult()['order'])) {
        $order = $event->getResult()['order'];
    }
    if ($this->Orders->save($order)) {
        // ...
    }
    // ...
}

*** リスナーの削除

Cake\Event\EventManager::off()

イベントの注意

イベントは便利だが無思慮に使うとデバッグが困難になるので注意。

View

以下を参照して勉強したメモ
ビュー - 3.x

役割

HTML, XML, JSON, PDF生成等
XMLJSONビューは
JSON と XML ビュー - 3.x

AppView アプリのベースのView

主にヘルパーを読み込むように使用する。

<?php
namespace App\View;

use Cake\View\View;

class AppView extends View
{

    public function initialize()
    {
        $this->loadHelper('MyUtils');
    }

}

テンプレート ctp

両者は同じ意味

<?php echo $variable; ?>
<?= $variable ?>

テンプレート内での制御構文 (やりたくない。。)
if 、 for 、 foreach 、 switch 、そして while

<ul>
<?php foreach ($todo as $item): ?>
  <li><?= $item ?></li>
<?php endforeach; ?>
</ul>

このように":"で書いて、end***で閉じる。

ifの例

<?php if ($username === 'a'): ?>
   <h3>a</h3>
<?php elseif ($username === 'b'): ?>
   <h3>b</h3>
<?php else: ?>
   <h3>unknown</h3>
<?php endif; ?>

ビューレイヤーのパーツ

  1. ビュー(テンプレート)
  2. エレメント 描画時にビューのテンプレートに埋め込まれる
  3. レイアウト ビューのテンプレートを包む
  4. ヘルパー ビューロジックのカプセル化
  5. cells   自己完結型のUI部品

ビューへコントローラから値を渡す

コントローラのset

エスケープ

h()

ビューからレイアウトやエレメントに値を渡す

ビューのset

$this->set('activeMenuButton', 'posts');

ビューのテンプレートを継承したい。

$this->extendを用いる。入れ子にできる。これとビューブロックを用いて親テンプレートと子テンプレートをつくり継承関係をつくる。

ビューブロック

使用メソッド
start() 、 append() 、 prepend() 、 assign() 、 fetch() 、 そして end()

サイドバーブロックを定義する。

// sidebar ブロックを作成する。
$this->start('sidebar');
echo $this->element('sidebar/recent_topics');
echo $this->element('sidebar/recent_comments');
$this->end();

これでサイドバーブロックが定義されたので、
使う場合、

<?= $this->fetch('sidebar') ?>

とすれば使えるようになる。

ビューブロックが定義されていない場合も考慮する場合

<?php if ($this->fetch('sidebar')): ?>
<?= $this->fetch('sidebar') ?>
<?php endif; ?>

fetchの第2引数を定義すると、ビューブロックがない場合の既定値にできる。

    <?= $this->fetch('sidebar', 'サイドバーがない') ?>

ビューテンプレートの継承

親 src/Template/Common/view.ctp

<h1><?= $this->fetch('title') ?></h1>
<?= $this->fetch('content') ?>

<div class="actions">
    <h3>サイドバー</h3>
    <ul>
    <?= $this->fetch('sidebar') ?>
    </ul>
</div>

子  src/Template/Posts/view.ctp

<?php
// 親のビューを継承する
$this->extend('/Common/view');

// 親の`title`に$postの値を入れる。
$this->assign('title', $post);

// 親のサイドバーの部分を定義
$this->start('sidebar');
?>
<li>
<?php
echo $this->Html->link('edit', [
    'action' => 'edit',
    $post->id
]); ?>
</li>
<?php $this->end(); ?>

// 他はすべて親のcontetのところになる。(contentは特殊)
<?= h($post->body) ?>

ビューブロックの列挙

$list = $this->blocks();

ビューブロックの詳細

既存ブロックへの追加

$this->append('sidebar');
echo $this->element('sidebar/popular_topics');
$this->end();
$this->append('sidebar', $this->element('sidebar/popular_topics'));

既存ブロックの手前に追加

$this->prepend('sidebar', 'このコンテンツはサイドバーの先頭に来ます');

ブロックの消去

$this->reset('sidebar');
// or 
$this->assign('sidebar', '');

レイアウト

デフォルトレイアウト
src/Template/Layout/default.ctp

<!DOCTYPE html>
<html lang="en">
<head>
<title><?= h($this->fetch('title')) ?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- 外部ファイルとスクリプトファイルがここに入れます (詳しくは HTML ヘルパーを参照。) -->
<?php
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>

<!-- もしすべてのビューでメニューを表示したい場合、ここに入れます -->
<div id="header">
    <div id="menu">...</div>
</div>

<!-- ここがビューで表示されるようにしたい場所です -->
<?= $this->fetch('content') ?>

<!-- 表示される各ページにフッターを追加します -->
<div id="footer">...</div>

</body>
</html>

fetchが使われているので子で色々値を入れたりすることがわかる(ビューの継承と同じ)。

デフォルトレイアウトからの変更はControler->viewBuilder()->setLayout

3.4以前は違うらしい。

ビューからも変えられる? View->layout

エレメント

エレメントをテンプレートに埋め込む

echo $this->element('helpbox');

データを渡す。

echo $this->element('helpbox', [
    "helptext" => "hoge!"
]);

エレメントはキャッシュとコールバックを定義できる。

echo $this->element('helpbox', [
        "helptext" => "help!",
        "foobar" => "hogehoge",
    ],
    [
        "cache" => true,
        // エレメントから before/afterRender が呼び出されるには true に設定してください
        "callbacks" => true
    ]
);

キャッシュの詳細は
ビュー - 3.x
をみよ。

しかし、callbackとかでロジックがいるようならビューセルを検討する。

ビューイベント

View.beforeRender
View.beforeRenderFile
View.afterRenderFile
View.afterRender
View.beforeLayout
View.afterLayout

イベントリスナーを登録する?
EventListenerInterface
勉強中
イベントシステム - 3.x

独自のビューロジックを持つビューをつくる

src/Viewに配置、参照の際はViewを除いた部分。

// src/View/HogeView.php の中で
namespace App\View;

use Cake\View\View;

class HogeView extends View
{
    public function render($view = null, $layout = null)
    {
        // カスタムロジック
    }
}

ビューセル

ビューセル - 3.x

src/Template/Cell/に置く。

namespace App\View\Cell;

use Cake\View\Cell;

class HogeCell extends Cell
{

    public function display()
    {
    }

}

bakeでも作れる

bin/cake bake cell Hoge

未読メッセージの数を出す。

namespace App\View\Cell;

use Cake\View\Cell;

class HogeCell extends Cell
{

    public function display()
    {
        $this->loadModel('Messages');
        $unread = $this->Messages->find('unread');
        $this->set('unread_count', $unread->count());
    }

   public function other()
  {
  }
}

ポイントはcellはコントローラと同じようにloadModelでき、setでセルテンプレートにsetできること。
セルテンプレート側では

<!-- src/Template/Cell/Hoge/display.ctp -->
<div class="notification-icon">
    未読メッセージが <?= $unread_count ?> 件あります。
</div>

このあたりもコントローラとの関係と近い。

そのセルをビューテンプレートで用いる

$cell = $this->cell('Hoge');

render() ?>
cellをechoすると__toString()を使用するために意味のあるエラーメッセージを読み取れなくなるらしいのでrenderする。

// HogeCellの他のメソッドを呼び出す

$cell = $this->cell('Hoge::other');

値をcellに渡す。

$cell = $this->cell('Hoge::other', ['ok']);

セル側は

   public function other($okString)
  {
  }


異なるセルテンプレートを用いる。

echo $this->cell('Hoge::other')->render('messages');

もしくは

$cell = $this->cell('Hoge::other');
$cell->template = 'messages';
echo $cell;

セルはキャッシュもできる。
ビューセル - 3.x

$cell = $this->cell('Hoge', [], ['cache' => true]);

コントローラからセルを使いたい

namespace App\Controller;

use App\Controller\AppController;
use Cake\View\CellTrait;

class FooController extends AppController
{
    use CellTrait;

    // 他のコード。
}

ヘルパー

以下を参照している。
ヘルパー - 3.x

使うヘルパーはビューでロードする。

class AppView extends View
{
    public function initialize()
    {
        parent::initialize();
        $this->loadHelper('Html');
        $this->loadHelper('Form');
        $this->loadHelper('Flash');
    }
}

CakePHPにビルトインされているヘルパーはロードしなくても使える。

条件付きでヘルパーを読み込みたい

class AppView extends View
{
    public function initialize()
    {
        parent::initialize();
        if ($this->request->getParam('action') === 'index') {
            $this->loadHelper('ListPage');
        }
    }
}

コントローラ側で読み込んでおきたいならビュービルダーで

class HogesController extends AppController
{
    public function beforeRender(Event $event)
    {
        parent::beforeRender($event);
        $this->viewBuilder()->helpers(['MyHelper']);
    }
}

ヘルパーにオプションを渡す。
3.2以降

namespace App\View\Helper;

use Cake\View\Helper;
use Cake\View\View;

class HogeHelper extends Helper
{
    public function initialize(array $config)
    {
        debug($config);
    }
}

渡す方は

namespace App\Controller;

use App\Controller\AppController;

class HogesController extends AppController
{
    public $helpers = ['Hoge' => ['option1' => 'value1']];
}

等としてやる。

オプションのデフォルト値は必ず定義がいる。

namespace App\View\Helper;

use Cake\View\Helper;
use Cake\View\StringTemplateTrait;

class HogeHelper extends Helper
{

    use StringTemplateTrait;

    protected $_defaultConfig = [
        'option1' => 'o',
    ];
}

設定の読み取り

$option1= $this->Hoge->config('option1');

ヘルパーの別名
勉強中

ヘルパーの使用
echo $this->Hoge->foo('styles');
既存ヘルパーにメソッド追加
/* src/View/Helper/HogeHelper.php (他のヘルパーを使用) */

namespace App\View\Helper;

use Cake\View\Helper;

class HogeHelper extends Helper
{
    public $helpers = ['Html'];

    public function makeEdit($title, $url)
    {
        // 出力に HTML ヘルパーを使用
        // 整形されたデータ:

        $link = $this->Html->link($title, $url, ['class' => 'edit']);

        return '<div class="editOuter">' . $link . '</div>';
    }
}
ヘルパー内からビューの変数にアクセスできる。。。

$this->_View->get()

class HogeHelper extends Helper
{

    public $helpers = ['Html'];

    public someMethod()
    {
        // meta description の設定
        echo $this->Html->meta(
            'description', $this->_View->get('metaDescription'), ['block' => 'meta']
        );
    }
}

エレメントも当然できる。
$this->_View->element()

ヘルパーにある各種コールバック
  1. Helper::beforeRenderFile(Event $event, $viewFile)
  2. Helper::afterRenderFile(Event $event, $viewFile, $content)
  3. Helper::beforeRender(Event $event, $viewFile)
  4. Helper::afterRender(Event $event, $viewFile)
  5. Helper::beforeLayout(Event $event, $layoutFile)
  6. Helper::afterLayout(Event $event, $layoutFile)

テーマ

勉強中

HelloWorld 3回目

モデルと

Helloコントローラ
<?php
namespace App\Controller;

use App\Controller\AppController;

class HelloController extends AppController {
    public $autoRender = true;
    //public $name = "Hello";


    public function index()
    {
        /// Hogesモデルを利用
        $this->loadModel('Hoges');

//        echo "hello world!!";
    //src/Template/Layout/default.ctp レイアウトの使用
        $this->viewBuilder()->autoLayout(true);
        $this->ViewBuilder()->layout('Hello'); //Hello.ctpつかう。

// セットした値はテンプレート側で$poi等で見える。
        $this->set('poi',100);
        $this->set('poi2',200);
        $this->set('poi3',"hoge");

        // Hogesテーブルのすべてをとってくる
        $query = $this->Hoges->find(); // { "id": 1, "setting": 112121 }配列
        $this->set('hoges',$query);

        
    }

    public function other()
    {
        echo "hello other world!!";
    }
}
?>
Helloテンプレ

デフォルトレイアウトが適用されている。

    <h1>midashi</h1>
    <p> hello hello </p>
    <?= $poi ?>
    <?= $poi2 ?>
    <?= $poi3 ?>
    <?= $hoges ?>


    <?php foreach ($hoges as $obj): ?>
    <?= $obj ?>
    <?php endforeach; ?>

<!-- ヘルパーを使ってテーブルで表示 -->
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>SETTING</th>
    </tr>
  </thead>
  <?php
  $arr = $hoges->toArray();// 配列に取り出す
  for ($i = 0 ; $i < count($arr); $i++) {
    echo $this->Html->tableCells(
      $arr[$i]->toArray(),
      ['style' => 'background-color:#f0f0f0'],
      ['style' => 'font-weight:bold'],
      true);
  }
    ?>
  </table>


  <?= $this->element('fooelement', ['va'=>$hoges]) ?>

エレメント
<!-- $vaを必要とする? -->
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>SETTING</th>
    </tr>
  </thead>
  <?php
  $arr = $va->toArray();// 配列に取り出す
  for ($i = 0 ; $i < count($arr); $i++) {
    echo $this->Html->tableCells(
      $arr[$i]->toArray(),
      ['style' => 'background-color:#f0f0f0'],
      ['style' => 'font-weight:bold'],
      true);
  }
    ?>
  </table>
*** Hogesテーブル(bakeで作った)
>|php|
<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Hoges Model
 *
 * @method \App\Model\Entity\Hoge get($primaryKey, $options = [])
 * @method \App\Model\Entity\Hoge newEntity($data = null, array $options = [])
 * @method \App\Model\Entity\Hoge[] newEntities(array $data, array $options = [])
 * @method \App\Model\Entity\Hoge|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Hoge patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
 * @method \App\Model\Entity\Hoge[] patchEntities($entities, array $data, array $options = [])
 * @method \App\Model\Entity\Hoge findOrCreate($search, callable $callback = null, $options = [])
 */
class HogesTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('hoges');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->integer('setting')
            ->allowEmpty('setting');

        return $validator;
    }
}

画像をUIImageに

    UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, [[UIScreen mainScreen] scale]);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, 0);
    CGContextScaleCTM(context, 1.0, 1.0);
    [self.layer renderInContext:context];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;

背景を塗っておかないと変になる。

CakePHPの勉強のまとめ

勉強ログの記事一覧