diff options
| author | Jan-Hendrik Willms <tleilax+github@gmail.com> | 2021-07-22 16:07:19 +0200 |
|---|---|---|
| committer | Jan-Hendrik Willms <tleilax+github@gmail.com> | 2021-07-22 16:19:12 +0200 |
| commit | a3da1483a9e689846179159355badfec8073dbec (patch) | |
| tree | 770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/elearning | |
current code from svn, revision 62608
Diffstat (limited to 'lib/elearning')
39 files changed, 7666 insertions, 0 deletions
diff --git a/lib/elearning/ConnectedCMS.class.php b/lib/elearning/ConnectedCMS.class.php new file mode 100644 index 0000000..7245761 --- /dev/null +++ b/lib/elearning/ConnectedCMS.class.php @@ -0,0 +1,458 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/** +* main-class for connected systems +* +* This class contains the main methods of the elearning-interface to connect content-management-systems. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ConnectedCMS +* @package ELearning-Interface +*/ +class ConnectedCMS +{ + var $title; + + var $is_active; + var $cms_type; + var $name; + var $ABSOLUTE_PATH_ELEARNINGMODULES; + var $ABSOLUTE_PATH_SOAP; + var $RELATIVE_PATH_DB_CLASSES; + var $CLASS_PREFIX; + var $auth_necessary; + var $USER_AUTO_CREATE; + var $USER_PREFIX; + var $target_file; + var $logo_file; + var $DB_ELEARNINGMODULES_HOST; + var $DB_ELEARNINGMODULES_USER; + var $DB_ELEARNINGMODULES_PASSWORD; + var $DB_ELEARNINGMODULES_DATABASE; + var $db_classes; + var $soap_data; + var $soap_client; + var $types; + var $roles; + + var $db; + var $db_class; + var $link; + var $user; + var $permissions; + var $content_module; + /** + * constructor + * + * init class. don't call directly but by extending class ("new Ilias3ConnectedCMS($cms)" for example), except for basic administration + * @access + * @param string $cms system-type + */ + public function __construct($cms = "") + { + $this->cms_type = $cms; + if (Config::get()->getValue("ELEARNING_INTERFACE_{$this->cms}_ACTIVE")) { + $this->is_active = true; + } + else { + $this->is_active = false; + } + $this->init($cms); + } + + /** + * init settings + * + * gets settings from config-array and initializes db + * @access private + * @param string $cms system-type + */ + public function init($cms) + { + global $ELEARNING_INTERFACE_MODULES; + $this->name = $ELEARNING_INTERFACE_MODULES[$cms]["name"]; + $this->ABSOLUTE_PATH_ELEARNINGMODULES = $ELEARNING_INTERFACE_MODULES[$cms]["ABSOLUTE_PATH_ELEARNINGMODULES"]; + $this->ABSOLUTE_PATH_SOAP = $ELEARNING_INTERFACE_MODULES[$cms]["ABSOLUTE_PATH_SOAP"]; + if (isset($ELEARNING_INTERFACE_MODULES[$cms]["RELATIVE_PATH_DB_CLASSES"])) + { + $this->RELATIVE_PATH_DB_CLASSES = $ELEARNING_INTERFACE_MODULES[$cms]["RELATIVE_PATH_DB_CLASSES"]; + $this->db_classes = $ELEARNING_INTERFACE_MODULES[$cms]["db_classes"]; + } + else { + $this->RELATIVE_PATH_DB_CLASSES = false; + } + $this->CLASS_PREFIX = $ELEARNING_INTERFACE_MODULES[$cms]["CLASS_PREFIX"]; + $this->auth_necessary = $ELEARNING_INTERFACE_MODULES[$cms]["auth_necessary"]; + $this->USER_AUTO_CREATE = $ELEARNING_INTERFACE_MODULES[$cms]["USER_AUTO_CREATE"]; + $this->USER_PREFIX = $ELEARNING_INTERFACE_MODULES[$cms]["USER_PREFIX"]; + $this->target_file = $ELEARNING_INTERFACE_MODULES[$cms]["target_file"]; + $this->logo_file = $ELEARNING_INTERFACE_MODULES[$cms]["logo_file"]; + $this->DB_ELEARNINGMODULES_HOST = $ELEARNING_INTERFACE_MODULES[$cms]["DB_ELEARNINGMODULES_HOST"]; + $this->DB_ELEARNINGMODULES_USER = $ELEARNING_INTERFACE_MODULES[$cms]["DB_ELEARNINGMODULES_USER"]; + $this->DB_ELEARNINGMODULES_PASSWORD = $ELEARNING_INTERFACE_MODULES[$cms]["DB_ELEARNINGMODULES_PASSWORD"]; + $this->DB_ELEARNINGMODULES_DATABASE = $ELEARNING_INTERFACE_MODULES[$cms]["DB_ELEARNINGMODULES_DATABASE"]; + if ($this->DB_ELEARNINGMODULES_HOST != "") { + $this->db = new DB_ELearning($this->cms_type); + } + $this->soap_data = $ELEARNING_INTERFACE_MODULES[$cms]["soap_data"]; + $this->types = $ELEARNING_INTERFACE_MODULES[$cms]["types"]; + $this->roles = $ELEARNING_INTERFACE_MODULES[$cms]["roles"]; + } + + /** + * init subclasses + * + * loads classes for user-functions + * @access public + */ + public function initSubclasses() + { + if ($this->auth_necessary) + { + require_once($this->CLASS_PREFIX . "ConnectedUser.class.php"); + $classname = $this->CLASS_PREFIX . "ConnectedUser"; + $this->user = new $classname($this->cms_type); + require_once($this->CLASS_PREFIX . "ConnectedPermissions.class.php"); + $classname = $this->CLASS_PREFIX . "ConnectedPermissions"; + $this->permissions = new $classname($this->cms_type); + } + require_once($this->CLASS_PREFIX . "ConnectedLink.class.php"); + $classname = $this->CLASS_PREFIX . "ConnectedLink"; + $this->link = new $classname($this->cms_type); + } + + /** + * get connection status + * + * checks settings + * @access public + * @param string $cms system-type + * @return array messages + */ + public function getConnectionStatus($cms = "") + { + if ($this->cms_type == "") + { + $this->init($cms); + } + // check connection to CMS + + if (!$this->auth_necessary) { + $msg["auth"]["info"] = sprintf(_("Eine Authentifizierung ist für dieses System nicht vorgesehen.")); + } + + // check for SOAP-Interface + if (in_array($this->CLASS_PREFIX, ['Ilias3','Ilias4','Ilias5'])) + { + $check = @get_headers($this->ABSOLUTE_PATH_ELEARNINGMODULES . 'login.php'); + if (strpos($check[0], '200') === false) { + $msg["path"]["error"] = sprintf(_("Die Verbindung zum System \"%s\" konnte nicht hergestellt werden. Der Pfad \"$this->ABSOLUTE_PATH_ELEARNINGMODULES\" ist ungültig."), $this->name); + + } else { + $msg["path"]["info"] = sprintf(_("Die %s-Installation wurde gefunden."), $this->name); + } + + if (!Config::get()->SOAP_ENABLE) { + $msg["soap"]["error"] = sprintf(_("Das Stud.IP-Modul für die SOAP-Schnittstelle ist nicht aktiviert. Ändern Sie den entsprechenden Eintrag in der Konfigurationsdatei \"local.inc\".")); + } + elseif (! is_array($this->soap_data)) { + $msg["soap"]["error"] = sprintf(_("Die SOAP-Verbindungsdaten sind für dieses System nicht gesetzt. Ergänzen Sie die Einstellungen für dieses Systems um den Eintrag \"soap_data\" in der Konfigurationsdatei \"local.inc\".")); + } + else + { + $this->soap_client = new StudipSoapClient($this->ABSOLUTE_PATH_SOAP); + $msg["soap"]["info"] = sprintf(_("Das SOAP-Modul ist aktiv.")); + } + } else { + $file = fopen($this->ABSOLUTE_PATH_ELEARNINGMODULES."", "r"); + if ($file == false) + { + $msg["path"]["error"] = sprintf(_("Die Verbindung zum System \"%s\" konnte nicht hergestellt werden. Der Pfad \"$this->ABSOLUTE_PATH_ELEARNINGMODULES\" ist ungültig."), $this->name); + } + else + { + fclose($file); + $msg["path"]["info"] = sprintf(_("Die %s-Installation wurde gefunden."), $this->name); + + // check if target-file exists + $file = fopen($this->ABSOLUTE_PATH_ELEARNINGMODULES.$this->target_file, "r"); + if ($file == false) + { + $msg["auth"]["error"] = sprintf(_("Die Zieldatei \"%s\" liegt nicht im Hauptverzeichnis der %s-Installation."), $this->target_file, $this->name); + } + else + { + fclose($file); + $msg["auth"]["info"] = sprintf(_("Die Zieldatei ist vorhanden.")); + } + } + } + + $el_path = $GLOBALS['STUDIP_BASE_PATH'] . '/lib/elearning'; + // check if needed classes exist + if (!file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedUser.class.php") && ($this->auth_necessary)) { + $msg["class_user"]["error"] .= sprintf(_("Die Datei \"%s\" existiert nicht."), $el_path."/" . $this->CLASS_PREFIX . "ConnectedUser.class.php"); + } + if (!file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedPermissions.class.php") && ($this->auth_necessary)) { + $msg["class_perm"]["error"] .= sprintf(_("Die Datei \"%s\" existiert nicht."), $el_path."/" . $this->CLASS_PREFIX . "ConnectedPermissions.class.php"); + } + if (!file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedLink.class.php")) { + $msg["class_link"]["error"] .= sprintf(_("Die Datei \"%s\" existiert nicht."), $el_path."/" . $this->CLASS_PREFIX . "ConnectedLink.class.php"); + } + if (!file_exists($el_path."/" . $this->CLASS_PREFIX . "ContentModule.class.php")) { + $msg["class_content"]["error"] .= sprintf(_("Die Datei \"%s\" existiert nicht."), $el_path."/" . $this->CLASS_PREFIX . "ContentModule.class.php"); + } + if (!file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedCMS.class.php")) { + $msg["class_cms"]["error"] .= sprintf(_("Die Datei \"%s\" existiert nicht."), $el_path."/" . $this->CLASS_PREFIX . "ConnectedCMS.class.php"); + } + if (file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedCMS.class.php") && + (file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedUser.class.php") || (!$this->auth_necessary)) && + (file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedPermissions.class.php") || (!$this->auth_necessary)) && + file_exists($el_path."/" . $this->CLASS_PREFIX . "ConnectedLink.class.php") && + file_exists($el_path."/" . $this->CLASS_PREFIX . "ContentModule.class.php")) + { + require_once ($el_path."/" . $this->CLASS_PREFIX . "ConnectedCMS.class.php"); + $msg["classes"]["info"] .= sprintf(_("Die Klassen der Schnittstelle zum System \"%s\" wurden geladen."), $this->name); + } + else + { + $msg["classes"]["error"] .= sprintf(_("Die Klassen der Schnittstelle zum System \"%s\" wurden nicht geladen."), $this->name); + } + + return $msg; + } + + /** + * get preferences + * + * shows additional settings. can be overwritten by subclass. + * @access public + */ + public function getPreferences() + { + if ($this->types != "") + { + echo "<b>" . _("Angebundene Lernmodul-Typen: ") . "</b>"; + echo "<br>\n"; + foreach($this->types as $key => $type) + echo Icon::create($type["icon"], Icon::ROLE_INACTIVE)->asImg() . $type["name"] . " ($key)<br>\n"; + echo "<br>\n"; + } + + if ($this->db_classes != "") + { + echo "<b>" . _("Verwendete DB-Zugriffs-Klassen: ") . "</b>"; + echo "<br>\n"; + foreach($this->db_classes as $key => $type) { + echo $type["file"] . " ($key)<br>\n"; + } + echo "<br>\n"; + } + } + + /** + * create new instance of subclass content-module with given values + * + * creates new instance of subclass content-module with given values + * @access public + * @param array $data module-data + * @param boolean $is_connected is module connected to seminar? + */ + public function setContentModule($data, $is_connected = false) + { + global $current_module; + $current_module = $data["ref_id"]; + + require_once($this->CLASS_PREFIX . "ContentModule.class.php"); + $classname = $this->CLASS_PREFIX . "ContentModule"; + + $this->content_module[$current_module] = new $classname("", $data["type"], $this->cms_type); + $this->content_module[$current_module]->setId($data["ref_id"]); + $this->content_module[$current_module]->setTitle($data["title"]); + $this->content_module[$current_module]->setDescription($data["description"]); + $this->content_module[$current_module]->setConnectionType($is_connected); + } + + /** + * create new instance of subclass content-module + * + * creates new instance of subclass content-module + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param boolean $is_connected is module connected to seminar? + */ + public function newContentModule($module_id, $module_type, $is_connected = false) + { + global $current_module; + $current_module = $module_id; + + require_once($this->CLASS_PREFIX . "ContentModule.class.php"); + $classname = $this->CLASS_PREFIX . "ContentModule"; + + if ($is_connected == false) + { + $this->content_module[$module_id] = new $classname("", $module_type, $this->cms_type); + $this->content_module[$module_id]->setId($module_id); + } + else + { + $this->content_module[$module_id] = new $classname($module_id, $module_type, $this->cms_type); + } + + $this->content_module[$module_id]->setConnectionType($is_connected); + } + + /** + * get name of cms + * + * returns name of cms + * @access public + * @return string name + */ + public function getName() + { + return $this->name; + } + + /** + * get type of cms + * + * returns type of cms + * @access public + * @return string type + */ + public function getCMSType() + { + return $this->cms_type; + } + + /** + * get path of cms + * + * returns path of cms + * @access public + * @return string path + */ + public function getAbsolutePath() + { + return $this->ABSOLUTE_PATH_ELEARNINGMODULES; + } + + /** + * get target file of cms + * + * returns target file of cms + * @access public + * @return string target file + */ + public function getTargetFile() + { + return $this->target_file; + } + + /** + * get class prefix + * + * returns class prefix + * @access public + * @return string class prefix + */ + public function getClassPrefix() + { + return $this->CLASS_PREFIX; + } + + /** + * get authentification-setting + * + * returns true, if authentification is necessary + * @access public + * @return boolean authentification-setting + */ + public function isAuthNecessary() + { + return $this->auth_necessary; + } + + /** + * get active-setting + * + * returns true, if cms is active + * @access public + * @return boolean active-setting + function isActive($cms = "") + { + return $this->is_active; + } + */ + + /** + * get user prefix + * + * returns user prefix + * @access public + * @return string user prefix + */ + public function getUserPrefix() + { + return $this->USER_PREFIX; + } + + /** + * get logo-image + * + * returns logo-image + * @access public + * @return string logo-image + */ + public function getLogo() + { + return "<img src=\"" . $this->logo_file . "\">"; + } + + /** + * get user modules + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + public function getUserContentModules() + { + return false; + } + + /** + * search modules + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + public function searchContentModules($key) + { + return false; + } + + /** + * terminate + * + * dummy-method. returns false. can be overwritten by subclass. + * @access public + * @return boolean returns false + */ + public function terminate() + { + return false; + } + + public function deleteConnectedModules($object_id){ + return ObjectConnections::DeleteAllConnections($object_id, $this->cms_type); + } +}
\ No newline at end of file diff --git a/lib/elearning/ConnectedLink.class.php b/lib/elearning/ConnectedLink.class.php new file mode 100644 index 0000000..2be5a12 --- /dev/null +++ b/lib/elearning/ConnectedLink.class.php @@ -0,0 +1,129 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/** +* class to generate links to connected systems +* +* This class contains methods to generate links to connected content-management-systems. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ConnectedLink +* @package ELearning-Interface +*/ + +use Studip\Button, Studip\LinkButton; + +class ConnectedLink +{ + var $cms_type; + var $cms_link; + /** + * constructor + * + * init class. don't call directly, class is loaded by ConnectedCMS. + * @access public + * @param string $cms system-type + */ + function __construct($cms) + { + global $ELEARNING_INTERFACE_MODULES; + + $this->cms_type = $cms; + $this->cms_link = $ELEARNING_INTERFACE_MODULES[$cms]["ABSOLUTE_PATH_ELEARNINGMODULES"] . $ELEARNING_INTERFACE_MODULES[$cms]["target_file"]; + } + + /** + * get link to create new account + * + * returns link to create new user-account + * @access public + * @return string html-code + */ + function getNewAccountLink() + { + global $connected_cms, $cms_select, $current_module; + + $output .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">\n"; + $output .= CSRFProtection::tokenTag(); + $output .= "<input type=\"HIDDEN\" name=\"view\" value=\"" . Request::option('view') . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"ref_id\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getId()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_type\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"search_key\" value=\"" . htmlReady(Request::get('search_key')) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"cms_select\" value=\"" . htmlReady($cms_select) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"new_account_cms\" value=\"" . htmlReady($this->cms_type) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"new_account_step\" value=\"0\">\n"; + $output .= Button::createAccept(_('Starten'), 'start'); + $output .= "</form>"; + return $output; + } + + /** + * get module-links for user + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function getUserModuleLinks() + { + return false; + } + + /** + * get module-links for admin + * + * returns links to remove or add module to object + * @access public + * @return string html-code + */ + function getAdminModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + $output .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">\n"; + $output .= CSRFProtection::tokenTag(); + $output .= "<input type=\"HIDDEN\" name=\"view\" value=\"" . htmlReady($view) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"search_key\" value=\"" . htmlReady($search_key) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"cms_select\" value=\"" . htmlReady($cms_select) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_type\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_id\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getId()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_system_type\" value=\"" . htmlReady($this->cms_type) . "\">\n"; + + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isConnected()) + $output .= " " . Button::create(_('Entfernen'), 'remove'); + else + $output .= " " . Button::create(_('Hinzufügen'), 'add'); + $output .= "</form>"; + + return $output; + } + + /** + * get new module link + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function getNewModuleLink() + { + return false; + } + + /** + * get start page link + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function getStartpageLink() + { + return false; + } +} +?> diff --git a/lib/elearning/ConnectedPermissions.class.php b/lib/elearning/ConnectedPermissions.class.php new file mode 100644 index 0000000..a2216b7 --- /dev/null +++ b/lib/elearning/ConnectedPermissions.class.php @@ -0,0 +1,57 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/** +* class to handle access controls +* +* This class contains methods to handle permissions on connected objects. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ConnectedPermission +* @package ELearning-Interface +*/ +class ConnectedPermissions +{ + var $cms_type; + + var $db_class; + /** + * constructor + * + * init class. don't call directly, class is loaded by ConnectedCMS. + * @access public + * @param string $cms system-type + */ + function __construct($cms) + { + global $connected_cms, $ELEARNING_INTERFACE_MODULES; + + $this->cms_type = $cms; + if ($ELEARNING_INTERFACE_MODULES[$this->cms_type]["RELATIVE_PATH_DB_CLASSES"] != false) + { + require_once('lib/elearning/' . $ELEARNING_INTERFACE_MODULES[$this->cms_type]["RELATIVE_PATH_DB_CLASSES"] + . "/" . $ELEARNING_INTERFACE_MODULES[$this->cms_type]["db_classes"]["permissions"]["file"] ); + $classname = $ELEARNING_INTERFACE_MODULES[$this->cms_type]["db_classes"]["permissions"]["classname"]; + $this->db_class = new $classname(); + } + + } + + /** + * get module-permissions + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @param string $module_id module-id + * @return boolean returns false + */ + function getContentModulePerms($module_id) + { + return false; + } +} +?>
\ No newline at end of file diff --git a/lib/elearning/ConnectedUser.class.php b/lib/elearning/ConnectedUser.class.php new file mode 100644 index 0000000..9351955 --- /dev/null +++ b/lib/elearning/ConnectedUser.class.php @@ -0,0 +1,514 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +DEFINE ("USER_TYPE_ORIGINAL" , "1"); +DEFINE ("USER_TYPE_CREATED", "0"); + +/** +* class to handle user-accounts +* +* This class contains methods to handle connected user-accounts. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ConnectedUser +* @package ELearning-Interface +*/ +class ConnectedUser +{ + var $cms_type; + var $id; + var $studip_id; + var $studip_login; + var $studip_password; + var $login; + var $external_password; + var $category; + var $gender; + var $title_front; + var $title_rear; + var $title; + var $firstname; + var $lastname; + var $institution; + var $department; + var $street; + var $city; + var $zipcode; + var $country; + var $phone_home; + var $fax; + var $matriculation; + var $email; + var $type; + var $is_connected; + + var $db_class; + /** + * constructor + * + * init class. don't call directly, class is loaded by ConnectedCMS. + * @access public + * @param string $cms system-type + */ + function __construct($cms, $user_id = false) + { + global $auth, $ELEARNING_INTERFACE_MODULES; + + $this->studip_id = $user_id ? $user_id : $auth->auth["uid"]; + $this->cms_type = $cms; + + if ($ELEARNING_INTERFACE_MODULES[$this->cms_type]["RELATIVE_PATH_DB_CLASSES"] != false) + { + require_once("lib/elearning/" . $ELEARNING_INTERFACE_MODULES[$this->cms_type]["RELATIVE_PATH_DB_CLASSES"] . "/" . $ELEARNING_INTERFACE_MODULES[$this->cms_type]["db_classes"]["user"]["file"] ); + $classname = $ELEARNING_INTERFACE_MODULES[$this->cms_type]["db_classes"]["user"]["classname"]; + $this->db_class = new $classname(); + } + $this->readData(); + $this->getStudipUserData(); + } + + /** + * get data + * + * gets data from database + * @access public + * @return boolean returns false, if no data was found + */ + function readData() + { + $query = "SELECT external_user_id, external_user_name, external_user_password, external_user_category, external_user_type + FROM auth_extern + WHERE studip_user_id = ? AND external_user_system_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->studip_id, $this->cms_type]); + $data = $statement->fetch(PDO::FETCH_ASSOC); + + if (!$data) { + $this->id = ''; + $this->is_connected = false; + return false; + } + + $this->id = $data['external_user_id']; + $this->login = $data['external_user_name']; + $this->external_password = $data['external_user_password']; + $this->category = $data['external_user_category']; + $this->type = $data['external_user_type']; + $this->is_connected = true; + } + + /** + * get stud.ip-user-data + * + * gets stud.ip-user-data from database + * @access public + * @return boolean returns false, if no data was found + */ + function getStudipUserData() + { + global $connected_cms; + + $query = "SELECT username, password, title_front, title_rear, Vorname, + Nachname, Email, privatnr, privadr, geschlecht + FROM auth_user_md5 + LEFT JOIN user_info USING (user_id) + WHERE user_id = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->studip_id]); + $data = $statement->fetch(PDO::FETCH_ASSOC); + + if (!$data) { + return false; + } + + $this->studip_login = $data['username']; + if ($this->is_connected == false) { + $this->login = $connected_cms[$this->cms_type]->getUserPrefix() . $this->studip_login; + } + + $this->studip_password = $data['password']; + $this->title_front = $data['title_front']; + $this->title_rear = $data['title_rear']; + $this->firstname = $data['Vorname']; + $this->lastname = $data['Nachname']; + $this->email = $data['Email']; + $this->phone_home = $data['privatnr']; + $this->street = $data['privadr']; + $this->gender = ($data['geschlecht'] == 2 ? 'f' : 'm'); + + if ($this->title_front != '') { + $this->title = $this->title_front; + } + if ($this->title_front != '' && $this->title_rear != '') { + $this->title .= ' '; + } + if ($this->title_rear != '') { + $this->title .= $this->title_rear; + } + return true; + } + + /** + * create new user-account + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function newUser() + { + return false; + } + + /** + * update user-account + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function updateUser() + { + return false; + } + + /** + * delete user-account + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function deleteUser() + { + return false; + } + + /** + * get login-data of user-account + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function getLoginData($username) + { + return false; + } + + /** + * get id + * + * returns id + * @access public + * @return string id + */ + function getId() + { + return $this->id; + } + + /** + * get stud.ip user-id + * + * returns id + * @access public + * @return string stud.ip user-id + */ + function getStudipId() + { + return $this->studip_id; + } + + /** + * get username + * + * returns username + * @access public + * @return string username + */ + function getUsername() + { + return $this->login; + } + + /** + * set username + * + * sets username + * @access public + * @param string $user_login username + */ + function setUsername($user_login) + { + $this->login = $user_login; + } + + /** + * get password + * + * returns password + * @access public + * @return string password + */ + function getPassword() + { + return $this->external_password; + } + + /** + * set password + * + * sets password + * @access public + * @param string $user_password password + */ + function setPassword($user_password) + { + $this->external_password = $user_password; + } + + /** + * get user category + * + * returns id + * @access public + * @return string id + */ + function getCategory() + { + return $this->category; + } + + /** + * set user category + * + * sets user category + * @access public + * @param string $user_category category + */ + function setCategory($user_category) + { + $this->category = $user_category; + } + + /** + * get crypted password + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @return boolean returns false + */ + function getCryptedPassword($password) + { + return false; + } + + /** + * verify login data + * + * returns true, if login-data is valid + * @access public + * @param string $username username + * @param string $password password + * @return boolean login-validation + */ + function verifyLogin($username, $password) + { + $this->getLoginData($username); + if (($username == "") OR ($password == "")) + return false; + if ( ($this->login == $username) AND ($this->external_password == $this->getCryptedPassword($password) ) ) + return true; + return false; + } + + /** + * get gender + * + * returns gender-setting + * @access public + * @return string gender-setting + */ + function getGender() + { + return $this->gender; + } + + /** + * set gender + * + * sets gender + * @access public + * @param string $user_gender gender-setting + */ + function setGender($user_gender) + { + $this->gender = $user_gender; + } + + /** + * get full name + * + * returns full name + * @access public + * @return string name + */ + function getName() + { + if ($this->title != "") + return $this->title . ' ' . $this->firstname . ' ' . $this->lastname; + else + return $this->firstname . ' ' . $this->lastname; + } + + /** + * get firstname + * + * returns firstname + * @access public + * @return string firstname + */ + function getFirstname() + { + return $this->firstname; + } + + /** + * set firstname + * + * sets firstname + * @access public + * @param string $user_firstname firstname + */ + function setFirstname($user_firstname) + { + $this->firstname = $user_firstname; + } + + /** + * get lastname + * + * returns lastname + * @access public + * @return string lastname + */ + function getLastname() + { + return $this->lastname; + } + + /** + * set lastname + * + * sets lastname + * @access public + * @param string $user_lastname lastname + */ + function setLastname($user_lastname) + { + $this->lastname = $user_lastname; + } + + /** + * get email-adress + * + * returns email-adress + * @access public + * @return string email-adress + */ + function getEmail() + { + return $this->email; + } + + /** + * set email-adress + * + * sets email-adress + * @access public + * @param string $user_email email-adress + */ + function setEmail($user_email) + { + $this->email = $user_email; + } + + /** + * get user-type + * + * returns user-type + * @access public + * @return string user-type + */ + function getUserType() + { + return $this->type; + } + + /** + * set user-type + * + * sets user-type + * @access public + * @param string $user_type user-type + */ + function setUserType($user_type) + { + $this->type = $user_type; + } + + /** + * save connection for user-account + * + * saves user-connection to database and sets type for actual user + * @access public + * @param string $user_type user-type + */ + function setConnection($user_type) + { + $this->setUserType($user_type); + + $query = "INSERT INTO auth_extern (studip_user_id, external_user_id, external_user_name, + external_user_password, external_user_category, + external_user_system_type, external_user_type) + VALUES (?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY + UPDATE external_user_name = VALUES(external_user_name), + external_user_password = VALUES(external_user_password), + external_user_category = VALUES(external_user_category), + external_user_id = VALUES(external_user_id), + external_user_type = VALUES(external_user_type)"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + (string)$this->studip_id, + (string)$this->id, + (string)$this->login, + (string)$this->external_password, + (string)$this->category, + (string)$this->cms_type, + (int)$this->type, + ]); + + $this->is_connected = true; + $this->readData(); + } + + /** + * get connection-status + * + * returns true, if there is a connected user + * @access public + * @return boolean connection-status + */ + function isConnected() + { + return $this->is_connected; + } +} +?> diff --git a/lib/elearning/ContentModule.class.php b/lib/elearning/ContentModule.class.php new file mode 100644 index 0000000..64ce29b --- /dev/null +++ b/lib/elearning/ContentModule.class.php @@ -0,0 +1,383 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** +* class to handle content module data +* +* This class contains methods to handle connected content module data. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ContentModule +* @package ELearning-Interface +*/ +class ContentModule +{ + var $id; + var $title; + var $module_type; + var $module_type_name; + var $icon_file; + var $cms_type; + var $cms_name; + var $description; + var $authors; + var $is_connected; + var $is_dummy; + var $allowed_operations; + + var $db_class; + var $view; + /** + * constructor + * + * init class. don't call directly, class is loaded by ConnectedCMS. + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param string $cms_type system-type + */ + function __construct($module_id = "", $module_type, $cms_type) + { + global $connected_cms; + + $this->is_dummy = false; + $this->setCMSType($cms_type); + $this->setModuleType($module_type); + if ($module_id != "") + { + $this->setId($module_id); + + $this->readData(); + } + $this->view = new ContentModuleView($this->cms_type); + +/**/ } + +/* // Dummy-method. Must be overwritten by subclass. + function readData() + { + return false; + } +*/ + + /** + * set id + * + * sets id + * @access public + * @param string $module_id id + */ + function setId($module_id) + { + $this->id = $module_id; + } + + /** + * get id + * + * returns id + * @access public + * @return string id + */ + function getId() + { + return $this->id; + } + + /** + * set cms-type + * + * sets cms-type + * @access public + * @param string $module_cms_type cms-type + */ + function setCMSType($module_cms_type) + { + global $ELEARNING_INTERFACE_MODULES; + $this->cms_type = $module_cms_type; + $this->cms_name = $ELEARNING_INTERFACE_MODULES[$module_cms_type]["name"]; + } + + /** + * get cms-type + * + * returns cms-type + * @access public + * @return string cms-type + */ + function getCMSType() + { + return $this->cms_type; + } + + /** + * get cms name + * + * returns cms name + * @access public + * @return string cms name + */ + function getCMSName() + { + return $this->cms_name; + } + + /** + * set module-type + * + * sets module-type + * @access public + * @param string $module_type module-type + */ + function setModuleType($module_type) + { + global $ELEARNING_INTERFACE_MODULES; + $this->module_type = $module_type; + $this->module_type_name = $ELEARNING_INTERFACE_MODULES[$this->cms_type]["types"][$module_type]["name"]; + $this->icon_file = $ELEARNING_INTERFACE_MODULES[$this->cms_type]["types"][$module_type]["icon"]; + } + + /** + * get module-type + * + * returns module-type + * @access public + * @return string module-type + */ + function getModuleType() + { + return $this->module_type; + } + + /** + * get module-type name + * + * returns module-type name + * @access public + * @return string module-type name + */ + function getModuleTypeName() + { + return $this->module_type_name; + } + + /** + * set title + * + * sets title + * @access public + * @param string $module_title title + */ + function setTitle($module_title) + { + $this->title = $module_title; + } + + /** + * get title + * + * returns title + * @access public + * @return string title + */ + function getTitle() + { + return $this->title; + } + + /** + * set description + * + * sets description + * @access public + * @param string $module_description description + */ + function setDescription($module_description) + { + $this->description = $module_description; + } + + /** + * get description + * + * returns description + * @access public + * @return string description + */ + function getDescription() + { + return $this->description; + } + + /** + * set authors + * + * sets authors + * @access public + * @param array $module_authors authors + */ + function setAuthors($module_authors) + { + $this->authors = $module_authors; + } + + /** + * get authors + * + * returns authors + * @access public + * @return array authors + */ + function getAuthors() + { + return $this->authors; + } + + /** + * set connection + * + * sets connection with seminar + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function setConnection($seminar_id) + { + $this->is_connected = true; +// echo "$this->id, $this->module_type, $this->cms_type"; + return ObjectConnections::setConnection($seminar_id, $this->id, $this->module_type, $this->cms_type); + } + + /** + * unset connection + * + * unsets connection with seminar + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function unsetConnection($seminar_id) + { + $this->is_connected = false; + return ObjectConnections::unsetConnection($seminar_id, $this->id, $this->module_type, $this->cms_type); + } + + /** + * set connection-status + * + * sets connection-status + * @access public + * @param boolean $is_connected connection-status + */ + function setConnectionType($is_connected) + { + $this->is_connected = $is_connected; + } + + /** + * get connection-status + * + * returns true, if module is connected to seminar + * @access public + * @return boolean connection-status + */ + function isConnected() + { + return $this->is_connected; + } + + /** + * get reference string + * + * returns reference string for content-module + * @access public + * @return string reference string + */ + function getReferenceString() + { + return $this->cms_type."_".$this->module_type."_".$this->id; + } + + /** + * get icon-image + * + * returns icon-image + * @access public + * @return string icon-image + */ + function getIcon() + { + if (!$this->icon_file) { + $this->icon_file = 'learnmodule'; + } + if (mb_strpos('http', $this->icon_file) === 0) { + return "<img src=\"" . $this->icon_file . "\">"; + } else { + return Icon::create($this->icon_file, 'inactive')->asImg(); + } + } + + /** + * get module-status + * + * returns true, if module is a dummy + * @access public + * @return boolean module-status + */ + function isDummy() + { + return $this->is_dummy; + } + + /** + * create module-dummy + * + * sets title and description of module to display error-message + * @access public + * @param string $error error-type + */ + function createDummyForErrormessage($error = "unknown") + { + global $connected_cms; + + switch($error) + { + case "no permission": + $this->setTitle(_("--- Keine Lese-Berechtigung! ---")); + $this->setDescription(sprintf(_("Sie haben im System \"%s\" keine Lese-Berechtigung für das Lernmodul, das dieser Veranstaltung / Einrichtung an dieser Stelle zugeordnet ist."), $this->getCMSName())); + break; + case "not found": + $this->setTitle(_("--- Dieses Content-Modul existiert nicht mehr im angebundenen System! ---")); + $this->setDescription(sprintf(_("Das Lernmodul, das dieser Veranstaltung / Einrichtung an dieser Stelle zugeordnet war, existiert nicht mehr. Dieser Fehler tritt auf, wenn das angebundene LCMS \"%s\" nicht erreichbar ist oder wenn das Lernmodul innerhalb des angebundenen Systems gelöscht wurde."), $this->getCMSName())); + break; + case "deleted": + $this->setTitle(_("--- Dieses Content-Modul wurde im angebundenen System gelöscht! ---")); + $this->setDescription(sprintf(_("Das Lernmodul, das dieser Veranstaltung / Einrichtung an dieser Stelle zugeordnet war, wurde gelöscht."), $this->getCMSName())); + break; + default: + $this->setTitle(_("--- Es ist ein unbekannter Fehler aufgetreten! ---")); + $this->setDescription(sprintf(_("Unbekannter Fehler beim Lernmodul mit der Referenz-ID \"%s\" im LCMS \"%s\""), $this->getId(), $this->getCMSName())); + } + + $this->is_dummy = true; + } + + /** + * ask for permission for given operation + * + * dummy-method. returns false. must be overwritten by subclass. + * @access public + * @param string $operation operation + * @return boolean returns false + */ + function isAllowed($operation) + { + return false; + } +} +?> diff --git a/lib/elearning/ContentModuleView.class.php b/lib/elearning/ContentModuleView.class.php new file mode 100644 index 0000000..c351c1c --- /dev/null +++ b/lib/elearning/ContentModuleView.class.php @@ -0,0 +1,189 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/** +* class to show content-module data +* +* This class contains methods for output of connected module data. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ContentModuleView +* @package ELearning-Interface +*/ +class ContentModuleView +{ + var $view_mode; + var $change_date; + var $module_new; + var $cms_type; + /** + * constructor + * + * init class. don't call directly, class is loaded by ContentModule. + * @access public + * @param string $cms system-type + */ + function __construct($cms) + { + global $connected_cms; + + $this->change_date = 0; + $this->module_new = false; + $this->cms_type = $cms; + $this->setViewMode("closed"); + } + + /** + * show module-data + * + * show module-data in printhead/printcontent-style. user-mode + * @access public + */ + function show($mode = "") + { + global $connected_cms, $view, $search_key, $cms_select, $current_module, $anker_target; + + $content_module = $connected_cms[$this->cms_type]->content_module[$current_module]; + + if ( (! $content_module->isDummy()) AND ($connected_cms[$this->cms_type]->isAuthNecessary() == true) AND ($connected_cms[$this->cms_type]->user->isConnected() == true)) { + if (! $content_module->isAllowed(OPERATION_VISIBLE)) { + return false; + } + } + + if ($_SESSION['elearning_open_close'][$content_module->getReferenceString()] == true) + $this->setViewMode("open"); + $module_title = $content_module->getTitle(); +/*/ + if ($mode == "searchresult") { + $module_title = $module_title . " (ID " . $content_module->getId() . ", "; + if ($content_module->isAllowed(OPERATION_WRITE)) + $module_title = $module_title . " " . _("Schreibzugriff") . ")"; + else + $module_title = $module_title . " " . _("Lesezugriff") . ")"; + }/**/ + if ($this->isOpen() == true) + $module_link = URLHelper::getLink('?do_close='. $content_module->getReferenceString() . '&view='.$view.'&search_key='.$search_key.'&cms_select='.$cms_select.'#anker'); + else + $module_link = URLHelper::getLink('?do_open='. $content_module->getReferenceString() . '&view='.$view.'&search_key='.$search_key.'&cms_select='.$cms_select.'#anker'); + if (! $content_module->isDummy()) + $module_buttons = $connected_cms[$this->cms_type]->link->getUserModuleLinks(); + $template = $GLOBALS['template_factory']->open('elearning/_content_module.php'); + $template->set_attribute('module_anker_target', ($anker_target == $content_module->getReferenceString())); + $template->set_attribute('module_link', $module_link); + $template->set_attribute('module_buttons', $module_buttons); + $template->set_attribute('module_authors', $content_module->getAuthors()); + $template->set_attribute('module_title', $module_title); + $template->set_attribute('module_description', $content_module->getDescription()); + $template->set_attribute('module_is_new', $this->module_new); + $template->set_attribute('module_chdate', $this->change_date); + $template->set_attribute('module_reference', $content_module->getReferenceString()); + $template->set_attribute('module_source', $content_module->getCMSName() . " / " . $content_module->getModuleTypeName()); + $template->set_attribute('module_icon', $content_module->getIcon()); + $template->set_attribute('module_is_open', $this->isOpen()); + return $template->render(); + } + + /** + * show module-data to admin + * + * show module-data in printhead/printcontent-style. admin-mode + * @access public + */ + function showAdmin($mode = "") + { + global $connected_cms, $view, $search_key, $cms_select, $current_module, $anker_target; + + $content_module = $connected_cms[$this->cms_type]->content_module[$current_module]; + + if ( (! $content_module->isDummy()) AND ($connected_cms[$this->cms_type]->isAuthNecessary() == true) AND ($connected_cms[$this->cms_type]->user->isConnected() == true)) { + if (! $content_module->isAllowed(OPERATION_VISIBLE)) { + return false; + } + } + + if ($_SESSION['elearning_open_close'][$content_module->getReferenceString()] == true) + $this->setViewMode("open"); + + $module_title = $content_module->getTitle(); + $module_title = $module_title . " (ID " . $content_module->getId(); + if ($content_module->isAllowed(OPERATION_WRITE)) + $module_title = $module_title . ", " . _("Schreibzugriff"); + elseif ($content_module->isAllowed(OPERATION_READ)) + $module_title = $module_title . ", " . _("Lesezugriff"); + else + $module_title = $module_title . ", " . _("kein Lesezugriff"); + $module_title = $module_title . ")"; + + if ($this->isOpen() == true) + $module_link = URLHelper::getLink('?do_close='. $content_module->getReferenceString() . '&view='.$view.'&search_key='.$search_key.'&cms_select='.$cms_select.'#anker'); + else + $module_link = URLHelper::getLink('?do_open='. $content_module->getReferenceString() . '&view='.$view.'&search_key='.$search_key.'&cms_select='.$cms_select.'#anker'); + + $template = $GLOBALS['template_factory']->open('elearning/_content_module.php'); + $template->set_attribute('module_anker_target', ($anker_target == $content_module->getReferenceString())); + $template->set_attribute('module_link', $module_link); + if ($content_module->isAllowed(OPERATION_READ)) + $module_buttons = $connected_cms[$this->cms_type]->link->getAdminModuleLinks(); + $template->set_attribute('module_buttons', $module_buttons); + $template->set_attribute('module_authors', $content_module->getAuthors()); + $template->set_attribute('module_title', $module_title); + $template->set_attribute('module_description', $content_module->getDescription()); + $template->set_attribute('module_is_new', $this->module_new); + $template->set_attribute('module_chdate', $this->change_date); + $template->set_attribute('module_reference', $content_module->getReferenceString()); + $template->set_attribute('module_source', $content_module->getCMSName() . " / " . $content_module->getModuleTypeName()); + $template->set_attribute('module_icon', $content_module->getIcon()); + $template->set_attribute('module_is_open', $this->isOpen()); + return $template->render(); + } + + /** + * get open-status + * + * returns true, if module is opened + * @access public + * @return boolean open-status + */ + function isOpen() + { + if ($this->view_mode == "open") + return true; + else + return false; + } + + /** + * set view-mode + * + * sets view-mode + * @access public + * @param boolean $module_mode view-mode + */ + function setViewMode($module_mode) + { + $this->view_mode = $module_mode; + } + + /** + * set changedate + * + * sets changedate for view + * @access public + * @param string $module_chdate changedate + */ + function setChangeDate($module_chdate) + { + $this->change_date = $module_chdate; + + if (object_get_visit(Context::getId(), "elearning_interface") < $this->change_date) + $this->module_new = true; + else + $this->module_new = false; + } +} +?> diff --git a/lib/elearning/ELearningUtils.class.php b/lib/elearning/ELearningUtils.class.php new file mode 100644 index 0000000..86dd037 --- /dev/null +++ b/lib/elearning/ELearningUtils.class.php @@ -0,0 +1,614 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/** +* class with several forms and tools for the elearning interface +* +* This class contains Utilities for the elearning-interface. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @package ELearning-Interface +*/ + +use Studip\Button, Studip\LinkButton; + +class ELearningUtils +{ + /** + * loads class ConnectedCMS for given system-type and creates an instance + * + * @param string $cms system-type + */ + public static function loadClass($cms) + { + global $connected_cms, $ELEARNING_INTERFACE_MODULES; + + if (!is_object($connected_cms[$cms])) { + require_once "lib/elearning/{$ELEARNING_INTERFACE_MODULES[$cms]['CLASS_PREFIX']}ConnectedCMS.class.php"; + $classname = "{$ELEARNING_INTERFACE_MODULES[$cms]['CLASS_PREFIX']}ConnectedCMS"; + $connected_cms[$cms] = new $classname($cms); + $connected_cms[$cms]->initSubclasses(); + } + } + + public static function initElearningInterfaces() + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + if (is_array($ELEARNING_INTERFACE_MODULES)) { + foreach (array_keys($ELEARNING_INTERFACE_MODULES) as $cms) { + if (self::isCMSActive($cms)) { + self::loadClass($cms); + } + } + } + return is_array($connected_cms) ? count($connected_cms) : false; + } + + /** + * gets config-value with given name from globals + * + * @param string $name entry-name + * @param string $cms system-type + * @return boolean returns false if no cms is given + */ + public static function getConfigValue($name, $cms) + { + if (!$cms) { + return false; + } + return Config::get()->getValue("ELEARNING_INTERFACE_{$cms}_{$name}"); + } + + /** + * set config-value + * + * writes config-value with given name and value to database + * + * @param string $name entry-name + * @param string $value value + * @param string $cms system-type + */ + public static function setConfigValue($name, $value, $cms) + { + if (!$cms) { + return; + } + + try { + Config::get()->store("ELEARNING_INTERFACE_{$cms}_{$name}", $value); + } catch (InvalidArgumentException $e) { + Config::get()->create("ELEARNING_INTERFACE_{$cms}_{$name}", [ + 'value' => $value, + 'type' => 'string', + ]); + } + } + + /** + * check cms-status + * + * checks if connected content-management-system is activated + * + * @param string $cms system-type + */ + public static function isCMSActive($cms) + { + return self::getConfigValue('ACTIVE', $cms); + } + + /** + * get cms-selectbox + * + * returns a form to select a cms + * + * @param string $message description-text + * @param boolean $check_active show only activated systems + * @return string returns html-code + */ + public static function getCMSSelectbox($message, $check_active = true) + { + global $ELEARNING_INTERFACE_MODULES, $cms_select, $search_key, $view; + if (!is_array($ELEARNING_INTERFACE_MODULES)) { + $msg = sprintf(_("Die ELearning-Schnittstelle ist nicht korrekt konfiguriert. Die Variable \"%s\" " + ."muss in der Konfigurationsdatei von Stud.IP erst mit den Verbindungsdaten angebundener " + ."Learning-Content-Management-Systeme aufgefüllt werden. Solange dies nicht geschehen " + ."ist, setzen Sie die Variable \"%s\" auf FALSE!"), "\$ELEARNING_INTERFACE_MODULES", "\$ELEARNING_INTERFACE_ENABLE"); + PageLayout::postError($msg); + return false; + } + $options = []; + foreach ($ELEARNING_INTERFACE_MODULES as $cms => $cms_preferences) { + if (!$check_active || self::isCMSActive($cms)) { + $options[$cms] = $cms_preferences['name']; + } + } + $template = $GLOBALS['template_factory']->open('elearning/_cms_selectbox.php'); + $template->cms_select = $cms_select; + $template->options = $options; + $template->search_key = $search_key; + $template->view = $view; + $template->message = $message; + return $template->render(); + } + + /** + * get moduletype-selectbox + * + * returns a form to select type for new contentmodule + * + * @param string $cms system-type + * @return string returns html-code + */ + public static function getTypeSelectbox($cms) + { + global $ELEARNING_INTERFACE_MODULES; + $options = []; + foreach ($ELEARNING_INTERFACE_MODULES[$cms]['types'] as $type => $info) { + $options[$type] = $info['name']; + if (Request::get("module_type_{$cms}") === $type) { + $selected = $type; + } + } + $template = $GLOBALS['template_factory']->open('elearning/_type_selectbox.php'); + $template->options = $options; + $template->selected = $selected; + $template->cms = $cms; + return $template->render(); + } + + /** + * get searchfield + * + * returns a form to search for modules + * + * @param string $message description-text + * @return string returns html-code + */ + public static function getSearchfield($message) + { + global $cms_select, $search_key, $view; + $template = $GLOBALS['template_factory']->open('elearning/_searchfield.php'); + $template->cms_select = $cms_select; + $template->search_key = $search_key; + $template->view = $view; + $template->message = $message; + return $template->render(); + } + + /** + * get form for new content-module + * + * returns a form to choose module-type and to create a new content-module + * + * @param string $cms system-type + * @return string returns html-code + */ + public static function getNewModuleForm($cms) + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + if (sizeof($ELEARNING_INTERFACE_MODULES[$cms]["types"]) == 1) + foreach($ELEARNING_INTERFACE_MODULES[$cms]["types"] as $type => $info) + Request::set("module_type_" . $cms, $type); + $link = $connected_cms[$cms]->link->getNewModuleLink(); + + if ($link == false) + return false; + $types = []; + $cms_types = []; + foreach ($ELEARNING_INTERFACE_MODULES as $cms_type => $cms_data) + $cms_types["module_type_" . $cms_type] = Request::option("module_type_" . $cms_type); + $template = $GLOBALS['template_factory']->open('elearning/_new_module_form.php'); + $template->set_attribute('link', $link); + $template->set_attribute('cms', $cms); + $template->set_attribute('cms_types', $cms_types); + $template->set_attribute('types', $ELEARNING_INTERFACE_MODULES[$cms]["types"]); + return $template->render(); + } + + /** + * get form for external user-account + * + * returns a form for administration of external user-account + * + * @param string message message-string + * @param string my_account_cms cms-type + * @return string returns html-code + */ + public static function getMyAccountForm($message, $my_account_cms) + { + global $connected_cms; + $template = $GLOBALS['template_factory']->open('elearning/_my_account_form.php'); + if ($connected_cms[$my_account_cms]->user->isConnected()) { + $template->set_attribute('login', $connected_cms[$my_account_cms]->user->getUsername()); + $template->set_attribute('is_connected', 1); + } + $template->set_attribute('my_account_cms', $my_account_cms); + $template->set_attribute('search_key', $search_key); + $template->set_attribute('view', $view); + $template->set_attribute('message', $message); + return $template->render(); + } + + /** + * get form for new user + * + * returns a form to add a user-account to connected cms + * + * @param string $new_account_cms system-type + * @return string returns html-code + */ + public static function getNewAccountForm(&$new_account_cms) + { + global $connected_cms, $cms_select, $view, $current_module, $messages, + $ELEARNING_INTERFACE_MODULES; + + $new_account_step = Request::int('new_account_step'); + $ext_password = Request::get('ext_password'); + $ext_password_2 = Request::get('ext_password_2'); + $ext_username = Request::get('ext_username'); + $ref_id = Request::get('ref_id'); + $module_type = Request::get('module_type'); + + self::loadClass($new_account_cms); + + //Password was sent, but is to short + if (isset($ext_password_2) && !Request::submitted('go_back') && Request::submitted('next') && mb_strlen($ext_password_2) < 6) { + PageLayout::postError(_('Das Passwort muss mindestens 6 Zeichen lang sein!')); + $new_account_step--; + } elseif (isset($ext_password_2) && ! Request::submitted('go_back') && Request::submitted('next') && $ext_password != $ext_password_2) { + //Passwords doesn't match password repeat + PageLayout::postError(_('Das Passwort entspricht nicht der Passwort-Wiederholung!')); + $new_account_step--; + } + + // Benutzername was sent + if ($ext_username && !Request::submitted('go_back') && Request::submitted('assign')) { + $caching_status = $connected_cms[$new_account_cms]->soap_client->getCachingStatus(); + $connected_cms[$new_account_cms]->soap_client->setCachingStatus(false); + if ($connected_cms[$new_account_cms]->user->verifyLogin($ext_username, $ext_password)) { + $is_verified = true; + PageLayout::postInfo(_('Der Account wurde zugeordnet.')); + $connected_cms[$new_account_cms]->user->setCategory(""); + $connected_cms[$new_account_cms]->user->setUsername($ext_username); + $connected_cms[$new_account_cms]->user->setPassword($ext_password); + $connected_cms[$new_account_cms]->user->setConnection(USER_TYPE_ORIGINAL); + if ($ref_id) { + $connected_cms[$new_account_cms]->newContentModule($ref_id, $module_type, true); + $module_title = $connected_cms[$new_account_cms]->content_module[$current_module]->getTitle(); + $module_links = $connected_cms[$new_account_cms]->link->getUserModuleLinks(); + } + } else { + $new_account_step = 1; + PageLayout::postError(_('Die eingegebenen Login-Daten sind nicht korrekt.')); + } + $connected_cms[$new_account_cms]->soap_client->setCachingStatus($caching_status); + } + + if (Request::submitted('start')) { + $new_account_step = 1; + } + if (Request::submitted('go_back')) { + $new_account_step--; + if ($new_account_step < 1) { + $new_account_cms = ''; + return false; + } + } elseif (Request::submitted('next') || Request::submitted('assign')) { + $new_account_step++; + } + + if ($new_account_step == 2 && Request::submitted('assign')) { + // Assign existing Account + $step = 'assign'; + } elseif ($new_account_step == 2 && Request::submitted('next')) { + // Create new Account: ask for new password + $step = 'new_account'; + } elseif ($new_account_step == 3 && Request::submitted('next')) { + // Create new Account + $connected_cms[$new_account_cms]->user->setPassword($ext_password); + if ($connected_cms[$new_account_cms]->user->newUser()) { + $is_verified = true; + PageLayout::postInfo(sprintf(_("Der Account wurde erzeugt und zugeordnet. Ihr Loginname ist %s."), "<b>" . htmlReady($connected_cms[$new_account_cms]->user->getUsername()) . "</b>")); + if ($ref_id) { + $connected_cms[$new_account_cms]->newContentModule($ref_id, $module_type, true); + $module_title = $connected_cms[$new_account_cms]->content_module[$current_module]->getTitle(); + $module_links = $connected_cms[$new_account_cms]->link->getUserModuleLinks(); + } + } + } elseif (!$is_verified) { + $output .= '<font size="-1">'; + if (Request::submitted('start')) { + $messages["info"] = sprintf(_("Sie versuchen zum erstem Mal ein Lernmodul des angebundenen Systems %s zu starten. Bevor Sie das Modul nutzen können, muss Ihrem Stud.IP-Benutzeraccount ein Account im angebundenen System zugeordnet werden."), htmlReady($connected_cms[$new_account_cms]->getName())) . "<br><br>\n\n"; + } + } + $template = $GLOBALS['template_factory']->open('elearning/_new_account_form.php'); + $template->cms_title = htmlReady($connected_cms[$new_account_cms]->getName()); + $template->cms_select = $cms_select; + $template->module_title = $module_title; + $template->module_links = $module_links; + $template->module_type = $module_type; + $template->ref_id = $ref_id; + $template->ext_username = $ext_username; + $template->new_account_cms = $new_account_cms; + $template->new_account_step = $new_account_step; + $template->is_connected = $connected_cms[$new_account_cms]->user->isConnected(); + $template->is_verified = $is_verified; + $template->step = $step; + + // TODO: Should this really be below the assignment? + if ($is_verified) { + $new_account_cms = ""; + } + + return $template->render(); + } + + /** + * get table-header for connected cms + * + * returns a table-header for connected cms + * + * @param string $title table-title + * @return string returns html-code + */ + public static function getCMSHeader($title) + { + $template = $GLOBALS['template_factory']->open('elearning/_cms_header.php'); + $template->title = $title; + return $template->render(); + } + + /** + * get table-footer for connected cms + * + * returns a table-footer for connected cms + * + * @param string $logo system-logo + * @return string returns html-code + */ + public static function getCMSFooter($logo) + { + $template = $GLOBALS['template_factory']->open('elearning/_cms_footer.php'); + $template->logo = $logo; + return $template->render(); + } + + /** + * get headline for modules + * + * returns a table with a headline + * + * @param string $title headline + * @return string returns html-code + */ + public static function getModuleHeader($title) + { + global $view, $cms_select, $search_key; + $template = $GLOBALS['template_factory']->open('elearning/_module_header.php'); + $template->title = $title; + $template->view = $view; + $template->cms_select = $cms_select; + $template->search_key = $search_key; + $template->all_open = $_SESSION['elearning_open_close']['all open']; + return $template->render(); + } + + /** + * get Headline + * + * returns a table with a headline + * + * @param string $title headline + * @return string returns html-code + */ + public static function getHeader($title) + { + $template = $GLOBALS['template_factory']->open('elearning/_header.php'); + $template->title = $title; + return $template->render(); + } + + /** + * save timestamp + * + * saves a timestamp for debugging and performance-check + * + * @param string $stri description + */ + public static function bench($stri) + { + $GLOBALS['timearray'][] = [ + 'zeit' => microtime(true), + 'name' => $stri, + ]; + } + + /** + * show benchmark + * + * shows saved timestamps with descriptions + * + * @param string $stri description + */ + public static function showbench() + { + global $timearray; + echo "<table><tr><td>Zeit (".$timearray[0]["name"].")</td><td align=\"right\"></td></tr>"; + for ($i = 0; $i < count($timearray); $i++) { + echo "<tr><td>".$timearray[$i]["name"].": </td><td align=\"right\">" . number_format(($timearray[$i]["zeit"]-$timearray[$i-1]["zeit"])*1000,2) . " msek</td></tr>"; + } + echo "<tr><td>Gesamtzeit: </td><td align=\"right\">" . number_format(($timearray[$i-1]["zeit"]-$timearray[0]["zeit"])*1000,2)." msek</td></tr></table>"; + } + + /** + * delete cms-data + * + * deletes all data belonging to the specified cms from stud.ip database + * + * @return boolean successful + */ + public static function deleteCMSData($cms_type) + { + $db = DBManager::get(); + $db->execute("DELETE FROM auth_extern WHERE external_user_system_type = ?", [$cms_type]); + $db->execute("DELETE FROM object_contentmodules WHERE system_type = ?", [$cms_type]); + + $config = Config::get(); + foreach ($config->getFields('global' ,null , "ELEARNING_INTERFACE_{$cms_type}") as $key) { + $config->delete($key); + } + } + + /** + * get ilias courses + * + * creates output of ilias courses linked to the chosen seminar. also updates object-connections. + * + * @return boolean successful + */ + public static function getIliasCourses($sem_id) + { + global $connected_cms, $messages, $view, $cms_select; + $db = DBManager::get(); + + $rs = $db->query("SELECT DISTINCT system_type, module_id + FROM object_contentmodules + WHERE module_type = 'crs' AND object_id = " . $db->quote($sem_id)) + ->fetchAll(PDO::FETCH_ASSOC); + foreach ($rs as $row) $courses[$row['system_type']] = $row['module_id']; + if (is_array($courses)) + foreach($courses as $system_type => $crs_id) + if (self::isCMSActive($system_type)) { + self::loadClass($system_type); + $connected_courses['courses'][$system_type] = [ + 'url' => UrlHelper::getLink($connected_cms[$system_type]->link->cms_link . '?client_id=' . $connected_cms[$system_type]->getClientId() . '&cms_select=' . $system_type . '&ref_id=' . $crs_id . '&type=crs&target=start'), + 'cms_name' => $connected_cms[$system_type]->getName()]; + $course_output[] = "<a href=\"" . UrlHelper::getLink($connected_cms[$system_type]->link->cms_link . "?" . "client_id=" . $connected_cms[$system_type]->getClientId() . "&cms_select=" . $system_type . "&ref_id=" . $crs_id . "&type=crs&target=start") . "\" target=\"_blank\" rel=\"noopener noreferrer\">".sprintf(_("Kurs in %s"), htmlReady($connected_cms[$system_type]->getName()))."</a>"; + // gegebenenfalls zugeordnete Module aktualisieren + if (Request::option('update')) { + if ((method_exists($connected_cms[$system_type], "updateConnections"))) { + $connected_cms[$system_type]->updateConnections( $crs_id ); + } + } + if (method_exists($connected_cms[$system_type]->permissions, 'CheckUserPermissions')) { + $connected_cms[$system_type]->permissions->CheckUserPermissions($crs_id); + } + } + + if ($connected_courses['courses']) { + if (count($connected_courses['courses']) > 1) + $connected_courses['text'] = _("Diese Veranstaltung ist mit folgenden Ilias-Kursen verknüpft. Hier gelangen Sie direkt in den jeweiligen Kurs: "); + else + $connected_courses['text'] = _("Diese Veranstaltung ist mit einem Ilias-Kurs verknüpft. Hier gelangen Sie direkt in den Kurs: "); + $output["update"] .= _("Hier können Sie die Zuordnungen zu den verknüpften Kursen aktualisieren."). "<br>"; + $output["update"] .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "#anker\">\n"; + $output["update"] .= CSRFProtection::tokenTag(); + $output["update"] .= "<input type=\"HIDDEN\" name=\"view\" value=\"" . htmlReady($view) . "\">\n"; + $output["update"] .= "<input type=\"HIDDEN\" name=\"cms_select\" value=\"" . htmlReady($cms_select) . "\">\n"; + $output["update"] .= Button::create(_('Aktualisieren'), 'update'); + $output["update"] .= "</form>"; + } + + return $connected_courses; + } + + /** + * check db-integrity + * + * checks if there are broken links in the database + * + * @return boolean successful + */ + public static function checkIntegrity() + { + global $ELEARNING_INTERFACE_MODULES, $messages; + $db = DBManager::get(); + + foreach ($ELEARNING_INTERFACE_MODULES as $cms_type =>$data) $cmsystems[$cms_type] = []; + + $config = Config::get(); + foreach ($config->getFields('global' ,null , 'ELEARNING_INTERFACE_') as $key) { + $parts = explode("_", $key); + $cmsystems[$parts[2]]["config"]++; + } + + $rs = $db->query("SELECT external_user_system_type, COUNT(*) as c FROM auth_extern GROUP BY external_user_system_type"); + while ($row = $rs->fetch()) + $cmsystems[$row["external_user_system_type"]]["accounts"] = $row['c']; + $rs = $db->query("SELECT system_type, COUNT(*) FROM object_contentmodules GROUP BY system_type"); + while ($row = $rs->fetch()) + $cmsystems[$row["system_type"]]["modules"] = $row['c']; + + if (Request::submitted('delete')) { + $messages["info"] .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">"; + $messages["info"] .= CSRFProtection::tokenTag(); + $messages["info"] .= "<table>"; + $messages["info"] .= "<tr><td> </td></tr>"; + $messages["info"] .= "<tr><td>" . sprintf(_("Durch das Löschen der Daten zum System mit dem Index \"%s\" werden %s Konfigurationseinträge und Verknüpfungen von Stud.IP-Veranstaltungen und -User-Accounts unwiederbringlich aus der Stud.IP-Datenbank entfernt. Wollen Sie diese Daten jetzt löschen?"), Request::quoted('delete_cms'), $cmsystems[Request::quoted('delete_cms')]["accounts"]+$cmsystems[Request::quoted('delete_cms')]["modules"]+$cmsystems[Request::quoted('delete_cms')]["config"] ) . "</td></tr>"; + $messages["info"] .= "<tr><td align=\"center\"><input type=\"hidden\" name=\"delete_cms\" value=\"".Request::quoted('delete_cms')."\">"; + $messages["info"] .= '<div class="button-group">' . Button::create(_('Alle löschen'), 'confirm_delete') . Button::createCancel(_('Abbrechen'), 'abbruch') . '<div></td></tr>'; + $messages["info"] .= "<tr><td align=\"center\"></td></tr>"; + $messages["info"] .= "</table>"; + $messages["info"] .= "</form>"; + } + + if (Request::submitted('confirm_delete')) { + unset($cmsystems[Request::quoted('delete_cms')]); +// deleteCMSData(Request::quoted('delete_cms')); + $messages["info"] .= _("Daten wurden gelöscht."); + } + + foreach ($cmsystems as $cms_type =>$data) { + if ($ELEARNING_INTERFACE_MODULES[$cms_type]) { + $output .= self::getCMSHeader($ELEARNING_INTERFACE_MODULES[$cms_type]["name"]); + $output .= "<table>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + if (self::isCMSActive($cms_type)) { + $output .= "<tr><td>" . Icon::create('checkbox-checked', 'clickable')->asImg(['class' => 'text-top']) . "</td><td><b>". sprintf(_("Die Schnittstelle zum System %s ist aktiv."), $ELEARNING_INTERFACE_MODULES[$cms_type]["name"]) . "</b></td></tr>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + } + elseif ($data["config"] < 1) + $output .= "<tr><td>" . Icon::create('checkbox-unchecked', 'clickable')->asImg(['class' => 'text-top']) . "</td><td><i>". sprintf(_("Die Schnittstelle für das System %s wurde noch nicht eingerichtet."), $ELEARNING_INTERFACE_MODULES[$cms_type]["name"]) . "</i></td></tr>"; + elseif ($data["config"] < 1) + $output .= "<tr><td>" . Icon::create('checkbox-unchecked', 'clickable')->asImg(['class' => 'text-top']) . "</td><td><i>". sprintf(_("Die Schnittstelle wurde noch nicht aktiviert."), $ELEARNING_INTERFACE_MODULES[$cms_type]["name"]) . "</i></td></tr>"; + + if ($data["accounts"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Stud.IP-User-Accounts sind mit Accounts im System %s verknüpft."), $data["accounts"], $ELEARNING_INTERFACE_MODULES[$cms_type]["name"]) . "</td></tr>"; + if ($data["modules"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Objekte sind Stud.IP-Veranstaltungen oder -Einrichtungen zugeordnet."), $data["modules"]) . "</td></tr>"; + if ($data["config"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Einträge in der config-Tabelle der Stud.IP-Datenbank."), $data["config"]) . "</td></tr>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + $output .= "</table>"; + $output .= self::getCMSFooter(($ELEARNING_INTERFACE_MODULES[$cms_type]["logo_file"] ? "<img src=\"".$ELEARNING_INTERFACE_MODULES[$cms_type]["logo_file"]."\" border=\"0\">" : $cms_type)); + } + else { + $output .= self::getCMSHeader("<font color=FF0000> Unbekanntes System: " . $cms_type . "</font>"); + $output .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">"; + $output .= CSRFProtection::tokenTag(); + $output .= "<table>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + $output .= "<tr><td>" . Icon::create('decline', 'attention')->asImg(['class' => 'text-top']) . "</td><td><i>".sprintf(_("Für das System mit dem Index \"%s\" existieren keine Voreinstellungen in den Konfigurationsdateien mehr."), $cms_type) . "</i></td></tr>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + $output .= "<tr><td colspan=\"2\"><b>". _("In der Stud.IP-Datenbank sind noch folgende Informationen zu diesem System gespeichert:") . "</b></td></tr>"; + if ($data["accounts"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Stud.IP-User-Accounts sind mit externen Accounts mit dem Index \"%s\" verknüpft."), $data["accounts"], $cms_type) . "</td></tr>"; + if ($data["modules"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Objekte sind Stud.IP-Veranstaltungen oder -Einrichtungen zugeordnet."), $data["modules"]) . "</td></tr>"; + if ($data["config"]) + $output .= "<tr><td colspan=\"2\">". sprintf(_("%s Einträge in der config-Tabelle der Stud.IP-Datenbank."), $data["config"]) . "</td></tr>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + $output .= "<tr><td align=\"center\" colspan=\"2\"><input type=\"hidden\" name=\"delete_cms\" value=\"".$cms_type."\">" . Button::create(_('Löschen'), 'delete') . "</td></tr>"; + $output .= "<tr><td colspan=\"2\"> </td></tr>"; + $output .= "</table>"; + $output .= "</form>"; + $output .= self::getCMSFooter(''); + } + $output .= "<br>"; + } + + return $output; + } +} diff --git a/lib/elearning/Ilias3ConnectedCMS.class.php b/lib/elearning/Ilias3ConnectedCMS.class.php new file mode 100644 index 0000000..83e6921 --- /dev/null +++ b/lib/elearning/Ilias3ConnectedCMS.class.php @@ -0,0 +1,362 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +use Studip\Button, Studip\LinkButton; + +/** +* main-class for connection to ILIAS 3 +* +* This class contains the main methods of the elearning-interface to connect to ILIAS 3. Extends ConnectedCMS. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3ConnectedCMS +* @package ELearning-Interface +*/ +class Ilias3ConnectedCMS extends ConnectedCMS +{ + var $client_id; +// var $root_user_id; + var $root_user_sid; + var $main_category_node_id; + var $user_role_template_id; + var $user_skin; + var $user_style; + var $crs_roles; + var $global_roles; + + var $db_class_object; + var $db_class_tree; + var $db_class_course; + + var $soap_client; + /** + * constructor + * + * init class. + * @access public + * @param string $cms system-type + */ + function __construct($cms) + { + global $ELEARNING_INTERFACE_MODULES; + + parent::__construct($cms); + + require_once($this->CLASS_PREFIX . "Soap.class.php"); + $classname = $this->CLASS_PREFIX . "Soap"; + $this->soap_client = new $classname($this->cms_type); + $this->soap_client->setCachingStatus(true); + + $this->main_category_node_id = ELearningUtils::getConfigValue("category_id", $cms); + + if ((ELearningUtils::getConfigValue("user_role_template_id", $cms) == "") AND ($GLOBALS["role_template_name"] == "")) + $GLOBALS["role_template_name"] = "Author"; + $this->user_role_template_id = ELearningUtils::getConfigValue("user_role_template_id", $cms); + $this->user_skin = ELearningUtils::getConfigValue("user_skin", $cms); + $this->user_style = ELearningUtils::getConfigValue("user_style", $cms); + $this->encrypt_passwords = ELearningUtils::getConfigValue("encrypt_passwords", $cms); + + $this->crs_roles = $ELEARNING_INTERFACE_MODULES[$cms]["crs_roles"]; + $this->client_id = $ELEARNING_INTERFACE_MODULES[$cms]["soap_data"]["client"]; + $this->global_roles = $ELEARNING_INTERFACE_MODULES[$cms]["global_roles"]; +// $this->root_user_sid = $this->soap_client->login(); + $this->is_first_call = true; + } + + /** + * get preferences + * + * shows additional settings. + * @access public + */ + function getPreferences() + { + global $connected_cms; + + $role_template_name = Request::get('role_template_name'); + $cat_name = Request::get('cat_name'); + $style_setting = Request::option('style_setting'); + $encrypt_passwords = Request::option('encrypt_passwords'); + + $this->soap_client->setCachingStatus(false); + + if ($cat_name != "") + { + $cat = $this->soap_client->getReferenceByTitle( trim( $cat_name ), "cat"); + if ($cat == false) + $messages["error"] .= sprintf(_("Das Objekt mit dem Namen \"%s\" wurde im System %s nicht gefunden."), htmlReady($cat_name), htmlReady($this->getName())) . "<br>\n"; + if ($cat != "") + { + ELearningUtils::setConfigValue("category_id", $cat, $this->cms_type); + $this->main_category_node_id = $cat; + } + } + + if ($role_template_name != "") + { + $role_template = $this->soap_client->getObjectByTitle( trim( $role_template_name ), "rolt" ); + if ($role_template == false) + $messages["error"] .= sprintf(_("Das Rollen-Template mit dem Namen \"%s\" wurde im System %s nicht gefunden."), htmlReady($role_template_name), htmlReady($this->getName())) . "<br>\n"; + if (is_array($role_template)) + { + ELearningUtils::setConfigValue("user_role_template_id", $role_template["obj_id"], $this->cms_type); + ELearningUtils::setConfigValue("user_role_template_name", $role_template["title"], $this->cms_type); + $this->user_role_template_id = $role_template["obj_id"]; + } + } + + if (Request::submitted('submit')) + { + ELearningUtils::setConfigValue("user_style", $style_setting, $this->cms_type); + ELearningUtils::setConfigValue("user_skin", $style_setting, $this->cms_type); + ELearningUtils::setConfigValue("encrypt_passwords", $encrypt_passwords, $this->cms_type); + } + else + { + if (ELearningUtils::getConfigValue("user_style", $this->cms_type) != "") + $style_setting = ELearningUtils::getConfigValue("user_style", $this->cms_type); + if (ELearningUtils::getConfigValue("encrypt_passwords", $this->cms_type) != "") + $encrypt_passwords = ELearningUtils::getConfigValue("encrypt_passwords", $this->cms_type); + } + + + if ($messages["error"] != "") + echo "<b>" . Icon::create('decline', 'attention')->asImg(['class' => 'text-top', 'title' => _('Fehler')]) . " " . $messages["error"] . "</b><br><br>"; + + echo "<table>"; + echo "<tr valign=\"top\"><td width=30% align=\"left\"><font size=\"-1\">"; + echo "<b>" . _("SOAP-Verbindung: ") . "</b>"; + echo "</td><td><font size=\"-1\">"; + $error = $this->soap_client->getError(); + if ($error != false) + echo sprintf(_("Beim Herstellen der SOAP-Verbindung trat folgender Fehler auf:")) . "<br><br>" . $error; + else + echo sprintf(_("Die SOAP-Verbindung zum Klienten \"%s\" wurde hergestellt, der Name des Administrator-Accounts ist \"%s\"."), htmlReady($this->soap_data["client"]), htmlReady($this->soap_data["username"])); + echo "<br>\n"; + echo "<br>\n"; + echo "</td></tr><tr><td width=30% align=\"left\"><font size=\"-1\">"; + + $cat = $this->soap_client->getObjectByReference( $this->main_category_node_id ); + echo '<b>' . _('Kategorie') . ':</b>'; + echo "</td><td>"; + echo "<input type=\"text\" size=\"20\" border=0 value=\"" . $cat["title"] . "\" name=\"cat_name\"> "; + echo Icon::create('info-circle', 'inactive', ['title' => _('Geben Sie hier den Namen einer bestehenden ILIAS 3 - Kategorie ein, in der die Lernmodule und User-Kategorien abgelegt werden sollen.')])->asImg(); + echo "</td></tr><tr><td></td><td><font size=\"-1\">"; + echo " (ID " . $this->main_category_node_id; + if ($cat["description"] != "") + echo ", " . _("Beschreibung: ") . htmlReady($cat["description"]); + echo ")"; + echo "<br>\n"; + echo "<br>\n"; + echo "</td></tr><tr><td width=30% align=\"left\"><font size=\"-1\">"; + + + echo "<b>" . _("Rollen-Template für die persönliche Kategorie: ") . "</b>"; + echo "</td><td>"; + echo "<input type=\"text\" size=\"20\" border=0 value=\"" . ELearningUtils::getConfigValue("user_role_template_name", $this->cms_type) . "\" name=\"role_template_name\"> "; + echo Icon::create('info-circle', 'inactive', ['title' => _('Geben Sie den Namen des Rollen-Templates ein, das für die persönliche Kategorie von Lehrenden verwendet werden soll (z.B. \"Author\").')])->asImg(); + echo "</td></tr><tr><td></td><td><font size=\"-1\">"; + echo " (ID " . $this->user_role_template_id; + echo ")"; + echo "<br>\n"; + echo "<br>\n"; + echo "</td></tr><tr><td width=30% align=\"left\"><font size=\"-1\">"; + + echo "<b>" . _("Passwörter: ") . "</b>"; + echo "</td><td><font size=\"-1\">"; + echo "<input type=\"checkbox\" border=0 value=\"md5\" name=\"encrypt_passwords\""; + if ($encrypt_passwords == "md5") + echo " checked"; + echo "> " . _("ILIAS-Passwörter verschlüsselt speichern."); + echo Icon::create('info-circle', 'inactive', ['title' => _('Wählen Sie diese Option, wenn die ILIAS-Passwörter der zugeordneten Accounts verschlüsselt in der Stud.IP-Datenbank abgelegt werden sollen.')])->asImg(); + echo "</td></tr><tr><td></td><td><font size=\"-1\">"; + echo "<br>\n"; + echo "<br>\n"; + echo "</td></tr><tr><td width=30% align=\"left\"><font size=\"-1\">"; + + echo "<b>" . _("Style / Skin: ") . "</b>"; + echo "</td><td><font size=\"-1\">"; + echo "<input type=\"checkbox\" border=0 value=\"studip\" name=\"style_setting\""; + if ($style_setting == "studip") + echo " checked"; + echo "> " . _("Stud.IP-Style für neue Nutzer-Accounts voreinstellen."); + echo Icon::create('info-circle', 'inactive', ['title' => _('Wählen Sie diese Option, wenn für alle von Stud.IP angelegten ILIAS-Accounts das Stud.IP-Layout als System-Style eingetragen werden soll. ILIAS-seitig angelegte Accounts erhalten weiterhin den Standard-Style.')])->asImg(); + echo "</td></tr><tr><td></td><td><font size=\"-1\">"; + echo "<br>\n"; + echo "<br>\n"; + + + + + echo "</td></tr>"; + echo "</table>"; + echo "<center>" . Button::create(_('übernehmen'), 'submit') . "</center><br>"; + echo "<br>\n"; + + parent::getPreferences(); + + echo "<br>\n"; + } + + function setContentModule($data, $is_connected = false) + { + parent::setContentModule($data, $is_connected); + + if ($data["owner"] != "") + { + $user_data = $this->soap_client->getUser($data["owner"]); + $user_name = trim($user_data["title"] . " " . $user_data["firstname"] . " " . $user_data["lastname"]); + $this->content_module[$data["ref_id"]]->setAuthors($user_name); + } + $this->content_module[$data["ref_id"]]->setPermissions($data["accessInfo"], $data["operations"]); + } + + /** + * create new instance of subclass content-module + * + * creates new instance of subclass content-module and gets permissions + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param string $is_connected is module connected to seminar? + */ + function newContentModule($module_id, $module_type, $is_connected = false) + { + global $seminar_id, $current_module, $caching_active; + + $current_module = $module_id; +// echo "call module $module_id"; + + if ($this->is_first_call AND ($seminar_id != "") AND ($is_connected == true)) + { + $id = ObjectConnections::getConnectionModuleId( $seminar_id, "crs", $this->cms_type ); + if ($id != false) + { + if ($this->user->isConnected()) + $this->permissions->checkUserPermissions($id); + $this->is_first_call = false; + } +// echo "first call, ref_id $id"; + } + + parent::newContentModule($module_id, $module_type, $is_connected); + } + + /** + * get user modules + * + * returns user content modules + * @access public + * @return array list of content modules + */ + function getUserContentModules() + { + global $connected_cms; + + $types = []; + foreach ($this->types as $type => $name) + { + $types[] = $type; + } + if ($this->user->getCategory() == false) + return false; + $result = $this->soap_client->getTreeChilds($this->user->getCategory(), $types, $connected_cms[$this->cms_type]->user->getId()); + $obj_ids = []; + if (is_array($result)) + foreach($result as $key => $object_data){ + if (is_array($object_data["operations"])){ + if ((!in_array($object_data["obj_id"], $obj_ids) && in_array(OPERATION_READ, $object_data["operations"])) + || in_array(OPERATION_WRITE, $object_data["operations"])) + { + if (is_array($user_modules[$object_data["obj_id"]]["operations"])){ + if (in_array(OPERATION_WRITE, $user_modules[$object_data["obj_id"]]["operations"])){ + continue; + } + } + $user_modules[$object_data["obj_id"]] = $object_data; + $obj_ids[] = $result[$key]["obj_id"]; + } + } + } + return $user_modules; + } + + /** + * search for content modules + * + * returns found content modules + * @access public + * @param string $key keyword + * @return array list of content modules + */ + function searchContentModules($key) + { + global $connected_cms; + + $types = []; + foreach ($this->types as $type => $name) + { + $types[] = $type; + } + + $result = $this->soap_client->searchObjects($types, $key,"and", $connected_cms[$this->cms_type]->user->getId()); + return $result; + } + + + /** + * get client-id + * + * returns client-id + * @access public + * @return string client-id + */ + function getClientId() + { + return $this->client_id; + } + + /** + * get session-id + * + * returns soap-session-id + * @access public + * @return string session-id + */ + function getSID() + { + return $this->root_user_sid; + } + + /** + * terminate + * + * terminates connection. + * @access public + * @return boolean returns false + */ + function terminate() + { +// $this->soap_client->logout(); + $this->soap_client->saveCacheData(); + } + + //we have to delete the course only + function deleteConnectedModules($object_id){ + global $connected_cms; + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + $connected_cms[$this->cms_type]->soap_client->clearCache(); + $connected_cms[$this->cms_type]->soap_client->user_type == "admin"; + $crs_id = ObjectConnections::getConnectionModuleId($object_id, "crs", $this->cms_type); + if($crs_id && $connected_cms[$this->cms_type]->soap_client->checkReferenceById($crs_id)){ + $connected_cms[$this->cms_type]->soap_client->deleteObject($crs_id); + } + return parent::deleteConnectedModules($object_id); + } +} +?> diff --git a/lib/elearning/Ilias3ConnectedLink.class.php b/lib/elearning/Ilias3ConnectedLink.class.php new file mode 100644 index 0000000..7565cfb --- /dev/null +++ b/lib/elearning/Ilias3ConnectedLink.class.php @@ -0,0 +1,191 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +use Studip\Button, Studip\LinkButton; + +/** +* class to generate links to ILIAS 3 +* +* This class contains methods to generate links to ILIAS 3. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3ConnectedLink +* @package ELearning-Interface +*/ +class Ilias3ConnectedLink extends ConnectedLink +{ + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + parent::__construct($cms); + $this->cms_link = "ilias3_referrer.php"; + } + + /** + * get user module links + * + * returns content module links for user + * @access public + * @return string html-code + */ + function getUserModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + if ($connected_cms[$this->cms_type]->isAuthNecessary() AND (! $connected_cms[$this->cms_type]->user->isConnected())) + { + $output .= $this->getNewAccountLink(); + } + else + { + if (! $connected_cms[$this->cms_type]->content_module[$current_module]->isDummy() ) + { + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isAllowed(OPERATION_READ)) + { + + $output .= LinkButton::create(_('Starten'), URLHelper::getURL($this->cms_link . "?" + . "client_id=" . $connected_cms[$this->cms_type]->getClientId() + . "&cms_select=" . $this->cms_type +// . "&sess_id=" . $connected_cms[$this->cms_type]->user->getSessionId() + . "&ref_id=" . $connected_cms[$this->cms_type]->content_module[$current_module]->getId() + . "&type=" . $connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType() + . $auth_data + . "&target=start"), [ + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ]); + $output .= " "; + } + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isAllowed(OPERATION_WRITE)) + { + $output .= LinkButton::create(_('Bearbeiten'), URLHelper::getURL($this->cms_link . "?" + . "client_id=" . $connected_cms[$this->cms_type]->getClientId() + . "&cms_select=" . $this->cms_type +// . "&sess_id=" . $connected_cms[$this->cms_type]->user->getSessionId() + . "&ref_id=" . $connected_cms[$this->cms_type]->content_module[$current_module]->getId() + . "&type=" . $connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType() + . $auth_data + . "&target=edit"), [ + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ]); + $output .= " "; + + } + } + } + + return $output; + } + + /** + * get admin module links + * + * returns links add or remove a module from course + * @access public + * @return string returns html-code + */ + function getAdminModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + $output .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">\n"; + $output .= CSRFProtection::tokenTag(); + $output .= "<input type=\"HIDDEN\" name=\"view\" value=\"" . htmlReady($view) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"search_key\" value=\"" . htmlReady($search_key) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"cms_select\" value=\"" . htmlReady($cms_select) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_type\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_id\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getId()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_system_type\" value=\"" . htmlReady($this->cms_type) . "\">\n"; + + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isConnected()) + $output .= " " . Button::create(_('Entfernen'), 'remove'); + elseif ($connected_cms[$this->cms_type]->content_module[$current_module]->isAllowed(OPERATION_WRITE)) + { + $output .= "<div align=\"left\"><input type=\"CHECKBOX\" value=\"1\" name=\"write_permission\" style=\"vertical-align:middle\">"; + $output .= _("Mit Schreibrechten für alle Lehrenden/Tutoren und Tutorinnen dieser Veranstaltung") . "<br>"; + $output .= "<input type=\"CHECKBOX\" value=\"1\" style=\"vertical-align:middle\" name=\"write_permission_autor\">"; + $output .= _("Mit Schreibrechten für alle Teilnehmenden dieser Veranstaltung") . "</div>"; + $output .= Button::create(_('Hinzufügen'), 'add') . "<br>"; + } + else + $output .= " " . Button::create(_('Hinzufügen'), 'add'); + $output .= "</form>"; + + return $output; +// $output .= parent::getAdminModuleLinks(); + } + + /** + * get new module link + * + * returns link to create a new module if allowed + * @access public + * @return string returns html-code or false + */ + function getNewModuleLink() + { + global $connected_cms, $auth; + $output = "\n"; +// echo "NML."; + if ((Request::get("module_type_" . $this->cms_type) != "")) + { +// echo "TYPE."; + if ($connected_cms[$this->cms_type]->user->category == "") + { +// echo "NoCat."; + $connected_cms[$this->cms_type]->user->newUserCategory(); + if ($connected_cms[$this->cms_type]->user->category == false) + return $output; + } + $output = " " . LinkButton::create(_('Neu anlegen'), URLHelper::getURL($this->cms_link . "?" + . "client_id=" . $connected_cms[$this->cms_type]->getClientId() + . "&cms_select=" . $this->cms_type +// . "&sess_id=" . $connected_cms[$this->cms_type]->user->getSessionId() + . "&ref_id=" . $connected_cms[$this->cms_type]->user->category + . $auth_data + . "&type=" . Request::option("module_type_" . $this->cms_type) . "&target=new"), [ + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ]); +// echo $output . "."; + } + $user_crs_role = $connected_cms[$this->cms_type]->crs_roles[$auth->auth["perm"]]; + if ($user_crs_role=="admin") + return $output; + else + return false; + } + + /** + * get start page link + * + * returns link to ilias start-page + * @access public + * @return string returns url or false + */ + function getStartpageLink() + { + global $connected_cms; + + if ($connected_cms[$this->cms_type]->user->isConnected()) { + $output = $this->cms_link . "?" + . "client_id=" . $connected_cms[$this->cms_type]->getClientId() + . "&cms_select=" . $this->cms_type + . "&target=login"; + } + return $output; + } +} +?> diff --git a/lib/elearning/Ilias3ConnectedPermissions.class.php b/lib/elearning/Ilias3ConnectedPermissions.class.php new file mode 100644 index 0000000..81bb54c --- /dev/null +++ b/lib/elearning/Ilias3ConnectedPermissions.class.php @@ -0,0 +1,260 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +DEFINE ("CRS_NOTIFICATION", "1"); +DEFINE ("CRS_NO_NOTIFICATION", "2"); +DEFINE ("CRS_ADMIN_ROLE", "1"); +DEFINE ("CRS_MEMBER_ROLE", "2"); +DEFINE ("CRS_TUTOR_ROLE", "3"); +DEFINE ("CRS_PASSED_VALUE", "0"); + +DEFINE ("OPERATION_VISIBLE", "visible"); +DEFINE ("OPERATION_READ", "read"); +DEFINE ("OPERATION_WRITE", "write"); +DEFINE ("OPERATION_DELETE", "delete"); +DEFINE ("OPERATION_CREATE_LM", "create_lm"); +DEFINE ("OPERATION_CREATE_TEST", "create_tst"); +DEFINE ("OPERATION_CREATE_QUESTIONS", "create_qps"); +DEFINE ("OPERATION_CREATE_FILE", "create_file"); + +/** +* class to handle ILIAS 3 access controls +* +* This class contains methods to handle permissions on connected objects. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3ConnectedPermission +* @package ELearning-Interface +*/ +class Ilias3ConnectedPermissions extends ConnectedPermissions +{ + var $operations; + var $allowed_operations; + var $tree_allowed_operations; + + var $USER_OPERATIONS; + var $AUTHOR_OPERATIONS; + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + global $connected_cms; + + parent::__construct($cms); + $this->readData(); + + if ($connected_cms[$this->cms_type]->user->isConnected()) + { + $roles = $this->getUserRoles(); + $connected_cms[$this->cms_type]->user->setRoles( $roles ); + } + $this->USER_OPERATIONS = [OPERATION_VISIBLE, OPERATION_READ]; +// $this->AUTHOR_OPERATIONS = array(OPERATION_VISIBLE, OPERATION_READ, OPERATION_CREATE_LM, OPERATION_CREATE_TEST, OPERATION_CREATE_QUESTIONS, OPERATION_CREATE_FILE); + $this->permissions_changed = false; + } + + /** + * read data + * + * reads acces control data from database + * @access public + */ + function readData() + { + global $connected_cms; + +// $this->operations = $this->db_class->getOperations($connected_cms[$this->cms_type]->db); + + $this->operations = $connected_cms[$this->cms_type]->soap_client->getOperations(); + } + + /** + * check user permissions + * + * checks user permissions for connected course and changes setting if necessary + * @access public + * @param string $course_id course-id + * @return boolean returns false on error + */ + function checkUserPermissions($course_id = "") + { + global $connected_cms, $messages; + + if ($course_id == "") + return false; + if ($connected_cms[$this->cms_type]->user->getId() == "") + return false; + + // get course role folder and local roles + $local_roles = $connected_cms[$this->cms_type]->soap_client->getLocalRoles($course_id); + $active_role = ""; + $proper_role = ""; + $user_crs_role = $connected_cms[$this->cms_type]->crs_roles[$perm->get_studip_perm(Context::getId())]; + if (is_array($local_roles)) + foreach ($local_roles as $key => $role_data) + // check only if local role is il_crs_member, -tutor or -admin + if (! (mb_strpos($role_data["title"], "_crs_") === false)) + { + if ( in_array( $role_data["obj_id"], $connected_cms[$this->cms_type]->user->getRoles() ) ) + $active_role = $role_data["obj_id"]; + if ( mb_strpos( $role_data["title"], $user_crs_role) > 0 ) + $proper_role = $role_data["obj_id"]; + } + // if ($GLOBALS["debug"] == true) + // echo "P$proper_role A$active_role U" . $user_crs_role . " R" . implode($connected_cms[$this->cms_type]->user->getRoles(), ".")."<br>"; + + // is user already course-member? otherwise add member with proper role + $is_member = $connected_cms[$this->cms_type]->soap_client->isMember( $connected_cms[$this->cms_type]->user->getId(), $course_id); + if (! $is_member) + { + $member_data["usr_id"] = $connected_cms[$this->cms_type]->user->getId(); + $member_data["ref_id"] = $course_id; + $member_data["status"] = CRS_NO_NOTIFICATION; + $type = ""; + switch ($user_crs_role) + { + case "admin": + $member_data["role"] = CRS_ADMIN_ROLE; + $type = "Admin"; + break; + case "tutor": + $member_data["role"] = CRS_TUTOR_ROLE; + $type = "Tutor"; + break; + case "member": + $member_data["role"] = CRS_MEMBER_ROLE; + $type = "Member"; + break; + default: + } + $member_data["passed"] = CRS_PASSED_VALUE; + if ($type != "") + { + $connected_cms[$this->cms_type]->soap_client->addMember( $connected_cms[$this->cms_type]->user->getId(), $type, $course_id ); + if ($GLOBALS["debug"] == true) + echo "addMember"; + $this->permissions_changed = true; + } + } + + // check if user has proper local role + // if not, change it + if ($active_role != $proper_role) + { + if ($active_role != "") + { + $connected_cms[$this->cms_type]->soap_client->deleteUserRoleEntry( $connected_cms[$this->cms_type]->user->getId(), $active_role); + if ($GLOBALS["debug"] == true) + echo "Role $active_role deleted."; + } + + if ($proper_role != "") + { + $connected_cms[$this->cms_type]->soap_client->addUserRoleEntry( $connected_cms[$this->cms_type]->user->getId(), $proper_role); + if ($GLOBALS["debug"] == true) + echo "Role $proper_role added."; + } + $this->permissions_changed = true; + + } + if (!$this->getContentModulePerms($course_id)) { + $messages["info"] .= _("Für den zugeordneten ILIAS-Kurs konnten keine Berechtigungen ermittelt werden.") . "<br>"; + } + } + + /** + * get user roles + * + * returns roles for current user + * @access public + * @return array role-ids + */ + function getUserRoles() + { + global $connected_cms; + + return $connected_cms[$this->cms_type]->soap_client->getUserRoles($connected_cms[$this->cms_type]->user->getId()); + } + + /** + * get permissions for content module + * + * returns allowed operations for given user and module + * @access public + * @param string $module_id module-id + * @return boolean returns false on error + */ + function getContentModulePerms($module_id) + { + global $connected_cms, $current_module; + + if (is_array($connected_cms[$this->cms_type]->content_module[$current_module]->allowed_operations)) + return true; + $this->allowed_operations = []; + $this->tree_allowed_operations = $connected_cms[$this->cms_type]->soap_client->getObjectTreeOperations( + $module_id, + $connected_cms[$this->cms_type]->user->getId() + ); +// echo "MID".$module_id."UID".$connected_cms[$this->cms_type]->user->getId()."OPS".implode($this->tree_allowed_operations,"-") ; + if (! is_array($this->tree_allowed_operations)) + return false; + + $no_permission = false; + if (isset($current_module)) { //TODO: fixes Warning:Creating default object from empty value - possible side effects + if ((! in_array($this->operations[OPERATION_READ], $this->tree_allowed_operations)) OR (! in_array($this->operations[OPERATION_VISIBLE], $this->tree_allowed_operations))) + $no_permission = true; + + if ($no_permission == false) + $connected_cms[$this->cms_type]->content_module[$current_module]->allowed_operations = $this->tree_allowed_operations; + else + $connected_cms[$this->cms_type]->content_module[$current_module]->allowed_operations = false; + } + return true; + } + + /** + * get operation + * + * returns id for given operation-string + * @access public + * @param string $operation operation + * @return integer operation-id + */ + function getOperation($operation) + { + return $this->operations[$operation]; + } + + /** + * get operation-ids + * + * returns an array of operation-ids + * @access public + * @param string $operation operation + * @return array operation-ids + */ + function getOperationArray($operation) + { + if (is_array($operation)) + { + foreach ($operation as $key => $operation_name) + { + $ops_array[] = $this->operations[$operation_name]; + } + } + else + return false; + return $ops_array; + } +} +?> diff --git a/lib/elearning/Ilias3ConnectedUser.class.php b/lib/elearning/Ilias3ConnectedUser.class.php new file mode 100644 index 0000000..90170f1 --- /dev/null +++ b/lib/elearning/Ilias3ConnectedUser.class.php @@ -0,0 +1,350 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** +* class to handle ILIAS 3 user-accounts +* +* This class contains methods to handle connected ILIAS 3 user-accounts. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3ConnectedUser +* @package ELearning-Interface +*/ +class Ilias3ConnectedUser extends ConnectedUser +{ + var $roles; + var $user_sid; + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms, $user_id = false) + { + global $connected_cms, $perm; + + parent::__construct($cms, $user_id); + // create account automatically if it doesn't exist + if (! $this->isConnected() AND ($connected_cms[$this->cms_type]->USER_AUTO_CREATE == true)) + { + $this->setPassword(md5(uniqid("4dfmjsnll"))); + $this->newUser(true); + $this->readData(); + } + $this->roles = [$connected_cms[$cms]->roles[$perm->get_perm($this->studip_id)]]; + } + + function readData() + { + global $connected_cms; + parent::readData(); + if($this->is_connected){ + $user_id = $connected_cms[$this->cms_type]->soap_client->lookupUser($this->login); + if (!$user_id) { + //do not delete in case of error + if($user_id !== false) { + $query = "DELETE FROM auth_extern WHERE studip_user_id = ? LIMIT 1"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->studip_id]); + } + $this->id = ''; + $this->login = ''; + $this->external_password = ''; + $this->category = ''; + $this->type = ''; + $this->is_connected = false; + } elseif($this->category != ''){ + $cat = $connected_cms[$this->cms_type]->soap_client->checkReferenceById($this->category); + if(!$cat){ + $query = "UPDATE auth_extern SET external_user_category = '' WHERE studip_user_id = ? LIMIT 1"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->studip_id]); + + $this->category = ''; + } + } + } + return $this->is_connected; + } + + /** + * get login-data + * + * gets login-data from database + * @access public + * @param string $username username + * @return boolean returns false, if no data was found + */ + function getLoginData($username) + { + global $connected_cms; + + if (!$username) { + return false; + } + $user_id = $connected_cms[$this->cms_type]->soap_client->lookupUser($username); + + if ($user_id == false) + return false; + + $user_data = $connected_cms[$this->cms_type]->soap_client->getUser($user_id); + + if ($user_data == false) + return false; + + $this->id = $user_data["usr_id"]; + $this->login = $user_data["login"]; + $this->external_password = $user_data["passwd"]; + return true; + } + + /** + * get crypted password + * + * returns ILIAS 3 password + * @access public + * @param string $password password + * @return string password + */ + function getCryptedPassword($password) + { + return md5($password); + } + + /** + * set roles + * + * sets roles + * @access public + * @param array $role_array role-array + */ + function setRoles($role_array) + { + $this->roles = $role_array; + } + + /** + * get roles + * + * returns roles + * @access public + * @return array roles + */ + function getRoles() + { + return $this->roles; + } + + /** + * create new user category + * + * create new user category + * @access public + * @return boolean returns false on error + */ + function newUserCategory() + { + global $connected_cms, $messages; + + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + + // data for user-category in ILIAS 3 + $object_data["title"] = sprintf(_("Eigene Daten von %s (%s)."), $this->getName(), $this->getId()); + $object_data["description"] = sprintf(_("Hier befinden sich die persönlichen Lernmodule des Benutzers %s."), $this->getName()); + $object_data["type"] = "cat"; + $object_data["owner"] = $this->getId(); + + $cat = $connected_cms[$this->cms_type]->soap_client->getReferenceByTitle($object_data["title"]); + if ($cat != false && $connected_cms[$this->cms_type]->soap_client->checkReferenceById($cat) ) + { + $messages["info"] .= sprintf(_("Ihre persönliche Kategorie wurde bereits angelegt."), $this->login) . "<br>\n"; + $this->category = $cat; + } + else + { + $this->category = $connected_cms[$this->cms_type]->soap_client->addObject($object_data, $connected_cms[$this->cms_type]->main_category_node_id); + } + if ($this->category != false) + parent::setConnection( $this->getUserType() ); + else + { + echo "CATEGORY_ERROR".$connected_cms[$this->cms_type]->main_category_node_id ."-"; + return false; + } + // data for personal user-role in ILIAS 3 + $role_data["title"] = "studip_usr" . $this->getId() . "_cat" . $this->category; + $role_data["description"] = sprintf(_("User-Rolle von %s. Diese Rolle wurde von Stud.IP generiert."), $this->getName()); + $role_id = $connected_cms[$this->cms_type]->soap_client->getObjectByTitle($role_data["title"], "role"); + if ($role_id != false) + $messages["info"] .= sprintf(_("Ihre persönliche Userrolle wurde bereits angelegt."), $this->login) . "<br>\n"; + else + $role_id = $connected_cms[$this->cms_type]->soap_client->addRoleFromTemplate($role_data, $this->category, $connected_cms[$this->cms_type]->user_role_template_id); + $connected_cms[$this->cms_type]->soap_client->addUserRoleEntry($this->getId(), $role_id); + // delete permissions for all global roles for this category + foreach ($connected_cms[$this->cms_type]->global_roles as $key => $role) + $connected_cms[$this->cms_type]->soap_client->revokePermissions($role, $this->category); + return true; + } + + /** + * new user + * + * save new user + * @access public + * @return boolean returns false on error + */ + function newUser($ignore_encrypt_passwords = false) + { + global $connected_cms, $auth, $messages; + + if ($this->getLoginData($this->login)) + { + $messages["error"] .= sprintf(_("Es existiert bereits ein Account mit dem Benutzernamen \"%s\"."), $this->login) . "<br>\n"; + return false; + } + + // data for user-account in ILIAS 3 + $user_data["login"] = $this->login; + $user_data["passwd"] = $this->external_password; + $user_data["firstname"] = $this->firstname; + $user_data["lastname"] = $this->lastname; + $user_data["title"] = $this->title; + $user_data["gender"] = $this->gender; + $user_data["email"] = $this->email; + $user_data["street"] = $this->street; + $user_data["phone_home"] = $this->phone_home; + $user_data["time_limit_unlimited"] = 1; + $user_data["active"] = 1; + $user_data["approve_date"] = date('Y-m-d H:i:s'); + $user_data["accepted_agreement"] = true; + + if ($connected_cms[$this->cms_type]->user_style != "") + $user_data["user_style"] = $connected_cms[$this->cms_type]->user_style; + if ($connected_cms[$this->cms_type]->user_skin != "") + $user_data["user_skin"] = $connected_cms[$this->cms_type]->user_skin; + + $role_id = $connected_cms[$this->cms_type]->roles[$auth->auth["perm"]]; + + $user_id = $connected_cms[$this->cms_type]->soap_client->addUser($user_data, $role_id); + + if ($user_id != false) + { + $this->id = $user_id; + +// $connected_cms[$this->cms_type]->soap_client->updatePassword($user_id, $user_data["passwd"]); + +// $this->newUserCategory(); + + $this->setConnection(USER_TYPE_CREATED, $ignore_encrypt_passwords); + return true; + } + echo $connected_cms[$this->cms_type]->soap_client->getError(); + return false; + } + + /** + * update user + * + * update user-account + * @access public + * @return boolean returns false on error + */ + function updateUser() + { + } + + /** + * delete user + * + * delete user-account + * @access public + * @return boolean returns false on error + */ + function deleteUser() + { + global $connected_cms; + $ret = null; + $connected_cms[$this->cms_type]->soap_client->user_type == "admin"; + $connected_cms[$this->cms_type]->soap_client->caching_active = false; + if($this->category){ + $ret['cat_deleted'] = $connected_cms[$this->cms_type]->soap_client->deleteObject($this->category); + } + if($this->type == 0 && $this->id){ + $ret['iliasuser_deleted'] = $connected_cms[$this->cms_type]->soap_client->deleteUser($this->id); + } + $query = "DELETE FROM auth_extern WHERE studip_user_id = ? LIMIT 1"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->studip_id]); + + $ret['auth_extern_deleted'] = $statement->rowCount(); + return $ret; + } + + /** + * set connection + * + * set user connection + * @access public + * @param string user_type user-type + * @return boolean returns false on error + */ + function setConnection($user_type, $ignore_encrypt_passwords = false) + { + global $connected_cms; + + if (!$ignore_encrypt_passwords && $connected_cms[$this->cms_type]->encrypt_passwords == "md5") + { +// echo "PASSWORD-ENCRYPTION"; + $this->external_password = $this->getCryptedPassword( $this->external_password ); + } + + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + parent::setConnection($user_type); + } + + /** + * get sid + * + * returns soap-sid + * @access public + * @return string soap-sid + */ + function getSID() + { + global $connected_cms; + + $caching_status = $connected_cms[$this->cms_type]->soap_client->getCachingStatus(); + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + + $connected_cms[$this->cms_type]->soap_client->setUserType("user"); + $this->user_sid = $connected_cms[$this->cms_type]->soap_client->login(); + + $connected_cms[$this->cms_type]->soap_client->setCachingStatus($caching_status); + $connected_cms[$this->cms_type]->soap_client->setUserType("admin"); + return $this->user_sid; + } + + /** + * get session-id + * + * returns soap-session-id + * @access public + * @return string soap-session-id + */ + function getSessionId() + { + $sid = $this->getSID(); + if ($sid == false) + return false; + $arr = explode("::", $sid); + return $arr[0]; + } +} +?> diff --git a/lib/elearning/Ilias3ContentModule.class.php b/lib/elearning/Ilias3ContentModule.class.php new file mode 100644 index 0000000..1304c6c --- /dev/null +++ b/lib/elearning/Ilias3ContentModule.class.php @@ -0,0 +1,297 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** +* class to handle ILIAS 3 learning modules and tests +* +* This class contains methods to handle ILIAS 3 learning modules and tests. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3ContentModule +* @package ELearning-Interface +*/ +class Ilias3ContentModule extends ContentModule +{ + var $object_id; + + /** + * constructor + * + * init class. + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param string $cms_type system-type + */ + function __construct($module_id = "", $module_type, $cms_type) + { + parent::__construct($module_id, $module_type, $cms_type); + if ($module_id != "") + $this->readData(); + } + + /** + * read data + * + * get module data from database. + * @access public + */ + function readData() + { + global $connected_cms; + + $object_data = $connected_cms[$this->cms_type]->soap_client->getObjectByReference($this->id, $connected_cms[$this->cms_type]->user->getId()); + if ( (! ($object_data == false)) AND ($connected_cms[$this->cms_type]->types[$object_data["type"]] != "") ) + { + // If User has no external Account, show module and link to user-assignment + if (! $connected_cms[$this->cms_type]->user->isConnected()) + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ] ); + + //set module data + $this->setObjectId($object_data["obj_id"]); + $this->setTitle($object_data["title"]); + $this->setDescription($object_data["description"]); + if ($object_data["owner"] != "") + { + $user_data = $connected_cms[$this->cms_type]->soap_client->getUser($object_data["owner"]); + $user_name = trim($user_data["title"] . " " . $user_data["firstname"] . " " . $user_data["lastname"]); + $this->setAuthors($user_name); + } +// echo $object_data["accessInfo"] . ": " . implode($object_data["operations"], "."); + $this->setPermissions($object_data["accessInfo"], $object_data["operations"]); + } + else + { + // If module doesn't exist, show errormessage + $this->createDummyForErrormessage("not found"); + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ, OPERATION_DELETE] ); + } + } + + /** + * set permissions + * + * sets permissions for content-module + * @access public + * @param string $acces_info access-status + * @param array $operations array of operations + * @return boolean successful + */ + function setPermissions($access_info, $operations) + { + global $connected_cms; + + switch ($access_info) + { + case "granted": + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray($operations ); + break; + case "no_permission": + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray($operations ); + $this->setDescription($object_data["description"] . "<br><br><i>" . _("Sie haben keine Leseberechtigung für dieses Modul.") . "</i>"); + return false; + break; + case "missing_precondition": + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray($operations ); + $this->setDescription($object_data["description"] . "<br><br><i>" . _("Sie haben zur Zeit noch keinen Zugriff auf deses Modul (fehlende Vorbedingungen).") . "</i>"); + break; + case "no_object_access": + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray($operations ); + $this->setDescription($object_data["description"] . "<br><br><i>" . _("Dieses Modul ist momentan offline oder durch Payment-Regeln gesperrt.") . "</i>"); + break; + case "no_parent_access": + $this->allowed_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray($operations ); + $this->setDescription($object_data["description"] . "<br><br><i>" . _("Sie haben keinen Zugriff auf die übergeordneten Objekte dieses Moduls.") . "</i>"); + return false; + break; + case "object_deleted": + $this->createDummyForErrormessage("deleted"); + return false; + break; + } + if ($connected_cms[$this->cms_type]->isAuthNecessary() AND ($connected_cms[$this->cms_type]->user->isConnected())) + { + // If User has no permission, don't show module data + if ((! $this->isAllowed(OPERATION_VISIBLE) ) AND (! $this->isDummy()) AND ($connected_cms[$this->cms_type]->user->isConnected())) + $this->createDummyForErrormessage("no permission"); + } + +// echo "PERM".implode($this->allowed_operations,"-"); + } + + /** + * set connection + * + * sets connection with seminar + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function setConnection($seminar_id) + { + global $connected_cms, $messages; + + $write_permission = Request::option("write_permission"); + $write_permission_autor = Request::option("write_permission_autor"); + + $crs_id = ObjectConnections::getConnectionModuleId($seminar_id, "crs", $this->cms_type); +// echo "SET?".$this->cms_type; + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + $connected_cms[$this->cms_type]->soap_client->clearCache(); + + // Check, ob Kurs in ILIAS gelöscht wurde + if (($crs_id != false) AND ($connected_cms[$this->cms_type]->soap_client->getObjectByReference($crs_id) == false)) + { + ObjectConnections::unsetConnection($seminar_id, $crs_id, "crs", $this->cms_type); +// echo "deleted: ".ObjectConnections::getConnectionModuleId($seminar_id, "crs", $this->cms_type); +// echo "Der zugeordnete ILIAS-Kurs (ID $crs_id) existiert nicht mehr. Ein neuer Kurs wird angelegt."; + $messages["info"] .= _("Der zugeordnete ILIAS-Kurs (ID $crs_id) existiert nicht mehr. Ein neuer Kurs wird angelegt.") . "<br>"; + $crs_id = false; + } + + if ($crs_id == false) + { + + $lang_array = explode("_",Config::get()->DEFAULT_LANGUAGE); + $course_data["language"] = $lang_array[0]; + $course_data["title"] = "Stud.IP-Kurs " . Context::get()->Name; + $course_data["description"] = ""; + $ref_id = $connected_cms[$this->cms_type]->main_category_node_id; + $crs_id = $connected_cms[$this->cms_type]->soap_client->addCourse($course_data, $ref_id); + + if ($crs_id == false) + { + $messages["error"] .= _("Zuordnungs-Fehler: Kurs konnte nicht angelegt werden."); + return false; + } + ObjectConnections::setConnection($seminar_id, $crs_id, "crs", $this->cms_type); + + // Rollen zuordnen + $connected_cms[$this->cms_type]->permissions->CheckUserPermissions($crs_id); +// $messages["info"] .= "Neue Kurs-ID: $crs_id. <br>"; + } + + + $ref_id = $this->getId(); + $ref_id = $connected_cms[$this->cms_type]->soap_client->addReference($this->id, $crs_id); + $local_roles = $connected_cms[$this->cms_type]->soap_client->getLocalRoles($crs_id); + $member_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ]); + $admin_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ, OPERATION_WRITE]); + foreach ($local_roles as $key => $role_data){ + // check only if local role is il_crs_member, -tutor or -admin + if (mb_strpos($role_data["title"], "il_crs_") === 0) { + if(mb_strpos($role_data["title"], 'il_crs_member') === 0){ + $operations = $write_permission_autor ? $admin_operations : $member_operations; + } else if(mb_strpos($role_data["title"], 'il_crs_tutor') === 0){ + $operations = $write_permission_autor || $write_permission ? $admin_operations : $member_operations; + } else { + continue; + } + $connected_cms[$this->cms_type]->soap_client->revokePermissions($role_data["obj_id"], $ref_id); + $connected_cms[$this->cms_type]->soap_client->grantPermissions($operations, $role_data["obj_id"], $ref_id); + } + } + if ($ref_id) + { + $this->setId($ref_id); + return parent::setConnection($seminar_id); + } + else + $messages["error"] .= _("Die Zuordnung konnte nicht gespeichert werden."); + return false; + } + + /** + * unset connection + * + * unsets connection with seminar + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function unsetConnection($seminar_id) + { + global $connected_cms, $messages; + + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + { + if ( $this->getObjectId() != false) + $connected_cms[$this->cms_type]->soap_client->deleteObject($this->getId()); + return parent::unsetConnection($seminar_id); + } + $messages["error"] .= _("Die Zuordnung konnte nicht entfernt werden."); + return false; + } + + /** + * set object id + * + * sets object id + * @access public + * @param string $module_object_id object id + */ + function setObjectId($module_object_id) + { + $this->object_id = $module_object_id; + } + + /** + * get object id + * + * returns object id + * @access public + * @return string object id + */ + function getObjectId() + { + return $this->object_id; + } + + /** + * set allowed operations + * + * sets allowed operations + * @access public + * @param array $operation_array operation-ids + */ + function setAllowedOperations( $operation_array ) + { + global $connected_cms; + + $this->allowed_operations = []; + foreach($operation_array as $key => $operation) + { +// echo "O$operation = I".$connected_cms[$this->cms_type]->permissions->getOperation[$operation]."<br>"; + $this->allowed_operations[] = $connected_cms[$this->cms_type]->permissions->getOperation[$operation]; + } + } + + /** + * get permission-status + * + * returns true, if operation is allowed + * @access public + * @param string $operation operation + * @return boolean allowed + */ + function isAllowed($operation) + { + global $connected_cms; + + if (is_array($this->allowed_operations)) + { + if (in_array($connected_cms[$this->cms_type]->permissions->getOperation($operation), $this->allowed_operations)) + return true; + else + return false; + } + else + return false; + } +} +?> diff --git a/lib/elearning/Ilias3ObjectXMLParser.class.php b/lib/elearning/Ilias3ObjectXMLParser.class.php new file mode 100644 index 0000000..2dc76b4 --- /dev/null +++ b/lib/elearning/Ilias3ObjectXMLParser.class.php @@ -0,0 +1,239 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/* + +-----------------------------------------------------------------------------+ + | ILIAS open source | + +-----------------------------------------------------------------------------+ + | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | + | | + | This program is free software; you can redistribute it and/or | + | modify it under the terms of the GNU General Public License | + | as published by the Free Software Foundation; either version 2 | + | of the License, or (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of the GNU General Public License | + | along with this program; if not, write to the Free Software | + | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | + +-----------------------------------------------------------------------------+ +*/ + + +/** +* Object XML Parser +* +* @author Stefan Meyer <smeyer@databay.de> +* +* @extends ilSaxParser +* @package common +*/ + +class Ilias3ObjectXMLParser extends Ilias3SaxParser +{ + var $object_data = []; + + /** + * Constructor + * + * @param object $a_content_object must be of type ilObjContentObject + * ilObjTest or ilObjQuestionPool + * @param string $a_xml_file xml data + * @param string $a_subdir subdirectory in import directory + * @access public + */ + function __construct($a_xml_data = '') + { + parent::__construct(); + $this->setXMLContent($a_xml_data); + } + + function getObjectData() + { + return $this->object_data ? $this->object_data : []; + } + + /** + * set event handlers + * + * @param resource reference to the xml parser + * @access private + */ + function setHandlers($a_xml_parser) + { + xml_set_object($a_xml_parser,$this); + xml_set_element_handler($a_xml_parser,'handlerBeginTag','handlerEndTag'); + xml_set_character_data_handler($a_xml_parser,'handlerCharacterData'); + } + + + + + /** + * handler for begin of element + * + * @param resource $a_xml_parser xml parser + * @param string $a_name element name + * @param array $a_attribs element attributes array + */ + function handlerBeginTag($a_xml_parser,$a_name,$a_attribs) + { + + switch($a_name) + { + case 'Objects': + $this->curr_obj = -1; + break; + + case 'Object': + ++$this->curr_obj; + $this->reference_count = -1; + + $this->addProperty__('type',$a_attribs['type']); + $this->addProperty__('obj_id',$a_attribs['obj_id']); + break; + + case 'Title': + break; + + case 'Description': + break; + + case 'Owner': + break; + + case 'CreateDate': + break; + + case 'LastUpdate': + break; + + case 'ImportId': + break; + + case 'References': + ++$this->reference_count; + $this->addReference__($a_attribs['ref_id'], $a_attribs['accessInfo']); + break; + + case 'Operation': + break; + } + } + + + + /** + * handler for end of element + * + * @param resource $a_xml_parser xml parser + * @param string $a_name element name + */ + function handlerEndTag($a_xml_parser,$a_name) + { + switch($a_name) + { + case 'Objects': + break; + + case 'Object': + break; + + case 'Title': + $this->addProperty__('title',trim($this->cdata)); + break; + + case 'Description': + $this->addProperty__('description',trim($this->cdata)); + break; + + case 'Owner': + $this->addProperty__('owner',trim($this->cdata)); + break; + + case 'CreateDate': + $this->addProperty__('create_date',trim($this->cdata)); + break; + + case 'LastUpdate': + $this->addProperty__('last_update',trim($this->cdata)); + break; + + case 'ImportId': + $this->addProperty__('import_id',trim($this->cdata)); + break; + + case 'References': + $this->addReference__(trim($this->cdata)); + break; + + case 'Operation': + $this->addOperation__(trim($this->cdata)); + break; + } + + $this->cdata = ''; + + return; + } + + /** + * handler for character data + * + * @param resource $a_xml_parser xml parser + * @param string $a_data character data + */ + function handlerCharacterData($a_xml_parser,$a_data) + { + if($a_data != "\n") + { + // Replace multiple tabs with one space + $a_data = preg_replace("/\t+/"," ",$a_data); + + $this->cdata .= $a_data; + } + + + } + + // PRIVATE + function addProperty__($a_name,$a_value) + { + $this->object_data[$this->curr_obj][$a_name] = $a_value; + /*/ + if (is_array($this->object_data[$this->curr_obj][$a_name])) + $this->object_data[$this->curr_obj][$a_name][] = $a_value; + elseif ($this->object_data[$this->curr_obj][$a_name] != "") + { + $old_value = $this->object_data[$this->curr_obj][$a_name]; + $this->object_data[$this->curr_obj][$a_name] = array($old_value); + $this->object_data[$this->curr_obj][$a_name][] = $a_value; + } + else + $this->object_data[$this->curr_obj][$a_name] = $a_value; + /**/ + } + + function addReference__($a_value, $a_accessinfo = "") + { + if($a_value) + { + $this->object_data[$this->curr_obj]['references'][$this->reference_count]["ref_id"] = $a_value; + $this->object_data[$this->curr_obj]['references'][$this->reference_count]["accessInfo"] = $a_accessinfo; + } + } + + function addOperation__($a_value) + { + if($a_value) + $this->object_data[$this->curr_obj]['references'][$this->reference_count]["operations"][] = $a_value; + } + +} +?>
\ No newline at end of file diff --git a/lib/elearning/Ilias3SaxParser.class.php b/lib/elearning/Ilias3SaxParser.class.php new file mode 100644 index 0000000..92d247d --- /dev/null +++ b/lib/elearning/Ilias3SaxParser.class.php @@ -0,0 +1,230 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO +/* + +-----------------------------------------------------------------------------+ + | ILIAS open source | + +-----------------------------------------------------------------------------+ + | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | + | | + | This program is free software; you can redistribute it and/or | + | modify it under the terms of the GNU General Public License | + | as published by the Free Software Foundation; either version 2 | + | of the License, or (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of the GNU General Public License | + | along with this program; if not, write to the Free Software | + | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | + +-----------------------------------------------------------------------------+ +*/ + + +/** +* Base class for sax-based expat parsing +* extended classes need to overwrite the method setHandlers and implement their own handler methods +* +* +* @author Stefan Meyer <smeyer@databay> +* +* @package ilias-core +*/ +class Ilias3SaxParser +{ + /** + * XML-Content type 'file' or 'string' + * If you choose file set the filename in constructor + * If you choose 'String' call the constructor with no argument and use setXMLContent() + * @var string + * @access private + */ + var $input_type = null; + + /** + * XML-Content in case of content type 'string' + + * @var string + * @access private + */ + var $xml_content = ''; + + /** + * ilias object + * @var object ilias + * @access private + */ + var $ilias; + + /** + * language object + * @var object language + * @access private + */ + var $lng; + + /** + * xml filename + * @var filename + * @access private + */ + var $xml_file; + + /** + * Constructor + * setup ILIAS global object + * @access public + */ + function __construct($a_xml_file = '') + { + global $ilias, $lng; + + if($a_xml_file) + { + $this->xml_file = $a_xml_file; + $this->input_type = 'file'; + } + + $this->ilias = &$ilias; + $this->lng = &$lng; + } + + function setXMLContent($a_xml_content) + { + $this->xml_content = $a_xml_content; + $this->input_type = 'string'; + } + + function getXMLContent() + { + return $this->xml_content; + } + + function getInputType() + { + return $this->input_type; + } + + /** + * stores xml data in array + * + * @access private + */ + function startParsing() + { + $xml_parser = $this->createParser(); + $this->setOptions($xml_parser); + $this->setHandlers($xml_parser); + + switch($this->getInputType()) + { + case 'file': + $fp = $this->openXMLFile(); + $this->parse($xml_parser,$fp); + break; + + case 'string': + $this->parse($xml_parser); + break; + + default: + echo "No input type given. Set filename in constructor or choose setXMLContent()"; + break; + } + $this->freeParser($xml_parser); + } + /** + * create parser + * + * @access private + */ + function createParser() + { + $xml_parser = xml_parser_create("UTF-8"); + + if($xml_parser == false) + { + echo "Cannot create an XML parser handle"; + } + return $xml_parser; + } + /** + * set parser options + * + * @access private + */ + function setOptions($a_xml_parser) + { + xml_parser_set_option($a_xml_parser,XML_OPTION_CASE_FOLDING,false); + } + /** + * set event handler + * should be overwritten by inherited class + * @access private + */ + function setHandlers($a_xml_parser) + { + echo 'ilSaxParser::setHandlers() must be overwritten'; + } + /** + * open xml file + * + * @access private + */ + function openXMLFile() + { + if(!($fp = fopen($this->xml_file,'r'))) + { + echo "Cannot open xml file"; + } + return $fp; + } + /** + * parse xml file + * + * @access private + */ + function parse($a_xml_parser,$a_fp = null) + { + switch($this->getInputType()) + { + case 'file': + + while($data = fread($a_fp,4096)) + { + $parseOk = xml_parse($a_xml_parser,$data,feof($a_fp)); + } + break; + + case 'string': + $parseOk = xml_parse($a_xml_parser,$this->getXMLContent()); + break; + } + if(!$parseOk + && (xml_get_error_code($a_xml_parser) != XML_ERROR_NONE)) + { + echo $this->getXMLContent(); + echo "XML Parse Error: ".xml_get_error_code($a_xml_parser); + } + return true; + + } + /** + * free xml parser handle + * + * @access private + */ + function freeParser($a_xml_parser) + { + if(!xml_parser_free($a_xml_parser)) + { + echo "Error freeing xml parser handle "; + } + } +} +?> diff --git a/lib/elearning/Ilias3Soap.class.php b/lib/elearning/Ilias3Soap.class.php new file mode 100644 index 0000000..98627de --- /dev/null +++ b/lib/elearning/Ilias3Soap.class.php @@ -0,0 +1,1070 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** +* class to use ILIAS-3-Webservices +* +* This class contains methods to connect to the ILIAS-3-Soap-Server. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module Ilias3Soap +* @package ELearning-Interface +*/ +class Ilias3Soap extends StudipSoapClient +{ + var $cms_type; + var $admin_sid; + var $user_sid; + var $user_type; + var $soap_cache; + + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + $this->cms_type = $cms; + + parent::__construct($ELEARNING_INTERFACE_MODULES[$cms]["ABSOLUTE_PATH_SOAP"]); + $this->user_type = "admin"; + + $this->loadCacheData($cms); + $this->caching_active = false; + } + + + + /** + * set usertype + * + * sets usertype fpr soap-calls + * @access public + * @param string user_type usertype (admin or user) + */ + function setUserType($user_type) + { + $this->user_type = $user_type; + } + + /** + * get sid + * + * returns soap-session-id + * @access public + * @return string session-id + */ + function getSID() + { + if ($this->user_type == "admin") + { + if ($this->admin_sid == false) + $this->login(); +// echo "a"; + return $this->admin_sid; + } + if ($this->user_type == "user") + { + if ($this->user_sid == false) + $this->login(); +// echo "u"; + return $this->user_sid; + } + return false; + } + + /** + * call soap-function + * + * calls soap-function with given parameters + * @access public + * @param string method method-name + * @param string params parameters + * @return mixed result + */ + function call($method, $params) + { + $index = md5($method . ":" . implode($params, "-")); + // return false if no session_id is given + if (($method != "login") AND ($params["sid"] == "")) + return false; +// echo $this->caching_active; + if (($this->caching_active == true) AND (isset($this->soap_cache[$index]))) + { +// echo $index; +// echo " from Cache<br>"; + $result = $this->soap_cache[$index]; + } + else + { + $result = $this->_call($method, $params); + // if Session is expired, re-login and try again + if (($method != "login") AND $this->soap_client->fault AND in_array(mb_strtolower($this->faultstring), ["session not valid","session invalid", "session idled"]) ) + { +// echo "LOGIN AGAIN."; + $caching_status = $this->caching_active; + $this->caching_active = false; + $params["sid"] = $this->login(); + $result = $this->_call($method, $params); + $this->caching_active = $caching_status; + } + elseif (! $this->soap_client->fault) + $this->soap_cache[$index] = $result; + } + return $result; + } + + /** + * load cache + * + * load soap-cache + * @access public + * @param string cms cms-type + */ + function loadCacheData($cms) + { + $this->soap_cache = (array)$_SESSION["cache_data"][$cms]; + } + + /** + * get caching status + * + * gets caching-status + * @access public + * @return boolean status + */ + function getCachingStatus() + { + return $this->caching_active; + } + + /** + * set caching status + * + * sets caching-status + * @access public + * @param boolean bool_value status + */ + function setCachingStatus($bool_value) + { + $this->caching_active = $bool_value; +// echo "SET:".$this->caching_active."<br>"; + } + + /** + * clear cache + * + * clears cache + * @access public + */ + function clearCache() + { + $this->soap_cache = []; + $_SESSION["cache_data"][$this->cms_type] = []; + + } + + /** + * save cache + * + * saves soap-cache in session-variable + * @access public + */ + function saveCacheData() + { + $_SESSION["cache_data"][$this->cms_type] = $this->soap_cache; + + } + + /** + * parse xml + * + * use xml-parser + * @access public + * @param string data xml-data + * @return array object + */ + function ParseXML($data) + { + $xml_parser = new Ilias3ObjectXMLParser($data); + $xml_parser->startParsing(); + return $xml_parser->getObjectData(); + } + + /** + * login + * + * login to soap-webservice + * @access public + * @return string result + */ + function login() + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + if ($this->user_type == "admin") + $param = [ + 'client' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["client"], + 'username' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["username"], + 'password' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["password"] + ]; + elseif ($this->user_type == "user") + $param = [ + 'client' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["client"], + 'username' => $connected_cms[$this->cms_type]->user->getUsername(), + 'password' => $connected_cms[$this->cms_type]->user->getPassword() + ]; + $result = $this->call('login', $param); + if ($this->user_type == "admin") + $this->admin_sid = $result; + if ($this->user_type == "user") + $this->user_sid = $result; +// if ($this->user_type == "user") echo "SID".$this->call('login', $param).$param["username"]; + return $result; + } + + /** + * logout + * + * logout from soap-webservice + * @access public + * @return boolean result + */ + function logout() + { + $param = [ + 'sid' => $this->getSID() + ]; + return $this->call('logout', $param); + } + + +/////////////////////////// +// OBJECT-FUNCTIONS // +////////////////////////// + + /** + * search objects + * + * search for ilias-objects + * @access public + * @param array types types + * @param string key keyword + * @param string combination search-combination + * @param string user_id ilias-user-id + * @return array objects + */ + function searchObjects($types, $key, $combination, $user_id = "") + { + $param = [ + 'sid' => $this->getSID(), + 'types' => $types, + 'key' => $key, + 'combination' => $combination + ]; + if ($user_id != "") + $param["user_id"] = $user_id; + $result = $this->call('searchObjects', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + $all_objects = []; + foreach($objects as $count => $object_data){ + if (is_array($object_data["references"])) + { + foreach($object_data["references"] as $ref_data) + if ($ref_data["accessInfo"] == "granted" + && (count($all_objects[$object_data["obj_id"]]["operations"]) < count($ref_data["operations"]))) + { + $all_objects[$object_data["obj_id"]] = $object_data; + unset($all_objects[$object_data["obj_id"]]["references"]); + $all_objects[$object_data["obj_id"]]["ref_id"] = $ref_data["ref_id"]; + $all_objects[$object_data["obj_id"]]["accessInfo"] = $ref_data["accessInfo"]; + $all_objects[$object_data["obj_id"]]["operations"] = $ref_data["operations"]; + } + } + } + if (count($all_objects)){ + foreach($all_objects as $one_object){ + $ret[$one_object['ref_id']] = $one_object; + } + return $ret; + } + } + return false; + + } + + /** + * get object by reference + * + * gets object by reference-id + * @access public + * @param ref reference_id + * @param string user_id ilias-user-id + * @return array object + */ + function getObjectByReference($ref, $user_id = "") + { + $param = [ + 'sid' => $this->getSID(), + 'reference_id' => $ref + ]; + if ($user_id != "") + $param["user_id"] = $user_id; + $result = $this->call('getObjectByReference', $param); + if ($result != false) + { + + $objects = $this->parseXML($result); + foreach($objects as $count => $object_data) + if (is_array($object_data["references"])) + { + foreach($object_data["references"] as $ref_data) + if ($ref_data["accessInfo"] != "object_deleted" && $ref == $ref_data["ref_id"]) + { + $all_objects[$ref_data["ref_id"]] = $object_data; + unset($all_objects[$ref_data["ref_id"]]["references"]); + $all_objects[$ref_data["ref_id"]]["ref_id"] = $ref_data["ref_id"]; + $all_objects[$ref_data["ref_id"]]["accessInfo"] = $ref_data["accessInfo"]; + $all_objects[$ref_data["ref_id"]]["operations"] = $ref_data["operations"]; + } + } + return $all_objects[$ref]; + } + return false; + } + + /** + * get object by title + * + * gets object by title + * @access public + * @param string key keyword + * @param string type object-type + * @return array object + */ + function getObjectByTitle($key, $type = "") + { + $param = [ + 'sid' => $this->getSID(), + 'title' => $key + ]; + $result = $this->call('getObjectsByTitle', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + foreach($objects as $index => $object_data) + { + if (($type != "") AND ($object_data["type"] != $type)) + unset($objects[$index]); + elseif (! (mb_strpos(mb_strtolower($object_data["title"]), mb_strtolower(trim($key)) ) === 0)) + unset($objects[$index]); + } + reset($objects); + if (sizeof($objects) > 0) + return current($objects); + } + return false; + } + + /** + * get reference by title + * + * gets reference-id by object-title + * @access public + * @param string key keyword + * @param string type object-type + * @return string reference-id + */ + function getReferenceByTitle($key, $type = "") + { + $param = [ + 'sid' => $this->getSID(), + 'title' => $key + ]; + $result = $this->call('getObjectsByTitle', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + foreach($objects as $index => $object_data) + { + if (($type != "") AND ($object_data["type"] != $type)) + unset($objects[$index]); + elseif (mb_strpos(mb_strtolower($object_data["title"]), mb_strtolower(trim($key)) ) === false) + unset($objects[$index]); + } + if (sizeof($objects) > 0) + foreach($objects as $object_data) + if (sizeof($object_data["references"]) > 0) + { + return $object_data["references"][0]["ref_id"]; + } + } + return false; + } + + /** + * add object + * + * adds new ilias-object + * @access public + * @param array object_data object-data + * @param string ref_id reference-id + * @return string result + */ + function addObject($object_data, $ref_id) + { + $type = $object_data["type"]; + $title = htmlReady($object_data["title"]); + $description = htmlReady($object_data["description"]); + + $xml = "<!DOCTYPE Objects SYSTEM \"http://www.ilias.uni-koeln.de/download/dtd/ilias_object_0_1.dtd\"> +<Objects> + <Object type=\"$type\"> + <Title> + $title + </Title> + <Description> + $description + </Description> + </Object> +</Objects>"; + + $param = [ + 'sid' => $this->getSID(), + 'target_id' => $ref_id, + 'object_xml' => $xml + ]; + return $this->call('addObject', $param); + } + + /** + * delete object + * + * deletes ilias-object + * @access public + * @param string ref_id reference-id + * @return boolean result + */ + function deleteObject($reference_id) + { + $param = [ + 'sid' => $this->getSID(), + 'reference_id' => $reference_id + ]; + return $this->call('deleteObject', $param); + } + + /** + * add reference + * + * add a new reference to an existing ilias-object + * @access public + * @param string object_id source-object-id + * @param string ref_id target-id + * @return string created reference-id + */ + function addReference($object_id, $ref_id) + { + $param = [ + 'sid' => $this->getSID(), + 'source_id' => $object_id, + 'target_id' => $ref_id + ]; + return $this->call('addReference', $param); + } + + /** + * get tree childs + * + * gets child-objects of the given tree node + * @access public + * @param string ref_id reference-id + * @param array types show only childs with these types + * @param string user_id user-id for permissions + * @return array objects + */ + function getTreeChilds($ref_id, $types = "", $user_id = "") + { + if ($types == "") + $types = []; + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id, + 'types' => $types + ]; + if ($user_id != "") + $param["user_id"] = $user_id; + $result = $this->call('getTreeChilds', $param); + if ($result != false) + { + + $objects = $this->parseXML($result); + foreach($objects as $count => $object_data) + if (is_array($object_data["references"])) + foreach($object_data["references"] as $ref_data) + if ($ref_data["accessInfo"] != "object_deleted") + { + $all_objects[$ref_data["ref_id"]] = $object_data; +// unset($all_objects[$ref_id]["references"]); + $all_objects[$ref_data["ref_id"]]["ref_id"] = $ref_data["ref_id"]; + $all_objects[$ref_data["ref_id"]]["accessInfo"] = $ref_data["accessInfo"]; + $all_objects[$ref_data["ref_id"]]["operations"] = $ref_data["operations"]; + } + if (sizeof($all_objects) > 0) { + return $all_objects; + } else { + return []; + } + } + return false; + } + +///////////////////////// +// RBAC-FUNCTIONS // +/////////////////////// + /** + * get operation + * + * gets all ilias operations + * @access public + * @return array operations + */ + function getOperations() + { + $param = [ + 'sid' => $this->getSID() + ]; + $result = $this->call('getOperations', $param); + if (is_array($result)) + foreach ($result as $operation_set) + $operations[$operation_set["operation"]] = $operation_set["ops_id"]; + return $operations; + } + + /** + * get object tree operations + * + * gets permissions for object at given tree-node + * @access public + * @param string ref_id reference-id + * @param string user_id user-id for permissions + * @return array operation-ids + */ + function getObjectTreeOperations($ref_id, $user_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id, + 'user_id' => $user_id + ]; + $result = $this->call('getObjectTreeOperations', $param); + if ($result != false) + { + $ops_ids = []; + foreach ($result as $operation_set) + $ops_ids[] = $operation_set["ops_id"]; + return $ops_ids; + } + return false; + } + + /** + * get user roles + * + * gets user roles + * @access public + * @param string user_id user-id + * @return array role-ids + */ + function getUserRoles($user_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id + ]; + $result = $this->call('getUserRoles', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + $roles = []; + foreach ($objects as $count => $role) + $roles[$count] = $role["obj_id"]; +// echo implode($roles, "."); + return $roles; + } + return false; + } + + /** + * get local roles + * + * gets local roles for given object + * @access public + * @param string course_id object-id + * @return array role-objects + */ + function getLocalRoles($course_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $course_id + ]; + $result = $this->call('getLocalRoles', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + return $objects; + } + return false; + } + + /** + * add role + * + * adds a new role + * @access public + * @param array role_data data for role-object + * @param string ref_id reference-id + * @return string role-id + */ + function addRole($role_data, $ref_id) + { + $type = "role"; + $title = htmlReady($role_data["title"]); + $description = htmlReady($role_data["description"]); + + $xml = "<!DOCTYPE Objects SYSTEM \"http://www.ilias.uni-koeln.de/download/dtd/ilias_object_0_1.dtd\"> +<Objects> + <Object type=\"$type\"> + <Title> + $title + </Title> + <Description> + $description + </Description> + </Object> +</Objects>"; + + $param = [ + 'sid' => $this->getSID(), + 'target_id' => $ref_id, + 'obj_xml' => $xml + ]; + $result = $this->call('addRole', $param); + if (is_array($result)) + return current($result); + else + return false; + } + + /** + * add role from tremplate + * + * adds a new role and adopts properties of the given role template + * @access public + * @param array role_data data for role-object + * @param string ref_id reference-id + * @param string role_id role-template-id + * @return string role-id + */ + function addRoleFromTemplate($role_data, $ref_id, $role_id) + { + $type = "role"; + $title = htmlReady($role_data["title"]); + $description = htmlReady($role_data["description"]); + + $xml = "<!DOCTYPE Objects SYSTEM \"http://www.ilias.uni-koeln.de/download/dtd/ilias_object_0_1.dtd\"> +<Objects> + <Object type=\"$type\"> + <Title> + $title + </Title> + <Description> + $description + </Description> + </Object> +</Objects>"; + + $param = [ + 'sid' => $this->getSID(), + 'target_id' => $ref_id, + 'obj_xml' => $xml, + 'role_template_id' => $role_id + ]; + $result = $this->call('addRoleFromTemplate', $param); + if (is_array($result)) + return current($result); + else + return false; + } + + /** + * delete user role entry + * + * deletes a role entry from the given user + * @access public + * @param string user_id user-id + * @param string role_id role-id + * @return boolean result + */ + function deleteUserRoleEntry($user_id, $role_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id, + 'role_id' => $role_id + ]; + return $this->call('deleteUserRoleEntry', $param); + } + + /** + * add user role entry + * + * adds a role entry for the given user + * @access public + * @param string user_id user-id + * @param string role_id role-id + * @return boolean result + */ + function addUserRoleEntry($user_id, $role_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id, + 'role_id' => $role_id + ]; + return $this->call('addUserRoleEntry', $param); + } + + /** + * grant permissions + * + * grants permissions for given operations at role-id and ref-id + * @access public + * @param array operations operation-array + * @param string role_id role-id + * @param string ref_id reference-id + * @return boolean result + */ + function grantPermissions($operations, $role_id, $ref_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id, + 'role_id' => $role_id, + 'operations' => $operations, + ]; + return $this->call('grantPermissions', $param); + } + + /** + * revoke permissions + * + * revokes all permissions role-id and ref-id + * @access public + * @param string role_id role-id + * @param string ref_id reference-id + * @return boolean result + */ + function revokePermissions($role_id, $ref_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id, + 'role_id' => $role_id, + ]; + return $this->call('revokePermissions', $param); + } + +///////////////////////// +// USER-FUNCTIONS // +/////////////////////// + + /** + * lookup user + * + * gets user-id for given username + * @access public + * @param string username username + * @return string user-id + */ + function lookupUser($username) + { + $param = [ + 'sid' => $this->getSID(), + 'user_name' => $username, + ]; + return $this->call('lookupUser', $param); // returns user_id + } + + /** + * get user + * + * gets user-data for given user-id + * @access public + * @param string user_id user-id + * @return array user-data + */ + function getUser($user_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id, + ]; + $result = $this->call('getUser', $param); // returns user-data-array + return $result; + } + + /** + * add user + * + * adds new user and sets role-id + * @access public + * @param array user_data user-data + * @param string role_id global role-id for new user + * @return string user-id + */ + function addUser($user_data, $role_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_data' => $user_data, + 'global_role_id' => $role_id + ]; + return $this->call('addUser', $param); // returns user_id + } + + /** + * update user + * + * update user-data + * @access public + * @param array user_data user-data + * @return string result + */ + function updateUser($user_data) + { + $param = [ + 'sid' => $this->getSID(), + 'user_data' => $user_data + ]; + return $this->call('updateUser', $param); // returns boolean + } + + /** + * update password + * + * update password with given string and write it uncrypted to the ilias-database + * @access public + * @param string user_id user-id + * @param string password password + * @return string result + */ + function updatePassword($user_id, $password) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id, + 'new_password' => $password + ]; + return $this->call('updatePassword', $param); // returns boolean + } + + /** + * delete user + * + * deletes user-account + * @access public + * @param string user_id user-id + * @return string result + */ + function deleteUser($user_id) + { + $param = [ + 'sid' => $this->getSID(), + 'user_id' => $user_id + ]; + return $this->call('deleteUser', $param); // returns boolean + } + +//////////////////////////// +// COURSE-FUNCTIONS // +////////////////////////// + + /** + * is course member + * + * checks if user is course-member + * @access public + * @param string user_id user-id + * @param string course_id course-id + * @return boolean result + */ + function isMember($user_id, $course_id) + { + $param = [ + 'sid' => $this->getSID(), + 'course_id' => $course_id, + 'user_id' => $user_id + ]; + $status = $this->call('isAssignedToCourse', $param); // returns 0 if not assigned, 1 => course admin, 2 => course member or 3 => course tutor + if ($status == 0) + return false; + else + return true; + } + + /** + * add course member + * + * adds user to course + * @access public + * @param string user_id user-id + * @param string type member-type (Admin, Tutor or Member) + * @param string course_id course-id + * @return boolean result + */ + function addMember($user_id, $type, $course_id) + { + $param = [ + 'sid' => $this->getSID(), + 'course_id' => $course_id, + 'user_id' => $user_id, + 'type' => $type + ]; + return $this->call('assignCourseMember', $param); + } + + /** + * add course + * + * adds course + * @access public + * @param array course_data course-data + * @param string ref_id target-id + * @return string course-id + */ + function addCourse($course_data, $ref_id) + { + foreach($course_data as $key => $value) { + $course_data[$key] = htmlReady($course_data[$key]); + } + + $xml = $this->getCourseXML($course_data); + $param = [ + 'sid' => $this->getSID(), + 'target_id' => $ref_id, + 'crs_xml' => $xml + ]; + $crs_id = $this->call('addCourse', $param); + return $crs_id; + } + + /** + * get course-xml + * + * gets course xml-object for given course-data + * @access public + * @param array course_data course-data + * @return string course-xml + */ + function getCourseXML($course_data) + { + $crs_language = $course_data["language"]; + $crs_admin_id = $course_data["admin_id"]; + $crs_title = $course_data["title"]; + $crs_desc = $course_data["description"]; + + $xml = "<!DOCTYPE Course SYSTEM \"http://www.ilias.uni-koeln.de/download/dtd/ilias_course_0_1.dtd\"> +<Course> + <MetaData> + <General Structure=\"Hierarchical\"> + <Identifier Catalog=\"ILIAS\"/> + <Title Language=\"$crs_language\"> + $crs_title + </Title> + <Language Language=\"$crs_language\"/> + <Description Language=\"$crs_language\"> + $crs_desc + </Description> + <Keyword Language=\"$crs_language\"> + </Keyword> + </General> + </MetaData> + <Admin id=\"$crs_admin_id\" notification=\"Yes\" passed=\"No\"> + </Admin> + <Settings> + <Availability> + <Unlimited/> + </Availability> + <Syllabus> + </Syllabus> + <Contact> + <Name> + </Name> + <Responsibility> + </Responsibility> + <Phone> + </Phone> + <Email> + </Email> + <Consultation> + </Consultation> + </Contact> + <Registration registrationType=\"Password\" maxMembers=\"0\" notification=\"No\"> + <Disabled/> + </Registration> + <Sort type=\"Manual\"/> + <Archive Access=\"Disabled\"> + </Archive> + </Settings> +</Course>"; + return $xml; + } + + /** + * check reference by title + * + * gets reference-id by object-title + * @access public + * @param string key keyword + * @param string type object-type + * @return string reference-id + */ + function checkReferenceById($id) + { + $param = [ + 'sid' => $this->getSID(), + 'reference_id' => $id + ]; + + $result = $this->call('getObjectByReference', $param); + if ($result != false) + { + $objects = $this->parseXML($result); + //echo "<pre><hr>".print_r($objects,1); + //echo "\n</pre><hr>"; + if(is_array($objects)){ + foreach($objects as $index => $object_data){ + if(is_array($object_data['references'])){ + foreach($object_data['references'] as $reference){ + if($reference['ref_id'] == $id && $reference['accessInfo'] != 'object_deleted') return $object_data['obj_id']; + } + } + } + } + } + return false; + } +} + diff --git a/lib/elearning/Ilias4ConnectedCMS.class.php b/lib/elearning/Ilias4ConnectedCMS.class.php new file mode 100644 index 0000000..f9e566a --- /dev/null +++ b/lib/elearning/Ilias4ConnectedCMS.class.php @@ -0,0 +1,270 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** + * main-class for connection to ILIAS 4 + * + * This class contains the main methods of the elearning-interface to connect to ILIAS 4. Extends Ilias3ConnectedCMS. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ConnectedCMS + * @package ELearning-Interface + */ +class Ilias4ConnectedCMS extends Ilias3ConnectedCMS +{ + var $user_category_node_id; + var $ldap_enable; + /** + * constructor + * + * init class. + * @access public + * @param string $cms system-type + */ + function __construct($cms) + { + global $messages; + parent::__construct($cms); + if (ELearningUtils::getConfigValue("user_category_id", $cms)) { + $this->user_category_node_id = ELearningUtils::getConfigValue("user_category_id", $cms); + } else { + $this->user_category_node_id = $this->main_category_node_id; + } + if (ELearningUtils::getConfigValue("ldap_enable", $cms)) { + $this->ldap_enable = ELearningUtils::getConfigValue("ldap_enable", $cms); + } + } + + /** + * Helper function to fetch childs including objects in folders + * + * @access public + * @param string $parent_id + * @return array result + */ + function getChilds($parent_id) { + $types[] = 'fold'; + foreach ($this->types as $type => $name) { + $types[] = $type; + } + + $result = $this->soap_client->getTreeChilds($parent_id, $types, $this->user->getId()); + if ($result) { + $parent_path = $this->soap_client->getRawPath($parent_id) . '_' . $parent_id; + foreach($result as $ref_id => $data) { + // Workaround: getTreeChilds() liefert ALLE Referenzen der beteiligten Objekte, hier sollen aber nur die aus dem Kurs geprüft werden. Deshalb Abgleich der Pfade aller gefundenen Objekt-Referenzen. + if (($data["accessInfo"] != "granted") OR ($this->soap_client->getRawPath($ref_id) != $parent_path)) + unset($result[$ref_id]); + elseif ($data['type'] == 'fold') { + unset($result[$ref_id]); + $result = $result + $this->getChilds($ref_id); + } + } + } + + if (is_array($result)) + return $result; + else + return []; + } + + /** + * check connected modules and update connections + * + * checks if there are modules in the course that are not connected to the seminar + * @access public + * @param string $course_id course-id + * @return boolean successful + */ + function updateConnections($course_id) + { + global $connected_cms, $messages, $object_connections; + + $db = DBManager::get(); + + $result = $this->soap_client->getObjectByReference($course_id); + if ($result) { + $course_path = $this->soap_client->getRawPath($course_id) . '_' . $result["ref_id"]; + } + $this->soap_client->setCachingStatus(false); + // fetch childs + $result = $this->getChilds($course_id); + + if (is_array($result)) { + $check = $db->prepare("SELECT 1 FROM object_contentmodules WHERE object_id = ? AND module_id = ? AND system_type = ? AND module_type = ?"); + $found = []; + $added = 0; + $deleted = 0; + $messages["info"] .= "<b>".sprintf(_("Aktualisierung der Zuordnungen zum System \"%s\":"), $this->getName()) . "</b><br>"; + foreach($result as $ref_id => $data) { + $check->execute([Context::getId(), $ref_id, $this->cms_type, $data["type"]]); + if (!$check->fetch()) { + $messages["info"] .= sprintf(_("Zuordnung zur Lerneinheit \"%s\" wurde hinzugefügt."), ($data["title"])) . "<br>"; + ObjectConnections::setConnection(Context::getId(), $ref_id, $data["type"], $this->cms_type); + $added++; + } + $found[] = $ref_id . '_' . $data["type"]; + } + $to_delete = $db->prepare("SELECT module_id,module_type FROM object_contentmodules WHERE module_type <> 'crs' AND object_id = ? AND system_type = ? AND CONCAT_WS('_', module_id,module_type) NOT IN (?)"); + $to_delete->execute([Context::getId(), $this->cms_type, count($found) ? $found : ['']]); + while ($row = $to_delete->fetch(PDO::FETCH_ASSOC)) { + ObjectConnections::unsetConnection(Context::getId(), $row["module_id"], $row["module_type"], $this->cms_type); + $deleted++; + $messages["info"] .= sprintf(_("Zuordnung zu \"%s\" wurde entfernt."), $row["module_id"] . '_' . $row["module_type"]) . "<br>"; + } + if (($added + $deleted) < 1) { + $messages["info"] .= _("Die Zuordnungen sind bereits auf dem aktuellen Stand.") . "<br>"; + } + } + ELearningUtils::bench("update connections"); + } + + /** + * create course + * + * creates new ilias course + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function createCourse($seminar_id) + { + global $messages, $ELEARNING_INTERFACE_MODULES; + + $crs_id = ObjectConnections::getConnectionModuleId($seminar_id, "crs", $this->cms_type); + $this->soap_client->setCachingStatus(false); + $this->soap_client->clearCache(); + + if ($crs_id == false) { + $seminar = Seminar::getInstance($seminar_id); + $home_institute = Institute::find($seminar->getInstitutId()); + if ($home_institute) { + $ref_id = ObjectConnections::getConnectionModuleId($home_institute->getId(), "cat", $this->cms_type); + } + if ($ref_id < 1) { + // Kategorie für Heimateinrichtung anlegen + $object_data["title"] = sprintf("%s", $home_institute->name); + $object_data["description"] = sprintf(_("Hier befinden sich die Veranstaltungsdaten zur Stud.IP-Einrichtung \"%s\"."), $home_institute->name); + $object_data["type"] = "cat"; + $object_data["owner"] = $this->soap_client->LookupUser($ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["username"]); + $ref_id = $this->soap_client->addObject($object_data, $this->main_category_node_id); + ObjectConnections::setConnection($home_institute->getId(), $ref_id, "cat", $this->cms_type); + } + if ($ref_id < 1) { + $ref_id = $this->main_category_node_id; + } + + // Kurs anlegen + $lang_array = explode("_", Config::get()->DEFAULT_LANGUAGE); + $course_data["language"] = $lang_array[0]; + $course_data["title"] = "Stud.IP-Kurs " . $seminar->getName(); + $course_data["description"] = ""; + $crs_id = $this->soap_client->addCourse($course_data, $ref_id); + if ($crs_id == false) { + $messages["error"] .= _("Zuordnungs-Fehler: Kurs konnte nicht angelegt werden."); + return false; + } + ObjectConnections::setConnection($seminar_id, $crs_id, "crs", $this->cms_type); + + // Rollen zuordnen + $this->permissions->CheckUserPermissions($crs_id); + } + return $crs_id; + } + + /** + * get preferences + * + * shows additional settings. + * @access public + */ + function getPreferences() + { + global $connected_cms; + + $role_template_name = Request::get('role_template_name'); + $cat_name = Request::get('cat_name'); + + $this->soap_client->setCachingStatus(false); + + if ($cat_name != "") { + $cat = $this->soap_client->getReferenceByTitle( trim( $cat_name ), "cat"); + if ($cat == false) { + $messages["error"] .= sprintf(_("Das Objekt mit dem Namen \"%s\" wurde im System %s nicht gefunden."), htmlReady($cat_name), htmlReady($this->getName())) . "<br>\n"; + } elseif ($cat != "") { + ELearningUtils::setConfigValue("category_id", $cat, $this->cms_type); + $this->main_category_node_id = $cat; + } + } + + if (($this->main_category_node_id != false) AND (ELearningUtils::getConfigValue("user_category_id", $this->cms_type) == "")) { + $object_data["title"] = sprintf(_("User-Daten")); + $object_data["description"] = _("Hier befinden sich die persönlichen Ordner der Stud.IP-User."); + $object_data["type"] = "cat"; + $object_data["owner"] = $this->user->getId(); + $user_cat = $connected_cms[$this->cms_type]->soap_client->addObject($object_data, $connected_cms[$this->cms_type]->main_category_node_id); + if ($user_cat != false) { + $this->user_category_node_id = $user_cat; + ELearningUtils::setConfigValue("user_category_id", $user_cat, $this->cms_type); + } else { + $messages["error"] .= _("Die Kategorie für User-Daten konnte nicht angelegt werden.") . "<br>\n"; + } + } + + if ($role_template_name != "") { + $role_template = $this->soap_client->getObjectByTitle( trim( $role_template_name ), "rolt" ); + if ($role_template == false) { + $messages["error"] .= sprintf(_("Das Rollen-Template mit dem Namen \"%s\" wurde im System %s nicht gefunden."), htmlReady($role_template_name), htmlReady($this->getName())) . "<br>\n"; + } + if (is_array($role_template)) { + ELearningUtils::setConfigValue("user_role_template_id", $role_template["obj_id"], $this->cms_type); + ELearningUtils::setConfigValue("user_role_template_name", $role_template["title"], $this->cms_type); + $this->user_role_template_id = $role_template["obj_id"]; + } + } + + if (Request::submitted('submit')) { + ELearningUtils::setConfigValue("encrypt_passwords", Request::option("encrypt_passwords"), $this->cms_type); + $encrypt_passwords = Request::option("encrypt_passwords"); + ELearningUtils::setConfigValue("ldap_enable", Request::option("ldap_enable"), $this->cms_type); + $this->ldap_enable = Request::option("ldap_enable"); + } else { + if (ELearningUtils::getConfigValue("encrypt_passwords", $this->cms_type) != "") + $encrypt_passwords = ELearningUtils::getConfigValue("encrypt_passwords", $this->cms_type); + } + + $cat = $this->soap_client->getObjectByReference( $this->main_category_node_id ); + $user_cat = $this->soap_client->getObjectByReference( $this->user_category_node_id ); + $title = $this->link->getModuleLink($user_cat["title"], $this->user_category_node_id, "cat"); + $ldap_options = []; + foreach (StudipAuthAbstract::GetInstance() as $plugin) { + if ($plugin instanceof StudipAuthLdap) { + $ldap_options[] = '<option '.($plugin->plugin_name == $this->ldap_enable ? 'selected' : '').'>' . $plugin->plugin_name . '</option>'; + } + } + ob_start(); + ConnectedCMS::getPreferences(); + $module_types = ob_get_clean(); + + $template = $GLOBALS['template_factory']->open('elearning/ilias4_connected_cms_preferences.php'); + $template->set_attribute('messages', $messages); + $template->set_attribute('soap_error', $this->soap_client->getError()); + $template->set_attribute('soap_data', $this->soap_data); + $template->set_attribute('main_category_node_id', $this->main_category_node_id); + $template->set_attribute('main_category_node_id_title', $cat['title']); + $template->set_attribute('user_category_node_id', $this->user_category_node_id); + $template->set_attribute('user_category_node_id_title', $title); + $template->set_attribute('user_role_template_name', ELearningUtils::getConfigValue("user_role_template_name", $this->cms_type)); + $template->set_attribute('user_role_template_id', $this->user_role_template_id); + $template->set_attribute('encrypt_passwords', $encrypt_passwords); + $template->set_attribute('ldap_options', count($ldap_options) ? join("\n", array_merge(['<option></option>'], $ldap_options)) : ''); + $template->set_attribute('module_types', $module_types); + echo $template->render(); + } + +} diff --git a/lib/elearning/Ilias4ConnectedLink.class.php b/lib/elearning/Ilias4ConnectedLink.class.php new file mode 100644 index 0000000..ea241e8 --- /dev/null +++ b/lib/elearning/Ilias4ConnectedLink.class.php @@ -0,0 +1,122 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +use Studip\Button, Studip\LinkButton; + +/** + * class to generate links to ILIAS 4 + * + * This class contains methods to generate links to ILIAS 4. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ConnectedLink + * @package ELearning-Interface + */ +class Ilias4ConnectedLink extends Ilias3ConnectedLink +{ + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + parent::__construct($cms); + $this->cms_link = "ilias3_referrer.php"; + } + + /** + * get module link + * + * returns link to the specified ilias object. works without initializing module-class. + * @access public + * @return string html-code + */ + function getModuleLink($title, $module_id, $module_type) + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + if ($connected_cms[$this->cms_type]->isAuthNecessary() AND (! $connected_cms[$this->cms_type]->user->isConnected())) { + return false; + } + $output = "<a href=\"" . UrlHelper::getLink($this->cms_link . "?" + . "client_id=" . $connected_cms[$this->cms_type]->getClientId() + . "&cms_select=" . $this->cms_type + . "&ref_id=" . $module_id + . "&type=" . $module_type + . "&target=start"). "\" target=\"_blank\" rel=\"noopener noreferrer\">"; + $output .= $title; + $output .= "</a> "; + + return $output; + } + + /** + * get admin module links + * + * returns links add or remove a module from course + * @access public + * @return string returns html-code + */ + function getAdminModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + if (! $connected_cms[$this->cms_type]->content_module[$current_module]->isDummy()) { + $result = $connected_cms[$this->cms_type]->soap_client->getPath($connected_cms[$this->cms_type]->content_module[$current_module]->getId()); + } + if ($result) { + $output .= "<i>Pfad: ". htmlReady($result) . "</i><br><br>"; + } + $output .= "<form method=\"POST\" action=\"" . URLHelper::getLink() . "\">\n"; + $output .= CSRFProtection::tokenTag(); + $output .= "<input type=\"HIDDEN\" name=\"view\" value=\"" . htmlReady($view) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"search_key\" value=\"" . htmlReady($search_key) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"cms_select\" value=\"" . htmlReady($cms_select) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_type\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getModuleType()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_id\" value=\"" . htmlReady($connected_cms[$this->cms_type]->content_module[$current_module]->getId()) . "\">\n"; + $output .= "<input type=\"HIDDEN\" name=\"module_system_type\" value=\"" . htmlReady($this->cms_type) . "\">\n"; + + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isConnected()) { + $output .= " " . Button::create(_('Entfernen'), 'remove'); + } elseif ($connected_cms[$this->cms_type]->content_module[$current_module]->isAllowed(OPERATION_WRITE)) { + $output .= "<div align=\"left\">"; + if ($connected_cms[$this->cms_type]->content_module[$current_module]->isAllowed(OPERATION_COPY) AND (! in_array($connected_cms[$this->cms_type]->content_module[$current_module]->module_type, ["lm", "htlm", "sahs", "cat", "crs", "dbk"]))) { + $output .= "<input type=\"CHECKBOX\" name=\"copy_object\" value=\"1\">"; + $output .= _("Als Kopie anlegen") . " "; + $output .= Icon::create('info-circle', 'inactive', ['title' => _('Wenn Sie diese Option wählen, wird eine identische Kopie als eigenständige Instanz des Lernmoduls erstellt. Anderenfalls wird ein Link zum Lernmodul gesetzt.')])->asImg(); + $output .= "<br>"; + } + $output .= "<input type=\"RADIO\" name=\"write_permission\" value=\"none\" checked>"; + $output .= _("Keine Schreibrechte") . " "; + $output .= Icon::create('info-circle', 'inactive', ['title' => _('Nur der/die BesitzerIn des Lernmoduls hat Schreibzugriff für Inhalte und Struktur des Lernmoduls. Tutor/-innen und Lehrende können die Verknüpfung zur Veranstaltung wieder löschen.')])->asImg(); + $output .= "<br>"; + $output .= "<input type=\"RADIO\" name=\"write_permission\" value=\"dozent\">"; + $output .= _("Mit Schreibrechten für alle Lehrenden dieser Veranstaltung") . " "; + $output .= Icon::create('info-circle', 'inactive', ['title' => _('Lehrende haben Schreibzugriff für Inhalte und Struktur des Lernmoduls. Tutor/-innen und Lehrende können die Verknüpfung zur Veranstaltung wieder löschen.')])->asImg(); + $output .= "<br>"; + $output .= "<input type=\"RADIO\" name=\"write_permission\" value=\"tutor\">"; + $output .= _("Mit Schreibrechten für alle Lehrenden und Tutor/-innen dieser Veranstaltung") . " "; + $output .= Icon::create('info-circle', 'inactive', ['title' => _('Lehrende und Tutor/-innen haben Schreibzugriff für Inhalte und Struktur des Lernmoduls. Tutor/-innen und Lehrende können die Verknüpfung zur Veranstaltung wieder löschen.')])->asImg(); + $output .= "<br>"; + $output .= "<input type=\"RADIO\" name=\"write_permission\" value=\"autor\">"; + $output .= _("Mit Schreibrechten für alle Personen dieser Veranstaltung") . " "; + $output .= Icon::create('info-circle', 'inactive', ['title' => _('Lehrende, Tutor/-innen und Teilnehmende haben Schreibzugriff für Inhalte und Struktur des Lernmoduls. Tutor/-innen und Lehrende können die Verknüpfung zur Veranstaltung wieder löschen.')])->asImg(); + $output .= "</div>"; + $output .= "</div><br>" . Button::create(_('Hinzufügen'), 'add') . "<br>"; + } else { + $output .= " " . Button::create(_('Hinzufügen'), 'add'); + } + $output .= "</form>"; + + return $output; + } +} +?> diff --git a/lib/elearning/Ilias4ConnectedPermissions.class.php b/lib/elearning/Ilias4ConnectedPermissions.class.php new file mode 100644 index 0000000..b44e7a2 --- /dev/null +++ b/lib/elearning/Ilias4ConnectedPermissions.class.php @@ -0,0 +1,128 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +DEFINE ("OPERATION_COPY", "copy"); + +/** + * class to handle ILIAS 4 access controls + * + * This class contains methods to handle permissions on connected objects. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ConnectedPermission + * @package ELearning-Interface + */ +class Ilias4ConnectedPermissions extends Ilias3ConnectedPermissions +{ + var $operations; + var $allowed_operations; + var $tree_allowed_operations; + + var $USER_OPERATIONS; + var $AUTHOR_OPERATIONS; + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + parent::__construct($cms); + } + + /** + * check user permissions + * + * checks user permissions for connected course and changes setting if necessary + * @access public + * @param string $course_id course-id + * @return boolean returns false on error + */ + function checkUserPermissions($course_id = "") + { + global $connected_cms, $messages; + + if ($course_id == "") return false; + if ($connected_cms[$this->cms_type]->user->getId() == "") return false; + + // get course role folder and local roles + $local_roles = $connected_cms[$this->cms_type]->soap_client->getLocalRoles($course_id); + $active_role = ""; + $proper_role = ""; + $user_crs_role = $connected_cms[$this->cms_type]->crs_roles[$GLOBALS["perm"]->get_studip_perm(Context::getId())]; + if (is_array($local_roles)) { + foreach ($local_roles as $key => $role_data) { + // check only if local role is il_crs_member, -tutor or -admin + if (! (mb_strpos($role_data["title"], "_crs_") === false)) { + if ( in_array( $role_data["obj_id"], $connected_cms[$this->cms_type]->user->getRoles() ) ) { + $active_role = $role_data["obj_id"]; + } + if ( mb_strpos( $role_data["title"], $user_crs_role) > 0 ) { + $proper_role = $role_data["obj_id"]; + } + } + } + } + + // is user already course-member? otherwise add member with proper role + $is_member = $connected_cms[$this->cms_type]->soap_client->isMember( $connected_cms[$this->cms_type]->user->getId(), $course_id); + if (!$is_member) { + $member_data["usr_id"] = $connected_cms[$this->cms_type]->user->getId(); + $member_data["ref_id"] = $course_id; + $member_data["status"] = CRS_NO_NOTIFICATION; + $type = ""; + switch ($user_crs_role) + { + case "admin": + $member_data["role"] = CRS_ADMIN_ROLE; + $type = "Admin"; + break; + case "tutor": + $member_data["role"] = CRS_TUTOR_ROLE; + $type = "Tutor"; + break; + case "member": + $member_data["role"] = CRS_MEMBER_ROLE; + $type = "Member"; + break; + default: + } + $member_data["passed"] = CRS_PASSED_VALUE; + if ($type != "") { + $connected_cms[$this->cms_type]->soap_client->addMember( $connected_cms[$this->cms_type]->user->getId(), $type, $course_id ); + if ($GLOBALS["debug"] == true) echo "addMember"; + $this->permissions_changed = true; + } + } + + // check if user has proper local role + // if not, change it + if ($active_role != $proper_role) { + if ($active_role != "") { + $connected_cms[$this->cms_type]->soap_client->deleteUserRoleEntry( $connected_cms[$this->cms_type]->user->getId(), $active_role); + if ($GLOBALS["debug"] == true) echo "Role $active_role deleted."; + } + + if ($proper_role != "") { + $connected_cms[$this->cms_type]->soap_client->addUserRoleEntry( $connected_cms[$this->cms_type]->user->getId(), $proper_role); + if ($GLOBALS["debug"] == true) echo "Role $proper_role added."; + } + $this->permissions_changed = true; + + } + + if (! $this->getContentModulePerms( $course_id )) { + $messages["info"] .= _("Für den zugeordneten ILIAS-Kurs konnten keine Berechtigungen ermittelt werden.") . "<br>"; + } + + return true; + } +} +?> diff --git a/lib/elearning/Ilias4ConnectedUser.class.php b/lib/elearning/Ilias4ConnectedUser.class.php new file mode 100644 index 0000000..0d480d4 --- /dev/null +++ b/lib/elearning/Ilias4ConnectedUser.class.php @@ -0,0 +1,164 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** + * class to handle ILIAS 4 user-accounts + * + * This class contains methods to handle connected ILIAS 4 user-accounts. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ConnectedUser + * @package ELearning-Interface + */ +class Ilias4ConnectedUser extends Ilias3ConnectedUser +{ + var $roles; + var $user_sid; + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms, $user_id = false) + { + // get auth_plugin + $user_id = $user_id ? $user_id : $GLOBALS['user']->id; + $this->auth_plugin = DBManager::get()->query("SELECT IFNULL(auth_plugin, 'standard') FROM auth_user_md5 WHERE user_id = '" . $user_id . "'")->fetchColumn(); + parent::__construct($cms, $user_id); + } + + /** + * new user + * + * save new user + * @access public + * @return boolean returns false on error + */ + function newUser($ignore_encrypt_passwords = false) + { + global $connected_cms, $auth, $messages; + + if ($this->getLoginData($this->login)) { + //automatische Zuordnung von bestehenden Ilias Accounts + //nur wenn ldap Modus benutzt wird und Stud.IP Nutzer passendes ldap plugin hat + if ($connected_cms[$this->cms_type]->USER_AUTO_CREATE == true && + $connected_cms[$this->cms_type]->USER_PREFIX == '' && + $this->auth_plugin && + $this->auth_plugin != "standard" && + $this->auth_plugin == $connected_cms[$this->cms_type]->ldap_enable) { + if (!$this->external_password) { + $this->setPassword(md5(uniqid("4dfmjsnll"))); + } + $ok = $connected_cms[$this->cms_type]->soap_client->updatePassword($this->id, $this->external_password); + $this->setConnection($this->getUserType(), true); + if ($ok) { + $messages["info"] .= sprintf(_("Verbindung mit Nutzer ID %s wiederhergestellt."), $this->id); + } + return true; + } + $messages["error"] .= sprintf(_("Es existiert bereits ein Account mit dem Benutzernamen \"%s\" (Account ID %s)."), $this->login, $this->id) . "<br>\n"; + return false; + } + + // data for user-account in ILIAS 4 + $user_data["login"] = $this->login; + $user_data["passwd"] = $this->external_password; + $user_data["firstname"] = $this->firstname; + $user_data["lastname"] = $this->lastname; + $user_data["title"] = $this->title; + $user_data["gender"] = $this->gender; + $user_data["email"] = $this->email; + $user_data["street"] = $this->street; + $user_data["phone_home"] = $this->phone_home; + $user_data["time_limit_unlimited"] = 1; + $user_data["active"] = 1; + $user_data["approve_date"] = date('Y-m-d H:i:s'); + $user_data["accepted_agreement"] = true; + // new values for ILIAS 4 + $user_data["agree_date"] = date('Y-m-d H:i:s'); + $user_data["external_account"] = $this->login; + if ($this->auth_plugin && $this->auth_plugin != "standard" && ($this->auth_plugin == $connected_cms[$this->cms_type]->ldap_enable)) { + $user_data["auth_mode"] = "ldap"; + } else { + $user_data["auth_mode"] = "default"; + } + if ($connected_cms[$this->cms_type]->user_style != "") { + $user_data["user_style"] = $connected_cms[$this->cms_type]->user_style; + } + if ($connected_cms[$this->cms_type]->user_skin != "") { + $user_data["user_skin"] = $connected_cms[$this->cms_type]->user_skin; + } + + $role_id = $connected_cms[$this->cms_type]->roles[$auth->auth["perm"]]; + + $user_id = $connected_cms[$this->cms_type]->soap_client->addUser($user_data, $role_id); + + if ($user_id != false) { + $this->id = $user_id; + + // $connected_cms[$this->cms_type]->soap_client->updatePassword($user_id, $user_data["passwd"]); + + // $this->newUserCategory(); + + $this->setConnection(USER_TYPE_CREATED); + return true; + } + return false; + } + + /** + * create new user category + * + * create new user category + * @access public + * @return boolean returns false on error + */ + function newUserCategory() + { + global $connected_cms, $messages; + + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + + // data for user-category in ILIAS 4 + $object_data["title"] = sprintf(_("Eigene Daten von %s (%s)."), $this->getName(), $this->getId()); + $object_data["description"] = sprintf(_("Hier befinden sich die persönlichen Lernmodule des Benutzers %s."), $this->getName()); + $object_data["type"] = "cat"; + $object_data["owner"] = $this->getId(); + + $cat = $connected_cms[$this->cms_type]->soap_client->getReferenceByTitle($object_data["title"]); + if ($cat != false && $connected_cms[$this->cms_type]->soap_client->checkReferenceById($cat) ) { + $messages["info"] .= sprintf(_("Ihre persönliche Kategorie wurde bereits angelegt."), $this->login) . "<br>\n"; + $this->category = $cat; + } else { + $this->category = $connected_cms[$this->cms_type]->soap_client->addObject($object_data, $connected_cms[$this->cms_type]->user_category_node_id); + } + if ($this->category != false) { + parent::setConnection($this->getUserType(), true); + } else { + echo "CATEGORY_ERROR".$connected_cms[$this->cms_type]->user_category_node_id ."-"; + return false; + } + // data for personal user-role in ILIAS 4 + $role_data["title"] = "studip_usr" . $this->getId() . "_cat" . $this->category; + $role_data["description"] = sprintf(_("User-Rolle von %s. Diese Rolle wurde von Stud.IP generiert."), $this->getName()); + $role_id = $connected_cms[$this->cms_type]->soap_client->getObjectByTitle($role_data["title"], "role"); + if ($role_id != false) { + $messages["info"] .= sprintf(_("Ihre persönliche Userrolle wurde bereits angelegt."), $this->login) . "<br>\n"; + } else { + $role_id = $connected_cms[$this->cms_type]->soap_client->addRoleFromTemplate($role_data, $this->category, $connected_cms[$this->cms_type]->user_role_template_id); + } + $connected_cms[$this->cms_type]->soap_client->addUserRoleEntry($this->getId(), $role_id); + // delete permissions for all global roles for this category + foreach ($connected_cms[$this->cms_type]->global_roles as $key => $role) { + $connected_cms[$this->cms_type]->soap_client->revokePermissions($role, $this->category); + } + return true; + } +}
\ No newline at end of file diff --git a/lib/elearning/Ilias4ContentModule.class.php b/lib/elearning/Ilias4ContentModule.class.php new file mode 100644 index 0000000..1d5392e --- /dev/null +++ b/lib/elearning/Ilias4ContentModule.class.php @@ -0,0 +1,106 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** + * class to handle ILIAS 4 learning modules and tests + * + * This class contains methods to handle ILIAS 4 learning modules and tests. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ContentModule + * @package ELearning-Interface + */ +class Ilias4ContentModule extends Ilias3ContentModule +{ + var $object_id; + + /** + * constructor + * + * init class. + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param string $cms_type system-type + */ + function __construct($module_id = "", $module_type, $cms_type) + { + parent::__construct($module_id, $module_type, $cms_type); + } + + /** + * set connection + * + * sets connection with seminar + * @access public + * @param string $seminar_id seminar-id + * @return boolean successful + */ + function setConnection($seminar_id) + { + global $connected_cms, $messages; + + $write_permission = Request::option("write_permission"); + + $crs_id = ObjectConnections::getConnectionModuleId($seminar_id, "crs", $this->cms_type); + $connected_cms[$this->cms_type]->soap_client->setCachingStatus(false); + $connected_cms[$this->cms_type]->soap_client->clearCache(); + + // Check, ob Kurs in ILIAS gelöscht wurde + if (($crs_id != false) AND ($connected_cms[$this->cms_type]->soap_client->getObjectByReference($crs_id) == false)) { + ObjectConnections::unsetConnection($seminar_id, $crs_id, "crs", $this->cms_type); + $messages["info"] .= _("Der zugeordnete ILIAS-Kurs (ID $crs_id) existiert nicht mehr. Ein neuer Kurs wird angelegt.") . "<br>"; + $crs_id = false; + } + + $crs_id == $connected_cms[$this->cms_type]->createCourse($seminar_id); + + if ($crs_id == false) return false; + + $ref_id = $this->getId(); + if (Request::get("copy_object") == "1") { + $connected_cms[$this->cms_type]->soap_client->user_type = 'user'; + $ref_id = $connected_cms[$this->cms_type]->soap_client->copyObject($this->id, $crs_id); + $connected_cms[$this->cms_type]->soap_client->user_type = 'admin'; + } else { + $ref_id = $connected_cms[$this->cms_type]->soap_client->addReference($this->id, $crs_id); + } + if (!$ref_id) { + $messages["error"] .= _("Zuordnungs-Fehler: Objekt konnte nicht angelegt werden."); + return false; + } + $local_roles = $connected_cms[$this->cms_type]->soap_client->getLocalRoles($crs_id); + $member_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ]); + $admin_operations = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ, OPERATION_WRITE, OPERATION_DELETE]); + $admin_operations_no_delete = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ, OPERATION_WRITE]); + $admin_operations_readonly = $connected_cms[$this->cms_type]->permissions->getOperationArray([OPERATION_VISIBLE, OPERATION_READ, OPERATION_DELETE]); + foreach ($local_roles as $key => $role_data) { + // check only if local role is il_crs_member, -tutor or -admin + if (mb_strpos($role_data["title"], "il_crs_") === 0) { + if(mb_strpos($role_data["title"], 'il_crs_member') === 0){ + $operations = ($write_permission == "autor") ? $admin_operations_no_delete : $member_operations; + } elseif(mb_strpos($role_data["title"], 'il_crs_tutor') === 0){ + $operations = (($write_permission == "tutor") || ($write_permission == "autor")) ? $admin_operations : $admin_operations_readonly; + } elseif(mb_strpos($role_data["title"], 'il_crs_admin') === 0){ + $operations = (($write_permission == "dozent") || ($write_permission == "tutor") || ($write_permission == "autor")) ? $admin_operations : $admin_operations_readonly; + } else { + continue; + } + $connected_cms[$this->cms_type]->soap_client->revokePermissions($role_data["obj_id"], $ref_id); + $connected_cms[$this->cms_type]->soap_client->grantPermissions($operations, $role_data["obj_id"], $ref_id); + } + } + if ($ref_id) { + $this->setId($ref_id); + return ContentModule::setConnection($seminar_id); + } else { + $messages["error"] .= _("Die Zuordnung konnte nicht gespeichert werden."); + } + return false; + } +}
\ No newline at end of file diff --git a/lib/elearning/Ilias4Soap.class.php b/lib/elearning/Ilias4Soap.class.php new file mode 100644 index 0000000..d6d2527 --- /dev/null +++ b/lib/elearning/Ilias4Soap.class.php @@ -0,0 +1,185 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** + * class to use ILIAS-4-Webservices + * + * This class contains methods to connect to the ILIAS-4-Soap-Server. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4Soap + * @package ELearning-Interface + */ +class Ilias4Soap extends Ilias3Soap +{ + var $cms_type; + var $admin_sid; + var $user_sid; + var $user_type; + var $soap_cache; + var $separator_string; + + /** + * constructor + * + * init class. + * @access + * @param string $cms system-type + */ + function __construct($cms) + { + parent::__construct($cms); + $this->seperator_string = " / "; + } + + /** + * add user by importUsers + * + * adds new user and sets role-id + * @access public + * @param array user_data user-data + * @param string role_id global role-id for new user + * @return string user-id + */ + function addUser($user_data, $role_id) + { + foreach($user_data as $key => $value) { + $user_data[$key] = htmlReady($user_data[$key]); + } + + $usr_xml = "<Users> +<User> +<UDFDefinitions></UDFDefinitions> +<Login>".$user_data["login"]."</Login> +<Password Type=\"PLAIN\">".$user_data["passwd"]."</Password> +<Firstname>".$user_data["firstname"]."</Firstname> +<Lastname>".$user_data["lastname"]."</Lastname> +<Title>".$user_data["title"]."</Title> +<Gender>".$user_data["gender"]."</Gender> +<Email>".$user_data["email"]."</Email> +<Street>".$user_data["street"]."</Street> +<PhoneHome>".$user_data["phone_home"]."</PhoneHome> +<Role Id=\"".$role_id."\" Type=\"Global\"/> +<Active>true</Active> +<TimeLimitUnlimited>".$user_data["time_limit_unlimited"]."</TimeLimitUnlimited> +<TimeLimitMessage>0</TimeLimitMessage> +<ApproveDate>".$user_data["approve_date"]."</ApproveDate> +<AgreeDate>".$user_data["agree_date"]."</AgreeDate>"; + if (($user_data["user_skin"] != "") OR ($user_data["user_style"] != "")) { + $usr_xml .= "<Look Skin=\"".$user_data["user_skin"]."\" Style=\"".$user_data["user_style"]."\"/>"; + } + $usr_xml .= "<AuthMode type=\"".$user_data["auth_mode"]."\"/> +<ExternalAccount>".$user_data["external_account"]."</ExternalAccount> +</User> +</Users>"; + + $param = [ + 'sid' => $this->getSID(), + 'folder_id' => -1, + 'usr_xml' => $usr_xml, + 'conflict_role' => 1, + 'send_account_mail' => 0 + ]; + $result = $this->call('importUsers', $param); + + $s = simplexml_load_string($result); + + if ((string)$s->rows->row->column[3] == "successful") + return (string)$s->rows->row->column[0]; + else + return false; + } + + /** + * copy object + * + * copy ilias-object + * @access public + * @param string source_id reference-id + * @param string target_id reference-id + * @return string result + */ + function copyObject($source_id, $target_id) + { + $type = $object_data["type"]; + $title = $object_data["title"]; + $description = $object_data["description"]; + + $xml = "<Settings source_id=\"$source_id\" target_id=\"$target_id\" default_action=\"COPY\"/>"; + + $param = [ + 'sid' => $this->getSID(), + 'xml' => $xml + ]; + return $this->call('copyObject', $param); + } + + /** + * get path + * + * returns repository-path to ilias-object + * @access public + * @param string source_id reference-id + * @param string target_id reference-id + * @return string result + */ + function getPath($ref_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id + ]; + $result = $this->call('getPathForRefId', $param); + + if ($result) { + $s = simplexml_load_string($result); + + foreach ($s->rows->row as $row) { + $path[] = (string)$row->column[2]; + } + } + + if (is_array($path)) { + return implode($path, $this->seperator_string); + } else { + return false; + } + } + + /** + * + * returns repository-path to ilias-object + * + * @access public + * @param string source_id reference-id + * @param string target_id reference-id + * @return string result + */ + function getRawPath($ref_id) + { + $param = [ + 'sid' => $this->getSID(), + 'ref_id' => $ref_id + ]; + $result = $this->call('getPathForRefId', $param); + + if ($result) { + $s = simplexml_load_string($result); + + foreach ($s->rows->row as $row) { + $path[] = (string)$row->column[0]; + } + } + + if (is_array($path)) { + return implode($path, '_'); + } else { + return false; + } + } +} diff --git a/lib/elearning/Ilias5ConnectedCMS.class.php b/lib/elearning/Ilias5ConnectedCMS.class.php new file mode 100644 index 0000000..011d046 --- /dev/null +++ b/lib/elearning/Ilias5ConnectedCMS.class.php @@ -0,0 +1,21 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/** + * main-class for connection to ILIAS 5.2 + * + * This class contains the main methods of the elearning-interface to connect to ILIAS 5. Extends Ilias3ConnectedCMS. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias5ConnectedCMS + * @package ELearning-Interface + */ +class Ilias5ConnectedCMS extends Ilias4ConnectedCMS +{ + +} diff --git a/lib/elearning/Ilias5ConnectedLink.class.php b/lib/elearning/Ilias5ConnectedLink.class.php new file mode 100644 index 0000000..0ce4a0f --- /dev/null +++ b/lib/elearning/Ilias5ConnectedLink.class.php @@ -0,0 +1,16 @@ +<?php +/** + * class to generate links to ILIAS 5.2 + * + * This class contains methods to generate links to ILIAS 5. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias5ConnectedLink + * @package ELearning-Interface + */ +class Ilias5ConnectedLink extends Ilias4ConnectedLink +{ +} +?>
\ No newline at end of file diff --git a/lib/elearning/Ilias5ConnectedPermissions.class.php b/lib/elearning/Ilias5ConnectedPermissions.class.php new file mode 100644 index 0000000..17d6f0d --- /dev/null +++ b/lib/elearning/Ilias5ConnectedPermissions.class.php @@ -0,0 +1,17 @@ +<?php +/** + * class to handle ILIAS 5.2 access controls + * + * This class contains methods to handle permissions on connected objects. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias4ConnectedPermission + * @package ELearning-Interface + */ +class Ilias5ConnectedPermissions extends Ilias4ConnectedPermissions +{ + +} +?>
\ No newline at end of file diff --git a/lib/elearning/Ilias5ConnectedUser.class.php b/lib/elearning/Ilias5ConnectedUser.class.php new file mode 100644 index 0000000..6172976 --- /dev/null +++ b/lib/elearning/Ilias5ConnectedUser.class.php @@ -0,0 +1,40 @@ +<?php +/** + * class to handle ILIAS 5.2 user-accounts + * + * This class contains methods to handle connected ILIAS 5 user-accounts. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias5ConnectedUser + * @package ELearning-Interface + */ +class Ilias5ConnectedUser extends Ilias4ConnectedUser +{ + + /** + * verify login data + * + * returns true, if login-data is valid + * @access public + * @param string $username username + * @param string $password password + * @return boolean login-validation + */ + function verifyLogin($username, $password) + { + global $connected_cms, $messages; + $result = $connected_cms[$this->cms_type]->soap_client->checkPassword($username, $password); + if (strpos($result, '::') > 0) { + return $this->getLoginData($username); + } + return false; + } + + function setConnection($user_type, $ignore_encrypted_passwords = false) + { + $this->external_password = ''; + parent::setConnection($user_type, true); + } +}
\ No newline at end of file diff --git a/lib/elearning/Ilias5ContentModule.class.php b/lib/elearning/Ilias5ContentModule.class.php new file mode 100644 index 0000000..3f50c02 --- /dev/null +++ b/lib/elearning/Ilias5ContentModule.class.php @@ -0,0 +1,16 @@ +<?php +/** + * class to handle ILIAS 5.2 learning modules and tests + * + * This class contains methods to handle ILIAS 5 learning modules and tests. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias5ContentModule + * @package ELearning-Interface + */ +class Ilias5ContentModule extends Ilias4ContentModule +{ + +}
\ No newline at end of file diff --git a/lib/elearning/Ilias5Soap.class.php b/lib/elearning/Ilias5Soap.class.php new file mode 100644 index 0000000..80c683d --- /dev/null +++ b/lib/elearning/Ilias5Soap.class.php @@ -0,0 +1,114 @@ +<?php +/** + * class to use ILIAS-5-Webservices + * + * This class contains methods to connect to the ILIAS-5-Soap-Server. + * + * @author Arne Schröder <schroeder@data-quest.de> + * @access public + * @modulegroup elearning_interface_modules + * @module Ilias5Soap + * @package ELearning-Interface + */ +class Ilias5Soap extends Ilias4Soap +{ + var $cms_type; + var $admin_sid; + var $user_sid; + var $user_type; + var $soap_cache; + var $separator_string; + + /** + * call soap-function + * + * calls soap-function with given parameters + * @access public + * @param string method method-name + * @param string params parameters + * @return mixed result + */ + function call($method, $params) + { + $index = md5($method . ":" . implode($params, "-")); + // return false if no session_id is given + if (($method != "login") AND ($params["sid"] == "")) + return false; +// echo $this->caching_active; + if (($this->caching_active == true) AND (isset($this->soap_cache[$index]))) + { +// echo $index; +// echo " from Cache<br>"; + $result = $this->soap_cache[$index]; + } + else + { + $result = $this->_call($method, $params); + // if Session is expired, re-login and try again + if (($method != "login") AND $this->soap_client->fault AND in_array(mb_strtolower($this->faultstring), ["session not valid","session invalid", "session idled"]) ) + { + $caching_status = $this->caching_active; + $this->caching_active = false; + $user_type = $this->user_type; + $this->user_type = 'admin'; + $params["sid"] = $this->login(); + $result = $this->_call($method, $params); + $this->caching_active = $caching_status; + $this->user_type = $user_type; + } + elseif (! $this->soap_client->fault) + $this->soap_cache[$index] = $result; + } + return $result; + } + + /** + * login + * + * login to soap-webservice + * @access public + * @return string result + */ + function login() + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + if ($this->user_type == "admin") { + $param = [ + 'client' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["client"], + 'username' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["username"], + 'password' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["password"] + ]; + $result = $this->call('login', $param); + } elseif ($this->user_type == "user") { + $param = [ + 'sid' => $this->admin_sid, + 'user_id' => $connected_cms[$this->cms_type]->user->getId() + ]; + $result = $this->call('loginStudipUser', $param); + } + if ($this->user_type == "admin") + $this->admin_sid = $result; + if ($this->user_type == "user") + $this->user_sid = $result; + return $result; + } + + /** + * Check Auth + * + * login to soap-webservice + * @access public + * @return string result + */ + function checkPassword($username, $password) + { + global $ELEARNING_INTERFACE_MODULES, $connected_cms; + $param = [ + 'client' => $ELEARNING_INTERFACE_MODULES[$this->cms_type]["soap_data"]["client"], + 'username' => $username, + 'password' => $password + ]; + $result = $this->call('login', $param); + return $result; + } +}
\ No newline at end of file diff --git a/lib/elearning/LonCapaConnectedCMS.class.php b/lib/elearning/LonCapaConnectedCMS.class.php new file mode 100644 index 0000000..2f86aa8 --- /dev/null +++ b/lib/elearning/LonCapaConnectedCMS.class.php @@ -0,0 +1,67 @@ +<?php +/** + * main-class for connection to LonCapa + * + * This class contains the main methods of the elearning-interface to connect to + * LonCapa. Extends ConnectedCMS. + * + * @access public + * @modulegroup elearning_interface_modules + * @module LonCapaConnectedCMS + * @package ELearning-Interface + */ +class LonCapaConnectedCMS extends ConnectedCMS +{ + public $user; + protected $seminarId; + protected $lcRequest; + protected $cmsUrl; + + public function __construct($cms = '') + { + parent::__construct($cms); + + $this->seminarId = Context::getId(); + $this->user = User::findCurrent(); + $this->lcRequest = new LonCapaRequest(); + $this->cmsUrl = $this->ABSOLUTE_PATH_ELEARNINGMODULES; + } + + + /** + * search for content modules + * + * returns found content modules + * @throws AccessDeniedException + * @param string $key keyword + * @return array list of content modules + */ + public function searchContentModules($key) + { + + if (!$GLOBALS['perm']->have_studip_perm('tutor', $this->seminarId)) { + throw new AccessDeniedException(); + } + + $url = $this->cmsUrl . '/courses?search=' . urlencode($key) . '&owner=' . urlencode($this->user->username); + $response = $this->lcRequest->request($url); + + if ($response) { + $courses = new SimpleXMLElement($response); + + $result = []; + foreach ($courses->course as $course) { + $temp = explode(':', (string)$course->owner); + + $result[] = [ + 'ref_id' => (string)$course->id, + 'title' => (string)$course->description, + 'authors' => $temp[0], + 'type' => $this->cms_type + ]; + } + } + + return $result; + } +} diff --git a/lib/elearning/LonCapaConnectedLink.class.php b/lib/elearning/LonCapaConnectedLink.class.php new file mode 100644 index 0000000..c00958b --- /dev/null +++ b/lib/elearning/LonCapaConnectedLink.class.php @@ -0,0 +1,67 @@ +<?php +/** + * + * This class contains methods to generate links to LonCapa + * + * @modulegroup elearning_interface_modules + * @module LonCapaConnectedLink + * @package ELearning-Interface + */ +class LonCapaConnectedLink extends ConnectedLink +{ + /** + * get user module links + * + * returns content module links for user + * @return string html-code + */ + public function getUserModuleLinks() + { + global $connected_cms, $current_module; + + $url = URLHelper::getURL('dispatch.php/loncapa/enter', ['cms_type' => $this->cms_type, 'module' => $current_module]); + + return Studip\LinkButton::create(_('Starten'), $url, [ + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ]); + } + + /** + * get admin module links + * + * returns links add or remove a module from course + * @return string returns html-code + */ + public function getAdminModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + global $template_factory; + + $template = $template_factory->open('elearning/loncapa_connected_link_edit'); + $template->current_module = $connected_cms[$this->cms_type]->content_module[$current_module]->getId(); + $template->connected = $connected_cms[$this->cms_type]->content_module[$current_module]->isConnected(); + $template->cms_type = $this->cms_type; + $template->search_key = $search_key; + return $template->render(compact('view', 'search_key', 'cms_select', 'current_module')); + } + + /** + * returns url for connected LonCapa course + * + * @param string $module_id LonCapa ID + * @param string $course_id Stud.IP course ID + * @return string url for LonCapa + */ + public function getRedirectUrl($module_id, $course_id) + { + return sprintf( + '%s/enter/%s?token=%s&courseid=%s&systemid=%s', + $this->cms_link, + $module_id, + Token::create(60), + $course_id, + $this->cms_type + ); + } +} diff --git a/lib/elearning/LonCapaContentModule.class.php b/lib/elearning/LonCapaContentModule.class.php new file mode 100644 index 0000000..70976cc --- /dev/null +++ b/lib/elearning/LonCapaContentModule.class.php @@ -0,0 +1,86 @@ +<?php +/** + * + * This class contains methods to handle LonCapa learning modules + * + * @modulegroup elearning_interface_modules + * @module LonCapaContentModule + * @package ELearning-Interface + */ + +class LonCapaContentModule extends ContentModule +{ + /** + * @var LonCapaRequest + */ + public $lcRequest; + /** + * @var string + */ + public $cmsUrl; + + /** + * LonCapaContentModule constructor. + * @param string $module_id + * @param string $module_type + * @param string $cms_type + */ + public function __construct($module_id = "", $module_type, $cms_type) + { + $this->lcRequest = new LonCapaRequest(); + $this->cmsUrl = $GLOBALS['ELEARNING_INTERFACE_MODULES'][$cms_type]['ABSOLUTE_PATH_ELEARNINGMODULES']; + + parent::__construct($module_id, $module_type, $cms_type); + } + + /** + *fetch data from LonCapa + * + */ + public function readData() + { + $url = $this->cmsUrl . '/course/' . urlencode($this->id); + $response = $this->lcRequest->request($url); + + if ($response) { + $courses = new SimpleXMLElement($response); + $course = $courses->course[0]; + + list($author, $dummy) = explode(':', (string)$course->owner); + + $this->id = (string)$course->id; + $this->title = (string)$course->description; + $this->authors = $author; + } + + } + + /** + * get permission-status + * + * + * @param string $operation operation + * @return boolean allowed + */ + public function isAllowed($operation) + { + return true; + } + + /** + * store connection between Stud.IP course and LonCapa course + * + * @param string $seminar_id + * @return bool + */ + public function setConnection($seminar_id) + { + $this->is_connected = true; + return ObjectConnections::setConnection( + $seminar_id, + $this->id, + $this->module_type, + $this->cms_type + ); + } +} diff --git a/lib/elearning/LonCapaRequest.class.php b/lib/elearning/LonCapaRequest.class.php new file mode 100644 index 0000000..ecf3075 --- /dev/null +++ b/lib/elearning/LonCapaRequest.class.php @@ -0,0 +1,110 @@ +<?php +/** + * + * This class is used to communicate with LonCapa + * + * @depends curl + * @modulegroup elearning_interface_modules + * @module LonCapaContentModule + * @package ELearning-Interface + */ +class LonCapaRequest +{ + /** + * options for curl + * @var array + */ + protected $options; + /** + * curl resource + * @var resource + */ + protected $ch; + + /** + * LonCapaRequest constructor. + */ + public function __construct() + { + $this->ch = curl_init(); + $this->initOptions(); + } + + /** + * initializes curl options + */ + public function initOptions() + { + $this->options = [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + //CURLOPT_CAINFO => '', + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false + ]; + } + + /** + * close connection + */ + public function __destruct() + { + curl_close($this->ch); + } + + /** + * set curl options + * @param $key + * @param $value + */ + public function setOption($key, $value) + { + $this->options[$key] = $value; + } + + /** + * do a curl request on the given url and return the result if successfull + * + * @param $url string + * @param array $postfields + * @return string + */ + public function request($url, $postfields = null) + { + $result = $this->sendRequest($url, $postfields); + if ($result['statusCode'] == 200) { + return $result['response']; + } else { + // TODO: fehlermeldung wäre schöner + return null; + } + } + + /** + * do a curl request on the given url and return the result if successfull + * @param $url string + * @param array $postfields + * @return array + */ + protected function sendRequest($url, $postfields = null) + { + $options = $this->options; + $options[CURLOPT_URL] = $url; + + if ($postfields) { + $options[CURLOPT_POST] = true; + $options[CURLOPT_POSTFIELDS] = $postfields; + } + + curl_setopt_array($this->ch, $options); + $response = curl_exec($this->ch); + + $statusCode = curl_getinfo($this->ch, CURLINFO_HTTP_CODE); + + if ($response === false) { + $last_error = curl_error($this->ch); + Log::error(__CLASS__ . ' curl_exec failed: ' . $last_error); + } + return compact('statusCode', 'response'); + } +} diff --git a/lib/elearning/ObjectConnections.class.php b/lib/elearning/ObjectConnections.class.php new file mode 100644 index 0000000..fc28b9b --- /dev/null +++ b/lib/elearning/ObjectConnections.class.php @@ -0,0 +1,256 @@ +<?php +# Lifter002: DONE +# Lifter003: TEST +# Lifter007: TODO +# Lifter010: TODO +/** +* class to handle object connections +* +* This class contains methods to handle connections between stud.ip-objects and external content. +* +* @author Arne Schröder <schroeder@data-quest.de> +* @access public +* @modulegroup elearning_interface_modules +* @module ObjectConnections +* @package ELearning-Interface +*/ +class ObjectConnections +{ + var $id; + var $object_connections; + /** + * constructor + * + * init class. + * @access public + * @param string $object_id object-id + */ + function __construct($object_id = "") + { + $this->id = $object_id; + if ($object_id != "") + $this->readData(); + } + + /** + * read object connections + * + * gets object connections from database + * @access public + */ + function readData() + { + global $ELEARNING_INTERFACE_MODULES; + + $this->object_connections = []; + + $query = "SELECT system_type, module_type, module_id, chdate + FROM object_contentmodules + WHERE object_id = ? + ORDER BY chdate DESC"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$this->id]); + + $module_count = 0; + while ($row = $statement->fetch(PDO::FETCH_ASSOC)) { + // show only connected modules with valid module-type + if ($ELEARNING_INTERFACE_MODULES[$row['system_type']]['types'][$row['module_type']] == '') { + continue; + } + $module_count += 1; + $d_system_type = $row['system_type']; + $d_module_type = $row['module_type']; + $d_module_id = $row['module_id']; + + $reference = $d_system_type . '_' . $d_module_type . '_' . $d_module_id; + $this->object_connections[$reference]['cms'] = $d_system_type; + $this->object_connections[$reference]['type'] = $d_module_type; + $this->object_connections[$reference]['id'] = $d_module_id; + $this->object_connections[$reference]['chdate'] = $row['chdate']; + } + + if ($module_count == 0) { + $this->object_connections = false; + } + } + + /** + * get object connections + * + * returns object connections + * @access public + * @return array object connections + */ + function getConnections() + { + return $this->object_connections; + } + + /** + * get connection-status + * + * returns true, if object has connections + * @access public + * @return boolean connection-status + */ + function isConnected() + { + return (boolean) $this->object_connections; + } + + /** + * get connection-status + * + * returns true, if object has connections + * @access public + * @param string $object_id object-id (optional) + * @return boolean connection-status + */ + public static function isObjectConnected($object_id = null) + { + if (isset($object_id)) { + $query = "SELECT 1 FROM object_contentmodules WHERE object_id = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$object_id]); + return (bool)$statement->fetchColumn(); + } + } + + /** + * get module-id + * + * returns module-id of given connection + * @access public + * @param string $connection_object_id object-id + * @param string $connection_module_type module-type + * @param string $connection_cms system-type + * @return string module-id + */ + public static function getConnectionModuleId($connection_object_id, $connection_module_type, $connection_cms) + { + $query = "SELECT module_id + FROM object_contentmodules + WHERE object_id = ? AND system_type = ? AND module_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_object_id, + $connection_cms, + $connection_module_type + ]); + return $statement->fetchColumn() ?: false; + } + + /** + * set connection + * + * sets connection with object + * @access public + * @param string $connection_object_id object-id + * @param string $connection_module_id module-id + * @param string $connection_module_type module-type + * @param string $connection_cms system-type + * @return boolean successful + */ + public static function setConnection($connection_object_id, $connection_module_id, $connection_module_type, $connection_cms) + { + $query = "SELECT 1 + FROM object_contentmodules + WHERE object_id = ? AND module_id = ? AND system_type = ? + AND module_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_object_id, + $connection_module_id, + $connection_cms, + $connection_module_type + ]); + $check = $statement->fetchColumn(); + + if ($check) { + $query = "UPDATE object_contentmodules + SET module_type = ?, chdate = UNIX_TIMESTAMP() + WHERE object_id = ? AND module_id = ? AND system_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_module_type, + $connection_object_id, + $connection_module_id, + $connection_cms + ]); + } else { + $query = "INSERT INTO object_contentmodules + (object_id, module_id, system_type, module_type, mkdate, chdate) + VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_object_id, + $connection_module_id, + $connection_cms, + $connection_module_type + ]); + } + return true; + } + + /** + * unset connection + * + * deletes connection with object + * @access public + * @param string $connection_object_id object-id + * @param string $connection_module_id module-id + * @param string $connection_module_type module-type + * @param string $connection_cms system-type + * @return boolean successful + */ + public static function unsetConnection($connection_object_id, $connection_module_id, $connection_module_type, $connection_cms) + { + $query = "SELECT 1 + FROM object_contentmodules + WHERE object_id = ? AND module_id = ? AND system_type = ? + AND module_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_object_id, + $connection_module_id, + $connection_cms, + $connection_module_type + ]); + $check = $statement->fetchColumn(); + + + if ($check) { + $query = "DELETE FROM object_contentmodules + WHERE object_id = ? AND module_id = ? AND system_type = ? + AND module_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([ + $connection_object_id, + $connection_module_id, + $connection_cms, + $connection_module_type + ]); + return true; + } + return false; + } + + public static function GetConnectedSystems($object_id) + { + $query = "SELECT DISTINCT system_type + FROM object_contentmodules + WHERE object_id = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$object_id]); + return $statement->fetchAll(PDO::FETCH_COLUMN); + } + + public static function DeleteAllConnections($object_id, $cms_type) + { + $query = "DELETE FROM object_contentmodules + WHERE object_id = ? AND system_type = ?"; + $statement = DBManager::get()->prepare($query); + $statement->execute([$object_id, $cms_type]); + return $statement->rowCount(); + } +} diff --git a/lib/elearning/PmWikiConnectedCMS.class.php b/lib/elearning/PmWikiConnectedCMS.class.php new file mode 100644 index 0000000..5c123be --- /dev/null +++ b/lib/elearning/PmWikiConnectedCMS.class.php @@ -0,0 +1,84 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/* + * PmWikiConnectedCMS.class.php - Provides search capabilities + * to search WikiFarm + * + * Copyright (C) 2006 - Marco Diedrich (mdiedric@uos.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +require_once 'clients/xml_rpc_webservice_client.php'; +require_once 'clients/soap_webservice_client.php'; +require_once 'clients/webservice_client.php'; + +/** +* main-class for connection to PmWiki +* +* This class contains the main methods of the elearning-interface to connect to PmWiki. Extends ConnectedCMS. +* +* @author Marco Diedrich <mdiedric@uos.de> +* @access public +* @modulegroup elearning_interface_modules +* @module PmWikiConnectedCMS +* @package ELearning-Interface +*/ + +class PmWikiConnectedCMS extends ConnectedCMS +{ + function __construct($cms) + { + parent::__construct($cms); + $this->client = WebserviceClient::instance( $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['ABSOLUTE_PATH_SOAP'] . + '?' . $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['URL_PARAMS'], + $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['WEBSERVICE_CLASS']); + + $this->api_key = $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['soap_data']['api-key']; + } + + function init($cms) + { + parent::init($cms); + $this->field_script = $GLOBALS['ELEARNING_INTERFACE_MODULES'][$cms]["field_script"]; + } + + /** + * search for content modules + * + * returns found content modules + * @access public + * @param string $key keyword + * @return array list of content modules + */ + + function searchContentModules($key) + { + $fields_found = $this->client->call("search_content_modules", $args = [ + $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['soap_data']['api-key'], + $key]); + + $result = []; + + foreach($fields_found as $field) + { + + $result[$field['field_id']] = [ 'ref_id' => $field['field_id'], + 'type' => $field['field_type'], + 'obj_id' => $field_id, + 'create_date' => $field['create_date'], + 'last_update' => $field['change_date'], + 'title' => $field['field_title'], + 'description' => $field['field_description']]; + } + return $result; + } + +} diff --git a/lib/elearning/PmWikiConnectedLink.class.php b/lib/elearning/PmWikiConnectedLink.class.php new file mode 100644 index 0000000..8ed7416 --- /dev/null +++ b/lib/elearning/PmWikiConnectedLink.class.php @@ -0,0 +1,134 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/* + * PmWikiConnectedLink.class.php - Provides links to PmWiki Modules + * + * Copyright (C) 2006 - Marco Diedrich (mdiedric@uos.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +use Studip\Button, Studip\LinkButton; + +require_once 'lib/webservices/api/studip_seminar.php'; + +/** +* +* This class contains methods to generate links to PmWiki-Farm +* +* @author Marco Diedrich <mdiedric@uos.de> +* @access public +* @modulegroup elearning_interface_modules +* @module PmWikiConnectedLink +* @package ELearning-Interface +*/ + +class PmWikiConnectedLink extends ConnectedLink +{ + function __construct($cms) + { + parent::__construct($cms); + $this->cms_link = "pmwiki_referrer.php"; + } + + /** + * get user module links + * + * returns content module links for user + * @access public + * @return string html-code + */ + + function getUserModuleLinks() + { + $range_id = Context::getId(); + $username = get_username($GLOBALS['auth']->auth['uid']); + + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + // hier muss die Authentifizierung mit übergeben werden... + // + if (Context::isCourse()) { + $context = 'seminar'; + + $status = StudipSeminarHelper::get_user_status($username, $range_id); + + } else if (Context::isInstitute()) { + $context = 'institute'; + + $status = StudipInstituteHelper::get_user_status($username, $range_id); + } + + ob_start(); ?> + <form method="post" target="_blank" rel="noopener noreferrer" + action="<?= $connected_cms[$this->cms_type]->content_module[$current_module]->link ?>"> + + <?= CSRFProtection::tokenTag() ?> + <input type='hidden' name='authid' value='<?= htmlReady($GLOBALS['auth']->auth['uname']) ?>'> + <input type='hidden' name='authpw' value='<?= htmlReady(Token::create()) ?>'> + <input type='hidden' name='_permission' value='<?= htmlReady($status) ?>'> + <input type='hidden' name='_range_id' value='<?= htmlReady($range_id) ?>'> + <input type='hidden' name='_server' value='<?= htmlReady(Config::get()->STUDIP_INSTALLATION_ID) ?>'> + <input type='hidden' name='_context' value='<?= htmlReady($context) ?>'> + <?= Button::createAccept(_('Starten')) ?> + + </form> + + <?php + + $output = ob_get_contents(); + ob_end_clean(); + return $output; + } + + /** + * get admin module links + * + * returns links add or remove a module from course + * @access public + * @return string returns html-code + */ + + function getAdminModuleLinks() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + ob_start(); ?> + + <form method="post" action="<?= URLHelper::getLink() ?>"> + <?= CSRFProtection::tokenTag() ?> + <input type="hidden" name="view" value="<?= htmlReady($view) ?>"> + <input type="hidden" name="search_key" value="<?= htmlReady($search_key) ?>"> + <input type="hidden" name="cms_select" value="<?= htmlReady($cms_select) ?>"> + <input type="hidden" name="module_type" value="wiki"> + <input type="hidden" name="module_id" value="<?= htmlReady($current_module) ?>"> + <input type="hidden" name="module_system_type" value="<?= htmlReady($this->cms_type) ?>"> + + <?php if ($connected_cms[$this->cms_type]->content_module[$current_module]->isConnected()) : ?> + + <?= Button::create(_('Entfernen'), 'remove') ?> + + <?php else :?> + + <?= Button::create(_('Hinzufügen'), 'add') ?> + + <?php endif ; ?> + + </form> + <?php + + $output = ob_get_contents(); + + ob_end_clean(); + + return $output; + } + +} diff --git a/lib/elearning/PmWikiContentModule.class.php b/lib/elearning/PmWikiContentModule.class.php new file mode 100644 index 0000000..e16756a --- /dev/null +++ b/lib/elearning/PmWikiContentModule.class.php @@ -0,0 +1,111 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +/* + * PmWikiContentModule.class.php - Provides access PmWiki Modules + * + * Copyright (C) 2006 - Marco Diedrich (mdiedric@uos.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +/** +* +* This class contains methods to handle PmWiki learning modules +* +* @author Marco Diedrich <mdiedric@uos.de> +* @access public +* @modulegroup elearning_interface_modules +* @module PmWikiContentModule +* @package ELearning-Interface +*/ + +class PmWikiContentModule extends ContentModule +{ + + /** + * constructor + * + * init class. + * @access public + * @param string $module_id module-id + * @param string $module_type module-type + * @param string $cms_type system-type + */ + + function __construct($module_id = "", $module_type, $cms_type) + { + parent::__construct($module_id, $module_type, $cms_type); + $this->link = $GLOBALS['connected_cms'][$this->cms_type]->ABSOLUTE_PATH_ELEARNINGMODULES.$this->id."/"; + $this->client = WebserviceClient::instance( $this->link. '?' . + $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['URL_PARAMS'], + $GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['WEBSERVICE_CLASS']); + } + + /** + * reads data for content module + * + */ + + function readData() + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + $args = [$GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['soap_data']['api-key'], $this->id]; + + $field_data = $connected_cms[$this->cms_type]->client->call('get_field_info', $args); + + $this->title = $field_data['field_title']; + $this->authors = $field_data['field_author']; + $this->chdate = $field_data['change_date']; + + $this->accepted_users = $field_data['field_accepted_users']; + + return false; + } + + /** + * get permission-status + * + * returns true, if operation is allowed + * @access public + * @param string $operation operation + * @return boolean allowed + */ + + function isAllowed($operation) + { + global $connected_cms, $view, $search_key, $cms_select, $current_module; + + if (Config::get()->STUDIP_INSTALLATION_ID) + { + $username = Config::get()->STUDIP_INSTALLATION_ID."#".$GLOBALS['auth']->auth['uname']; + } else + { + $username = $GLOBALS['auth']->auth['uname']; + } + + $args = [$GLOBALS['ELEARNING_INTERFACE_MODULES'][$this->cms_type]['soap_data']['api-key'],$this->id, $username]; + + $authorized = $connected_cms[$this->cms_type]->client->call('field_accessable_by_user', $args); + + if ($authorized) + { + return true; + } else + { + # old authorization + if (is_array($this->accepted_users) && in_array($username, $this->accepted_users)) + return true; + else + return false; + } + + } +} diff --git a/lib/elearning/clients/soap_webservice_client.php b/lib/elearning/clients/soap_webservice_client.php new file mode 100644 index 0000000..9573f13 --- /dev/null +++ b/lib/elearning/clients/soap_webservice_client.php @@ -0,0 +1,23 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +require_once 'webservice_client.php'; +require_once 'vendor/nusoap/nusoap.php'; + +class Soap_WebserviceClient extends WebserviceClient +{ + public function __construct($webservice_url) + { + $this->client = new soap_client($webservice_url); + $this->client->response_timeout = 7600; + } + + public function &call($method_name, &$args) + { + return $this->client->call($method_name, $args); + } +} + diff --git a/lib/elearning/clients/webservice_client.php b/lib/elearning/clients/webservice_client.php new file mode 100644 index 0000000..eea74a0 --- /dev/null +++ b/lib/elearning/clients/webservice_client.php @@ -0,0 +1,29 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +class WebserviceClient +{ + public static function instance($webservice_url, $classname) + { + static $instances = []; + + if (!$instances[$classname . $webservice_url]) { + $instances[$classname . $webservice_url] = new $classname($webservice_url); + } + + return $instances[$classname . $webservice_url]; + } + + public function __construct() + { + trigger_error("this class can't be instantiated"); + } + + public function &call($method_name, &$args) + { + trigger_error("WebserviceCaller::WebserviceCaller:: call not defined"); + } +} diff --git a/lib/elearning/clients/xml_rpc_webservice_client.php b/lib/elearning/clients/xml_rpc_webservice_client.php new file mode 100644 index 0000000..6060a0e --- /dev/null +++ b/lib/elearning/clients/xml_rpc_webservice_client.php @@ -0,0 +1,33 @@ +<?php +# Lifter002: TODO +# Lifter007: TODO +# Lifter003: TODO +# Lifter010: TODO + +require_once __DIR__ . '/webservice_client.php'; + +class XML_RPC_WebserviceClient extends WebserviceClient +{ + public function __construct($webservice_url) + { + $this->client = new xmlrpc_client($webservice_url); + #$this->client->verifyhost = true; + $this->client->debug = false; + $this->client->verifypeer = false; + $this->client->response_timeout = 7600; + $this->client->return_type = 'phpvals'; + + } + + public function &call($method_name, &$args) + { + $xmlrpc_args = []; + foreach ($args as $arg) + { + $xmlrpc_args[] = php_xmlrpc_encode($arg); + } + + $xmlrpc_return = $this->client->send(new xmlrpcmsg($method_name, $xmlrpc_args), 300); + return $xmlrpc_return->value(); + } +} diff --git a/lib/elearning/studip_referrer.php b/lib/elearning/studip_referrer.php new file mode 100644 index 0000000..7a0257c --- /dev/null +++ b/lib/elearning/studip_referrer.php @@ -0,0 +1,124 @@ +<?php +/* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */ + +/** +* redirect script for studip-users +* +* @author Arne Schroeder <schroeder@data-quest.de> +* @author Andre Noack <noack@data-quest.de> +* +*/ + +/* ILIAS Version 4.4.x */ + +if(file_exists("./ilias.ini.php")){ + require_once("./Services/Init/classes/class.ilIniFile.php"); + $ilIliasIniFile = new ilIniFile("./ilias.ini.php"); + $ilIliasIniFile->read(); + $serverSettings = $ilIliasIniFile->readGroup("server"); + if ($serverSettings["studip"] != 1) + { + echo 'Option "studip" in ilias.ini.php is not enabled. You need to add studip = "1" to the server section.'; + exit(); + } + + $cookie_path = dirname($_SERVER['PHP_SELF']); + if (mb_substr($cookie_path,-1) != "/") { + $cookie_path .= "/"; + } + if (isset($_GET['sess_id'])) + { + setcookie('PHPSESSID',$_GET['sess_id'],0, $cookie_path); + $_COOKIE['PHPSESSID'] = $_GET['sess_id']; + } + + if (isset($_GET['client_id'])) + { + setcookie('ilClientId',$_GET['client_id'],0, $cookie_path); + $_COOKIE['ilClientId'] = $_GET['client_id']; + } + + require_once "./include/inc.header.php"; + + $base_url= "ilias.php?baseClass=ilPersonalDesktopGUI"; + + + // redirect to specified page + $redirect = false; + switch($_GET['target']) + { + case 'start': + switch($_GET['type']) + { + case 'lm': + $base_url= "ilias.php?baseClass=ilLMPresentationGUI"; + break; + case 'tst': + $base_url= "ilias.php?cmd=infoScreen&cmdClass=ilobjtestgui&baseClass=ilRepositoryGUI"; + break; + case 'svy': + $base_url= "ilias.php?cmd=infoScreen&cmdClass=ilObjSurveyGUI&baseClass=ilRepositoryGUI"; + break; + case 'exc': + $base_url= "ilias.php?cmd=infoScreen&cmdClass=ilExerciseHandlerGUI&baseClass=ilRepositoryGUI"; + break; + case 'sahs': + $base_url = "ilias.php?baseClass=ilSAHSPresentationGUI"; + break; + case 'htlm': + $base_url = "ilias.php?baseClass=ilHTLMPresentationGUI"; + break; + case 'glo': + $base_url = "ilias.php?baseClass=ilGlossaryPresentationGUI"; + break; + case 'cat': + case 'crs': + $base_url= "ilias.php?cmd=render&cmdClass=ilrepositorygui&baseClass=ilRepositoryGUI"; + break; + case 'webr': + $base_url= "ilias.php?cmd=calldirectlink&baseClass=ilLinkResourceHandlerGUI"; + break; + } + break; + case 'new': + $base_url = "ilias.php?baseClass=ilRepositoryGUI&cmd=create&new_type=".preg_replace('/[^a-z]/', '', $_GET['type']); + break; + case 'edit': + switch($_GET['type']) + { + case 'lm': + $base_url = "ilias.php?baseClass=ilLMEditorGUI"; + break; + case 'tst': + $base_url = "ilias.php?baseClass=ilObjTestGUI"; + break; + case 'sahs': + $base_url = "ilias.php?baseClass=ilSAHSEditGUI"; + break; + case 'htlm': + $base_url = "ilias.php?baseClass=ilHTLMEditorGUI"; + break; + case 'glo': + $base_url = "ilias.php?baseClass=ilGlossaryEditorGUI"; + break; + case 'svy': + $base_url = "ilias.php?baseClass=ilObjSurveyGUI"; + break; + case 'exc': + $base_url = "ilias.php?baseClass=ilExerciseHandlerGUI"; + break; + case 'webr': + $base_url = "ilias.php?baseClass=ilLinkResourceHandlerGUI"; + break; + } + break; + } + if ($base_url) + { + $base_url .= "&ref_id=".(int)$_GET['ref_id']; + $base_url = html_entity_decode($ilCtrl->appendRequestTokenParameterString($base_url)); + header("Location: " . $base_url); + exit(); + } +} +?>
\ No newline at end of file |
