root/websites/events.php.gr.jp/trunk/cake/dispatcher.php

Revision 35512, 19.3 kB (checked in by kaz_29, 2 years ago)

revert some changes.

Line 
1<?php
2/* SVN FILE: $Id: dispatcher.php 7296 2008-06-27 09:09:03Z gwoo $ */
3/**
4 * Dispatcher takes the URL information, parses it for paramters and
5 * tells the involved controllers what to do.
6 *
7 * This is the heart of Cake's operation.
8 *
9 * PHP versions 4 and 5
10 *
11 * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
12 * Copyright 2005-2008, Cake Software Foundation, Inc.
13 *                                1785 E. Sahara Avenue, Suite 490-204
14 *                                Las Vegas, Nevada 89104
15 *
16 * Licensed under The MIT License
17 * Redistributions of files must retain the above copyright notice.
18 *
19 * @filesource
20 * @copyright        Copyright 2005-2008, Cake Software Foundation, Inc.
21 * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
22 * @package            cake
23 * @subpackage        cake.cake
24 * @since            CakePHP(tm) v 0.2.9
25 * @version            $Revision: 7296 $
26 * @modifiedby        $LastChangedBy: gwoo $
27 * @lastmodified    $Date: 2008-06-27 02:09:03 -0700 (Fri, 27 Jun 2008) $
28 * @license            http://www.opensource.org/licenses/mit-license.php The MIT License
29 */
30/**
31 * List of helpers to include
32 */
33App::import('Core', array('Router', 'Controller'));
34/**
35 * Dispatcher translates URLs to controller-action-paramter triads.
36 *
37 * Dispatches the request, creating appropriate models and controllers.
38 *
39 * @package        cake
40 * @subpackage    cake.cake
41 */
42class Dispatcher extends Object {
43/**
44 * Base URL
45 *
46 * @var string
47 * @access public
48 */
49    var $base = false;
50/**
51 * webroot path
52 *
53 * @var string
54 * @access public
55 */
56    var $webroot = '/';
57/**
58 * Current URL
59 *
60 * @var string
61 * @access public
62 */
63    var $here = false;
64/**
65 * Admin route (if on it)
66 *
67 * @var string
68 * @access public
69 */
70    var $admin = false;
71/**
72 * Plugin being served (if any)
73 *
74 * @var string
75 * @access public
76 */
77    var $plugin = null;
78/**
79 * the params for this request
80 *
81 * @var string
82 * @access public
83 */
84    var $params = null;
85/**
86 * Constructor.
87 */
88    function __construct($url = null, $base = false) {
89        if ($base !== false) {
90            Configure::write('App.base', $base);
91        }
92        $this->base = Configure::read('App.base');
93
94        if ($url !== null) {
95            return $this->dispatch($url);
96        }
97    }
98/**
99 * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set).
100 *
101 * If no controller of given name can be found, invoke() shows error messages in
102 * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called
103 * Actions).
104 *
105 * @param string $url URL information to work on
106 * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
107 * @return boolean Success
108 * @access public
109 */
110    function dispatch($url = null, $additionalParams = array()) {
111        $parse = true;
112
113        if ($this->base === false) {
114            $this->base = $this->baseUrl();
115        }
116
117        if (is_array($url)) {
118            $url = $this->__extractParams($url, $additionalParams);
119            $parse = false;
120        }
121
122        if ($url !== null) {
123            $_GET['url'] = $url;
124        }
125
126        if ($parse) {
127            $url = $this->getUrl();
128        }
129        $this->here = $this->base . '/' . $url;
130
131        if ($this->cached($url)) {
132            $this->_stop();
133        }
134
135        if ($parse) {
136            $this->params = array_merge($this->parseParams($url), $additionalParams);
137        }
138        $controller = $this->__getController();
139
140        if (!is_object($controller)) {
141            Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot)));
142            return $this->cakeError('missingController', array(
143                array(
144                    'className' => Inflector::camelize($this->params['controller']) . 'Controller',
145                    'webroot' => $this->webroot,
146                    'url' => $url,
147                    'base' => $this->base)));
148        }
149        $missingAction = $missingView = $privateAction = false;
150
151        if (empty($this->params['action'])) {
152            $this->params['action'] = 'index';
153        }
154        $prefixes = Router::prefixes();
155
156        if (!empty($prefixes)) {
157            if (isset($this->params['prefix'])) {
158                $this->params['action'] = $this->params['prefix'] . '_' . $this->params['action'];
159            } elseif (strpos($this->params['action'], '_') !== false) {
160                list($prefix, $action) = explode('_', $this->params['action']);
161                $privateAction = in_array($prefix, $prefixes);
162            }
163        }
164        $protected = array_map('strtolower', get_class_methods('controller'));
165        $classMethods = array_map('strtolower', get_class_methods($controller));
166
167        if (in_array(strtolower($this->params['action']), $protected) || strpos($this->params['action'], '_', 0) === 0) {
168            $privateAction = true;
169        }
170
171        if (!in_array(strtolower($this->params['action']), $classMethods)) {
172            $missingAction = true;
173        }
174
175        if (in_array('return', array_keys($this->params)) && $this->params['return'] == 1) {
176            $controller->autoRender = false;
177        }
178        $controller->base = $this->base;
179        $controller->here = $this->here;
180        $controller->webroot = $this->webroot;
181        $controller->plugin = $this->plugin;
182        $controller->params =& $this->params;
183        $controller->action =& $this->params['action'];
184        $controller->passedArgs = array_merge($this->params['pass'], $this->params['named']);
185
186        if (!empty($this->params['data'])) {
187            $controller->data =& $this->params['data'];
188        } else {
189            $controller->data = null;
190        }
191
192        if (!empty($this->params['bare'])) {
193            $controller->autoLayout = false;
194        }
195
196        if (isset($this->params['layout'])) {
197            if ($this->params['layout'] === '') {
198                $controller->autoLayout = false;
199            } else {
200                $controller->layout = $this->params['layout'];
201            }
202        }
203
204        if (isset($this->params['viewPath'])) {
205            $controller->viewPath = $this->params['viewPath'];
206        }
207
208        foreach (array('components', 'helpers') as $var) {
209            if (isset($this->params[$var]) && !empty($this->params[$var]) && is_array($controller->{$var})) {
210                $diff = array_diff($this->params[$var], $controller->{$var});
211                $controller->{$var} = array_merge($controller->{$var}, $diff);
212            }
213        }
214        Router::setRequestInfo(array($this->params, array('base' => $this->base, 'here' => $this->here, 'webroot' => $this->webroot)));
215        $controller->constructClasses();
216
217        if ($privateAction) {
218            return $this->cakeError('privateAction', array(
219                array(
220                    'className' => Inflector::camelize($this->params['controller']."Controller"),
221                    'action' => $this->params['action'],
222                    'webroot' => $this->webroot,
223                    'url' => $url,
224                    'base' => $this->base)));
225        }
226
227        $controller->Component->initialize($controller);
228        $controller->beforeFilter();
229        $controller->Component->startup($controller);
230        return $this->_invoke($controller, $this->params, $missingAction);
231    }
232/**
233 * Invokes given controller's render action if autoRender option is set. Otherwise the
234 * contents of the operation are returned as a string.
235 *
236 * @param object $controller Controller to invoke
237 * @param array $params Parameters with at least the 'action' to invoke
238 * @param boolean $missingAction Set to true if missing action should be rendered, false otherwise
239 * @return string Output as sent by controller
240 * @access protected
241 */
242    function _invoke(&$controller, $params, $missingAction = false) {
243        $classVars = get_object_vars($controller);
244        if ($missingAction && in_array('scaffold', array_keys($classVars))) {
245            App::import('Core', 'Scaffold');
246            return new Scaffold($controller, $params);
247        } elseif ($missingAction && !in_array('scaffold', array_keys($classVars))) {
248            return $this->cakeError('missingAction', array(
249                array(
250                    'className' => Inflector::camelize($params['controller']."Controller"),
251                    'action' => $params['action'],
252                    'webroot' => $this->webroot,
253                    'url' => $this->here,
254                    'base' => $this->base)));
255        } else {
256            $output = $controller->dispatchMethod($params['action'], $params['pass']);
257        }
258
259        if ($controller->autoRender) {
260            $controller->output = $controller->render();
261        } elseif (empty($controller->output)) {
262            $controller->output = $output;
263        }
264        $controller->Component->shutdown($controller);
265        $controller->afterFilter();
266
267        if (isset($params['return'])) {
268            return $controller->output;
269        }
270        echo($controller->output);
271    }
272/**
273 * Sets the params when $url is passed as an array to Object::requestAction();
274 *
275 * @param array $url
276 * @param array $additionalParams
277 * @return null
278 * @access private
279 * @todo commented Router::url(). this improved performance,
280 *       will work on this more later.
281 */
282    function __extractParams($url, $additionalParams = array()) {
283        $defaults = array('pass' => array(), 'named' => array(), 'form' => array());
284        $this->params = array_merge($defaults, $url, $additionalParams);
285        //$url = Router::url($url);
286        //return $url;
287    }
288/**
289 * Returns array of GET and POST parameters. GET parameters are taken from given URL.
290 *
291 * @param string $fromUrl URL to mine for parameter information.
292 * @return array Parameters found in POST and GET.
293 * @access public
294 */
295    function parseParams($fromUrl) {
296        $params = array();
297
298        if (isset($_POST)) {
299            $params['form'] = $_POST;
300            if (ini_get('magic_quotes_gpc') == 1) {
301                $params['form'] = stripslashes_deep($params['form']);
302            }
303            if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
304                $params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
305            }
306            if (isset($params['form']['_method'])) {
307                if (isset($_SERVER) && !empty($_SERVER)) {
308                    $_SERVER['REQUEST_METHOD'] = $params['form']['_method'];
309                } else {
310                    $_ENV['REQUEST_METHOD'] = $params['form']['_method'];
311                }
312                unset($params['form']['_method']);
313            }
314        }
315        extract(Router::getNamedExpressions());
316        include CONFIGS . 'routes.php';
317        $params = array_merge(Router::parse($fromUrl), $params);
318
319        if (isset($params['form']['data'])) {
320            $params['data'] = Router::stripEscape($params['form']['data']);
321            unset($params['form']['data']);
322        }
323
324        if (isset($_GET)) {
325            if (ini_get('magic_quotes_gpc') == 1) {
326                $url = stripslashes_deep($_GET);
327            } else {
328                $url = $_GET;
329            }
330            if (isset($params['url'])) {
331                $params['url'] = array_merge($params['url'], $url);
332            } else {
333                $params['url'] = $url;
334            }
335        }
336
337        foreach ($_FILES as $name => $data) {
338            if ($name != 'data') {
339                $params['form'][$name] = $data;
340            }
341        }
342
343        if (isset($_FILES['data'])) {
344            foreach ($_FILES['data'] as $key => $data) {
345                foreach ($data as $model => $fields) {
346                    foreach ($fields as $field => $value) {
347                        if (is_array($value)) {
348                            $params['data'][$model][$field][key($value)][$key] = current($value);
349                        } else {
350                            $params['data'][$model][$field][$key] = $value;
351                        }
352                    }
353                }
354            }
355        }
356        return $params;
357    }
358/**
359 * Returns a base URL and sets the proper webroot
360 *
361 * @return string Base URL
362 * @access public
363 */
364    function baseUrl() {
365        $dir = $webroot = null;
366        $config = Configure::read('App');
367        extract($config);
368
369        if (!$base) {
370            $base = $this->base;
371        }
372
373        if ($base !== false) {
374            $this->webroot = $base . '/';
375            return $base;
376        }
377
378        if (!$baseUrl) {
379            $base = dirname(env('PHP_SELF'));
380
381            if ($webroot === 'webroot' && $webroot === basename($base)) {
382                $base = dirname($base);
383            }
384            if ($dir === 'app' && $dir === basename($base)) {
385                $base = dirname($base);
386            }
387
388            if (in_array($base, array(DS, '.'))) {
389                $base = '';
390            }
391
392            $this->webroot = $base .'/';
393            return $base;
394        }
395        $file = null;
396
397        if ($baseUrl) {
398            $file = '/' . basename($baseUrl);
399            $base = dirname($baseUrl);
400
401            if (in_array($base, array(DS, '.'))) {
402                $base = '';
403            }
404            $this->webroot = $base .'/';
405
406            if (strpos($this->webroot, $dir) === false) {
407                $this->webroot .= $dir . '/' ;
408            }
409            if (strpos($this->webroot, $webroot) === false) {
410                $this->webroot .= $webroot . '/';
411            }
412            return $base . $file;
413        }
414        return false;
415    }
416/**
417 * Restructure params in case we're serving a plugin.
418 *
419 * @param array $params Array on where to re-set 'controller', 'action', and 'pass' indexes
420 * @param boolean $reverse
421 * @return array Restructured array
422 * @access protected
423 */
424    function _restructureParams($params, $reverse = false) {
425        if($reverse === true) {
426            extract(Router::getArgs($params['action']));
427            $params = array_merge($params, array('controller'=> $params['plugin'],
428                        'action'=> $params['controller'],
429                        'pass' => array_merge($pass, $params['pass']),
430                        'named' => array_merge($named, $params['named'])));
431            $this->plugin = $params['plugin'];
432        } else {
433            $params['plugin'] = $params['controller'];
434            $params['controller'] = $params['action'];
435            if (isset($params['pass'][0])) {
436                $params['action'] = $params['pass'][0];
437                array_shift($params['pass']);
438            } else {
439                $params['action'] = null;
440            }
441        }
442        return $params;
443    }
444/**
445 * Get controller to use, either plugin controller or application controller
446 *
447 * @param array $params Array of parameters
448 * @return mixed name of controller if not loaded, or object if loaded
449 * @access private
450 */
451    function __getController($params = null) {
452        if (!is_array($params)) {
453            $params = $this->params;
454        }
455        $controller = false;
456
457        if (!$ctrlClass = $this->__loadController($params)) {
458            if (!isset($params['plugin'])) {
459                $params = $this->_restructureParams($params);
460            } else {
461                $params = $this->_restructureParams($params, true);
462            }
463
464            if (!$ctrlClass = $this->__loadController($params)) {
465                return false;
466            }
467        }
468        $name = $ctrlClass;
469        $ctrlClass = $ctrlClass . 'Controller';
470
471        if (class_exists($ctrlClass)) {
472            if (strtolower(get_parent_class($ctrlClass)) === strtolower($name . 'AppController') && empty($params['plugin'])) {
473                $params = $this->_restructureParams($params);
474                $params = $this->_restructureParams($params, true);
475            }
476            $this->params = $params;
477            $controller =& new $ctrlClass();
478        }
479        return $controller;
480    }
481/**
482 * Load controller and return controller class
483 *
484 * @param array $params Array of parameters
485 * @return string|bool Name of controller class name
486 * @access private
487 */
488    function __loadController($params) {
489        $pluginName = $pluginPath = $controller = null;
490
491        if (!empty($params['plugin'])) {
492            $this->plugin = $params['plugin'];
493            $pluginName = Inflector::camelize($params['plugin']);
494            $pluginPath = $pluginName . '.';
495            $this->params['controller'] = $this->plugin;
496            $controller = $pluginName;
497        }
498
499        if (!empty($params['controller'])) {
500            $controller = Inflector::camelize($params['controller']);
501        }
502
503        if ($pluginPath . $controller) {
504            if (App::import('Controller', $pluginPath . $controller)) {
505                return $controller;
506            }
507        }
508        return false;
509    }
510/**
511 * Returns the REQUEST_URI from the server environment, or, failing that,
512 * constructs a new one, using the PHP_SELF constant and other variables.
513 *
514 * @return string URI
515 * @access public
516 */
517    function uri() {
518        foreach (array('HTTP_X_REWRITE_URL', 'REQUEST_URI', 'argv') as $var) {
519            if ($uri = env($var)) {
520                if ($var == 'argv') {
521                    $uri = $uri[0];
522                }
523                break;
524            }
525        }
526        $base = preg_replace('/^\//', '', '' . Configure::read('App.baseUrl'));
527
528        if ($base) {
529            $uri = preg_replace('/^(?:\/)?(?:' . preg_quote($base, '/') . ')?(?:url=)?/', '', $uri);
530        }
531
532        if (Configure::read('App.server') == 'IIS') {
533            $uri = preg_replace('/^(?:\/)?(?:\/)?(?:\?)?(?:url=)?/', '', $uri);
534        }
535
536        if (!empty($uri)) {
537            if (key($_GET) && strpos(key($_GET), '?') !== false) {
538                unset($_GET[key($_GET)]);
539            }
540            $uri = preg_split('/\?/', $uri, 2);
541
542            if (isset($uri[1])) {
543                parse_str($uri[1], $_GET);
544            }
545            $uri = $uri[0];
546        } elseif (empty($uri) && is_string(env('QUERY_STRING'))) {
547            $uri = env('QUERY_STRING');
548        }
549
550        if (strpos($uri, 'index.php') !== false) {
551            list(, $uri) = explode('index.php', $uri, 2);
552        }
553
554        if (empty($uri) || $uri == '/' || $uri == '//') {
555            return '';
556        }
557        return str_replace('//', '/', '/' . $uri);
558    }
559/**
560 * Returns and sets the $_GET[url] derived from the REQUEST_URI
561 *
562 * @param string $uri Request URI
563 * @param string $base Base path
564 * @return string URL
565 * @access public
566 */
567    function getUrl($uri = null, $base = null) {
568        if (empty($_GET['url'])) {
569            if ($uri == null) {
570                $uri = $this->uri();
571            }
572
573            if ($base == null) {
574                $base = $this->base;
575            }
576            $url = null;
577            $tmpUri = preg_replace('/^(?:\?)?(?:\/)?/', '', $uri);
578            $baseDir = preg_replace('/^\//', '', dirname($base)) . '/';
579
580            if ($tmpUri === '/' || $tmpUri == $baseDir || $tmpUri == $base) {
581                $url = $_GET['url'] = '/';
582            } else {
583                if ($base && strpos($uri, $base) !== false) {
584                    $elements = explode($base, $uri);
585                } elseif (preg_match('/^[\/\?\/|\/\?|\?\/]/', $uri)) {
586                    $elements = array(1 => preg_replace('/^[\/\?\/|\/\?|\?\/]/', '', $uri));
587                } else {
588                    $elements = array();
589                }
590
591                if (!empty($elements[1])) {
592                    $_GET['url'] = $elements[1];
593                    $url = $elements[1];
594                } else {
595                    $url = $_GET['url'] = '/';
596                }
597
598                if (strpos($url, '/') === 0 && $url != '/') {
599                    $url = $_GET['url'] = substr($url, 1);
600                }
601            }
602        } else {
603            $url = $_GET['url'];
604        }
605
606        if ($url{0} == '/') {
607            $url = substr($url, 1);
608        }
609        return $url;
610    }
611/**
612 * Outputs cached dispatch for js, css, img, view cache
613 *
614 * @param string $url Requested URL
615 * @access public
616 */
617    function cached($url) {
618        if (strpos($url, 'css/') !== false || strpos($url, 'js/') !== false || strpos($url, 'img/') !== false) {
619            if (strpos($url, 'ccss/') === 0) {
620                include WWW_ROOT . DS . Configure::read('Asset.filter.css');
621                $this->_stop();
622            } elseif (strpos($url, 'cjs/') === 0) {
623                include WWW_ROOT . DS . Configure::read('Asset.filter.js');
624                $this->_stop();
625            }
626            $isAsset = false;
627            $assets = array('js' => 'text/javascript', 'css' => 'text/css', 'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'png' => 'image/png');
628            $ext = array_pop(explode('.', $url));
629
630            foreach ($assets as $type => $contentType) {
631                if ($type === $ext) {
632                    if ($type === 'css' || $type === 'js') {
633                        $pos = strpos($url, $type . '/');
634                    } else {
635                        $pos = strpos($url, 'img/');
636                    }
637                    $isAsset = true;
638                    break;
639                }
640            }
641
642            if ($isAsset === true) {
643                $ob = @ini_get("zlib.output_compression") !== true && extension_loaded("zlib") && (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
644
645                if ($ob && Configure::read('Asset.compress')) {
646                    ob_start();
647                    ob_start('ob_gzhandler');
648                }
649                $assetFile = null;
650                $paths = array();
651
652                if ($pos > 0) {
653                    $plugin = substr($url, 0, $pos - 1);
654                    $url = str_replace($plugin . '/', '', $url);
655                    $pluginPaths = Configure::read('pluginPaths');
656                    $count = count($pluginPaths);
657                    for ($i = 0; $i < $count; $i++) {
658                        $paths[] = $pluginPaths[$i] . $plugin . DS . 'vendors' . DS;
659                    }
660                }
661                $paths = array_merge($paths, Configure::read('vendorPaths'));
662
663                foreach ($paths as $path) {
664                    if (is_file($path . $url) && file_exists($path . $url)) {
665                        $assetFile = $path . $url;
666                        break;
667                    }
668                }
669
670                if ($assetFile !== null) {
671                    $fileModified = filemtime($assetFile);
672                    header("Date: " . date("D, j M Y G:i:s ", $fileModified) . 'GMT');
673                    header('Content-type: ' . $assets[$type]);
674                    header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
675                    header("Cache-Control: cache");
676                    header("Pragma: cache");
677                    include ($assetFile);
678
679                    if(Configure::read('Asset.compress')) {
680                        header("Content-length: " . ob_get_length());
681                        ob_end_flush();
682                    }
683                    $this->_stop();
684                }
685            }
686        }
687
688        if (Configure::read('Cache.check') === true) {
689            $path = $this->here;
690            if ($this->here == '/') {
691                $path = 'home';
692            }
693            $path = Inflector::slug($path);
694
695            $filename = CACHE . 'views' . DS . $path . '.php';
696
697            if (!file_exists($filename)) {
698                $filename = CACHE . 'views' . DS . $path . '_index.php';
699            }
700
701            if (file_exists($filename)) {
702                if (!class_exists('View')) {
703                    App::import('Core', 'View');
704                }
705                $controller = null;
706                $view = new View($controller, false);
707                return $view->renderCache($filename, getMicrotime());
708            }
709        }
710        return false;
711    }
712}
713?>
Note: See TracBrowser for help on using the browser.