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\Handler;
  4: 
  5: // Dependencies from PSR-3 (logger)
  6: use Psr\Log\LoggerAwareInterface;
  7: use Psr\Log\LoggerAwareTrait;
  8: 
  9: // Dependencies from PSR-7 (HTTP Messaging)
 10: use Psr\Http\Message\ResponseInterface;
 11: use Psr\Http\Message\ServerRequestInterface;
 12: use Psr\Http\Message\UriInterface;
 13: 
 14: // Dependency from Pimple
 15: use Pimple\Container;
 16: 
 17: // Dependency from 'charcoal-config'
 18: use Charcoal\Config\ConfigurableInterface;
 19: use Charcoal\Config\ConfigurableTrait;
 20: 
 21: // Dependencies from 'charcoal-view'
 22: use Charcoal\View\ViewInterface;
 23: use Charcoal\View\ViewableInterface;
 24: use Charcoal\View\ViewableTrait;
 25: 
 26: // Dependencies from 'charcoal-translator'
 27: use Charcoal\Translator\TranslatorAwareTrait;
 28: 
 29: // Intra-module (`charcoal-app`) dependencies
 30: use Charcoal\App\AppConfig;
 31: use Charcoal\App\Template\TemplateInterface;
 32: use Charcoal\App\Handler\HandlerInterface;
 33: use Charcoal\App\Handler\HandlerConfig;
 34: 
 35: /**
 36:  * Base Error Handler
 37:  *
 38:  * Enhanced version Slim's error handlers.
 39:  *
 40:  * It outputs messages in either JSON, XML or HTML
 41:  * based on the Accept header.
 42:  */
 43: abstract class AbstractHandler implements
 44:     ConfigurableInterface,
 45:     HandlerInterface,
 46:     LoggerAwareInterface,
 47:     ViewableInterface
 48: {
 49:     use ConfigurableTrait;
 50:     use LoggerAwareTrait;
 51:     use TranslatorAwareTrait;
 52:     use ViewableTrait;
 53: 
 54:     /**
 55:      * Container
 56:      *
 57:      * @var Container
 58:      */
 59:     protected $container;
 60: 
 61:     /**
 62:      * URL for the home page
 63:      *
 64:      * @var string
 65:      */
 66:     protected $baseUrl;
 67: 
 68:     /**
 69:      * Known handled content types
 70:      *
 71:      * @var array
 72:      */
 73:     protected $knownContentTypes = [
 74:         'application/json',
 75:         'application/xml',
 76:         'text/xml',
 77:         'text/html',
 78:     ];
 79: 
 80:     /**
 81:      * Return a new AbstractHandler object.
 82:      *
 83:      * @param Container $container A dependencies container instance.
 84:      */
 85:     public function __construct(Container $container)
 86:     {
 87:         $this->setDependencies($container);
 88:     }
 89: 
 90:     /**
 91:      * Initialize the AbstractHandler object.
 92:      *
 93:      * @return AbstractHandler Chainable
 94:      */
 95:     public function init()
 96:     {
 97:         return $this;
 98:     }
 99: 
100:     /**
101:      * Inject dependencies from a Pimple Container.
102:      *
103:      * ## Dependencies
104:      *
105:      * - `AppConfig $appConfig` — The application's configuration.
106:      * - `UriInterface $baseUri` — A base URI.
107:      * - `ViewInterface $view` — A view instance.
108:      *
109:      * @param  Container $container A dependencies container instance.
110:      * @return AbstractHandler Chainable
111:      */
112:     public function setDependencies(Container $container)
113:     {
114:         $this->setLogger($container['logger']);
115:         $this->setContainer($container);
116:         $this->setBaseUrl($container['base-url']);
117:         $this->setView($container['view']);
118:         $this->setTranslator($container['translator']);
119: 
120:         if (isset($container['config']['handlers.defaults'])) {
121:             $this->setConfig($container['config']['handlers.defaults']);
122:         }
123: 
124:         return $this;
125:     }
126: 
127:     /**
128:      * Set container for use with the template controller
129:      *
130:      * @param  Container $container A dependencies container instance.
131:      * @return AbstractHandler Chainable
132:      */
133:     public function setContainer(Container $container)
134:     {
135:         $this->container = $container;
136:         return $this;
137:     }
138: 
139:     /**
140:      * ConfigurableTrait > createConfig()
141:      *
142:      * @see    ConfigurableTrait::createConfig()
143:      * @param  mixed|null $data Optional config data.
144:      * @return ConfigInterface
145:      */
146:     public function createConfig($data = null)
147:     {
148:         return new HandlerConfig($data);
149:     }
150: 
151:     /**
152:      * Determine which content type we know about is wanted using "Accept" header
153:      *
154:      * @param  ServerRequestInterface $request The most recent Request object.
155:      * @return string
156:      */
157:     protected function determineContentType(ServerRequestInterface $request)
158:     {
159:         $acceptHeader = $request->getHeaderLine('Accept');
160:         $selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes);
161: 
162:         if (count($selectedContentTypes)) {
163:             return reset($selectedContentTypes);
164:         }
165: 
166:         // handle +json and +xml specially
167:         if (preg_match('/\+(json|xml)/', $acceptHeader, $matches)) {
168:             $mediaType = 'application/'.$matches[1];
169:             if (in_array($mediaType, $this->knownContentTypes)) {
170:                 return $mediaType;
171:             }
172:         }
173: 
174:         return 'text/html';
175:     }
176: 
177:     /**
178:      * Render HTML Error Page
179:      *
180:      * @return string
181:      */
182:     protected function renderHtmlOutput()
183:     {
184:         $config    = $this->config();
185:         $container = $this->container;
186: 
187:         $templateIdent = $config['template'];
188: 
189:         if ($config['cache']) {
190:             $cachePool = $container['cache'];
191:             $cacheKey  = str_replace('/', '.', 'template/'.$templateIdent);
192:             $cacheItem = $cachePool->getItem($cacheKey);
193: 
194:             $output = $cacheItem->get();
195:             if ($cacheItem->isMiss()) {
196:                 $output = $this->renderHtmlTemplate();
197: 
198:                 $cacheItem->set($output, $config['cache_ttl']);
199:             }
200:         } else {
201:             $output = $this->renderHtmlTemplate();
202:         }
203: 
204:         return $output;
205:     }
206: 
207:     /**
208:      * Render title of error
209:      *
210:      * @return string
211:      */
212:     public function messageTitle()
213:     {
214:         return $this->translator()->translate('Application Error');
215:     }
216: 
217:     /**
218:      * Render body of HTML error
219:      *
220:      * @return string
221:      */
222:     abstract public function renderHtmlMessage();
223: 
224:     /**
225:      * Render HTML Error Page
226:      *
227:      * @return string
228:      */
229:     protected function renderHtmlTemplate()
230:     {
231:         $config    = $this->config();
232:         $container = $this->container;
233: 
234:         $templateIdent      = $config['template'];
235:         $templateController = $config['controller'];
236:         $templateData       = $config['template_data'];
237: 
238:         $templateFactory = $container['template/factory'];
239:         if (isset($config['default_controller'])) {
240:             $templateFactory->setDefaultClass($config['default_controller']);
241:         }
242: 
243:         if (!$templateController) {
244:             return '';
245:         }
246: 
247:         $template = $templateFactory->create($templateController);
248: 
249:         if (!isset($templateData['error_title'])) {
250:             $templateData['error_title'] = $this->messageTitle();
251:         }
252: 
253:         if (!isset($templateData['error_message'])) {
254:             $templateData['error_message'] = $this->renderHtmlMessage();
255:         }
256: 
257:         $template->setData($templateData);
258:         return $container['view']->render($templateIdent, $template);
259:     }
260: 
261:     /**
262:      * Set the base URL (home page).
263:      *
264:      * @param  string|UriInterface $url A URL to the base URL.
265:      * @return AbstractHandler Chainable
266:      */
267:     public function setBaseUrl($url)
268:     {
269:         if ($url instanceof UriInterface) {
270:             $url = $url->withPath('')->withQuery('')->withFragment('');
271:         }
272: 
273:         $this->baseUrl = $url;
274: 
275:         return $this;
276:     }
277: 
278:     /**
279:      * Retrieves the URL for the home page.
280:      *
281:      * @return string A URL representing the home page.
282:      */
283:     public function baseUrl()
284:     {
285:         return $this->baseUrl;
286:     }
287: }
288: 
API documentation generated by ApiGen