ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
Renderer.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 2017 Jesús López <lopez@leifos.de> Extended GPL, see docs/LICENSE */
3 
5 
9 
15 {
16  const MODE_ROLE = "group";
17 
22  public function render(Component\Component $component, RendererInterface $default_renderer)
23  {
24  $this->checkComponent($component);
25 
26  if ($component instanceof Component\ViewControl\Mode) {
27  return $this->renderMode($component, $default_renderer);
28  }
29  if ($component instanceof Component\ViewControl\Section) {
30  return $this->renderSection($component, $default_renderer);
31  }
32  if ($component instanceof Component\ViewControl\Sortation) {
33  return $this->renderSortation($component, $default_renderer);
34  }
35  if ($component instanceof Component\ViewControl\Pagination) {
36  return $this->renderPagination($component, $default_renderer);
37  }
38  }
39 
40  protected function renderMode(Component\ViewControl\Mode $component, RendererInterface $default_renderer)
41  {
42  $f = $this->getUIFactory();
43 
44  $tpl = $this->getTemplate("tpl.mode.html", true, true);
45 
46  $active = $component->getActive();
47  if ($active == "") {
48  $activate_first_item = true;
49  }
50 
51  foreach ($component->getLabelledActions() as $label => $action) {
52  $tpl->setVariable("ARIA", $this->txt($component->getAriaLabel()));
53  $tpl->setVariable("ROLE", self::MODE_ROLE);
54 
55  $tpl->setCurrentBlock("view_control");
56 
57  //At this point we don't have an specific text for the button aria label. component->getAriaLabel gets the main viewcontrol aria label.
58  $button = $f->button()->standard($label, $action)->withAriaLabel($label);
59  if ($activate_first_item) {
60  $button = $button->withEngagedState(true)->withUnavailableAction();
61  $activate_first_item = false;
62  } elseif ($active == $label) {
63  $button = $button->withEngagedState(true)->withUnavailableAction();
64  } else {
65  $button = $button->withEngagedState(false);
66  }
67  $tpl->setVariable("BUTTON", $default_renderer->render($button));
68  $tpl->parseCurrentBlock();
69  }
70 
71  return $tpl->get();
72  }
73 
74  protected function renderSection(Component\ViewControl\Section $component, RendererInterface $default_renderer)
75  {
76  $f = $this->getUIFactory();
77 
78  $tpl = $this->getTemplate("tpl.section.html", true, true);
79 
80  // render middle button
81  $tpl->setVariable("BUTTON", $default_renderer->render($component->getSelectorButton()));
82 
83  // previous button
84  $this->renderSectionButton($component->getPreviousActions(), $tpl, "prev");
85 
86  // next button
87  $this->renderSectionButton($component->getNextActions(), $tpl, "next");
88 
89  return $tpl->get();
90  }
91 
97  protected function renderSectionButton(Component\Button\Button $component, $tpl, $type)
98  {
99  $uptype = strtoupper($type);
100 
101  $action = $component->getAction();
102  $tpl->setVariable($uptype . "_ACTION", $action);
103  $label = ($type == "next")
104  ? $this->txt("next")
105  : $this->txt("previous");
106  $tpl->setVariable($uptype . "_LABEL", $label);
107  if ($component->isActive()) {
108  $tpl->setCurrentBlock($type . "_with_href");
109  $tpl->setVariable($uptype . "_HREF", $action);
110  $tpl->parseCurrentBlock();
111  } else {
112  $tpl->touchBlock($type . "_disabled");
113  }
114  $this->maybeRenderId($component, $tpl, $type . "_with_id", $uptype . "_ID");
115  }
116 
117 
118  protected function renderSortation(Component\ViewControl\Sortation $component, RendererInterface $default_renderer)
119  {
120  $f = $this->getUIFactory();
121 
122  $tpl = $this->getTemplate("tpl.sortation.html", true, true);
123 
124  $component = $component->withResetSignals();
125  $triggeredSignals = $component->getTriggeredSignals();
126  if ($triggeredSignals) {
127  $internal_signal = $component->getSelectSignal();
128  $signal = $triggeredSignals[0]->getSignal();
129  $options = json_encode($signal->getOptions());
130 
131  $component = $component->withOnLoadCode(function ($id) use ($internal_signal, $signal) {
132  return "$(document).on('{$internal_signal}', function(event, signalData) {
133  il.UI.viewcontrol.sortation.onInternalSelect(event, signalData, '{$signal}', '{$id}');
134  return false;
135  })";
136  });
137 
138  //maybeRenderId does not return id
139  $id = $this->bindJavaScript($component);
140  $tpl->setVariable('ID', $id);
141  }
142 
143  //setup entries
144  $options = $component->getOptions();
145  $init_label = $component->getLabel();
146  $items = array();
147  foreach ($options as $val => $label) {
148  if ($triggeredSignals) {
149  $shy = $f->button()->shy($label, $val)->withOnClick($internal_signal);
150  } else {
151  $url = $component->getTargetURL();
152  $url .= (strpos($url, '?') === false) ? '?' : '&';
153  $url .= $component->getParameterName() . '=' . $val;
154  $shy = $f->button()->shy($label, $url);
155  }
156  $items[] = $shy;
157  }
158 
159  $dd = $f->dropdown()->standard($items)
160  ->withLabel($init_label);
161 
162  $tpl->setVariable('SORTATION_DROPDOWN', $default_renderer->render($dd));
163  return $tpl->get();
164  }
165 
166 
167 
168  protected function renderPagination(Component\ViewControl\Pagination $component, RendererInterface $default_renderer)
169  {
170  $tpl = $this->getTemplate("tpl.pagination.html", true, true);
171 
172  $component = $component->withResetSignals();
173  $triggeredSignals = $component->getTriggeredSignals();
174  if ($triggeredSignals) {
175  $internal_signal = $component->getInternalSignal();
176  $signal = $triggeredSignals[0]->getSignal();
177  $component = $component->withOnLoadCode(function ($id) use ($internal_signal, $signal) {
178  return "$(document).on('{$internal_signal}', function(event, signalData) {
179  il.UI.viewcontrol.pagination.onInternalSelect(event, signalData, '{$signal}', '{$id}');
180  return false;
181  })";
182  });
183 
184  $id = $this->bindJavaScript($component);
185  $tpl->setVariable('ID', $id);
186  }
187 
188  $range = $this->getPaginationRange($component);
189  $chunk_options = array();
190  foreach ($range as $entry) {
191  $shy = $this->getPaginationShyButton($entry, $component);
192  if ((int) $entry === $component->getCurrentPage()) {
193  $shy = $shy->withUnavailableAction();
194  }
195  $chunk_options[] = $shy;
196  }
197 
198  if ($component->getDropdownAt() == null ||
199  $component->getDropdownAt() > $component->getNumberOfPages()) {
200  foreach ($chunk_options as $entry) {
201  $tpl->setCurrentBlock("entry");
202  $tpl->setVariable('BUTTON', $default_renderer->render($entry));
203  $tpl->parseCurrentBlock();
204  }
205  } else {
206  //if threshold is reached, render as dropdown
207  $f = $this->getUIFactory();
208 
209  $dd_label_template = $component->getDropdownLabel();
210  if ($dd_label_template === $component->getDefaultDropdownLabel()) {
211  $dd_label_template = $this->txt($dd_label_template);
212  }
213  $dd_label = sprintf(
214  $dd_label_template,
215  $component->getCurrentPage() + 1,
216  $component->getNumberOfPages()
217  );
218 
219  $dd = $f->dropdown()->standard($chunk_options)->withLabel($dd_label);
220  $tpl->setCurrentBlock("entry");
221  $tpl->setVariable('BUTTON', $default_renderer->render($dd));
222  $tpl->parseCurrentBlock();
223  }
224 
225  if ($component->getMaxPaginationButtons()) {
226  $this->setPaginationFirstLast($component, $range, $default_renderer, $tpl);
227  }
228 
229  $this->setPaginationBrowseControls($component, $default_renderer, $tpl);
230  return $tpl->get();
231  }
232 
240  protected function getPaginationRange(Component\ViewControl\Pagination $component)
241  {
242  if (!$component->getMaxPaginationButtons()) {
243  $start = 0;
244  $stop = max($component->getNumberOfPages() - 1, 0);
245  } else {
246  //current page should be in the middle, so start is half the amount of max entries:
247  $start = (int) ($component->getCurrentPage() - floor($component->getMaxPaginationButtons() / 2));
248  $start = max($start, 0); //0, if negative
249  //stop is (calculated) start plus number of entries:
250  $stop = $start + $component->getMaxPaginationButtons() - 1;
251  //if stop exceeds max pages, recalculate both:
252  if ($stop > $component->getNumberOfPages() - 1) {
253  $stop = max($component->getNumberOfPages() - 1, 0); //0, if negative
254  $start = $stop - $component->getMaxPaginationButtons();
255  $start = max($start, 0); //0, if negative
256  }
257  }
258  return range($start, $stop);
259  }
260 
261 
269  protected function getPaginationShyButton($val, Component\ViewControl\Pagination $component, $label = '')
270  {
271  $f = $this->getUIFactory();
272 
273  if ($label === '') {
274  $label = (string) ($val + 1);
275  }
276 
277  if ($component->getTriggeredSignals()) {
278  $shy = $f->button()->shy($label, (string) $val)->withOnClick($component->getInternalSignal());
279  } else {
280  $url = $component->getTargetURL();
281  if (strpos($url, '?') === false) {
282  $url .= '?' . $component->getParameterName() . '=' . $val;
283  } else {
284  $base = substr($url, 0, strpos($url, '?') + 1);
285  $query = parse_url($url, PHP_URL_QUERY);
286  parse_str($query, $params);
287  $params[$component->getParameterName()] = $val;
288  $url = $base . http_build_query($params);
289  }
290  $shy = $f->button()->shy($label, $url);
291  }
292  return $shy;
293  }
294 
304  protected function setPaginationBrowseControls(Component\ViewControl\Pagination $component, RendererInterface $default_renderer, &$tpl)
305  {
306  $prev = max(0, $component->getCurrentPage() - 1);
307  $next = $component->getCurrentPage() + 1;
308 
309  $f = $this->getUIFactory();
310 
311  if ($component->getTriggeredSignals()) {
312  $back = $f->symbol()->glyph()->back('')->withOnClick($component->getInternalSignal());
313  $forward = $f->symbol()->glyph()->next('')->withOnClick($component->getInternalSignal());
314  } else {
315  $url = $component->getTargetURL();
316  if (strpos($url, '?') === false) {
317  $url_prev = $url . '?' . $component->getParameterName() . '=' . $prev;
318  $url_next = $url . '?' . $component->getParameterName() . '=' . $next;
319  } else {
320  $base = substr($url, 0, strpos($url, '?') + 1);
321  $query = parse_url($url, PHP_URL_QUERY);
322  parse_str($query, $params);
323 
324  $params[$component->getParameterName()] = $prev;
325  $url_prev = $base . http_build_query($params);
326  $params[$component->getParameterName()] = $next;
327  $url_next = $base . http_build_query($params);
328  }
329 
330  $back = $f->symbol()->glyph()->back($url_prev);
331  $forward = $f->symbol()->glyph()->next($url_next);
332  }
333 
334  if ($component->getCurrentPage() === 0) {
335  $back = $back->withUnavailableAction();
336  }
337  if ($component->getCurrentPage() >= $component->getNumberOfPages() - 1) {
338  $forward = $forward->withUnavailableAction();
339  }
340 
341  $tpl->setVariable('PREVIOUS', $default_renderer->render($back));
342  $tpl->setVariable('NEXT', $default_renderer->render($forward));
343  }
344 
355  protected function setPaginationFirstLast(Component\ViewControl\Pagination $component, $range, RendererInterface $default_renderer, &$tpl)
356  {
357  if (!in_array(0, $range)) {
358  $shy = $this->getPaginationShyButton(0, $component);
359  $tpl->setVariable('FIRST', $default_renderer->render($shy));
360  }
361  $last = max($component->getNumberOfPages() - 1, 0);
362  if (!in_array($last, $range)) {
363  $shy = $this->getPaginationShyButton($component->getNumberOfPages() - 1, $component);
364  $tpl->setVariable('LAST', $default_renderer->render($shy));
365  }
366  }
367 
368 
372  public function registerResources(\ILIAS\UI\Implementation\Render\ResourceRegistry $registry)
373  {
374  parent::registerResources($registry);
375  $registry->register('./src/UI/templates/js/ViewControl/sortation.js');
376  $registry->register('./src/UI/templates/js/ViewControl/pagination.js');
377  }
378 
379 
380  protected function maybeRenderId(Component\Component $component, $tpl, $block, $template_var)
381  {
382  $id = $this->bindJavaScript($component);
383  if ($id !== null) {
384  $tpl->setCurrentBlock($block);
385  $tpl->setVariable($template_var, $id);
386  $tpl->parseCurrentBlock();
387  }
388  }
389 
393  protected function getComponentInterfaceName()
394  {
395  return array(
396  Component\ViewControl\Mode::class,
397  Component\ViewControl\Section::class,
398  Component\ViewControl\Sortation::class,
399  Component\ViewControl\Pagination::class
400  );
401  }
402 }
renderSection(Component\ViewControl\Section $component, RendererInterface $default_renderer)
Definition: Renderer.php:74
renderSortation(Component\ViewControl\Sortation $component, RendererInterface $default_renderer)
Definition: Renderer.php:118
Class Factory.
if(isset($_FILES['img_file']['size']) && $_FILES['img_file']['size'] > 0) $tpl
checkComponent(Component $component)
Check if a given component fits this renderer and throw if that is not the case. ...
$type
setPaginationBrowseControls(Component\ViewControl\Pagination $component, RendererInterface $default_renderer, &$tpl)
Add back/next-glyphs to the template for left/right browsing in pagination.
Definition: Renderer.php:304
Class ChatMainBarProvider .
getPaginationShyButton($val, Component\ViewControl\Pagination $component, $label='')
Definition: Renderer.php:269
renderSectionButton(Component\Button\Button $component, $tpl, $type)
Definition: Renderer.php:97
$base
Definition: index.php:4
getPaginationRange(Component\ViewControl\Pagination $component)
Get the range of pagination-buttons to show.
Definition: Renderer.php:240
registerResources(\ILIAS\UI\Implementation\Render\ResourceRegistry $registry)
Definition: Renderer.php:372
renderMode(Component\ViewControl\Mode $component, RendererInterface $default_renderer)
Definition: Renderer.php:40
$query
maybeRenderId(Component\Component $component, $tpl, $block, $template_var)
Definition: Renderer.php:380
render(Component\Component $component, RendererInterface $default_renderer)
Definition: Renderer.php:22
setPaginationFirstLast(Component\ViewControl\Pagination $component, $range, RendererInterface $default_renderer, &$tpl)
Add quick-access to first/last pages in pagination.
Definition: Renderer.php:355
renderPagination(Component\ViewControl\Pagination $component, RendererInterface $default_renderer)
Definition: Renderer.php:168
$url
getTemplate($name, $purge_unfilled_vars, $purge_unused_blocks)
Get template of component this renderer is made for.
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.