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}
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
__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.
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
getTemplatePath($name)
Get the path to the template of this component.
bindJavaScript(JavaScriptBindable $component)
Bind the component to JavaScript.
checkComponent(Component $component)
Check if a given component fits this renderer and throw \LogicError if that is not the case.
addTriggererOnLoadCode(Triggerer $triggerer)
Add onload-code for triggerer.
toJS($key)
Add language var to client side (il.Language)
getComponentInterfaceName()
Get the name of the component-interface this renderer is supposed to render.
bindOnloadCode(JavaScriptBindable $component)
Bind the JavaScript onload-code.
language handling
$key
Definition: croninfo.php:18
$code
Definition: example_050.php:99
if(!array_key_exists('StateId', $_REQUEST)) $id
A component is the most general form of an entity in the UI.
Definition: Component.php:14
Interface to be extended by components that have the possibility to bind to Javascript.
withAdditionalOnLoadCode(\Closure $binder)
Add some onload-code to the component instead of replacing the existing one.
getOnLoadCode()
Get the currently bound on load code.
getTriggeredSignals()
Get all triggered signals of this component.
This is how the factory for UI elements looks.
Definition: Factory.php:16
An entity that renders components to a string output.
Provides methods to interface with javascript.
Registry for resources required by rendered output like Javascript or CSS.
Interface for a factory that provides templates.
trait JavaScriptBindable
Trait for components implementing JavaScriptBindable providing standard implementation.