Overview

Namespaces

  • Charcoal
    • App
      • Action
      • Config
      • Handler
      • Middleware
      • Module
      • Route
      • Script
      • ServiceProvider
      • Template

Classes

  • Charcoal\App\Action\AbstractAction
  • Charcoal\App\App
  • Charcoal\App\AppConfig
  • Charcoal\App\AppContainer
  • Charcoal\App\Config\CacheConfig
  • Charcoal\App\Config\DatabaseConfig
  • Charcoal\App\Config\FilesystemConfig
  • Charcoal\App\Config\LoggerConfig
  • Charcoal\App\Config\MemcacheCacheConfig
  • Charcoal\App\Config\MemcacheCacheServerConfig
  • Charcoal\App\Handler\AbstractHandler
  • Charcoal\App\Handler\Error
  • Charcoal\App\Handler\HandlerConfig
  • Charcoal\App\Handler\NotAllowed
  • Charcoal\App\Handler\NotFound
  • Charcoal\App\Handler\PhpError
  • Charcoal\App\Handler\Shutdown
  • Charcoal\App\Middleware\CacheMiddleware
  • Charcoal\App\Module\AbstractModule
  • Charcoal\App\Module\ModuleConfig
  • Charcoal\App\Module\ModuleManager
  • Charcoal\App\Route\ActionRoute
  • Charcoal\App\Route\ActionRouteConfig
  • Charcoal\App\Route\RouteConfig
  • Charcoal\App\Route\RouteManager
  • Charcoal\App\Route\ScriptRoute
  • Charcoal\App\Route\ScriptRouteConfig
  • Charcoal\App\Route\TemplateRoute
  • Charcoal\App\Route\TemplateRouteConfig
  • Charcoal\App\Script\AbstractScript
  • Charcoal\App\ServiceProvider\AppServiceProvider
  • Charcoal\App\ServiceProvider\CacheServiceProvider
  • Charcoal\App\ServiceProvider\DatabaseServiceProvider
  • Charcoal\App\ServiceProvider\FilesystemServiceProvider
  • Charcoal\App\ServiceProvider\LoggerServiceProvider
  • Charcoal\App\ServiceProvider\ViewServiceProvider
  • Charcoal\App\Template\AbstractTemplate
  • Charcoal\App\Template\AbstractWidget
  • Charcoal\App\Template\WidgetBuilder

Interfaces

  • Charcoal\App\Action\ActionInterface
  • Charcoal\App\AppAwareInterface
  • Charcoal\App\Handler\HandlerInterface
  • Charcoal\App\Module\ModuleInterface
  • Charcoal\App\Route\RouteInterface
  • Charcoal\App\Script\CronScriptInterface
  • Charcoal\App\Script\ScriptInterface
  • Charcoal\App\Template\TemplateInterface
  • Charcoal\App\Template\WidgetInterface

