1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16: if (!defined('OFFSET_PATH')) {
17: define('OFFSET_PATH', 3);
18: require_once(dirname(dirname(__FILE__)) . '/functions.php');
19:
20: if (isset($_GET['action']) && $_GET['action'] == 'clear_rating') {
21: if (!zp_loggedin(ADMIN_RIGHTS)) {
22:
23: header('Location: ' . FULLWEBPATH . '/' . ZENFOLDER . '/admin.php?from=' . currentRelativeURL());
24: exitZP();
25: }
26:
27: require_once(dirname(dirname(__FILE__)) . '/admin-functions.php');
28: if (session_id() == '') {
29:
30: if (secureServer()) {
31: $CookieInfo = session_get_cookie_params();
32: session_set_cookie_params($CookieInfo['lifetime'], $CookieInfo['path'], $CookieInfo['domain'], TRUE);
33: }
34: session_start();
35: }
36: XSRFdefender('clear_rating');
37: query('UPDATE ' . prefix('images') . ' SET total_value=0, total_votes=0, rating=0, used_ips="" ');
38: query('UPDATE ' . prefix('albums') . ' SET total_value=0, total_votes=0, rating=0, used_ips="" ');
39: query('UPDATE ' . prefix('news') . ' SET total_value=0, total_votes=0, rating=0, used_ips="" ');
40: query('UPDATE ' . prefix('pages') . ' SET total_value=0, total_votes=0, rating=0, used_ips="" ');
41: header('Location: ' . FULLWEBPATH . '/' . ZENFOLDER . '/admin.php?action=external&msg=' . gettext('All ratings have been set to <em>unrated</em>.'));
42: exitZP();
43: }
44: }
45:
46: $plugin_is_filter = 5 | ADMIN_PLUGIN | THEME_PLUGIN;
47: $plugin_description = gettext("Adds several theme functions to enable images, album, news, or pages to be rated by users. ");
48: $plugin_author = "Stephen Billard (sbillard) and Malte Müller (acrylian)";
49:
50: $option_interface = 'jquery_rating';
51:
52: zp_register_filter('edit_album_utilities', 'jquery_rating::optionVoteStatus');
53: zp_register_filter('save_album_utilities_data', 'jquery_rating::optionVoteStatusSave');
54: zp_register_filter('admin_utilities_buttons', 'jquery_rating::rating_purgebutton');
55:
56: if (getOption('rating_image_individual_control')) {
57: zp_register_filter('edit_image_utilities', 'jquery_rating::optionVoteStatus');
58: zp_register_filter('save_image_utilities_data', 'jquery_rating::optionVoteStatusSave');
59: }
60:
61:
62: if (in_context(ZP_INDEX)) {
63: zp_register_filter('theme_head', 'jquery_rating::ratingJS');
64: }
65:
66: 67: 68: 69:
70: class jquery_rating {
71:
72: var $ratingstate;
73:
74: 75: 76: 77: 78:
79: function __construct() {
80: setOptionDefault('rating_recast', 1);
81: setOptionDefault('rating_stars_count', 5);
82: setOptionDefault('rating_split_stars', 2);
83: setOptionDefault('rating_status', 3);
84: setOptionDefault('rating_image_individual_control', 0);
85: $this->ratingstate = array(gettext('open') => 3, gettext('members & guests') => 2, gettext('members only') => 1, gettext('closed') => 0);
86: }
87:
88: 89: 90: 91: 92:
93: function getOptionsSupported() {
94: $stars = ceil(getOption('rating_stars_count'));
95: return array(gettext('Voting state') => array('key' => 'rating_status', 'type' => OPTION_TYPE_RADIO,
96: 'buttons' => $this->ratingstate,
97: 'desc' => gettext('<em>Enable</em> state of voting.')),
98: gettext('Stars') => array('key' => 'rating_stars_count', 'type' => OPTION_TYPE_TEXTBOX,
99: 'desc' => sprintf(ngettext('Rating will use %u star.', 'Rating will use %u stars.', $stars), $stars)),
100: gettext('Split stars') => array('key' => 'rating_split_stars', 'type' => OPTION_TYPE_RADIO,
101: 'buttons' => array(gettext('full') => 1, gettext('half') => 2, gettext('third') => 3),
102: 'desc' => gettext('Show fractional stars based on rating. May cause performance problems for pages with large numbers of rating elements.')),
103: gettext('Individual image control') => array('key' => 'rating_image_individual_control', 'type' => OPTION_TYPE_CHECKBOX,
104: 'desc' => gettext('Enable to allow voting status control on individual images.')),
105: gettext('Recast vote') => array('key' => 'rating_recast', 'type' => OPTION_TYPE_RADIO,
106: 'buttons' => array(gettext('No') => 0, gettext('Show rating') => 1, gettext('Show previous vote') => 2),
107: 'desc' => gettext('Allow users to change their vote. If Show previous vote is chosen, the stars will reflect the last vote of the viewer. Otherwise they will reflect the current rating.')),
108: gettext('Disguise IP') => array('key' => 'rating_hash_ip', 'type' => OPTION_TYPE_CHECKBOX,
109: 'desc' => gettext('Causes the stored IP addressed to be hashed so as to avoid privacy tracking issues.'))
110: );
111: }
112:
113: function handleOption($option, $currentValue) {
114:
115: }
116:
117: static function ratingJS() {
118: $ME = substr(basename(__FILE__), 0, -4);
119: ?>
120: <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/' . $ME; ?>/jquery.MetaData.js"></script>
121: <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/' . $ME; ?>/jquery.rating.js"></script>
122: <?php
123: $css = getPlugin('rating/jquery.rating.css', true, true);
124: ?>
125: <link rel="stylesheet" href="<?php echo pathurlencode($css); ?>" type="text/css" />
126: <script type="text/javascript">
127:
128: $.fn.rating.options = {cancel: '<?php echo gettext('retract'); ?>'};
129:
130: </script>
131: <?php
132: }
133:
134: 135: 136: 137: 138: 139: 140: 141:
142: static function optionVoteStatus($prior, $object, $prefix) {
143: $me = new jquery_rating();
144: $currentvalue = $object->get('rating_status');
145: $output = gettext('Vote Status:') . '<br />' . "\n";
146: foreach ($me->ratingstate as $text => $value) {
147: if ($value == $currentvalue) {
148: $checked = 'checked="checked"';
149: } else {
150: $checked = '';
151: }
152: $output .= "<label class='checkboxlabel'>\n<input type='radio' name='rating_status" . $prefix . "' id='rating_status" . $value . "-" . $prefix . "' value='" . ($value + 1) . "' " . $checked . "/> " . $text . "\n</label>" . "\n";
153: }
154: $output = $prior . "\n" . $output . '<br /clear="all">';
155: return $output;
156: }
157:
158: 159: 160: 161: 162: 163:
164: static function optionVoteStatusSave($object, $prefix) {
165: if (isset($_POST['rating_status' . $prefix])) {
166: $object->set('rating_status', sanitize_numeric($_POST['rating_status' . $prefix]) - 1);
167: }
168: return $object;
169: }
170:
171: static function rating_purgebutton($buttons) {
172: $buttons[] = array(
173: 'category' => gettext('Database'),
174: 'enable' => true,
175: 'button_text' => gettext('Reset all ratings'),
176: 'formname' => 'clearrating_button',
177: 'action' => PLUGIN_FOLDER . '/rating.php?action=clear_rating',
178: 'icon' => 'images/reset.png',
179: 'title' => gettext('Sets all ratings to unrated.'),
180: 'alt' => '',
181: 'hidden' => '<input type="hidden" name="action" value="clear_rating" />',
182: 'rights' => ADMIN_RIGHTS,
183: 'XSRFTag' => 'clear_rating'
184: );
185: return $buttons;
186: }
187:
188: 189: 190: 191: 192: 193: 194: 195: 196:
197: static function getRatingByIP($ip, $usedips, $ratingAverage) {
198: global $_rating_current_IPlist;
199: $rating = 0;
200: if (empty($_rating_current_IPlist)) {
201: if (!empty($usedips)) {
202: $_rating_current_IPlist = getSerializedArray($usedips);
203: if (array_key_exists($ip, $_rating_current_IPlist)) {
204: return $_rating_current_IPlist[$ip];
205: }
206: }
207: }
208: return false;
209: }
210:
211: 212: 213: 214: 215: 216:
217: static function getCurrentPageObject() {
218: global $_zp_gallery_page, $_zp_current_album, $_zp_current_image, $_zp_current_zenpage_news, $_zp_current_zenpage_page;
219: switch ($_zp_gallery_page) {
220: case 'album.php':
221: return $_zp_current_album;
222: case 'image.php':
223: return $_zp_current_image;
224: case 'news.php':
225: return $_zp_current_zenpage_news;
226: case 'pages.php':
227: return $_zp_current_zenpage_page;
228: default:
229: return NULL;
230: }
231: }
232:
233: 234: 235: 236:
237: static function id() {
238: if (getOption('rating_hash_ip')) {
239: return sha1(getUserIP());
240: } else {
241: return getUserIP();
242: }
243: }
244:
245: }
246:
247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260:
261: function printRating($vote = 3, $object = NULL, $text = true) {
262: global $_zp_gallery_page;
263: if (is_null($object)) {
264: $object = jquery_rating::getCurrentPageObject();
265: }
266: if (!is_object($object)) {
267: return;
268: }
269: $table = $object->table;
270: $vote = min($vote, getOption('rating_status'), $object->get('rating_status'));
271: switch ($vote) {
272: case 1:
273: if (!zp_loggedin()) {
274: $vote = 0;
275: }
276: break;
277: case 2:
278: switch ($_zp_gallery_page) {
279: case 'album.php':
280: $album = $object;
281: $hint = '';
282: if (!(zp_loggedin() || checkAlbumPassword($album->name))) {
283: $vote = 0;
284: }
285: break;
286: case 'pages.php':
287: case 'news.php':
288: if (!zp_loggedin()) {
289: $vote = 0;
290: }
291: break;
292: default:
293: $album = $object->getAlbum();
294: $hint = '';
295: if (!(zp_loggedin() || checkAlbumPassword($album->name))) {
296: $vote = 0;
297: }
298: break;
299: }
300: }
301:
302: $stars = ceil(getOption('rating_stars_count'));
303: $recast = getOption('rating_recast');
304: $split_stars = max(1, getOption('rating_split_stars'));
305: $rating = $object->get('rating');
306: $votes = $object->get('total_votes');
307: $id = $object->getID();
308: $unique = '_' . $table . '_' . $id;
309:
310: $ip = jquery_rating::id();
311: $oldrating = jquery_rating::getRatingByIP($ip, $object->get('used_ips'), $object->get('rating'));
312: if ($vote && $recast == 2 && $oldrating) {
313: $starselector = round($oldrating * $split_stars);
314: } else {
315: $starselector = round($rating * $split_stars);
316: }
317: $disable = !$vote || ($oldrating && !$recast);
318: if ($rating > 0) {
319: $msg = sprintf(ngettext('Rating %2$.1f (%1$u vote)', 'Rating %2$.1f (%1$u votes)', $votes), $votes, $rating);
320: } else {
321: $msg = gettext('Not yet rated');
322: }
323: if ($split_stars > 1) {
324: $step = $split_stars;
325: $split = " {split:$step}";
326: $step = 1 / $step;
327: } else {
328: $split = '';
329: $step = 1;
330: }
331: ?>
332: <form name="star_rating<?php echo $unique; ?>" id="star_rating<?php echo $unique; ?>" action="submit">
333: <?php
334: $j = 0;
335: for ($i = $step; $i <= $stars; $i = $i + $step) {
336: $v = ceil($i);
337: $j++;
338: ?>
339: <input type="radio" class="star<?php echo $split; ?>" name="star_rating-value<?php echo $unique; ?>" value="<?php echo $j; ?>" title="<?php printf(ngettext('%u star', '%u stars', $v), $v); ?>" />
340: <?php
341: }
342: if (!$disable) {
343: ?>
344: <span id="submit_button<?php echo $unique; ?>">
345: <input type="button" class="button buttons" value="<?php echo gettext('Submit »'); ?>" onclick="cast<?php echo $unique; ?>();" />
346: </span>
347: <?php
348: }
349: ?>
350: </form>
351: <span class="clearall" ></span>
352: <span class="vote" id="vote<?php echo $unique; ?>" <?php if (!$text) echo 'style="display:none;"'; ?>>
353: <?php echo $msg; ?>
354: </span>
355: <script type="text/javascript">
356:
357: var recast<?php echo $unique; ?> = <?php printf('%u', $recast && $oldrating); ?>;
358: $(document).ready(function() {
359: $('#star_rating<?php echo $unique; ?> :radio.star').rating('select', '<?php echo $starselector; ?>');
360: <?php
361: if ($disable) {
362: ?>
363: $('#star_rating<?php echo $unique; ?> :radio.star').rating('disable');
364: <?php
365: }
366: ?>
367: });
368:
369: function cast<?php echo $unique; ?>() {
370: var dataString = $('#star_rating<?php echo $unique; ?>').serialize();
371: if (dataString || recast<?php echo $unique; ?>) {
372: <?php
373: if ($recast) {
374: ?>
375: if (!dataString) {
376: dataString = 'star_rating-value<?php echo $unique; ?>=0';
377: }
378: <?php
379: } else {
380: ?>
381: $('#star_rating<?php echo $unique; ?> :radio.star').rating('disable');
382: $('#submit_button<?php echo $unique; ?>').hide();
383: <?php
384: }
385: ?>
386: $.ajax({
387: type: 'POST',
388: cache: false,
389: url: '<?php echo WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/' . substr(basename(__FILE__), 0, -4); ?>/update.php',
390: data: dataString + '&id=<?php echo $id; ?>&table=<?php echo $table; ?>'
391: });
392: recast<?php echo $unique; ?> = <?php printf('%u', $recast); ?>;
393: $('#vote<?php echo $unique; ?>').html('<?php echo gettext('Vote Submitted'); ?>');
394: } else {
395: $('#vote<?php echo $unique; ?>').html('<?php echo gettext('nothing to submit'); ?>');
396: }
397: }
398:
399: </script>
400: <?php
401: }
402:
403: 404: 405: 406: 407: 408:
409: function getRating($object = NULL) {
410: if (is_null($object)) {
411: $object = jquery_rating::getCurrentPageObject();
412: if (!$object)
413: return NULL;
414: }
415: return $object->get('rating');
416: }
417: ?>