1 <?php
2 3 4 5 6 7
8 namespace Cross\Core;
9
10 use Cross\Exception\CoreException;
11 use Cross\Exception\FrontException;
12 use Cross\Runtime\ClosureContainer;
13 use Cross\I\RouterInterface;
14 use Cross\Http\Response;
15 use Cross\Http\Request;
16 use Closure;
17
18
19 version_compare(PHP_VERSION, '5.3.6', '>=') or die('requires PHP 5.3.6!');
20
21
22 defined('PROJECT_PATH') or die('undefined PROJECT_PATH');
23
24
25 define('PROJECT_REAL_PATH', rtrim(PROJECT_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR);
26
27
28 define('APP_PATH_DIR', PROJECT_REAL_PATH . 'app' . DIRECTORY_SEPARATOR);
29
30
31 define('CP_PATH', dirname(__DIR__) . DIRECTORY_SEPARATOR);
32
33 34 35 36 37
38 class Delegate
39 {
40 41 42
43 public $app_name;
44
45 46 47
48 private $app;
49
50 51 52
53 private $router;
54
55 56 57
58 private $config;
59
60 61 62
63 private $loader;
64
65 66 67 68 69
70 private $runtime_config;
71
72 73 74 75 76
77 private $action_container;
78
79 80 81 82 83
84 private static $instance;
85
86 87 88 89 90 91 92 93
94 private function __construct($app_name, array $runtime_config)
95 {
96 $this->app_name = $app_name;
97 $this->runtime_config = $runtime_config;
98
99 $this->loader = Loader::init();
100 $this->config = self::initConfig($app_name, $runtime_config);
101
102 $this->registerNamespace();
103 $this->action_container = new ClosureContainer();
104 $this->router = new Router($this);
105 $this->app = new Application($app_name, $this);
106 }
107
108 109 110 111 112
113 static function getVersion()
114 {
115 return '1.6.1';
116 }
117
118 119 120 121 122 123 124 125 126
127 static function loadApp($app_name, array $runtime_config = array())
128 {
129 if (!isset(self::$instance[$app_name])) {
130 self::$instance[$app_name] = new Delegate($app_name, $runtime_config);
131 }
132
133 return self::$instance[$app_name];
134 }
135
136 137 138 139 140 141 142 143 144 145 146 147
148 public function get($controller, $args = array(), $return_content = false)
149 {
150 return $this->app->dispatcher($controller, $args, $return_content);
151 }
152
153 154 155 156 157 158
159 public function run()
160 {
161 $this->app->dispatcher($this->router->getRouter());
162 }
163
164 165 166 167 168 169
170 public function rRun(RouterInterface $router)
171 {
172 $this->app->dispatcher($router);
173 }
174
175 176 177 178 179 180 181 182 183 184 185 186 187
188 public function rest()
189 {
190 return Rest::getInstance($this);
191 }
192
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
212 public function cliRun($run_argc = false, $run_argv = false)
213 {
214 if (PHP_SAPI !== 'cli') {
215 die('This app is only running from CLI');
216 }
217
218 if (false === $run_argc) {
219 $run_argc = $_SERVER['argc'];
220 }
221
222 if (false === $run_argv) {
223 $run_argv = $_SERVER['argv'];
224 }
225
226 if ($run_argc == 1) {
227 die('Please specify params: controller:action params');
228 }
229
230
231 array_shift($run_argv);
232 $controller = array_shift($run_argv);
233
234
235 $this->get($controller, $run_argv);
236 }
237
238 239 240 241 242 243 244
245 function on($name, Closure $f)
246 {
247 $this->action_container->add($name, $f);
248 return $this;
249 }
250
251 252 253 254 255
256 function getApplication()
257 {
258 return $this->app;
259 }
260
261 262 263 264 265
266 function getConfig()
267 {
268 return $this->config;
269 }
270
271 272 273 274 275
276 function getLoader()
277 {
278 return $this->loader;
279 }
280
281 282 283 284 285
286 function getRuntimeConfig()
287 {
288 return $this->runtime_config;
289 }
290
291 292 293
294 function getRouter()
295 {
296 return $this->router;
297 }
298
299 300 301 302 303
304 function getClosureContainer()
305 {
306 return $this->action_container;
307 }
308
309 310 311
312 function getRequest()
313 {
314 return Request::getInstance();
315 }
316
317 318 319
320 function getResponse()
321 {
322 return Response::getInstance();
323 }
324
325 326 327 328 329 330 331 332 333
334 private static function initConfig($app_name, array $runtime_config)
335 {
336 $request = Request::getInstance();
337 $host = $request->getHostInfo();
338 $index_name = $request->getIndexName();
339
340 $request_url = $request->getBaseUrl();
341 $script_path = $request->getScriptFilePath();
342
343
344 $runtime_config['app'] = array(
345 'name' => $app_name,
346 'path' => APP_PATH_DIR . $app_name . DIRECTORY_SEPARATOR
347 );
348
349 $env_config = array(
350
351 'url' => array(
352 'host' => $host,
353 'index' => $index_name,
354 'request' => $request_url,
355 'full_request' => $host . $request_url
356 ),
357
358
359 'path' => array(
360 'cache' => PROJECT_REAL_PATH . 'cache' . DIRECTORY_SEPARATOR,
361 'config' => PROJECT_REAL_PATH . 'config' . DIRECTORY_SEPARATOR,
362 'script' => $script_path . DIRECTORY_SEPARATOR,
363 ),
364
365
366 'static' => array(
367 'url' => $host . $request_url . '/static/',
368 'path' => $script_path . DIRECTORY_SEPARATOR . 'static' . DIRECTORY_SEPARATOR
369 )
370 );
371
372 foreach ($env_config as $key => $value) {
373 if (isset($runtime_config[$key]) && is_array($runtime_config[$key])) {
374 $runtime_config[$key] = array_merge($value, $runtime_config[$key]);
375 } elseif (!isset($runtime_config[$key])) {
376 $runtime_config[$key] = $value;
377 }
378 }
379
380 return Config::load(APP_PATH_DIR . $app_name . DIRECTORY_SEPARATOR . 'init.php')->combine($runtime_config);
381 }
382
383 384 385 386 387
388 private function registerNamespace()
389 {
390 $namespaceConfig = $this->config->get('namespace');
391 if (!empty($namespaceConfig)) {
392 foreach ($namespaceConfig as $namespace => $libDir) {
393 $libDir = PROJECT_REAL_PATH . $libDir;
394 if (file_exists($libDir)) {
395 $this->loader->registerNamespace($namespace, $libDir);
396 } else {
397 throw new CoreException("Register namespace {$namespace} failed");
398 }
399 }
400 }
401 }
402 }
403