Traits

  • Charcoal\App\AppAwareTrait
  • Charcoal\App\CallableResolverAwareTrait
  • Charcoal\App\Script\ArgScriptTrait
  • Charcoal\App\Script\CronScriptTrait
  • Charcoal\App\Script\PathScriptTrait
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Charcoal\App;
  4: 
  5: // PHP Dependencies
  6: use Exception;
  7: use LogicException;
  8: 
  9: // Dependency from 'Slim'
 10: use Slim\App as SlimApp;
 11: 
 12: // Dependencies from 'PSR-3' (Logging)
 13: use Psr\Log\LoggerAwareInterface;
 14: use Psr\Log\LoggerAwareTrait;
 15: 
 16: // Dependencies from 'PSR-7' (HTTP Messaging)
 17: use Psr\Http\Message\RequestInterface;
 18: use Psr\Http\Message\ResponseInterface;
 19: 
 20: // Dependencies from 'charcoal-config'
 21: use Charcoal\Config\ConfigurableInterface;
 22: use Charcoal\Config\ConfigurableTrait;
 23: 
 24: // Local namespace dependencies
 25: use Charcoal\App\AppConfig;
 26: use Charcoal\App\AppContainer;
 27: use Charcoal\App\Module\ModuleManager;
 28: use Charcoal\App\Route\RouteManager;
 29: use Charcoal\App\Route\RouteFactory;
 30: 
 31: /**
 32:  * Charcoal App
 33:  *
 34:  * This is the primary class with which you instantiate, configure,
 35:  * and run a Slim Framework application within Charcoal.
 36:  */
 37: class App extends SlimApp implements
 38:     ConfigurableInterface
 39: {
 40:     use ConfigurableTrait;
 41: 
 42:     /**
 43:      * Store the unique instance
 44:      *
 45:      * @var App $instance
 46:      */
 47:     protected static $instance;
 48: 
 49:     /**
 50:      * @var ModuleManager
 51:      */
 52:     private $moduleManager;
 53: 
 54:     /**
 55:      * @var RouteManager
 56:      */
 57:     private $routeManager;
 58: 
 59:     /**
 60:      * Getter for creating/returning the unique instance of this class.
 61:      *
 62:      * @param Container|array $container The application's settings.
 63:      * @return self
 64:      */
 65:     public static function instance($container = [])
 66:     {
 67:         if (!isset(static::$instance)) {
 68:             $called_class = get_called_class();
 69: 
 70:             static::$instance = new $called_class($container);
 71:         }
 72: 
 73:         return static::$instance;
 74:     }
 75: 
 76:     /**
 77:      * Create new Charcoal application (and SlimApp).
 78:      *
 79:      * ### Dependencies
 80:      *
 81:      * **Required**
 82:      *
 83:      * - `config` — AppConfig
 84:      *
 85:      * **Optional**
 86:      *
 87:      * - `logger` — PSR-3 Logger
 88:      *
 89:      * @uses  SlimApp::__construct()
 90:      * @param ContainerInterface|array $container The application's settings.
 91:      * @throws LogicException If trying to create a new instance of a singleton.
 92:      */
 93:     public function __construct($container = [])
 94:     {
 95:         if (isset(static::$instance)) {
 96:             throw new LogicException(
 97:                 sprintf(
 98:                     '"%s" is a singleton. Use static instance() method.',
 99:                     get_called_class()
100:                 )
101:             );
102:         }
103: 
104:         // Ensure the DI container is
105:         if (is_array($container)) {
106:             $container = new AppContainer($container);
107:         }
108: 
109:         // SlimApp constructor
110:         parent::__construct($container);
111: 
112:         if (isset($container['config'])) {
113:             $this->setConfig($container['config']);
114:         }
115:     }
116: 
117:     /**
118:      * Run application.
119:      *
120:      * Initialize the Charcoal application before running (with SlimApp).
121:      *
122:      * @uses   self::setup()
123:      * @param  boolean $silent If true, will run in silent mode (no response).
124:      * @return ResponseInterface The PSR7 HTTP response.
125:      */
126:     public function run($silent = false)
127:     {
128:         $this->setup();
129: 
130:         return parent::run($silent);
131:     }
132: 
133:     /**
134:      * @throws LogicException If trying to clone an instance of a singleton.
135:      * @return void
136:      */
137:     final private function __clone()
138:     {
139:         throw new LogicException(
140:             sprintf(
141:                 'Cloning "%s" is not allowed.',
142:                 get_called_class()
143:             )
144:         );
145:     }
146: 
147:     /**
148:      * @throws LogicException If trying to unserialize an instance of a singleton.
149:      * @return void
150:      */
151:     final private function __wakeup()
152:     {
153:         throw new LogicException(
154:             sprintf(
155:                 'Unserializing "%s" is not allowed.',
156:                 get_called_class()
157:             )
158:         );
159:     }
160: 
161:     /**
162:      * Retrieve the application's module manager.
163:      *
164:      * @return ModuleManager
165:      */
166:     protected function moduleManager()
167:     {
168:         if (!isset($this->moduleManager)) {
169:             $config  = $this->config();
170:             $modules = (isset($config['modules']) ? $config['modules'] : [] );
171: 
172:             $container = $this->getContainer();
173:             $this->moduleManager = new ModuleManager([
174:                 'config' => $modules,
175:                 'app'    => $this,
176:                 'logger' => $container['logger'],
177:                 'module_factory' => $container['module/factory']
178:             ]);
179:         }
180: 
181:         return $this->moduleManager;
182:     }
183: 
184:     /**
185:      * Retrieve the application's route manager.
186:      *
187:      * @return RouteManager
188:      */
189:     protected function routeManager()
190:     {
191:         if (!isset($this->routeManager)) {
192:             $config = $this->config();
193:             $routes = (isset($config['routes']) ? $config['routes'] : [] );
194: 
195:             $this->routeManager = new RouteManager([
196:                 'config' => $routes,
197:                 'app'    => $this
198:             ]);
199:         }
200: 
201:         return $this->routeManager;
202:     }
203: 
204:     /**
205:      * Registers the default services and features that Charcoal needs to work.
206:      *
207:      * @return void
208:      */
209:     private function setup()
210:     {
211:         $config = $this->config();
212:         date_default_timezone_set($config['timezone']);
213: 
214:         // Setup routes
215:         $this->routeManager()->setupRoutes();
216: 
217:         // Setup modules
218:         $this->moduleManager()->setupModules($this);
219: 
220:         // Setup routable
221:         $this->setupRoutables();
222: 
223:         // Cache generator; added last, so it will be executed first
224:         $container = $this->getContainer();
225:         if ($container['cache/config']['middleware']['active']) {
226:             $this->add($container['cache/middleware']);
227:         }
228:     }
229: 
230: 
231:     /**
232:      * Setup the application's "global" routables.
233:      *
234:      * Routables can only be defined globally (app-level) for now.
235:      *
236:      * @return void
237:      */
238:     protected function setupRoutables()
239:     {
240:         $app = $this;
241:         // For now, need to rely on a catch-all...
242:         $this->get(
243:             '{catchall:.*}',
244:             function (
245:                 RequestInterface $request,
246:                 ResponseInterface $response,
247:                 array $args
248:             ) use ($app) {
249:                 $config = $app->config();
250:                 $routables = $config['routables'];
251:                 if ($routables === null || count($routables) === 0) {
252:                     return $this['notFoundHandler']($request, $response);
253:                 }
254:                 $routeFactory = $this['route/factory'];
255:                 foreach ($routables as $routableType => $routableOptions) {
256:                     $route = $routeFactory->create($routableType, [
257:                         'path' => $args['catchall'],
258:                         'config' => $routableOptions
259:                     ]);
260:                     if ($route->pathResolvable($this)) {
261:                         $this['logger']->debug(
262:                             sprintf('Loaded routable "%s" for path %s', $routableType, $args['catchall'])
263:                         );
264:                         return $route($this, $request, $response);
265:                     }
266:                 }
267: 
268:                 // If this point is reached, no routable has provided a callback. 404.
269:                 return $this['notFoundHandler']($request, $response);
270:             }
271:         );
272:     }
273: }
274: 
API documentation generated by ApiGen