flag.pages.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. /**
  3. * @file
  4. * Menu callbacks for the Flag module.
  5. */
  6. /**
  7. * Menu callback for (un)flagging a node.
  8. *
  9. * Used both for the regular callback as well as the JS version.
  10. *
  11. * @param $action
  12. * The action about to be performed. One of 'flag' or 'unflag'.
  13. * @param $flag
  14. * The flag object.
  15. * @param $entity_id
  16. * The ID of the entity to be acted upon. The type is implicit in the flag.
  17. */
  18. function flag_page($action, $flag, $entity_id) {
  19. global $user;
  20. // Shorten up the variables that affect the behavior of this page.
  21. $js = isset($_REQUEST['js']);
  22. $token = $_REQUEST['token'];
  23. // Specifically $_GET to avoid getting the $_COOKIE variable by the same key.
  24. $has_js = isset($_GET['has_js']);
  25. // Check the flag token, and then javascript status.
  26. if (!flag_check_token($token, $entity_id)) {
  27. $flag->errors['token'] = t('Bad token. You seem to have followed an invalid link.');
  28. }
  29. elseif ($user->uid == 0 && !$has_js) {
  30. $flag->errors['javascript'] = t('You must have JavaScript and cookies enabled in your browser to flag content.');
  31. }
  32. // If no errors have been detected thus far, perform the flagging.
  33. // Further errors may still be detected during validation and prevent
  34. // the operation from succeeding.
  35. if (!$flag->errors) {
  36. $flag->flag($action, $entity_id);
  37. }
  38. // If successful, return data according to the request type.
  39. if ($js) {
  40. drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
  41. $flag->link_type = 'toggle';
  42. // Any errors that have been set will be output below
  43. // the flag link with javascript.
  44. print drupal_json_encode(flag_build_javascript_info($flag, $entity_id));
  45. drupal_exit();
  46. }
  47. else {
  48. $errors = $flag->get_errors();
  49. if ($errors) {
  50. // If an error was received, set a message and exit.
  51. foreach ($errors as $error) {
  52. drupal_set_message($error, 'error');
  53. }
  54. if (isset($errors['access-denied'])) {
  55. return MENU_ACCESS_DENIED;
  56. }
  57. else {
  58. drupal_goto();
  59. }
  60. }
  61. else {
  62. drupal_set_message($flag->get_label($action . '_message', $entity_id));
  63. drupal_goto();
  64. }
  65. }
  66. }
  67. /**
  68. * Form for confirming the (un)flagging of an entity.
  69. *
  70. * @param string $action
  71. * Either 'flag' or 'unflag'.
  72. * @param flag_flag $flag
  73. * A loaded flag object.
  74. * @param int $entity_id
  75. * The id of the entity to operate on. The type is implicit in the flag.
  76. *
  77. * @see flag_confirm_submit()
  78. */
  79. function flag_confirm($form, &$form_state, $action, $flag, $entity_id) {
  80. $form['#flag'] = $flag;
  81. $form['action'] = array(
  82. '#type' => 'value',
  83. '#value' => $action,
  84. );
  85. $form['entity_id'] = array(
  86. '#type' => 'value',
  87. '#value' => $entity_id,
  88. );
  89. $question = $flag->get_label($action . '_confirmation', $entity_id);
  90. $path = isset($_GET['destination']) ? $_GET['destination'] : '<front>';
  91. $yes = strip_tags($flag->get_label($action . '_short', $entity_id));
  92. if ($action == 'flag') {
  93. // If the action 'flag', we're potentially about to create a new
  94. // flagging entity. We need an empty new entity to pass to FieldAPI.
  95. $flagging = $flag->new_flagging($entity_id);
  96. field_attach_form('flagging', $flagging, $form, $form_state);
  97. $form['#flagging'] = $flagging;
  98. // Take the same approach as Core entity forms: shove all the entity
  99. // properties into the form as values so that entity_form_field_validate()
  100. // can build a pseudoentity from $form_values in the validate handler.
  101. foreach (array(
  102. 'flag_name',
  103. 'entity_type',
  104. 'entity_id',
  105. 'uid',
  106. ) as $key) {
  107. $form[$key] = array(
  108. '#type' => 'value',
  109. '#value' => isset($flagging->$key) ? $flagging->$key : NULL,
  110. );
  111. }
  112. }
  113. return confirm_form($form, $question, $path, '', $yes);
  114. }
  115. /**
  116. * Validate handler for the flag confirm form.
  117. *
  118. * Validate any Field API fields on the Flagging.
  119. *
  120. * @see flag_confirm()
  121. */
  122. function flag_confirm_validate($form, &$form_state) {
  123. // Only validate the entity fields when we're saving an entity.
  124. $action = $form_state['values']['action'];
  125. if ($action == 'flag') {
  126. entity_form_field_validate('flagging', $form, $form_state);
  127. }
  128. }
  129. /**
  130. * Submit handler for the flag confirm form.
  131. *
  132. * Note that validating whether the user may perform the action is done here,
  133. * rather than in a form validation handler.
  134. *
  135. * @see flag_confirm()
  136. */
  137. function flag_confirm_submit(&$form, &$form_state) {
  138. $flag = $form['#flag'];
  139. $action = $form_state['values']['action'];
  140. $entity_id = $form_state['values']['entity_id'];
  141. if ($action == 'flag') {
  142. // If the action 'flag', further build up the new entity from form values.
  143. $flagging = $form['#flagging'];
  144. entity_form_submit_build_entity('flagging', $flagging, $form, $form_state);
  145. $result = $flag->flag($action, $entity_id, NULL, FALSE, $flagging);
  146. }
  147. else {
  148. $result = $flag->flag($action, $entity_id, NULL, FALSE);
  149. }
  150. if (!$result) {
  151. if ($errors = $flag->get_errors()) {
  152. foreach ($errors as $error) {
  153. drupal_set_message($error, 'error');
  154. }
  155. }
  156. }
  157. else {
  158. drupal_set_message($flag->get_label($action . '_message', $entity_id));
  159. }
  160. }
  161. /**
  162. * Builds the JavaScript structure describing the flagging operation.
  163. */
  164. function flag_build_javascript_info($flag, $entity_id) {
  165. $errors = $flag->get_errors();
  166. $info = array(
  167. 'status' => TRUE,
  168. 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array(
  169. 'after_flagging' => TRUE,
  170. 'errors' => $errors,
  171. )),
  172. // Further information for the benefit of custom JavaScript event handlers:
  173. 'flagSuccess' => !$errors,
  174. 'contentId' => $entity_id,
  175. 'entityType' => $flag->entity_type,
  176. 'flagName' => $flag->name,
  177. 'flagStatus' => $flag->is_flagged($entity_id) ? 'flagged' : 'unflagged',
  178. );
  179. drupal_alter('flag_javascript_info', $info, $flag);
  180. return $info;
  181. }