Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
RendererController.php
1 <?php
2 /**
3  * Gentics Portal.Node PHP
4  * Author & Copyright (c) by Gentics Software GmbH
5  * sales@gentics.com
6  * http://www.gentics.com
7  * Licenses can be found in the LICENSE.txt file in the root-folder of this installation
8  * You must not use this software without a valid license agreement.
9  *
10  * Controller which recieve all requests to Content Repository
11  *
12  * All request for pages which should be rendered(html, php) handled by actionDynamic()
13  * All other requests, for static content (img, doc, pdf, etc.) handled by actionStatic()
14  * Css and js files also handled by actionStatic() if they are not wrapped
15  * in Yii::app()->clientScript->registerCssFile() or Yii::app()->clientScript->registerScriptFile().
16  * If they are wrapped then they will compressed and stored in /assets folder.
17  *
18  * To handle request to specific node from content repository add these lines into routers.php
19  * 'rules' => array(
20 '<path:nodename\/.+\.(php|html)>' => 'contentRepository/dynamic',
21 '<path:nodename\/.+>' => 'contentRepository/static',
22 ),
23  * nodename - name of node(for exaple - gportal)
24  *
25  */
27 {
28  /**
29  * Default action
30  *
31  * @return void
32  */
33  function actionIndex()
34  {
35  $this->redirect(Yii::app()->createUrl(Yii::app()->getModule('user')->homePageUrl));
36  }
37 
38  /**
39  * Action which render all static content: js, css, doc, pdf files etc.
40  *
41  * @throws CHttpException
42  * @throws Exception
43  *
44  * @return void
45  */
46  function actionStatic()
47  {
48  if (Yii::app()->request->getParam('path',false)) {
49  $path = '/' . Yii::app()->request->getParam('path','');
50 
51  $content = $this->_getContentSource()->getContent($path);
52  if ($content) {
53  if ($content->hasAccess(Yii::app()->user)) {
54  $fileContent = file_get_contents($content->getFile());
55  array_map(
56  function($header)
57  {
58  header($header);
59  },
60  array_merge(
61  HeadersHelper::forFile($path, $fileContent),
62  // set the expires header
63  HeadersHelper::expires($this->_getContentSource()->getBrowserCacheTimeByFileName($path)),
64  // set the browser cache control for static files
65  HeadersHelper::cache($this->_getContentSource()->getBrowserCacheTimeByFileName($path))
66  )
67  );
68  echo $fileContent;
69  die;
70  } else {
71  $this->_noAccess($content);
72  }
73  } else {
74  if (YII_DEBUG) {
75  throw new Exception('Path not exists: ' . $this->_getContentSource()->contentSource->contentFile($path));
76  } else {
77  throw new CHttpException(404);
78  }
79  }
80  }
81  }
82 
83  /**
84  * Action which render all dynamic content: php, html files
85  *
86  * @throws CHttpException
87  * @throws Exception
88  *
89  * @return void
90  */
91  function actionDynamic()
92  {
93  if (Yii::app()->request->getParam('path',false)) {
94  $path = '/' . Yii::app()->request->getParam('path','');
95 
96  $content = $this->_getContentSource()->getContent($path);
97  if ($content) {
98 
99 
100  if ($content->hasAccess(Yii::app()->user)) {
101  $content = $this->renderFile($content->getFile(), null, true);
102  echo $this->processOutput($content);
103  } else {
104  $this->_noAccess($content);
105  }
106  } else {
107  if (YII_DEBUG) {
108  throw new Exception('Path not exists: ' . $this->_getContentSource()->contentSource->contentFile($path));
109  } else {
110  throw new CHttpException(404);
111  }
112  }
113  }
114  }
115 
116  /**
117  * Handle folder start page. In case user make request to folder like /Content.Node/service/
118  *
119  * @return void
120  * @author Me
121  **/
122  public function actionStartPage()
123  {
124  if($this->module->getContentSource() instanceof FileSystemContentSource) {
125  throw new CHttpException(404);
126  }
127 
128  $folder = Yii::app()->request->getParam('folder', '').'/';
129  $startPage = $this->module->getContentSource()->getStartPage($folder, substr(Yii::app()->locale->id, 0, 2));
130 
131  if($startPage === false) {
132  $startPage = '/' . Yii::app()->request->getParam('path','') . $folder . $this->module->startPageFallback;
133  }
134 
135  if($this->module->startPageDynamic) {
136  $_GET['path'] = substr($startPage,1);
137  $this->actionDynamic();
138  } else {
139  $this->redirect($startPage);
140  }
141  }
142  /**
143  * Sets corresponding messages and performs redirect if user don't have access to requested content
144  *
145  * @param string $path content path
146  *
147  * @return void
148  */
149  private function _noAccess($content)
150  {
151  if (Yii::app()->user->isGuest) {
152  $message = UserModule::t('Please login to access required content.');
153  } else {
154  $message = UserModule::t("You don't have enough rights to access this content. You should have such permissions: {permissions}", array('{permissions}'=> implode(', ', $content->getPersonalisationAttributes())));
155  }
156 
157  Yii::app()->user->setFlash(
158  Yii::app()->getModule('user')->userLoginWidgetFlashError,
159  $message
160  );
161  Yii::app()->user->setReturnUrl($content->getPath());
162  $this->redirect(Yii::app()->getModule('user')->loginUrl);
163  }
164 
165  public function processOutput($output){
166  $processed = parent::processOutput($output);
167  $headPosition = strpos($processed, '<head>');
168  $is_head = false;
169  preg_match("/<head>(?P<head_content>.*)<\/head>/s", $processed, $is_head);
170  if(!empty($is_head)){
171  $is_head = trim($is_head['head_content']);
172  $is_head = strlen($is_head) ? true: false;
173  }else{
174  $is_head = false;
175  }
176  if($headPosition && $is_head){
177  $processed = substr_replace($processed, AppHelper::footprint('<!-- generated by Gentics Portal.Node -->'), $headPosition, 0);
178  if(isset($_GET['error'])){
179  $error_code = $_GET['error'];
180  $error_msg = self::getStatusText($error_code);
181  header("HTTP/1.1 $error_code $error_msg");
182  }
183  }
184  return $processed;
185  }
186 
187  static function getStatusText($code){
188 
189  $status_codes = array (
190 
191  100 => 'Continue',
192  101 => 'Switching Protocols',
193  102 => 'Processing',
194  200 => 'OK',
195  201 => 'Created',
196  202 => 'Accepted',
197  203 => 'Non-Authoritative Information',
198  204 => 'No Content',
199  205 => 'Reset Content',
200  206 => 'Partial Content',
201  207 => 'Multi-Status',
202  300 => 'Multiple Choices',
203  301 => 'Moved Permanently',
204  302 => 'Found',
205  303 => 'See Other',
206  304 => 'Not Modified',
207  305 => 'Use Proxy',
208  307 => 'Temporary Redirect',
209  400 => 'Bad Request',
210  401 => 'Unauthorized',
211  402 => 'Payment Required',
212  403 => 'Forbidden',
213  404 => 'Not Found',
214  405 => 'Method Not Allowed',
215  406 => 'Not Acceptable',
216  407 => 'Proxy Authentication Required',
217  408 => 'Request Timeout',
218  409 => 'Conflict',
219  410 => 'Gone',
220  411 => 'Length Required',
221  412 => 'Precondition Failed',
222  413 => 'Request Entity Too Large',
223  414 => 'Request-URI Too Long',
224  415 => 'Unsupported Media Type',
225  416 => 'Requested Range Not Satisfiable',
226  417 => 'Expectation Failed',
227  422 => 'Unprocessable Entity',
228  423 => 'Locked',
229  424 => 'Failed Dependency',
230  426 => 'Upgrade Required',
231  500 => 'Internal Server Error',
232  501 => 'Not Implemented',
233  502 => 'Bad Gateway',
234  503 => 'Service Unavailable',
235  504 => 'Gateway Timeout',
236  505 => 'HTTP Version Not Supported',
237  506 => 'Variant Also Negotiates',
238  507 => 'Insufficient Storage',
239  509 => 'Bandwidth Limit Exceeded',
240  510 => 'Not Extended'
241  );
242 
243  $msg = isset($status_codes[$code])?$status_codes[$code]:'An unknown error';
244 
245  return $msg;
246  }
247 
248  /**
249  * Register css file in page
250  *
251  * @param string $file filename
252  * @param null $timestamp last update timestamp of this file
253  * @param bool $combine if combine and compress this file
254  * @param string $media media that the CSS code should be applied to. If empty, it means all media types.
255  *
256  * @return void
257  */
258  public function getCss($file, $timestamp = null, $combine = true, $media = '')
259  {
260  Yii::app()->clientScript->registerCssFile($file, $media, $timestamp, $combine, true, true);
261  }
262 
263  /**
264  * Register js file in page
265  *
266  * @param string $file filename
267  * @param null $timestamp last update timestamp of this file
268  * @param bool $combine if combine and compress this file
269  *
270  * @return void
271  */
272  public function getJs($file, $timestamp = null, $combine = true)
273  {
274  Yii::app()->clientScript->registerScriptFile($file, CClientScript::POS_HEAD, $timestamp, $combine, true, true);
275  }
276 
277  /**
278  * Register general javascript library which is used by page and widgets and which should be of the same version in many palces.
279  * For example jQuery library
280  *
281  * @param string $file filename
282  *
283  * @return void
284  */
285  public function getCoreJs($file)
286  {
287  Yii::app()->clientScript->registerCoreScript($file, true);
288  }
289 
290  /**
291  * Get current content source for Static or Dynamic content renderer
292  *
293  * @return ContentSourceModule
294  */
295  private function _getContentSource()
296  {
297  return Yii::app()->getModule('contentSource');
298  }
299 }