Phalcon で Flash を拡張してみる


エラーメッセージなどをビューで表示する際には Phalcon では flash を使うときがあるが,これの見た目を変えたいと思うこともある.ここでは Flash を拡張して bootstrap の見た目を使うようにしてみる.

コード

bootstrap のアラートを使うようにするコード.何も設定してなければ bootstrap で使われてる class 名を指定するようにしている.

Bootstrap/Flash/Session.php
<?php

namespace Bootstrap\Flash;

use Phalcon\Flash\Session as PhFlash;

class Session extends PhFlash
{
        public function __construct($cssClasses = null)
        {
                if ($cssClasses === null) {
                        $cssClasses = array(
                                'success' => 'alert alert-success',
                                'notice'  => 'alert alert-info',
                                'warning' => 'alert alert-warning',
                                'error'   => 'alert alert-danger',
                       );
                }
                parent::__construct($cssClasses);
        }
}

同じように bootstrap を使ってアラートを表示してさらに閉じられるようにするクラス.
与えられた class 名に fade in を追加している.

Bootstrap/Flash/Closable.php
<?php

namespace Bootstrap\Flash;

class Closable extends Session
{
        public function __construct($cssClasses = null)
        {   
                if (is_array($cssClasses)) {
                        $cssClasses = array_map(function ($cssClass) {
                                return $cssClass.' fade in';
                        }, $cssClasses);
                }   
                parent::__construct($cssClasses);
        }   

        public function message($type, $message)
        {   
                $button = '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>';
                parent::message($type, $button.$message);
        }   
}

使う場合は DI で flash コンポーネントがこれらのクラスのインスタンスを返すようにする.

config/service.php

$di['flash'] = function () {   
     return new Bootstrap\Flash\Closable();
}; 

動作例

例えばこんなメッセージを出してみる.

controllers/IndexController.php
<?php

use Phalcon\Mvc\Controller;

class IndexController extends Controller
{
    public function indexAction()
    {
        $this->flash->success('Well done! You successfully read this important alert message. ');
        $this->flash->notice('Heads up! This alert needs your attention, but it\'s not super important. ');
        $this->flash->warning('Warning! Better check yourself, you\'re not looking too good. ');
        $this->flash->error('Oh snap! Change a few things up and try submitting again. ');
    }
}

ここでは bower で bootstrap を入れてるので components ディレクトリで指定している.

views/index.volt
<!DOCTYPE html>
<html>
<head>
    <title>Phalcon PHP Framework</title>
    {{ stylesheet_link('components/bootstrap/dist/css/bootstrap.min.css') }}
</head>
<body>
    {{ content() }}
    {{ javascript_include('components/jquery/dist/jquery.min.js') }}
    {{ javascript_include('components/bootstrap/dist/js/bootstrap.min.js') }}
</body>
</html>
views/index/index.volt
<div class="container">
    {{ flash.output() }}
</div>

表示してみるとこんな感じ.x を押すと消える.