eccube-3.0.16\src\Eccube\Application.php eccube-3.0.17\src\Eccube\Application.php
<?php <?php
/* /*
* This file is part of EC-CUBE * This file is part of EC-CUBE
* *
* Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved. * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
* *
* http://www.lockon.co.jp/ * http://www.lockon.co.jp/
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/  */ 
   
namespace Eccube; namespace Eccube;
   
use Binfo\Silex\MobileDetectServiceProvider; use Binfo\Silex\MobileDetectServiceProvider;
use Eccube\Application\ApplicationTrait; use Eccube\Application\ApplicationTrait;
use Eccube\Common\Constant; use Eccube\Common\Constant;
use Eccube\Doctrine\ORM\Mapping\Driver\YamlDriver; use Eccube\Doctrine\ORM\Mapping\Driver\YamlDriver;
use Eccube\EventListener\TransactionListener; use Eccube\EventListener\TransactionListener;
use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
   
class Application extends ApplicationTrait class Application extends ApplicationTrait
{ {
   protected static $instance;    protected static $instance;
   
   protected $initialized = false;    protected $initialized = false;
   protected $initializedPlugin = false;    protected $initializedPlugin = false;
   protected $testMode = false;    protected $testMode = false;
   
   public static function getInstance(array $values = array())    public static function getInstance(array $values = array())
   {    {
       if (!is_object(self::$instance)) {        if (!is_object(self::$instance)) {
           self::$instance = new Application($values);            self::$instance = new Application($values);
       }        }
   
       return self::$instance;        return self::$instance;
   }    }
   
   public static function clearInstance()    public static function clearInstance()
   {    {
       self::$instance = null;        self::$instance = null;
   }    }
   
   final public function __clone()    final public function __clone()
   {    {
       throw new \Exception('Clone is not allowed against '.get_class($this));        throw new \Exception('Clone is not allowed against '.get_class($this));
   }    }
   
   public function __construct(array $values = array())    public function __construct(array $values = array())
   {    {
       parent::__construct($values);        parent::__construct($values);
   
       if (is_null(self::$instance)) {        if (is_null(self::$instance)) {
           self::$instance = $this;            self::$instance = $this;
       }        }
   
       // load config        // load config
       $this->initConfig();        $this->initConfig();
   
       // init monolog        // init monolog
       $this->initLogger();        $this->initLogger();
   }    }
   
   /**    /**
    * Application::runが実行されているか親クラスのプロパティから判定     * Application::runが実行されているか親クラスのプロパティから判定
    *     *
    * @return bool     * @return bool
    */      */ 
   public function isBooted()    public function isBooted()
   {    {
       return $this->booted;        return $this->booted;
   }    }
   
   public function initConfig()    public function initConfig()
   {    {
       // load config        // load config
       $app = $this;        $app = $this;
       $this['config'] = $this->share(function() use ($app) {        $this['config'] = $this->share(function() use ($app) {
           $configAll = array();            $configAll = array();
           $app->parseConfig('constant', $configAll)            $app->parseConfig('constant', $configAll)
               ->parseConfig('path', $configAll)                ->parseConfig('path', $configAll)
               ->parseConfig('config', $configAll)                ->parseConfig('config', $configAll)
               ->parseConfig('database', $configAll)                ->parseConfig('database', $configAll)
               ->parseConfig('mail', $configAll)                ->parseConfig('mail', $configAll)
               ->parseConfig('log', $configAll)                ->parseConfig('log', $configAll)
               ->parseConfig('nav', $configAll, true)                ->parseConfig('nav', $configAll, true)
               ->parseConfig('doctrine_cache', $configAll)                ->parseConfig('doctrine_cache', $configAll)
               ->parseConfig('http_cache', $configAll)                ->parseConfig('http_cache', $configAll)
               ->parseConfig('session_handler', $configAll);                ->parseConfig('session_handler', $configAll);
   
           return $configAll;            return $configAll;
       });        });
   }    }
   
   public function initLogger()    public function initLogger()
   {    {
       $app = $this;        $app = $this;
       $this->register(new ServiceProvider\LogServiceProvider($app));        $this->register(new ServiceProvider\LogServiceProvider($app));
   }    }
   
   public function initialize()    public function initialize()
   {    {
       if ($this->initialized) {        if ($this->initialized) {
           return;            return;
       }        }
   
       // init locale        // init locale
       $this->initLocale();        $this->initLocale();
   
       // init session        // init session
       if (!$this->isSessionStarted()) {        if (!$this->isSessionStarted()) {
           $this->initSession();            $this->initSession();
       }        }
   
       // init twig        // init twig
       $this->initRendering();        $this->initRendering();
   
       // init provider        // init provider
       $this->register(new \Silex\Provider\HttpCacheServiceProvider(), array(        $this->register(new \Silex\Provider\HttpCacheServiceProvider(), array(
           'http_cache.cache_dir' => __DIR__.'/../../app/cache/http/',            'http_cache.cache_dir' => __DIR__.'/../../app/cache/http/',
       ));        ));
       $this->register(new \Silex\Provider\HttpFragmentServiceProvider());        $this->register(new \Silex\Provider\HttpFragmentServiceProvider());
       $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());        $this->register(new \Silex\Provider\UrlGeneratorServiceProvider());
       $this->register(new \Silex\Provider\FormServiceProvider());        $this->register(new \Silex\Provider\FormServiceProvider());
       $this->register(new \Silex\Provider\SerializerServiceProvider());        $this->register(new \Silex\Provider\SerializerServiceProvider());
       $this->register(new \Silex\Provider\ValidatorServiceProvider());        $this->register(new \Silex\Provider\ValidatorServiceProvider());
       $this->register(new MobileDetectServiceProvider());        $this->register(new MobileDetectServiceProvider());
   
       $app = $this;        $app = $this;
       $this->error(function (\Exception $e, $code) use ($app) {        $this->error(function (\Exception $e, $code) use ($app) {
           if ($app['debug']) {            if ($app['debug']) {
               return;                return;
           }            }
   
           switch ($code) {            switch ($code) {
               case 403:                case 403:
                   $title = 'アクセスできません。';                    $title = 'アクセスできません。';
                   $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。';                    $message = 'お探しのページはアクセスができない状況にあるか、移動もしくは削除された可能性があります。';
                   break;                    break;
               case 404:                case 404:
                   $title = 'ページがみつかりません。';                    $title = 'ページがみつかりません。';
                   $message = 'URLに間違いがないかご確認ください。';                    $message = 'URLに間違いがないかご確認ください。';
                   break;                    break;
               default:                default:
                   $title = 'システムエラーが発生しました。';                    $title = 'システムエラーが発生しました。';
                   $message = '大変お手数ですが、サイト管理者までご連絡ください。';                    $message = '大変お手数ですが、サイト管理者までご連絡ください。';
                   break;                    break;
           }            }
   
           return $app->render('error.twig', array(            return $app->render('error.twig', array(
               'error_title' => $title,                'error_title' => $title,
               'error_message' => $message,                'error_message' => $message,
           ));            ));
       });        });
   
       // init mailer        // init mailer
       $this->initMailer();        $this->initMailer();
   
       // init doctrine orm        // init doctrine orm
       $this->initDoctrine();        $this->initDoctrine();
   
       // Set up the DBAL connection now to check for a proper connection to the database.        // Set up the DBAL connection now to check for a proper connection to the database.
       $this->checkDatabaseConnection();        $this->checkDatabaseConnection();
   
       // init security        // init security
       $this->initSecurity();        $this->initSecurity();
   
       // init proxy        // init proxy
       $this->initProxy();        $this->initProxy();
   
       // init ec-cube service provider        // init ec-cube service provider
       $this->register(new ServiceProvider\EccubeServiceProvider());        $this->register(new ServiceProvider\EccubeServiceProvider());
   
       // mount controllers        // mount controllers
       $this->register(new \Silex\Provider\ServiceControllerServiceProvider());        $this->register(new \Silex\Provider\ServiceControllerServiceProvider());
       $this->mount('', new ControllerProvider\FrontControllerProvider());        $this->mount('', new ControllerProvider\FrontControllerProvider());
       $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());        $this->mount('/'.trim($this['config']['admin_route'], '/').'/', new ControllerProvider\AdminControllerProvider());
       Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする        Request::enableHttpMethodParameterOverride(); // PUTやDELETEできるようにする
   
       // add transaction listener        // add transaction listener
       $this['dispatcher']->addSubscriber(new TransactionListener($this));        $this['dispatcher']->addSubscriber(new TransactionListener($this));
   
       // init http cache        // init http cache
       $this->initCacheRequest();        $this->initCacheRequest();
   
       $this->initialized = true;        $this->initialized = true;
   }    }
   
   public function initLocale()    public function initLocale()
   {    {
   
       // timezone        // timezone
       if (!empty($this['config']['timezone'])) {        if (!empty($this['config']['timezone'])) {
           date_default_timezone_set($this['config']['timezone']);            date_default_timezone_set($this['config']['timezone']);
       }        }
   
       $this->register(new \Silex\Provider\TranslationServiceProvider(), array(        $this->register(new \Silex\Provider\TranslationServiceProvider(), array(
           'locale' => $this['config']['locale'],            'locale' => $this['config']['locale'],
           'translator.cache_dir' => $this['debug'] ? null : $this['config']['root_dir'].'/app/cache/translator',            'translator.cache_dir' => $this['debug'] ? null : $this['config']['root_dir'].'/app/cache/translator',
       ));        ));
       $this['translator'] = $this->share($this->extend('translator', function ($translator, \Silex\Application $app) {        $this['translator'] = $this->share($this->extend('translator', function ($translator, \Silex\Application $app) {
           $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());            $translator->addLoader('yaml', new \Symfony\Component\Translation\Loader\YamlFileLoader());
   
           $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';            $file = __DIR__.'/Resource/locale/validator.'.$app['locale'].'.yml';
           if (file_exists($file)) {            if (file_exists($file)) {
               $translator->addResource('yaml', $file, $app['locale'], 'validators');                $translator->addResource('yaml', $file, $app['locale'], 'validators');
           }            }
   
           $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';            $file = __DIR__.'/Resource/locale/message.'.$app['locale'].'.yml';
           if (file_exists($file)) {            if (file_exists($file)) {
               $translator->addResource('yaml', $file, $app['locale']);                $translator->addResource('yaml', $file, $app['locale']);
           }            }
   
           return $translator;            return $translator;
       }));        }));
   }    }
   
   public function initSession()    public function initSession()
   {    {
       $this->register(new \Silex\Provider\SessionServiceProvider(), array(        $this->register(new \Silex\Provider\SessionServiceProvider(), array(
           'session.storage.save_path' => $this['config']['root_dir'].'/app/cache/eccube/session',            'session.storage.save_path' => $this['config']['root_dir'].'/app/cache/eccube/session',
           'session.storage.options' => array(            'session.storage.options' => array(
               'name' => $this['config']['cookie_name'],                'name' => $this['config']['cookie_name'],
               'cookie_path' => $this['config']['root_urlpath'] ?: '/',                'cookie_path' => $this['config']['root_urlpath'] ?: '/',
               'cookie_secure' => $this['config']['force_ssl'],                'cookie_secure' => $this['config']['force_ssl'],
               'cookie_lifetime' => $this['config']['cookie_lifetime'],                'cookie_lifetime' => $this['config']['cookie_lifetime'],
               'cookie_httponly' => true,                'cookie_httponly' => true,
               // cookie_domainは指定しない                // cookie_domainは指定しない
               // http://blog.tokumaru.org/2011/10/cookiedomain.html                // http://blog.tokumaru.org/2011/10/cookiedomain.html
           ),            ),
       ));        ));
   
       $options = $this['config']['session_handler'];        $options = $this['config']['session_handler'];
   
       if ($options['enabled']) {        if ($options['enabled']) {
           // @see http://silex.sensiolabs.org/doc/providers/session.html#custom-session-configurations            // @see http://silex.sensiolabs.org/doc/providers/session.html#custom-session-configurations
           $this['session.storage.handler'] = null;            $this['session.storage.handler'] = null;
           ini_set('session.save_handler', $options['save_handler']);            ini_set('session.save_handler', $options['save_handler']);
           ini_set('session.save_path', $options['save_path']);            ini_set('session.save_path', $options['save_path']);
       }        }
   }    }
   
   public function initRendering()    public function initRendering()
   {    {
       $this->register(new \Silex\Provider\TwigServiceProvider(), array(        $this->register(new \Silex\Provider\TwigServiceProvider(), array(
           'twig.form.templates' => array('Form/form_layout.twig'),            'twig.form.templates' => array('Form/form_layout.twig'),
       ));        ));
       $this['twig'] = $this->share($this->extend('twig', function (\Twig_Environment $twig, \Silex\Application $app) {        $this['twig'] = $this->share($this->extend('twig', function (\Twig_Environment $twig, \Silex\Application $app) {
           $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));            $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));
           $twig->addExtension(new \Twig_Extension_StringLoader());            $twig->addExtension(new \Twig_Extension_StringLoader());
   
           return $twig;            return $twig;
       }));        }));
   
       $this->before(function (Request $request, \Silex\Application $app) {        $this->before(function (Request $request, \Silex\Application $app) {
           $app['admin'] = false;            $app['admin'] = false;
           $app['front'] = false;            $app['front'] = false;
           $pathinfo = rawurldecode($request->getPathInfo());            $pathinfo = rawurldecode($request->getPathInfo());
           if (strpos($pathinfo, '/'.trim($app['config']['admin_route'], '/').'/') === 0) {            if (strpos($pathinfo, '/'.trim($app['config']['admin_route'], '/').'/') === 0) {
               $app['admin'] = true;                $app['admin'] = true;
           } else {            } else {
               $app['front'] = true;                $app['front'] = true;
           }            }
   
           // フロント or 管理画面ごとにtwigの探索パスを切り替える.            // フロント or 管理画面ごとにtwigの探索パスを切り替える.
           $app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twig, \Silex\Application $app) {            $app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twig, \Silex\Application $app) {
               $paths = array();                $paths = array();
   
               // 互換性がないのでprofiler とproduction 時のcacheを分離する                // 互換性がないのでprofiler とproduction 時のcacheを分離する
               if (isset($app['profiler'])) {                if (isset($app['profiler'])) {
                   $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/profiler/';
               } else {                } else {
                   $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';                    $cacheBaseDir = __DIR__.'/../../app/cache/twig/production/';
               }                }
   
               if ($app->isAdminRequest()) {                if ($app->isAdminRequest()) {
                   if (file_exists(__DIR__.'/../../app/template/admin')) {                    if (file_exists(__DIR__.'/../../app/template/admin')) {
                       $paths[] = __DIR__.'/../../app/template/admin';                        $paths[] = __DIR__.'/../../app/template/admin';
                   }                    }
                   $paths[] = $app['config']['template_admin_realdir'];                    $paths[] = $app['config']['template_admin_realdir'];
                   $paths[] = __DIR__.'/../../app/Plugin';                    $paths[] = __DIR__.'/../../app/Plugin';
                   $cache = $cacheBaseDir.'admin';                    $cache = $cacheBaseDir.'admin';
   
               } else {                } else {
                   if (file_exists($app['config']['template_realdir'])) {                    if (file_exists($app['config']['template_realdir'])) {
                       $paths[] = $app['config']['template_realdir'];                        $paths[] = $app['config']['template_realdir'];
                   }                    }
                   $paths[] = $app['config']['template_default_realdir'];                    $paths[] = $app['config']['template_default_realdir'];
                   $paths[] = __DIR__.'/../../app/Plugin';                    $paths[] = __DIR__.'/../../app/Plugin';
                   $cache = $cacheBaseDir.$app['config']['template_code'];                    $cache = $cacheBaseDir.$app['config']['template_code'];
                   $app['front'] = true;                    $app['front'] = true;
               }                }
               $twig->setCache($cache);                $twig->setCache($cache);
               $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));                $app['twig.loader']->addLoader(new \Twig_Loader_Filesystem($paths));
   
               return $twig;                return $twig;
           }));            }));
   
           // 管理画面のIP制限チェック.            // 管理画面のIP制限チェック.
           if ($app->isAdminRequest()) {            if ($app->isAdminRequest()) {
               // IP制限チェック                // IP制限チェック
               $allowHost = $app['config']['admin_allow_host'];                $allowHost = $app['config']['admin_allow_host'];
               if (count($allowHost) > 0) {                if (count($allowHost) > 0) {
                   if (array_search($app['request']->getClientIp(), $allowHost) === false) {                    if (array_search($app['request']->getClientIp(), $allowHost) === false) {
                       throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();                        throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();
                   }                    }
               }                }
           }            }
       }, self::EARLY_EVENT);        }, self::EARLY_EVENT);
   
       // twigのグローバル変数を定義.        // twigのグローバル変数を定義.
       $app = $this;        $app = $this;
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function (\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function (\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
           // 未ログイン時にマイページや管理画面以下にアクセスするとSubRequestで実行されるため,            // 未ログイン時にマイページや管理画面以下にアクセスするとSubRequestで実行されるため,
           // $event->isMasterRequest()ではなく、グローバル変数が初期化済かどうかの判定を行う            // $event->isMasterRequest()ではなく、グローバル変数が初期化済かどうかの判定を行う
           if (isset($app['twig_global_initialized']) && $app['twig_global_initialized'] === true) {            if (isset($app['twig_global_initialized']) && $app['twig_global_initialized'] === true) {
               return;                return;
           }            }
           // ショップ基本情報            // ショップ基本情報
           $BaseInfo = $app['eccube.repository.base_info']->get();            $BaseInfo = $app['eccube.repository.base_info']->get();
           $app['twig']->addGlobal('BaseInfo', $BaseInfo);            $app['twig']->addGlobal('BaseInfo', $BaseInfo);
   
           if ($app->isAdminRequest()) {            if ($app->isAdminRequest()) {
               // 管理画面                // 管理画面
               // 管理画面メニュー                // 管理画面メニュー
               $menus = array('', '', '');                $menus = array('', '', '');
               $app['twig']->addGlobal('menus', $menus);                $app['twig']->addGlobal('menus', $menus);
   
               $Member = $app->user();                $Member = $app->user();
               if (is_object($Member)) {                if (is_object($Member)) {
                   // ログインしていれば管理者のロールを取得                    // ログインしていれば管理者のロールを取得
                   $AuthorityRoles = $app['eccube.repository.authority_role']->findBy(array('Authority' => $Member->getAuthority()));                    $AuthorityRoles = $app['eccube.repository.authority_role']->findBy(array('Authority' => $Member->getAuthority()));
   
                   $roles = array();                    $roles = array();
                   foreach ($AuthorityRoles as $AuthorityRole) {                    foreach ($AuthorityRoles as $AuthorityRole) {
                       // 管理画面でメニュー制御するため相対パス全てをセット                        // 管理画面でメニュー制御するため相対パス全てをセット
                       $roles[] = $app['request']->getBaseUrl().'/'.$app['config']['admin_route'].$AuthorityRole->getDenyUrl();                        $roles[] = $app['request']->getBaseUrl().'/'.$app['config']['admin_route'].$AuthorityRole->getDenyUrl();
                   }                    }
   
                   $app['twig']->addGlobal('AuthorityRoles', $roles);                    $app['twig']->addGlobal('AuthorityRoles', $roles);
               }                }
   
           } else {            } else {
               // フロント画面                // フロント画面
               $request = $event->getRequest();                $request = $event->getRequest();
               $route = $request->attributes->get('_route');                $route = $request->attributes->get('_route');
               $page = $route;                $page = $route;
               // ユーザ作成画面                // ユーザ作成画面
               if ($route === 'user_data') {                if ($route === 'user_data') {
                   $params = $request->attributes->get('_route_params');                    $params = $request->attributes->get('_route_params');
                   $route = $params['route'];                    $route = $params['route'];
                   // プレビュー画面                    // プレビュー画面
               } elseif ($request->get('preview')) {                } elseif ($request->get('preview')) {
                   $route = 'preview';                    $route = 'preview';
               }                }
   
               try {                try {
                   $DeviceType = $app['eccube.repository.master.device_type']                    $DeviceType = $app['eccube.repository.master.device_type']
                       ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);                        ->find(\Eccube\Entity\Master\DeviceType::DEVICE_TYPE_PC);
                   $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route, $page);                    $PageLayout = $app['eccube.repository.page_layout']->getByUrl($DeviceType, $route, $page);
               } catch (\Doctrine\ORM\NoResultException $e) {                } catch (\Doctrine\ORM\NoResultException $e) {
                   $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType);                    $PageLayout = $app['eccube.repository.page_layout']->newPageLayout($DeviceType);
               }                }
   
               $app['twig']->addGlobal('PageLayout', $PageLayout);                $app['twig']->addGlobal('PageLayout', $PageLayout);
               $app['twig']->addGlobal('title', $PageLayout->getName());                $app['twig']->addGlobal('title', $PageLayout->getName());
           }            }
   
           $app['twig_global_initialized'] = true;            $app['twig_global_initialized'] = true;
       });        });
   }    }
   
   public function initMailer()    public function initMailer()
   {    {
   
       // メール送信時の文字エンコード指定(デフォルトはUTF-8)        // メール送信時の文字エンコード指定(デフォルトはUTF-8)
       if (isset($this['config']['mail']['charset_iso_2022_jp']) && is_bool($this['config']['mail']['charset_iso_2022_jp'])) {        if (isset($this['config']['mail']['charset_iso_2022_jp']) && is_bool($this['config']['mail']['charset_iso_2022_jp'])) {
           if ($this['config']['mail']['charset_iso_2022_jp'] === true) {            if ($this['config']['mail']['charset_iso_2022_jp'] === true) {
               \Swift::init(function () {                \Swift::init(function () {
                   \Swift_DependencyContainer::getInstance()                    \Swift_DependencyContainer::getInstance()
                       ->register('mime.qpheaderencoder')                        ->register('mime.qpheaderencoder')
                       ->asAliasOf('mime.base64headerencoder');                        ->asAliasOf('mime.base64headerencoder');
                   \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');                    \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
               });                });
           }            }
       }        }
   
       $this->register(new \Silex\Provider\SwiftmailerServiceProvider());        $this->register(new \Silex\Provider\SwiftmailerServiceProvider());
       $this['swiftmailer.options'] = $this['config']['mail'];        $this['swiftmailer.options'] = $this['config']['mail'];
   
       if (isset($this['config']['mail']['use_spool']) && is_bool($this['config']['mail']['use_spool'])) {        if (isset($this['config']['mail']['use_spool']) && is_bool($this['config']['mail']['use_spool'])) {
           $this['swiftmailer.use_spool'] = $this['config']['mail']['use_spool'];            $this['swiftmailer.use_spool'] = $this['config']['mail']['use_spool'];
       }        }
       // デフォルトはsmtpを使用        // デフォルトはsmtpを使用
       $transport = $this['config']['mail']['transport'];        $transport = $this['config']['mail']['transport'];
       if ($transport == 'sendmail') {        if ($transport == 'sendmail') {
           $this['swiftmailer.transport'] = \Swift_SendmailTransport::newInstance();            $this['swiftmailer.transport'] = \Swift_SendmailTransport::newInstance();
       } elseif ($transport == 'mail') {        } elseif ($transport == 'mail') {
           $this['swiftmailer.transport'] = \Swift_MailTransport::newInstance();            $this['swiftmailer.transport'] = \Swift_MailTransport::newInstance();
       }        }
   }    }
   
   public function initDoctrine()    public function initDoctrine()
   {    {
       $this->register(new \Silex\Provider\DoctrineServiceProvider(), array(        $this->register(new \Silex\Provider\DoctrineServiceProvider(), array(
           'dbs.options' => array(            'dbs.options' => array(
               'default' => $this['config']['database']                'default' => $this['config']['database']
           )));            )));
       $this->register(new \Saxulum\DoctrineOrmManagerRegistry\Silex\Provider\DoctrineOrmManagerRegistryProvider());        $this->register(new \Saxulum\DoctrineOrmManagerRegistry\Silex\Provider\DoctrineOrmManagerRegistryProvider());
   
       // プラグインのmetadata定義を合わせて行う.        // プラグインのmetadata定義を合わせて行う.
       $pluginConfigs = $this->getPluginConfigAll();        $pluginConfigs = $this->getPluginConfigAll();
       $ormMappings = array();        $ormMappings = array();
       $ormMappings[] = array(        $ormMappings[] = array(
           'type' => 'yml',            'type' => 'yml',
           'namespace' => 'Eccube\Entity',            'namespace' => 'Eccube\Entity',
           'path' => array(            'path' => array(
               __DIR__.'/Resource/doctrine',                __DIR__.'/Resource/doctrine',
               __DIR__.'/Resource/doctrine/master',                __DIR__.'/Resource/doctrine/master',
           ),            ),
       );        );
   
       foreach ($pluginConfigs as $code) {        foreach ($pluginConfigs as $code) {
           $config = $code['config'];            $config = $code['config'];
           // Doctrine Extend            // Doctrine Extend
           if (isset($config['orm.path']) && is_array($config['orm.path'])) {            if (isset($config['orm.path']) && is_array($config['orm.path'])) {
               $paths = array();                $paths = array();
               foreach ($config['orm.path'] as $path) {                foreach ($config['orm.path'] as $path) {
                   $paths[] = $this['config']['plugin_realdir'].'/'.$config['code'].$path;                    $paths[] = $this['config']['plugin_realdir'].'/'.$config['code'].$path;
               }                }
               $ormMappings[] = array(                $ormMappings[] = array(
                   'type' => 'yml',                    'type' => 'yml',
                   'namespace' => 'Plugin\\'.$config['code'].'\\Entity',                    'namespace' => 'Plugin\\'.$config['code'].'\\Entity',
                   'path' => $paths,                    'path' => $paths,
               );                );
           }            }
       }        }
   
       $options = array(        $options = array(
           'mappings' => $ormMappings            'mappings' => $ormMappings
       );        );
   
       if (!$this['debug']) {        if (!$this['debug']) {
           $cacheDrivers = array();            $cacheDrivers = array();
           if (array_key_exists('doctrine_cache', $this['config'])) {            if (array_key_exists('doctrine_cache', $this['config'])) {
               $cacheDrivers = $this['config']['doctrine_cache'];                $cacheDrivers = $this['config']['doctrine_cache'];
           }            }
   
           if (array_key_exists('metadata_cache', $cacheDrivers)) {            if (array_key_exists('metadata_cache', $cacheDrivers)) {
               $options['metadata_cache'] = $cacheDrivers['metadata_cache'];                $options['metadata_cache'] = $cacheDrivers['metadata_cache'];
           }            }
           if (array_key_exists('query_cache', $cacheDrivers)) {            if (array_key_exists('query_cache', $cacheDrivers)) {
               $options['query_cache'] = $cacheDrivers['query_cache'];                $options['query_cache'] = $cacheDrivers['query_cache'];
           }            }
           if (array_key_exists('result_cache', $cacheDrivers)) {            if (array_key_exists('result_cache', $cacheDrivers)) {
               $options['result_cache'] = $cacheDrivers['result_cache'];                $options['result_cache'] = $cacheDrivers['result_cache'];
           }            }
           if (array_key_exists('hydration_cache', $cacheDrivers)) {            if (array_key_exists('hydration_cache', $cacheDrivers)) {
               $options['hydration_cache'] = $cacheDrivers['hydration_cache'];                $options['hydration_cache'] = $cacheDrivers['hydration_cache'];
           }            }
       }        }
   
       $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(        $this->register(new \Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider(), array(
           'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine/proxies',            'orm.proxies_dir' => __DIR__.'/../../app/cache/doctrine/proxies',
           'orm.em.options' => $options,            'orm.em.options' => $options,
           'orm.custom.functions.string' => array(            'orm.custom.functions.string' => array(
               'NORMALIZE' => 'Eccube\Doctrine\ORM\Query\Normalize',                'NORMALIZE' => 'Eccube\Doctrine\ORM\Query\Normalize',
           ),            ),
           'orm.custom.functions.numeric' => array(            'orm.custom.functions.numeric' => array(
               'EXTRACT' => 'Eccube\Doctrine\ORM\Query\Extract',                'EXTRACT' => 'Eccube\Doctrine\ORM\Query\Extract',
           ),            ),
       ));        ));
   
       /**        /**
        * YamlDriverのPHP7対応. Doctrine2.4で修正されれば不要.         * YamlDriverのPHP7対応. Doctrine2.4で修正されれば不要.
        * @see https://github.com/EC-CUBE/ec-cube/issues/1338         * @see https://github.com/EC-CUBE/ec-cube/issues/1338
        */          */ 
       $config = $this['orm.em']->getConfiguration();        $config = $this['orm.em']->getConfiguration();
       /** @var $driver \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain */         /** @var $driver \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain */ 
       $chain = $config->getMetadataDriverImpl();        $chain = $config->getMetadataDriverImpl();
       // $ormMappingsの1要素ごとにDriverが生成されている.        // $ormMappingsの1要素ごとにDriverが生成されている.
       $drivers = $chain->getDrivers();        $drivers = $chain->getDrivers();
       foreach ($drivers as $namespace => $oldDriver) {        foreach ($drivers as $namespace => $oldDriver) {
           /** @var $newDriver \Eccube\Doctrine\ORM\Mapping\Driver\YamlDriver */             /** @var $newDriver \Eccube\Doctrine\ORM\Mapping\Driver\YamlDriver */ 
           $newDriver = new YamlDriver($oldDriver->getLocator());            $newDriver = new YamlDriver($oldDriver->getLocator());
           // 修正したDriverに差し替える. メソッド名はaddだけど実際はsetしてる.            // 修正したDriverに差し替える. メソッド名はaddだけど実際はsetしてる.
           $chain->addDriver($newDriver, $namespace);            $chain->addDriver($newDriver, $namespace);
       }        }
   }    }
   
   public function initSecurity()    public function initSecurity()
   {    {
       $this->register(new \Silex\Provider\SecurityServiceProvider());        $this->register(new \Silex\Provider\SecurityServiceProvider());
       $this->register(new \Silex\Provider\RememberMeServiceProvider());        $this->register(new \Silex\Provider\RememberMeServiceProvider());
   
       $this['security.firewalls'] = array(        $this['security.firewalls'] = array(
           'admin' => array(            'admin' => array(
               'pattern' => "^/{$this['config']['admin_route']}/",                'pattern' => "^/{$this['config']['admin_route']}/",
               'form' => array(                'form' => array(
                   'login_path' => "/{$this['config']['admin_route']}/login",                    'login_path' => "/{$this['config']['admin_route']}/login",
                   'check_path' => "/{$this['config']['admin_route']}/login_check",                    'check_path' => "/{$this['config']['admin_route']}/login_check",
                   'username_parameter' => 'login_id',                    'username_parameter' => 'login_id',
                   'password_parameter' => 'password',                    'password_parameter' => 'password',
                   'with_csrf' => true,                    'with_csrf' => true,
                   'use_forward' => true,                    'use_forward' => true,
                   'default_target_path' => "/{$this['config']['admin_route']}",                    'default_target_path' => "/{$this['config']['admin_route']}",
               ),                ),
               'logout' => array(                'logout' => array(
                   'logout_path' => "/{$this['config']['admin_route']}/logout",                    'logout_path' => "/{$this['config']['admin_route']}/logout",
                   'target_url' => "/{$this['config']['admin_route']}/",                    'target_url' => "/{$this['config']['admin_route']}/",
               ),                ),
               'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
               'anonymous' => true,                'anonymous' => true,
           ),            ),
           'customer' => array(            'customer' => array(
               'pattern' => '^/',                'pattern' => '^/',
               'form' => array(                'form' => array(
                   'login_path' => '/mypage/login',                    'login_path' => '/mypage/login',
                   'check_path' => '/login_check',                    'check_path' => '/login_check',
                   'username_parameter' => 'login_email',                    'username_parameter' => 'login_email',
                   'password_parameter' => 'login_pass',                    'password_parameter' => 'login_pass',
                   'with_csrf' => true,                    'with_csrf' => true,
                   'use_forward' => true,                    'use_forward' => true,
               ),                ),
               'logout' => array(                'logout' => array(
                   'logout_path' => '/logout',                    'logout_path' => '/logout',
                   'target_url' => '/',                    'target_url' => '/',
               ),                ),
               'remember_me' => array(                'remember_me' => array(
                   'key' => sha1($this['config']['auth_magic']),                    'key' => sha1($this['config']['auth_magic']),
                   'name' => $this['config']['cookie_name'].'_rememberme',                    'name' => $this['config']['cookie_name'].'_rememberme',
                   // lifetimeはデフォルトの1年間にする                    // lifetimeはデフォルトの1年間にする
                   // 'lifetime' => $this['config']['cookie_lifetime'],                    // 'lifetime' => $this['config']['cookie_lifetime'],
                   'path' => $this['config']['root_urlpath'] ?: '/',                    'path' => $this['config']['root_urlpath'] ?: '/',
                   'secure' => $this['config']['force_ssl'],                    'secure' => $this['config']['force_ssl'],
                   'httponly' => true,                    'httponly' => true,
                   'always_remember_me' => false,                    'always_remember_me' => false,
                   'remember_me_parameter' => 'login_memory',                    'remember_me_parameter' => 'login_memory',
               ),                ),
               'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
               'anonymous' => true,                'anonymous' => true,
           ),            ),
       );        );
   
       $channel = null;        $channel = null;
       // 強制SSL        // 強制SSL
       if ($this['config']['force_ssl'] == \Eccube\Common\Constant::ENABLED) {        if ($this['config']['force_ssl'] == \Eccube\Common\Constant::ENABLED) {
           $channel = "https";            $channel = "https";
       }        }
   
       $this['security.access_rules'] = array(        $this['security.access_rules'] = array(
           array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),            array("^/{$this['config']['admin_route']}/login", 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),
           array("^/{$this['config']['admin_route']}/", 'ROLE_ADMIN', $channel),            array("^/{$this['config']['admin_route']}/", 'ROLE_ADMIN', $channel),
           array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),            array('^/mypage/login', 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),
           array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),            array('^/mypage/withdraw_complete', 'IS_AUTHENTICATED_ANONYMOUSLY', $channel),
           array('^/mypage/change', 'IS_AUTHENTICATED_FULLY', $channel),            array('^/mypage/change', 'IS_AUTHENTICATED_FULLY', $channel),
           array('^/mypage', 'ROLE_USER', $channel),            array('^/mypage', 'ROLE_USER', $channel),
       );        );
   
       $this['eccube.password_encoder'] = $this->share(function ($app) {        $this['eccube.password_encoder'] = $this->share(function ($app) {
           return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);            return new \Eccube\Security\Core\Encoder\PasswordEncoder($app['config']);
       });        });
       $this['security.encoder_factory'] = $this->share(function ($app) {        $this['security.encoder_factory'] = $this->share(function ($app) {
           return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(            return new \Symfony\Component\Security\Core\Encoder\EncoderFactory(array(
               'Eccube\Entity\Customer' => $app['eccube.password_encoder'],                'Eccube\Entity\Customer' => $app['eccube.password_encoder'],
               'Eccube\Entity\Member' => $app['eccube.password_encoder'],                'Eccube\Entity\Member' => $app['eccube.password_encoder'],
           ));            ));
       });        });
       $this['eccube.event_listner.security'] = $this->share(function ($app) {        $this['eccube.event_listner.security'] = $this->share(function ($app) {
           return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);            return new \Eccube\EventListener\SecurityEventListener($app['orm.em']);
       });        });
       $this['user'] = function ($app) {        $this['user'] = function ($app) {
           $token = $app['security']->getToken();            $token = $app['security']->getToken();
   
           return ($token !== null) ? $token->getUser() : null;            return ($token !== null) ? $token->getUser() : null;
       };        };
   
       // ログイン時のイベントを設定.        // ログイン時のイベントを設定.
       $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));        $this['dispatcher']->addListener(\Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN, array($this['eccube.event_listner.security'], 'onInteractiveLogin'));
   
       // Voterの設定        // Voterの設定
       $app = $this;        $app = $this;
       $this['authority_voter'] = $this->share(function ($app) {        $this['authority_voter'] = $this->share(function ($app) {
           return new \Eccube\Security\Voter\AuthorityVoter($app);            return new \Eccube\Security\Voter\AuthorityVoter($app);
       });        });
   
       $app['security.voters'] = $app->extend('security.voters', function ($voters) use ($app) {        $app['security.voters'] = $app->extend('security.voters', function ($voters) use ($app) {
           $voters[] = $app['authority_voter'];            $voters[] = $app['authority_voter'];
   
           return $voters;            return $voters;
       });        });
   
       $this['security.access_manager'] = $this->share(function ($app) {        $this['security.access_manager'] = $this->share(function ($app) {
           return new \Symfony\Component\Security\Core\Authorization\AccessDecisionManager($app['security.voters'], 'unanimous');            return new \Symfony\Component\Security\Core\Authorization\AccessDecisionManager($app['security.voters'], 'unanimous');
       });        });
   
