NodeReview works perfect for 'normal' and 'label' rating types, but throws an error for 'fivestar' rating type.
The error message is: "An illegal choice has been detected. Please contact the site administrator."
And in the log: I can see nodereview entries like: 'Illegal choice 100 in Score element.'

It seems it tries to assing values such as 100, 80, 60, 40, 20 according to the number of stars in fivestars.
I wonder if it shouldn´t be 1, 2, 3, 4, 5...

Has anyone found similar behaviour?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yaworsk’s picture

I haven't run into that issue but haven't used the new dev version yet.

that said, the 100,80,60,40,20 are correct - fivestar uses the voting api module and that is how votes are recorded. I've never had an issue with the previous version of the module using those values.

i'll try to check it out tonight and see if i get a similar issue.

oscardax’s picture

Thanks yaworsk for trying to recreate the issue.
I´m using the following versions:
NodeReview 6.x-1.x-dev (2011-Apr-16)
Fivestar 6.x-1.19
Voting API 6.x-2.3
Drupal core 6.22

I´ve reinstalled Voting API, Fivestar and NodeReview since I´ve been playing with different voting types ('normal' and 'label') to clean out previous votes, just in case votes of different types might be causing confusion to 'fivestar'... but the issue remains active yet.

Actually, I realize I can vote 1 or 2 stars (20 or 40 values), but cannot 3, 4, nor 5 (60, 40, 100 values).

oscardax’s picture

Status: Active » Needs review
FileSize
617 bytes

This patch seems to solve the problem for me.
In sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc, the loop in line 100 was provinding the following values....

$options[10]=1
$options[20]=2
$options[30]=3
$options[40]=4
$options[50]=5

...and that´s why it could only be selected 1 star (value 20) and 2 stars (value 40), because the other ones had values higher than 50 (namely: 60, 80, 100).

I've tried to create a patch following this post, with the command below:

diff -up
sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc
sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc.new
> nodereview/nodereview-fivestar_type_illegal_choice-1176242-3.patch.n

Though I´m not very sure it is the right way. Please someone to provide a proper patch if mine is not ok.

The patch content is as follows:

--- sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc 2011-04-15 15:40:47.000000000 +0100
+++ sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc.new 2011-06-05 12:46:52.000000000 +0100
@@ -96,7 +96,10 @@ function _nodereview_form_review(&$form,
for ($i = 1; $i < ($maxrating + 1); $i++) {
if (NODEREVIEW_LABEL_ENABLE) {
$options[$i * 10] = variable_get('nodereview_rating_label' . $i, '');;
- }
+ }
+ elseif (NODEREVIEW_FIVESTAR_ENABLE) {
+ $options[$i * 20] = $i);
+ }
else {
$options[$i * 10] = $i;
}

oscardax’s picture

The previous patch had an extra ) in line $options[$i * 20] = $i);
The corrected patch looks as follows

--- sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc 2011-04-15 15:40:47.000000000 +0100
+++ sites/all/modules/nodereview-6.x-1.x-dev/nodereview/nodereview_node_nodereview.inc.new 2011-06-05 12:46:52.000000000 +0100
@@ -96,7 +96,10 @@ function _nodereview_form_review(&$form,
for ($i = 1; $i < ($maxrating + 1); $i++) {
if (NODEREVIEW_LABEL_ENABLE) {
$options[$i * 10] = variable_get('nodereview_rating_label' . $i, '');;
- }
+ }
+ elseif (NODEREVIEW_FIVESTAR_ENABLE) {
+ $options[$i * 20] = $i;
+ }
else {
$options[$i * 10] = $i;
}

yaworsk’s picture

Hi Oscarda,
you're right on pointing out it's the loop on line 100. The patch you provided is a little off - it actually deletes the nodereview_node_nodereview.inc file and creates one with .inc.new... not sure if you know (i didn't until the most recent drupalcon), but there are instructions for every project on using GIT - you can find teh nodereview instructions here: http://drupal.org/project/nodereview/git-instructions

That said, I think the math is a little off in the patch as well. Looking at the code, the values of options need to equate to 100 (i.e., 100%), so if you have 5 options, each should be weighted as 20, or 2 options, each should be weighted as 50. Right now, the module bases the math on 10 options, so each option is being multipled by 10. With your code, each option is being multiplied by 20 so it would work if there were 5 options but it wouldn't help anyone using 2,3,4,etc. options.

I'm going to work on it now and should have the patch done soon.

Pete

oscardax’s picture

Thanks sincerely yaworsk for your comments and explanations, and sorry for the mess!! I've just got Git set up for proper patching in the future.

Following your clarification for the math, the for-loop in general may welcome the correction you suggest, which I think is the one in the code below. I've tested it for the 3 voting types (normal, label, fivestar), with different values for 'Maximum Rating' (in admin/content/nodereview), and checked that the % stored in votingapi_vote covers all the range till 100%.
Anyway after 2 wrong patches from my side, I better may just wait for yours.

if (NODEREVIEW_LABEL_ENABLE) {
$options[$i * 100/$maxrating] = variable_get('nodereview_rating_label' . $i, '');
}
else {
$options[$i * 100/$maxrating] = $i;
}

Thanks again!!

yaworsk’s picture

Assigned: Unassigned » yaworsk
FileSize
3.15 KB

My pleasure.

Here is the patch, a little different from yours but it does the same thing (I just create a weight variable which has the 100/$maxrating).

However, in testing some things out, I noticed that the calculation for the average weight in the hook_nodeapi function call in the .module file also assumes a 10 point rating. I tried to address that in the patch.

Lastly, I added a validation function to the configuration page so that if you are using fivestar, you cant choose values that don't give you 'nice' numbers for fivestar --- that is, if you are using a 6 point scale and choose a rating of 5, you'll get an error. As a result, the validation function won't let you choose a value other than 1, 2, 4, 5, or 10 -- all values which give you even numbers of a base 10 when divided by 100.

Only thing I didn't really test was the values being written to the database.

oscardax’s picture

Thanks for the patch yaworsk.
I've tested the correct storage of values in the database and seems to work all right.

The only weird thing that comes up is the display of values retrieved from the DB (now that the storage bug has been sorted out, the old buggy display begs for a similar fix). For instance playing around with $maxrating and the voting type (normal, label, fivestar) I've seen things like "6,6/3" instead of "2/3".

I think the fix could be in the hook nodereview_nodeapi() at line 394 in the .module file:

    if (NODEREVIEW_FIVESTAR_ENABLE) {
          $total = $total . '%';
        }
        elseif (NODEREVIEW_LABEL_ENABLE) {
--       $total = variable_get('nodereview_rating_label' . round($total/10), '');
++       $total = variable_get('nodereview_rating_label' . round($total/$weight), '');
        }
        else {
--       $total = round($total/$weight) . '/' . $maxrating;
++       $total = round($total/$weight);

Anyway, I don´t know if this should go to a different issue.

yaworsk’s picture

yeah, i saw similar things and that's what prompted me to work on the nodereview_nodeapi() function. I did it quickly so probably messed something up along the way. I'll have to take a look at it, hopefully tonight or tomorrow.

yaworsk’s picture

I was testing this tonight and couldn't replicate the issue. Can you provide some more details?

pete

oscardax’s picture

To replicate the strange behaviour I commented in #8:
1) install nodereview
2) apply the patch in comment #7
3) provide several ratings for a given node with maxrating = 10
4) change maxrating to 6, for instance
5) provide additional ratings for the same node in (3)
6) re-visit the node in (3), and you should see strange reviews like 8,8/6

