votingapi.api.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <?php
  2. /**
  3. * @file
  4. * Provides hook documentation for the VotingAPI module.
  5. */
  6. /**
  7. * Adds to or changes the calculated vote results for a piece of content.
  8. *
  9. * VotingAPI calculates a number of common aggregate functions automatically,
  10. * including the average vote and total number of votes cast. Results are
  11. * grouped by 'tag', 'value_type', and then 'function' in the following format:
  12. *
  13. * $results[$tag][$value_type][$aggregate_function] = $value;
  14. *
  15. * If no custom tag is being used for votes, the catch-all "vote" tag should be
  16. * used. In cases where custom tags are used to vote on different aspects of a
  17. * piece of content, a catch-all "vote" value should still be calculated for
  18. * use
  19. * on summary screens, etc.
  20. *
  21. * @param $vote_results
  22. * An alterable array of aggregate vote results.
  23. * @param $content_type
  24. * A string identifying the type of content being rated. Node, comment,
  25. * aggregator item, etc.
  26. * @param $content_id
  27. * The key ID of the content being rated.
  28. *
  29. * @see votingapi_recalculate_results()
  30. */
  31. function hook_votingapi_results_alter(&$vote_results, $content_type, $content_id) {
  32. // We're using a MySQLism (STDDEV isn't ANSI SQL), but it's OK because this is
  33. // an example. And no one would ever base real code on sample code. Ever. Never.
  34. $sql = "SELECT v.tag, STDDEV(v.value) as standard_deviation ";
  35. $sql .= "FROM {votingapi_vote} v ";
  36. $sql .= "WHERE v.content_type = '%s' AND v.content_id = %d AND v.value_type = 'percent' ";
  37. $sql .= "GROUP BY v.tag";
  38. // VotingAPI wants the data in the following format:
  39. // $vote_results[$tag][$value_type][$aggregate_function] = $value;
  40. while ($aggregate = db_query($sql, $content_type, $content_id)->fetchAssoc()) {
  41. $vote_results[$aggregate['tag']]['percent']['standard_deviation'] = $aggregate['standard_deviation'];
  42. }
  43. }
  44. /**
  45. * Adds to or alters metadata describing Voting tags, value_types, and
  46. * functions.
  47. *
  48. * If your module uses custom tags or value_types, or calculates custom
  49. * aggregate functions, please implement this hook so other modules can
  50. * properly interperet and display your data.
  51. *
  52. * Three major bins of data are stored: tags, value_types, and aggregate result
  53. * functions. Each entry in these bins is keyed by the value stored in the
  54. * actual VotingAPI tables, and contains an array with (minimally) 'name' and
  55. * 'description' keys. Modules can add extra keys to their entries if desired.
  56. *
  57. * @param $data
  58. * An alterable array of aggregate vote results.
  59. *
  60. * @see votingapi_metadata()
  61. */
  62. function hook_votingapi_metadata_alter(&$data) {
  63. // Document several custom tags for rating restaurants and meals.
  64. $data['tags']['bread'] = array(
  65. 'name' => t('Bread'),
  66. 'description' => t('The quality of the food at a restaurant.'),
  67. 'module' => 'mymodule',
  68. // This is optional; we can add it for our own purposes.
  69. );
  70. $data['tags']['circuses'] = array(
  71. 'name' => t('Circuses'),
  72. 'description' => t('The quality of the presentation and atmosphere at a restaurant.'),
  73. 'module' => 'mymodule',
  74. );
  75. // Document two custom aggregate function.
  76. $data['functions']['standard_deviation'] = array(
  77. 'name' => t('Standard deviation'),
  78. 'description' => t('The standard deviation of all votes cast on a given piece of content. Use this to find controversial content.'),
  79. 'module' => 'mymodule',
  80. );
  81. $data['functions']['median'] = array(
  82. 'name' => t('Median vote'),
  83. 'description' => t('The median vote value cast on a given piece of content. More accurate than a pure average when there are a few outlying votes.'),
  84. 'module' => 'mymodule',
  85. );
  86. }
  87. /**
  88. * Returns callback functions and descriptions to format a VotingAPI Views
  89. * field.
  90. *
  91. * Loads all votes for a given piece of content, then calculates and caches the
  92. * aggregate vote results. This is only intended for modules that have assumed
  93. * responsibility for the full voting cycle: the votingapi_set_vote() function
  94. * recalculates automatically.
  95. *
  96. * @param object $field
  97. * A Views field object. This can be used to expose formatters only for tags,
  98. * vote values, aggregate functions, etc.
  99. *
  100. * @return array
  101. * An array of key-value pairs, in which each key is a callback function and
  102. * each value is a human-readable description of the formatter.
  103. *
  104. * @see votingapi_set_votes()
  105. */
  106. function hook_votingapi_views_formatters($field) {
  107. if ($field->field == 'value') {
  108. return array('mymodule_funky_formatter' => t('MyModule value formatter'));
  109. }
  110. if ($field->field == 'tag') {
  111. return array('mymodule_funky_tags' => t('MyModule tag formatter'));
  112. }
  113. }
  114. /**
  115. * Save a vote in the database.
  116. *
  117. * @param $vote
  118. * See votingapi_add_votes() for the structure of this array, with the
  119. * defaults loaded from votingapi_prep_vote().
  120. */
  121. function hook_votingapi_storage_add_vote(&$vote) {
  122. _mongodb_votingapi_prepare_vote($vote);
  123. mongodb_collection('votingapi_vote')->insert($vote);
  124. }
  125. /**
  126. * Delete votes from the database.
  127. *
  128. * @param $votes
  129. * An array of votes to delete. Minimally, each vote must have the 'vote_id'
  130. * key set.
  131. * @param $vids
  132. * A list of the 'vote_id' values from $voes.
  133. */
  134. function hook_votingapi_storage_delete_votes($votes, $vids) {
  135. mongodb_collection('votingapi_vote')->delete(array('vote_id' => array('$in' => array_map('intval', $vids))));
  136. }
  137. /**
  138. * Select invidual votes from the database
  139. *
  140. * @param array $criteria
  141. * A keyed array used to build the select query. Keys can contain
  142. * a single value or an array of values to be matched.
  143. * $criteria['vote_id'] (If this is set, all other keys are skipped)
  144. * $criteria['entity_id']
  145. * $criteria['entity_type']
  146. * $criteria['value_type']
  147. * $criteria['tag']
  148. * $criteria['uid']
  149. * $criteria['vote_source']
  150. * $criteria['timestamp'] If this is set, records with timestamps
  151. * GREATER THAN the set value will be selected. Defaults to
  152. * REQUEST_TIME - variable_get('votingapi_anonymous_window', 3600); if
  153. * the anonymous window is above zero.
  154. * @param int $limit
  155. * An integer specifying the maximum number of votes to return. 0 means
  156. * unlimited and is the default.
  157. *
  158. * @return array
  159. * An array of votes matching the criteria.
  160. */
  161. function hook_votingapi_storage_select_votes($criteria, $limit) {
  162. _mongodb_votingapi_prepare_vote($criteria);
  163. $find = array();
  164. foreach ($criteria as $key => $value) {
  165. $find[$key] = is_array($value) ? array('$in' => $value) : $value;
  166. }
  167. $cursor = mongodb_collection('votingapi_vote')->find($find);
  168. if (!empty($limit)) {
  169. $cursor->limit($limit);
  170. }
  171. $votes = array();
  172. foreach ($cursor as $vote) {
  173. $votes[] = $vote;
  174. }
  175. return $votes;
  176. }
  177. /**
  178. * Allows to act on votes before being inserted.
  179. *
  180. * @param $votes
  181. * An array of votes, each with the following structure:
  182. * $vote['entity_type'] (Optional, defaults to 'node')
  183. * $vote['entity_id'] (Required)
  184. * $vote['value_type'] (Optional, defaults to 'percent')
  185. * $vote['value'] (Required)
  186. * $vote['tag'] (Optional, defaults to 'vote')
  187. * $vote['uid'] (Optional, defaults to current user)
  188. * $vote['vote_source'] (Optional, defaults to current IP)
  189. * $vote['timestamp'] (Optional, defaults to REQUEST_TIME)
  190. */
  191. function hook_votingapi_preset_votes(&$votes) {
  192. foreach ($votes as $vote) {
  193. if ($vote['tag'] == 'recommend') {
  194. // Do something if the 'recommend' vote is being inserted.
  195. }
  196. }
  197. }
  198. /**
  199. * TODO
  200. *
  201. */
  202. function hook_votingapi_storage_standard_results($entity_id, $entity) {
  203. // TODO
  204. }