1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194:
<?php
/**
* TipyApp
*
* @package tipy
*/
/**
* Application singleton
*
* Initializes application context and executes controller's action
*
* <code>
* $app = TipyApp::getInstance();
* </code>
*
* ### Lazy database connection
*
* Application instance does not immediately connect to the database.
* Database connection is established on first TipyModel or TipyDAO object creation.
*
* @see TipyController
* @see TipyModel
* @see TipyDAO
*/
class TipyApp {
private static $instance = null;
/**
* @var TipyConfig
*/
public $config;
/**
* @var TipyView
*/
public $env;
/**
* @var TipyCookie
*/
public $cookie;
/**
* MySQL database connection
* @var mysqli|null
*/
public $db;
/**
* @var TipyInput
*/
public $in;
/**
* @var TipyOutput
*/
public $out;
/**
* @var TipyView
*/
public $view;
/**
* @var TipySession
*/
public $session;
/**
* @var TipyLogger
*/
public $logger;
/**
* Path to your application's **public** directory
* @var string
*/
public $documentRoot;
private function __clone() {}
private function __wakeup() {}
/**
* Hidden from user. Runs only once.
* Initializes application context.
* @internal
*/
private function __construct() {
$this->config = new TipyConfig();
$this->request = new TipyRequest();
$this->env = new TipyEnv();
$this->cookie = new TipyCookie();
$this->in = new TipyInput();
$this->out = new TipyOutput();
$this->view = new TipyView();
$this->db = null; // Lazy database connection
if (CLI_MODE) {
$this->session = new TipyCliSession();
} else {
$this->session = new TipySession();
}
// dispatcher.php is called by Apache with current working dir set to DocumentRoot
$cwd = getcwd();
$this->documentRoot = $cwd;
$this->view->setTemplatePath(realpath($cwd.'/../app/views'));
$this->setupLogger();
}
/**
* Get application instance
*
* Contruct application if it has not been initialized yet.
*
* **NOTE** Does not connect to database.
*
* @return TipyApp
* @see TipyApp::connectToDb()
*/
public static function getInstance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Connect to database
*/
public function connectToDb() {
new TipyDAO();
}
/**
* Open log stream specified in config.ini and set threshold
*/
private function setupLogger() {
$logFile = $this->config->get('log_file');
if (!$logFile || preg_match('/^\W*$/', $logFile)) {
$logFile = 'php://stderr';
}
$threshold = $this->config->get('log_level_threshold');
if (!$threshold || preg_match('/^\W*$/', $threshold)) {
$threshold = 'OFF';
}
$this->logger = new TipyLogger($logFile);
$this->logger->setThreshold($threshold);
}
/**
* Initialize controller and run action
*
* Requires **$app->in('controller')** and **$app->in('action')**
* parameters to be defined.
*
* @see TipyController
* @todo Different exceptions handling in production and development modes
*/
public function run() {
$this->logger->debug($this->request->method().': '.$this->request->uri());
try {
// Get controller and action name
$controllerName = $this->in->get('controller');
$actionName = $this->in->get('action');
// Some basic checking
if (!$controllerName || preg_match('/^\W*$/', $controllerName)) {
throw new TipyException('Controller name is missing');
}
if (!$actionName || preg_match('/^\W*$/', $actionName)) {
throw new TipyException('Action name is missing');
}
$controllerName = TipyInflector::controllerize($controllerName).'Controller';
if (class_exists($controllerName)) {
$controller = new $controllerName();
} else {
throw new TipyException('Unable to find '.$controllerName.' class');
}
$actionName = TipyInflector::camelCase($actionName);
if (in_array($actionName, get_class_methods($controllerName))) {
$this->logger->debug('Executing '.$controllerName.'::'.$actionName.'();');
$controller->execute($actionName);
} else {
throw new TipyException('Undefined action '.$controllerName.'::'.$actionName.'()');
}
} catch (Exception $exception) {
throw new TipyException($exception->getMessage(), $exception->getCode(), $exception);
}
}
}