HCE Project DC service web UI  0.2
Hierarchical Cluster Engine DC service web UI
 All Classes Namespaces Files Functions Variables Pages
TbJsonGridView.php
Go to the documentation of this file.
1 <?php
10 Yii::import('booster.widgets.TbGridView');
11 Yii::import('booster.widgets.TbJsonDataColumn');
12 
22 {
26  public $json;
27 
31  public $template = "{pager}\n{items}\n{summary}\n{pager}";
32 
36  public $cacheTTL = 1;
37 
44  public $cacheTTLType = 's';
45 
49  public $localCache = true;
50 
55  public $pager = array('class' => 'booster.widgets.TbJsonPager');
56 
60  protected $_showSummary;
61 
65  public function init()
66  {
67  // parse request to find out whether is an ajax request or not, if so, then return $dataProvider JSON formatted
68  $this->json = Yii::app()->getRequest()->getIsAjaxRequest();
69  if ($this->json) {
70  $this->_showSummary = (strpos($this->template, '{summary}')) ? true : false;
71  $this->template = '{items}';
72  } // going to render only items!
73 
74  parent::init();
75  }
76 
82  public function run()
83  {
84  if (!$this->json) {
85  parent::run();
86  } else {
87  $this->registerClientScript();
88  $this->renderContent();
89  }
90  }
91 
95  public function renderPager()
96  {
97  if (!$this->json) {
99  return true;
100  }
101 
102  $pager = array();
103  if (is_string($this->pager)) {
105  } else if (is_array($this->pager)) {
107  if (isset($pager['class'])) {
108  $class = $pager['class'];
109  unset($pager['class']);
110  }
111  }
112  $pager['pages'] = $this->dataProvider->getPagination();
113 
114  if ($pager['pages']->getPageCount() > 1) {
115  $pager['json'] = $this->json;
116  $widget = $this->createWidget($class, $pager);
117 
118  return $widget->run();
119  } else {
120  return array();
121  }
122  }
123 
127  protected function initColumns()
128  {
129  foreach ($this->columns as $i => $column) {
130  if (is_array($column) && !isset($column['class'])) {
131  $this->columns[$i]['class'] = 'booster.widgets.TbJsonDataColumn';
132  }
133  }
134 
136  }
137 
141  public function renderItems()
142  {
143  if ($this->json) {
144  echo function_exists('json_encode')
145  ? json_encode($this->renderTableBody())
146  : CJSON::encode(
147  $this->renderTableBody()
148  );
149 
150  } elseif ($this->dataProvider->getItemCount() > 0 || $this->showTableOnEmpty) {
151  echo "<table class=\"{$this->itemsCssClass}\">\n";
152  $this->renderTableHeader();
153  ob_start();
154  $this->renderTableBody();
155  $body = ob_get_clean();
156  $this->renderTableFooter();
157  echo $body; // TFOOT must appear before TBODY according to the standard.
158  echo "</table>";
159  $this->renderTemplates();
160 
161  } else {
162  $this->renderEmptyText();
163  }
164  }
165 
166  public function renderSummary()
167  {
168  if (!$this->json)
169  {
171  return true;
172  }
173 
174  if (!$this->_showSummary)
175  {
176  return null;
177  }
178 
179  ob_start();
181  $summary = ob_get_clean();
182  return array(
183  'class' => $this->summaryCssClass,
184  'text' => $summary
185  );
186 
187  }
191  protected function renderTemplates()
192  {
193  echo $this->renderTemplate($this->id . '-col-template', '<td <%=this.attrs%>><%=this.content%></td>');
194  echo $this->renderTemplate(
195  $this->id . '-row-template',
196  '<tr class="<%=this.class%>"><% var t = "#' . $this->id . '-col-template"; out += $.jqote(t, this.cols);%></tr>'
197  );
198  echo $this->renderTemplate($this->id . '-keys-template', '<span><%=this%></span>');
199 
200  echo $this->renderTemplate(
201  $this->id . '-pager-template',
202  '<li class="<%=this.class%>"><a href="<%=this.url%>"><%=this.text%></a></li>'
203  );
204 
205  echo $this->renderTemplate(
206  $this->id . '-summary-template',
207  '<div class="<%=this.class%>"><%=this.text%></div>'
208  );
209 
210  }
211 
220  public function renderTemplate($id, $text)
221  {
222  return "<script type=\"text/x-jqote-template\" id=\"{$id}\">\n<![CDATA[\n{$text}\n]]>\n</script>";
223  }
224 
228  public function renderTableBody()
229  {
230  $data = $this->dataProvider->getData();
231  $n = count($data);
232 
233  if ($this->json) {
234  return $this->renderTableBodyJSON($n);
235  }
236 
237  echo CHtml::openTag('tbody');
238 
239  if ($n > 0) {
240  for ($row = 0; $row < $n; ++$row) {
241  $this->renderTableRow($row);
242  }
243  } else {
244  echo '<tr><td colspan="' . count($this->columns) . '" class="empty">';
245  $this->renderEmptyText();
246  echo "</td></tr>\n";
247  }
248 
249  echo CHtml::closeTag('tbody');
250  }
251 
259  protected function renderTableBodyJSON($rows)
260  {
261  $tbody = array(
262  'headers' => array(),
263  'rows' => array(),
264  'keys' => array(),
265  'summary' => array()
266  );
267  foreach ($this->columns as $column) {
269  // TODO: what is this?
270  // if (property_exists($column, 'json')) {
271  // $column->json = $this->json;
272  $tbody['headers'][] = $column->renderHeaderCell();
273  // }
274  }
275 
276  if ($rows > 0) {
277  for ($row = 0; $row < $rows; ++$row) {
278  $tbody['rows'][] = $this->renderTableRowJSON($row);
279  }
280 
281  foreach ($this->dataProvider->getKeys() as $key) {
282  $tbody['keys'][] = CHtml::encode($key);
283  }
284 
285  } else {
286  ob_start();
287  $this->renderEmptyText();
288  $content = ob_get_contents();
289  ob_end_clean();
290 
291  $tbody['rows'][0]['cols'][] = array(
292  'attrs' => "colspan=\"" . count($this->columns) . "\"",
293  'content' => $content
294  );
295  $tbody['rows'][0]['class'] = " ";
296  }
297  $tbody['pager'] = $this->renderPager();
298  $tbody['url'] = Yii::app()->getRequest()->getUrl();
299  $tbody['summary'] = $this->renderSummary();
300  return $tbody;
301  }
302 
308  public function renderTableRow($row)
309  {
310  if ($this->rowCssClassExpression !== null) {
311  $data = $this->dataProvider->data[$row];
312  echo '<tr class="' . $this->evaluateExpression(
313  $this->rowCssClassExpression,
314  array('row' => $row, 'data' => $data)
315  ) . '">';
316  } else if (is_array($this->rowCssClass) && ($n = count($this->rowCssClass)) > 0) {
317  echo '<tr class="' . $this->rowCssClass[$row % $n] . '">';
318  } else {
319  echo '<tr>';
320  }
321  foreach ($this->columns as $column) {
323  $column->renderDataCell($row);
324  }
325  echo "</tr>\n";
326  }
327 
335  protected function renderTableRowJSON($row)
336  {
337  $json = array();
338  if ($this->rowCssClassExpression !== null) {
339  $data = $this->dataProvider->data[$row];
340  $json['class'] = $this->evaluateExpression(
341  $this->rowCssClassExpression,
342  array('row' => $row, 'data' => $data)
343  );
344  } else if (is_array($this->rowCssClass) && ($n = count($this->rowCssClass)) > 0) {
345  $json['class'] = $this->rowCssClass[$row % $n];
346  } else {
347  echo '<tr>';
348  }
349  foreach ($this->columns as $column) {
350  $json['cols'][] = $column->renderDataCell($row);
351  }
352 
353  return $json;
354  }
355 
364  protected function createDataColumn($text)
365  {
366  if (!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/', $text, $matches)) {
367  throw new CException(Yii::t(
368  'zii',
369  'The column must be specified in the format of "Name:Type:Label", where "Type" and "Label" are optional.'
370  ));
371  }
372 
373  $column = new TbJsonDataColumn($this);
374  $column->name = $matches[1];
375 
376  if (isset($matches[3]) && $matches[3] !== '') {
377  $column->type = $matches[3];
378  }
379 
380  if (isset($matches[5])) {
381  $column->header = $matches[5];
382  }
383 
384  return $column;
385  }
386 
390  public function registerClientScript()
391  {
392  $id = $this->getId();
393 
394  if ($this->ajaxUpdate === false) {
395  $ajaxUpdate = false;
396  } else {
397  $ajaxUpdate = array_unique(
398  preg_split('/\s*,\s*/', $this->ajaxUpdate . ',' . $id, -1, PREG_SPLIT_NO_EMPTY)
399  );
400  }
401  $options = array(
402  'ajaxUpdate' => $ajaxUpdate,
403  'ajaxVar' => $this->ajaxVar,
404  'pagerClass' => $this->pagerCssClass,
405  'summaryClass' => $this->summaryCssClass,
406  'loadingClass' => $this->loadingCssClass,
407  'filterClass' => $this->filterCssClass,
408  'tableClass' => $this->itemsCssClass,
409  'selectableRows' => $this->selectableRows,
410  'enableHistory' => $this->enableHistory,
411  'updateSelector' => $this->updateSelector,
412  'cacheTTL' => $this->cacheTTL,
413  'cacheTTLType' => $this->cacheTTLType,
414  'localCache' => $this->localCache
415  );
416  if ($this->ajaxUrl !== null) {
417  $options['url'] = CHtml::normalizeUrl($this->ajaxUrl);
418  }
419  if ($this->enablePagination) {
420  $options['pageVar'] = $this->dataProvider->getPagination()->pageVar;
421  }
422 
423  foreach (array('beforeAjaxUpdate', 'afterAjaxUpdate', 'ajaxUpdateError', 'selectionChanged') as $prop) {
424  if ($this->{$prop} !== null) {
425  if ((!$this->{$prop} instanceof CJavaScriptExpression) && strpos($this->{$prop}, 'js:') !== 0) {
426  $options[$prop] = new CJavaScriptExpression($this->{$prop});
427  } else {
428  $options[$prop] = $this->{$prop};
429  }
430  }
431  }
432 
433  $options = CJavaScript::encode($options);
435  $cs = Yii::app()->getClientScript();
436  $cs->registerCoreScript('jquery');
437  $cs->registerCoreScript('bbq');
438  if ($this->enableHistory) {
439  $cs->registerCoreScript('history');
440  }
441 
442  $cs->registerPackage('json-grid-view');
443 
444  $cs->registerScript(__CLASS__ . '#' . $id, "jQuery('#$id').yiiJsonGridView($options);");
445  }
446 }