00001 <?php
00002 require_once dirname(__FILE__) . '/viewbase.cls.php';
00003
00004
00005
00006
00007
00008
00009
00010 class PageViewBase extends ViewBase {
00011 const POLICY_GZIP = 1024;
00012
00013
00014
00015
00016 protected $cache_manager = null;
00017
00018
00019
00020
00021
00022
00023 protected $page_data = null;
00024
00025 public function __construct(PageData $page_data, $file = false) {
00026 $this->page_data = $page_data;
00027 $this->cache_manager = $page_data->get_cache_manager();
00028
00029 if (empty($file)) {
00030 $file = 'page';
00031 }
00032 parent::__construct($file, $this->cache_manager->get_cache_id());
00033 }
00034
00035
00036
00037
00038
00039
00040
00041 public function render($policy = self::NONE) {
00042 if (Config::has_feature(Config::GZIP_SUPPORT)) {
00043 $policy |= self::POLICY_GZIP;
00044 }
00045 return parent::render($policy);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054 protected function render_preprocess($policy) {
00055 parent::render_preprocess($policy);
00056
00057 if (!empty($this->page_data->page_template)) {
00058 $this->template = $this->page_data->page_template;
00059 }
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069 protected function render_content(&$rendered_content, $policy) {
00070 parent::render_content($rendered_content, $policy);
00071 if (Common::flag_is_set($policy, self::POLICY_GZIP)) {
00072 $rendered_content = gzdeflate($rendered_content, 9);
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083 protected function render_postprocess(&$rendered_content, $policy) {
00084 if (!Common::flag_is_set($policy, self::CONTENT_ONLY)) {
00085 $this->send_status();
00086 $cache_header_manager = $this->cache_manager->get_cache_header_manager();
00087 $cache_header_manager->send_headers(
00088 $rendered_content,
00089 $this->cache_manager->get_expiration_datetime(),
00090 $this->cache_manager->get_creation_datetime()
00091 );
00092
00093 if (Common::flag_is_set($policy, self::POLICY_GZIP)) {
00094 GyroHeaders::set('Content-Encoding', 'deflate', true);
00095 }
00096 GyroHeaders::set('Vary', 'Accept-Encoding', false);
00097 GyroHeaders::set('Date', GyroDate::http_date(time()), true);
00098
00099 GyroHeaders::send();
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108 protected function should_cache() {
00109 $ret = parent::should_cache();
00110 if ($ret) {
00111
00112 $ret = empty($this->page_data->status) || $this->page_data->status->is_empty();
00113 }
00114 return $ret;
00115 }
00116
00117
00118
00119
00120
00121
00122 protected function get_cache_lifetime() {
00123 return $this->cache_manager->get_expiration_datetime() - time();
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133 protected function store_cache($cache_key, $content, $lifetime, $policy) {
00134 $headers = array();
00135 $forbidden = array(
00136 'age',
00137 'date',
00138 'content-encoding',
00139 'content-length',
00140 'server',
00141 'set-cookie',
00142 'transfer-encoding',
00143 'x-powered-by',
00144 'keep-alive',
00145 'connection'
00146 );
00147 foreach(GyroHeaders::headers() as $name => $val) {
00148 if (!in_array($name, $forbidden)) {
00149 $headers[] = $val;
00150 }
00151 }
00152 $cache_data = array(
00153 'status' => $this->page_data->status_code,
00154 'in_history' => $this->page_data->in_history,
00155 'headers' => $headers,
00156 'cacheheadermanager' => $this->cache_manager->get_cache_header_manager()
00157 );
00158 $gziped = Common::flag_is_set($policy, self::POLICY_GZIP);
00159 Cache::store($cache_key, $content, $lifetime, $cache_data, $gziped);
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 protected function do_render_cache($cache, $policy) {
00170 $ret = '';
00171 if ($cache) {
00172 $cache_data = $cache->get_data();
00173 foreach(Arr::get_item($cache_data, 'headers', array()) as $header) {
00174 GyroHeaders::set($header, false, true);
00175 }
00176
00177 $cache_header_manager = Arr::get_item($cache_data, 'cacheheadermanager', $this->cache_manager->get_cache_header_manager());
00178 $this->cache_manager->set_cache_header_manager($cache_header_manager);
00179 $this->page_data->status_code = Arr::get_item($cache_data, 'status', '');
00180 $this->page_data->in_history = Arr::get_item($cache_data, 'in_history', true);
00181 if (Common::flag_is_set($policy, self::POLICY_GZIP)) {
00182 $ret = $cache->get_content_compressed();
00183 }
00184 else {
00185 $ret = $cache->get_content_plain();
00186 }
00187 }
00188 return $ret;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 protected function send_cache_headers($lastmodified, $expires, $max_age = 600, $etag = '') {
00199 $max_age = intval($max_age);
00200 GyroHeaders::set('Pragma', '', false);
00201 GyroHeaders::set('Cache-Control', "private, must-revalidate, max-age=$max_age", false);
00202 GyroHeaders::set('Last-Modified', GyroDate::http_date($lastmodified), false);
00203 GyroHeaders::set('Expires', GyroDate::http_date($expires), false);
00204 GyroHeaders::set('Etag', $etag, true);
00205 }
00206
00207
00208
00209
00210
00211
00212 protected function assign_default_vars($policy) {
00213 parent::assign_default_vars($policy);
00214
00215
00216 switch ($this->page_data->status_code) {
00217 case CONTROLLER_ACCESS_DENIED:
00218 case CONTROLLER_NOT_FOUND:
00219 case CONTROLLER_INTERNAL_ERROR:
00220 $error_view = ViewFactory::create_view(
00221 IViewFactory::CONTENT,
00222 'errors/' . String::plain_ascii($this->page_data->status_code, '_'),
00223 $this->page_data
00224 );
00225 $this->page_data->head->robots_index = ROBOTS_NOINDEX_FOLLOW;
00226 $error_view->render();
00227 break;
00228 default:
00229 break;
00230 }
00231
00232 $this->page_data->sort_blocks();
00233 $this->assign('page_data', $this->page_data);
00234 $this->assign('pagetitle', $this->page_data->head->title);
00235 $this->assign('pagedescr', String::substr_word($this->page_data->head->description, 0, 200));
00236 $this->assign('status', $this->page_data->status);
00237 $this->assign('blocks', $this->page_data->blocks);
00238 $this->assign('content', $this->page_data->content);
00239 $breadcrumb = is_string($this->page_data->breadcrumb) ? $this->page_data->breadcrumb : WidgetBreadcrumb::output($this->page_data->breadcrumb);
00240 if (Config::get_value(Config::VERSION_MAX) < 0.6) {
00241
00242 $this->page_data->breadcrumb = $breadcrumb;
00243 }
00244 $this->assign('breadcrumb', $breadcrumb);
00245
00246 if ($this->page_data->router) {
00247 $this->assign('route_id', $this->page_data->router->get_route_id());
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 protected function format_error($message) {
00258 return html::error($message);
00259 }
00260
00261
00262
00263
00264 protected function send_status() {
00265 $log = Config::has_feature(Config::LOG_HTML_ERROR_STATUS);
00266 switch ($this->page_data->status_code) {
00267 case CONTROLLER_ACCESS_DENIED:
00268 Common::send_status_code(403);
00269 break;
00270 case CONTROLLER_NOT_FOUND:
00271 Common::send_status_code(404);
00272 break;
00273 case CONTROLLER_INTERNAL_ERROR:
00274 Common::send_status_code(503);
00275 break;
00276 default:
00277
00278 if ($this->page_data->in_history) {
00279 History::push(Url::current());
00280 }
00281 $log = false;
00282 break;
00283 }
00284 if ($log) {
00285 Load::components('referer', 'logger');
00286 $referer = Referer::current();
00287 $request = RequestInfo::current();
00288 $params = array(
00289 'code' => $this->page_data->status_code,
00290 'referer' => $referer->build(),
00291 'referer_org' => $referer->get_original_referer_url(),
00292 'useragent' => $request->user_agent(),
00293 'host' => $request->remote_host()
00294 );
00295 Logger::log('html_error_status', $params);
00296 }
00297 }
00298 }