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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/Guardfile +9 -0
- data/LICENSE.md +26 -0
- data/README.md +54 -0
- data/Rakefile +15 -0
- data/app/assets/images/store/reviews/delete.gif +0 -0
- data/app/assets/images/store/reviews/star.gif +0 -0
- data/app/assets/javascripts/spree/backend/jiffyshirts_spree_reviews.js +7 -0
- data/app/assets/javascripts/spree/frontend/jiffyshirts_spree_reviews.js +7 -0
- data/app/assets/stylesheets/spree/backend/jiffyshirts_spree_reviews.css +3 -0
- data/app/assets/stylesheets/spree/frontend/jiffyshirts_spree_reviews.css.erb +83 -0
- data/app/controllers/spree/admin/feedback_reviews_controller.rb +6 -0
- data/app/controllers/spree/admin/review_settings_controller.rb +21 -0
- data/app/controllers/spree/admin/reviews_controller.rb +34 -0
- data/app/controllers/spree/feedback_reviews_controller.rb +41 -0
- data/app/controllers/spree/products_controller_decorator.rb +5 -0
- data/app/controllers/spree/reviews_controller.rb +48 -0
- data/app/helpers/spree/reviews_helper.rb +17 -0
- data/app/models/spree/feedback_review.rb +17 -0
- data/app/models/spree/product_decorator.rb +21 -0
- data/app/models/spree/review.rb +36 -0
- data/app/models/spree/reviews_ability.rb +17 -0
- data/app/models/spree/reviews_configuration.rb +23 -0
- data/app/overrides/add_reviews_after_product_properties.rb +5 -0
- data/app/overrides/add_reviews_tab_to_admin.rb +4 -0
- data/app/overrides/add_reviews_to_admin_configuration_sidebar.rb +5 -0
- data/app/overrides/fix_highlighting_of_products_tab.rb +5 -0
- data/app/views/spree/admin/feedback_reviews/index.html.erb +44 -0
- data/app/views/spree/admin/review_settings/edit.html.erb +40 -0
- data/app/views/spree/admin/reviews/_form.html.erb +22 -0
- data/app/views/spree/admin/reviews/edit.html.erb +26 -0
- data/app/views/spree/admin/reviews/index.html.erb +111 -0
- data/app/views/spree/feedback_reviews/_form.html.erb +13 -0
- data/app/views/spree/feedback_reviews/_summary.html.erb +6 -0
- data/app/views/spree/feedback_reviews/create.js.erb +7 -0
- data/app/views/spree/reviews/_form.html.erb +27 -0
- data/app/views/spree/reviews/_stars.html.erb +13 -0
- data/app/views/spree/reviews/index.html.erb +1 -0
- data/app/views/spree/reviews/new.html.erb +3 -0
- data/app/views/spree/shared/_rating.html.erb +15 -0
- data/app/views/spree/shared/_review.html.erb +24 -0
- data/app/views/spree/shared/_review_summary.html.erb +9 -0
- data/app/views/spree/shared/_reviews.html.erb +15 -0
- data/app/views/spree/shared/_shortrating.html.erb +9 -0
- data/config/initializers/constants.rb +1 -0
- data/config/initializers/load_preferences.rb +5 -0
- data/config/locales/de-CH.yml +67 -0
- data/config/locales/de.yml +67 -0
- data/config/locales/en-GB.yml +67 -0
- data/config/locales/en.yml +65 -0
- data/config/locales/es.yml +67 -0
- data/config/locales/fr.yml +67 -0
- data/config/locales/pl.yml +71 -0
- data/config/locales/pt-BR.yml +67 -0
- data/config/locales/pt.yml +68 -0
- data/config/locales/ro.yml +75 -0
- data/config/locales/ru.yml +73 -0
- data/config/locales/sv.yml +65 -0
- data/config/locales/tr.yml +67 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20081020220724_create_reviews.rb +21 -0
- data/db/migrate/20101222083309_create_feedback_reviews.rb +17 -0
- data/db/migrate/20110406083603_add_rating_to_products.rb +21 -0
- data/db/migrate/20110606150524_add_user_to_reviews.rb +9 -0
- data/db/migrate/20110806093221_add_ip_address_to_reviews.rb +9 -0
- data/db/migrate/20120110172331_namespace_tables.rb +6 -0
- data/db/migrate/20120123141326_recalculate_ratings.rb +20 -0
- data/db/migrate/20120712182514_add_locale_to_reviews.rb +9 -0
- data/db/migrate/20120712182627_add_locale_to_feedback_reviews.rb +9 -0
- data/db/sample/ratings.yml +16 -0
- data/db/sample/reviews.yml +59 -0
- data/jiffyshirts_spree_reviews.gemspec +31 -0
- data/lib/generators/jiffyshirts_spree_reviews/install/install_generator.rb +30 -0
- data/lib/jiffyshirts_spree_reviews/engine.rb +23 -0
- data/lib/jiffyshirts_spree_reviews.rb +4 -0
- data/script/rails +5 -0
- data/spec/controllers/admin/feedback_reviews_controller_spec.rb +29 -0
- data/spec/controllers/admin/review_settings_controller_spec.rb +57 -0
- data/spec/controllers/admin/reviews_controller_spec.rb +63 -0
- data/spec/controllers/feedback_reviews_controller_spec.rb +71 -0
- data/spec/controllers/products_controller_spec.rb +9 -0
- data/spec/controllers/reviews_controller_spec.rb +136 -0
- data/spec/factories/feedback_review_factory.rb +8 -0
- data/spec/factories/review_factory.rb +15 -0
- data/spec/features/admin_spec.rb +35 -0
- data/spec/features/reviews_spec.rb +106 -0
- data/spec/helpers/review_helper_spec.rb +28 -0
- data/spec/models/feedback_review_spec.rb +78 -0
- data/spec/models/product_spec.rb +62 -0
- data/spec/models/review_spec.rb +169 -0
- data/spec/models/reviews_ability_spec.rb +46 -0
- data/spec/models/reviews_configuration_spec.rb +45 -0
- data/spec/spec_helper.rb +48 -0
- data/vendor/assets/javascripts/jquery.rating.js +376 -0
- 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
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
Binary file
|
Binary file
|
@@ -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,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,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, " ✮ ".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/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 %>
|