usermanager.lib.php 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020
  1. <?php // $Id: usermanager.lib.php 22378 2009-07-26 19:58:38Z yannoo $
  2. /* For licensing terms, see /dokeos_license.txt */
  3. /**
  4. ==============================================================================
  5. * This library provides functions for user management.
  6. * Include/require it in your code to use its functionality.
  7. *
  8. * @package dokeos.library
  9. ==============================================================================
  10. */
  11. // Constants for user extra field types.
  12. define('USER_FIELD_TYPE_TEXT', 1);
  13. define('USER_FIELD_TYPE_TEXTAREA', 2);
  14. define('USER_FIELD_TYPE_RADIO',3);
  15. define('USER_FIELD_TYPE_SELECT',4);
  16. define('USER_FIELD_TYPE_SELECT_MULTIPLE', 5);
  17. define('USER_FIELD_TYPE_DATE', 6);
  18. define('USER_FIELD_TYPE_DATETIME', 7);
  19. define('USER_FIELD_TYPE_DOUBLE_SELECT', 8);
  20. define('USER_FIELD_TYPE_DIVIDER', 9);
  21. class UserManager {
  22. private function __construct () {
  23. }
  24. /**
  25. * Creates a new user for the platform
  26. * @author Hugues Peeters <peeters@ipm.ucl.ac.be>,
  27. * Roan Embrechts <roan_embrechts@yahoo.com>
  28. *
  29. * @param string Firstname
  30. * @param string Lastname
  31. * @param int Status (1 for course tutor, 5 for student, 6 for anonymous)
  32. * @param string e-mail address
  33. * @param string Login
  34. * @param string Password
  35. * @param string Any official code (optional)
  36. * @param string User language (optional)
  37. * @param string Phone number (optional)
  38. * @param string Picture URI (optional)
  39. * @param string Authentication source (optional, defaults to 'platform', dependind on constant)
  40. * @param string Account expiration date (optional, defaults to '0000-00-00 00:00:00')
  41. * @param int Whether the account is enabled or disabled by default
  42. * @param int The user ID of the person who registered this user (optional, defaults to null)
  43. * @param int The department of HR in which the user is registered (optional, defaults to 0)
  44. * @return mixed new user id - if the new user creation succeeds, false otherwise
  45. *
  46. * @desc The function tries to retrieve $_user['user_id'] from the global space.
  47. * if it exists, $_user['user_id'] is the creator id. If a problem arises,
  48. * it stores the error message in global $api_failureList
  49. */
  50. public static function create_user($firstName, $lastName, $status, $email, $loginName, $password, $official_code = '', $language = '', $phone = '', $picture_uri = '', $auth_source = PLATFORM_AUTH_SOURCE, $expiration_date = '0000-00-00 00:00:00', $active = 1, $hr_dept_id = 0, $extra = null) {
  51. global $_user, $userPasswordCrypted;
  52. $firstName = Security::remove_XSS($firstName);
  53. $lastName = Security::remove_XSS($lastName);
  54. $loginName = Security::remove_XSS($loginName);
  55. $phone = Security::remove_XSS($phone);
  56. // database table definition
  57. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  58. // default langauge
  59. if ($language == '') {
  60. $language = api_get_setting('platformLanguage');
  61. }
  62. if ($_user['user_id']) {
  63. $creator_id = $_user['user_id'];
  64. } else {
  65. $creator_id = '';
  66. }
  67. // First check wether the login already exists
  68. if (!self::is_username_available($loginName)) {
  69. return api_set_failure('login-pass already taken');
  70. }
  71. //$password = "PLACEHOLDER";
  72. $password = api_get_encrypted_password($password);
  73. //$password = ($userPasswordCrypted ? md5($password) : $password);
  74. $current_date = date('Y-m-d H:i:s', time());
  75. $sql = "INSERT INTO $table_user
  76. SET lastname = '".Database::escape_string(trim($lastName))."',
  77. firstname = '".Database::escape_string(trim($firstName))."',
  78. username = '".Database::escape_string(trim($loginName))."',
  79. status = '".Database::escape_string($status)."',
  80. password = '".Database::escape_string($password)."',
  81. email = '".Database::escape_string($email)."',
  82. official_code = '".Database::escape_string($official_code)."',
  83. picture_uri = '".Database::escape_string($picture_uri)."',
  84. creator_id = '".Database::escape_string($creator_id)."',
  85. auth_source = '".Database::escape_string($auth_source)."',
  86. phone = '".Database::escape_string($phone)."',
  87. language = '".Database::escape_string($language)."',
  88. registration_date = '".$current_date."',
  89. expiration_date = '".Database::escape_string($expiration_date)."',
  90. hr_dept_id = '".Database::escape_string($hr_dept_id)."',
  91. active = '".Database::escape_string($active)."'";
  92. $result = Database::query($sql, __FILE__, __LINE__);
  93. if ($result) {
  94. //echo "id returned";
  95. $return = Database::get_last_insert_id();
  96. global $_configuration;
  97. require_once api_get_path(LIBRARY_PATH).'urlmanager.lib.php';
  98. if ($_configuration['multiple_access_urls'] == true) {
  99. if (api_get_current_access_url_id() != -1) {
  100. UrlManager::add_user_to_url($return, api_get_current_access_url_id());
  101. } else {
  102. UrlManager::add_user_to_url($return, 1);
  103. }
  104. } else {
  105. //we are adding by default the access_url_user table with access_url_id = 1
  106. UrlManager::add_user_to_url($return, 1);
  107. }
  108. // add event to system log
  109. $time = time();
  110. $user_id_manager = api_get_user_id();
  111. event_system(LOG_USER_CREATE, LOG_USER_ID, $return, $time, $user_id_manager);
  112. } else {
  113. //echo "false - failed" ;
  114. $return=false;
  115. }
  116. if (is_array($extra) && count($extra) > 0) {
  117. $res = true;
  118. foreach($extra as $fname => $fvalue) {
  119. $res = $res && self::update_extra_field($return, $fname, $fvalue);
  120. }
  121. }
  122. return $return;
  123. }
  124. /**
  125. * Can user be deleted?
  126. * This functions checks if there's a course in which the given user is the
  127. * only course administrator. If that is the case, the user can't be
  128. * deleted because the course would remain without a course admin.
  129. * @param int $user_id The user id
  130. * @return boolean true if user can be deleted
  131. */
  132. public static function can_delete_user($user_id) {
  133. $table_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  134. $sql = "SELECT * FROM $table_course_user WHERE status = '1' AND user_id = '".$user_id."'";
  135. $res = Database::query($sql, __FILE__, __LINE__);
  136. while ($course = Database::fetch_object($res)) {
  137. $sql = "SELECT user_id FROM $table_course_user WHERE status='1' AND course_code ='".$course->course_code."'";
  138. $res2 = Database::query($sql, __FILE__, __LINE__);
  139. if (Database::num_rows($res2) == 1) {
  140. return false;
  141. }
  142. }
  143. return true;
  144. }
  145. /**
  146. * Delete a user from the platform
  147. * @param int $user_id The user id
  148. * @return boolean true if user is succesfully deleted, false otherwise
  149. */
  150. public static function delete_user($user_id) {
  151. global $_configuration;
  152. if (!self::can_delete_user($user_id)) {
  153. return false;
  154. }
  155. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  156. $table_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  157. $table_class_user = Database :: get_main_table(TABLE_MAIN_CLASS_USER);
  158. $table_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  159. $table_admin = Database :: get_main_table(TABLE_MAIN_ADMIN);
  160. $table_session_user = Database :: get_main_table(TABLE_MAIN_SESSION_USER);
  161. $table_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  162. // Unsubscribe the user from all groups in all his courses
  163. $sql = "SELECT * FROM $table_course c, $table_course_user cu WHERE cu.user_id = '".$user_id."' AND c.code = cu.course_code";
  164. $res = Database::query($sql, __FILE__, __LINE__);
  165. while ($course = Database::fetch_object($res)) {
  166. $table_group = Database :: get_course_table(TABLE_GROUP_USER, $course->db_name);
  167. $sql = "DELETE FROM $table_group WHERE user_id = '".$user_id."'";
  168. Database::query($sql, __FILE__, __LINE__);
  169. }
  170. // Unsubscribe user from all classes
  171. $sql = "DELETE FROM $table_class_user WHERE user_id = '".$user_id."'";
  172. Database::query($sql, __FILE__, __LINE__);
  173. // Unsubscribe user from all courses
  174. $sql = "DELETE FROM $table_course_user WHERE user_id = '".$user_id."'";
  175. Database::query($sql, __FILE__, __LINE__);
  176. // Unsubscribe user from all courses in sessions
  177. $sql = "DELETE FROM $table_session_course_user WHERE id_user = '".$user_id."'";
  178. Database::query($sql, __FILE__, __LINE__);
  179. // Unsubscribe user from all sessions
  180. $sql = "DELETE FROM $table_session_user WHERE id_user = '".$user_id."'";
  181. Database::query($sql, __FILE__, __LINE__);
  182. // Delete user picture
  183. // TODO: Logic about api_get_setting('split_users_upload_directory') === 'true' , a user has 4 differnt sized photos to be deleted.
  184. $user_info = api_get_user_info($user_id);
  185. if (strlen($user_info['picture_uri']) > 0) {
  186. $img_path = api_get_path(SYS_CODE_PATH).'upload/users/'.$user_id.'/'.$user_info['picture_uri'];
  187. unlink($img_path);
  188. }
  189. // Delete the personal course categories
  190. $course_cat_table = Database::get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  191. $sql = "DELETE FROM $course_cat_table WHERE user_id = '".$user_id."'";
  192. Database::query($sql, __FILE__, __LINE__);
  193. // Delete user from database
  194. $sql = "DELETE FROM $table_user WHERE user_id = '".$user_id."'";
  195. Database::query($sql, __FILE__, __LINE__);
  196. // Delete user from the admin table
  197. $sql = "DELETE FROM $table_admin WHERE user_id = '".$user_id."'";
  198. Database::query($sql, __FILE__, __LINE__);
  199. // Delete the personal agenda-items from this user
  200. $agenda_table = Database :: get_user_personal_table(TABLE_PERSONAL_AGENDA);
  201. $sql = "DELETE FROM $agenda_table WHERE user = '".$user_id."'";
  202. Database::query($sql, __FILE__, __LINE__);
  203. $gradebook_results_table = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
  204. $sql = 'DELETE FROM '.$gradebook_results_table.' WHERE user_id = '.$user_id;
  205. Database::query($sql, __FILE__, __LINE__);
  206. $user = Database::fetch_array($res);
  207. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  208. $sqlv = "DELETE FROM $t_ufv WHERE user_id = $user_id";
  209. $resv = Database::query($sqlv, __FILE__, __LINE__);
  210. if ($_configuration['multiple_access_urls']) {
  211. require_once api_get_path(LIBRARY_PATH).'urlmanager.lib.php';
  212. $url_id = 1;
  213. if (api_get_current_access_url_id() != -1) {
  214. $url_id = api_get_current_access_url_id();
  215. }
  216. UrlManager::delete_url_rel_user($user_id, $url_id);
  217. }
  218. // add event to system log
  219. $time = time();
  220. $user_id_manager = api_get_user_id();
  221. event_system(LOG_USER_DELETE, LOG_USER_ID, $user_id, $time, $user_id_manager);
  222. return true;
  223. }
  224. /**
  225. * Update user information with new openid
  226. * @param int $user_id
  227. * @param string $openid
  228. * @return boolean true if the user information was updated
  229. */
  230. public static function update_openid($user_id, $openid) {
  231. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  232. $sql = "UPDATE $table_user SET
  233. openid='".Database::escape_string($openid)."'";
  234. $sql .= " WHERE user_id='$user_id'";
  235. return Database::query($sql, __FILE__, __LINE__);
  236. }
  237. /**
  238. * Update user information
  239. * @param int $user_id
  240. * @param string $firstname
  241. * @param string $lastname
  242. * @param string $username
  243. * @param string $password
  244. * @param string $auth_source
  245. * @param string $email
  246. * @param int $status
  247. * @param string $official_code
  248. * @param string $phone
  249. * @param string $picture_uri
  250. * @param int The user ID of the person who registered this user (optional, defaults to null)
  251. * @param int The department of HR in which the user is registered (optional, defaults to 0)
  252. * @param array A series of additional fields to add to this user as extra fields (optional, defaults to null)
  253. * @return boolean true if the user information was updated
  254. */
  255. public static function update_user($user_id, $firstname, $lastname, $username, $password = null, $auth_source = null, $email, $status, $official_code, $phone, $picture_uri, $expiration_date, $active, $creator_id = null, $hr_dept_id = 0, $extra = null, $language = 'english') {
  256. global $userPasswordCrypted;
  257. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  258. $sql = "UPDATE $table_user SET
  259. lastname='".Database::escape_string($lastname)."',
  260. firstname='".Database::escape_string($firstname)."',
  261. username='".Database::escape_string($username)."',
  262. language='".Database::escape_string($language)."',";
  263. if (!is_null($password)) {
  264. //$password = $userPasswordCrypted ? md5($password) : $password;
  265. $password = api_get_encrypted_password($password);
  266. $sql .= " password='".Database::escape_string($password)."',";
  267. }
  268. if (!is_null($auth_source)) {
  269. $sql .= " auth_source='".Database::escape_string($auth_source)."',";
  270. }
  271. $sql .= "
  272. email='".Database::escape_string($email)."',
  273. status='".Database::escape_string($status)."',
  274. official_code='".Database::escape_string($official_code)."',
  275. phone='".Database::escape_string($phone)."',
  276. picture_uri='".Database::escape_string($picture_uri)."',
  277. expiration_date='".Database::escape_string($expiration_date)."',
  278. active='".Database::escape_string($active)."',
  279. hr_dept_id=".intval($hr_dept_id);
  280. if (!is_null($creator_id)) {
  281. $sql .= ", creator_id='".Database::escape_string($creator_id)."'";
  282. }
  283. $sql .= " WHERE user_id='$user_id'";
  284. $return = Database::query($sql, __FILE__, __LINE__);
  285. if (is_array($extra) && count($extra) > 0) {
  286. $res = true;
  287. foreach($extra as $fname => $fvalue) {
  288. $res = $res && self::update_extra_field($user_id,$fname,$fvalue);
  289. }
  290. }
  291. return $return;
  292. }
  293. /**
  294. * Check if a username is available
  295. * @param string the wanted username
  296. * @return boolean true if the wanted username is available
  297. */
  298. public static function is_username_available($username) {
  299. $table_user = Database :: get_main_table(TABLE_MAIN_USER);
  300. $sql = "SELECT username FROM $table_user WHERE username = '".addslashes($username)."'";
  301. $res = Database::query($sql, __FILE__, __LINE__);
  302. return Database::num_rows($res) == 0;
  303. }
  304. /**
  305. * Creates a username using person's names, i.e. creates jmontoya from Julio Montoya.
  306. * @param string $firstname The first name of the user.
  307. * @param string $lastname The last name of the user.
  308. * @param string $language (optional) The language in which comparison is to be made. If language is omitted, interface language is assumed then.
  309. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  310. * @return string Suggests a username that contains only ASCII-letters and digits, without check for uniqueness within the system.
  311. * @author Julio Montoya Armas
  312. * @author Ivan Tcholakov, 2009 - rework about internationalization.
  313. */
  314. public static function create_username($firstname, $lastname, $language = null, $encoding = null) {
  315. if (is_null($encoding)) {
  316. $encoding = api_get_system_encoding();
  317. }
  318. if (is_null($language)) {
  319. $language = api_get_interface_language();
  320. }
  321. $firstname = substr(preg_replace(USERNAME_PURIFIER, '', api_transliterate($firstname, '', $encoding)), 0, 1); // The first letter only.
  322. $lastname = preg_replace(USERNAME_PURIFIER, '', api_transliterate($lastname, '', $encoding));
  323. $username = api_is_western_name_order(null, $language) ? $firstname.$lastname : $lastname.$firstname;
  324. if (empty($username)) {
  325. $username = 'user';
  326. }
  327. return strtolower(substr($username, 0, USERNAME_MAX_LENGTH - 3));
  328. }
  329. /**
  330. * Creates a unique username, using:
  331. * 1. the first name and the last name of a user;
  332. * 2. an already created username but not checked for uniqueness yet.
  333. * @param string $firstname The first name of a given user. If the second parameter $lastname is NULL, then this
  334. * parameter is treated as username which is to be checked for uniqueness and to be modified when it is necessary.
  335. * @param string $lastname The last name of the user.
  336. * @param string $language (optional) The language in which comparison is to be made. If language is omitted, interface language is assumed then.
  337. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  338. * @return string Returns a username that contains only ASCII-letters and digits, and that is unique within the system.
  339. * Note: When the method is called several times with same parameters, its results look like the following sequence: ivan, ivan2, ivan3, ivan4, ...
  340. * @author Ivan Tcholakov, 2009
  341. */
  342. public static function create_unique_username($firstname, $lastname = null, $language = null, $encoding = null) {
  343. if (is_null($lastname)) {
  344. // In this case the actual input parameter $firstname should contain ASCII-letters and digits only.
  345. // For making this method tolerant of mistakes, let us transliterate and purify the suggested input username anyway.
  346. // So, instead of the sentence $username = $firstname; we place the following:
  347. $username = strtolower(preg_replace(USERNAME_PURIFIER, '', api_transliterate($firstname, '', $encoding)));
  348. } else {
  349. $username = self::create_username($firstname, $lastname, $language, $encoding);
  350. }
  351. if (!self::is_username_available($username)) {
  352. $i = 2;
  353. $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string)$i)).$i;
  354. while (!self::is_username_available($temp_username)) {
  355. $i++;
  356. $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string)$i)).$i;
  357. }
  358. $username = $temp_username;
  359. }
  360. return $username;
  361. }
  362. /**
  363. * Modifies a given username accordingly to the specification for valid characters and length.
  364. * @param $username string The input username.
  365. * @param bool $strict (optional) When this flag is TRUE, the result is guaranteed for full compliance, otherwise compliance may be partial. The default value is FALSE.
  366. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  367. * @return string The resulting purified username.
  368. */
  369. public function purify_username($username, $strict = false, $encoding = null) {
  370. if ($strict) {
  371. // 1. Conversion of unacceptable letters (latinian letters with accents for example) into ASCII letters in order they not to be totally removed.
  372. // 2. Applying the strict purifier.
  373. // 3. Length limitation.
  374. return substr(preg_replace(USERNAME_PURIFIER, '', api_transliterate($username, '', $encoding)), 0, USERNAME_MAX_LENGTH);
  375. }
  376. // 1. Applying the shallow purifier.
  377. // 2. Length limitation.
  378. return substr(preg_replace(USERNAME_PURIFIER_SHALLOW, '', $username), 0, USERNAME_MAX_LENGTH);
  379. }
  380. /**
  381. * Checks whether a given username matches to the specification strictly. The empty username is assumed here as invalid.
  382. * Mostly this function is to be used in the user interface built-in validation routines for providing feedback while usernames are enterd manually.
  383. * @param string $username The input username.
  384. * @param string $encoding (optional) The character encoding for the input names. If it is omitted, the platform character set will be used by default.
  385. * @return bool Returns TRUE if the username is valid, FALSE otherwise.
  386. */
  387. public function is_username_valid($username, $encoding = null) {
  388. return !empty($username) && $username == self::purify_username($username, true);
  389. }
  390. /**
  391. * Checks whether a username is empty. If the username contains whitespace characters, such as spaces, tabulators, newlines, etc.,
  392. * it is assumed as empty too. This function is safe for validation unpurified data (during importing).
  393. * @param string $username The given username.
  394. * @return bool Returns TRUE if length of the username exceeds the limit, FALSE otherwise.
  395. */
  396. public static function is_username_empty($username) {
  397. return (strlen(self::purify_username($username, false)) == 0);
  398. }
  399. /**
  400. * Checks whether a username is too long or not.
  401. * @param string $username The given username, it should contain only ASCII-letters and digits.
  402. * @return bool Returns TRUE if length of the username exceeds the limit, FALSE otherwise.
  403. */
  404. public static function is_username_too_long($username) {
  405. return (strlen($username) > USERNAME_MAX_LENGTH);
  406. }
  407. /**
  408. * Get a list of users of which the given conditions match with an = 'cond'
  409. * @param array $conditions a list of condition (exemple : status=>STUDENT)
  410. * @param array $order_by a list of fields on which sort
  411. * @return array An array with all users of the platform.
  412. * @todo optional course code parameter, optional sorting parameters...
  413. */
  414. public static function get_user_list($conditions = array(), $order_by = array()) {
  415. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  416. $return_array = array();
  417. $sql_query = "SELECT * FROM $user_table";
  418. if (count($conditions) > 0) {
  419. $sql_query .= ' WHERE ';
  420. foreach ($conditions as $field => $value) {
  421. $field = Database::escape_string($field);
  422. $value = Database::escape_string($value);
  423. $sql_query .= $field.' = '.$value;
  424. }
  425. }
  426. if (count($order_by) > 0) {
  427. $sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by));
  428. }
  429. $sql_result = Database::query($sql_query, __FILE__, __LINE__);
  430. while ($result = Database::fetch_array($sql_result)) {
  431. $return_array[] = $result;
  432. }
  433. return $return_array;
  434. }
  435. /**
  436. * Get a list of users of which the given conditions match with a LIKE '%cond%'
  437. * @param array $conditions a list of condition (exemple : status=>STUDENT)
  438. * @param array $order_by a list of fields on which sort
  439. * @return array An array with all users of the platform.
  440. * @todo optional course code parameter, optional sorting parameters...
  441. */
  442. function get_user_list_like($conditions = array(), $order_by = array()) {
  443. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  444. $return_array = array();
  445. $sql_query = "SELECT * FROM $user_table";
  446. if (count($conditions) > 0) {
  447. $sql_query .= ' WHERE ';
  448. foreach ($conditions as $field => $value) {
  449. $field = Database::escape_string($field);
  450. $value = Database::escape_string($value);
  451. $sql_query .= $field.' LIKE \'%'.$value.'%\'';
  452. }
  453. }
  454. if (count($order_by) > 0) {
  455. $sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by));
  456. }
  457. $sql_result = Database::query($sql_query, __FILE__, __LINE__);
  458. while ($result = Database::fetch_array($sql_result)) {
  459. $return_array[] = $result;
  460. }
  461. return $return_array;
  462. }
  463. /**
  464. * Get user information
  465. * @param string The username
  466. * @return array All user information as an associative array
  467. */
  468. public static function get_user_info($username) {
  469. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  470. $sql = "SELECT * FROM $user_table WHERE username='".$username."'";
  471. $res = Database::query($sql, __FILE__, __LINE__);
  472. if (Database::num_rows($res) > 0) {
  473. return Database::fetch_array($res);
  474. }
  475. return false;
  476. }
  477. /**
  478. * Get user information
  479. * @param string The id
  480. * @param boolean Whether to return the user's extra fields (defaults to false)
  481. * @return array All user information as an associative array
  482. */
  483. public static function get_user_info_by_id($user_id, $user_fields = false) {
  484. $user_id = intval($user_id);
  485. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  486. $sql = "SELECT * FROM $user_table WHERE user_id=".$user_id;
  487. $res = Database::query($sql, __FILE__, __LINE__);
  488. if (Database::num_rows($res) > 0) {
  489. $user = Database::fetch_array($res);
  490. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  491. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  492. $sqlf = "SELECT * FROM $t_uf ORDER BY field_order";
  493. $resf = Database::query($sqlf, __FILE__, __LINE__);
  494. if (Database::num_rows($resf) > 0) {
  495. while ($rowf = Database::fetch_array($resf)) {
  496. $sqlv = "SELECT * FROM $t_ufv WHERE field_id = ".$rowf['id']." AND user_id = ".$user['user_id']." ORDER BY id DESC";
  497. $resv = Database::query($sqlv, __FILE__, __LINE__);
  498. if (Database::num_rows($resv) > 0) {
  499. //There should be only one value for a field and a user
  500. $rowv = Database::fetch_array($resv);
  501. $user['extra'][$rowf['field_variable']] = $rowv['field_value'];
  502. } else {
  503. $user['extra'][$rowf['field_variable']] = '';
  504. }
  505. }
  506. }
  507. return $user;
  508. }
  509. return false;
  510. }
  511. /** Get the teacher list
  512. * @param int the course ID
  513. * @param array Content the list ID of user_id selected
  514. */
  515. //for survey
  516. // TODO: Ivan, 14-SEP-2009: It seems that this method is not used at all (it can be located in a test unit only. To be deprecated?
  517. public static function get_teacher_list($course_id, $sel_teacher = '') {
  518. $user_course_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  519. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  520. $sql_query = "SELECT * FROM $user_table a, $user_course_table b where a.user_id=b.user_id AND b.status=1 AND b.course_code='$course_id'";
  521. $sql_result = Database::query($sql_query, __FILE__, __LINE__);
  522. echo "<select name=\"author\">";
  523. while ($result = Database::fetch_array($sql_result)) {
  524. if ($sel_teacher == $result['user_id']) $selected ="selected";
  525. echo "\n<option value=\"".$result['user_id']."\" $selected>".$result['firstname']."</option>";
  526. }
  527. echo "</select>";
  528. }
  529. /**
  530. * Get user picture URL or path from user ID (returns an array).
  531. * The return format is a complete path, enabling recovery of the directory
  532. * with dirname() or the file with basename(). This also works for the
  533. * functions dealing with the user's productions, as they are located in
  534. * the same directory.
  535. * @param integer User ID
  536. * @param string Type of path to return (can be 'none', 'system', 'rel', 'web')
  537. * @param bool Whether we want to have the directory name returned 'as if' there was a file or not (in the case we want to know which directory to create - otherwise no file means no split subdir)
  538. * @param bool If we want that the function returns the /main/img/unknown.jpg image set it at true
  539. * @return array Array of 2 elements: 'dir' and 'file' which contain the dir and file as the name implies if image does not exist it will return the unknow image if anonymous parameter is true if not it returns an empty er's
  540. */
  541. public static function get_user_picture_path_by_id($id, $type = 'none', $preview = false, $anonymous = false) {
  542. switch ($type) {
  543. case 'system': // Base: absolute system path.
  544. $base = api_get_path(SYS_CODE_PATH);
  545. break;
  546. case 'rel': // Base: semi-absolute web path (no server base).
  547. $base = api_get_path(REL_CODE_PATH);
  548. break;
  549. case 'web': // Base: absolute web path.
  550. $base = api_get_path(WEB_CODE_PATH);
  551. break;
  552. case 'none':
  553. default: // Base: empty, the result path below will be relative.
  554. $base = '';
  555. }
  556. if (empty($id) || empty($type)) {
  557. return $anonymous ? array('dir' => $base.'img/', 'file' => 'unknown.jpg') : array('dir' => '', 'file' => '');
  558. }
  559. $user_id = intval($id);
  560. $user_table = Database :: get_main_table(TABLE_MAIN_USER);
  561. $sql = "SELECT picture_uri FROM $user_table WHERE user_id=".$user_id;
  562. $res = Database::query($sql, __FILE__, __LINE__);
  563. if (!Database::num_rows($res)) {
  564. return $anonymous ? array('dir' => $base.'img/', 'file' => 'unknown.jpg') : array('dir' => '', 'file' => '');
  565. }
  566. $user = Database::fetch_array($res);
  567. $picture_filename = trim($user['picture_uri']);
  568. if (api_get_setting('split_users_upload_directory') === 'true') {
  569. if (!empty($picture_filename)) {
  570. $dir = $base.'upload/users/'.substr($picture_filename, 0, 1).'/'.$user_id.'/';
  571. } elseif ($preview) {
  572. $dir = $base.'upload/users/'.substr((string)$user_id, 0, 1).'/'.$user_id.'/';
  573. } else {
  574. $dir = $base.'upload/users/'.$user_id.'/';
  575. }
  576. } else {
  577. $dir = $base.'upload/users/'.$user_id.'/';
  578. }
  579. if (empty($picture_filename) && $anonymous) {
  580. return array('dir' => $base.'img/', 'file' => 'unknown.jpg');
  581. }
  582. return array('dir' => $dir, 'file' => $picture_filename);
  583. }
  584. /**
  585. * Creates new user pfotos in various sizes of a user, or deletes user pfotos.
  586. * Note: This method relies on configuration setting from dokeos/main/inc/conf/profile.conf.php
  587. * @param int $user_id The user internal identitfication number.
  588. * @param string $file The common file name for the newly created pfotos. It will be checked and modified for compatibility with the file system.
  589. * If full name is provided, path component is ignored.
  590. * If an empty name is provided, then old user photos are deleted only, @see UserManager::delete_user_picture() as the prefered way for deletion.
  591. * @param string $source_file The full system name of the image from which user photos will be created.
  592. * @return string/bool Returns the resulting common file name of created images which usually should be stored in database.
  593. * When deletion is recuested returns empty string. In case of internal error or negative validation returns FALSE.
  594. */
  595. public static function update_user_picture($user_id, $file = null, $source_file = null) {
  596. // Validation 1.
  597. if (empty($user_id)) {
  598. return false;
  599. }
  600. $delete = empty($file);
  601. if (empty($source_file)) {
  602. $source_file = $file;
  603. }
  604. // Configuration options about user photos.
  605. require_once api_get_path(CONFIGURATION_PATH).'profile.conf.php';
  606. // User-reserved directory where photos have to be placed.
  607. $path_info = self::get_user_picture_path_by_id($user_id, 'system', true);
  608. $path = $path_info['dir'];
  609. // If this directory does not exist - we create it.
  610. if (!file_exists($path)) {
  611. $perm = api_get_setting('permissions_for_new_directories');
  612. $perm = octdec(!empty($perm) ? $perm : '0770');
  613. @mkdir($path, $perm, true);
  614. }
  615. // The old photos (if any).
  616. $old_file = $path_info['file'];
  617. // Let us delete them.
  618. if (!empty($old_file)) {
  619. if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) {
  620. $prefix = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_';
  621. @rename($path.'small_'.$old_file, $path.$prefix.'small_'.$old_file);
  622. @rename($path.'medium_'.$old_file, $path.$prefix.'medium_'.$old_file);
  623. @rename($path.'big_'.$old_file, $path.$prefix.'big_'.$old_file);
  624. @rename($path.$old_file, $path.$prefix.$old_file);
  625. } else {
  626. @unlink($path.'small_'.$old_file);
  627. @unlink($path.'medium_'.$old_file);
  628. @unlink($path.'big_'.$old_file);
  629. @unlink($path.$old_file);
  630. }
  631. }
  632. // Exit if only deletion has been requested. Return an empty picture name.
  633. if ($delete) {
  634. return '';
  635. }
  636. // Validation 2.
  637. $allowed_types = array('jpg', 'jpeg', 'png', 'gif');
  638. $file = str_replace('\\', '/', $file);
  639. $filename = (($pos = strrpos($file, '/')) !== false) ? substr($file, $pos + 1) : $file;
  640. $extension = strtolower(substr(strrchr($filename, '.'), 1));
  641. if (!in_array($extension, $allowed_types)) {
  642. return false;
  643. }
  644. // This is the common name for the new photos.
  645. if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && !empty($old_file)) {
  646. $old_extension = strtolower(substr(strrchr($old_file, '.'), 1));
  647. $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file;
  648. $filename = (substr($filename, -1) == '.') ? $filename.$extension : $filename.'.'.$extension;
  649. } else {
  650. $filename = replace_dangerous_char($filename);
  651. if (PREFIX_IMAGE_FILENAME_WITH_UID) {
  652. $filename = uniqid('').'_'.$filename;
  653. }
  654. // We always prefix user photos with user ids, so on setting
  655. // api_get_setting('split_users_upload_directory') === 'true'
  656. // the correspondent directories to be found successfully.
  657. $filename = $user_id.'_'.$filename;
  658. }
  659. // Storing the new photos in 4 versions with various sizes.
  660. $picture_info = @getimagesize($source_file);
  661. $type = $picture_info[2];
  662. $small = self::resize_picture($source_file, 22);
  663. $medium = self::resize_picture($source_file, 85);
  664. $normal = self::resize_picture($source_file, 200);
  665. $big = new image($source_file); // This is the original picture.
  666. $ok = false;
  667. $detected = array(1 => 'GIF', 2 => 'JPG', 3 => 'PNG');
  668. if (in_array($type, array_keys($detected))) {
  669. $ok = $small->send_image($detected[$type], $path.'small_'.$filename)
  670. && $medium->send_image($detected[$type], $path.'medium_'.$filename)
  671. && $normal->send_image($detected[$type], $path.$filename)
  672. && $big->send_image($detected[$type], $path.'big_'.$filename);
  673. }
  674. return $ok ? $filename : false;
  675. }
  676. /**
  677. * Deletes user pfotos.
  678. * Note: This method relies on configuration setting from dokeos/main/inc/conf/profile.conf.php
  679. * @param int $user_id The user internal identitfication number.
  680. * @return string/bool Returns empty string on success, FALSE on error.
  681. */
  682. public static function delete_user_picture($user_id) {
  683. return self::update_user_picture($user_id);
  684. }
  685. /*
  686. -----------------------------------------------------------
  687. PRODUCTIONS FUNCTIONS
  688. -----------------------------------------------------------
  689. */
  690. /**
  691. * Returns an XHTML formatted list of productions for a user, or FALSE if he
  692. * doesn't have any.
  693. *
  694. * If there has been a request to remove a production, the function will return
  695. * without building the list unless forced to do so by the optional second
  696. * parameter. This increases performance by avoiding to read through the
  697. * productions on the filesystem before the removal request has been carried
  698. * out because they'll have to be re-read afterwards anyway.
  699. *
  700. * @param $user_id User id
  701. * @param $force Optional parameter to force building after a removal request
  702. * @return A string containing the XHTML code to dipslay the production list, or FALSE
  703. */
  704. public static function build_production_list($user_id, $force = false, $showdelete = false) {
  705. if (!$force && !empty($_POST['remove_production'])) {
  706. return true; // postpone reading from the filesystem
  707. }
  708. $productions = self::get_user_productions($user_id);
  709. if (empty($productions)) {
  710. return false;
  711. }
  712. $production_path = self::get_user_picture_path_by_id($user_id, 'web', true);
  713. $production_dir = $production_path['dir'].$user_id.'/';
  714. $del_image = api_get_path(WEB_CODE_PATH).'img/delete.gif';
  715. $del_text = get_lang('Delete');
  716. $production_list = '';
  717. if (count($productions) > 0) {
  718. $production_list = '<ul id="productions">';
  719. foreach ($productions as $file) {
  720. $production_list .= '<li><a href="'.$production_dir.urlencode($file).'" target="_blank">'.htmlentities($file).'</a>';
  721. if ($showdelete) {
  722. $production_list .= '<input type="image" name="remove_production['.urlencode($file).']" src="'.$del_image.'" alt="'.$del_text.'" title="'.$del_text.' '.htmlentities($file).'" onclick="javascript: return confirmation(\''.htmlentities($file).'\');" /></li>';
  723. }
  724. }
  725. $production_list .= '</ul>';
  726. }
  727. return $production_list;
  728. }
  729. /**
  730. * Returns an array with the user's productions.
  731. *
  732. * @param $user_id User id
  733. * @return An array containing the user's productions
  734. */
  735. public static function get_user_productions($user_id) {
  736. $production_path = self::get_user_picture_path_by_id($user_id, 'system', true);
  737. $production_repository = $production_path['dir'].$user_id.'/';
  738. $productions = array();
  739. if (is_dir($production_repository)) {
  740. $handle = opendir($production_repository);
  741. while ($file = readdir($handle)) {
  742. if ($file == '.' || $file == '..' || $file == '.htaccess' || is_dir($production_repository.$file)) {
  743. continue; // skip current/parent directory and .htaccess
  744. }
  745. if (preg_match('/('.$user_id.'|[0-9a-f]{13}|saved)_.+\.(png|jpg|jpeg|gif)$/i', $file)) {
  746. // User's photos should not be listed as productions.
  747. continue;
  748. }
  749. $productions[] = $file;
  750. }
  751. }
  752. return $productions; // can be an empty array
  753. }
  754. /**
  755. * Remove a user production.
  756. *
  757. * @param $user_id User id
  758. * @param $production The production to remove
  759. */
  760. public static function remove_user_production($user_id, $production) {
  761. $production_path = self::get_user_picture_path_by_id($user_id, 'system', true);
  762. unlink($production_path['dir'].$user_id.'/'.$production);
  763. }
  764. /**
  765. * Update an extra field. This function is called when a user changes his/her profile
  766. * and by consequence fills or edits his/her extra fields.
  767. *
  768. * @param integer Field ID
  769. * @param array Database columns and their new value
  770. * @return boolean true if field updated, false otherwise
  771. */
  772. public static function update_extra_field($fid, $columns) {
  773. //TODO check that values added are values proposed for enumerated field types
  774. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  775. $fid = Database::escape_string($fid);
  776. $sqluf = "UPDATE $t_uf SET ";
  777. $known_fields = array('id', 'field_variable', 'field_type', 'field_display_text', 'field_default_value', 'field_order', 'field_visible', 'field_changeable', 'field_filter');
  778. $safecolumns = array();
  779. foreach ($columns as $index => $newval) {
  780. if (in_array($index, $known_fields)) {
  781. $safecolumns[$index] = Database::escape_string($newval);
  782. $sqluf .= $index." = '".$safecolumns[$index]."', ";
  783. }
  784. }
  785. $time = time();
  786. $sqluf .= " tms = FROM_UNIXTIME($time) WHERE id='$fid'";
  787. $resuf = Database::query($sqluf, __FILE__, __LINE__);
  788. return $resuf;
  789. }
  790. /**
  791. * Update an extra field value for a given user
  792. * @param integer User ID
  793. * @param string Field variable name
  794. * @param string Field value
  795. * @return boolean true if field updated, false otherwise
  796. */
  797. public static function update_extra_field_value($user_id, $fname, $fvalue = '') {
  798. //TODO check that values added are values proposed for enumerated field types
  799. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  800. $t_ufo = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  801. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  802. $fname = Database::escape_string($fname);
  803. $fvalues = '';
  804. if (is_array($fvalue)) {
  805. foreach($fvalue as $val) {
  806. $fvalues .= Database::escape_string($val).';';
  807. }
  808. if (!empty($fvalues)) {
  809. $fvalues = substr($fvalues, 0, -1);
  810. }
  811. } else {
  812. $fvalues = Database::escape_string($fvalue);
  813. }
  814. $sqluf = "SELECT * FROM $t_uf WHERE field_variable='$fname'";
  815. $resuf = Database::query($sqluf, __FILE__, __LINE__);
  816. if (Database::num_rows($resuf) == 1) {
  817. //ok, the field exists
  818. // Check if enumerated field, if the option is available
  819. $rowuf = Database::fetch_array($resuf);
  820. switch ($rowuf['field_type']) {
  821. case 3:
  822. case 4:
  823. case 5:
  824. $sqluo = "SELECT * FROM $t_ufo WHERE field_id = ".$rowuf['id'];
  825. $resuo = Database::query($sqluo, __FILE__, __LINE__);
  826. $values = split(';',$fvalues);
  827. if (Database::num_rows($resuo) > 0) {
  828. $check = false;
  829. while ($rowuo = Database::fetch_array($resuo)) {
  830. if (in_array($rowuo['option_value'], $values)) {
  831. $check = true;
  832. break;
  833. }
  834. }
  835. if ($check == false) {
  836. return false; //option value not found
  837. }
  838. } else {
  839. return false; //enumerated type but no option found
  840. }
  841. break;
  842. case 1:
  843. case 2:
  844. default:
  845. break;
  846. }
  847. $tms = time();
  848. $sqlufv = "SELECT * FROM $t_ufv WHERE user_id = $user_id AND field_id = ".$rowuf['id']." ORDER BY id";
  849. $resufv = Database::query($sqlufv, __FILE__, __LINE__);
  850. $n = Database::num_rows($resufv);
  851. if ($n > 1) {
  852. //problem, we already have to values for this field and user combination - keep last one
  853. while ($rowufv = Database::fetch_array($resufv)) {
  854. if ($n > 1) {
  855. $sqld = "DELETE FROM $t_ufv WHERE id = ".$rowufv['id'];
  856. $resd = Database::query($sqld, __FILE__, __LINE__);
  857. $n--;
  858. }
  859. $rowufv = Database::fetch_array($resufv);
  860. if ($rowufv['field_value'] != $fvalues) {
  861. $sqlu = "UPDATE $t_ufv SET field_value = '$fvalues', tms = FROM_UNIXTIME($tms) WHERE id = ".$rowufv['id'];
  862. $resu = Database::query($sqlu, __FILE__, __LINE__);
  863. return($resu ? true : false);
  864. }
  865. return true;
  866. }
  867. }
  868. elseif ($n == 1) {
  869. //we need to update the current record
  870. $rowufv = Database::fetch_array($resufv);
  871. if ($rowufv['field_value'] != $fvalues) {
  872. $sqlu = "UPDATE $t_ufv SET field_value = '$fvalues', tms = FROM_UNIXTIME($tms) WHERE id = ".$rowufv['id'];
  873. //error_log('UM::update_extra_field_value: '.$sqlu);
  874. $resu = Database::query($sqlu, __FILE__, __LINE__);
  875. return($resu ? true : false);
  876. }
  877. return true;
  878. } else {
  879. $sqli = "INSERT INTO $t_ufv (user_id,field_id,field_value,tms) " .
  880. "VALUES ($user_id,".$rowuf['id'].",'$fvalues',FROM_UNIXTIME($tms))";
  881. //error_log('UM::update_extra_field_value: '.$sqli);
  882. $resi = Database::query($sqli, __FILE__, __LINE__);
  883. return($resi ? true : false);
  884. }
  885. } else {
  886. return false; //field not found
  887. }
  888. }
  889. /**
  890. * Get an array of extra fieds with field details (type, default value and options)
  891. * @param integer Offset (from which row)
  892. * @param integer Number of items
  893. * @param integer Column on which sorting is made
  894. * @param string Sorting direction
  895. * @param boolean Optional. Whether we get all the fields or just the visible ones
  896. * @return array Extra fields details (e.g. $list[2]['type'], $list[4]['options'][2]['title']
  897. */
  898. public static function get_extra_fields($from = 0, $number_of_items = 0, $column = 5, $direction = 'ASC', $all_visibility = true) {
  899. $fields = array();
  900. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  901. $t_ufo = Database :: get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  902. $columns = array('id', 'field_variable', 'field_type', 'field_display_text', 'field_default_value', 'field_order', 'field_filter', 'tms');
  903. $sort_direction = '';
  904. if (in_array(strtoupper($direction), array('ASC', 'DESC'))) {
  905. $sort_direction = strtoupper($direction);
  906. }
  907. $sqlf = "SELECT * FROM $t_uf ";
  908. if ($all_visibility == false) {
  909. $sqlf .= " WHERE field_visible = 1 ";
  910. }
  911. $sqlf .= " ORDER BY ".$columns[$column]." $sort_direction " ;
  912. if ($number_of_items != 0) {
  913. $sqlf .= " LIMIT ".Database::escape_string($from).','.Database::escape_string($number_of_items);
  914. }
  915. $resf = Database::query($sqlf, __FILE__, __LINE__);
  916. if (Database::num_rows($resf) > 0) {
  917. while($rowf = Database::fetch_array($resf)) {
  918. $fields[$rowf['id']] = array(
  919. 0 => $rowf['id'],
  920. 1 => $rowf['field_variable'],
  921. 2 => $rowf['field_type'],
  922. //3 => (empty($rowf['field_display_text']) ? '' : get_lang($rowf['field_display_text'], '')),
  923. // Temporarily removed auto-translation. Need update to get_lang() to know if translation exists (todo)
  924. // Ivan, 15-SEP-2009: get_lang() has been modified accordingly in order this issue to be solved.
  925. 3 => (empty($rowf['field_display_text']) ? '' : $rowf['field_display_text']),
  926. 4 => $rowf['field_default_value'],
  927. 5 => $rowf['field_order'],
  928. 6 => $rowf['field_visible'],
  929. 7 => $rowf['field_changeable'],
  930. 8 => $rowf['field_filter'],
  931. 9 => array()
  932. );
  933. $sqlo = "SELECT * FROM $t_ufo WHERE field_id = ".$rowf['id']." ORDER BY option_order ASC";
  934. $reso = Database::query($sqlo, __FILE__, __LINE__);
  935. if (Database::num_rows($reso) > 0) {
  936. while ($rowo = Database::fetch_array($reso)) {
  937. $fields[$rowf['id']][9][$rowo['id']] = array(
  938. 0 => $rowo['id'],
  939. 1 => $rowo['option_value'],
  940. //2 => (empty($rowo['option_display_text']) ? '' : get_lang($rowo['option_display_text'], '')),
  941. 2 => (empty($rowo['option_display_text']) ? '' : $rowo['option_display_text']),
  942. 3 => $rowo['option_order']
  943. );
  944. }
  945. }
  946. }
  947. }
  948. return $fields;
  949. }
  950. /**
  951. * Get the list of options attached to an extra field
  952. * @param string $fieldname the name of the field
  953. * @return array the list of options
  954. */
  955. public static function get_extra_field_options($field_name) {
  956. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  957. $t_ufo = Database :: get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  958. $sql = 'SELECT options.*
  959. FROM '.$t_ufo.' options
  960. INNER JOIN '.$t_uf.' fields
  961. ON fields.id = options.field_id
  962. AND fields.field_variable="'.Database::escape_string($field_name).'"';
  963. $rs = Database::query($sql, __FILE__, __LINE__);
  964. return Database::store_result($rs);
  965. }
  966. /**
  967. * Get the number of extra fields currently recorded
  968. * @param boolean Optional switch. true (default) returns all fields, false returns only visible fields
  969. * @return integer Number of fields
  970. */
  971. public static function get_number_of_extra_fields($all_visibility = true) {
  972. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  973. $sqlf = "SELECT * FROM $t_uf ";
  974. if ($all_visibility == false) {
  975. $sqlf .= " WHERE field_visible = 1 ";
  976. }
  977. $sqlf .= " ORDER BY field_order";
  978. $resf = Database::query($sqlf, __FILE__, __LINE__);
  979. return Database::num_rows($resf);
  980. }
  981. /**
  982. * Creates a new extra field
  983. * @param string Field's internal variable name
  984. * @param int Field's type
  985. * @param string Field's language var name
  986. * @param string Field's default value
  987. * @param string Optional comma-separated list of options to provide for select and radio
  988. * @return int new user id - if the new user creation succeeds, false otherwise
  989. */
  990. public static function create_extra_field($fieldvarname, $fieldtype, $fieldtitle, $fielddefault, $fieldoptions = '') {
  991. // database table definition
  992. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  993. $table_field_options= Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  994. // First check wether the login already exists
  995. if (self::is_extra_field_available($fieldvarname)) {
  996. return api_set_failure('login-pass already taken');
  997. }
  998. $sql = "SELECT MAX(field_order) FROM $table_field";
  999. $res = Database::query($sql, __FILE__, __LINE__);
  1000. $order = 0;
  1001. if (Database::num_rows($res) > 0) {
  1002. $row = Database::fetch_array($res);
  1003. $order = $row[0]+1;
  1004. }
  1005. $time = time();
  1006. $sql = "INSERT INTO $table_field
  1007. SET field_type = '".Database::escape_string($fieldtype)."',
  1008. field_variable = '".Database::escape_string($fieldvarname)."',
  1009. field_display_text = '".Database::escape_string($fieldtitle)."',
  1010. field_default_value = '".Database::escape_string($fielddefault)."',
  1011. field_order = '$order',
  1012. tms = FROM_UNIXTIME($time)";
  1013. $result = Database::query($sql);
  1014. if ($result) {
  1015. //echo "id returned";
  1016. $return = Database::get_last_insert_id();
  1017. } else {
  1018. //echo "false - failed" ;
  1019. return false;
  1020. }
  1021. if (!empty($fieldoptions) && in_array($fieldtype, array(USER_FIELD_TYPE_RADIO, USER_FIELD_TYPE_SELECT, USER_FIELD_TYPE_SELECT_MULTIPLE, USER_FIELD_TYPE_DOUBLE_SELECT))) {
  1022. if ($fieldtype == USER_FIELD_TYPE_DOUBLE_SELECT) {
  1023. $twolist = explode('|', $fieldoptions);
  1024. $counter = 0;
  1025. foreach ($twolist as $individual_list) {
  1026. $splitted_individual_list = split(';', $individual_list);
  1027. foreach ($splitted_individual_list as $individual_list_option) {
  1028. //echo 'counter:'.$counter;
  1029. if ($counter == 0) {
  1030. $list[] = $individual_list_option;
  1031. } else {
  1032. $list[] = str_repeat('*', $counter).$individual_list_option;
  1033. }
  1034. }
  1035. $counter++;
  1036. }
  1037. } else {
  1038. $list = split(';', $fieldoptions);
  1039. }
  1040. foreach ($list as $option) {
  1041. $option = Database::escape_string($option);
  1042. $sql = "SELECT * FROM $table_field_options WHERE field_id = $return AND option_value = '".$option."'";
  1043. $res = Database::query($sql, __FILE__, __LINE__);
  1044. if (Database::num_rows($res) > 0) {
  1045. //the option already exists, do nothing
  1046. } else {
  1047. $sql = "SELECT MAX(option_order) FROM $table_field_options WHERE field_id = $return";
  1048. $res = Database::query($sql, __FILE__, __LINE__);
  1049. $max = 1;
  1050. if (Database::num_rows($res) > 0) {
  1051. $row = Database::fetch_array($res);
  1052. $max = $row[0] + 1;
  1053. }
  1054. $time = time();
  1055. $sql = "INSERT INTO $table_field_options (field_id,option_value,option_display_text,option_order,tms) VALUES ($return,'$option','$option',$max,FROM_UNIXTIME($time))";
  1056. $res = Database::query($sql, __FILE__, __LINE__);
  1057. if ($res === false) {
  1058. $return = false;
  1059. }
  1060. }
  1061. }
  1062. }
  1063. return $return;
  1064. }
  1065. /**
  1066. * Save the changes in the definition of the extra user profile field
  1067. * The function is called after you (as admin) decide to store the changes you have made to one of the fields you defined
  1068. *
  1069. * There is quite some logic in this field
  1070. * 1. store the changes to the field (tupe, name, label, default text)
  1071. * 2. remove the options and the choices of the users from the database that no longer occur in the form field 'possible values'. We should only remove
  1072. * the options (and choices) that do no longer have to appear. We cannot remove all options and choices because if you remove them all
  1073. * and simply re-add them all then all the user who have already filled this form will loose their selected value.
  1074. * 3. we add the options that are newly added
  1075. *
  1076. * @example current options are a;b;c and the user changes this to a;b;x (removing c and adding x)
  1077. * we first remove c (and also the entry in the option_value table for the users who have chosen this)
  1078. * we then add x
  1079. * a and b are neither removed nor added
  1080. *
  1081. * @param integer $fieldid the id of the field we are editing
  1082. * @param string $fieldvarname the internal variable name of the field
  1083. * @param int $fieldtype the type of the field
  1084. * @param string $fieldtitle the title of the field
  1085. * @param string $fielddefault the default value of the field
  1086. * @param string $fieldoptions Optional comma-separated list of options to provide for select and radio
  1087. * @return boolean true
  1088. *
  1089. *
  1090. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  1091. * @version July 2008
  1092. * @since Dokeos 1.8.6
  1093. */
  1094. public static function save_extra_field_changes($fieldid, $fieldvarname, $fieldtype, $fieldtitle, $fielddefault, $fieldoptions = '') {
  1095. // database table definition
  1096. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1097. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1098. $table_field_options_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1099. // we first update the field definition with the new values
  1100. $time = time();
  1101. $sql = "UPDATE $table_field
  1102. SET field_type = '".Database::escape_string($fieldtype)."',
  1103. field_variable = '".Database::escape_string($fieldvarname)."',
  1104. field_display_text = '".Database::escape_string($fieldtitle)."',
  1105. field_default_value = '".Database::escape_string($fielddefault)."',
  1106. tms = FROM_UNIXTIME($time)
  1107. WHERE id = '".Database::escape_string($fieldid)."'";
  1108. $result = Database::query($sql, __FILE__, __LINE__);
  1109. // we create an array with all the options (will be used later in the script)
  1110. if ($fieldtype == USER_FIELD_TYPE_DOUBLE_SELECT) {
  1111. $twolist = explode('|', $fieldoptions);
  1112. $counter = 0;
  1113. foreach ($twolist as $individual_list) {
  1114. $splitted_individual_list = split(';', $individual_list);
  1115. foreach ($splitted_individual_list as $individual_list_option) {
  1116. //echo 'counter:'.$counter;
  1117. if ($counter == 0) {
  1118. $list[] = trim($individual_list_option);
  1119. } else {
  1120. $list[] = str_repeat('*', $counter).trim($individual_list_option);
  1121. }
  1122. }
  1123. $counter++;
  1124. }
  1125. } else {
  1126. $templist = split(';', $fieldoptions);
  1127. $list = array_map('trim', $templist);
  1128. }
  1129. // Remove all the field options (and also the choices of the user) that are NOT in the new list of options
  1130. $sql = "SELECT * FROM $table_field_options WHERE option_value NOT IN ('".implode("','", $list)."') AND field_id = '".Database::escape_string($fieldid)."'";
  1131. $result = Database::query($sql, __FILE__, __LINE__);
  1132. $return['deleted_options'] = 0;
  1133. while ($row = Database::fetch_array($result)) {
  1134. // deleting the option
  1135. $sql_delete_option = "DELETE FROM $table_field_options WHERE id='".Database::escape_string($row['id'])."'";
  1136. $result_delete_option = Database::query($sql_delete_option, __FILE__, __LINE__);
  1137. $return['deleted_options']++;
  1138. // deleting the answer of the user who has chosen this option
  1139. $sql_delete_option_value = "DELETE FROM $table_field_options_values WHERE field_id = '".Database::escape_string($fieldid)."' AND field_value = '".Database::escape_string($row['option_value'])."'";
  1140. $result_delete_option_value = Database::query($sql_delete_option_value, __FILE__, __LINE__);
  1141. $return['deleted_option_values'] = $return['deleted_option_values'] + Database::affected_rows();
  1142. }
  1143. // we now try to find the field options that are newly added
  1144. $sql = "SELECT * FROM $table_field_options WHERE field_id = '".Database::escape_string($fieldid)."'";
  1145. $result = Database::query($sql, __FILE__, __LINE__);
  1146. while ($row = Database::fetch_array($result)) {
  1147. // we remove every option that is already in the database from the $list
  1148. if (in_array(trim($row['option_display_text']), $list)) {
  1149. $key = array_search(trim($row['option_display_text']), $list);
  1150. unset($list[$key]);
  1151. }
  1152. }
  1153. // we store the new field options in the database
  1154. foreach ($list as $key => $option) {
  1155. $sql = "SELECT MAX(option_order) FROM $table_field_options WHERE field_id = '".Database::escape_string($fieldid)."'";
  1156. $res = Database::query($sql, __FILE__, __LINE__);
  1157. $max = 1;
  1158. if (Database::num_rows($res) > 0) {
  1159. $row = Database::fetch_array($res);
  1160. $max = $row[0] + 1;
  1161. }
  1162. $time = time();
  1163. $sql = "INSERT INTO $table_field_options (field_id,option_value,option_display_text,option_order,tms) VALUES ('".Database::escape_string($fieldid)."','".Database::escape_string($option)."','".Database::escape_string($option)."',$max,FROM_UNIXTIME($time))";
  1164. $result = Database::query($sql, __FILE__, __LINE__);
  1165. }
  1166. return true;
  1167. }
  1168. /**
  1169. * Check if a field is available
  1170. * @param string the wanted fieldname
  1171. * @return boolean true if the wanted username is available
  1172. */
  1173. public static function is_extra_field_available($fieldname) {
  1174. $t_uf = Database :: get_main_table(TABLE_MAIN_USER_FIELD);
  1175. $sql = "SELECT * FROM $t_uf WHERE field_variable = '".Database::escape_string($fieldname)."'";
  1176. $res = Database::query($sql, __FILE__, __LINE__);
  1177. return Database::num_rows($res) > 0;
  1178. }
  1179. /**
  1180. * Gets user extra fields data
  1181. * @param integer User ID
  1182. * @param boolean Whether to prefix the fields indexes with "extra_" (might be used by formvalidator)
  1183. * @param boolean Whether to return invisible fields as well
  1184. * @param boolean Whether to split multiple-selection fields or not
  1185. * @return array Array of fields => value for the given user
  1186. */
  1187. public static function get_extra_user_data($user_id, $prefix = false, $all_visibility = true, $splitmultiple = false) {
  1188. // A sanity check.
  1189. if (empty($user_id)) {
  1190. $user_id = 0;
  1191. }
  1192. $extra_data = array();
  1193. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1194. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1195. $user_id = Database::escape_string($user_id);
  1196. $sql = "SELECT f.id as id, f.field_variable as fvar, f.field_type as type FROM $t_uf f ";
  1197. if ($all_visibility == false) {
  1198. $sql .= " WHERE f.field_visible = 1 ";
  1199. }
  1200. $sql .= " ORDER BY f.field_order";
  1201. $res = Database::query($sql, __FILE__, __LINE__);
  1202. if (Database::num_rows($res) > 0) {
  1203. while ($row = Database::fetch_array($res)) {
  1204. $sqlu = "SELECT field_value as fval " .
  1205. " FROM $t_ufv " .
  1206. " WHERE field_id=".$row['id']."" .
  1207. " AND user_id=".$user_id;
  1208. $resu = Database::query($sqlu, __FILE__, __LINE__);
  1209. $fval = '';
  1210. // get default value
  1211. $sql_df = "SELECT field_default_value as fval_df " .
  1212. " FROM $t_uf " .
  1213. " WHERE id=".$row['id'];
  1214. $res_df = Database::query($sql_df, __FILE__, __LINE__);
  1215. if (Database::num_rows($resu) > 0) {
  1216. $rowu = Database::fetch_array($resu);
  1217. $fval = $rowu['fval'];
  1218. if ($row['type'] == USER_FIELD_TYPE_SELECT_MULTIPLE) {
  1219. $fval = split(';',$rowu['fval']);
  1220. }
  1221. } else {
  1222. $row_df = Database::fetch_array($res_df);
  1223. $fval = $row_df['fval_df'];
  1224. }
  1225. if ($prefix) {
  1226. if ($row['type'] == USER_FIELD_TYPE_RADIO) {
  1227. $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval;
  1228. } else {
  1229. $extra_data['extra_'.$row['fvar']] = $fval;
  1230. }
  1231. } else {
  1232. if ($row['type'] == USER_FIELD_TYPE_RADIO) {
  1233. $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval;
  1234. } else {
  1235. $extra_data[$row['fvar']] = $fval;
  1236. }
  1237. }
  1238. }
  1239. }
  1240. return $extra_data;
  1241. }
  1242. /** Get extra user data by field
  1243. * @param int user ID
  1244. * @param string the internal variable name of the field
  1245. * @return array with extra data info of a user i.e array('field_variable'=>'value');
  1246. */
  1247. public static function get_extra_user_data_by_field($user_id, $field_variable, $prefix = false, $all_visibility = true, $splitmultiple = false) {
  1248. // A sanity check.
  1249. if (empty($user_id)) {
  1250. $user_id = 0;
  1251. }
  1252. $extra_data = array();
  1253. $t_uf = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1254. $t_ufv = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1255. $user_id = Database::escape_string($user_id);
  1256. $sql = "SELECT f.id as id, f.field_variable as fvar, f.field_type as type FROM $t_uf f ";
  1257. $sql .= " WHERE f.field_variable = '$field_variable' ";
  1258. if ($all_visibility == false) {
  1259. $sql .= " AND f.field_visible = 1 ";
  1260. }
  1261. $sql .= " ORDER BY f.field_order";
  1262. $res = Database::query($sql, __FILE__, __LINE__);
  1263. if (Database::num_rows($res) > 0) {
  1264. while ($row = Database::fetch_array($res)) {
  1265. $sqlu = "SELECT field_value as fval " .
  1266. " FROM $t_ufv " .
  1267. " WHERE field_id=".$row['id']."" .
  1268. " AND user_id=".$user_id;
  1269. $resu = Database::query($sqlu, __FILE__, __LINE__);
  1270. $fval = '';
  1271. if (Database::num_rows($resu) > 0) {
  1272. $rowu = Database::fetch_array($resu);
  1273. $fval = $rowu['fval'];
  1274. if ($row['type'] == USER_FIELD_TYPE_SELECT_MULTIPLE) {
  1275. $fval = split(';',$rowu['fval']);
  1276. }
  1277. }
  1278. if ($prefix) {
  1279. $extra_data['extra_'.$row['fvar']] = $fval;
  1280. } else {
  1281. $extra_data[$row['fvar']] = $fval;
  1282. }
  1283. }
  1284. }
  1285. return $extra_data;
  1286. }
  1287. /**
  1288. * Get the extra field information for a certain field (the options as well)
  1289. * @param int The name of the field we want to know everything about
  1290. * @return array Array containing all the information about the extra profile field (first level of array contains field details, then 'options' sub-array contains options details, as returned by the database)
  1291. * @author Julio Montoya
  1292. * @since Dokeos 1.8.6
  1293. */
  1294. public static function get_extra_field_information_by_name($field_variable, $fuzzy = false) {
  1295. // database table definition
  1296. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1297. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1298. // all the information of the field
  1299. $sql = "SELECT * FROM $table_field WHERE field_variable='".Database::escape_string($field_variable)."'";
  1300. $result = Database::query($sql, __FILE__, __LINE__);
  1301. $return = Database::fetch_array($result);
  1302. // all the options of the field
  1303. $sql = "SELECT * FROM $table_field_options WHERE field_id='".Database::escape_string($return['id'])."' ORDER BY option_order ASC";
  1304. $result = Database::query($sql, __FILE__, __LINE__);
  1305. while ($row = Database::fetch_array($result)) {
  1306. $return['options'][$row['id']] = $row;
  1307. }
  1308. return $return;
  1309. }
  1310. /**
  1311. * Get all the extra field information of a certain field (also the options)
  1312. *
  1313. * @param int $field_name the name of the field we want to know everything of
  1314. * @return array $return containing all th information about the extra profile field
  1315. * @author Julio Montoya
  1316. * @since Dokeos 1.8.6
  1317. */
  1318. public static function get_extra_field_information($field_id) {
  1319. // database table definition
  1320. $table_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1321. $table_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1322. // all the information of the field
  1323. $sql = "SELECT * FROM $table_field WHERE id='".Database::escape_string($field_id)."'";
  1324. $result = Database::query($sql, __FILE__, __LINE__);
  1325. $return = Database::fetch_array($result);
  1326. // all the options of the field
  1327. $sql = "SELECT * FROM $table_field_options WHERE field_id='".Database::escape_string($field_id)."' ORDER BY option_order ASC";
  1328. $result = Database::query($sql, __FILE__, __LINE__);
  1329. while ($row = Database::fetch_array($result)) {
  1330. $return['options'][$row['id']] = $row;
  1331. }
  1332. return $return;
  1333. }
  1334. /** Get extra user data by value
  1335. * @param string the internal variable name of the field
  1336. * @param string the internal value of the field
  1337. * @return array with extra data info of a user i.e array('field_variable'=>'value');
  1338. */
  1339. public static function get_extra_user_data_by_value($field_variable, $field_value, $all_visibility = true) {
  1340. $extra_data = array();
  1341. $table_user_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
  1342. $table_user_field_values = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
  1343. $table_user_field_options = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
  1344. $where = '';
  1345. /*
  1346. if (is_array($field_variable_array) && is_array($field_value_array)) {
  1347. if (count($field_variable_array) == count($field_value_array)) {
  1348. $field_var_count = count($field_variable_array);
  1349. for ($i = 0; $i < $field_var_count; $i++) {
  1350. if ($i != 0 && $i != $field_var_count) {
  1351. $where.= ' AND ';
  1352. }
  1353. $where.= "field_variable='".Database::escape_string($field_variable_array[$i])."' AND user_field_options.id='".Database::escape_string($field_value_array[$i])."'";
  1354. }
  1355. }
  1356. }*/
  1357. $where = "field_variable='".Database::escape_string($field_variable)."' AND field_value='".Database::escape_string($field_value)."'";
  1358. $sql = "SELECT user_id FROM $table_user_field user_field INNER JOIN $table_user_field_values user_field_values
  1359. ON (user_field.id = user_field_values.field_id)
  1360. WHERE $where";
  1361. if ($all_visibility == true) {
  1362. $sql .= " AND user_field.field_visible = 1 ";
  1363. } else {
  1364. $sql .= " AND user_field.field_visible = 0 ";
  1365. }
  1366. $res = Database::query($sql, __FILE__, __LINE__);
  1367. $result_data = array();
  1368. if (Database::num_rows($res) > 0) {
  1369. while ($row = Database::fetch_array($res)) {
  1370. $result_data[] = $row['user_id'];
  1371. }
  1372. }
  1373. return $result_data;
  1374. }
  1375. /**
  1376. * Gives a list of [session_id-course_code] => [status] for the current user.
  1377. * @param integer $user_id
  1378. * @return array list of statuses (session_id-course_code => status)
  1379. */
  1380. public static function get_personal_session_course_list($user_id) {
  1381. // Database Table Definitions
  1382. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1383. $tbl_course = Database :: get_main_table(TABLE_MAIN_COURSE);
  1384. $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
  1385. $tbl_session = Database :: get_main_table(TABLE_MAIN_SESSION);
  1386. $tbl_session_user = Database :: get_main_table(TABLE_MAIN_SESSION_USER);
  1387. $tbl_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
  1388. $tbl_session_course = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE);
  1389. $tbl_session_course_user = Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1390. $user_id = Database::escape_string($user_id);
  1391. //we filter the courses from the URL
  1392. $join_access_url = $where_access_url = '';
  1393. global $_configuration;
  1394. if ($_configuration['multiple_access_urls'] == true) {
  1395. $access_url_id = api_get_current_access_url_id();
  1396. if ($access_url_id != -1) {
  1397. $tbl_url_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
  1398. $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course ON url_rel_course.course_code= course.code";
  1399. $where_access_url = " AND access_url_id = $access_url_id ";
  1400. }
  1401. }
  1402. // variable initialisation
  1403. $personal_course_list_sql = '';
  1404. $personal_course_list = array();
  1405. //Courses in which we suscribed out of any session
  1406. /*$personal_course_list_sql = "SELECT course.code k, course.directory d, course.visual_code c, course.db_name db, course.title i,
  1407. course.tutor_name t, course.course_language l, course_rel_user.status s, course_rel_user.sort sort,
  1408. course_rel_user.user_course_cat user_course_cat
  1409. FROM ".$tbl_course." course,".$main_course_user_table." course_rel_user
  1410. WHERE course.code = course_rel_user.course_code"."
  1411. AND course_rel_user.user_id = '".$user_id."'
  1412. ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC,i";*/
  1413. $tbl_user_course_category = Database :: get_user_personal_table(TABLE_USER_COURSE_CATEGORY);
  1414. $personal_course_list_sql = "SELECT course.code k, course.directory d, course.visual_code c, course.db_name db, course.title i, course.tutor_name t, course.course_language l, course_rel_user.status s, course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
  1415. FROM ".$tbl_course_user." course_rel_user
  1416. LEFT JOIN ".$tbl_course." course
  1417. ON course.code = course_rel_user.course_code
  1418. LEFT JOIN ".$tbl_user_course_category." user_course_category
  1419. ON course_rel_user.user_course_cat = user_course_category.id
  1420. $join_access_url
  1421. WHERE course_rel_user.user_id = '".$user_id."' $where_access_url
  1422. ORDER BY user_course_category.sort,course.title,course_rel_user.sort ASC";
  1423. $course_list_sql_result = Database::query($personal_course_list_sql, __FILE__, __LINE__);
  1424. //var_dump($course_list_sql_result); exit;
  1425. while ($result_row = Database::fetch_array($course_list_sql_result)) {
  1426. $personal_course_list[] = $result_row;
  1427. }
  1428. // get the list of sessions where the user is subscribed as student
  1429. $sessions_sql = "SELECT DISTINCT id, name, date_start, date_end
  1430. FROM $tbl_session_user, $tbl_session
  1431. WHERE id_session=id AND id_user=$user_id
  1432. AND (date_start <= CURDATE() AND date_end >= CURDATE() OR date_start='0000-00-00')
  1433. ORDER BY date_start, date_end, name";
  1434. $result = Database::query($sessions_sql, __FILE__, __LINE__);
  1435. $sessions=Database::store_result($result);
  1436. $sessions = array_merge($sessions, Database::store_result($result));
  1437. // get the list of sessions where the user is subscribed as coach in a course
  1438. $sessions_sql = "SELECT DISTINCT id, name, date_start, date_end, DATE_SUB(date_start, INTERVAL nb_days_access_before_beginning DAY), ADDDATE(date_end, INTERVAL nb_days_access_after_end DAY)
  1439. FROM $tbl_session as session
  1440. INNER JOIN $tbl_session_course as session_rel_course
  1441. ON session_rel_course.id_session = session.id
  1442. AND session_rel_course.id_coach = $user_id
  1443. WHERE (CURDATE() >= DATE_SUB(date_start, INTERVAL nb_days_access_before_beginning DAY)
  1444. AND CURDATE() <= ADDDATE(date_end, INTERVAL nb_days_access_after_end DAY)
  1445. OR date_start='0000-00-00')
  1446. ORDER BY date_start, date_end, name";
  1447. $result = Database::query($sessions_sql, __FILE__, __LINE__);
  1448. $session_is_coach = Database::store_result($result);
  1449. $sessions = array_merge($sessions, $session_is_coach);
  1450. // get the list of sessions where the user is subscribed as coach
  1451. $sessions_sql = "SELECT DISTINCT id, name, date_start, date_end
  1452. FROM $tbl_session as session
  1453. WHERE session.id_coach = $user_id
  1454. AND (CURDATE() >= DATE_SUB(date_start, INTERVAL nb_days_access_before_beginning DAY)
  1455. AND CURDATE() <= ADDDATE(date_end, INTERVAL nb_days_access_after_end DAY)
  1456. OR date_start='0000-00-00')
  1457. ORDER BY date_start, date_end, name";
  1458. $result = Database::query($sessions_sql, __FILE__, __LINE__);
  1459. $sessions = array_merge($sessions, Database::store_result($result));
  1460. if (api_is_allowed_to_create_course()) {
  1461. foreach($sessions as $enreg) {
  1462. $id_session = $enreg['id'];
  1463. $personal_course_list_sql = "SELECT DISTINCT course.code k, course.directory d, course.visual_code c, course.db_name db, course.title i, ".(api_is_western_name_order() ? "CONCAT(user.firstname,' ',user.lastname)" : "CONCAT(user.lastname,' ',user.firstname)")." t, email, course.course_language l, 1 sort, category_code user_course_cat, date_start, date_end, session.id as id_session, session.name as session_name
  1464. FROM $tbl_session_course as session_course
  1465. INNER JOIN $tbl_course AS course
  1466. ON course.code = session_course.course_code
  1467. INNER JOIN $tbl_session as session
  1468. ON session.id = session_course.id_session
  1469. LEFT JOIN $tbl_user as user
  1470. ON user.user_id = session_course.id_coach
  1471. WHERE session_course.id_session = $id_session
  1472. AND (session_course.id_coach=$user_id OR session.id_coach=$user_id)
  1473. ORDER BY i";
  1474. $course_list_sql_result = Database::query($personal_course_list_sql, __FILE__, __LINE__);
  1475. while ($result_row = Database::fetch_array($course_list_sql_result)) {
  1476. $result_row['s'] = 2;
  1477. $key = $result_row['id_session'].' - '.$result_row['k'];
  1478. $personal_course_list[$key] = $result_row;
  1479. }
  1480. }
  1481. }
  1482. foreach ($sessions as $enreg) {
  1483. $id_session = $enreg['id'];
  1484. $personal_course_list_sql = "SELECT DISTINCT course.code k, course.directory d, course.visual_code c, course.db_name db, course.title i, ".(api_is_western_name_order() ? "CONCAT(user.firstname,' ',user.lastname)" : "CONCAT(user.lastname,' ',user.firstname)")." t, email, course.course_language l, 1 sort, category_code user_course_cat, date_start, date_end, session.id as id_session, session.name as session_name, IF(session_course.id_coach = ".$user_id.",'2', '5')
  1485. FROM $tbl_session_course as session_course
  1486. INNER JOIN $tbl_course AS course
  1487. ON course.code = session_course.course_code
  1488. LEFT JOIN $tbl_user as user
  1489. ON user.user_id = session_course.id_coach
  1490. INNER JOIN $tbl_session_course_user
  1491. ON $tbl_session_course_user.id_session = $id_session
  1492. AND $tbl_session_course_user.id_user = $user_id
  1493. INNER JOIN $tbl_session as session
  1494. ON session_course.id_session = session.id
  1495. WHERE session_course.id_session = $id_session
  1496. ORDER BY i";
  1497. $course_list_sql_result = Database::query($personal_course_list_sql, __FILE__, __LINE__);
  1498. while ($result_row = Database::fetch_array($course_list_sql_result)) {
  1499. $key = $result_row['id_session'].' - '.$result_row['k'];
  1500. $result_row['s'] = $result_row['14'];
  1501. if (!isset($personal_course_list[$key])) {
  1502. $personal_course_list[$key] = $result_row;
  1503. }
  1504. }
  1505. }
  1506. //print_r($personal_course_list);
  1507. return $personal_course_list;
  1508. }
  1509. /**
  1510. * Get user id from a username
  1511. * @param string Username
  1512. * @return int User ID (or false if not found)
  1513. */
  1514. public static function get_user_id_from_username($username) {
  1515. $username = Database::escape_string($username);
  1516. $t_user = Database::get_main_table(TABLE_MAIN_USER);
  1517. $sql = "SELECT user_id FROM $t_user WHERE username = '$username'";
  1518. $res = Database::query($sql, __FILE__, __LINE__);
  1519. if ($res === false) { return false; }
  1520. if (Database::num_rows($res) !== 1) { return false; }
  1521. $row = Database::fetch_array($res);
  1522. return $row['user_id'];
  1523. }
  1524. /**
  1525. * Get the users files upload from his share_folder
  1526. * @param string User ID
  1527. * @param string course directory
  1528. * @param int deprecated
  1529. * @return int User ID (or false if not found)
  1530. */
  1531. public static function get_user_upload_files_by_course($user_id, $course, $column = 2) {
  1532. $return = '';
  1533. if (!empty($user_id) && !empty($course)) {
  1534. $user_id = intval($user_id);
  1535. $path = api_get_path(SYS_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/';
  1536. $web_path = api_get_path(WEB_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/';
  1537. $file_list = array();
  1538. if (is_dir($path)) {
  1539. $handle = opendir($path);
  1540. while ($file = readdir($handle)) {
  1541. if ($file == '.' || $file == '..' || $file == '.htaccess' || is_dir($path.$file)) {
  1542. continue; // skip current/parent directory and .htaccess
  1543. }
  1544. $file_list[] = $file;
  1545. }
  1546. if (count($file_list) > 0) {
  1547. $return = $course;
  1548. $return .= '<ul>';
  1549. }
  1550. foreach ($file_list as $file) {
  1551. $return .= '<li><a href="'.$web_path.urlencode($file).'" target="_blank">'.htmlentities($file).'</a>';
  1552. }
  1553. $return .= '</ul>';
  1554. }
  1555. }
  1556. return $return;
  1557. }
  1558. /**
  1559. * Gets the API key (or keys) and return them into an array
  1560. * @param int Optional user id (defaults to the result of api_get_user_id())
  1561. * @result array Non-indexed array containing the list of API keys for this user, or FALSE on error
  1562. */
  1563. public static function get_api_keys($user_id = null, $api_service = 'dokeos') {
  1564. if ($user_id != strval(intval($user_id))) return false;
  1565. if (empty($user_id)) { $user_id = api_get_user_id(); }
  1566. if ($user_id === false) return false;
  1567. $service_name = Database::escape_string($api_service);
  1568. if (is_string($service_name) === false) { return false;}
  1569. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  1570. $sql = "SELECT id, api_key FROM $t_api WHERE user_id = ".$user_id." AND api_service='".$api_service."';";
  1571. $res = Database::query($sql, __FILE__, __LINE__);
  1572. if ($res === false) return false; //error during query
  1573. $num = Database::num_rows($res);
  1574. if ($num == 0) return false;
  1575. $list = array();
  1576. while ($row = Database::fetch_array($res)) {
  1577. $list[$row['id']] = $row['api_key'];
  1578. }
  1579. return $list;
  1580. }
  1581. /**
  1582. * Adds a new API key to the users' account
  1583. * @param int Optional user ID (defaults to the results of api_get_user_id())
  1584. * @return boolean True on success, false on failure
  1585. */
  1586. public static function add_api_key($user_id = null, $api_service = 'dokeos') {
  1587. if ($user_id != strval(intval($user_id))) return false;
  1588. if (empty($user_id)) { $user_id = api_get_user_id(); }
  1589. if ($user_id === false) return false;
  1590. $service_name = Database::escape_string($api_service);
  1591. if (is_string($service_name) === false) { return false; }
  1592. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  1593. $md5 = md5((time() + ($user_id * 5)) - rand(10000, 10000)); //generate some kind of random key
  1594. $sql = "INSERT INTO $t_api (user_id, api_key,api_service) VALUES ($user_id,'$md5','$service_name')";
  1595. $res = Database::query($sql, __FILE__, __LINE__);
  1596. if ($res === false) return false; //error during query
  1597. $num = Database::insert_id();
  1598. return ($num == 0) ? false : $num;
  1599. }
  1600. /**
  1601. * Deletes an API key from the user's account
  1602. * @param int API key's internal ID
  1603. * @return boolean True on success, false on failure
  1604. */
  1605. public static function delete_api_key($key_id) {
  1606. if ($key_id != strval(intval($key_id))) return false;
  1607. if ($key_id === false) return false;
  1608. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  1609. $sql = "SELECT * FROM $t_api WHERE id = ".$key_id;
  1610. $res = Database::query($sql, __FILE__, __LINE__);
  1611. if ($res === false) return false; //error during query
  1612. $num = Database::num_rows($res);
  1613. if ($num !== 1) return false;
  1614. $sql = "DELETE FROM $t_api WHERE id = ".$key_id;
  1615. $res = Database::query($sql, __FILE__, __LINE__);
  1616. if ($res === false) return false; //error during query
  1617. return true;
  1618. }
  1619. /**
  1620. * Regenerate an API key from the user's account
  1621. * @param int user ID (defaults to the results of api_get_user_id())
  1622. * @param string API key's internal ID
  1623. * @return int num
  1624. */
  1625. public static function update_api_key($user_id, $api_service) {
  1626. if ($user_id != strval(intval($user_id))) return false;
  1627. if ($user_id === false) return false;
  1628. $service_name = Database::escape_string($api_service);
  1629. if (is_string($service_name) === false) { return false; }
  1630. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  1631. $sql = "SELECT id FROM $t_api WHERE user_id=".$user_id." AND api_service='".$api_service."'";
  1632. $res = Database::query($sql, __FILE__, __LINE__);
  1633. $num = Database::num_rows($res);
  1634. if ($num == 1) {
  1635. $id_key = Database::fetch_array($res, 'ASSOC');
  1636. self::delete_api_key($id_key['id']);
  1637. $num = self::add_api_key($user_id, $api_service);
  1638. } elseif ($num == 0) {
  1639. $num = self::add_api_key($user_id);
  1640. }
  1641. return $num;
  1642. }
  1643. /**
  1644. * @param int user ID (defaults to the results of api_get_user_id())
  1645. * @param string API key's internal ID
  1646. * @return int row ID, not return a boolean
  1647. */
  1648. public static function get_api_key_id($user_id, $api_service) {
  1649. if ($user_id != strval(intval($user_id))) return false;
  1650. if ($user_id === false) return false;
  1651. $service_name = Database::escape_string($api_service);
  1652. if (is_string($service_name) === false) { return false; }
  1653. $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY);
  1654. $sql = "SELECT id FROM $t_api WHERE user_id=".$user_id." AND api_service='".$api_service."'";
  1655. $res = Database::query($sql, __FILE__, __LINE__);
  1656. $row = Database::fetch_array($res, 'ASSOC');
  1657. return $row['id'];
  1658. }
  1659. /**
  1660. * Subscribes users to the given session and optionally (default) unsubscribes previous users
  1661. * @param int Session ID
  1662. * @param array List of user IDs
  1663. * @param bool Whether to unsubscribe existing users (true, default) or not (false)
  1664. * @return void Nothing, or false on error
  1665. */
  1666. public static function suscribe_users_to_session($id_session, $UserList, $empty_users = true) {
  1667. if ($id_session != strval(intval($id_session))) return false;
  1668. foreach ($UserList as $intUser) {
  1669. if ($intUser != strval(intval($intUser))) return false;
  1670. }
  1671. $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
  1672. $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
  1673. $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
  1674. $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
  1675. $sql = "SELECT id_user FROM $tbl_session_rel_user WHERE id_session='$id_session'";
  1676. $result = Database::query($sql, __FILE__, __LINE__);
  1677. $existingUsers = array();
  1678. while($row = Database::fetch_array($result)) {
  1679. $existingUsers[] = $row['id_user'];
  1680. }
  1681. $sql = "SELECT course_code FROM $tbl_session_rel_course WHERE id_session='$id_session'";
  1682. $result = Database::query($sql, __FILE__, __LINE__);
  1683. $CourseList = array();
  1684. while($row = Database::fetch_array($result)) {
  1685. $CourseList[] = $row['course_code'];
  1686. }
  1687. foreach ($CourseList as $enreg_course) {
  1688. // for each course in the session
  1689. $nbr_users = 0;
  1690. $enreg_course = Database::escape_string($enreg_course);
  1691. // delete existing users
  1692. if ($empty_users !== false) {
  1693. foreach ($existingUsers as $existing_user) {
  1694. if(!in_array($existing_user, $UserList)) {
  1695. $sql = "DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code='$enreg_course' AND id_user='$existing_user'";
  1696. Database::query($sql, __FILE__, __LINE__);
  1697. if (Database::affected_rows()) {
  1698. $nbr_users--;
  1699. }
  1700. }
  1701. }
  1702. }
  1703. // insert new users into session_rel_course_rel_user and ignore if they already exist
  1704. foreach ($UserList as $enreg_user) {
  1705. if (!in_array($enreg_user, $existingUsers)) {
  1706. $enreg_user = Database::escape_string($enreg_user);
  1707. $insert_sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user(id_session,course_code,id_user) VALUES('$id_session','$enreg_course','$enreg_user')";
  1708. Database::query($insert_sql, __FILE__, __LINE__);
  1709. if (Database::affected_rows()) {
  1710. $nbr_users++;
  1711. }
  1712. }
  1713. }
  1714. // count users in this session-course relation
  1715. $sql = "SELECT COUNT(id_user) as nbUsers FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code='$enreg_course'";
  1716. $rs = Database::query($sql, __FILE__, __LINE__);
  1717. list($nbr_users) = Database::fetch_array($rs);
  1718. // update the session-course relation to add the users total
  1719. $update_sql = "UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users WHERE id_session='$id_session' AND course_code='$enreg_course'";
  1720. Database::query($update_sql, __FILE__, __LINE__);
  1721. }
  1722. // delete users from the session
  1723. if ($empty_users !== false) {
  1724. Database::query("DELETE FROM $tbl_session_rel_user WHERE id_session = $id_session", __FILE__, __LINE__);
  1725. }
  1726. // insert missing users into session
  1727. $nbr_users = 0;
  1728. foreach ($UserList as $enreg_user) {
  1729. $enreg_user = Database::escape_string($enreg_user);
  1730. $nbr_users++;
  1731. $insert_sql = "INSERT IGNORE INTO $tbl_session_rel_user(id_session, id_user) VALUES('$id_session','$enreg_user')";
  1732. Database::query($insert_sql, __FILE__, __LINE__);
  1733. }
  1734. // update number of users in the session
  1735. $nbr_users = count($UserList);
  1736. $update_sql = "UPDATE $tbl_session SET nbr_users= $nbr_users WHERE id='$id_session' ";
  1737. Database::query($update_sql, __FILE__, __LINE__);
  1738. }
  1739. /**
  1740. * Checks if a user_id is platform admin
  1741. * @param int user ID
  1742. * @return boolean True if is admin, false otherwise
  1743. * @see main_api.lib.php::api_is_platform_admin() for a context-based check
  1744. */
  1745. function is_admin($user_id) {
  1746. if (empty($user_id) or $user_id != strval(intval($user_id))) { return false; }
  1747. $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN);
  1748. $sql = "SELECT * FROM $admin_table WHERE user_id = $user_id";
  1749. $res = Database::query($sql);
  1750. return Database::num_rows($res) === 1;
  1751. }
  1752. /**
  1753. * Get the total count of users
  1754. * @return mixed Number of users or false on error
  1755. */
  1756. public static function get_number_of_users() {
  1757. $t_u = Database::get_main_table(TABLE_MAIN_USER);
  1758. $sql = "SELECT count(*) FROM $t_u";
  1759. $res = Database::query($sql);
  1760. if (Database::num_rows($res) === 1) {
  1761. return (int) Database::result($res, 0, 0);
  1762. }
  1763. return false;
  1764. }
  1765. /**
  1766. * Resize a picture
  1767. *
  1768. * @param string file picture
  1769. * @param int size in pixels
  1770. * @return obj image object
  1771. */
  1772. public static function resize_picture($file, $max_size_for_picture) {
  1773. if (!class_exists('image')) {
  1774. require_once api_get_path(LIBRARY_PATH).'image.lib.php';
  1775. }
  1776. $temp = new image($file);
  1777. $picture_infos = api_getimagesize($file);
  1778. if ($picture_infos[0] > $max_size_for_picture) {
  1779. $thumbwidth = $max_size_for_picture;
  1780. if (empty($thumbwidth) or $thumbwidth == 0) {
  1781. $thumbwidth = $max_size_for_picture;
  1782. }
  1783. $new_height = round(($thumbwidth / $picture_infos[0]) * $picture_infos[1]);
  1784. if ($new_height > $max_size_for_picture)
  1785. $new_height = $thumbwidth;
  1786. $temp->resize($thumbwidth, $new_height, 0);
  1787. }
  1788. return $temp;
  1789. }
  1790. /**
  1791. * Gets the current user image
  1792. * @param string user id
  1793. * @param string picture user name
  1794. * @param string height
  1795. * @param string picture size it can be small_, medium_ or big_
  1796. * @param string style css
  1797. * @return array with the file and the style of an image i.e $array['file'] $array['style']
  1798. */
  1799. public static function get_picture_user($user_id, $picture_file, $height, $size_picture = 'medium_', $style = '') {
  1800. $patch_profile = 'upload/users/';
  1801. $picture = array();
  1802. $picture['style'] = $style;
  1803. if ($picture_file == 'unknown.jpg') {
  1804. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/'.$picture_file;
  1805. return $picture;
  1806. }
  1807. $image_array_sys = self::get_user_picture_path_by_id($user_id, 'system', false, true);
  1808. $image_array = self::get_user_picture_path_by_id($user_id, 'web', false, true);
  1809. $file = $image_array_sys['dir'].$size_picture.$picture_file;
  1810. if (file_exists($file)) {
  1811. $picture['file'] = $image_array['dir'].$size_picture.$picture_file;
  1812. $picture['style'] = '';
  1813. if ($height > 0) {
  1814. $dimension = api_getimagesize($picture['file']);
  1815. $margin = (($height - $dimension[1]) / 2);
  1816. $picture['style'] = ' style="padding-top:'.$margin.'px; width:'.$dimension[0].'px; height:'.$dimension[1].';" ';
  1817. }
  1818. } else {
  1819. //$file = api_get_path(SYS_CODE_PATH).$patch_profile.$user_id.'/'.$picture_file;
  1820. $file = $image_array_sys['dir'].$picture_file;
  1821. if (file_exists($file)) {
  1822. $picture['file'] = $image_array['dir'].$picture_file;
  1823. } else {
  1824. $picture['file'] = api_get_path(WEB_CODE_PATH).'img/unknown.jpg';
  1825. }
  1826. }
  1827. return $picture;
  1828. }
  1829. /**
  1830. * @author Isaac flores <isaac.flores@dokeos.com>
  1831. * @param string The email administrator
  1832. * @param integer The user id
  1833. * @param string The message title
  1834. * @param string The content message
  1835. */
  1836. public static function send_message_in_outbox($email_administrator, $user_id, $title, $content) {
  1837. $table_message = Database::get_main_table(TABLE_MESSAGE);
  1838. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  1839. $title = api_utf8_decode($title);
  1840. $content = api_utf8_decode($content);
  1841. //message in inbox
  1842. $sql_message_outbox = 'SELECT user_id from '.$table_user.' WHERE email="'.$email_administrator.'" ';
  1843. //$num_row_query = Database::num_rows($sql_message_outbox);
  1844. $res_message_outbox = Database::query($sql_message_outbox, __FILE__, __LINE__);
  1845. $array_users_administrator = array();
  1846. while ($row_message_outbox = Database::fetch_array($res_message_outbox, 'ASSOC')) {
  1847. $array_users_administrator[] = $row_message_outbox['user_id'];
  1848. }
  1849. //allow to insert messages in outbox
  1850. for ($i = 0; $i < count($array_users_administrator); $i++) {
  1851. $sql_insert_outbox = "INSERT INTO $table_message(user_sender_id, user_receiver_id, msg_status, send_date, title, content ) ".
  1852. " VALUES (".
  1853. "'".(int)$user_id."', '".(int)($array_users_administrator[$i])."', '4', '".date('Y-m-d H:i:s')."','".Database::escape_string($title)."','".Database::escape_string($content)."'".
  1854. ")";
  1855. $rs = Database::query($sql_insert_outbox, __FILE__, __LINE__);
  1856. }
  1857. }
  1858. }