Show Advanced KnowledgeHide Advanced KnowledgeRepository Object Plugins
The goal of the repository object plugin slot is to implement new types of learning resources that can be added to the ILIAS repository like the existing ones (e.g. forums, glossaries, tests, ...).
Please make sure that you have read the general plugin implementation documentation.
This slot is defined by the Repository Service of ILIAS and named "RepositoryObject". This means all plugins have to be installed into directories at:
Customizing/global/plugins/Services/Repository/RepositoryObject/<Plugin_Name>
The ID of the Repository Service Component is "rep", the ID of the slot is "robj". These are used as prefixes together with your plugin id for database tables and for language variable identifiers:
DB Table / Language VariablePrefixes: rep_robj_<Plugin_ID>_
Plugin Directory Structure
A repository object plugin has the following file/directory structure:
<PluginName> (Directory) classes (Directory) class.il<PluginName>Plugin.php class.ilObj<PluginName>.php class.ilObj<PluginName>Access.php class.ilObj<PluginName>GUI.php class.ilObj<PluginName>ListGUI.php lang (Directory) ilias_<LangKey>.lang sql (Directory) dbupdate.php templates (Directory) images (Directory) ... tpl...html plugin.php |
Plugin Files
We will now have a detailed look on all mandatory files and an example implementation. The name of the plugin is "TestRepositoryObject", so its location will be at (an example of this plugin can be downloaded here: https://github.com/ILIAS-eLearning/TestRepositoryObject):
Customizing/global/plugins/Services/Repository/RepositoryObject/TestRepositoryObject
plugin.php
All plugins must include a plugin.php file.
<?php $id = "xtst"; // code version; must be changed for all code changes $version = "0.0.4"; // ilias min and max version; must always reflect the versions that should // run with the plugin $ilias_min_version = "5.1.0"; $ilias_max_version = "5.2.999"; // optional, but useful: Add one or more responsible persons and a contact email $responsible = "ILIAS Development"; $responsible_mail = "info@ilias.de"; $supports_export = true; // Enable learning progress $learning_progress = true; ?> |
The plugin id is also used as an internal repository object type ID. All ILIAS repository objects are internally represented by a type ID, e.g. "glo" for glossaries or "chat" for chats. This sets additional constrains on the plugin id:
The plugin ID must have a length of three or four characters. The plugin ID must start with an "x". Type IDs starting with "x" are reserved for plugins and will not be used by future ILIAS repository objects. Please check the plugin data collection for your preferred ID to avoid a duplicate ID.
classes/class.il<PluginName>Plugin.php
<?php include_once("./Services/Repository/classes/class.ilRepositoryObjectPlugin.php"); /** */ class ilTestRepositoryObjectPlugin extends ilRepositoryObjectPlugin { const ID = "xtst"; // must correspond to the plugin subdirectory function getPluginName() { return "TestRepositoryObject"; } protected function uninstallCustom() { // TODO: Nothing to do here. } } ?> |
The implementation of the plugin class is quite easy. It must be derived from ilRepositoryObjectPlugin
. Most likely you will only have to replace the two occurrences of "Example" by your plugin name in the code above.
classes/class.ilObj<PluginName>.php
This is the main application class of the repository object. It is derived from ilObjectPlugin
which is derived from ilObject2
which again derives from ilObject
. All ILIAS repository objects implement a class that is derived from ilObject2
. Please have a look at the general architecure to understand the separation of responsibilities between application and GUI classes. Also have a look at the guidelines about database handling.
<?php include_once("./Services/Repository/classes/class.ilObjectPlugin.php"); require_once("./Services/Tracking/interfaces/interface.ilLPStatusPlugin.php"); require_once("./Customizing/global/plugins/Services/Repository/RepositoryObject/TestRepositoryObject/classes/class.ilObjTestRepositoryObjectGUI.php"); /** */ class ilObjTestRepositoryObject extends ilObjectPlugin implements ilLPStatusPluginInterface { /** * Constructor * * @access public * @param int $a_ref_id */ function __construct($a_ref_id = 0) { parent::__construct($a_ref_id); } /** * Get type. */ final function initType() { $this->setType(ilTestRepositoryObjectPlugin::ID); } /** * Create object */ function doCreate() { global $ilDB; $ilDB->manipulate("INSERT INTO rep_robj_xtst_data ". "(id, is_online, option_one, option_two) VALUES (". $ilDB->quote($this->getId(), "integer").",". $ilDB->quote(0, "integer").",". $ilDB->quote("default 1", "text").",". $ilDB->quote("default 2", "text"). ")"); } /** * Read data from db */ function doRead() { global $ilDB; $set = $ilDB->query("SELECT * FROM rep_robj_xtst_data ". " WHERE id = ".$ilDB->quote($this->getId(), "integer") ); while ($rec = $ilDB->fetchAssoc($set)) { $this->setOnline($rec["is_online"]); } } /** * Update data */ function doUpdate() { global $ilDB; $ilDB->manipulate($up = "UPDATE rep_robj_xtst_data SET ". " is_online = ".$ilDB->quote($this->isOnline(), "integer")."". " WHERE id = ".$ilDB->quote($this->getId(), "integer") ); } /** * Delete data from db */ function doDelete() { global $ilDB; $ilDB->manipulate("DELETE FROM rep_robj_xtst_data WHERE ". " id = ".$ilDB->quote($this->getId(), "integer") ); } /** * Do Cloning */ function doClone($a_target_id,$a_copy_id,$new_obj) { global $ilDB; $new_obj->setOnline($this->isOnline()); $new_obj->setOptionOne($this->getOptionOne()); $new_obj->setOptionTwo($this->getOptionTwo()); $new_obj->update(); } /** * Set online * * @param boolean online */ function setOnline($a_val) { $this->online = $a_val; } /** * Get online * * @return boolean online */ function isOnline() { return $this->online; } /** * Get all user ids with LP status completed * * @return array */ public function getLPCompleted() { return array(); } /** * Get all user ids with LP status not attempted * * @return array */ public function getLPNotAttempted() { return array(); } /** * Get all user ids with LP status failed * * @return array */ public function getLPFailed() { return array(6); } /** * Get all user ids with LP status in progress * * @return array */ public function getLPInProgress() { return array(); } /** * Get current status for given user * * @param int $a_user_id * @return int */ public function getLPStatusForUser($a_user_id) { global $ilUser; if($ilUser->getId() == $a_user_id) return $_SESSION[ilObjTestRepositoryObjectGUI::LP_SESSION_ID]; else return ilLPStatus::LP_STATUS_NOT_ATTEMPTED_NUM; } } ?> |
The main responsibility of the application class is handling the persistent layer by reading from and writing into the database. You must overwrite the following method:
- initType()
- The
initType()
method must set the same ID as the plugin ID.
And you should override the following methods:
- doCreate()
- This method is called, when a new repository object is created. The Object-ID of the new object can be obtained by
$this->getId()
. You can store any properties of your object that you need. It is also possible to use multiple tables. In this example we store three properties, an "is online" flag and two text options. Standard properites like title and description are handled by the parent classes.
- doRead()
- This method is called when an instance of a repository object is created and an existing Reference-ID is provided to the constructor. All you need to do is to read the properties of your object from the database and to call the corresponding set-methods.
- doUpdate()
- This method is called, when an existing object is updated.
- doDelete()
- This method is called, when a repository object is finally deleted from the system. It is not called if an object is moved to the trash.
- doCloneObject()
- This method is called, when a repository object is copied.
sql/dbupdate.php
The object application class is using a database table called "rep_robj_xexo_data". This cryptic name starts with the component id "rep" and slot id "robj" followed by the id of your plugin "xexo". The name "data" is the chosen table name in this case. You can choose every name you want, as long as the overall table name is not longer than 22 characters, all characters are lowercase a-z or numbers 0-9. The table is created in the file sql/dbupdate.php
.
<#1> <?php $fields = array( 'id' => array( 'type' => 'integer', 'length' => 4, 'notnull' => true ), 'is_online' => array( 'type' => 'integer', 'length' => 1, 'notnull' => false ), 'option_one' => array( 'type' => 'text', 'length' => 10, 'fixed' => false, 'notnull' => false ), 'option_two' => array( 'type' => 'text', 'length' => 10, 'fixed' => false, 'notnull' => false ) ); $ilDB->createTable("rep_robj_xtst_data", $fields); $ilDB->addPrimaryKey("rep_robj_xtst_data", array("id")); ?> |
The file contains a number of php code sections starting with a sequential number <#1>, <#2>, ... Each code section is wrapped into <?php ... ?> tags. Each step manipulates the database by adding, altering, deleting tables or table columns or updating data as you want it. See the database guidelines to see how to do this.
If you add any steps to this file you must also increase the plugin version number in your plugin.php file:
$version = "0.0.8";
This will automatically deactivate the plugin (if it has been activated before) and offer an "update" link in the ILIAS "Modules, Services and Plugins" administration.
ILIAS internally stores the maximum step number that has already been executed. If you implement your plugin, you sometimes need to run certain steps again. This value is stored in an ILIAS table called "il_plugin" in a column "db_version". Look for the record with your plugin name/ID. You may set this to a lower value, if necessary. Again you have to increase the plugin version value in plugin.php, too, to get the update link in the ILIAS administration.
classes/class.ilObj<PluginName>GUI.php
This one is the major user interface class for your repository object. See the basic architectur for responsibilities of user interface classes.
The flow of control between user interface classes is handled by a controller object called $ilCtrl. Every request is targeted to a command that is executed in one user interface class, but involves a larger number of user interface classes that generate the HTML that is responded to the browser of the user. The $ilCtrl class forwards the flow of control to most of the user interface classes involved in a request (sometimes GUI classes call other GUI classes directly to get certain HTML snippets).
<?php include_once("./Services/Repository/classes/class.ilObjectPluginGUI.php"); require_once("./Services/Form/classes/class.ilPropertyFormGUI.php"); require_once("./Services/Form/classes/class.ilTextInputGUI.php"); require_once("./Services/Form/classes/class.ilCheckboxInputGUI.php"); require_once("./Services/Tracking/classes/class.ilLearningProgress.php"); require_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php"); require_once("./Services/Tracking/classes/status/class.ilLPStatusPlugin.php"); require_once("./Customizing/global/plugins/Services/Repository/RepositoryObject/TestRepositoryObject/classes/class.ilTestRepositoryObjectPlugin.php"); /** * @ilCtrl_isCalledBy ilObjTestRepositoryObjectGUI: ilRepositoryGUI, ilAdministrationGUI, ilObjPluginDispatchGUI * @ilCtrl_Calls ilObjTestRepositoryObjectGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI, ilCommonActionDispatcherGUI, ilExportGUI */ class ilObjTestRepositoryObjectGUI extends ilObjectPluginGUI { const LP_SESSION_ID = 'xtst_lp_session_state'; /** @var ilCtrl */ protected $ctrl; /** @var ilTabsGUI */ protected $tabs; /** @var ilTemplate */ public $tpl; /** * Initialisation */ protected function afterConstructor() { global $ilCtrl, $ilTabs, $tpl; $this->ctrl = $ilCtrl; $this->tabs = $ilTabs; $this->tpl = $tpl; } public function executeCommand() { global $tpl; $next_class = $this->ctrl->getNextClass($this); switch ($next_class) { case 'ilexportgui': // only if plugin supports it? $tpl->setTitle($this->object->getTitle()); $tpl->setTitleIcon(ilObject::_getIcon($this->object->getId())); $this->setLocator(); $tpl->getStandardTemplate(); $this->setTabs(); include_once './Services/Export/classes/class.ilExportGUI.php'; $this->tabs->activateTab("export"); $exp = new ilExportGUI($this); $exp->addFormat('xml'); $this->ctrl->forwardCommand($exp); $tpl->show(); return; break; } $return_value = parent::executeCommand(); return $return_value; } /** * Get type. */ final function getType() { return ilTestRepositoryObjectPlugin::ID; } /** * Handles all commmands of this class, centralizes permission checks */ function performCommand($cmd) { switch ($cmd) { case "editProperties": // list all commands that need write permission here case "updateProperties": case "saveProperties": case "showExport": $this->checkPermission("write"); $this->$cmd(); break; case "showContent": // list all commands that need read permission here case "setStatusToCompleted": case "setStatusToFailed": case "setStatusToInProgress": case "setStatusToNotAttempted": $this->checkPermission("read"); $this->$cmd(); break; } } /** * After object has been created -> jump to this command */ function getAfterCreationCmd() { return "editProperties"; } /** * Get standard command */ function getStandardCmd() { return "showContent"; } // // DISPLAY TABS // /** * Set tabs */ function setTabs() { global $ilCtrl, $ilAccess; // tab for the "show content" command if ($ilAccess->checkAccess("read", "", $this->object->getRefId())) { $this->tabs->addTab("content", $this->txt("content"), $ilCtrl->getLinkTarget($this, "showContent")); } // standard info screen tab $this->addInfoTab(); // a "properties" tab if ($ilAccess->checkAccess("write", "", $this->object->getRefId())) { $this->tabs->addTab("properties", $this->txt("properties"), $ilCtrl->getLinkTarget($this, "editProperties")); $this->tabs->addTab("export", $this->txt("export"), $ilCtrl->getLinkTargetByClass("ilexportgui", "")); } // standard permission tab $this->addPermissionTab(); $this->activateTab(); } /** * Edit Properties. This commands uses the form class to display an input form. */ protected function editProperties() { $this->tabs->activateTab("properties"); $form = $this->initPropertiesForm(); $this->addValuesToForm($form); $this->tpl->setContent($form->getHTML()); } /** * @return ilPropertyFormGUI */ protected function initPropertiesForm() { $form = new ilPropertyFormGUI(); $form->setTitle($this->plugin->txt("obj_xtst")); $title = new ilTextInputGUI($this->plugin->txt("title"), "title"); $title->setRequired(true); $form->addItem($title); $description = new ilTextInputGUI($this->plugin->txt("description"), "description"); $form->addItem($description); $online = new ilCheckboxInputGUI($this->plugin->txt("online"), "online"); $form->addItem($online); $form->setFormAction($this->ctrl->getFormAction($this, "saveProperties")); $form->addCommandButton("saveProperties", $this->plugin->txt("update")); return $form; } /** * @param $form ilPropertyFormGUI */ protected function addValuesToForm(&$form) { $form->setValuesByArray(array( "title" => $this->object->getTitle(), "description" => $this->object->getDescription(), "online" => $this->object->isOnline(), )); } /** * */ protected function saveProperties() { $form = $this->initPropertiesForm(); $form->setValuesByPost(); if($form->checkInput()) { $this->fillObject($this->object, $form); $this->object->update(); ilUtil::sendSuccess($this->plugin->txt("update_successful"), true); $this->ctrl->redirect($this, "editProperties"); } $this->tpl->setContent($form->getHTML()); } protected function showContent() { $this->tabs->activateTab("content"); /** @var ilTemplate $template */ $template = $this->plugin->getTemplate("tpl.content.html"); /** @var ilObjTestRepositoryObject $object */ $object = $this->object; $template->setVariable("TITLE", $object->getTitle()); $template->setVariable("DESCRIPTION", $object->getDescription()); $template->setVariable("ONLINE_STATUS", $object->isOnline()?"Online":"Offline"); $template->setVariable("ONLINE_COLOR", $object->isOnline()?"green":"red"); $template->setVariable("SET_COMPLETED", $this->ctrl->getLinkTarget($this, "setStatusToCompleted")); $template->setVariable("SET_COMPLETED_TXT", $this->plugin->txt("set_completed")); $template->setVariable("SET_NOT_ATTEMPTED", $this->ctrl->getLinkTarget($this, "setStatusToNotAttempted")); $template->setVariable("SET_NOT_ATTEMPTED_TXT", $this->plugin->txt("set_not_attempted")); $template->setVariable("SET_FAILED", $this->ctrl->getLinkTarget($this, "setStatusToFailed")); $template->setVariable("SET_FAILED_TXT", $this->plugin->txt("set_failed")); $template->setVariable("SET_IN_PROGRESS", $this->ctrl->getLinkTarget($this, "setStatusToInProgress")); $template->setVariable("SET_IN_PROGRESS_TXT", $this->plugin->txt("set_in_progress")); global $ilUser; $progress = new ilLPStatusPlugin($this->object->getId()); $status = $progress->determineStatus($this->object->getId(), $ilUser->getId()); $template->setVariable("LP_STATUS", $this->plugin->txt("lp_status_".$status)); $template->setVariable("LP_INFO", $this->plugin->txt("lp_status_info")); $this->tpl->setContent($template->get()); } /** * @param $object ilObjTestRepositoryObject * @param $form ilPropertyFormGUI */ private function fillObject($object, $form) { $object->setTitle($form->getInput('title')); $object->setDescription($form->getInput('description')); $object->setOnline($form->getInput('online')); } protected function showExport() { require_once("./Services/Export/classes/class.ilExportGUI.php"); $export = new ilExportGUI($this); $export->addFormat("xml"); $ret = $this->ctrl->forwardCommand($export); } /** * We need this method if we can't access the tabs otherwise... */ private function activateTab() { $next_class = $this->ctrl->getCmdClass(); switch($next_class) { case 'ilexportgui': $this->tabs->activateTab("export"); break; } return; } private function setStatusToCompleted() { $this->setStatusAndRedirect(ilLPStatus::LP_STATUS_COMPLETED_NUM); } private function setStatusAndRedirect($status) { global $ilUser; $_SESSION[self::LP_SESSION_ID] = $status; ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId()); $this->ctrl->redirect($this, $this->getStandardCmd()); } protected function setStatusToFailed() { $this->setStatusAndRedirect(ilLPStatus::LP_STATUS_FAILED_NUM); } protected function setStatusToInProgress() { $this->setStatusAndRedirect(ilLPStatus::LP_STATUS_IN_PROGRESS_NUM); } protected function setStatusToNotAttempted() { $this->setStatusAndRedirect(ilLPStatus::LP_STATUS_NOT_ATTEMPTED_NUM); } } ?> |
Your class must be derived from ilObjectPluginGUI which is an extension of ilObjectGUI. There are some important comment lines in the header starting with @ilCtrl_isCalledBy and @ilCtrl_Calls.
Do not remove the comment lines starting with * @ilCtrl_isCalledBy and * @ilCtrl_Calls. Without them your plugin will not work. You must replace occurences of "ilObjTestRepositoryObjectGUI" with your class name in these lines.
There are some abstract functions that must be implemented:
- getType()
- You must return the plugin ID here.
- performCommand()
- This central method calls all command related methods and checks the permissions.
- getAfterCreationCmd()
- After creation of a new object, the user is redirected to this command.
- getStandardCmd()
- This command is used, as a target for permanent links.
Please notice the way the performCommand() method handles incoming commands, especially how commands are grouped per permission that is needed to execute the command. This code ensures that no command is executed without the appropriate permission to do so. Please do not add a "default" branch to this switch structure, since it would make the whole setting less secure.
You should also overwite the setTabs() method that defines the set of tabs occuring on the screen. You must include the info and permission tab within this function.
The standard template is already initialized with title/icon/locator when performCommand() is called. All you need to do is to generate the HTML output and to pass it to $tpl->setContent(...). The example uses the ILIAS form class to generate a HTML form.
classes/class.ilObj<PluginName>Access.php
Whether a user can access a certain object or not depends on different conditions. One of them is, whether the user has the permission that is needed to execute a given command on an object. This is handled by the ILIAS role based access control system RBAC. Other conditions are related to the object directly.
In this case the example object has an "online" status. If the object is not online, users without write permission may not access the object. If the object is online, the read permission is sufficient.
These conditions that are directly related to the object must be handled in the ...Access class. The smallest implementation possible only contains a method _checkAccess, that returns true everytime.
<?php include_once("./Services/Repository/classes/class.ilObjectPluginAccess.php"); /** * Access/Condition checking for Example object * * Please do not create instances of large application classes (like ilObjExample) * Write small methods within this class to determine the status. * * @author Alex Killing <alex.killing@gmx.de> * @version $Id$ */ class ilObjExampleAccess extends ilObjectPluginAccess { /** * Checks wether a user may invoke a command or not * (this method is called by ilAccessHandler::checkAccess) * * Please do not check any preconditions handled by * ilConditionHandler here. Also don't do usual RBAC checks. * * @param string $a_cmd command (not permission!) * @param string $a_permission permission * @param int $a_ref_id reference id * @param int $a_obj_id object id * @param int $a_user_id user id (default is current user) * * @return boolean true, if everything is ok */ function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "") { global $ilUser, $ilAccess; if ($a_user_id == "") { $a_user_id = $ilUser->getId(); } switch ($a_permission) { case "read": if (!ilObjExampleAccess::checkOnline($a_obj_id) && !$ilAccess->checkAccessOfUser($a_user_id, "write", "", $a_ref_id)) { return false; } break; } return true; } /** * Check online status of example object */ static function checkOnline($a_id) { global $ilDB; $set = $ilDB->query("SELECT is_online FROM rep_robj_xexo_data ". " WHERE id = ".$ilDB->quote($a_id, "integer") ); $rec = $ilDB->fetchAssoc($set); return (boolean) $rec["is_online"]; } } ?> |
Container objects like categories, courses or group must create instances of access classes of all types of objects that are occuring on the screen. This can cost a lot of memory if the access classes create instances of large objects. Please avoid this and use small methods that access your database tables directly within the access class.
classes/class.ilObj<PluginName>ListGUI.php
The ListGUI classes are used to present the object in container listings, e.g. in a course or in a category. The class defines the commands that should be available already on the container level (usually displayed as an "Action" drop-down list) and properties that should be displayed under the title and the description.
<?php include_once "./Services/Repository/classes/class.ilObjectPluginListGUI.php"; /** * handles the presentation in container items (categories, courses, ...) * together with the corresponding ...Access class. * * PLEASE do not create instances of larger classes here. Use the * ...Access class to get DB data and keep it small. */ class ilObjTestRepositoryObjectListGUI extends ilObjectPluginListGUI { /** * Init type */ function initType() { $this->setType(ilTestRepositoryObjectPlugin::ID); } /** * Get name of gui class handling the commands */ function getGuiClass() { return "ilObjTestRepositoryObjectGUI"; } /** * Get commands */ function initCommands() { return array ( array( "permission" => "read", "cmd" => "showContent", "default" => true), array( "permission" => "write", "cmd" => "editProperties", "txt" => $this->txt("edit"), "default" => false), ); } /** * Get item properties * * @return array array of property arrays: * "alert" (boolean) => display as an alert property (usually in red) * "property" (string) => property name * "value" (string) => property value */ function getProperties() { global $lng, $ilUser; $props = array(); $this->plugin->includeClass("class.ilObjTestRepositoryObjectAccess.php"); if (!ilObjTestRepositoryObjectAccess::checkOnline($this->obj_id)) { $props[] = array("alert" => true, "property" => $this->txt("status"), "value" => $this->txt("offline")); } return $props; } } ?> |
The following abstract methods must be overwritten in this class:
- initType()
- You must set the type to your plugin ID here.
- getGuiClass()
- This returns the GUI class, that handles the commands. Usually this is the main GUI class of your plugin.
- initCommands()
- This returns all commands that should be listed within container objects like categories or courses. One command should be flagged as "default" command ("default" => true). This one is put behind the title link.
Additionally you can overwrite the
getProperties()
method and provide property/value pairs that should be listed within the container listing.
Container objects like categories, courses or group must create instances of ListGUI classes of all types of objects that are occuring on the screen. This can cost a lot of memory if the access classes create instances of large objects. Please avoid this and use your corresponding access class to get any information from the database.
lang/ilias_<LangKey>.lang
Some general information on how internationalization is handled in plugins can be found in the main plugin documentation.
obj_xtst#:#Test Repository Object objs_xtst#:#Test Repository Objects obj_xtst_duplicate#:#Copy objs_xtst_duplicate#:#Copy Test Repository Objects obj_xtst_select#:#Select Test Repository Object xtst_add#:#Add Test Repository Object xtst_new#:#Add New Test Repository Object xtst_read#:#Read access to Test Repository Object xtst_write#:#Edit Test Repository Object xtst_delete#:#Delete Test Repository Object xtst_visible#:#Test Repository Object is visible xtst_edit_permission#:#Change permission settings crs_create_xtst#:#Create Test Repository Object grp_create_xtst#:#Create Test Repository Object fold_create_xtst#:#Create Test Repository Object root_create_xtst#:#Create Test Repository Object cat_create_xtst#:#Create Test Repository Object title#:#Title description#:#Description online#:#Online save#:#Save update#:#Update properties#:#Properties content#:#Content copy#:#Copy edit#:#Edit export#:#Export set_not_attempted#:#Set LP Status to not attempted set_in_progress#:#Set LP Status to in progress set_passed#:#Set LP Status to not completed set_failed#:#Set LP Status to not failed set_completed#:#Set LP Status to completed lp_status_0#:#Not Attempted lp_status_1#:#In Progress lp_status_2#:#Completed lp_status_3#:#Failed lp_status_#:#No state yet. lp_status_info#:#Attention: Setting the LP Status will set the LP status of the currently logged in user to the chosen Stauts. THE STATUS OF EVERY OTHER USER WILL BE SET TO NOT ATTEMPTED! offline:#:Offline |
The lang file must contain the entries listed above. Replace "xexo" with your plugin ID.
classes/class.il<PluginName>Exporter.php
classes/class.il<PluginName>Importer.php
To enable export and import of the plugin please add the following line to plugin.php:
$supports_export = true;
Implement the exporter and importer classes as defined by the base classes (ilXmlExporter and ilXmlImporter) and it should work as expected.
Download Full Example
Latest update of this example: 28 Mar 2011.
An important change due to bug 5347 has been made on 16 Oct 2009. If your plugin is older, you need to add "ilObjectCopyGUI" to line
* @ilCtrl_Calls ilObjExampleGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI
to prevent this problem.
The full Example-Plugin can be downloaded here:
https://github.com/ILIAS-eLearning/TestRepositoryObject
Migration
Usually we try to keep the changes that are necessary to migrate plugins from one major release to the next as small as possible or to avoid them completely. We will try to provide a list of changes that need to be done here.
ILIAS 4.2 to 4.3
classes/class.ilObj<PluginName>GUI.php: You must include a new class "ilCommonActionDispatcherGUI" in the list of classes included in the @ilCtrl_Calls comment. Do not forget to increase the version number in plugin.php afterwards.
<?php include_once("./Services/Repository/classes/class.ilObjectPluginGUI.php"); /** * User Interface class for example repository object. * ... * @ilCtrl_isCalledBy ilObjExampleGUI: ilRepositoryGUI, ilAdministrationGUI, ilObjPluginDispatchGUI * @ilCtrl_Calls ilObjExampleGUI: ilPermissionGUI, ilInfoScreenGUI, ilObjectCopyGUI * @ilCtrl_Calls ilObjExampleGUI: ilCommonActionDispatcherGUI */ |
templates/images: All images must be converted into the .png file format.
Please report any bugs to our bug tracker.
ILIAS 4.4 to 5.0
templates/images: All icons must be converted into the .svg file format.
CSS/Templating: Use Bootstrap classes wherever possible.