aboutsummaryrefslogtreecommitdiff
path: root/lib/elearning
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/elearning
current code from svn, revision 62608
Diffstat (limited to 'lib/elearning')
-rw-r--r--lib/elearning/ConnectedCMS.class.php458
-rw-r--r--lib/elearning/ConnectedLink.class.php129
-rw-r--r--lib/elearning/ConnectedPermissions.class.php57
-rw-r--r--lib/elearning/ConnectedUser.class.php514
-rw-r--r--lib/elearning/ContentModule.class.php383
-rw-r--r--lib/elearning/ContentModuleView.class.php189
-rw-r--r--lib/elearning/ELearningUtils.class.php614
-rw-r--r--lib/elearning/Ilias3ConnectedCMS.class.php362
-rw-r--r--lib/elearning/Ilias3ConnectedLink.class.php191
-rw-r--r--lib/elearning/Ilias3ConnectedPermissions.class.php260
-rw-r--r--lib/elearning/Ilias3ConnectedUser.class.php350
-rw-r--r--lib/elearning/Ilias3ContentModule.class.php297
-rw-r--r--lib/elearning/Ilias3ObjectXMLParser.class.php239
-rw-r--r--lib/elearning/Ilias3SaxParser.class.php230
-rw-r--r--lib/elearning/Ilias3Soap.class.php1070
-rw-r--r--lib/elearning/Ilias4ConnectedCMS.class.php270
-rw-r--r--lib/elearning/Ilias4ConnectedLink.class.php122
-rw-r--r--lib/elearning/Ilias4ConnectedPermissions.class.php128
-rw-r--r--lib/elearning/Ilias4ConnectedUser.class.php164
-rw-r--r--lib/elearning/Ilias4ContentModule.class.php106
-rw-r--r--lib/elearning/Ilias4Soap.class.php185
-rw-r--r--lib/elearning/Ilias5ConnectedCMS.class.php21
-rw-r--r--lib/elearning/Ilias5ConnectedLink.class.php16
-rw-r--r--lib/elearning/Ilias5ConnectedPermissions.class.php17
-rw-r--r--lib/elearning/Ilias5ConnectedUser.class.php40
-rw-r--r--lib/elearning/Ilias5ContentModule.class.php16
-rw-r--r--lib/elearning/Ilias5Soap.class.php114
-rw-r--r--lib/elearning/LonCapaConnectedCMS.class.php67
-rw-r--r--lib/elearning/LonCapaConnectedLink.class.php67
-rw-r--r--lib/elearning/LonCapaContentModule.class.php86
-rw-r--r--lib/elearning/LonCapaRequest.class.php110
-rw-r--r--lib/elearning/ObjectConnections.class.php256
-rw-r--r--lib/elearning/PmWikiConnectedCMS.class.php84
-rw-r--r--lib/elearning/PmWikiConnectedLink.class.php134
-rw-r--r--lib/elearning/PmWikiContentModule.class.php111
-rw-r--r--lib/elearning/clients/soap_webservice_client.php23
-rw-r--r--lib/elearning/clients/webservice_client.php29
-rw-r--r--lib/elearning/clients/xml_rpc_webservice_client.php33
-rw-r--r--lib/elearning/studip_referrer.php124
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 .= "&nbsp;" . Button::create(_('Entfernen'), 'remove');
+ else
+ $output .= "&nbsp;" . 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>&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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\">&nbsp;";
+ 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\">&nbsp;";
+ 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 ">&nbsp;" . _("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 ">&nbsp;" . _("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 .= "&nbsp;";
+ }
+ 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 .= "&nbsp;";
+
+ }
+ }
+ }
+
+ 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 .= "&nbsp;" . 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 .= "&nbsp;" . 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 = "&nbsp;" . 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>&nbsp;";
+
+ 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 .= "&nbsp;" . 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") . "&nbsp;";
+ $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") . "&nbsp;";
+ $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") . "&nbsp;";
+ $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") . "&nbsp;";
+ $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") . "&nbsp;";
+ $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 .= "&nbsp;" . 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()) : ?>
+
+ &nbsp;<?= Button::create(_('Entfernen'), 'remove') ?>
+
+ <?php else :?>
+
+ &nbsp;<?= 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