00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 App::import('Core', array('Router', 'Controller'));
00032
00033
00034
00035
00036
00037
00038
00039
00040 class Dispatcher extends Object {
00041
00042
00043
00044
00045
00046
00047 var $base = false;
00048
00049
00050
00051
00052
00053
00054 var $webroot = '/';
00055
00056
00057
00058
00059
00060
00061 var $here = false;
00062
00063
00064
00065
00066
00067
00068 var $admin = false;
00069
00070
00071
00072
00073
00074
00075 var $plugin = null;
00076
00077
00078
00079
00080
00081
00082 var $params = null;
00083
00084
00085
00086 function __construct($url = null, $base = false) {
00087 if ($base !== false) {
00088 Configure::write('App.base', $base);
00089 }
00090 if ($url !== null) {
00091 return $this->dispatch($url);
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 function dispatch($url = null, $additionalParams = array()) {
00107 if ($this->base === false) {
00108 $this->base = $this->baseUrl();
00109 }
00110
00111 if (is_array($url)) {
00112 $url = $this->__extractParams($url, $additionalParams);
00113 } else {
00114 if ($url) {
00115 $_GET['url'] = $url;
00116 }
00117 $url = $this->getUrl();
00118 $this->params = array_merge($this->parseParams($url), $additionalParams);
00119 }
00120
00121 $this->here = $this->base . '/' . $url;
00122
00123 if ($this->cached($url)) {
00124 $this->_stop();
00125 }
00126
00127 $controller =& $this->__getController();
00128
00129 if (!is_object($controller)) {
00130 Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot)));
00131 return $this->cakeError('missingController', array(array(
00132 'className' => Inflector::camelize($this->params['controller']) . 'Controller',
00133 'webroot' => $this->webroot,
00134 'url' => $url,
00135 'base' => $this->base
00136 )));
00137 }
00138
00139 $privateAction = (bool)(strpos($this->params['action'], '_', 0) === 0);
00140 $prefixes = Router::prefixes();
00141
00142 if (!empty($prefixes)) {
00143 if (isset($this->params['prefix'])) {
00144 $this->params['action'] = $this->params['prefix'] . '_' . $this->params['action'];
00145 } elseif (strpos($this->params['action'], '_') !== false && !$privateAction) {
00146 list($prefix, $action) = explode('_', $this->params['action']);
00147 $privateAction = in_array($prefix, $prefixes);
00148 }
00149 }
00150
00151 Router::setRequestInfo(array(
00152 $this->params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot)
00153 ));
00154
00155 if ($privateAction) {
00156 return $this->cakeError('privateAction', array(array(
00157 'className' => Inflector::camelize($this->params['controller'] . "Controller"),
00158 'action' => $this->params['action'],
00159 'webroot' => $this->webroot,
00160 'url' => $url,
00161 'base' => $this->base
00162 )));
00163 }
00164
00165 $controller->base = $this->base;
00166 $controller->here = $this->here;
00167 $controller->webroot = $this->webroot;
00168 $controller->plugin = $this->plugin;
00169 $controller->params =& $this->params;
00170 $controller->action =& $this->params['action'];
00171 $controller->passedArgs = array_merge($this->params['pass'], $this->params['named']);
00172
00173 if (!empty($this->params['data'])) {
00174 $controller->data =& $this->params['data'];
00175 } else {
00176 $controller->data = null;
00177 }
00178 if (array_key_exists('return', $this->params) && $this->params['return'] == 1) {
00179 $controller->autoRender = false;
00180 }
00181 if (!empty($this->params['bare'])) {
00182 $controller->autoLayout = false;
00183 }
00184 if (array_key_exists('layout', $this->params)) {
00185 if (empty($this->params['layout'])) {
00186 $controller->autoLayout = false;
00187 } else {
00188 $controller->layout = $this->params['layout'];
00189 }
00190 }
00191 if (isset($this->params['viewPath'])) {
00192 $controller->viewPath = $this->params['viewPath'];
00193 }
00194 return $this->_invoke($controller, $this->params);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 function _invoke(&$controller, $params) {
00207 $controller->constructClasses();
00208 $controller->Component->initialize($controller);
00209 $controller->beforeFilter();
00210 $controller->Component->startup($controller);
00211
00212 $methods = array_flip($controller->methods);
00213
00214 if (!isset($methods[strtolower($params['action'])])) {
00215 if ($controller->scaffold !== false) {
00216 App::import('Core', 'Scaffold');
00217 return new Scaffold($controller, $params);
00218 }
00219 return $this->cakeError('missingAction', array(array(
00220 'className' => Inflector::camelize($params['controller']."Controller"),
00221 'action' => $params['action'],
00222 'webroot' => $this->webroot,
00223 'url' => $this->here,
00224 'base' => $this->base
00225 )));
00226 }
00227 $output = $controller->dispatchMethod($params['action'], $params['pass']);
00228
00229 if ($controller->autoRender) {
00230 $controller->output = $controller->render();
00231 } elseif (empty($controller->output)) {
00232 $controller->output = $output;
00233 }
00234 $controller->Component->shutdown($controller);
00235 $controller->afterFilter();
00236
00237 if (isset($params['return'])) {
00238 return $controller->output;
00239 }
00240 echo($controller->output);
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 function __extractParams($url, $additionalParams = array()) {
00251 $defaults = array('pass' => array(), 'named' => array(), 'form' => array());
00252 $this->params = array_merge($defaults, $url, $additionalParams);
00253 return Router::url($url);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 function parseParams($fromUrl) {
00263 $params = array();
00264
00265 if (isset($_POST)) {
00266 $params['form'] = $_POST;
00267 if (ini_get('magic_quotes_gpc') === '1') {
00268 $params['form'] = stripslashes_deep($params['form']);
00269 }
00270 if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
00271 $params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
00272 }
00273 if (isset($params['form']['_method'])) {
00274 if (isset($_SERVER) && !empty($_SERVER)) {
00275 $_SERVER['REQUEST_METHOD'] = $params['form']['_method'];
00276 } else {
00277 $_ENV['REQUEST_METHOD'] = $params['form']['_method'];
00278 }
00279 unset($params['form']['_method']);
00280 }
00281 }
00282 $namedExpressions = Router::getNamedExpressions();
00283 extract($namedExpressions);
00284 include CONFIGS . 'routes.php';
00285 $params = array_merge(Router::parse($fromUrl), $params);
00286
00287 if (strlen($params['action']) === 0) {
00288 $params['action'] = 'index';
00289 }
00290 if (isset($params['form']['data'])) {
00291 $params['data'] = Router::stripEscape($params['form']['data']);
00292 unset($params['form']['data']);
00293 }
00294 if (isset($_GET)) {
00295 if (ini_get('magic_quotes_gpc') === '1') {
00296 $url = stripslashes_deep($_GET);
00297 } else {
00298 $url = $_GET;
00299 }
00300 if (isset($params['url'])) {
00301 $params['url'] = array_merge($params['url'], $url);
00302 } else {
00303 $params['url'] = $url;
00304 }
00305 }
00306 foreach ($_FILES as $name => $data) {
00307 if ($name != 'data') {
00308 $params['form'][$name] = $data;
00309 }
00310 }
00311 if (isset($_FILES['data'])) {
00312 foreach ($_FILES['data'] as $key => $data) {
00313 foreach ($data as $model => $fields) {
00314 foreach ($fields as $field => $value) {
00315 if (is_array($value)) {
00316 foreach ($value as $k => $v) {
00317 $params['data'][$model][$field][$k][$key] = $v;
00318 }
00319 } else {
00320 $params['data'][$model][$field][$key] = $value;
00321 }
00322 }
00323 }
00324 }
00325 }
00326 return $params;
00327 }
00328
00329
00330
00331
00332
00333
00334 function baseUrl() {
00335 $dir = $webroot = null;
00336 $config = Configure::read('App');
00337 extract($config);
00338
00339 if (!$base) {
00340 $base = $this->base;
00341 }
00342 if ($base !== false) {
00343 $this->webroot = $base . '/';
00344 return $this->base = $base;
00345 }
00346 if (!$baseUrl) {
00347 $replace = array('<', '>', '*', '\'', '"');
00348 $base = str_replace($replace, '', dirname(env('PHP_SELF')));
00349
00350 if ($webroot === 'webroot' && $webroot === basename($base)) {
00351 $base = dirname($base);
00352 }
00353 if ($dir === 'app' && $dir === basename($base)) {
00354 $base = dirname($base);
00355 }
00356
00357 if ($base === DS || $base === '.') {
00358 $base = '';
00359 }
00360
00361 $this->webroot = $base .'/';
00362 return $base;
00363 }
00364 $file = null;
00365
00366 if ($baseUrl) {
00367 $file = '/' . basename($baseUrl);
00368 $base = dirname($baseUrl);
00369
00370 if ($base === DS || $base === '.') {
00371 $base = '';
00372 }
00373 $this->webroot = $base .'/';
00374
00375 if (strpos($this->webroot, $dir) === false) {
00376 $this->webroot .= $dir . '/' ;
00377 }
00378 if (strpos($this->webroot, $webroot) === false) {
00379 $this->webroot .= $webroot . '/';
00380 }
00381 return $base . $file;
00382 }
00383 return false;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 function _restructureParams($params, $reverse = false) {
00394 if ($reverse === true) {
00395 extract(Router::getArgs($params['action']));
00396 $params = array_merge($params, array(
00397 'controller'=> $params['plugin'],
00398 'action'=> $params['controller'],
00399 'pass' => array_merge($pass, $params['pass']),
00400 'named' => array_merge($named, $params['named'])
00401 ));
00402 $this->plugin = $params['plugin'];
00403 } else {
00404 $params['plugin'] = $params['controller'];
00405 $params['controller'] = $params['action'];
00406 if (isset($params['pass'][0])) {
00407 $params['action'] = $params['pass'][0];
00408 array_shift($params['pass']);
00409 } else {
00410 $params['action'] = null;
00411 }
00412 }
00413 return $params;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422 function &__getController($params = null) {
00423 if (!is_array($params)) {
00424 $original = $params = $this->params;
00425 }
00426 $controller = false;
00427 $ctrlClass = $this->__loadController($params);
00428 if (!$ctrlClass) {
00429 if (!isset($params['plugin'])) {
00430 $params = $this->_restructureParams($params);
00431 } else {
00432 if (empty($original['pass']) && $original['action'] == 'index') {
00433 $params['action'] = null;
00434 }
00435 $params = $this->_restructureParams($params, true);
00436 }
00437 $ctrlClass = $this->__loadController($params);
00438 if (!$ctrlClass) {
00439 $this->params = $original;
00440 return $controller;
00441 }
00442 } else {
00443 $params = $this->params;
00444 }
00445 $name = $ctrlClass;
00446 $ctrlClass = $ctrlClass . 'Controller';
00447 if (class_exists($ctrlClass)) {
00448 if (strtolower(get_parent_class($ctrlClass)) === strtolower($name . 'AppController') && empty($params['plugin'])) {
00449 $params = $this->_restructureParams($params);
00450 $params = $this->_restructureParams($params, true);
00451 }
00452 $this->params = $params;
00453 $controller =& new $ctrlClass();
00454 }
00455 return $controller;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464 function __loadController($params) {
00465 $pluginName = $pluginPath = $controller = null;
00466 if (!empty($params['plugin'])) {
00467 $this->plugin = $params['plugin'];
00468 $pluginName = Inflector::camelize($params['plugin']);
00469 $pluginPath = $pluginName . '.';
00470 $this->params['controller'] = $this->plugin;
00471 $controller = $pluginName;
00472 }
00473 if (!empty($params['controller'])) {
00474 $this->params['controller'] = $params['controller'];
00475 $controller = Inflector::camelize($params['controller']);
00476 }
00477 if ($pluginPath . $controller) {
00478 if (App::import('Controller', $pluginPath . $controller)) {
00479 return $controller;
00480 }
00481 }
00482 return false;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 function uri() {
00492 foreach (array('HTTP_X_REWRITE_URL', 'REQUEST_URI', 'argv') as $var) {
00493 if ($uri = env($var)) {
00494 if ($var == 'argv') {
00495 $uri = $uri[0];
00496 }
00497 break;
00498 }
00499 }
00500 $base = preg_replace('/^\
00501
00502 if ($base) {
00503 $uri = preg_replace('/^(?:\/)?(?:' . preg_quote($base, '/') . ')?(?:url=)?/', '', $uri);
00504 }
00505 if (PHP_SAPI == 'isapi') {
00506 $uri = preg_replace('/^(?:\/)?(?:\/)?(?:\?)?(?:url=)?/', '', $uri);
00507 }
00508 if (!empty($uri)) {
00509 if (key($_GET) && strpos(key($_GET), '?') !== false) {
00510 unset($_GET[key($_GET)]);
00511 }
00512 $uri = preg_split('/\?/', $uri, 2);
00513
00514 if (isset($uri[1])) {
00515 parse_str($uri[1], $_GET);
00516 }
00517 $uri = $uri[0];
00518 } else {
00519 $uri = env('QUERY_STRING');
00520 }
00521 if (is_string($uri) && strpos($uri, 'index.php') !== false) {
00522 list(, $uri) = explode('index.php', $uri, 2);
00523 }
00524 if (empty($uri) || $uri == '/' || $uri == '
00525 return '';
00526 }
00527 return str_replace('
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537 function getUrl($uri = null, $base = null) {
00538 if (empty($_GET['url'])) {
00539 if ($uri == null) {
00540 $uri = $this->uri();
00541 }
00542 if ($base == null) {
00543 $base = $this->base;
00544 }
00545 $url = null;
00546 $tmpUri = preg_replace('/^(?:\?)?(?:\/)?/', '', $uri);
00547 $baseDir = preg_replace('/^\
00548
00549 if ($tmpUri === '/' || $tmpUri == $baseDir || $tmpUri == $base) {
00550 $url = $_GET['url'] = '/';
00551 } else {
00552 if ($base && strpos($uri, $base) !== false) {
00553 $elements = explode($base, $uri);
00554 } elseif (preg_match('/^[\/\?\/|\/\?|\?\/]/', $uri)) {
00555 $elements = array(1 => preg_replace('/^[\/\?\/|\/\?|\?\/]/', '', $uri));
00556 } else {
00557 $elements = array();
00558 }
00559
00560 if (!empty($elements[1])) {
00561 $_GET['url'] = $elements[1];
00562 $url = $elements[1];
00563 } else {
00564 $url = $_GET['url'] = '/';
00565 }
00566
00567 if (strpos($url, '/') === 0 && $url != '/') {
00568 $url = $_GET['url'] = substr($url, 1);
00569 }
00570 }
00571 } else {
00572 $url = $_GET['url'];
00573 }
00574 if ($url{0} == '/') {
00575 $url = substr($url, 1);
00576 }
00577 return $url;
00578 }
00579
00580
00581
00582
00583
00584
00585 function cached($url) {
00586 if (strpos($url, 'css/') !== false || strpos($url, 'js/') !== false || strpos($url, 'img/') !== false) {
00587 if (strpos($url, 'ccss/') === 0) {
00588 include WWW_ROOT . DS . Configure::read('Asset.filter.css');
00589 $this->_stop();
00590 } elseif (strpos($url, 'cjs/') === 0) {
00591 include WWW_ROOT . DS . Configure::read('Asset.filter.js');
00592 $this->_stop();
00593 }
00594 $isAsset = false;
00595 $assets = array('js' => 'text/javascript', 'css' => 'text/css', 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'png' => 'image/png');
00596 $ext = array_pop(explode('.', $url));
00597
00598 foreach ($assets as $type => $contentType) {
00599 if ($type === $ext) {
00600 if ($type === 'css' || $type === 'js') {
00601 $pos = strpos($url, $type . '/');
00602 } else {
00603 $pos = strpos($url, 'img/');
00604 }
00605 $isAsset = true;
00606 break;
00607 }
00608 }
00609
00610 if ($isAsset === true) {
00611 $ob = @ini_get("zlib.output_compression") !== '1' && extension_loaded("zlib") && (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
00612
00613 if ($ob && Configure::read('Asset.compress')) {
00614 ob_start();
00615 ob_start('ob_gzhandler');
00616 }
00617 $assetFile = null;
00618 $paths = array();
00619
00620 if ($pos > 0) {
00621 $plugin = substr($url, 0, $pos - 1);
00622 $url = str_replace($plugin . '/', '', $url);
00623 $pluginPaths = Configure::read('pluginPaths');
00624 $count = count($pluginPaths);
00625 for ($i = 0; $i < $count; $i++) {
00626 $paths[] = $pluginPaths[$i] . $plugin . DS . 'vendors' . DS;
00627 }
00628 }
00629 $paths = array_merge($paths, Configure::read('vendorPaths'));
00630
00631 foreach ($paths as $path) {
00632 if (is_file($path . $url) && file_exists($path . $url)) {
00633 $assetFile = $path . $url;
00634 break;
00635 }
00636 }
00637
00638 if ($assetFile !== null) {
00639 $fileModified = filemtime($assetFile);
00640 header("Date: " . date("D, j M Y G:i:s ", $fileModified) . 'GMT');
00641 header('Content-type: ' . $assets[$type]);
00642 header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
00643 header("Cache-Control: cache");
00644 header("Pragma: cache");
00645 if ($type === 'css' || $type === 'js') {
00646 include($assetFile);
00647 } else {
00648 readfile($assetFile);
00649 }
00650
00651 if (Configure::read('Asset.compress')) {
00652 ob_end_flush();
00653 }
00654 return true;
00655 }
00656 }
00657 }
00658
00659 if (Configure::read('Cache.check') === true) {
00660 $path = $this->here;
00661 if ($this->here == '/') {
00662 $path = 'home';
00663 }
00664 $path = strtolower(Inflector::slug($path));
00665
00666 $filename = CACHE . 'views' . DS . $path . '.php';
00667
00668 if (!file_exists($filename)) {
00669 $filename = CACHE . 'views' . DS . $path . '_index.php';
00670 }
00671
00672 if (file_exists($filename)) {
00673 if (!class_exists('View')) {
00674 App::import('Core', 'View');
00675 }
00676 $controller = null;
00677 $view =& new View($controller, false);
00678 return $view->renderCache($filename, getMicrotime());
00679 }
00680 }
00681 return false;
00682 }
00683 }
00684 ?>