ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
Input.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use ILIAS\Data\Factory as DataFactory;
26use ILIAS\Refinery\Factory as Refinery;
29use ILIAS\UI\Implementation\Component\ComponentHelper;
34use LogicException;
35use Generator;
36use InvalidArgumentException;
38
42abstract class Input implements InputInternal
43{
44 use ComponentHelper;
45
52 protected $value = null;
53
57 protected ?string $error = null;
58
59 private ?string $name = null;
60
61 protected ?string $dedicated_name = null;
62
68 protected ?Result $content = null;
69
73 protected array $operations = [];
74
78 public function __construct(
79 protected DataFactory $data_factory,
80 protected Refinery $refinery,
81 ) {
82 }
83
89 public function getValue()
90 {
91 return $this->value;
92 }
93
101 public function withValue($value): self
102 {
103 $this->checkArg("value", $this->isClientSideValueOk($value), "Display value does not match input type.");
104 $clone = clone $this;
105 $clone->value = $value;
106 return $clone;
107 }
108
114 abstract protected function isClientSideValueOk($value): bool;
115
119 public function getError(): ?string
120 {
121 return $this->error;
122 }
123
127 public function withError(string $error): self
128 {
129 $clone = clone $this;
130 $clone->setError($error);
131 return $clone;
132 }
133
137 private function setError(string $error): void
138 {
139 $this->error = $error;
140 }
141
145 public function withAdditionalTransformation(Transformation $trafo): self
146 {
147 $clone = clone $this;
148 $clone->setAdditionalTransformation($trafo);
149 return $clone;
150 }
151
158 protected function setAdditionalTransformation(Transformation $trafo): void
159 {
160 $this->operations[] = $trafo;
161 if ($this->content !== null) {
162 if (!$this->content->isError()) {
163 $this->content = $trafo->applyTo($this->content);
164 }
165 if ($this->content->isError()) {
166 $this->setError($this->content->error());
167 }
168 }
169 }
170
174 final public function getDedicatedName(): ?string
175 {
176 return $this->dedicated_name;
177 }
178
182 final public function withDedicatedName(string $dedicated_name): self
183 {
184 $clone = clone $this;
185 $clone->dedicated_name = $dedicated_name;
186 return $clone;
187 }
188
192 final public function getName(): ?string
193 {
194 return $this->name;
195 }
196
200 public function withNameFrom(NameSource $source, ?string $parent_name = null): self
201 {
202 $clone = clone $this;
203 if ($source instanceof DynamicInputsNameSource) {
204 $clone->name = '';
205 } else {
206 $clone->name = ($parent_name !== null) ? $parent_name . '/' : '';
207 }
208 $clone->name .= ($clone->dedicated_name !== null)
209 ? $source->getNewDedicatedName($clone->dedicated_name)
210 : $source->getNewName();
211 return $clone;
212 }
213
220 public function withInput(InputData $input): self
221 {
222 if ($this->getName() === null) {
223 throw new LogicException("Can only collect if input has a name.");
224 }
225
226
227 //TODO: Discuss, is this correct here. If there is no input contained in this post
228 //We assign null. Note that unset checkboxes are not contained in POST.
229 $value = $input->getOr($this->getName(), null);
230 // ATTENTION: There was a special case for the Filter Input Container here,
231 // which lead to #27909. The issue will most certainly appear again in. If
232 // you are the one debugging it and came here: Please don't put knowledge
233 // of the special case for the filter in this general class. Have a look
234 // into https://mantis.ilias.de/view.php?id=27909 for the according discussion.
235 $clone = $this->withValue($value);
236
237 $clone->content = $this->applyOperationsTo($clone->getValue());
238 if ($clone->content->isError()) {
239 $error = $clone->content->error();
240 if ($error instanceof \Exception) {
242 }
243 return $clone->withError("" . $error);
244 }
245
246 return $clone;
247 }
248
254 protected function applyOperationsTo($res): Result
255 {
256 $res = $this->data_factory->ok($res);
257 foreach ($this->getOperations() as $op) {
258 if ($res->isError()) {
259 return $res;
260 }
261 $res = $op->applyTo($res);
262 }
263
264 return $res;
265 }
266
272 protected function getOperations(): Generator
273 {
274 foreach ($this->operations as $op) {
275 yield $op;
276 }
277 }
278
282 public function getContent(): Result
283 {
284 if (is_null($this->content)) {
285 throw new LogicException("No content of this field has been evaluated yet. Seems withRequest was not called.");
286 }
287 return $this->content;
288 }
289}
Builds data types.
Definition: Factory.php:36
Other than the FormInputNameSource this name source is for inputs that can be dynamically added multi...
getName()
The name of the input as used in HTML.
Definition: Input.php:192
withInput(InputData $input)
Collects the input, applies trafos on the input and returns a new input reflecting the data that was ...
Definition: Input.php:220
setError(string $error)
Set an error on this input.
Definition: Input.php:137
applyOperationsTo($res)
Applies the operations in this instance to the value.
Definition: Input.php:254
withDedicatedName(string $dedicated_name)
Sets an optional dedicated name for this input which is used in the NAME attribute of the rendered in...
Definition: Input.php:182
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Input.php:101
withAdditionalTransformation(Transformation $trafo)
Apply a transformation to the current or future content.
Definition: Input.php:145
getValue()
Get the value that is displayed in the input client side.
Definition: Input.php:89
withNameFrom(NameSource $source, ?string $parent_name=null)
Definition: Input.php:200
getOperations()
Get the operations that should be performed on the input.
Definition: Input.php:272
__construct(protected DataFactory $data_factory, protected Refinery $refinery,)
Input constructor.
Definition: Input.php:78
withError(string $error)
Get an input like this one, with a different error.
Definition: Input.php:127
getError()
The error of the input as used in HTML.
Definition: Input.php:119
isClientSideValueOk($value)
Check if the value is good to be displayed client side.
setAdditionalTransformation(Transformation $trafo)
Apply a transformation to the current or future content.
Definition: Input.php:158
getContent()
Get the current content of the input.
Definition: Input.php:282
Result $content
This is the current content of the input in the abstraction.
Definition: Input.php:68
ilErrorHandling $error
Definition: class.ilias.php:69
error(string $a_errmsg)
A result encapsulates a value or an error and simplifies the handling of those.
Definition: Result.php:29
A constraint encodes some resrtictions on values.
Definition: Constraint.php:32
A transformation is a function from one datatype to another.
applyTo(Result $result)
Perform the transformation and reify possible failures.
Describes how Input-Elements want to interact with posted data.
Definition: InputData.php:30
getOr(string $name, $default)
Get a named value from the data and fallback to default if that name does not exist.
This describes commonalities between all inputs.
Definition: Input.php:47
withValue($value)
Get an input like this with another value displayed on the client side.
Describes the interface of inputs that is used for internal processing of data from the client.
Describes a source for input names.
Definition: NameSource.php:27
getNewName()
Generates a unique name on every call.
$res
Definition: ltiservices.php:69
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setError(string $error)
This setter will be used by withInput() to set possible errors.
trait JavaScriptBindable
Trait for components implementing JavaScriptBindable providing standard implementation.