Completed
Push — master ( 8dedcf...0160d5 )
by Julito
29:07
created

api.lib.php ➔ api_get_setting()   C

Complexity

Conditions 11
Paths 11

Size

Total Lines 42
Code Lines 34

Duplication

Lines 18
Ratio 42.86 %

Importance

Changes 0
Metric Value
cc 11
eloc 34
nc 11
nop 1
dl 18
loc 42
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
use Chamilo\CourseBundle\Entity\CItemProperty;
6
use Symfony\Component\Validator\Constraints as Assert;
7
use Chamilo\UserBundle\Entity\User;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, User.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use Chamilo\CoreBundle\Entity\Course;
9
use Chamilo\CoreBundle\Framework\Container;
10
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
11
12
/**
13
 * This is a code library for Chamilo.
14
 * It is included by default in every Chamilo file (through including the global.inc.php)
15
 * This library is in process of being transferred to src/Chamilo/CoreBundle/Component/Utils/ChamiloApi.
16
 * Whenever a function is transferred to the ChamiloApi class, the places where it is used should include
17
 * the "use Chamilo\CoreBundle\Component\Utils\ChamiloApi;" statement.
18
 * @package chamilo.library
19
 */
20
21
/**
22
 * Constants declaration
23
 */
24
25
// PHP version requirement.
26
define('REQUIRED_PHP_VERSION', '7.0');
27
define('REQUIRED_MIN_MEMORY_LIMIT', '128');
28
define('REQUIRED_MIN_UPLOAD_MAX_FILESIZE', '10');
29
define('REQUIRED_MIN_POST_MAX_SIZE', '10');
30
31
// USER STATUS CONSTANTS
32
/** global status of a user: student */
33
define('STUDENT', 5);
34
/** global status of a user: course manager */
35
define('COURSEMANAGER', 1);
36
/** global status of a user: session admin */
37
define('SESSIONADMIN', 3);
38
/** global status of a user: human ressource manager */
39
define('DRH', 4);
40
/** global status of a user: human ressource manager */
41
define('ANONYMOUS', 6);
42
/** global status of a user: low security, necessary for inserting data from
43
 * the teacher through HTMLPurifier */
44
define('COURSEMANAGERLOWSECURITY', 10);
45
// Soft user status
46
define('PLATFORM_ADMIN', 11);
47
define('SESSION_COURSE_COACH', 12);
48
define('SESSION_GENERAL_COACH', 13);
49
define('COURSE_STUDENT', 14);   //student subscribed in a course
50
define('SESSION_STUDENT', 15);  //student subscribed in a session course
51
define('COURSE_TUTOR', 16); // student is tutor of a course (NOT in session)
52
define('STUDENT_BOSS', 17); // student is boss
53
define('INVITEE', 20);
54
55
// Table of status
56
$_status_list[COURSEMANAGER] = 'teacher';        // 1
57
$_status_list[SESSIONADMIN] = 'session_admin';  // 3
58
$_status_list[DRH] = 'drh';            // 4
59
$_status_list[STUDENT] = 'user';           // 5
60
$_status_list[ANONYMOUS] = 'anonymous';      // 6
61
$_status_list[INVITEE] = 'invited';        // 20
62
63
// COURSE VISIBILITY CONSTANTS
64
/** only visible for course admin */
65
define('COURSE_VISIBILITY_CLOSED', 0);
66
/** only visible for users registered in the course */
67
define('COURSE_VISIBILITY_REGISTERED', 1);
68
/** Open for all registered users on the platform */
69
define('COURSE_VISIBILITY_OPEN_PLATFORM', 2);
70
/** Open for the whole world */
71
define('COURSE_VISIBILITY_OPEN_WORLD', 3);
72
/** Invisible to all except admin */
73
define('COURSE_VISIBILITY_HIDDEN', 4);
74
75
define('COURSE_REQUEST_PENDING', 0);
76
define('COURSE_REQUEST_ACCEPTED', 1);
77
define('COURSE_REQUEST_REJECTED', 2);
78
define('DELETE_ACTION_ENABLED', false);
79
80
// EMAIL SENDING RECIPIENT CONSTANTS
81
define('SEND_EMAIL_EVERYONE', 1);
82
define('SEND_EMAIL_STUDENTS', 2);
83
define('SEND_EMAIL_TEACHERS', 3);
84
85
// SESSION VISIBILITY CONSTANTS
86
define('SESSION_VISIBLE_READ_ONLY', 1);
87
define('SESSION_VISIBLE', 2);
88
define('SESSION_INVISIBLE', 3); // not available
89
define('SESSION_AVAILABLE', 4);
90
91
define('SESSION_LINK_TARGET', '_self');
92
93
define('SUBSCRIBE_ALLOWED', 1);
94
define('SUBSCRIBE_NOT_ALLOWED', 0);
95
define('UNSUBSCRIBE_ALLOWED', 1);
96
define('UNSUBSCRIBE_NOT_ALLOWED', 0);
97
98
// SURVEY VISIBILITY CONSTANTS
99
define('SURVEY_VISIBLE_TUTOR', 0);
100
define('SURVEY_VISIBLE_TUTOR_STUDENT', 1);
101
define('SURVEY_VISIBLE_PUBLIC', 2);
102
103
// CONSTANTS defining all tools, using the english version
104
/* When you add a new tool you must add it into function api_get_tools_lists() too */
105
define('TOOL_DOCUMENT', 'document');
106
define('TOOL_LP_FINAL_ITEM', 'final_item');
107
define('TOOL_THUMBNAIL', 'thumbnail');
108
define('TOOL_HOTPOTATOES', 'hotpotatoes');
109
define('TOOL_CALENDAR_EVENT', 'calendar_event');
110
define('TOOL_LINK', 'link');
111
define('TOOL_LINK_CATEGORY', 'link_category');
112
define('TOOL_COURSE_DESCRIPTION', 'course_description');
113
define('TOOL_SEARCH', 'search');
114
define('TOOL_LEARNPATH', 'learnpath');
115
define('TOOL_AGENDA', 'agenda');
116
define('TOOL_ANNOUNCEMENT', 'announcement');
117
define('TOOL_FORUM', 'forum');
118
define('TOOL_FORUM_CATEGORY', 'forum_category');
119
define('TOOL_FORUM_THREAD', 'forum_thread');
120
define('TOOL_FORUM_POST', 'forum_post');
121
define('TOOL_FORUM_ATTACH', 'forum_attachment');
122
define('TOOL_FORUM_THREAD_QUALIFY', 'forum_thread_qualify');
123
define('TOOL_THREAD', 'thread');
124
define('TOOL_POST', 'post');
125
define('TOOL_DROPBOX', 'dropbox');
126
define('TOOL_QUIZ', 'quiz');
127
define('TOOL_TEST_CATEGORY', 'test_category');
128
define('TOOL_USER', 'user');
129
define('TOOL_GROUP', 'group');
130
define('TOOL_BLOGS', 'blog_management');
131
define('TOOL_CHAT', 'chat');
132
define('TOOL_STUDENTPUBLICATION', 'student_publication');
133
define('TOOL_TRACKING', 'tracking');
134
define('TOOL_HOMEPAGE_LINK', 'homepage_link');
135
define('TOOL_COURSE_SETTING', 'course_setting');
136
define('TOOL_BACKUP', 'backup');
137
define('TOOL_COPY_COURSE_CONTENT', 'copy_course_content');
138
define('TOOL_RECYCLE_COURSE', 'recycle_course');
139
define('TOOL_COURSE_HOMEPAGE', 'course_homepage');
140
define('TOOL_COURSE_RIGHTS_OVERVIEW', 'course_rights');
141
define('TOOL_UPLOAD', 'file_upload');
142
define('TOOL_COURSE_MAINTENANCE', 'course_maintenance');
143
define('TOOL_SURVEY', 'survey');
144
define('TOOL_WIKI', 'wiki');
145
define('TOOL_GLOSSARY', 'glossary');
146
define('TOOL_GRADEBOOK', 'gradebook');
147
define('TOOL_NOTEBOOK', 'notebook');
148
define('TOOL_ATTENDANCE', 'attendance');
149
define('TOOL_COURSE_PROGRESS', 'course_progress');
150
151
// CONSTANTS defining Chamilo interface sections
152
define('SECTION_CAMPUS', 'mycampus');
153
define('SECTION_COURSES', 'mycourses');
154
define('SECTION_CATALOG', 'catalog');
155
define('SECTION_MYPROFILE', 'myprofile');
156
define('SECTION_MYAGENDA', 'myagenda');
157
define('SECTION_COURSE_ADMIN', 'course_admin');
158
define('SECTION_PLATFORM_ADMIN', 'platform_admin');
159
define('SECTION_MYGRADEBOOK', 'mygradebook');
160
define('SECTION_TRACKING', 'session_my_space');
161
define('SECTION_SOCIAL', 'social-network');
162
define('SECTION_DASHBOARD', 'dashboard');
163
define('SECTION_REPORTS', 'reports');
164
define('SECTION_GLOBAL', 'global');
165
166
// CONSTANT name for local authentication source
167
define('PLATFORM_AUTH_SOURCE', 'platform');
168
define('CAS_AUTH_SOURCE', 'cas');
169
define('LDAP_AUTH_SOURCE', 'extldap');
170
171
// CONSTANT defining the default HotPotatoes files directory
172
define('DIR_HOTPOTATOES', '/HotPotatoes_files');
173
174
// event logs types
175
define('LOG_COURSE_DELETE', 'course_deleted');
176
define('LOG_COURSE_CREATE', 'course_created');
177
178
// @todo replace 'soc_gr' with social_group
179
define('LOG_GROUP_PORTAL_CREATED', 'soc_gr_created');
180
define('LOG_GROUP_PORTAL_UPDATED', 'soc_gr_updated');
181
define('LOG_GROUP_PORTAL_DELETED', 'soc_gr_deleted');
182
define('LOG_GROUP_PORTAL_USER_DELETE_ALL', 'soc_gr_delete_users');
183
184
define('LOG_GROUP_PORTAL_ID', 'soc_gr_portal_id');
185
define('LOG_GROUP_PORTAL_REL_USER_ARRAY', 'soc_gr_user_array');
186
187
define('LOG_GROUP_PORTAL_USER_SUBSCRIBED', 'soc_gr_u_subs');
188
define('LOG_GROUP_PORTAL_USER_UNSUBSCRIBED', 'soc_gr_u_unsubs');
189
define('LOG_GROUP_PORTAL_USER_UPDATE_ROLE', 'soc_gr_update_role');
190
191
define('LOG_USER_DELETE', 'user_deleted');
192
define('LOG_USER_CREATE', 'user_created');
193
define('LOG_USER_ENABLE', 'user_enable');
194
define('LOG_USER_DISABLE', 'user_disable');
195
define('LOG_USER_FIELD_CREATE', 'user_field_created');
196
define('LOG_USER_FIELD_DELETE', 'user_field_deleted');
197
define('LOG_SESSION_CREATE', 'session_created');
198
define('LOG_SESSION_DELETE', 'session_deleted');
199
define('LOG_SESSION_ADD_USER_COURSE', 'session_add_user_course');
200
define('LOG_SESSION_DELETE_USER_COURSE', 'session_delete_user_course');
201
define('LOG_SESSION_DELETE_USER', 'session_delete_user');
202
define('LOG_SESSION_ADD_COURSE', 'session_add_course');
203
define('LOG_SESSION_DELETE_COURSE', 'session_delete_course');
204
205
define('LOG_SESSION_CATEGORY_CREATE', 'session_cat_created'); //changed in 1.9.8
206
define('LOG_SESSION_CATEGORY_DELETE', 'session_cat_deleted'); //changed in 1.9.8
207
define('LOG_CONFIGURATION_SETTINGS_CHANGE', 'settings_changed');
208
define('LOG_PLATFORM_LANGUAGE_CHANGE', 'platform_lng_changed'); //changed in 1.9.8
209
define('LOG_SUBSCRIBE_USER_TO_COURSE', 'user_subscribed');
210
define('LOG_UNSUBSCRIBE_USER_FROM_COURSE', 'user_unsubscribed');
211
define('LOG_ATTEMPTED_FORCED_LOGIN', 'attempted_forced_login');
212
213
define('LOG_HOMEPAGE_CHANGED', 'homepage_changed');
214
215
define('LOG_PROMOTION_CREATE', 'promotion_created');
216
define('LOG_PROMOTION_DELETE', 'promotion_deleted');
217
define('LOG_CAREER_CREATE', 'career_created');
218
define('LOG_CAREER_DELETE', 'career_deleted');
219
220
define('LOG_USER_PERSONAL_DOC_DELETED', 'user_doc_deleted');
221
define('LOG_WIKI_ACCESS', 'wiki_page_view');
222
223
define('LOG_EXERCISE_RESULT_DELETE', 'exe_result_deleted');
224
define('LOG_LP_ATTEMPT_DELETE', 'lp_attempt_deleted');
225
define('LOG_QUESTION_RESULT_DELETE', 'qst_attempt_deleted');
226
227
define('LOG_MY_FOLDER_CREATE', 'my_folder_created');
228
define('LOG_MY_FOLDER_CHANGE', 'my_folder_changed');
229
define('LOG_MY_FOLDER_DELETE', 'my_folder_deleted');
230
define('LOG_MY_FOLDER_COPY', 'my_folder_copied');
231
define('LOG_MY_FOLDER_CUT', 'my_folder_cut');
232
define('LOG_MY_FOLDER_PASTE', 'my_folder_pasted');
233
define('LOG_MY_FOLDER_UPLOAD', 'my_folder_uploaded');
234
235
// Event logs data types (max 20 chars)
236
define('LOG_COURSE_CODE', 'course_code');
237
define('LOG_COURSE_ID', 'course_id');
238
define('LOG_USER_ID', 'user_id');
239
define('LOG_USER_OBJECT', 'user_object');
240
define('LOG_USER_FIELD_VARIABLE', 'user_field_variable');
241
define('LOG_SESSION_ID', 'session_id');
242
define('LOG_SESSION_CATEGORY_ID', 'session_category_id');
243
define('LOG_CONFIGURATION_SETTINGS_CATEGORY', 'settings_category');
244
define('LOG_CONFIGURATION_SETTINGS_VARIABLE', 'settings_variable');
245
define('LOG_PLATFORM_LANGUAGE', 'default_platform_language');
246
define('LOG_CAREER_ID', 'career_id');
247
define('LOG_PROMOTION_ID', 'promotion_id');
248
define('LOG_GRADEBOOK_LOCKED', 'gradebook_locked');
249
define('LOG_GRADEBOOK_UNLOCKED', 'gradebook_unlocked');
250
define('LOG_GRADEBOOK_ID', 'gradebook_id');
251
define('LOG_WIKI_PAGE_ID', 'wiki_page_id');
252
define('LOG_EXERCISE_ID', 'exercise_id');
253
define('LOG_EXERCISE_AND_USER_ID', 'exercise_and_user_id');
254
define('LOG_LP_ID', 'lp_id');
255
define('LOG_EXERCISE_ATTEMPT_QUESTION_ID', 'exercise_a_q_id');
256
257
define('LOG_WORK_DIR_DELETE', 'work_dir_delete');
258
define('LOG_WORK_FILE_DELETE', 'work_file_delete');
259
define('LOG_WORK_DATA', 'work_data_array');
260
261
define('LOG_MY_FOLDER_PATH', 'path');
262
define('LOG_MY_FOLDER_NEW_PATH', 'new_path');
263
264
define('USERNAME_PURIFIER', '/[^0-9A-Za-z_\.]/');
265
266
//used when login_is_email setting is true
267
define('USERNAME_PURIFIER_MAIL', '/[^0-9A-Za-z_\.@]/');
268
define('USERNAME_PURIFIER_SHALLOW', '/\s/');
269
270
// This constant is a result of Windows OS detection, it has a boolean value:
271
// true whether the server runs on Windows OS, false otherwise.
272
define('IS_WINDOWS_OS', api_is_windows_os());
273
274
// Checks for installed optional php-extensions.
275
define('INTL_INSTALLED', function_exists('intl_get_error_code'));   // intl extension (from PECL), it is installed by default as of PHP 5.3.0
276
define('ICONV_INSTALLED', function_exists('iconv'));                // iconv extension, for PHP5 on Windows it is installed by default.
277
define('MBSTRING_INSTALLED', function_exists('mb_strlen'));         // mbstring extension.
278
279
// Patterns for processing paths.                                   // Examples:
280
define('REPEATED_SLASHES_PURIFIER', '/\/{2,}/');                    // $path = preg_replace(REPEATED_SLASHES_PURIFIER, '/', $path);
281
define('VALID_WEB_PATH', '/https?:\/\/[^\/]*(\/.*)?/i');            // $is_valid_path = preg_match(VALID_WEB_PATH, $path);
282
define('VALID_WEB_SERVER_BASE', '/https?:\/\/[^\/]*/i');            // $new_path = preg_replace(VALID_WEB_SERVER_BASE, $new_base, $path);
283
284
// Constants for api_get_path() and api_get_path_type(), etc. - registered path types.
285
// basic (leaf elements)
286
define('REL_CODE_PATH', 'REL_CODE_PATH');
287
define('REL_COURSE_PATH', 'REL_COURSE_PATH');
288
define('REL_HOME_PATH', 'REL_HOME_PATH');
289
290
// Constants for api_get_path() and api_get_path_type(), etc. - registered path types.
291
define('WEB_PATH', 'WEB_PATH');
292
define('WEB_APP_PATH', 'WEB_APP_PATH');
293
define('SYS_PATH', 'SYS_PATH');
294
define('SYS_APP_PATH', 'SYS_APP_PATH');
295
define('SYS_UPLOAD_PATH', 'SYS_UPLOAD_PATH');
296
define('WEB_UPLOAD_PATH', 'WEB_UPLOAD_PATH');
297
298
define('REL_PATH', 'REL_PATH');
299
define('WEB_COURSE_PATH', 'WEB_COURSE_PATH');
300
define('SYS_COURSE_PATH', 'SYS_COURSE_PATH');
301
define('WEB_CODE_PATH', 'WEB_CODE_PATH');
302
define('SYS_CODE_PATH', 'SYS_CODE_PATH');
303
define('SYS_LANG_PATH', 'SYS_LANG_PATH');
304
define('WEB_IMG_PATH', 'WEB_IMG_PATH');
305
define('WEB_CSS_PATH', 'WEB_CSS_PATH');
306
define('WEB_PUBLIC_PATH', 'WEB_PUBLIC_PATH');
307
define('SYS_CSS_PATH', 'SYS_CSS_PATH');
308
define('SYS_PLUGIN_PATH', 'SYS_PLUGIN_PATH');
309
define('WEB_PLUGIN_PATH', 'WEB_PLUGIN_PATH');
310
define('SYS_ARCHIVE_PATH', 'SYS_ARCHIVE_PATH');
311
define('WEB_ARCHIVE_PATH', 'WEB_ARCHIVE_PATH');
312
define('SYS_INC_PATH', 'SYS_INC_PATH');
313
define('LIBRARY_PATH', 'LIBRARY_PATH');
314
define('CONFIGURATION_PATH', 'CONFIGURATION_PATH');
315
define('WEB_LIBRARY_PATH', 'WEB_LIBRARY_PATH');
316
define('WEB_LIBRARY_JS_PATH', 'WEB_LIBRARY_JS_PATH');
317
define('WEB_AJAX_PATH', 'WEB_AJAX_PATH');
318
define('SYS_TEST_PATH', 'SYS_TEST_PATH');
319
define('WEB_TEMPLATE_PATH', 'WEB_TEMPLATE_PATH');
320
define('SYS_TEMPLATE_PATH', 'SYS_TEMPLATE_PATH');
321
define('SYS_PUBLIC_PATH', 'SYS_PUBLIC_PATH');
322
define('SYS_HOME_PATH', 'SYS_HOME_PATH');
323
define('WEB_HOME_PATH', 'WEB_HOME_PATH');
324
define('WEB_FONTS_PATH', 'WEB_FONTS_PATH');
325
define('SYS_FONTS_PATH', 'SYS_FONTS_PATH');
326
327
define('SYS_DEFAULT_COURSE_DOCUMENT_PATH', 'SYS_DEFAULT_COURSE_DOCUMENT_PATH');
328
define('REL_DEFAULT_COURSE_DOCUMENT_PATH', 'REL_DEFAULT_COURSE_DOCUMENT_PATH');
329
define('WEB_DEFAULT_COURSE_DOCUMENT_PATH', 'WEB_DEFAULT_COURSE_DOCUMENT_PATH');
330
331
// Relations type with Course manager
332
define('COURSE_RELATION_TYPE_COURSE_MANAGER', 1);
333
define('SESSION_RELATION_TYPE_COURSE_MANAGER', 1);
334
335
// Relations type with Human resources manager
336
define('COURSE_RELATION_TYPE_RRHH', 1);
337
define('SESSION_RELATION_TYPE_RRHH', 1);
338
339
//User image sizes
340
define('USER_IMAGE_SIZE_ORIGINAL', 1);
341
define('USER_IMAGE_SIZE_BIG', 2);
342
define('USER_IMAGE_SIZE_MEDIUM', 3);
343
define('USER_IMAGE_SIZE_SMALL', 4);
344
345
// Relation type between users
346
define('USER_UNKNOW', 0);
347
define('USER_RELATION_TYPE_UNKNOW', 1);
348
define('USER_RELATION_TYPE_PARENT', 2); // should be deprecated is useless
349
define('USER_RELATION_TYPE_FRIEND', 3);
350
define('USER_RELATION_TYPE_GOODFRIEND', 4); // should be deprecated is useless
351
define('USER_RELATION_TYPE_ENEMY', 5); // should be deprecated is useless
352
define('USER_RELATION_TYPE_DELETED', 6);
353
define('USER_RELATION_TYPE_RRHH', 7);
354
define('USER_RELATION_TYPE_BOSS', 8);
355
356
// Gradebook link constants
357
// Please do not change existing values, they are used in the database !
358
define('GRADEBOOK_ITEM_LIMIT', 1000);
359
360
define('LINK_EXERCISE', 1);
361
define('LINK_DROPBOX', 2);
362
define('LINK_STUDENTPUBLICATION', 3);
363
define('LINK_LEARNPATH', 4);
364
define('LINK_FORUM_THREAD', 5);
365
//define('LINK_WORK',6);
366
define('LINK_ATTENDANCE', 7);
367
define('LINK_SURVEY', 8);
368
define('LINK_HOTPOTATOES', 9);
369
370
// Score display types constants
371
define('SCORE_DIV', 1);    // X / Y
372
define('SCORE_PERCENT', 2);    // XX %
373
define('SCORE_DIV_PERCENT', 3);    // X / Y (XX %)
374
define('SCORE_AVERAGE', 4);    // XX %
375
define('SCORE_DECIMAL', 5);    // 0.50  (X/Y)
376
define('SCORE_BAR', 6);    // Uses the Display::bar_progress function
377
define('SCORE_SIMPLE', 7);    // X
378
define('SCORE_IGNORE_SPLIT', 8);    //  ??
379
define('SCORE_DIV_PERCENT_WITH_CUSTOM', 9);    // X / Y (XX %) - Good!
380
define('SCORE_CUSTOM', 10);    // Good!
381
define('SCORE_DIV_SIMPLE_WITH_CUSTOM', 11);    // X - Good!
382
define('SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS', 12);    // X - Good!
383
define('SCORE_ONLY_SCORE', 13);    // X - Good!
384
385
define('SCORE_BOTH', 1);
386
define('SCORE_ONLY_DEFAULT', 2);
387
define('SCORE_ONLY_CUSTOM', 3);
388
389
// From display.lib.php
390
391
define('MAX_LENGTH_BREADCRUMB', 100);
392
define('ICON_SIZE_ATOM', 8);
393
define('ICON_SIZE_TINY', 16);
394
define('ICON_SIZE_SMALL', 22);
395
define('ICON_SIZE_MEDIUM', 32);
396
define('ICON_SIZE_LARGE', 48);
397
define('ICON_SIZE_BIG', 64);
398
define('ICON_SIZE_HUGE', 128);
399
define('SHOW_TEXT_NEAR_ICONS', false);
400
401
// Session catalog
402
define('CATALOG_COURSES', 0);
403
define('CATALOG_SESSIONS', 1);
404
define('CATALOG_COURSES_SESSIONS', 2);
405
406
// Hook type events, pre-process and post-process.
407
// All means to be executed for both hook event types
408
define('HOOK_EVENT_TYPE_PRE', 0);
409
define('HOOK_EVENT_TYPE_POST', 1);
410
define('HOOK_EVENT_TYPE_ALL', 10);
411
412
define('CAREER_STATUS_ACTIVE', 1);
413
define('CAREER_STATUS_INACTIVE', 0);
414
415
define('PROMOTION_STATUS_ACTIVE', 1);
416
define('PROMOTION_STATUS_INACTIVE', 0);
417
418
// Group permissions
419
define('GROUP_PERMISSION_OPEN', '1');
420
define('GROUP_PERMISSION_CLOSED', '2');
421
422
// Group user permissions
423
define('GROUP_USER_PERMISSION_ADMIN', '1'); // the admin of a group
424
define('GROUP_USER_PERMISSION_READER', '2'); // a normal user
425
define('GROUP_USER_PERMISSION_PENDING_INVITATION', '3'); // When an admin/moderator invites a user
426
define('GROUP_USER_PERMISSION_PENDING_INVITATION_SENT_BY_USER', '4'); // an user joins a group
427
define('GROUP_USER_PERMISSION_MODERATOR', '5'); // a moderator
428
define('GROUP_USER_PERMISSION_ANONYMOUS', '6'); // an anonymous user
429
define('GROUP_USER_PERMISSION_HRM', '7'); // a human resources manager
430
431
define('GROUP_IMAGE_SIZE_ORIGINAL', 1);
432
define('GROUP_IMAGE_SIZE_BIG', 2);
433
define('GROUP_IMAGE_SIZE_MEDIUM', 3);
434
define('GROUP_IMAGE_SIZE_SMALL', 4);
435
define('GROUP_TITLE_LENGTH', 50);
436
437
// Exercise
438
// @todo move into a class
439
define('ALL_ON_ONE_PAGE', 1);
440
define('ONE_PER_PAGE', 2);
441
442
define('EXERCISE_FEEDBACK_TYPE_END', 0); //Feedback 		 - show score and expected answers
443
define('EXERCISE_FEEDBACK_TYPE_DIRECT', 1); //DirectFeedback - Do not show score nor answers
444
define('EXERCISE_FEEDBACK_TYPE_EXAM', 2); //NoFeedback 	 - Show score only
445
446
define('RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS', 0); //show score and expected answers
447
define('RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS', 1); //Do not show score nor answers
448
define('RESULT_DISABLE_SHOW_SCORE_ONLY', 2); //Show score only
449
define('RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES', 3); //Show final score only with categories
450
define('RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT', 4); //Show final score only with categories
451
452
define('EXERCISE_MAX_NAME_SIZE', 80);
453
454
// Question types (edit next array as well when adding values)
455
// @todo move into a class
456
define('UNIQUE_ANSWER', 1);
457
define('MULTIPLE_ANSWER', 2);
458
define('FILL_IN_BLANKS', 3);
459
define('MATCHING', 4);
460
define('FREE_ANSWER', 5);
461
define('HOT_SPOT', 6);
462
define('HOT_SPOT_ORDER', 7);
463
define('HOT_SPOT_DELINEATION', 8);
464
define('MULTIPLE_ANSWER_COMBINATION', 9);
465
define('UNIQUE_ANSWER_NO_OPTION', 10);
466
define('MULTIPLE_ANSWER_TRUE_FALSE', 11);
467
define('MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE', 12);
468
define('ORAL_EXPRESSION', 13);
469
define('GLOBAL_MULTIPLE_ANSWER', 14);
470
define('MEDIA_QUESTION', 15);
471
define('CALCULATED_ANSWER', 16);
472
define('UNIQUE_ANSWER_IMAGE', 17);
473
define('DRAGGABLE', 18);
474
define('MATCHING_DRAGGABLE', 19);
475
476
define('EXERCISE_CATEGORY_RANDOM_SHUFFLED', 1);
477
define('EXERCISE_CATEGORY_RANDOM_ORDERED', 2);
478
define('EXERCISE_CATEGORY_RANDOM_DISABLED', 0);
479
480
// Question selection type
481
define('EX_Q_SELECTION_ORDERED', 1);
482
define('EX_Q_SELECTION_RANDOM', 2);
483
define('EX_Q_SELECTION_CATEGORIES_ORDERED_QUESTIONS_ORDERED', 3);
484
define('EX_Q_SELECTION_CATEGORIES_RANDOM_QUESTIONS_ORDERED', 4);
485
define('EX_Q_SELECTION_CATEGORIES_ORDERED_QUESTIONS_RANDOM', 5);
486
define('EX_Q_SELECTION_CATEGORIES_RANDOM_QUESTIONS_RANDOM', 6);
487
define('EX_Q_SELECTION_CATEGORIES_RANDOM_QUESTIONS_ORDERED_NO_GROUPED', 7);
488
define('EX_Q_SELECTION_CATEGORIES_RANDOM_QUESTIONS_RANDOM_NO_GROUPED', 8);
489
define('EX_Q_SELECTION_CATEGORIES_ORDERED_BY_PARENT_QUESTIONS_ORDERED', 9);
490
define('EX_Q_SELECTION_CATEGORIES_ORDERED_BY_PARENT_QUESTIONS_RANDOM', 10);
491
492
// one big string with all question types, for the validator in pear/HTML/QuickForm/Rule/QuestionType
493
define('QUESTION_TYPES',
494
    UNIQUE_ANSWER.':'.
495
    MULTIPLE_ANSWER.':'.
496
    FILL_IN_BLANKS.':'.
497
    MATCHING.':'.
498
    FREE_ANSWER.':'.
499
    HOT_SPOT.':'.
500
    HOT_SPOT_ORDER.':'.
501
    HOT_SPOT_DELINEATION.':'.
502
    MULTIPLE_ANSWER_COMBINATION.':'.
503
    UNIQUE_ANSWER_NO_OPTION.':'.
504
    MULTIPLE_ANSWER_TRUE_FALSE.':'.
505
    MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE.':'.
506
    ORAL_EXPRESSION.':'.
507
    GLOBAL_MULTIPLE_ANSWER.':'.
508
    MEDIA_QUESTION.':'.
509
    CALCULATED_ANSWER.':'.
510
    UNIQUE_ANSWER_IMAGE.':'.
511
    DRAGGABLE.':'.
512
    MATCHING_DRAGGABLE
513
);
514
515
//Some alias used in the QTI exports
516
define('MCUA', 1);
517
define('TF', 1);
518
define('MCMA', 2);
519
define('FIB', 3);
520
521
// Skills
522
define('SKILL_TYPE_REQUIREMENT', 'required');
523
define('SKILL_TYPE_ACQUIRED', 'acquired');
524
define('SKILL_TYPE_BOTH', 'both');
525
526
// Message
527
define('MESSAGE_STATUS_NEW', '0');
528
define('MESSAGE_STATUS_UNREAD', '1');
529
//2 ??
530
define('MESSAGE_STATUS_DELETED', '3');
531
define('MESSAGE_STATUS_OUTBOX', '4');
532
define('MESSAGE_STATUS_INVITATION_PENDING', '5');
533
define('MESSAGE_STATUS_INVITATION_ACCEPTED', '6');
534
define('MESSAGE_STATUS_INVITATION_DENIED', '7');
535
define('MESSAGE_STATUS_WALL', '8');
536
define('MESSAGE_STATUS_WALL_DELETE', '9');
537
define('MESSAGE_STATUS_WALL_POST', '10');
538
// Images
539
define('IMAGE_WALL_SMALL_SIZE', 200);
540
define('IMAGE_WALL_MEDIUM_SIZE', 500);
541
define('IMAGE_WALL_BIG_SIZE', 2000);
542
define('IMAGE_WALL_SMALL', 'small');
543
define('IMAGE_WALL_MEDIUM', 'medium');
544
define('IMAGE_WALL_BIG', 'big');
545
546
// Social PLUGIN PLACES
547
define('SOCIAL_LEFT_PLUGIN', 1);
548
define('SOCIAL_CENTER_PLUGIN', 2);
549
define('SOCIAL_RIGHT_PLUGIN', 3);
550
define('CUT_GROUP_NAME', 50);
551
552
/**
553
 * FormValidator Filter
554
 */
555
define('NO_HTML', 1);
556
define('STUDENT_HTML', 2);
557
define('TEACHER_HTML', 3);
558
define('STUDENT_HTML_FULLPAGE', 4);
559
define('TEACHER_HTML_FULLPAGE', 5);
560
561
// Timeline
562
define('TIMELINE_STATUS_ACTIVE', '1');
563
define('TIMELINE_STATUS_INACTIVE', '2');
564
565
// Event email template class
566
define('EVENT_EMAIL_TEMPLATE_ACTIVE',  1);
567
define('EVENT_EMAIL_TEMPLATE_INACTIVE', 0);
568
569
// Course home
570
define('SHORTCUTS_HORIZONTAL', 0);
571
define('SHORTCUTS_VERTICAL', 1);
572
573
// Image class
574
define('IMAGE_PROCESSOR', 'gd'); // 'imagick' or 'gd' strings
575
576
// Course copy
577
define('FILE_SKIP', 1);
578
define('FILE_RENAME', 2);
579
define('FILE_OVERWRITE', 3);
580
define('UTF8_CONVERT', false); //false by default
581
582
define('DOCUMENT','file');
583
define('FOLDER','folder');
584
585
define('RESOURCE_DOCUMENT', 'document');
586
define('RESOURCE_GLOSSARY', 'glossary');
587
define('RESOURCE_EVENT', 'calendar_event');
588
define('RESOURCE_LINK', 'link');
589
define('RESOURCE_COURSEDESCRIPTION', 'course_description');
590
define('RESOURCE_LEARNPATH', 'learnpath');
591
define('RESOURCE_ANNOUNCEMENT', 'announcement');
592
define('RESOURCE_FORUM', 'forum');
593
define('RESOURCE_FORUMTOPIC', 'thread');
594
define('RESOURCE_FORUMPOST', 'post');
595
define('RESOURCE_QUIZ', 'quiz');
596
define('RESOURCE_TEST_CATEGORY', 'test_category');
597
define('RESOURCE_QUIZQUESTION', 'Exercise_Question');
598
define('RESOURCE_TOOL_INTRO', 'Tool introduction');
599
define('RESOURCE_LINKCATEGORY', 'Link_Category');
600
define('RESOURCE_FORUMCATEGORY', 'Forum_Category');
601
define('RESOURCE_SCORM', 'Scorm');
602
define('RESOURCE_SURVEY', 'survey');
603
define('RESOURCE_SURVEYQUESTION', 'survey_question');
604
define('RESOURCE_SURVEYINVITATION', 'survey_invitation');
605
define('RESOURCE_WIKI', 'wiki');
606
define('RESOURCE_THEMATIC', 'thematic');
607
define('RESOURCE_ATTENDANCE', 'attendance');
608
define('RESOURCE_WORK', 'work');
609
define('RESOURCE_SESSION_COURSE', 'session_course');
610
define('RESOURCE_GRADEBOOK', 'gradebook');
611
define('ADD_THEMATIC_PLAN', 6);
612
613
// Max online users to show per page (whoisonline)
614
define('MAX_ONLINE_USERS', 12);
615
616
// Make sure the CHAMILO_LOAD_WYSIWYG constant is defined
617
// To remove CKeditor libs from HTML, set this constant to true before loading
618
if (!defined('CHAMILO_LOAD_WYSIWYG')) {
619
    define('CHAMILO_LOAD_WYSIWYG', true);
620
}
621
622
define('TOOL_PUBLIC', 'Public');
623
define('TOOL_PUBLIC_BUT_HIDDEN', 'PublicButHide');
624
define('TOOL_COURSE_ADMIN', 'courseAdmin');
625
define('TOOL_PLATFORM_ADMIN', 'platformAdmin');
626
define('TOOL_AUTHORING', 'toolauthoring');
627
define('TOOL_INTERACTION', 'toolinteraction');
628
define('TOOL_COURSE_PLUGIN', 'toolcourseplugin'); //all plugins that can be enabled in courses
629
define('TOOL_ADMIN', 'tooladmin');
630
define('TOOL_ADMIN_PLATFORM', 'tooladminplatform');
631
define('TOOL_DRH', 'tool_drh');
632
define('TOOL_STUDENT_VIEW', 'toolstudentview');
633
define('TOOL_ADMIN_VISIBLE', 'tooladminvisible');
634
635
/**
636
 * Inclusion of internationalization libraries
637
 */
