diff options
| author | Rasmus Fuhse <fuhse@data-quest.de> | 2022-06-13 08:55:14 +0000 |
|---|---|---|
| committer | Rasmus Fuhse <fuhse@data-quest.de> | 2022-06-13 08:55:14 +0000 |
| commit | 3fb174cb7d12d3b5c354683ce808937fd5493381 (patch) | |
| tree | ea3d73814c577f4d2e58a8ec693152089705f49c /lib/classes/forms/Input.php | |
| parent | b08012913fae1f5fd996e39e792a921cb506e3b4 (diff) | |
Resolve "Formularbaukasten und Ankündigungsbearbeitung"
Closes #837
Merge request studip/studip!455
Diffstat (limited to 'lib/classes/forms/Input.php')
| -rw-r--r-- | lib/classes/forms/Input.php | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/lib/classes/forms/Input.php b/lib/classes/forms/Input.php new file mode 100644 index 0000000..3018a5b --- /dev/null +++ b/lib/classes/forms/Input.php @@ -0,0 +1,271 @@ +<?php + +namespace Studip\Forms; + +abstract class Input +{ + protected $title = null; + protected $value = null; + protected $attributes = []; + protected $name = null; + protected $parent = null; + public $mapper = null; + public $store = null; + public $if = null; + public $permission = true; + public $required = false; + + /** + * A static constructor. Returns a new Input-object. + * @param string $name + * @param string $title + * @param mixed $value + * @param array $attributes + * @return static + */ + public static function create($name, $title, $value, array $attributes = []) + { + return new static($name, $title, $value, $attributes); + } + + /** + * This static method returns fielddata as an array from metadata of a database-field. + * This array will be used internally to create the best fitting Input object to the + * database field. + * @param array $meta + * @param $object: most likely a SimpleORMap object. + * @return array + */ + public static function getFielddataFromMeta($meta, $object) : array + { + $bracket_pos = strpos($meta['type'], '('); + if ($bracket_pos !== false) { + $type = substr($meta['type'], 0, $bracket_pos); + } else { + $type = $meta['type']; + } + $fielddata = []; + switch ($type) { + case 'enum': + $fielddata['type'] = 'select'; + preg_match("/\((.*)\)/", $meta['type'], $matches); + $matches = explode(',', $matches[1]); + foreach ($matches as $key => $status) { + $matches[$key] = substr($status, 1, strlen($status) - 2); + } + $fielddata['attributes']['options'] = $matches; + break; + case 'tinyint': + preg_match("/\((.*)\)/", $meta['type'], $matches); + if ($matches[1] == 1) { + $fielddata['type'] = 'checkbox'; + break; + } + case 'integer': + $fielddata['type'] = 'number'; + break; + case 'text': + if ($object->isI18nField($meta['name'])) { + $fielddata['type'] = 'i18n_textarea'; + } else { + $fielddata['type'] = 'textarea'; + } + break; + default: + if ($object->isI18nField($meta['name'])) { + $fielddata['type'] = 'i18n_text'; + } else { + $fielddata['type'] = 'text'; + } + } + return $fielddata; + } + + /** + * Constructor of the Input class. + * @param $name + * @param $title + * @param $value + * @param $attributes + */ + public function __construct($name, $title, $value, array $attributes = []) + { + $this->name = $name; + $this->title = $title; + $this->value = $value; + $this->attributes = $attributes; + } + + /** + * Sets the parent of this Input object. Usually this is done automatically by the framework in the moment that + * the input is initialized in the Form object. So you usually don't need to call this method on your own. + * @param Part $parent + * @return $this + */ + public function setParent(Part $parent) + { + $this->parent = $parent; + return $this; + } + + /** + * Returns the parent of this Input if there is already one. + * @return null|Part + */ + public function getParent() + { + return $this->parent; + } + + public function dataMapper($value) + { + return $value; + } + + /** + * Returns the name of the given input. Also have a look at the method getAllInputNames if you want to + * provide multiple input elements (like in i18n input fields) within one virtual input. In that case + * this getName method returns the main-input name like the attribute in the SORM class. + * @return null + */ + public function getName() + { + return $this->name; + } + + /** + * Returns the value of this input. + * @return null + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns an array with all names of all inputs that this Input-object has. Normally this is just one + * name because there is only one input. But if you think of i18n-inputs there are possibly more + * textareas - one for each language. In that case this function would return all names of all inputs that + * are present. + * @return string[] + */ + public function getAllInputNames() + { + return [$this->getName()]; + } + + /** + * Renders the Input but maybe encapsulated in a template that is displayed only if a condition is true. + * This is helpful for the if-attribute on the Input like in setIfCondition. + * @return string + */ + public function renderWithCondition() + { + if (!$this->permission) { + return ''; + } + $html = $this->render(); + if (!trim($html)) { + return ''; + } + if ($this->if !== null) { + $html = '<template v-if="' . htmlReady($this->if) . '">' . $html . '</template>'; + } + return $html; + } + + /** + * This renders the Input. + * @return string + */ + abstract public function render(); + + /** + * Returns the context-object which is usually a SimpleORMap object. + * @return null|\SimpleORMap + */ + public function getContextObject() + { + if ($this->getParent()) { + return $this->getParent()->getContextObject(); + } + return null; + } + + /** + * Sets a special mapper-function to turn the request-values into the real values for the database. + * @param callable $callback + * @return $this + */ + public function setMapper(Callable $callback) + { + $this->mapper = $callback; + return $this; + } + + /** + * Sets the storing function. This would override the normal storing-function that just sets the value + * of a given context object like a SORM object. + * @param callable $store + * @return $this + */ + public function setStoringFunction(Callable $store) + { + $this->store = $store; + return $this; + } + + /** + * Sets a condition to display this input. The condition is a javascript condition which is used by vue to + * hide the input if the condition is not satisfies. + * @param string $if + * @return $this + */ + public function setIfCondition($if) + { + $this->if = $if; + return $this; + } + + /** + * Set if the user is able to see and edit this input + * @param boolean $if + * @return $this + */ + public function setPermission(bool $permission) + { + $this->permission = $permission; + return $this; + } + + /** + * Marks the input as a required field. + * @param $required + * @return $this + */ + public function setRequired($required = true) + { + $this->required = $required; + return $this; + } + + /** + * Returns the values from the request. Normally this is \Request::get, but special Input-classes could also + * return arrays or objects. + * @return string|null + */ + public function getRequestValue() + { + return \Request::get($this->name); + } + + protected function extractOptionsFromAttributes(array &$attributes) + { + $options = null; + if (isset($attributes['options'])) { + $options = $attributes['options']; + unset($attributes['options']); + } + return $options; + } +} |