I think the bug is in the 2 lines I suggested to change in comment #8.
--bug $total = variable_get('nodereview_rating_label' . round($total/10), '');
++sugestion $total = variable_get('nodereview_rating_label' . round($total/$weight), '');
(since the value we enter in the database, after applying the patch in #7, is "$i * $weight", instead of the old "$i*10": ""$options[$i * $weight] = variable_get('nodereview_rating_label' . $i, '');"")

--bug $total = round($total/$weight) . '/' . $maxrating;
++sugestion $total = round($total/$weight);
(since "$weight = 100 / $maxrating;" we are dividing twice by $maxrating: )

Applying manually these 2 changes, the reviews seem to behave correctly in my test environment.
I hope this can be of some help.

yaworsk’s picture

Thanks for the detailed steps, that helps.

I think you are right with:
++sugestion $total = variable_get('nodereview_rating_label' . round($total/$weight), '');

However, with regards to:
--bug $total = round($total/$weight) . '/' . $maxrating;
++sugestion $total = round($total/$weight);

We are only dividing once with round($total/weight) - the . '/' . is actually creating the string to pass back as the average score, so we get something like 5/5.

That said, there is a problem if you have an existing bunch of reviews with a max rating of 10 and then you switch up that max rating after the fact. There are two things to do there, you can stop administrators from switching the axis max rating once you have existing reviews or you have to update all the existing scores in the database to be relative to the new max. i.e., if a node had a rating of 5 / 10 and the max rating is switched to 5, that review should be updated to 2.5 / 5. However, this could be a pretty intensive job given the number of existing reviews, so my recommendation would be to prohibit people to changing the max score.

oscardax’s picture

Thanks yaworsk again for spotting a fault in my suggested solution. I missread the string concatenation as an expression.

Regarding the numerical calcultations, for some reason I wrongly thought that the stored values in the database were normalized to 100; this is: a 1/4 rating would store like 25; and if you change maxrating to 10, then the retieved 25 would be translated to 2.5/10. But I realize now from your explanation that it doesn't work like that.

Thank God there is peer-review in open-source, or for every minor fix a bunch of bugs would slip in.

yaworsk’s picture

No worries on the misreading, I was actually updating the code and about to save it then looked it for a second and realized what it was actually doing.

I have to revisit how the scores are saved to confirm - I think you're right that they are normalized to 100 but only when using fivestar because it uses the votingapi which bases everyone on 100 (that's why you can only use total votes of 1, 2, 5 or 10). However, I can't remember off the top of my head if the actual value is also stored in one of the tables, I'd have to confirm.

Definitely agreed on the peer review.

danielhonrade’s picture

I think this is a problem with fivestars, there are certain maximum numbers which fivestars is not compatible with, like 3, 6, 7, 9, works with 1, 2, 4, 5, 8, 10

BTW, I made changes to all ratings, I discovered some bugs.
Like total reviews should be based on user and content_id and not on content_id alone

You can now easily convert from normal rating to label to fivestars, and from 1 to 10 max ratings because of this new variables, with the exception of some max numbers above for fivestars :

$maxrating_proportion = round(($score_from_voting_api/100) * NODEREVIEW_MAXRATING);

The voting api always gets from 0 to 100 values, so our maximum rating will always adjust the current value proportionate to maximum rating, like:

3/6 - max of 6 becomes 5/10 on max of 10

danielhonrade’s picture

Status: Needs review » Fixed
yaworsk’s picture

What happens when you have something like 5/6 and go to an axis of 10? You can't have an 8.3 stars...

danielhonrade’s picture

Max of six is not working for fivestars, as I mentioned previously, "I think this is a problem with fivestars, there are certain maximum numbers which fivestars is not compatible with, like 3, 6, 7, 9, works with 1, 2, 4, 5, 8, 10".

Probably the solution is, we put a limit to every type of rating?
1) Normal 1 - 100
2) Label 1 - 10
3) Fivestars - 1 - 5

I am just wondering now that since it's called fivestars, should it be just fivestars and not more?

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.