638
require_once __DIR__.'/internationalization.lib.php';
639
640
/**
641
 * Returns a path to a certain resource within the Chamilo area, specifyed through a parameter.
642
 * Also, this function provides conversion between path types, in this case the input path points inside the Chamilo area too.
643
 *
644
 * See $_configuration['course_folder'] in the configuration.php to alter the WEB_COURSE_PATH and SYS_COURSE_PATH parameters.
645
646
 * @param string $path (optional)   A path which type is to be converted. Also, it may be a defined constant for a path.
647
 * This parameter has meaning when $type parameter has one of the following values: TO_WEB, TO_SYS, TO_REL. Otherwise it is ignored.
648
 * @return string                   The requested path or the converted path.
649
 *
650
 *
651
 * Notes about the current behaviour model:
652
 * 1. Windows back-slashes are converted to slashes in the result.
653
 * 2. A semi-absolute web-path is detected by its leading slash. On Linux systems, absolute system paths start with
654
 * a slash too, so an additional check about presence of leading system server base is implemented. For example, the function is
655
 * able to distinguish type difference between /var/www/chamilo/courses/ (SYS) and /chamilo/courses/ (REL).
656
 * 3. The function api_get_path() returns only these three types of paths, which in some sense are absolute. The function has
657
 * no a mechanism for processing relative web/system paths, such as: lesson01.html, ./lesson01.html, ../css/my_styles.css.
658
 * It has not been identified as needed yet.
659
 * 4. Also, resolving the meta-symbols "." and ".." within paths has not been implemented, it is to be identified as needed.
660
 *
661
 * For examples go to: *
662
 * See main/admin/system_status.php?section=paths
663
 *
664
 * Vchamilo changes : allow using an alternate configuration
665
 * to get vchamilo  instance paths
666
*/
667
function api_get_path($path = '', $configuration = [])
668
{
669
    global $paths;
670
671
    // get proper configuration data if exists
672
    global $_configuration;
673
674
    if (empty($configuration)) {
675
        $configuration = (array) $_configuration;
676
    }
677
678
    $course_folder = 'courses/';
679
    $root_sys = Container::getRootDir();
680
681
    // Resolve master hostname.
682
    if (!empty($configuration) && array_key_exists('root_web', $configuration)) {
683
        $root_web = $configuration['root_web'];
684
    } else {
685
        $root_web = Container::getUrlGenerator()->generate(
686
            'home',
687
            []
688
        );
689
    }
690
691
    if (isset($configuration['multiple_access_urls']) && $configuration['multiple_access_urls']) {
692
        // To avoid that the api_get_access_url() function fails since global.inc.php also calls the main_api.lib.php
693
        if (isset($configuration['access_url']) && !empty($configuration['access_url'])) {
694
            // We look into the DB the function api_get_access_url
695
            $url_info = api_get_access_url($configuration['access_url']);
696
            // Avoid default value
697
            $defaulValues = ['http://localhost/', 'https://localhost/'];
698
            if (!empty($url_info['url']) && !in_array($url_info['url'], $defaulValues)) {
699
                $root_web = $url_info['active'] == 1 ? $url_info['url'] : $configuration['root_web'];
700
            }
701
        }
702
    }
703
704
    if (empty($paths)) {
705
        $paths = [];
706
    }
707
708
    $paths = [];
709
    // Initialise cache with default values.
710
    if (!array_key_exists($root_web, $paths)) {
711
        $paths[$root_web] = array(
712
            WEB_PATH => '',
713
            SYS_PATH => '',
714
            REL_PATH => '',
715
            WEB_COURSE_PATH => '',
716
            SYS_COURSE_PATH => '',
717
            REL_COURSE_PATH => '',
718
            WEB_CODE_PATH => 'main/',
719
            SYS_CODE_PATH => 'main/',
720
            REL_CODE_PATH => '/main/',
721
            SYS_LANG_PATH => 'lang/',
722
            WEB_IMG_PATH => 'img/',
723
            WEB_CSS_PATH => 'web/css/',
724
            SYS_CSS_PATH => 'app/Resources/public/css/',
725
            SYS_PLUGIN_PATH => 'plugin/',
726
            WEB_PLUGIN_PATH => 'plugin/',
727
            SYS_ARCHIVE_PATH => 'app/cache/',
728
            WEB_ARCHIVE_PATH => 'app/cache/',
729
            SYS_HOME_PATH => 'app/home/',
730
            WEB_HOME_PATH => 'app/home/',
731
            REL_HOME_PATH => 'app/home/',
732
            SYS_APP_PATH => 'app/',
733
            WEB_APP_PATH => 'app/',
734
            SYS_UPLOAD_PATH => 'app/upload/',
735
            SYS_INC_PATH => 'inc/',
736
            CONFIGURATION_PATH => 'app/config/',
737
            LIBRARY_PATH => 'inc/lib/',
738
            WEB_LIBRARY_PATH => 'inc/lib/',
739
            WEB_LIBRARY_JS_PATH => 'inc/lib/javascript/',
740
            WEB_AJAX_PATH => 'inc/ajax/',
741
            SYS_TEST_PATH => 'tests/',
742
            WEB_TEMPLATE_PATH => 'template/',
743
            SYS_TEMPLATE_PATH => 'template/',
744
            WEB_UPLOAD_PATH => 'app/upload/',
745
            WEB_PUBLIC_PATH => 'web/',
746
            SYS_PUBLIC_PATH => 'web/',
747
            WEB_FONTS_PATH => 'fonts/',
748
            SYS_FONTS_PATH => 'fonts/',
749
        );
750
    }
751
752
    $isInitialized = [];
753
    $course_folder = isset($configuration['course_folder']) ? $configuration['course_folder'] : $course_folder;
754
    $root_rel = isset($configuration['url_append']) ? $configuration['url_append'] : '';
755
756
    // Web server base and system server base.
757
    if (!array_key_exists($root_web, $isInitialized)) {
758
        // process absolute global roots
759
        $code_folder = 'main';
760
        // Support for the installation process.
761
        // Developers might use the function api_get_path() directly or indirectly (this is difficult to be traced), at the moment when
762
        // configuration has not been created yet. This is why this function should be upgraded to return correct results in this case.
763
764
        // Dealing with trailing slashes.
765
        $slashed_root_web = api_add_trailing_slash($root_web);
766
767
        $root_sys = api_add_trailing_slash($root_sys);
768
        $root_rel = api_add_trailing_slash($root_rel);
769
        $code_folder = api_add_trailing_slash($code_folder);
770
        $course_folder = api_add_trailing_slash($course_folder);
771
772
        // Initialization of a table that contains common-purpose paths.
773
        $paths[$root_web][REL_PATH] = $root_rel;
774
        $paths[$root_web][REL_COURSE_PATH] = $root_rel.$course_folder;
775
        $paths[$root_web][REL_DEFAULT_COURSE_DOCUMENT_PATH] = $paths[$root_web][REL_PATH].'main/default_course_document/';
776
777
        $paths[$root_web][WEB_PATH] = $slashed_root_web;
778
        $paths[$root_web][WEB_CODE_PATH] = $paths[$root_web][WEB_PATH].$code_folder;
779
        $paths[$root_web][WEB_COURSE_PATH] = $paths[$root_web][WEB_PATH].$course_folder;
780
        $paths[$root_web][WEB_DEFAULT_COURSE_DOCUMENT_PATH] = $paths[$root_web][WEB_CODE_PATH].'default_course_document/';
781
        $paths[$root_web][WEB_APP_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_APP_PATH];
782
        $paths[$root_web][WEB_PLUGIN_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_PLUGIN_PATH];
783
        $paths[$root_web][WEB_ARCHIVE_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_ARCHIVE_PATH];
784
785
        $paths[$root_web][WEB_CSS_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_CSS_PATH];
786
        $paths[$root_web][WEB_IMG_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_IMG_PATH];
787
        $paths[$root_web][WEB_LIBRARY_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_LIBRARY_PATH];
788
        $paths[$root_web][WEB_LIBRARY_JS_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_LIBRARY_JS_PATH];
789
        $paths[$root_web][WEB_AJAX_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_AJAX_PATH];
790
        $paths[$root_web][WEB_FONTS_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_FONTS_PATH];
791
        $paths[$root_web][WEB_TEMPLATE_PATH] = $paths[$root_web][WEB_CODE_PATH].$paths[$root_web][WEB_TEMPLATE_PATH];
792
        $paths[$root_web][WEB_UPLOAD_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_UPLOAD_PATH];
793
        $paths[$root_web][WEB_PUBLIC_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][WEB_PUBLIC_PATH];
794
        $paths[$root_web][WEB_HOME_PATH] = $paths[$root_web][WEB_PATH].$paths[$root_web][REL_HOME_PATH];
795
796
        $paths[$root_web][SYS_PATH] = $root_sys;
797
        $paths[$root_web][SYS_CODE_PATH] = $root_sys.$code_folder;
798
        $paths[$root_web][SYS_TEST_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_TEST_PATH];
799
        $paths[$root_web][SYS_TEMPLATE_PATH] = $paths[$root_web][SYS_CODE_PATH].$paths[$root_web][SYS_TEMPLATE_PATH];
800
        $paths[$root_web][SYS_PUBLIC_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_PUBLIC_PATH];
801
        $paths[$root_web][SYS_CSS_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_CSS_PATH];
802
        $paths[$root_web][SYS_FONTS_PATH] = $paths[$root_web][SYS_CODE_PATH].$paths[$root_web][SYS_FONTS_PATH];
803
        $paths[$root_web][SYS_ARCHIVE_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_ARCHIVE_PATH];
804
        $paths[$root_web][SYS_APP_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_APP_PATH];
805
        $paths[$root_web][SYS_COURSE_PATH] = $paths[$root_web][SYS_APP_PATH].$course_folder;
806
        $paths[$root_web][SYS_UPLOAD_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_UPLOAD_PATH];
807
        $paths[$root_web][SYS_LANG_PATH] = $paths[$root_web][SYS_CODE_PATH].$paths[$root_web][SYS_LANG_PATH];
808
        $paths[$root_web][SYS_HOME_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_HOME_PATH];
809
        $paths[$root_web][SYS_PLUGIN_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][SYS_PLUGIN_PATH];
810
        $paths[$root_web][SYS_INC_PATH] = $paths[$root_web][SYS_CODE_PATH].$paths[$root_web][SYS_INC_PATH];
811
812
        $paths[$root_web][LIBRARY_PATH] = $paths[$root_web][SYS_CODE_PATH].$paths[$root_web][LIBRARY_PATH];
813
        $paths[$root_web][CONFIGURATION_PATH] = $paths[$root_web][SYS_PATH].$paths[$root_web][CONFIGURATION_PATH];
814
815
        global $virtualChamilo;
816
        if (!empty($virtualChamilo)) {
817
            $paths[$root_web][SYS_ARCHIVE_PATH] = api_add_trailing_slash($virtualChamilo[SYS_ARCHIVE_PATH]);
818
            $paths[$root_web][SYS_HOME_PATH] = api_add_trailing_slash($virtualChamilo[SYS_HOME_PATH]);
819
            $paths[$root_web][SYS_COURSE_PATH] = api_add_trailing_slash($virtualChamilo[SYS_COURSE_PATH]);
820
            $paths[$root_web][SYS_UPLOAD_PATH] = api_add_trailing_slash($virtualChamilo[SYS_UPLOAD_PATH]);
821
            //$paths[$root_web][REL_PATH] = $virtualChamilo[REL_PATH];
822
            //$paths[$root_web][REL_COURSE_PATH] = $virtualChamilo[REL_COURSE_PATH];
823
        }
824
825
        $isInitialized[$root_web] = true;
826
    }
827
828
    $path = trim($path);
829
830
    // Retrieving a common-purpose path.
831
    if (isset($paths[$root_web][$path])) {
832
        return $paths[$root_web][$path];
833
    }
834
835
    // Second purification.
836
837
    // Replacing Windows back slashes.
838
    $path = str_replace('\\', '/', $path);
839
    // Query strings sometimes mighth wrongly appear in non-URLs.
840
    // Let us check remove them from all types of paths.
841
    if (($pos = strpos($path, '?')) !== false) {
842
        $path = substr($path, 0, $pos);
843
    }
844
845
    // Detection of the input path type. Conversion to semi-absolute type ( /chamilo/main/inc/.... ).
846
847
    if (preg_match(VALID_WEB_PATH, $path)) {
848
        // A special case: When a URL points to the document download script directly, without
849
        // mod-rewrite translation, we have to translate it into an "ordinary" web path.
850
        // For example:
851
        // http://localhost/chamilo/main/document/download.php?doc_url=/image.png&cDir=/
852
        // becomes
853
        // http://localhost/chamilo/courses/TEST/document/image.png
854
        // TEST is a course directory name, so called "system course code".
855
        if (strpos($path, 'download.php') !== false) { // Fast detection first.
856
            $path = urldecode($path);
857
            if (preg_match('/(.*)main\/document\/download.php\?doc_url=\/(.*)&cDir=\/(.*)?/', $path, $matches)) {
858
                $sys_course_code =
859
                    isset($_SESSION['_course']['sysCode'])  // User is inside a course?
860
                        ? $_SESSION['_course']['sysCode']   // Yes, then use course's directory name.
861
                        : '{SYS_COURSE_CODE}';              // No, then use a fake code, it may be processed later.
862
                $path = $matches[1].'courses/'.$sys_course_code.'/document/'.str_replace('//', '/', $matches[3].'/'.$matches[2]);
863
            }
864
        }
865
        // Replacement of the present web server base with a slash '/'.
866
        $path = preg_replace(VALID_WEB_SERVER_BASE, '/', $path);
867
    }
868
869
    // Path now is semi-absolute. It is convenient at this moment repeated slashes to be removed.
870
    $path = preg_replace(REPEATED_SLASHES_PURIFIER, '/', $path);
871
872
    return $path;
873
}
874
875
/**
876
 * Gets a modified version of the path for the CDN, if defined in
877
 * configuration.php
878
 * @param string $web_path The path of the resource without CDN
879
 * @return string The path of the resource converted to CDN
880
 * @author Yannick Warnier <[email protected]>
881
 */
882
function api_get_cdn_path($web_path)
883
{
884
    global $_configuration;
885
    $web_root = api_get_path(WEB_PATH);
886
    $ext = substr($web_path,strrpos($web_path,'.'));
887
    if (isset($ext[2])) { // faster version of strlen to check if len>2
888
        // Check for CDN definitions
889
        if (!empty($_configuration['cdn_enable']) && !empty($ext)) {
890
            foreach ($_configuration['cdn'] as $host => $exts) {
891
                if (in_array($ext,$exts)) {
892
                    //Use host as defined in $_configuration['cdn'], without
893
                    // trailing slash
894
                    return str_replace($web_root,$host.'/',$web_path);
895
                }
896
            }
897
        }
898
    }
899
    return $web_path;
900
}
901
902
/**
903
 * @return bool Return true if CAS authentification is activated
904
 *
905
 */
906
function api_is_cas_activated() {
907
    return api_get_setting('cas_activate') == "true";
908
}
909
910
/**
911
 * @return bool     Return true if LDAP authentification is activated
912
 *
913
 */
914
function api_is_ldap_activated() {
915
    global $extAuthSource;
916
    return is_array($extAuthSource[LDAP_AUTH_SOURCE]);
917
}
918
919
/**
920
 * @return bool     Return true if Facebook authentification is activated
921
 *
922
 */
923
function api_is_facebook_auth_activated() {
924
    global $_configuration;
925
    return (isset($_configuration['facebook_auth']) && $_configuration['facebook_auth'] == 1);
926
}
927
928
/**
929
 * This function checks whether a given path points inside the system.
930
 * @param string $path      The path to be tested.
931
 * It should be full path, web-absolute (WEB), semi-absolute (REL) or system-absolyte (SYS).
932
 * @return bool             Returns true when the given path is inside the system, false otherwise.
933
 */
934
function api_is_internal_path($path) {
935
    $path = str_replace('\\', '/', trim($path));
936
    if (empty($path)) {
937
        return false;
938
    }
939
    if (strpos($path, api_remove_trailing_slash(api_get_path(WEB_PATH))) === 0) {
940
        return true;
941
    }
942
    if (strpos($path, api_remove_trailing_slash(api_get_path(SYS_PATH))) === 0) {
943
        return true;
944
    }
945
    $server_base_web = api_remove_trailing_slash(api_get_path(REL_PATH));
946
    $server_base_web = empty($server_base_web) ? '/' : $server_base_web;
947
    if (strpos($path, $server_base_web) === 0) {
948
        return true;
949
    }
950
    return false;
951
}
952
953
/**
954
 * Adds to a given path a trailing slash if it is necessary (adds "/" character at the end of the string).
955
 * @param string $path          The input path.
956
 * @return string               Returns the modified path.
957
 */
958
function api_add_trailing_slash($path) {
959
    return substr($path, -1) == '/' ? $path : $path.'/';
960
}
961
962
/**
963
 * Removes from a given path the trailing slash if it is necessary (removes "/" character from the end of the string).
964
 * @param string $path          The input path.
965
 * @return string               Returns the modified path.
966
 */
967
function api_remove_trailing_slash($path) {
968
    return substr($path, -1) == '/' ? substr($path, 0, -1) : $path;
969
}
970
971
/**
972
 * Checks the RFC 3986 syntax of a given URL.
973
 * @param string $url       The URL to be checked.
974
 * @param bool $absolute    Whether the URL is absolute (beginning with a scheme such as "http:").
975
 * @return string|false             Returns the URL if it is valid, FALSE otherwise.
976
 * This function is an adaptation from the function valid_url(), Drupal CMS.
977
 * @link http://drupal.org
978
 * Note: The built-in function filter_var($urs, FILTER_VALIDATE_URL) has a bug for some versions of PHP.
979
 * @link http://bugs.php.net/51192
980
 */
981
function api_valid_url($url, $absolute = false) {
982
    if ($absolute) {
983
        if (preg_match("
984
            /^                                                      # Start at the beginning of the text
985
            (?:ftp|https?|feed):\/\/                                # Look for ftp, http, https or feed schemes
986
            (?:                                                     # Userinfo (optional) which is typically
987
                (?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)*    # a username or a username and password
988
                (?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@        # combination
989
            )?
990
            (?:
991
                (?:[a-z0-9\-\.]|%[0-9a-f]{2})+                      # A domain name or a IPv4 address
992
                |(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\])       # or a well formed IPv6 address
993
            )
994
            (?::[0-9]+)?                                            # Server port number (optional)
995
            (?:[\/|\?]
996
                (?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2}) # The path and query (optional)
997
            *)?
998
            $/xi", $url)) {
999
            return $url;
1000
        }
1001
        return false;
1002
    } else {
1003
        return preg_match("/^(?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})+$/i", $url) ? $url : false;
1004
    }
1005
}
1006
1007
/**
1008
 * Checks whether a given string looks roughly like an email address.
1009
 *
1010
 * @param string $address   The e-mail address to be checked.
1011
 * @return mixed            Returns the e-mail if it is valid, FALSE otherwise.
1012
 */
1013
function api_valid_email($address)
1014
{
1015
    return filter_var($address, FILTER_VALIDATE_EMAIL);
1016
}
1017
1018
/* PROTECTION FUNCTIONS
1019
   Use these functions to protect your scripts. */
1020
1021
/**
1022
 * Function used to protect a course script.
1023
 * The function blocks access when
1024
 * - there is no $_SESSION["_course"] defined; or
1025
 * - $is_allowed_in_course is set to false (this depends on the course
1026
 * visibility and user status).
1027
 *
1028
 * This is only the first proposal, test and improve!
1029
 * @param boolean       Option to print headers when displaying error message. Default: false
1030
 * @param boolean       Whether session admins should be allowed or not.
1031
 * @return boolean      True if the user has access to the current course or is out of a course context, false otherwise
1032
 * @todo replace global variable
1033
 * @author Roan Embrechts
1034
 */
1035
function api_protect_course_script($print_headers = false, $allow_session_admins = false, $allow_drh = false)
1036
{
1037
    $is_allowed_in_course = api_is_allowed_in_course();
1038
1039
    $is_visible = false;
1040
    $course_info = api_get_course_info();
1041
1042
    if (empty($course_info)) {
1043
        api_not_allowed($print_headers);
1044
        return false;
1045
    }
1046
1047
    if (api_is_drh()) {
1048
        return true;
1049
    }
1050
1051
    if (api_is_platform_admin($allow_session_admins)) {
1052
        return true;
1053
    }
1054
1055
    if (isset($course_info) && isset($course_info['visibility'])) {
1056
        switch ($course_info['visibility']) {
1057
            default:
1058 View Code Duplication
            case COURSE_VISIBILITY_CLOSED:
1059
                // Completely closed: the course is only accessible to the teachers. - 0
1060
                if (api_get_user_id() && !api_is_anonymous() && $is_allowed_in_course) {
1061
                    $is_visible = true;
1062
                }
1063
                break;
1064 View Code Duplication
            case COURSE_VISIBILITY_REGISTERED:
1065
                // Private - access authorized to course members only - 1
1066
                if (api_get_user_id() && !api_is_anonymous() && $is_allowed_in_course) {
1067
                    $is_visible = true;
1068
                }
1069
                break;
1070 View Code Duplication
            case COURSE_VISIBILITY_OPEN_PLATFORM:
1071
                // Open - access allowed for users registered on the platform - 2
1072
                if (api_get_user_id() && !api_is_anonymous() && $is_allowed_in_course) {
1073
                    $is_visible = true;
1074
                }
1075
                break;
1076
            case COURSE_VISIBILITY_OPEN_WORLD:
1077
                //Open - access allowed for the whole world - 3
1078
                $is_visible = true;
1079
                break;
1080
            case COURSE_VISIBILITY_HIDDEN:
1081
                //Completely closed: the course is only accessible to the teachers. - 0
1082
                if (api_is_platform_admin()) {
1083
                    $is_visible = true;
1084
                }
1085
                break;
1086
        }
1087
1088
        //If password is set and user is not registered to the course then the course is not visible
1089
        if ($is_allowed_in_course == false &
0 ignored issues
show
Comprehensibility introduced by
Consider adding parentheses for clarity. Current Interpretation: ($is_allowed_in_course =...o['registration_code']), Probably Intended Meaning: $is_allowed_in_course ==...['registration_code']))

When comparing the result of a bit operation, we suggest to add explicit parenthesis and not to rely on PHP’s built-in operator precedence to ensure the code behaves as intended and to make it more readable.

Let’s take a look at these examples:

// Returns always int(0).
return 0 === $foo & 4;
return (0 === $foo) & 4;

// More likely intended return: true/false
return 0 === ($foo & 4);
Loading history...
1090
            isset($course_info['registration_code']) &&
1091
            !empty($course_info['registration_code'])
1092
        ) {
1093
            $is_visible = false;
1094
        }
1095
    }
1096
1097
    // Check session visibility
1098
    $session_id = api_get_session_id();
1099
1100
    if (!empty($session_id)) {
1101
        //$is_allowed_in_course was set in local.inc.php
1102
        if (!$is_allowed_in_course) {
1103
            $is_visible = false;
1104
        }
1105
    }
1106
1107
    if (!$is_visible) {
1108
        api_not_allowed($print_headers);
1109
        return false;
1110
    }
1111
    return true;
1112
}
1113
1114
/**
1115
 * Function used to protect an admin script.
1116
 *
1117
 * The function blocks access when the user has no platform admin rights
1118
 * with an error message printed on default output
1119
 * @param bool Whether to allow session admins as well
1120
 * @param bool Whether to allow HR directors as well
1121
 * @param string An optional message (already passed through get_lang)
1122
 * @return bool True if user is allowed, false otherwise.
1123
 * The function also outputs an error message in case not allowed
1124
 * @author Roan Embrechts (original author)
1125
 */
1126
function api_protect_admin_script($allow_sessions_admins = false, $allow_drh = false, $message = null)
1127
{
1128
    if (!api_is_platform_admin($allow_sessions_admins, $allow_drh)) {
1129
        api_not_allowed(true, $message);
1130
        return false;
1131
    }
1132
    return true;
1133
}
1134
1135
/**
1136
 * Function used to protect a teacher script.
1137
 * The function blocks access when the user has no teacher rights.
1138
 *
1139
 * @author Yoselyn Castillo
1140
 */
1141
function api_protect_teacher_script($allow_sessions_admins = false)
1142
{
1143
    if (!api_is_allowed_to_edit()) {
1144
        api_not_allowed(true);
1145
        return false;
1146
    }
1147
    return true;
1148
}
1149
1150
/**
1151
 * Function used to prevent anonymous users from accessing a script.
1152
 * @param bool|true $printHeaders
1153
 * @author Roan Embrechts
1154
 *
1155
 * @return bool
1156
 */
1157
function api_block_anonymous_users($printHeaders = true)
1158
{
1159
    $user = api_get_user_info();
1160 View Code Duplication
    if (!(isset($user['user_id']) && $user['user_id']) || api_is_anonymous($user['user_id'], true)) {
1161
        api_not_allowed($printHeaders);
1162
        return false;
1163
    }
1164
1165
    return true;
1166
}
1167
1168
/**
1169
 * @return array with the navigator name and version
1170
 */
1171
function api_get_navigator() {
1172
    $navigator = 'Unknown';
1173
    $version = 0;
1174
1175
    if (!isset($_SERVER['HTTP_USER_AGENT'])) {
1176
        return array('name' => 'Unknown', 'version' => '0.0.0');
1177
    }
1178
1179
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false) {
1180
        $navigator = 'Opera';
1181
        list (, $version) = explode('Opera', $_SERVER['HTTP_USER_AGENT']);
1182 View Code Duplication
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) {
1183
        $navigator = 'Internet Explorer';
1184
        list (, $version) = explode('MSIE', $_SERVER['HTTP_USER_AGENT']);
1185
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== false) {
1186
        $navigator = 'Chrome';
1187
        list (, $version) = explode('Chrome', $_SERVER['HTTP_USER_AGENT']);
1188 View Code Duplication
    } elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'safari') !== false) {
1189
        $navigator = 'Safari';
1190
        list (, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
1191
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false) {
1192
        $navigator = 'Mozilla';
1193
        list (, $version) = explode('; rv:', $_SERVER['HTTP_USER_AGENT']);
1194 View Code Duplication
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Netscape') !== false) {
1195
        $navigator = 'Netscape';
1196
        list (, $version) = explode('Netscape', $_SERVER['HTTP_USER_AGENT']);
1197
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror') !== false) {
1198
        $navigator = 'Konqueror';
1199
        list (, $version) = explode('Konqueror', $_SERVER['HTTP_USER_AGENT']);
1200 View Code Duplication
    } elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'applewebkit') !== false) {
1201
        $navigator = 'AppleWebKit';
1202
        list (, $version) = explode('Version/', $_SERVER['HTTP_USER_AGENT']);
1203
    }
1204
    $version = str_replace('/', '', $version);
1205
    if (strpos($version, '.') === false) {
1206
        $version = number_format(doubleval($version), 1);
1207
    }
1208
    $return = array('name' => $navigator, 'version' => $version);
1209
    return $return;
1210
}
1211
1212
/**
1213
 * @return True if user self registration is allowed, false otherwise.
1214
 */
1215
function api_is_self_registration_allowed()
1216
{
1217
    return isset($GLOBALS['allowSelfReg']) ? $GLOBALS['allowSelfReg'] : false;
1218
}
1219
1220
/**
1221
 * This function returns the id of the user which is stored in the $_user array.
1222
 *
1223
 * example: The function can be used to check if a user is logged in
1224
 *          if (api_get_user_id())
1225
 * @return integer the id of the current user, 0 if is empty
1226
 */
1227
function api_get_user_id()
1228
{
1229
    $userInfo = Session::read('_user');
1230
    if ($userInfo && isset($userInfo['user_id'])) {
1231
        return $userInfo['user_id'];
1232
    }
1233
    return 0;
1234
}
1235
1236
/**
1237
 * Gets the list of courses a specific user is subscribed to
1238
 * @param int       User ID
1239
 * @param boolean   $fetch_session Whether to get session courses or not - NOT YET IMPLEMENTED
1240
 * @return array    Array of courses in the form [0]=>('code'=>xxx,'db'=>xxx,'dir'=>xxx,'status'=>d)
1241
 */
1242
function api_get_user_courses($userid, $fetch_session = true)
1243
{
1244
    // Get out if not integer
1245
    if ($userid != strval(intval($userid))) {
1246
        return array();
1247
    }
1248
1249
    $t_course = Database::get_main_table(TABLE_MAIN_COURSE);
1250
    $t_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1251
1252
    $sql = "SELECT cc.id as real_id, cc.code code, cc.directory dir, cu.status status
1253
            FROM    $t_course       cc,
1254
                    $t_course_user   cu
1255
            WHERE
1256
                cc.id = cu.c_id AND
1257
                cu.user_id = '".$userid."' AND
1258
                cu.relation_type<>".COURSE_RELATION_TYPE_RRHH." ";
1259
    $result = Database::query($sql);
1260
    if ($result === false) {
1261
        return array();
1262
    }
1263
1264
    $courses = array();
1265
    while ($row = Database::fetch_array($result)) {
1266
        // we only need the database name of the course
1267
        $courses[] = $row;
1268
    }
1269
1270
    return $courses;
1271
}
1272
1273
/**
1274
 * Formats user information into a standard array
1275
 * This function should be only used inside api_get_user_info()
1276
 *
1277
 * @param array Non-standard user array
1278
 * @param bool $add_password
1279
 *
1280
 * @return array Standard user array
1281
 */
1282
function _api_format_user($user, $add_password = false)
1283
{
1284
    $result = array();
1285
1286
    $firstname = null;
1287
    $lastname = null;
1288
    if (isset($user['firstname']) && isset($user['lastname'])) {
1289
        $firstname = $user['firstname'];
1290
        $lastname = $user['lastname'];
1291
    } elseif (isset($user['firstName']) && isset($user['lastName'])) {
1292
        $firstname = isset($user['firstName']) ? $user['firstName'] : null;
1293
        $lastname = isset($user['lastName']) ? $user['lastName'] : null;
1294
    }
1295
1296
    $result['complete_name'] = api_get_person_name($firstname, $lastname);
1297
1298
    $result['complete_name_with_username'] = $result['complete_name'];
1299
1300
    if (!empty($user['username'])) {
1301
        $result['complete_name_with_username'] = $result['complete_name'].' ('.$user['username'].')';
1302
    }
1303
1304
    $result['firstname'] = $firstname;
1305
    $result['lastname'] = $lastname;
1306
1307
    // Kept for historical reasons
1308
    $result['firstName'] = $firstname;
1309
    $result['lastName'] = $lastname;
1310
1311
    $attributes = array(
1312
        'phone',
1313
        'address',
1314
        'picture_uri',
1315
        'official_code',
1316
        'status',
1317
        'active',
1318
        'auth_source',
1319
        'username',
1320
        'theme',
1321
        'language',
1322
        'creator_id',
1323
        'registration_date',
1324
        'hr_dept_id',
1325
        'expiration_date',
1326
        'last_login'
1327
    );
1328
    if (api_get_setting('extended_profile') === 'true') {
1329
        $attributes[] = 'competences';
1330
        $attributes[] = 'diplomas';
1331
        $attributes[] = 'teach';
1332
        $attributes[] = 'openarea';
1333
    }
1334
1335
    foreach ($attributes as $attribute) {
1336
        $result[$attribute] = isset($user[$attribute]) ? $user[$attribute] : null;
1337
    }
1338
1339
    if (isset($user['email'])) {
1340
        $result['mail'] = isset($user['email']) ? $user['email'] : null;
1341
        $result['email'] = isset($user['email'])? $user['email'] : null;
1342
    } else {
1343
        $result['mail'] = isset($user['mail']) ? $user['mail'] : null;
1344
        $result['email'] = isset($user['mail'])? $user['mail'] : null;
1345
    }
1346
    $user_id = intval($user['user_id']);
1347
    // Maintain the user_id index for backwards compatibility
1348
    $result['user_id'] = $result['id'] = $user_id;
1349
    $result['last_login'] = $user['last_login'];
1350
1351
    // Getting user avatar.
1352
    $originalFile = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_ORIGINAL, null, $result);
1353
    $smallFile = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_SMALL, null, $result);
1354
    $mediumFile = UserManager::getUserPicture($user_id, USER_IMAGE_SIZE_MEDIUM, null, $result);
1355
1356
    $result['avatar'] = $originalFile;
1357
    $avatarString = explode('?', $originalFile);
1358
    $result['avatar_no_query'] = reset($avatarString);
1359
    $result['avatar_small'] = $smallFile;
1360
    $result['avatar_medium'] = $mediumFile;
1361
1362
    if (isset($user['user_is_online'])) {
1363
        $result['user_is_online'] = $user['user_is_online'] == true ? 1 : 0;
1364
    }
1365
    if (isset($user['user_is_online_in_chat'])) {
1366
        $result['user_is_online_in_chat'] = intval($user['user_is_online_in_chat']);
1367
    }
1368
1369
    if ($add_password) {
1370
        $result['password'] = $user['password'];
1371
    }
1372
1373
    if (isset($result['profile_completed'])) {
1374
        $result['profile_completed'] = $user['profile_completed'];
1375
    }
1376
1377
    $result['profile_url'] = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$user_id;
1378
1379
    if (isset($user['extra'])) {
1380
        $result['extra'] = $user['extra'];
1381
    }
1382
1383
    return $result;
1384
}
1385
1386
/**
1387
 * Finds all the information about a user.
1388
 * If no parameter is passed you find all the information about the current user.
1389
 * @param int  $user_id
1390
 * @param bool $checkIfUserOnline
1391
 * @param bool $showPassword
1392
 * @param bool $loadExtraData
1393
 * @param bool $loadOnlyVisibleExtraData Get the user extra fields that are visible
1394
 * @return array $user_info user_id, lastname, firstname, username, email, etc
1395
 * @author Patrick Cool <[email protected]>
1396
 * @author Julio Montoya
1397
 * @version 21 September 2004
1398
 */
1399
function api_get_user_info(
1400
    $user_id = 0,
1401
    $checkIfUserOnline = false,
1402
    $showPassword = false,
1403
    $loadExtraData = false,
1404
    $loadOnlyVisibleExtraData = false
1405
) {
1406
    if (empty($user_id)) {
1407
        $userFromSession = Session::read('_user');
1408
        if (isset($userFromSession)) {
1409
            return _api_format_user($userFromSession);
1410
        }
1411
1412
        return false;
1413
    }
1414
1415
    $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)."
1416
            WHERE id='".intval($user_id)."'";
1417
    $result = Database::query($sql);
1418
    if (Database::num_rows($result) > 0) {
1419
        $result_array = Database::fetch_array($result);
1420
        if ($checkIfUserOnline) {
1421
            $use_status_in_platform = UserManager::user_is_online($user_id);
1422
1423
            $result_array['user_is_online'] = $use_status_in_platform;
1424
            $user_online_in_chat = 0;
1425
1426
            if ($use_status_in_platform) {
1427
                $user_status = UserManager::get_extra_user_data_by_field(
1428
                    $user_id,
1429
                    'user_chat_status',
1430
                    false,
1431
                    true
1432
                );
1433
                if (intval($user_status['user_chat_status']) == 1) {
1434
                    $user_online_in_chat = 1;
1435
                }
1436
            }
1437
            $result_array['user_is_online_in_chat'] = $user_online_in_chat;
1438
        }
1439
1440
        if ($loadExtraData) {
1441
            $fieldValue = new ExtraFieldValue('user');
1442
1443
            $result_array['extra'] = $fieldValue->getAllValuesForAnItem(
1444
                $user_id,
1445
                $loadOnlyVisibleExtraData
1446
            );
1447
        }
1448
        $user = _api_format_user($result_array, $showPassword);
1449
1450
        return $user;
1451
    }
1452
    return false;
1453
}
1454
1455
/**
1456
 * @param int $userId
1457
 * @return User
1458
 */
1459
function api_get_user_entity($userId)
1460
{
1461
    /** @var \Chamilo\UserBundle\Repository\UserRepository $repo */
1462
    $repo = Database::getManager()->getRepository('ChamiloUserBundle:User');
1463
1464
    return $repo->find($userId);
1465
}
1466
1467
/**
1468
 * @param int $courseId
1469
 *
1470
 * @return Course
1471
 */
1472
function api_get_user_course_entity($courseId = null)
1473
{
1474
    if (empty($courseId)) {
1475
        $courseId = api_get_course_int_id();
1476
    }
1477
    return CourseManager::getManager()->find($courseId);
1478
}
1479
1480
/**
1481
 * Finds all the information about a user from username instead of user id
1482
 * @param string $username
1483
 * @return array $user_info array user_id, lastname, firstname, username, email
1484
 * @author Yannick Warnier <[email protected]>
1485
 */
1486 View Code Duplication
function api_get_user_info_from_username($username = '')
1487
{
1488
    if (empty($username)) {
1489
        return false;
1490
    }
1491
    $username = trim($username);
1492
1493
    $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)."
1494
            WHERE username='".Database::escape_string($username)."'";
1495
    $result = Database::query($sql);
1496
    if (Database::num_rows($result) > 0) {
1497
        $result_array = Database::fetch_array($result);
1498
        return _api_format_user($result_array);
1499
    }
1500
    return false;
1501
}
1502
1503
/**
1504
 * Get first user with an email
1505
 * @param string $email
1506
 * @return array|bool
1507
 */
1508 View Code Duplication
function api_get_user_info_from_email($email = '')
1509
{
1510
    if (empty($email)) {
1511
        return false;
1512
    }
1513
    $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)."
1514
            WHERE email ='".Database::escape_string($email)."' LIMIT 1";
1515
    $result = Database::query($sql);
1516
    if (Database::num_rows($result) > 0) {
1517
        $result_array = Database::fetch_array($result);
1518
        return _api_format_user($result_array);
1519
    }
1520
1521
    return false;
1522
}
1523
1524
/**
1525
 * @return string
1526
 */
1527
function api_get_course_id()
1528
{
1529
    return Session::read('_cid', null);
1530
}
1531
1532
/**
1533
 * Returns the current course id (integer)
1534
 * @param   string  $code   Optional course code
1535
 * @return int
1536
 */
1537
function api_get_course_int_id($code = null)
1538
{
1539 View Code Duplication
    if (!empty($code)) {
1540
        $code = Database::escape_string($code);
1541
        $row = Database::select(
1542
            'id',
1543
            Database::get_main_table(TABLE_MAIN_COURSE),
1544
            array('where'=> array('code = ?' => array($code))),
1545
            'first'
1546
        );
1547
1548
        if (is_array($row) && isset($row['id'])) {
1549
            return $row['id'];
1550
        } else {
1551
            return false;
1552
        }
1553
    }
1554
    return Session::read('_real_cid', 0);
1555
}
1556
1557
/**
1558
 * Returns the current course directory
1559
 *
1560
 * This function relies on api_get_course_info()
1561
 * @param string    The course code - optional (takes it from session if not given)
1562
 * @return string   The directory where the course is located inside the Chamilo "courses" directory
1563
 * @author Yannick Warnier <[email protected]>
1564
 */
1565
function api_get_course_path($course_code = null)
1566
{
1567
    $info = !empty($course_code) ? api_get_course_info($course_code) : api_get_course_info();
1568
    return $info['path'];
1569
}
1570
1571
/**
1572
 * Gets a course setting from the current course_setting table. Try always using integer values.
1573
 * @param string    The name of the setting we want from the table
1574
 * @param string    Optional: course code
1575
 * @param string $setting_name
1576
 * @return mixed    The value of that setting in that table. Return -1 if not found.
1577
 */
1578
function api_get_course_setting($setting_name, $course_code = null)
1579
{
1580
    $course_info = api_get_course_info($course_code);
1581
    $table = Database::get_course_table(TABLE_COURSE_SETTING);
1582
    $setting_name = Database::escape_string($setting_name);
1583
    if (!empty($course_info['real_id']) && !empty($setting_name)) {
1584
        $sql = "SELECT value FROM $table
1585
                WHERE c_id = {$course_info['real_id']} AND variable = '$setting_name'";
1586
        $res = Database::query($sql);
1587
        if (Database::num_rows($res) > 0) {
1588
            $row = Database::fetch_array($res);
1589
            return $row['value'];
1590
        }
1591
    }
1592
    return -1;
1593
}
1594
1595
/**
1596
 * Gets an anonymous user ID
1597
 *
1598
 * For some tools that need tracking, like the learnpath tool, it is necessary
1599
 * to have a usable user-id to enable some kind of tracking, even if not
1600
 * perfect. An anonymous ID is taken from the users table by looking for a
1601
 * status of "6" (anonymous).
1602
 * @return int  User ID of the anonymous user, or O if no anonymous user found
1603
 */
1604 View Code Duplication
function api_get_anonymous_id()
1605
{
1606
    $table = Database::get_main_table(TABLE_MAIN_USER);
1607
    $sql = "SELECT user_id FROM $table WHERE status = ".ANONYMOUS;
1608
    $res = Database::query($sql);
1609
    if (Database::num_rows($res) > 0) {
1610
        $row = Database::fetch_array($res);
1611
        return $row['user_id'];
1612
    }
1613
1614
    // No anonymous user was found.
1615
    return 0;
1616
}
1617
1618
/**
1619
 * @param string $courseCode
1620
 * @param int $sessionId
1621
 * @param int $groupId
1622
 * @return string
1623
 */
1624
function api_get_cidreq_params($courseCode, $sessionId = 0, $groupId = 0)
1625
{
1626
    $courseCode = !empty($courseCode) ? htmlspecialchars($courseCode) : '';
1627
    $sessionId = !empty($sessionId) ? (int) $sessionId : 0;
1628
    $groupId = !empty($groupId) ? (int) $groupId : 0;
1629
1630
    $url = 'cidReq='.$courseCode;
1631
    $url .= '&id_session='.$sessionId;
1632
    $url .= '&gidReq='.$groupId;
1633
1634
    return $url;
1635
}
1636
1637
/**
1638
 * Returns the current course url part including session, group, and gradebook params
1639
 *
1640
 * @param bool $addSessionId
1641
 * @param bool $addGroupId
1642
 * @param string $origin
1643
 *
1644
 * @return  string  Course & session references to add to a URL
1645
 *
1646
 */
