Skip to content

Instantly share code, notes, and snippets.

@ajshort
Created July 3, 2012 07:45
Show Gist options
  • Save ajshort/3038323 to your computer and use it in GitHub Desktop.
Save ajshort/3038323 to your computer and use it in GitHub Desktop.
<?php
/**
* @package framework
* @subpackage core
*/
namespace SilverStripe\Framework\Core;
use SilverStripe\Framework\FrameworkModule;
use SilverStripe\Framework\Injector\Injector;
use SilverStripe\Framework\Injector\ApplicationServiceConfigurationLocator;
use SilverStripe\Framework\Manifest\ClassLoader;
use SilverStripe\Framework\Manifest\Manifest;
use SilverStripe\Framework\Manifest\TemplateLoader;
/**
* @package framework
* @subpackage core
*/
abstract class Application {
private static $curr;
protected $modules = array();
protected $manifest;
protected $config;
protected $injector;
protected $classLoader;
protected $templateLoader;
protected $appPath;
protected $tempPath;
/**
* Returns the currently active application instance.
*
* @return Application
*/
public static function curr() {
return self::$curr;
}
/**
* Initialises the application so it is ready to begin handling requests.
*/
public function start() {
// Register this application as the current one
self::$curr = $this;
// Register modules
$this->registerModules();
// Bootstrap the environment
Bootstrap::bootstrap($this);
// Create the manifest, and register loaders
$this->initManifest();
$this->initClassLoader();
$this->initTemplateLoader();
// Create the config and then use it to create the injector, which will
// be used for later dependencies
$this->createInjector();
$this->initConfig();
$this->initInjector();
// Register the created objects with the injector
$injector = $this->getInjector();
$injector->registerNamedService('application', $this);
$injector->registerNamedService('manifest', $this->getManifest());
$injector->registerNamedService('config', $this->getConfig());
$injector->registerNamedService('class_loader', $this->getClassLoader());
$injector->registerNamedService('template_loader', $this->getTemplateLoader());
}
/**
* Stops the application, should be called after the response has been
* generated.
*/
public function stop() {
if(self::$curr !== $this) {
throw new \Exception('The application is not currently running');
}
self::$curr = null;
}
/**
* Passes a request to the dispatcher and returns the response.
*
* @param Request $request
* @return Response
*/
public function handle(Request $request) {
return $this->injector->get('dispatcher')->handle($request);
}
/**
* Returns the registered module instances.
*
* @return array
*/
public function getModules() {
return $this->modules;
}
/**
* Returns a module instance by name.
*
* @param string $name
* @return ModuleInterface
*/
public function getModule($name) {
if(isset($this->modules[$name])) return $this->modules[$name];
}
/**
* @return Manifest
*/
public function getManifest() {
return $this->manifest;
}
/**
* @return Config
*/
public function getConfig() {
return $this->config;
}
/**
* @return Injector
*/
public function getInjector() {
return $this->injector;
}
/**
* @return ClassLoader
*/
public function getClassLoader() {
return $this->classLoader;
}
/**
* @return TemplateLoader
*/
public function getTemplateLoader() {
return $this->templateLoader;
}
/**
* Returns the path to the application.
*
* @return string
*/
public function getPath() {
if(!$this->appPath) {
$reflector = new \ReflectionObject($this);
$this->appPath = dirname($reflector->getFileName());
}
return $this->appPath;
}
/**
* Returns the path to the base of the application.
*
* @return string
*/
public function getBasePath() {
return dirname($this->getPath());
}
/**
* Returns the path to the publically accesible webroot.
*
* @return string
*/
public function getPublicPath() {
throw new \Exception('Not yet implemented');
}
/**
* Returns the path to the app-specific temp directory, creating one if
* one doesn't exist.
*
* @return string
*/
public function getTempPath() {
if(!$this->tempPath) {
$dir = 'silverstripe-' . md5($this->getPath());
$dir = sys_get_temp_dir() . '/' . $dir;
if(!is_dir($dir)) {
mkdir($dir);
}
$this->tempPath = $dir;
}
return $this->tempPath;
}
/**
* Registers the module instances for this application.
*/
protected function registerModules() {
$this->registerModule(new FrameworkModule());
}
/**
* Registers a module. This can either be passed a {@link ModuleInterface}
* instance, or the module name and path. The path can either be absolute
* or relative to the base path.
*
* @param ModuleInterface|string $module
* @param string $path
*/
protected function registerModule() {
if(func_num_args() == 1) {
$module = func_get_arg(0);
} else {
$name = func_get_arg(0);
$path = func_get_arg(1);
if($path[0] != '/') {
$path = $this->getBasePath() . '/' . $path;
}
$module = new Module($name, $path);
}
if(!$module instanceof ModuleInterface) {
throw new \Exception('The module must implement ModuleInterface');
}
if($this->getModule($module->getName())) {
throw new \Exception("The module {$module->getName()} is already registered");
}
$this->modules[$module->getName()] = $module;
}
/**
* Creates and initialises the application manifest.
*/
protected function initManifest() {
$this->manifest = new Manifest($this);
$this->manifest->init(isset($_GET['flush']));
}
/**
* Creates and initialises the application config instance.
*/
protected function initConfig() {
$this->config = new Config($this->manifest->getConfigManifest());
$this->config->init();
}
/**
* Createss the injector but does not initialise it. This must be done in
* two stages as initialisation requires the config to be available.
*/
protected function createInjector() {
$this->injector = new Injector();
}
/**
* Initialises the previously created injector.
*/
protected function initInjector() {
$this->getInjector()->setConfigLocator(new ApplicationServiceConfigurationLocator($this));
}
/**
* Creates and initialises the class loader instance.
*/
protected function initClassLoader() {
$this->classLoader = new ClassLoader($this->manifest->getPhpManifest());
$this->classLoader->register();
}
/**
* Creates and initialises the template loader instance.
*/
protected function initTemplateLoader() {
$this->templateLoader = new TemplateLoader($this->manifest->getTemplateManifest());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment