2 require_once 'core/pluggable/pluggable.php';
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
17 class Simplicity
extends smp_Pluggable
{
19 static private $_instance;
21 private $_options = array(
23 'config_backend' => 'Array',
24 'config_backend_options' => array(
25 'root' => '{APP}config'
30 * Config driver instance
32 * @var smp_ConfigDriver
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();
51 * Returns the single Simplicity instance.
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() {}
68 * Sets any runtime options for the Simplicity framework.
70 * @param $options array An associative array of options to configure Simplicity.
74 public function setOptions(array $options = array())
76 $this->_options
= array_merge($this->_options
,$options);
81 * Initialises the Simplicity framework
85 public function init()
87 $this->initEnvironment();
91 smp_Enviroment
::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');
110 * Executes the module chain(s) and dies.
113 public function run()
117 $this->_alias
= $this->_config
->get('modules.alias');
118 $this->_chains
= $this->_config
->get('modules.chains');
122 'chain' => array('Static'),
123 'match' => '/_static/*',
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']);
136 foreach ($this->_chains
as $name => $chain)
138 if (!isset($chain['match']))
140 $this->runChain($name);
143 elseif (isset($chain['match']) && smp_Request
::getInstance()->uriMatch($chain['match']))
145 $this->runChain($name);
150 smp_Response
::getInstance()->sendStatus();
151 smp_Response
::getInstance()->sendHeaders();
152 smp_Response
::getInstance()->sendContent();
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
);
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.
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);
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);
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.
228 public function addModuleToChain($module)
230 $this->_chain
[] = $module;
234 * Returns the last executed module identifier.
238 public function getLastModule()
240 return $this->_last_module
;
244 * Return the module for the given $alias.
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.
283 public function getConfig()
285 return $this->_config
;
289 * Initialise the environment.
292 private function initEnvironment()
294 ini_set('display_errors',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';
329 * Initialise the autoloader.
332 private function initTapped()
334 $path = $this->_root
.'core'.DS
.'tapped'.DS
.'tapped.php';
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);