ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
AbstractComponentRenderer.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 2016 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4 
6 
11 
20 {
24  private $ui_factory;
25 
29  private $tpl_factory;
30 
34  private $lng;
35 
39  private $js_binding;
43  private static $component_storage = [];
44 
49  {
50  $this->ui_factory = $ui_factory;
51  $this->tpl_factory = $tpl_factory;
52  $this->lng = $lng;
53  $this->js_binding = $js_binding;
54  }
55 
59  public function registerResources(ResourceRegistry $registry)
60  {
61  $registry->register('./src/UI/templates/js/Core/ui.js');
62  }
63 
71  final protected function getUIFactory()
72  {
73  return $this->ui_factory;
74  }
75 
82  final public function txt($id)
83  {
84  return $this->lng->txt($id);
85  }
86 
91  final public function toJS($key)
92  {
93  $this->lng->toJS($key);
94  }
95 
101  public function getLangKey()
102  {
103  return $this->lng->getLangKey();
104  }
105 
106 
110  final protected function getJavascriptBinding()
111  {
112  return $this->js_binding;
113  }
114 
127  final protected function getTemplate($name, $purge_unfilled_vars, $purge_unused_blocks)
128  {
129  $path = $this->getTemplatePath($name);
130  return $this->tpl_factory->getTemplate($path, $purge_unfilled_vars, $purge_unused_blocks);
131  }
132 
139  protected function getTemplatePath($name)
140  {
141  $component = $this->getMyComponent();
142  return "src/UI/templates/default/$component/$name";
143  }
144 
154  final protected function bindJavaScript(JavaScriptBindable $component)
155  {
156  if ($component instanceof Triggerer) {
157  $component = $this->addTriggererOnLoadCode($component);
158  }
159  return $this->bindOnloadCode($component);
160  }
161 
168  private function bindOnloadCode(JavaScriptBindable $component)
169  {
170  $binder = $component->getOnLoadCode();
171  if ($binder === null) {
172  return null;
173  }
174 
175  $id = $this->js_binding->createId();
176  $on_load_code = $binder($id);
177  if (!is_string($on_load_code)) {
178  throw new \LogicException(
179  "Expected JavaScript binder to return string" .
180  " (used component: " . get_class($component) . ")"
181  );
182  }
183  $this->js_binding->addOnLoadCode($on_load_code);
184  return $id;
185  }
186 
193  private function addTriggererOnLoadCode(Triggerer $triggerer)
194  {
195  $triggered_signals = $triggerer->getTriggeredSignals();
196  if (count($triggered_signals) == 0) {
197  return $triggerer;
198  }
199  return $triggerer->withAdditionalOnLoadCode(function ($id) use ($triggered_signals) {
200  $code = "";
201  foreach ($triggered_signals as $triggered_signal) {
202  $signal = $triggered_signal->getSignal();
203  $event = $triggered_signal->getEvent();
204  $options = json_encode($signal->getOptions());
205  //Note this switch is necessary since $(#...).on('load', ...) could be fired before the binding of the event.
206  if ($event == 'load') {
207  $code .=
208  "$(this).trigger('{$signal}',
209  {
210  'id' : '{$signal}', 'event' : '{$event}',
211  'triggerer' : $('#{$id}'),
212  'options' : JSON.parse('{$options}')
213  }
214  );";
215  } else {
216  $code .=
217  "$('#{$id}').on('{$event}', function(event) {
218  $(this).trigger('{$signal}',
219  {
220  'id' : '{$signal}', 'event' : '{$event}',
221  'triggerer' : $(this),
222  'options' : JSON.parse('{$options}')
223  }
224  );
225  return false;
226  });";
227  }
228  }
229  return $code;
230  });
231  }
232 
241  final protected function checkComponent(Component $component)
242  {
243  $interfaces = $this->getComponentInterfaceName();
244  if (!is_array($interfaces)) {
245  throw new \LogicException(
246  "Expected array, found '" . (string) (null) . "' when rendering."
247  );
248  }
249 
250  foreach ($interfaces as $interface) {
251  if ($component instanceof $interface) {
252  return;
253  }
254  }
255  $ifs = implode(", ", $interfaces);
256  throw new \LogicException(
257  "Expected $ifs, found '" . get_class($component) . "' when rendering."
258  );
259  }
260 
268  abstract protected function getComponentInterfaceName();
269 
270 
271  private function getMyComponent()
272  {
273  $class = get_class($this);
274  if (isset(self::$component_storage[$class])) {
275  return self::$component_storage[$class];
276  }
277  $matches = array();
278  // Extract component
279  $re = "%ILIAS\\\\UI\\\\Implementation\\\\Component\\\\(\\w+)\\\\(\\w+)%";
280  preg_match($re, $class, $matches);
281  if (preg_match($re, $class, $matches) !== 1) {
282  throw new \LogicException("The Renderer needs to be located in ILIAS\\UI\\Implementation\\Component\\*.");
283  }
284  self::$component_storage[$class] = $matches[1];
285 
286  return self::$component_storage[$class];
287  }
288 }
Registry for resources required by rendered output like Javascript or CSS.
getTemplatePath($name)
Get the path to the template of this component.
$path
Definition: aliased.php:25
addTriggererOnLoadCode(Triggerer $triggerer)
Add onload-code for triggerer.
checkComponent(Component $component)
Check if a given component fits this renderer and throw if that is not the case. ...
$code
Definition: example_050.php:99
An entity that renders components to a string output.
trait JavaScriptBindable
Trait for components implementing JavaScriptBindable providing standard implementation.
if(!array_key_exists('StateId', $_REQUEST)) $id
toJS($key)
Add language var to client side (il.Language)
bindOnloadCode(JavaScriptBindable $component)
Bind the JavaScript onload-code.
getComponentInterfaceName()
Get the name of the component-interface this renderer is supposed to render.
This is how the factory for UI elements looks.
Definition: Factory.php:15
getOnLoadCode()
Get the currently bound on load code.
__construct(Factory $ui_factory, TemplateFactory $tpl_factory, \ilLanguage $lng, JavaScriptBinding $js_binding)
Component renderers must only depend on a UI-Factory and a Template Factory.
Provides methods to interface with javascript.
withAdditionalOnLoadCode(\Closure $binder)
Add some onload-code to the component instead of replacing the existing one.
getTriggeredSignals()
Get all triggered signals of this component.
language handling
getTemplate($name, $purge_unfilled_vars, $purge_unused_blocks)
Get template of component this renderer is made for.
registerResources(ResourceRegistry $registry)
Announce resources this renderer requires.null
Interface for a factory that provides templates.
$key
Definition: croninfo.php:18
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.