Index: lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java =================================================================== diff -u -r1c42119baf51e12d0ef19919cb5a266a186d4b7d -r65dbec4aea67b0a746b4f08f24168fb4a5d7f9f6 --- lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java (.../RatingServlet.java) (revision 1c42119baf51e12d0ef19919cb5a266a186d4b7d) +++ lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java (.../RatingServlet.java) (revision 65dbec4aea67b0a746b4f08f24168fb4a5d7f9f6) @@ -25,7 +25,11 @@ import java.io.IOException; import java.text.NumberFormat; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; +import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -37,8 +41,11 @@ import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.rating.dto.ItemRatingCriteriaDTO; +import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; import org.lamsfoundation.lams.rating.model.LearnerItemRatingCriteria; +import org.lamsfoundation.lams.rating.model.Rating; import org.lamsfoundation.lams.rating.model.RatingCriteria; +import org.lamsfoundation.lams.rating.model.ToolActivityRatingCriteria; import org.lamsfoundation.lams.rating.service.RatingService; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.WebUtil; @@ -75,37 +82,59 @@ // get rating value as either float or comment String try { - if (criteria.isCommentsEnabled()) { - String comment = WebUtil.readStrParam(request, "comment"); - ratingService.commentItem(criteria, userId, itemId, comment); - JSONObject.put("comment", StringEscapeUtils.escapeCsv(comment)); + boolean doSave = true; + + Long maxRatingsForItem = WebUtil.readLongParam(request, "maxRatingsForItem", true); + log.debug("RatingServlet: Check Max rates for an item reached. Item "+itemId+" criteria id "+criteria.getRatingCriteriaId()+" maxRatingsForItem "+maxRatingsForItem); + if ( maxRatingsForItem != null && maxRatingsForItem > 0) { + if ( ! ToolActivityRatingCriteria.class.isInstance(criteria) ) { + log.error("Unable to enforce max ratings on a non ToolActivityRatingCritera class. Need tool content id to do the db lookup!"); + } else { + ToolActivityRatingCriteria toolCriteria = (ToolActivityRatingCriteria) criteria; + List itemIds = new LinkedList(); + itemIds.add(itemId); + Map itemIdToRatedUsersCountMap = ratingService.countUsersRatedEachItem(toolCriteria.getToolContentId(), itemIds, userId.intValue()); + Long currentRatings = itemIdToRatedUsersCountMap.get(itemId); + if ( currentRatings != null && maxRatingsForItem.compareTo(currentRatings) <= 0 ) { + JSONObject.put("error", true); + JSONObject.put("message", "Maximum number of ratings for this item has been reached. No more may be saved."); + log.debug("RatingServlet: Max rates for an item reached. Item "+itemId+" criteria id "+criteria.getRatingCriteriaId()+" count "+currentRatings); + doSave = false; + } + } + } - } else { - float rating = Float.parseFloat((String) request.getParameter("rate")); + if ( doSave ) { + if (criteria.isCommentsEnabled()) { + String comment = WebUtil.readStrParam(request, "comment"); + ratingService.commentItem(criteria, userId, itemId, comment); + JSONObject.put("comment", StringEscapeUtils.escapeCsv(comment)); + } else { + float rating = Float.parseFloat((String) request.getParameter("rate")); - ItemRatingCriteriaDTO averageRatingDTO = ratingService.rateItem(criteria, userId, itemId, rating); + ItemRatingCriteriaDTO averageRatingDTO = ratingService.rateItem(criteria, userId, itemId, rating); - NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); - numberFormat.setMaximumFractionDigits(1); - JSONObject.put("userRating", numberFormat.format(rating)); - JSONObject.put("averageRating", averageRatingDTO.getAverageRating()); - JSONObject.put("numberOfVotes", averageRatingDTO.getNumberOfVotes()); - } - + NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); + numberFormat.setMaximumFractionDigits(1); + JSONObject.put("userRating", numberFormat.format(rating)); + JSONObject.put("averageRating", averageRatingDTO.getAverageRating()); + JSONObject.put("numberOfVotes", averageRatingDTO.getNumberOfVotes()); + } - boolean hasRatingLimits = WebUtil.readBooleanParam(request, "hasRatingLimits", false); - // refresh countRatedItems in case there is rating limit set - if (hasRatingLimits) { - // as long as this can be requested only for LEARNER_ITEM_CRITERIA_TYPE type, cast Criteria - LearnerItemRatingCriteria learnerItemRatingCriteria = (LearnerItemRatingCriteria) criteria; - Long toolContentId = learnerItemRatingCriteria.getToolContentId(); + boolean hasRatingLimits = WebUtil.readBooleanParam(request, "hasRatingLimits", false); - int countRatedItems = ratingService.getCountItemsRatedByUser(toolContentId, userId); - JSONObject.put("countRatedItems", countRatedItems); + // refresh countRatedItems in case there is rating limit set + if (hasRatingLimits) { + // as long as this can be requested only for LEARNER_ITEM_CRITERIA_TYPE type, cast Criteria + LearnerItemRatingCriteria learnerItemRatingCriteria = (LearnerItemRatingCriteria) criteria; + Long toolContentId = learnerItemRatingCriteria.getToolContentId(); + + int countRatedItems = ratingService.getCountItemsRatedByUser(toolContentId, userId); + JSONObject.put("countRatedItems", countRatedItems); + } } - } catch (JSONException e) { throw new ServletException(e); } Index: lams_central/web/includes/javascript/rating.js =================================================================== diff -u -r1c42119baf51e12d0ef19919cb5a266a186d4b7d -r65dbec4aea67b0a746b4f08f24168fb4a5d7f9f6 --- lams_central/web/includes/javascript/rating.js (.../rating.js) (revision 1c42119baf51e12d0ef19919cb5a266a186d4b7d) +++ lams_central/web/includes/javascript/rating.js (.../rating.js) (revision 65dbec4aea67b0a746b4f08f24168fb4a5d7f9f6) @@ -1,41 +1,46 @@ -//Please, set up LAMS_URL, COUNT_RATED_ITEMS, COMMENTS_MIN_WORDS_LIMIT, MAX_RATES and MIN_RATES, +//Please, set up LAMS_URL, COUNT_RATED_ITEMS, COMMENTS_MIN_WORDS_LIMIT, MAX_RATES and MIN_RATES, MAX_RATINGS_FOR_ITEM, //COMMENT_TEXTAREA_TIP_LABEL, WARN_COMMENTS_IS_BLANK_LABEL, WARN_MIN_NUMBER_WORDS_LABEL constants in parent document //constant indicating there is rting limits set up var HAS_RATING_LIMITS; $(document).ready(function(){ HAS_RATING_LIMITS = MAX_RATES!=0 || MIN_RATES!=0; - + initializeJRating(); //check minimum rates limit initially if (MIN_RATES != 0) { checkMinimumRatesLimit(COUNT_RATED_ITEMS); } + }); -//initialize jRating and post comment button +//initialize jRating and post comment button. Note: we need the quotes around undefined for the typeof ! function initializeJRating() { + + var maxRatingsForItem; + if ( typeof MAX_RATINGS_FOR_ITEM === "undefined" || MAX_RATINGS_FOR_ITEM === undefined ) + maxRatingsForItem = ""; + else + maxRatingsForItem = MAX_RATINGS_FOR_ITEM; $(".rating-stars-new").filter($(".rating-stars")).jRating({ - phpPath : LAMS_URL + "servlet/rateItem?hasRatingLimits=" + HAS_RATING_LIMITS, + phpPath : LAMS_URL + "servlet/rateItem?hasRatingLimits=" + HAS_RATING_LIMITS+"&maxRatingsForItem="+maxRatingsForItem, rateMax : 5, decimalLength : 1, onSuccess : function(data, itemId){ - $("#user-rating-" + itemId).html(data.userRating); $("#average-rating-" + itemId).html(data.averageRating); $("#number-of-votes-" + itemId).html(data.numberOfVotes); $("#rating-stars-caption-" + itemId).css("visibility", "visible"); //handle rating limits if available handleRatingLimits(data.countRatedItems); - }, onError : function(){ - jError('Error. Please, retry'); + handleError(); } }); @@ -82,25 +87,31 @@ data: { idBox: commentsCriteriaId + '-' + itemId, comment: comment, - hasRatingLimits: HAS_RATING_LIMITS + hasRatingLimits: HAS_RATING_LIMITS, + maxRatingsForItem: MAX_RATINGS_FOR_ITEM }, success: function(data, textStatus) { - - //add comment to HTML - jQuery('
', { - 'class': "rating-comment", - html: data.comment - }).appendTo('#comments-area-' + itemId); - - //hide comments textarea and button - $("#add-comment-area-" + itemId).hide(); - - //handle rating limits if available - if (HAS_RATING_LIMITS) { - handleRatingLimits(data.countRatedItems); - } - - } + if ( data.error ) { + handleError(); + } else { + //add comment to HTML + jQuery('
', { + 'class': "rating-comment", + html: data.comment + }).appendTo('#comments-area-' + itemId); + + //hide comments textarea and button + $("#add-comment-area-" + itemId).hide(); + + //handle rating limits if available + if (HAS_RATING_LIMITS) { + handleRatingLimits(data.countRatedItems); + } + } + }, + onError : function(){ + handleError(); + } }); //apply only once }).removeClass("add-comment-new"); @@ -139,4 +150,13 @@ function checkMinimumRatesLimit(countRatedItems) { $( "#learner-submit" ).toggle( countRatedItems >= MIN_RATES ); -} \ No newline at end of file +} + +function handleError() { + //callback function + if (typeof onRatingErrorCallback === "function") { + onRatingErrorCallback(); + } else { + alert("Error saving rating. Please retry."); + } +}