user_progress.module

  1. cis7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  2. cle7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  3. ecd7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  4. elmsmedia7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  5. harmony7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  6. icor7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  7. meedjum_blog7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module
  8. mooc7 sites/all/modules/elmsln_contrib/user_progress/user_progress.module

Hooks provided by Regions.

Functions

Namesort descending Description
user_progress_menu Implements hook_menu().
user_progress_permission Implements hook_permission().
user_progress_registry_load User Progress database load function.
user_progress_registry_load_all Load all registry records.
user_progress_registry_save Helper function to save item to registry.
user_progress_user_progress_define_types Implements hook_user_progress_define_types().
user_progress_views_api Implements hook_views_api().
_user_progress_convert_value Helper function to utilize type defined data handler
_user_progress_get Implementation of user_progress API to get values from drupal.
_user_progress_get_maxvalue Helper function to get max value for an activity of a user
_user_progress_get_numtries Helper function to get the number of attempts on an action
_user_progress_get_registry_ids Helper function to get a list of available activities from the registry
_user_progress_get_registry_upt_name Helper function to get a upt_name based on upregid.
_user_progress_get_value Helper function to get a value for an activity of a user
_user_progress_js_setup Helper function to include javascript logic for ajax calls.
_user_progress_list_types Helper function to build list of types.
_user_progress_rebuild_types Helper function to populate the user_progress_types table.
_user_progress_set Implementation of user_progress API to set values in drupal.
_user_progress_settings Implements hook_settings().
_user_progress_settings_submit Implements hook_settings_submit().
_user_progress_set_record Helper function to insert into records
_user_progress_verify Helper function for verifying values are valid

Constants

File

