File indexing completed on 2024-04-21 16:36:32

0001 <?php /** @noinspection PhpIncludeInspection */
0002 
0003 /**
0004  * Flooer Framework
0005  *
0006  * LICENSE: BSD License (2 Clause)
0007  *
0008  * @category    Flooer
0009  * @package     Flooer_Application
0010  * @author      Akira Ohgaki <akiraohgaki@gmail.com>
0011  * @copyright   Akira Ohgaki
0012  * @license     https://opensource.org/licenses/BSD-2-Clause  BSD License (2 Clause)
0013  * @link        https://github.com/akiraohgaki/flooer
0014  */
0015 
0016 /**
0017  * Usage
0018  *
0019  * $application = new Flooer_Application();
0020  * $application->setConfig('baseDir', '../application');
0021  * $application->setConfig('environment', 'development');
0022  * $application->run();
0023  */
0024 
0025 /**
0026  * Application environment class of application
0027  *
0028  * @category    Flooer
0029  * @package     Flooer_Application
0030  * @author      Akira Ohgaki <akiraohgaki@gmail.com>
0031  */
0032 class Flooer_Application
0033 {
0034 
0035     /**
0036      * Configuration options
0037      *
0038      * @var     array
0039      */
0040     protected $_config = array();
0041 
0042     /**
0043      * Application resources
0044      *
0045      * @var     array
0046      */
0047     protected $_resources = array();
0048 
0049     /**
0050      * Application status
0051      *
0052      * @var     bool
0053      */
0054     protected $_status = false;
0055 
0056     /**
0057      * Constructor
0058      *
0059      * @param array $config
0060      *
0061      * @return  void
0062      */
0063     public function __construct(array $config = null)
0064     {
0065         ob_start();
0066         $this->_config = array(
0067             'baseDir'               => './',
0068             'environment'           => 'production',
0069             'safeModeSupport'       => ini_get('safe_mode'),
0070             'magicQuotesSupport'    => false,
0071             'mbstringSupport'       => extension_loaded('mbstring'),
0072             'memoryLimit'           => '128M',
0073             'maxExecutionTime'      => 30,
0074             'socketTimeout'         => 20,
0075             'timezone'              => 'UTC',
0076             'encoding'              => 'UTF-8',
0077             'newline'               => 'LF',
0078             'mbLanguage'            => 'uni',
0079             'mbDetectOrder'         => 'ASCII, JIS, UTF-8, EUC-JP, SJIS',
0080             'mbSubstituteCharacter' => 'none',
0081             'bootstrap'             => 'Bootstrap',
0082             'bootstrapFileSuffix'   => '.php',
0083             'autoloadConfig'        => array(
0084                 'register'   => true,
0085                 'extensions' => '.php',
0086             ),
0087             'bootstrapConfig'       => array(),
0088         );
0089         if ($config) {
0090             $this->_config = $config + $this->_config;
0091         }
0092     }
0093 
0094     /**
0095      * Destructor
0096      *
0097      * @return  void
0098      */
0099     public function __destruct()
0100     {
0101         if (ob_get_level()) {
0102             ob_end_flush();
0103         }
0104     }
0105 
0106     /**
0107      * Run an application
0108      *
0109      * @return  void
0110      * @throws Flooer_Exception
0111      */
0112     public function run()
0113     {
0114         if ($this->_status) {
0115             trigger_error(
0116                 'Application is already running', E_USER_NOTICE
0117             );
0118         }
0119         $this->_status = true;
0120         $this->_setup();
0121         $this->_bootstrap();
0122         $this->_dispatch();
0123     }
0124 
0125     /**
0126      * Setup an application environment
0127      *
0128      * @return  void
0129      */
0130     protected function _setup()
0131     {
0132         $this->_config['baseDir'] = realpath($this->_config['baseDir']);
0133         $this->_config['environment'] = strtolower($this->_config['environment']);
0134         set_include_path(
0135             implode(
0136                 PATH_SEPARATOR, array(
0137                                   dirname(dirname(__FILE__)),
0138                                   $this->_config['baseDir'],
0139                                   get_include_path(),
0140                               )
0141             )
0142         );
0143         switch ($this->_config['environment']) {
0144             case 'debug':
0145                 ini_set('display_errors', 1);
0146                 error_reporting(E_ALL | E_NOTICE | E_STRICT);
0147                 break;
0148             case 'development':
0149                 // Continue to testing
0150             case 'testing':
0151                 ini_set('display_errors', 1);
0152                 error_reporting(E_ALL ^ E_NOTICE);
0153                 break;
0154             case 'staging':
0155                 // Continue to production
0156             case 'production':
0157                 // Continue to default
0158             default:
0159                 ini_set('display_errors', 0);
0160                 error_reporting(E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE);
0161                 break;
0162         }
0163         ini_set('memory_limit', $this->_config['memoryLimit']);
0164         ini_set('default_socket_timeout', $this->_config['socketTimeout']);
0165         date_default_timezone_set($this->_config['timezone']);
0166         if (!$this->_config['safeModeSupport']) {
0167             set_time_limit($this->_config['maxExecutionTime']);
0168         }
0169         if ($this->_config['mbstringSupport']) {
0170             mb_language($this->_config['mbLanguage']);
0171             mb_internal_encoding($this->_config['encoding']);
0172             mb_regex_encoding($this->_config['encoding']);
0173             mb_http_output($this->_config['encoding']);
0174             mb_detect_order($this->_config['mbDetectOrder']);
0175             mb_substitute_character($this->_config['mbSubstituteCharacter']);
0176         }
0177         require_once 'Flooer/Exception.php';
0178         Flooer_Exception::setExceptionHandler();
0179         Flooer_Exception::setErrorHandler();
0180         require_once 'Flooer/Autoload.php';
0181         $this->_resources['autoload'] = new Flooer_Autoload(
0182             $this->_config['autoloadConfig']
0183         );
0184     }
0185 
0186     /**
0187      * Bootstrap application
0188      *
0189      * @return  void
0190      */
0191     protected function _bootstrap()
0192     {
0193         require_once 'Flooer/Application/Bootstrap.php';
0194         if (is_file(
0195             $this->_config['baseDir'] . '/' . $this->_config['bootstrap'] . $this->_config['bootstrapFileSuffix']
0196         )) {
0197             include_once $this->_config['baseDir'] . '/' . $this->_config['bootstrap'] . $this->_config['bootstrapFileSuffix'];
0198             if (class_exists($this->_config['bootstrap'], false)) {
0199                 $bootstrap = new $this->_config['bootstrap'](
0200                     $this, $this->_config['bootstrapConfig']
0201                 );
0202                 if ($bootstrap instanceof Flooer_Application_Bootstrap) {
0203                     $bootstrap->bootstrap();
0204 
0205                     return;
0206                 }
0207             }
0208             trigger_error(
0209                 'Invalid bootstrapper', E_USER_ERROR
0210             );
0211         }
0212         $bootstrap = new Flooer_Application_Bootstrap(
0213             $this, $this->_config['bootstrapConfig']
0214         );
0215         $bootstrap->bootstrap();
0216     }
0217 
0218     /**
0219      * Dispatch to a page script or an action controller
0220      *
0221      * @param string $filename
0222      *
0223      * @return  void
0224      * @throws Flooer_Exception
0225      */
0226     protected function _dispatch($filename = null)
0227     {
0228         if (isset($this->_resources['dispatch']) && $this->_resources['dispatch'] instanceof Flooer_Application_Dispatch && isset($this->_resources['request']) && $this->_resources['request'] instanceof Flooer_Http_Request && isset($this->_resources['response']) && $this->_resources['response'] instanceof Flooer_Http_Response) {
0229             $this->_resources['dispatch']->dispatch($filename);
0230 
0231             return;
0232         }
0233         trigger_error(
0234             'Resource for dispatcher, HTTP request and response' . ' must be initialized for application', E_USER_ERROR
0235         );
0236     }
0237 
0238     /**
0239      * Show an application information page
0240      *
0241      * @return  void
0242      * @throws Flooer_Exception
0243      */
0244     public function info()
0245     {
0246         if ($this->_status) {
0247             trigger_error(
0248                 'Application is already running', E_USER_NOTICE
0249             );
0250         }
0251         $this->_status = true;
0252         $this->_setup();
0253         $this->_bootstrap();
0254         $this->_dispatch(
0255             dirname(__FILE__) . '/Application/pages/info.phtml'
0256         );
0257     }
0258 
0259     /**
0260      * Set a configuration options
0261      *
0262      * @param array $config
0263      *
0264      * @return  void
0265      */
0266     public function setConfigs(array $config)
0267     {
0268         $this->_config = $config;
0269     }
0270 
0271     /**
0272      * Get a configuration options
0273      *
0274      * @return  array
0275      */
0276     public function getConfigs()
0277     {
0278         return $this->_config;
0279     }
0280 
0281     /**
0282      * Get a configuration option
0283      *
0284      * @param string $key
0285      *
0286      * @return  mixed
0287      */
0288     public function getConfig($key)
0289     {
0290         if (isset($this->_config[$key])) {
0291             return $this->_config[$key];
0292         }
0293 
0294         return null;
0295     }
0296 
0297     /**
0298      * Set a configuration option
0299      *
0300      * @param string $key
0301      * @param mixed  $value
0302      *
0303      * @return  void
0304      */
0305     public function setConfig($key, $value)
0306     {
0307         $this->_config[$key] = $value;
0308     }
0309 
0310     /**
0311      * Get a resources
0312      *
0313      * @return  array
0314      */
0315     public function getResources()
0316     {
0317         return $this->_resources;
0318     }
0319 
0320     /**
0321      * Set a resources
0322      *
0323      * @param array $resources
0324      *
0325      * @return  void
0326      */
0327     public function setResources(array $resources)
0328     {
0329         $this->_resources = $resources;
0330     }
0331 
0332     /**
0333      * Set a resource
0334      *
0335      * @param string $key
0336      * @param mixed  $value
0337      *
0338      * @return  void
0339      */
0340     public function setResource($key, $value)
0341     {
0342         $this->_resources[$key] = $value;
0343     }
0344 
0345     /**
0346      * Get a resource
0347      *
0348      * @param string $key
0349      *
0350      * @return  mixed
0351      */
0352     public function getResource($key)
0353     {
0354         if (isset($this->_resources[$key])) {
0355             return $this->_resources[$key];
0356         }
0357 
0358         return null;
0359     }
0360 
0361 }