[Git][noosfero/noosfero][master] Add Organization Ratings Plugin
Daniela Feitosa
gitlab at gitlab.com
Thu Sep 10 17:39:18 BRT 2015
Daniela Feitosa pushed to branch master at Noosfero / noosfero
Commits:
29249040 by Daniela Feitosa at 2015-09-10T20:33:41Z
Add Organization Ratings Plugin
A plugin that allow users to rate a organization and comment about it.
Signed-off-by: Alexandre Torres <alexandrekry at gmail.com>
Signed-off-by: Andre Bernardes <andrebsguedes at gmail.com>
Signed-off-by: Brenddon Gontijo <brenddongontijo at msn.com>
Signed-off-by: DylanGuedes <djmgguedes at gmail.com>
Signed-off-by: Fabio Teixeira <fabio1079 at gmail.com>
Signed-off-by: Filipe Ribeiro <firibeiro77 at live.com>
Signed-off-by: Gabriela Navarro <navarro1703 at gmail.com
Signed-off-by: Hebert Douglas <hebertdougl at gmail.com>
Signed-off-by: Luciano Prestes Cavalcanti <lucianopcbr at gmail.com>
Signed-off-by: Omar Junior <omarroinuj at gmail.com>
Signed-off-by: Pedro de Lyra <pedrodelyra at gmail.com>
Signed-off-by: Simião Carvalho <simiaosimis at gmail.com>
Signed-off-by: Tallys Martins <tallysmartins at gmail.com>
- - - - -
43 changed files:
- lib/noosfero/plugin.rb
- + plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb
- + plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
- + plugins/organization_ratings/db/migrate/20150830225546_create_organization_ratings.rb
- + plugins/organization_ratings/db/migrate/20150830225733_create_organization_ratings_config.rb
- + plugins/organization_ratings/db/migrate/20150830230047_add_comments_count_to_profile.rb
- + plugins/organization_ratings/features/rate_community.feature
- + plugins/organization_ratings/lib/average_rating_block.rb
- + plugins/organization_ratings/lib/create_organization_rating_comment.rb
- + plugins/organization_ratings/lib/ext/comments.rb
- + plugins/organization_ratings/lib/ext/environment.rb
- + plugins/organization_ratings/lib/ext/organization.rb
- + plugins/organization_ratings/lib/ext/person.rb
- + plugins/organization_ratings/lib/organization_rating.rb
- + plugins/organization_ratings/lib/organization_ratings_block.rb
- + plugins/organization_ratings/lib/organization_ratings_config.rb
- + plugins/organization_ratings/lib/organization_ratings_plugin.rb
- + plugins/organization_ratings/lib/ratings_helper.rb
- + plugins/organization_ratings/public/images/small-star-negative.png
- + plugins/organization_ratings/public/images/small-star-positive.png
- + plugins/organization_ratings/public/images/star-negative-medium.png
- + plugins/organization_ratings/public/images/star-negative.png
- + plugins/organization_ratings/public/images/star-positive-medium.png
- + plugins/organization_ratings/public/images/star-positive.png
- + plugins/organization_ratings/public/images/user-not-logged.png
- + plugins/organization_ratings/public/organization_rating_management.js
- + plugins/organization_ratings/public/rate.js
- + plugins/organization_ratings/style.css
- + plugins/organization_ratings/test/functional/organization_ratings_plugin_admin_controller_test.rb
- + plugins/organization_ratings/test/functional/organization_ratings_plugin_profile_controller_test.rb
- + plugins/organization_ratings/test/unit/organization_rating_config_test.rb
- + plugins/organization_ratings/test/unit/organization_rating_test.rb
- + plugins/organization_ratings/test/unit/ratings_helper_test.rb
- + plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb
- + plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb
- + plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb
- + plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb
- + plugins/organization_ratings/views/organization_ratings_plugin_profile/new_rating.html.erb
- + plugins/organization_ratings/views/shared/_make_report_block.html.erb
- + plugins/organization_ratings/views/shared/_rating_button.html.erb
- + plugins/organization_ratings/views/shared/_user_rating_container.html.erb
- + plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb
- plugins/statistics/lib/statistics_block.rb
Changes:
=====================================
lib/noosfero/plugin.rb
=====================================
--- a/lib/noosfero/plugin.rb
+++ b/lib/noosfero/plugin.rb
@@ -241,6 +241,16 @@ class Noosfero::Plugin
nil
end
+ # -> Customize the way comments are counted for Profiles and Environment
+ # considering more than just articles comments
+ # Used on statistic block
+ # Ex: a plugin may want that Communities receive comments themselves
+ # as evaluations
+ # returns = the number of comments to be sum on the statistics
+ def more_comments_count owner
+ nil
+ end
+
# -> Adds tabs to the profile
# returns = { :title => title, :id => id, :content => content, :start => start }
# title = name that will be displayed.
=====================================
plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb
@@ -0,0 +1,19 @@
+class OrganizationRatingsPluginAdminController < PluginAdminController
+
+ include RatingsHelper
+ helper :ratings
+ append_view_path File.join(File.dirname(__FILE__) + '/../views')
+
+ def index
+ end
+
+ def update
+ if env_organization_ratings_config.update_attributes(params[:organization_ratings_config])
+ session[:notice] = _('Configuration updated successfully.')
+ else
+ session[:notice] = _('Configuration could not be saved.')
+ end
+ render :action => 'index'
+ end
+
+end
\ No newline at end of file
=====================================
plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
@@ -0,0 +1,76 @@
+class OrganizationRatingsPluginProfileController < ProfileController
+ include RatingsHelper
+ helper :ratings
+
+ def new_rating
+ @rating_available = user_can_rate_now?
+ @users_ratings = get_ratings(profile.id).paginate(
+ :per_page => env_organization_ratings_config.per_page,
+ :page => params[:npage]
+ )
+ if request.post?
+ if @rating_available
+ create_new_rate
+ else
+ session[:notice] = _("You can not vote on this %s") % profile.class.name
+ end
+ end
+ end
+
+ private
+
+ def user_can_rate_now?
+ return false unless user
+ ratings = OrganizationRating.where(
+ :organization_id => profile.id,
+ :person_id => user.id
+ )
+
+ return false if (!ratings.empty? && env_organization_ratings_config.vote_once)
+
+ if ratings.empty?
+ true
+ else
+ elapsed_time_since_last_rating = Time.zone.now - ratings.last.created_at
+ elapsed_time_since_last_rating > env_organization_ratings_config.cooldown.hours
+ end
+ end
+
+ def create_new_rate
+ rating = OrganizationRating.new(params[:organization_rating])
+ rating.person = current_user.person
+ rating.organization = profile
+ rating.value = params[:organization_rating_value] if params[:organization_rating_value]
+
+ if rating.save
+ create_rating_comment(rating)
+ session[:notice] = _("%s successfully rated!") % profile.name
+ else
+ session[:notice] = _("Sorry, there were problems rating this profile.")
+ end
+
+ redirect_to :controller => 'profile', :action => 'index'
+ end
+
+ def create_rating_comment(rating)
+ if params[:comments]
+ comment_task = CreateOrganizationRatingComment.create!(
+ params[:comments].merge(
+ :requestor => rating.person,
+ :organization_rating_id => rating.id,
+ :target => rating.organization
+ )
+ )
+ comment_task.finish if can_perform?(params)
+ end
+ end
+
+ def can_perform? (params)
+ (params[:comments][:body].blank? ||
+ !env_organization_ratings_config.are_moderated)
+ end
+
+ def permission
+ :manage_memberships
+ end
+end
=====================================
plugins/organization_ratings/db/migrate/20150830225546_create_organization_ratings.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/db/migrate/20150830225546_create_organization_ratings.rb
@@ -0,0 +1,12 @@
+class CreateOrganizationRatings < ActiveRecord::Migration
+ def change
+ create_table :organization_ratings do |t|
+ t.belongs_to :organization
+ t.belongs_to :person
+ t.belongs_to :comment
+ t.integer :value
+
+ t.timestamps
+ end
+ end
+end
=====================================
plugins/organization_ratings/db/migrate/20150830225733_create_organization_ratings_config.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/db/migrate/20150830225733_create_organization_ratings_config.rb
@@ -0,0 +1,14 @@
+class CreateOrganizationRatingsConfig < ActiveRecord::Migration
+
+ def change
+ create_table :organization_ratings_configs do |t|
+ t.belongs_to :environment
+ t.integer :cooldown, :integer, :default => 24
+ t.integer :default_rating, :integer, :default => 1
+ t.string :order, :string, :default => "recent"
+ t.integer :per_page, :integer, :default => 10
+ t.boolean :vote_once, :boolean, :default => false
+ t.boolean :are_moderated, :boolean, :default => true
+ end
+ end
+end
=====================================
plugins/organization_ratings/db/migrate/20150830230047_add_comments_count_to_profile.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/db/migrate/20150830230047_add_comments_count_to_profile.rb
@@ -0,0 +1,11 @@
+class AddCommentsCountToProfile < ActiveRecord::Migration
+ def self.up
+ change_table :profiles do |t|
+ t.integer :comments_count
+ end
+ end
+
+ def self.down
+ remove_column :profiles, :comments_count
+ end
+end
\ No newline at end of file
=====================================
plugins/organization_ratings/features/rate_community.feature
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/features/rate_community.feature
@@ -0,0 +1,30 @@
+Feature: rate_community
+ As a user
+ I want to be able rate a community
+ So that users can see my feedback about that community
+
+ Background:
+ Given plugin "OrganizationRatings" is enabled on environment
+ Given the following user
+ | login | name |
+ | joaosilva | Joao Silva |
+ And the following community
+ | identifier | name |
+ | mycommunity | My Community |
+ And the following blocks
+ | owner | type |
+ | mycommunity | AverageRatingBlock |
+ | mycommunity | OrganizationRatingsBlock |
+ And the environment domain is "localhost"
+ And I am logged in as "joaosilva"
+
+ @selenium
+ Scenario: display rate button inside average block
+ Given I am on mycommunity's homepage
+ Then I should see "Rate this Community" within ".average-rating-block"
+ And I should see "Be the first to rate" within ".average-rating-block"
+
+ @selenium
+ Scenario: display rate button inside communities ratings block
+ Given I am on mycommunity's homepage
+ Then I should see "Rate Community" within ".make-report-block"
=====================================
plugins/organization_ratings/lib/average_rating_block.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/average_rating_block.rb
@@ -0,0 +1,30 @@
+class AverageRatingBlock < Block
+ include RatingsHelper
+
+ def self.description
+ _('Organization Average Rating')
+ end
+
+ def help
+ _('This block displays the organization average rating.')
+ end
+
+ def content(args = {})
+ profile_identifier = self.owner.identifier
+ average_rating = OrganizationRating.average_rating self.owner.id
+
+ proc do
+ render(
+ :file => 'blocks/display_organization_average_rating',
+ :locals => {
+ :profile_identifier => profile_identifier,
+ :average_rating => average_rating
+ }
+ )
+ end
+ end
+
+ def cacheable?
+ false
+ end
+end
=====================================
plugins/organization_ratings/lib/create_organization_rating_comment.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/create_organization_rating_comment.rb
@@ -0,0 +1,131 @@
+class CreateOrganizationRatingComment < Task
+ include Rails.application.routes.url_helpers
+
+ validates_presence_of :requestor_id, :organization_rating_id, :target_id
+
+ settings_items :organization_rating_id, :type => Integer, :default => nil
+ settings_items :organization_rating_comment_id, :type => Integer, :default => nil
+
+ attr_accessible :organization_rating_id, :body, :requestor
+ attr_accessible :reject_explanation, :target
+
+ before_save :update_comment_body
+
+ DATA_FIELDS = ['body']
+ DATA_FIELDS.each do |field|
+ settings_items field.to_sym
+ end
+
+ def update_comment_body
+ if self.organization_rating_comment_id.nil?
+ create_comment
+ else
+ comment = Comment.find_by_id(self.organization_rating_comment_id)
+ comment.body = get_comment_message
+ comment.save
+ end
+ end
+
+ def create_comment
+ if (self.body && !self.body.blank?)
+ comment_body = _("Comment waiting for approval")
+ comment = Comment.create!(:source => self.target, :body => comment_body, :author => self.requestor)
+
+
+ self.organization_rating_comment_id = comment.id
+ link_comment_with_its_rating(comment)
+ end
+ end
+
+ def link_comment_with_its_rating(user_comment)
+ rating = OrganizationRating.find(self.organization_rating_id)
+ rating.comment = user_comment
+ rating.save
+ end
+
+ def get_comment_message
+ if self.status == Status::CANCELLED
+ _("Comment rejected")
+ elsif self.status == Status::FINISHED
+ self.body
+ else
+ _("No comment")
+ end
+ end
+
+ def accept_details
+ true
+ end
+
+ def title
+ _("New Comment")
+ end
+
+ def information
+ message = _("<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this %{target_class}") %
+ {:requestor_url => url_for(self.requestor.url), :requestor => self.requestor.name, :target_class => self.target.class.name.downcase}
+
+ {:message => message}
+ end
+
+ def reject_details
+ true
+ end
+
+ def icon
+ {:type => :profile_image, :profile => requestor, :url => requestor.url}
+ end
+
+ # tells if this request was rejected
+ def rejected?
+ self.status == Task::Status::CANCELLED
+ end
+
+ # tells if this request was appoved
+ def approved?
+ self.status == Task::Status::FINISHED
+ end
+
+ def target_notification_description
+ _("%{requestor} wants to create a comment in this \"%{target}\"") %
+ {:requestor => self.requestor.name, :target => self.target.class.name.downcase }
+ end
+
+ def target_notification_message
+ _("User \"%{user}\" just requested to create a comment in the %{target_class}
+ \"%{target_name}\".
+ You have to approve or reject it through the \"Pending Validations\"
+ section in your control panel.\n") %
+ { :user => self.requestor.name, :target_class => self.target.class.name.downcase, :target_name => self.target.name }
+ end
+
+ def task_created_message
+ _("Your request for commenting at %{target} was
+ just sent. Environment administrator will receive it and will approve or
+ reject your request according to his methods and criteria.
+ You will be notified as soon as environment administrator has a position
+ about your request.") %
+ { :target => self.target.name }
+ end
+
+ def task_cancelled_message
+ _("Your request for commenting at %{target} was
+ not approved by the environment administrator. The following explanation
+ was given: \n\n%{explanation}") %
+ { :target => self.target.name,
+ :explanation => self.reject_explanation }
+ end
+
+ def task_finished_message
+ _('Your request for commenting was approved.
+ You can access %{url} to see your comment.') %
+ { :url => ratings_url }
+ end
+
+ private
+
+ def ratings_url
+ url = url_for(self.target.public_profile_url) + "/plugin/organization_ratings/new_rating"
+ end
+
+end
=====================================
plugins/organization_ratings/lib/ext/comments.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/ext/comments.rb
@@ -0,0 +1,6 @@
+require_dependency "comment"
+
+Comment.class_eval do
+
+ has_one :organization_rating
+end
=====================================
plugins/organization_ratings/lib/ext/environment.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/ext/environment.rb
@@ -0,0 +1,5 @@
+require_dependency "environment"
+
+class Environment
+ has_one :organization_ratings_config
+end
=====================================
plugins/organization_ratings/lib/ext/organization.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/ext/organization.rb
@@ -0,0 +1,7 @@
+require_dependency 'organization'
+
+Organization.class_eval do
+ has_many :organization_ratings
+
+ has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc'
+end
=====================================
plugins/organization_ratings/lib/ext/person.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/ext/person.rb
@@ -0,0 +1,5 @@
+require_dependency 'person'
+
+Person.class_eval do
+ has_many :organization_ratings
+end
=====================================
plugins/organization_ratings/lib/organization_rating.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/organization_rating.rb
@@ -0,0 +1,25 @@
+class OrganizationRating < ActiveRecord::Base
+ belongs_to :person
+ belongs_to :organization
+ belongs_to :comment
+
+ attr_accessible :value, :person, :organization, :comment
+
+ validates :value,
+ :presence => true, :inclusion => {
+ in: 1..5, message: _("must be between 1 and 5")
+ }
+
+ validates :organization_id, :person_id,
+ :presence => true
+
+
+ def self.average_rating organization_id
+ average = OrganizationRating.where(organization_id: organization_id).average(:value)
+
+ if average
+ (average - average.truncate) >= 0.5 ? average.ceil : average.floor
+ end
+ end
+
+end
=====================================
plugins/organization_ratings/lib/organization_ratings_block.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/organization_ratings_block.rb
@@ -0,0 +1,30 @@
+class OrganizationRatingsBlock < Block
+ include RatingsHelper
+
+ def self.description
+ _('Organization Ratings')
+ end
+
+ def help
+ _('This block displays the community ratings.')
+ end
+
+ def content(args = {})
+ block = self
+
+ proc do
+ render(
+ :file => 'blocks/organization_ratings_block',
+ :locals => {:block => block}
+ )
+ end
+ end
+
+ def limit_number_of_ratings
+ env_organization_ratings_config.per_page
+ end
+
+ def cacheable?
+ false
+ end
+end
=====================================
plugins/organization_ratings/lib/organization_ratings_config.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/organization_ratings_config.rb
@@ -0,0 +1,53 @@
+class OrganizationRatingsConfig < ActiveRecord::Base
+
+ belongs_to :environment
+
+ attr_accessible :cooldown, :default_rating, :order, :per_page
+ attr_accessible :vote_once, :are_moderated, :environment_id
+
+ ORDER_OPTIONS = {recent: _('More Recent'), best: _('Best Ratings')}
+
+ MINIMUM_RATING = 1
+ MAX_COOLDOWN = 1000
+
+ validates :default_rating,
+ :presence => true, :numericality => {
+ greater_than_or_equal_to: MINIMUM_RATING,
+ less_than_or_equal_to: 5
+ }
+
+ validates :cooldown,
+ :presence => true, :numericality => {
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: MAX_COOLDOWN
+ }
+
+ validates :per_page,
+ :presence => true, :numericality => {
+ :greater_than_or_equal_to => 5,
+ :less_than_or_equal_to => 20
+ }
+
+
+ def order_options
+ ORDER_OPTIONS
+ end
+
+ def minimum_ratings
+ MINIMUM_RATING
+ end
+
+ def max_cooldown
+ MAX_COOLDOWN
+ end
+
+ class << self
+ def instance
+ environment = Environment.default
+ environment.organization_ratings_config || create(environment_id: environment.id)
+ end
+
+ private :new
+ end
+
+end
=====================================
plugins/organization_ratings/lib/organization_ratings_plugin.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/organization_ratings_plugin.rb
@@ -0,0 +1,73 @@
+class OrganizationRatingsPlugin < Noosfero::Plugin
+ include Noosfero::Plugin::HotSpot
+
+ def self.plugin_name
+ "Organization Ratings"
+ end
+
+ def self.plugin_description
+ _("A plugin that allows you to rate a organization and comment about it.")
+ end
+
+ module Hotspots
+ def organization_ratings_plugin_comments_extra_fields
+ nil
+ end
+
+ def organization_ratings_title
+ nil
+ end
+
+ def organization_ratings_plugin_star_message
+ nil
+ end
+
+ def organization_ratings_plugin_extra_fields_show_data user_rating
+ nil
+ end
+ end
+
+ # Plugin Hotspot to display the average rating
+ def display_organization_average_rating organization
+ unless organization.nil?
+ average_rating = OrganizationRating.average_rating organization.id
+
+ Proc::new {
+ render :file => 'blocks/display_organization_average_rating',
+ :locals => {
+ :profile_identifier => organization.identifier,
+ :average_rating => average_rating
+ }
+ }
+ end
+ end
+
+ def more_comments_count owner
+ if owner.kind_of?(Environment) then
+ owner.profiles.sum(:comments_count)
+ elsif owner.kind_of?(Profile) then
+ owner.comments_count
+ else
+ 0
+ end
+ end
+
+ def self.extra_blocks
+ {
+ OrganizationRatingsBlock => {:type => [Enterprise, Community], :position => ['1']},
+ AverageRatingBlock => {:type => [Enterprise, Community]}
+ }
+ end
+
+ def stylesheet?
+ true
+ end
+
+ def js_files
+ %w(
+ public/rate.js
+ public/comunities_rating_management.js
+ )
+ end
+
+end
=====================================
plugins/organization_ratings/lib/ratings_helper.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/lib/ratings_helper.rb
@@ -0,0 +1,15 @@
+module RatingsHelper
+
+ def env_organization_ratings_config
+ OrganizationRatingsConfig.instance
+ end
+
+ def get_ratings (profile_id)
+ order_options = env_organization_ratings_config.order_options
+ if env_organization_ratings_config.order.downcase == order_options[:recent]
+ ratings = OrganizationRating.where(organization_id: profile_id).order("value DESC")
+ else
+ ratings = OrganizationRating.where(organization_id: profile_id).order("created_at DESC")
+ end
+ end
+end
\ No newline at end of file
=====================================
plugins/organization_ratings/public/images/small-star-negative.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/small-star-negative.png differ
=====================================
plugins/organization_ratings/public/images/small-star-positive.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/small-star-positive.png differ
=====================================
plugins/organization_ratings/public/images/star-negative-medium.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/star-negative-medium.png differ
=====================================
plugins/organization_ratings/public/images/star-negative.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/star-negative.png differ
=====================================
plugins/organization_ratings/public/images/star-positive-medium.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/star-positive-medium.png differ
=====================================
plugins/organization_ratings/public/images/star-positive.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/star-positive.png differ
=====================================
plugins/organization_ratings/public/images/user-not-logged.png
=====================================
Binary files /dev/null and b/plugins/organization_ratings/public/images/user-not-logged.png differ
=====================================
plugins/organization_ratings/public/organization_rating_management.js
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/public/organization_rating_management.js
@@ -0,0 +1,35 @@
+(function($) {
+ "use strict";
+
+ var VoteOnce = {
+ init: function() {
+ this.cacheDom();
+ this.setEvents();
+ },
+
+
+ cacheDom: function() {
+ this.$vote_once_checkbox = $("#environment_organization_ratings_vote_once");
+ this.$hours_timer_input = $("#environment_organization_ratings_cooldown");
+ },
+
+
+ setEvents: function() {
+ this.$vote_once_checkbox.on("click", this.verifyHoursTimerDisable.bind(this));
+ },
+
+
+ verifyHoursTimerDisable: function() {
+ if (this.$vote_once_checkbox.is(":checked")) {
+ this.$hours_timer_input.attr("disabled", "disabled");
+ } else {
+ this.$hours_timer_input.removeAttr("disabled");
+ }
+ }
+ }
+
+
+ $(document).ready(function() {
+ VoteOnce.init();
+ });
+}) (jQuery);
=====================================
plugins/organization_ratings/public/rate.js
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/public/rate.js
@@ -0,0 +1,122 @@
+;(function($, undefined) {
+ "use strict";
+
+ /*
+ * All global data that are used in the stars feature.
+ */
+ var DATA = {
+ selected_rate: 0, // The actual selected star when the user click on a star
+ maximum_stars: 5, // (const) The maximum number of allowed stars
+ minimum_stars: 1, // (const) The minimum number of allowed stars
+ DATA_RATE_ATTRIBUTE: "data-star-rate", // (const) The data attribute with the star rate
+ NOT_SELECTED_VALUE: 0 // (const) The value when there is no selected rate
+ }
+
+
+ /*
+ * Prepare the global data that are variable.
+ * If the user already rated the organization, set the selected_rate as the rated value
+ */
+ function set_global_data() {
+ var selected_rate = parseInt($("#selected-star-rate").val());
+ var minimum_stars = parseInt($("#minimum_stars").val());
+ DATA.selected_rate = selected_rate;
+ DATA.minimum_stars = minimum_stars;
+ }
+
+
+ /*
+ * Given a start rate, an end rate and the elements, it makes a regex that filter
+ * the elements by the given range and returns it.
+ */
+ function star_filter(start, end, elements) {
+ var test_regex = undefined;
+
+ // Verify if it is a valid range and makes its range regex: /[start-end]/
+ if (end >= start) {
+ test_regex = new RegExp("["+(start)+"-"+(end)+"]");
+ } else {
+ // If the range is invalid, make a regex that will return no element
+ test_regex = new RegExp("[]");
+ }
+
+ // Filter the elements that are in the given range
+ var result = elements.filter(function(i, element) {
+ var rate = parseInt(element.getAttribute(DATA.DATA_RATE_ATTRIBUTE));
+
+ return test_regex.test(rate);
+ });
+
+ return result;
+ }
+
+
+ /*
+ * Show or hide the stars depending on the mouse position and the limit rate.
+ * Given the mouseover rate, the limit rate and the css classes to be swapped,
+ *
+ * It verify if the user already selected a star rate:
+ * If true:
+ * It swap the css classes from the selected star up to the given limit rate
+ * If false:
+ * It swap the css classes from the minimum rate up to the mouseover rate
+ */
+ function change_stars_class(rate_mouseover, limit_rate, remove_class, add_class) {
+ var previous_stars = undefined;
+
+ // The default not selected rate value is 0 and minimum is 1.
+ if (DATA.selected_rate >= DATA.minimum_stars) {
+ previous_stars = star_filter(DATA.selected_rate+1, limit_rate, $("."+remove_class));
+ } else {
+ previous_stars = star_filter(DATA.minimum_stars, rate_mouseover, $("."+remove_class));
+ }
+
+ previous_stars.switchClass(remove_class, add_class);
+ }
+
+
+ /*
+ * Sets the stars mouse events.
+ */
+ function set_star_hover_actions() {
+ $(".star-negative, .star-positive")
+ .on("mouseover", function() { // On mouse over, show the current rate star
+ var rate_mouseover = parseInt(this.getAttribute(DATA.DATA_RATE_ATTRIBUTE));
+
+ change_stars_class(rate_mouseover, rate_mouseover, "star-negative", "star-positive");
+ })
+
+ .on("mouseout", function() { // On mouse out, hide the stars
+ var rate_mouseover = parseInt(this.getAttribute(DATA.DATA_RATE_ATTRIBUTE));
+
+ change_stars_class(rate_mouseover, DATA.maximum_stars, "star-positive", "star-negative");
+ })
+
+ .on("click", function() { // On mouse click, set the selected star rate
+ var rate_mouseover = parseInt(this.getAttribute(DATA.DATA_RATE_ATTRIBUTE));
+
+ // If the new rate is different from actual, update it
+ if (rate_mouseover !== DATA.selected_rate && rate_mouseover > DATA.minimum_stars) {
+ DATA.selected_rate = rate_mouseover;
+ } else { // or else, uncheck it
+ DATA.selected_rate = DATA.minimum_stars;
+ }
+
+ // Mark the selected_rate
+ $("#selected-star-rate").val(DATA.selected_rate);
+
+ var star_notice = $(".star-notice");
+ star_notice.find("span").html(DATA.selected_rate);
+ star_notice.removeClass("star-hide");
+ });
+ }
+
+
+ /*
+ * When the page DOM is ready, set all the stars events
+ */
+ $(document).ready(function() {
+ set_global_data();
+ set_star_hover_actions();
+ });
+}) (jQuery);
=====================================
plugins/organization_ratings/style.css
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/style.css
@@ -0,0 +1,200 @@
+.star-container {
+ width: 100%;
+ height: 20px;
+}
+
+.star-negative, .star-positive {
+ width: 20px;
+ height: 20px;
+ background-repeat: no-repeat;
+ margin-right: 2px;
+ position: relative;
+ float: left;
+ cursor: pointer;
+}
+
+.star-negative {
+ background-image: url('public/images/star-negative.png');
+}
+
+.star-positive {
+ background-image: url('public/images/star-positive.png');
+}
+
+.small-star-negative, .small-star-positive {
+ background-repeat: no-repeat;
+ float: left;
+ height: 15px;
+ margin-right: 2px;
+ position: relative;
+ width: 15px;
+}
+
+.small-star-negative {
+ background-image: url('public/images/small-star-negative.png');
+}
+
+.small-star-positive {
+ background-image: url('public/images/small-star-positive.png');
+}
+
+.medium-star-negative, .medium-star-positive {
+ background-repeat: no-repeat;
+ float: left;
+ height: 20px;
+ margin-right: 2px;
+ position: relative;
+ width: 20px;
+}
+
+.medium-star-positive {
+ background-image: url('public/images/star-positive-medium.png');
+}
+
+.medium-star-negative {
+ background-image: url('public/images/star-negative-medium.png');
+}
+
+.star-hide {
+ display: none;
+}
+
+.organization-average-rating-container {
+ border-top: 1px dotted #D3D6DE;
+ margin-top: 20px;
+ padding-top: 10px;
+}
+
+.organization-average-rating-container .star-rate-text {
+ float: left;
+ margin-right: 10px;
+ padding-top: 5px;
+}
+
+.organization-average-rating-container .rating-invitation {
+ font-size: 14px;
+ float: left;
+ margin-right: 10px;
+ padding-top: 3px;
+}
+
+.organization-average-rating-container .star-container {
+ float: left;
+ width: 120px;
+}
+
+.organization-average-rating-container .rate-this-organization {
+ border-left: 1px dotted #D3D6DE;
+ float: left;
+ padding: 4px 0px 2px 10px;
+}
+
+.star-rate-data {
+ width: 100%;
+ padding-top: 20px;
+ position: relative;
+ overflow: auto;
+}
+
+.star-profile-information, .star-rate-form {
+ display: table-cell;
+ vertical-align: top;
+ width: 362px;
+}
+
+.star-profile-information {
+ width: 134px;
+}
+
+.star-rate-form {
+ display: table-cell;
+ vertical-align: top;
+}
+
+.star-profile-image, .star-profile-name {
+ text-align: center;
+}
+
+.star-profile-name {
+ word-break: break-word;
+ margin: auto;
+ margin-top: 5px;
+ width: 66px;
+}
+
+.star-rate-data .star-rate-form .star-comment-container .formfield textarea {
+ width: 361px;
+}
+
+/************* Users ratings list ****************/
+
+.ratings-list .user-rating-block,
+.ratings-list .make-report-block {
+ border-top: 1px solid #D3D6DE;
+ margin-top: 25px;
+ padding-top: 20px;
+}
+
+.ratings-list .make-report-block {
+ padding-bottom: 25px;
+}
+
+.ratings-list .see-more{
+ border-top: 1px solid #D3D6DE;
+}
+.ratings-list .user-rating-block .user-testimony-container {
+ display: table-cell;
+ padding-left: 20px;
+}
+
+.ratings-list .make-report-block .make-report-container {
+ display: table-cell;
+}
+
+.ratings-list .user-rating-block .user-testimony-container .star-container {
+ display: table-cell;
+}
+
+.ratings-list .user-rating-block .user-testimony-container .testimony-rate-date {
+ display: table-cell;
+ max-width: 95px;
+ min-width: 95px;
+ padding-right: 160px;
+ white-space: nowrap;
+}
+
+.ratings-list .user-rating-block .user-testimony-container .user-testimony {
+ margin-top: 10px;
+ word-break: break-word;
+}
+
+.ratings-list .make-report-block .make-report-container .make-report-message {
+ font-size: 14px;
+ font-style: italic;
+ word-break: break-word;
+}
+
+.ratings-list .make-report-block .make-report-container .button-bar {
+ overflow: auto;
+ padding-top: 15px;
+}
+
+.ratings-list .user-rating-block .star-profile-information {
+ border-right: 1px dotted #D3D6DE;
+}
+
+.ratings-list .icon-arrow-right-p {
+ background: url(/designs/themes/base/imgs/arrow-right-p.png) 100% 50% no-repeat;
+ display: block;
+ float: right;
+ margin-top: 20px;
+ padding-right: 15px;
+}
+
+.task_information .comment {
+ padding-left: 60px;
+}
+
+.average-rating-block {
+ height: 55px;
+}
=====================================
plugins/organization_ratings/test/functional/organization_ratings_plugin_admin_controller_test.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/test/functional/organization_ratings_plugin_admin_controller_test.rb
@@ -0,0 +1,49 @@
+require File.expand_path(File.dirname(__FILE__)) + '/../../../../test/test_helper'
+require File.expand_path(File.dirname(__FILE__)) + '/../../controllers/organization_ratings_plugin_admin_controller'
+
+# Re-raise errors caught by the controller.
+class OrganizationRatingsPluginAdminController; def rescue_action(e) raise e end; end
+
+class OrganizationRatingsPluginAdminControllerTest < ActionController::TestCase
+
+ def setup
+ @controller = OrganizationRatingsPluginAdminController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @environment = Environment.default
+ @environment.enabled_plugins = ['OrganizationRatingsPlugin']
+ @environment.save
+
+ @community = Community.create(:name => "TestCommunity")
+
+ login_as(create_admin_user(@environment))
+ end
+
+ test "should update organization rating plugin configuration" do
+ post :update, :organization_ratings_config => { :default_rating => 5,
+ :cooldown => 12,
+ :order => "recent",
+ :per_page => 10,
+ :vote_once => true }
+
+ assert :success
+ @environment.reload
+ assert_equal 5, @environment.organization_ratings_config.default_rating
+ assert_equal "Configuration updated successfully.", session[:notice]
+ end
+
+ test "should not update organization rating plugin configuration with negative cooldown time" do
+ post :update, :organization_ratings_config => { :default_rating => 5,
+ :cooldown => -50,
+ :order => "recent",
+ :per_page => 10,
+ :vote_once => true }
+
+ assert :success
+ @environment.reload
+ assert_equal 24, @environment.organization_ratings_config.cooldown
+ assert_equal "Configuration could not be saved.", session[:notice]
+ end
+end
+
=====================================
plugins/organization_ratings/test/functional/organization_ratings_plugin_profile_controller_test.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/test/functional/organization_ratings_plugin_profile_controller_test.rb
@@ -0,0 +1,104 @@
+require File.expand_path(File.dirname(__FILE__)) + '/../../../../test/test_helper'
+require File.expand_path(File.dirname(__FILE__)) + '/../../controllers/organization_ratings_plugin_profile_controller'
+
+# Re-raise errors caught by the controller.
+class OrganizationRatingsPluginProfileController; def rescue_action(e) raise e end; end
+
+class OrganizationRatingsPluginProfileControllerTest < ActionController::TestCase
+
+ def setup
+ @controller = OrganizationRatingsPluginProfileController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @environment = Environment.default
+ @environment.enabled_plugins = ['OrganizationRatingsPlugin']
+ @environment.save
+
+ @person = create_user('testuser').person
+ @community = Community.create(:name => "TestCommunity")
+ @enterprise = fast_create(Enterprise)
+ @config = OrganizationRatingsConfig.instance
+ login_as(@person.identifier)
+ @controller.stubs(:logged_in?).returns(true)
+ @controller.stubs(:current_user).returns(@person.user)
+ end
+
+ test "should add new comment to community" do
+ post :new_rating, profile: @community.identifier, :comments => {:body => "This is a test"}, :organization_rating_value => 4
+ assert_equal "#{@community.name} successfully rated!", session[:notice]
+ end
+
+ test "Create community_rating without comment body" do
+ post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => 2
+
+ assert_equal "#{@community.name} successfully rated!", session[:notice]
+ end
+
+ test "Do not create community_rating without a rate value" do
+ post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => nil
+
+ assert_equal "Sorry, there were problems rating this profile.", session[:notice]
+ end
+
+ test "do not create two ratings on Community when vote once config is true" do
+ post :new_rating, profile: @community.identifier, :comments => {:body => "This is a test"}, :organization_rating_value => 3
+
+ assert_equal "#{@community.name} successfully rated!", session[:notice]
+
+ @environment.organization_ratings_config.vote_once = true
+ @environment.save
+
+ post :new_rating, profile: @community.identifier, :comments => {:body => "This is a test 2"}, :organization_rating_value => 3
+ assert_equal "You can not vote on this Community", session[:notice]
+ end
+
+ test "do not create two ratings on Enterprise when vote once config is true" do
+ post :new_rating, profile: @enterprise.identifier, :comments => {:body => "This is a test"}, :organization_rating_value => 3
+
+ assert_equal "#{@enterprise.name} successfully rated!", session[:notice]
+
+ @environment.organization_ratings_config.vote_once = true
+ @environment.save
+
+ post :new_rating, profile: @enterprise.identifier, :comments => {:body => "This is a test 2"}, :organization_rating_value => 3
+ assert_equal "You can not vote on this Enterprise", session[:notice]
+ end
+
+ test "should count organization ratings on statistic block when block owner = Environment" do
+ block = StatisticsBlock.new
+ enterprise = fast_create(Enterprise)
+ post :new_rating, profile: enterprise.identifier, :comments => {:body => "body board"}, :organization_rating_value => 1
+ enterprise.reload
+ @environment.reload
+ block.expects(:owner).at_least_once.returns(@environment)
+ assert_equal 1, block.comments
+ end
+
+
+ test "should count organization ratings on statistic block when block owner = Profile" do
+ @config.cooldown = 0
+ @config.save
+
+ block = StatisticsBlock.new
+
+ post :new_rating, profile: @community.identifier, :comments => {:body => "body board"}, :organization_rating_value => 1
+ post :new_rating, profile: @community.identifier, :comments => {:body => "body surf"}, :organization_rating_value => 5
+
+ block.expects(:owner).at_least_once.returns(@community)
+ @community.reload
+ assert_equal 2, block.comments
+ end
+
+ test "Display unavailable rating message for users that must wait the rating cooldown time" do
+ post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => 3
+ assert_not_match(/The administrators set the minimum time of/, @response.body)
+ valid_rating = OrganizationRating.last
+
+ post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => 3
+ assert_match(/The administrators set the minimum time of/, @response.body)
+ new_rating = OrganizationRating.last
+
+ assert_equal valid_rating.id, new_rating.id
+ end
+end
=====================================
plugins/organization_ratings/test/unit/organization_rating_config_test.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/test/unit/organization_rating_config_test.rb
@@ -0,0 +1,43 @@
+require File.expand_path(File.dirname(__FILE__)) + '/../../../../test/test_helper'
+
+class OrganizationRatingConfigTest < ActiveSupport::TestCase
+
+ def setup
+ @environment = Environment.default
+ @environment.enabled_plugins = ['OrganizationRatingsPlugin']
+ @environment.save
+ @organization_ratings_config = OrganizationRatingsConfig.instance
+ end
+
+ test "Community ratings config default rating validation" do
+ @organization_ratings_config.default_rating = 0
+ @organization_ratings_config.save
+
+ assert_equal false, @organization_ratings_config.valid?
+ assert_equal "must be greater than or equal to 1", @organization_ratings_config.errors[:default_rating].first
+
+ @organization_ratings_config.default_rating = 6
+ assert_equal false, @organization_ratings_config.valid?
+
+ assert_equal "must be less than or equal to 5", @organization_ratings_config.errors[:default_rating].first
+ end
+
+ test "Communities ratings config cooldown validation" do
+ @organization_ratings_config.cooldown = -1
+ assert_equal false, @organization_ratings_config.valid?
+
+ assert_equal "must be greater than or equal to 0", @organization_ratings_config.errors[:cooldown].first
+ end
+
+ # test "communities ratings per page validation" do
+ # environment = Environment.new :communities_ratings_per_page => 4
+ # environment.valid?
+
+ # assert_equal "must be greater than or equal to 5", environment.errors[:communities_ratings_per_page].first
+
+ # environment.communities_ratings_per_page = 21
+ # environment.valid?
+
+ # assert_equal "must be less than or equal to 20", environment.errors[:communities_ratings_per_page].first
+ # end
+end
=====================================
plugins/organization_ratings/test/unit/organization_rating_test.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/test/unit/organization_rating_test.rb
@@ -0,0 +1,154 @@
+require File.expand_path(File.dirname(__FILE__)) + '/../../../../test/test_helper'
+
+class OrganizationRatingTest < ActiveSupport::TestCase
+ test "The value must be between 1 and 5" do
+ organization_rating1 = OrganizationRating.new :value => -1
+ organization_rating2 = OrganizationRating.new :value => 6
+
+ assert_equal false, organization_rating1.valid?
+ assert_equal false, organization_rating2.valid?
+
+ assert_equal true, organization_rating1.errors[:value].include?("must be between 1 and 5")
+ assert_equal true, organization_rating2.errors[:value].include?("must be between 1 and 5")
+
+ organization_rating1.value = 1
+ organization_rating1.valid?
+
+ organization_rating2.value = 5
+ organization_rating2.valid?
+
+ assert_equal false, organization_rating1.errors[:value].include?("must be between 1 and 5")
+ assert_equal false, organization_rating2.errors[:value].include?("must be between 1 and 5")
+ end
+
+ test "Create task for create a rating comment" do
+ person = create_user('molly').person
+ person.email = "person at email.com"
+ person.save!
+
+ community = fast_create(Community)
+ community.add_admin(person)
+
+ organization_rating = OrganizationRating.create!(
+ :value => 3,
+ :person => person,
+ :organization => community
+ )
+
+ create_organization_rating_comment = CreateOrganizationRatingComment.create!(
+ :requestor => person,
+ :organization_rating_id => organization_rating.id,
+ :target => community
+ )
+
+ assert community.tasks.include?(create_organization_rating_comment)
+ end
+
+ test "Check comment message when Task status = ACTIVE" do
+ person = create_user('molly').person
+ person.email = "person at email.com"
+ person.save!
+
+ community = fast_create(Community)
+ community.add_admin(person)
+
+
+ organization_rating = OrganizationRating.create!(
+ :value => 3,
+ :person => person,
+ :organization => community
+ )
+
+ create_organization_rating_comment = CreateOrganizationRatingComment.create!(
+ :requestor => person,
+ :organization_rating_id => organization_rating.id,
+ :target => community,
+ :body => "sample comment"
+ )
+ assert_equal 1, create_organization_rating_comment.status
+ message = "Comment waiting for approval"
+ comment = Comment.find_by_id(create_organization_rating_comment.organization_rating_comment_id)
+ assert_equal message, comment.body
+ end
+
+ test "Check comment message when Task status = CANCELLED" do
+ person = create_user('molly').person
+ person.email = "person at email.com"
+ person.save!
+
+ community = fast_create(Community)
+ community.add_admin(person)
+
+
+ organization_rating = OrganizationRating.create!(
+ :value => 3,
+ :person => person,
+ :organization => community
+ )
+
+ create_organization_rating_comment = CreateOrganizationRatingComment.create!(
+ :requestor => person,
+ :organization_rating_id => organization_rating.id,
+ :target => community,
+ :body => "sample comment"
+ )
+ create_organization_rating_comment.cancel
+ assert_equal 2, create_organization_rating_comment.status
+ message = "Comment rejected"
+ comment = Comment.find_by_id(create_organization_rating_comment.organization_rating_comment_id)
+ assert_equal message, comment.body
+ end
+
+ test "Check comment message when Task status = FINISHED" do
+ person = create_user('molly').person
+ person.email = "person at email.com"
+ person.save!
+
+ community = fast_create(Community)
+ community.add_admin(person)
+
+ comment = Comment.create!(source: community,
+ body: "regular comment",
+ author: person)
+
+ organization_rating = OrganizationRating.create!(
+ :value => 3,
+ :person => person,
+ :organization => community,
+ :comment => comment
+ )
+
+ create_organization_rating_comment = CreateOrganizationRatingComment.create!(
+ :body => comment.body,
+ :requestor => organization_rating.person,
+ :organization_rating_id => organization_rating.id,
+ :target => organization_rating.organization,
+ :body => "sample comment"
+ )
+
+ create_organization_rating_comment.finish
+ assert_equal 3, create_organization_rating_comment.status
+ message = "sample comment"
+ comment = Comment.find_by_id(create_organization_rating_comment.organization_rating_comment_id)
+ assert_equal message, comment.body
+ end
+
+
+ test "Should calculate community's rating average" do
+ community = fast_create Community
+ p1 = fast_create Person, :name=>"Person 1"
+ p2 = fast_create Person, :name=>"Person 2"
+ p3 = fast_create Person, :name=>"Person 3"
+
+ OrganizationRating.create! :value => 2, :organization => community, :person => p1
+ OrganizationRating.create! :value => 3, :organization => community, :person => p2
+ OrganizationRating.create! :value => 5, :organization => community, :person => p3
+
+ assert_equal 3, OrganizationRating.average_rating(community)
+
+ p4 = fast_create Person, :name=>"Person 4"
+ OrganizationRating.create! :value => 4, :organization => community, :person => p4
+
+ assert_equal 4, OrganizationRating.average_rating(community)
+ end
+end
=====================================
plugins/organization_ratings/test/unit/ratings_helper_test.rb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/test/unit/ratings_helper_test.rb
@@ -0,0 +1,63 @@
+require File.expand_path(File.dirname(__FILE__)) + '/../../../../test/test_helper'
+require 'ratings_helper'
+
+class RatingsHelperTest < ActiveSupport::TestCase
+ include RatingsHelper
+
+ def setup
+
+ @environment = Environment.default
+ @environment.enabled_plugins = ['OrganizationRatingsPlugin']
+ @environment.save
+ @person = create_user('testuser').person
+ @community = Community.create(:name => "TestCommunity")
+ @organization_ratings_config = OrganizationRatingsConfig.instance
+ end
+
+ should "get the ratings of a community ordered by most recent ratings" do
+ ratings_array = []
+
+ first_rating = OrganizationRating.new
+ first_rating.organization = @community
+ first_rating.person = @person
+ first_rating.value = 3
+ first_rating.save
+
+ most_recent_rating = OrganizationRating.new
+ most_recent_rating.organization = @community
+ most_recent_rating.person = @person
+ most_recent_rating.value = 5
+ sleep 2
+ most_recent_rating.save
+
+ ratings_array << most_recent_rating
+ ratings_array << first_rating
+
+ assert_equal @organization_ratings_config.order, "recent"
+ assert_equal ratings_array, get_ratings(@community.id)
+ end
+
+ should "get the ratings of a community ordered by best ratings" do
+ ratings_array = []
+ @organization_ratings_config = "best"
+ @environment.save
+
+ first_rating = OrganizationRating.new
+ first_rating.organization = @community
+ first_rating.person = @person
+ first_rating.value = 3
+ first_rating.save
+
+ second_rating = OrganizationRating.new
+ second_rating.organization = @community
+ second_rating.person = @person
+ second_rating.value = 5
+ sleep 2
+ second_rating.save
+
+ ratings_array << second_rating
+ ratings_array << first_rating
+
+ assert_equal ratings_array, get_ratings(@community.id)
+ end
+end
=====================================
plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb
@@ -0,0 +1,25 @@
+<div class="organization-average-rating-container">
+ <% if average_rating %>
+ <div class="star-rate-text">
+ <%= _("Rating: ") %>
+ </div>
+
+ <div class="star-container">
+ <% (1..5).each do |star_number| %>
+ <% if star_number <= average_rating %>
+ <div class="medium-star-positive"></div>
+ <% else %>
+ <div class="medium-star-negative"></div>
+ <% end %>
+ <% end %>
+ </div>
+ <% else %>
+ <div class="rating-invitation">
+ <%= _("Be the first to rate!") %>
+ </div>
+ <% end %>
+
+ <div class="rate-this-organization">
+ <%= link_to _("Rate this %s" % profile.class.name), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile=>profile_identifier) %>
+ </div>
+</div>
\ No newline at end of file
=====================================
plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb
@@ -0,0 +1,21 @@
+<div class="ratings-title">
+ <%= block_title(block.title) %>
+ <% if block.get_ratings(block.owner.id).empty? %>
+ <div class="ratings-list">
+ <%= render :partial => 'shared/make_report_block' %>
+ </div>
+ <% else %>
+ <div class="ratings-list">
+ <% block.get_ratings(block.owner.id).each_with_index do |r, index| %>
+ <% break if index >= block.limit_number_of_ratings %>
+ <%= render :partial => "shared/user_rating_container", :locals => {:user_rate => r} %>
+ <% end %>
+
+ <%= render :partial => 'shared/make_report_block' %>
+
+ <div class="see-more">
+ <%= link_to _('See more'), url_for(:controller => 'organization_ratings_plugin_profile', :action => 'new_rating'), :class => 'icon-arrow-right-p' %>
+ </div>
+ </div>
+ <% end %>
+</div>
=====================================
plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb
@@ -0,0 +1,54 @@
+<% config = env_organization_ratings_config %>
+
+<h1><%= _("Organization Rating Management") %> </h1>
+
+<%= labelled_form_for(:organization_ratings_config, :url => {:action => 'update'}) do |f| %>
+ <%= labelled_fields_for(:organization_ratings_config, config) do |c| %>
+ <table>
+ <tr>
+ <th><%= c_('Configuration') %></th>
+ <th><%= _('Value') %></th>
+ </tr>
+ <tr>
+ <td><%= _('Default amount of stars marked on evaluations') %></td>
+ <td><%= c.select :default_rating, (config.minimum_ratings)..5 %></td>
+ </tr>
+ <tr>
+ <td><%= _('Can rate an organization only once') %></td>
+ <td><%= c.check_box :vote_once %></td>
+ </tr>
+ <tr>
+ <td><%= _('The comments are moderated') %></td>
+ <td><%= c.check_box :are_moderated %></td>
+ </tr>
+ <tr>
+ <td>
+ <%= _('Time in hours between evaluations from the same user.') %>
+ <span class="hint" title=" <%= _('To disable cooldown use zero (0) value.') %> ">(?)</span>
+ </td>
+ <% hours_options = {size: 2} %>
+ <% hours_options[:disabled] = "disabled" if config.vote_once %>
+ <td><%= c.text_field :cooldown, hours_options %>
+ </td>
+ </tr>
+ <tr>
+ <td><%= _('Order ratings by') %></td>
+ <% order_options = [] %>
+ <% config.order_options.select{|k,v| order_options << v } %>
+ <td><%= c.select :order, order_options %></td>
+ </tr>
+ <tr>
+ <td><%= _('Ratings per page') %></td>
+ <td>
+ <%= c.select :per_page, 5..20 %>
+ </td>
+ </tr>
+ </table>
+ <div>
+ <% button_bar do %>
+ <%= submit_button('save', c_('Save changes')) %>
+ <%= button :back, _('Back'), :controller => 'plugins' %>
+ <% end %>
+ </div>
+ <% end %>
+<% end %>
=====================================
plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb
@@ -0,0 +1,80 @@
+<% min_rate = env_organization_ratings_config.minimum_ratings %>
+<% default_rating = env_organization_ratings_config.default_rating %>
+
+<div class="star-page-title">
+ <%= @plugins.dispatch(:organization_ratings_title).collect { |content| instance_exec(&content) }.join("") %>
+</div>
+
+<div class="star-rate-data">
+
+ <div class="star-profile-information">
+ <div class="star-profile-image">
+ <%= profile_image(current_user.person, :portrait) %>
+ </div>
+
+ <div class="star-profile-name">
+ <%= current_user.name %>
+ </div>
+ </div>
+
+ <% if @rating_available %>
+ <div class="star-rate-form">
+ <div data-rate-url=<%= url_for controller: "organization_ratings_plugin_profile", :action => "rate" %>>
+ <div class="star-rate-text">
+ <%= @plugins.dispatch(:organization_ratings_plugin_star_message).collect { |content| instance_exec(&content) }.join("") %>
+ </div>
+
+ <div class="star-container" data-min-rate="<%= min_rate %>">
+
+ <% (1..5).each do |rate_number| %>
+ <% if rate_number <= default_rating %>
+ <div class="star-positive" data-star-rate="<%= rate_number %>"></div>
+ <% else %>
+ <div class="star-negative" data-star-rate="<%= rate_number %>"></div>
+ <% end %>
+ <% end %>
+ </div>
+
+ <div class="star-notice star-hide">
+ <%= _("Rated as") %> <span></span> <%= _("stars") %>
+ </div>
+ </div>
+
+ <div class="star-comment-container">
+ <%= form_for :comments do |c| %>
+ <div class="formfieldline formfield type-text">
+ <%= c.label :body, _('Comment (Optional):'), :class => "formlabel" %>
+ <%= c.text_area :body %>
+ </div>
+
+ <%= @plugins.dispatch(:organization_ratings_plugin_comments_extra_fields).collect { |content| instance_exec(&content) }.join("") %>
+
+ <div class="button-bar">
+ <%= submit_button(:save, _('Save'), :cancel => {controller: 'profile', action: 'index'}) %>
+ </div>
+
+ <input type="hidden" id="selected-star-rate" name="organization_rating_value" value="<%= @default_rate %>">
+ <input type="hidden" id="minimum_stars" name="organization_rating_min_value" value="<%= min_rate %>">
+ <% end %>
+ </div>
+
+ <% elsif env_organization_ratings_config.vote_once %>
+ <div class="star-rate-form rating-vote-once">
+ <%= _("Hi, %s! The administrators set that you can vote") % current_user.name %>
+ <strong><%= _("only once") %></strong>
+ <%= _("for this %s.") % profile.class.name.downcase %>
+ <%= render :partial => 'shared/rating_button', :locals => { :disabled => true } %>
+ </div>
+ <% else %>
+ <div class="star-rate-form rating-cooldown">
+ <%= _("Hi, %s! The administrators set the minimum time of") % current_user.name %>
+ <strong><%= _("%s hour(s)" % env_organization_ratings_config.cooldown) %></strong>
+ <%= _("between each evaluation.") %>
+
+ <%= render :partial => 'shared/rating_button', :locals => { :disabled => true } %>
+ </div>
+ <% end %>
+
+
+ </div>
+</div>
\ No newline at end of file
=====================================
plugins/organization_ratings/views/organization_ratings_plugin_profile/new_rating.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/organization_ratings_plugin_profile/new_rating.html.erb
@@ -0,0 +1,18 @@
+<% config = env_organization_ratings_config %>
+<% if logged_in? %>
+ <%= render :partial => "new_rating_fields" %>
+<% else %>
+ <div class="ratings-list">
+ <%= render :partial => "shared/make_report_block" %>
+ </div>
+<% end %>
+
+<div class="ratings-list">
+ <% @users_ratings.each do |user_rate| %>
+ <%= render :partial => "shared/user_rating_container", :locals => {:user_rate => user_rate} %>
+ <% end %>
+</div>
+
+<div id='pagination-profiles'>
+ <%= pagination_links @users_ratings, :param_name => 'npage' %>
+</div>
\ No newline at end of file
=====================================
plugins/organization_ratings/views/shared/_make_report_block.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/shared/_make_report_block.html.erb
@@ -0,0 +1,28 @@
+<% logged_in_image = profile_image(current_user.person, :portrait) if current_user %>
+<% logged_out_image = image_tag('plugins/organization_ratings/public/images/user-not-logged.png') %>
+
+<div class="make-report-block">
+ <div class="star-profile-information">
+ <div class="star-profile-image">
+ <%= logged_in? ? logged_in_image : logged_out_image %>
+ </div>
+
+ <div class="star-profile-name">
+ <%= logged_in? ? current_user.person.name : _('User not logged *') %>
+ </div>
+ </div>
+
+ <div class="make-report-container">
+ <div class="make-report-message">
+ <%= _('Report your experiences.') %>
+ </div>
+
+ <%= render :partial => 'shared/rating_button', :locals => { :disabled => false } %>
+
+ <% unless logged_in? %>
+ <div class="alert">
+ <%= _('* You must be logged in to submit a report.') %>
+ </div>
+ <% end %>
+ </div>
+</div>
\ No newline at end of file
=====================================
plugins/organization_ratings/views/shared/_rating_button.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/shared/_rating_button.html.erb
@@ -0,0 +1,10 @@
+<% button_bar do %>
+ <% if logged_in? %>
+ <%= button(:new,_("Rate %s ") % profile.class.name,
+ {:controller => "organization_ratings_plugin_profile",
+ :action => "new_rating"}) %>
+ <% else %>
+ <%= button(:login,_("Log in") , {:controller => 'account',
+ :action => 'login'}) %>
+ <% end %>
+<% end %>
=====================================
plugins/organization_ratings/views/shared/_user_rating_container.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/shared/_user_rating_container.html.erb
@@ -0,0 +1,33 @@
+<div class="user-rating-block">
+ <div class="star-profile-information">
+ <div class="star-profile-image">
+ <%= profile_image(user_rate.person, :portrait) %>
+ </div>
+
+ <div class="star-profile-name">
+ <%= user_rate.person.name %>
+ </div>
+ </div>
+
+ <div class="user-testimony-container">
+ <div class="testimony-rate-date">
+ <%= time_ago_in_words(user_rate.created_at) %>
+ </div>
+
+ <div class="star-container">
+ <% (1..5).each do |rate_number| %>
+ <% if rate_number <= user_rate.value %>
+ <div class="small-star-positive"></div>
+ <% else %>
+ <div class="small-star-negative"></div>
+ <% end %>
+ <% end %>
+ </div>
+
+ <div class="user-testimony">
+ <%= user_rate.comment.nil? ? _("No comment") : user_rate.comment.body %>
+ </div>
+
+ <%= @plugins.dispatch(:organization_ratings_plugin_extra_fields_show_data, user_rate).collect { |content| instance_exec(&content) }.join("") %>
+ </div>
+</div>
=====================================
plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb
=====================================
--- /dev/null
+++ b/plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb
@@ -0,0 +1,4 @@
+<div class="organization-rating-comment-body">
+ <%= _("Comment:")%>
+ <%= "\"#{task.body}\""%>
+</div>
=====================================
plugins/statistics/lib/statistics_block.rb
=====================================
--- a/plugins/statistics/lib/statistics_block.rb
+++ b/plugins/statistics/lib/statistics_block.rb
@@ -128,11 +128,12 @@ class StatisticsBlock < Block
end
end
+ include Noosfero::Plugin::HotSpot
def comments
if owner.kind_of?(Environment) then
- owner.profiles.joins(:articles).sum(:comments_count).to_i
+ owner.articles.sum(:comments_count).to_i + plugins.dispatch(:more_comments_count, owner).first.to_i
elsif owner.kind_of?(Profile) then
- owner.articles.sum(:comments_count)
+ owner.articles.sum(:comments_count) + plugins.dispatch(:more_comments_count, owner).first.to_i
else
0
end
View it on GitLab: https://gitlab.com/noosfero/noosfero/commit/29249040654c0a8948afeb1748ddd3f3e6819042
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150910/75c2f6ac/attachment-0001.html>
More information about the Noosfero-dev
mailing list