user.module

  1. 6.x modules/user/user.module
  2. 4.x modules/user/user.module
  3. 5.x modules/user/user.module

File

modules/user/user.module
View source
  1. <?php
  2. /**
  3. * Implementation of hook_menu
  4. */
  5. function user_menu() {
  6. $items = array();
  7. // This one will appear in our admin menu
  8. $items["admin/config/users"] = array(
  9. "title" => "Users",
  10. "description" => "Search and manage FlightPath users",
  11. "page_callback" => "user_subtab_switchboard",
  12. "access_arguments" => array("manage_users"),
  13. "type" => MENU_TYPE_NORMAL_ITEM,
  14. "tab_parent" => "admin-tools/admin",
  15. "page_settings" => array(
  16. "menu_icon" => fp_get_module_path('user') . "/icons/group.png",
  17. ),
  18. );
  19. // Subtab for which type of user we want to work on.
  20. $items["admin/users/faculty"] = array(
  21. "title" => "Faculty / Staff Users",
  22. "description" => "Search and manage faculty/staff users",
  23. "page_callback" => "user_display_users",
  24. "access_arguments" => array("manage_users"),
  25. "page_settings" => array(
  26. "page_hide_report_error" => TRUE,
  27. "menu_links" => array(
  28. 0 => array(
  29. "text" => "Admin Console",
  30. "path" => "admin-tools/admin",
  31. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  32. ),
  33. ),
  34. ),
  35. "type" => MENU_TYPE_SUB_TAB,
  36. "tab_family" => "users",
  37. "tab_parent" => "admin-tools/admin",
  38. "weight" => 100,
  39. );
  40. $items["admin/users/students"] = array(
  41. "title" => "Student Users",
  42. "page_callback" => "user_display_student_users",
  43. "access_arguments" => array("manage_users"),
  44. "page_settings" => array(
  45. "page_hide_report_error" => TRUE,
  46. "menu_links" => array(
  47. 0 => array(
  48. "text" => "Admin Console",
  49. "path" => "admin-tools/admin",
  50. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  51. ),
  52. ),
  53. ),
  54. "type" => MENU_TYPE_SUB_TAB,
  55. "tab_family" => "users",
  56. "tab_parent" => "admin-tools/admin",
  57. "file" => menu_get_module_path("user") . "/user.student.inc",
  58. 'weight' => 110,
  59. );
  60. $items["admin/config/user-roles"] = array(
  61. "title" => "User roles",
  62. "description" => "Manage roles for users. Ex: advisors, viewers, etc.",
  63. "page_callback" => "fp_render_form",
  64. "page_arguments" => array("user_user_roles_form"),
  65. "access_arguments" => array("can_edit_user_roles"),
  66. "page_settings" => array(
  67. "menu_icon" => fp_get_module_path('user') . "/icons/medal_gold_1.png",
  68. "page_hide_report_error" => TRUE,
  69. "menu_links" => array(
  70. 0 => array(
  71. "text" => "Admin Console",
  72. "path" => "admin-tools/admin",
  73. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  74. ),
  75. ),
  76. ),
  77. "type" => MENU_TYPE_NORMAL_ITEM,
  78. "tab_parent" => "admin-tools/admin",
  79. );
  80. $items["admin/users/edit-user"] = array(
  81. "title" => "Edit Faculty/Staff User",
  82. "page_callback" => "fp_render_form",
  83. "page_arguments" => array("user_edit_user_form"),
  84. "access_arguments" => array("manage_users"),
  85. "page_settings" => array(
  86. "page_hide_report_error" => TRUE,
  87. "menu_links" => array(
  88. 0 => array(
  89. "text" => "Admin Console",
  90. "path" => "admin-tools/admin",
  91. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  92. ),
  93. 1 => array(
  94. "text" => "Back to Users list",
  95. "path" => "admin/users/faculty",
  96. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  97. ),
  98. ),
  99. ),
  100. "type" => MENU_TYPE_NORMAL_ITEM,
  101. "tab_parent" => "admin-tools/admin",
  102. );
  103. $items["admin/users/edit-user/advisees"] = array(
  104. "title" => "Edit Faculty/Staff User Advisees",
  105. "page_callback" => "fp_render_form",
  106. "page_arguments" => array("user_edit_user_advisees_form"),
  107. "access_arguments" => array("manage_users"),
  108. "page_settings" => array(
  109. "page_hide_report_error" => TRUE,
  110. "menu_links" => array(
  111. 0 => array(
  112. "text" => "Admin Console",
  113. "path" => "admin-tools/admin",
  114. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  115. ),
  116. 1 => array(
  117. "text" => "Back to Users list",
  118. "path" => "admin/users/faculty",
  119. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  120. ),
  121. ),
  122. ),
  123. "type" => MENU_TYPE_NORMAL_ITEM,
  124. "tab_parent" => "admin-tools/admin",
  125. );
  126. $items["admin/users/edit-student-user"] = array(
  127. "title" => "Edit Student",
  128. "page_callback" => "fp_render_form",
  129. "page_arguments" => array("user_edit_student_user_form"),
  130. "access_arguments" => array("manage_users"),
  131. "page_settings" => array(
  132. "page_hide_report_error" => TRUE,
  133. "menu_links" => array(
  134. 0 => array(
  135. "text" => "Admin Console",
  136. "path" => "admin-tools/admin",
  137. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  138. ),
  139. 1 => array(
  140. "text" => "Back to Users list",
  141. "path" => "admin/users/students",
  142. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  143. ),
  144. ),
  145. ),
  146. "type" => MENU_TYPE_NORMAL_ITEM,
  147. "tab_parent" => "admin-tools/admin",
  148. "file" => menu_get_module_path("user") . "/user.student.inc",
  149. );
  150. $items["admin/users/edit-student-user/courses"] = array(
  151. "title" => "Edit Student Courses",
  152. "page_callback" => "fp_render_form",
  153. "page_arguments" => array("user_student_edit_student_courses_form"),
  154. "access_arguments" => array("manage_users"),
  155. "page_settings" => array(
  156. "page_hide_report_error" => TRUE,
  157. "menu_links" => array(
  158. 0 => array(
  159. "text" => "Admin Console",
  160. "path" => "admin-tools/admin",
  161. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  162. ),
  163. 1 => array(
  164. "text" => "Back to Users list",
  165. "path" => "admin/users/students",
  166. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  167. ),
  168. ),
  169. ),
  170. "type" => MENU_TYPE_CALLBACK,
  171. "tab_parent" => "admin-tools/admin",
  172. "file" => menu_get_module_path("user") . "/user.student.inc",
  173. );
  174. // For students...
  175. $items["admin/users/edit-student-user/attributes"] = array(
  176. "title" => "Edit User Attributes",
  177. "page_callback" => "fp_render_form",
  178. "page_arguments" => array("user_edit_user_attributes_form"),
  179. "access_arguments" => array("manage_users"),
  180. "page_settings" => array(
  181. "page_hide_report_error" => TRUE,
  182. "menu_links" => array(
  183. 0 => array(
  184. "text" => "Admin Console",
  185. "path" => "admin-tools/admin",
  186. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  187. ),
  188. 1 => array(
  189. "text" => "Back to Users list",
  190. "path" => "admin/users/students",
  191. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  192. ),
  193. ),
  194. ),
  195. "type" => MENU_TYPE_CALLBACK,
  196. "tab_parent" => "admin-tools/admin",
  197. );
  198. // For faculty, but we are going to copy the entry for students and only change what
  199. // we need to.
  200. $items["admin/users/edit-user/attributes"] = $items["admin/users/edit-student-user/attributes"];
  201. $items["admin/users/edit-user/attributes"]['page_settings']['menu_links'][1]['path'] = 'admin/users/faculty';
  202. $items["admin/config/permissions"] = array(
  203. "title" => "Permissions",
  204. "description" => "Manage permissions for user roles in FlightPath",
  205. "page_callback" => "fp_render_form",
  206. "page_arguments" => array("user_permissions_form"),
  207. "access_arguments" => array("can_edit_permissions"),
  208. "page_settings" => array(
  209. "menu_icon" => fp_get_module_path('user') . "/icons/key.png",
  210. "page_hide_report_error" => TRUE,
  211. "menu_links" => array(
  212. 0 => array(
  213. "text" => "Admin Console",
  214. "path" => "admin-tools/admin",
  215. "query" => "de_catalog_year=%DE_CATALOG_YEAR%",
  216. ),
  217. ),
  218. ),
  219. "type" => MENU_TYPE_NORMAL_ITEM,
  220. "tab_parent" => "admin-tools/admin",
  221. );
  222. $items["user-settings"] = array(
  223. "title" => t("User Settings"),
  224. "page_callback" => "fp_render_form",
  225. "page_arguments" => array('user_user_settings_form'),
  226. "access_arguments" => array("access_logged_in_content"),
  227. "type" => MENU_TYPE_TAB,
  228. "tab_family" => "user_settings",
  229. "weight" => 0,
  230. );
  231. $items["user/%/edit-attribute/%"] = array(
  232. "title" => "Edit Attribute",
  233. "page_callback" => "fp_render_form",
  234. "page_arguments" => array("user_edit_attribute_form", "", 1, 3),
  235. "access_callback" => TRUE, // TODO: set to something else
  236. "page_settings" => array(
  237. "page_hide_report_error" => TRUE,
  238. ),
  239. );
  240. return $items;
  241. }
  242. function user_edit_user_attributes_form() {
  243. $form = array();
  244. $user_id = intval($_REQUEST['user_id']);
  245. $student_cwid = @strip_tags($_REQUEST["student_cwid"]); // now getting it from argument
  246. $faculty_cwid = @strip_tags($_REQUEST["faculty_cwid"]); // now getting it from argument
  247. $de_catalog_year = @strip_tags($_REQUEST["de_catalog_year"]);
  248. $user_type = strip_tags($_REQUEST['user_type']);
  249. $attributes = user_get_registered_attributes();
  250. $account = fp_load_user($user_id);
  251. fp_set_title(t("Edit User Attributes @name", array("@name" => "$account->f_name $account->l_name ($account->cwid)")));
  252. $form['user_id'] = array(
  253. 'type' => 'hidden',
  254. 'value' => $user_id,
  255. );
  256. // Set up sub tabs.
  257. $tab_array = array();
  258. // Figure out what the page's sub-tabs should be, and set them.
  259. if ($student_cwid != '') {
  260. $tab_array[0]["title"] = t("Edit Student");
  261. $tab_array[0]["active"] = FALSE;
  262. $tab_array[0]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-student-user", "student_cwid=$student_cwid&de_catalog_year=$de_catalog_year") . "\"";
  263. $tab_array[1]["title"] = t("Edit Student Courses");
  264. $tab_array[1]["active"] = FALSE;
  265. $tab_array[1]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-student-user/courses", "student_cwid=$student_cwid&de_catalog_year=$de_catalog_year") . "\"";
  266. $tab_array[2]["title"] = t("Edit User Attributes");
  267. $tab_array[2]["active"] = TRUE;
  268. $tab_array[2]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/attributes", "user_id=$user_id&user_type=$user_type&student_cwid=$student_cwid&de_catalog_year=$de_catalog_year") . "\"";
  269. }
  270. else if ($faculty_cwid != '') {
  271. $tab_array = array();
  272. $tab_array[0]["title"] = t("Edit Faculty/Staff User");
  273. $tab_array[0]["active"] = TRUE;
  274. $tab_array[0]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  275. $tab_array[1]["title"] = t("Edit Faculty Advisees");
  276. $tab_array[1]["active"] = FALSE;
  277. $tab_array[1]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/advisees", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  278. $tab_array[2]["title"] = t("Edit User Attributes");
  279. $tab_array[2]["active"] = TRUE;
  280. $tab_array[2]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/attributes", "user_id=$user_id&user_type=$user_type&faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  281. }
  282. fp_set_page_sub_tabs($tab_array);
  283. $form['mark_top'] = array(
  284. 'value' => '<p>' . t("The following attributes are available to view/edit, depending on your permission level.") . "</p>",
  285. );
  286. $bool_something_to_edit = FALSE;
  287. foreach ($attributes as $name => $definition) {
  288. if (!isset($attributes[$name]['fields'])) {
  289. // Create a "default" field of "value" that's a simple textfield.
  290. $attributes[$name]['fields']['value'] = array(
  291. 'label' => $attributes[$name]['title'],
  292. 'type' => 'textfield',
  293. );
  294. }
  295. foreach($attributes[$name]["fields"] as $field_name => $field_details) {
  296. $ofield_name = $field_name;
  297. $field_name = $name . "__" . $field_name;
  298. if (isset($attributes[$name]['settings']['#validate_handlers'])) {
  299. $form['#validate_handlers'] += $attributes[$name]['settings']['#validate_handlers'];
  300. }
  301. if (isset($attributes[$name]['settings']['#submit_handlers'])) {
  302. $form['#submit_handlers'] += $attributes[$name]['settings']['#submit_handlers'];
  303. }
  304. // Any js or css to add for this form, defined in the settings?
  305. if (isset($attributes[$name]['settings']['js'])) {
  306. fp_add_js($attributes[$name]['settings']['js']);
  307. }
  308. if (isset($attributes[$name]['settings']['css'])) {
  309. fp_add_css($attributes[$name]['settings']['css']);
  310. }
  311. if (user_has_permission("edit_attribute_$name")) {
  312. // We may edit
  313. $form[$field_name] = $field_details;
  314. $form[$field_name]['prefix'] = "<h3>" . $definition['title'] . "</h3>" . $form[$field_name]['prefix'];
  315. $form[$field_name]['suffix'] .= "<hr>";
  316. // Set the value properly...
  317. if ($field_details['type'] != 'cfieldset') {
  318. $value = user_get_attribute($user_id, $field_name, '');
  319. $form[$field_name]['value'] = $value;
  320. // If this is a datetime-local field, then the value needs to be adjusted for it to work correctly. (it was stored as UTC in database)
  321. if ($form[$field_name]['type'] == 'datetime-local') {
  322. if (trim($value) != '') {
  323. $form[$field_name]["value"] = date('Y-m-d\TH:i', convert_time(strtotime($value)));
  324. }
  325. }
  326. // Similar to datetime-local, if this is a "time" field, then it has been stored as UTC in the database, and now
  327. // needs to be converted to local timezone.
  328. if ($form[$field_name]['type'] == 'time') {
  329. if (trim($value) != '') {
  330. $form[$field_name]["value"] = date('H:i', convert_time(strtotime($value)));
  331. }
  332. }
  333. } // is not cfieldset
  334. else {
  335. // If this is a fieldset, then we need to assign values to its ELEMENTS. If not empty, then OPEN the cfieldset!
  336. foreach ($form[$field_name]['elements'] as $c => $efields) {
  337. foreach ($efields as $efield_name => $efield_details) {
  338. $value = user_get_attribute($user_id, $field_name, '');
  339. $efield_details['value'] = $value;
  340. // If this is a datetime-local field, then the value needs to be adjusted for it to work correctly.
  341. if ($efield_details['type'] == 'datetime-local') {
  342. if (trim($value) != '') {
  343. $value = date('Y-m-d\TH:i', convert_time(strtotime($value)));
  344. }
  345. }
  346. // Similar to datetime-local, if this is a "time" field, then it has been stored as UTC in the database, and now
  347. // needs to be converted to local timezone.
  348. if ($efield_details['type'] == 'time') {
  349. if (trim($value) != '') {
  350. $value = date('H:i', convert_time(strtotime($value)));
  351. }
  352. }
  353. $form[$field_name]['elements'][$c][$efield_name]["value"] = $value;
  354. if (trim($value)) {
  355. $form[$field_name]['start_closed'] = FALSE;
  356. }
  357. }
  358. }
  359. } // else is fieldset
  360. $bool_something_to_edit = TRUE;
  361. }
  362. else if (user_has_permission("view_attribute_$name")) {
  363. // We may only view
  364. $value = user_get_attribute($user_id, $field_name, '');
  365. $display_value = filter_markup($value, 'plain');
  366. // Is there any special way this value is meant to be displayed?
  367. // Ex: if its a date field, should we change how that gets displayed?
  368. invoke_hook("alter_user_attribute_display", array($field_name, &$display_value));
  369. if (isset($definition['fields'][$field_name]['options'][$value])) {
  370. $display_value = $definition['fields'][$field_name]['options'][$value];
  371. }
  372. $html = "";
  373. $html_val = "";
  374. $details = array();
  375. if (isset($definition['display'][$ofield_name])) {
  376. $details = $definition['display'][$ofield_name];
  377. }
  378. $html .= "<h3>" . $definition['title'] . "</h3>";
  379. $html .= "<strong>" . @$details['label'] . "</strong> ";
  380. $html .= "<span class='attrib-val'>";
  381. $html_val .= @$details['value'];
  382. $html_val = str_replace("@value", $display_value, $html_val);
  383. $html_val = str_replace("@key", $value, $html_val);
  384. if (trim($html_val) == "") {
  385. $html_val .= $display_value; // meaning, it's empty.
  386. }
  387. $html .= "$html_val</span><hr>";
  388. $form["mark_$field_name"] = array(
  389. 'value' => $html,
  390. );
  391. }
  392. }
  393. } // foreach attributes
  394. if ($bool_something_to_edit) {
  395. $form['submit_btn'] = array(
  396. 'type' => 'submit',
  397. 'value' => 'Submit',
  398. 'weight' => 9990,
  399. );
  400. }
  401. return $form;
  402. } // end function
  403. function user_edit_user_attributes_form_submit($form, $form_state) {
  404. $values = $form_state['values'];
  405. $user_id = intval($values['user_id']);
  406. $attributes = user_get_registered_attributes();
  407. foreach ($attributes as $name => $definition) {
  408. if (!isset($attributes[$name]['fields'])) {
  409. // Create a "default" field of "value" that's a simple textfield.
  410. $attributes[$name]['fields']['value'] = array(
  411. 'label' => $attributes[$name]['title'],
  412. 'type' => 'textfield',
  413. );
  414. }
  415. foreach ($attributes[$name]['fields'] as $attr_key => $details) {
  416. $fieldname = $name . "__" . $attr_key;
  417. if (user_has_permission("edit_attribute_" . $name)) {
  418. $val = @trim($values[$fieldname]);
  419. user_set_attribute($user_id, $fieldname, $val);
  420. };
  421. }
  422. }
  423. fp_add_message(t("User attributes have been updated successfully."));
  424. } // ... submit
  425. /**
  426. * Implements hook_alter_student_profile_items
  427. *
  428. * We want to see if any modules have registered attributes which are visible or editible in the student profile box.
  429. */
  430. function user_alter_student_profile_items($bool_mini, &$extra_profile_items, $bool_balance = TRUE, $alt_section = "") {
  431. global $current_student_id;
  432. $user_id = db_get_user_id_from_cwid($current_student_id, 'student');
  433. $attributes = user_get_registered_attributes();
  434. if (count($attributes) === 0) return; // nothing to do.
  435. foreach ($attributes as $attr => $definition) {
  436. if ($alt_section != "" && @$definition['settings']['alt_section'] != $alt_section) continue;
  437. if (!isset($definition['display'])) {
  438. // No display set, so create a "default" one that just uses the title of the attribute
  439. $definition['display']['value'] = array(
  440. 'label' => $definition['title'],
  441. );
  442. }
  443. foreach ($definition['display'] as $attr_key => $details) {
  444. $value = user_get_attribute($user_id, $attr . "__" . $attr_key, '');
  445. $display_value = filter_markup($value, 'plain');
  446. // Is there any special way this value is meant to be displayed?
  447. // Ex: if its a date field, should we change how that gets displayed?
  448. invoke_hook("alter_user_attribute_display", array($attr . '__' . $attr_key, &$display_value));
  449. // If this attribute had "options", like radios or select, then use THAT value. Doesn't work with select lists that
  450. // make use of optgroups.
  451. if (isset($definition['fields'][$attr_key]['options'][$value])) {
  452. $display_value = $definition['fields'][$attr_key]['options'][$value];
  453. }
  454. $item = array();
  455. $item['label'] = $details['label'];
  456. $item['content'] = (isset($details['value']) == TRUE) ? $details['value'] : '';
  457. $item['content'] = str_replace("@value", $display_value, $item['content']);
  458. $item['content'] = str_replace("@key", $value, $item['content']);
  459. if (trim($item['content']) == "") $item['content'] = $display_value;
  460. $bool_add_it = FALSE;
  461. $bool_added_edit = FALSE;
  462. $edit_link = "";
  463. $url = fp_url("user/$user_id/edit-attribute/$attr", "window_mode=popup");
  464. $title = t("Edit ") . $definition['title'];
  465. $title = htmlentities($title, ENT_QUOTES);
  466. if (user_has_permission("edit_attribute_$attr")) {
  467. $edit_link = "<a class='user-edit-attribute-link' href='javascript:fpOpenSmallIframeDialog(\"$url\", \"$title\");'><i class='fa fa-pencil'></i></a>";
  468. }
  469. if (!$bool_mini) {
  470. if ($definition['settings']['large_profile']) {
  471. // We are on the large profile, and this element shoudl show on the large profile.
  472. $bool_add_it = TRUE;
  473. } // large_profile
  474. if ($definition['settings']['large_profile_editable']) {
  475. $bool_add_it = TRUE;
  476. // Display link to edit this attribute.
  477. $item['content'] .= $edit_link;
  478. $bool_added_edit = TRUE;
  479. }
  480. } // if NOT mini
  481. else if ($bool_mini) {
  482. // This IS mini
  483. if ($definition['settings']['mini_profile']) {
  484. // We are on the large profile, and this element should show on the mini profile.
  485. $bool_add_it = TRUE;
  486. }
  487. if ($definition['settings']['mini_profile_editable']) {
  488. // We are on the large profile, and this element should show on the mini profile.
  489. $bool_add_it = TRUE;
  490. $item['content'] .= $edit_link;
  491. $bool_added_edit = TRUE;
  492. }
  493. } // else is mini
  494. if ($alt_section != "" && isset($definition['settings']['alt_section'])) {
  495. // Are we adding to some alt_section? Is it editable?
  496. if ($definition['settings']['alt_section'] == $alt_section) {
  497. // We are defined some alt section
  498. $bool_add_it = TRUE;
  499. }
  500. if (@$definition['settings']['alt_editable'] && $bool_added_edit == FALSE) {
  501. // We are on the large profile, and this element should show on the mini profile.
  502. $bool_add_it = TRUE;
  503. $item['content'] .= $edit_link;
  504. $bool_added_edit = TRUE;
  505. }
  506. }
  507. } // foreach
  508. if ($bool_add_it && $bool_balance) {
  509. // permission check as to whether it can be viewed at all
  510. if (user_has_permission("view_attribute_$attr")) {
  511. fp_push_and_balance_profile_items($extra_profile_items, array($attr . "__" . $attr_key => $item));
  512. }
  513. }
  514. else if ($bool_add_it) {
  515. $extra_profile_items[$attr . '__' . $attr_key] = $item;
  516. }
  517. } // foreach attributes
  518. } // hook alter_student_profile_items
  519. /**
  520. * invokes the right hook to return back all the "registered" attributes from other modules.
  521. */
  522. function user_get_registered_attributes() {
  523. $rtn = array();
  524. // Save effort by saving to a globals cache.
  525. if (isset($GLOBALS['user_registered_attributes_cache'])) {
  526. return $GLOBALS['user_registered_attributes_cache'];
  527. }
  528. $modules = modules_implement_hook("user_register_user_attributes");
  529. foreach($modules as $module) {
  530. $types = call_user_func($module . '_user_register_user_attributes');
  531. $rtn += $types;
  532. }
  533. $GLOBALS['user_registered_attributes_cache'] = $rtn;
  534. return $rtn;
  535. } // user_get_registered_attributes
  536. /**
  537. * The form which lets us actually edit this user's attribute (ex: Visa Status)
  538. * Meant to be very similar to:
  539. * @see content_edit_content_form()
  540. */
  541. function user_edit_attribute_form($user_id = 0, $attribute_name = "") {
  542. $form = array();
  543. if ($user_id === 0) {
  544. fp_add_message(t("Could not find user."), 'error');
  545. return;
  546. }
  547. $account = fp_load_user($user_id);
  548. if (isset($_GET['tabs']) && $_GET['tabs'] === 'false') { // the string "false", not FALSE
  549. fp_add_body_class('user-tabs-false');
  550. }
  551. fp_add_css(fp_get_module_path("user") . "/css/user.css");
  552. fp_add_js(fp_get_module_path("user") . "/js/user.js");
  553. $attributes = user_get_registered_attributes();
  554. $name = $attribute_name;
  555. $title = $attributes[$name]['title'];
  556. fp_set_title(t("Edit %title for @name", array("%title" => $title, "@name" => "$account->f_name $account->l_name ($account->cwid)")));
  557. if ($_REQUEST['window_mode'] == 'popup') {
  558. $form['mark_top'] = array(
  559. 'value' => '<h2>' . t("Edit %title for @name", array("%title" => $title, "@name" => "$account->f_name $account->l_name ($account->cwid)")) . "</h2>",
  560. );
  561. }
  562. fp_add_body_class('user-edit-attributes--' . $name);
  563. // For simplicity, and because it causes no harm except a small amount of extra bandwidth, we will
  564. // state that all "attribute" forms are multipart (so they can handle file uploads) even if there
  565. // are no files being uploaded.
  566. $form["#attributes"] = array("enctype" => 'multipart/form-data');
  567. $form["attribute_name"] = array(
  568. "type" => "hidden",
  569. "value" => $name,
  570. );
  571. $form["user_id"] = array(
  572. "type" => "hidden",
  573. "value" => $account->id,
  574. );
  575. if (isset($attributes[$name]['settings']['#redirect'])) {
  576. $form['#redirect'] = $attributes[$name]['settings']['#redirect'];
  577. }
  578. if (isset($attributes[$name]['settings']['#validate_handlers'])) {
  579. $form['#validate_handlers'] = $attributes[$name]['settings']['#validate_handlers'];
  580. }
  581. if (isset($attributes[$name]['settings']['#submit_handlers'])) {
  582. $form['#submit_handlers'] = $attributes[$name]['settings']['#submit_handlers'];
  583. }
  584. // If a #redirect has not been set, then we'll go back to this user's attribute edit page...
  585. if (!isset($form['#redirect'])) {
  586. //$form['#redirect'] = array('path' => 'content/' . $cid);
  587. // TODO: go to user's attribute edit page.
  588. }
  589. // Any js or css to add for this form, defined in the settings?
  590. if (isset($attributes[$name]['settings']['js'])) {
  591. fp_add_js($attributes[$name]['settings']['js']);
  592. }
  593. if (isset($attributes[$name]['settings']['css'])) {
  594. fp_add_css($attributes[$name]['settings']['css']);
  595. }
  596. if (!isset($attributes[$name]['fields'])) {
  597. // Create a "default" field of "value" that's a simple textfield.
  598. $attributes[$name]['fields']['value'] = array(
  599. 'label' => $attributes[$name]['title'],
  600. 'type' => 'textfield',
  601. );
  602. }
  603. // Show the fields.
  604. if (isset($attributes[$name]['fields'])) {
  605. foreach($attributes[$name]["fields"] as $field_name => $field_details) {
  606. $field_name = $name . "__" . $field_name;
  607. $form[$field_name] = $field_details;
  608. if ($field_details['type'] != 'cfieldset') {
  609. $value = user_get_attribute($user_id, $field_name, '');
  610. $form[$field_name]['value'] = $value;
  611. // If this is a datetime-local field, then the value needs to be adjusted for it to work correctly. (it was stored as UTC in database)
  612. if ($form[$field_name]['type'] == 'datetime-local') {
  613. if (trim($value) != '') {
  614. $form[$field_name]["value"] = date('Y-m-d\TH:i', convert_time(strtotime($value)));
  615. }
  616. }
  617. // Similar to datetime-local, if this is a "time" field, then it has been stored as UTC in the database, and now
  618. // needs to be converted to local timezone.
  619. if ($form[$field_name]['type'] == 'time') {
  620. if (trim($value) != '') {
  621. $form[$field_name]["value"] = date('H:i', convert_time(strtotime($value)));
  622. }
  623. }
  624. } // is not cfieldset
  625. else {
  626. // If this is a fieldset, then we need to assign values to its ELEMENTS. If not empty, then OPEN the cfieldset!
  627. foreach ($form[$field_name]['elements'] as $c => $efields) {
  628. foreach ($efields as $efield_name => $efield_details) {
  629. $value = user_get_attribute($user_id, $field_name, '');
  630. $efield_details['value'] = $value;
  631. // If this is a datetime-local field, then the value needs to be adjusted for it to work correctly.
  632. if ($efield_details['type'] == 'datetime-local') {
  633. if (trim($value) != '') {
  634. $value = date('Y-m-d\TH:i', convert_time(strtotime($value)));
  635. }
  636. }
  637. // Similar to datetime-local, if this is a "time" field, then it has been stored as UTC in the database, and now
  638. // needs to be converted to local timezone.
  639. if ($efield_details['type'] == 'time') {
  640. if (trim($value) != '') {
  641. $value = date('H:i', convert_time(strtotime($value)));
  642. }
  643. }
  644. $form[$field_name]['elements'][$c][$efield_name]["value"] = $value;
  645. if (trim($value)) {
  646. $form[$field_name]['start_closed'] = FALSE;
  647. }
  648. }
  649. }
  650. } // else is fieldset
  651. } // foreach
  652. } // if isset
  653. // Draw the controls (buttons)
  654. $form["submit_submit"] = array(
  655. "type" => "submit",
  656. "value" => t("Submit"),
  657. "spinner" => TRUE,
  658. 'weight' => 9920,
  659. 'attributes' => array('class' => 'user-attribute-submit-btn'),
  660. );
  661. watchdog('user', "edit_attribute_form user_id:$user_id name:$name", array(), WATCHDOG_DEBUG);
  662. return $form;
  663. } // user_edit_attribute_form
  664. function user_edit_attribute_form_submit($form, $form_state) {
  665. $values = $form_state['values'];
  666. $name = $values['attribute_name'];
  667. $user_id = intval($values['user_id']);
  668. // Find and save the values from the form....
  669. foreach ($values as $key => $val) {
  670. if (str_starts_with($key, $name . "__")) {
  671. user_set_attribute($user_id, $key, $val);
  672. }
  673. }
  674. fp_add_message(t("User attributes have been updated successfully."));
  675. } // ..._submit
  676. /**
  677. * This is the main settings form for a user.
  678. */
  679. function user_user_settings_form() {
  680. global $user;
  681. $form = array();
  682. fp_add_css(fp_get_module_path("user") . "/css/user.css");
  683. fp_set_title($user->f_name . " " . $user->l_name . " (" . $user->cwid . ")");
  684. $html = "";
  685. $image_url = @$user->settings['image_url'];
  686. // if faculty, display things like email and such which we have in the database.
  687. if ($user->is_faculty) {
  688. $html .= "<div class='user-profile-markup-faculty'>";
  689. if ($image_url) {
  690. $html .= "<span class='small-profile-image'>
  691. <img src='$image_url'>
  692. </span>";
  693. }
  694. $html .= " <div class='profile-item'><strong>" . t("Email:") . "</strong> $user->email</div>
  695. <div class='profile-item'><strong>" . t("Roles:") . "</strong>
  696. ";
  697. foreach ($user->roles as $role) {
  698. $html .= "" . $role . ", ";
  699. }
  700. $html = rtrim($html, ', ');
  701. $html .= "</div>";
  702. $html .= "</div>"; // user-profile-markup-faculty
  703. }
  704. $form['mark_top'] = array(
  705. 'type' => 'markup',
  706. 'value' => $html,
  707. );
  708. $form['mark_clear'] = array(
  709. 'type' => 'markup',
  710. 'value' => "<div class='clear'></div>",
  711. );
  712. // Are we allowed to change our password?
  713. if (user_has_permission('change_own_password')) {
  714. if (!isset($_SESSION['fp_logged_in_external']) || $_SESSION['fp_logged_in_external'] === FALSE) {
  715. $form['current_password'] = array(
  716. 'label' => t("Current password"),
  717. 'type' => 'password',
  718. 'description' => t('If you wish to change your password, enter your current password here, then your new password below.'),
  719. );
  720. $form['new_password1'] = array(
  721. 'label' => t("New password"),
  722. 'type' => 'password',
  723. );
  724. $form['new_password2'] = array(
  725. 'label' => t("New password (re-enter)"),
  726. 'type' => 'password',
  727. 'suffix' => '<hr>',
  728. );
  729. }
  730. else if (isset($_SESSION['fp_logged_in_external']) && $_SESSION['fp_logged_in_external'] === TRUE) {
  731. $form['mark_external_login'] = array(
  732. 'type' => 'markup',
  733. 'value' => "<fieldset><legend>" . t("Password Change") . "</legend>" . t("<b>Note:</b> You logged in using an external service. Therefore, you cannot change your FlightPath password from here.
  734. Please inquire with your IT department on how to change your password.") . "</strong></fieldset>",
  735. );
  736. }
  737. } // user has perm change_own_password
  738. if (user_has_permission('change_own_image')) {
  739. $form['image_url'] = array(
  740. 'label' => t('Image URL'),
  741. 'type' => 'textfield',
  742. 'value' => @$user->settings['image_url'],
  743. 'description' => t('Enter the full URL/URI to your profile image. Make sure your
  744. image is in "portrait" orientation, and generally no larger than 20 or 30kb in filesize.
  745. Also make sure that the originating server is HTTPS and not HTTP.'),
  746. 'suffix' => '<hr>',
  747. );
  748. } // user has permission to change their image
  749. $system_timezone = variable_get('system_timezone', 'America/Chicago');
  750. $form['timezone'] = array(
  751. 'label' => t('Your timezone (if not %tz)', array('%tz' => $system_timezone)),
  752. 'type' => 'select',
  753. 'options' => get_timezones(),
  754. 'value' => @$user->settings['timezone'],
  755. 'description' => t("By default, times will be displayed based on the system timezone of %tz. If you wish to override
  756. with your own timezone, please select it here.", array("%tz" => $system_timezone)),
  757. );
  758. $form['hide_charts'] = array(
  759. 'label' => t('Should student pie charts be displayed?'),
  760. 'type' => 'select',
  761. 'options' => array('show' => t('Yes (default)'), 'hide' => t('No, hide pie charts on Degree page')),
  762. 'value' => @$user->settings['hide_charts'],
  763. 'description' => t('If set to No, pie charts will not be visible on student Degree tabs. If you
  764. are unsure what to select, choose "Yes".'),
  765. );
  766. if (user_has_permission('view_any_advising_session')) {
  767. $value = @$user->settings['default_student_load_tab'];
  768. if (!$value || $value == "") {
  769. // No specific setting, so use the system's default setting.
  770. $value = variable_get('system_default_student_load_tab', 'profile');
  771. }
  772. $form['default_student_load_tab'] = array(
  773. 'label' => t('What is the default tab you want to see when you load a new student?'),
  774. 'type' => 'select',
  775. 'hide_please_select' => TRUE,
  776. 'options' => array('profile' => t('Student Profile'), 'engagements' => t("Engagements"), 'degree' => t('Degree')),
  777. 'value' => $value,
  778. 'description' => t('If you are unsure what to select, choose "Student Profile" or leave set to its current setting.'),
  779. );
  780. }
  781. $options = array('email' => t("Email"));
  782. $phone_number = user_get_attribute($user->id, 'mobile_phone', '');
  783. if (variable_get('sms_project_id', '') != '' && $phone_number != "") {
  784. $options['txt'] = t("Text Message");
  785. $options['email_txt'] = t("Both email and text message");
  786. }
  787. $form['default_notification_method'] = array(
  788. 'label' => t('Default notification method for important events'),
  789. 'type' => 'select',
  790. 'hide_please_select' => TRUE,
  791. 'options' => $options,
  792. 'value' => @$user->settings['default_notification_method'],
  793. 'description' => t('These would be notifications sent out by FlightPath. For example, when you schedule an appointment or to send out a reminder.
  794. If you are unsure what to select, choose "Email".'),
  795. );
  796. if ($phone_number) {
  797. $phone_number = engagements_convert_to_valid_phone_number($phone_number);
  798. $form['sms_opt_out__' . $phone_number] = array(
  799. 'label' => t('Opt-out of receiving text messages at %num?', array("%num" => engagements_convert_to_pretty_phone_number($phone_number))),
  800. 'type' => 'select',
  801. 'hide_please_select' => TRUE,
  802. 'options' => array('no' => t('No - Receive text messages normally (default)'), 'yes' => t('Yes - Opt-out, and do not receive text messages from @flightpath', array("@flightpath", variable_get("system_name", "FlightPath")))),
  803. 'value' => @$user->settings['sms_opt_out__' . $phone_number],
  804. 'description' => t('This setting controls whether you wish to completely opt-out of receiving text messages on your phone. If set to "Yes", then your default notification method
  805. above will automatically be set to "Email" only. If unsure what to select, choose "No".'),
  806. );
  807. }
  808. $form['submit_btn'] = array(
  809. 'type' => 'submit',
  810. 'value' => 'Save',
  811. );
  812. return $form;
  813. } // user_user_settings_form
  814. /**
  815. * Needed if we are trying to change password.
  816. */
  817. function user_user_settings_form_validate($form, $form_state) {
  818. global $user;
  819. $values = $form_state['values'];
  820. $current_password = $values['current_password'];
  821. $new_password1 = $values['new_password1'];
  822. $new_password2 = $values['new_password2'];
  823. if ($new_password1 != "" || $new_password2 != "") {
  824. if ($new_password1 !== $new_password2) {
  825. form_error('new_password1', t("Sorry, the passwords you entered do not match. Please check your spelling and try again."));
  826. return;
  827. }
  828. // Did we get the current password right?
  829. $res = db_query("SELECT * FROM users WHERE user_id = ? ", $user->id);
  830. $cur = db_fetch_array($res);
  831. // Check the user's password is valid.
  832. $stored_hash = @$cur["password"];
  833. if (!user_check_password($current_password, $stored_hash)) {
  834. form_error("current_password", t("Sorry, but the current password you entered is not correct. Please check your spelling and try again."));
  835. return;
  836. }
  837. }
  838. // If we got to here, we're good to proceed. Other modules might decide to add their own validate function,
  839. // to check for password complexity. They'd do this by adding to the validate_handlers in hook_form_alter.
  840. }
  841. /**
  842. * Save values from our settings form into the user_settings table (or other tables), as appropriate.
  843. */
  844. function user_user_settings_form_submit($form, $form_state) {
  845. global $user;
  846. $timezone = $form_state['values']['timezone'];
  847. $hide_charts = $form_state['values']['hide_charts'];
  848. $image_url = $form_state['values']['image_url'];
  849. $default_student_load_tab = $form_state['values']['default_student_load_tab'];
  850. $default_notification_method = $form_state['values']['default_notification_method'];
  851. $phone_number = user_get_attribute($user->id, 'mobile_phone', '');
  852. $phone_number = engagements_convert_to_valid_phone_number($phone_number);
  853. $sms_opt_out = $form_state['values']['sms_opt_out__' . $phone_number];
  854. if ($sms_opt_out === 'yes' && $phone_number) {
  855. db_query("DELETE FROM sms_do_not_txt WHERE phone_number = ?", array($phone_number));
  856. db_query("INSERT INTO sms_do_not_txt (user_id, cwid, phone_number, prev_notification_method, updated)
  857. VALUES (?, ?, ?, ?, ?)", array($user->id, $user->cwid, $phone_number, $default_notification_method, time()));
  858. $default_notification_method = 'email';
  859. }
  860. else if ($sms_opt_out === 'no' && $phone_number) {
  861. // Opt back in!
  862. $notification_method = db_result(db_query("SELECT prev_notification_method FROM sms_do_not_txt WHERE phone_number = ?", array($phone_number)));
  863. if ($notification_method) {
  864. $default_notification_method = $notification_method;
  865. }
  866. db_query("DELETE FROM sms_do_not_txt WHERE phone_number = ?", array($phone_number));
  867. }
  868. // are we updating password? (If we made it here, we have already passed validation, and may continue.
  869. $new_password1 = $form_state['values']['new_password1'];
  870. if ($new_password1 != "") {
  871. $new_pass = user_hash_password($new_password1);
  872. db_query("UPDATE users
  873. SET password = ?
  874. WHERE user_id = ? ", array($new_pass, $user->id));
  875. fp_add_message(t("Password has been updated successfully."));
  876. watchdog("user_self_edit", "User with user_id @uid changed password", array("@uid" => $user->id));
  877. }
  878. user_set_setting($user->id, "timezone", $timezone);
  879. user_set_setting($user->id, "hide_charts", $hide_charts);
  880. user_set_setting($user->id, "default_student_load_tab", $default_student_load_tab);
  881. user_set_setting($user->id, "default_notification_method", $default_notification_method);
  882. user_set_setting($user->id, "sms_opt_out__" . $phone_number, $sms_opt_out);
  883. user_set_setting($user->id, "image_url", $image_url);
  884. fp_add_message(t("User settings saved successfully."));
  885. $values = $form_state['values'];
  886. unset($values['new_password1']);
  887. unset($values['new_password2']);
  888. unset($values['current_password']);
  889. watchdog("user_self_edit", "User with user_id @uid updated other values: @other", array("@uid" => $user->id, "@other" => ppm($values, TRUE)));
  890. } // user_settings_form_submit
  891. /**
  892. * Very similar to variable_set
  893. */
  894. function user_set_setting($user_id, $name, $value) {
  895. db_query("REPLACE INTO user_settings (user_id, name, value, updated) VALUES (?, ?, ?, ?)", array($user_id, $name, $value, time()));
  896. }
  897. /**
  898. * Very similar to variable_get
  899. */
  900. function user_get_setting($user_id, $name, $default_value = "") {
  901. $val = db_result(db_query("SELECT value FROM user_settings WHERE user_id = ? AND name = ?", array($user_id, $name)));
  902. if (!$val) {
  903. $val = $default_value;
  904. }
  905. return $val;
  906. }
  907. /**
  908. * Very similar to variable_set
  909. */
  910. function user_set_attribute($user_id, $name, $value) {
  911. db_query("REPLACE INTO user_attributes (user_id, name, value, updated) VALUES (?, ?, ?, ?)", array($user_id, $name, $value, time()));
  912. }
  913. /**
  914. * Very similar to variable_get
  915. */
  916. function user_get_attribute($user_id, $name, $default_value = "") {
  917. $val = db_result(db_query("SELECT value FROM user_attributes WHERE user_id = ? AND name = ?", array($user_id, $name)));
  918. if (!$val) {
  919. $val = $default_value;
  920. }
  921. return $val;
  922. }
  923. /**
  924. * Decide what should happen when we go to "admin/config/users" by itself
  925. */
  926. function user_subtab_switchboard() {
  927. // For now, we will just always go to the faculty section, though this function
  928. // is helpful if that needs to change one day.
  929. $de_catalog_year = admin_get_de_catalog_year();
  930. fp_goto("admin/users/faculty", "de_catalog_year=$de_catalog_year");
  931. }
  932. function user_perm() {
  933. $perms = array(
  934. "can_edit_user_roles" => array(
  935. "title" => t("Edit user roles"),
  936. "description" => t("The user may add/edit/delete user roles in the system."),
  937. ),
  938. "can_edit_permissions" => array(
  939. "title" => t("Edit permissions"),
  940. "description" => t("The user may assign permissions to different roles in the system."),
  941. "admin_restricted" => TRUE, // means only appears for admin (user_id == 1)
  942. ),
  943. "manage_users" => array(
  944. "title" => t("Manage users"),
  945. "description" => t("This is a powerful permission! It allows the user to edit the details
  946. of other users, as well as create users."),
  947. ),
  948. "delete_users" => array(
  949. "title" => t("Delete users"),
  950. "description" => t("This is a powerful permission! It allows the user delete users from the system."),
  951. "admin_restricted" => TRUE, // means only appears for admin (user_id == 1)
  952. ),
  953. "change_own_password" => array(
  954. "title" => t("Change own password?"),
  955. "description" => t("Check this if the user is allowed to change their own password (from their profile page)."),
  956. ),
  957. "change_own_image" => array(
  958. "title" => t("Change own image?"),
  959. "description" => t("This lets the user change their own image URL. In general, leave this disabled if images are programmed to come from another source."),
  960. ),
  961. );
  962. $attributes = user_get_registered_attributes();
  963. foreach ($attributes as $attr => $definition) {
  964. $perms['view_attribute_' . $attr] = array(
  965. 'title' => t("View attribute %attr", array("%attr" => $definition['title'])),
  966. 'description' => t("Check this is the user should be able to view this attribute. (Ex: on student profile page)."),
  967. );
  968. $perms['edit_attribute_' . $attr] = array(
  969. 'title' => t("Edit attribute %attr", array("%attr" => $definition['title'])),
  970. 'description' => t("Check this is the user should be able to edit this attribute. (Ex: on student profile page). You <strong>must</strong> also
  971. select the View permission above for this attribute."),
  972. );
  973. }
  974. return $perms;
  975. }
  976. /**
  977. * This is the permissions form, where users can set which roles have which permissions.
  978. */
  979. function user_permissions_form() {
  980. global $user;
  981. $form = array();
  982. fp_add_css(fp_get_module_path("user") . "/css/user.css");
  983. // Let's get all of our permissions from the permissions table.
  984. $permissions = array();
  985. $res = db_query("SELECT * FROM role_permissions");
  986. while ($cur = db_fetch_array($res)) {
  987. $permissions[$cur["rid"]][] = $cur["perm"];
  988. }
  989. $cb = $m = 1;
  990. $form["mark" . $m++] = array(
  991. "value" => t("Use this form to assign permissions to roles in the system.
  992. These permissions are defined by module."),
  993. );
  994. $roles = array();
  995. $res = db_query("SELECT * FROM roles ORDER BY rid ");
  996. while ($cur = db_fetch_array($res)) {
  997. $roles[$cur["rid"]] = $cur["name"];
  998. }
  999. $col_count = count($roles) + 1;
  1000. $form["mark" . $m++] = array(
  1001. "value" => "<table class='admin-perm-table' width='100%' cellpadding='0' cellspacing='0'>
  1002. ",
  1003. );
  1004. // Go through all of the modules, then call hook_perm for them, to get their permissions.
  1005. $modules = modules_implement_hook("perm");
  1006. $mcount = 0;
  1007. foreach ($modules as $module) {
  1008. $disp_module = $module;
  1009. $disp_module = ucwords(str_replace("_", " ", $disp_module));
  1010. $form["mark" . $m++] = array(
  1011. "value" => "<tr><td colspan='$col_count' class='perm-module-name'>" . $disp_module . " " . t("module") . "</td></tr>",
  1012. );
  1013. if ($mcount == 0) {
  1014. // Draw the headers...
  1015. $form["mark" . $m++] = array(
  1016. "value" => "<tr class='headers'><th class='permission-name-and-desc'>" . t("Permission") . "</th>",
  1017. );
  1018. foreach ($roles as $key => $role) {
  1019. $form["mark" . $m++] = array(
  1020. "value" => "<th class='role-" . fp_get_machine_readable($role) . "')>" . $role . "</th>",
  1021. );
  1022. }
  1023. $form["mark" . $m++] = array(
  1024. "value" => "</tr>",
  1025. );
  1026. // End of headers
  1027. }
  1028. $mcount++;
  1029. $zebra = "even";
  1030. // Let's get all the perms.
  1031. $perms = call_user_func($module . "_perm");
  1032. foreach ($perms as $perm_name => $perm_details) {
  1033. $title = @$perm_details["title"];
  1034. $desc = @$perm_details["description"];
  1035. $extra_desc = "";
  1036. $attributes = array();
  1037. if (isset($perm_details['admin_restricted']) && intval($perm_details['admin_restricted']) === 1 && intval($user->id) !== 1) {
  1038. // This permission is restricted to admin only. Meaning only user_id 1 is allowed to grant it.
  1039. $extra_desc = "<div class='restricted-permissions'>" . t("Sorry, you cannot access this permission.") . "</div>";
  1040. $attributes['disabled'] = 'disabled';
  1041. }
  1042. $zebra = ($zebra == "even") ? "odd" : "even";
  1043. $form["mark" . $m++] = array(
  1044. "value" => "<tr class='perm-cb-row perm-cb-row-$zebra'><td class='perm-details' valign='top'>
  1045. <div class='perm-title' title='$perm_name'>$title</div>
  1046. <div class='perm-desc' title='$perm_name'>$desc</div>
  1047. $extra_desc
  1048. </td>",
  1049. );
  1050. foreach ($roles as $key => $role) {
  1051. // Should this be checked by default (cause it was all ready in our table?)
  1052. $default_value = array();
  1053. if (@is_array($permissions[$key]) && in_array($perm_name, $permissions[$key])) {
  1054. // Yes, it was in there! Set up the default_value as an array that
  1055. // looks like array(key => key). That is how we set a checkbox to be checked
  1056. // by default.
  1057. $default_value = array($key . "___$perm_name" => $key . "___$perm_name");
  1058. }
  1059. $element_name = "perm_cb_" . $cb++;
  1060. if (isset($attributes['disabled'])) {
  1061. $form[$element_name] = array(
  1062. 'type' => 'value',
  1063. 'value' => current($default_value),
  1064. );
  1065. $element_name = "markperm_disabledcb_" . $cb++;
  1066. }
  1067. $form[$element_name] = array(
  1068. "type" => "checkboxes",
  1069. "options" => array("$key" . "___$perm_name" => ""),
  1070. "value" => $default_value,
  1071. "prefix" => "<td class='perm-cb'>",
  1072. "suffix" => "</td>",
  1073. "attributes" => $attributes,
  1074. );
  1075. } // foreach roles
  1076. $form["mark" . $m++] = array(
  1077. "value" => "</tr>",
  1078. );
  1079. } // foreach perms
  1080. } // foreach modules
  1081. $form["mark" . $m++] = array(
  1082. "value" => "</table>",
  1083. );
  1084. $form["submit"] = array(
  1085. "type" => "submit",
  1086. "value" => t("Save permissions"),
  1087. "spinner" => TRUE,
  1088. "prefix" => "<hr>",
  1089. );
  1090. return $form;
  1091. }
  1092. /**
  1093. * Submit handler for the permissions form.
  1094. */
  1095. function user_permissions_form_submit($form, $form_submit) {
  1096. global $user;
  1097. // Get all of the perms, so later we can make sure that we aren't trying to save an admin_restricted one (if we are not admin).
  1098. $perms = invoke_hook("perm");
  1099. $values = $form_submit["values"];
  1100. // Create our temp table. We do this so we don't truncate the production table, since if a hacker is trying
  1101. // to circumvent the admin_restricted status of a permission, it would break the system when we fp_goto the front page.
  1102. db_query("CREATE TEMPORARY TABLE `TEMP_role_permissions` LIKE `role_permissions`");
  1103. // We should begin by truncating our permissions table, then re-inserting
  1104. // everything we get from this submission.
  1105. db_query("TRUNCATE TABLE `TEMP_role_permissions` ");
  1106. // Find all the perm checkboxes.
  1107. foreach($values as $key => $val) {
  1108. if (strstr($key, "perm_cb_")) {
  1109. if (is_array($val)) {
  1110. $cb = current($val);
  1111. }
  1112. else if (trim($val) != "") {
  1113. $cb = trim($val);
  1114. }
  1115. if (strstr($cb, "___")) {
  1116. $temp = explode("___", $cb);
  1117. $rid = $temp[0];
  1118. $perm = $temp[1];
  1119. // Okay, save this to our table.
  1120. db_query("INSERT INTO TEMP_role_permissions (rid, perm)
  1121. VALUES (?, ?) ", $rid, $perm);
  1122. }
  1123. }
  1124. }
  1125. // Copy everything from temp table to production table...
  1126. db_query("TRUNCATE role_permissions");
  1127. db_query("INSERT role_permissions SELECT * FROM `TEMP_role_permissions` ");
  1128. db_query("DROP TABLE `TEMP_role_permissions` ");
  1129. fp_add_message(t("Permissions saved successfully."));
  1130. }
  1131. /**
  1132. * This form allows the user to manage the roles in the system.
  1133. */
  1134. function user_user_roles_form() {
  1135. $form = array();
  1136. $m = 0;
  1137. fp_add_css(fp_get_module_path("user") . "/css/user.css");
  1138. fp_add_js(fp_get_module_path("admin") . "/js/admin.js");
  1139. $form["mark" . $m++] = array(
  1140. "type" => "markup",
  1141. "value" => t("Roles are able to be assigned permissions in FlightPath, and then users are assigned
  1142. those roles. You may not remove the two roles, 'anonymous user' and 'authenticated user'.
  1143. Those are assigned automatically when the user logs in or out.
  1144. However, you may add as many more roles as you wish.")
  1145. . "<br><br><b>" . t("roles:") . "</b>
  1146. <table style='padding-left: 20px;'>",
  1147. );
  1148. $res = db_query("SELECT * FROM roles ORDER BY rid");
  1149. while ($cur = db_fetch_array($res)) {
  1150. $key = $cur["rid"];
  1151. $value = $cur["name"];
  1152. $prompt_link = fp_get_js_prompt_link("Enter a new name to change this role to:", $value, "document.getElementById(\"element-perform_action2\").value=\"edit~_~$key~_~\" + response; document.getElementById(\"fp-form-user_user_roles_form\").submit(); ", t("edit")) . " | ";
  1153. $confirm_link = fp_get_js_confirm_link(t("Are you sure you wish to delete this role?\\nIt will be removed from users' accounts. This action cannot be undone.\\n\\nProceed?"), "document.getElementById(\"element-perform_action2\").value=\"del~_~$key\"; document.getElementById(\"fp-form-user_user_roles_form\").submit(); ", t("delete"));
  1154. if ($key == 1 || $key == 2) {
  1155. $prompt_link = $confirm_link = "";
  1156. }
  1157. $form["mark" . $m++] = array(
  1158. "type" => "markup",
  1159. "value" => "<tr><td>$value</td><td>" . $prompt_link . "
  1160. " . $confirm_link . "</td></tr>",
  1161. );
  1162. }
  1163. $form["mark" . $m++] = array(
  1164. "type" => "markup",
  1165. "value" => "</table>",
  1166. );
  1167. $form["perform_action2"] = array(
  1168. "type" => "hidden",
  1169. );
  1170. $form["new_role"] = array(
  1171. "type" => "textfield",
  1172. "label" => t("Add a new role:"),
  1173. );
  1174. $form["submit"] = array(
  1175. "type" => "submit",
  1176. "value" => t("Add new"),
  1177. );
  1178. return $form;
  1179. }
  1180. function user_user_roles_form_submit($form, $form_state) {
  1181. $values = $form_state["values"];
  1182. if (trim($values["new_role"]) != "") {
  1183. $new_role = strtolower(trim($values["new_role"]));
  1184. // Clean up any trouble chars
  1185. $new_role = preg_replace("/[^a-zA-Z0-9_]/", " ", $new_role);
  1186. // Okay, add to the roles table.
  1187. db_query("INSERT INTO roles (name) VALUES (?) ", $new_role);
  1188. fp_add_message("The new role has been added successfully.");
  1189. }
  1190. if (strstr($values["perform_action2"], "del~_~")) {
  1191. $temp = explode("~_~", $values["perform_action2"]);
  1192. $i = trim($temp[1]);
  1193. // Remove this rid from the table.
  1194. db_query("DELETE FROM roles WHERE rid = ? ", $i);
  1195. fp_add_message("The role has been deleted successfully.");
  1196. }
  1197. if (strstr($values["perform_action2"], "edit~_~")) {
  1198. $temp = explode("~_~", $values["perform_action2"]);
  1199. $i = trim($temp[1]);
  1200. $new_name = strtolower(trim($temp[2]));
  1201. $new_name = preg_replace("/[^a-zA-Z0-9_]/", " ", $new_name);
  1202. if (trim($new_name) != "") {
  1203. // Let's update the table.
  1204. db_query("UPDATE roles SET name = ? WHERE rid = ? ", $new_name, $i);
  1205. fp_add_message("The role has been edited successfully.");
  1206. }
  1207. }
  1208. }
  1209. /**
  1210. * This form lets us populate the advisor_student table
  1211. */
  1212. function user_edit_user_advisees_form() {
  1213. $form = array();
  1214. $faculty_cwid = $_REQUEST["faculty_cwid"];
  1215. $user_id = db_get_user_id_from_cwid($faculty_cwid);
  1216. $de_catalog_year = @$_REQUEST["de_catalog_year"];
  1217. // Figure out what the page's sub-tabs should be, and set them.
  1218. $tab_array = array();
  1219. $tab_array[0]["title"] = t("Edit Faculty/Staff User");
  1220. $tab_array[0]["active"] = FALSE;
  1221. $tab_array[0]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1222. $tab_array[1]["title"] = t("Edit Faculty Advisees");
  1223. $tab_array[1]["active"] = TRUE;
  1224. $tab_array[1]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/advisees", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1225. // If there are attributes for a student, then show the tab.
  1226. $attributes = user_get_registered_attributes();
  1227. foreach ($attributes as $def) {
  1228. if (@$def['settings']['user_type'] == 'faculty' || @$def['settings']['user_type'] == 'all') {
  1229. $tab_array[2]["title"] = t("Edit User Attributes");
  1230. $tab_array[2]["active"] = FALSE;
  1231. $tab_array[2]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/attributes", "user_id=$user_id&user_type=faculty&faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1232. break;
  1233. }
  1234. }
  1235. fp_set_page_sub_tabs($tab_array);
  1236. if ($faculty_cwid != "new") {
  1237. $name = fp_get_faculty_name($faculty_cwid);
  1238. fp_set_title(t("Edit Faculty/Staff Advisees of @name (@id)", array("@name" => $name, "@id" => $faculty_cwid)));
  1239. }
  1240. else {
  1241. // A new student! We can't create a new student until a CWID is assigned.
  1242. fp_set_title(t("Create New Faculty/Staff User"));
  1243. $form["mark_sorry"] = array(
  1244. "type" => "markup",
  1245. "value" => "<p>" . t("Sorry, but you cannot add advisees to this faculty member until the faculty member
  1246. has been fully created (and given a CWID). Use the Edit Faculty/Staff User button above
  1247. to return to that screen.") . "</p>",
  1248. );
  1249. return $form;
  1250. }
  1251. $form["user_id"] = array(
  1252. "type" => "hidden",
  1253. "value" => $user_id,
  1254. );
  1255. $form["perform_action2"] = array(
  1256. "type" => "hidden",
  1257. "value" => "",
  1258. );
  1259. $form["faculty_cwid"] = array(
  1260. "type" => "hidden",
  1261. "value" => $faculty_cwid,
  1262. );
  1263. // We are good to go... display the box for entering CWIDS
  1264. $form["markup_explain"] = array(
  1265. "value" => "<p>" . t("
  1266. If this faculty user is an advisor, you may enter their advisees' CWIDs in the box below, one
  1267. per line. This will be used to populate the advisor_student table.
  1268. <br><br>
  1269. <i>Anything after a # sign will be ignored. It is for your benefit only, it will NOT be saved.</i>
  1270. <br><br>
  1271. <b>Important:</b> If you have any routines which modify or edit the advisor_student table,
  1272. this data will be overwritten.") . "</p>",
  1273. );
  1274. $contents = "";
  1275. $db = get_global_database_handler();
  1276. // begin by reading what's already there.
  1277. $res = db_query("SELECT * FROM advisor_student WHERE faculty_id = ? ", $faculty_cwid);
  1278. while ($cur = db_fetch_array($res)) {
  1279. $contents .= trim($cur["student_id"]);
  1280. // If this student exists, get their name and other info as well, to help with display.
  1281. $name = $db->get_student_name($cur["student_id"]);
  1282. $student_majors = $db->get_student_majors_from_db($cur["student_id"], TRUE);
  1283. $majors = "";
  1284. foreach ($student_majors as $code => $details) {
  1285. $majors .= $code . ", ";
  1286. }
  1287. $majors = rtrim(trim($majors), ",");
  1288. if ($name || $majors) {
  1289. $contents .= " # $name - $majors ";
  1290. }
  1291. $contents .= "\n";
  1292. }
  1293. $contents = trim($contents);
  1294. $form["students"] = array(
  1295. "type" => "textarea",
  1296. "label" => t("Advisee Student CWIDs:"),
  1297. "value" => $contents,
  1298. "rows" => 20,
  1299. "cols" => 50,
  1300. "description" => t("Enter advisee student CWIDs for this faculty user, one per line."),
  1301. );
  1302. $form["warn_me"] = array(
  1303. "type" => "checkbox",
  1304. "label" => t("Warn me if I enter a student CWID which doesn't exist in the students/users table yet (good for catching typos)"),
  1305. "value" => "yes",
  1306. );
  1307. $form["submit_btn"] = array(
  1308. "type" => "submit",
  1309. "value" => "Submit",
  1310. );
  1311. return $form;
  1312. } // edit_user_advisees_form
  1313. /**
  1314. * Check to see if we entered a CWID which doesn't exist in students table.
  1315. */
  1316. function user_edit_user_advisees_form_validate($form, $form_state) {
  1317. if ($form_state["values"]["warn_me"] === TRUE) {
  1318. $students = trim($form_state["values"]["students"]);
  1319. $lines = explode("\n", $students);
  1320. foreach($lines as $line) {
  1321. $temp = explode("#", $line);
  1322. $line = trim($temp[0]);
  1323. if ($line == "") continue;
  1324. // $line should now contain the CWID
  1325. // Otherwise, check that it exists.
  1326. $uid = db_get_user_id_from_cwid($line, "student");
  1327. if ($uid < 2 || !$uid) {
  1328. form_error("students", t("The CWID %cwid could not be found in the users table as a student. Your data has NOT been saved.", array("%cwid" => $line)));
  1329. }
  1330. }
  1331. }
  1332. }
  1333. /**
  1334. * Save to the advisor_student table
  1335. */
  1336. function user_edit_user_advisees_form_submit($form, $form_state) {
  1337. // Begin by clearing the table for this advisor.
  1338. $faculty_cwid = trim($form_state["values"]["faculty_cwid"]);
  1339. db_query("DELETE FROM advisor_student WHERE faculty_id = ? ", $faculty_cwid);
  1340. $students = trim($form_state["values"]["students"]);
  1341. $lines = explode("\n", $students);
  1342. foreach($lines as $line) {
  1343. $temp = explode("#", $line);
  1344. $line = trim($temp[0]);
  1345. if ($line == "") continue;
  1346. // Okay, $line should now contain the CWID.
  1347. // Insert into db. (use REPLACE to prevent an error if data was entered twice)
  1348. db_query("REPLACE INTO advisor_student (faculty_id, student_id)
  1349. VALUES (?, ?) ", $faculty_cwid, $line);
  1350. }
  1351. watchdog("user_edit_advisees", "Update faculty (@cwid) advisees values: @other", array("@cwid" => $faculty_cwid, "@other" => ppm($form_state['values'], TRUE)));
  1352. fp_add_message(t("The advisees have been updated for this faculty member."));
  1353. }
  1354. /**
  1355. * Let the user edit a user's roles and other information.
  1356. */
  1357. function user_edit_user_form() {
  1358. fp_add_js(fp_get_module_path("user") . "/js/user.js");
  1359. $form = array();
  1360. $m = 0;
  1361. $faculty_cwid = strip_tags($_REQUEST["faculty_cwid"]);
  1362. $user_id = db_get_user_id_from_cwid($faculty_cwid);
  1363. $school_id = db_get_school_id_for_user_id($user_id);
  1364. $de_catalog_year = @strip_tags($_REQUEST["de_catalog_year"]);
  1365. $name = fp_get_faculty_name($faculty_cwid);
  1366. fp_set_title(t("Edit Faculty/Staff User @name (@id)", array("@name" => $name, "@id" => $faculty_cwid)));
  1367. // Figure out what the page's sub-tabs should be, and set them.
  1368. $tab_array = array();
  1369. $tab_array[0]["title"] = t("Edit Faculty/Staff User");
  1370. $tab_array[0]["active"] = TRUE;
  1371. $tab_array[0]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1372. $tab_array[1]["title"] = t("Edit Faculty Advisees");
  1373. $tab_array[1]["active"] = FALSE;
  1374. $tab_array[1]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/advisees", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1375. // If there are attributes for a student, then show the tab.
  1376. $attributes = user_get_registered_attributes();
  1377. foreach ($attributes as $def) {
  1378. if (@$def['settings']['user_type'] == 'faculty' || @$def['settings']['user_type'] == 'all') {
  1379. $tab_array[2]["title"] = t("Edit User Attributes");
  1380. $tab_array[2]["active"] = FALSE;
  1381. $tab_array[2]["on_click"] = "window.location=\"" . fp_url("admin/users/edit-user/attributes", "user_id=$user_id&user_type=faculty&faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "\"";
  1382. break;
  1383. }
  1384. }
  1385. fp_set_page_sub_tabs($tab_array);
  1386. $user_roles = system_get_roles_for_user($user_id);
  1387. //fpm($user_roles);
  1388. $default_values = array();
  1389. foreach ($user_roles as $rid => $val) {
  1390. $default_values[$rid] = $rid;
  1391. }
  1392. $form["user_id"] = array(
  1393. "type" => "hidden",
  1394. "value" => $user_id,
  1395. );
  1396. $form["perform_action2"] = array(
  1397. "type" => "hidden",
  1398. "value" => "",
  1399. );
  1400. $form["faculty_cwid"] = array(
  1401. "type" => "hidden",
  1402. "value" => $faculty_cwid,
  1403. );
  1404. // Show a list of roles in the system which we may select from, and check the ones
  1405. // all ready assigned to this user.
  1406. if ($faculty_cwid != "new") {
  1407. // Not for new users, since we don't have a user_id for them yet.
  1408. $options = array();
  1409. $res = db_query("SELECT * FROM roles ORDER BY rid");
  1410. while ($cur = db_fetch_array($res)) {
  1411. $key = $cur["rid"];
  1412. $value = $cur["name"];
  1413. if ($key > 2) {
  1414. $options[$key] = $value;
  1415. }
  1416. }
  1417. //fpm($default_values);
  1418. $form["roles"] = array(
  1419. "label" => t("Check which roles this user should have."),
  1420. "type" => "checkboxes",
  1421. "options" => $options,
  1422. "value" => $default_values,
  1423. "weight" => 10,
  1424. );
  1425. }
  1426. /////////////////////
  1427. // Let's present the form elements to allow some basic editing of this user.
  1428. // Only if we are making a new user...
  1429. if ($faculty_cwid == "new") {
  1430. $form["new_faculty_cwid"] = array(
  1431. "label" => t("Enter a new CWID, unique to faculty:"),
  1432. "type" => "textfield",
  1433. "size" => 20,
  1434. "required" => TRUE,
  1435. "description" => t("Enter an alpha-numeric ID for this faculty. It may be the same
  1436. as a student, but may not be the same as any existing
  1437. faculty. You will not be able to edit this value, once saved."),
  1438. "weight" => 20,
  1439. );
  1440. $form["new_user_name"] = array(
  1441. "label" => t("Enter a new username, unique to all users:"),
  1442. "type" => "textfield",
  1443. "size" => 20,
  1444. "required" => TRUE,
  1445. "description" => t("Enter a username for this user. This is what the user will
  1446. use to log in. It must be unique to all users (cannot have both
  1447. a faculty and a student with the same username). You will not
  1448. be able to edit this value, once saved."),
  1449. "weight" => 30,
  1450. );
  1451. $cur = array();
  1452. }
  1453. else {
  1454. // NOT a new faculty. Load their information normally.
  1455. $res = db_query("SELECT * FROM users u, faculty s
  1456. WHERE u.cwid = ?
  1457. AND u.is_faculty = '1'
  1458. AND u.cwid = s.cwid", $faculty_cwid);
  1459. $cur = db_fetch_array($res);
  1460. }
  1461. @$user_name = $cur["user_name"];
  1462. if ($user_name != "") {
  1463. $form["mark" . $m++] = array(
  1464. "value" => "<p><b>Username:</b> $user_name</p>",
  1465. "weight" => 40,
  1466. );
  1467. }
  1468. $form["new_password"] = array(
  1469. "label" => t("Enter a new password for this user:"),
  1470. "type" => "textfield",
  1471. "size" => 20,
  1472. "required" => ($faculty_cwid == "new") ? TRUE : FALSE,
  1473. "description" => t("If you enter any value here, it will change the
  1474. user's password in FlightPath. If you are using the LDAP, SAML, or other external login module,
  1475. the external password will be unaffected."),
  1476. "weight" => 50,
  1477. );
  1478. $form["email"] = array(
  1479. "label" => t("Email:"),
  1480. "type" => "textfield",
  1481. "value" => @$cur["email"],
  1482. "weight" => 60,
  1483. );
  1484. $form["f_name"] = array(
  1485. "label" => t("First name:"),
  1486. "type" => "textfield",
  1487. "value" => @$cur["f_name"],
  1488. "weight" => 70,
  1489. );
  1490. $form["l_name"] = array(
  1491. "label" => t("Last name:"),
  1492. "type" => "textfield",
  1493. "value" => @$cur["l_name"],
  1494. "weight" => 80,
  1495. );
  1496. $form["is_disabled"] = array(
  1497. "label" => t("Active/Disabled status:"),
  1498. "type" => "select",
  1499. "options" => array(0 => t("Active (default)"), 1 => t("Disabled")),
  1500. "hide_please_select" => TRUE,
  1501. "value" => @$cur["is_disabled"],
  1502. "description" => t("If set to 'Disabled', the user will
  1503. be ignored by FlightPath, and they will not be able to log in or be searched for.
  1504. It is safer to disable a user, than to delete them."),
  1505. "weight" => 90,
  1506. );
  1507. // Unique to faculty...
  1508. $form["college"] = array(
  1509. "label" => t("College:"),
  1510. "type" => "textfield",
  1511. "value" => @$cur["college"],
  1512. "size" => 5,
  1513. "weight" => 100,
  1514. );
  1515. $department_code = @$cur['department_code'];
  1516. $departments = fp_get_departments($school_id);
  1517. $form["department"] = array(
  1518. "label" => t("Department:"),
  1519. "type" => "select",
  1520. "options" => $departments,
  1521. "value" => $department_code,
  1522. "weight" => 110,
  1523. "description" => "Select which department this user belongs to (if any). Note: departments are defined on the 'Configure school settings' admin page.",
  1524. );
  1525. $form["major_code_csv"] = array(
  1526. "label" => t("Major code CSV:"),
  1527. "type" => "textfield",
  1528. "value" => @$cur["major_code_csv"],
  1529. "size" => 60,
  1530. "maxlength" => 255,
  1531. "description" => t("Enter the major codes which this faculty member is over, separated by commas. Ex: ACCT,MATH
  1532. <br>If the user is only over 1 major code, just enter that one major code."),
  1533. "weight" => 120,
  1534. );
  1535. // TXT lines (from the engagements module)
  1536. if (module_enabled('engagements')) {
  1537. $user_id = intval($form['user_id']['value']);
  1538. $options = engagements_get_from_phones_for_fapi(TRUE);
  1539. $default_value = engagements_get_user_notify_sms_receipt_values($user_id);
  1540. if (count($options) > 0 && $user_id > 0) {
  1541. $form['receive_notifications_from_numbers'] = array(
  1542. 'type' => 'checkboxes',
  1543. 'label' => t("Select the SMS/Text lines (if any) that this user should be notified of when receiving a Text message:"),
  1544. 'options' => $options,
  1545. 'value' => $default_value,
  1546. 'weight' => 130,
  1547. 'description' => t("Note: the user will always receive a notification if the sender is designated as one of this user's advisees."),
  1548. );
  1549. }
  1550. }
  1551. $form["submit"] = array(
  1552. "type" => "submit",
  1553. "value" => "Submit",
  1554. "prefix" => "<hr>",
  1555. "weight" => 500,
  1556. );
  1557. if ($faculty_cwid != "new" && user_has_permission("delete_users")) {
  1558. $form["mark" . $m++] = array(
  1559. "type" => "markup",
  1560. "value" => "<div align='right'>
  1561. " . t("Delete this faculty member?") . " <input type='button' value='X'
  1562. onClick='userDeleteFaculty();'>
  1563. </div>",
  1564. "weight" => 600,
  1565. );
  1566. }
  1567. return $form;
  1568. }
  1569. /**
  1570. * Validate handler for editing faculty users.
  1571. */
  1572. function user_edit_user_form_validate($form, $form_state) {
  1573. $values = $form_state["values"];
  1574. // If a password was given, make sure it is appropriate.
  1575. if (trim($values["new_password"]) != "") {
  1576. if (strlen(trim($values["new_password"])) < 5) {
  1577. form_error("new_password", t("Please enter a password that is at least 5 characters long."));
  1578. return;
  1579. }
  1580. }
  1581. // If creating a new user, make sure new_student_cwid and new_user_name are not
  1582. // already in use.
  1583. if ($values["faculty_cwid"] == "new") {
  1584. $new_cwid = trim($values["new_faculty_cwid"]);
  1585. $new_user_name = trim($values["new_user_name"]);
  1586. // Check that username is at least 4 characters
  1587. if (strlen($new_user_name) < 4) {
  1588. form_error("new_user_name", t("The username you entered is too short. It must be at least 4 characters.
  1589. Please select a different username."));
  1590. return;
  1591. }
  1592. // Check cwid isn't already in use.
  1593. $test = db_result(db_query("SELECT cwid FROM users WHERE cwid = ? AND is_faculty = '1'", $new_cwid));
  1594. if ($test == $new_cwid) {
  1595. form_error("new_faculty_cwid", t("The cwid you entered is already in use. Please select a different cwid."));
  1596. return;
  1597. }
  1598. // Check user_name isn't already in use.
  1599. $test = db_result(db_query("SELECT user_name FROM users WHERE user_name = ? ", $new_user_name));
  1600. if ($test == $new_user_name) {
  1601. form_error("new_user_name", t("The username you entered is already in use. Please select a different username."));
  1602. return;
  1603. }
  1604. }
  1605. }
  1606. /**
  1607. * Submit handler for our edit faculty form
  1608. */
  1609. function user_edit_user_form_submit($form, $form_state) {
  1610. $values = $form_state["values"];
  1611. foreach ($values as $key => $val) {
  1612. if (!is_array($val)) {
  1613. $values[$key] = trim($val);
  1614. }
  1615. }
  1616. $user_id = intval($values["user_id"]);
  1617. $faculty_cwid = $values["faculty_cwid"];
  1618. $dept_code = trim($values['department']);
  1619. // Save the roles into the database for this user.
  1620. // Begin by deleting what's there all ready.
  1621. db_query("DELETE FROM user_roles WHERE user_id = ? ", $user_id);
  1622. if (is_array($values["roles"])) {
  1623. foreach ($values["roles"] as $rid) {
  1624. //fpm("inserting $rid");
  1625. db_query("INSERT INTO user_roles (user_id, rid)
  1626. VALUES (?, ?) ", $user_id, $rid);
  1627. watchdog("user_edit", "Setting role for user @$user_id", array("@user_id" => $user_id, "@rid" => $rid));
  1628. }
  1629. }
  1630. // Are we supposed to DELETE a faculty?
  1631. if ($values["perform_action2"] == "delete_faculty" && user_has_permission("delete_users")) {
  1632. db_query("DELETE FROM faculty WHERE cwid = ? ", $faculty_cwid);
  1633. db_query("DELETE FROM users WHERE cwid = ? AND is_faculty = '1' ", $faculty_cwid);
  1634. watchdog("user_edit", "Delete faculty user with cwid @$faculty_cwid", array("@faculty_cwid" => $faculty_cwid));
  1635. fp_add_message(t("User has been deleted."));
  1636. fp_goto("admin/users/faculty");
  1637. return;
  1638. }
  1639. if ($faculty_cwid != "new") {
  1640. // NOT a new faculty! Insert values normally.
  1641. // First-- was there a password given? If so, insert that separate.
  1642. if (trim($values["new_password"]) != "") {
  1643. $new_pass = user_hash_password(trim($values["new_password"]));
  1644. db_query("UPDATE users
  1645. SET password = ?
  1646. WHERE cwid = ?
  1647. AND is_faculty = '1' ", $new_pass, $faculty_cwid);
  1648. watchdog("user_edit", "Updating faculty user with cwid @faculty_cwid with new password.", array("@faculty_cwid" => $faculty_cwid));
  1649. unset($values["new_password"]);
  1650. }
  1651. // Okay, now we can just update everything else.
  1652. // Update users table first...
  1653. db_query("UPDATE users
  1654. SET email = ?,
  1655. f_name = ?,
  1656. l_name = ?,
  1657. is_disabled = ?
  1658. WHERE cwid = ?
  1659. AND is_faculty = '1' ", trim(strtolower($values["email"])), $values["f_name"],
  1660. $values["l_name"], $values["is_disabled"],
  1661. $faculty_cwid);
  1662. // Now, update the faculty table entry.
  1663. db_query("UPDATE faculty
  1664. SET college = ?,
  1665. department_code = ?,
  1666. major_code_csv = ?
  1667. WHERE cwid = ? ", $values["college"], $dept_code,
  1668. $values["major_code_csv"], $faculty_cwid);
  1669. watchdog("user_edit", "Updating faculty user with various other values: @other", array("@other" => ppm($values, TRUE)));
  1670. }
  1671. else {
  1672. // This is a NEW user! We need to perform inserts. Thanks to our validate handler,
  1673. // we know all of the values we have are valid.
  1674. if (trim($values["l_name"]) == "") {
  1675. // No last name? Set to username.
  1676. $values['l_name'] = $values['new_user_name'];
  1677. }
  1678. db_query("INSERT INTO users (user_name, password, is_faculty, email, cwid, f_name, l_name, is_disabled)
  1679. VALUES (?, ?, '1', ?, ?, ?, ?, ?)
  1680. ", $values["new_user_name"], user_hash_password($values["new_password"]), trim(strtolower($values["email"])), $values["new_faculty_cwid"],
  1681. $values["f_name"], $values["l_name"], $values["is_disabled"]);
  1682. db_query("INSERT INTO faculty (cwid, college, department_code, major_code_csv)
  1683. VALUES (?, ?, ?, ?)
  1684. ", $values["new_faculty_cwid"], $values["college"], $dept_code, $values["major_code_csv"]);
  1685. unset($values['new_password']);
  1686. watchdog("user_edit", "Create new faculty user with various values: @other", array("@other" => ppm($values, TRUE)));
  1687. fp_add_message(t("User created successfully."));
  1688. fp_goto("admin/users/edit-user", "faculty_cwid=" . $values["new_faculty_cwid"]);
  1689. }
  1690. // Do we have any phone lines listed (from the core Engagements module) that this user should be notified of when they
  1691. // receive a txt message? If so, save that information in the user_settings table.
  1692. if (isset($values['receive_notifications_from_numbers'])) {
  1693. // Delete existing settings values...
  1694. db_query("DELETE FROM user_settings WHERE user_id = ? AND name LIKE ?", array($user_id, 'notify_sms_receipt__%'));
  1695. if (is_array($values['receive_notifications_from_numbers'])) {
  1696. foreach ($values['receive_notifications_from_numbers'] as $num) {
  1697. user_set_setting($user_id, "notify_sms_receipt__" . $num, $num);
  1698. }
  1699. }
  1700. }
  1701. fp_add_message(t("User updated successfully."));
  1702. }
  1703. /**
  1704. * Display our list of faculty/staff users in the system.
  1705. */
  1706. function user_display_users() {
  1707. global $db, $screen;
  1708. $de_catalog_year = @$GLOBALS["de_catalog_year"];
  1709. if (!$de_catalog_year) {
  1710. $de_catalog_year = @intval($_REQUEST['de_catalog_year']);
  1711. }
  1712. $cc = 1;
  1713. // Do this using $render array, so it can be altered
  1714. // by hook_content_alter
  1715. $render = array();
  1716. $render['#id'] = 'user_display_users';
  1717. fp_add_css(fp_get_module_path("admin") . "/css/admin.css");
  1718. fp_add_css(fp_get_module_path("user") . "/css/user.css");
  1719. if (@$_REQUEST['clear_filters'] == 'true') {
  1720. unset($_SESSION['users_filter_name']);
  1721. // Meaning, a letter was specified, so let's reset the filter values.
  1722. foreach ($_SESSION as $key => $val) {
  1723. if (strstr($key,"users_filter_")) {
  1724. unset($_SESSION[$key]);
  1725. }
  1726. }
  1727. }
  1728. $html = "";
  1729. $html .= "<div class='add-new-user'>" . l("<i class='fa fa-plus'></i> " . t("Create a new faculty/staff user"), "admin/users/edit-user", "faculty_cwid=new&de_catalog_year=$de_catalog_year") . "</div>";
  1730. $letter_ranges = array(
  1731. "A" => array("A", "AZZZZ"),
  1732. "B" => array("B", "BZZZZ"),
  1733. "C" => array("C", "CZZZ"),
  1734. "D" => array("D", "DZZZZ"),
  1735. "E" => array("E", "EZZZZ"),
  1736. "F" => array("F", "FZZZZ"),
  1737. "G" => array("G", "GZZZZ"),
  1738. "H" => array("H", "HZZZZ"),
  1739. "I" => array("I", "IZZZ"),
  1740. "J" => array("J", "JZZZ"),
  1741. "K" => array("K", "KZZZ"),
  1742. "L" => array("L", "LZZZ"),
  1743. "M" => array("M", "MZZZ"),
  1744. "N" => array("N", "NZZZ"),
  1745. "O" => array("O", "OZZZ"),
  1746. "P" => array("P", "PZZZ"),
  1747. "Q-R" => array("Q", "RZZZZ"),
  1748. "S" => array("S", "SZZZ"),
  1749. "T" => array("T", "TZZZZ"),
  1750. "U" => array("U", "UZZZ"),
  1751. "V-Z" => array("V", "ZZZZ"),
  1752. );
  1753. $ur = trim(@$_GET["ur"]);
  1754. $lr = trim(@$_GET["lr"]);
  1755. if ($ur == "" && !isset($_SESSION['users_filter_submit'])) {
  1756. //if ($ur == "") {
  1757. $ur = "A";
  1758. $lr = "AZZZZZ"; // first time through.
  1759. }
  1760. // If we are going by filters, show that as option and select it.
  1761. if (isset($_SESSION['users_filter_submit'])) {
  1762. $letter_ranges[t(" - Filter -")] = array("filter", "filter");
  1763. }
  1764. $html .= "<div class='user-select-letter-bar' style='padding-top: 20px;'>
  1765. ";
  1766. foreach($letter_ranges as $disp => $vals) {
  1767. $selected_class = "";
  1768. if ($ur == $vals[0]) {
  1769. $selected_class = "selected";
  1770. }
  1771. if ($vals[0] == 'filter') {
  1772. $selected_class = "selected";
  1773. $html .= "<a href='javascript:void(0);' class='admin-courses-letter-link filter-indicator $selected_class'>$disp</a> &nbsp; ";
  1774. continue;
  1775. }
  1776. $html .= l($disp, "admin/users/faculty", "de_catalog_year=$de_catalog_year&clear_filters=true&ur=" . $vals[0] . "&lr=" . $vals[1], array("class" => "admin-courses-letter-link $selected_class")) . " &nbsp; ";
  1777. }
  1778. $html .= "</div>";
  1779. $render['upper_links'] = array(
  1780. 'value' => $html,
  1781. );
  1782. if ($ur == "")
  1783. { // meaning, no range was set. Use A - C
  1784. $ur = @$_SESSION["ur"];
  1785. $lr = @$_SESSION["lr"];
  1786. if ($ur == "")
  1787. { // if still blank, assign it..
  1788. $ur = "A";
  1789. $lr = "AZZZZ";
  1790. }
  1791. }
  1792. $_SESSION["ur"] = $ur;
  1793. $_SESSION["lr"] = $lr;
  1794. $mark = "";
  1795. $mark .= "<div class='degrees-filter'>";
  1796. $mark .= fp_render_form("user_list_filter_form");
  1797. $mark .= "</div>";
  1798. $render['users_filter'] = array(
  1799. 'value' => $mark,
  1800. );
  1801. $extra_where_conditions = "";
  1802. $params = array();
  1803. $params[":ur"] = $ur;
  1804. $params[":lr"] = $lr;
  1805. if (isset($_SESSION['users_filter_submit'])) {
  1806. // We clicked to filter, so the letter range should be ignored.
  1807. $params[":ur"] = "A";
  1808. $params[":lr"] = "ZZZZZZZZZZZZ";
  1809. }
  1810. $filter_name = @trim($_SESSION['users_filter_name']);
  1811. $filter_school = @intval($_SESSION['users_filter_school']);
  1812. $filter_dept = @trim($_SESSION['users_filter_dept']);
  1813. $filter_role = @intval($_SESSION['users_filter_role']);
  1814. $extra_where_conditions .= " AND u.school_id = :school_id ";
  1815. $params[":school_id"] = $filter_school;
  1816. if ($filter_name) {
  1817. $extra_where_conditions .= " AND (l_name LIKE :search1 OR f_name LIKE :search2 OR u.cwid LIKE :search3) ";
  1818. $params[":search1"] = "%$filter_name%";
  1819. $params[":search2"] = "%$filter_name%";
  1820. $params[":search3"] = "%$filter_name%";
  1821. // If we are searching by name, then we do not care about what letters we selected.
  1822. $params[":ur"] = "A";
  1823. $params[":lr"] = "ZZZZZZZZZZZZZZ";
  1824. }
  1825. if ($filter_role > 0) {
  1826. $extra_where_conditions .= " AND rid = :rid ";
  1827. $params[":rid"] = $filter_role;
  1828. }
  1829. if ($filter_dept) {
  1830. $extra_where_conditions .= " AND department_code = :dept ";
  1831. $params[":dept"] = $filter_dept;
  1832. }
  1833. watchdog("user", "Viewed admin user list. Range: $ur - $lr. Name: $filter_name. Dept: $filter_dept. Role: $filter_role. School: $filter_school", array(), WATCHDOG_DEBUG);
  1834. $result = db_query("SELECT * FROM (users u, faculty f)
  1835. LEFT JOIN user_roles r ON (r.user_id = u.user_id)
  1836. WHERE
  1837. u.is_faculty = 1
  1838. AND u.cwid = f.cwid
  1839. AND l_name BETWEEN :ur AND :lr
  1840. $extra_where_conditions
  1841. ORDER BY l_name, f_name", $params);
  1842. $html = "";
  1843. $html .= "
  1844. <table border='0' width='100%' cellpadding='3' cellspacing='0' class='user-list'>
  1845. <tr>
  1846. <th width='5%'>Actions</th>
  1847. <th>CWID</th>
  1848. <th>Name</th>
  1849. <th></th>
  1850. <th>Department</th>
  1851. <th>Roles</th>
  1852. <th>Last Login</th>
  1853. </tr>
  1854. ";
  1855. $render['users_table_top'] = array(
  1856. 'value' => $html,
  1857. );
  1858. while ($cur = db_fetch_array($result)) {
  1859. $user_id = $cur["user_id"]; // Note: will be NULL if no roles are set, due to left join in query.
  1860. $school_id = db_get_school_id_for_user_id($user_id);
  1861. $departments = fp_get_departments($school_id);
  1862. $l_name = trim(ucwords(strtolower($cur["l_name"])));
  1863. $f_name = trim(ucwords(strtolower($cur["f_name"])));
  1864. $faculty_cwid = trim($cur["cwid"]);
  1865. $dept_name = @$departments[$cur["department_code"]];
  1866. if ($dept_name == "") $dept_name = $cur['department_code'];
  1867. $last_login = intval($cur['last_login']);
  1868. if ($last_login == 0) {
  1869. $last_login = t("Never");
  1870. }
  1871. else {
  1872. $last_login = format_date(convert_time($last_login), 'short');
  1873. }
  1874. $ast = "";
  1875. $reason = "";
  1876. $fgcol = "black";
  1877. $roles = "";
  1878. $roles_classes = "no-roles";
  1879. $temp = system_get_roles_for_user($user_id);
  1880. if (count($temp) > 1) $roles_classes = "";
  1881. foreach ($temp as $rid => $t) {
  1882. if ($rid > 2) {
  1883. // rid 1 and 2 are anonymous and authenticated-- no need to show them.
  1884. $roles .= "<div class='list-role'>$t</div>";
  1885. $roles_classes .= " role-" . fp_get_machine_readable($t);
  1886. }
  1887. }
  1888. $render['user_row_' . $faculty_cwid] = array(
  1889. 'value' => "<tr class='$roles_classes'>
  1890. <td valign='top'>" . l("<i class='fa fa-pencil' title='Edit'></i>", "admin/users/edit-user", "faculty_cwid=$faculty_cwid&de_catalog_year=$de_catalog_year") . "</td>
  1891. <td valign='top' width='15%'>$faculty_cwid</td>
  1892. <td valign='top' width='15%'>$f_name</td>
  1893. <td valign='top' width='15%'>$l_name</td>
  1894. <td valign='top'>$dept_name</td>
  1895. <td valign='top'>$roles</td>
  1896. <td valign='top'>$last_login</td>
  1897. </tr>",
  1898. 'data' => array(
  1899. 'is_faculty' => 1,
  1900. 'cwid' => $faculty_cwid,
  1901. 'db_row' => $cur,
  1902. ),
  1903. );
  1904. } // while
  1905. $render['users_table_bottom'] = array(
  1906. 'value' => "</table>",
  1907. );
  1908. $rtn = fp_render_content($render);
  1909. return $rtn;
  1910. }
  1911. function user_list_filter_form() {
  1912. $form = array();
  1913. $form['mark_top'] = array(
  1914. 'type' => 'markup',
  1915. 'value' => "<strong>" . t('Filter by...') . "</strong>",
  1916. 'weight' => 0,
  1917. );
  1918. $form['de_catalog_year'] = array(
  1919. 'type' => 'hidden',
  1920. 'value' => @$_REQUEST['de_catalog_year'],
  1921. );
  1922. $filter_name_value = @trim($_SESSION['users_filter_name']);
  1923. $form['filter_name'] = array(
  1924. 'type' => 'textfield',
  1925. 'label' => '',
  1926. 'attributes' => array("placeholder" => t("Name or CWID")),
  1927. 'value' => $filter_name_value,
  1928. 'size' => 20,
  1929. 'weight' => 10,
  1930. );
  1931. // Show list of departments
  1932. if (module_enabled('schools')) {
  1933. $dept_options = fp_get_departments(0, TRUE);
  1934. }
  1935. else {
  1936. $dept_options = fp_get_departments();
  1937. }
  1938. $filter_dept_value = @trim($_SESSION['users_filter_dept']);
  1939. $form['filter_dept'] = array(
  1940. 'type' => 'select',
  1941. 'label' => t('Department:'),
  1942. 'options' => $dept_options,
  1943. 'value' => $filter_dept_value,
  1944. 'weight' => 20,
  1945. );
  1946. // Show list of roles
  1947. $role_options = array();
  1948. $res = db_query("SELECT * FROM roles ORDER BY rid");
  1949. while ($cur = db_fetch_array($res)) {
  1950. $key = $cur["rid"];
  1951. $value = $cur["name"];
  1952. $dispval = $value;
  1953. // Skip anonymous and authenticated
  1954. if ($key == 1 || $key == 2) continue;
  1955. if (strlen($dispval) > 25) {
  1956. $dispval = trim(substr($dispval, 0, 22)) . "...";
  1957. }
  1958. $role_options[$key] = $dispval;
  1959. }
  1960. $filter_role_value = @intval($_SESSION['users_filter_role']);
  1961. $form['filter_role'] = array(
  1962. 'type' => 'select',
  1963. 'label' => t('Role:'),
  1964. 'options' => $role_options,
  1965. 'value' => $filter_role_value,
  1966. 'weight' => 30,
  1967. );
  1968. // If we have enabled the schools module, then have a selector for that as well
  1969. if (module_enabled('schools')) {
  1970. $filter_school_value = @intval($_SESSION['users_filter_school']);
  1971. $options = schools_get_schools_for_fapi(TRUE, TRUE, 'user', TRUE);
  1972. $options[0] = t('- Default -');
  1973. $form['filter_school'] = array(
  1974. 'type' => 'select',
  1975. 'label' => t('School:'),
  1976. 'options' => $options,
  1977. 'value' => $filter_school_value,
  1978. 'weight' => 40,
  1979. 'hide_please_select' => TRUE,
  1980. );
  1981. } // if schools enabled
  1982. $form['submit_btn'] = array(
  1983. 'type' => 'submit',
  1984. 'value' => t('Apply'),
  1985. 'weight' => 100,
  1986. );
  1987. $form['reset_btn'] = array(
  1988. 'type' => 'submit',
  1989. 'value' => t('Reset'),
  1990. 'weight' => 110,
  1991. );
  1992. return $form;
  1993. }
  1994. function user_list_filter_form_submit($form, $form_state) {
  1995. $values = $form_state['values'];
  1996. unset($_SESSION['users_filter_name']);
  1997. unset($_SESSION['users_filter_school']);
  1998. unset($_SESSION['users_filter_dept']);
  1999. unset($_SESSION['users_filter_role']);
  2000. unset($_SESSION['users_filter_submit']);
  2001. if ($values['submit_btn'] != '') {
  2002. $_SESSION['users_filter_name'] = trim($values['filter_name']);
  2003. $_SESSION['users_filter_school'] = $values['filter_school'];
  2004. $_SESSION['users_filter_dept'] = $values['filter_dept'];
  2005. $_SESSION['users_filter_role'] = $values['filter_role'];
  2006. $_SESSION['users_filter_submit'] = "yes"; // simply notes that we did indeed press the submit btn.
  2007. }
  2008. fp_goto("admin/users/faculty", "de_catalog_year=" . $values['de_catalog_year']);
  2009. }
  2010. /**
  2011. * Simple function to return the human-readable name for a role, by rid.
  2012. *
  2013. * @param unknown_type $rid
  2014. */
  2015. function user_get_role_name($rid) {
  2016. $name = db_result(db_query("SELECT name FROM roles WHERE rid = ? ", $rid));
  2017. return $name;
  2018. }

Functions

Namesort descending Description
user_alter_student_profile_items Implements hook_alter_student_profile_items
user_display_users Display our list of faculty/staff users in the system.
user_edit_attribute_form The form which lets us actually edit this user's attribute (ex: Visa Status) Meant to be very similar to:
user_edit_attribute_form_submit
user_edit_user_advisees_form This form lets us populate the advisor_student table
user_edit_user_advisees_form_submit Save to the advisor_student table
user_edit_user_advisees_form_validate Check to see if we entered a CWID which doesn't exist in students table.
user_edit_user_attributes_form
user_edit_user_attributes_form_submit
user_edit_user_form Let the user edit a user's roles and other information.
user_edit_user_form_submit Submit handler for our edit faculty form
user_edit_user_form_validate Validate handler for editing faculty users.
user_get_attribute Very similar to variable_get
user_get_registered_attributes invokes the right hook to return back all the "registered" attributes from other modules.
user_get_role_name Simple function to return the human-readable name for a role, by rid.
user_get_setting Very similar to variable_get
user_list_filter_form
user_list_filter_form_submit
user_menu Implementation of hook_menu
user_perm
user_permissions_form This is the permissions form, where users can set which roles have which permissions.
user_permissions_form_submit Submit handler for the permissions form.
user_set_attribute Very similar to variable_set
user_set_setting Very similar to variable_set
user_subtab_switchboard Decide what should happen when we go to "admin/config/users" by itself
user_user_roles_form This form allows the user to manage the roles in the system.
user_user_roles_form_submit
user_user_settings_form This is the main settings form for a user.
user_user_settings_form_submit Save values from our settings form into the user_settings table (or other tables), as appropriate.
user_user_settings_form_validate Needed if we are trying to change password.