sites/all/modules/elmsln_contrib/user_progress/user_progress.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Hooks provided by Regions.
  5. */
  6. // max data points that can be defined, helps provide some limits.
  7. define('USER_PROGRESS_MAX_DATA_POINTS', 16);
  8. /**
  9. * Implements hook_permission().
  10. */
  11. function user_progress_permission() {
  12. $types = _user_progress_list_types();
  13. // Generate a list of regions and permissions.
  14. if (!empty($types)) {
  15. foreach (array_keys($types) as $type) {
  16. $perms['set ' . $type . ' progress record'] = array(
  17. 'title' => $types[$type]->name,
  18. 'description' => t('Grant access to use the %title requirements dashboard', array('%title' => $types[$type]->name)),
  19. );
  20. }
  21. }
  22. $perms['get user progress record'] = array(
  23. 'title' => t('GET up records'),
  24. 'description' => t('This is the permission needed for generally receiving data from user progress.'),
  25. );
  26. $perms['set user progress record'] = array(
  27. 'title' => t('SET up records'),
  28. 'description' => t('This is the permission needed for generally sending data to user progress.'),
  29. );
  30. return $perms;
  31. }
  32. /**
  33. * Helper function to build list of types.
  34. */
  35. function _user_progress_list_types() {
  36. $types = array();
  37. $result = db_query("SELECT * FROM {user_progress_types}");
  38. foreach ($result as $val) {
  39. $types[$val->upt_name] = $val;
  40. }
  41. return $types;
  42. }
  43. /**
  44. * Helper function to include javascript logic for ajax calls.
  45. */
  46. function _user_progress_js_setup($ary = array()) {
  47. // establish environment variables
  48. $node = menu_get_object();
  49. $js_vars = array(
  50. 'last_call' => 0,
  51. 'guid' => drupal_get_token(),
  52. 'ajax_path' => base_path() . 'user_progress',
  53. 'nid' => $node->nid,
  54. );
  55. // merge potential external values with required locals
  56. $js_variables = array_merge($js_vars, $ary);
  57. drupal_add_js(array('user_progress' => $js_variables), array('type' => "setting", 'scope' => JS_DEFAULT));
  58. // add up js api
  59. drupal_add_js(drupal_get_path('module', 'user_progress') . '/js/user_progress.js', array('type' => 'header', 'scope' => JS_DEFAULT));
  60. }
  61. /**
  62. * Implements hook_menu().
  63. */
  64. function user_progress_menu() {
  65. // a call to rebuild the menu cache means we should rebuild the type definitions
  66. _user_progress_rebuild_types();
  67. $items = array();
  68. $items['user_progress/get'] = array(
  69. 'access arguments' => array('get user progress record'),
  70. 'page callback' => '_user_progress_get',
  71. 'page arguments' => array(2),
  72. 'type' => MENU_CALLBACK,
  73. );
  74. $items['user_progress/set'] = array(
  75. 'access arguments' => array('set user progress record'),
  76. 'page callback' => '_user_progress_set',
  77. 'page arguments' => array(2),
  78. 'type' => MENU_CALLBACK,
  79. );
  80. $items['admin/config/people/user_progress'] = array(
  81. 'title' => 'User Progress',
  82. 'description' => 'User Progress global settings',
  83. 'page callback' => 'drupal_get_form',
  84. 'page arguments' => array('_user_progress_settings'),
  85. 'type' => MENU_NORMAL_ITEM,
  86. 'access arguments' => array('administer site configuration'),
  87. );
  88. return $items;
  89. }
  90. /**
  91. * Implements hook_settings().
  92. */
  93. function _user_progress_settings($form_state) {
  94. // get all types
  95. $types = _user_progress_list_types();
  96. // build the header
  97. $header = array(t('ID'), t('Name'), t('Value handler'), t('Data handler'));
  98. // render type list as a table
  99. $rows = array();
  100. foreach ($types as $type) {
  101. $rows[] = array('data' => array($type->upt_name, $type->name, $type->value_handler, $type->data_handler));
  102. $type_options[$type->upt_name] = $type->name;
  103. }
  104. // build table as an array
  105. $table = array(
  106. 'header' => $header,
  107. 'rows' => $rows,
  108. 'caption' => t('Defined types'),
  109. );
  110. // output the table
  111. $form['table'] = array(
  112. '#markup' => theme('table', $table),
  113. );
  114. // get a listing of all items in the registry and render them
  115. $result = db_query("SELECT * FROM {user_progress_registry}");
  116. $header = array(t('ID'), t('Title'), t('Type'), t('Group'));
  117. $rows = array();
  118. // loop through them all
  119. foreach ($result as $val) {
  120. if (empty($val->nid)) {
  121. $gname = '';
  122. }
  123. else {
  124. $group = node_load($val->nid);
  125. $gname = l($group->title, 'node/' . $group->nid);
  126. }
  127. $rows[] = array('data' => array($val->upregid, $val->title, $val->upt_name, $gname));
  128. }
  129. // build a table
  130. $table = array(
  131. 'header' => $header,
  132. 'rows' => $rows,
  133. 'caption' => t('Activity registry'),
  134. );
  135. // table markup
  136. $form['table2'] = array(
  137. '#markup' => theme('table', $table),
  138. );
  139. // setup ability to add a new record
  140. $form['add'] = array(
  141. '#type' => 'fieldset',
  142. '#title' => t('Add activity to registry'),
  143. '#collapsed' => FALSE,
  144. '#collapsible' => TRUE,
  145. );
  146. $options[0] = t('none');
  147. // if og is enabled, populate the list of available groups to this user
  148. if (module_exists('og')) {
  149. $result = db_query(db_rewrite_sql("SELECT title, n.nid FROM {node} AS n JOIN {og} AS g ON g.nid=n.nid"));
  150. foreach ($result as $val) {
  151. $options[$val->nid] = $val->title;
  152. }
  153. }
  154. // allow for associating to a group
  155. if (module_exists('og')) {
  156. $form['add']['nid'] = array(
  157. '#type' => 'select',
  158. '#title' => t('Group'),
  159. '#options' => $options,
  160. '#description' => t('Group associated to this instance of the UP type'),
  161. );
  162. }
  163. $form['add']['title'] = array(
  164. '#type' => 'textfield',
  165. '#title' => t('Title'),
  166. '#description' => t('Human readable title of the type instance'),
  167. );
  168. $form['add']['upt_name'] = array(
  169. '#type' => 'select',
  170. '#title' => t('Type'),
  171. '#options' => $type_options,
  172. '#required' => TRUE,
  173. '#description' => t('Select a type for this activity'),
  174. );
  175. $form['submit'] = array(
  176. '#type' => 'submit',
  177. '#value' => t('Add activity'),
  178. );
  179. return $form;
  180. }
  181. /**
  182. * Implements hook_settings_submit().
  183. */
  184. function _user_progress_settings_submit($form, &$form_state) {
  185. // Allow for optional association to a node / group
  186. if (isset($form_state['values']['nid'])) {
  187. $nid = $form_state['values']['nid'];
  188. }
  189. else {
  190. $nid = 0;
  191. }
  192. $title = check_plain($form_state['values']['title']);
  193. $type = check_plain($form_state['values']['upt_name']);
  194. // build a record
  195. $record = array(
  196. 'title' => $title,
  197. 'type' => $type,
  198. 'nid' => $nid,
  199. );
  200. $id = user_progress_registry_save($record);
  201. }
  202. /**
  203. * Helper function to save item to registry.
  204. */
  205. function user_progress_registry_save($record) {
  206. return db_insert('user_progress_registry')
  207. ->fields(array(
  208. 'title' => $record['title'],
  209. 'upt_name' => $record['type'],
  210. 'nid' => $record['nid'],
  211. ))
  212. ->execute();
  213. }
  214. /**
  215. * Implementation of user_progress API to get values from drupal.
  216. */
  217. function _user_progress_get($action) {
  218. // see what action has been requested
  219. $valid = TRUE;
  220. global $user;
  221. // verify there is a user logged in
  222. if ($user->uid != 0) {
  223. switch ($action) {
  224. case 'guid':
  225. // generate the GUID so we can communicate safely
  226. $output = drupal_get_token();
  227. break;
  228. case 'maxvalue':
  229. // if this is valid, return the high value
  230. if (_user_progress_verify('guid') && _user_progress_verify('upregid')) {
  231. $data_point = $_GET['data_point'];
  232. $upregid = $_GET['upregid'];
  233. $uid = $user->uid;
  234. // select the count of records based on the current user and assignment
  235. $output = _user_progress_get_maxvalue($data_point, $upregid, $uid);
  236. }
  237. else {
  238. $output = 0;
  239. }
  240. break;
  241. case 'numtries':
  242. // if this is valid, get a count of everything
  243. if (_user_progress_verify('guid') && _user_progress_verify('upregid')) {
  244. $upregid = $_GET['upregid'];
  245. $uid = $user->uid;
  246. // select the count of records based on the current user and assignment
  247. $output = _user_progress_get_numtries($upregid, $uid);
  248. }
  249. else {
  250. $output = 0;
  251. }
  252. break;
  253. case 'data':
  254. // if this is valid, get a count of everything
  255. if (_user_progress_verify('guid') && _user_progress_verify('uprid') && _user_progress_verify('data_point')) {
  256. $uprid = $_GET['uprid'];
  257. $data_point = $_GET['data_point'];
  258. $uid = $user->uid;
  259. // select the unique value pairing to current user for security
  260. $params = array(':datapt' => 'data' . $data_point, ':uprid' => $uprid, ':uid' => $uid);
  261. $val = db_query("SELECT :datapt, upregid FROM {user_progress_records} WHERE uprid = :uprid AND uid = :uid", $params)->fetchObject();
  262. _user_progress_convert_value($val->{'data' . $data_point}, $val->upregid, 'data' . $data_point . '_handler', TRUE);
  263. $output = $val->{'data' . $data_point};
  264. }
  265. else {
  266. $output = 0;
  267. }
  268. break;
  269. }
  270. }
  271. else {
  272. $output = 0;
  273. }
  274. print $output;
  275. exit;
  276. }
  277. /**
  278. * Implementation of user_progress API to set values in drupal.
  279. */
  280. function _user_progress_set($action) {
  281. $valid = TRUE;
  282. global $user;
  283. // verify user is logged in
  284. if ($user->uid != 0) {
  285. // see what action is incoming
  286. switch ($action) {
  287. case 'value':
  288. // if we passed validation, set the values in the database
  289. // requirement is that 1 data point was passed to us
  290. if (_user_progress_verify('guid') && _user_progress_verify('upregid') && _user_progress_verify('data1')) {
  291. // activity id
  292. $upregid = $_GET['upregid'];
  293. // user id
  294. $uid = $user->uid;
  295. // see if there's any nid set, otherwise null
  296. if (_user_progress_verify('nid', $_GET['nid'], FALSE)) {
  297. $nid = $_GET['nid'];
  298. }
  299. else {
  300. $nid = NULL;
  301. }
  302. // verify each potential data point, only 1 is required above
  303. for ($i=1; $i<USER_PROGRESS_MAX_DATA_POINTS+1; $i++) {
  304. if (isset($_GET['data' . $i])) {
  305. $data['data' . $i] = $_GET['data' . $i];
  306. // look up how to handle data storage
  307. _user_progress_convert_value($data, $upregid, 'data' . $i . '_handler');
  308. }
  309. }
  310. // create the record
  311. $output = _user_progress_set_record($upregid, $uid, $nid, $data);
  312. }
  313. else {
  314. $output = 0;
  315. }
  316. break;
  317. default:
  318. // invalid request, return 0
  319. $output = 0;
  320. break;
  321. }
  322. }
  323. else {
  324. $output = 0;
  325. }
  326. print $output;
  327. exit;
  328. }
  329. /**
  330. * Helper function to utilize type defined data handler
  331. */
  332. function _user_progress_convert_value(&$data, $upregid, $field = 'default_handler', $reverse = FALSE) {
  333. // need to invoke as more data is here then we store in the database cache
  334. $type_data = module_invoke_all('user_progress_define_types');
  335. drupal_alter('user_progress_define_types', $type_data);
  336. $upt_name = db_query("SELECT upt_name FROM {user_progress_registry} WHERE upregid = :upregid", array(':upregid' => $upregid))->fetchField();
  337. switch ($type_data[$upt_name][$field]) {
  338. case 'int':
  339. case 'string':
  340. // don't do anything for ints and strings
  341. $data = $data;
  342. break;
  343. case 'blob':
  344. // serialize so we can store in the database
  345. if ($reverse) {
  346. $data = unserialize($data);
  347. }
  348. else {
  349. $data = serialize($data);
  350. }
  351. break;
  352. case 'time':
  353. // make sure its in timestamp format and convert if not
  354. if (!is_numeric($data)) {
  355. $data = strtotime($data);
  356. }
  357. break;
  358. }
  359. }
  360. /**
  361. * Helper function for verifying values are valid
  362. */
  363. function _user_progress_verify($type, $val = NULL, $report = TRUE) {
  364. $valid = TRUE;
  365. // if we weren't passed a val use GET
  366. if (empty($val)) {
  367. // verify value is set
  368. if (!isset($_GET[$type])) {
  369. $valid = FALSE;
  370. }
  371. else {
  372. $val = $_GET[$type];
  373. }
  374. }
  375. // validate the type
  376. if ($type == 'guid') {
  377. // verify the token
  378. if (!drupal_valid_token($val)) {
  379. $valid = FALSE;
  380. }
  381. }
  382. elseif ($type == 'data') {
  383. // ignore data, we don't validate beyond set
  384. }
  385. elseif ($type == 'upregid') {
  386. // make sure this is numeric and they have permission to act
  387. if (!is_numeric($val) || !user_access('set ' . _user_progress_get_registry_upt_name($val) . ' progress record')) {
  388. $valid = FALSE;
  389. }
  390. }
  391. else {
  392. // make sure this is a number
  393. if (!is_numeric($val)) {
  394. $valid = FALSE;
  395. }
  396. }
  397. // if it wasn't valid, record it
  398. if (!$valid && $report) {
  399. watchdog('up_debug', '@value not valid', array('@value' => $type));
  400. }
  401. return $valid;
  402. }
  403. /**
  404. * Helper function to insert into records
  405. */
  406. function _user_progress_set_record($upregid, $uid, $nid, $data) {
  407. $field_names = array_keys($data);
  408. $field_names = array_merge(array('upregid', 'uid', 'nid', 'created'), $field_names);
  409. $values = array_merge(array($upregid, $uid, $nid, time()), $data);
  410. // align these arrays
  411. foreach ($field_names as $key => $name) {
  412. $fields[$name] = $values[$key];
  413. }
  414. // insert the record
  415. $uprid = db_insert('user_progress_records')->fields($fields)->execute();
  416. return $uprid;
  417. }
  418. /**
  419. * Helper function to get max value for an activity of a user
  420. */
  421. function _user_progress_get_maxvalue($upregid, $uid) {
  422. return db_query("SELECT MAX(value) FROM {user_progress_records} WHERE upregid = :upregid AND uid = :uid", array(':upregid' => $upregid, ':uid' => $uid))->fetchField();
  423. }
  424. /**
  425. * Helper function to get a value for an activity of a user
  426. */
  427. function _user_progress_get_value($uprid, $uid) {
  428. return db_query("SELECT value FROM {user_progress_records} WHERE uprid = :uprid AND uid = :uid", array(':uprid' => $uprid, ':uid' => $uid))->fetchField();
  429. }
  430. /**
  431. * Helper function to get the number of attempts on an action
  432. */
  433. function _user_progress_get_numtries($upregid, $uid) {
  434. $val = db_query("SELECT COUNT(value) as valcount FROM {user_progress_records} WHERE upregid = :upregid AND uid = :uid", array(':upregid' => $upregid, ':uid' => $uid))->fetchField();
  435. return $val['valcount'];
  436. }
  437. /**
  438. * Helper function to get a list of available activities from the registry
  439. */
  440. function _user_progress_get_registry_ids($upt_name, $nid = NULL) {
  441. // test for nid being null as the query changes
  442. if (is_null($nid)) {
  443. $result = db_query("SELECT upregid, title FROM {user_progress_registry} WHERE upt_name = :upt_name", array(':upt_name' => $upt_name));
  444. }
  445. else {
  446. $result = db_query("SELECT upregid, title FROM {user_progress_registry} WHERE upt_name = :upt_name AND nid = :nid", array(':upt_name' => $upt_name, ':nid' => $nid));
  447. }
  448. // loop through and return an array of possible values
  449. // most time user will only request 1 value but don't want to assume that
  450. foreach ($result as $val) {
  451. $ary[] = array(
  452. 'upregid' => $val->upregid,
  453. 'title' => $val->title,
  454. );
  455. }
  456. if (isset($ary)) {
  457. return $ary;
  458. }
  459. }
  460. /**
  461. * Helper function to get a upt_name based on upregid.
  462. */
  463. function _user_progress_get_registry_upt_name($upregid) {
  464. return db_query("SELECT upt_name FROM {user_progress_registry} WHERE upregid = :upregid", array(':upregid' => $upregid))->fetchField();
  465. }
  466. /**
  467. * Helper function to populate the user_progress_types table.
  468. */
  469. function _user_progress_rebuild_types() {
  470. // this is more efficient then invoking with every call
  471. $types = module_invoke_all('user_progress_define_types');
  472. drupal_alter('user_progress_define_types', $types);
  473. // act on each type record we found
  474. foreach ($types as $key => $type) {
  475. $exists = db_query("SELECT COUNT(upt_name) FROM {user_progress_types} WHERE upt_name = :upt_name", array(':upt_name' => $key))->fetchField();
  476. // does not exist, insert as this is new or first install
  477. if ($exists == 0) {
  478. $id = db_insert('user_progress_types')
  479. ->fields(array(
  480. 'upt_name' => $key,
  481. 'name' => $type['name'],
  482. ))
  483. ->execute();
  484. }
  485. else {
  486. // update existing records just to make sure db mirrors code
  487. db_update('user_progress_types')
  488. ->fields(array(
  489. 'name' => $type['name'],
  490. ))
  491. ->condition('upt_name', $key)
  492. ->execute();
  493. }
  494. }
  495. return $types;
  496. }
  497. /**
  498. * Implements hook_views_api().
  499. */
  500. function user_progress_views_api() {
  501. return array(
  502. 'api' => '2',
  503. );
  504. }
  505. /**
  506. * Implements hook_user_progress_define_types().
  507. */
  508. function user_progress_user_progress_define_types() {
  509. return array();
  510. }
  511. /**
  512. * User Progress database load function.
  513. */
  514. function user_progress_registry_load($upregid) {
  515. $result = db_query("SELECT * FROM {user_progress_registry} WHERE upregid = :upregid", array(':upregid' => $upregid));
  516. $record = $results->fetchObject();
  517. $row = NULL;
  518. if ($record != NULL) {
  519. $row = array(
  520. 'upregid' => $upregid,
  521. 'title' => $record->title,
  522. 'upt_name' => $record->upt_name,
  523. 'nid' => $record->nid,
  524. );
  525. }
  526. return $row;
  527. }
  528. /**
  529. * Load all registry records.
  530. */
  531. function user_progress_registry_load_all() {
  532. $result = db_query("SELECT * FROM {user_progress_registry}");
  533. $record = array();
  534. foreach ($result as $record) {
  535. if ($record != NULL) {
  536. $rows[] = array(
  537. 'upregid' => $upregid,
  538. 'title' => $record->title,
  539. 'upt_name' => $record->upt_name,
  540. 'nid' => $record->nid,
  541. );
  542. }
  543. }
  544. return $rows;
  545. }
Error | ELMSLN API

Error

×

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/elmsln_community/api.elmsln.org/includes/common.inc:2791) in drupal_send_headers() (line 1499 of /var/www/html/elmsln_community/api.elmsln.org/includes/bootstrap.inc).
  • Error: Call to undefined function apc_delete() in DrupalAPCCache->clear() (line 289 of /var/www/html/elmsln_community/api.elmsln.org/sites/all/modules/apc/drupal_apc_cache.inc).
The website encountered an unexpected error. Please try again later.