1647
function api_get_cidreq($addSessionId = true, $addGroupId = true, $origin = '')
1648
{
1649
    $courseCode = api_get_course_id();
1650
    $url = empty($courseCode) ? '' : 'cidReq='.htmlspecialchars($courseCode);
1651
    $origin = empty($origin) ? api_get_origin() : Security::remove_XSS($origin);
1652
1653
    if ($addSessionId) {
1654
        if (!empty($url)) {
1655
            $url .= api_get_session_id() == 0 ? '&id_session=0' : '&id_session='.api_get_session_id();
1656
        }
1657
    }
1658
1659
    if ($addGroupId) {
1660
        if (!empty($url)) {
1661
            $url .= api_get_group_id() == 0 ? '&gidReq=0' : '&gidReq='.api_get_group_id();
1662
        }
1663
    }
1664
1665
    if (!empty($url)) {
1666
        $url .= '&gradebook='.intval(api_is_in_gradebook());
1667
        $url .= '&origin='.$origin;
1668
    }
1669
1670
    return $url;
1671
}
1672
1673
/**
1674
 * get gradebook in session
1675
 */
1676
function api_is_in_gradebook()
1677
{
1678
    return Session::read('in_gradebook', false);
1679
}
1680
1681
/**
1682
 * set gradebook session
1683
 */
1684
function api_set_in_gradebook()
1685
{
1686
    Session::write('in_gradebook', true);
1687
}
1688
1689
/**
1690
 * remove gradebook session
1691
 */
1692
function api_remove_in_gradebook()
1693
{
1694
    Session::erase('in_gradebook');
1695
}
1696
1697
/**
1698
 * Returns the current course info array see api_format_course_array()
1699
 * If the course_code is given, the returned array gives info about that
1700
 * particular course, if none given it gets the course info from the session.
1701
 *
1702
 * @param string $course_code
1703
 * @param bool $strict
1704
 *
1705
 * @return array
1706
 */
1707
function api_get_course_info($course_code = null, $strict = false)
1708
{
1709
    if (!empty($course_code)) {
1710
        $course_code = Database::escape_string($course_code);
1711
        $courseId = api_get_course_int_id($course_code);
1712
1713
        if (empty($courseId)) {
1714
            return array();
1715
        }
1716
1717
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1718
        $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
1719
        $sql = "SELECT
1720
                    course.*,
1721
                    course_category.code faCode,
1722
                    course_category.name faName
1723
                FROM $course_table
1724
                LEFT JOIN $course_cat_table
1725
                ON course.category_code = course_category.code
1726
                WHERE course.id = $courseId";
1727
        $result = Database::query($sql);
1728
        $courseInfo = array();
1729
        if (Database::num_rows($result) > 0) {
1730
            $data = Database::fetch_array($result);
1731
            $courseInfo = api_format_course_array($data);
1732
        }
1733
1734
        return $courseInfo;
1735
    }
1736
1737
    $_course = Session::read('_course');
1738
    if ($_course == '-1') {
1739
        $_course = array();
1740
    }
1741
1742
    return $_course;
1743
}
1744
1745
/**
1746
 * Returns the current course info array.
1747
1748
 * Now if the course_code is given, the returned array gives info about that
1749
 * particular course, not specially the current one.
1750
 * @param int $id Numeric ID of the course
1751
 * @return array The course info as an array formatted by api_format_course_array, including category.name
1752
 */
1753
function api_get_course_info_by_id($id = null)
1754
{
1755
    if (!empty($id)) {
1756
        $id = intval($id);
1757
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1758
        $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
1759
        $sql = "SELECT
1760
                    course.*,
1761
                    course_category.code faCode,
1762
                    course_category.name faName
1763
                FROM $course_table
1764
                LEFT JOIN $course_cat_table
1765
                ON course.category_code =  course_category.code
1766
                WHERE course.id = $id";
1767
        $result = Database::query($sql);
1768
        $_course = array();
1769
        if (Database::num_rows($result) > 0) {
1770
            $course_data = Database::fetch_array($result);
1771
            $_course = api_format_course_array($course_data);
1772
        }
1773
        return $_course;
1774
    }
1775
1776
    global $_course;
1777
    if ($_course == '-1') $_course = array();
1778
    return $_course;
1779
}
1780
1781
/**
1782
 * Reformat the course array (output by api_get_course_info()) in order, mostly,
1783
 * to switch from 'code' to 'id' in the array. This is a legacy feature and is
1784
 * now possibly causing massive confusion as a new "id" field has been added to
1785
 * the course table in 1.9.0.
1786
 * @param $course_data
1787
 * @return array
1788
 * @todo eradicate the false "id"=code field of the $_course array and use the int id
1789
 */
1790
function api_format_course_array($course_data)
1791
{
1792
    if (empty($course_data)) {
1793
        return array();
1794
    }
1795
1796
    $_course = array();
1797
    $_course['id'] = $course_data['code'];
1798
    $_course['real_id'] = $course_data['id'];
1799
1800
    // Added
1801
    $_course['code'] = $course_data['code'];
1802
    $_course['name'] = $course_data['title'];
1803
    $_course['title'] = $course_data['title'];
1804
    $_course['official_code'] = $course_data['visual_code'];
1805
    $_course['visual_code'] = $course_data['visual_code'];
1806
    $_course['sysCode'] = $course_data['code'];
1807
    $_course['path'] = $course_data['directory']; // Use as key in path.
1808
    $_course['directory'] = $course_data['directory'];
1809
    $_course['creation_date'] = $course_data['creation_date'];
1810
    $_course['titular'] = $course_data['tutor_name'];
1811
    $_course['language'] = $course_data['course_language'];
1812
    $_course['extLink']['url'] = $course_data['department_url'];
1813
    $_course['extLink']['name'] = $course_data['department_name'];
1814
    $_course['categoryCode'] = $course_data['faCode'];
1815
    $_course['categoryName'] = $course_data['faName'];
1816
    $_course['visibility'] = $course_data['visibility'];
1817
    $_course['subscribe_allowed'] = $course_data['subscribe'];
1818
    $_course['subscribe'] = $course_data['subscribe'];
1819
    $_course['unsubscribe'] = $course_data['unsubscribe'];
1820
    $_course['course_language'] = $course_data['course_language'];
1821
    $_course['activate_legal'] = isset($course_data['activate_legal']) ? $course_data['activate_legal'] : false;
1822
    $_course['legal'] = $course_data['legal'];
1823
    $_course['show_score'] = $course_data['show_score']; //used in the work tool
1824
    $_course['department_name'] = $course_data['department_name'];
1825
    $_course['department_url'] = $course_data['department_url'];
1826
1827
    // Course password
1828
    $_course['registration_code'] = !empty($course_data['registration_code']) ? sha1($course_data['registration_code']) : null;
1829
    $_course['disk_quota'] = $course_data['disk_quota'];
1830
    $_course['course_public_url'] = api_get_path(WEB_COURSE_PATH).$course_data['directory'].'/index.php';
1831
1832
    if (array_key_exists('add_teachers_to_sessions_courses', $course_data)) {
1833
        $_course['add_teachers_to_sessions_courses'] = $course_data['add_teachers_to_sessions_courses'];
1834
    }
1835
1836
    if (file_exists(api_get_path(SYS_COURSE_PATH).$course_data['directory'].'/course-pic85x85.png')) {
1837
        $url_image = api_get_path(WEB_COURSE_PATH).$course_data['directory'].'/course-pic85x85.png';
1838
    } else {
1839
        $url_image = Display::return_icon('course.png', null, null, ICON_SIZE_BIG, null, true, false);
1840
    }
1841
    $_course['course_image'] = $url_image;
1842
1843
    if (file_exists(api_get_path(SYS_COURSE_PATH).$course_data['directory'].'/course-pic.png')) {
1844
        $url_image = api_get_path(WEB_COURSE_PATH).$course_data['directory'].'/course-pic.png';
1845
    } else {
1846
        $url_image = Display::returnIconPath('session_default.png');
1847
    }
1848
    $_course['course_image_large'] = $url_image;
1849
1850
    $_course['extra_fields'] = isset($course_data['extra_fields']) ? $course_data['extra_fields'] : array();
1851
    $_course['settings'] = isset($course_data['settings']) ? $course_data['settings'] : array();
1852
    $_course['teacher_list'] = isset($course_data['teacher_list']) ? $course_data['teacher_list'] : array();
1853
    $_course['teacher_list_formatted'] = isset($course_data['teacher_list_formatted']) ? $course_data['teacher_list_formatted'] : array();
1854
1855
    return $_course;
1856
}
1857
1858
/**
1859
 * Add a parameter to the existing URL. If this parameter already exists,
1860
 * just replace it with the new value
1861
 * @param   string  The URL
1862
 * @param   string  param=value string
1863
 * @param   boolean Whether to filter XSS or not
1864
 * @return  string  The URL with the added parameter
1865
 */
1866
function api_add_url_param($url, $param, $filter_xss = true) {
1867
    if (empty($param)) {
1868
        return $url;
1869
    }
1870
    if (strpos($url, '?') !== false) {
1871
        if ($param[0] != '&') {
1872
            $param = '&'.$param;
1873
        }
1874
        list (, $query_string) = explode('?', $url);
1875
        $param_list1 = explode('&', $param);
1876
        $param_list2 = explode('&', $query_string);
1877
        $param_list1_keys = $param_list1_vals = array();
1878
        foreach ($param_list1 as $key => $enreg) {
1879
            list ($param_list1_keys[$key], $param_list1_vals[$key]) = explode('=', $enreg);
1880
        }
1881
        $param_list1 = array ('keys' => $param_list1_keys, 'vals' => $param_list1_vals);
1882
        foreach ($param_list2 as $enreg) {
1883
            $enreg = explode('=', $enreg);
1884
            $key = array_search($enreg[0], $param_list1['keys']);
1885
            if (!is_null($key) && !is_bool($key)) {
1886
                $url = str_replace($enreg[0].'='.$enreg[1], $enreg[0].'='.$param_list1['vals'][$key], $url);
1887
                $param = str_replace('&'.$enreg[0].'='.$param_list1['vals'][$key], '', $param);
1888
            }
1889
        }
1890
        $url .= $param;
1891
    } else {
1892
        $url = $url.'?'.$param;
1893
    }
1894
    if ($filter_xss === true) {
1895
        $url = Security::remove_XSS(urldecode($url));
1896
    }
1897
    return $url;
1898
}
1899
1900
/**
1901
 * Returns a difficult to guess password.
1902
 * @param int $length the length of the password
1903
 * @return string the generated password
1904
 */
1905
function api_generate_password($length = 8)
1906
{
1907
    $characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
1908
    $numbers = '23456789';
1909
1910
    if ($length < 2) {
1911
        $length = 2;
1912
    }
1913
    $password = '';
1914
    for ($i = 0; $i < $length; $i ++) {
1915
        $password .= $characters[rand() % strlen($characters)];
1916
    }
1917
1918
    // At least 2 digits
1919
    for ($i = 0; $i < 2; $i ++) {
1920
        $password .= $numbers[rand() % strlen($numbers)];
1921
    }
1922
1923
    return $password;
1924
}
1925
1926
/**
1927
 * Checks a password to see wether it is OK to use.
1928
 * @param string $password
1929
 * @return boolean if the password is acceptable, false otherwise
1930
 * Notes about what a password "OK to use" is:
1931
 * 1. The password should be at least 5 characters long.
1932
 * 2. Only English letters (uppercase or lowercase, it doesn't matter) and digits are allowed.
1933
 * 3. The password should contain at least 3 letters.
1934
 * 4. It should contain at least 2 digits.
1935
 * 5. It should not contain 3 or more consequent (according to ASCII table) characters.
1936
 */
1937
function api_check_password($password) {
1938
    $password_length = api_strlen($password);
1939
    if ($password_length < 5) {
1940
        return false;
1941
    }
1942
    $password = api_strtolower($password);
1943
    $letters = 0;
1944
    $digits = 0;
1945
    $consequent_characters = 0;
1946
    $previous_character_code = 0;
1947
    for ($i = 0; $i < $password_length; $i ++) {
1948
        $current_character_code = api_ord(api_substr($password, $i, 1));
0 ignored issues
show
Security Bug introduced by
It seems like api_substr($password, $i, 1) targeting api_substr() can also be of type false; however, api_ord() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1949
        if ($i && abs($current_character_code - $previous_character_code) <= 1) {
1950
            $consequent_characters ++;
1951
            if ($consequent_characters == 3) {
1952
                return false;
1953
            }
1954
        } else {
1955
            $consequent_characters = 1;
1956
        }
1957
        if ($current_character_code >= 97 && $current_character_code <= 122) {
1958
            $letters ++;
1959
        } elseif ($current_character_code >= 48 && $current_character_code <= 57) {
1960
            $digits ++;
1961
        } else {
1962
            return false;
1963
        }
1964
        $previous_character_code = $current_character_code;
1965
    }
1966
    return ($letters >= 3 && $digits >= 2);
1967
}
1968
1969
/**
1970
 * Clears the user ID from the session if it was the anonymous user. Generally
1971
 * used on out-of-tools pages to remove a user ID that could otherwise be used
1972
 * in the wrong context.
1973
 * This function is to be used in conjunction with the api_set_anonymous()
1974
 * function to simulate the user existence in case of an anonymous visit.
1975
 * @param bool      database check switch - passed to api_is_anonymous()
1976
 * @return bool     true if succesfully unregistered, false if not anonymous.
1977
 */
1978
function api_clear_anonymous($db_check = false)
1979
{
1980
    global $_user;
1981
    if (api_is_anonymous($_user['user_id'], $db_check)) {
1982
        unset($_user['user_id']);
1983
        Session::erase('_uid');
1984
        return true;
1985
    }
1986
    return false;
1987
}
1988
1989
/**
1990
 * Returns the status string corresponding to the status code
1991
 * @author Noel Dieschburg
1992
 * @param the int status code
1993
 */
1994
function get_status_from_code($status_code)
1995
{
1996
    switch ($status_code) {
1997
        case STUDENT:
1998
            return get_lang('Student', '');
1999
        case TEACHER:
2000
            return get_lang('Teacher', '');
2001
        case COURSEMANAGER:
2002
            return get_lang('Manager', '');
2003
        case SESSIONADMIN:
2004
            return get_lang('SessionsAdmin', '');
2005
        case DRH:
2006
            return get_lang('Drh', '');
2007
    }
2008
}
2009
2010
/**
2011
 * Sets the current user as anonymous if it hasn't been identified yet. This
2012
 * function should be used inside a tool only. The function api_clear_anonymous()
2013
 * acts in the opposite direction by clearing the anonymous user's data every
2014
 * time we get on a course homepage or on a neutral page (index, admin, my space)
2015
 * @return bool     true if set user as anonymous, false if user was already logged in or anonymous id could not be found
2016
 */
2017
function api_set_anonymous() {
2018
    global $_user;
2019
2020
    if (!empty($_user['user_id'])) {
2021
        return false;
2022
    }
2023
    $user_id = api_get_anonymous_id();
2024
    if ($user_id == 0) {
2025
        return false;
2026
    }
2027
    Session::erase('_user');
2028
    $_user['user_id'] = $user_id;
2029
    $_user['is_anonymous'] = true;
2030
    $GLOBALS['_user'] = $_user;
2031
    Session::write('_user', $_user);
2032
    return true;
2033
}
2034
2035
/**
2036
 * Gets the current Chamilo (not PHP/cookie) session ID
2037
 * @return  int     O if no active session, the session ID otherwise
2038
 */
2039
function api_get_session_id()
2040
{
2041
    return Session::read('id_session', 0);
2042
}
2043
2044
/**
2045
 * Gets the current Chamilo (not social network) group ID
2046
 * @return  int     O if no active session, the session ID otherwise
2047
 */
2048
function api_get_group_id()
2049
{
2050
    return Session::read('_gid', 0);
2051
}
2052
2053
/**
2054
 * Gets the current or given session name
2055
 * @param   int     Session ID (optional)
2056
 * @return  string  The session name, or null if unfound
2057
 */
2058
function api_get_session_name($session_id = 0)
2059
{
2060
    if (empty($session_id)) {
2061
        $session_id = api_get_session_id();
2062
        if (empty($session_id)) {
2063
            return null;
2064
        }
2065
    }
2066
    $t = Database::get_main_table(TABLE_MAIN_SESSION);
2067
    $s = "SELECT name FROM $t WHERE id = ".(int)$session_id;
2068
    $r = Database::query($s);
2069
    $c = Database::num_rows($r);
2070
    if ($c > 0) {
2071
        //technically, there can be only one, but anyway we take the first
2072
        $rec = Database::fetch_array($r);
2073
        return $rec['name'];
2074
    }
2075
    return null;
2076
}
2077
2078
/**
2079
 * Gets the session info by id
2080
 * @param int       Session ID
2081
 * @return array    information of the session
2082
 */
2083
function api_get_session_info($session_id)
2084
{
2085
    return SessionManager::fetch($session_id);
2086
}
2087
2088
/**
2089
 * Gets the session visibility by session id
2090
 * @param int $session_id
2091
 * @param int $courseId
2092
 * @param bool $ignore_visibility_for_admins
2093
 * @return int
2094
 *  0 = session still available,
2095
 *  SESSION_VISIBLE_READ_ONLY = 1,
2096
 *  SESSION_VISIBLE = 2,
2097
 *  SESSION_INVISIBLE = 3
2098
 */
2099
function api_get_session_visibility(
2100
    $session_id,
2101
    $courseId = null,
2102
    $ignore_visibility_for_admins = true
2103
) {
2104
    // Means that the session is still available.
2105
    $visibility = 0;
2106
2107
    if (api_is_platform_admin()) {
2108
        if ($ignore_visibility_for_admins) {
2109
            return SESSION_AVAILABLE;
2110
        }
2111
    }
2112
2113
    $now = time();
2114
    if (!empty($session_id)) {
2115
        $session_id = intval($session_id);
2116
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2117
2118
        $sql = "SELECT * FROM $tbl_session
2119
                WHERE id = $session_id ";
2120
2121
        $result = Database::query($sql);
2122
2123
        if (Database::num_rows($result) > 0) {
2124
            $row = Database::fetch_array($result, 'ASSOC');
2125
            $visibility = $original_visibility = $row['visibility'];
2126
2127
            // I don't care the session visibility.
2128
            if (empty($row['access_start_date']) && empty($row['access_end_date'])) {
2129
                // Session duration per student.
2130
                if (isset($row['duration']) && !empty($row['duration'])) {
2131
                    $duration = $row['duration'] * 24 * 60 * 60;
2132
2133
                    $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
2134
                        $session_id,
2135
                        api_get_user_id()
2136
                    );
2137
2138
                    // If there is a session duration but there is no previous
2139
                    // access by the user, then the session is still available
2140
                    if (count($courseAccess) == 0) {
2141
                        return SESSION_AVAILABLE;
2142
                    }
2143
2144
                    $currentTime = time();
2145
                    $firstAccess = 0;
2146
                    if (isset($courseAccess['login_course_date'])) {
2147
                        $firstAccess = api_strtotime(
2148
                            $courseAccess['login_course_date'],
2149
                            'UTC'
2150
                        );
2151
                    }
2152
                    $userDurationData = SessionManager::getUserSession(
2153
                        api_get_user_id(),
2154
                        $session_id
2155
                    );
2156
                    $userDuration = 0;
2157
                    if (isset($userDurationData['duration'])) {
2158
                        $userDuration = intval($userDurationData['duration']) * 24 * 60 * 60;
2159
                    }
2160
2161
                    $totalDuration = $firstAccess + $duration + $userDuration;
2162
                    if ($totalDuration > $currentTime) {
2163
                        return SESSION_AVAILABLE;
2164
                    } else {
2165
                        return SESSION_INVISIBLE;
2166
                    }
2167
                }
2168
2169
                return SESSION_AVAILABLE;
2170
            } else {
2171
                // If start date was set.
2172
                if (!empty($row['access_start_date'])) {
2173
                    if ($now > api_strtotime($row['access_start_date'], 'UTC')) {
2174
                        $visibility = SESSION_AVAILABLE;
2175
                    } else {
2176
                        $visibility = SESSION_INVISIBLE;
2177
                    }
2178
                }
2179
2180
                // If the end date was set.
2181
                if (!empty($row['access_end_date'])) {
2182
                    // Only if date_start said that it was ok
2183
                    if ($visibility === SESSION_AVAILABLE) {
2184
                        if ($now < api_strtotime($row['access_end_date'], 'UTC')) {
2185
                            // Date still available
2186
                            $visibility = SESSION_AVAILABLE;
2187
                        } else {
2188
                            // Session ends
2189
                            $visibility = $row['visibility'];
2190
                        }
2191
                    }
2192
                }
2193
            }
2194
2195
            /* If I'm a coach the visibility can change in my favor depending in
2196
             the coach dates */
2197
            $isCoach = api_is_coach($session_id, $courseId);
2198
2199
            if ($isCoach) {
2200
                // Test end date.
2201
                if (!empty($row['coach_access_end_date'])) {
2202
                    $endDateCoach = api_strtotime($row['coach_access_end_date'], 'UTC');
2203
2204
                    if ($endDateCoach >= $now) {
2205
                        $visibility = SESSION_AVAILABLE;
2206
                    } else {
2207
                        $visibility = SESSION_INVISIBLE;
2208
                    }
2209
                }
2210
2211
                // Test start date.
2212
                if (!empty($row['coach_access_start_date'])) {
2213
                    $start = api_strtotime($row['coach_access_start_date'], 'UTC');
2214
                    if ($start < $now) {
2215
                        $visibility = SESSION_AVAILABLE;
2216
                    } else {
2217
                        $visibility = SESSION_INVISIBLE;
2218
                    }
2219
                }
2220
            }
2221
        } else {
2222
            $visibility = SESSION_INVISIBLE;
2223
        }
2224
    }
2225
    return $visibility;
2226
}
2227
2228
/**
2229
 * This function returns a (star) session icon if the session is not null and
2230
 * the user is not a student
2231
 * @param int   $session_id
2232
 * @param int   $status_id User status id - if 5 (student), will return empty
2233
 * @return string   Session icon
2234
 */
2235
function api_get_session_image($session_id, $status_id)
2236
{
2237
    $session_id = (int)$session_id;
2238
    $session_img = '';
2239
    if ((int)$status_id != 5) { //check whether is not a student
2240
        if ($session_id > 0) {
2241
            $session_img = "&nbsp;&nbsp;".Display::return_icon(
2242
                'star.png',
2243
                get_lang('SessionSpecificResource'),
2244
                array('align' => 'absmiddle'),
2245
                ICON_SIZE_SMALL
2246
            );
2247
        }
2248
    }
2249
    return $session_img;
2250
}
2251
2252
/**
2253
 * This function add an additional condition according to the session of the course
2254
 * @param int       $session_id session id
2255
 * @param bool      $and optional, true if more than one condition false if the only condition in the query
2256
 * @param bool      $with_base_content optional, true to accept content with session=0 as well, false for strict session condition
2257
 * @return string   condition of the session
2258
 */
2259
function api_get_session_condition(
2260
    $session_id,
2261
    $and = true,
2262
    $with_base_content = false,
2263
    $session_field = "session_id"
2264
) {
2265
    $session_id = intval($session_id);
2266
2267
    if (empty($session_field)) {
2268
        $session_field = "session_id";
2269
    }
2270
    // Condition to show resources by session
2271
    $condition_add = $and ? " AND " : " WHERE ";
2272
2273
    if ($with_base_content) {
2274
        $condition_session = $condition_add." ( $session_field = $session_id OR $session_field = 0 OR $session_field IS NULL) ";
2275
    } else {
2276
        if (empty($session_id)) {
2277
            $condition_session = $condition_add." ($session_field = $session_id OR $session_field IS NULL)";
2278
        } else {
2279
            $condition_session = $condition_add." $session_field = $session_id ";
2280
        }
2281
    }
2282
    return $condition_session;
2283
}
2284
2285
/**
2286
 * @param string $variable
2287
 * @param string $option
2288
 * @return bool
2289
 */
2290
function api_get_setting_in_list($variable, $option)
2291
{
2292
    $value = api_get_setting($variable);
2293
2294
    return in_array($option, $value);
2295
}
2296
2297
2298
/**
2299
 * Returns the value of a setting from the web-adjustable admin config settings.
2300
 *
2301
 * WARNING true/false are stored as string, so when comparing you need to check e.g.
2302
 * if (api_get_setting('course.show_navigation_menu') == 'true') //CORRECT
2303
 * instead of
2304
 * if (api_get_setting('course.show_navigation_menu') == true) //INCORRECT
2305
 * @param string    $variable The variable name
2306
 * @return string
2307
 *
2308
 * @author Julio Montoya
2309
 */
2310
function api_get_setting($variable)
2311
{
2312
    $variable = trim($variable);
2313
2314
    switch ($variable) {
2315 View Code Duplication
        case 'header_extra_content':
2316
            $filename = api_get_path(SYS_PATH).api_get_home_path().'header_extra_content.txt';
2317
            if (file_exists($filename)) {
2318
                $value = file_get_contents($filename);
2319
                    return $value ;
2320
            } else {
2321
                return '';
2322
            }
2323
            break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
2324 View Code Duplication
        case 'footer_extra_content':
2325
            $filename = api_get_path(SYS_PATH).api_get_home_path().'footer_extra_content.txt';
2326
            if (file_exists($filename)) {
2327
                $value = file_get_contents($filename);
2328
                return $value ;
2329
            } else {
2330
                return '';
2331
            }
2332
            break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
2333
        case 'server_type':
2334
            $test = ['dev', 'test'];
2335
            $environment = Container::getEnvironment();
2336
            if (in_array($environment, $test)) {
2337
                return 'test';
2338
            }
2339
            return 'prod';
2340
        case 'stylesheets':
2341
            $variable = 'platform.theme';
2342
            break;
2343
        // deprecated settings
2344
        case 'openid_authentication':
2345
        case 'sso_authentication':
2346
        case 'service_ppt2lp':
2347
            break;
2348
        default:
2349
            return Container::getSettingsManager()->getSetting($variable);
2350
    }
2351
}
2352
2353
/**
2354
 * @param string $plugin
2355
 * @param string $variable
2356
 * @return string
2357
 */
2358
function api_get_plugin_setting($plugin, $variable)
2359
{
2360
    $variableName = $plugin.'_'.$variable;
2361
    $result = api_get_setting($variableName);
2362
    if (isset($result[$plugin])) {
2363
        return $result[$plugin];
2364
    }
2365
2366
    return null;
2367
}
2368
2369
/**
2370
 * Returns the value of a setting from the web-adjustable admin config settings.
2371
 **/
2372
function api_get_settings_params($params) {
2373
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
2374
    $result = Database::select('*', $table, array('where' => $params));
2375
    return $result;
2376
}
2377
2378
function api_get_settings_params_simple($params) {
2379
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
2380
    $result = Database::select('*', $table, array('where' => $params), 'one');
2381
    return $result;
2382
}
2383
2384
/**
2385
 * Returns the value of a setting from the web-adjustable admin config settings.
2386
 **/
2387
function api_delete_settings_params($params) {
2388
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
2389
    $result = Database::delete($table, $params);
2390
    return $result;
2391
}
2392
2393
/**
2394
 * Returns an escaped version of $_SERVER['PHP_SELF'] to avoid XSS injection
2395
 * @return string   Escaped version of $_SERVER['PHP_SELF']
2396
 */
2397
function api_get_self() {
2398
    return htmlentities($_SERVER['PHP_SELF']);
2399
}
2400
2401
/**
2402
 * Checks whether current user is a platform administrator
2403
 * @param boolean $allowSessionAdmins Whether session admins should be considered admins or not
2404
 * @param boolean $allowDrh Whether HR directors should be considered admins or not
2405
 * @return boolean True if the user has platform admin rights,
2406
 * false otherwise.
2407
 * @see usermanager::is_admin(user_id) for a user-id specific function
2408
 */
