Please login or register.

Login with username, password and session length
Advanced search  

News:

You need/want an older version of sNews ? Download an older/unsupported version here.

Author Topic: Trying to get article ratings in sNews  (Read 5723 times)

harry

  • Newbie
  • *
  • Karma: 1
  • Posts: 37
    • http://www.thebusinesscardshop.net/order/
Trying to get article ratings in sNews
« on: December 09, 2006, 03:24:24 AM »

OK, have been trying to get ratings for my articles in snews.

After searching around and reading up on a few free ratings scripts, i found this good small php script to get ratings on articles. http://www.gr0w.com/articles/code/php_5_star_rating_system_using_hreview/index.php

Problem is with only one file in snews, i have been having some trouble getting it to function properly.
I now have the ratings after the comments box under the article, and am able to rate, problem is it is that the same rating is being displayed under all the articles.

The rating script calls this function:
$rater_id=1;
$rater_item_name='Item 1';
include("rater.php");
?>

$rater_id=2;
$rater_item_name='Item 2';
include("rater.php");
?>

I need a way to make the id number correspond with a specific article. As at the moment all articles are the same item.

Maybe someone who is more php adept could help this along? Maybe it just ain't possible?!?

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #1 on: December 09, 2006, 09:24:56 AM »

ok, this will get you started...
To use, create a directory under root to put this script (save as rater.php).
To use as per this post, make the directory name   rater
Create a  img directory, and put the rater images in it.

..and here is the modified rater.php
Take particular note of the extra user settings I have added.
Code: [Select]
//Based on rating application from
//http://www.gr0w.com/articles/code/php_5_star_rating_system_using_hreview/index.php
//PHP, 5 Star Rating System (using hReview)
// Modified for use in sNews1.5 by philmoz
////////////////////////////////////////
// USER SETTINGS/////
$rater_ip_voting_restriction = true; // restrict ip address voting (true or false)
$rater_ip_vote_qty=1; // how many times an ip address can vote
$rater_already_rated_msg="You have already rated this item. You were allowed ".$rater_ip_vote_qty." vote(s).";
$rater_not_selected_msg="You have not selected a rating value.";
$rater_thankyou_msg="Thankyou for voting.";
$rater_generic_text="this item"; // generic item text
$rater_end_of_line_char="\r\n"; // may want to change for different operating systems
$rater_dir="rater/";   // added this. set it to where you have this file and images
if(!isset($rater_id)) $rater_id='1';
if(!isset($rater_item_name)) $rater_item_name=$rater_generic_text;
// for rated articles, and for short displayed articles.
$rater_rated_heading='
'.$rater_item_name.' rated by viewers as:-
';
// for unrated full articles.
$rater_unrated_heading= '

Rate '.$rater_item_name.'

