00001 <?php
00002 Load::directories('controller/base/cachemanager');
00003 Load::directories('controller/base/cachemanager/headermanager');
00004 Load::directories('controller/base/renderdecorators');
00005 require_once dirname(__FILE__) . '/../renderer/rendererchain.cls.php';
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 class RouteBase implements IRoute, IDispatcher, IUrlBuilder {
00018 protected $controller = null;
00019 protected $action = '';
00020 protected $path = '';
00021 protected $scheme = '';
00022 protected $decorators = null;
00023 protected $is_directory = false;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 public function __construct($path, $controller, $action, $decorators = null) {
00034 $this->controller = $controller;
00035 $this->action = $action;
00036
00037 $pos_scheme = strpos($path, '://');
00038 if ($pos_scheme !== false) {
00039 $this->scheme = substr($path, 0, $pos_scheme);
00040 $path = substr($path, $pos_scheme + 3);
00041 } else {
00042 $this->scheme = Config::get_value(Config::DEFAULT_SCHEME);
00043 }
00044 if ($this->scheme == 'https' && !Config::has_feature(Config::ENABLE_HTTPS)) {
00045 $this->scheme = 'http';
00046 }
00047 $this->path = ($path !== '/') ? ltrim($path, '/') : $path;
00048 $this->is_directory = (substr($path, -1) === '/');
00049 $this->decorators = is_array($decorators) ? $decorators : array($decorators);
00050 ActionMapper::register_url($action, $this);
00051 }
00052
00053
00054
00055
00056
00057
00058
00059 public static function split_route_id($route_id) {
00060 $tmp = explode('::', $route_id);
00061 return array(
00062 'action' => array_pop($tmp),
00063 'controller' => array_pop($tmp)
00064 );
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 public function get_renderer($page_data) {
00074
00075 $arr_default_decorator = $this->get_default_render_decorators();
00076 $arr_overloaded_default_decorators = $page_data->get_render_decorators($this);
00077 $arr_decorators = array();
00078
00079 foreach($this->decorators as $decorator) {
00080 if ($decorator instanceof ICacheManager) {
00081 $arr_decorators[] = new CacheRenderDecorator($decorator);
00082 }
00083 else {
00084 $arr_decorators[] = $decorator;
00085 }
00086 }
00087 $arr_decorators = array_merge($arr_decorators, $arr_overloaded_default_decorators, $arr_default_decorator);
00088 return new RendererChain($page_data, $arr_decorators);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 public function prepend_renderdecorator(IRenderDecorator $dec) {
00098 array_unshift($this->decorators, $dec);
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 public function append_renderdecorator(IRenderDecorator $dec) {
00108 $this->decorators[] = $dec;
00109 }
00110
00111
00112
00113
00114
00115
00116 protected function get_default_render_decorators() {
00117 return array(
00118 new DispatcherInvokeRenderDecorator($this)
00119 );
00120 }
00121
00122
00123
00124
00125 public function identify() {
00126 $ret = '';
00127 if ($this->controller) {
00128 $ret .= get_class($this->controller) . '::';
00129 }
00130 $ret .= $this->action;
00131 return $ret;
00132 }
00133
00134
00135
00136
00137 public function is_directory() {
00138 return $this->is_directory;
00139 }
00140
00141
00142
00143
00144
00145
00146 public function initialize($page_data) {
00147 if ($this->scheme != 'any' && Url::current()->get_scheme() != $this->scheme) {
00148
00149 Url::current()->set_scheme($this->scheme)->redirect(Url::PERMANENT);
00150 exit;
00151 }
00152
00153 $this->initialize_adjust_path($page_data);
00154 $this->initialize_cache_manager($page_data);
00155 }
00156
00157
00158
00159
00160
00161
00162 protected function initialize_cache_manager($page_data) {
00163
00164
00165
00166
00167 }
00168
00169
00170
00171
00172
00173
00174 protected function initialize_adjust_path($page_data) {
00175 $pathstack = $page_data->get_pathstack();
00176 $pathstack->adjust($this->path);
00177 }
00178
00179
00180
00181
00182 public function weight_against_path($path) {
00183
00184
00185 $ret = self::WEIGHT_NO_MATCH;
00186 if (String::starts_with($path, $this->path)) {
00187 $tmp = new PathStack($path);
00188 if ($tmp->adjust($this->path)) {
00189 $ret = $tmp->count_front();
00190 }
00191 }
00192
00193
00194 return $ret;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 public function invoke($page_data) {
00204 if (empty($this->controller)) {
00205 throw new Exception(
00206 tr('No controller on dispatcher %c', 'core', array('%c' => get_class($this)))
00207 );
00208 }
00209 if (empty($this->action)) {
00210 throw new Exception(
00211 tr('No action on dispatcher %c', 'core', array('%c' => get_class($this)))
00212 );
00213 }
00214
00215
00216 $funcname = $this->get_action_func_name($this->action);
00217
00218
00219 if (method_exists($this->controller, 'before_action')) {
00220 $this->controller->before_action();
00221 }
00222
00223 $status = $this->invoke_action_func($this->controller, $funcname, $page_data);
00224 if (empty($status) || $status == CONTROLLER_OK) {
00225 if ($page_data->get_pathstack()->current()) {
00226
00227 $status = CONTROLLER_NOT_FOUND;
00228 }
00229 else {
00230 $status = CONTROLLER_OK;
00231 }
00232 }
00233 $page_data->status_code = $status;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 protected function invoke_action_func($controller, $funcname, $page_data) {
00246 $this->check_action_func($controller, $funcname);
00247 return $this->controller->$funcname($page_data);
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257 protected function check_action_func($controller, $funcname) {
00258 if (method_exists($controller, $funcname) == false) {
00259 throw new Exception(
00260 tr('Action %a on controller %c not found', 'core', array('%a' => $funcname, '%c' => get_class($this->controller)))
00261 );
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 protected function get_action_func_name($action) {
00272 return 'action_' . $action;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 public function build_url($absolute_or_relative, $params = null) {
00286 $ret = $this->build_url_base($absolute_or_relative);
00287 $ret .= preg_replace('|/+|', '/', $this->build_url_path($params));
00288 $ret = rtrim($ret, '.');
00289 return $ret;
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 protected function build_url_path($params) {
00299 $ret = $this->path;
00300 if (!is_null($params)) {
00301 $ret .= '/';
00302 if (is_array($params)) {
00303 $ret .= implode('/', $params);
00304 }
00305 else {
00306 $ret .= $params;
00307 }
00308 }
00309 return $ret;
00310 }
00311
00312 protected function build_url_base($absolute_or_relative) {
00313 if ($this->scheme != 'any' && Url::current()->get_scheme() != $this->scheme) {
00314
00315 $absolute_or_relative = self::ABSOLUTE;
00316 }
00317 if (Url::current()->get_host() != Config::get_value(Config::URL_DOMAIN)) {
00318 $absolute_or_relative = self::ABSOLUTE;
00319 }
00320 $ret = Config::get_value(Config::URL_BASEDIR);
00321 if ($absolute_or_relative == self::ABSOLUTE) {
00322 switch ($this->scheme) {
00323 case 'https':
00324 $ret = Config::get_url(Config::URL_BASEURL_SAFE);
00325 break;
00326 case 'any':
00327 $ret = Url::create(Config::get_url(Config::URL_BASEURL))->set_scheme(Url::current()->get_scheme())->build(Url::ABSOLUTE);
00328 break;
00329 default:
00330 $ret = Config::get_url(Config::URL_BASEURL);
00331 break;
00332 }
00333 }
00334 return $ret;
00335 }
00336 }