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\Route;
  4: 
  5: use InvalidArgumentException;
  6: 
  7: // Dependencies from PSR-7 (HTTP Messaging)
  8: use Psr\Http\Message\RequestInterface;
  9: use Psr\Http\Message\ResponseInterface;
 10: 
 11: // Dependency from Pimple
 12: use Pimple\Container;
 13: 
 14: // Dependency from Slim
 15: use Slim\Http\Uri;
 16: 
 17: // Dependency from 'charcoal-config'
 18: use Charcoal\Config\ConfigurableInterface;
 19: use Charcoal\Config\ConfigurableTrait;
 20: 
 21: // Intra-module ('charcoal-app') dependencies
 22: use Charcoal\App\AppInterface;
 23: use Charcoal\App\Template\TemplateInterface;
 24: 
 25: // Local namespace dependencies
 26: use Charcoal\App\Route\RouteInterface;
 27: use Charcoal\App\Route\TemplateRouteConfig;
 28: 
 29: /**
 30:  * Template Route Handler.
 31:  *
 32:  * A route handler is a simple `invokale` object with the signature:
 33:  * `__invoke(Container $container, RequestInterface $request, ResponseInterface $response)`
 34:  * It is only called (invoked) when a route is matched.
 35:  *
 36:  * This is the default "Slim Route Handler" for _template_ style routes.
 37:  * It uses a `TemplateRouteConfig` to properly either:
 38:  *
 39:  * - redirect the request, if explicitely set
 40:  * - load and render a "Template" object
 41:  *
 42:  * Templates can be any objects that can be loaded with a "TemplateFactory".
 43:  * The Template Factory used is an external dependency (`template/factory`) expected to be set on the container.
 44:  *
 45:  * Template-level cache is possible by setting the "cache" config option to true.
 46:  * Cached template can not have any options; they will always return the exact same content for all "template".
 47:  *
 48:  */
 49: class TemplateRoute implements
 50:     ConfigurableInterface,
 51:     RouteInterface
 52: {
 53:     use ConfigurableTrait;
 54: 
 55:     /**
 56:      * Create new template route
 57:      *
 58:      * **Required dependencies**
 59:      *
 60:      * - `config` — ScriptRouteConfig
 61:      *
 62:      * @param array $data Dependencies.
 63:      */
 64:     public function __construct(array $data)
 65:     {
 66:         $this->setConfig($data['config']);
 67:     }
 68: 
 69:     /**
 70:      * ConfigurableTrait > createConfig()
 71:      *
 72:      * @param  mixed|null $data Optional config data.
 73:      * @return TemplateRouteConfig
 74:      */
 75:     public function createConfig($data = null)
 76:     {
 77:         return new TemplateRouteConfig($data);
 78:     }
 79: 
 80:     /**
 81:      * @param  Container         $container A DI (Pimple) container.
 82:      * @param  RequestInterface  $request   A PSR-7 compatible Request instance.
 83:      * @param  ResponseInterface $response  A PSR-7 compatible Response instance.
 84:      * @return ResponseInterface
 85:      */
 86:     public function __invoke(
 87:         Container $container,
 88:         RequestInterface $request,
 89:         ResponseInterface $response
 90:     ) {
 91:         $config = $this->config();
 92: 
 93:         // Handle explicit redirects
 94:         if (!empty($config['redirect'])) {
 95:             $redirect = $container['translator']->translation($config['redirect']);
 96:             $uri = $this->parseRedirect((string)$redirect, $request);
 97: 
 98:             if ($uri) {
 99:                 return $response->withRedirect($uri, $config['redirect_mode']);
100:             }
101:         }
102: 
103:         $templateContent = $this->templateContent($container, $request);
104: 
105:         $response->getBody()->write($templateContent);
106: 
107:         return $response;
108:     }
109: 
110:     /**
111:      * @param  Container        $container A DI (Pimple) container.
112:      * @param  RequestInterface $request   The request to intialize the template with.
113:      * @return string
114:      */
115:     protected function templateContent(
116:         Container $container,
117:         RequestInterface $request
118:     ) {
119:         $config = $this->config();
120: 
121:         if ($this->cacheEnabled()) {
122:             $cachePool = $container['cache'];
123:             $cacheKey  = str_replace('/', '.', 'template.'.$this->cacheIdent());
124:             $cacheItem = $cachePool->getItem($cacheKey);
125: 
126:             $template = $cacheItem->get();
127:             if ($cacheItem->isMiss()) {
128:                 $template = $this->renderTemplate($container, $request);
129: 
130:                 $cachePool->save($cacheItem->set($template, $this->cacheTtl()));
131:             }
132:         } else {
133:             $template = $this->renderTemplate($container, $request);
134:         }
135: 
136:         return $template;
137:     }
138: 
139:     /**
140:      * @param  Container        $container A DI (Pimple) container.
141:      * @param  RequestInterface $request   The request to intialize the template with.
142:      * @return string
143:      */
144:     protected function renderTemplate(Container $container, RequestInterface $request)
145:     {
146:         $config   = $this->config();
147:         $template = $this->createTemplate($container, $request);
148: 
149:         return $container['view']->render($config['template'], $template);
150:     }
151: 
152:     /**
153:      * @param  Container        $container A DI (Pimple) container.
154:      * @param  RequestInterface $request   The request to intialize the template with.
155:      * @return string
156:      */
157:     protected function createTemplate(Container $container, RequestInterface $request)
158:     {
159:         $config = $this->config();
160: 
161:         $templateFactory = $container['template/factory'];
162:         $templateFactory->setDefaultClass($config['default_controller']);
163: 
164:         $template = $templateFactory->create($config['controller']);
165:         $template->init($request);
166: 
167:         // Set custom data from config.
168:         $template->setData($config['template_data']);
169: 
170:         return $template;
171:     }
172: 
173:     /**
174:      * @param  string           $redirection The route's destination.
175:      * @param  RequestInterface $request     A PSR-7 compatible Request instance.
176:      * @return Uri|null
177:      */
178:     protected function parseRedirect($redirection, RequestInterface $request)
179:     {
180:         $uri   = $request->getUri()->withUserInfo('');
181:         $parts = parse_url($redirection);
182: 
183:         if (!empty($parts)) {
184:             if (isset($parts['host'])) {
185:                 $uri = Uri::createFromString($redirection);
186:             } else {
187:                 if (isset($parts['path'])) {
188:                     $uri = $uri->withPath($parts['path']);
189:                 }
190: 
191:                 if (isset($parts['query'])) {
192:                     $uri = $uri->withQuery($parts['query']);
193:                 }
194: 
195:                 if (isset($parts['fragment'])) {
196:                     $uri = $uri->withFragment($parts['fragment']);
197:                 }
198:             }
199: 
200:             if ((string)$uri !== (string)$request->getUri()) {
201:                 return $uri;
202:             }
203:         }
204: 
205:         return null;
206:     }
207: 
208:     /**
209:      * @return boolean
210:      */
211:     protected function cacheEnabled()
212:     {
213:         $config = $this->config();
214:         return $config['cache'];
215:     }
216: 
217:     /**
218:      * @return integer
219:      */
220:     protected function cacheTtl()
221:     {
222:         $config = $this->config();
223:         return $config['cache_ttl'];
224:     }
225: 
226:     /**
227:      * @return string
228:      */
229:     protected function cacheIdent()
230:     {
231:         $config = $this->config;
232:         return $config['template'];
233:     }
234: }
235: 
API documentation generated by ApiGen