.         $app = $this;
         $app['security.authentication.success_handler.admin'] = $app->share(function ($app) {
             $handler = new \Eccube\Security\Http\Authentication\EccubeAuthenticationSuccessHandler(
                 $app['security.http_utils'],
                 $app['security.firewalls']['admin']['form']
             );
   
             $handler->setProviderKey('admin');
   
             return $handler;
         });
   
         $app['security.authentication.failure_handler.admin'] = $app->share(function ($app) {
             return new \Eccube\Security\Http\Authentication\EccubeAuthenticationFailureHandler(
                 $app,
                 $app['security.http_utils'],
                 $app['security.firewalls']['admin']['form'],
                 $app['logger']
             );
         });
   
         $app['security.authentication.success_handler.customer'] = $app->share(function ($app) {
             $handler = new \Eccube\Security\Http\Authentication\EccubeAuthenticationSuccessHandler(
                 $app['security.http_utils'],
                 $app['security.firewalls']['customer']['form']
             );
   
             $handler->setProviderKey('customer');
   
             return $handler;
         });
   
         $app['security.authentication.failure_handler.customer'] = $app->share(function ($app) {
             return new \Eccube\Security\Http\Authentication\EccubeAuthenticationFailureHandler(
                 $app,
                 $app['security.http_utils'],
                 $app['security.firewalls']['customer']['form'],
                 $app['logger']
             );
         });
   }    }
   
   /**    /**
    * ロードバランサー、プロキシサーバの設定を行う     * ロードバランサー、プロキシサーバの設定を行う
    */      */ 
   public function initProxy()    public function initProxy()
   {    {
       $config = $this['config'];        $config = $this['config'];
       if (isset($config['trusted_proxies_connection_only']) && !empty($config['trusted_proxies_connection_only'])) {        if (isset($config['trusted_proxies_connection_only']) && !empty($config['trusted_proxies_connection_only'])) {
           $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($config) {            $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($config) {
               // サブリクエストのREMOTE_ADDRも動的に設定を行う必要があるため、KernelEvents::REQUESTを使用する                // サブリクエストのREMOTE_ADDRも動的に設定を行う必要があるため、KernelEvents::REQUESTを使用する
               Request::setTrustedProxies(array_merge(array($event->getRequest()->server->get('REMOTE_ADDR')), $config['trusted_proxies']));                Request::setTrustedProxies(array_merge(array($event->getRequest()->server->get('REMOTE_ADDR')), $config['trusted_proxies']));
           }, self::EARLY_EVENT);            }, self::EARLY_EVENT);
       } elseif (isset($config['trusted_proxies']) && !empty($config['trusted_proxies'])) {        } elseif (isset($config['trusted_proxies']) && !empty($config['trusted_proxies'])) {
           Request::setTrustedProxies($config['trusted_proxies']);            Request::setTrustedProxies($config['trusted_proxies']);
       }        }
   }    }
   
   public function initializePlugin()    public function initializePlugin()
   {    {
       if ($this->initializedPlugin) {        if ($this->initializedPlugin) {
           return;            return;
       }        }
   
       // setup event dispatcher        // setup event dispatcher
       $this->initPluginEventDispatcher();        $this->initPluginEventDispatcher();
   
       // load plugin        // load plugin
       $this->loadPlugin();        $this->loadPlugin();
   
       $this->initializedPlugin = true;        $this->initializedPlugin = true;
   }    }
   
   public function initPluginEventDispatcher()    public function initPluginEventDispatcher()
   {    {
       // EventDispatcher        // EventDispatcher
       $this['eccube.event.dispatcher'] = $this->share(function () {        $this['eccube.event.dispatcher'] = $this->share(function () {
           return new EventDispatcher();            return new EventDispatcher();
       });        });
   
       $app = $this;        $app = $this;
   
       // hook point        // hook point
       $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {        $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
           $hookpoint = 'eccube.event.app.before';            $hookpoint = 'eccube.event.app.before';
           $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
       }, self::EARLY_EVENT);        }, self::EARLY_EVENT);
   
       $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {        $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
           $hookpoint = "eccube.event.controller.$route.before";            $hookpoint = "eccube.event.controller.$route.before";
           $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
       });        });
   
       $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {        $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
           $hookpoint = "eccube.event.controller.$route.after";            $hookpoint = "eccube.event.controller.$route.after";
           $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
       });        });
   
       $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {        $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
           $hookpoint = 'eccube.event.app.after';            $hookpoint = 'eccube.event.app.after';
           $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
       }, self::LATE_EVENT);        }, self::LATE_EVENT);
   
       $this->on(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($app) {        $this->on(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($app) {
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
           $hookpoint = "eccube.event.controller.$route.finish";            $hookpoint = "eccube.event.controller.$route.finish";
           $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);            $app['eccube.event.dispatcher']->dispatch($hookpoint, $event);
       });        });
   
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
           $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.render.'.$route.'.before', $event);
       });        });
   
       // Request Event        // Request Event
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function (\Symfony\Component\HttpKernel\Event\GetResponseEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, function (\Symfony\Component\HttpKernel\Event\GetResponseEvent $event) use ($app) {
   
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
   
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
   
           if (is_null($route)) {            if (is_null($route)) {
               return;                return;
           }            }
   
           $app['monolog']->debug('KernelEvents::REQUEST '.$route);            $app['monolog']->debug('KernelEvents::REQUEST '.$route);
   
           // 全体            // 全体
           $app['eccube.event.dispatcher']->dispatch('eccube.event.app.request', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.request', $event);
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.request', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.request', $event);
           } else {            } else {
               // フロント画面                // フロント画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.front.request', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.request', $event);
           }            }
   
           // ルーティング単位            // ルーティング単位
           $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.request", $event);            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.request", $event);
   
       }, 30); // Routing(32)が解決しし, 認証判定(8)が実行される前のタイミング.        }, 30); // Routing(32)が解決しし, 認証判定(8)が実行される前のタイミング.
   
       // Controller Event        // Controller Event
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function (\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER, function (\Symfony\Component\HttpKernel\Event\FilterControllerEvent $event) use ($app) {
   
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
   
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
   
           if (is_null($route)) {            if (is_null($route)) {
               return;                return;
           }            }
   
           $app['monolog']->debug('KernelEvents::CONTROLLER '.$route);            $app['monolog']->debug('KernelEvents::CONTROLLER '.$route);
   
           // 全体            // 全体
           $app['eccube.event.dispatcher']->dispatch('eccube.event.app.controller', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.controller', $event);
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.controller', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.controller', $event);
           } else {            } else {
               // フロント画面                // フロント画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.front.controller', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.controller', $event);
           }            }
   
           // ルーティング単位            // ルーティング単位
           $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.controller", $event);            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.controller", $event);
       });        });
   
       // Response Event        // Response Event
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
   
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
   
           if (is_null($route)) {            if (is_null($route)) {
               return;                return;
           }            }
   
           $app['monolog']->debug('KernelEvents::RESPONSE '.$route);            $app['monolog']->debug('KernelEvents::RESPONSE '.$route);
   
           // ルーティング単位            // ルーティング単位
           $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.response", $event);            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.response", $event);
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.response', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.response', $event);
           } else {            } else {
               // フロント画面                // フロント画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.front.response', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.response', $event);
           }            }
   
           // 全体            // 全体
           $app['eccube.event.dispatcher']->dispatch('eccube.event.app.response', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.response', $event);
       });        });
   
       // Exception Event        // Exception Event
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, function (\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::EXCEPTION, function (\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event) use ($app) {
   
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
   
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
   
           if (is_null($route)) {            if (is_null($route)) {
               return;                return;
           }            }
   
           $app['monolog']->debug('KernelEvents::EXCEPTION '.$route);            $app['monolog']->debug('KernelEvents::EXCEPTION '.$route);
   
           // ルーティング単位            // ルーティング単位
           $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.exception", $event);            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.exception", $event);
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.exception', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.exception', $event);
           } else {            } else {
               // フロント画面                // フロント画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.front.exception', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.exception', $event);
           }            }
   
           // 全体            // 全体
           $app['eccube.event.dispatcher']->dispatch('eccube.event.app.exception', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.exception', $event);
       });        });
   
       // Terminate Event        // Terminate Event
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::TERMINATE, function (\Symfony\Component\HttpKernel\Event\PostResponseEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::TERMINATE, function (\Symfony\Component\HttpKernel\Event\PostResponseEvent $event) use ($app) {
   
           $route = $event->getRequest()->attributes->get('_route');            $route = $event->getRequest()->attributes->get('_route');
   
           if (is_null($route)) {            if (is_null($route)) {
               return;                return;
           }            }
   
           $app['monolog']->debug('KernelEvents::TERMINATE '.$route);            $app['monolog']->debug('KernelEvents::TERMINATE '.$route);
   
           // ルーティング単位            // ルーティング単位
           $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.terminate", $event);            $app['eccube.event.dispatcher']->dispatch("eccube.event.route.{$route}.terminate", $event);
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.terminate', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.admin.terminate', $event);
           } else {            } else {
               // フロント画面                // フロント画面
               $app['eccube.event.dispatcher']->dispatch('eccube.event.front.terminate', $event);                $app['eccube.event.dispatcher']->dispatch('eccube.event.front.terminate', $event);
           }            }
   
           // 全体            // 全体
           $app['eccube.event.dispatcher']->dispatch('eccube.event.app.terminate', $event);            $app['eccube.event.dispatcher']->dispatch('eccube.event.app.terminate', $event);
       });        });
   }    }
   
   public function loadPlugin()    public function loadPlugin()
   {    {
       // プラグインディレクトリを探索.        // プラグインディレクトリを探索.
       $basePath = $this['config']['plugin_realdir'];        $basePath = $this['config']['plugin_realdir'];
       $pluginConfigs = $this->getPluginConfigAll();        $pluginConfigs = $this->getPluginConfigAll();
   
       // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成        // ハンドラ優先順位をdbから持ってきてハッシュテーブルを作成
       $priorities = array();        $priorities = array();
       $handlers = $this['orm.em']        $handlers = $this['orm.em']
           ->getRepository('Eccube\Entity\PluginEventHandler')            ->getRepository('Eccube\Entity\PluginEventHandler')
           ->getHandlers();            ->getHandlers();
   
       foreach ($handlers as $handler) {        foreach ($handlers as $handler) {
           if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {            if ($handler->getPlugin()->getEnable() && !$handler->getPlugin()->getDelFlg()) {
   
               $priority = $handler->getPriority();                $priority = $handler->getPriority();
           } else {            } else {
               // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす                // Pluginがdisable、削除済みの場合、EventHandlerのPriorityを全て0とみなす
               $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED;
           }            }
           $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;            $priorities[$handler->getPlugin()->getClassName()][$handler->getEvent()][$handler->getHandler()] = $priority;
       }        }
   
       // プラグインをロードする.        // プラグインをロードする.
       // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.        // config.yml/event.ymlの定義に沿ってインスタンスの生成を行い, イベント設定を行う.
       foreach ($pluginConfigs as $code => $pluginConfig) {        foreach ($pluginConfigs as $code => $pluginConfig) {
           // 正しい形式の pluginConfig のみ読み込む            // 正しい形式の pluginConfig のみ読み込む
           $path = $basePath.'/'.$code;            $path = $basePath.'/'.$code;
           try {            try {
               $this['eccube.service.plugin']->checkPluginArchiveContent($path, $pluginConfig['config']);                $this['eccube.service.plugin']->checkPluginArchiveContent($path, $pluginConfig['config']);
           } catch (\Eccube\Exception\PluginException $e) {            } catch (\Eccube\Exception\PluginException $e) {
               $this['monolog']->warning("Configuration file config.yml for plugin {$code} not found or is invalid. Skipping loading.", array(                $this['monolog']->warning("Configuration file config.yml for plugin {$code} not found or is invalid. Skipping loading.", array(
                   'path' => $path,                    'path' => $path,
                   'original-message' => $e->getMessage()                    'original-message' => $e->getMessage()
               ));                ));
               continue;                continue;
           }            }
           $config = $pluginConfig['config'];            $config = $pluginConfig['config'];
   
           $plugin = $this['orm.em']            $plugin = $this['orm.em']
               ->getRepository('Eccube\Entity\Plugin')                ->getRepository('Eccube\Entity\Plugin')
               ->findOneBy(array('code' => $config['code']));                ->findOneBy(array('code' => $config['code']));
   
           // const            // const
           if (isset($config['const'])) {            if (isset($config['const'])) {
               $this['config'] = $this->share($this->extend('config', function ($eccubeConfig) use ($config) {                $this['config'] = $this->share($this->extend('config', function ($eccubeConfig) use ($config) {
                   $eccubeConfig[$config['code']] = array(                    $eccubeConfig[$config['code']] = array(
                       'const' => $config['const'],                        'const' => $config['const'],
                   );                    );
   
                   return $eccubeConfig;                    return $eccubeConfig;
               }));                }));
           }            }
   
           if ($plugin && $plugin->getEnable() == Constant::DISABLED) {            if ($plugin && $plugin->getEnable() == Constant::DISABLED) {
               // プラグインが無効化されていれば読み込まない                // プラグインが無効化されていれば読み込まない
               continue;                continue;
           }            }
   
           // Type: Event            // Type: Event
           if (isset($config['event'])) {            if (isset($config['event'])) {
               $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];                $class = '\\Plugin\\'.$config['code'].'\\'.$config['event'];
               $eventExists = true;                $eventExists = true;
   
               if (!class_exists($class)) {                if (!class_exists($class)) {
                   $this['monolog']->warning("Event class for plugin {$code} not exists.", array(                    $this['monolog']->warning("Event class for plugin {$code} not exists.", array(
                       'class' => $class,                        'class' => $class,
                   ));                    ));
                   $eventExists = false;                    $eventExists = false;
               }                }
   
               if ($eventExists && isset($config['event'])) {                if ($eventExists && isset($config['event'])) {
   
                   $subscriber = new $class($this);                    $subscriber = new $class($this);
   
                   foreach ($pluginConfig['event'] as $event => $handlers) {                    foreach ($pluginConfig['event'] as $event => $handlers) {
                       foreach ($handlers as $handler) {                        foreach ($handlers as $handler) {
                           if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする                            if (!isset($priorities[$config['event']][$event][$handler[0]])) { // ハンドラテーブルに登録されていない(ソースにしか記述されていない)ハンドラは一番後ろにする
                               $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;                                $priority = \Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_LATEST;
                           } else {                            } else {
                               $priority = $priorities[$config['event']][$event][$handler[0]];                                $priority = $priorities[$config['event']][$event][$handler[0]];
                           }                            }
                           // 優先度が0のプラグインは登録しない                            // 優先度が0のプラグインは登録しない
                           if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {                            if (\Eccube\Entity\PluginEventHandler::EVENT_PRIORITY_DISABLED != $priority) {
                               $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);                                $this['eccube.event.dispatcher']->addListener($event, array($subscriber, $handler[0]), $priority);
                           }                            }
                       }                        }
                   }                    }
               }                }
           }            }
           // Type: ServiceProvider            // Type: ServiceProvider
           if (isset($config['service'])) {            if (isset($config['service'])) {
               foreach ($config['service'] as $service) {                foreach ($config['service'] as $service) {
                   $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;                    $class = '\\Plugin\\'.$config['code'].'\\ServiceProvider\\'.$service;
                   if (!class_exists($class)) {                    if (!class_exists($class)) {
                       $this['monolog']->warning("Service provider class for plugin {$code} not exists.", array(                        $this['monolog']->warning("Service provider class for plugin {$code} not exists.", array(
                           'class' => $class,                            'class' => $class,
                       ));                        ));
                       continue;                        continue;
                   }                    }
                   $this->register(new $class($this));                    $this->register(new $class($this));
               }                }
           }            }
       }        }
   }    }
   
   /**    /**
    * PHPUnit を実行中かどうかを設定する.     * PHPUnit を実行中かどうかを設定する.
    *     *
    * @param boolean $testMode PHPUnit を実行中の場合 true     * @param boolean $testMode PHPUnit を実行中の場合 true
    */      */ 
   public function setTestMode($testMode)    public function setTestMode($testMode)
   {    {
       $this->testMode = $testMode;        $this->testMode = $testMode;
   }    }
   
   /**    /**
    * PHPUnit を実行中かどうか.     * PHPUnit を実行中かどうか.
    *     *
    * @return boolean PHPUnit を実行中の場合 true     * @return boolean PHPUnit を実行中の場合 true
    */      */ 
   public function isTestMode()    public function isTestMode()
   {    {
       return $this->testMode;        return $this->testMode;
   }    }
   
   /**    /**
    *     *
    * データベースの接続を確認     * データベースの接続を確認
    * 成功 : trueを返却     * 成功 : trueを返却
    * 失敗 : \Doctrine\DBAL\DBALExceptionエラーが発生( 接続に失敗した場合 )、エラー画面を表示しdie()     * 失敗 : \Doctrine\DBAL\DBALExceptionエラーが発生( 接続に失敗した場合 )、エラー画面を表示しdie()
    * 備考 : app['debug']がtrueの際は処理を行わない     * 備考 : app['debug']がtrueの際は処理を行わない
    *     *
    * @return boolean true     * @return boolean true
    *     *
    */      */ 
   protected function checkDatabaseConnection()    protected function checkDatabaseConnection()
   {    {
       if ($this['debug']) {        if ($this['debug']) {
           return;            return;
       }        }
       try {        try {
           $this['db']->connect();            $this['db']->connect();
       } catch (\Doctrine\DBAL\DBALException $e) {        } catch (\Doctrine\DBAL\DBALException $e) {
           $this['monolog']->error($e->getMessage());            $this['monolog']->error($e->getMessage());
           $this['twig.path'] = array(__DIR__.'/Resource/template/exception');            $this['twig.path'] = array(__DIR__.'/Resource/template/exception');
           $html = $this['twig']->render('error.twig', array(            $html = $this['twig']->render('error.twig', array(
               'error_title' => 'データーベース接続エラー',                'error_title' => 'データーベース接続エラー',
               'error_message' => 'データーベースを確認してください',                'error_message' => 'データーベースを確認してください',
           ));            ));
           $response = new Response();            $response = new Response();
           $response->setContent($html);            $response->setContent($html);
           $response->setStatusCode('500');            $response->setStatusCode('500');
           $response->headers->set('Content-Type', 'text/html');            $response->headers->set('Content-Type', 'text/html');
           $response->send();            $response->send();
           die();            die();
       }        }
   
       return true;        return true;
   }    }
   
   /**    /**
    * Config ファイルをパースし、連想配列を返します.     * Config ファイルをパースし、連想配列を返します.
    *     *
    * $config_name.yml ファイルをパースし、連想配列を返します.     * $config_name.yml ファイルをパースし、連想配列を返します.
    * $config_name.php が存在する場合は、 PHP ファイルに記述された連想配列を使用します。     * $config_name.php が存在する場合は、 PHP ファイルに記述された連想配列を使用します。
    *     *
    * @param string $config_name Config 名称     * @param string $config_name Config 名称
    * @param array $configAll Config の連想配列     * @param array $configAll Config の連想配列
    * @param boolean $wrap_key Config の連想配列に config_name のキーを生成する場合 true, デフォルト false     * @param boolean $wrap_key Config の連想配列に config_name のキーを生成する場合 true, デフォルト false
    * @param string $ymlPath config yaml を格納したディレクトリ     * @param string $ymlPath config yaml を格納したディレクトリ
    * @param string $distPath config yaml dist を格納したディレクトリ     * @param string $distPath config yaml dist を格納したディレクトリ
    * @return Application     * @return Application
    */      */ 
   public function parseConfig($config_name, array &$configAll, $wrap_key = false, $ymlPath = null, $distPath = null)    public function parseConfig($config_name, array &$configAll, $wrap_key = false, $ymlPath = null, $distPath = null)
   {    {
       $ymlPath = $ymlPath ? $ymlPath : __DIR__.'/../../app/config/eccube';        $ymlPath = $ymlPath ? $ymlPath : __DIR__.'/../../app/config/eccube';
       $distPath = $distPath ? $distPath : __DIR__.'/../../src/Eccube/Resource/config';        $distPath = $distPath ? $distPath : __DIR__.'/../../src/Eccube/Resource/config';
       $config = array();        $config = array();
       $config_php = $ymlPath.'/'.$config_name.'.php';        $config_php = $ymlPath.'/'.$config_name.'.php';
       if (!file_exists($config_php)) {        if (!file_exists($config_php)) {
           $config_yml = $ymlPath.'/'.$config_name.'.yml';            $config_yml = $ymlPath.'/'.$config_name.'.yml';
           if (file_exists($config_yml)) {            if (file_exists($config_yml)) {
               $config = Yaml::parse(file_get_contents($config_yml));                $config = Yaml::parse(file_get_contents($config_yml));
               $config = empty($config) ? array() : $config;                $config = empty($config) ? array() : $config;
               if (isset($this['output_config_php']) && $this['output_config_php']) {                if (isset($this['output_config_php']) && $this['output_config_php']) {
                   file_put_contents($config_php, sprintf('<?php return %s', var_export($config, true)).';');                    file_put_contents($config_php, sprintf('<?php return %s', var_export($config, true)).';');
               }                }
           }            }
       } else {        } else {
           $config = require $config_php;            $config = require $config_php;
       }        }
   
       $config_dist = array();        $config_dist = array();
       $config_php_dist = $distPath.'/'.$config_name.'.dist.php';        $config_php_dist = $distPath.'/'.$config_name.'.dist.php';
       if (!file_exists($config_php_dist)) {        if (!file_exists($config_php_dist)) {
           $config_yml_dist = $distPath.'/'.$config_name.'.yml.dist';            $config_yml_dist = $distPath.'/'.$config_name.'.yml.dist';
           if (file_exists($config_yml_dist)) {            if (file_exists($config_yml_dist)) {
               $config_dist = Yaml::parse(file_get_contents($config_yml_dist));                $config_dist = Yaml::parse(file_get_contents($config_yml_dist));
               if (isset($this['output_config_php']) && $this['output_config_php']) {                if (isset($this['output_config_php']) && $this['output_config_php']) {
                   file_put_contents($config_php_dist, sprintf('<?php return %s', var_export($config_dist, true)).';');                    file_put_contents($config_php_dist, sprintf('<?php return %s', var_export($config_dist, true)).';');
               }                }
           }            }
       } else {        } else {
           $config_dist = require $config_php_dist;            $config_dist = require $config_php_dist;
       }        }
   
       if ($wrap_key) {        if ($wrap_key) {
           $configAll = array_replace_recursive($configAll, array($config_name => $config_dist), array($config_name => $config));            $configAll = array_replace_recursive($configAll, array($config_name => $config_dist), array($config_name => $config));
       } else {        } else {
           $configAll = array_replace_recursive($configAll, $config_dist, $config);            $configAll = array_replace_recursive($configAll, $config_dist, $config);
       }        }
   
       return $this;        return $this;
   }    }
   
   /**    /**
    * セッションが開始されているかどうか.     * セッションが開始されているかどうか.
    *     *
    * @return boolean セッションが開始済みの場合 true     * @return boolean セッションが開始済みの場合 true
    * @link http://php.net/manual/ja/function.session-status.php#113468     * @link http://php.net/manual/ja/function.session-status.php#113468
    */      */ 
   protected function isSessionStarted()    protected function isSessionStarted()
   {    {
       if (php_sapi_name() !== 'cli') {        if (php_sapi_name() !== 'cli') {
           if (version_compare(phpversion(), '5.4.0', '>=')) {            if (version_compare(phpversion(), '5.4.0', '>=')) {
               return session_status() === PHP_SESSION_ACTIVE ? true : false;                return session_status() === PHP_SESSION_ACTIVE ? true : false;
           } else {            } else {
               return session_id() === '' ? false : true;                return session_id() === '' ? false : true;
           }            }
       }        }
   
       return false;        return false;
   }    }
   
   /**    /**
    * Http Cache対応     * Http Cache対応
    */      */ 
   protected function initCacheRequest()    protected function initCacheRequest()
   {    {
       // httpキャッシュが無効の場合はイベント設定を行わない.        // httpキャッシュが無効の場合はイベント設定を行わない.
       if (!$this['config']['http_cache']['enabled']) {        if (!$this['config']['http_cache']['enabled']) {
           return;            return;
       }        }
   
       $app = $this;        $app = $this;
   
       // Response Event(http cache対応、event実行は一番遅く設定)        // Response Event(http cache対応、event実行は一番遅く設定)
       $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {        $this->on(\Symfony\Component\HttpKernel\KernelEvents::RESPONSE, function (\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event) use ($app) {
   
           if (!$event->isMasterRequest()) {            if (!$event->isMasterRequest()) {
               return;                return;
           }            }
   
           $request = $event->getRequest();            $request = $event->getRequest();
           $response = $event->getResponse();            $response = $event->getResponse();
   
           $route = $request->attributes->get('_route');            $route = $request->attributes->get('_route');
   
           $etag = md5($response->getContent());            $etag = md5($response->getContent());
   
           if (strpos($route, 'admin') === 0) {            if (strpos($route, 'admin') === 0) {
               // 管理画面                // 管理画面
   
               // 管理画面ではコンテンツの中身が変更された時点でキャッシュを更新し、キャッシュの適用範囲はprivateに設定                // 管理画面ではコンテンツの中身が変更された時点でキャッシュを更新し、キャッシュの適用範囲はprivateに設定
               $response->setCache(array(                $response->setCache(array(
                   'etag' => $etag,                    'etag' => $etag,
                   'private' => true,                    'private' => true,
               ));                ));
   
               if ($response->isNotModified($request)) {                if ($response->isNotModified($request)) {
                   return $response;                    return $response;
               }                }
   
           } else {            } else {
               // フロント画面                // フロント画面
               $cacheRoute = $app['config']['http_cache']['route'];                $cacheRoute = $app['config']['http_cache']['route'];
   
               if (in_array($route, $cacheRoute) === true) {                if (in_array($route, $cacheRoute) === true) {
                   // キャッシュ対象となる画面lが含まれていた場合、キャッシュ化                    // キャッシュ対象となる画面lが含まれていた場合、キャッシュ化
                   // max-ageを設定しているためExpiresは不要                    // max-ageを設定しているためExpiresは不要
                   // Last-Modifiedだと比較する項目がないためETagで対応                    // Last-Modifiedだと比較する項目がないためETagで対応
                   // max-ageを設定していた場合、contentの中身が変更されても変更されな                    // max-ageを設定していた場合、contentの中身が変更されても変更されな
   
                   $age = $app['config']['http_cache']['age'];                    $age = $app['config']['http_cache']['age'];
   
                   $response->setCache(array(                    $response->setCache(array(
                       'etag' => $etag,                        'etag' => $etag,
                       'max_age' => $age,                        'max_age' => $age,
                       's_maxage' => $age,                        's_maxage' => $age,
                       'public' => true,                        'public' => true,
                   ));                    ));
   
                   if ($response->isNotModified($request)) {                    if ($response->isNotModified($request)) {
                       return $response;                        return $response;
                   }                    }
               }                }
           }            }
   
       }, -1024);        }, -1024);
   }    }
   
   /**    /**
    * すべてのプラグインの設定情報を返す.     * すべてのプラグインの設定情報を返す.
    *     *
    * すべてのプラグインの config.yml 及び event.yml を読み込み、連想配列で返す.     * すべてのプラグインの config.yml 及び event.yml を読み込み、連想配列で返す.
    * キャッシュファイルが存在する場合は、キャッシュを利用する.     * キャッシュファイルが存在する場合は、キャッシュを利用する.
    * キャッシュファイルが存在しない場合は、キャッシュを生成する.     * キャッシュファイルが存在しない場合は、キャッシュを生成する.
    * $app['debug'] = true の場合は、キャッシュを利用しない.     * $app['debug'] = true の場合は、キャッシュを利用しない.
    *     *
    * @return array     * @return array
    */      */ 
   public function getPluginConfigAll()    public function getPluginConfigAll()
   {    {
       if ($this['debug']) {        if ($this['debug']) {
           return $this->parsePluginConfigs();            return $this->parsePluginConfigs();
       }        }
       $pluginConfigCache = $this->getPluginConfigCacheFile();        $pluginConfigCache = $this->getPluginConfigCacheFile();
       if (file_exists($pluginConfigCache)) {        if (file_exists($pluginConfigCache)) {
           return require $pluginConfigCache;            return require $pluginConfigCache;
       }        }
       if ($this->writePluginConfigCache($pluginConfigCache) === false) {        if ($this->writePluginConfigCache($pluginConfigCache) === false) {
           return $this->parsePluginConfigs();            return $this->parsePluginConfigs();
       } else {        } else {
           return require $pluginConfigCache;            return require $pluginConfigCache;
       }        }
   }    }
   
   /**    /**
    * プラグイン設定情報のキャッシュを書き込む.     * プラグイン設定情報のキャッシュを書き込む.
    *     *
    * @param string $cacheFile     * @param string $cacheFile
    * @return int|boolean file_put_contents() の結果     * @return int|boolean file_put_contents() の結果
    */      */ 
   public function writePluginConfigCache($cacheFile = null)    public function writePluginConfigCache($cacheFile = null)
   {    {
       if (is_null($cacheFile)) {        if (is_null($cacheFile)) {
           $cacheFile = $this->getPluginConfigCacheFile();            $cacheFile = $this->getPluginConfigCacheFile();
       }        }
       $pluginConfigs = $this->parsePluginConfigs();        $pluginConfigs = $this->parsePluginConfigs();
       if (!file_exists($this['config']['plugin_temp_realdir'])) {        if (!file_exists($this['config']['plugin_temp_realdir'])) {
           @mkdir($this['config']['plugin_temp_realdir']);            @mkdir($this['config']['plugin_temp_realdir']);
       }        }
       $this['monolog']->debug("write plugin config cache", array($pluginConfigs));        $this['monolog']->debug("write plugin config cache", array($pluginConfigs));
       return file_put_contents($cacheFile, sprintf('<?php return %s', var_export($pluginConfigs, true)).';');        return file_put_contents($cacheFile, sprintf('<?php return %s', var_export($pluginConfigs, true)).';');
   }    }
   
   /**    /**
    * プラグイン設定情報のキャッシュファイルを削除する.     * プラグイン設定情報のキャッシュファイルを削除する.
    *     *
    * @return boolean     * @return boolean
    */      */ 
   public function removePluginConfigCache()    public function removePluginConfigCache()
   {    {
       $cacheFile = $this->getPluginConfigCacheFile();        $cacheFile = $this->getPluginConfigCacheFile();
       if (file_exists($cacheFile)) {        if (file_exists($cacheFile)) {
           $this['monolog']->debug("remove plugin config cache");            $this['monolog']->debug("remove plugin config cache");
           return unlink($cacheFile);            return unlink($cacheFile);
       }        }
       return false;        return false;
   }    }
   
   /**    /**
    * プラグイン設定情報のキャッシュファイルパスを返す.     * プラグイン設定情報のキャッシュファイルパスを返す.
    *     *
    * @return string     * @return string
    */      */ 
   public function getPluginConfigCacheFile()    public function getPluginConfigCacheFile()
   {    {
       return $this['config']['plugin_temp_realdir'].'/config_cache.php';        return $this['config']['plugin_temp_realdir'].'/config_cache.php';
   }    }
   
   /**    /**
    * プラグイン設定情報をパースし, 連想配列で返す.     * プラグイン設定情報をパースし, 連想配列で返す.
    *     *
    * すべてのプラグインを探索し、 config.yml 及び event.yml をパースする.     * すべてのプラグインを探索し、 config.yml 及び event.yml をパースする.
    * パースした情報を連想配列で返す.     * パースした情報を連想配列で返す.
    *     *
    * @return array     * @return array
    */      */ 
   public function parsePluginConfigs()    public function parsePluginConfigs()
   {    {
   
       $finder = Finder::create()        $finder = Finder::create()
           ->in($this['config']['plugin_realdir'])            ->in($this['config']['plugin_realdir'])
           ->directories()            ->directories()
           ->depth(0);            ->depth(0);
       $finder->sortByName();        $finder->sortByName();
   
       $pluginConfigs = array();        $pluginConfigs = array();
       foreach ($finder as $dir) {        foreach ($finder as $dir) {
           $code = $dir->getBaseName();            $code = $dir->getBaseName();
           if (!$code) {            if (!$code) {
               //PHP5.3のgetBaseNameバグ対応                //PHP5.3のgetBaseNameバグ対応
               if (PHP_VERSION_ID < 50400) {                if (PHP_VERSION_ID < 50400) {
                   $code = $dir->getFilename();                    $code = $dir->getFilename();
               }                }
           }            }
           $file = $dir->getRealPath().'/config.yml';            $file = $dir->getRealPath().'/config.yml';
           $config = null;            $config = null;
           if (file_exists($file)) {            if (file_exists($file)) {
               $config = Yaml::parse(file_get_contents($file));                $config = Yaml::parse(file_get_contents($file));
           } else {            } else {
               $this['monolog']->warning("skip {$code} orm.path loading. config.yml not found.", array('path' => $file));                $this['monolog']->warning("skip {$code} orm.path loading. config.yml not found.", array('path' => $file));
               continue;                continue;
           }            }
   
           $file = $dir->getRealPath().'/event.yml';            $file = $dir->getRealPath().'/event.yml';
           $event = null;            $event = null;
           if (file_exists($file)) {            if (file_exists($file)) {
               $event = Yaml::parse(file_get_contents($file));                $event = Yaml::parse(file_get_contents($file));
           } else {            } else {
               $this['monolog']->info("skip {$code} event.yml not found.", array('path' => $file));                $this['monolog']->info("skip {$code} event.yml not found.", array('path' => $file));
           }            }
           if (!is_null($config)) {            if (!is_null($config)) {
               $pluginConfigs[$code] = array(                $pluginConfigs[$code] = array(
                   'config' => $config,                    'config' => $config,
                   'event' => $event                    'event' => $event
               );                );
               $this['monolog']->debug("parse {$code} config", array($code => $pluginConfigs[$code]));                $this['monolog']->debug("parse {$code} config", array($code => $pluginConfigs[$code]));
           }            }
       }        }
   
       return $pluginConfigs;        return $pluginConfigs;
   }    }
} }