1
|
|
|
<?php |
2
|
|
|
/* See license terms in /license.txt */ |
3
|
|
|
|
4
|
|
|
use ChamiloSession as Session; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Class AppPlugin. |
8
|
|
|
*/ |
9
|
|
|
class AppPlugin |
10
|
|
|
{ |
11
|
|
|
public $plugin_regions = [ |
12
|
|
|
'main_top', |
13
|
|
|
'main_bottom', |
14
|
|
|
'login_top', |
15
|
|
|
'login_bottom', |
16
|
|
|
'menu_top', |
17
|
|
|
'menu_bottom', |
18
|
|
|
'content_top', |
19
|
|
|
'content_bottom', |
20
|
|
|
'header_main', |
21
|
|
|
'header_center', |
22
|
|
|
'header_left', |
23
|
|
|
'header_right', |
24
|
|
|
'pre_footer', |
25
|
|
|
'footer_left', |
26
|
|
|
'footer_center', |
27
|
|
|
'footer_right', |
28
|
|
|
'menu_administrator', |
29
|
|
|
'course_tool_plugin', |
30
|
|
|
]; |
31
|
|
|
|
32
|
|
|
public $installedPluginListName = []; |
33
|
|
|
public $installedPluginListObject = []; |
34
|
|
|
private static $instance; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Constructor. |
38
|
|
|
*/ |
39
|
|
|
public function __construct() |
40
|
|
|
{ |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @return AppPlugin |
45
|
|
|
*/ |
46
|
|
|
public static function getInstance() |
47
|
|
|
{ |
48
|
|
|
if (!isset(self::$instance)) { |
49
|
|
|
self::$instance = new self(); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
return self::$instance; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Read plugin from path. |
57
|
|
|
* |
58
|
|
|
* @return array |
59
|
|
|
*/ |
60
|
|
|
public function read_plugins_from_path() |
61
|
|
|
{ |
62
|
|
|
/* We scan the plugin directory. Each folder is a potential plugin. */ |
63
|
|
|
$pluginPath = api_get_path(SYS_PLUGIN_PATH); |
64
|
|
|
$plugins = []; |
65
|
|
|
$handle = @opendir($pluginPath); |
66
|
|
|
while (false !== ($file = readdir($handle))) { |
67
|
|
|
if ($file != '.' && $file != '..' && is_dir(api_get_path(SYS_PLUGIN_PATH).$file)) { |
68
|
|
|
$plugins[] = $file; |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
@closedir($handle); |
|
|
|
|
72
|
|
|
sort($plugins); |
73
|
|
|
|
74
|
|
|
return $plugins; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @return array |
79
|
|
|
*/ |
80
|
|
|
public function getInstalledPluginListName() |
81
|
|
|
{ |
82
|
|
|
if (empty($this->installedPluginListName)) { |
83
|
|
|
$this->installedPluginListName = $this->getInstalledPlugins(); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
return $this->installedPluginListName; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @return array List of Plugin |
91
|
|
|
*/ |
92
|
|
|
public function getInstalledPluginListObject() |
93
|
|
|
{ |
94
|
|
|
if (empty($this->installedPluginListObject)) { |
95
|
|
|
$this->setInstalledPluginListObject(); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
return $this->installedPluginListObject; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
public function setInstalledPluginListObject() |
102
|
|
|
{ |
103
|
|
|
$pluginListName = $this->getInstalledPluginListName(); |
104
|
|
|
$pluginList = []; |
105
|
|
|
if (!empty($pluginListName)) { |
106
|
|
|
foreach ($pluginListName as $pluginName) { |
107
|
|
|
$pluginInfo = $this->getPluginInfo($pluginName, true); |
108
|
|
|
if (isset($pluginInfo['plugin_class'])) { |
109
|
|
|
$pluginList[] = $pluginInfo['plugin_class']::create(); |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
$this->installedPluginListObject = $pluginList; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @param string $plugin |
118
|
|
|
* |
119
|
|
|
* @return bool |
120
|
|
|
*/ |
121
|
|
|
public function isInstalled($plugin) |
122
|
|
|
{ |
123
|
|
|
$list = self::getInstalledPlugins(false); |
|
|
|
|
124
|
|
|
|
125
|
|
|
return in_array($plugin, $list); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Returns a list of all installed plugins. |
130
|
|
|
* |
131
|
|
|
* @param bool $fromDatabase |
132
|
|
|
* |
133
|
|
|
* @return array |
134
|
|
|
*/ |
135
|
|
|
public function getInstalledPlugins($fromDatabase = true) |
136
|
|
|
{ |
137
|
|
|
static $installedPlugins = null; |
138
|
|
|
|
139
|
|
|
if ($fromDatabase === false) { |
140
|
|
|
if (is_array($installedPlugins)) { |
141
|
|
|
return $installedPlugins; |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
if ($fromDatabase || $installedPlugins === null) { |
146
|
|
|
$installedPlugins = []; |
147
|
|
|
$plugins = api_get_settings_params( |
148
|
|
|
[ |
149
|
|
|
'variable = ? AND selected_value = ? AND category = ? ' => ['status', 'installed', 'Plugins'], |
150
|
|
|
] |
151
|
|
|
); |
152
|
|
|
|
153
|
|
|
if (!empty($plugins)) { |
154
|
|
|
foreach ($plugins as $row) { |
155
|
|
|
$installedPlugins[$row['subkey']] = true; |
156
|
|
|
} |
157
|
|
|
$installedPlugins = array_keys($installedPlugins); |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
return $installedPlugins; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
public function getInstalledPluginsInCurrentUrl() |
165
|
|
|
{ |
166
|
|
|
$installedPlugins = []; |
167
|
|
|
$urlId = api_get_current_access_url_id(); |
168
|
|
|
$plugins = api_get_settings_params( |
169
|
|
|
[ |
170
|
|
|
'variable = ? AND selected_value = ? AND category = ? AND access_url = ?' => ['status', 'installed', 'Plugins', $urlId], |
171
|
|
|
] |
172
|
|
|
); |
173
|
|
|
|
174
|
|
|
if (!empty($plugins)) { |
175
|
|
|
foreach ($plugins as $row) { |
176
|
|
|
$installedPlugins[$row['subkey']] = true; |
177
|
|
|
} |
178
|
|
|
$installedPlugins = array_keys($installedPlugins); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return $installedPlugins; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Returns a list of all official (delivered with the Chamilo package) |
186
|
|
|
* plugins. This list is maintained manually and updated with every new |
187
|
|
|
* release to avoid hacking. |
188
|
|
|
* |
189
|
|
|
* @return array |
190
|
|
|
*/ |
191
|
|
|
public function getOfficialPlugins() |
192
|
|
|
{ |
193
|
|
|
static $officialPlugins = null; |
194
|
|
|
// Please keep this list alphabetically sorted |
195
|
|
|
$officialPlugins = [ |
196
|
|
|
'add_cas_login_button', |
197
|
|
|
'add_cas_logout_button', |
198
|
|
|
'add_facebook_login_button', |
199
|
|
|
'add_shibboleth_login_button', |
200
|
|
|
'advanced_subscription', |
201
|
|
|
'azure_active_directory', |
202
|
|
|
'bbb', |
203
|
|
|
'before_login', |
204
|
|
|
'buycourses', |
205
|
|
|
'card_game', |
206
|
|
|
'check_extra_field_author_company', |
207
|
|
|
'cleandeletedfiles', |
208
|
|
|
'clockworksms', |
209
|
|
|
'courseblock', |
210
|
|
|
'coursehomenotify', |
211
|
|
|
'courselegal', |
212
|
|
|
'createdrupaluser', |
213
|
|
|
'customcertificate', |
214
|
|
|
'customfooter', |
215
|
|
|
'dashboard', |
216
|
|
|
'date', |
217
|
|
|
'dictionary', |
218
|
|
|
'embedregistry', |
219
|
|
|
'exercise_signature', |
220
|
|
|
'ext_auth_chamilo_logout_button_behaviour', |
221
|
|
|
'follow_buttons', |
222
|
|
|
'formLogin_hide_unhide', |
223
|
|
|
'google_maps', |
224
|
|
|
'google_meet', |
225
|
|
|
'grading_electronic', |
226
|
|
|
'h5p', |
227
|
|
|
'hello_world', |
228
|
|
|
'ims_lti', |
229
|
|
|
'jcapture', |
230
|
|
|
'justification', |
231
|
|
|
'kannelsms', |
232
|
|
|
'keycloak', |
233
|
|
|
'learning_calendar', |
234
|
|
|
'maintenancemode', |
235
|
|
|
'migrationmoodle', |
236
|
|
|
'mindmap', |
237
|
|
|
'nosearchindex', |
238
|
|
|
'notebookteacher', |
239
|
|
|
'oauth2', |
240
|
|
|
'olpc_peru_filter', |
241
|
|
|
'openmeetings', |
242
|
|
|
'pausetraining', |
243
|
|
|
'pens', |
244
|
|
|
'positioning', |
245
|
|
|
'questionoptionsevaluation', |
246
|
|
|
'redirection', |
247
|
|
|
'remedial_course', |
248
|
|
|
'reports', |
249
|
|
|
'resubscription', |
250
|
|
|
'rss', |
251
|
|
|
'search_course', |
252
|
|
|
'send_notification_new_lp', |
253
|
|
|
'sepe', |
254
|
|
|
'share_buttons', |
255
|
|
|
'show_regions', |
256
|
|
|
'show_user_info', |
257
|
|
|
'static', |
258
|
|
|
'studentfollowup', |
259
|
|
|
'surveyexportcsv', |
260
|
|
|
'surveyexporttxt', |
261
|
|
|
'test2pdf', |
262
|
|
|
'toplinks', |
263
|
|
|
'tour', |
264
|
|
|
'userremoteservice', |
265
|
|
|
'vchamilo', |
266
|
|
|
'whispeakauth', |
267
|
|
|
'zoom', |
268
|
|
|
'xapi', |
269
|
|
|
]; |
270
|
|
|
|
271
|
|
|
return $officialPlugins; |
272
|
|
|
} |
273
|
|
|
/** |
274
|
|
|
* @param string $pluginName |
275
|
|
|
* @param int $urlId |
276
|
|
|
*/ |
277
|
|
|
public function install($pluginName, $urlId = null) |
278
|
|
|
{ |
279
|
|
|
$urlId = (int) $urlId; |
280
|
|
|
if (empty($urlId)) { |
281
|
|
|
$urlId = api_get_current_access_url_id(); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
api_add_setting( |
285
|
|
|
'installed', |
286
|
|
|
'status', |
287
|
|
|
$pluginName, |
288
|
|
|
'setting', |
289
|
|
|
'Plugins', |
290
|
|
|
$pluginName, |
291
|
|
|
'', |
292
|
|
|
'', |
293
|
|
|
'', |
294
|
|
|
$urlId, |
295
|
|
|
1 |
296
|
|
|
); |
297
|
|
|
|
298
|
|
|
$pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/install.php'; |
299
|
|
|
|
300
|
|
|
if (is_file($pluginPath) && is_readable($pluginPath)) { |
301
|
|
|
// Execute the install procedure. |
302
|
|
|
|
303
|
|
|
require $pluginPath; |
304
|
|
|
} |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* @param string $pluginName |
309
|
|
|
* @param int $urlId |
310
|
|
|
*/ |
311
|
|
|
public function uninstall($pluginName, $urlId = null) |
312
|
|
|
{ |
313
|
|
|
$urlId = (int) $urlId; |
314
|
|
|
if (empty($urlId)) { |
315
|
|
|
$urlId = api_get_current_access_url_id(); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
// First call the custom uninstall to allow full access to global settings |
319
|
|
|
$pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/uninstall.php'; |
320
|
|
|
if (is_file($pluginPath) && is_readable($pluginPath)) { |
321
|
|
|
// Execute the uninstall procedure. |
322
|
|
|
|
323
|
|
|
require $pluginPath; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
// Second remove all remaining global settings |
327
|
|
|
api_delete_settings_params( |
328
|
|
|
['category = ? AND access_url = ? AND subkey = ? ' => ['Plugins', $urlId, $pluginName]] |
329
|
|
|
); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* @param string $pluginName |
334
|
|
|
* |
335
|
|
|
* @return array |
336
|
|
|
*/ |
337
|
|
|
public function get_areas_by_plugin($pluginName) |
338
|
|
|
{ |
339
|
|
|
$result = api_get_settings('Plugins'); |
340
|
|
|
$areas = []; |
341
|
|
|
foreach ($result as $row) { |
342
|
|
|
if ($pluginName == $row['selected_value']) { |
343
|
|
|
$areas[] = $row['variable']; |
344
|
|
|
} |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
return $areas; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* @param string $pluginName |
352
|
|
|
* |
353
|
|
|
* @return bool |
354
|
|
|
*/ |
355
|
|
|
public function is_valid_plugin($pluginName) |
356
|
|
|
{ |
357
|
|
|
if (is_dir(api_get_path(SYS_PLUGIN_PATH).$pluginName)) { |
358
|
|
|
if (is_file(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/index.php')) { |
359
|
|
|
return true; |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
return false; |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
/** |
367
|
|
|
* @return array |
368
|
|
|
*/ |
369
|
|
|
public function get_plugin_regions() |
370
|
|
|
{ |
371
|
|
|
sort($this->plugin_regions); |
372
|
|
|
|
373
|
|
|
return $this->plugin_regions; |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* @param string $region |
378
|
|
|
* @param Template $template |
379
|
|
|
* @param bool $forced |
380
|
|
|
* |
381
|
|
|
* @return string|null |
382
|
|
|
*/ |
383
|
|
|
public function load_region($region, $template, $forced = false) |
384
|
|
|
{ |
385
|
|
|
if ($region == 'course_tool_plugin') { |
386
|
|
|
return ''; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
ob_start(); |
390
|
|
|
$this->get_all_plugin_contents_by_region($region, $template, $forced); |
391
|
|
|
$content = ob_get_contents(); |
392
|
|
|
ob_end_clean(); |
393
|
|
|
|
394
|
|
|
return $content; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
/** |
398
|
|
|
* Loads the translation files inside a plugin if exists. |
399
|
|
|
* It loads by default english see the hello world plugin. |
400
|
|
|
* |
401
|
|
|
* @param string $plugin_name |
402
|
|
|
* |
403
|
|
|
* @todo add caching |
404
|
|
|
*/ |
405
|
|
|
public function load_plugin_lang_variables($plugin_name) |
406
|
|
|
{ |
407
|
|
|
global $language_interface; |
408
|
|
|
$root = api_get_path(SYS_PLUGIN_PATH); |
409
|
|
|
$strings = null; |
410
|
|
|
|
411
|
|
|
// 1. Loading english if exists |
412
|
|
|
$english_path = $root.$plugin_name."/lang/english.php"; |
413
|
|
|
|
414
|
|
|
if (is_readable($english_path)) { |
415
|
|
|
include $english_path; |
416
|
|
|
|
417
|
|
|
foreach ($strings as $key => $string) { |
|
|
|
|
418
|
|
|
$GLOBALS[$key] = $string; |
419
|
|
|
} |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
// 2. Loading the system language |
423
|
|
|
if ($language_interface != 'english') { |
424
|
|
|
$path = $root.$plugin_name."/lang/$language_interface.php"; |
425
|
|
|
|
426
|
|
|
if (is_readable($path)) { |
427
|
|
|
include $path; |
428
|
|
|
if (!empty($strings)) { |
429
|
|
|
foreach ($strings as $key => $string) { |
430
|
|
|
$GLOBALS[$key] = $string; |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
} else { |
434
|
|
|
$interfaceLanguageId = api_get_language_id($language_interface); |
435
|
|
|
$interfaceLanguageInfo = api_get_language_info($interfaceLanguageId); |
436
|
|
|
$languageParentId = intval($interfaceLanguageInfo['parent_id']); |
437
|
|
|
|
438
|
|
|
if ($languageParentId > 0) { |
439
|
|
|
$languageParentInfo = api_get_language_info($languageParentId); |
440
|
|
|
$languageParentFolder = $languageParentInfo['dokeos_folder']; |
441
|
|
|
|
442
|
|
|
$parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php"; |
443
|
|
|
if (is_readable($parentPath)) { |
444
|
|
|
include $parentPath; |
445
|
|
|
if (!empty($strings)) { |
446
|
|
|
foreach ($strings as $key => $string) { |
447
|
|
|
$this->strings[$key] = $string; |
448
|
|
|
} |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
} |
452
|
|
|
} |
453
|
|
|
} |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* @param string $region |
458
|
|
|
* @param Template $template |
459
|
|
|
* @param bool $forced |
460
|
|
|
* |
461
|
|
|
* @return bool |
462
|
|
|
* |
463
|
|
|
* @todo improve this function |
464
|
|
|
*/ |
465
|
|
|
public function get_all_plugin_contents_by_region($region, $template, $forced = false) |
466
|
|
|
{ |
467
|
|
|
global $_plugins; |
468
|
|
|
if (isset($_plugins[$region]) && is_array($_plugins[$region])) { |
469
|
|
|
// Load the plugin information |
470
|
|
|
foreach ($_plugins[$region] as $plugin_name) { |
471
|
|
|
// The plugin_info variable is available inside the plugin index |
472
|
|
|
$plugin_info = $this->getPluginInfo($plugin_name, $forced); |
473
|
|
|
|
474
|
|
|
// We also know where the plugin is |
475
|
|
|
$plugin_info['current_region'] = $region; |
476
|
|
|
|
477
|
|
|
// Loading the plugin/XXX/index.php file |
478
|
|
|
$plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php"; |
479
|
|
|
|
480
|
|
|
if (file_exists($plugin_file)) { |
481
|
|
|
//Loading the lang variables of the plugin if exists |
482
|
|
|
self::load_plugin_lang_variables($plugin_name); |
|
|
|
|
483
|
|
|
|
484
|
|
|
// Printing the plugin index.php file |
485
|
|
|
require $plugin_file; |
486
|
|
|
|
487
|
|
|
// If the variable $_template is set we assign those values to be accessible in Twig |
488
|
|
|
if (isset($_template)) { |
489
|
|
|
$_template['plugin_info'] = $plugin_info; |
490
|
|
|
} else { |
491
|
|
|
$_template = []; |
492
|
|
|
$_template['plugin_info'] = $plugin_info; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
// Setting the plugin info available in the template if exists. |
496
|
|
|
$template->assign($plugin_name, $_template); |
|
|
|
|
497
|
|
|
|
498
|
|
|
// Loading the Twig template plugin files if exists |
499
|
|
|
$template_list = []; |
500
|
|
|
if (isset($plugin_info) && isset($plugin_info['templates'])) { |
501
|
|
|
$template_list = $plugin_info['templates']; |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
if (!empty($template_list)) { |
505
|
|
|
foreach ($template_list as $plugin_tpl) { |
506
|
|
|
if (!empty($plugin_tpl)) { |
507
|
|
|
$template_plugin_file = "$plugin_name/$plugin_tpl"; // for twig |
508
|
|
|
$template->display($template_plugin_file, false); |
509
|
|
|
} |
510
|
|
|
} |
511
|
|
|
} |
512
|
|
|
} |
513
|
|
|
} |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
return true; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
/** |
520
|
|
|
* Loads plugin info. |
521
|
|
|
* |
522
|
|
|
* @staticvar array $plugin_data |
523
|
|
|
* |
524
|
|
|
* @param string $plugin_name |
525
|
|
|
* @param bool $forced load from DB or from the static array |
526
|
|
|
* |
527
|
|
|
* @return array |
528
|
|
|
* |
529
|
|
|
* @todo filter setting_form |
530
|
|
|
*/ |
531
|
|
|
public function getPluginInfo($plugin_name, $forced = false) |
532
|
|
|
{ |
533
|
|
|
$pluginData = Session::read('plugin_data'); |
534
|
|
|
if (isset($pluginData[$plugin_name]) && $forced == false) { |
|
|
|
|
535
|
|
|
return $pluginData[$plugin_name]; |
536
|
|
|
} else { |
537
|
|
|
$plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/plugin.php"; |
538
|
|
|
|
539
|
|
|
$plugin_info = []; |
540
|
|
|
if (file_exists($plugin_file)) { |
541
|
|
|
require $plugin_file; |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
// @todo check if settings are already added |
545
|
|
|
// Extra options |
546
|
|
|
$plugin_settings = api_get_settings_params( |
547
|
|
|
[ |
548
|
|
|
"subkey = ? AND category = ? AND type = ? AND access_url = ?" => [ |
549
|
|
|
$plugin_name, |
550
|
|
|
'Plugins', |
551
|
|
|
'setting', |
552
|
|
|
api_get_current_access_url_id(), |
553
|
|
|
], |
554
|
|
|
] |
555
|
|
|
); |
556
|
|
|
|
557
|
|
|
$settings_filtered = []; |
558
|
|
|
foreach ($plugin_settings as $item) { |
559
|
|
|
if (!empty($item['selected_value'])) { |
560
|
|
|
$unserialized = UnserializeApi::unserialize('not_allowed_classes', $item['selected_value'], true); |
561
|
|
|
if (false !== $unserialized) { |
562
|
|
|
$item['selected_value'] = $unserialized; |
563
|
|
|
} |
564
|
|
|
} |
565
|
|
|
$settings_filtered[$item['variable']] = $item['selected_value']; |
566
|
|
|
} |
567
|
|
|
$plugin_info['settings'] = $settings_filtered; |
568
|
|
|
$pluginData[$plugin_name] = $plugin_info; |
569
|
|
|
Session::write('plugin_data', $pluginData); |
570
|
|
|
|
571
|
|
|
return $plugin_info; |
572
|
|
|
} |
573
|
|
|
} |
574
|
|
|
|
575
|
|
|
/** |
576
|
|
|
* Get the template list. |
577
|
|
|
* |
578
|
|
|
* @param string $pluginName |
579
|
|
|
* |
580
|
|
|
* @return bool |
581
|
|
|
*/ |
582
|
|
|
public function get_templates_list($pluginName) |
583
|
|
|
{ |
584
|
|
|
$plugin_info = $this->getPluginInfo($pluginName); |
585
|
|
|
if (isset($plugin_info) && isset($plugin_info['templates'])) { |
586
|
|
|
return $plugin_info['templates']; |
587
|
|
|
} |
588
|
|
|
|
589
|
|
|
return false; |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* Remove all regions of an specific plugin. |
594
|
|
|
* |
595
|
|
|
* @param string $plugin |
596
|
|
|
*/ |
597
|
|
|
public function remove_all_regions($plugin) |
598
|
|
|
{ |
599
|
|
|
$access_url_id = api_get_current_access_url_id(); |
600
|
|
|
if (!empty($plugin)) { |
601
|
|
|
api_delete_settings_params( |
602
|
|
|
[ |
603
|
|
|
'category = ? AND type = ? AND access_url = ? AND subkey = ? ' => [ |
604
|
|
|
'Plugins', |
605
|
|
|
'region', |
606
|
|
|
$access_url_id, |
607
|
|
|
$plugin, |
608
|
|
|
], |
609
|
|
|
] |
610
|
|
|
); |
611
|
|
|
} |
612
|
|
|
} |
613
|
|
|
|
614
|
|
|
/** |
615
|
|
|
* Add a plugin to a region. |
616
|
|
|
* |
617
|
|
|
* @param string $plugin |
618
|
|
|
* @param string $region |
619
|
|
|
*/ |
620
|
|
|
public function add_to_region($plugin, $region) |
621
|
|
|
{ |
622
|
|
|
api_add_setting( |
623
|
|
|
$plugin, |
624
|
|
|
$region, |
625
|
|
|
$plugin, |
626
|
|
|
'region', |
627
|
|
|
'Plugins', |
628
|
|
|
$plugin, |
629
|
|
|
'', |
630
|
|
|
'', |
631
|
|
|
'', |
632
|
|
|
api_get_current_access_url_id(), |
633
|
|
|
1 |
634
|
|
|
); |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
/** |
638
|
|
|
* @param int $courseId |
639
|
|
|
*/ |
640
|
|
|
public function install_course_plugins($courseId) |
641
|
|
|
{ |
642
|
|
|
$pluginList = $this->getInstalledPluginListObject(); |
643
|
|
|
|
644
|
|
|
if (!empty($pluginList)) { |
645
|
|
|
/** @var Plugin $obj */ |
646
|
|
|
foreach ($pluginList as $obj) { |
647
|
|
|
$pluginName = $obj->get_name(); |
648
|
|
|
$plugin_path = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php'; |
649
|
|
|
|
650
|
|
|
if (file_exists($plugin_path)) { |
651
|
|
|
require $plugin_path; |
652
|
|
|
if (isset($plugin_info) && isset($plugin_info['plugin_class']) && $obj->isCoursePlugin) { |
|
|
|
|
653
|
|
|
$obj->course_install($courseId); |
654
|
|
|
} |
655
|
|
|
} |
656
|
|
|
} |
657
|
|
|
} |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/** |
661
|
|
|
* Trigger for Plugin::doWhenDeleting[Item] functions. |
662
|
|
|
* |
663
|
|
|
* @param string $itemType |
664
|
|
|
* @param int $itemId |
665
|
|
|
*/ |
666
|
|
|
public function performActionsWhenDeletingItem($itemType, $itemId) |
667
|
|
|
{ |
668
|
|
|
$pluginList = $this->getInstalledPluginListObject(); |
669
|
|
|
|
670
|
|
|
if (empty($pluginList)) { |
671
|
|
|
return; |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
/** @var Plugin $pluginObj */ |
675
|
|
|
foreach ($pluginList as $pluginObj) { |
676
|
|
|
switch ($itemType) { |
677
|
|
|
case 'course': |
678
|
|
|
$pluginObj->doWhenDeletingCourse($itemId); |
679
|
|
|
break; |
680
|
|
|
case 'session': |
681
|
|
|
$pluginObj->doWhenDeletingSession($itemId); |
682
|
|
|
break; |
683
|
|
|
case 'user': |
684
|
|
|
$pluginObj->doWhenDeletingUser($itemId); |
685
|
|
|
break; |
686
|
|
|
} |
687
|
|
|
} |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
/** |
691
|
|
|
* Add the course settings to the course settings form. |
692
|
|
|
* |
693
|
|
|
* @param FormValidator $form |
694
|
|
|
*/ |
695
|
|
|
public function add_course_settings_form($form) |
696
|
|
|
{ |
697
|
|
|
$pluginList = $this->getInstalledPluginListObject(); |
698
|
|
|
/** @var Plugin $obj */ |
699
|
|
|
foreach ($pluginList as $obj) { |
700
|
|
|
$plugin_name = $obj->get_name(); |
701
|
|
|
$pluginTitle = $obj->get_title(); |
702
|
|
|
if (!empty($obj->course_settings)) { |
703
|
|
|
if (is_file(api_get_path(SYS_CODE_PATH).'img/icons/'.ICON_SIZE_SMALL.'/'.$plugin_name.'.png')) { |
704
|
|
|
$icon = Display::return_icon( |
705
|
|
|
$plugin_name.'.png', |
706
|
|
|
Security::remove_XSS($pluginTitle), |
707
|
|
|
'', |
708
|
|
|
ICON_SIZE_SMALL |
709
|
|
|
); |
710
|
|
|
} else { |
711
|
|
|
$icon = Display::return_icon( |
712
|
|
|
'plugins.png', |
713
|
|
|
Security::remove_XSS($pluginTitle), |
714
|
|
|
'', |
715
|
|
|
ICON_SIZE_SMALL |
716
|
|
|
); |
717
|
|
|
} |
718
|
|
|
|
719
|
|
|
$form->addHtml('<div class="panel panel-default">'); |
720
|
|
|
$form->addHtml(' |
721
|
|
|
<div class="panel-heading" role="tab" id="heading-'.$plugin_name.'-settings"> |
722
|
|
|
<h4 class="panel-title"> |
723
|
|
|
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-'.$plugin_name.'-settings" aria-expanded="false" aria-controls="collapse-'.$plugin_name.'-settings"> |
724
|
|
|
'); |
725
|
|
|
$form->addHtml($icon.' '.$pluginTitle); |
726
|
|
|
$form->addHtml(' |
727
|
|
|
</a> |
728
|
|
|
</h4> |
729
|
|
|
</div> |
730
|
|
|
'); |
731
|
|
|
$form->addHtml(' |
732
|
|
|
<div id="collapse-'.$plugin_name.'-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-'.$plugin_name.'-settings"> |
733
|
|
|
<div class="panel-body"> |
734
|
|
|
'); |
735
|
|
|
|
736
|
|
|
$groups = []; |
737
|
|
|
foreach ($obj->course_settings as $setting) { |
738
|
|
|
if ($obj->validateCourseSetting($setting['name']) === false) { |
739
|
|
|
continue; |
740
|
|
|
} |
741
|
|
|
if ($setting['type'] != 'checkbox') { |
742
|
|
|
$form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name'])); |
743
|
|
|
} else { |
744
|
|
|
$element = &$form->createElement( |
745
|
|
|
$setting['type'], |
746
|
|
|
$setting['name'], |
747
|
|
|
'', |
748
|
|
|
$obj->get_lang($setting['name']) |
749
|
|
|
); |
750
|
|
|
if (isset($setting['init_value']) && $setting['init_value'] == 1) { |
751
|
|
|
$element->setChecked(true); |
752
|
|
|
} |
753
|
|
|
$form->addElement($element); |
754
|
|
|
|
755
|
|
|
if (isset($setting['group'])) { |
756
|
|
|
$groups[$setting['group']][] = $element; |
757
|
|
|
} |
758
|
|
|
} |
759
|
|
|
} |
760
|
|
|
foreach ($groups as $k => $v) { |
761
|
|
|
$form->addGroup($groups[$k], $k, [$obj->get_lang($k)]); |
762
|
|
|
} |
763
|
|
|
$form->addButtonSave(get_lang('SaveSettings')); |
764
|
|
|
$form->addHtml(' |
765
|
|
|
</div> |
766
|
|
|
</div> |
767
|
|
|
'); |
768
|
|
|
$form->addHtml('</div>'); |
769
|
|
|
} |
770
|
|
|
} |
771
|
|
|
} |
772
|
|
|
|
773
|
|
|
/** |
774
|
|
|
* Get all course settings from all installed plugins. |
775
|
|
|
* |
776
|
|
|
* @return array |
777
|
|
|
*/ |
778
|
|
|
public function getAllPluginCourseSettings() |
779
|
|
|
{ |
780
|
|
|
$pluginList = $this->getInstalledPluginListObject(); |
781
|
|
|
/** @var Plugin $obj */ |
782
|
|
|
$courseSettings = []; |
783
|
|
|
if (!empty($pluginList)) { |
784
|
|
|
foreach ($pluginList as $obj) { |
785
|
|
|
$pluginCourseSetting = $obj->getCourseSettings(); |
786
|
|
|
$courseSettings = array_merge($courseSettings, $pluginCourseSetting); |
787
|
|
|
} |
788
|
|
|
} |
789
|
|
|
|
790
|
|
|
return $courseSettings; |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
/** |
794
|
|
|
* When saving the plugin values in the course settings, check whether |
795
|
|
|
* a callback method should be called and send it the updated settings. |
796
|
|
|
* |
797
|
|
|
* @param array $values The new settings the user just saved |
798
|
|
|
*/ |
799
|
|
|
public function saveCourseSettingsHook($values) |
800
|
|
|
{ |
801
|
|
|
$pluginList = $this->getInstalledPluginListObject(); |
802
|
|
|
|
803
|
|
|
/** @var Plugin $obj */ |
804
|
|
|
foreach ($pluginList as $obj) { |
805
|
|
|
$settings = $obj->getCourseSettings(); |
806
|
|
|
$subValues = []; |
807
|
|
|
if (!empty($settings)) { |
808
|
|
|
foreach ($settings as $v) { |
809
|
|
|
if (isset($values[$v])) { |
810
|
|
|
$subValues[$v] = $values[$v]; |
811
|
|
|
} |
812
|
|
|
} |
813
|
|
|
} |
814
|
|
|
|
815
|
|
|
if (!empty($subValues)) { |
816
|
|
|
$obj->course_settings_updated($subValues); |
817
|
|
|
} |
818
|
|
|
} |
819
|
|
|
} |
820
|
|
|
|
821
|
|
|
/** |
822
|
|
|
* Get first SMS plugin name. |
823
|
|
|
* |
824
|
|
|
* @return string|bool |
825
|
|
|
*/ |
826
|
|
|
public function getSMSPluginName() |
827
|
|
|
{ |
828
|
|
|
$installedPluginsList = $this->getInstalledPluginListObject(); |
829
|
|
|
foreach ($installedPluginsList as $installedPlugin) { |
830
|
|
|
if ($installedPlugin->isMailPlugin) { |
831
|
|
|
return get_class($installedPlugin); |
832
|
|
|
} |
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
return false; |
836
|
|
|
} |
837
|
|
|
|
838
|
|
|
/** |
839
|
|
|
* @return SmsPluginLibraryInterface |
840
|
|
|
*/ |
841
|
|
|
public function getSMSPluginLibrary() |
842
|
|
|
{ |
843
|
|
|
$className = $this->getSMSPluginName(); |
844
|
|
|
$className = str_replace('Plugin', '', $className); |
845
|
|
|
|
846
|
|
|
if (class_exists($className)) { |
847
|
|
|
return new $className(); |
848
|
|
|
} |
849
|
|
|
|
850
|
|
|
return false; |
851
|
|
|
} |
852
|
|
|
} |
853
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.