2409
function api_is_platform_admin($allowSessionAdmins = false, $allowDrh = false)
2410
{
2411
    $checker = Container::getAuthorizationChecker();
2412
    if ($checker) {
2413
        if ($checker->isGranted('ROLE_ADMIN')) {
2414
        return true;
2415
    }
2416
        if ($allowSessionAdmins) {
2417
            if ($checker->isGranted('ROLE_SESSION_MANAGER')) {
2418
                return true;
2419
            }
2420
        }
2421
    }
2422
2423
    return false;
2424
2425
    $isPlatformAdmin = Session::read('is_platformAdmin');
0 ignored issues
show
Unused Code introduced by
$isPlatformAdmin = \Cham...ad('is_platformAdmin'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
2426
    if ($isPlatformAdmin) {
2427
        return true;
2428
    }
2429
    $_user = api_get_user_info();
2430
2431
    return
2432
        isset($_user['status']) &&
2433
        (
2434
            ($allowSessionAdmins && $_user['status'] == SESSIONADMIN) ||
2435
            ($allowDrh && $_user['status'] == DRH)
2436
        );
2437
}
2438
2439
/**
2440
 * Checks whether the user given as user id is in the admin table.
2441
 * @param int $user_id. If none provided, will use current user
0 ignored issues
show
Documentation introduced by
There is no parameter named $user_id.. Did you maybe mean $user_id?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
2442
 * @param int $url URL ID. If provided, also check if the user is active on given URL
2443
 * @result bool True if the user is admin, false otherwise
2444
 */
2445
function api_is_platform_admin_by_id($user_id = null, $url = null)
2446
{
2447
    $user_id = intval($user_id);
2448
    if (empty($user_id)) {
2449
        $user_id = api_get_user_id();
2450
    }
2451
2452
    $em = Container::getEntityManager();
2453
    $user = $em->getRepository('ChamiloUserBundle:User')->find($user_id);
2454
    $is_admin = $user->hasRole('ROLE_ADMIN');
2455
2456
    if (!$is_admin or !isset($url)) {
2457
        return $is_admin;
2458
    }
2459
2460
    // We get here only if $url is set
2461
    $url = intval($url);
2462
    $url_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
2463
    $sql = "SELECT * FROM $url_user_table
2464
            WHERE access_url_id = $url AND user_id = $user_id";
2465
    $res = Database::query($sql);
2466
    $is_on_url = Database::num_rows($res) === 1;
2467
2468
    return $is_on_url;
2469
}
2470
2471
/**
2472
 * Returns the user's numeric status ID from the users table
2473
 * @param int $user_id If none provided, will use current user
2474
 * @return int User's status (1 for teacher, 5 for student, etc)
2475
 */
2476 View Code Duplication
function api_get_user_status($user_id = null)
2477
{
2478
    $user_id = intval($user_id);
2479
    if (empty($user_id)) {
2480
        $user_id = api_get_user_id();
2481
    }
2482
    $table = Database::get_main_table(TABLE_MAIN_USER);
2483
    $sql = "SELECT status FROM $table WHERE user_id = $user_id ";
2484
    $result = Database::query($sql);
2485
    $status = null;
2486
    if (Database::num_rows($result)) {
2487
        $row = Database::fetch_array($result);
2488
        $status = $row['status'];
2489
    }
2490
    return $status;
2491
}
2492
2493
/**
2494
 * Checks whether current user is allowed to create courses
2495
 * @return boolean True if the user has course creation rights,
2496
 * false otherwise.
2497
 */
2498
function api_is_allowed_to_create_course()
2499
{
2500
    if (api_is_platform_admin()) {
2501
        return true;
2502
    }
2503
2504
    // Teachers can only create courses
2505
    if (api_is_teacher()) {
2506
        if (api_get_setting('allow_users_to_create_courses') === 'true') {
2507
            return true;
2508
        } else {
2509
            return false;
2510
        }
2511
    }
2512
2513
    return Session::read('is_allowedCreateCourse');
2514
}
2515
2516
/**
2517
 * Checks whether the current user is a course administrator
2518
 * @return boolean True if current user is a course administrator
2519
 */
2520
function api_is_course_admin() {
2521
    if (api_is_platform_admin()) {
2522
        return true;
2523
    }
2524
    return Session::read('is_courseAdmin');
2525
}
2526
2527
/**
2528
 * Checks whether the current user is a course coach
2529
 * @return bool     True if current user is a course coach
2530
 */
2531
function api_is_course_coach() {
2532
    return Session::read('is_courseCoach');
2533
}
2534
2535
/**
2536
 * Checks whether the current user is a course tutor
2537
 * @return bool     True if current user is a course tutor
2538
 */
2539
function api_is_course_tutor() {
2540
    return Session::read('is_courseTutor');
2541
}
2542
2543
/**
2544
 * @param int $user_id
2545
 * @param int $courseId
2546
 * @param int $session_id
2547
 * @return bool
2548
 */
2549
function api_is_course_session_coach($user_id, $courseId, $session_id)
2550
{
2551
    $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
2552
    $session_rel_course_rel_user_table  = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2553
2554
    $user_id = intval($user_id);
2555
    $session_id = intval($session_id);
2556
    $courseId = intval($courseId);
2557
2558
    $sql = "SELECT DISTINCT session.id
2559
            FROM $session_table
2560
            INNER JOIN $session_rel_course_rel_user_table session_rc_ru
2561
            ON session.id = session_rc_ru.session_id
2562
            WHERE
2563
                session_rc_ru.user_id = '".$user_id."'  AND
2564
                session_rc_ru.c_id = '$courseId' AND
2565
                session_rc_ru.status = 2 AND
2566
                session_rc_ru.session_id = '$session_id'";
2567
    $result = Database::query($sql);
2568
2569
    return Database::num_rows($result) > 0;
2570
}
2571
2572
/**
2573
 * Checks whether the current user is a course or session coach
2574
 * @param int $session_id
2575
 * @param int $courseId
2576
 * @param bool  Check whether we are in student view and, if we are, return false
2577
 * @return boolean True if current user is a course or session coach
2578
 */
2579
function api_is_coach($session_id = 0, $courseId = null, $check_student_view = true)
2580
{
2581
    $userId = api_get_user_id();
2582
2583
    if (!empty($session_id)) {
2584
        $session_id = intval($session_id);
2585
    } else {
2586
        $session_id = api_get_session_id();
2587
    }
2588
2589
    // The student preview was on
2590 View Code Duplication
    if ($check_student_view &&
2591
        isset($_SESSION['studentview']) && $_SESSION['studentview'] == "studentview"
2592
    ) {
2593
        return false;
2594
    }
2595
2596
    if (!empty($courseId)) {
2597
        $courseId = intval($courseId);
2598
    } else {
2599
        $courseId = api_get_course_int_id();
2600
    }
2601
2602
    $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
2603
    $session_rel_course_rel_user_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2604
    $sessionIsCoach = null;
2605
2606
    if (!empty($courseId)) {
2607
        $sql = "SELECT DISTINCT s.id, name, access_start_date, access_end_date
2608
                FROM $session_table s
2609
                INNER JOIN $session_rel_course_rel_user_table session_rc_ru
2610
                ON session_rc_ru.session_id = s.id AND session_rc_ru.user_id = '".$userId."'
2611
                WHERE
2612
                    session_rc_ru.c_id = '$courseId' AND
2613
                    session_rc_ru.status = 2 AND
2614
                    session_rc_ru.session_id = '$session_id'";
2615
        $result = Database::query($sql);
2616
        $sessionIsCoach = Database::store_result($result);
2617
    }
2618
2619
    if (!empty($session_id)) {
2620
        $sql = "SELECT DISTINCT id, name, access_start_date, access_end_date
2621
                FROM $session_table
2622
                WHERE session.id_coach = $userId AND id = $session_id
2623
                ORDER BY access_start_date, access_end_date, name";
2624
        $result = Database::query($sql);
2625
        if (!empty($sessionIsCoach)) {
2626
            $sessionIsCoach = array_merge($sessionIsCoach , Database::store_result($result));
2627
        } else {
2628
            $sessionIsCoach = Database::store_result($result);
2629
        }
2630
    }
2631
2632
    return (count($sessionIsCoach) > 0);
2633
}
2634
2635
/**
2636
 * Checks whether the current user is a session administrator
2637
 * @return boolean True if current user is a course administrator
2638
 */
2639
function api_is_session_admin()
2640
{
2641
    $user = api_get_user_info();
2642
    return isset($user['status']) && $user['status'] == SESSIONADMIN;
2643
}
2644
2645
/**
2646
 * Checks whether the current user is a human resources manager
2647
 * @return boolean True if current user is a human resources manager
2648
 */
2649
function api_is_drh()
2650
{
2651
    $user = api_get_user_info();
2652
    return isset($user['status']) && $user['status'] == DRH;
2653
}
2654
2655
/**
2656
 * Checks whether the current user is a student
2657
 * @return boolean True if current user is a human resources manager
2658
 */
2659
function api_is_student()
2660
{
2661
    $user = api_get_user_info();
2662
    return isset($user['status']) && $user['status'] == STUDENT;
2663
}
2664
2665
/**
2666
 * Checks whether the current user has the status 'teacher'
2667
 * @return boolean True if current user is a human resources manager
2668
 */
2669
function api_is_teacher()
2670
{
2671
    $user = api_get_user_info();
2672
    return isset($user['status']) && $user['status'] == COURSEMANAGER;
2673
}
2674
2675
/**
2676
 * Checks whether the current user is a invited user
2677
 * @return boolean
2678
 */
2679
function api_is_invitee()
2680
{
2681
    $user = api_get_user_info();
2682
2683
    return isset($user['status']) && $user['status'] == INVITEE;
2684
}
2685
2686
/**
2687
 * This function checks whether a session is assigned into a category
2688
 * @param int       - session id
2689
 * @param string    - category name
2690
 * @return bool     - true if is found, otherwise false
2691
 */
2692
function api_is_session_in_category($session_id, $category_name)
2693
{
2694
    $session_id = intval($session_id);
2695
    $category_name = Database::escape_string($category_name);
2696
2697
    $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2698
    $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2699
2700
    $sql = "SELECT 1
2701
            FROM $tbl_session
2702
            WHERE $session_id IN (
2703
                SELECT s.id FROM $tbl_session s, $tbl_session_category sc
2704
                WHERE
2705
                  s.session_category_id = sc.id AND
2706
                  sc.name LIKE '%$category_name'
2707
            )";
2708
    $rs = Database::query($sql);
2709
2710
    if (Database::num_rows($rs) > 0) {
2711
        return true;
2712
    } else {
2713
        return false;
2714
    }
2715
}
2716
2717
/**
2718
 * Displays the title of a tool.
2719
 * Normal use: parameter is a string:
2720
 * api_display_tool_title("My Tool")
2721
 *
2722
 * Optionally, there can be a subtitle below
2723
 * the normal title, and / or a supra title above the normal title.
2724
 *
2725
 * e.g. supra title:
2726
 * group
2727
 * GROUP PROPERTIES
2728
 *
2729
 * e.g. subtitle:
2730
 * AGENDA
2731
 * calender & events tool
2732
 *
2733
 * @author Hugues Peeters <[email protected]>
2734
 * @param  mixed $title_element - it could either be a string or an array
2735
 *                               containing 'supraTitle', 'mainTitle',
2736
 *                               'subTitle'
2737
 * @return void
2738
 */
2739
function api_display_tool_title($title_element) {
2740
    if (is_string($title_element)) {
2741
        $tit = $title_element;
2742
        unset ($title_element);
2743
        $title_element['mainTitle'] = $tit;
2744
    }
2745
    echo '<h3>';
2746
    if (!empty($title_element['supraTitle'])) {
2747
        echo '<small>'.$title_element['supraTitle'].'</small><br />';
2748
    }
2749
    if (!empty($title_element['mainTitle'])) {
2750
        echo $title_element['mainTitle'];
2751
    }
2752
    if (!empty($title_element['subTitle'])) {
2753
        echo '<br /><small>'.$title_element['subTitle'].'</small>';
2754
    }
2755
    echo '</h3>';
2756
}
2757
2758
/**
2759
 * Displays options for switching between student view and course manager view
2760
 *
2761
 * Changes in version 1.2 (Patrick Cool)
2762
 * Student view switch now behaves as a real switch. It maintains its current state until the state
2763
 * is changed explicitly
2764
 *
2765
 * Changes in version 1.1 (Patrick Cool)
2766
 * student view now works correctly in subfolders of the document tool
2767
 * student view works correctly in the new links tool
2768
 *
2769
 * Example code for using this in your tools:
2770
 * //if ($is_courseAdmin && api_get_setting('student_view_enabled') == 'true') {
2771
 * //   display_tool_view_option($isStudentView);
2772
 * //}
2773
 * //and in later sections, use api_is_allowed_to_edit()
2774
 *
2775
 * @author Roan Embrechts
2776
 * @author Patrick Cool
2777
 * @author Julio Montoya, changes added in Chamilo
2778
 * @version 1.2
2779
 * @todo rewrite code so it is easier to understand
2780
 */
2781
function api_display_tool_view_option() {
2782
    if (api_get_setting('student_view_enabled') != 'true') {
2783
        return '';
2784
    }
2785
2786
    $sourceurl = '';
2787
    $is_framed = false;
2788
    // Exceptions apply for all multi-frames pages
2789
    if (strpos($_SERVER['REQUEST_URI'], 'chat/chat_banner.php') !== false) {
2790
        // The chat is a multiframe bit that doesn't work too well with the student_view, so do not show the link
2791
        return '';
2792
    }
2793
2794
    // Uncomment to remove student view link from document view page
2795
    if (strpos($_SERVER['REQUEST_URI'], 'lp/lp_header.php') !== false) {
2796
        if (empty($_GET['lp_id'])) {
2797
            return '';
2798
        }
2799
        $sourceurl = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?'));
2800
        $sourceurl = str_replace('lp/lp_header.php', 'lp/lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.intval($_GET['lp_id']).'&isStudentView='.($_SESSION['studentview']=='studentview' ? 'false' : 'true'), $sourceurl);
2801
        //showinframes doesn't handle student view anyway...
2802
        //return '';
2803
        $is_framed = true;
2804
    }
2805
2806
    // Check whether the $_SERVER['REQUEST_URI'] contains already url parameters (thus a questionmark)
2807
    if (!$is_framed) {
2808
        if (strpos($_SERVER['REQUEST_URI'], '?') === false) {
2809
            $sourceurl = api_get_self().'?'.api_get_cidreq();
2810
        } else {
2811
            $sourceurl = $_SERVER['REQUEST_URI'];
2812
        }
2813
    }
2814
2815
    $output_string = '';
2816
    if (!empty($_SESSION['studentview'])) {
2817
        if ($_SESSION['studentview'] == 'studentview') {
2818
            // We have to remove the isStudentView=true from the $sourceurl
2819
            $sourceurl = str_replace('&isStudentView=true', '', $sourceurl);
2820
            $sourceurl = str_replace('&isStudentView=false', '', $sourceurl);
2821
            $output_string .= '<a class="btn btn-primary btn-sm" href="'.$sourceurl.'&isStudentView=false" target="_self">'.Display::returnFontAwesomeIcon('eye').' '.get_lang('SwitchToTeacherView').'</a>';
2822
        } elseif ($_SESSION['studentview'] == 'teacherview') {
2823
            // Switching to teacherview
2824
            $sourceurl = str_replace('&isStudentView=true', '', $sourceurl);
2825
            $sourceurl = str_replace('&isStudentView=false', '', $sourceurl);
2826
            $output_string .= '<a class="btn btn-default btn-sm" href="'.$sourceurl.'&isStudentView=true" target="_self">'.Display::returnFontAwesomeIcon('eye').' '.get_lang('SwitchToStudentView').'</a>';
2827
        }
2828
    } else {
2829
        $output_string .= '<a class="btn btn-default btn-sm" href="'.$sourceurl.'&isStudentView=true" target="_self">'.Display::returnFontAwesomeIcon('eye').' '.get_lang('SwitchToStudentView').'</a>';
2830
    }
2831
    $html = Display::tag('div', $output_string, array('class'=>'view-options'));
2832
    return $html;
2833
}
2834
2835
// TODO: This is for the permission section.
2836
/**
2837
 * Function that removes the need to directly use is_courseAdmin global in
2838
 * tool scripts. It returns true or false depending on the user's rights in
2839
 * this particular course.
2840
 * Optionally checking for tutor and coach roles here allows us to use the
2841
 * student_view feature altogether with these roles as well.
2842
 * @param bool  Whether to check if the user has the tutor role
2843
 * @param bool  Whether to check if the user has the coach role
2844
 * @param bool  Whether to check if the user has the session coach role
2845
 * @param bool  check the student view or not
2846
 *
2847
 * @author Roan Embrechts
2848
 * @author Patrick Cool
2849
 * @author Julio Montoya
2850
 * @version 1.1, February 2004
2851
 * @return boolean true: the user has the rights to edit, false: he does not
2852
 */
2853
2854
function api_is_allowed_to_edit(
2855
    $tutor = false,
2856
    $coach = false,
2857
    $session_coach = false,
2858
    $check_student_view = true
2859
) {
2860
    $my_session_id = api_get_session_id();
2861
    $is_allowed_coach_to_edit = api_is_coach(null, null, $check_student_view);
2862
    $session_visibility = api_get_session_visibility($my_session_id);
2863
2864
    // Admins can edit anything.
2865
    if (api_is_platform_admin(false)) {
2866
        //The student preview was on
2867 View Code Duplication
        if ($check_student_view &&
2868
            isset($_SESSION['studentview']) &&
2869
            $_SESSION['studentview'] == "studentview"
2870
        ) {
2871
            return false;
2872
        } else {
2873
            return true;
2874
        }
2875
    }
2876
2877
    $is_courseAdmin = api_is_course_admin();
2878
2879
    if (!$is_courseAdmin && $tutor) {
2880
        // If we also want to check if the user is a tutor...
2881
        $is_courseAdmin = $is_courseAdmin || api_is_course_tutor();
2882
    }
2883
2884
    if (!$is_courseAdmin && $coach) {
2885
        // If we also want to check if the user is a coach...';
2886
        // Check if session visibility is read only for coaches.
2887
        if ($session_visibility == SESSION_VISIBLE_READ_ONLY) {
2888
            $is_allowed_coach_to_edit = false;
2889
        }
2890
2891
        if (api_get_setting('allow_coach_to_edit_course_session') == 'true') {
2892
            // Check if coach is allowed to edit a course.
2893
            $is_courseAdmin = $is_courseAdmin || $is_allowed_coach_to_edit;
2894
        }
2895
    }
2896
2897
    if (!$is_courseAdmin && $session_coach) {
2898
        $is_courseAdmin = $is_courseAdmin || $is_allowed_coach_to_edit;
2899
    }
2900
2901
    // Check if the student_view is enabled, and if so, if it is activated.
2902
    if (api_get_setting('student_view_enabled') == 'true') {
2903
        if (!empty($my_session_id)) {
2904
            // Check if session visibility is read only for coaches.
2905
            if ($session_visibility == SESSION_VISIBLE_READ_ONLY) {
2906
                $is_allowed_coach_to_edit = false;
2907
            }
2908
2909
            if (api_get_setting('allow_coach_to_edit_course_session') == 'true') {
2910
                // Check if coach is allowed to edit a course.
2911
                $is_allowed = $is_allowed_coach_to_edit;
2912
            } else {
2913
                $is_allowed = false;
2914
            }
2915
            if ($check_student_view) {
2916
                $is_allowed = $is_allowed && $_SESSION['studentview'] != 'studentview';
2917
            }
2918
        } else {
2919
            if ($check_student_view) {
2920
                $is_allowed = $is_courseAdmin && $_SESSION['studentview'] != 'studentview';
2921
            } else {
2922
                $is_allowed = $is_courseAdmin;
2923
            }
2924
        }
2925
2926
        return $is_allowed;
2927
    } else {
2928
2929
        return $is_courseAdmin;
2930
    }
2931
}
2932
2933
/**
2934
 * Returns true if user is a course coach of at least one course in session
2935
 * @param int $sessionId
2936
 * @return bool
2937
 */
2938
function api_is_coach_of_course_in_session($sessionId)
2939
{
2940
    if (api_is_platform_admin()) {
2941
        return true;
2942
    }
2943
2944
    $userId = api_get_user_id();
2945
    $courseList = UserManager::get_courses_list_by_session(
2946
        $userId,
2947
        $sessionId
2948
    );
2949
2950
    // Session visibility.
2951
    $visibility = api_get_session_visibility(
2952
        $sessionId,
2953
        null,
2954
        false
2955
    );
2956
2957 View Code Duplication
    if ($visibility != SESSION_VISIBLE && !empty($courseList)) {
2958
        // Course Coach session visibility.
2959
        $blockedCourseCount = 0;
2960
        $closedVisibilityList = array(
2961
            COURSE_VISIBILITY_CLOSED,
2962
            COURSE_VISIBILITY_HIDDEN
2963
        );
2964
2965
        foreach ($courseList as $course) {
2966
            // Checking session visibility
2967
            $sessionCourseVisibility = api_get_session_visibility(
2968
                $sessionId,
2969
                $course['real_id'],
2970
                $ignore_visibility_for_admins
0 ignored issues
show
Bug introduced by
The variable $ignore_visibility_for_admins does not exist. Did you mean $visibility?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
2971
            );
2972
2973
            $courseIsVisible = !in_array(
2974
                $course['visibility'],
2975
                $closedVisibilityList
2976
            );
2977
            if ($courseIsVisible === false || $sessionCourseVisibility == SESSION_INVISIBLE) {
2978
                $blockedCourseCount++;
2979
            }
2980
        }
2981
2982
        // If all courses are blocked then no show in the list.
2983
        if ($blockedCourseCount === count($courseList)) {
2984
            $visibility = SESSION_INVISIBLE;
2985
        } else {
2986
            $visibility = SESSION_VISIBLE;
2987
        }
2988
    }
2989
2990
    switch ($visibility) {
2991
        case SESSION_VISIBLE_READ_ONLY:
2992
        case SESSION_VISIBLE:
2993
        case SESSION_AVAILABLE:
2994
            return true;
2995
            break;
2996
        case SESSION_INVISIBLE:
2997
            return false;
2998
    }
2999
3000
    return false;
3001
}
3002
3003
/**
3004
* Checks if a student can edit contents in a session depending
3005
* on the session visibility
3006
* @param bool $tutor  Whether to check if the user has the tutor role
3007
* @param bool  $coach Whether to check if the user has the coach role
3008
* @return boolean true: the user has the rights to edit, false: he does not
3009
*/
3010
function api_is_allowed_to_session_edit($tutor = false, $coach = false)
3011
{
3012
    if (api_is_allowed_to_edit($tutor, $coach)) {
3013
        // If I'm a teacher, I will return true in order to not affect the normal behaviour of Chamilo tools.
3014
        return true;
3015
    } else {
3016
        if (api_get_session_id() == 0) {
3017
            // I'm not in a session so i will return true to not affect the normal behaviour of Chamilo tools.
3018
            return true;
3019
        } else {
3020
            // I'm in a session and I'm a student
3021
            $session_id = api_get_session_id();
3022
3023
            // Get the session visibility
3024
            $session_visibility = api_get_session_visibility($session_id);
3025
            // if 5 the session is still available
3026
3027
            //@todo We could load the session_rel_course_rel_user permission to increase the level of detail.
3028
            //echo api_get_user_id();
3029
            //echo api_get_course_id();
3030
3031
            switch ($session_visibility) {
3032
                case SESSION_VISIBLE_READ_ONLY: // 1
3033
                    return false;
3034
                case SESSION_VISIBLE:           // 2
3035
                    return true;
3036
                case SESSION_INVISIBLE:         // 3
3037
                    return false;
3038
                case SESSION_AVAILABLE:         //5
3039
                    return true;
3040
            }
3041
        }
3042
    }
3043
}
3044
3045
/**
3046
* Checks whether the user is allowed in a specific tool for a specific action
3047
* @param string $tool the tool we are checking if the user has a certain permission
3048
* @param string $action the action we are checking (add, edit, delete, move, visibility)
3049
* @author Patrick Cool <[email protected]>, Ghent University
3050
* @author Julio Montoya
3051
* @version 1.0
3052
*/
3053
function api_is_allowed($tool, $action, $task_id = 0)
3054
{
3055
    $_user = api_get_user_info();
3056
    $_course = api_get_course_info();
3057
3058
    if (api_is_course_admin()) {
3059
        return true;
3060
    }
3061
    //if (!$_SESSION['total_permissions'][$_course['code']] and $_course)
3062
    if (is_array($_course) and count($_course) > 0) {
3063
        require_once api_get_path(SYS_CODE_PATH).'permissions/permissions_functions.inc.php';
3064
3065
        // Getting the permissions of this user.
3066
        if ($task_id == 0) {
3067
            $user_permissions = get_permissions('user', $_user['user_id']);
3068
            $_SESSION['total_permissions'][$_course['code']] = $user_permissions;
3069
        }
3070
3071
        // Getting the permissions of the task.
3072
        if ($task_id != 0) {
3073
            $task_permissions = get_permissions('task', $task_id);
3074
            /* !!! */$_SESSION['total_permissions'][$_course['code']] = $task_permissions;
3075
        }
3076
        //print_r($_SESSION['total_permissions']);
3077
3078
        // Getting the permissions of the groups of the user
3079
        //$groups_of_user = GroupManager::get_group_ids($_course['db_name'], $_user['user_id']);
3080
3081
        //foreach($groups_of_user as $group)
3082
        //   $this_group_permissions = get_permissions('group', $group);
3083
3084
        // Getting the permissions of the courseroles of the user
3085
        $user_courserole_permissions = get_roles_permissions('user', $_user['user_id']);
3086
3087
        // Getting the permissions of the platformroles of the user
3088
        //$user_platformrole_permissions = get_roles_permissions('user', $_user['user_id'], ', platform');
3089
3090
        // Getting the permissions of the roles of the groups of the user
3091
        //foreach($groups_of_user as $group)
3092
        //    $this_group_courserole_permissions = get_roles_permissions('group', $group);
3093
3094
        // Getting the permissions of the platformroles of the groups of the user
3095
        //foreach($groups_of_user as $group)
3096
        //    $this_group_platformrole_permissions = get_roles_permissions('group', $group, 'platform');
3097
    }
3098
3099
    // If the permissions are limited, we have to map the extended ones to the limited ones.
3100
    if (api_get_setting('permissions') == 'limited') {
3101
        if ($action == 'Visibility') {
3102
            $action = 'Edit';
3103
        }
3104
        if ($action == 'Move') {
3105
            $action = 'Edit';
3106
        }
3107
    }
3108
3109
    // The session that contains all the permissions already exists for this course
3110
    // so there is no need to requery everything.
3111
    //my_print_r($_SESSION['total_permissions'][$_course['code']][$tool]);
3112
    if (is_array($_SESSION['total_permissions'][$_course['code']][$tool])) {
3113
        if (in_array($action, $_SESSION['total_permissions'][$_course['code']][$tool])) {
3114
            return true;
3115
        } else {
3116
            return false;
3117
        }
3118
    }
3119
}
3120
3121
/**
3122
 * Tells whether this user is an anonymous user
3123
 * @param int  $user_id      User ID (optional, will take session ID if not provided)
3124
 * @param bool $db_check     Whether to check in the database (true) or simply in
3125
 * the session (false) to see if the current user is the anonymous user
3126
 * @return bool     true if this user is anonymous, false otherwise
3127
 */
3128
function api_is_anonymous($user_id = null, $db_check = false)
3129
{
3130
    if (!isset($user_id)) {
3131
        $user_id = api_get_user_id();
3132
    }
3133
3134
    if ($db_check) {
3135
        $info = api_get_user_info($user_id);
3136
        if ($info['status'] == ANONYMOUS) {
3137
            return true;
3138
        }
3139
    }
3140
3141
    $_user = api_get_user_info();
3142
3143
    if (isset($_user['status']) && $_user['status'] == ANONYMOUS) {
3144
        //if ($_user['user_id'] == 0) {
3145
        // In some cases, api_set_anonymous doesn't seem to be triggered in local.inc.php. Make sure it is.
3146
        // Occurs in agenda for admin links - YW
3147
        global $use_anonymous;
3148
        if (isset($use_anonymous) && $use_anonymous) {
3149
            api_set_anonymous();
3150
        }
3151
3152
        return true;
3153
    }
3154
3155
    return (isset($_user['is_anonymous']) && $_user['is_anonymous'] === true) || $_user === false;
3156
}
3157
3158
/**
3159
 * Displays message "You are not allowed here..." and exits the entire script.
3160
 * @param bool   $print_headers    Whether or not to print headers (default = false -> does not print them)
3161
 * @param string $message
3162
 */
3163
function api_not_allowed($print_headers = false, $message = null)
3164
{
3165
    if (empty($message)) {
3166
        $message = get_lang('NotAllowed');
3167
    }
3168
    throw new Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException($message);
3169
3170
    if (api_get_setting('sso_authentication') === 'true') {
0 ignored issues
show
Unused Code introduced by
if (api_get_setting('sso...osso->logout(); } } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
3171
        global $osso;
3172
        if ($osso) {
3173
            $osso->logout();
3174
        }
3175
    }
3176
    $home_url = api_get_path(WEB_PATH);
3177
    $user_id = api_get_user_id();
3178
    $course = api_get_course_id();
3179
3180
    global $this_section;
3181
3182
    if (CustomPages::enabled() && !isset($user_id)) {
3183
3184
        if (empty($user_id)) {
3185
            // Why the CustomPages::enabled() need to be to set the request_uri
3186
            $_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
3187
        }
3188
3189
        CustomPages::display(CustomPages::INDEX_UNLOGGED);
3190
    }
3191
3192
    $origin = isset($_GET['origin']) ? $_GET['origin'] : '';
3193
3194
    $msg = null;
3195
    if (isset($message)) {
3196
        $msg = $message;
3197 View Code Duplication
    } else {
3198
        $msg = Display::return_message(
3199
            get_lang('NotAllowedClickBack').'<br/><br/><a href="'.$home_url.'">'.get_lang('ReturnToCourseHomepage').'</a>',
3200
            'error',
3201
            false
3202
        );
3203
    }
3204
3205
    $msg = Display::div($msg, array('align'=>'center'));
3206
3207
    $show_headers = 0;
3208
3209
    if ($print_headers && $origin != 'learnpath') {
3210
        $show_headers = 1;
3211
    }
3212
3213
    $tpl = new Template(null, $show_headers, $show_headers);
3214
    $tpl->assign('hide_login_link', 1);
3215
    $tpl->assign('content', $msg);
3216
3217
    if (($user_id != 0 && !api_is_anonymous()) &&
3218
        (!isset($course) || $course == -1) &&
3219
        empty($_GET['cidReq'])
3220
    ) {
3221
        // if the access is not authorized and there is some login information
3222
        // but the cidReq is not found, assume we are missing course data and send the user
3223
        // to the user_portal
3224
        $tpl->display_one_col_template();
3225
        exit;
3226
    }
3227
3228
    if (!empty($_SERVER['REQUEST_URI']) &&
3229
        (!empty($_GET['cidReq']) ||
3230
            $this_section == SECTION_MYPROFILE ||
3231
            $this_section == SECTION_PLATFORM_ADMIN
3232
        )
3233
    ) {
3234
        $courseCode = api_get_course_id();
3235
        // Only display form and return to the previous URL if there was a course ID included
3236
        if ($user_id != 0 && !api_is_anonymous()) {
3237
            //if there is a user ID, then the user is not allowed but the session is still there. Say so and exit
3238
            $tpl->assign('content', $msg);
3239
            $tpl->display_one_col_template();
3240
            exit;
3241
        }
3242
3243
        if (!is_null($courseCode)) {
3244
            api_set_firstpage_parameter($courseCode);
3245
        }
3246
3247
        // If the user has no user ID, then his session has expired
3248
        $action = api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']);
3249
        $action = str_replace('&amp;', '&', $action);
3250
        $form = new FormValidator(
3251
            'formLogin',
3252
            'post',
3253
            $action,
3254
            null,
3255
            array(),
3256
            FormValidator::LAYOUT_BOX_NO_LABEL
3257
        );
3258
        $form->addElement(
3259
            'text',
3260
            'login',
3261
            null,
3262
            array('placeholder' => get_lang('UserName'), 'autocapitalize' => 'none')
3263
        );
3264
        $form->addElement(
3265
            'password',
3266
            'password',
3267
            null,
3268
            array('placeholder' => get_lang('Password'), 'autocapitalize' => 'none')
3269
        );
3270
        $form->addButton('submitAuth', get_lang('LoginEnter'), '', 'primary');
3271
3272
        // see same text in auth/gotocourse.php and main_api.lib.php function api_not_allowed (above)
3273
        $content = Display::return_message(get_lang('NotAllowed'), 'error', false);
3274
3275
        if (!empty($courseCode)) {
3276
            $content .= '<h4>'.get_lang('LoginToGoToThisCourse').'</h4>';
3277
        }
3278
3279
        if (api_is_cas_activated()) {
3280
            $content .= Display::return_message(sprintf(get_lang('YouHaveAnInstitutionalAccount'), api_get_setting("Institution")), '', false);
3281
            $content .= Display::div("<br/><a href='".get_cas_direct_URL(api_get_course_id())."'>".sprintf(get_lang('LoginWithYourAccount'), api_get_setting("Institution"))."</a><br/><br/>", array('align'=>'center'));
3282
            $content .= Display::return_message(get_lang('YouDontHaveAnInstitutionAccount'));
3283
            $content .= "<p style='text-align:center'><a href='#' onclick='$(this).parent().next().toggle()'>".get_lang('LoginWithExternalAccount')."</a></p>";
3284
            $content .= "<div style='display:none;'>";
3285
        }
3286
        $content .= '<div class="well">';
3287
        $content .= $form->returnForm();
3288
        $content .='</div>';
3289
        if (api_is_cas_activated()) {
3290
            $content .= "</div>";
3291
        }
3292
3293
        if (!empty($courseCode)) {
3294
            $content .= '<hr/><p style="text-align:center"><a href="'.$home_url.'">'.
3295
                get_lang('ReturnToCourseHomepage').'</a></p>';
3296
        } else {
3297
            $content .= '<hr/><p style="text-align:center"><a href="'.$home_url.'">'.
3298
                get_lang('BackHome').'</a></p>';
3299
        }
3300
3301
        $tpl->setLoginBodyClass();
3302
        $tpl->assign('content', $content);
3303
        $tpl->display_one_col_template();
3304
        exit;
3305
    }
3306
3307
    if ($user_id != 0 && !api_is_anonymous()) {
3308
        $tpl->display_one_col_template();
3309
        exit;
3310
    }
3311
3312
    $msg = null;
3313
3314
    // The session is over and we were not in a course,
3315
    // or we try to get directly to a private course without being logged
3316
    $courseId = api_get_course_int_id();
3317
    if (!empty($courseId)) {
3318
        api_set_firstpage_parameter(api_get_course_id());
3319
        $tpl->setLoginBodyClass();
3320
        $action = api_get_self().'?'.Security::remove_XSS($_SERVER['QUERY_STRING']);
3321
        $action = str_replace('&amp;', '&', $action);
3322
        $form = new FormValidator('formLogin', 'post', $action, null, array('class'=>'form-stacked'));
3323
        $form->addElement('text', 'login', null, array('autocapitalize' => 'none', 'placeholder' => get_lang('UserName'), 'class' => 'col-md-3'));
3324
        $form->addElement('password', 'password', null, array('placeholder' => get_lang('Password'), 'class' => 'col-md-3')); //new
3325
        $form->addButtonNext(get_lang('LoginEnter'), 'submitAuth');
3326
3327
        // see same text in auth/gotocourse.php and main_api.lib.php function api_not_allowed (bellow)
3328
        $msg = Display::return_message(get_lang('NotAllowed'), 'error', false);
3329
        $msg .= '<h4>'.get_lang('LoginToGoToThisCourse').'</h4>';
3330
        $casEnabled = api_is_cas_activated();
3331
        if ($casEnabled) {
3332
            $msg .= Display::return_message(sprintf(get_lang('YouHaveAnInstitutionalAccount'), api_get_setting("Institution")), '', false);
3333
            $msg .= Display::div("<br/><a href='".get_cas_direct_URL(api_get_course_int_id())."'>".getCASLogoHTML()." ".sprintf(get_lang('LoginWithYourAccount'), api_get_setting("Institution"))."</a><br/><br/>", array('align'=>'center'));
3334
            $msg .= Display::return_message(get_lang('YouDontHaveAnInstitutionAccount'));
3335
            $msg .= "<p style='text-align:center'><a href='#' onclick='$(this).parent().next().toggle()'>".get_lang('LoginWithExternalAccount')."</a></p>";
3336
            $msg .= "<div style='display:none;'>";
3337
        }
3338
        $msg .= '<div class="well">';
3339
        $msg .= $form->returnForm();
3340
        $msg .='</div>';
3341
        if ($casEnabled) {
3342
            $msg .= "</div>";
3343
        }
3344 View Code Duplication
    } else {
3345
        // we were not in a course, return to home page
3346
        $msg = Display::return_message(
3347
            get_lang('NotAllowed').'<br/><br/><a href="'.$home_url.'">'.get_lang('BackHome').'</a><br />',
3348
            'error',
3349
            false
3350
        );
3351
    }
3352
3353
    $tpl->assign('content', $msg);
3354
    $tpl->display_one_col_template();
3355
    exit;
3356
}
3357
3358
/**
3359
 * Gets a UNIX timestamp from a database (MySQL) datetime format string
3360
 * @param $last_post_datetime standard output date in a sql query
3361
 * @return integer timestamp
3362
 * @author Toon Van Hoecke <[email protected]>
3363
 * @version October 2003
3364
 * @desc convert sql date to unix timestamp
3365
 */
3366
function convert_sql_date($last_post_datetime) {
3367
    list ($last_post_date, $last_post_time) = explode(' ', $last_post_datetime);
3368
    list ($year, $month, $day) = explode('-', $last_post_date);
3369
    list ($hour, $min, $sec) = explode(':', $last_post_time);
3370
    return mktime((int)$hour, (int)$min, (int)$sec, (int)$month, (int)$day, (int)$year);
3371
}
3372
3373
/**
3374
 * Gets item visibility from the item_property table
3375
 *
3376
 * Getting the visibility is done by getting the last updated visibility entry,
3377
 * using the largest session ID found if session 0 and another was found (meaning
3378
 * the only one that is actually from the session, in case there are results from
3379
 * session 0 *AND* session n).
3380
 * @param array     Course properties array (result of api_get_course_info())
3381
 * @param string    Tool (learnpath, document, etc)
3382
 * @param int       The item ID in the given tool
3383
 * @param int       The session ID (optional)
3384
 * @param string $tool
3385
 * @param integer $user_id
3386
 * @param string $type
3387
 * @return int      -1 on error, 0 if invisible, 1 if visible
3388
 */
3389
function api_get_item_visibility(
3390
    $_course,
3391
    $tool,
3392
    $id,
3393
    $session = 0,
3394
    $user_id = null,
3395
    $type = null,
3396
    $group_id = null
3397
) {
3398
    if (!is_array($_course) || count($_course) == 0 || empty($tool) || empty($id)) {
3399
        return -1;
3400
    }
3401
3402
    $tool = Database::escape_string($tool);
3403
    $id = intval($id);
3404
    $session = (int) $session;
3405
    $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
3406
    $course_id = intval($_course['real_id']);
3407
3408
    $userCondition = '';
3409
    if (!empty($user_id)) {
3410
        $user_id = intval($user_id);
3411
        $userCondition = " AND to_user_id = $user_id ";
3412
    }
3413
3414
    $typeCondition = '';
3415
    if (!empty($type)) {
3416
        $type = Database::escape_string($type);
3417
        $typeCondition = " AND lastedit_type = '$type' ";
3418
    }
3419
3420
    $groupCondition = '';
3421
    if (!empty($group_id)) {
3422
        $group_id = intval($group_id);
3423
        $groupCondition = " AND to_group_id = '$group_id' ";
3424
    }
3425
3426
    $sql = "SELECT visibility
3427
            FROM $TABLE_ITEMPROPERTY
3428
            WHERE
3429
                c_id = $course_id AND
3430
                tool = '$tool' AND
3431
                ref = $id AND
3432
                (session_id = $session OR session_id = 0 OR session_id IS NULL)
3433
                $userCondition $typeCondition $groupCondition
3434
            ORDER BY session_id DESC, lastedit_date DESC
3435
            LIMIT 1";
3436
3437
    $res = Database::query($sql);
3438
    if ($res === false || Database::num_rows($res) == 0) {
3439
        return -1;
3440
    }
3441
    $row = Database::fetch_array($res);
3442
3443
    return $row['visibility'];
3444
}
3445
3446
/**
3447
 * Delete a row in the c_item_property table
3448
 *
3449
 * @param array $courseInfo
3450
 * @param string $tool
3451
 * @param int $itemId
3452
 * @param int $userId
3453
 * @param int $groupId
3454
 * @param int $sessionId
3455
 * @return false|null
3456
 */
3457
function api_item_property_delete(
3458
    $courseInfo,
3459
    $tool,
3460
    $itemId,
3461
    $userId,
3462
    $groupId = 0,
3463
    $sessionId = 0
3464
) {
3465
    if (empty($courseInfo)) {
3466
        return false;
3467
    }
3468
3469
    $courseId = intval($courseInfo['real_id']);
3470
3471
    if (empty($courseId) || empty($tool) || empty($itemId)) {
3472
        return false;
3473
    }
3474
3475
    $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
3476
    $tool = Database::escape_string($tool);
3477
    $itemId = intval($itemId);
3478
    $userId = intval($userId);
3479
    $groupId = intval($groupId);
3480
    $sessionId = intval($sessionId);
3481
3482
    $groupCondition = " AND to_group_id = $groupId ";
3483
    if (empty($groupId)) {
3484
        $groupCondition = " AND (to_group_id is NULL OR to_group_id = 0) ";
3485
    }
3486
3487
    $userCondition = " AND to_user_id = $userId ";
3488
    if (empty($userId)) {
3489
        $userCondition = " AND (to_user_id is NULL OR to_user_id = 0) ";
3490
    }
3491
    $sessionCondition = api_get_session_condition($sessionId, true, false, 'session_id');
3492
    $sql = "DELETE FROM $table
3493
            WHERE
3494
                c_id = $courseId AND
3495
                tool  = '$tool' AND
3496
                ref = $itemId
3497
                $sessionCondition
3498
                $userCondition
3499
                $groupCondition
3500
            ";
3501
3502
    Database::query($sql);
3503
}
3504
3505
/**
3506
 * Updates or adds item properties to the Item_propetry table
3507
 * Tool and lastedit_type are language independant strings (langvars->get_lang!)
3508
 *
3509
 * @param array $_course array with course properties
3510
 * @param string $tool tool id, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
3511
 * @param int $item_id id of the item itself, linked to key of every tool ('id', ...)
3512
 * @param string $last_edit_type add or update action
3513
 * (1) message to be translated (in trad4all) : e.g. DocumentAdded, DocumentUpdated;
3514
 * (2) "delete"
3515
 * (3) "visible"
3516
 * (4) "invisible"
3517
 * @param int $user_id id of the editing/adding user
3518
 * @param int $to_group_id group.iid
3519
 * @param int $to_user_id id of the intended user (always has priority over $to_group_id !), only relevant for $type (1)
3520
 * @param string $start_visible 0000-00-00 00:00:00 format
3521
 * @param string $end_visible 0000-00-00 00:00:00 format
3522
 * @param int $session_id The session ID, if any, otherwise will default to 0
3523
 * @return boolean False if update fails.
3524
 * @author Toon Van Hoecke <[email protected]>, Ghent University
3525
 * @version January 2005
3526
 * @desc update the item_properties table (if entry not exists, insert) of the course
3527
 */
3528
function api_item_property_update(
3529
    $_course,
3530
    $tool,
3531
    $item_id,
3532
    $last_edit_type,
3533
    $user_id,
3534
    $to_group_id = 0,
3535
    $to_user_id = null,
3536
    $start_visible = '',
3537
    $end_visible = '',
3538
    $session_id = 0
3539
) {
3540
    if (empty($_course)) {
3541
        return false;
3542
    }
3543
3544
    $course_id = $_course['real_id'];
3545
3546
    if (empty($course_id)) {
3547
        return false;
3548
    }
3549
3550
    $em = Database::getManager();
3551
3552
    // Definition of variables.
3553
    $tool = Database::escape_string($tool);
3554
    $item_id = intval($item_id);
3555
    $lastEditTypeNoFilter = $last_edit_type;
3556
    $last_edit_type = Database::escape_string($last_edit_type);
3557
    $user_id = intval($user_id);
3558
3559
    $startVisible = "NULL";
3560
    if (!empty($start_visible)) {
3561
        $start_visible = Database::escape_string($start_visible);
3562
        $startVisible = "'$start_visible'";
3563
    }
3564
3565
    $endVisible = "NULL";
3566
    if (!empty($end_visible)) {
3567
        $end_visible = Database::escape_string($end_visible);
3568
        $endVisible = "'$end_visible'";
3569
    }
3570
3571
    $to_filter = '';
3572
    $time = api_get_utc_datetime();
3573
3574
    if (!empty($session_id)) {
3575
        $session_id = intval($session_id);
3576
    } else {
3577
        $session_id = api_get_session_id();
3578
    }
3579
3580
    // Definition of tables.
3581
    $tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
3582
3583
    if ($to_user_id <= 0) {
3584
        $to_user_id = null; // No to_user_id set
3585
    }
3586
3587
    if (!is_null($to_user_id)) {
3588
        // $to_user_id has more priority than $to_group_id
3589
        $to_user_id = intval($to_user_id);
3590
        $to_field = 'to_user_id';
3591
        $to_value = $to_user_id;
3592
    } else {
3593
        // $to_user_id is not set.
3594
        $to_field = 'to_group_id';
3595
        $to_value = $to_group_id;
3596
    }
3597
3598
    $toValueCondition = empty($to_value) ? "NULL" : "'$to_value'";
3599
3600
    // Set filters for $to_user_id and $to_group_id, with priority for $to_user_id
3601
    $condition_session = " AND session_id = $session_id ";
3602
    if (empty($session_id)) {
3603
        $condition_session = " AND (session_id = 0 OR session_id IS NULL) ";
3604
    }
3605
3606
    $filter = " c_id = $course_id AND tool = '$tool' AND ref = $item_id $condition_session ";
3607
3608
    // Check whether $to_user_id and $to_group_id are passed in the function call.
3609
    // If both are not passed (both are null) then it is a message for everybody and $to_group_id should be 0 !
3610
    if (is_null($to_user_id) && is_null($to_group_id)) {
3611
        $to_group_id = 0;
3612
    }
3613
3614
    if (!is_null($to_user_id)) {
3615
        // Set filter to intended user.
3616
        $to_filter = " AND to_user_id = $to_user_id $condition_session";
3617
    } else {
3618
        // Set filter to intended group.
3619
        if (($to_group_id != 0) && $to_group_id == strval(intval($to_group_id))) {
3620
            $to_filter = " AND to_group_id = $to_group_id $condition_session";
3621
        }
3622
    }
3623
3624
    // Adding filter if set.
3625
    $filter .= $to_filter;
3626
3627
    // Update if possible
3628
    $set_type = '';
3629
3630
    switch ($lastEditTypeNoFilter) {
3631 View Code Duplication
        case 'delete':
3632
            // delete = make item only visible for the platform admin.
3633
            $visibility = '2';
3634
            if (!empty($session_id)) {
3635
                // Check whether session id already exist into item_properties for updating visibility or add it.
3636
                $sql = "SELECT session_id FROM $tableItemProperty
3637
                        WHERE
3638
                            c_id = $course_id AND
3639
                            tool = '$tool' AND
3640
                            ref = $item_id AND
3641
                            session_id = $session_id";
3642
                $rs = Database::query($sql);
3643
                if (Database::num_rows($rs) > 0) {
3644
                    $sql = "UPDATE $tableItemProperty
3645
                            SET lastedit_type       = '".str_replace('_', '', ucwords($tool))."Deleted',
3646
                                lastedit_date       = '$time',
3647
                                lastedit_user_id    = $user_id,
3648
                                visibility          = $visibility,
3649
                                session_id          = $session_id $set_type
3650
                            WHERE $filter";
3651
                    $result = Database::query($sql);
3652
                } else {
3653
                    $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id, $to_field, visibility, start_visible, end_visible, session_id)
3654
                            VALUES ($course_id, '$tool',$item_id, '$time', $user_id, '$time', '$last_edit_type',$user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)";
3655
                    $result = Database::query($sql);
3656
                    $id = Database::insert_id();
3657
                    if ($id) {
3658
                        $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id";
3659
                        Database::query($sql);
3660
                    }
3661
                }
3662
            } else {
3663
                $sql = "UPDATE $tableItemProperty
3664
                        SET
3665
                            lastedit_type='".str_replace('_', '', ucwords($tool))."Deleted',
3666
                            lastedit_date='$time',
3667
                            lastedit_user_id = $user_id,
3668
                            visibility = $visibility $set_type
3669
                        WHERE $filter";
3670
                $result = Database::query($sql);
3671
            }
3672
            break;
3673 View Code Duplication
        case 'visible' : // Change item to visible.
3674
            $visibility = '1';
3675
            if (!empty($session_id)) {
3676
                // Check whether session id already exist into item_properties for updating visibility or add it.
3677
                $sql = "SELECT session_id FROM $tableItemProperty
3678
                        WHERE
3679
                            c_id = $course_id AND
3680
                            tool = '$tool' AND
3681
                            ref = $item_id AND
3682
                            session_id = $session_id";
3683
                $rs = Database::query($sql);
3684
                if (Database::num_rows($rs) > 0) {
3685
                    $sql = "UPDATE $tableItemProperty
3686
                            SET
3687
                                lastedit_type='".str_replace('_', '', ucwords($tool))."Visible',
3688
                                lastedit_date='$time',
3689
                                lastedit_user_id = $user_id,
3690
                                visibility = $visibility,
3691
                                session_id = $session_id $set_type
3692
                            WHERE $filter";
3693
                    $result = Database::query($sql);
3694
                } else {
3695
                    $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id, $to_field, visibility, start_visible, end_visible, session_id)
3696
                            VALUES ($course_id, '$tool', $item_id, '$time', $user_id, '$time', '$last_edit_type', $user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)";
3697
                    $result = Database::query($sql);
3698
                    $id = Database::insert_id();
3699
                    if ($id) {
3700
                        $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id";
3701
                        Database::query($sql);
3702
                    }
3703
                }
3704
            } else {
3705
                $sql = "UPDATE $tableItemProperty
3706
                        SET
3707
                            lastedit_type='".str_replace('_', '', ucwords($tool))."Visible',
3708
                            lastedit_date='$time',
3709
                            lastedit_user_id = $user_id,
3710
                            visibility = $visibility $set_type
3711
                        WHERE $filter";
3712
                $result = Database::query($sql);
3713
            }
3714
            break;
3715 View Code Duplication
        case 'invisible' : // Change item to invisible.
3716
            $visibility = '0';
3717
            if (!empty($session_id)) {
3718
                // Check whether session id already exist into item_properties for updating visibility or add it
3719
                $sql = "SELECT session_id FROM $tableItemProperty
3720
                        WHERE
3721
                            c_id = $course_id AND
3722
                            tool = '$tool' AND
3723
                            ref = $item_id AND
3724
                            session_id = $session_id";
3725
                $rs = Database::query($sql);
3726
                if (Database::num_rows($rs) > 0) {
3727
                    $sql = "UPDATE $tableItemProperty
3728
                            SET
3729
                                lastedit_type = '".str_replace('_', '', ucwords($tool))."Invisible',
3730
                                lastedit_date = '$time',
3731
                                lastedit_user_id = $user_id,
3732
                                visibility = $visibility,
3733
                                session_id = $session_id $set_type
3734
                            WHERE $filter";
3735
                    $result = Database::query($sql);
3736
                } else {
3737
                    $sql = "INSERT INTO $tableItemProperty (c_id, tool, ref, insert_date, insert_user_id, lastedit_date, lastedit_type, lastedit_user_id,$to_field, visibility, start_visible, end_visible, session_id)
3738
                            VALUES ($course_id, '$tool', $item_id, '$time', $user_id, '$time', '$last_edit_type', $user_id, $toValueCondition, $visibility, $startVisible, $endVisible, $session_id)";
3739
                    $result = Database::query($sql);
3740
                    $id = Database::insert_id();
3741
                    if ($id) {
3742
                        $sql = "UPDATE $tableItemProperty SET id = iid WHERE iid = $id";
3743
                        Database::query($sql);
3744
                    }
3745
                }
3746
            } else {
3747
                $sql = "UPDATE $tableItemProperty
3748
                        SET
3749
                            lastedit_type = '".str_replace('_', '', ucwords($tool))."Invisible',
3750
                            lastedit_date = '$time',
3751
                            lastedit_user_id = $user_id,
3752
                            visibility = $visibility $set_type
3753
                        WHERE $filter";
3754
                $result = Database::query($sql);
3755
            }
3756
            break;
3757
        default: // The item will be added or updated.
3758
            $set_type = ", lastedit_type = '$last_edit_type' ";
3759
            $visibility = '1';
3760
            //$filter .= $to_filter; already added
3761
            $sql = "UPDATE $tableItemProperty
3762
                    SET
3763
                      lastedit_date = '$time',
3764
                      lastedit_user_id = $user_id $set_type
3765
                    WHERE $filter";
3766
            $result = Database::query($sql);
3767
    }
3768
3769
    // Insert if no entries are found (can only happen in case of $last_edit_type switch is 'default').
3770
    if ($result == false || Database::affected_rows($result) == 0) {
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, affected_rows() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
3771
        $objCourse = $em->find('ChamiloCoreBundle:Course', intval($course_id));
3772
        $objTime = new DateTime('now', new DateTimeZone('UTC'));
3773
        $objUser = $em->find('ChamiloUserBundle:User', intval($user_id));
3774
        $objGroup = $em->find('ChamiloCourseBundle:CGroupInfo', intval($to_group_id));
3775
        $objToUser = $em->find('ChamiloUserBundle:User', intval($to_user_id));
3776
        $objSession = $em->find('ChamiloCoreBundle:Session', intval($session_id));
3777
3778
        $startVisibleDate = !empty($start_visible) ? new DateTime($start_visible, new DateTimeZone('UTC')) : null;
3779
        $endVisibleDate = !empty($endVisibleDate) ? new DateTime($endVisibleDate, new DateTimeZone('UTC')) : null;
0 ignored issues
show
Bug introduced by
The variable $endVisibleDate seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
3780
3781
        $cItemProperty = new CItemProperty($objCourse);
3782
        $cItemProperty
3783
            ->setTool($tool)
3784
            ->setRef($item_id)
3785
            ->setInsertDate($objTime)
3786
            ->setInsertUser($objUser)
3787
            ->setLasteditDate($objTime)
3788
            ->setLasteditType($last_edit_type)
3789
            ->setGroup($objGroup)
3790
            ->setToUser($objToUser)
3791
            ->setVisibility($visibility)
3792
            ->setStartVisible($startVisibleDate)
3793
            ->setEndVisible($endVisibleDate)
3794
            ->setSession($objSession);
3795
3796
        $em->persist($cItemProperty);
3797
        $em->flush();
3798
3799
        $id = $cItemProperty->getIid();
3800
3801
        if ($id) {
3802
            $cItemProperty->setId($id);
3803
            $em->merge($cItemProperty);
3804
            $em->flush();
3805
3806
            return false;
3807
        }
3808
    }
3809
3810
    return true;
3811
}
3812
3813
/**
3814
 * Gets item property by tool
3815
 * @param string    course code
3816
 * @param string    tool name, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
3817
 * @param int       id of the item itself, linked to key of every tool ('id', ...), "*" = all items of the tool
3818
 * @param int $session_id
3819
 * @param string $tool
3820
 * @param string $course_code
3821
 * @return array All fields from c_item_property (all rows found) or empty array
3822
 */
3823 View Code Duplication
function api_get_item_property_by_tool($tool, $course_code, $session_id = null)
3824
{
3825
    $course_info = api_get_course_info($course_code);
3826
    $tool = Database::escape_string($tool);
3827
3828
    // Definition of tables.
3829
    $item_property_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
3830
    $session_id = intval($session_id);
3831
    $session_condition = ' AND session_id = '.$session_id;
3832
    if (empty($session_id)) {
3833
        $session_condition = " AND (session_id = 0 OR session_id IS NULL) ";
3834
    }
3835
    $course_id = $course_info['real_id'];
3836
3837
    $sql = "SELECT * FROM $item_property_table
3838
            WHERE
3839
                c_id = $course_id AND
3840
                tool = '$tool'
3841
                $session_condition ";
3842
    $rs  = Database::query($sql);
3843
    $list = array();
3844
    if (Database::num_rows($rs) > 0) {
3845
        while ($row = Database::fetch_array($rs, 'ASSOC')) {
3846
            $list[] = $row;
3847
        }
3848
    }
3849
    return $list;
3850
}
3851
3852
/**
3853
 * Gets item property by tool and user
3854
 * @param int $userId
3855
 * @param int $tool
3856
 * @param int $courseId
3857
 * @param int $session_id
3858
 * @return array
3859
 */
3860 View Code Duplication
function api_get_item_property_list_by_tool_by_user(
3861
    $userId,
3862
    $tool,
3863
    $courseId,
3864
    $session_id = 0
3865
) {
3866
    $userId = intval($userId);
3867
    $tool = Database::escape_string($tool);
3868
    $session_id = intval($session_id);
3869
    $courseId = intval($courseId);
3870
3871
    // Definition of tables.
3872
    $item_property_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
3873
    $session_condition = ' AND session_id = '.$session_id;
3874
    if (empty($session_id)) {
3875
        $session_condition = " AND (session_id = 0 OR session_id IS NULL) ";
3876
    }
3877
    $sql = "SELECT * FROM $item_property_table
3878
            WHERE
3879
                insert_user_id = $userId AND
3880
                c_id = $courseId AND
3881
                tool = '$tool'
3882
                $session_condition ";
3883
3884
    $rs = Database::query($sql);
3885
    $list = array();
3886
    if (Database::num_rows($rs) > 0) {
3887
        while ($row = Database::fetch_array($rs, 'ASSOC')) {
3888
            $list[] = $row;
3889
        }
3890
    }
3891
3892
    return $list;
3893
}
3894
3895
/**
3896
 * Gets item property id from tool of a course
3897
 * @param string $course_code course code
3898
 * @param string $tool tool name, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
3899
 * @param int $ref id of the item itself, linked to key of every tool ('id', ...), "*" = all items of the tool
3900
 * @param int $sessionId Session ID (optional)
3901
 * @return int
3902
 */
3903
function api_get_item_property_id($course_code, $tool, $ref, $sessionId = 0)
3904
{
3905
    $course_info = api_get_course_info($course_code);
3906
    $tool = Database::escape_string($tool);
3907
    $ref = intval($ref);
3908
3909
    // Definition of tables.
3910
    $tableItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
3911
    $course_id = $course_info['real_id'];
3912
    $sessionId = (int) $sessionId;
3913
    $sessionCondition = " AND session_id = $sessionId ";
3914
    if (empty($sessionId)) {
3915
        $sessionCondition = " AND (session_id = 0 OR session_id IS NULL) ";
3916
    }
3917
    $sql = "SELECT id FROM $tableItemProperty
3918
            WHERE
3919
                c_id = $course_id AND
3920
                tool = '$tool' AND
3921
                ref = $ref
3922
                $sessionCondition";
3923
    $rs  = Database::query($sql);
3924
    $item_property_id = '';
3925
    if (Database::num_rows($rs) > 0) {
3926
        $row = Database::fetch_array($rs);
3927
        $item_property_id = $row['id'];
3928
    }
3929
    return $item_property_id;
3930
}
3931
3932
/**
3933
 * Inserts a record in the track_e_item_property table (No update)
3934
 * @param string $tool
3935
 * @param int $ref
3936
 * @param string $title
3937
 * @param string $content
3938
 * @param int $progress
3939
 * @return bool|int
3940
 */
3941
function api_track_item_property_update($tool, $ref, $title, $content, $progress)
3942
{
3943
    $tbl_stats_item_property = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY);
3944
    $course_id = api_get_course_int_id(); //numeric
3945
    $course_code = api_get_course_id(); //alphanumeric
3946
    $item_property_id = api_get_item_property_id($course_code, $tool, $ref);
3947
    if (!empty($item_property_id)) {
3948
        $sql = "INSERT IGNORE INTO $tbl_stats_item_property SET
3949
                course_id           = '$course_id',
3950
                item_property_id    = '$item_property_id',
3951
                title               = '".Database::escape_string($title)."',
3952
                content             = '".Database::escape_string($content)."',
3953
                progress            = '".intval($progress)."',
3954
                lastedit_date       = '".api_get_utc_datetime()."',
3955
                lastedit_user_id    = '".api_get_user_id()."',
3956
                session_id          = '".api_get_session_id()."'";
3957
        $result = Database::query($sql);
3958
        $affected_rows = Database::affected_rows($result);
3959
3960
        return $affected_rows;
3961
    }
3962
3963
    return false;
3964
}
3965
3966
/**
3967
 * @param string $tool
3968
 * @param int $ref
3969
 * @return array|resource
3970
 */
3971 View Code Duplication
function api_get_track_item_property_history($tool, $ref)
3972
{
3973
    $tbl_stats_item_property = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY);
3974
    $course_id = api_get_course_int_id(); //numeric
3975
    $course_code = api_get_course_id(); //alphanumeric
3976
    $item_property_id = api_get_item_property_id($course_code, $tool, $ref);
3977
    $sql = "SELECT * FROM $tbl_stats_item_property
3978
            WHERE item_property_id = $item_property_id AND course_id = $course_id
3979
            ORDER BY lastedit_date DESC";
3980
    $result = Database::query($sql);
3981
    if ($result == false) {
3982
        $result = array();
3983
    } else {
3984
        $result = Database::store_result($result,'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
3985
    }
3986
3987
    return $result;
3988
}
3989
3990
/**
3991
 * Gets item property data from tool of a course id
3992
 * @param int $course_id
3993
 * @param string $tool   tool name, linked to 'rubrique' of the course tool_list (Warning: language sensitive !!)
3994
 * @param int $ref id of the item itself, linked to key of every tool ('id', ...), "*" = all items of the tool
3995
 * @param int $session_id
3996
 * @param int $groupId
3997
 *
3998
 * @return array Array with all fields from c_item_property, empty array if not found or false if course could not be found
3999
 */
4000
function api_get_item_property_info($course_id, $tool, $ref, $session_id = 0, $groupId = 0)
4001
{
4002
    $courseInfo = api_get_course_info_by_id($course_id);
4003
4004
    if (empty($courseInfo)) {
4005
        return false;
4006
    }
4007
4008
    $tool = Database::escape_string($tool);
4009
    $ref = intval($ref);
4010
    $course_id = $courseInfo['real_id'];
4011
    $session_id = intval($session_id);
4012
4013
    $sessionCondition = " session_id = $session_id";
4014
    if (empty($session_id)) {
4015
        $sessionCondition = " (session_id = 0 OR session_id IS NULL) ";
4016
    }
4017
4018
    // Definition of tables.
4019
    $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
4020
4021
    $sql = "SELECT * FROM $table
4022
            WHERE
4023
                c_id = $course_id AND
4024
                tool = '$tool' AND
4025
                ref = $ref AND
4026
                $sessionCondition ";
4027
4028
    if (!empty($groupId)) {
4029
        $groupId = intval($groupId);
4030
        $sql .= " AND to_group_id = $groupId ";
4031
    }
4032
4033
    $rs  = Database::query($sql);
4034
    $row = array();
4035
    if (Database::num_rows($rs) > 0) {
4036
        $row = Database::fetch_array($rs,'ASSOC');
4037
    }
4038
4039
    return $row;
4040
}
4041
4042
/**
4043
 * Displays a combo box so the user can select his/her preferred language.
4044
 * @param string The desired name= value for the select
4045
 * @param bool Whether we use the JQuery Chozen library or not
4046
 * (in some cases, like the indexing language picker, it can alter the presentation)
4047
 * @return string
4048
 */
4049
function api_get_languages_combo($name = 'language')
4050
{
4051
    $ret = '';
4052
    $platformLanguage = api_get_setting('platformLanguage');
4053
4054
    // Retrieve a complete list of all the languages.
4055
    $language_list = api_get_languages();
4056
4057
    if (count($language_list['name']) < 2) {
4058
        return $ret;
4059
    }
4060
4061
    // The the current language of the user so that his/her language occurs as selected in the dropdown menu.
4062
    if (isset($_SESSION['user_language_choice'])) {
4063
        $default = $_SESSION['user_language_choice'];
4064
    } else {
4065
        $default = $platformLanguage;
4066
    }
4067
4068
    $languages  = $language_list['name'];
4069
    $folder     = $language_list['folder'];
4070
4071
    $ret .= '<select name="' . $name . '" id="language_chosen" class="selectpicker show-tick form-control">';
4072
    foreach ($languages as $key => $value) {
4073
        if ($folder[$key] == $default) {
4074
            $selected = ' selected="selected"';
4075
        } else {
4076
            $selected = '';
4077
        }
4078
        $ret .= sprintf('<option value=%s" %s>%s</option>', $folder[$key], $selected, $value);
4079
    }
4080
    $ret .= '</select>';
4081
    return $ret;
4082
}
4083
4084
/**
4085
 * Displays a form (drop down menu) so the user can select his/her preferred language.
4086
 * The form works with or without javascript
4087
 * @param  boolean Hide form if only one language available (defaults to false = show the box anyway)
4088
 * @return null|string Display the box directly
4089
 */
4090
function api_display_language_form($hide_if_no_choice = false)
4091
{
4092
    // Retrieve a complete list of all the languages.
4093
    $language_list = api_get_languages();
4094
    if (count($language_list['name']) <= 1 && $hide_if_no_choice) {
4095
        return; //don't show any form
4096
    }
4097
4098
    // The the current language of the user so that his/her language occurs as selected in the dropdown menu.
4099
    if (isset($_SESSION['user_language_choice'])) {
4100
        $user_selected_language = $_SESSION['user_language_choice'];
4101
    }
4102
    if (empty($user_selected_language)) {
4103
        $user_selected_language = api_get_setting('platformLanguage');
4104
    }
4105
4106
    $original_languages = $language_list['name'];
4107
    $folder = $language_list['folder']; // This line is probably no longer needed.
4108
    $html = '<script>    
4109
    $(document).ready(function() {
4110
        $("#language_list").change(function() {
4111
            jumpMenu("parent",this,0);
4112
        });
4113
    });
4114
4115
    function jumpMenu(targ,selObj,restore){ // v3.0
4116
        eval(targ+".location=\'"+selObj.options[selObj.selectedIndex].value+"\'");
4117
        if (restore) selObj.selectedIndex=0;
4118
    }
4119
    </script>';
4120
    $html .= '<form id="lang_form" name="lang_form" method="post" action="'.api_get_self().'">';
4121
    $html .= '<label style="display: none;" for="language_list">' . get_lang('Language') . '</label>';
4122
    $html .=  '<select id="language_list" class="selectpicker show-tick form-control" name="language_list" >';
4123
4124
    foreach ($original_languages as $key => $value) {
4125
        if ($folder[$key] == $user_selected_language) {
4126
            $option_end = ' selected="selected" >';
4127
        } else {
4128
            $option_end = '>';
4129
        }
4130
        $html .=  '<option value="'.api_get_self().'?language='.$folder[$key].'"'.$option_end;
4131
        //echo substr($value, 0, 16); // Cut string to keep 800x600 aspect.
4132
        $html .=  $value.'</option>';
4133
    }
4134
    $html .=  '</select>';
4135
    $html .=  '<noscript><input type="submit" name="user_select_language" value="'.get_lang('Ok').'" /></noscript>';
4136
    $html .=  '</form>';
4137
    return $html;
4138
}
4139
4140
/**
4141
 * Returns a list of all the languages that are made available by the admin.
4142
 * @return array An array with all languages. Structure of the array is
4143
 *  array['name'] = An array with the name of every language
4144
 *  array['folder'] = An array with the corresponding names of the language-folders in the filesystem
4145
 */
4146
function api_get_languages() {
4147
    $tbl_language = Database::get_main_table(TABLE_MAIN_LANGUAGE);
4148
    $sql = "SELECT * FROM $tbl_language WHERE available='1' 
4149
            ORDER BY original_name ASC";
4150
    $result = Database::query($sql);
4151
    $language_list = array();
4152
   while ($row = Database::fetch_array($result)) {
4153
        $language_list[$row['isocode']] = $row['original_name'];
4154
    }
4155
    return $language_list;
4156
}
4157
4158
/**
4159
 * Returns a list of all the languages that are made available by the admin.
4160
 * @return array
4161
 */
4162 View Code Duplication
function api_get_languages_to_array() {
4163
    $tbl_language = Database::get_main_table(TABLE_MAIN_LANGUAGE);
4164
    $sql = "SELECT * FROM $tbl_language WHERE available='1' ORDER BY original_name ASC";
4165
    $result = Database::query($sql);
4166
    $languages = array();
4167
    while ($row = Database::fetch_array($result)) {
4168
        $languages[$row['dokeos_folder']] = $row['original_name'];
4169
    }
4170
    return $languages;
4171
}
4172
4173
/**
4174
 * Returns the id (the database id) of a language
4175
 * @param   string  language name (the corresponding name of the language-folder in the filesystem)
4176
 * @return  int     id of the language
4177
 */
4178 View Code Duplication
function api_get_language_id($language)
4179
{
4180
    $tbl_language = Database::get_main_table(TABLE_MAIN_LANGUAGE);
4181
    if (empty($language)) {
4182
        return null;
4183
    }
4184
    $language = Database::escape_string($language);
4185
    $sql = "SELECT id FROM $tbl_language
4186
            WHERE dokeos_folder = '$language' LIMIT 1";
4187
    $result = Database::query($sql);
4188
    $row = Database::fetch_array($result);
4189
    return $row['id'];
4190
}
4191
4192
/**
4193
 * Gets language of the requested type for the current user. Types are :
4194
 * user_profil_lang : profile language of current user
4195
 * user_select_lang : language selected by user at login
4196
 * course_lang : language of the current course
4197
 * platform_lang : default platform language
4198
 * @param string $lang_type
4199
 * @return string
4200
 **/
4201
function api_get_language_from_type($lang_type)
4202
{
4203
    $return = false;
4204
    switch ($lang_type) {
4205
        case 'platform_lang':
4206
            $temp_lang = api_get_setting('platformLanguage');
4207
            if (!empty($temp_lang))
4208
                $return = $temp_lang;
4209
            break;
4210
        case 'user_profil_lang':
4211
            $_user = api_get_user_info();
4212
4213
            if (isset($_user['language']) && !empty($_user['language']))
4214
                $return = $_user['language'];
4215
            break;
4216
        case 'user_selected_lang':
4217 View Code Duplication
            if (isset($_SESSION['user_language_choice']) && !empty($_SESSION['user_language_choice']))
4218
                $return = $_SESSION['user_language_choice'];
4219
            break;
4220
        case 'course_lang':
4221
            global $_course;
4222
            $cidReq = null;
4223
            if (empty($_course)) {
4224
4225
                // Code modified because the local.inc.php file it's declarated after this work
4226
                // causing the function api_get_course_info() returns a null value
4227
                $cidReq = isset($_GET["cidReq"]) ? Database::escape_string($_GET["cidReq"]) : null;
4228
                $cDir = (!empty($_GET['cDir']) ? $_GET['cDir'] : null);
4229
                if (empty($cidReq) && !empty($cDir)) {
4230
                    $c = CourseManager::get_course_id_from_path($cDir);
4231
                    if ($c) {
4232
                        $cidReq = $c;
4233
                    }
4234
                }
4235
            }
4236
            $_course = api_get_course_info($cidReq);
4237
            if (isset($_course['language']) && !empty($_course['language'])) {
4238
                $return = $_course['language'];
4239
                $showCourseInUserLanguage = api_get_course_setting('show_course_in_user_language');
4240
                if ($showCourseInUserLanguage == 1) {
4241
                    $userInfo = api_get_user_info();
4242
                    if (isset($userInfo['language'])) {
4243
                        $return = $userInfo['language'];
4244
                    }
4245
                }
4246
            }
4247
            break;
4248
        default:
4249
            $return = false;
4250
        break;
4251
    }
4252
4253
    return $return;
4254
}
4255
4256
/**
4257
 * Get the language information by its id
4258
 * @param int $languageId
4259
 * @return array
4260
 */
4261
function api_get_language_info($languageId) {
4262
    $language = Database::getManager()
4263
        ->find('ChamiloCoreBundle:Language', intval($languageId));
4264
4265
    if (!$language) {
4266
        return [];
4267
    }
4268
4269
    return [
4270
        'id' => $language->getId(),
4271
        'original_name' => $language->getOriginalName(),
4272
        'english_name' => $language->getEnglishName(),
4273
        'isocode' => $language->getIsocode(),
4274
        'dokeos_folder' => $language->getDokeosFolder(),
4275
        'available' => $language->getAvailable(),
4276
        'parent_id' => $language->getParent() ? $language->getParent()->getId() : null
4277
    ];
4278
}
4279
4280
/**
4281
 * Returns the name of the visual (CSS) theme to be applied on the current page.
4282
 * The returned name depends on the platform, course or user -wide settings.
4283
 * @return string   The visual theme's name, it is the name of a folder inside .../chamilo/main/css/
4284
 */
4285
function api_get_visual_theme()
4286
{
4287
    static $visual_theme;
4288
    if (!isset($visual_theme)) {
4289
4290
        $platform_theme = api_get_setting('stylesheets');
4291
4292
        // Platform's theme.
4293
        $visual_theme = $platform_theme;
4294
4295
        if (api_get_setting('profile.user_selected_theme') == 'true') {
4296
            $user_info = api_get_user_info();
4297
            if (isset($user_info['theme'])) {
4298
                $user_theme = $user_info['theme'];
4299
4300
                if (!empty($user_theme)) {
4301
                    $visual_theme = $user_theme;
4302
                    // User's theme.
4303
                }
4304
            }
4305
        }
4306
4307
        $course_id = api_get_course_id();
4308
4309
        if (!empty($course_id) && $course_id != -1) {
4310
            if (api_get_setting('course.allow_course_theme') == 'true') {
4311
                $course_theme = api_get_course_setting('course_theme');
4312
4313
                if (!empty($course_theme) && $course_theme != -1) {
4314
                    if (!empty($course_theme)) {
4315
                        // Course's theme.
4316
                        $visual_theme = $course_theme;
4317
                    }
4318
                }
4319
4320
                $allow_lp_theme = api_get_course_setting('allow_learning_path_theme');
4321
                if ($allow_lp_theme == 1) {
4322
                    global $lp_theme_css, $lp_theme_config;
4323
                    // These variables come from the file lp_controller.php.
4324
                    if (!$lp_theme_config) {
4325
                        if (!empty($lp_theme_css)) {
4326
                            // LP's theme.
4327
                            $visual_theme = $lp_theme_css;
4328
                        }
4329
                    }
4330
                }
4331
            }
4332
        }
4333
4334
        if (empty($visual_theme)) {
4335
            $visual_theme = 'chamilo';
4336
        }
4337
4338
        global $lp_theme_log;
4339
        if ($lp_theme_log) {
4340
            $visual_theme = $platform_theme;
4341
        }
4342
    }
4343
4344
    return $visual_theme;
4345
}
4346
4347
/**
4348
 * Returns a list of CSS themes currently available in the CSS folder
4349
 * @return array        List of themes directories from the css folder
4350
 * Note: Directory names (names of themes) in the file system should contain ASCII-characters only.
4351
 */
4352
function api_get_themes() {
4353
    $cssdir = api_get_path(SYS_CSS_PATH) . 'themes/';
4354
    $list_dir = array();
4355
    $list_name = array();
4356
4357
    if (is_dir($cssdir)) {
4358
        $themes = @scandir($cssdir);
4359
4360
        if (is_array($themes)) {
4361
            if ($themes !== false) {
4362
                sort($themes);
4363
4364
                foreach ($themes as & $theme) {
4365
                    if (substr($theme, 0, 1) == '.') {
4366
                        continue;
4367
                    } else {
4368
                        if (is_dir($cssdir.$theme)) {
4369
                            $list_dir[] = $theme;
4370
                            $list_name[] = ucwords(str_replace('_', ' ', $theme));
4371
                        }
4372
                    }
4373
                }
4374
            }
4375
        }
4376
    }
4377
4378
    return array($list_dir, $list_name);
4379
}
4380
4381
/**
4382
 * Find the largest sort value in a given user_course_category
4383
 * This function is used when we are moving a course to a different category
4384
 * and also when a user subscribes to courses (the new course is added at the end of the main category
4385
 * @author Patrick Cool <[email protected]>, Ghent University
4386
 * @param int $user_course_category the id of the user_course_category
4387
 * @param integer $user_id
4388
 * @return int the value of the highest sort of the user_course_category
4389
 */
4390 View Code Duplication
function api_max_sort_value($user_course_category, $user_id)
4391
{
4392
    $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
4393
    $sql = "SELECT max(sort) as max_sort FROM $tbl_course_user
4394
            WHERE
4395
                user_id='".intval($user_id)."' AND
4396
                relation_type<>".COURSE_RELATION_TYPE_RRHH." AND
4397
                user_course_cat='".intval($user_course_category)."'";
4398
    $result_max = Database::query($sql);
4399
    if (Database::num_rows($result_max) == 1) {
4400
        $row_max = Database::fetch_array($result_max);
4401
        return $row_max['max_sort'];
4402
    }
4403
    return 0;
4404
}
4405
4406
/**
4407
 * Determines the number of plugins installed for a given location
4408
 */
4409
function api_number_of_plugins($location) {
4410
    global $_plugins;
4411
    return isset($_plugins[$location]) && is_array($_plugins[$location]) ? count($_plugins[$location]) : 0;
4412
}
4413
4414
/**
4415
 * Transforms a number of seconds in hh:mm:ss format
4416
 * @author Julian Prud'homme
4417
 * @param integer the number of seconds
4418
 * @return string the formated time
4419
 */
4420
function api_time_to_hms($seconds)
4421
{
4422
    // $seconds = -1 means that we have wrong data in the db.
4423
    if ($seconds == -1) {
4424
        return
4425
            get_lang('Unknown').
4426
            Display::return_icon(
4427
                'info2.gif',
4428
                get_lang('WrongDatasForTimeSpentOnThePlatform'),
4429
                array('align' => 'absmiddle', 'hspace' => '3px')
4430
            );
4431
    }
4432
4433
    // How many hours ?
4434
    $hours = floor($seconds / 3600);
4435
4436
    // How many minutes ?
4437
    $min = floor(($seconds - ($hours * 3600)) / 60);
4438
4439
    // How many seconds
4440
    $sec = floor($seconds - ($hours * 3600) - ($min * 60));
4441
4442
    if ($sec < 10) {
4443
        $sec = "0$sec";
4444
    }
4445
4446
    if ($min < 10) {
4447
        $min = "0$min";
4448
    }
4449
4450
    return "$hours:$min:$sec";
4451
}
4452
4453
/* FILE SYSTEM RELATED FUNCTIONS */
4454
4455
/**
4456
 * Returns the permissions to be assigned to every newly created directory by the web-server.
4457
 * The return value is based on the platform administrator's setting
4458
 * "Administration > Configuration settings > Security > Permissions for new directories".
4459
 * @return int  Returns the permissions in the format "Owner-Group-Others, Read-Write-Execute", as an integer value.
4460
 */
4461 View Code Duplication
function api_get_permissions_for_new_directories() {
4462
    static $permissions;
4463
    if (!isset($permissions)) {
4464
        $permissions = trim(api_get_setting('permissions_for_new_directories'));
4465
        // The default value 0777 is according to that in the platform administration panel after fresh system installation.
4466
        $permissions = octdec(!empty($permissions) ? $permissions : '0777');
4467
    }
4468
    return $permissions;
4469
}
4470
4471
/**
4472
 * Returns the permissions to be assigned to every newly created directory by the web-server.
4473
 * The return value is based on the platform administrator's setting
4474
 * "Administration > Configuration settings > Security > Permissions for new files".
4475
 * @return int Returns the permissions in the format
4476
 * "Owner-Group-Others, Read-Write-Execute", as an integer value.
4477
 */
4478 View Code Duplication
function api_get_permissions_for_new_files() {
4479
    static $permissions;
4480
    if (!isset($permissions)) {
4481
        $permissions = trim(api_get_setting('permissions_for_new_files'));
4482
        // The default value 0666 is according to that in the platform
4483
        // administration panel after fresh system installation.
4484
        $permissions = octdec(!empty($permissions) ? $permissions : '0666');
4485
    }
4486
    return $permissions;
4487
}
4488
4489
/**
4490
 * Deletes a file, or a folder and its contents
4491
 *
4492
 * @author      Aidan Lister <[email protected]>
4493
 * @version     1.0.3
4494
 * @param       string   $dirname    Directory to delete
4495
 * @param       bool     Deletes only the content or not
4496
 * @param       bool     $strict if one folder/file fails stop the loop
4497
 * @return      bool     Returns TRUE on success, FALSE on failure
4498
 * @link http://aidanlister.com/2004/04/recursively-deleting-a-folder-in-php/
4499
 * @author      Yannick Warnier, adaptation for the Chamilo LMS, April, 2008
4500
 * @author      Ivan Tcholakov, a sanity check about Directory class creation has been added, September, 2009
4501
 */
4502
function rmdirr($dirname, $delete_only_content_in_folder = false, $strict = false) {
4503
    $res = true;
4504
4505
    // A sanity check.
4506
    if (!file_exists($dirname)) {
4507
        return false;
4508
    }
4509
    $php_errormsg = '';
4510
    // Simple delete for a file.
4511
    if (is_file($dirname) || is_link($dirname)) {
4512
        $res = unlink($dirname);
4513 View Code Duplication
        if ($res === false) {
4514
            error_log(__FILE__.' line '.__LINE__.': '.((bool)ini_get('track_errors') ? $php_errormsg : 'Error not recorded because track_errors is off in your php.ini'), 0);
4515
        }
4516
        return $res;
4517
    }
4518
4519
    // Loop through the folder.
4520
    $dir = dir($dirname);
4521
    // A sanity check.
4522
    $is_object_dir = is_object($dir);
4523 View Code Duplication
    if ($is_object_dir) {
4524
        while (false !== $entry = $dir->read()) {
4525
            // Skip pointers.
4526
            if ($entry == '.' || $entry == '..') {
4527
                continue;
4528
            }
4529
4530
            // Recurse.
4531
            if ($strict) {
4532
                $result = rmdirr("$dirname/$entry");
4533
                if ($result == false) {
4534
                    $res = false;
4535
                    break;
4536
                }
4537
            } else {
4538
                rmdirr("$dirname/$entry");
4539
            }
4540
        }
4541
    }
4542
4543
    // Clean up.
4544
    if ($is_object_dir) {
4545
        $dir->close();
4546
    }
4547
4548
    if ($delete_only_content_in_folder == false) {
4549
        $res = rmdir($dirname);
4550 View Code Duplication
        if ($res === false) {
4551
            error_log(__FILE__.' line '.__LINE__.': '.((bool)ini_get('track_errors') ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
4552
        }
4553
    }
4554
    return $res;
4555
}
4556
4557
// TODO: This function is to be simplified. File access modes to be implemented.
4558
/**
4559
 * function adapted from a php.net comment
4560
 * copy recursively a folder
4561
 * @param the source folder
4562
 * @param the dest folder
4563
 * @param an array of excluded file_name (without extension)
4564
 * @param copied_files the returned array of copied files
4565
 * @param string $source
4566
 * @param string $dest
4567
 */
4568
function copyr($source, $dest, $exclude = array(), $copied_files = array()) {
4569
    if (empty($dest)) { return false; }
4570
    // Simple copy for a file
4571
    if (is_file($source)) {
4572
        $path_info = pathinfo($source);
4573
        if (!in_array($path_info['filename'], $exclude)) {
4574
            copy($source, $dest);
4575
        }
4576
        return true;
4577
    } elseif (!is_dir($source)) {
4578
        //then source is not a dir nor a file, return
4579
        return false;
4580
    }
4581
4582
    // Make destination directory.
4583
    if (!is_dir($dest)) {
4584
        mkdir($dest, api_get_permissions_for_new_directories());
4585
    }
4586
4587
    // Loop through the folder.
4588
    $dir = dir($source);
4589
    while (false !== $entry = $dir->read()) {
4590
        // Skip pointers
4591
        if ($entry == '.' || $entry == '..') {
4592
            continue;
4593
        }
4594
4595
        // Deep copy directories.
4596
        if ($dest !== "$source/$entry") {
4597
            $files = copyr("$source/$entry", "$dest/$entry", $exclude, $copied_files);
4598
        }
4599
    }
4600
    // Clean up.
4601
    $dir->close();
4602
    return true;
4603
}
4604
4605
// TODO: Using DIRECTORY_SEPARATOR is not recommended, this is an obsolete approach. Documentation header to be added here.
4606
/**
4607
 * @param string $pathname
4608
 * @param string $base_path_document
4609
 * @param integer $session_id
4610
 */
4611
function copy_folder_course_session(
4612
    $pathname,
4613
    $base_path_document,
4614
    $session_id,
4615
    $course_info,
4616
    $document,
4617
    $source_course_id
4618
) {
4619
    $table = Database :: get_course_table(TABLE_DOCUMENT);
4620
    $session_id = intval($session_id);
4621
    $source_course_id = intval($source_course_id);
4622
4623
    // Check whether directory already exists.
4624
    if (is_dir($pathname) || empty($pathname)) {
4625
        return true;
4626
    }
4627
4628
    // Ensure that a file with the same name does not already exist.
4629
    if (is_file($pathname)) {
4630
        trigger_error('copy_folder_course_session(): File exists', E_USER_WARNING);
4631
        return false;
4632
    }
4633
4634
    $course_id = $course_info['real_id'];
4635
4636
    $folders = explode(DIRECTORY_SEPARATOR,str_replace($base_path_document.DIRECTORY_SEPARATOR,'',$pathname));
4637
4638
    $new_pathname = $base_path_document;
4639
    $path = '';
4640
4641
    foreach ($folders as $folder) {
4642
        $new_pathname .= DIRECTORY_SEPARATOR.$folder;
4643
        $path .= DIRECTORY_SEPARATOR.$folder;
4644
4645
        if (!file_exists($new_pathname)) {
4646
            $path = Database::escape_string($path);
4647
4648
            $sql = "SELECT * FROM $table
4649
                    WHERE
4650
                        c_id = $source_course_id AND
4651
                        path = '$path' AND
4652
                        filetype = 'folder' AND
4653
                        session_id = '$session_id'";
4654
            $rs1  = Database::query($sql);
4655
            $num_rows = Database::num_rows($rs1);
4656
4657
            if ($num_rows == 0) {
4658
                mkdir($new_pathname, api_get_permissions_for_new_directories());
4659
4660
                // Insert new folder with destination session_id.
4661
                $params = [
4662
                    'c_id' => $course_id,
4663
                    'path' => $path,
4664
                    'comment' => $document->comment,
4665
                    'title' => basename($new_pathname),
4666
                    'filetype' => 'folder',
4667
                    'size' => '0',
4668
                    'session_id' => $session_id
4669
                ];
4670
                $document_id = Database::insert($table, $params);
4671 View Code Duplication
                if ($document_id) {
4672
4673
                    $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
4674
                    Database::query($sql);
4675
4676
                    api_item_property_update(
4677
                        $course_info,
4678
                        TOOL_DOCUMENT,
4679
                        $document_id,
4680
                        'FolderCreated',
4681
                        api_get_user_id(),
4682
                        0,
4683
                        0,
4684
                        null,
4685
                        null,
4686
                        $session_id
4687
                    );
4688
                }
4689
            }
4690
        }
4691
4692
    } // en foreach
4693
}
4694
4695
// TODO: chmodr() is a better name. Some corrections are needed. Documentation header to be added here.
4696
/**
4697
 * @param string $path
4698
 */
4699
function api_chmod_R($path, $filemode) {
4700
    if (!is_dir($path)) {
4701
        return chmod($path, $filemode);
4702
    }
4703
4704
    $handler = opendir($path);
4705
    while ($file = readdir($handler)) {
4706
        if ($file != '.' && $file != '..') {
4707
            $fullpath = "$path/$file";
4708
            if (!is_dir($fullpath)) {
4709
                if (!chmod($fullpath, $filemode)) {
4710
                    return false;
4711
                }
4712
            } else {
4713
                if (!api_chmod_R($fullpath, $filemode)) {
4714
                    return false;
4715
                }
4716
            }
4717
        }
4718
    }
4719
4720
    closedir($handler);
4721
    return chmod($path, $filemode);
4722
}
4723
4724
4725
// TODO: Where the following function has been copy/pased from? There is no information about author and license. Style, coding conventions...
4726
/**
4727
 * Parse info file format. (e.g: file.info)
4728
 *
4729
 * Files should use an ini-like format to specify values.
4730
 * White-space generally doesn't matter, except inside values.
4731
 * e.g.
4732
 *
4733
 * @verbatim
4734
 *   key = value
4735
 *   key = "value"
4736
 *   key = 'value'
4737
 *   key = "multi-line
4738
 *
4739
 *   value"
4740
 *   key = 'multi-line
4741
 *
4742
 *   value'
4743
 *   key
4744
 *   =
4745
 *   'value'
4746
 * @endverbatim
4747
 *
4748
 * Arrays are created using a GET-like syntax:
4749
 *
4750
 * @verbatim
4751
 *   key[] = "numeric array"
4752
 *   key[index] = "associative array"
4753
 *   key[index][] = "nested numeric array"
4754
 *   key[index][index] = "nested associative array"
4755
 * @endverbatim
4756
 *
4757
 * PHP constants are substituted in, but only when used as the entire value:
4758
 *
4759
 * Comments should start with a semi-colon at the beginning of a line.
4760
 *
4761
 * This function is NOT for placing arbitrary module-specific settings. Use
4762
 * variable_get() and variable_set() for that.
4763
 *
4764
 * Information stored in the module.info file:
4765
 * - name: The real name of the module for display purposes.
4766
 * - description: A brief description of the module.
4767
 * - dependencies: An array of shortnames of other modules this module depends on.
4768
 * - package: The name of the package of modules this module belongs to.
4769
 *
4770
 * Example of .info file:
4771
 * <code>
4772
 * @verbatim
4773
 *   name = Forum
4774
 *   description = Enables threaded discussions about general topics.
4775
 *   dependencies[] = taxonomy
4776
 *   dependencies[] = comment
4777
 *   package = Core - optional
4778
 *   version = VERSION
4779
 * @endverbatim
4780
 * </code>
4781
 * @param string $filename
4782
 *   The file we are parsing. Accepts file with relative or absolute path.
4783
 * @return
4784
 *   The info array.
4785
 */
4786
function api_parse_info_file($filename) {
4787
    $info = array();
4788
4789
    if (!file_exists($filename)) {
4790
        return $info;
4791
    }
4792
4793
    $data = file_get_contents($filename);
4794
    if (preg_match_all('
4795
        @^\s*                           # Start at the beginning of a line, ignoring leading whitespace
4796
        ((?:
4797
          [^=;\[\]]|                    # Key names cannot contain equal signs, semi-colons or square brackets,
4798
          \[[^\[\]]*\]                  # unless they are balanced and not nested
4799
        )+?)
4800
        \s*=\s*                         # Key/value pairs are separated by equal signs (ignoring white-space)
4801
        (?:
4802
          ("(?:[^"]|(?<=\\\\)")*")|     # Double-quoted string, which may contain slash-escaped quotes/slashes
4803
          (\'(?:[^\']|(?<=\\\\)\')*\')| # Single-quoted string, which may contain slash-escaped quotes/slashes
4804
          ([^\r\n]*?)                   # Non-quoted string
4805
        )\s*$                           # Stop at the next end of a line, ignoring trailing whitespace
4806
        @msx', $data, $matches, PREG_SET_ORDER)) {
4807
        $key = $value1 = $value2 = $value3 = '';
4808
        foreach ($matches as $match) {
4809
            // Fetch the key and value string.
4810
            $i = 0;
4811
            foreach (array('key', 'value1', 'value2', 'value3') as $var) {
4812
                $$var = isset($match[++$i]) ? $match[$i] : '';
4813
            }
4814
            $value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3;
4815
4816
            // Parse array syntax.
4817
            $keys = preg_split('/\]?\[/', rtrim($key, ']'));
4818
            $last = array_pop($keys);
4819
            $parent = &$info;
4820
4821
            // Create nested arrays.
4822
            foreach ($keys as $key) {
4823
                if ($key == '') {
4824
                    $key = count($parent);
4825
                }
4826
                if (!isset($parent[$key]) || !is_array($parent[$key])) {
4827
                    $parent[$key] = array();
4828
                }
4829
                $parent = &$parent[$key];
4830
            }
4831
4832
            // Handle PHP constants.
4833
            if (defined($value)) {
4834
                $value = constant($value);
4835
            }
4836
4837
            // Insert actual value.
4838
            if ($last == '') {
4839
                $last = count($parent);
4840
            }
4841
            $parent[$last] = $value;
4842
        }
4843
    }
4844
    return $info;
4845
}
4846
4847
/**
4848
 * Gets Chamilo version from the configuration files
4849
 * @return string   A string of type "1.8.4", or an empty string if the version could not be found
4850
 */
4851
function api_get_version()
4852
{
4853
    return (string) api_get_configuration_value('system_version');
4854
}
4855
4856
/**
4857
 * Gets the software name (the name/brand of the Chamilo-based customized system)
4858
 * @return string
4859
 */
4860
function api_get_software_name() {
4861
    $name = api_get_configuration_value('software_name');
4862
    if (!empty($name)) {
4863
        return $name;
4864
    } else {
4865
        return 'Chamilo';
4866
    }
4867
}
4868
4869
/**
4870
 * Checks whether status given in parameter exists in the platform
4871
 * @param mixed the status (can be either int either string)
4872
 * @return boolean if the status exists, else returns false
4873
 */
4874
function api_status_exists($status_asked) {
4875
    global $_status_list;
4876
    return in_array($status_asked, $_status_list) ? true : isset($_status_list[$status_asked]);
4877
}
4878
4879
/**
4880
 * Checks whether status given in parameter exists in the platform. The function
4881
 * returns the status ID or false if it does not exist, but given the fact there
4882
 * is no "0" status, the return value can be checked against
4883
 * if(api_status_key()) to know if it exists.
4884
 * @param   mixed   The status (can be either int or string)
4885
 * @return  mixed   Status ID if exists, false otherwise
4886
 */
4887
function api_status_key($status) {
4888
    global $_status_list;
4889
    return isset($_status_list[$status]) ? $status : array_search($status, $_status_list);
4890
}
4891
4892
/**
4893
 * Gets the status langvars list
4894
 * @return string[] the list of status with their translations
4895
 */
4896
function api_get_status_langvars() {
4897
    return array(
4898
        COURSEMANAGER   => get_lang('Teacher', ''),
4899
        SESSIONADMIN    => get_lang('SessionsAdmin', ''),
4900
        DRH             => get_lang('Drh', ''),
4901
        STUDENT         => get_lang('Student', ''),
4902
        ANONYMOUS       => get_lang('Anonymous', ''),
4903
        STUDENT_BOSS    => get_lang('RoleStudentBoss', ''),
4904
        INVITEE         => get_lang('Invited'),
4905
    );
4906
}
4907
4908
/**
4909
* The function that retrieves all the possible settings for a certain config setting
4910
* @author Patrick Cool <[email protected]>, Ghent University
4911
*/
4912 View Code Duplication
function api_get_settings_options($var) {
4913
    $table_settings_options = Database :: get_main_table(TABLE_MAIN_SETTINGS_OPTIONS);
4914
    $var = Database::escape_string($var);
4915
    $sql = "SELECT * FROM $table_settings_options
4916
            WHERE variable = '$var'
4917
            ORDER BY id";
4918
    $result = Database::query($sql);
4919
    $settings_options_array = array();
4920
    while ($row = Database::fetch_array($result, 'ASSOC')) {
4921
        $settings_options_array[] = $row;
4922
    }
4923
    return $settings_options_array;
4924
}
4925
4926
/**
4927
 * @param array $params
4928
 */
4929
function api_set_setting_option($params) {
4930
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_OPTIONS);
4931 View Code Duplication
    if (empty($params['id'])) {
4932
        Database::insert($table, $params);
4933
    } else {
4934
        Database::update($table, $params, array('id = ? '=> $params['id']));
4935
    }
4936
}
4937
4938
/**
4939
 * @param array $params
4940
 */
4941
function api_set_setting_simple($params) {
4942
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
4943
    $url_id = api_get_current_access_url_id();
4944
4945 View Code Duplication
    if (empty($params['id'])) {
4946
        $params['access_url'] = $url_id;
4947
        Database::insert($table, $params);
4948
    } else {
4949
        Database::update($table, $params, array('id = ? '=> array($params['id'])));
4950
    }
4951
}
4952
4953
/**
4954
 * @param int $id
4955
 */
4956
function api_delete_setting_option($id) {
4957
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_OPTIONS);
4958
    if (!empty($id)) {
4959
        Database::delete($table, array('id = ? '=> $id));
4960
    }
4961
}
4962
4963
/**
4964
 * Sets a platform configuration setting to a given value
4965
 * @param string    The variable we want to update
4966
 * @param string    The value we want to record
4967
 * @param string    The sub-variable if any (in most cases, this will remain null)
4968
 * @param string    The category if any (in most cases, this will remain null)
4969
 * @param int       The access_url for which this parameter is valid
4970
 * @param string $cat
4971
 */
4972
function api_set_setting($var, $value, $subvar = null, $cat = null, $access_url = 1)
4973
{
4974
    if (empty($var)) {
4975
        return false;
4976
    }
4977
    $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
4978
    $var = Database::escape_string($var);
4979
    $value = Database::escape_string($value);
4980
    $access_url = (int)$access_url;
4981
    if (empty($access_url)) { $access_url = 1; }
4982
    $select = "SELECT id FROM $t_settings WHERE variable = '$var' ";
4983
    if (!empty($subvar)) {
4984
        $subvar = Database::escape_string($subvar);
4985
        $select .= " AND subkey = '$subvar'";
4986
    }
4987
    if (!empty($cat)) {
4988
        $cat = Database::escape_string($cat);
4989
        $select .= " AND category = '$cat'";
4990
    }
4991
    if ($access_url > 1) {
4992
        $select .= " AND access_url = $access_url";
4993
    } else {
4994
        $select .= " AND access_url = 1 ";
4995
    }
4996
    $res = Database::query($select);
4997
    if (Database::num_rows($res) > 0) {
4998
        // Found item for this access_url.
4999
        $row = Database::fetch_array($res);
5000
        $sql = "UPDATE $t_settings SET selected_value = '$value'
5001
                WHERE id = ".$row['id'];
5002
        Database::query($sql);
5003
    } else {
5004
        // Item not found for this access_url, we have to check if it exist with access_url = 1
5005
        $select = "SELECT * FROM $t_settings
5006
                   WHERE variable = '$var' AND access_url = 1 ";
5007
        // Just in case
5008
        if ($access_url == 1) {
5009
            if (!empty($subvar)) {
5010
                $select .= " AND subkey = '$subvar'";
5011
            }
5012
            if (!empty($cat)) {
5013
                $select .= " AND category = '$cat'";
5014
            }
5015
            $res = Database::query($select);
5016
            if (Database::num_rows($res) > 0) {
5017
                // We have a setting for access_url 1, but none for the current one, so create one.
5018
                $row = Database::fetch_array($res);
5019
                $insert = "INSERT INTO $t_settings (variable, subkey, type,category, selected_value, title, comment, scope, subkeytext, access_url)
5020
                        VALUES
5021
                        ('".$row['variable']."',".(!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL")."," .
5022
                        "'".$row['type']."','".$row['category']."'," .
5023
                        "'$value','".$row['title']."'," .
5024
                        "".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL")."," .
5025
                        "".(!empty($row['subkeytext'])?"'".$row['subkeytext']."'":"NULL").",$access_url)";
5026
                Database::query($insert);
5027
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
5028
                // Such a setting does not exist.
5029
                //error_log(__FILE__.':'.__LINE__.': Attempting to update setting '.$var.' ('.$subvar.') which does not exist at all', 0);
5030
            }
5031
        } else {
5032
            // Other access url.
5033
            if (!empty($subvar)) {
5034
                $select .= " AND subkey = '$subvar'";
5035
            }
5036
            if (!empty($cat)) {
5037
                $select .= " AND category = '$cat'";
5038
            }
5039
            $res = Database::query($select);
5040
5041
            if (Database::num_rows($res) > 0) {
5042
                // We have a setting for access_url 1, but none for the current one, so create one.
5043
                $row = Database::fetch_array($res);
5044
                if ($row['access_url_changeable'] == 1) {
5045
                    $insert = "INSERT INTO $t_settings (variable,subkey, type,category, selected_value,title, comment,scope, subkeytext,access_url, access_url_changeable) VALUES
5046
                            ('".$row['variable']."',".
5047
                            (!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL")."," .
5048
                            "'".$row['type']."','".$row['category']."'," .
5049
                            "'$value','".$row['title']."'," .
5050
                            "".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".
5051
                            (!empty($row['scope']) ? "'".$row['scope']."'" : "NULL")."," .
5052
                            "".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url,".$row['access_url_changeable'].")";
5053
                    Database::query($insert);
5054
                }
5055
            } else { // Such a setting does not exist.
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
5056
                //error_log(__FILE__.':'.__LINE__.': Attempting to update setting '.$var.' ('.$subvar.') which does not exist at all. The access_url is: '.$access_url.' ',0);
5057
            }
5058
        }
5059
    }
5060
}
5061
5062
/**
5063
 * Sets a whole category of settings to one specific value
5064
 * @param string    Category
5065
 * @param string    Value
5066
 * @param int       Access URL. Optional. Defaults to 1
5067
 * @param array     Optional array of filters on field type
5068
 * @param string $category
5069
 * @param string $value
5070
 */
5071
function api_set_settings_category($category, $value = null, $access_url = 1, $fieldtype = array())
5072
{
5073
    if (empty($category)) {
5074
        return false;
5075
    }
5076
    $category = Database::escape_string($category);
5077
    $t_s = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
5078
    $access_url = (int) $access_url;
5079
    if (empty($access_url)) { $access_url = 1; }
5080
    if (isset($value)) {
5081
        $value = Database::escape_string($value);
5082
        $sql = "UPDATE $t_s SET selected_value = '$value'
5083
                WHERE category = '$category' AND access_url = $access_url";
5084 View Code Duplication
        if (is_array($fieldtype) && count($fieldtype)>0) {
5085
            $sql .= " AND ( ";
5086
            $i = 0;
5087
            foreach ($fieldtype as $type){
5088
                if ($i > 0) {
5089
                    $sql .= ' OR ';
5090
                }
5091
                $type = Database::escape_string($type);
5092
                $sql .= " type='".$type."' ";
5093
                $i++;
5094
            }
5095
            $sql .= ")";
5096
        }
5097
        $res = Database::query($sql);
5098
        return $res !== false;
5099
    } else {
5100
        $sql = "UPDATE $t_s SET selected_value = NULL
5101
                WHERE category = '$category' AND access_url = $access_url";
5102 View Code Duplication
        if (is_array($fieldtype) && count($fieldtype)>0) {
5103
            $sql .= " AND ( ";
5104
            $i = 0;
5105
            foreach ($fieldtype as $type){
5106
                if ($i > 0) {
5107
                    $sql .= ' OR ';
5108
                }
5109
                $type = Database::escape_string($type);
5110
                $sql .= " type='".$type."' ";
5111
                $i++;
5112
            }
5113
            $sql .= ")";
5114
        }
5115
        $res = Database::query($sql);
5116
        return $res !== false;
5117
    }
5118
}
5119
5120
/**
5121
 * Gets all available access urls in an array (as in the database)
5122
 * @return array    An array of database records
5123
 */
5124
function api_get_access_urls($from = 0, $to = 1000000, $order = 'url', $direction = 'ASC')
5125
{
5126
    $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
5127
    $from = (int) $from;
5128
    $to = (int) $to;
5129
    $order = Database::escape_string($order, null, false);
5130
    $direction = Database::escape_string($direction, null, false);
5131
    $sql = "SELECT id, url, description, active, created_by, tms
5132
            FROM $table
5133
            ORDER BY $order $direction
5134
            LIMIT $to OFFSET $from";
5135
    $res = Database::query($sql);
5136
    return Database::store_result($res);
5137
}
5138
5139
/**
5140
 * Gets the access url info in an array
5141
 * @param int $id Id of the access url
5142
 * @param bool $returnDefault Set to false if you want the real URL if URL 1 is still 'http://localhost/'
5143
 * @return array All the info (url, description, active, created_by, tms)
5144
 * from the access_url table
5145
 * @author Julio Montoya
5146
 */
5147
function api_get_access_url($id, $returnDefault = true)
5148
{
5149
    $id = intval($id);
5150
    // Calling the Database:: library dont work this is handmade.
5151
    $table_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
5152
    $sql = "SELECT url, description, active, created_by, tms
5153
            FROM $table_access_url WHERE id = '$id' ";
5154
    $res = Database::query($sql);
5155
    $result = @Database::fetch_array($res);
5156
    // If the result url is 'http://localhost/' (the default) and the root_web
5157
    // (=current url) is different, and the $id is = 1 (which might mean
5158
    // api_get_current_access_url_id() returned 1 by default), then return the
5159
    // root_web setting instead of the current URL
5160
    // This is provided as an option to avoid breaking the storage of URL-specific
5161
    // homepages in home/localhost/
5162
    if ($id === 1 && $returnDefault === false) {
5163
        $currentUrl = api_get_current_access_url_id();
5164
        // only do this if we are on the main URL (=1), otherwise we could get
5165
        // information on another URL instead of the one asked as parameter
5166
        if ($currentUrl === 1) {
5167
            $rootWeb = api_get_path(WEB_PATH);
5168
            $default = 'http://localhost/';
5169
            if ($result['url'] === $default && $rootWeb != $default) {
5170
                $result['url'] = $rootWeb;
5171
            }
5172
        }
5173
    }
5174
5175
    return $result;
5176
}
5177
5178
/**
5179
 * Gets all the current settings for a specific access url
5180
 * @param string    The category, if any, that we want to get
5181
 * @param string    Whether we want a simple list (display a category) or
5182
 * a grouped list (group by variable as in settings.php default). Values: 'list' or 'group'
5183
 * @param int       Access URL's ID. Optional. Uses 1 by default, which is the unique URL
5184
 * @return array    Array of database results for the current settings of the current access URL
5185
 */
5186
function &api_get_settings($cat = null, $ordering = 'list', $access_url = 1, $url_changeable = 0)
5187
{
5188
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
5189
    $access_url = (int) $access_url;
5190
    $where_condition = '';
5191
    if ($url_changeable == 1) {
5192
        $where_condition = " AND access_url_changeable= '1' ";
5193
    }
5194
    if (empty($access_url) || $access_url == -1) {
5195
        $access_url = 1;
5196
    }
5197
    $sql = "SELECT * FROM $table
5198
            WHERE access_url = $access_url  $where_condition ";
5199
5200
    if (!empty($cat)) {
5201
        $cat = Database::escape_string($cat);
5202
        $sql .= " AND category='$cat' ";
5203
    }
5204
    if ($ordering == 'group') {
5205
        $sql .= " ORDER BY id ASC";
5206
    } else {
5207
        $sql .= " ORDER BY 1,2 ASC";
5208
    }
5209
    $result = Database::query($sql);
5210
    $result = Database::store_result($result,'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
5211
5212
    return $result;
5213
}
5214
5215
/**
5216
 * Sets a platform configuration setting to a given value
5217
 * @param string    The value we want to record
5218
 * @param string    The variable name we want to insert
5219
 * @param string    The subkey for the variable we want to insert
5220
 * @param string    The type for the variable we want to insert
5221
 * @param string    The category for the variable we want to insert
5222
 * @param string    The title
5223
 * @param string    The comment
5224
 * @param string    The scope
5225
 * @param string    The subkey text
5226
 * @param int       The access_url for which this parameter is valid
5227
 * @param int       The changeability of this setting for non-master urls
5228
 * @param string $val
5229
 * @param string $var
5230
 * @param string $sk
5231
 * @param string $c
5232
 * @return boolean  true on success, false on failure
5233
 */
5234
function api_add_setting(
5235
    $val,
5236
    $var,
5237
    $sk = null,
5238
    $type = 'textfield',
5239
    $c = null,
5240
    $title = '',
5241
    $com = '',
5242
    $sc = null,
5243
    $skt = null,
5244
    $a = 1,
5245
    $v = 0
5246
) {
5247
    if (empty($var) || !isset($val)) { return false; }
5248
    $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
5249
    $var = Database::escape_string($var);
5250
    $val = Database::escape_string($val);
5251
    $a = (int) $a;
5252
    if (empty($a)) { $a = 1; }
5253
    // Check if this variable doesn't exist already
5254
    $select = "SELECT id FROM $t_settings WHERE variable = '$var' ";
5255
    if (!empty($sk)) {
5256
        $sk = Database::escape_string($sk);
5257
        $select .= " AND subkey = '$sk'";
5258
    }
5259
    if ($a > 1) {
5260
        $select .= " AND access_url = $a";
5261
    } else {
5262
        $select .= " AND access_url = 1 ";
5263
    }
5264
    $res = Database::query($select);
5265
    if (Database::num_rows($res) > 0) { // Found item for this access_url.
5266
        $row = Database::fetch_array($res);
5267
        Database::update(
5268
            $t_settings,
5269
            array('selected_value' => $val),
5270
            array('id = ?' => array($row['id']))
5271
        );
5272
        return $row['id'];
5273
    }
5274
5275
    // Item not found for this access_url, we have to check if the whole thing is missing
5276
    // (in which case we ignore the insert) or if there *is* a record but just for access_url = 1
5277
    $insert = "INSERT INTO $t_settings " .
5278
                "(variable,selected_value," .
5279
                "type,category," .
5280
                "subkey,title," .
5281
                "comment,scope," .
5282
                "subkeytext,access_url,access_url_changeable)" .
5283
                " VALUES ('$var','$val',";
5284
    if (isset($type)) {
5285
        $type = Database::escape_string($type);
5286
        $insert .= "'$type',";
5287
    } else {
5288
        $insert .= "NULL,";
5289
    }
5290
    if (isset($c)) { // Category
5291
        $c = Database::escape_string($c);
5292
        $insert .= "'$c',";
5293
    } else {
5294
        $insert .= "NULL,";
5295
    }
5296
    if (isset($sk)) { // Subkey
5297
        $sk = Database::escape_string($sk);
5298
        $insert .= "'$sk',";
5299
    } else {
5300
        $insert .= "NULL,";
5301
    }
5302
    if (isset($title)) { // Title
5303
        $title = Database::escape_string($title);
5304
        $insert .= "'$title',";
5305
    } else {
5306
        $insert .= "NULL,";
5307
    }
5308
    if (isset($com)) { // Comment
5309
        $com = Database::escape_string($com);
5310
        $insert .= "'$com',";
5311
    } else {
5312
        $insert .= "NULL,";
5313
    }
5314
    if (isset($sc)) { // Scope
5315
        $sc = Database::escape_string($sc);
5316
        $insert .= "'$sc',";
5317
    } else {
5318
        $insert .= "NULL,";
5319
    }
5320
    if (isset($skt)) { // Subkey text
5321
        $skt = Database::escape_string($skt);
5322
        $insert .= "'$skt',";
5323
    } else {
5324
        $insert .= "NULL,";
5325
    }
5326
    $insert .= "$a,$v)";
5327
    $res = Database::query($insert);
5328
    return $res;
5329
}
5330
5331
/**
5332
 * Checks wether a user can or can't view the contents of a course.
5333
 *
5334
 * @param   int $userid     User id or NULL to get it from $_SESSION
5335
 * @param   int $cid        Course id to check whether the user is allowed.
5336
 * @return  bool
5337
 */
5338
function api_is_course_visible_for_user($userid = null, $cid = null) {
5339
    if ($userid === null) {
5340
        $userid = api_get_user_id();
5341
    }
5342
    if (empty($userid) || strval(intval($userid)) != $userid) {
5343
        if (api_is_anonymous()) {
5344
            $userid = api_get_anonymous_id();
5345
        } else {
5346
            return false;
5347
        }
5348
    }
5349
    $cid = Database::escape_string($cid);
5350
5351
    $courseInfo = api_get_course_info($cid);
5352
    $courseId = $courseInfo['real_id'];
5353
5354
    global $is_platformAdmin;
5355
5356
    $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
5357
    $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
5358
5359
    $sql = "SELECT
5360
                $course_table.category_code,
5361
                $course_table.visibility,
5362
                $course_table.code,
5363
                $course_cat_table.code
5364
            FROM $course_table
5365
            LEFT JOIN $course_cat_table
5366
                ON $course_table.category_code = $course_cat_table.code
5367
            WHERE
5368
                $course_table.code = '$cid'
5369
            LIMIT 1";
5370
5371
    $result = Database::query($sql);
5372
5373
    if (Database::num_rows($result) > 0) {
5374
        $visibility = Database::fetch_array($result);
5375
        $visibility = $visibility['visibility'];
5376
    } else {
5377
        $visibility = 0;
5378
    }
5379
    // Shortcut permissions in case the visibility is "open to the world".
5380
    if ($visibility === COURSE_VISIBILITY_OPEN_WORLD) {
5381
        return true;
5382
    }
5383
5384
    $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
5385
5386
    $sql = "SELECT
5387
                is_tutor, status
5388
            FROM $tbl_course_user
5389
            WHERE
5390
                user_id  = '$userid' AND
5391
                relation_type <> '".COURSE_RELATION_TYPE_RRHH."' AND
5392
                c_id = $courseId
5393
            LIMIT 1";
5394
5395
    $result = Database::query($sql);
5396
5397 View Code Duplication
    if (Database::num_rows($result) > 0) {
5398
        // This user has got a recorded state for this course.
5399
        $cuData = Database::fetch_array($result);
5400
        $is_courseMember = true;
5401
        $is_courseTutor = ($cuData['is_tutor'] == 1);
5402
        $is_courseAdmin = ($cuData['status'] == 1);
5403
    }
5404
5405
    if (!$is_courseAdmin) {
5406
        // This user has no status related to this course.
5407
        // Is it the session coach or the session admin?
5408
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5409
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5410
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5411
5412
        $sql = "SELECT
5413
                    session.id_coach, session_admin_id, session.id
5414
                FROM
5415
                    $tbl_session as session
5416
                INNER JOIN $tbl_session_course
5417
                    ON session_rel_course.session_id = session.id
5418
                    AND session_rel_course.c_id = '$courseId'
5419
                LIMIT 1";
5420
5421
        $result = Database::query($sql);
5422
        $row = Database::store_result($result);
5423
5424
        if ($row[0]['id_coach'] == $userid) {
5425
            $is_courseMember = true;
5426
            $is_courseTutor = true;
5427
            $is_courseAdmin = false;
5428
            $is_courseCoach = true;
5429
            $is_sessionAdmin = false;
5430
        }
5431
        elseif ($row[0]['session_admin_id'] == $userid) {
5432
            $is_courseMember = false;
5433
            $is_courseTutor = false;
5434
            $is_courseAdmin = false;
5435
            $is_courseCoach = false;
5436
            $is_sessionAdmin = true;
5437
        } else {
5438
            // Check if the current user is the course coach.
5439
            $sql = "SELECT 1
5440
                    FROM $tbl_session_course
5441
                    WHERE session_rel_course.c_id = '$courseId'
5442
                    AND session_rel_course.id_coach = '$userid'
5443
                    LIMIT 1";
5444
5445
            $result = Database::query($sql);
5446
5447
            //if ($row = Database::fetch_array($result)) {
5448
            if (Database::num_rows($result) > 0 ) {
5449
                $is_courseMember = true;
5450
                $is_courseTutor = true;
5451
                $is_courseCoach = true;
5452
                $is_sessionAdmin = false;
5453
5454
                $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
5455
5456
                $sql = "SELECT status FROM $tbl_user
5457
                        WHERE user_id = $userid
5458
                        LIMIT 1";
5459
5460
                $result = Database::query($sql);
5461
5462
                if (Database::result($result, 0, 0) == 1) {
5463
                    $is_courseAdmin = true;
5464
                } else {
5465
                    $is_courseAdmin = false;
5466
                }
5467
            } else {
5468
                // Check if the user is a student is this session.
5469
                $sql = "SELECT  id
5470
                        FROM $tbl_session_course_user
5471
                        WHERE
5472
                            user_id  = '$userid' AND
5473
                            c_id = '$courseId'
5474
                        LIMIT 1";
5475
5476
                if (Database::num_rows($result) > 0) {
5477
                    // This user haa got a recorded state for this course.
5478
                    while ($row = Database::fetch_array($result)) {
5479
                        $is_courseMember = true;
5480
                        $is_courseTutor = false;
5481
                        $is_courseAdmin = false;
5482
                        $is_sessionAdmin = false;
5483
                    }
5484
                }
5485
            }
5486
        }
5487
    }
5488
5489
    switch ($visibility) {
5490
        case COURSE_VISIBILITY_OPEN_WORLD:
5491
            return true;
5492
        case COURSE_VISIBILITY_OPEN_PLATFORM:
5493
            return isset($userid);
5494
        case COURSE_VISIBILITY_REGISTERED:
5495
        case COURSE_VISIBILITY_CLOSED:
5496
            return $is_platformAdmin || $is_courseMember || $is_courseAdmin;
5497
        case COURSE_VISIBILITY_HIDDEN:
5498
            return $is_platformAdmin;
5499
    }
5500
5501
    return false;
5502
}
5503
5504
/**
5505
 * Returns whether an element (forum, message, survey ...) belongs to a session or not
5506
 * @param String the tool of the element
5507
 * @param int the element id in database
5508
 * @param int the session_id to compare with element session id
5509
 * @param string $tool
5510
 * @return boolean true if the element is in the session, false else
5511
 */
5512
function api_is_element_in_the_session($tool, $element_id, $session_id = null) {
5513
    if (is_null($session_id)) {
5514
        $session_id = api_get_session_id();
5515
    }
5516
5517
    // Get information to build query depending of the tool.
5518
    switch ($tool) {
5519
        case TOOL_SURVEY :
5520
            $table_tool = Database::get_course_table(TABLE_SURVEY);
5521
            $key_field = 'survey_id';
5522
            break;
5523
        case TOOL_ANNOUNCEMENT :
5524
            $table_tool = Database::get_course_table(TABLE_ANNOUNCEMENT);
5525
            $key_field = 'id';
5526
            break;
5527
        case TOOL_AGENDA :
5528
            $table_tool = Database::get_course_table(TABLE_AGENDA);
5529
            $key_field = 'id';
5530
            break;
5531
        case TOOL_GROUP :
5532
            $table_tool = Database::get_course_table(TABLE_GROUP);
5533
            $key_field = 'id';
5534
            break;
5535
        default:
5536
            return false;
5537
    }
5538
    $course_id = api_get_course_int_id();
5539
5540
    $sql = "SELECT session_id FROM $table_tool 
5541
            WHERE c_id = $course_id AND $key_field =  ".intval($element_id);
5542
    $rs = Database::query($sql);
5543
    if ($element_session_id = Database::result($rs, 0, 0)) {
5544
        if ($element_session_id == intval($session_id)) {
5545
            // The element belongs to the session.
5546
            return true;
5547
        }
5548
    }
5549
    return false;
5550
}
5551
5552
/**
5553
 * Replaces "forbidden" characters in a filename string.
5554
 *
5555
 * @param string $filename
5556
 * @param bool $treat_spaces_as_hyphens
5557
 *
5558
 * @return string
5559
 */
5560
function api_replace_dangerous_char($filename, $treat_spaces_as_hyphens = true)
5561
{
5562
    return URLify::filter($filename, 250, '', true, true, false, false, $treat_spaces_as_hyphens);
5563
}
5564
5565
/**
5566
 * Fixes the $_SERVER['REQUEST_URI'] that is empty in IIS6.
5567
 * @author Ivan Tcholakov, 28-JUN-2006.
5568
 */
5569
function api_request_uri() {
5570
    if (!empty($_SERVER['REQUEST_URI'])) {
5571
        return $_SERVER['REQUEST_URI'];
5572
    }
5573
    $uri = $_SERVER['SCRIPT_NAME'];
5574
    if (!empty($_SERVER['QUERY_STRING'])) {
5575
        $uri .= '?'.$_SERVER['QUERY_STRING'];
5576
    }
5577
    $_SERVER['REQUEST_URI'] = $uri;
5578
    return $uri;
5579
}
5580
5581
5582
/** Gets the current access_url id of the Chamilo Platform
5583
 * @author Julio Montoya <[email protected]>
5584
 * @return int access_url_id of the current Chamilo Installation
5585
 */
5586 View Code Duplication
function api_get_current_access_url_id() {
5587
    $access_url_table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
5588
    $path = Database::escape_string(api_get_path(WEB_PATH));
5589
    $sql = "SELECT id FROM $access_url_table WHERE url = '".$path."'";
5590
    $result = Database::query($sql);
5591
    if (Database::num_rows($result) > 0) {
5592
        $access_url_id = Database::result($result, 0, 0);
5593
        return $access_url_id;
5594
    }
5595
    //if the url in WEB_PATH was not found, it can only mean that there is
5596
    // either a configuration problem or the first URL has not been defined yet
5597
    // (by default it is http://localhost/). Thus the more sensible thing we can
5598
    // do is return 1 (the main URL) as the user cannot hack this value anyway
5599
    return 1;
5600
}
5601
5602
/**
5603
 * Gets the registered urls from a given user id
5604
 * @author Julio Montoya <[email protected]>
5605
 * @return int user id
5606
 */
5607 View Code Duplication
function api_get_access_url_from_user($user_id) {
5608
    $user_id = intval($user_id);
5609
    $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
5610
    $table_url          = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
5611
    $sql = "SELECT access_url_id
5612
            FROM $table_url_rel_user url_rel_user
5613
            INNER JOIN $table_url u
5614
            ON (url_rel_user.access_url_id = u.id)
5615
            WHERE user_id = ".intval($user_id);
5616
    $result = Database::query($sql);
5617
    $url_list = array();
5618
    while ($row = Database::fetch_array($result, 'ASSOC')) {
5619
        $url_list[] = $row['access_url_id'];
5620
    }
5621
    return $url_list;
5622
}
5623
5624
/**
5625
 * Gets the status of a user in a course
5626
 * @param int       $user_id
5627
 * @param int    $courseId
5628
 * @return int      user status
5629
 */
5630
function api_get_status_of_user_in_course($user_id, $courseId)
5631
{
5632
    $tbl_rel_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
5633
    if (!empty($user_id) && !empty($courseId)) {
5634
        $user_id = intval($user_id);
5635
        $courseId = intval($courseId);
5636
        $sql = 'SELECT status
5637
                FROM '.$tbl_rel_course_user.'
5638
                WHERE user_id='.$user_id.' AND c_id = '.$courseId;
5639
        $result = Database::query($sql);
5640
        $row_status = Database::fetch_array($result, 'ASSOC');
5641
        return $row_status['status'];
5642
    } else {
5643
        return 0;
5644
    }
5645
}
5646
5647
/**
5648
 * Checks whether the curent user is in a group or not.
5649
 *
5650
 * @param string        The group id - optional (takes it from session if not given)
5651
 * @param string        The course code - optional (no additional check by course if course code is not given)
5652
 * @return boolean
5653
 * @author Ivan Tcholakov
5654
 */
5655
function api_is_in_group($groupIdParam = null, $courseCodeParam = null)
5656
{
5657
    if (!empty($courseCodeParam)) {
5658
        $courseCode = api_get_course_id();
5659
        if (!empty($courseCode)) {
5660
            if ($courseCodeParam != $courseCode) {
5661
                return false;
5662
            }
5663
        } else {
5664
            return false;
5665
        }
5666
    }
5667
5668
    $groupId = api_get_group_id();
5669
5670
    if (isset($groupId) && $groupId != '') {
5671
        if (!empty($groupIdParam)) {
5672
            return $groupIdParam == $groupId;
5673
        } else {
5674
            return true;
5675
        }
5676
    }
5677
5678
    return false;
5679
}
5680
5681
/**
5682
 * Checks whether a secret key is valid
5683
 * @param string $original_key_secret  - secret key from (webservice) client
5684
 * @param string $security_key - security key from Chamilo
5685
 * @return boolean - true if secret key is valid, false otherwise
5686
 */
5687
function api_is_valid_secret_key($original_key_secret, $security_key) {
5688
    return $original_key_secret == sha1($security_key);
5689
}
5690
5691
/**
5692
 * Checks whether a user is into course
5693
 * @param int $course_id - the course id
5694
 * @param int $user_id - the user id
5695
 */
5696
function api_is_user_of_course($course_id, $user_id) {
5697
    $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5698
    $sql = 'SELECT user_id FROM '.$tbl_course_rel_user.'
5699
            WHERE
5700
                c_id ="'.intval($course_id).'" AND
5701
                user_id = "'.intval($user_id).'" AND
5702
                relation_type <> '.COURSE_RELATION_TYPE_RRHH.' ';
5703
    $result = Database::query($sql);
5704
    return Database::num_rows($result) == 1;
5705
}
5706
5707
/**
5708
 * Checks whether the server's operating system is Windows (TM).
5709
 * @return boolean - true if the operating system is Windows, false otherwise
5710
 */
5711
function api_is_windows_os() {
5712
    if (function_exists('php_uname')) {
5713
        // php_uname() exists as of PHP 4.0.2, according to the documentation.
5714
        // We expect that this function will always work for Chamilo 1.8.x.
5715
        $os = php_uname();
5716
    }
5717
    // The following methods are not needed, but let them stay, just in case.
5718
    elseif (isset($_ENV['OS'])) {
5719
        // Sometimes $_ENV['OS'] may not be present (bugs?)
5720
        $os = $_ENV['OS'];
5721
    }
5722
    elseif (defined('PHP_OS')) {
5723
        // PHP_OS means on which OS PHP was compiled, this is why
5724
        // using PHP_OS is the last choice for detection.
5725
        $os = PHP_OS;
5726
    } else {
5727
        return false;
5728
    }
5729
    return strtolower(substr((string)$os, 0, 3 )) == 'win';
5730
}
5731
5732
/**
5733
 * This function informs whether the sent request is XMLHttpRequest
5734
 */
5735
function api_is_xml_http_request() {
5736
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
5737
}
5738
5739
/**
5740
 * This wrapper function has been implemented for avoiding some known problems about the function getimagesize().
5741
 * @link http://php.net/manual/en/function.getimagesize.php
5742
 * @link http://www.dokeos.com/forum/viewtopic.php?t=12345
5743
 * @link http://www.dokeos.com/forum/viewtopic.php?t=16355
5744
 * @return integer
5745
 */
5746
function api_getimagesize($path) {
5747
    $image = new Image($path);
5748
    return $image->get_image_size();
5749
}
5750
5751
/**
5752
 * This function resizes an image, with preserving its proportions (or aspect ratio).
5753
 * @author Ivan Tcholakov, MAY-2009.
5754
 * @param int $image            System path or URL of the image
5755
 * @param int $target_width     Targeted width
5756
 * @param int $target_height    Targeted height
5757
 * @return array                Calculated new width and height
5758
 */
5759
function api_resize_image($image, $target_width, $target_height) {
5760
    $image_properties = api_getimagesize($image);
5761
    return api_calculate_image_size($image_properties['width'], $image_properties['height'], $target_width, $target_height);
5762
}
5763
5764
/**
5765
 * This function calculates new image size, with preserving image's proportions (or aspect ratio).
5766
 * @author Ivan Tcholakov, MAY-2009.
5767
 * @author The initial idea has been taken from code by Patrick Cool, MAY-2004.
5768
 * @param int $image_width      Initial width
5769
 * @param int $image_height     Initial height
5770
 * @param int $target_width     Targeted width
5771
 * @param int $target_height    Targeted height
5772
 * @return array                Calculated new width and height
5773
 */
5774
function api_calculate_image_size($image_width, $image_height, $target_width, $target_height) {
5775
    // Only maths is here.
5776
    $result = array('width' => $image_width, 'height' => $image_height);
5777
    if ($image_width <= 0 || $image_height <= 0) {
5778
        return $result;
5779
    }
5780
    $resize_factor_width = $target_width / $image_width;
5781
    $resize_factor_height = $target_height / $image_height;
5782
    $delta_width = $target_width - $image_width * $resize_factor_height;
5783
    $delta_height = $target_height - $image_height * $resize_factor_width;
5784
    if ($delta_width > $delta_height) {
5785
        $result['width'] = ceil($image_width * $resize_factor_height);
5786
        $result['height'] = ceil($image_height * $resize_factor_height);
5787
    }
5788
    elseif ($delta_width < $delta_height) {
5789
        $result['width'] = ceil($image_width * $resize_factor_width);
5790
        $result['height'] = ceil($image_height * $resize_factor_width);
5791
    }
5792
    else {
5793
        $result['width'] = ceil($target_width);
5794
        $result['height'] = ceil($target_height);
5795
    }
5796
    return $result;
5797
}
5798
5799
/**
5800
 * Returns a list of Chamilo's tools or
5801
 * checks whether a given identificator is a valid Chamilo's tool.
5802
 * @author Isaac flores paz
5803
 * @param string The tool name to filter
5804
 * @return mixed Filtered string or array
5805
 */
5806
function api_get_tools_lists($my_tool = null) {
5807
    $tools_list = array(
5808
        TOOL_DOCUMENT,
5809
        TOOL_THUMBNAIL,
5810
        TOOL_HOTPOTATOES,
5811
        TOOL_CALENDAR_EVENT,
5812
        TOOL_LINK,
5813
        TOOL_COURSE_DESCRIPTION,
5814
        TOOL_SEARCH,
5815
        TOOL_LEARNPATH,
5816
        TOOL_ANNOUNCEMENT,
5817
        TOOL_FORUM,
5818
        TOOL_THREAD,
5819
        TOOL_POST,
5820
        TOOL_DROPBOX,
5821
        TOOL_QUIZ,
5822
        TOOL_USER,
5823
        TOOL_GROUP,
5824
        TOOL_BLOGS,
5825
        TOOL_CHAT,
5826
        TOOL_STUDENTPUBLICATION,
5827
        TOOL_TRACKING,
5828
        TOOL_HOMEPAGE_LINK,
5829
        TOOL_COURSE_SETTING,
5830
        TOOL_BACKUP,
5831
        TOOL_COPY_COURSE_CONTENT,
5832
        TOOL_RECYCLE_COURSE,
5833
        TOOL_COURSE_HOMEPAGE,
5834
        TOOL_COURSE_RIGHTS_OVERVIEW,
5835
        TOOL_UPLOAD,
5836
        TOOL_COURSE_MAINTENANCE,
5837
        TOOL_SURVEY,
5838
        TOOL_WIKI,
5839
        TOOL_GLOSSARY,
5840
        TOOL_GRADEBOOK,
5841
        TOOL_NOTEBOOK,
5842
        TOOL_ATTENDANCE,
5843
        TOOL_COURSE_PROGRESS,
5844
    );
5845
    if (empty($my_tool)) {
5846
        return $tools_list;
5847
    }
5848
    return in_array($my_tool, $tools_list) ? $my_tool : '';
5849
}
5850
5851
/**
5852
 * Checks whether we already approved the last version term and condition
5853
 * @param int user id
5854
 * @return bool true if we pass false otherwise
5855
 */
5856
function api_check_term_condition($user_id)
5857
{
5858
    if (api_get_setting('allow_terms_conditions') == 'true') {
5859
        //check if exists terms and conditions
5860
        if (LegalManager::count() == 0) {
5861
5862
            return true;
5863
        }
5864
5865
        $extraFieldValue = new ExtraFieldValue('user');
5866
        $data = $extraFieldValue->get_values_by_handler_and_field_variable(
5867
            $user_id,
5868
            'legal_accept'
5869
        );
5870
5871
        if (!empty($data) && isset($data['value'])) {
5872
            $rowv = $data['value'];
5873
            $user_conditions = explode(':', $rowv);
5874
            $version = $user_conditions[0];
5875
            $lang_id = $user_conditions[1];
5876
            $real_version = LegalManager::get_last_version($lang_id);
5877
5878
            return $version >= $real_version;
5879
        }
5880
        return false;
5881
    }
5882
    return false;
5883
}
5884
5885
/**
5886
 * Gets all information of a tool into course
5887
 * @param int The tool id
5888
 * @return array
5889
 */
5890
function api_get_tool_information($tool_id) {
5891
    $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
5892
    $course_id = api_get_course_int_id();
5893
    $sql = "SELECT * FROM $t_tool WHERE c_id = $course_id AND id = ".intval($tool_id);
5894
    $rs  = Database::query($sql);
5895
    return Database::fetch_array($rs);
5896
}
5897
5898
/**
5899
 * Gets all information of a tool into course
5900
 * @param int The tool id
5901
 * @return array
5902
 */
5903 View Code Duplication
function api_get_tool_information_by_name($name) {
5904
    $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
5905
    $course_id = api_get_course_int_id();
5906
    $sql = "SELECT * FROM $t_tool
5907
            WHERE c_id = $course_id  AND name = '".Database::escape_string($name)."' ";
5908
    $rs  = Database::query($sql);
5909
    return Database::fetch_array($rs, 'ASSOC');
5910
}
5911
5912
/**
5913
 * Function used to protect a "global" admin script.
5914
 * The function blocks access when the user has no global platform admin rights.
5915
 * Global admins are the admins that are registered in the main.admin table
5916
 * AND the users who have access to the "principal" portal.
5917
 * That means that there is a record in the main.access_url_rel_user table
5918
 * with his user id and the access_url_id=1
5919
 *
5920
 * @author Julio Montoya
5921
 * @param integer $user_id
5922
 */
5923
function api_is_global_platform_admin($user_id = null)
5924
{
5925
    $user_id = intval($user_id);
5926
    if (empty($user_id)) {
5927
        $user_id = api_get_user_id();
5928
    }
5929
    if (api_is_platform_admin_by_id($user_id)) {
5930
        $urlList = api_get_access_url_from_user($user_id);
5931
        // The admin is registered in the first "main" site with access_url_id = 1
5932
        if (in_array(1, $urlList)) {
5933
            return true;
5934
        } else {
5935
            return false;
5936
        }
5937
    }
5938
    return false;
5939
}
5940
5941
/**
5942
 * @param int $admin_id_to_check
5943
 * @param int  $my_user_id
5944
 * @param bool $allow_session_admin
5945
 * @return bool
5946
 */
5947
function api_global_admin_can_edit_admin($admin_id_to_check, $my_user_id = null, $allow_session_admin = false)
5948
{
5949
    if (empty($my_user_id)) {
5950
        $my_user_id = api_get_user_id();
5951
    }
5952
5953
    $iam_a_global_admin = api_is_global_platform_admin($my_user_id);
5954
    $user_is_global_admin = api_is_global_platform_admin($admin_id_to_check);
5955
5956
    if ($iam_a_global_admin) {
5957
        // Global admin can edit everything
5958
        return true;
5959
    } else {
5960
        // If i'm a simple admin
5961
        $is_platform_admin = api_is_platform_admin_by_id($my_user_id);
5962
5963
        if ($allow_session_admin) {
5964
            $is_platform_admin = api_is_platform_admin_by_id($my_user_id) || (api_get_user_status($my_user_id) == SESSIONADMIN);
5965
        }
5966
5967
        if ($is_platform_admin) {
5968
            if ($user_is_global_admin) {
5969
                return false;
5970
            } else {
5971
                return true;
5972
            }
5973
        } else {
5974
            return false;
5975
        }
5976
    }
5977
}
5978
5979
/**
5980
 * @param int $admin_id_to_check
5981
 * @param int  $my_user_id
5982
 * @param bool $allow_session_admin
5983
 * @return boolean|null
5984
 */
5985
function api_protect_super_admin($admin_id_to_check, $my_user_id = null, $allow_session_admin = false)
5986
{
5987
    if (api_global_admin_can_edit_admin($admin_id_to_check, $my_user_id, $allow_session_admin)) {
5988
        return true;
5989
    } else {
5990
        api_not_allowed();
5991
    }
5992
}
5993
5994
/**
5995
 * Function used to protect a global admin script.
5996
 * The function blocks access when the user has no global platform admin rights.
5997
 * See also the api_is_global_platform_admin() function wich defines who's a "global" admin
5998
 *
5999
 * @author Julio Montoya
6000
 */
6001
function api_protect_global_admin_script() {
6002
    if (!api_is_global_platform_admin()) {
6003
        api_not_allowed();
6004
        return false;
6005
    }
6006
    return true;
6007
}
6008
6009
/**
6010
 * Get active template
6011
 * @param string    theme type (optional: default)
6012
 * @param string    path absolute(abs) or relative(rel) (optional:rel)
6013
 * @return string   actived template path
6014
 */
6015
function api_get_template($path_type = 'rel') {
6016
    $path_types = array('rel', 'abs');
6017
    $template_path = '';
6018
    if (in_array($path_type, $path_types)) {
6019
        if ($path_type == 'rel') {
6020
            $template_path = api_get_path(SYS_TEMPLATE_PATH);
6021
        } else {
6022
            $template_path = api_get_path(WEB_TEMPLATE_PATH);
6023
        }
6024
    }
6025
    $actived_theme = 'default';
6026
    /*if (api_get_setting('active_template')) {
6027
        $actived_theme = api_get_setting('active_template');
6028
    }*/
6029
    $actived_theme_path = $template_path.$actived_theme.DIRECTORY_SEPARATOR;
6030
    return $actived_theme_path;
6031
}
6032
6033
/**
6034
 * Check browser support for type files
6035
 * This function check if the users browser support a file format or
6036
 * return the current browser and major ver when $format=check_browser
6037
 * @param string $format
6038
 *
6039
 * @return bool or return text array if $format=check_browser
6040
 * @author Juan Carlos Raña Trabado
6041
 */
6042
function api_browser_support($format = '')
6043
{
6044
    $browser = new Browser();
6045
    $current_browser = $browser->getBrowser();
6046
    $a_versiontemp = explode('.', $browser->getVersion());
6047
    $current_majorver = $a_versiontemp[0];
6048
6049
    // Native svg support
6050
    if ($format == 'svg') {
6051
        if (($current_browser == 'Internet Explorer' && $current_majorver >= 9) ||
6052
            ($current_browser == 'Firefox' && $current_majorver > 1) ||
6053
            ($current_browser == 'Safari' && $current_majorver >= 4) ||
6054
            ($current_browser == 'Chrome' && $current_majorver >= 1) ||
6055
            ($current_browser == 'Opera' && $current_majorver >= 9)
6056
        ) {
6057
            return true;
6058
        } else {
6059
            return false;
6060
        }
6061
    } elseif ($format == 'pdf') {
6062
        //native pdf support
6063
        if ($current_browser == 'Chrome' && $current_majorver >= 6) {
6064
            return true;
6065
        } else {
6066
            return false;
6067
        }
6068
    } elseif ($format == 'tif' || $format == 'tiff') {
6069
        //native tif support
6070
        if ($current_browser == 'Safari' && $current_majorver >= 5) {
6071
            return true;
6072
        } else {
6073
            return false;
6074
        }
6075 View Code Duplication
    } elseif ($format == 'ogg' || $format == 'ogx' || $format == 'ogv' || $format == 'oga') {
6076
        //native ogg, ogv,oga support
6077
        if (($current_browser == 'Firefox' && $current_majorver >= 3) ||
6078
            ($current_browser == 'Chrome' && $current_majorver >= 3) ||
6079
            ($current_browser == 'Opera' && $current_majorver >= 9)) {
6080
            return true;
6081
        } else {
6082
            return false;
6083
        }
6084
    } elseif ($format == 'mpg' || $format == 'mpeg') {
6085
        //native mpg support
6086
        if (($current_browser == 'Safari' && $current_majorver >= 5)) {
6087
            return true;
6088
        } else {
6089
            return false;
6090
        }
6091
    } elseif ($format == 'mp4') {
6092
        //native mp4 support (TODO: Android, iPhone)
6093
        if ($current_browser == 'Android' || $current_browser == 'iPhone') {
6094
            return true;
6095
        } else {
6096
            return false;
6097
        }
6098
    } elseif ($format == 'mov') {
6099
        //native mov support( TODO:check iPhone)
6100
        if ($current_browser == 'Safari' && $current_majorver >= 5 || $current_browser == 'iPhone') {
6101
            return true;
6102
        } else {
6103
            return false;
6104
        }
6105
    } elseif ($format == 'avi') {
6106
        //native avi support
6107
        if ($current_browser == 'Safari' && $current_majorver >= 5) {
6108
            return true;
6109
        } else {
6110
            return false;
6111
        }
6112
    } elseif ($format == 'wmv') {
6113
        //native wmv support
6114
        if ($current_browser == 'Firefox' && $current_majorver >= 4) {
6115
            return true;
6116
        } else {
6117
            return false;
6118
        }
6119 View Code Duplication
    } elseif ($format == 'webm') {
6120
        //native webm support (TODO:check IE9, Chrome9, Android)
6121
        if (($current_browser == 'Firefox' && $current_majorver >= 4) ||
6122
            ($current_browser == 'Opera' && $current_majorver >= 9) ||
6123
            ($current_browser == 'Internet Explorer' && $current_majorver >= 9) ||
6124
            ($current_browser == 'Chrome' && $current_majorver >= 9) ||
6125
            $current_browser == 'Android'
6126
        ) {
6127
            return true;
6128
        } else {
6129
            return false;
6130
        }
6131
    } elseif ($format == 'wav') {
6132
        //native wav support (only some codecs !)
6133
        if (($current_browser == 'Firefox' && $current_majorver >= 4) ||
6134
            ($current_browser == 'Safari' && $current_majorver >= 5) ||
6135
            ($current_browser == 'Opera' && $current_majorver >= 9) ||
6136
            ($current_browser == 'Internet Explorer' && $current_majorver >= 9) ||
6137
            ($current_browser == 'Chrome' && $current_majorver > 9) ||
6138
            $current_browser == 'Android' ||
6139
            $current_browser == 'iPhone'
6140
        ) {
6141
            return true;
6142
        } else {
6143
            return false;
6144
        }
6145
    } elseif ($format == 'mid' || $format == 'kar') {
6146
        //native midi support (TODO:check Android)
6147
        if ($current_browser == 'Opera' && $current_majorver >= 9 || $current_browser == 'Android') {
6148
            return true;
6149
        } else {
6150
            return false;
6151
        }
6152
    } elseif ($format == 'wma') {
6153
        //native wma support
6154
        if ($current_browser == 'Firefox' && $current_majorver >= 4) {
6155
            return true;
6156
        } else {
6157
            return false;
6158
        }
6159
    } elseif ($format == 'au') {
6160
        //native au support
6161
        if ($current_browser == 'Safari' && $current_majorver >= 5) {
6162
            return true;
6163
        } else {
6164
            return false;
6165
        }
6166 View Code Duplication
    } elseif ($format == 'mp3') {
6167
        //native mp3 support (TODO:check Android, iPhone)
6168
        if (($current_browser == 'Safari' && $current_majorver >= 5) ||
6169
            ($current_browser == 'Chrome' && $current_majorver >= 6) ||
6170
            ($current_browser == 'Internet Explorer' && $current_majorver >= 9) ||
6171
            $current_browser == 'Android' ||
6172
            $current_browser == 'iPhone' ||
6173
            $current_browser == 'Firefox'
6174
        ) {
6175
            return true;
6176
        } else {
6177
            return false;
6178
        }
6179
    } elseif ($format == "check_browser") {
6180
        $array_check_browser = array($current_browser, $current_majorver);
6181
        return $array_check_browser;
6182
    } else {
6183
        return false;
6184
    }
6185
}
6186
6187
/**
6188
 * This function checks if exist path and file browscap.ini
6189
 * In order for this to work, your browscap configuration setting in php.ini
6190
 * must point to the correct location of the browscap.ini file on your system
6191
 * http://php.net/manual/en/function.get-browser.php
6192
 *
6193
 * @return bool
6194
 *
6195
 * @author Juan Carlos Raña Trabado
6196
 */
6197
function api_check_browscap() {
6198
    $setting = ini_get('browscap');
6199
    if ($setting) {
6200
        $browser = get_browser($_SERVER['HTTP_USER_AGENT'], true);
6201
        if (strpos($setting, 'browscap.ini') && !empty($browser)) {
6202
            return true;
6203
        }
6204
    }
6205
    return false;
6206
}
6207
6208
/**
6209
 * Returns the <script> HTML tag
6210
 */
6211
function api_get_js($file) {
6212
    return '<script type="text/javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/'.$file.'"></script>'."\n";
6213
}
6214
6215
/**
6216
 * Returns the <script> HTML tag
6217
 *
6218
 * @param string $file
6219
 * @param bool $getURL only returns the URL without the <script> tag
6220
 * @return string
6221
 */
6222
function api_get_asset($file, $getURL = false)
6223
{
6224
    $url = Container::getAsset()->getUrl("assets/".$file);
6225
6226
    if ($getURL) {
6227
        return $url;
6228
    }
6229
6230
    return '<script type="text/javascript" src="'.$url.'"></script>'."\n";
6231
}
6232
6233
/**
6234
 *
6235
 * Returns the <link> HTML tag
6236
 *
6237
 * @param $file
6238
 * @param string $media
6239
 * @return string
6240
 */
6241
function api_get_css_asset($file, $media = 'screen')
6242
{
6243
    $url = Container::getAsset()->getUrl("assets/".$file);
6244
    return '<link href="'.$url.'" rel="stylesheet" media="'.$media.'" type="text/css" />'."\n";
6245
}
6246
6247
/**
6248
 * Returns the <link> HTML tag
6249
 *
6250
 * @param string $file
6251
 * @param string $media
6252
 *
6253
 * @return string
6254
 */
6255
function api_get_css($file, $media = 'screen')
6256
{
6257
    return '<link href="'.$file.'" rel="stylesheet" media="'.$media.'" type="text/css" />'."\n";
6258
}
6259
6260
/**
6261
 * Returns the js header to include the jquery library
6262
 */
6263
function api_get_jquery_js()
6264
{
6265
    return api_get_asset('jquery/dist/jquery.min.js');
6266
}
6267
6268
/**
6269
 * Returns the jquery path
6270
 * @return string
6271
 */
6272
function api_get_jquery_web_path()
6273
{
6274
    return api_get_path(WEB_PATH).'web/assets/jquery/dist/jquery.min.js';
6275
}
6276
6277
/**
6278
 * @return string
6279
 */
6280
function api_get_jquery_ui_js_web_path()
6281
{
6282
    return api_get_path(WEB_PATH).'web/assets/jquery-ui/jquery-ui.min.js';
6283
}
6284
6285
/**
6286
 * @return string
6287
 */
6288
function api_get_jquery_ui_css_web_path()
6289
{
6290
    return api_get_path(WEB_PATH).'web/assets/jquery-ui/themes/smoothness/jquery-ui.min.css';
6291
}
6292
6293
/**
6294
 * Returns the jquery-ui library js headers
6295
 * @param   bool    add the jqgrid library
6296
 * @return  string  html tags
6297
 *
6298
 */
6299
function api_get_jquery_ui_js($include_jqgrid = false) {
6300
    $libraries = array();
6301
    if ($include_jqgrid) {
6302
       $libraries[]='jqgrid';
6303
    }
6304
    return api_get_jquery_libraries_js($libraries);
6305
}
6306
6307
function api_get_jqgrid_js() {
6308
    return api_get_jquery_libraries_js(array('jqgrid'));
6309
}
6310
6311
/**
6312
 * Returns the jquery library js and css headers
6313
 *
6314
 * @param   array   list of jquery libraries supported jquery-ui, jqgrid
6315
 * @param   bool    add the jquery library
6316
 * @return  string  html tags
6317
 *
6318
 */
6319
function api_get_jquery_libraries_js($libraries) {
6320
    $js = '';
6321
    $js_path = api_get_path(WEB_LIBRARY_PATH).'javascript/';
6322
6323
    //jqgrid js and css
6324
    if (in_array('jqgrid', $libraries)) {
6325
        $languaje   = 'en';
6326
        $platform_isocode = strtolower(api_get_language_isocode());
6327
6328
        //languages supported by jqgrid see files in main/inc/lib/javascript/jqgrid/js/i18n
6329
        $jqgrid_langs = array(
6330
            'bg', 'bg1251', 'cat','cn','cs','da','de','el','en','es','fa','fi','fr','gl','he','hu','is','it','ja','nl','no','pl','pt-br','pt','ro','ru','sk','sr','sv','tr','ua'
6331
        );
6332
6333
        if (in_array($platform_isocode, $jqgrid_langs)) {
6334
            $languaje = $platform_isocode;
6335
        }
6336
        //$js .= '<link rel="stylesheet" href="'.$js_path.'jqgrid/css/ui.jqgrid.css" type="text/css">';
6337
        $js .= api_get_css($js_path.'jqgrid/css/ui.jqgrid.css');
6338
        $js .= api_get_js('jqgrid/js/i18n/grid.locale-'.$languaje.'.js');
6339
        $js .= api_get_js('jqgrid/js/jquery.jqGrid.min.js');
6340
    }
6341
6342
    //Document multiple upload funcionality
6343
    if (in_array('jquery-upload', $libraries)) {
6344
6345
        $js .= api_get_asset('blueimp-load-image/js/load-image.all.min.js');
6346
        $js .= api_get_asset('blueimp-canvas-to-blob/js/canvas-to-blob.min.js');
6347
        $js .= api_get_asset('jquery-file-upload/js/jquery.iframe-transport.js');
6348
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload.js');
6349
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-process.js');
6350
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-image.js');
6351
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-audio.js');
6352
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-video.js');
6353
        $js .= api_get_asset('jquery-file-upload/js/jquery.fileupload-validate.js');
6354
6355
        $js .= api_get_css(api_get_path(WEB_PATH).'web/assets/jquery-file-upload/css/jquery.fileupload.css');
6356
        $js .= api_get_css(api_get_path(WEB_PATH).'web/assets/jquery-file-upload/css/jquery.fileupload-ui.css');
6357
    }
6358
6359
    // jquery datepicker
6360
    if (in_array('datepicker', $libraries)) {
6361
        $languaje   = 'en-GB';
6362
        $platform_isocode = strtolower(api_get_language_isocode());
6363
6364
        // languages supported by jqgrid see files in main/inc/lib/javascript/jqgrid/js/i18n
6365
        $datapicker_langs = array(
6366
            'af', 'ar', 'ar-DZ', 'az', 'bg', 'bs', 'ca', 'cs', 'cy-GB', 'da', 'de', 'el', 'en-AU', 'en-GB', 'en-NZ', 'eo', 'es', 'et', 'eu', 'fa', 'fi', 'fo', 'fr', 'fr-CH', 'gl', 'he', 'hi', 'hr', 'hu', 'hy', 'id', 'is', 'it', 'ja', 'ka', 'kk', 'km', 'ko', 'lb', 'lt', 'lv', 'mk', 'ml', 'ms', 'nl', 'nl-BE', 'no', 'pl', 'pt', 'pt-BR', 'rm', 'ro', 'ru', 'sk', 'sl', 'sq', 'sr', 'sr-SR', 'sv', 'ta', 'th', 'tj', 'tr', 'uk', 'vi', 'zh-CN', 'zh-HK', 'zh-TW'
6367
        );
6368
        if (in_array($platform_isocode, $datapicker_langs)) {
6369
            $languaje = $platform_isocode;
6370
        }
6371
6372
        $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
6373
        $script = '<script>
6374
        $(function(){
6375
            $.datepicker.setDefaults($.datepicker.regional["'.$languaje.'"]);
6376
            $.datepicker.regional["local"] = $.datepicker.regional["'.$languaje.'"];
6377
        });
6378
        </script>
6379
        ';
6380
        $js .= $script;
6381
    }
6382
    return $js;
6383
}
6384
6385
/**
6386
 * Returns the course's URL
6387
 *
6388
 * This function relies on api_get_course_info()
6389
 * @param   string  The course code - optional (takes it from session if not given)
6390
 * @param   int     The session id  - optional (takes it from session if not given)
6391
 * @param integer $session_id
6392
 * @return  string|null   The URL of the course or null if something does not work
6393
 * @author  Julio Montoya <[email protected]>
6394
 */
6395
function api_get_course_url($course_code = null, $session_id = null)
6396
{
6397
    if (empty($course_code)) {
6398
        $course_info = api_get_course_info();
6399
    } else {
6400
        $course_info = api_get_course_info($course_code);
6401
    }
6402
    if (empty($session_id)) {
6403
        $session_url = '?id_session='.api_get_session_id();
6404
    } else {
6405
        $session_url = '?id_session='.intval($session_id);
6406
    }
6407
    /*
6408
    if (empty($group_id)) {
6409
        $group_url = '&gidReq='.api_get_group_id();
6410
    } else {
6411
        $group_url = '&gidReq='.intval($group_id);
6412
    }*/
6413
    if (!empty($course_info['path'])) {
6414
        return api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php'.$session_url;
6415
    }
6416
    return null;
6417
}
6418
6419
/**
6420
 *
6421
 * Check if the current portal has the $_configuration['multiple_access_urls'] parameter on
6422
 * @return bool true if multi site is enabled
6423
 *
6424
 **/
6425
function api_get_multiple_access_url() {
6426
    global $_configuration;
6427
    if (isset($_configuration['multiple_access_urls']) && $_configuration['multiple_access_urls']) {
6428
        return true;
6429
    }
6430
    return false;
6431
}
6432
6433
/**
6434
 * @return bool
6435
 */
6436
function api_is_multiple_url_enabled() {
6437
    return api_get_multiple_access_url();
6438
}
6439
6440
/**
6441
 * Returns a md5 unique id
6442
 * @todo add more parameters
6443
 */
6444
function api_get_unique_id() {
6445
    $id = md5(time().uniqid().api_get_user_id().api_get_course_id().api_get_session_id());
6446
    return $id;
6447
}
6448
6449
/**
6450
 * Get home path
6451
 * @return string
6452
 */
6453
function api_get_home_path()
6454
{
6455
    // FIX : Start the routing determination from central path definition
6456
    $home = api_get_path(SYS_HOME_PATH);
6457
    if (api_get_multiple_access_url()) {
6458
        $access_url_id = api_get_current_access_url_id();
6459
        $url_info = api_get_access_url($access_url_id);
6460
        $url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
6461
        $clean_url = api_replace_dangerous_char($url);
6462
        $clean_url = str_replace('/', '-', $clean_url);
6463
        $clean_url .= '/';
6464
        if ($clean_url != 'localhost/') {
6465
            // means that the multiple URL was not well configured we don't rename the $home variable
6466
            return "{$home}{$clean_url}";
6467
        }
6468
    }
6469
6470
    return $home;
6471
}
6472
6473
/**
6474
 *
6475
 * @param int Course id
6476
 * @param int tool id: TOOL_QUIZ, TOOL_FORUM, TOOL_STUDENTPUBLICATION, TOOL_LEARNPATH
6477
 * @param int the item id (tool id, exercise id, lp id)
6478
 *
6479
 */
6480
function api_resource_is_locked_by_gradebook($item_id, $link_type, $course_code = null) {
6481
    if (api_is_platform_admin()) {
6482
        return false;
6483
    }
6484
    if (api_get_setting('gradebook_locking_enabled') == 'true') {
6485
        if (empty($course_code)) {
6486
            $course_code = api_get_course_id();
6487
        }
6488
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
6489
        $item_id = intval($item_id);
6490
        $link_type = intval($link_type);
6491
        $course_code = Database::escape_string($course_code);
6492
        $sql = "SELECT locked FROM $table
6493
                WHERE locked = 1 AND ref_id = $item_id AND type = $link_type AND course_code = '$course_code' ";
6494
        $result = Database::query($sql);
6495
        if (Database::num_rows($result)) {
6496
            return true;
6497
        }
6498
    }
6499
    return false;
6500
}
6501
6502
/**
6503
 * Blocks a page if the item was added in a gradebook
6504
 *
6505
 * @param int       exercise id, work id, thread id,
6506
 * @param int       LINK_EXERCISE, LINK_STUDENTPUBLICATION, LINK_LEARNPATH LINK_FORUM_THREAD, LINK_ATTENDANCE
6507
 * see gradebook/lib/be/linkfactory
6508
 * @param string    course code
6509
 * @return false|null
6510
 */
6511
function api_block_course_item_locked_by_gradebook($item_id, $link_type, $course_code = null) {
6512
    if (api_is_platform_admin()) {
6513
        return false;
6514
    }
6515
6516
    if (api_resource_is_locked_by_gradebook($item_id, $link_type, $course_code)) {
6517
        $message = Display::return_message(get_lang('ResourceLockedByGradebook'), 'warning');
6518
        api_not_allowed(true, $message);
6519
    }
6520
}
6521
/**
6522
 * Checks the PHP version installed is enough to run Chamilo
6523
 * @param string Include path (used to load the error page)
6524
 * @return void
6525
 */
6526
function api_check_php_version($my_inc_path = null) {
6527
    if (!function_exists('version_compare') || version_compare( phpversion(), REQUIRED_PHP_VERSION, '<')) {
6528
        $global_error_code = 1;
6529
        // Incorrect PHP version
6530
        $global_page = $my_inc_path.'global_error_message.inc.php';
6531
        if (file_exists($global_page)) {
6532
            require $global_page;
6533
        }
6534
        exit;
6535
    }
6536
}
6537
/**
6538
 * Checks whether the Archive directory is present and writeable. If not,
6539
 * prints a warning message.
6540
 */
6541
function api_check_archive_dir() {
6542 View Code Duplication
    if (is_dir(api_get_path(SYS_ARCHIVE_PATH)) && !is_writable(api_get_path(SYS_ARCHIVE_PATH))) {
6543
        $message = Display::return_message(get_lang('ArchivesDirectoryNotWriteableContactAdmin'),'warning');
6544
        api_not_allowed(true, $message);
6545
    }
6546
}
6547
/**
6548
 * Returns an array of global configuration settings which should be ignored
6549
 * when printing the configuration settings screens
6550
 * @return array Array of strings, each identifying one of the excluded settings
6551
 */
6552
function api_get_locked_settings() {
6553
    return array(
6554
        'server_type',
6555
        'permanently_remove_deleted_files',
6556
        'account_valid_duration',
6557
        'service_ppt2lp',
6558
        'wcag_anysurfer_public_pages',
6559
        'upload_extensions_list_type',
6560
        'upload_extensions_blacklist',
6561
        'upload_extensions_whitelist',
6562
        'upload_extensions_skip',
6563
        'upload_extensions_replace_by',
6564
        'hide_dltt_markup',
6565
        'split_users_upload_directory',
6566
        'permissions_for_new_directories',
6567
        'permissions_for_new_files',
6568
        'platform_charset',
6569
        'ldap_description',
6570
        'cas_activate',
6571
        'cas_server',
6572
        'cas_server_uri',
6573
        'cas_port',
6574
        'cas_protocol',
6575
        'cas_add_user_activate',
6576
        'update_user_info_cas_with_ldap',
6577
        'languagePriority1',
6578
        'languagePriority2',
6579
        'languagePriority3',
6580
        'languagePriority4',
6581
        'login_is_email',
6582
        'chamilo_database_version'
6583
    );
6584
}
6585
6586
/**
6587
 * Checks if the user is corrently logged in. Returns the user ID if he is, or
6588
 * false if he isn't. If the user ID is given and is an integer, then the same
6589
 * ID is simply returned
6590
 * @param  integer User ID
6591
 * @return boolean Integer User ID is logged in, or false otherwise
6592
 */
6593
function api_user_is_login($user_id = null) {
6594
    $user_id = empty($user_id) ? api_get_user_id() : intval($user_id);
6595
    return $user_id && !api_is_anonymous();
6596
}
6597
6598
/**
6599
 * Guess the real ip for register in the database, even in reverse proxy cases.
6600
 * To be recognized, the IP has to be found in either $_SERVER['REMOTE_ADDR'] or
6601
 * in $_SERVER['HTTP_X_FORWARDED_FOR'], which is in common use with rproxies.
6602
 * @return string the user's real ip (unsafe - escape it before inserting to db)
6603
 * @author Jorge Frisancho Jibaja <[email protected]>, USIL - Some changes to allow the use of real IP using reverse proxy
6604
 * @version CEV CHANGE 24APR2012
6605
 */
6606
function api_get_real_ip(){
6607
    // Guess the IP if behind a reverse proxy
6608
    global $debug;
6609
    $ip = trim($_SERVER['REMOTE_ADDR']);
6610
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
6611
        if (preg_match('/,/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
6612
            @list($ip1, $ip2) = @explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
6613
        } else {
6614
            $ip1 = $_SERVER['HTTP_X_FORWARDED_FOR'];
6615
        }
6616
        $ip = trim($ip1);
6617
    }
6618
    if (!empty($debug)) error_log('Real IP: '.$ip);
6619
    return $ip;
6620
}
6621
6622
/**
6623
 * Checks whether an IP is included inside an IP range
6624
 * @param string IP address
6625
 * @param string IP range
6626
 * @param string $ip
6627
 * @return bool True if IP is in the range, false otherwise
6628
 * @author claudiu at cnixs dot com  on http://www.php.net/manual/fr/ref.network.php#55230
6629
 * @author Yannick Warnier for improvements and managment of multiple ranges
6630
 * @todo check for IPv6 support
6631
 */
6632
function api_check_ip_in_range($ip,$range)
6633
{
6634
    if (empty($ip) or empty($range)) {
6635
        return false;
6636
    }
6637
    $ip_ip = ip2long ($ip);
6638
    // divide range param into array of elements
6639
    if (strpos($range,',')!==false) {
6640
        $ranges = explode(',',$range);
6641
    } else {
6642
        $ranges = array($range);
6643
    }
6644
    foreach ($ranges as $range) {
6645
        $range = trim($range);
6646
        if (empty($range)) { continue; }
6647
        if (strpos($range,'/')===false) {
6648
            if (strcmp($ip,$range)===0) {
6649
                return true; // there is a direct IP match, return OK
6650
            }
6651
            continue; //otherwise, get to the next range
6652
        }
6653
        // the range contains a "/", so analyse completely
6654
        list ($net, $mask) = explode("/", $range);
6655
6656
        $ip_net = ip2long ($net);
6657
        // mask binary magic
6658
        $ip_mask = ~((1 << (32 - $mask)) - 1);
6659
6660
        $ip_ip_net = $ip_ip & $ip_mask;
6661
        if ($ip_ip_net == $ip_net) {
6662
            return true;
6663
        }
6664
    }
6665
6666
    return false;
6667
}
6668
6669
function api_check_user_access_to_legal($course_visibility) {
6670
    $course_visibility_list = array(COURSE_VISIBILITY_OPEN_WORLD, COURSE_VISIBILITY_OPEN_PLATFORM);
6671
    return in_array($course_visibility, $course_visibility_list) || api_is_drh();
6672
}
6673
6674
/**
6675
 * Checks if the global chat is enabled or not
6676
 *
6677
 * @return bool
6678
 */
6679
function api_is_global_chat_enabled()
6680
{
6681
    return
6682
        !api_is_anonymous() &&
6683
        api_get_setting('allow_global_chat') == 'true' &&
6684
        api_get_setting('allow_social_tool') == 'true';
6685
}
6686
6687
/**
6688
 * @todo Fix tool_visible_by_default_at_creation labels
6689
 * @todo Add sessionId parameter to avoid using context
6690
 *
6691
 * @param int $item_id
6692
 * @param int $tool_id
6693
 * @param int $group_id iid
6694
 * @param array $courseInfo
6695
 */
6696
function api_set_default_visibility(
6697
    $item_id,
6698
    $tool_id,
6699
    $group_id = 0,
6700
    $courseInfo = array(),
6701
    $sessionId = 0,
6702
    $userId = 0
6703
) {
6704
    $courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
6705
    $courseId = $courseInfo['real_id'];
6706
    $courseCode = $courseInfo['code'];
6707
    $sessionId = empty($sessionId) ? api_get_session_id() : $sessionId;
6708
    $userId = empty($userId) ? api_get_user_id() : $userId;
6709
6710
    if (empty($group_id)) {
6711
        $group_id = api_get_group_id();
6712
    }
6713
6714
    $groupInfo = GroupManager::get_group_properties($group_id);
6715
    $groupIid = 0;
6716
    if ($groupInfo) {
6717
        $groupIid = $groupInfo['iid'];
6718
    }
6719
6720
    $original_tool_id = $tool_id;
6721
6722
    switch ($tool_id) {
6723
        case TOOL_LINK:
6724
        case TOOL_LINK_CATEGORY:
6725
            $tool_id = 'links';
6726
            break;
6727
        case TOOL_DOCUMENT:
6728
            $tool_id = 'documents';
6729
            break;
6730
        case TOOL_LEARNPATH:
6731
            $tool_id = 'learning';
6732
            break;
6733
        case TOOL_ANNOUNCEMENT:
6734
            $tool_id = 'announcements';
6735
            break;
6736
        case TOOL_FORUM:
6737
        case TOOL_FORUM_CATEGORY:
6738
        case TOOL_FORUM_THREAD:
6739
            $tool_id = 'forums';
6740
            break;
6741
        case TOOL_QUIZ:
6742
            $tool_id = 'quiz';
6743
            break;
6744
    }
6745
    $setting = api_get_setting('tool_visible_by_default_at_creation');
6746
6747
    if (isset($setting[$tool_id])) {
6748
        $visibility = 'invisible';
6749
        if ($setting[$tool_id] == 'true') {
6750
            $visibility = 'visible';
6751
        }
6752
6753
        // Read the portal and course default visibility
6754
        if ($tool_id == 'documents') {
6755
            $visibility = DocumentManager::getDocumentDefaultVisibility($courseCode);
6756
        }
6757
6758
        api_item_property_update(
6759
            $courseInfo,
6760
            $original_tool_id,
6761
            $item_id,
6762
            $visibility,
6763
            $userId,
6764
            $groupIid,
6765
            null,
6766
            null,
6767
            null,
6768
            api_get_session_id()
6769
        );
6770
6771
        // Fixes default visibility for tests
6772
6773
        switch ($original_tool_id) {
6774
            case TOOL_QUIZ:
6775
                if (empty($sessionId)) {
6776
                    $objExerciseTmp = new Exercise($courseId);
6777
                    $objExerciseTmp->read($item_id);
6778
                    if ($visibility == 'visible') {
6779
                        $objExerciseTmp->enable();
6780
                        $objExerciseTmp->save();
6781
                    } else {
6782
                        $objExerciseTmp->disable();
6783
                        $objExerciseTmp->save();
6784
                    }
6785
                }
6786
                break;
6787
        }
6788
    }
6789
}
6790
6791
/**
6792
 * @return string
6793
 */
6794
function api_get_security_key() {
6795
    return api_get_configuration_value('security_key');
6796
}
6797
6798
/**
6799
 * @param int $user_id
6800
 * @param int $courseId
6801
 * @param int $session_id
6802
 * @return array
6803
 */
6804
function api_detect_user_roles($user_id, $courseId, $session_id = 0)
6805
{
6806
    $user_roles = array();
6807
    /*$user_info = api_get_user_info($user_id);
6808
    $user_roles[] = $user_info['status'];*/
6809
    $courseInfo = api_get_course_info_by_id($courseId);
6810
    $course_code = $courseInfo['code'];
6811
6812
    $url_id = api_get_current_access_url_id();
6813
    if (api_is_platform_admin_by_id($user_id, $url_id)) {
6814
        $user_roles[] = PLATFORM_ADMIN;
6815
    }
6816
6817
    /*if (api_is_drh()) {
6818
        $user_roles[] = DRH;
6819
    }*/
6820
6821
    if (!empty($session_id)) {
6822
        if (SessionManager::user_is_general_coach($user_id, $session_id)) {
6823
            $user_roles[] = SESSION_GENERAL_COACH;
6824
        }
6825
    }
6826
6827
    if (!empty($course_code)) {
6828
        if (empty($session_id)) {
6829
            if (CourseManager::is_course_teacher($user_id, $course_code)) {
6830
                $user_roles[] = COURSEMANAGER;
6831
            }
6832
            if (CourseManager::get_tutor_in_course_status($user_id, $courseInfo['real_id'])) {
6833
                $user_roles[] = COURSE_TUTOR;
6834
            }
6835
6836
            if (CourseManager::is_user_subscribed_in_course($user_id, $course_code)) {
6837
                $user_roles[] = COURSE_STUDENT;
6838
            }
6839
        } else {
6840
            $user_status_in_session = SessionManager::get_user_status_in_course_session(
6841
                $user_id,
6842
                $courseId,
6843
                $session_id
6844
            );
6845
6846
            if (!empty($user_status_in_session)) {
6847
                if ($user_status_in_session == 0) {
6848
                    $user_roles[] = SESSION_STUDENT;
6849
                }
6850
                if ($user_status_in_session == 2) {
6851
                    $user_roles[] = SESSION_COURSE_COACH;
6852
                }
6853
            }
6854
6855
            /*if (api_is_course_session_coach($user_id, $course_code, $session_id)) {
6856
               $user_roles[] = SESSION_COURSE_COACH;
6857
            }*/
6858
        }
6859
    }
6860
    return $user_roles;
6861
}
6862
6863
/**
6864
 * @param int $courseId
6865
 * @param int $session_id
6866
 * @return bool
6867
 */
6868
function api_coach_can_edit_view_results($courseId = null, $session_id = null)
6869
{
6870
    $user_id = api_get_user_id();
6871
6872
    if (empty($courseId)) {
6873
        $courseId = api_get_course_int_id();
6874
    }
6875
6876
    if (empty($session_id)) {
6877
        $session_id = api_get_session_id();
6878
    }
6879
6880
    if (api_is_platform_admin()) {
6881
        return true;
6882
    }
6883
6884
    $roles = api_detect_user_roles($user_id, $courseId, $session_id);
6885
6886
    if (in_array(SESSION_COURSE_COACH, $roles)) {
6887
        //return api_get_setting('session_tutor_reports_visibility') == 'true';
6888
        return true;
6889
    } else {
6890
        if (in_array(COURSEMANAGER, $roles)) {
6891
            return true;
6892
        }
6893
        return false;
6894
    }
6895
}
6896
6897
function api_get_js_simple($file) {
6898
    return '<script type="text/javascript" src="'.$file.'"></script>'."\n";
6899
}
6900
6901
function api_set_settings_and_plugins() {
6902
    global $_configuration;
6903
    $_setting = array();
6904
    $_plugins = array();
6905
6906
    // access_url == 1 is the default chamilo location
6907
    $settings_by_access_list = array();
6908
    $access_url_id = api_get_current_access_url_id();
6909 View Code Duplication
    if ($access_url_id != 1) {
6910
        $url_info = api_get_access_url($_configuration['access_url']);
6911
        if ($url_info['active'] == 1) {
6912
            $settings_by_access = & api_get_settings(null, 'list', $_configuration['access_url'], 1);
6913
            foreach ($settings_by_access as & $row) {
6914
                if (empty($row['variable'])) {
6915
                    $row['variable'] = 0;
6916
                }
6917
                if (empty($row['subkey'])) {
6918
                    $row['subkey'] = 0;
6919
                }
6920
                if (empty($row['category'])) {
6921
                    $row['category'] = 0;
6922
                }
6923
                $settings_by_access_list[$row['variable']][$row['subkey']][$row['category']] = $row;
6924
            }
6925
        }
6926
    }
6927
6928
    $result = api_get_settings(null, 'list', 1);
6929
6930 View Code Duplication
    foreach ($result as & $row) {
6931
        if ($access_url_id != 1) {
6932
            if ($url_info['active'] == 1) {
6933
                $var = empty($row['variable']) ? 0 : $row['variable'];
6934
                $subkey = empty($row['subkey']) ? 0 : $row['subkey'];
6935
                $category = empty($row['category']) ? 0 : $row['category'];
6936
            }
6937
6938
            if ($row['access_url_changeable'] == 1 && $url_info['active'] == 1) {
6939
                if (isset($settings_by_access_list[$var]) &&
6940
                    $settings_by_access_list[$var][$subkey][$category]['selected_value'] != '') {
6941
                    if ($row['subkey'] == null) {
6942
                        $_setting[$row['variable']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
6943
                    } else {
6944
                        $_setting[$row['variable']][$row['subkey']] = $settings_by_access_list[$var][$subkey][$category]['selected_value'];
6945
                    }
6946
                } else {
6947
                    if ($row['subkey'] == null) {
6948
                        $_setting[$row['variable']] = $row['selected_value'];
6949
                    } else {
6950
                        $_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
6951
                    }
6952
                }
6953
            } else {
6954
                if ($row['subkey'] == null) {
6955
                    $_setting[$row['variable']] = $row['selected_value'];
6956
                } else {
6957
                    $_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
6958
                }
6959
            }
6960
        } else {
6961
            if ($row['subkey'] == null) {
6962
                $_setting[$row['variable']] = $row['selected_value'];
6963
            } else {
6964
                $_setting[$row['variable']][$row['subkey']] = $row['selected_value'];
6965
            }
6966
        }
6967
    }
6968
6969
    $result = api_get_settings('Plugins', 'list', $access_url_id);
6970
    $_plugins = array();
6971 View Code Duplication
    foreach ($result as & $row) {
6972
        $key = & $row['variable'];
6973
        if (is_string($_setting[$key])) {
6974
            $_setting[$key] = array();
6975
        }
6976
        $_setting[$key][] = $row['selected_value'];
6977
        $_plugins[$key][] = $row['selected_value'];
6978
    }
6979
6980
    $_SESSION['_setting'] = $_setting;
6981
    $_SESSION['_plugins'] = $_plugins;
6982
}
6983
6984
/**
6985
 * Tries to set memory limit, if authorized and new limit is higher than current
6986
 * @param string New memory limit
6987
 * @param string $mem
6988
 * @return bool True on success, false on failure or current is higher than suggested
6989
 * @assert (null) === false
6990
 * @assert (-1) === false
6991
 * @assert (0) === true
6992
 * @assert ('1G') === true
6993
 */
6994
function api_set_memory_limit($mem){
6995
    //if ini_set() not available, this function is useless
6996
    if (!function_exists('ini_set') || is_null($mem) || $mem == -1) {
6997
        return false;
6998
    }
6999
7000
    $memory_limit = ini_get('memory_limit');
7001
    if (api_get_bytes_memory_limit($mem) > api_get_bytes_memory_limit($memory_limit)){
7002
        ini_set('memory_limit', $mem);
7003
        return true;
7004
    }
7005
    return false;
7006
}
7007
7008
/**
7009
 * Gets memory limit in bytes
7010
 * @param string The memory size (128M, 1G, 1000K, etc)
7011
 * @return int
7012
 * @assert (null) === false
7013
 * @assert ('1t')  === 1099511627776
7014
 * @assert ('1g')  === 1073741824
7015
 * @assert ('1m')  === 1048576
7016
 * @assert ('100k') === 102400
7017
 */
7018
function api_get_bytes_memory_limit($mem){
7019
    $size = strtolower(substr($mem,-1));
7020
7021
    switch ($size) {
7022
        case 't':
7023
            $mem = intval(substr($mem,-1))*1024*1024*1024*1024;
7024
            break;
7025
        case 'g':
7026
            $mem = intval(substr($mem,0,-1))*1024*1024*1024;
7027
            break;
7028
        case 'm':
7029
            $mem = intval(substr($mem,0,-1))*1024*1024;
7030
            break;
7031
        case 'k':
7032
            $mem = intval(substr($mem,0,-1))*1024;
7033
            break;
7034
        default:
7035
            // we assume it's integer only
7036
            $mem = intval($mem);
7037
            break;
7038
    }
7039
    return $mem;
7040
}
7041
7042
/**
7043
 * Finds all the information about a user from username instead of user id
7044
 *
7045
 * @param string $officialCode
7046
 * @return array $user_info user_id, lastname, firstname, username, email, ...
7047
 * @author Yannick Warnier <[email protected]>
7048
 */
7049 View Code Duplication
function api_get_user_info_from_official_code($officialCode)
7050
{
7051
    if (empty($officialCode)) {
7052
        return false;
7053
    }
7054
    $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)."
7055
            WHERE official_code ='".Database::escape_string($officialCode)."'";
7056
    $result = Database::query($sql);
7057
    if (Database::num_rows($result) > 0) {
7058
        $result_array = Database::fetch_array($result);
7059
        return _api_format_user($result_array);
7060
    }
7061
    return false;
7062
}
7063
7064
/**
7065
 * @param string $usernameInputId
7066
 * @param string $passwordInputId
7067
 * @return null|string
7068
 */
7069
function api_get_password_checker_js($usernameInputId, $passwordInputId)
7070
{
7071
    $checkPass = api_get_setting('allow_strength_pass_checker');
7072
    $useStrengthPassChecker = $checkPass === 'true';
7073
7074
    if ($useStrengthPassChecker === false) {
7075
        return null;
7076
    }
7077
7078
    $translations = [
7079
        'wordLength' => get_lang('PasswordIsTooShort'),
7080
        'wordNotEmail' => get_lang('YourPasswordCannotBeTheSameAsYourEmail'),
7081
        'wordSimilarToUsername' => get_lang('YourPasswordCannotContainYourUsername'),
7082
        'wordTwoCharacterClasses' => get_lang('WordTwoCharacterClasses'),
7083
        'wordRepetitions' => get_lang('TooManyRepetitions'),
7084
        'wordSequences' => get_lang('YourPasswordContainsSequences'),
7085
        'errorList' => get_lang('ErrorsFound'),
7086
        'veryWeak' => get_lang('PasswordVeryWeak'),
7087
        'weak' => get_lang('PasswordWeak'),
7088
        'normal' => get_lang('PasswordNormal'),
7089
        'medium' => get_lang('PasswordMedium'),
7090
        'strong' => get_lang('PasswordStrong'),
7091
        'veryStrong' => get_lang('PasswordVeryStrong')
7092
    ];
7093
7094
    $js = api_get_asset('pwstrength-bootstrap/dist/pwstrength-bootstrap.min.js');
7095
    $js .=  "<script>    
7096
    var errorMessages = {
7097
        password_to_short : \"" . get_lang('PasswordIsTooShort')."\",
7098
        same_as_username : \"".get_lang('YourPasswordCannotBeTheSameAsYourUsername')."\"
7099
    };
7100
7101
    $(document).ready(function() {
7102
        var lang = ".json_encode($translations).";     
7103
        var options = {        
7104
            onLoad : function () {
7105
                //$('#messages').text('Start typing password');
7106
            },
7107
            onKeyUp: function (evt) {
7108
                $(evt.target).pwstrength('outputErrorList');
7109
            },
7110
            errorMessages : errorMessages,
7111
            viewports: {
7112
                progress: '#password_progress',
7113
                verdict: '#password-verdict',
7114
                errors: '#password-errors'
7115
            },
7116
            usernameField: '$usernameInputId'
7117
        };
7118
        options.i18n = {
7119
            t: function (key) {
7120
                var result = lang[key];
7121
                return result === key ? '' : result; // This assumes you return the                
7122
            }
7123
        };
7124
        $('".$passwordInputId."').pwstrength(options);
7125
    });
7126
    </script>";
7127
7128
    return $js;
7129
}
7130
7131
/**
7132
 * @param string $username
7133
 * create an user extra field called 'captcha_blocked_until_date'
7134
 */
7135
function api_block_account_captcha($username)
7136
{
7137
    $userInfo = api_get_user_info_from_username($username);
7138
    if (empty($userInfo)) {
7139
        return false;
7140
    }
7141
    $minutesToBlock = api_get_setting('captcha_time_to_block');
7142
    $time = time() + $minutesToBlock*60;
7143
    UserManager::update_extra_field_value(
7144
        $userInfo['user_id'],
7145
        'captcha_blocked_until_date',
7146
        api_get_utc_datetime($time)
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime($time) targeting api_get_utc_datetime() can also be of type null or object<DateTime>; however, UserManager::update_extra_field_value() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
7147
    );
7148
}
7149
7150
/**
7151
 * @param string $username
7152
 */
7153
function api_clean_account_captcha($username)
7154
{
7155
    $userInfo = api_get_user_info_from_username($username);
7156
    if (empty($userInfo)) {
7157
        return false;
7158
    }
7159
    Session::erase('loginFailedCount');
7160
    UserManager::update_extra_field_value(
7161
        $userInfo['user_id'],
7162
        'captcha_blocked_until_date',
7163
        null
7164
    );
7165
}
7166
7167
/**
7168
 * @param string $username
7169
 * @return bool
7170
 */
7171
function api_get_user_blocked_by_captcha($username)
7172
{
7173
    $userInfo = api_get_user_info_from_username($username);
7174
    if (empty($userInfo)) {
7175
        return false;
7176
    }
7177
    $data = UserManager::get_extra_user_data_by_field(
7178
        $userInfo['user_id'],
7179
        'captcha_blocked_until_date'
7180
    );
7181
    if (isset($data) && isset($data['captcha_blocked_until_date'])) {
7182
        return $data['captcha_blocked_until_date'];
7183
    }
7184
    return false;
7185
}
7186
7187
/**
7188
 * Remove tags from HTML anf return the $in_number_char first non-HTML char
7189
 * Postfix the text with "..." if it has been truncated.
7190
 * @param integer $in_number_char
7191
 * @return string
7192
 * @author hubert borderiou
7193
 */
7194
function api_get_short_text_from_html($in_html, $in_number_char)
7195
{
7196
    $out_res = api_remove_tags_with_space($in_html, false);
7197
    $postfix = "...";
7198
    if (strlen($out_res) > $in_number_char) {
7199
        $out_res = substr($out_res, 0, $in_number_char).$postfix;
7200
    }
7201
    return $out_res;
7202
}
7203
7204
/**
7205
 * Replace tags with a space in a text.
7206
 * If $in_double_quote_replace, replace " with '' (for HTML attribute purpose, for exemple)
7207
 * @return string
7208
 * @author hubert borderiou
7209
 */
7210
function api_remove_tags_with_space($in_html, $in_double_quote_replace = true) {
7211
    $out_res = $in_html;
7212
    if ($in_double_quote_replace) {
7213
        $out_res = str_replace('"', "''", $out_res);
7214
    }
7215
    // avoid text stuck together when tags are removed, adding a space after >
7216
    $out_res = str_replace (">", "> ", $out_res);
7217
    $out_res = strip_tags($out_res);
7218
7219
    return $out_res;
7220
}
7221
7222
/**
7223
 * If true, the drh can access all content (courses, users) inside a session
7224
 * @return bool
7225
 */
7226
function api_drh_can_access_all_session_content()
7227
{
7228
    $value = api_get_setting('drh_can_access_all_session_content');
7229
7230
    return $value === 'true';
7231
}
7232
7233
/**
7234
 * @param string $tool
7235
 * @param string $setting
7236
 * @param integer $defaultValue
7237
 * @return string
7238
 */
7239
function api_get_default_tool_setting($tool, $setting, $defaultValue)
7240
{
7241
    global $_configuration;
7242
    if (isset($_configuration[$tool]) &&
7243
        isset($_configuration[$tool]['default_settings']) &&
7244
        isset($_configuration[$tool]['default_settings'][$setting])
7245
    ) {
7246
        return $_configuration[$tool]['default_settings'][$setting];
7247
    }
7248
7249
    return $defaultValue;
7250
}
7251
7252
/**
7253
 * Checks if user can login as another user
7254
 *
7255
 * @param int $loginAsUserId the user id to log in
7256
 * @param int $userId my user id
7257
 * @return bool
7258
 */
7259
function api_can_login_as($loginAsUserId, $userId = null)
7260
{
7261
    if (empty($userId)) {
7262
        $userId = api_get_user_id();
7263
    }
7264
    if ($loginAsUserId == $userId) {
7265
        return false;
7266
    }
7267
7268
    if (empty($loginAsUserId)) {
7269
        return false;
7270
    }
7271
7272
    if ($loginAsUserId != strval(intval($loginAsUserId))) {
7273
        return false;
7274
    }
7275
7276
    // Check if the user to login is an admin
7277
    if (api_is_platform_admin_by_id($loginAsUserId)) {
7278
        // Only super admins can login to admin accounts
7279
        if (!api_global_admin_can_edit_admin($loginAsUserId)) {
7280
            return false;
7281
        }
7282
    }
7283
7284
    $userInfo = api_get_user_info($userId);
7285
7286
    $isDrh = function() use($loginAsUserId) {
7287
        if (api_is_drh()) {
7288
            if (api_drh_can_access_all_session_content()) {
7289
                $users = SessionManager::getAllUsersFromCoursesFromAllSessionFromStatus('drh_all', api_get_user_id());
7290
                $userList = array();
7291
                if (is_array($users)) {
7292
                    foreach ($users as $user) {
7293
                        $userList[] = $user['user_id'];
7294
                    }
7295
                }
7296
                if (in_array($loginAsUserId, $userList)) {
7297
                    return true;
7298
                }
7299
            } else {
7300
                if (api_is_drh() && UserManager::is_user_followed_by_drh($loginAsUserId, api_get_user_id())) {
7301
                    return true;
7302
                }
7303
            }
7304
        }
7305
        return false;
7306
    };
7307
7308
    return api_is_platform_admin() || (api_is_session_admin() && $userInfo['status'] == 5) || $isDrh();
7309
}
7310
7311
/**
7312
 * @return bool
7313
 */
7314
function api_is_allowed_in_course()
7315
{
7316
    return Session::read('is_allowed_in_course');
7317
}
7318
7319
/**
7320
 * Set the cookie to go directly to the course code $in_firstpage
7321
 * after login
7322
 * @param string $in_firstpage is the course code of the course to go
7323
 */
7324
function api_set_firstpage_parameter($in_firstpage)
7325
{
7326
    setcookie('GotoCourse', $in_firstpage);
7327
}
7328
7329
/**
7330
 * Delete the cookie to go directly to the course code $in_firstpage
7331
 * after login
7332
 */
7333
function api_delete_firstpage_parameter()
7334
{
7335
    setcookie('GotoCourse', '', time() - 3600);
7336
}
7337
7338
/**
7339
 * @return boolean if course_code for direct course access after login is set
7340
 */
7341
function exist_firstpage_parameter()
7342
{
7343
    return (isset($_COOKIE['GotoCourse']) && $_COOKIE['GotoCourse'] != "");
7344
}
7345
7346
/**
7347
 * @return return the course_code of the course where user login
7348
 */
7349
function api_get_firstpage_parameter()
7350
{
7351
    return $_COOKIE['GotoCourse'];
7352
}
7353
7354
/**
7355
 * Return true on https install
7356
 * @return boolean
7357
 */
7358
function api_is_https()
7359
{
7360
    return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off');
7361
}
7362
7363
/**
7364
 * Return protocol (http or https)
7365
 * @return string
7366
 */
7367
function api_get_protocol()
7368
{
7369
    return api_is_https() ? 'https' : 'http';
7370
}
7371
7372
/**
7373
 * Return a string where " are replaced with 2 '
7374
 * It is useful when you pass a PHP variable in a Javascript browser dialog
7375
 * e.g. : alert("<?php get_lang('Message') ?>");
7376
 * and message contains character "
7377
 *
7378
 * @param string $in_text
7379
 * @return string
7380
 */
7381
function convert_double_quote_to_single($in_text)
7382
{
7383
    return api_preg_replace('/"/', "''", $in_text);
7384
}
7385
7386
/**
7387
 * Get origin
7388
 *
7389
 * @param string
7390
 * @return string
7391
 **/
7392
function api_get_origin()
7393
{
7394
    if (isset($_REQUEST['origin'])) {
7395
        return $_REQUEST['origin'] === 'learnpath' ? 'learnpath' : '';
7396
    }
7397
7398
    return '';
7399
}
7400
7401
/**
7402
 * Warns an user that the portal reach certain limit.
7403
 * @param string $limitName
7404
 */
7405
function api_warn_hosting_contact($limitName)
7406
{
7407
    $hostingParams = api_get_configuration_value(1);
7408
    $email = null;
7409
7410
    if (!empty($hostingParams)) {
7411
        if (isset($hostingParams['hosting_contact_mail'])) {
7412
            $email = $hostingParams['hosting_contact_mail'];
7413
        }
7414
    }
7415
7416
    if (!empty($email)) {
7417
        $subject = get_lang('HostingWarningReached');
7418
        $body = get_lang('PortalName').': '.api_get_path(WEB_PATH)." \n ";
7419
        $body .= get_lang('PortalLimitType').': '.$limitName." \n ";
7420
        if (isset($hostingParams[$limitName])) {
7421
            $body .= get_lang('Value') . ': ' . $hostingParams[$limitName];
7422
        }
7423
        api_mail_html(null, $email, $subject, $body);
7424
    }
7425
}
7426
7427
/**
7428
 * @param string $variable
7429
 * @return bool|mixed
7430
 */
7431
function api_get_configuration_value($variable)
7432
{
7433
    global $_configuration;
7434
    if (isset($_configuration[$variable])) {
7435
        return $_configuration[$variable];
7436
    }
7437
    return false;
7438
}
7439
7440
/**
7441
 * Returns supported image extensions in the portal
7442
 * @param   bool    $supportVectors Whether vector images should also be accepted or not
7443
 * @return  array   Supported image extensions in the portal
7444
 */
7445
function api_get_supported_image_extensions($supportVectors = true)
7446
{
7447
    // jpg can also be called jpeg, jpe, jfif and jif. See https://en.wikipedia.org/wiki/JPEG#JPEG_filename_extensions
7448
    $supportedImageExtensions = array('jpg', 'jpeg', 'png', 'gif', 'jpe', 'jfif', 'jif');
7449
    if ($supportVectors) {
7450
        array_push($supportedImageExtensions, 'svg');
7451
    }
7452
    if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
7453
        array_push($supportedImageExtensions, 'webp');
7454
    }
7455
    return $supportedImageExtensions;
7456
}
7457
7458
/**
7459
 * This setting changes the registration status for the campus
7460
 *
7461
 * @author Patrick Cool <[email protected]>, Ghent University
7462
 * @version August 2006
7463
 * @param   bool    $listCampus Whether we authorize
7464
 * @todo the $_settings should be reloaded here. => write api function for this and use this in global.inc.php also.
7465
 */
7466 View Code Duplication
function api_register_campus($listCampus = true) {
7467
    $tbl_settings = Database :: get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
7468
7469
    $sql = "UPDATE $tbl_settings SET selected_value='true' WHERE variable='registered'";
7470
    Database::query($sql);
7471
7472
    if (!$listCampus) {
7473
        $sql = "UPDATE $tbl_settings SET selected_value='true' WHERE variable='donotlistcampus'";
7474
        Database::query($sql);
7475
    }
7476
}
7477
7478
/**
7479
 * Checks whether current user is a student boss
7480
 * @global array $_user
7481
 * @return boolean
7482
 */
7483
function api_is_student_boss()
7484
{
7485
    $_user = api_get_user_info();
7486
7487
    return isset($_user['status']) && $_user['status'] == STUDENT_BOSS;
7488
}
7489
7490
/**
7491
 * Check whether the user type should be exclude.
7492
 * Such as invited or anonymous users
7493
 * @param boolean $checkDB Optional. Whether check the user status
7494
 * @param int $userId Options. The user id
7495
 *
7496
 * @return boolean
7497
 */
7498
function api_is_excluded_user_type($checkDB = false, $userId = 0)
7499
{
7500
    if ($checkDB) {
7501
        $userId = empty($userId) ? api_get_user_id() : intval($userId);
7502
7503
        if ($userId == 0) {
7504
            return true;
7505
        }
7506
7507
        $userInfo = api_get_user_info($userId);
7508
7509
        switch ($userInfo['status']) {
7510
            case INVITEE:
7511
                //no break;
7512
            case ANONYMOUS:
7513
                return true;
7514
            default:
7515
                return false;
7516
        }
7517
    }
7518
7519
    $isInvited = api_is_invitee();
7520
    $isAnonymous = api_is_anonymous();
7521
7522
    if ($isInvited || $isAnonymous) {
7523
        return true;
7524
    }
7525
7526
    return false;
7527
}
7528
7529
/**
7530
 * Get the user status to ignore in reports
7531
 * @param string $format Optional. The result type (array or string)
7532
 * @return array|string
7533
 */
7534
function api_get_users_status_ignored_in_reports($format = 'array')
7535
{
7536
    $excludedTypes = array(
7537
        INVITEE,
7538
        ANONYMOUS
7539
    );
7540
7541
    if ($format == 'string') {
7542
        return implode(', ', $excludedTypes);
7543
    }
7544
7545
    return $excludedTypes;
7546
}
7547
7548
/**
7549
 * Set the Site Use Cookie Warning for 1 year
7550
 */
7551
function api_set_site_use_cookie_warning_cookie()
7552
{
7553
    setcookie('ChamiloUsesCookies', 'ok', time()+31556926);
7554
}
7555
7556
/**
7557
 * Return true if the Site Use Cookie Warning Cookie warning exists
7558
 * @return bool
7559
 */
7560
function api_site_use_cookie_warning_cookie_exist()
7561
{
7562
    return isset($_COOKIE['ChamiloUsesCookies']);
7563
}
7564
7565
/**
7566
 * Given a number of seconds, format the time to show hours, minutes and seconds
7567
 * @param int $time The time in seconds
7568
 * @param string $originFormat Optional. PHP o JS
7569
 * @return string (00h00'00")
7570
 */
7571
function api_format_time($time, $originFormat = 'php')
7572
{
7573
    $h = get_lang('h');
7574
    $hours = $time / 3600;
7575
    $mins = ($time % 3600) / 60;
7576
    $secs = ($time % 60);
7577
7578
    if ($time < 0) {
7579
        $hours = 0;
7580
        $mins = 0;
7581
        $secs = 0;
7582
    }
7583
7584
    if ($originFormat == 'js') {
7585
        $formattedTime = trim(sprintf("%02d : %02d : %02d", $hours, $mins, $secs));
7586
    } else {
7587
        $formattedTime = trim(sprintf("%02d$h%02d'%02d\"", $hours, $mins, $secs));
7588
    }
7589
7590
    return $formattedTime;
7591
}
7592
7593
/**
7594
 * Create a new empty directory with index.html file
7595
 * @param string $name The new directory name
7596
 * @param string $parentDirectory Directory parent directory name
7597
 * @return boolean Return true if the directory was create. Otherwise return false
7598
 */
7599
function api_create_protected_dir($name, $parentDirectory)
7600
{
7601
    $isCreated = false;
7602
7603
    if (!is_writable($parentDirectory)) {
7604
        return false;
7605
    }
7606
7607
    $fullPath = $parentDirectory . api_replace_dangerous_char($name);
7608
7609
    if (mkdir($fullPath, api_get_permissions_for_new_directories(), true)) {
7610
        $fp = fopen($fullPath . '/index.html', 'w');
7611
7612
        if ($fp) {
7613
            if (fwrite($fp, '<html><head></head><body></body></html>')) {
7614
                $isCreated = true;
7615
            }
7616
        }
7617
7618
        fclose($fp);
7619
    }
7620
7621
    return $isCreated;
7622
}
7623
7624
/**
7625
 * Sends an HTML email using the phpmailer class (and multipart/alternative to downgrade gracefully)
7626
 * Sender name and email can be specified, if not specified
7627
 * name and email of the platform admin are used
7628
 *
7629
 * @author Bert Vanderkimpen ICT&O UGent
7630
 * @author Yannick Warnier <[email protected]>
7631
 *
7632
 * @param string    name of recipient
7633
 * @param string    email of recipient
7634
 * @param string    email subject
7635
 * @param string    email body
7636
 * @param string    sender name
7637
 * @param string    sender e-mail
7638
 * @param array     extra headers in form $headers = array($name => $value) to allow parsing
7639
 * @param array     data file (path and filename)
7640
 * @param bool      True for attaching a embedded file inside content html (optional)
7641
 * @param array     Additional parameters
7642
 * @return          integer true if mail was sent
7643
 * @see             class.phpmailer.php
7644
 */
7645
function api_mail_html(
7646
    $recipient_name,
7647
    $recipient_email,
7648
    $subject,
7649
    $message,
7650
    $senderName = '',
7651
    $senderEmail = '',
7652
    $extra_headers = array(),
7653
    $data_file = array(),
7654
    $embedded_image = false,
7655
    $additionalParameters = array()
7656
) {
7657
    global $platform_email;
7658
7659
    $mail = new PHPMailer();
7660
    $mail->Mailer = $platform_email['SMTP_MAILER'];
7661
    $mail->Host = $platform_email['SMTP_HOST'];
7662
    $mail->Port = $platform_email['SMTP_PORT'];
7663
    $mail->CharSet = $platform_email['SMTP_CHARSET'];
7664
    // Stay far below SMTP protocol 980 chars limit.
7665
    $mail->WordWrap = 200;
7666
7667
    if ($platform_email['SMTP_AUTH']) {
7668
        $mail->SMTPAuth = 1;
7669
        $mail->Username = $platform_email['SMTP_USER'];
7670
        $mail->Password = $platform_email['SMTP_PASS'];
7671
        if (isset($platform_email['SMTP_SECURE'])) {
7672
            $mail->SMTPSecure = $platform_email['SMTP_SECURE'];
7673
        }
7674
    }
7675
    $mail->SMTPDebug = isset($platform_email['SMTP_DEBUG'])?$platform_email['SMTP_DEBUG']:0;
7676
7677
    // 5 = low, 1 = high
7678
    $mail->Priority = 3;
7679
    $mail->SMTPKeepAlive = true;
7680
7681
    // Default values
7682
    $notification = new Notification();
7683
    $defaultEmail = $notification->getDefaultPlatformSenderEmail();
7684
    $defaultName = $notification->getDefaultPlatformSenderName();
7685
7686
    // If the parameter is set don't use the admin.
7687
    $senderName = !empty($senderName) ? $senderName : $defaultName;
7688
    $senderEmail = !empty($senderEmail) ? $senderEmail : $defaultEmail;
7689
7690
    // Reply to first
7691
    if (isset($extra_headers['reply_to'])) {
7692
        $mail->AddReplyTo(
7693
            $extra_headers['reply_to']['mail'],
7694
            $extra_headers['reply_to']['name']
7695
        );
7696
            // Errors to sender
7697
        $mail->AddCustomHeader('Errors-To: '.$extra_headers['reply_to']['mail']);
7698
        $mail->Sender = $extra_headers['reply_to']['mail'];
7699
        unset($extra_headers['reply_to']);
7700
    } else {
7701
        $mail->AddCustomHeader('Errors-To: '.$defaultEmail);
7702
    }
7703
7704
    //If the SMTP configuration only accept one sender
7705
    if (isset($platform_email['SMTP_UNIQUE_SENDER']) && $platform_email['SMTP_UNIQUE_SENDER']) {
7706
        $senderName = $platform_email['SMTP_FROM_NAME'];
7707
        $senderEmail = $platform_email['SMTP_FROM_EMAIL'];
7708
    }
7709
    $mail->SetFrom($defaultEmail, $defaultName);
7710
    $mail->From = $defaultEmail;
7711
    $mail->Sender = $defaultEmail;
7712
    $mail->Subject = $subject;
7713
    $mail->AltBody = strip_tags(
7714
        str_replace('<br />', "\n", api_html_entity_decode($message))
7715
    );
7716
7717
    // Send embedded image.
7718
    if ($embedded_image) {
7719
        // Get all images html inside content.
7720
        preg_match_all("/<img\s+.*?src=[\"\']?([^\"\' >]*)[\"\']?[^>]*>/i", $message, $m);
7721
        // Prepare new tag images.
7722
        $new_images_html = array();
7723
        $i = 1;
7724
        if (!empty($m[1])) {
7725
            foreach ($m[1] as $image_path) {
7726
                $real_path = realpath($image_path);
7727
                $filename  = basename($image_path);
7728
                $image_cid = $filename.'_'.$i;
7729
                $encoding = 'base64';
7730
                $image_type = mime_content_type($real_path);
7731
                $mail->AddEmbeddedImage(
7732
                    $real_path,
7733
                    $image_cid,
7734
                    $filename,
7735
                    $encoding,
7736
                    $image_type
7737
                );
7738
                $new_images_html[] = '<img src="cid:'.$image_cid.'" />';
7739
                $i++;
7740
            }
7741
        }
7742
7743
        // Replace origin image for new embedded image html.
7744
        $x = 0;
7745
        if (!empty($m[0])) {
7746
            foreach ($m[0] as $orig_img) {
7747
                $message = str_replace($orig_img, $new_images_html[$x], $message);
7748
                $x++;
7749
            }
7750
        }
7751
    }
7752
7753
    $mailView = new Template(null, false, false, false, false, false, false);
7754
    $mailView->assign('content', $message);
7755
7756
    if (isset($additionalParameters['link'])) {
7757
        $mailView->assign('link', $additionalParameters['link']);
7758
    }
7759
7760
    $layout = $mailView->get_template('mail/mail.tpl');
7761
    $mail->Body = $mailView->fetch($layout);
7762
7763
    // Attachment ...
7764
    if (!empty($data_file)) {
7765
        $o = 0;
7766
        foreach ($data_file as $file_attach) {
7767
            if (!empty($file_attach['path']) && !empty($file_attach['filename'])) {
7768
                $mail->AddAttachment($file_attach['path'], $file_attach['filename']);
7769
            }
7770
            $o++;
7771
        }
7772
    }
7773
7774
    // Only valid addresses are accepted.
7775
    if (is_array($recipient_email)) {
7776
        foreach ($recipient_email as $dest) {
7777
            if (api_valid_email($dest)) {
7778
                $mail->AddAddress($dest, $recipient_name);
7779
            }
7780
        }
7781
    } else {
7782
        if (api_valid_email($recipient_email)) {
7783
            $mail->AddAddress($recipient_email, $recipient_name);
7784
        } else {
7785
            return 0;
7786
        }
7787
    }
7788
7789
    if (is_array($extra_headers) && count($extra_headers) > 0) {
7790
        foreach ($extra_headers as $key => $value) {
7791
            switch (strtolower($key)) {
7792
                case 'encoding':
7793
                case 'content-transfer-encoding':
7794
                    $mail->Encoding = $value;
7795
                    break;
7796
                case 'charset':
7797
                    $mail->Charset = $value;
7798
                    break;
7799
                case 'contenttype':
7800
                case 'content-type':
7801
                    $mail->ContentType = $value;
7802
                    break;
7803
                default:
7804
                    $mail->AddCustomHeader($key.':'.$value);
7805
                    break;
7806
            }
7807
        }
7808
    } else {
7809
        if (!empty($extra_headers)) {
7810
            $mail->AddCustomHeader($extra_headers);
7811
        }
7812
    }
7813
7814
    // WordWrap the html body (phpMailer only fixes AltBody) FS#2988
7815
    $mail->Body = $mail->WrapText($mail->Body, $mail->WordWrap);
7816
7817
    // Send the mail message.
7818
    if (!$mail->Send()) {
7819
        error_log('ERROR: mail not sent to '.$recipient_name.' ('.$recipient_email.') because of '.$mail->ErrorInfo.'<br />');
7820
        if ($mail->SMTPDebug) {
7821
            error_log(
7822
                "Connection details :: " .
7823
                "Protocol: " . $mail->Mailer . ' :: ' .
7824
                "Host/Port: " . $mail->Host . ':' . $mail->Port . ' :: ' .
7825
                "Authent/Open: " . ($mail->SMTPAuth?'Authent':'Open') . ' :: ' .
7826
                ($mail->SMTPAuth?"  User/Pass: " . $mail->Username . ':' . $mail->Password:'')
7827
            );
7828
        }
7829
        return 0;
7830
    }
7831
7832
    if (!empty($additionalParameters)) {
7833
        $plugin = new AppPlugin();
7834
        $smsPlugin = $plugin->getSMSPluginLibrary();
7835
        if ($smsPlugin) {
7836
            $smsPlugin->send($additionalParameters);
7837
        }
7838
    }
7839
7840
    // Clear all the addresses.
7841
    $mail->ClearAddresses();
7842
7843
    // Clear all attachments
7844
    $mail->ClearAttachments();
7845
7846
    return 1;
7847
}
7848
7849
/**
7850
 * @param string $tool Possible values:
7851
 * GroupManager::GROUP_TOOL_*
7852
 *
7853
 */
7854
function api_protect_course_group($tool, $showHeader = true)
7855
{
7856
    $userId = api_get_user_id();
7857
    $groupId = api_get_group_id();
7858
    $groupInfo = GroupManager::get_group_properties($groupId);
7859
7860
    if (!empty($groupInfo)) {
7861
        $allow = GroupManager::user_has_access(
7862
            $userId,
7863
            $groupInfo['iid'],
7864
            $tool
7865
        );
7866
7867
        if (!$allow) {
7868
            api_not_allowed($showHeader);
7869
        }
7870
    }
7871
}
7872
7873
/**
7874
 * Check if a date is in a date range
7875
 *
7876
 * @param datetime $startDate
7877
 * @param datetime $endDate
7878
 * @param datetime $currentDate
7879
 * @return bool true if date is in rage, false otherwise
7880
 */
7881
function api_is_date_in_date_range($startDate, $endDate, $currentDate = null)
7882
{
7883
    $startDate = strtotime(api_get_local_time($startDate));
7884
    $endDate = strtotime(api_get_local_time($endDate));
7885
    $currentDate = strtotime(api_get_local_time($currentDate));
7886
7887
    if ($currentDate >= $startDate && $currentDate <= $endDate) {
7888
        return true;
7889
    }
7890
7891
    return false;
7892
}
7893
7894
/**
7895
 * Eliminate the duplicates of a multidimensional array by sending the key
7896
 *
7897
 * @param array $array multidimensional array
7898
 * @param int $key key to find to compare
7899
 * @return array
7900
 *
7901
 */
7902
function api_unique_multidim_array($array, $key){
7903
    $temp_array = [];
7904
    $i = 0;
7905
    $key_array = [];
7906
7907
    foreach($array as $val){
7908
        if(!in_array($val[$key],$key_array)){
7909
            $key_array[$i] = $val[$key];
7910
            $temp_array[$i] = $val;
7911
        }
7912
        $i++;
7913
    }
7914
    return $temp_array;
7915
}
7916
7917
/**
7918
 * Limit the access to Session Admins wheen the limit_session_admin_role
7919
 * configuration variable is set to true
7920
 */
7921
function api_protect_limit_for_session_admin()
7922
{
7923
    $limitAdmin = api_get_setting('limit_session_admin_role');
7924
    if (api_is_session_admin() && $limitAdmin === 'true') {
7925
        api_not_allowed(true);
7926
    }
7927
}
7928
7929
function api_is_student_view_active() {
7930
    $studentView = Session::read('studentview');
7931
    return $studentView == 'studentview';
7932
}
7933
7934
/**
7935
 * Adds a file inside the upload/$type/id
7936
 *
7937
 * @param string $type
7938
 * @param array $file
7939
 * @param int $itemId
7940
 * @param string $cropParameters
7941
 * @return array|bool
7942
 */
7943
function api_upload_file($type, $file, $itemId, $cropParameters = '')
7944
{
7945
    $upload = process_uploaded_file($file);
7946
    if ($upload) {
7947
        $name = api_replace_dangerous_char($file['name']);
7948
7949
        // No "dangerous" files
7950
        $name = disable_dangerous_file($name);
7951
7952
        $pathId = '/'.substr((string)$itemId, 0, 1).'/'.$itemId.'/';
7953
        $path = api_get_path(SYS_UPLOAD_PATH).$type.$pathId;
7954
7955
        if (!is_dir($path)) {
7956
            mkdir($path, api_get_permissions_for_new_directories(), true);
7957
        }
7958
7959
        $pathToSave = $path.$name;
7960
7961
        $result = move_uploaded_file($file['tmp_name'], $pathToSave);
7962
        if ($result) {
7963
            if (!empty($cropParameters)) {
7964
                $image = new Image($pathToSave);
7965
                $image->crop($cropParameters);
7966
            }
7967
7968
            return ['path_to_save' => $pathId.$name];
7969
        }
7970
        return false;
7971
    }
7972
}
7973
7974
/**
7975
 * @param string $type
7976
 * @param string $file
7977
 */
7978
function api_remove_uploaded_file($type, $file)
7979
{
7980
    $path = api_get_path(SYS_UPLOAD_PATH).$type.'/'.$file;
7981
    if (file_exists($path)) {
7982
        unlink($path);
7983
    }
7984
}
7985
7986
7987