123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- <?php
- /* For licensing terms, see /license.txt */
- /**
- * Class Plugin
- * Base class for plugins
- *
- * This class has to be extended by every plugin. It defines basic methods
- * to install/uninstall and get information about a plugin
- *
- * @author Julio Montoya <gugli100@gmail.com>
- * @author Yannick Warnier <ywarnier@beeznest.org>
- * @author Laurent Opprecht <laurent@opprecht.info>
- * @copyright 2012 University of Geneva
- * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
- *
- */
- class Plugin
- {
- protected $version = '';
- protected $author = '';
- protected $fields = [];
- private $settings = [];
- // Translation strings.
- private $strings = null;
- public $isCoursePlugin = false;
- public $isAdminPlugin = false;
- public $isMailPlugin = false;
- // Adds icon in the course home
- public $addCourseTool = true;
- /**
- * 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')
- );
- */
- 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 $settings settings to be proposed to configure the plugin
- */
- 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();
- }
- /**
- * Gets an array of information about this plugin (name, version, ...)
- * @return array Array of information elements about this plugin
- */
- public function get_info()
- {
- $result = array();
- $result['obj'] = $this;
- $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->isCoursePlugin;
- $result['is_admin_plugin'] = $this->isAdminPlugin;
- $result['is_mail_plugin'] = $this->isMailPlugin;
- if ($form = $this->get_settings_form()) {
- $result['settings_form'] = $form;
- foreach ($this->fields as $name => $type) {
- $value = $this->get($name);
- if (is_array($type)) {
- $value = $type['options'];
- }
- $result[$name] = $value;
- }
- }
- return $result;
- }
- /**
- * Returns the "system" name of the plugin in lowercase letters
- * @return string
- */
- public function get_name()
- {
- $result = get_class($this);
- $result = str_replace('Plugin', '', $result);
- $result = strtolower($result);
- return $result;
- }
- /**
- * @return string
- */
- public function getCamelCaseName()
- {
- $result = get_class($this);
- return str_replace('Plugin', '', $result);
- }
- /**
- * Returns the title of the plugin
- * @return string
- */
- public function get_title()
- {
- return $this->get_lang('plugin_title');
- }
- /**
- * Returns the description of the plugin
- * @return string
- */
- public function get_comment()
- {
- return $this->get_lang('plugin_comment');
- }
- /**
- * Returns the version of the plugin
- * @return string
- */
- public function get_version()
- {
- return $this->version;
- }
- /**
- * Returns the author of the plugin
- * @return string
- */
- public function get_author()
- {
- return $this->author;
- }
- /**
- * Returns the contents of the CSS defined by the plugin
- * @return string
- */
- public 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 FormValidator FormValidator-generated form
- */
- public function get_settings_form()
- {
- $result = new FormValidator($this->get_name());
- $defaults = array();
- $checkboxGroup = array();
- $checkboxCollection = array();
- if ($checkboxNames = array_keys($this->fields, 'checkbox')) {
- $pluginInfoCollection = api_get_settings('Plugins');
- foreach ($pluginInfoCollection as $pluginInfo) {
- if (array_search($pluginInfo['title'], $checkboxNames) !== false) {
- $checkboxCollection[$pluginInfo['title']] = $pluginInfo;
- }
- }
- }
- foreach ($this->fields as $name => $type) {
- $options = null;
- if (is_array($type) && isset($type['type']) && $type['type'] === 'select') {
- $options = $type['options'];
- $type = $type['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');
- if ($name === "show_main_menu_tab") {
- $pluginName = strtolower(str_replace('Plugin', '', get_class($this)));
- $pluginUrl = api_get_path(WEB_PATH)."plugin/$pluginName/index.php";
- $pluginUrl = "<a href=$pluginUrl>$pluginUrl</a>";
- $help = sprintf($help, $pluginUrl);
- }
- }
- switch ($type) {
- case 'html':
- $result->addElement('html', $this->get_lang($name));
- break;
- case 'wysiwyg':
- $result->addHtmlEditor($name, $this->get_lang($name), false);
- break;
- case 'text':
- $result->addElement($type, $name, array($this->get_lang($name), $help));
- break;
- case 'boolean':
- $group = array();
- $group[] = $result->createElement('radio', $name, '', get_lang('Yes'), 'true');
- $group[] = $result->createElement('radio', $name, '', get_lang('No'), 'false');
- $result->addGroup($group, null, array($this->get_lang($name), $help));
- break;
- case 'checkbox':
- $selectedValue = null;
- if (isset($checkboxCollection[$name])) {
- if ($checkboxCollection[$name]['selected_value'] === 'true') {
- $selectedValue = 'checked';
- }
- }
- $element = $result->createElement(
- $type,
- $name,
- '',
- $this->get_lang($name),
- $selectedValue
- );
- $element->_attributes['value'] = 'true';
- $checkboxGroup[] = $element;
- break;
- case 'select':
- $result->addElement(
- $type,
- $name,
- array($this->get_lang($name), $help),
- $options
- );
- break;
- }
- }
- if (!empty($checkboxGroup)) {
- $result->addGroup($checkboxGroup, null, array($this->get_lang('sms_types'), $help));
- }
- $result->setDefaults($defaults);
- $result->addButtonSave($this->get_lang('Save'), 'submit_button');
- return $result;
- }
- /**
- * Returns the value of a given plugin global setting
- * @param string $name of the plugin
- *
- * @return string Value of the plugin
- */
- public 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 (empty($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;
- }
- /**
- * Tells whether language variables are defined for this plugin or not
- * @param string $name System name of the plugin
- *
- * @return bool True if the plugin has language 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();
- $interfaceLanguageId = api_get_language_id($language_interface);
- $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
- $languageParentId = !empty($interfaceLanguageInfo['parent_id']) ? (int) $interfaceLanguageInfo['parent_id'] : 0;
- //1. Loading english if exists
- $english_path = $root.$plugin_name."/lang/english.php";
- if (is_readable($english_path)) {
- $strings = array();
- include $english_path;
- $this->strings = $strings;
- }
- $path = $root.$plugin_name."/lang/$language_interface.php";
- // 2. Loading the system language
- if (is_readable($path)) {
- include $path;
- if (!empty($strings)) {
- foreach ($strings as $key => $string) {
- $this->strings[$key] = $string;
- }
- }
- } elseif ($languageParentId > 0) {
- $languageParentInfo = api_get_language_info($languageParentId);
- $languageParentFolder = $languageParentInfo['dokeos_folder'];
- $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
- if (is_readable($parentPath)) {
- include $parentPath;
- if (!empty($strings)) {
- foreach ($strings as $key => $string) {
- $this->strings[$key] = $string;
- }
- }
- }
- }
- }
- if (isset($this->strings[$name])) {
- return $this->strings[$name];
- }
- return get_lang($name);
- }
- /**
- * Caller for the install_course_fields() function
- * @param int $courseId
- *
- * @param boolean $addToolLink Whether to add a tool link on the course homepage
- *
- * @return void
- */
- public function course_install($courseId, $addToolLink = true)
- {
- $this->install_course_fields($courseId, $addToolLink);
- }
- /**
- * Add course settings and, if not asked otherwise, add a tool link on the course homepage
- * @param int $courseId Course integer ID
- * @param boolean $add_tool_link Whether to add a tool link or not
- * (some tools might just offer a configuration section and act on the backend)
- *
- * @return boolean|null False on error, null otherwise
- */
- public function install_course_fields($courseId, $add_tool_link = true)
- {
- $plugin_name = $this->get_name();
- $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
- $courseId = (int) $courseId;
- if (empty($courseId)) {
- return false;
- }
- // Adding course settings.
- if (!empty($this->course_settings)) {
- foreach ($this->course_settings as $setting) {
- $variable = $setting['name'];
- $value = '';
- if (isset($setting['init_value'])) {
- $value = $setting['init_value'];
- }
- $type = 'textfield';
- if (isset($setting['type'])) {
- $type = $setting['type'];
- }
- if (isset($setting['group'])) {
- $group = $setting['group'];
- $sql = "SELECT value
- FROM $t_course
- WHERE
- c_id = $courseId AND
- variable = '".Database::escape_string($group)."' AND
- subkey = '".Database::escape_string($variable)."'
- ";
- $result = Database::query($sql);
- if (!Database::num_rows($result)) {
- $params = [
- 'c_id' => $courseId,
- 'variable' => $group,
- 'subkey' => $variable,
- 'value' => $value,
- 'category' => 'plugins',
- 'type' => $type,
- 'title' => ''
- ];
- Database::insert($t_course, $params);
- }
- } else {
- $sql = "SELECT value FROM $t_course
- WHERE c_id = $courseId AND variable = '$variable' ";
- $result = Database::query($sql);
- if (!Database::num_rows($result)) {
- $params = [
- 'c_id' => $courseId,
- 'variable' => $variable,
- 'subkey' => $plugin_name,
- 'value' => $value,
- 'category' => 'plugins',
- 'type' => $type,
- 'title' => ''
- ];
- Database::insert($t_course, $params);
- }
- }
- }
- }
- // Stop here if we don't want a tool link on the course homepage
- if (!$add_tool_link) {
- return true;
- }
- if ($this->addCourseTool == false) {
- return true;
- }
- //Add an icon in the table tool list
- $table = Database::get_course_table(TABLE_TOOL_LIST);
- $sql = "SELECT name FROM $table
- WHERE c_id = $courseId AND name = '$plugin_name' ";
- $result = Database::query($sql);
- if (!Database::num_rows($result)) {
- $tool_link = "$plugin_name/start.php";
- $cToolId = AddCourse::generateToolId($courseId);
- Database::insert(
- $table,
- [
- 'id' => $cToolId,
- 'c_id' => $courseId,
- 'name' => $plugin_name,
- 'link' => $tool_link,
- 'image' => "$plugin_name.png",
- 'visibility' => 1,
- 'admin' => 0,
- 'address' => 'squaregrey.gif',
- 'added_tool' => 0,
- 'target' => '_self',
- 'category' => 'plugin',
- 'session_id' => 0
- ]
- );
- }
- }
- /**
- * Delete the fields added to the course settings page and the link to the
- * tool on the course's homepage
- * @param int $courseId
- *
- * @return false|null
- */
- public function uninstall_course_fields($courseId)
- {
- $courseId = intval($courseId);
- if (empty($courseId)) {
- return false;
- }
- $plugin_name = $this->get_name();
- $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
- $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
- if (!empty($this->course_settings)) {
- foreach ($this->course_settings as $setting) {
- $variable = Database::escape_string($setting['name']);
- if (!empty($setting['group'])) {
- $variable = Database::escape_string($setting['group']);
- }
- if (empty($variable)) {
- continue;
- }
- $sql = "DELETE FROM $t_course
- WHERE c_id = $courseId AND variable = '$variable'";
- Database::query($sql);
- }
- }
- $plugin_name = Database::escape_string($plugin_name);
- $sql = "DELETE FROM $t_tool
- WHERE c_id = $courseId AND name = '$plugin_name'";
- Database::query($sql);
- }
- /**
- * Install the course fields and tool link of this plugin in all courses
- * @param boolean $add_tool_link Whether we want to add a plugin link on the course homepage
- *
- * @return void
- */
- public function install_course_fields_in_all_courses($add_tool_link = true)
- {
- // Update existing courses to add plugin settings
- $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
- $sql = "SELECT id FROM $t_courses ORDER BY id";
- $res = Database::query($sql);
- while ($row = Database::fetch_assoc($res)) {
- $this->install_course_fields($row['id'], $add_tool_link);
- }
- }
- /**
- * Uninstall the plugin settings fields from all courses
- * @return void
- */
- public function uninstall_course_fields_in_all_courses()
- {
- // Update existing courses to add conference settings
- $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
- $sql = "SELECT id FROM $t_courses
- ORDER BY id";
- $res = Database::query($sql);
- while ($row = Database::fetch_assoc($res)) {
- $this->uninstall_course_fields($row['id']);
- }
- }
- /**
- * @return array
- */
- public function getCourseSettings()
- {
- $settings = array();
- if (is_array($this->course_settings)) {
- foreach ($this->course_settings as $item) {
- if (isset($item['group'])) {
- if (!in_array($item['group'], $settings)) {
- $settings[] = $item['group'];
- }
- } else {
- $settings[] = $item['name'];
- }
- }
- }
- return $settings;
- }
- /**
- * Method to be extended when changing the setting in the course
- * configuration should trigger the use of a callback method
- * @param array $values sent back from the course configuration script
- *
- * @return void
- */
- public function course_settings_updated($values = array())
- {
- }
- /**
- * Add a tab to platform
- * @param string $tabName
- * @param string $url
- *
- * @return false|string
- */
- public function addTab($tabName, $url)
- {
- $sql = "SELECT * FROM settings_current
- WHERE
- variable = 'show_tabs' AND
- subkey LIKE 'custom_tab_%'";
- $result = Database::query($sql);
- $customTabsNum = Database::num_rows($result);
- $tabNum = $customTabsNum + 1;
- // Avoid Tab Name Spaces
- $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
- $subkeytext = "Tabs".$tabNameNoSpaces;
- // Check if it is already added
- $checkCondition = array(
- 'where' =>
- array(
- "variable = 'show_tabs' AND subkeytext = ?" => array(
- $subkeytext
- )
- )
- );
- $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
- if (!empty($checkDuplicate)) {
- return false;
- }
- // End Check
- $subkey = 'custom_tab_'.$tabNum;
- $attributes = array(
- 'variable' => 'show_tabs',
- 'subkey' => $subkey,
- 'type' => 'checkbox',
- 'category' => 'Platform',
- 'selected_value' => 'true',
- 'title' => $tabName,
- 'comment' => $url,
- 'subkeytext' => $subkeytext,
- 'access_url' => 1,
- 'access_url_changeable' => 0,
- 'access_url_locked' => 0
- );
- $resp = Database::insert('settings_current', $attributes);
- // Save the id
- $settings = $this->get_settings();
- $setData = array(
- 'comment' => $subkey
- );
- $whereCondition = array(
- 'id = ?' => key($settings)
- );
- Database::update('settings_current', $setData, $whereCondition);
- return $resp;
- }
- /**
- * Delete a tab to chamilo's platform
- * @param string $key
- * @return boolean $resp Transaction response
- */
- public function deleteTab($key)
- {
- $t = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
- $sql = "SELECT *
- FROM $t
- WHERE variable = 'show_tabs'
- AND subkey <> '$key'
- AND subkey like 'custom_tab_%'
- ";
- $resp = $result = Database::query($sql);
- $customTabsNum = Database::num_rows($result);
- if (!empty($key)) {
- $whereCondition = array(
- 'variable = ? AND subkey = ?' => array('show_tabs', $key)
- );
- $resp = Database::delete('settings_current', $whereCondition);
- //if there is more than one tab
- //re enumerate them
- if (!empty($customTabsNum) && $customTabsNum > 0) {
- $tabs = Database::store_result($result, 'ASSOC');
- $i = 1;
- foreach ($tabs as $row) {
- $attributes = array(
- 'subkey' => 'custom_tab_'.$i
- );
- $this->updateTab($row['subkey'], $attributes);
- $i++;
- }
- }
- }
- return $resp;
- }
- /**
- * Update the tabs attributes
- * @param string $key
- * @param array $attributes
- *
- * @return boolean
- */
- public function updateTab($key, $attributes)
- {
- $whereCondition = array(
- 'variable = ? AND subkey = ?' => array('show_tabs', $key)
- );
- $resp = Database::update('settings_current', $attributes, $whereCondition);
- return $resp;
- }
- /**
- * This method shows or hides plugin's tab
- * @param boolean $showTab Shows or hides the main menu plugin tab
- * @param string $filePath Plugin starter file path
- */
- public function manageTab($showTab, $filePath = 'index.php')
- {
- $langString = str_replace('Plugin', '', get_class($this));
- $pluginName = strtolower($langString);
- $pluginUrl = 'plugin/'.$pluginName.'/'.$filePath;
- if ($showTab === 'true') {
- $tabAdded = $this->addTab($langString, $pluginUrl);
- if ($tabAdded) {
- // The page must be refreshed to show the recently created tab
- echo "<script>location.href = '".Security::remove_XSS($_SERVER['REQUEST_URI'])."';</script>";
- }
- } else {
- $settingsCurrentTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
- $conditions = array(
- 'where' => array(
- "variable = 'show_tabs' AND title = ? AND comment = ? " => array(
- $langString,
- $pluginUrl
- )
- )
- );
- $result = Database::select('subkey', $settingsCurrentTable, $conditions);
- if (!empty($result)) {
- $this->deleteTab($result[0]['subkey']);
- }
- }
- }
- /**
- * @param string $variable
- * @return bool
- */
- public function validateCourseSetting($variable)
- {
- return true;
- }
- /**
- * @param string $region
- * @return string
- */
- public function renderRegion($region)
- {
- return '';
- }
- /**
- * Returns true if the plugin is installed, false otherwise
- * @return bool True if plugin is installed/enabled, false otherwise
- */
- public function isEnabled()
- {
- $settings = api_get_settings_params_simple(
- array(
- "subkey = ? AND category = ? AND type = ? AND variable = 'status' " => array($this->get_name(), 'Plugins', 'setting')
- )
- );
- if (is_array($settings) && isset($settings['selected_value']) && $settings['selected_value'] == 'installed') {
- return true;
- }
- return false;
- }
- }
|