Pluggin creation

6,280 views
6,152 views

Published on

Pluggin creation talk given by Giulianno Mandotti in the Chamiluda 2013.

Published in: Technology, Art & Photos
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,280
On SlideShare
0
From Embeds
0
Number of Embeds
371
Actions
Shares
0
Downloads
27
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Pluggin creation

  1. 1. Chamiluda Madrid 2013
  2. 2. Chamilo Plugin Creation By: Giuliano Mandotti Chamilo LMS Association Member
  3. 3. Summary Introduction ➔ Part A ➔ 1) Presenting 2 Plugin's Example ➔ 2) Deeper Analysis of the 2 plugins ➔ Part B ➔ 1) General Plugin Pattern-Model ➔ 2) Simple Plugin Creation example ➔ Conclusion ➔
  4. 4. Introduction Myself ➔ Chamilo LMS 1.9.x ➔
  5. 5. Introduction Myself ➔
  6. 6. Introduction Chamilo LMS 1.9.x ➔
  7. 7. Where does Chamilo come from? Claroline Dokeos Dokeos Latinoamérica 2001 2004 2007 1.0 Chamilo LMS 1.8 2010 Chamilo LMS 1.9 2012
  8. 8. Chamilo 1.9.6 still is... A Learning Management System ➔ A system to help manage learning. ➔ A system to help to manage knowledge ➔ Improves informal learning eficiency ➔ Improves learning monitoring ➔ Improves the way documents are kept ➔ Improves availability of courses ➔ Reduces costs and training times ➔
  9. 9. Part A 1) Presenting 2 Plugin's Example ➔ Show user information Plugin ➔ RSS Plugin ➔ 2) Deeper Analysis of the 2 plugins ➔
  10. 10. Part A / 1 Plugin Examples Show user information Plugin ➔ RSS Plugin ➔
  11. 11. Part A / 1 Plugin Examples Administration Panel
  12. 12. Part A / 1 Plugin Examples Administration Panel / Plugin SubPanel
  13. 13. Part A / 1 Plugin Examples Plugin List
  14. 14. Part A / 1 Plugin Examples Show User Info ➔
  15. 15. Part A / 1 Plugin Examples Plugin List
  16. 16. Part A / 1 Plugin Show User Info
  17. 17. Part A / 1 Plugin Show User Info
  18. 18. Part A / 1 Plugin Show User Info
  19. 19. Part A / 1 Plugin Examples RSS ➔
  20. 20. Part A / 1 Plugin RSS Plugin List
  21. 21. Part A / 1 Plugin RSS
  22. 22. Part A / 1 Plugin RSS
  23. 23. Part A / 1 Plugin RSS
  24. 24. Part A / 2 Deeper Analysis Show user information Plugin ➔ RSS Plugin ➔
  25. 25. Part A / 2 Plugin Deeper Analysis Show User Info ➔
  26. 26. Part A / 2 Deeper Analysis Plugin Show User Info Chamilo Directory Plugin Directory
  27. 27. Part A / 2 Deeper Analysis Plugin Show User Info
  28. 28. Part A / 2 Deeper Analysis Plugin Show User Info
  29. 29. Part A / 2 Deeper Analysis Plugin Show User Info
  30. 30. Part A / 2 Deeper Analysis Plugin Show User Info
  31. 31. Part A / 2 Deeper Analysis Plugin Show User Info
  32. 32. Part A / 2 Deeper Analysis Plugin Show User Info
  33. 33. Part A / 2 Plugin Deeper Analysis Rss ➔
  34. 34. Part A / 2 Deeper Analysis RSS Chamilo Directory Plugin Directory
  35. 35. Part A / 2 Deeper Analysis RSS
  36. 36. Part A / 2 Deeper Analysis RSS
  37. 37. Part A / 2 Deeper Analysis RSS
  38. 38. Part A / 2 Deeper Analysis RSS
  39. 39. Part A / 2 Deeper Analysis RSS
  40. 40. Part A / 2 Deeper Analysis RSS
  41. 41. Part A / 2 Deeper Analysis RSS
  42. 42. Part A / 2 Deeper Analysis RSS
  43. 43. Part A / 2 Deeper Analysis RSS
  44. 44. Part B 1) General Plugin Pattern-Model ➔ 2) Simple Plugin Creation example ➔
  45. 45. Part B / 1 General Plugin Pattern-Model Important Files ➔ Roles ➔
  46. 46. Part B / 1 General Plugin Pattern-Model Important Files ➔
  47. 47. Part B / 1 Important Files Which are the most important files that Chamilo use to include Plugins?
  48. 48. Part B / 1 Important Files Global.inc.php Settings.lib.php Settings.php Configure_plugin.php Plugin.class.php Plugin.lib.php
  49. 49. Part B / 1 Important Files Where can we find them?
  50. 50. Part B / 1 Important Files
  51. 51. Part B / 1 Important Files
  52. 52. Part B / 1 Important Files
  53. 53. Part B / 1 Important Files
  54. 54. Part B / 1 General Plugin Pattern-Model Roles ➔
  55. 55. Part B / 1 Their Roles Which are their roles?
  56. 56. Part B / 1 Roles Global.inc.php (part of) ➔
  57. 57. Part B / 1 Global.inc.php ….... ….... Catch all the plugin's settings info
  58. 58. Part B / 1 Roles Settings.lib.php ➔
  59. 59. Part B / 1 Settings.lib.php <?php /* For licensing terms, see /license.txt */ …..... /** * This function allows easy activating and inactivating of regions * @author Julio Montoya <gugli100@gmail.com> Beeznest 2012 */ function handle_regions() { …........ } $plugin_obj = new AppPlugin(); $possible_plugins = $plugin_obj->read_plugins_from_path(); $installed_plugins = $plugin_obj->get_installed_plugins(); if (!empty($installed_plugins)) { $not_installed = array_diff($possible_plugins, $installed_plugins); } else { $not_installed = $possible_plugins; } echo '<form name="plugins" method="post" action="'.api_get_self().'?category='.Security::remove_XSS($_GET['category']).'">'; echo '<table class="data_table">'; echo '<tr>'; echo '<th width="400px">'; echo get_lang('Plugin'); echo '</th><th>'; echo get_lang('Regions'); …......
  60. 60. Part B / 1 Settings.lib.php …... /* We display all the possible plugins and the checkboxes */ $plugin_region_list = array(); $my_plugin_list = $plugin_obj->get_plugin_regions(); foreach ($my_plugin_list as $plugin_item) { $plugin_region_list[$plugin_item] = $plugin_item; } ….....
  61. 61. Part B / 1 Settings.lib.php …...... /** * This function allows easy activating and inactivating of plugins …..... function handle_plugins() { $plugin_obj = new AppPlugin(); if (isset($_POST['submit_plugins'])) { store_plugins(); // Add event to the system log. $user_id = api_get_user_id(); $category = $_GET['category']; event_system(LOG_CONFIGURATION_SETTINGS_CHANGE, LOG_CONFIGURATION_SETTINGS_CATEGORY, $category, api_get_utc_datetime(), $user_id); Display :: display_confirmation_message(get_lang('SettingsStored')); } $all_plugins = $plugin_obj->read_plugins_from_path(); $installed_plugins = $plugin_obj->get_installed_plugins(); …...... $plugin_list = array(); $my_plugin_list = $plugin_obj->get_plugin_regions(); foreach($my_plugin_list as $plugin_item) { $plugin_list[$plugin_item] = $plugin_item; }
  62. 62. Part B / 1 Settings.lib.php foreach ($all_plugins as $plugin) { $plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$plugin.'/plugin.php'; if (file_exists($plugin_info_file)) { $plugin_info = array(); require $plugin_info_file; if (in_array($plugin, $installed_plugins)) { echo '<tr class="row_selected">'; } else { echo '<tr>'; } echo '<td>'; //Checkbox if (in_array($plugin, $installed_plugins)) { echo '<input type="checkbox" name="plugin_'.$plugin.'[]" checked="checked">'; …...... echo '<h4>'.$plugin_info['title'].' <small>v '.$plugin_info['version'].'</small></h4>'; echo '<p>'.$plugin_info['comment'].'</p>'; echo '<p>'.get_lang('Author').': '.$plugin_info['author'].'</p>'; echo '<div class="btn-group">'; if (in_array($plugin, $installed_plugins)) { echo Display::url(get_lang('Configure'), 'configure_plugin.php?name='.$plugin, array('class' => 'btn')); echo Display::url(get_lang('Regions'), 'settings.php?category=Regions&name='.$plugin, array('class' => 'btn')); } if (file_exists(api_get_path(SYS_PLUGIN_PATH).$plugin.'/readme.txt')) { echo Display::url("readme.txt", api_get_path(WEB_PLUGIN_PATH).$plugin."/readme.txt", array('class' => 'btn ajax', '_target' => '_blank')); } …..... echo '</table>'; echo '<div class="form-actions bottom_actions">'; echo '<button class="save" type="submit" name="submit_plugins">'.get_lang('EnablePlugins').'</button>';
  63. 63. Part B / 1 Settings.lib.php ….. function store_regions() { $plugin_obj = new AppPlugin(); // Get a list of all current 'Plugins' settings $installed_plugins = $plugin_obj->get_installed_plugins(); $shortlist_installed = array(); if (!empty($installed_plugins)) { foreach ($installed_plugins as $plugin) { if (isset($plugin['subkey'])) { $shortlist_installed[] = $plugin['subkey']; } } } $shortlist_installed = array_flip(array_flip($shortlist_installed)); $plugin_list = $plugin_obj->read_plugins_from_path(); foreach ($plugin_list as $plugin) { if (isset($_POST['plugin_'.$plugin])) { $areas_to_installed = $_POST['plugin_'.$plugin]; if (!empty($areas_to_installed)) { $plugin_obj->remove_all_regions($plugin); foreach ($areas_to_installed as $region) { if (!empty($region) && $region != '-1' ) { $plugin_obj->add_to_region($plugin, $region); } } ….......
  64. 64. Part B / 1 Settings.lib.php ….. /** * This function allows easy activating and inactivating of plugins * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University */ function store_plugins() { $plugin_obj = new AppPlugin(); // Get a list of all current 'Plugins' settings $plugin_list = $plugin_obj->read_plugins_from_path(); $installed_plugins = array(); foreach ($plugin_list as $plugin) { if (isset($_POST['plugin_'.$plugin])) { $plugin_obj->install($plugin); $installed_plugins[] = $plugin; } } if (!empty($installed_plugins)) { $remove_plugins = array_diff($plugin_list, $installed_plugins); } else { $remove_plugins = $plugin_list; } foreach ($remove_plugins as $plugin) { $plugin_obj->uninstall($plugin); } } /** ….......
  65. 65. Part B / 1 Settings.lib.php ….. function generate_settings_form($settings, $settings_by_access_list) { global $_configuration, $settings_to_avoid, $convert_byte_to_mega_list; $table_settings_current = Database :: get_main_table(TABLE_MAIN_SETTINGS_CURRENT); $form = new FormValidator('settings', 'post', 'settings.php?category='.Security::remove_XSS($_GET['category'])); $form->addElement('hidden', 'search_field', (!empty($_GET['search_field'])? Security::remove_XSS($_GET['search_field']):null)); $url_id = api_get_current_access_url_id(); if (!empty($_configuration['multiple_access_urls']) && api_is_global_platform_admin() && $url_id == 1) { $group = array(); $group[] = $form->createElement('button', 'mark_all', get_lang('MarkAll')); $group[] = $form->createElement('button', 'unmark_all', get_lang('UnmarkAll')); $form->addGroup($group, 'buttons_in_action_right'); …...
  66. 66. Part B / 1 Roles Settings.php ➔
  67. 67. Part B / 1 Settings.php <?php /* For licensing terms, see /license.txt */ /** * With this tool you can easily adjust non critical configuration settings. * Non critical means that changing them will not result in a broken campus. * * @author Patrick Cool * @author Julio Montoya - Multiple URL site * @package chamilo.admin */ …........ ….... // Database table definitions. $table_settings_current = Database :: get_main_table(TABLE_MAIN_SETTINGS_CURRENT); // Setting breadcrumbs. $interbreadcrumb[] = array('url' => 'index.php', 'name' => get_lang('PlatformAdmin')); // Setting the name of the tool. $tool_name = get_lang('PlatformConfigSettings'); if (empty($_GET['category'])) { $_GET['category'] = 'Platform'; } …....
  68. 68. Part B / 1 Settings.php ….. $url_id = api_get_current_access_url_id(); $settings = null; function get_settings($category = null) { $url_id = api_get_current_access_url_id(); $settings_by_access_list = array(); if ($url_id == 1) { $settings = api_get_settings($category, 'group', $url_id); } else { $url_info = api_get_access_url($url_id); …...... // One more validation if is changeable. if ($row['access_url_changeable'] == 1) $settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ] = $row; else $settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ] = array(); } } } if (isset($category) && $category== 'search_setting') { if (!empty($_REQUEST['search_field'])) { $settings = search_setting($_REQUEST['search_field']); } } return array('settings' => $settings, 'settings_by_access_list' => $settings_by_access_list); } // Build the form. ….....
  69. 69. Part B / 1 Settings.php …. // Including the header (banner). Display :: display_header($tool_name); // The action images. $action_images['platform'] = 'platform.png'; $action_images['course'] = 'course.png'; $action_images['session'] = 'session.png'; $action_images['tools'] = 'tools.png'; $action_images['user'] = 'user.png'; $action_images['gradebook'] = 'gradebook.png'; $action_images['ldap'] = 'ldap.png'; $action_images['cas'] = 'user_access.png'; $action_images['security'] = 'security.png'; $action_images['languages'] = 'languages.png'; $action_images['tuning'] = 'tuning.png'; $action_images['templates'] = 'template.png'; $action_images['search'] = 'search.png'; $action_images['editor'] = 'html_editor.png'; $action_images['timezones'] = 'timezone.png'; $action_images['extra'] = 'wizard.png'; $action_images['tracking'] = 'statistics.png'; $action_images['gradebook'] = 'gradebook.png'; $action_images['search'] = 'search.png'; $action_images['stylesheets'] = 'stylesheets.png'; $action_images['templates'] = 'template.png'; $action_images['plugins'] = 'plugins.png'; $action_images['shibboleth'] = 'shibboleth.png'; $action_images['facebook'] = 'facebook.png'; …...
  70. 70. Part B / 1 Settings.php ... $action_array = array(); $resultcategories = array(); $resultcategories[] = array('category' => 'Platform'); $resultcategories[] = array('category' => 'Course'); $resultcategories[] = array('category' => 'Session'); $resultcategories[] = array('category' => 'Languages'); $resultcategories[] = array('category' => 'User'); $resultcategories[] = array('category' => 'Tools'); $resultcategories[] = array('category' => 'Editor'); $resultcategories[] = array('category' => 'Security'); $resultcategories[] = array('category' => 'Tuning'); $resultcategories[] = array('category' => 'Gradebook'); $resultcategories[] = array('category' => 'Timezones'); $resultcategories[] = array('category' => 'Tracking'); $resultcategories[] = array('category' => 'Search'); $resultcategories[] = array('category' => 'Stylesheets'); $resultcategories[] = array('category' => 'Templates'); $resultcategories[] = array('category' => 'Plugins'); $resultcategories[] = array('category' => 'LDAP'); $resultcategories[] = array('category' => 'CAS'); $resultcategories[] = array('category' => 'Shibboleth'); $resultcategories[] = array('category' => 'Facebook'); ….
  71. 71. Part B / 1 Settings.php … if (!empty($_GET['category'])) { switch ($_GET['category']) { case 'Regions': handle_regions(); break; case 'Plugins': // Displaying the extensions: Plugins. // This will be available to all the sites (access_urls). if (isset($_POST['submit_dashboard_plugins'])) { $affected_rows = DashboardManager::store_dashboard_plugins($_POST); if ($affected_rows) { // add event to system log $user_id = api_get_user_id(); $category = $_GET['category']; event_system(LOG_CONFIGURATION_SETTINGS_CHANGE, LOG_CONFIGURATION_SETTINGS_CATEGORY, $category, api_get_utc_datetime(), $user_id); Display :: display_confirmation_message(get_lang('DashboardPluginsHaveBeenUpdatedSucesslly')); } ….... echo '<div id="tabs">'; echo '<ul>'; echo '<li><a href="#tabs-1">'.get_lang('Plugins').'</a></li>'; echo '<li><a href="#tabs-2">'.get_lang('DashboardPlugins').'</a></li>'; echo '<li><a href="#tabs-3">'.get_lang('ConfigureExtensions').'</a></li>'; echo '</ul>'; echo '<div id="tabs-1">'; handle_plugins(); echo '</div>'; echo '<div id="tabs-2">'; DashboardManager::handle_dashboard_plugins(); echo '</div>'; echo '<div id="tabs-3">'; handle_extensions(); echo '</div>'; …....
  72. 72. Part B / 1 Roles Config_plugin.php ➔
  73. 73. Part B / 1 Config_plugin.php <?php /* For licensing terms, see /license.txt */ /............ // name of the language file that needs to be included $language_file = array ('registration','admin'); $cidReset = true; require_once '../inc/global.inc.php'; // Access restrictions api_protect_admin_script(); $plugin_name = $_GET['name']; $plugin_obj = new AppPlugin(); $plugin_info = $plugin_obj->get_plugin_info($plugin_name, true); if (empty($plugin_info)) { api_not_allowed(); } $installed_plugins = $plugin_obj->get_installed_plugins(); if (!in_array($plugin_name, $installed_plugins)) { api_not_allowed(); } global $_configuration;
  74. 74. Part B / 1 Config_plugin.php $content = null; if (isset($plugin_info['settings_form'])) { $form = $plugin_info['settings_form']; if (isset($form)) { //We override the form attributes …........ } } else { $message = Display::return_message(get_lang('NoConfigurationSettingsForThisPlugin'), 'warning'); } if (isset($form)) { if ($form->validate()) { $values = $form->exportValues(); //api_delete_category_settings_by_subkey($plugin_name); $access_url_id = api_get_current_access_url_id(); api_delete_settings_params(array('category = ? AND access_url = ? AND subkey = ? AND type = ? and variable <> ?' => array('Plugins', $access_url_id, $plugin_name, 'setting', "status"))); foreach ($values as $key => $value) { $key = Database::escape_string($plugin_name.'_'.$key); api_add_setting($value, $key, $plugin_name, 'setting', 'Plugins', $plugin_name, null, null, null, $_configuration['access_url'], 1); } $message = Display::return_message(get_lang('Updated'), 'success'); } } $tpl = new Template($tool_name, true, true, false, true, false); $tpl->assign('actions', $actions); $tpl->assign('message', $message); $tpl->assign('content', $content); $tpl->display_one_col_template();
  75. 75. Part B / 1 Roles Plugin.class.php ➔
  76. 76. Part B / 1 Plugin.class.php <?php /* For licensing terms, see /license.txt */ /** * Base class for plugins * * This class has to be extended by every plugin. It defines basic methods ….... */ class Plugin { protected $version = ''; protected $author = ''; protected $fields = array(); private $settings = null; private $strings = null; //translation strings public $is_course_plugin = false; /** * When creating a new course, these settings are added to the course, in * the course_info/infocours.php * To show the plugin course icons you need to add these icons: * main/img/icons/22/plugin_name.png * main/img/icons/64/plugin_name.png * main/img/icons/64/plugin_name_na.png * @example * $course_settings = array( array('name' => 'big_blue_button_welcome_message', 'type' => 'text'), array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox') ); */ ….....
  77. 77. Part B / 1 Plugin.class.php …. public $course_settings = array(); /** * This indicates whether changing the setting should execute the callback * function. */ public $course_settings_callback = false; /** * Default constructor for the plugin class. By default, it only sets * a few attributes of the object * @param string Version of this plugin * @param string Author of this plugin * @param array Array of global settings to be proposed to configure the plugin * @return void */ protected function __construct($version, $author, $settings = array()) { $this->version = $version; $this->author = $author; $this->fields = $settings; global $language_files; $language_files[] = 'plugin_' . $this->get_name(); } /** …..
  78. 78. Part B / 1 Plugin.class.php … /** * Gets an array of information about this plugin (name, version, ...) * @return array Array of information elements about this plugin */ function get_info() { $result = array(); $result['title'] = $this->get_title(); $result['comment'] = $this->get_comment(); $result['version'] = $this->get_version(); $result['author'] = $this->get_author(); $result['plugin_class'] = get_class($this); $result['is_course_plugin'] = $this->is_course_plugin; if ($form = $this->get_settings_form()) { $result['settings_form'] = $form; foreach ($this->fields as $name => $type) { $value = $this->get($name); $result[$name] = $value; } } return $result; } /** * Returns the "system" name of the plugin in lowercase letters * @param string Name of the plugin */ function get_name() { $result = get_class($this); $result = str_replace('Plugin', '', $result); $result = strtolower($result); return $result; } /** ….
  79. 79. Part B / 1 Plugin.class.php … /** * Returns the title of the plugin * @param string Title of the plugin */ function get_title() { return $this->get_lang('plugin_title'); } /** * Returns the description of the plugin * @param string Description of the plugin */ function get_comment() { return $this->get_lang('plugin_comment'); } /** * Returns the version of the plugin * @param string Version of the plugin */ function get_version() { return $this->version; } /** * Returns the author of the plugin * @param string Author(s) of the plugin */ function get_author() { return $this->author; } ….
  80. 80. Part B / 1 Plugin.class.php … /** * Returns the contents of the CSS defined by the plugin * @param string The CSS string */ function get_css() { $name = $this->get_name(); $path = api_get_path(SYS_PLUGIN_PATH)."$name/resources/$name.css"; if (!is_readable($path)) { return ''; } $css = array(); $css[] = file_get_contents($path); $result = implode($css); return $result; } /** * Returns an HTML form (generated by FormValidator) of the plugin settings * @return string FormValidator-generated form */ function get_settings_form() { $result = new FormValidator($this->get_name()); $defaults = array(); foreach ($this->fields as $name => $type) { $value = $this->get($name); $defaults[$name] = $value; $type = isset($type) ? $type : 'text'; $help = null; if ($this->get_lang_plugin_exists($name.'_help')) { $help = $this->get_lang($name.'_help'); } switch ($type) { ….
  81. 81. Part B / 1 Plugin.class.php … /** * Returns the value of a given plugin global setting * @param string Name of the plugin * @return string Value of the plugin */ function get($name) { $settings = $this->get_settings(); foreach ($settings as $setting) { if ($setting['variable'] == ($this->get_name() . '_' . $name)) { return $setting['selected_value']; } } return false; } /** * Returns an array with the global settings for this plugin * @return array Plugin settings as an array */ public function get_settings() { if (is_null($this->settings)) { $settings = api_get_settings_params(array("subkey = ? AND category = ? AND type = ? " => array($this->get_name(), 'Plugins', 'setting'))); $this->settings = $settings; } return $this->settings; } ….
  82. 82. Part B / 1 Plugin.class.php … /** * Tells whether language variables are defined for this plugin or not * @param string System name of the plugin * @return boolean True if the plugin has languag variables defined, false otherwise */ public function get_lang_plugin_exists($name) { return isset($this->strings[$name]); } /** * Hook for the get_lang() function to check for plugin-defined language terms * @param string Name of the language variable we are looking for * @return string The translated language term of the plugin */ public function get_lang($name) { // Check whether the language strings for the plugin have already been // loaded. If so, no need to load them again. if (is_null($this->strings)) { global $language_interface; $root = api_get_path(SYS_PLUGIN_PATH); $plugin_name = $this->get_name(); //1. Loading english if exists $english_path = $root.$plugin_name."/lang/english.php"; if (is_readable($english_path)) { include $english_path; $this->strings = $strings; } ….
  83. 83. Part B / 1 Plugin.class.php … /** * Caller for the install_course_fields() function * @param int The course's integer ID * @param boolean Whether to add a tool link on the course homepage * @return void */ function course_install($course_id, $add_tool_link = true) { $this->install_course_fields($course_id, $add_tool_link); } /** * Add course settings and, if not asked otherwise, add a tool link on the course homepage * @param int Course integer ID * @param boolean Whether to add a tool link or not (some tools might just offer a configuration section and act on the backend) * @return boolean False on error, null otherwise */ public function install_course_fields($course_id, $add_tool_link = true) { $plugin_name = $this->get_name(); $t_course = Database::get_course_table(TABLE_COURSE_SETTING); ….
  84. 84. Part B / 1 Roles Plugin.lib.php ➔
  85. 85. Part B / 1 Plugin.lib.php <?php /* See license terms in /license.txt */ class AppPlugin { var $plugin_regions = array ( // 'loginpage_main', 'login_top', 'login_bottom', 'menu_top', 'menu_bottom', /* 'campushomepage_main', 'campushomepage_menu', 'mycourses_main', 'mycourses_menu',*/ 'content_top', 'content_bottom', 'header_main', 'header_center', 'header_left', 'header_right', //'footer', 'footer_left', 'footer_center', 'footer_right', 'course_tool_plugin' ); …...
  86. 86. Part B / 1 Plugin.lib.php …... function __construct() { } { function read_plugins_from_path() { /* We scan the plugin directory. Each folder is a potential plugin. */ $pluginpath = api_get_path(SYS_PLUGIN_PATH); $possible_plugins = array(); $handle = @opendir($pluginpath); while (false !== ($file = readdir($handle))) { if ($file != '.' && $file != '..' && is_dir(api_get_path(SYS_PLUGIN_PATH).$file)) $possible_plugins[] = $file; } } } @closedir($handle); sort($possible_plugins); return $possible_plugins; function get_installed_plugins_by_region(){ $used_plugins = array(); /* We retrieve all the active plugins. */ $result = api_get_settings('Plugins'); foreach ($result as $row) { $used_plugins[$row['variable']][] = $row['selected_value']; } return $used_plugins; } ….
  87. 87. Part B / 1 Plugin.lib.php …... function get_installed_plugins() { $installed_plugins = array(); $plugin_array = api_get_settings_params(array("variable = ? AND selected_value = ? AND category = ? " => array('status', 'installed', 'Plugins'))); } if (!empty($plugin_array)) { foreach ($plugin_array as $row) { $installed_plugins[$row['subkey']] = true; } $installed_plugins = array_keys($installed_plugins); } return $installed_plugins; function install($plugin_name, $access_url_id = null) { if (empty($access_url_id)) { $access_url_id = api_get_current_access_url_id(); } else { $access_url_id = intval($access_url_id); } api_add_setting('installed', 'status', $plugin_name, 'setting', 'Plugins', $plugin_name, null, null, null, $access_url_id, 1); //api_add_setting($plugin, $area, $plugin, null, 'Plugins', $plugin, null, null, null, $_configuration['access_url'], 1); $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/install.php'; } …. if (is_file($pluginpath) && is_readable($pluginpath)) { //execute the install procedure require $pluginpath; }
  88. 88. Part B / 1 Plugin.lib.php …... function uninstall($plugin_name, $access_url_id = null) { if (empty($access_url_id)) { $access_url_id = api_get_current_access_url_id(); } else { $access_url_id = intval($access_url_id); } api_delete_settings_params(array('category = ? AND access_url = ? AND subkey = ? ' => array('Plugins', $access_url_id, $plugin_name))); $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/uninstall.php'; if (is_file($pluginpath) && is_readable($pluginpath)) { //execute the uninstall procedure require $pluginpath; } } function get_areas_by_plugin($plugin_name) { $result = api_get_settings('Plugins'); $areas = array(); foreach ($result as $row) { if ($plugin_name == $row['selected_value']) { $areas[] = $row['variable']; } } return $areas; } function is_valid_plugin_location($location) { return in_array($location, $this->plugin_list); } function is_valid_plugin($plugin_name) { if (is_dir(api_get_path(SYS_PLUGIN_PATH).$plugin_name)) { if (is_file(api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/index.php')) { return true; } } return false; } ….
  89. 89. Part B / 1 Plugin.lib.php …... function load_region($region, $main_template, $forced = false) { if ($region == 'course_tool_plugin') { return null; } ob_start(); $this->get_all_plugin_contents_by_region($region, $main_template, $forced); $content = ob_get_contents(); ob_end_clean(); return $content; } /** * Loads the translation files inside a plugin if exists. It loads by default english see the hello world plugin * * @todo add caching * @param string $plugin_name */ function load_plugin_lang_variables($plugin_name) { global $language_interface; $root = api_get_path(SYS_PLUGIN_PATH); //1. Loading english if exists $english_path = $root.$plugin_name."/lang/english.php"; ….
  90. 90. Part B / 1 Plugin.lib.php …... */ function get_all_plugin_contents_by_region($region, $template, $forced = false) { global $_plugins; if (isset($_plugins[$region]) && is_array($_plugins[$region])) { //if (1) { //Load the plugin information foreach ($_plugins[$region] as $plugin_name) { //The plugin_info variable is available inside the plugin index $plugin_info = $this->get_plugin_info($plugin_name, $forced); //We also know where the plugin is $plugin_info['current_region'] = $region; // Loading the plugin/XXX/index.php file $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php"; ….
  91. 91. Part B / 1 Plugin.lib.php …... /** * Loads plugin info * @staticvar array $plugin_data * @param string plugin name * @param bool load from DB or from the static array * @todo filter setting_form * @return array */ function get_plugin_info($plugin_name, $forced = false) { static $plugin_data = array(); if (isset($plugin_data[$plugin_name]) && $forced == false) { return $plugin_data[$plugin_name]; } else { $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/plugin.php"; $plugin_info = array(); if (file_exists($plugin_file)) { require $plugin_file; } //extra options $plugin_settings = api_get_settings_params(array("subkey = ? AND category = ? AND type = ? " => array($plugin_name, 'Plugins','setting'))); $settings_filtered = array(); foreach ($plugin_settings as $item) { $settings_filtered[$item['variable']] = $item['selected_value']; } $plugin_info['settings'] = $settings_filtered; $plugin_data[$plugin_name] = $plugin_info; return $plugin_info; } …. }
  92. 92. Part B / 1 Plugin.lib.php …... /* * Get the template list */ function get_templates_list($plugin_name) { $plugin_info = $this->get_plugin_info($plugin_name); if (isset($plugin_info) && isset($plugin_info['templates'])) { return $plugin_info['templates']; } else { return false; } } …. /* * Add a plugin to a region */ function add_to_region($plugin, $region) { $access_url_id = api_get_current_access_url_id(); api_add_setting($plugin, $region, $plugin, 'region', 'Plugins', $plugin, null, null, null, $access_url_id, 1); } function install_course_plugins($course_id) { $plugin_list = $this->get_installed_plugins(); …... if (!empty($plugin_list)) { foreach ($plugin_list as $plugin_name) { $plugin_path = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/plugin.php'; if (file_exists($plugin_path)) { require_once $plugin_path; if (isset($plugin_info) && isset($plugin_info['plugin_class'])) { $plugin_info['plugin_class']::create()->course_install($course_id); } } } }
  93. 93. Part B / 1 Plugin.lib.php …... function add_course_settings_form($form) ….... function set_course_settings_defaults(& $values) { ….. function save_course_settings($values) { …... /** * Gets a nice array of keys for just the plugin's course settings * @param string The plugin ID * @return array Nice array of keys for course settings */ public function get_plugin_course_settings($plugin_name) { …...
  94. 94. Part B / 1 General Plugin Pattern-Model Development Pattern ➔
  95. 95. Part B / 1 Foundamental Files Plugin.php Index.php Readme.txt
  96. 96. Part B / 1 Optional Files Uninstall.php Template.tpl *.css and other resources
  97. 97. Part B / 1 Plugin Develop Pattern Create the foundamental and optional files Put this files in a directory named “MyPluginName” Copy this directory in chamilo plugin directory Activate plugin in Plugin List Panel as Admin
  98. 98. Part B / 2 Simple Plugin Creation Example ➔ Teacher List Plugin
  99. 99. Part B / 2 Teacher Plugin
  100. 100. Part B / 2 Teacher Plugin
  101. 101. Part B / 2 Teacher Plugin
  102. 102. Part B / 2 Teacher Plugin
  103. 103. Part B / 2 Teacher Plugin
  104. 104. Part B / 2 Teacher Plugin Admin Panel / Plugin SubPanel
  105. 105. Part B / 2 Teacher Plugin Plugin List
  106. 106. Part B / 2 Teacher Plugin
  107. 107. Part B / 2 Teacher Plugin
  108. 108. Part B / 2 Teacher Plugin
  109. 109. Part B / 2 Teacher Plugin User list
  110. 110. Part B / 2 Teacher Plugin
  111. 111. Conclusion Pattern Model ➔ Improvements ➔
  112. 112. Conclusion / Pattern Model Create a plugin is very simple There are necessary steps and optional steps Plugin creation is now a question of planning what to do and knowing chamilo functions and DB
  113. 113. Conclusion / Improvements Create a Plugin Management System Improve php files Complete Uninstall.php role Give more simple Api Package plugin-oriented
  114. 114. Contact Giuliano Mandotti Member of Chamilo Association info@giulianomandotti.com
  115. 115. Thank you! ¡Muchas Gracias!

×