plugin.class.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use Chamilo\CourseBundle\Entity\CTool;
  4. /**
  5. * Class Plugin
  6. * Base class for plugins
  7. *
  8. * This class has to be extended by every plugin. It defines basic methods
  9. * to install/uninstall and get information about a plugin
  10. *
  11. * @author Julio Montoya <gugli100@gmail.com>
  12. * @author Yannick Warnier <ywarnier@beeznest.org>
  13. * @author Laurent Opprecht <laurent@opprecht.info>
  14. * @copyright 2012 University of Geneva
  15. * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
  16. *
  17. */
  18. class Plugin
  19. {
  20. const TAB_FILTER_NO_STUDENT = '::no-student';
  21. const TAB_FILTER_ONLY_STUDENT = '::only-student';
  22. protected $version = '';
  23. protected $author = '';
  24. protected $fields = [];
  25. private $settings = [];
  26. // Translation strings.
  27. private $strings = null;
  28. public $isCoursePlugin = false;
  29. public $isAdminPlugin = false;
  30. public $isMailPlugin = false;
  31. // Adds icon in the course home
  32. public $addCourseTool = true;
  33. /**
  34. * When creating a new course, these settings are added to the course, in
  35. * the course_info/infocours.php
  36. * To show the plugin course icons you need to add these icons:
  37. * main/img/icons/22/plugin_name.png
  38. * main/img/icons/64/plugin_name.png
  39. * main/img/icons/64/plugin_name_na.png
  40. * @example
  41. * $course_settings = array(
  42. array('name' => 'big_blue_button_welcome_message', 'type' => 'text'),
  43. array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
  44. );
  45. */
  46. public $course_settings = [];
  47. /**
  48. * This indicates whether changing the setting should execute the callback
  49. * function.
  50. */
  51. public $course_settings_callback = false;
  52. /**
  53. * Default constructor for the plugin class. By default, it only sets
  54. * a few attributes of the object
  55. * @param string $version of this plugin
  56. * @param string $author of this plugin
  57. * @param array $settings settings to be proposed to configure the plugin
  58. */
  59. protected function __construct($version, $author, $settings = [])
  60. {
  61. $this->version = $version;
  62. $this->author = $author;
  63. $this->fields = $settings;
  64. global $language_files;
  65. $language_files[] = 'plugin_'.$this->get_name();
  66. }
  67. /**
  68. * Gets an array of information about this plugin (name, version, ...)
  69. * @return array Array of information elements about this plugin
  70. */
  71. public function get_info()
  72. {
  73. $result = [];
  74. $result['obj'] = $this;
  75. $result['title'] = $this->get_title();
  76. $result['comment'] = $this->get_comment();
  77. $result['version'] = $this->get_version();
  78. $result['author'] = $this->get_author();
  79. $result['plugin_class'] = get_class($this);
  80. $result['is_course_plugin'] = $this->isCoursePlugin;
  81. $result['is_admin_plugin'] = $this->isAdminPlugin;
  82. $result['is_mail_plugin'] = $this->isMailPlugin;
  83. if ($form = $this->getSettingsForm()) {
  84. $result['settings_form'] = $form;
  85. foreach ($this->fields as $name => $type) {
  86. $value = $this->get($name);
  87. if (is_array($type)) {
  88. $value = $type['options'];
  89. }
  90. $result[$name] = $value;
  91. }
  92. }
  93. return $result;
  94. }
  95. /**
  96. * Returns the "system" name of the plugin in lowercase letters
  97. * @return string
  98. */
  99. public function get_name()
  100. {
  101. $result = get_class($this);
  102. $result = str_replace('Plugin', '', $result);
  103. $result = strtolower($result);
  104. return $result;
  105. }
  106. /**
  107. * @return string
  108. */
  109. public function getCamelCaseName()
  110. {
  111. $result = get_class($this);
  112. return str_replace('Plugin', '', $result);
  113. }
  114. /**
  115. * Returns the title of the plugin
  116. * @return string
  117. */
  118. public function get_title()
  119. {
  120. return $this->get_lang('plugin_title');
  121. }
  122. /**
  123. * Returns the description of the plugin
  124. * @return string
  125. */
  126. public function get_comment()
  127. {
  128. return $this->get_lang('plugin_comment');
  129. }
  130. /**
  131. * Returns the version of the plugin
  132. * @return string
  133. */
  134. public function get_version()
  135. {
  136. return $this->version;
  137. }
  138. /**
  139. * Returns the author of the plugin
  140. * @return string
  141. */
  142. public function get_author()
  143. {
  144. return $this->author;
  145. }
  146. /**
  147. * Returns the contents of the CSS defined by the plugin
  148. * @return string
  149. */
  150. public function get_css()
  151. {
  152. $name = $this->get_name();
  153. $path = api_get_path(SYS_PLUGIN_PATH)."$name/resources/$name.css";
  154. if (!is_readable($path)) {
  155. return '';
  156. }
  157. $css = [];
  158. $css[] = file_get_contents($path);
  159. $result = implode($css);
  160. return $result;
  161. }
  162. /**
  163. * Returns an HTML form (generated by FormValidator) of the plugin settings
  164. * @return FormValidator FormValidator-generated form
  165. */
  166. public function getSettingsForm()
  167. {
  168. $result = new FormValidator($this->get_name());
  169. $defaults = [];
  170. $checkboxGroup = [];
  171. $checkboxCollection = [];
  172. if ($checkboxNames = array_keys($this->fields, 'checkbox')) {
  173. $pluginInfoCollection = api_get_settings('Plugins');
  174. foreach ($pluginInfoCollection as $pluginInfo) {
  175. if (array_search($pluginInfo['title'], $checkboxNames) !== false) {
  176. $checkboxCollection[$pluginInfo['title']] = $pluginInfo;
  177. }
  178. }
  179. }
  180. foreach ($this->fields as $name => $type) {
  181. $options = null;
  182. if (is_array($type) && isset($type['type']) && $type['type'] === 'select') {
  183. $attributes = isset($type['attributes']) ? $type['attributes'] : [];
  184. $options = $type['options'];
  185. $type = $type['type'];
  186. }
  187. $value = $this->get($name);
  188. $defaults[$name] = $value;
  189. $type = isset($type) ? $type : 'text';
  190. $help = null;
  191. if ($this->get_lang_plugin_exists($name.'_help')) {
  192. $help = $this->get_lang($name.'_help');
  193. if ($name === "show_main_menu_tab") {
  194. $pluginName = strtolower(str_replace('Plugin', '', get_class($this)));
  195. $pluginUrl = api_get_path(WEB_PATH)."plugin/$pluginName/index.php";
  196. $pluginUrl = "<a href=$pluginUrl>$pluginUrl</a>";
  197. $help = sprintf($help, $pluginUrl);
  198. }
  199. }
  200. switch ($type) {
  201. case 'html':
  202. $result->addHtml($this->get_lang($name));
  203. break;
  204. case 'wysiwyg':
  205. $result->addHtmlEditor($name, $this->get_lang($name), false);
  206. break;
  207. case 'text':
  208. $result->addElement($type, $name, [$this->get_lang($name), $help]);
  209. break;
  210. case 'boolean':
  211. $group = [];
  212. $group[] = $result->createElement(
  213. 'radio',
  214. $name,
  215. '',
  216. get_lang('Yes'),
  217. 'true'
  218. );
  219. $group[] = $result->createElement(
  220. 'radio',
  221. $name,
  222. '',
  223. get_lang('No'),
  224. 'false'
  225. );
  226. $result->addGroup($group, null, [$this->get_lang($name), $help]);
  227. break;
  228. case 'checkbox':
  229. $selectedValue = null;
  230. if (isset($checkboxCollection[$name])) {
  231. if ($checkboxCollection[$name]['selected_value'] === 'true') {
  232. $selectedValue = 'checked';
  233. }
  234. }
  235. $element = $result->createElement(
  236. $type,
  237. $name,
  238. '',
  239. $this->get_lang($name),
  240. $selectedValue
  241. );
  242. $element->_attributes['value'] = 'true';
  243. $checkboxGroup[] = $element;
  244. break;
  245. case 'select':
  246. $result->addElement(
  247. $type,
  248. $name,
  249. [$this->get_lang($name), $help],
  250. $options,
  251. $attributes
  252. );
  253. break;
  254. }
  255. }
  256. if (!empty($checkboxGroup)) {
  257. $result->addGroup(
  258. $checkboxGroup,
  259. null,
  260. [$this->get_lang('sms_types'), $help]
  261. );
  262. }
  263. $result->setDefaults($defaults);
  264. $result->addButtonSave($this->get_lang('Save'), 'submit_button');
  265. return $result;
  266. }
  267. /**
  268. * Returns the value of a given plugin global setting
  269. * @param string $name of the plugin
  270. *
  271. * @return string Value of the plugin
  272. */
  273. public function get($name)
  274. {
  275. $settings = $this->get_settings();
  276. foreach ($settings as $setting) {
  277. if ($setting['variable'] == $this->get_name().'_'.$name) {
  278. if (!empty($setting['selected_value']) &&
  279. @unserialize($setting['selected_value']) !== false
  280. ) {
  281. $setting['selected_value'] = unserialize($setting['selected_value']);
  282. }
  283. return $setting['selected_value'];
  284. }
  285. }
  286. return false;
  287. }
  288. /**
  289. * Returns an array with the global settings for this plugin
  290. * @param bool $forceFromDB Optional. Force get settings from the database
  291. * @return array Plugin settings as an array
  292. */
  293. public function get_settings($forceFromDB = false)
  294. {
  295. if (empty($this->settings) || $forceFromDB) {
  296. $settings = api_get_settings_params(
  297. [
  298. "subkey = ? AND category = ? AND type = ? AND access_url = ?" => [
  299. $this->get_name(),
  300. 'Plugins',
  301. 'setting',
  302. api_get_current_access_url_id()
  303. ]
  304. ]
  305. );
  306. $this->settings = $settings;
  307. }
  308. return $this->settings;
  309. }
  310. /**
  311. * Tells whether language variables are defined for this plugin or not
  312. * @param string $name System name of the plugin
  313. *
  314. * @return bool True if the plugin has language variables defined, false otherwise
  315. */
  316. public function get_lang_plugin_exists($name)
  317. {
  318. return isset($this->strings[$name]);
  319. }
  320. /**
  321. * Hook for the get_lang() function to check for plugin-defined language terms
  322. * @param string $name of the language variable we are looking for
  323. *
  324. * @return string The translated language term of the plugin
  325. */
  326. public function get_lang($name)
  327. {
  328. // Check whether the language strings for the plugin have already been
  329. // loaded. If so, no need to load them again.
  330. if (is_null($this->strings)) {
  331. $language_interface = api_get_interface_language();
  332. $root = api_get_path(SYS_PLUGIN_PATH);
  333. $plugin_name = $this->get_name();
  334. $interfaceLanguageId = api_get_language_id($language_interface);
  335. if (empty($interfaceLanguageId)) {
  336. $language_interface = api_get_setting('platformLanguage');
  337. $interfaceLanguageId = api_get_language_id($language_interface);
  338. }
  339. $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
  340. $languageParentId = !empty($interfaceLanguageInfo['parent_id']) ? (int) $interfaceLanguageInfo['parent_id'] : 0;
  341. // 1. Loading english if exists
  342. $english_path = $root.$plugin_name."/lang/english.php";
  343. if (is_readable($english_path)) {
  344. $strings = [];
  345. include $english_path;
  346. $this->strings = $strings;
  347. }
  348. $path = $root.$plugin_name."/lang/$language_interface.php";
  349. // 2. Loading the system language
  350. if (is_readable($path)) {
  351. include $path;
  352. if (!empty($strings)) {
  353. foreach ($strings as $key => $string) {
  354. $this->strings[$key] = $string;
  355. }
  356. }
  357. } elseif ($languageParentId > 0) {
  358. $languageParentInfo = api_get_language_info($languageParentId);
  359. $languageParentFolder = $languageParentInfo['dokeos_folder'];
  360. $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
  361. if (is_readable($parentPath)) {
  362. include $parentPath;
  363. if (!empty($strings)) {
  364. foreach ($strings as $key => $string) {
  365. $this->strings[$key] = $string;
  366. }
  367. }
  368. }
  369. }
  370. }
  371. if (isset($this->strings[$name])) {
  372. return $this->strings[$name];
  373. }
  374. return get_lang($name);
  375. }
  376. /**
  377. * Caller for the install_course_fields() function
  378. * @param int $courseId
  379. *
  380. * @param boolean $addToolLink Whether to add a tool link on the course homepage
  381. *
  382. * @return void
  383. */
  384. public function course_install($courseId, $addToolLink = true)
  385. {
  386. $this->install_course_fields($courseId, $addToolLink);
  387. }
  388. /**
  389. * Add course settings and, if not asked otherwise, add a tool link on the course homepage
  390. * @param int $courseId Course integer ID
  391. * @param boolean $add_tool_link Whether to add a tool link or not
  392. * (some tools might just offer a configuration section and act on the backend)
  393. *
  394. * @return boolean|null False on error, null otherwise
  395. */
  396. public function install_course_fields($courseId, $add_tool_link = true)
  397. {
  398. $plugin_name = $this->get_name();
  399. $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
  400. $courseId = (int) $courseId;
  401. if (empty($courseId)) {
  402. return false;
  403. }
  404. // Adding course settings.
  405. if (!empty($this->course_settings)) {
  406. foreach ($this->course_settings as $setting) {
  407. $variable = $setting['name'];
  408. $value = '';
  409. if (isset($setting['init_value'])) {
  410. $value = $setting['init_value'];
  411. }
  412. $type = 'textfield';
  413. if (isset($setting['type'])) {
  414. $type = $setting['type'];
  415. }
  416. if (isset($setting['group'])) {
  417. $group = $setting['group'];
  418. $sql = "SELECT value
  419. FROM $t_course
  420. WHERE
  421. c_id = $courseId AND
  422. variable = '".Database::escape_string($group)."' AND
  423. subkey = '".Database::escape_string($variable)."'
  424. ";
  425. $result = Database::query($sql);
  426. if (!Database::num_rows($result)) {
  427. $params = [
  428. 'c_id' => $courseId,
  429. 'variable' => $group,
  430. 'subkey' => $variable,
  431. 'value' => $value,
  432. 'category' => 'plugins',
  433. 'type' => $type,
  434. 'title' => ''
  435. ];
  436. Database::insert($t_course, $params);
  437. }
  438. } else {
  439. $sql = "SELECT value FROM $t_course
  440. WHERE c_id = $courseId AND variable = '$variable' ";
  441. $result = Database::query($sql);
  442. if (!Database::num_rows($result)) {
  443. $params = [
  444. 'c_id' => $courseId,
  445. 'variable' => $variable,
  446. 'subkey' => $plugin_name,
  447. 'value' => $value,
  448. 'category' => 'plugins',
  449. 'type' => $type,
  450. 'title' => ''
  451. ];
  452. Database::insert($t_course, $params);
  453. }
  454. }
  455. }
  456. }
  457. // Stop here if we don't want a tool link on the course homepage
  458. if (!$add_tool_link || $this->addCourseTool == false) {
  459. return true;
  460. }
  461. //Add an icon in the table tool list
  462. $this->createLinkToCourseTool($plugin_name, $courseId);
  463. }
  464. /**
  465. * Delete the fields added to the course settings page and the link to the
  466. * tool on the course's homepage
  467. * @param int $courseId
  468. *
  469. * @return false|null
  470. */
  471. public function uninstall_course_fields($courseId)
  472. {
  473. $courseId = intval($courseId);
  474. if (empty($courseId)) {
  475. return false;
  476. }
  477. $pluginName = $this->get_name();
  478. $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
  479. $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
  480. if (!empty($this->course_settings)) {
  481. foreach ($this->course_settings as $setting) {
  482. $variable = Database::escape_string($setting['name']);
  483. if (!empty($setting['group'])) {
  484. $variable = Database::escape_string($setting['group']);
  485. }
  486. if (empty($variable)) {
  487. continue;
  488. }
  489. $sql = "DELETE FROM $t_course
  490. WHERE c_id = $courseId AND variable = '$variable'";
  491. Database::query($sql);
  492. }
  493. }
  494. $pluginName = Database::escape_string($pluginName);
  495. $sql = "DELETE FROM $t_tool
  496. WHERE c_id = $courseId AND
  497. (
  498. name = '$pluginName' OR
  499. name = '$pluginName:student' OR
  500. name = '$pluginName:teacher'
  501. )";
  502. Database::query($sql);
  503. }
  504. /**
  505. * Add an link for a course tool
  506. * @param string $name The tool name
  507. * @param int $courseId The course ID
  508. * @param string $iconName Optional. Icon file name
  509. * @param string $link Optional. Link URL
  510. * @return CTool|null
  511. */
  512. protected function createLinkToCourseTool(
  513. $name,
  514. $courseId,
  515. $iconName = null,
  516. $link = null
  517. ) {
  518. if (!$this->addCourseTool) {
  519. return null;
  520. }
  521. $visibility = $this->getToolIconVisibility();
  522. $em = Database::getManager();
  523. /** @var CTool $tool */
  524. $tool = $em
  525. ->getRepository('ChamiloCourseBundle:CTool')
  526. ->findOneBy([
  527. 'name' => $name,
  528. 'cId' => $courseId
  529. ]);
  530. if (!$tool) {
  531. $cToolId = AddCourse::generateToolId($courseId);
  532. $pluginName = $this->get_name();
  533. $tool = new CTool();
  534. $tool
  535. ->setId($cToolId)
  536. ->setCId($courseId)
  537. ->setName($name.$visibility)
  538. ->setLink($link ?: "$pluginName/start.php")
  539. ->setImage($iconName ?: "$pluginName.png")
  540. ->setVisibility(true)
  541. ->setAdmin(0)
  542. ->setAddress('squaregrey.gif')
  543. ->setAddedTool(false)
  544. ->setTarget('_self')
  545. ->setCategory('plugin')
  546. ->setSessionId(0);
  547. $em->persist($tool);
  548. $em->flush();
  549. }
  550. return $tool;
  551. }
  552. /**
  553. * Install the course fields and tool link of this plugin in all courses
  554. * @param boolean $add_tool_link Whether we want to add a plugin link on the course homepage
  555. *
  556. * @return void
  557. */
  558. public function install_course_fields_in_all_courses($add_tool_link = true)
  559. {
  560. // Update existing courses to add plugin settings
  561. $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
  562. $sql = "SELECT id FROM $t_courses ORDER BY id";
  563. $res = Database::query($sql);
  564. while ($row = Database::fetch_assoc($res)) {
  565. $this->install_course_fields($row['id'], $add_tool_link);
  566. }
  567. }
  568. /**
  569. * Uninstall the plugin settings fields from all courses
  570. * @return void
  571. */
  572. public function uninstall_course_fields_in_all_courses()
  573. {
  574. // Update existing courses to add conference settings
  575. $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
  576. $sql = "SELECT id FROM $t_courses
  577. ORDER BY id";
  578. $res = Database::query($sql);
  579. while ($row = Database::fetch_assoc($res)) {
  580. $this->uninstall_course_fields($row['id']);
  581. }
  582. }
  583. /**
  584. * @return array
  585. */
  586. public function getCourseSettings()
  587. {
  588. $settings = [];
  589. if (is_array($this->course_settings)) {
  590. foreach ($this->course_settings as $item) {
  591. if (isset($item['group'])) {
  592. if (!in_array($item['group'], $settings)) {
  593. $settings[] = $item['group'];
  594. }
  595. } else {
  596. $settings[] = $item['name'];
  597. }
  598. }
  599. }
  600. return $settings;
  601. }
  602. /**
  603. * Method to be extended when changing the setting in the course
  604. * configuration should trigger the use of a callback method
  605. * @param array $values sent back from the course configuration script
  606. *
  607. */
  608. public function course_settings_updated($values = [])
  609. {
  610. }
  611. /**
  612. * Add a tab to platform
  613. * @param string $tabName
  614. * @param string $url
  615. * @param string $userFilter Optional. Filter tab type
  616. * @return false|string
  617. */
  618. public function addTab($tabName, $url, $userFilter = null)
  619. {
  620. $sql = "SELECT * FROM settings_current
  621. WHERE
  622. variable = 'show_tabs' AND
  623. subkey LIKE 'custom_tab_%'";
  624. $result = Database::query($sql);
  625. $customTabsNum = Database::num_rows($result);
  626. $tabNum = $customTabsNum + 1;
  627. // Avoid Tab Name Spaces
  628. $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
  629. $subkeytext = "Tabs".$tabNameNoSpaces;
  630. // Check if it is already added
  631. $checkCondition = [
  632. 'where' =>
  633. [
  634. "variable = 'show_tabs' AND subkeytext = ?" => [
  635. $subkeytext
  636. ]
  637. ]
  638. ];
  639. $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
  640. if (!empty($checkDuplicate)) {
  641. return false;
  642. }
  643. // End Check
  644. $subkey = 'custom_tab_'.$tabNum;
  645. if (!empty($userFilter)) {
  646. switch ($userFilter) {
  647. case self::TAB_FILTER_NO_STUDENT:
  648. case self::TAB_FILTER_ONLY_STUDENT:
  649. $subkey .= $userFilter;
  650. break;
  651. }
  652. }
  653. $attributes = [
  654. 'variable' => 'show_tabs',
  655. 'subkey' => $subkey,
  656. 'type' => 'checkbox',
  657. 'category' => 'Platform',
  658. 'selected_value' => 'true',
  659. 'title' => $tabName,
  660. 'comment' => $url,
  661. 'subkeytext' => $subkeytext,
  662. 'access_url' => 1,
  663. 'access_url_changeable' => 1,
  664. 'access_url_locked' => 0
  665. ];
  666. $resp = Database::insert('settings_current', $attributes);
  667. // Save the id
  668. $settings = $this->get_settings();
  669. $setData = [
  670. 'comment' => $subkey
  671. ];
  672. $whereCondition = [
  673. 'id = ?' => key($settings)
  674. ];
  675. Database::update('settings_current', $setData, $whereCondition);
  676. return $resp;
  677. }
  678. /**
  679. * Delete a tab to chamilo's platform
  680. * @param string $key
  681. * @return boolean $resp Transaction response
  682. */
  683. public function deleteTab($key)
  684. {
  685. $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  686. $sql = "SELECT *
  687. FROM $table
  688. WHERE variable = 'show_tabs'
  689. AND subkey <> '$key'
  690. AND subkey like 'custom_tab_%'
  691. ";
  692. $resp = $result = Database::query($sql);
  693. $customTabsNum = Database::num_rows($result);
  694. if (!empty($key)) {
  695. $whereCondition = [
  696. 'variable = ? AND subkey = ?' => ['show_tabs', $key]
  697. ];
  698. $resp = Database::delete('settings_current', $whereCondition);
  699. //if there is more than one tab
  700. //re enumerate them
  701. if (!empty($customTabsNum) && $customTabsNum > 0) {
  702. $tabs = Database::store_result($result, 'ASSOC');
  703. $i = 1;
  704. foreach ($tabs as $row) {
  705. $newSubKey = "custom_tab_$i";
  706. if (strpos($row['subkey'], self::TAB_FILTER_NO_STUDENT) !== false) {
  707. $newSubKey .= self::TAB_FILTER_NO_STUDENT;
  708. } elseif (strpos($row['subkey'], self::TAB_FILTER_ONLY_STUDENT) !== false) {
  709. $newSubKey .= self::TAB_FILTER_ONLY_STUDENT;
  710. }
  711. $attributes = ['subkey' => $newSubKey];
  712. $this->updateTab($row['subkey'], $attributes);
  713. $i++;
  714. }
  715. }
  716. }
  717. return $resp;
  718. }
  719. /**
  720. * Update the tabs attributes
  721. * @param string $key
  722. * @param array $attributes
  723. *
  724. * @return boolean
  725. */
  726. public function updateTab($key, $attributes)
  727. {
  728. $whereCondition = [
  729. 'variable = ? AND subkey = ?' => ['show_tabs', $key]
  730. ];
  731. $resp = Database::update('settings_current', $attributes, $whereCondition);
  732. return $resp;
  733. }
  734. /**
  735. * This method shows or hides plugin's tab
  736. * @param boolean $showTab Shows or hides the main menu plugin tab
  737. * @param string $filePath Plugin starter file path
  738. */
  739. public function manageTab($showTab, $filePath = 'index.php')
  740. {
  741. $langString = str_replace('Plugin', '', get_class($this));
  742. $pluginName = strtolower($langString);
  743. $pluginUrl = 'plugin/'.$pluginName.'/'.$filePath;
  744. if ($showTab === 'true') {
  745. $tabAdded = $this->addTab($langString, $pluginUrl);
  746. if ($tabAdded) {
  747. // The page must be refreshed to show the recently created tab
  748. echo "<script>location.href = '".Security::remove_XSS($_SERVER['REQUEST_URI'])."';</script>";
  749. }
  750. } else {
  751. $settingsCurrentTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
  752. $conditions = [
  753. 'where' => [
  754. "variable = 'show_tabs' AND title = ? AND comment = ? " => [
  755. $langString,
  756. $pluginUrl
  757. ]
  758. ]
  759. ];
  760. $result = Database::select('subkey', $settingsCurrentTable, $conditions);
  761. if (!empty($result)) {
  762. $this->deleteTab($result[0]['subkey']);
  763. }
  764. }
  765. }
  766. /**
  767. * @param string $variable
  768. * @return bool
  769. */
  770. public function validateCourseSetting($variable)
  771. {
  772. return true;
  773. }
  774. /**
  775. * @param string $region
  776. * @return string
  777. */
  778. public function renderRegion($region)
  779. {
  780. return '';
  781. }
  782. /**
  783. * Returns true if the plugin is installed, false otherwise
  784. * @return bool True if plugin is installed/enabled, false otherwise
  785. */
  786. public function isEnabled()
  787. {
  788. $settings = api_get_settings_params_simple(
  789. [
  790. "subkey = ? AND category = ? AND type = ? AND variable = 'status' " => [
  791. $this->get_name(),
  792. 'Plugins',
  793. 'setting',
  794. ]
  795. ]
  796. );
  797. if (is_array($settings) && isset($settings['selected_value']) && $settings['selected_value'] == 'installed') {
  798. return true;
  799. }
  800. return false;
  801. }
  802. /**
  803. * Allow make some actions after configure the plugin parameters
  804. * This function is called from main/admin/configure_plugin.php page
  805. * when saving the plugin parameters
  806. * @return \Plugin
  807. */
  808. public function performActionsAfterConfigure()
  809. {
  810. return $this;
  811. }
  812. /**
  813. * This function allows to change the visibility of the icon inside a course
  814. * :student tool will be visible only for students
  815. * :teacher tool will be visible only for teachers
  816. * If nothing it's set then tool will be visible for both as a normal icon.
  817. *
  818. * @return string
  819. */
  820. public function getToolIconVisibility()
  821. {
  822. return '';
  823. }
  824. /**
  825. * Get the admin URL for the plugin if Plugin::isAdminPlugin is true
  826. * @return string
  827. */
  828. public function getAdminUrl()
  829. {
  830. if (!$this->isAdminPlugin) {
  831. return '';
  832. }
  833. $name = $this->get_name();
  834. $sysPath = api_get_path(SYS_PLUGIN_PATH).$name;
  835. $webPath = api_get_path(WEB_PLUGIN_PATH).$name;
  836. if (file_exists("$sysPath/admin.php")) {
  837. return "$webPath/admin.php";
  838. }
  839. if (file_exists("$sysPath/start.php")) {
  840. return "$webPath/start.php";
  841. }
  842. return '';
  843. }
  844. }