solidus_reviews 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +18 -0
- data/CONTRIBUTING.md +28 -0
- data/Gemfile +14 -0
- data/LICENSE.md +26 -0
- data/README.md +93 -0
- data/Rakefile +21 -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/solidus_reviews.js +7 -0
- data/app/assets/javascripts/spree/frontend/solidus_reviews.js +7 -0
- data/app/assets/stylesheets/spree/backend/solidus_reviews.css +3 -0
- data/app/assets/stylesheets/spree/frontend/solidus_reviews.scss +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 +26 -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/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 +34 -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 +28 -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/bin/rails +5 -0
- data/config/initializers/constants.rb +1 -0
- data/config/initializers/load_preferences.rb +5 -0
- data/config/locales/de-CH.yml +68 -0
- data/config/locales/de.yml +68 -0
- data/config/locales/en-GB.yml +68 -0
- data/config/locales/en.yml +67 -0
- data/config/locales/es.yml +68 -0
- data/config/locales/fr.yml +68 -0
- data/config/locales/pl.yml +72 -0
- data/config/locales/pt-BR.yml +68 -0
- data/config/locales/pt.yml +69 -0
- data/config/locales/ro.yml +76 -0
- data/config/locales/ru.yml +73 -0
- data/config/locales/sv.yml +66 -0
- data/config/locales/tr.yml +68 -0
- data/config/locales/uk.yml +75 -0
- data/config/locales/zh-CN.yml +65 -0
- data/config/locales/zh-TW.yml +65 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20081020220724_create_reviews.rb +18 -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/migrate/20140703200946_add_show_identifier_to_reviews.rb +6 -0
- data/db/sample/ratings.yml +16 -0
- data/db/sample/reviews.yml +59 -0
- data/lib/generators/solidus_reviews/install/install_generator.rb +30 -0
- data/lib/solidus_reviews/factories/feedback_review_factory.rb +8 -0
- data/lib/solidus_reviews/factories/review_factory.rb +20 -0
- data/lib/solidus_reviews/factories.rb +5 -0
- data/lib/solidus_reviews.rb +6 -0
- data/lib/spree_reviews/engine.rb +17 -0
- data/solidus_reviews.gemspec +35 -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/features/admin_spec.rb +35 -0
- data/spec/features/reviews_spec.rb +122 -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 +168 -0
- data/spec/models/reviews_ability_spec.rb +46 -0
- data/spec/models/reviews_configuration_spec.rb +45 -0
- data/spec/spec_helper.rb +55 -0
- data/vendor/assets/javascripts/jquery.rating.js +376 -0
- metadata +357 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f0b51c02c6474636cf9398f1e7c51ca332eadba8
|
4
|
+
data.tar.gz: 0fb923dfe70a7b22fed4ba65aedea239d73101bb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3257de4d8a2956c07f16e710559ed37505ffe456d2a1ad65b99ac70419556d92f112c1510a24374c96077db15d47127e32e5fd48c4de605ccfd44d4b352930b
|
7
|
+
data.tar.gz: ff881a9a9c17757c84aaff1877efde25378df3d22506bd87667b1918db9cf73459f75175ebf446b62187ad71126274a68a0075b1a3778b24be52b8e74f6f2685
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.3.3
|
4
|
+
sudo: false
|
5
|
+
cache: bundler
|
6
|
+
only: master
|
7
|
+
env:
|
8
|
+
matrix:
|
9
|
+
- SOLIDUS_BRANCH=v1.0 DB=mysql
|
10
|
+
- SOLIDUS_BRANCH=v1.0 DB=postgresql
|
11
|
+
- SOLIDUS_BRANCH=v1.1 DB=mysql
|
12
|
+
- SOLIDUS_BRANCH=v1.1 DB=postgresql
|
13
|
+
- SOLIDUS_BRANCH=v1.2 DB=mysql
|
14
|
+
- SOLIDUS_BRANCH=v1.2 DB=postgresql
|
15
|
+
- SOLIDUS_BRANCH=v1.3 DB=mysql
|
16
|
+
- SOLIDUS_BRANCH=v1.3 DB=postgresql
|
17
|
+
- SOLIDUS_BRANCH=v1.4 DB=mysql
|
18
|
+
- SOLIDUS_BRANCH=v1.4 DB=postgresql
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
In the spirit of [free software][1], **everyone** is encouraged to help improve this project.
|
4
|
+
|
5
|
+
Here are some ways *you* can contribute:
|
6
|
+
|
7
|
+
- by using prerelease versions
|
8
|
+
- by reporting [bugs][2]
|
9
|
+
- by suggesting new features
|
10
|
+
- by writing translations
|
11
|
+
- by writing or editing documentation
|
12
|
+
- by writing specifications
|
13
|
+
- by writing code (*no patch is too small*: fix typos, add comments, clean up inconsistent whitespace)
|
14
|
+
- by refactoring code
|
15
|
+
- by resolving [issues][2]
|
16
|
+
- by reviewing patches
|
17
|
+
|
18
|
+
Starting point:
|
19
|
+
|
20
|
+
- Fork the repo
|
21
|
+
- Clone your repo
|
22
|
+
- Run `bundle install`
|
23
|
+
- Run `bundle exec rake test_app` to create the test application in `spec/test_app`
|
24
|
+
- Ensure specs pass by running `bundle exec rspec spec`
|
25
|
+
- Submit your pull request
|
26
|
+
|
27
|
+
[1]: http://www.fsf.org/licensing/essays/free-sw.html
|
28
|
+
[2]: https://github.com/spree-contrib/spree_reviews/issues
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
branch = ENV.fetch('SOLIDUS_BRANCH', 'v1.4')
|
4
|
+
gem "solidus", github: "solidusio/solidus", branch: branch
|
5
|
+
gem "solidus_auth_devise", github: "solidusio/solidus_auth_devise"
|
6
|
+
|
7
|
+
case ENV['DB']
|
8
|
+
when 'mysql'
|
9
|
+
gem 'mysql2'
|
10
|
+
when 'postgresql'
|
11
|
+
gem 'pg'
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec
|
data/LICENSE.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2009-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,93 @@
|
|
1
|
+
# Reviews
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/solidusio-contrib/solidus_reviews.svg)](https://travis-ci.org/solidusio-contrib/solidus_reviews)
|
4
|
+
|
5
|
+
Straightforward review/rating functionality, updated for
|
6
|
+
[Solidus](https://solidus.io). While the Gem name has changed, the module
|
7
|
+
namespace and commands are still `spree` for now.
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add the following to your `Gemfile` to install from git:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'solidus_reviews', github: 'solidusio-contrib/solidus_reviews'
|
17
|
+
```
|
18
|
+
Now bundle up with:
|
19
|
+
|
20
|
+
bundle
|
21
|
+
|
22
|
+
Next, run the rake task that copies the necessary migrations and assets to your project:
|
23
|
+
|
24
|
+
rails g solidus_reviews:install
|
25
|
+
|
26
|
+
And finish with a migrate:
|
27
|
+
|
28
|
+
rake db:migrate
|
29
|
+
|
30
|
+
Now you should be able to boot up your server with:
|
31
|
+
|
32
|
+
rails s
|
33
|
+
|
34
|
+
That's all!
|
35
|
+
|
36
|
+
---
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
Action "submit" in "reviews" controller - goes to review entry form
|
41
|
+
|
42
|
+
Users must be logged in to submit a review
|
43
|
+
|
44
|
+
Three partials:
|
45
|
+
- `app/views/spree/products/_rating.html.erb` -- display number of stars
|
46
|
+
- `app/views/spree/products/_shortrating.html.erb` -- shorter version of above
|
47
|
+
- `app/views/spree/products/_review.html.erb` -- display a single review
|
48
|
+
|
49
|
+
Administrator can edit and/or approve and/or delete reviews.
|
50
|
+
|
51
|
+
## Factories
|
52
|
+
|
53
|
+
If you want factories for our models available in your application, simply
|
54
|
+
require our factories in your `spec_helper.rb`:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require "solidus_reviews/factories"
|
58
|
+
```
|
59
|
+
|
60
|
+
## Implementation
|
61
|
+
|
62
|
+
Reviews table is quite obvious - and note the "approved" flag which is for the
|
63
|
+
administrator to update.
|
64
|
+
|
65
|
+
Ratings table holds current fractional value - avoids frequent recalc...
|
66
|
+
|
67
|
+
---
|
68
|
+
|
69
|
+
## Discussion
|
70
|
+
|
71
|
+
Some points which might need modification in future:
|
72
|
+
|
73
|
+
- I don't track the actual user on a review (just their "screen name" at the
|
74
|
+
time), but we may want to use this information to avoid duplicate reviews
|
75
|
+
etc. See https://github.com/spree/spree_reviews/issues/18
|
76
|
+
- Rating votes are tied to a review, to avoid spam. However: ratings are
|
77
|
+
accepted whether or not the review is accepted. Perhaps they should only
|
78
|
+
be counted when the review is approved.
|
79
|
+
|
80
|
+
---
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
See corresponding [contributing guidelines][1].
|
85
|
+
|
86
|
+
---
|
87
|
+
|
88
|
+
Copyright (c) 2009-2014 [Spree Commerce][2] and [contributors][3], released under the [New BSD License][4]
|
89
|
+
|
90
|
+
[1]: ./CONTRIBUTING.md
|
91
|
+
[2]: https://github.com/spree
|
92
|
+
[3]: https://github.com/solidusio-contrib/solidus_reviews/graphs/contributors
|
93
|
+
[4]: ./LICENSE.md
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'spree/testing_support/extension_rake'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default do
|
10
|
+
if Dir["spec/dummy"].empty?
|
11
|
+
Rake::Task[:test_app].invoke
|
12
|
+
Dir.chdir("../../")
|
13
|
+
end
|
14
|
+
Rake::Task[:spec].invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generates a dummy app for testing'
|
18
|
+
task :test_app do
|
19
|
+
ENV['LIB_NAME'] = 'solidus_reviews'
|
20
|
+
Rake::Task['extension:test_app'].invoke
|
21
|
+
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 image-url('store/reviews/delete.gif') no-repeat scroll 0 -1px;
|
50
|
+
}
|
51
|
+
|
52
|
+
div.star-rating, div.star-rating a {
|
53
|
+
background: image-url('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, :show_identifier]
|
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: true,
|
13
|
+
greater_than_or_equal_to: 1,
|
14
|
+
less_than_or_equal_to: 5,
|
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,26 @@
|
|
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
|
+
|
24
|
+
# render checkbox for a user to approve to show their identifier (name or email) on their review
|
25
|
+
preference :render_show_identifier_checkbox, :boolean, :default => false
|
26
|
+
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)
|