plugin.lib.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <?php
  2. /* See license terms in /license.txt */
  3. class AppPlugin {
  4. var $plugin_regions = array (
  5. // 'loginpage_main',
  6. 'login_top',
  7. 'login_bottom',
  8. 'menu_top',
  9. 'menu_bottom',
  10. /* 'campushomepage_main',
  11. 'campushomepage_menu',
  12. 'mycourses_main',
  13. 'mycourses_menu',*/
  14. 'content_top',
  15. 'content_bottom',
  16. 'header_main',
  17. 'header_center',
  18. 'header_left',
  19. 'header_right',
  20. //'footer',
  21. 'footer_left',
  22. 'footer_center',
  23. 'footer_right',
  24. 'course_tool_plugin'
  25. );
  26. function __construct() {
  27. }
  28. function read_plugins_from_path() {
  29. /* We scan the plugin directory. Each folder is a potential plugin. */
  30. $pluginpath = api_get_path(SYS_PLUGIN_PATH);
  31. $possible_plugins = array();
  32. $handle = @opendir($pluginpath);
  33. while (false !== ($file = readdir($handle))) {
  34. if ($file != '.' && $file != '..' && is_dir(api_get_path(SYS_PLUGIN_PATH).$file)) {
  35. $possible_plugins[] = $file;
  36. }
  37. }
  38. @closedir($handle);
  39. sort($possible_plugins);
  40. return $possible_plugins;
  41. }
  42. function get_installed_plugins_by_region(){
  43. $used_plugins = array();
  44. /* We retrieve all the active plugins. */
  45. $result = api_get_settings('Plugins');
  46. foreach ($result as $row) {
  47. $used_plugins[$row['variable']][] = $row['selected_value'];
  48. }
  49. return $used_plugins;
  50. }
  51. function get_installed_plugins() {
  52. $installed_plugins = array();
  53. $plugin_array = api_get_settings_params(array("variable = ? AND selected_value = ? AND category = ? " =>
  54. array('status', 'installed', 'Plugins')));
  55. if (!empty($plugin_array)) {
  56. foreach ($plugin_array as $row) {
  57. $installed_plugins[$row['subkey']] = true;
  58. }
  59. $installed_plugins = array_keys($installed_plugins);
  60. }
  61. return $installed_plugins;
  62. }
  63. function install($plugin_name, $access_url_id = null) {
  64. if (empty($access_url_id)) {
  65. $access_url_id = api_get_current_access_url_id();
  66. } else {
  67. $access_url_id = intval($access_url_id);
  68. }
  69. api_add_setting('installed', 'status', $plugin_name, 'setting', 'Plugins', $plugin_name, null, null, null, $access_url_id, 1);
  70. //api_add_setting($plugin, $area, $plugin, null, 'Plugins', $plugin, null, null, null, $_configuration['access_url'], 1);
  71. $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/install.php';
  72. if (is_file($pluginpath) && is_readable($pluginpath)) {
  73. //execute the install procedure
  74. require $pluginpath;
  75. }
  76. }
  77. function uninstall($plugin_name, $access_url_id = null) {
  78. if (empty($access_url_id)) {
  79. $access_url_id = api_get_current_access_url_id();
  80. } else {
  81. $access_url_id = intval($access_url_id);
  82. }
  83. api_delete_settings_params(array('category = ? AND access_url = ? AND subkey = ? ' =>
  84. array('Plugins', $access_url_id, $plugin_name)));
  85. $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/uninstall.php';
  86. if (is_file($pluginpath) && is_readable($pluginpath)) {
  87. //execute the uninstall procedure
  88. require $pluginpath;
  89. }
  90. }
  91. function get_areas_by_plugin($plugin_name) {
  92. $result = api_get_settings('Plugins');
  93. $areas = array();
  94. foreach ($result as $row) {
  95. if ($plugin_name == $row['selected_value']) {
  96. $areas[] = $row['variable'];
  97. }
  98. }
  99. return $areas;
  100. }
  101. function is_valid_plugin_location($location) {
  102. return in_array($location, $this->plugin_list);
  103. }
  104. function is_valid_plugin($plugin_name) {
  105. if (is_dir(api_get_path(SYS_PLUGIN_PATH).$plugin_name)) {
  106. if (is_file(api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/index.php')) {
  107. return true;
  108. }
  109. }
  110. return false;
  111. }
  112. function get_plugin_regions() {
  113. sort($this->plugin_regions);
  114. return $this->plugin_regions;
  115. }
  116. function load_region($region, $main_template, $forced = false) {
  117. if ($region == 'course_tool_plugin') {
  118. return null;
  119. }
  120. ob_start();
  121. $this->get_all_plugin_contents_by_region($region, $main_template, $forced);
  122. $content = ob_get_contents();
  123. ob_end_clean();
  124. return $content;
  125. }
  126. /**
  127. * Loads the translation files inside a plugin if exists. It loads by default english see the hello world plugin
  128. *
  129. * @todo add caching
  130. * @param string $plugin_name
  131. */
  132. function load_plugin_lang_variables($plugin_name) {
  133. global $language_interface;
  134. $root = api_get_path(SYS_PLUGIN_PATH);
  135. //1. Loading english if exists
  136. $english_path = $root.$plugin_name."/lang/english.php";
  137. if (is_readable($english_path)) {
  138. include $english_path;
  139. foreach ($strings as $key => $string) {
  140. $GLOBALS[$key] = $string;
  141. }
  142. }
  143. //2. Loading the system language
  144. if ($language_interface != 'english') {
  145. $path = $root.$plugin_name."/lang/$language_interface.php";
  146. if (is_readable($path)) {
  147. include $path;
  148. if (!empty($strings)) {
  149. foreach ($strings as $key => $string) {
  150. $GLOBALS[$key] = $string;
  151. }
  152. }
  153. }
  154. }
  155. }
  156. /**
  157. *
  158. *
  159. * @param string $block
  160. * @param obj template obj
  161. * @todo improve this function
  162. */
  163. function get_all_plugin_contents_by_region($region, $template, $forced = false) {
  164. global $_plugins;
  165. if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
  166. //if (1) {
  167. //Load the plugin information
  168. foreach ($_plugins[$region] as $plugin_name) {
  169. //The plugin_info variable is available inside the plugin index
  170. $plugin_info = $this->get_plugin_info($plugin_name, $forced);
  171. //We also know where the plugin is
  172. $plugin_info['current_region'] = $region;
  173. // Loading the plugin/XXX/index.php file
  174. $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php";
  175. if (file_exists($plugin_file)) {
  176. //Loading the lang variables of the plugin if exists
  177. self::load_plugin_lang_variables($plugin_name);
  178. //Printing the plugin index.php file
  179. require $plugin_file;
  180. //If the variable $_template is set we assign those values to be accesible in Twig
  181. if (isset($_template)) {
  182. $_template['plugin_info'] = $plugin_info;
  183. } else {
  184. $_template = array();
  185. $_template['plugin_info'] = $plugin_info;
  186. }
  187. //Setting the plugin info available in the template if exists
  188. $template->assign($plugin_name, $_template);
  189. //Loading the Twig template plugin files if exists
  190. $template_list = array();
  191. if (isset($plugin_info) && isset($plugin_info['templates'])) {
  192. $template_list = $plugin_info['templates'];
  193. }
  194. if (!empty($template_list)) {
  195. foreach ($template_list as $plugin_tpl) {
  196. if (!empty($plugin_tpl)) {
  197. //$template_plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/$plugin_tpl"; //for smarty
  198. $template_plugin_file = "$plugin_name/$plugin_tpl"; // for twig
  199. $template->display($template_plugin_file);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. return true;
  207. }
  208. /**
  209. * Loads plugin info
  210. * @staticvar array $plugin_data
  211. * @param string plugin name
  212. * @param bool load from DB or from the static array
  213. * @todo filter setting_form
  214. * @return array
  215. */
  216. function get_plugin_info($plugin_name, $forced = false) {
  217. static $plugin_data = array();
  218. if (isset($plugin_data[$plugin_name]) && $forced == false) {
  219. return $plugin_data[$plugin_name];
  220. } else {
  221. $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/plugin.php";
  222. $plugin_info = array();
  223. if (file_exists($plugin_file)) {
  224. require $plugin_file;
  225. }
  226. //extra options
  227. $plugin_settings = api_get_settings_params(array("subkey = ? AND category = ? AND type = ? " =>
  228. array($plugin_name, 'Plugins','setting')));
  229. $settings_filtered = array();
  230. foreach ($plugin_settings as $item) {
  231. $settings_filtered[$item['variable']] = $item['selected_value'];
  232. }
  233. $plugin_info['settings'] = $settings_filtered;
  234. $plugin_data[$plugin_name] = $plugin_info;
  235. return $plugin_info;
  236. }
  237. }
  238. /*
  239. * Get the template list
  240. */
  241. function get_templates_list($plugin_name) {
  242. $plugin_info = $this->get_plugin_info($plugin_name);
  243. if (isset($plugin_info) && isset($plugin_info['templates'])) {
  244. return $plugin_info['templates'];
  245. } else {
  246. return false;
  247. }
  248. }
  249. /* *
  250. * Remove all regions of an specific plugin
  251. */
  252. function remove_all_regions($plugin) {
  253. $access_url_id = api_get_current_access_url_id();
  254. if (!empty($plugin)) {
  255. api_delete_settings_params(array('category = ? AND type = ? AND access_url = ? AND subkey = ? ' =>
  256. array('Plugins', 'region', $access_url_id, $plugin)));
  257. }
  258. }
  259. /*
  260. * Add a plugin to a region
  261. */
  262. function add_to_region($plugin, $region) {
  263. $access_url_id = api_get_current_access_url_id();
  264. api_add_setting($plugin, $region, $plugin, 'region', 'Plugins', $plugin, null, null, null, $access_url_id, 1);
  265. }
  266. function install_course_plugins($course_id) {
  267. $plugin_list = $this->get_installed_plugins();
  268. if (!empty($plugin_list)) {
  269. foreach ($plugin_list as $plugin_name) {
  270. $plugin_path = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/plugin.php';
  271. if (file_exists($plugin_path)) {
  272. require_once $plugin_path;
  273. if (isset($plugin_info) && isset($plugin_info['plugin_class'])) {
  274. $plugin_info['plugin_class']::create()->course_install($course_id);
  275. }
  276. }
  277. }
  278. }
  279. }
  280. function add_course_settings_form($form) {
  281. $plugin_list = $this->get_installed_plugins();
  282. foreach ($plugin_list as $plugin_name) {
  283. $plugin_info = $this->get_plugin_info($plugin_name);
  284. if (isset($plugin_info['plugin_class'])) {
  285. $obj = $plugin_info['plugin_class']::create();
  286. if (!empty($obj->course_settings)) {
  287. $icon = Display::return_icon($plugin_name.'.png', Security::remove_XSS($plugin_info['title']),'', ICON_SIZE_SMALL);
  288. //$icon = null;
  289. $form->addElement('html', '<div><h3>'.$icon.' '.Security::remove_XSS($plugin_info['title']).'</h3><div>');
  290. $groups = array();
  291. foreach ($obj->course_settings as $setting) {
  292. if ($setting['type'] != 'checkbox') {
  293. $form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name']));
  294. } else {
  295. //if (isset($groups[$setting['group']])) {
  296. $element = & $form->createElement($setting['type'], $setting['name'], '', $obj->get_lang($setting['name']));
  297. if ($setting['init_value'] == 1) {
  298. $element->setChecked(true);
  299. }
  300. $groups[$setting['group']][] = $element;
  301. //}
  302. }
  303. }
  304. foreach ($groups as $k => $v) {
  305. $form->addGroup($groups[$k], $k, array($obj->get_lang($k)));
  306. }
  307. $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class="save"');
  308. $form->addElement('html', '</div></div>');
  309. }
  310. }
  311. }
  312. }
  313. function set_course_settings_defaults(& $values) {
  314. $plugin_list = $this->get_installed_plugins();
  315. foreach ($plugin_list as $plugin_name) {
  316. $plugin_info = $this->get_plugin_info($plugin_name);
  317. if (isset($plugin_info['plugin_class'])) {
  318. $obj = $plugin_info['plugin_class']::create();
  319. if (!empty($obj->course_settings)) {
  320. foreach ($obj->course_settings as $setting) {
  321. if (isset($setting['name'])) {
  322. $result = api_get_course_setting($setting['name']);
  323. if ($result != '-1') {
  324. $values[$setting['name']] = $result;
  325. }
  326. }
  327. }
  328. }
  329. }
  330. }
  331. }
  332. /**
  333. * When saving the plugin values in the course settings, check whether
  334. * a callback method should be called and send it the updated settings
  335. * @param array The new settings the user just saved
  336. * @return void
  337. */
  338. function save_course_settings($values) {
  339. $plugin_list = $this->get_installed_plugins();
  340. foreach ($plugin_list as $plugin_name) {
  341. $settings = $this->get_plugin_course_settings($plugin_name);
  342. $subvalues = array();
  343. $i = 0;
  344. foreach ($settings as $v) {
  345. if (isset($values[$v])) {
  346. $subvalues[$v] = $values[$v];
  347. $i++;
  348. }
  349. }
  350. if ($i>0) {
  351. $plugin_info = $this->get_plugin_info($plugin_name);
  352. if (isset($plugin_info['plugin_class'])) {
  353. $obj = $plugin_info['plugin_class']::create();
  354. $obj->course_settings_updated($subvalues);
  355. }
  356. }
  357. }
  358. }
  359. /**
  360. * Gets a nice array of keys for just the plugin's course settings
  361. * @param string The plugin ID
  362. * @return array Nice array of keys for course settings
  363. */
  364. public function get_plugin_course_settings($plugin_name) {
  365. $settings = array();
  366. if (empty($plugin_name)) { return $settings; }
  367. $plugin_info = $this->get_plugin_info($plugin_name);
  368. if (isset($plugin_info['plugin_class'])) {
  369. $obj = $plugin_info['plugin_class']::create();
  370. if (is_array($obj->course_settings)) {
  371. foreach ($obj->course_settings as $item) {
  372. if (isset($item['group'])) {
  373. if (!in_array($item['group'],$settings)) {
  374. $settings[] = $item['group'];
  375. }
  376. } else {
  377. $settings[] = $item['name'];
  378. }
  379. }
  380. }
  381. unset($obj); unset($plugin_info);
  382. }
  383. return $settings;
  384. }
  385. }