aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/DataFieldEntry.class.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/classes/DataFieldEntry.class.php
current code from svn, revision 62608
Diffstat (limited to 'lib/classes/DataFieldEntry.class.php')
-rw-r--r--lib/classes/DataFieldEntry.class.php584
1 files changed, 584 insertions, 0 deletions
diff --git a/lib/classes/DataFieldEntry.class.php b/lib/classes/DataFieldEntry.class.php
new file mode 100644
index 0000000..552cc79
--- /dev/null
+++ b/lib/classes/DataFieldEntry.class.php
@@ -0,0 +1,584 @@
+<?php
+/**
+ * DataFieldEntry.class.php
+ *
+ * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
+ * @author Marcus Lunzenauer <mlunzena@uos.de>
+ * @author Martin Gieseking <mgieseki@uos.de>
+ * @license GPL2 or any later version
+ */
+abstract class DataFieldEntry
+{
+ protected static $supported_types = [
+ 'bool',
+ 'textline',
+ 'textlinei18n',
+ 'textarea',
+ 'textareai18n',
+ 'textmarkup',
+ 'textmarkupi18n',
+ 'selectbox',
+ 'selectboxmultiple',
+ 'date',
+ 'time',
+ 'email',
+ 'phone',
+ 'radio',
+ 'combo',
+ 'link',
+ ];
+
+ protected $language = '';
+
+ /**
+ * Returns all supported datafield types.
+ *
+ * @param string Object type of the datafield.
+ * @return array of supported types
+ */
+ public static function getSupportedTypes($object_type = null)
+ {
+ // no i18n fields for descriptors
+ if (in_array($object_type, ['moduldeskriptor', 'modulteildeskriptor'])) {
+ return array_diff(
+ self::$supported_types,
+ [
+ 'textlinei18n',
+ 'textareai18n',
+ 'textmarkupi18n'
+ ]);
+ }
+ return self::$supported_types;
+ }
+
+ /**
+ * Returns the according class for a given type.
+ *
+ * @param String $type Type of the datafield
+ * @return String class name
+ */
+ private static function getClassForType($type)
+ {
+ if ($type === 'selectboxmultiple') {
+ return 'DataFieldSelectboxMultipleEntry';
+ }
+ return 'DataField' . ucfirst($type) . 'Entry';
+ }
+
+ /**
+ * Factory method that returns the appropriate datafield object
+ * for the given parameters.
+ *
+ * @param DataField $datafield Underlying structure
+ * @param String $rangeID Range id
+ * @param mixed $value Value of the entry
+ * @return DataFieldEntry instance of appropriate type
+ */
+ public static function createDataFieldEntry(DataField $datafield, $rangeID = '', $value = null)
+ {
+ $type = $datafield->type;
+ if (!in_array($type, self::getSupportedTypes())) {
+ return false;
+ }
+
+ $entry_class = self::getClassForType($type);
+ $entry = new $entry_class($datafield, $rangeID, $value);
+
+ return $entry;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $range_id
+ * @param unknown_type $object_type
+ * @param unknown_type $object_class_hint
+ * @return unknown
+ */
+ public static function getDataFieldEntries($range_id, $object_type = '', $object_class_hint = '')
+ {
+ if (!$range_id) {
+ return []; // we necessarily need a range ID
+ }
+ $parameters = [];
+ if(is_array($range_id)) {
+ // rangeID may be an array ("classic" rangeID and second rangeID used for user roles)
+ $secRangeID = $range_id[1];
+ $rangeID = $range_id[0]; // to keep compatible with following code
+ if('usersemdata' !== $object_type && 'roleinstdata' !== $object_type) {
+ $object_type = 'userinstrole';
+ }
+ $clause1 = "AND sec_range_id= :sec_range_id";
+ $parameters[':sec_range_id'] = $secRangeID;
+ } else {
+ $rangeID = $range_id;
+ }
+ if (!$object_type) {
+ $object_type = get_object_type($rangeID);
+ }
+
+ if($object_type) {
+ switch ($object_type) {
+ case 'sem':
+ if ($object_class_hint) {
+ $object_class = SeminarCategories::GetByTypeId($object_class_hint);
+ } else {
+ $object_class = SeminarCategories::GetBySeminarId($rangeID);
+ }
+
+ $clause2 = "object_class = :object_class OR object_class IS NULL";
+ $parameters[':object_class'] = (int) $object_class->id;
+ $clause3 = 'a.institut_id IS NULL OR a.institut_id IN (:institut_ids)';
+ $query = "SELECT institut_id FROM seminar_inst WHERE seminar_id = :seminar_id";
+ $statement = DBManager::get()->prepare($query);
+ $statement->execute([':seminar_id' => $rangeID]);
+ $parameters[':institut_ids'] = array_keys($statement->fetchGrouped());
+ break;
+ case 'inst':
+ case 'fak':
+
+ if ($object_class_hint) {
+ $object_class = $object_class_hint;
+ } else {
+ $query = "SELECT type FROM Institute WHERE Institut_id = ?";
+ $statement = DBManager::get()->prepare($query);
+ $statement->execute([$rangeID]);
+ $object_class = $statement->fetchColumn();
+ }
+ $object_type = "inst";
+ $clause2 = "object_class = :object_class OR object_class IS NULL";
+ $parameters[':object_class'] = (int) $object_class;
+ $clause3 = 'a.institut_id IS NULL OR a.institut_id = :institut_id';
+ $parameters[':institut_id'] = $rangeID;
+ break;
+ case 'roleinstdata': //hmm tja, vermutlich so
+ case 'moduldeskriptor':
+ case 'modulteildeskriptor':
+ case 'studycourse':
+ $clause2 = '1';
+ $clause3 = '1';
+ if (is_array($range_id) && isset($range_id[0])) {
+ $clause3 = 'a.institut_id IS NULL OR a.institut_id = :institut_id';
+ $parameters[':institut_id'] = $range_id[0];
+ }
+ break;
+ case 'user':
+ case 'userinstrole':
+ case 'usersemdata':
+ $object_class = is_object($GLOBALS['perm']) ? DataField::permMask($GLOBALS['perm']->get_perm($rangeID)) : 0;
+ $clause2 = "((object_class & :object_class) OR object_class IS NULL)";
+ $parameters[':object_class'] = (int) $object_class;
+
+ $clause3 = 'a.institut_id IS NULL OR a.institut_id IN (:institut_ids)';
+ $query = "SELECT institut_id FROM user_inst WHERE user_id = :user_id";
+ $statement = DBManager::get()->prepare($query);
+ $statement->execute([':user_id' => $rangeID]);
+ $parameters[':institut_ids'] = array_keys($statement->fetchGrouped());
+ break;
+ }
+ $query = "SELECT a.*, content
+ FROM datafields AS a
+ LEFT JOIN datafields_entries AS b
+ ON (a.datafield_id = b.datafield_id AND range_id = :range_id {$clause1})
+ WHERE object_type = :object_type AND ({$clause2}) AND ($clause3)
+ ORDER BY priority";
+ $parameters[':range_id'] = $rangeID;
+ $parameters[':object_type'] = $object_type;
+
+ $rs = DBManager::get()->prepare($query);
+ $rs->execute($parameters);
+
+ $entries = [];
+ while ($data = $rs->fetch(PDO::FETCH_ASSOC)) {
+ $datafield = DataField::buildExisting($data);
+ $entries[$data['datafield_id']] = DataFieldEntry::createDataFieldEntry($datafield, $range_id, $data['content']);
+ }
+ }
+ return $entries ?: [];
+ }
+
+ /**
+ * Removes all datafields from a given range_id (and secondary range
+ * id if passed as array)
+ *
+ * @param mixed $range_id Range id (or array with range id and secondary
+ * range id)
+ * @return int representing the number of deleted entries
+ */
+ public static function removeAll($range_id)
+ {
+ if (is_array($range_id)) {
+ list ($rangeID, $secRangeID) = $range_id;
+ } else {
+ $rangeID = $range_id;
+ $secRangeID = "";
+ }
+
+ if (!$rangeID && !$secRangeID) {
+ return;
+ }
+
+ $conditions = [];
+ $parameters = [];
+
+ if ($rangeID) {
+ $conditions[] = 'range_id = ?';
+ $parameters[] = $rangeID;
+ }
+ if ($secRangeID) {
+ $conditions[] = 'sec_range_id = ?';
+ $parameters[] = $secRangeID;
+ }
+
+ $where = implode(' AND ', $conditions);
+
+ return DatafieldEntryModel::deleteBySQL($where, $parameters);
+ }
+
+ public $value;
+ public $model;
+ public $rangeID;
+
+ /**
+ * Constructs this datafield
+ *
+ * @param DataField $datafield Underlying model
+ * @param mixed $range_id Range id (or array with range id and secondary
+ * range id)
+ * @param mixed $value Value
+ */
+ public function __construct(DataField $datafield = null, $rangeID = '', $value = null)
+ {
+ $this->model = $datafield;
+ $this->rangeID = $rangeID;
+ $this->value = isset($value) ? $value : $datafield->default_value;
+ }
+
+ /**
+ * Stores this datafield entry
+ *
+ * @return int representing the number of changed entries
+ */
+ public function store()
+ {
+ $id = [
+ $this->model->id,
+ (string) $this->getRangeID(),
+ (string) $this->getSecondRangeID(),
+ (string) $this->language
+ ];
+ $entry = new DatafieldEntryModel($id);
+ $entry->lang = (string) $this->language;
+
+ $old_value = $entry->content;
+ $entry->content = $this->getValue();
+
+ if ($entry->content == $this->model->default_value) {
+ $result = $entry->isNew() ? 0 : $entry->delete();
+ } else {
+ $result = $entry->store();
+ }
+
+ if ($result) {
+ NotificationCenter::postNotification('DatafieldDidUpdate', $this, [
+ 'changed' => $result,
+ 'old_value' => $old_value,
+ ]);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns whether this datafield is required
+ *
+ * @return bool indicating whether the datafield is required or not
+ */
+ public function isRequired()
+ {
+ return $this->model->is_required;
+ }
+
+ /**
+ * Returns the description of this datafield
+ *
+ * @return String containing the description
+ */
+ public function getDescription()
+ {
+ return $this->model->description;
+ }
+
+ /**
+ * Returns the type of this datafield
+ *
+ * @return string type of entry
+ */
+ public function getType()
+ {
+ $class = mb_strtolower(get_class($this));
+ return mb_substr($class, 9, mb_strpos($class, 'entry') - 9);
+ }
+
+ /**
+ * Returns the display/rendered value of this datafield
+ *
+ * @param bool $entities Should html entities be encoded (defaults to true)
+ * @return String containg the rendered value
+ */
+ public function getDisplayValue($entities = true)
+ {
+ if ($entities) {
+ return htmlReady($this->getValue());
+ }
+ return $this->getValue();
+ }
+
+ /**
+ * Returns the value of the datafield
+ *
+ * @return mixed containing the value
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Returns the name of the datafield
+ *
+ * @return String containing the name
+ */
+ public function getName()
+ {
+ return $this->model->name;
+ }
+
+ /**
+ * Returns the id of the datafield
+ *
+ * @return String containing the id
+ */
+ public function getId()
+ {
+ return $this->model->id;
+ }
+
+ /**
+ * Returns the according input elements as html for this datafield
+ *
+ * @param String $name Name prefix of the associated input
+ * @param Array $variables Additional variables
+ * @return String containing the required html
+ */
+ public function getHTML($name = '', $variables = [])
+ {
+ $variables = array_merge([
+ 'name' => $name,
+ 'entry' => $this,
+ 'model' => $this->model,
+ 'value' => $this->getValue(),
+ ], $variables);
+
+ return $GLOBALS['template_factory']->render('datafields/' . $this->template, $variables);
+ }
+
+ /**
+ * Sets the value
+ *
+ * @param mixed $value The value
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+ }
+
+ /**
+ * Sets the value from a post request
+ *
+ * @param mixed $submitted_value The value from request
+ */
+ public function setValueFromSubmit($submitted_value)
+ {
+ $this->setValue($submitted_value);
+ }
+
+ /**
+ * Sets the range id
+ *
+ * @param String $range_id Range id
+ */
+ public function setRangeID($range_id)
+ {
+ $this->rangeID = $range_id;
+ }
+
+ /**
+ * Sets the secondary range id
+ *
+ * @param String $sec_range_id Secondary range id
+ */
+ public function setSecondRangeID($sec_range_id)
+ {
+ $this->rangeID = [$this->getRangeID(), $sec_range_id];
+ }
+
+ /**
+ * Sets the prefered content language if this is an i18n datafield.
+ *
+ * @param string $language The prefered display language
+ */
+ public function setContentLanguage($language)
+ {
+ if (!Config::get()->CONTENT_LANGUAGES[$language]) {
+ throw new InvalidArgumentException('Language not configured.');
+ }
+
+ $languages = array_keys(Config::get()->CONTENT_LANGUAGES);
+ if ($language == reset($languages)) {
+ $language = '';
+ }
+
+ $this->language = $language;
+ }
+
+ /**
+ * Checks if datafield is empty (was not set)
+ *
+ * @return bool true if empty, else false
+ */
+ public function isEmpty()
+ {
+ return $this->getValue() == '';
+ }
+
+ /**
+ * Returns whether the datafield contents are valid
+ *
+ * @return boolean indicating whether the datafield contents are valid
+ */
+ public function isValid()
+ {
+ return trim($this->getValue())
+ || !$this->model->is_required;
+ }
+
+ /**
+ * Returns the number of html fields this datafield uses for input.
+ *
+ * @return int representing the number of html fields
+ */
+ public function numberOfHTMLFields()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the range id
+ *
+ * @return String containing the range id
+ */
+ public function getRangeID()
+ {
+ if (is_array($this->rangeID)) {
+ return reset($this->rangeID);
+ }
+ return $this->rangeID;
+ }
+
+ /**
+ * Returns the secondary range id
+ *
+ * @return String containing the secondary range id
+ */
+ public function getSecondRangeID()
+ {
+ if (is_array($this->rangeID)) {
+ list (, $secRangeID) = $this->rangeID;
+ return $secRangeID;
+ }
+ return '';
+ }
+
+ /**
+ * Returns whether the datafield is visible for the current user
+ *
+ * @param String $perm Permissions to test against (optional, default to
+ * the current user's permissions)
+ * @param bool $test_ownership Defines whether the ownership of the field
+ * should be taken into account; a field may
+ * be invisible for a user according to the
+ * permissions but since the datafield belongs
+ * to the user, it is visible.
+ * @return boolean indicating whether the datafield is visible
+ */
+ public function isVisible($perm = null, $test_ownership = true)
+ {
+ if ($test_ownership) {
+ return $this->model->accessAllowed($perm,
+ $GLOBALS['user']->id,
+ $this->getRangeID());
+ }
+ return $this->model->accessAllowed($perm);
+ }
+
+ /**
+ * Returns whether the datafield is editable for the current user
+ *
+ * @param mixed $perms Perms to test against (optional, defaults to logged
+ * in user's perms)
+ * @return boolean indicating whether the datafield is editable
+ */
+ public function isEditable($perms = null)
+ {
+ return $this->model->editAllowed($perms ?: $GLOBALS['perm']->get_perm());
+ }
+
+ /**
+ * Returns a human readable string describing the view permissions
+ *
+ * @return String containing the descriptons of the view permissions
+ */
+ public function getPermsDescription()
+ {
+ if ($this->model->view_perms === 'all') {
+ return _('sichtbar für alle');
+ }
+ return sprintf(_('sichtbar nur für Sie und alle %s'),
+ $this->prettyPrintViewPerms());
+ }
+
+ /**
+ * Generates a full status description depending on the the perms
+ *
+ * @return string
+ */
+ protected function prettyPrintViewPerms()
+ {
+ switch ($this->model->view_perms) {
+ case 'all':
+ return _('alle');
+ break;
+ case 'root':
+ return _('Systemadministrator/-innen');
+ break;
+ case 'admin':
+ return _('Administrator/-innen');
+ break;
+ case 'dozent':
+ return _('Lehrenden');
+ break;
+ case 'tutor':
+ return _('Tutor/-innen');
+ break;
+ case 'autor':
+ return _('Studierenden');
+ break;
+ case 'user':
+ return _('Nutzer/-innen');
+ break;
+ }
+ return '';
+ }
+
+}