Finally getting on top of things :). Simplicity core release on the way...
[simplicity.git] / source / lib / simplicity / simplicity.php
blob7d6ce507723b20df8acff93016ccdc66ae1f786c
1 <?php
2 require_once 'core/pluggable/pluggable.php';
4 /**
5 * Simplicity
7 * The main public interface of the Simplicity Framework. This class bootstraps your application and manages and executes the module chain.
10 * @author John Le Drew <jp@antz29.com>
11 * @copyright Copyright (c) 2009, John Le Drew
12 * @license http://www.opensource.org/licenses/mit-license.php MIT License
13 * @version 2.0.0-alpha
15 * @see smp_Tapped
17 class Simplicity extends smp_Pluggable {
19 static private $_instance;
21 private $_options = array(
22 'tapped_cache' => 0,
23 'config_backend' => 'Array',
24 'config_backend_options' => array(
25 'root' => '{APP}config'
29 /**
30 * Config driver instance
32 * @var smp_ConfigDriver
34 private $_config;
36 private $_lib;
37 private $_root;
38 private $_app;
40 private $_modules = array();
42 private $_last_module = false;
44 private $_base = array();
45 private $_chains = array();
46 private $_chain = array();
48 private $_alias = array();
50 /**
51 * Returns the single Simplicity instance.
53 * @return Simplicity
55 static public function getInstance()
57 if (!(self::$_instance instanceof Simplicity))
59 self::$_instance = new Simplicity();
61 return self::$_instance;
64 private function __clone() {}
65 private function __construct() {}
67 /**
68 * Sets any runtime options for the Simplicity framework.
70 * @param $options array An associative array of options to configure Simplicity.
72 * @return Simplicity
74 public function setOptions(array $options = array())
76 $this->_options = array_merge($this->_options,$options);
77 return $this;
80 /**
81 * Initialises the Simplicity framework
83 * @return Simplicity
85 public function init()
87 $this->initEnvironment();
88 $this->initArchive();
89 $this->initTapped();
91 smp_Enviroment::init();
92 smp_Request::init();
94 $accept = smp_Request::getInstance()->getHeader('accept');
95 $accept = is_array($accept) ? $accept[0] : $accept;
96 smp_Response::getInstance()->setHeader('content-type',$accept);
98 $this->createExtensionPoint('smp_Module','dynamic');
99 $this->registerPluginPrefix('smp_','dynamic');
101 $this->createExtensionPoint('smp_ModuleStatic','static');
102 $this->registerPluginPrefix('smp_','static');
104 $this->initConfig();
106 return $this;
110 * Executes the module chain(s) and dies.
113 public function run()
115 $chains = array();
117 $this->_alias = $this->_config->get('modules.alias');
118 $this->_chains = $this->_config->get('modules.chains');
120 $chains = array(
121 '_static' => array(
122 'chain' => array('Static'),
123 'match' => '/_static/*',
124 'nobase' => true
128 $this->_chains = is_array($this->_chains) ? $this->_chains : array();
129 $this->_chains = array_merge($chains,$this->_chains);
131 $this->_base = isset($this->_chains['_base']['chain']) ? $this->_chains['_base']['chain'] : array();
133 unset($this->_chains['_base']);
135 $match = false;
136 foreach ($this->_chains as $name => $chain)
138 if (!isset($chain['match']))
140 $this->runChain($name);
141 break;
143 elseif (isset($chain['match']) && smp_Request::getInstance()->uriMatch($chain['match']))
145 $this->runChain($name);
146 break;
150 smp_Response::getInstance()->sendStatus();
151 smp_Response::getInstance()->sendHeaders();
152 smp_Response::getInstance()->sendContent();
154 die();
157 public function runChain($chain)
159 if (!isset($this->_chains[$chain])) throw new smp_Exception("Chain {$chain} does not exist.");
160 $chain = $this->_chains[$chain];
162 if (isset($chain['chain']) && is_array($chain['chain'])) {
163 $this->_chain = (isset($chain['chain']) && is_array($chain['chain'])) ? $chain['chain'] : array();
166 if (!isset($chain['nobase']) || !$chain['nobase']) {
167 $this->_chain = array_merge($this->_base,$this->_chain);
170 $output = array();
172 while($module = array_shift($this->_chain)) {
173 $output = $this->runModule($module,$output);
178 * Executed the specified $module identifier and an array of arguments. Module identifiers take the format of alias or alias:method.
180 * @param $module
181 * @param $args
182 * @return array
184 public function runModule($module,$args=array())
186 $module = explode(':',$module,2);
187 $method = isset($module[1]) ? $module[1] : 'exec';
188 $module = $module[0];
190 $module = $this->getModuleAlias($module);
192 if ($class = $this->getModuleClass($module,'dynamic')) {
193 $mod = $this->getModule($module);
195 ob_start();
196 $args = $mod->$method($args);
197 smp_Response::getInstance()->addContent(ob_get_clean());
199 $this->_last_module = $module;
201 while($next_mod = $mod->getNext())
203 $args = $this->runModule($next_mod,$args);
206 return $args;
208 else
210 throw new Exception("Module {$module} could not be found!");
215 * Clears the current module chain.
218 public function clearCurrentChain()
220 $this->_chain = array();
224 * Adds a module identifier to the current chain.
226 * @param $module
228 public function addModuleToChain($module)
230 $this->_chain[] = $module;
234 * Returns the last executed module identifier.
236 * @return string
238 public function getLastModule()
240 return $this->_last_module;
244 * Return the module for the given $alias.
246 * @param $alias
247 * @return string
249 public function getModuleAlias($alias)
251 return isset($this->_alias[$alias]) ? $this->_alias[$alias] : $alias;
255 * Instanciate and return an instance of the given module $alias. Optionally, only return the module class name by passing boolean
256 * boolean true on the second parameter.
258 * @param $alias string
259 * @param $class_only bool
260 * @return smp_Module|string
262 public function getModule($alias,$class_only=false)
264 $module = $this->getModuleAlias($alias);
266 $class = $this->getModuleClass($module,'dynamic');
268 if ($class_only) return $class;
270 if (!isset($this->_modules[$alias]) || !($this->_modules[$alias] instanceof $class))
272 $this->_modules[$alias] = new $class($this,$alias);
275 return $this->_modules[$alias];
279 * Gets the current shared config instance.
281 * @return smp_Config
283 public function getConfig()
285 return $this->_config;
289 * Initialise the environment.
292 private function initEnvironment()
294 ini_set('display_errors',1);
295 error_reporting(-1);
297 define('DS',DIRECTORY_SEPARATOR);
298 define('PS',PATH_SEPARATOR);
299 date_default_timezone_set('UTC');
301 $this->_lib = dirname(dirname(dirname(__FILE__))).DS.'lib'.DS;
302 $this->_app = dirname(dirname(dirname(__FILE__))).DS.'app'.DS;
303 $this->_root = $this->_lib.'simplicity'.DS;
305 define('LIB',$this->_lib);
306 define('APP',$this->_app);
307 define('ROOT',$this->_root);
309 foreach ($this->_options as &$option) {
310 $option = str_replace('{APP}',$this->_app,$option);
311 $option = str_replace('{ROOT}',$this->_root,$option);
312 $option = str_replace('{LIB}',$this->_lib,$option);
317 * Initialise the smp_Archive support.
320 private function initArchive()
322 $path = $this->_root.'core'.DS.'archive'.DS.'archive.php';
323 require $path;
325 smp_Archive::init();
329 * Initialise the autoloader.
332 private function initTapped()
334 $path = $this->_root.'core'.DS.'tapped'.DS.'tapped.php';
335 require $path;
337 $t = smp_Tapped::getInstance()
338 ->setCache($this->_options['tapped_cache'])
339 ->addPath($this->_root);
341 if (file_exists($this->_app)) {
342 $t->addPath($this->_app);
345 $t->registerAutoloader();
349 * Initialise the configuration.
352 private function initConfig()
354 $backend = $this->_options['config_backend'];
355 $options = $this->_options['config_backend_options'];
356 $options = is_array($options) ? $options : array();
358 $this->_config = new smp_Config($backend,$options);