jiffyshirts_spree_reviews 2.3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +6 -0
  6. data/Guardfile +9 -0
  7. data/LICENSE.md +26 -0
  8. data/README.md +54 -0
  9. data/Rakefile +15 -0
  10. data/app/assets/images/store/reviews/delete.gif +0 -0
  11. data/app/assets/images/store/reviews/star.gif +0 -0
  12. data/app/assets/javascripts/spree/backend/jiffyshirts_spree_reviews.js +7 -0
  13. data/app/assets/javascripts/spree/frontend/jiffyshirts_spree_reviews.js +7 -0
  14. data/app/assets/stylesheets/spree/backend/jiffyshirts_spree_reviews.css +3 -0
  15. data/app/assets/stylesheets/spree/frontend/jiffyshirts_spree_reviews.css.erb +83 -0
  16. data/app/controllers/spree/admin/feedback_reviews_controller.rb +6 -0
  17. data/app/controllers/spree/admin/review_settings_controller.rb +21 -0
  18. data/app/controllers/spree/admin/reviews_controller.rb +34 -0
  19. data/app/controllers/spree/feedback_reviews_controller.rb +41 -0
  20. data/app/controllers/spree/products_controller_decorator.rb +5 -0
  21. data/app/controllers/spree/reviews_controller.rb +48 -0
  22. data/app/helpers/spree/reviews_helper.rb +17 -0
  23. data/app/models/spree/feedback_review.rb +17 -0
  24. data/app/models/spree/product_decorator.rb +21 -0
  25. data/app/models/spree/review.rb +36 -0
  26. data/app/models/spree/reviews_ability.rb +17 -0
  27. data/app/models/spree/reviews_configuration.rb +23 -0
  28. data/app/overrides/add_reviews_after_product_properties.rb +5 -0
  29. data/app/overrides/add_reviews_tab_to_admin.rb +4 -0
  30. data/app/overrides/add_reviews_to_admin_configuration_sidebar.rb +5 -0
  31. data/app/overrides/fix_highlighting_of_products_tab.rb +5 -0
  32. data/app/views/spree/admin/feedback_reviews/index.html.erb +44 -0
  33. data/app/views/spree/admin/review_settings/edit.html.erb +40 -0
  34. data/app/views/spree/admin/reviews/_form.html.erb +22 -0
  35. data/app/views/spree/admin/reviews/edit.html.erb +26 -0
  36. data/app/views/spree/admin/reviews/index.html.erb +111 -0
  37. data/app/views/spree/feedback_reviews/_form.html.erb +13 -0
  38. data/app/views/spree/feedback_reviews/_summary.html.erb +6 -0
  39. data/app/views/spree/feedback_reviews/create.js.erb +7 -0
  40. data/app/views/spree/reviews/_form.html.erb +27 -0
  41. data/app/views/spree/reviews/_stars.html.erb +13 -0
  42. data/app/views/spree/reviews/index.html.erb +1 -0
  43. data/app/views/spree/reviews/new.html.erb +3 -0
  44. data/app/views/spree/shared/_rating.html.erb +15 -0
  45. data/app/views/spree/shared/_review.html.erb +24 -0
  46. data/app/views/spree/shared/_review_summary.html.erb +9 -0
  47. data/app/views/spree/shared/_reviews.html.erb +15 -0
  48. data/app/views/spree/shared/_shortrating.html.erb +9 -0
  49. data/config/initializers/constants.rb +1 -0
  50. data/config/initializers/load_preferences.rb +5 -0
  51. data/config/locales/de-CH.yml +67 -0
  52. data/config/locales/de.yml +67 -0
  53. data/config/locales/en-GB.yml +67 -0
  54. data/config/locales/en.yml +65 -0
  55. data/config/locales/es.yml +67 -0
  56. data/config/locales/fr.yml +67 -0
  57. data/config/locales/pl.yml +71 -0
  58. data/config/locales/pt-BR.yml +67 -0
  59. data/config/locales/pt.yml +68 -0
  60. data/config/locales/ro.yml +75 -0
  61. data/config/locales/ru.yml +73 -0
  62. data/config/locales/sv.yml +65 -0
  63. data/config/locales/tr.yml +67 -0
  64. data/config/routes.rb +17 -0
  65. data/db/migrate/20081020220724_create_reviews.rb +21 -0
  66. data/db/migrate/20101222083309_create_feedback_reviews.rb +17 -0
  67. data/db/migrate/20110406083603_add_rating_to_products.rb +21 -0
  68. data/db/migrate/20110606150524_add_user_to_reviews.rb +9 -0
  69. data/db/migrate/20110806093221_add_ip_address_to_reviews.rb +9 -0
  70. data/db/migrate/20120110172331_namespace_tables.rb +6 -0
  71. data/db/migrate/20120123141326_recalculate_ratings.rb +20 -0
  72. data/db/migrate/20120712182514_add_locale_to_reviews.rb +9 -0
  73. data/db/migrate/20120712182627_add_locale_to_feedback_reviews.rb +9 -0
  74. data/db/sample/ratings.yml +16 -0
  75. data/db/sample/reviews.yml +59 -0
  76. data/jiffyshirts_spree_reviews.gemspec +31 -0
  77. data/lib/generators/jiffyshirts_spree_reviews/install/install_generator.rb +30 -0
  78. data/lib/jiffyshirts_spree_reviews/engine.rb +23 -0
  79. data/lib/jiffyshirts_spree_reviews.rb +4 -0
  80. data/script/rails +5 -0
  81. data/spec/controllers/admin/feedback_reviews_controller_spec.rb +29 -0
  82. data/spec/controllers/admin/review_settings_controller_spec.rb +57 -0
  83. data/spec/controllers/admin/reviews_controller_spec.rb +63 -0
  84. data/spec/controllers/feedback_reviews_controller_spec.rb +71 -0
  85. data/spec/controllers/products_controller_spec.rb +9 -0
  86. data/spec/controllers/reviews_controller_spec.rb +136 -0
  87. data/spec/factories/feedback_review_factory.rb +8 -0
  88. data/spec/factories/review_factory.rb +15 -0
  89. data/spec/features/admin_spec.rb +35 -0
  90. data/spec/features/reviews_spec.rb +106 -0
  91. data/spec/helpers/review_helper_spec.rb +28 -0
  92. data/spec/models/feedback_review_spec.rb +78 -0
  93. data/spec/models/product_spec.rb +62 -0
  94. data/spec/models/review_spec.rb +169 -0
  95. data/spec/models/reviews_ability_spec.rb +46 -0
  96. data/spec/models/reviews_configuration_spec.rb +45 -0
  97. data/spec/spec_helper.rb +48 -0
  98. data/vendor/assets/javascripts/jquery.rating.js +376 -0
  99. metadata +339 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cd4ee18548affb28ed0d9ee64e900d47ba704280