';
////END USER SETTINGS/////
// DO NOT MODIFY BELOW THIS LINE
$rater_filename=$rater_dir.'item_'.$rater_id.".rating"; // added pathing
$rater_rating=0;
$rater_stars="";
$rater_stars_txt="";
$rater_rating=0;
$rater_votes=0;
$rater_msg="";
// Rating action
if(isset($_REQUEST["rate".$rater_id])){
 if(isset($_REQUEST["rating_".$rater_id])){
  while(list($key,$val)=each($_REQUEST["rating_".$rater_id])){
   $rater_rating=$val;
  }
  $rater_ip = getenv("REMOTE_ADDR");
  $rater_file=fopen($rater_filename,"a+");
  $rater_str="";
  $rater_str = rtrim(fread($rater_file, 1024*8),$rater_end_of_line_char);
  if($rater_str!=""){
   if($rater_ip_voting_restriction){
    $rater_data=explode($rater_end_of_line_char,$rater_str);
$rater_ip_vote_count=0;
    foreach($rater_data as $d){
$rater_tmp=explode("|",$d);
$rater_oldip=str_replace($rater_end_of_line_char,"",$rater_tmp[1]);
if($rater_ip==$rater_oldip){
 $rater_ip_vote_count++;
}
    }
if($rater_ip_vote_count > ($rater_ip_vote_qty - 1)){
     $rater_msg=$rater_already_rated_msg;
}else{
     fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
     $rater_msg=$rater_thankyou_msg;
}
   }else{
    fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
    $rater_msg=$rater_thankyou_msg;
   }
  }else{
   fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
   $rater_msg=$rater_thankyou_msg;
  }
  fclose($rater_file);
 }else{
  $rater_msg=$rater_not_selected_msg;
 }
}
// Get current rating
if(is_file($rater_filename)){
 $rater_file=fopen($rater_filename,"r");
 $rater_str="";
 $rater_str = fread($rater_file, 1024*8);
 if($rater_str!=""){
  $rater_data=explode($rater_end_of_line_char,$rater_str);
  $rater_votes=count($rater_data)-1;
  $rater_sum=0;
  foreach($rater_data as $d){
   $d=explode("|",$d);
   $rater_sum+=$d[0];
  }
  $rater_rating=number_format(($rater_sum/$rater_votes), 2, '.', '');
 }
 fclose($rater_file);
}else{
 $rater_file=fopen($rater_filename,"w");
 fclose($rater_file);
}
// Assign star image
if ($rater_rating <= 0  ){$rater_stars = $rater_dir."img/00star.gif";$rater_stars_txt="Not Rated";}
if ($rater_rating >= 0.5){$rater_stars = $rater_dir."img/05star.gif";$rater_stars_txt="0.5";}
if ($rater_rating >= 1  ){$rater_stars = $rater_dir."img/1star.gif";$rater_stars_txt="1";}
if ($rater_rating >= 1.5){$rater_stars = $rater_dir."img/15star.gif";$rater_stars_txt="1.5";}
if ($rater_rating >= 2  ){$rater_stars = $rater_dir."img/2star.gif";$rater_stars_txt="2";}
if ($rater_rating >= 2.5){$rater_stars = $rater_dir."img/25star.gif";$rater_stars_txt="2.5";}
if ($rater_rating >= 3  ){$rater_stars = $rater_dir."img/3star.gif";$rater_stars_txt="3";}
if ($rater_rating >= 3.5){$rater_stars = $rater_dir."img/35star.gif";$rater_stars_txt="3.5";}
if ($rater_rating >= 4  ){$rater_stars = $rater_dir."img/4star.gif";$rater_stars_txt="4";}
if ($rater_rating >= 4.5){$rater_stars = $rater_dir."img/45star.gif";$rater_stars_txt="4.5";}
if ($rater_rating >= 5  ){$rater_stars = $rater_dir."img/5star.gif";$rater_stars_txt="5";}
// Output
$echo= $rater_end_of_line_char.'
'.$rater_end_of_line_char;
$echo.= '';
if($rated=="true"){
$echo.= $rater_rated_heading;}else{$echo.= $rater_unrated_heading;}
$echo.= '
';
$echo.= ''.$rater_stars_txt.' stars Ave. rating: '.$rater_stars_txt.' from '.$rater_votes.' votes.';
$echo.= '
'.$rater_end_of_line_char;
if($rater_msg=="" && $rater_msg!=$rater_already_rated_msg && $rated=="false"){
$echo.= '
';
$echo.= ' '.$rater_end_of_line_char;
$echo.= ' '.$rater_end_of_line_char;
$echo.= ' '.$rater_end_of_line_char;
$echo.= ' '.$rater_end_of_line_char;
$echo.= ' '.$rater_end_of_line_char;
$echo.= ''.$rater_end_of_line_char;
$echo.= ''.$rater_end_of_line_char;
$echo.= '
'.$rater_end_of_line_char;}
if($rater_msg!="") $echo.= "
".$rater_msg."
".$rater_end_of_line_char;
$echo.= ''.$rater_end_of_line_char;
$echo.= '
'.$rater_end_of_line_char;
echo $echo;
?>
Now, plugging it into snews...
locate your center() functionabout 2/3rds down it, you will find
Code: [Select]
if ($infoline == true) {
foreach ($tag as $tag) {
switch ($tag) {
case ($tag == 'date'): echo $a_date_format; break;
case ($tag == 'readmore' && strlen($r['text']) > $shorten):
echo $link.$category.'/'.$r['seftitle'].'/" title="'.l('read_more').'">'.l('read_more').' '; break;
case ($tag == 'comments' && ($commentable == 'YES' || $commentable == 'FREEZ')):
echo $link.$category.'/'.$r['seftitle'].'/#'.l('comment').'1" title="'.l('comments').'">'.l('comments').' ('.$comments_num.') '; break;
case ($tag == 'edit' && $_SESSION[db('website').'Logged_In'] == 'True'): echo ' '.$edit_link; break;
case ($tag != 'readmore' && $tag != 'comments' && $tag != 'edit'): echo $tag; break;
}
}
}
else if ($_SESSION[db('website').'Logged_In'] == 'True') {echo '

'.$edit_link.'

';}
}
else if (substr($position, 0, 1) != '2' && empty($currentPage)) {
$edit_link = ''.l('edit').'';
if ($infoline == true) {
$tag = explode(',', tags('infoline'));
foreach ($tag as $tag ) {
switch ($tag) {
case 'date': echo $a_date_format; break;
case 'readmore':
case 'comments': ; break;
case 'edit': if ($_SESSION[db('website').'Logged_In'] == 'True') {echo '  '.$edit_link;} break;
default: echo $tag;
}
}
}
Make it look like this, by adding the extra lines... or copying this and pasting
Code: [Select]
if ($infoline == true) {
foreach ($tag as $tag) {
switch ($tag) {
case ($tag == 'date'): echo $a_date_format; break;
case ($tag == 'readmore' && strlen($r['text']) > $shorten):
echo $link.$category.'/'.$r['seftitle'].'/" title="'.l('read_more').'">'.l('read_more').' '; break;
case ($tag == 'comments' && ($commentable == 'YES' || $commentable == 'FREEZ')):
echo $link.$category.'/'.$r['seftitle'].'/#'.l('comment').'1" title="'.l('comments').'">'.l('comments').' ('.$comments_num.') '; break;
case ($tag == 'edit' && $_SESSION[db('website').'Logged_In'] == 'True'): echo ' '.$edit_link; break;
case ($tag != 'readmore' && $tag != 'comments' && $tag != 'edit'): echo $tag; break;
}
/*rating script -- */ }$rater_id=$r['id'];$rater_item_name=$r['title'];$rated="true";include("rater/rater.php"); ///place rated articles here.
}
else if ($_SESSION[db('website').'Logged_In'] == 'True') {echo '

'.$edit_link.'

';}
}
else if (substr($position, 0, 1) != '2' && empty($currentPage)) {
$edit_link = ''.l('edit').'';
if ($infoline == true) {
$tag = explode(',', tags('infoline'));
foreach ($tag as $tag ) {
switch ($tag) {
case 'date': echo $a_date_format; break;
case 'readmore':
case 'comments': ; break;
case 'edit': if ($_SESSION[db('website').'Logged_In'] == 'True') {echo '  '.$edit_link;} break;
default: echo $tag;
}
/*rating script -- */ }$rater_id=$r['id'];$rater_item_name=$r['title'];$rated="false";include("rater/rater.php");
}
Note, this is not perfect, but if you mess around with it, you might get it there....

As a tempter...

Logged
Of all the things I have lost, it is my mind that I miss the most.

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #2 on: December 09, 2006, 10:40:22 PM »

Actually, going through on my test server, and viewing... I actually like this ;)

However, the problem I see, is that if you get 100's or more actually rating the articles, all those files are going to get exceptionally large, which will potentially cause extra server drain.
Also, the use of dynamic ip's by isp's my result in someone not being permitted to perform a rating...

What to do?
I would be tempted to only store the last 'x' number of ip's, along with total number of ratings, and total score.

So, in psuedo code for full display.
-read 'item' file
-- extract stored ip's to ip_array
-- extract no.ratings and total ratings to vars (say $no_ratings and $tot_rating)
---- do the sums
-generate display
--- if (submit) check user ip with list and process accordingly
------ If(legit) add user ip to ip_array
---- If(legit) add 1 to $no_ratings, add score to $tot_rating
-write $no_ratings, $tot_rating, and last 'x' number of ip's from ip_array to the 'item' file

in psuedo code for part display.
-read 'item' file
-- extract no.ratings and total ratings to vars
---- do the sums
--generate display

Well, just some thoughts...
Logged
Of all the things I have lost, it is my mind that I miss the most.

harry

  • Newbie
  • *
  • Karma: 1
  • Posts: 37
    • http://www.thebusinesscardshop.net/order/
Trying to get article ratings in sNews
« Reply #3 on: December 11, 2006, 01:56:10 PM »

Big thanks m8, just what i was looking for. Working fantastic apart from one tiny thing. (Not sure if it is something i inadvertently messed up).

Getting an error message on items on the category page the have comments (although everything appears to work fine apart from the message). Articles without comments look 100% ok.

Error message reads:
Warning: Division by zero in /home/i/public_html/rater/rater.php on line 84

You can see the error and other-then-that the script working great on this page of my site: http://eslplayground.com/lower/

harry

  • Newbie
  • *
  • Karma: 1
  • Posts: 37
    • http://www.thebusinesscardshop.net/order/
Trying to get article ratings in sNews
« Reply #4 on: December 11, 2006, 02:07:19 PM »

Regarding expanding on this script, i would think i'd be difficult no? I mean by design it is only a simple script and like you said with the current way of storage, system resources and space will start becoming a problem.

I mean ideally what i would have been looking for was a ratings script that could store data in the tables that are already there in snews, i.e. add another field called ratings and store the score there. Not too sure how duplicates would be handled if it went this way though.

Also rss or display of highest rated articles is something that would have definitely been great.

As for the way it currently works i think the storing the ip address and avoiding duplicates is not the major problem. (having 'highest rated' would be much more desirable). I mean for me to say, getting rid of the ip address storage would be no problem, if it meant it would prevent storage and speed issues as sites grow (however i could see this could be troublesome with sites that an bias in ratings could unfairly/badly skew things.)

OK anyway, just joining in the conversation. Again thanks alot for the work so far

 :D

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #5 on: December 11, 2006, 08:56:51 PM »

WRG to the error...

I saw this as I was modding it.. don't recall what I did to get it, nor what I undid to fix...

Could you post the contents of your rater.php file here... or make a copy of it and call it rater.php.txt , then put it on your server and make link here so I can have a look for any differences/errors.

NOTE. I have moved the insertion points in snews.. and have updated the original code post.
_________
Also, am looking at redoing the whole script as described above. This one has so much repetitive code, it is ridiculous.
Since it will have the results for all in one file (with article ID, total votes, rating), it should be easy to create a highest rating (or rank) routine... would also be possible to add a field to db for article to store the rank value.
Also the ip's would be stored in a second file, and limited to say 25-50 ip's, which should restrict bias creation by voters.

But this will be later.
Logged
Of all the things I have lost, it is my mind that I miss the most.

Fred K

  • sNews Dude
  • ULTIMATE member
  • *****
  • Karma: 134
  • Posts: 2806
Trying to get article ratings in sNews
« Reply #6 on: December 12, 2006, 12:22:57 AM »

thanks, phil - very timely. i had it working without the error that harry got, but i got some extraneous

's, one after each rating form. the modified code fixed that. very nice.

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #7 on: December 12, 2006, 08:47:18 AM »

Quote from: harry
Getting an error message on items on the category page the have comments (although everything appears to work fine apart from the message). Articles without comments look 100% ok.

Error message reads:
Warning: Division by zero in /home/i/public_html/rater/rater.php on line 84

You can see the error and other-then-that the script working great on this page of my site: http://eslplayground.com/lower/
check this part of rater.php, and make sure the line shown blue here, is what you have in yours...
Quote
// Get current rating
if(is_file($rater_filename)){
 $rater_file=fopen($rater_filename,"r");
 $rater_str="";
 $rater_str = fread($rater_file, 1024*8);
if($rater_str!=""){
  $rater_data=explode($rater_end_of_line_char,$rater_str);
  $rater_votes=count($rater_data)-1;
  $rater_sum=0;
  foreach($rater_data as $d){
   $d=explode("|",$d);
   $rater_sum+=$d[0];
  }
  $rater_rating=number_format(($rater_sum/$rater_votes), 2, '.', '');
 }
« Last Edit: September 14, 2007, 02:52:27 AM by philmoz »
Logged
Of all the things I have lost, it is my mind that I miss the most.

harry

  • Newbie
  • *
  • Karma: 1
  • Posts: 37
    • http://www.thebusinesscardshop.net/order/
Trying to get article ratings in sNews
« Reply #8 on: December 12, 2006, 05:58:43 PM »

I have tried replacing the rater.php with the one you have in this post, but the error message still prevails. So i assume that maybe it is something i have mucked up in snews.php. I will try with the updated insertion points and code tomorrow and see how far i get.

Fred K

  • sNews Dude
  • ULTIMATE member
  • *****
  • Karma: 134
  • Posts: 2806
Trying to get article ratings in sNews
« Reply #9 on: December 12, 2006, 09:33:34 PM »

harry, have you tried changing permissions for the folder where rater.php is stored? When I pushed my site online, I had to change permissions on the rater folder for the script to "take". chmod 777 or 775 works for me, but not 755 or any other version I've tried. N.B: I don't know what -if any- security implications might be involved in doing this.

Have a look at http://www.frdk.com/snews/ if you like, there's one post that's been commented and the rating script seems to be working anyway (now).

Phil? Any ideas?

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #10 on: December 16, 2006, 05:37:11 PM »

harry, have you got this sorted yet??
Logged
Of all the things I have lost, it is my mind that I miss the most.

harry

  • Newbie
  • *
  • Karma: 1
  • Posts: 37
    • http://www.thebusinesscardshop.net/order/
Trying to get article ratings in sNews
« Reply #11 on: December 18, 2006, 03:32:05 PM »

Yeah, kind of mysterious error. Only happened on those 2 articles. After giving the articles ratings the error disappeared.

Also new articles with 1 comment and 0 ratings do not show the error.

This was all with no changes made.

But everything is working great now!!  :D

philmoz

  • High flyer
  • Administrator
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 2001
    • fiddle 'n fly
Trying to get article ratings in sNews
« Reply #12 on: December 18, 2006, 04:08:33 PM »

Are you game to try my version of the script...
Completely rewritten
-- ip can only vote once --- while ip is stored.
-- can set the number of ip's that are stored. When the number is exceeded, the earliest is dropped off.
-- can set the image directory, for easy changing of rating image sets
------- images MUST follow the naming convention, as the code builds the image request

as with the above script, it writes files to a directory (where the script is placed).
It also writes a results file... so instead of calculations done each and every time the rating is required to display, it just looks it up, and generates the display. Calcs are done only on submission of votes.

Can be seen on my site... http://www.fiddlenfolk.com
Test it out -- as far as I know, I'm the only one that has rated anything -- just to make sure it was actually working  ;)

Other parts of the code are very similar to the one above -- particularly the output.
and, as far as I can see, no errors generated -- but not going to claim  standards correctness yet...
Logged
Of all the things I have lost, it is my mind that I miss the most.