ILIAS  release_8 Revision v8.24
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
75 protected DataFactory $data_factory;
76 protected Refinery $refinery;
77
81 public function __construct(
82 DataFactory $data_factory,
83 Refinery $refinery
84 ) {
85 $this->data_factory = $data_factory;
86 $this->refinery = $refinery;
87 }
88
94 public function getValue()
95 {
96 return $this->value;
97 }
98
106 public function withValue($value)
107 {
108 $this->checkArg("value", $this->isClientSideValueOk($value), "Display value does not match input type.");
109 $clone = clone $this;
110 $clone->value = $value;
111 return $clone;
112 }
113
119 abstract protected function isClientSideValueOk($value): bool;
120
124 public function getError(): ?string
125 {
126 return $this->error;
127 }
128
132 public function withError(string $error)
133 {
134 $clone = clone $this;
135 $clone->setError($error);
136 return $clone;
137 }
138
142 private function setError(string $error): void
143 {
144 $this->error = $error;
145 }
146
151 {
152 $clone = clone $this;
153 $clone->setAdditionalTransformation($trafo);
154 return $clone;
155 }
156
163 protected function setAdditionalTransformation(Transformation $trafo): void
164 {
165 $this->operations[] = $trafo;
166 if ($this->content !== null) {
167 if (!$this->content->isError()) {
168 $this->content = $trafo->applyTo($this->content);
169 }
170 if ($this->content->isError()) {
171 $this->setError($this->content->error());
172 }
173 }
174 }
175
179 final public function getDedicatedName(): ?string
180 {
181 return $this->dedicated_name;
182 }
183
187 final public function withDedicatedName(string $dedicated_name): self
188 {
189 $clone = clone $this;
190 $clone->dedicated_name = $dedicated_name;
191 return $clone;
192 }
193
197 final public function getName(): ?string
198 {
199 return $this->name;
200 }
201
205 public function withNameFrom(NameSource $source, ?string $parent_name = null)
206 {
207 $clone = clone $this;
208 if ($source instanceof DynamicInputsNameSource) {
209 $clone->name = '';
210 } else {
211 $clone->name = ($parent_name !== null) ? $parent_name . '/' : '';
212 }
213 $clone->name .= ($clone->dedicated_name !== null)
214 ? $source->getNewDedicatedName($clone->dedicated_name)
215 : $source->getNewName();
216 return $clone;
217 }
218
225 public function withInput(InputData $input)
226 {
227 if ($this->getName() === null) {
228 throw new LogicException("Can only collect if input has a name.");
229 }
230
231
232 //TODO: Discuss, is this correct here. If there is no input contained in this post
233 //We assign null. Note that unset checkboxes are not contained in POST.
234 $value = $input->getOr($this->getName(), null);
235 // ATTENTION: There was a special case for the Filter Input Container here,
236 // which lead to #27909. The issue will most certainly appear again in. If
237 // you are the one debugging it and came here: Please don't put knowledge
238 // of the special case for the filter in this general class. Have a look
239 // into https://mantis.ilias.de/view.php?id=27909 for the according discussion.
240 $clone = $this->withValue($value);
241
242 $clone->content = $this->applyOperationsTo($clone->getValue());
243 if ($clone->content->isError()) {
244 $error = $clone->content->error();
245 if ($error instanceof \Exception) {
247 }
248 return $clone->withError("" . $error);
249 }
250
251 return $clone;
252 }
253
259 protected function applyOperationsTo($res): Result
260 {
261 $res = $this->data_factory->ok($res);
262 foreach ($this->getOperations() as $op) {
263 if ($res->isError()) {
264 return $res;
265 }
266 $res = $op->applyTo($res);
267 }
268
269 return $res;
270 }
271
277 protected function getOperations(): Generator
278 {
279 foreach ($this->operations as $op) {
280 yield $op;
281 }
282 }
283
287 public function getContent(): Result
288 {
289 if (is_null($this->content)) {
290 throw new LogicException("No content of this field has been evaluated yet. Seems withRequest was not called.");
291 }
292 return $this->content;
293 }
294}
Builds data types.
Definition: Factory.php:21
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:197
__construct(DataFactory $data_factory, Refinery $refinery)
Input constructor.
Definition: Input.php:81
withInput(InputData $input)
Collects the input, applies trafos on the input and returns a new input reflecting the data that was ...
Definition: Input.php:225
setError(string $error)
Set an error on this input.
Definition: Input.php:142
applyOperationsTo($res)
Applies the operations in this instance to the value.
Definition: Input.php:259
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:187
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Input.php:106
withAdditionalTransformation(Transformation $trafo)
Apply a transformation to the current or future content.
Definition: Input.php:150
getValue()
Get the value that is displayed in the input client side.
Definition: Input.php:94
withNameFrom(NameSource $source, ?string $parent_name=null)
Definition: Input.php:205
getOperations()
Get the operations that should be performed on the input.
Definition: Input.php:277
withError(string $error)
Get an input like this one, with a different error.
Definition: Input.php:132
getError()
The error of the input as used in HTML.
Definition: Input.php:124
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:163
getContent()
Get the current content of the input.
Definition: Input.php:287
Result $content
This is the current content of the input in the abstraction.
Definition: Input.php:68
ilErrorHandling $error
Definition: class.ilias.php:55
error(string $a_errmsg)
A result encapsulates a value or an error and simplifies the handling of those.
Definition: Result.php:15
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.
This describes commonalities between all inputs.
Definition: Input.php:49
withValue($value)
Get an input like this with another value displayed on the client side.
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.
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
$res
Definition: ltiservices.php:69
if($format !==null) $name
Definition: metadata.php:247
$source
Definition: metadata.php:93
Refinery Factory $refinery
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.