PageRenderTime 27ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/titania/includes/objects/rating.php

http://github.com/phpbb/customisation-db
PHP | 367 lines | 198 code | 52 blank | 117 comment | 23 complexity | 373d919f0fa8da7e01cc556eb074f727 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package Titania
  5. * @copyright (c) 2008 phpBB Customisation Database Team
  6. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License, version 2
  7. *
  8. */
  9. /**
  10. * @ignore
  11. */
  12. if (!defined('IN_TITANIA'))
  13. {
  14. exit;
  15. }
  16. if (!class_exists('titania_database_object'))
  17. {
  18. require TITANIA_ROOT . 'includes/core/object_database.' . PHP_EXT;
  19. }
  20. /**
  21. * Class to abstract titania ratings.
  22. * @package Titania
  23. */
  24. class titania_rating extends titania_database_object
  25. {
  26. /**
  27. * SQL Table
  28. *
  29. * @var string
  30. */
  31. protected $sql_table = TITANIA_RATINGS_TABLE;
  32. /**
  33. * SQL identifier field
  34. *
  35. * @var string
  36. */
  37. protected $sql_id_field = 'rating_id';
  38. /**
  39. * Rating Type
  40. * Check Rating Type Constants
  41. *
  42. * @var int
  43. */
  44. protected $rating_type_id = 0;
  45. /**
  46. * Cache Table
  47. * Rating table where the cache will be stored
  48. *
  49. * @var string
  50. */
  51. protected $cache_table = '';
  52. /**
  53. * Cache Rating
  54. * The field to update with the rating value cache
  55. *
  56. * @var string
  57. */
  58. protected $cache_rating = '';
  59. /**
  60. * Cache Rating Count
  61. * The field to update with the rating count cache
  62. *
  63. * @var string
  64. */
  65. protected $cache_rating_count = '';
  66. /**
  67. * Object column
  68. * The rating item primary key field (ex: user_id for rating authors)
  69. *
  70. * @var string
  71. */
  72. protected $object_column = '';
  73. /**
  74. * Object ID
  75. * The rating item ID (ex: user_id for rating authors)
  76. *
  77. * @var int
  78. */
  79. protected $rating_object_id = 0;
  80. /**
  81. * Rating
  82. * The rating of the item
  83. *
  84. * @var decimal
  85. */
  86. protected $rating = 0;
  87. /**
  88. * Rating Count
  89. * The number of ratings for the item
  90. *
  91. * @var int
  92. */
  93. protected $rating_count = 0;
  94. /**
  95. * Rating Type
  96. * The rating type
  97. *
  98. * @var string
  99. */
  100. protected $rating_type = 0;
  101. /**
  102. * Force the output to not let you rate
  103. *
  104. * @var bool
  105. */
  106. public $cannot_rate = false;
  107. /**
  108. * Constructor class for titania authors
  109. *
  110. * @param string $type The type of rating ('author', 'contrib')
  111. * @param object $object The object we will be rating (author/contrib object)
  112. */
  113. public function __construct($type, $object)
  114. {
  115. // Configure object properties
  116. $this->object_config = array_merge($this->object_config, array(
  117. 'rating_id' => array('default' => 0),
  118. 'rating_type_id' => array('default' => 0),
  119. 'rating_user_id' => array('default' => phpbb::$user->data['user_id']),
  120. 'rating_object_id' => array('default' => 0),
  121. 'rating_value' => array('default' => 0.0),
  122. ));
  123. $this->rating_type = $type;
  124. switch($this->rating_type)
  125. {
  126. case 'author' :
  127. $this->rating_type_id = TITANIA_AUTHOR;
  128. $this->cache_table = TITANIA_AUTHORS_TABLE;
  129. $this->cache_rating = 'author_rating';
  130. $this->cache_rating_count = 'author_rating_count';
  131. $this->object_column = 'user_id';
  132. break;
  133. case 'contrib' :
  134. $this->rating_type_id = TITANIA_CONTRIB;
  135. $this->cache_table = TITANIA_CONTRIBS_TABLE;
  136. $this->cache_rating = 'contrib_rating';
  137. $this->cache_rating_count = 'contrib_rating_count';
  138. $this->object_column = 'contrib_id';
  139. break;
  140. }
  141. // Get the rating, rating count, and item id
  142. $this->rating = $object->{$this->cache_rating};
  143. $this->rating_count = $object->{$this->cache_rating_count};
  144. $this->rating_object_id = $object->{$this->object_column};
  145. }
  146. /**
  147. * Get the current user's rating
  148. */
  149. public function load()
  150. {
  151. if (!phpbb::$user->data['is_registered'] || phpbb::$user->data['is_bot'])
  152. {
  153. return;
  154. }
  155. $sql = 'SELECT * FROM ' . $this->sql_table . '
  156. WHERE rating_type_id = ' . (int) $this->rating_type_id . '
  157. AND rating_user_id = ' . (int) phpbb::$user->data['user_id'] . '
  158. AND rating_object_id = ' . (int) $this->rating_object_id;
  159. $result = phpbb::$db->sql_query($sql);
  160. $this->sql_data = phpbb::$db->sql_fetchrow($result);
  161. phpbb::$db->sql_freeresult($result);
  162. if ($this->sql_data)
  163. {
  164. foreach ($this->sql_data as $key => $value)
  165. {
  166. $this->$key = $value;
  167. }
  168. }
  169. }
  170. /**
  171. * Get rating string
  172. *
  173. * @return string The rating string ready for output
  174. */
  175. public function get_rating_string()
  176. {
  177. $can_rate = (!$this->cannot_rate && phpbb::$user->data['is_registered'] && phpbb::$auth->acl_get('u_titania_rate') && !$this->rating_id) ? true : false;
  178. $rate_url = titania_url::build_url('rate', array('type' => $this->rating_type, 'id' => $this->rating_object_id));
  179. // If it has not had any ratings yet, give it 1/2 the max for the rating
  180. if ($this->rating_count == 0)
  181. {
  182. $this->rating = round(titania::$config->max_rating / 2, 1);
  183. }
  184. phpbb::$template->set_filenames(array(
  185. 'rate' => 'common/rate.html',
  186. ));
  187. phpbb::$template->assign_vars(array(
  188. 'OBJECT_ID' => $this->rating_object_id,
  189. 'OBJECT_RATING' => round($this->rating),
  190. 'RATE_URL' => $rate_url,
  191. 'S_HAS_RATED' => ($this->rating_id) ? true : false,
  192. 'S_CAN_RATE' => $can_rate,
  193. 'UA_GREY_STAR_SRC' => titania::$theme_path . '/images/star_grey.gif',
  194. 'UA_GREEN_STAR_SRC' => titania::$theme_path . '/images/star_green.gif',
  195. 'UA_RED_STAR_SRC' => titania::$theme_path . '/images/star_red.gif',
  196. 'UA_ORANGE_STAR_SRC' => titania::$theme_path . '/images/star_orange.gif',
  197. 'UA_REMOVE_STAR_SRC' => titania::$theme_path . '/images/star_remove.gif',
  198. 'UA_MAX_RATING' => titania::$config->max_rating,
  199. ));
  200. // reset the stars block
  201. phpbb::$template->destroy_block_vars('stars');
  202. for ($i = 1; $i <= titania::$config->max_rating; $i++)
  203. {
  204. $rating = (!$can_rate) ? $this->rating : (($this->rating_value) ? $this->rating_value : $i);
  205. phpbb::$template->assign_block_vars('stars', array(
  206. 'ALT' => $rating . '/' . titania::$config->max_rating,
  207. 'ID' => $i,
  208. 'RATE_URL' => titania_url::append_url($rate_url, array('value' => $i)),
  209. ));
  210. }
  211. return phpbb::$template->assign_display('rate', '', true);
  212. }
  213. /**
  214. * Add a Rating for an item
  215. *
  216. * @param mixed $rating The rating
  217. */
  218. public function add_rating($rating)
  219. {
  220. if ($this->cannot_rate || !phpbb::$user->data['is_registered'] || !phpbb::$auth->acl_get('u_titania_rate'))
  221. {
  222. return false;
  223. }
  224. if ($rating < 0 || $rating > titania::$config->max_rating || $this->rating_id)
  225. {
  226. return false;
  227. }
  228. $this->rating_value = $rating;
  229. parent::submit();
  230. // This is accurate enough as long as we have at least 2 decimal places
  231. $sql = "UPDATE {$this->cache_table} SET
  232. {$this->cache_rating} = ({$this->cache_rating} * {$this->rating_count} + {$this->rating_value}) / ({$this->rating_count} + 1),
  233. {$this->cache_rating_count} = {$this->cache_rating_count} + 1
  234. WHERE {$this->object_column} = {$this->rating_object_id}";
  235. phpbb::$db->sql_query($sql);
  236. return true;
  237. }
  238. /**
  239. * Delete the user's own rating
  240. */
  241. public function delete_rating()
  242. {
  243. if (!phpbb::$user->data['is_registered'] || !$this->rating_id)
  244. {
  245. return false;
  246. }
  247. parent::delete();
  248. if ($this->rating_count == 1)
  249. {
  250. $sql_ary = array(
  251. $this->cache_rating => 0,
  252. $this->cache_rating_count => 0,
  253. );
  254. $sql = 'UPDATE ' . $this->cache_table . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
  255. WHERE ' . $this->object_column . ' = ' . $this->rating_object_id;
  256. phpbb::$db->sql_query($sql);
  257. }
  258. else
  259. {
  260. // This is accurate enough as long as we have at least 2 decimal places
  261. $sql = "UPDATE {$this->cache_table} SET
  262. {$this->cache_rating} = ({$this->cache_rating} * {$this->rating_count} - {$this->rating_value}) / ({$this->rating_count} - 1),
  263. {$this->cache_rating_count} = {$this->cache_rating_count} - 1
  264. WHERE {$this->object_column} = {$this->rating_object_id}";
  265. phpbb::$db->sql_query($sql);
  266. }
  267. return true;
  268. }
  269. /**
  270. * Resync the cache table
  271. */
  272. public function resync()
  273. {
  274. $cnt = $total = 0;
  275. $sql = 'SELECT rating_value FROM ' . $this->sql_table . '
  276. WHERE rating_type_id = ' . (int) $this->rating_type_id . '
  277. AND rating_object_id = ' . (int) $this->rating_object_id;
  278. $result = phpbb::$db->sql_query($sql);
  279. while ($row = phpbb::$db->sql_fetchrow($result))
  280. {
  281. $cnt++;
  282. $total += $row['rating_value'];
  283. }
  284. phpbb::$db->sql_freeresult($result);
  285. $sql_ary = array(
  286. $this->cache_rating => ($cnt > 0) ? round($total / $cnt, 2) : 0,
  287. $this->cache_rating_count => $cnt,
  288. );
  289. $sql = 'UPDATE ' . $this->cache_table . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
  290. WHERE ' . $this->object_column . ' = ' . $this->rating_object_id;
  291. phpbb::$db->sql_query($sql);
  292. }
  293. /**
  294. * Reset the rating for this object
  295. */
  296. public function reset_rating()
  297. {
  298. if (!phpbb::$auth->acl_get('u_titania_mod_rate_reset'))
  299. {
  300. return false;
  301. }
  302. $sql = 'DELETE FROM ' . $this->sql_table . '
  303. WHERE rating_type_id = ' . (int) $this->rating_type_id . '
  304. AND rating_object_id = ' . (int) $this->rating_object_id;
  305. phpbb::$db->sql_query($sql);
  306. $sql_ary = array(
  307. $this->cache_rating => 0,
  308. $this->cache_rating_count => 0,
  309. );
  310. $sql = 'UPDATE ' . $this->cache_table . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
  311. WHERE ' . $this->object_column . ' = ' . $this->rating_object_id;
  312. phpbb::$db->sql_query($sql);
  313. return true;
  314. }
  315. }