solidus_reviews 1.0.0
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 +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
|
+
[](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)
|