4
+ data.tar.gz: 5c248b18db06d3614be6afc6729e7c74422517bf
5
+ SHA512:
6
+ metadata.gz: eb207aba2f483a65703670d677d54c35fba18a9acf3099627e392db1c2a165f14c42046cd30d9bd8794b14470ceb79bc934d2c0e0350299193a2b7b4f91be4a7
7
+ data.tar.gz: bd808587a7477ad999b9645c94bc8f75f99a50830d7d95797c3c0a63eb3c944926547ad2e7b04b53a2d79eb73e89d7741271bc19d53a8d2ab75568ee899f2667
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ *.swp
3
+ .bundle
4
+ .idea
5
+ .DS_Store
6
+ Gemfile.lock
7
+ pkg/*
8
+ spec/dummy
9
+ coverage
10
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ before_script:
2
+ - "sh -e /etc/init.d/xvfb start"
3
+ - "bundle exec rake test_app"
4
+ script:
5
+ - "export DISPLAY=:99.0"
6
+ - "bundle exec rspec spec"
7
+ rvm:
8
+ - 1.9.3
9
+ - 2.0.0
10
+ - 2.1.0
11
+ language: ruby
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'spree', github: 'spree/spree', branch: '2-3-stable'
4
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-3-stable'
5
+
6
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ guard "rspec", cmd: "bundle exec rspec" do
2
+ watch("spec/spec_helper.rb") { "spec" }
3
+ watch("config/routes.rb") { "spec/controllers" }
4
+ watch("app/controllers/application_controller.rb") { "spec/controllers" }
5
+ watch(%r{^spec/(.+)_spec\.rb$}) { |m| "spec/#{m[1]}_spec.rb"}
6
+ watch(%r{^app/(.+)_decorator\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch(%r{^(app|lib)/(.+)(\.rb|\.erb)$}) { |m| "spec/#{m[2]}_spec.rb" }
8
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb" }
9
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2014 Spree Commerce and contributors.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ Reviews
2
+ =======
3
+
4
+
5
+ Straightforward review/rating functionality.
6
+
7
+ Installation
8
+ ------------
9
+
10
+ Add the following to your `Gemfile` to install from git:
11
+ ```ruby
12
+ gem 'jiffyshirts_spree_review'
13
+ ```
14
+ Now bundle up with:
15
+
16
+ bundle
17
+
18
+ Next, run the rake task that copies the necessary migrations and assets to your project:
19
+
20
+ rails g jiffyshirts_spree_reviews:install
21
+
22
+ And finish with a migrate:
23
+
24
+ rake db:migrate
25
+
26
+ Now you should be able to boot up your server with:
27
+
28
+ rails s
29
+
30
+ That's all!
31
+
32
+ Usage
33
+ -----
34
+
35
+ Action "submit" in "reviews" controller - goes to review entry form
36
+
37
+ Users must be logged in to submit a review
38
+
39
+ Three partials:
40
+ - `app/views/spree/products/_rating.html.erb` -- display number of stars
41
+ - `app/views/spree/products/_shortrating.html.erb` -- shorter version of above
42
+ - `app/views/spree/products/_review.html.erb` -- display a single review
43
+
44
+ Administrator can edit and/or approve and/or delete reviews.
45
+
46
+ Implementation
47
+ --------------
48
+
49
+ Reviews table is quite obvious - and note the "approved" flag which is for the
50
+ administrator to update.
51
+
52
+ Ratings table holds current fractional value - avoids frequent recalc...
53
+
54
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/common_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default => [:spec]
10
+
11
+ desc 'Generates a dummy app for testing'
12
+ task :test_app do
13
+ ENV['LIB_NAME'] = 'jiffyshirts_spree_reviews'
14
+ Rake::Task['common:test_app'].invoke 'Spree::User'
15
+ end
@@ -0,0 +1,7 @@
1
+ //= require jquery.rating
2
+ //= require spree/backend
3
+
4
+ // Navigating to a page with ratings via TurboLinks shows the radio buttons
5
+ $(document).on('page:load', function () {
6
+ $('input[type=radio].star').rating();
7
+ });
@@ -0,0 +1,7 @@
1
+ //= require jquery.rating
2
+ //= require spree/frontend
3
+
4
+ // Navigating to a page with ratings via TurboLinks shows the radio buttons
5
+ $(document).on('page:load', function () {
6
+ $('input[type=radio].star').rating();
7
+ });
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require spree/backend
3
+ */
@@ -0,0 +1,83 @@
1
+ /*
2
+ *= require spree/frontend
3
+ */
4
+
5
+ #reviews div.header {
6
+ margin-top: 10px;
7
+ margin-bottom: 10px;
8
+ }
9
+
10
+ .lit {
11
+ background-color: #aaaaaa;
12
+ color: #0000bb;
13
+ margin-right: 1px;
14
+ padding-left: 1px;
15
+ }
16
+
17
+ .unlit {
18
+ background-color: #aaaaaa;
19
+ color: #000000;
20
+ margin-right: 1px;
21
+ padding-left: 1px;
22
+ }
23
+
24
+ .star-rating-control {
25
+ display: inline-block;
26
+ height: 14px;
27
+ }
28
+
29
+ .review_hr {
30
+ size: 1px;
31
+ background: silver;
32
+ border: none;
33
+ margin: 1em 0;
34
+ }
35
+
36
+ /* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */
37
+ div.rating-cancel, div.star-rating {
38
+ float: left;
39
+ width: 17px;
40
+ height: 16px;
41
+ text-indent: -999em;
42
+ cursor: pointer;
43
+ display: block;
44
+ background: transparent;
45
+ overflow: hidden
46
+ }
47
+
48
+ div.rating-cancel, div.rating-cancel a {
49
+ background: transparent url(<%= asset_path('store/reviews/delete.gif') %>) no-repeat scroll 0 -1px;
50
+ }
51
+
52
+ div.star-rating, div.star-rating a {
53
+ background: url(<%= asset_path('store/reviews/star.gif') %>) no-repeat 0 0px
54
+ }
55
+
56
+ div.rating-cancel a, div.star-rating a {
57
+ display: block;
58
+ width: 16px;
59
+ height: 100%;
60
+ background-position: 0 0px;
61
+ border: 0
62
+ }
63
+
64
+ div.star-rating-on a {
65
+ background-position: 0 -32px !important
66
+ }
67
+
68
+ div.star-rating-hover a {
69
+ background-position: 0 -32px
70
+ }
71
+
72
+ /* Read Only CSS */
73
+ div.star-rating-readonly a {
74
+ cursor: default !important
75
+ }
76
+
77
+ /* Partial Star CSS */
78
+ div.star-rating {
79
+ background: transparent !important;
80
+ overflow: hidden !important
81
+ }
82
+
83
+ /* END jQuery.Rating Plugin CSS */
@@ -0,0 +1,6 @@
1
+ class Spree::Admin::FeedbackReviewsController < Spree::Admin::ResourceController
2
+ belongs_to 'spree/review'
3
+ def index
4
+ @collection = parent.feedback_reviews
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ class Spree::Admin::ReviewSettingsController < Spree::Admin::BaseController
2
+ before_filter :process_unset_checkboxes, only: [:update]
3
+
4
+ def update
5
+ Spree::Reviews::Config.set(params[:preferences])
6
+
7
+ respond_to do |format|
8
+ format.html do
9
+ redirect_to edit_admin_review_settings_path
10
+ end
11
+ end
12
+ end
13
+
14
+ def process_unset_checkboxes
15
+ # workaround for unset checkbox behaviour
16
+ params[:preferences] ||= {}
17
+ Spree::ReviewsConfiguration.boolean_preferences.each do |sym|
18
+ params[:preferences][sym] = false if params[:preferences][sym].blank?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ class Spree::Admin::ReviewsController < Spree::Admin::ResourceController
2
+ helper Spree::ReviewsHelper
3
+
4
+ def index
5
+ @reviews = collection
6
+ end
7
+
8
+ def approve
9
+ r = Spree::Review.find(params[:id])
10
+
11
+ if r.update_attribute(:approved, true)
12
+ flash[:notice] = Spree.t("info_approve_review")
13
+ else
14
+ flash[:error] = Spree.t("error_approve_review")
15
+ end
16
+ redirect_to admin_reviews_path
17
+ end
18
+
19
+ def edit
20
+ if @review.product.nil?
21
+ flash[:error] = Spree.t("error_no_product")
22
+ redirect_to admin_reviews_path and return
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def collection
29
+ params[:q] ||= {}
30
+
31
+ @search = Spree::Review.ransack(params[:q])
32
+ @collection = @search.result.includes([:product, :user, :feedback_reviews]).page(params[:page]).per(params[:per_page])
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ class Spree::FeedbackReviewsController < Spree::StoreController
2
+ helper Spree::BaseHelper
3
+
4
+ before_filter :sanitize_rating, only: [:create]
5
+ before_filter :load_review, only: [:create]
6
+
7
+ def create
8
+
9
+ if @review.present?
10
+ @feedback_review = @review.feedback_reviews.new(feedback_review_params)
11
+ @feedback_review.user = spree_current_user
12
+ @feedback_review.locale = I18n.locale.to_s if Spree::Reviews::Config[:track_locale]
13
+ authorize! :create, @feedback_review
14
+ @feedback_review.save
15
+ end
16
+
17
+ respond_to do |format|
18
+ format.html { redirect_to :back }
19
+ format.js { render :action => :create }
20
+ end
21
+
22
+ end
23
+
24
+ protected
25
+ def load_review
26
+ @review ||= Spree::Review.find_by_id!(params[:review_id])
27
+ end
28
+
29
+ def permitted_feedback_review_attributes
30
+ [:rating, :comment]
31
+ end
32
+
33
+ def feedback_review_params
34
+ params.require(:feedback_review).permit(permitted_feedback_review_attributes)
35
+ end
36
+
37
+ def sanitize_rating
38
+ params[:feedback_review][:rating].to_s.sub!(/\s*[^0-9]*\z/,'') unless (params[:feedback_review] && params[:feedback_review][:rating].blank?)
39
+ end
40
+ end
41
+
@@ -0,0 +1,5 @@
1
+ Spree::ProductsController.class_eval do
2
+ helper Spree::ReviewsHelper
3
+
4
+ [:avg_rating, :reviews_count].each { |attrib| Spree::PermittedAttributes.product_attributes << attrib }
5
+ end
@@ -0,0 +1,48 @@
1
+ class Spree::ReviewsController < Spree::StoreController
2
+ helper Spree::BaseHelper
3
+ before_filter :load_product, :only => [:index, :new, :create]
4
+ rescue_from ActiveRecord::RecordNotFound, :with => :render_404
5
+
6
+ def index
7
+ @approved_reviews = Spree::Review.approved.where(product: @product)
8
+ end
9
+
10
+ def new
11
+ @review = Spree::Review.new(:product => @product)
12
+ authorize! :create, @review
13
+ end
14
+
15
+ # save if all ok
16
+ def create
17
+ params[:review][:rating].sub!(/\s*[^0-9]*\z/,'') unless params[:review][:rating].blank?
18
+
19
+ @review = Spree::Review.new(review_params)
20
+ @review.product = @product
21
+ @review.user = spree_current_user if spree_user_signed_in?
22
+ @review.ip_address = request.remote_ip
23
+ @review.locale = I18n.locale.to_s if Spree::Reviews::Config[:track_locale]
24
+
25
+ authorize! :create, @review
26
+ if @review.save
27
+ flash[:notice] = Spree.t('review_successfully_submitted')
28
+ redirect_to spree.product_path(@product)
29
+ else
30
+ render :new
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def load_product
37
+ @product = Spree::Product.friendly.find(params[:product_id])
38
+ end
39
+
40
+ def permitted_review_attributes
41
+ [:rating, :title, :review, :name]
42
+ end
43
+
44
+ def review_params
45
+ params.require(:review).permit(permitted_review_attributes)
46
+ end
47
+
48
+ end
@@ -0,0 +1,17 @@
1
+ module Spree::ReviewsHelper
2
+
3
+ def star(the_class)
4
+ content_tag(:span, " &#10030; ".html_safe, :class => the_class)
5
+ end
6
+
7
+ def mk_stars(m)
8
+ (1..5).collect {|n| n <= m ? star("lit") : star("unlit") }.join
9
+ end
10
+
11
+ def txt_stars(n, show_out_of = true)
12
+ res = Spree.t('star', :count => n)
13
+ res += " #{Spree.t('out_of_5')}" if show_out_of
14
+ res
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ class Spree::FeedbackReview < ActiveRecord::Base
2
+ belongs_to :user, :class_name => Spree.user_class.to_s
3
+
4
+ belongs_to :review, dependent: :destroy
5
+ validates :review, presence: true
6
+
7
+ validates :rating, numericality: { only_integer: true,
8
+ greater_than_or_equal_to: 1,
9
+ less_than_or_equal_to: 5,
10
+ message: Spree.t('you_must_enter_value_for_rating') }
11
+
12
+ scope :most_recent_first, -> { order("spree_feedback_reviews.created_at DESC") }
13
+ default_scope { most_recent_first }
14
+
15
+ scope :localized, lambda { |lc| where('spree_feedback_reviews.locale = ?', lc) }
16
+
17
+ end
@@ -0,0 +1,21 @@
1
+ # Add access to reviews/ratings to the product model
2
+ Spree::Product.class_eval do
3
+ has_many :reviews
4
+
5
+ def stars
6
+ avg_rating.try(:round) || 0
7
+ end
8
+
9
+ def recalculate_rating
10
+ reviews_count = self.reviews.reload.approved.count
11
+
12
+ self.reviews_count = reviews_count
13
+ if reviews_count > 0
14
+ self.avg_rating = self.reviews.approved.sum(:rating).to_f / reviews_count
15
+ else
16
+ self.avg_rating = 0
17
+ end
18
+ self.save
19
+ end
20
+
21
+ end
@@ -0,0 +1,36 @@
1
+ class Spree::Review < ActiveRecord::Base
2
+ belongs_to :product, touch: true
3
+ belongs_to :user, :class_name => Spree.user_class.to_s
4
+ has_many :feedback_reviews
5
+
6
+ after_save :recalculate_product_rating, :if => :approved?
7
+ after_destroy :recalculate_product_rating
8
+
9
+ validates :name, presence: true
10
+ validates :review, presence: true
11
+
12
+ validates :rating, numericality: { only_integer: false,
13
+ greater_than_or_equal_to: 0.5,
14
+ less_than_or_equal_to: 5.0,
15
+ message: Spree.t('you_must_enter_value_for_rating') }
16
+
17
+
18
+ default_scope { order("spree_reviews.created_at DESC") }
19
+
20
+ scope :localized, ->(lc) { where('spree_reviews.locale = ?', lc) }
21
+ scope :most_recent_first, -> { order('spree_reviews.created_at DESC') }
22
+ scope :oldest_first, -> { reorder('spree_reviews.created_at ASC') }
23
+ scope :preview, -> { limit(Spree::Reviews::Config[:preview_size]).oldest_first }
24
+ scope :approved, -> { where(approved: true) }
25
+ scope :not_approved, -> { where(approved: false) }
26
+ scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved }
27
+
28
+ def feedback_stars
29
+ return 0 if feedback_reviews.size <= 0
30
+ ((feedback_reviews.sum(:rating) / feedback_reviews.size) + 0.5).floor
31
+ end
32
+
33
+ def recalculate_product_rating
34
+ self.product.recalculate_rating if product.present?
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ class Spree::ReviewsAbility
2
+ include CanCan::Ability
3
+
4
+ def initialize user
5
+ review_ability_class = self.class
6
+ can :create, Spree::Review do |review|
7
+ review_ability_class.allow_anonymous_reviews? || !user.email.blank?
8
+ end
9
+ can :create, Spree::FeedbackReview do |review|
10
+ review_ability_class.allow_anonymous_reviews? || !user.email.blank?
11
+ end
12
+ end
13
+
14
+ def self.allow_anonymous_reviews?
15
+ !Spree::Reviews::Config[:require_login]
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ class Spree::ReviewsConfiguration < Spree::Preferences::Configuration
2
+ def self.boolean_preferences
3
+ %w(include_unapproved_reviews feedback_rating show_email require_login track_locale)
4
+ end
5
+
6
+ # include non-approved reviews in (public) listings
7
+ preference :include_unapproved_reviews, :boolean, :default => false
8
+
9
+ # control how many reviews are shown in summaries etc.
10
+ preference :preview_size, :integer, :default => 3
11
+
12
+ # show a reviewer's email address
13
+ preference :show_email, :boolean, :default => false
14
+
15
+ # show helpfullness rating form elements
16
+ preference :feedback_rating, :boolean, :default => false
17
+
18
+ # require login to post reviews
19
+ preference :require_login, :boolean, :default => true
20
+
21
+ # whether to keep track of the reviewer's locale
22
+ preference :track_locale, :boolean, :default => false
23
+ end
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/products/show",
2
+ :name => "converted_product_properties_767643482",
3
+ :insert_after => "[data-hook='product_properties']",
4
+ :partial => "spree/shared/reviews",
5
+ :disabled => false)
@@ -0,0 +1,4 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/shared/_product_sub_menu",
2
+ :name => "reviews_admin_tab",
3
+ :insert_bottom => "[data-hook='admin_product_sub_tabs']",
4
+ :text => "<%= tab(:reviews, :label => 'review_management') %>")
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/shared/_configuration_menu",
2
+ :name => "converted_admin_configurations_menu",
3
+ :insert_bottom => "[data-hook='admin_configurations_sidebar_menu'], #admin_configurations_sidebar_menu[data-hook]",
4
+ :text => "<%= configurations_sidebar_menu_item Spree.t('spree_reviews.review_settings'), edit_admin_review_settings_path %>",
5
+ :disabled => false)
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/admin/shared/_tabs",
2
+ :name => "reviews_admin_tab_root",
3
+ :replace_contents => "erb[loud]:contains('tab :products')",
4
+ :text => "tab :products, :option_types, :properties, :prototypes, :variants, :product_properties, :taxons, :reviews, :icon => 'icon-th-large'",
5
+ :original => '0abc74602592114216d5a53bc095823ec6759895')
@@ -0,0 +1,44 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t('feedback_review_for', :review => @review.title) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <li><%= button_link_to Spree.t(:back_to_reviews), admin_reviews_path, { :icon => 'icon-arrow-left' } %></li>
7
+ <% end %>
8
+
9
+ <% render 'spree/admin/shared/product_sub_menu' %>
10
+
11
+ <% if @collection.any? %>
12
+ <table class="index">
13
+ <colgroup>
14
+ <col style="width: 30%;">
15
+ <col style="width: 20%;">
16
+ <col style="width: 20%;">
17
+ <col style="width: 17%;">
18
+ </colgroup>
19
+ <thead>
20
+ <tr>
21
+ <th><%= Spree.t('user') %></th>
22
+ <th><%= Spree.t('stars') %></th>
23
+ <th><%= Spree.t('date') %></th>
24
+ <th></th>
25
+ </tr>
26
+ </thead>
27
+ <tbody>
28
+ <%- @collection.each do |feedback| -%>
29
+ <tr id="<%= dom_id(feedback) %>">
30
+ <td><%= l feedback.created_at %></td>
31
+ <td><%= feedback.user.try(:login) || Spree.t(:anonymous) %></td>
32
+ <td><%= feedback.rating %></td>
33
+ <td class="actions">
34
+ <%= link_to_delete feedback, :no_text => true %>
35
+ </td>
36
+ </tr>
37
+ <% end %>
38
+ </tbody>
39
+ </table>
40
+ <% else %>
41
+ <div class="no-objects-found">
42
+ <%= Spree.t(:no_results) %>
43
+ </div>
44
+ <% end %>