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: use Exception;
  6: use InvalidArgumentException;
  7: 
  8: // From PSR-7
  9: use Psr\Http\Message\UriInterface;
 10: 
 11: // From Slim
 12: use Slim\Http\Uri;
 13: 
 14: // From 'charcoal-config'
 15: use Charcoal\Config\AbstractConfig;
 16: 
 17: // From 'charcoal-view'
 18: use Charcoal\View\ViewConfig;
 19: 
 20: // From 'charcoal-app'
 21: use Charcoal\App\Config\CacheConfig;
 22: use Charcoal\App\Config\FilesystemConfig;
 23: use Charcoal\App\Config\LoggerConfig;
 24: 
 25: /**
 26:  * Charcoal App configuration
 27:  */
 28: class AppConfig extends AbstractConfig
 29: {
 30:     /**
 31:      * The application's timezone.
 32:      *
 33:      * @var string|null
 34:      */
 35:     private $timezone;
 36: 
 37:     /**
 38:      * The application's name.
 39:      *
 40:      * For internal usage.
 41:      *
 42:      * @var string|null
 43:      */
 44:     private $projectName;
 45: 
 46:     /**
 47:      * The base path for the Charcoal installation.
 48:      *
 49:      * @var string|null
 50:      */
 51:     private $basePath;
 52: 
 53:     /**
 54:      * The base URL (public) for the Charcoal installation.
 55:      *
 56:      * @var UriInterface|null
 57:      */
 58:     private $baseUrl;
 59: 
 60:     /**
 61:      * The path to the public / web directory.
 62:      *
 63:      * @var string|null
 64:      */
 65:     private $publicPath;
 66: 
 67:     /**
 68:      * The path to the storage directory.
 69:      *
 70:      * @var string|null
 71:      */
 72:     private $storagePath;
 73: 
 74:     /**
 75:      * Whether the debug mode is enabled (TRUE) or not (FALSE).
 76:      *
 77:      * @var boolean
 78:      */
 79:     private $devMode = false;
 80: 
 81:     /**
 82:      * The application's routes.
 83:      *
 84:      * @var array
 85:      */
 86:     private $routes = [];
 87: 
 88:     /**
 89:      * The application's dynamic routes.
 90:      *
 91:      * @var array
 92:      */
 93:     private $routables = [];
 94: 
 95:     /**
 96:      * The application's handlers.
 97:      *
 98:      * @var array
 99:      */
100:     private $handlers = [];
101: 
102:     /**
103:      * The application's modules.
104:      *
105:      * @var array
106:      */
107:     private $modules = [];
108: 
109:     /**
110:      * The application's caching configset.
111:      *
112:      * @var CacheConfig
113:      */
114:     private $cache;
115: 
116:     /**
117:      * The application's logging configset.
118:      *
119:      * @var LoggerConfig
120:      */
121:     private $logger;
122: 
123:     /**
124:      * The application's view/rendering configset.
125:      *
126:      * @var ViewConfig
127:      */
128:     protected $view;
129: 
130:     /**
131:      * The application's database configsets.
132:      *
133:      * @var array
134:      */
135:     private $databases = [];
136: 
137:     /**
138:      * The application's default database configset.
139:      *
140:      * @var string
141:      */
142:     private $defaultDatabase;
143: 
144:     /**
145:      * The application's filesystem configset.
146:      *
147:      * @var FilesystemConfig
148:      */
149:     private $filesystem;
150: 
151:     /**
152:      * Default app-config values.
153:      *
154:      * @return array
155:      */
156:     public function defaults()
157:     {
158:         /** @var string $baseDir Presume that Charcoal App _is_ the application */
159:         $baseDir = rtrim(realpath(__DIR__.'/../../../'), '/').'/';
160: 
161:         return [
162:             'project_name'     => '',
163:             'base_path'        => $baseDir,
164:             'public_path'      => null,
165:             'storage_path'     => null,
166:             'timezone'         => 'UTC',
167:             'routes'           => [],
168:             'routables'        => [],
169:             'handlers'         => [],
170:             'modules'          => [],
171:             'cache'            => [],
172:             'logger'           => [],
173:             'view'             => [],
174:             'databases'        => [],
175:             'default_database' => 'default',
176:             'dev_mode'         => false
177:         ];
178:     }
179: 
180:     /**
181:      * Set the application's absolute root path.
182:      *
183:      * Resolves symlinks with realpath() and ensure trailing slash.
184:      *
185:      * @param  string $path The absolute path to the application's root directory.
186:      * @throws InvalidArgumentException If the argument is not a string.
187:      * @return AppConfig Chainable
188:      */
189:     public function setBasePath($path)
190:     {
191:         if ($path === null) {
192:             throw new InvalidArgumentException(
193:                 'The base path is required.'
194:             );
195:         }
196: 
197:         if (!is_string($path)) {
198:             throw new InvalidArgumentException(
199:                 'The base path must be a string'
200:             );
201:         }
202: 
203:         $this->basePath = rtrim(realpath($path), '\\/').DIRECTORY_SEPARATOR;
204: 
205:         return $this;
206:     }
207: 
208:     /**
209:      * Retrieve the application's absolute root path.
210:      *
211:      * @return string The absolute path to the application's root directory.
212:      */
213:     public function basePath()
214:     {
215:         return $this->basePath;
216:     }
217: 
218:     /**
219:      * Set the application's absolute path to the public web directory.
220:      *
221:      * @param  string $path The path to the application's public directory.
222:      * @throws InvalidArgumentException If the argument is not a string.
223:      * @return AppConfig Chainable
224:      */
225:     public function setPublicPath($path)
226:     {
227:         if ($path === null) {
228:             $this->publicPath = null;
229: 
230:             return $this;
231:         }
232: 
233:         if (!is_string($path)) {
234:             throw new InvalidArgumentException(
235:                 'The public path must be a string'
236:             );
237:         }
238: 
239:         $this->publicPath = rtrim(realpath($path), '\\/').DIRECTORY_SEPARATOR;
240: 
241:         return $this;
242:     }
243: 
244:     /**
245:      * Retrieve the application's absolute path to the public web directory.
246:      *
247:      * @return string The absolute path to the application's public directory.
248:      */
249:     public function publicPath()
250:     {
251:         if (!isset($this->publicPath)) {
252:             return $this->basePath().'www'.DIRECTORY_SEPARATOR;
253:         }
254: 
255:         return $this->publicPath;
256:     }
257: 
258:     /**
259:      * Set the application's absolute path to the storage directory.
260:      *
261:      * @param  string|null $path The path to the application's storage directory.
262:      * @throws InvalidArgumentException If the argument is not a string.
263:      * @return $this
264:      */
265:     public function setStoragePath($path)
266:     {
267:         if ($path === null) {
268:             $this->storagePath = null;
269: 
270:             return $this;
271:         }
272: 
273:         if (!is_string($path)) {
274:             throw new InvalidArgumentException(
275:                 'The storage path must be a string'
276:             );
277:         }
278: 
279:         $this->storagePath = rtrim(realpath($path), '\\/').DIRECTORY_SEPARATOR;
280: 
281:         return $this;
282:     }
283: 
284:     /**
285:      * Get the path to the storage directory.
286:      *
287:      * Note that the storage space is outside of the public access.
288:      *
289:      * @return string
290:      */
291:     public function storagePath()
292:     {
293:         if (!isset($this->storagePath)) {
294:             return $this->basePath().'uploads'.DIRECTORY_SEPARATOR;
295:         }
296: 
297:         return $this->storagePath;
298:     }
299: 
300:     /**
301:      * Set the application's fully qualified base URL to the public web directory.
302:      *
303:      * @param  UriInterface|string $uri The base URI to the application's web directory.
304:      * @return AppConfig Chainable
305:      */
306:     public function setBaseUrl($uri)
307:     {
308:         $this->baseUrl = Uri::createFromString($uri);
309: 
310:         return $this;
311:     }
312: 
313:     /**
314:      * Retrieve the application's fully qualified base URL to the public web directory.
315:      *
316:      * @return UriInterface|null The base URI to the application's web directory.
317:      */
318:     public function baseUrl()
319:     {
320:         return $this->baseUrl;
321:     }
322: 
323:     /**
324:      * Set the application's default timezone.
325:      *
326:      * @param  string $timezone The timezone string.
327:      * @throws InvalidArgumentException If the argument is not a string.
328:      * @return AppConfig Chainable
329:      */
330:     public function setTimezone($timezone)
331:     {
332:         if (!is_string($timezone)) {
333:             throw new InvalidArgumentException(
334:                 'Timezone must be a string.'
335:             );
336:         }
337:         $this->timezone = $timezone;
338:         return $this;
339:     }
340: 
341:     /**
342:      * Retrieve the application's default timezone.
343:      *
344:      * Will be used by the PHP date and date-time functions.
345:      *
346:      * @return string
347:      */
348:     public function timezone()
349:     {
350:         if (isset($this->timezone)) {
351:             return $this->timezone;
352:         } else {
353:             return 'UTC';
354:         }
355:     }
356: 
357:     /**
358:      * Sets the project name.
359:      *
360:      * @param string|null $projectName The project name.
361:      * @throws InvalidArgumentException If the project argument is not a string (or null).
362:      * @return AppConfig Chainable
363:      */
364:     public function setProjectName($projectName)
365:     {
366:         if ($projectName === null) {
367:             $this->projectName = null;
368:             return $this;
369:         }
370:         if (!is_string($projectName)) {
371:             throw new InvalidArgumentException(
372:                 'Project name must be a string'
373:             );
374:         }
375:         $this->projectName = $projectName;
376:         return $this;
377:     }
378: 
379:     /**
380:      * @return string|null
381:      */
382:     public function projectName()
383:     {
384:         if ($this->projectName === null) {
385:             $baseUrl = $this->baseUrl();
386:             if ($baseUrl) {
387:                 return $baseUrl->getHost();
388:             }
389:         }
390:         return $this->projectName;
391:     }
392: 
393:     /**
394:      * @param boolean $devMode The "dev mode" flag.
395:      * @return AppConfig Chainable
396:      */
397:     public function setDevMode($devMode)
398:     {
399:         $this->devMode = !!$devMode;
400:         return $this;
401:     }
402: 
403:     /**
404:      * @return boolean
405:      */
406:     public function devMode()
407:     {
408:         return !!$this->devMode;
409:     }
410: 
411:     /**
412:      * @param array $view The view configuration structure to set.
413:      * @return AppConfig Chainable
414:      */
415:     public function setView(array $view)
416:     {
417:         if (!isset($this->view)) {
418:             $this->view = [];
419:         }
420: 
421:         $this->view = array_merge($this->view, $view);
422: 
423:         return $this;
424:     }
425: 
426:     /**
427:      * Parse the application's route configuration.
428:      *
429:      * @see    \Charcoal\Admin\Config::setRoutes() For a similar implementation.
430:      * @param  array $routes The route configuration structure to set.
431:      * @return AppConfig Chainable
432:      */
433:     public function setRoutes(array $routes)
434:     {
435:         if (!isset($this->routes)) {
436:             $this->routes = [];
437:         }
438: 
439:         $toIterate = [ 'templates', 'actions', 'scripts' ];
440:         foreach ($routes as $key => $val) {
441:             if (in_array($key, $toIterate) && isset($this->routes[$key])) {
442:                 $this->routes[$key] = array_merge($this->routes[$key], $val);
443:             } else {
444:                 $this->routes[$key] = $val;
445:             }
446:         }
447: 
448:         return $this;
449:     }
450: 
451:     /**
452:      * @return array
453:      */
454:     public function routes()
455:     {
456:         return $this->routes;
457:     }
458: 
459:     /**
460:      * @param array $routables The routable configuration structure to set.
461:      * @return AppConfig Chainable
462:      */
463:     public function setRoutables(array $routables)
464:     {
465:         $this->routables = $routables;
466:         return $this;
467:     }
468: 
469:     /**
470:      * @return array
471:      */
472:     public function routables()
473:     {
474:         return $this->routables;
475:     }
476: 
477:     /**
478:      * Define custom response and error handlers.
479:      *
480:      * Slim provides five standard handlers:
481:      * - "foundHandler"
482:      * - "notFoundHandler"
483:      * - "notAllowedHandler"
484:      * - "errorHandler"
485:      * - "phpErrorHandler"
486:      *
487:      * @param array $handlers The handlers configuration structure to set.
488:      * @return AppConfig Chainable
489:      */
490:     public function setHandlers(array $handlers)
491:     {
492:         $this->handlers = $handlers;
493:         return $this;
494:     }
495: 
496:     /**
497:      * @return array
498:      */
499:     public function handlers()
500:     {
501:         return $this->handlers;
502:     }
503: 
504:     /**
505:      * Set the configuration modules.
506:      *
507:      * The modules are defined in a `key`=>`\Charcoal\App\Module\ModuleConfig` structure.
508:      *
509:      * @param array $modules The module configuration structure to set.
510:      * @return AppConfig Chainable
511:      */
512:     public function setModules(array $modules)
513:     {
514:         $this->modules = $modules;
515:         return $this;
516:     }
517: 
518:     /**
519:      * @return array
520:      */
521:     public function modules()
522:     {
523:         return $this->modules;
524:     }
525: 
526:     /**
527:      * @param array|CacheConfig $cache The application global cache config.
528:      * @throws InvalidArgumentException If the argument is not an array or a config.
529:      * @return AppConfig Chainable
530:      */
531:     public function setCache($cache)
532:     {
533:         if ($cache instanceof CacheConfig) {
534:             $this->cache = $cache;
535:             $this->cache->addDelegate($this);
536:         } elseif (is_array($cache)) {
537:             $this->cache = new CacheConfig($cache, [$this]);
538:         } else {
539:             throw new InvalidArgumentException(
540:                 'Cache must be an array of config options or a CacheConfig object.'
541:             );
542:         }
543:         return $this;
544:     }
545: 
546:     /**
547:      * Get the application's global `CacheConfig`.
548:      *
549:      * @return CacheConfig
550:      */
551:     public function cache()
552:     {
553:         return $this->cache;
554:     }
555: 
556:     /**
557:      * @param array|LoggerConfig $logger The global logger config.
558:      * @throws InvalidArgumentException If the argument is not an array or a config.
559:      * @return AppConfig Chainable
560:      */
561:     public function setLogger($logger)
562:     {
563:         if ($logger instanceof LoggerConfig) {
564:             $this->logger = $logger;
565:             $this->logger->addDelegate($this);
566:         } elseif (is_array($logger)) {
567:             $this->logger = new LoggerConfig($logger, [$this]);
568:         } else {
569:             throw new InvalidArgumentException(
570:                 'Logger must be an array of config options or a LoggerConfig object.'
571:             );
572:         }
573:         return $this;
574:     }
575: 
576:     /**
577:      * Get the application's global `LoggerConfig`
578:      *
579:      * @return LoggerConfig
580:      */
581:     public function logger()
582:     {
583:         return $this->logger;
584:     }
585: 
586:     /**
587:      * @param array $databases The avaiable databases config.
588:      * @return Config Chainable
589:      */
590:     public function setDatabases(array $databases)
591:     {
592:         $this->databases = $databases;
593:         return $this;
594:     }
595: 
596:     /**
597:      * @throws Exception If trying to access this method and no databases were set.
598:      * @return array
599:      */
600:     public function databases()
601:     {
602:         if ($this->databases === null) {
603:             throw new Exception(
604:                 'Invalid app config: Databases are not set.'
605:             );
606:         }
607:         return $this->databases;
608:     }
609: 
610:     /**
611:      * @param string $ident The ident of the database to return the configuration of.
612:      * @throws InvalidArgumentException If the ident argument is not a string.
613:      * @throws Exception If trying to access an invalid database.
614:      * @return array
615:      */
616:     public function databaseConfig($ident)
617:     {
618:         if (!is_string($ident)) {
619:             throw new InvalidArgumentException(
620:                 'Invalid app config: default database must be a string.'
621:             );
622:         }
623:         $databases = $this->databases();
624:         if (!isset($databases[$ident])) {
625:             throw new Exception(
626:                 sprintf('Invalid app config: no database configuration matches "%s".', $ident)
627:             );
628:         }
629:         return $databases[$ident];
630:     }
631: 
632:     /**
633:      * @param string $defaultDatabase The default database ident.
634:      * @throws InvalidArgumentException If the argument is not a string.
635:      * @return AppConfig Chainable
636:      */
637:     public function setDefaultDatabase($defaultDatabase)
638:     {
639:         if (!is_string($defaultDatabase)) {
640:             throw new InvalidArgumentException(
641:                 'Invalid app config: Default database must be a string.'
642:             );
643:         }
644:         $this->defaultDatabase = $defaultDatabase;
645:         return $this;
646:     }
647: 
648:     /**
649:      * @param string $ident  The database ident.
650:      * @param array  $config The database options.
651:      * @throws InvalidArgumentException If the arguments are invalid.
652:      * @return AppConfig Chainable
653:      */
654:     public function addDatabase($ident, array $config)
655:     {
656:         if (!is_string($ident)) {
657:             throw new InvalidArgumentException(
658:                 'Invalid app config: database ident must be a string.'
659:             );
660:         }
661: 
662:         if ($this->databases === null) {
663:             $this->databases = [];
664:         }
665:         $this->databases[$ident] = $config;
666:         return $this;
667:     }
668: 
669:     /**
670:      * @throws Exception If trying to access this method before a setter.
671:      * @return mixed
672:      */
673:     public function defaultDatabase()
674:     {
675:         if ($this->defaultDatabase === null) {
676:             throw new Exception(
677:                 'Invalid app config: default database is not set.'
678:             );
679:         }
680:         return $this->defaultDatabase;
681:     }
682: 
683:     /**
684:      * @param array|FilesystemConfig $filesystem The application global cache config.
685:      * @throws InvalidArgumentException If the argument is not an array or a config.
686:      * @return AppConfig Chainable
687:      */
688:     public function setFilesystem($filesystem)
689:     {
690:         if ($filesystem instanceof FilesystemConfig) {
691:             $this->filesystem = $filesystem;
692:             $this->filesystem->addDelegate($this);
693:         } elseif (is_array($filesystem)) {
694:             $this->filesystem = new FileSystemConfig($filesystem, [$this]);
695:         } else {
696:             throw new InvalidArgumentException(
697:                 'Filesystem must be an array of config options or a FilesystemConfig object.'
698:             );
699:         }
700:         return $this;
701:     }
702: 
703:     /**
704:      * Get the application's global `FilesystemConfig`
705:      *
706:      * @return FilesystemConfig
707:      */
708:     public function filesystem()
709:     {
710:         return $this->filesystem;
711:     }
712: }
713: 
API documentation generated by ApiGen