hancock_cms_faq 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +55 -0
  9. data/Rakefile +1 -0
  10. data/app/assets/javascripts/hancock/faq.coffee +6 -0
  11. data/app/assets/javascripts/hancock/faq/form.coffee +9 -0
  12. data/app/assets/javascripts/hancock/faq/init.coffee +2 -0
  13. data/app/assets/stylesheets/hancock/faq.sass +0 -0
  14. data/app/controllers/concerns/hancock/faq/decorators/categories.rb +17 -0
  15. data/app/controllers/concerns/hancock/faq/decorators/questions.rb +71 -0
  16. data/app/controllers/hancock/faq/categories_controller.rb +7 -0
  17. data/app/controllers/hancock/faq/questions_controller.rb +7 -0
  18. data/app/models/concerns/hancock/faq/decorators/category.rb +36 -0
  19. data/app/models/concerns/hancock/faq/decorators/question.rb +48 -0
  20. data/app/models/hancock/faq/category.rb +11 -0
  21. data/app/models/hancock/faq/question.rb +11 -0
  22. data/app/views/hancock/faq/categories/index.html.slim +10 -0
  23. data/app/views/hancock/faq/categories/show.html.slim +8 -0
  24. data/app/views/hancock/faq/questions/_fields.html.slim +11 -0
  25. data/app/views/hancock/faq/questions/_fields_with_settings.html.slim +20 -0
  26. data/app/views/hancock/faq/questions/_form.html.slim +66 -0
  27. data/app/views/hancock/faq/questions/_form_with_wrapper.html.slim +2 -0
  28. data/app/views/hancock/faq/questions/_question_block.html.slim +33 -0
  29. data/app/views/hancock/faq/questions/_simple_captcha.html.slim +16 -0
  30. data/app/views/hancock/faq/questions/_success.html.slim +3 -0
  31. data/app/views/hancock/faq/questions/create.html.slim +1 -0
  32. data/app/views/hancock/faq/questions/index.html.slim +11 -0
  33. data/app/views/hancock/faq/questions/new.html.slim +6 -0
  34. data/app/views/hancock/faq/questions/show.html.slim +8 -0
  35. data/app/views/hancock/faq/questions/update_captcha.html.slim +16 -0
  36. data/bin/console +14 -0
  37. data/bin/setup +7 -0
  38. data/config/locales/hancock.faq.ru.yml +64 -0
  39. data/hancock_cms_faq.gemspec +36 -0
  40. data/lib/generators/hancock/faq/config/config_generator.rb +13 -0
  41. data/lib/generators/hancock/faq/config/templates/hancock_faq.erb +23 -0
  42. data/lib/generators/hancock/faq/controllers/all_generator.rb +28 -0
  43. data/lib/generators/hancock/faq/controllers/category_generator.rb +43 -0
  44. data/lib/generators/hancock/faq/controllers/decorators_generator.rb +24 -0
  45. data/lib/generators/hancock/faq/controllers/question_generator.rb +43 -0
  46. data/lib/generators/hancock/faq/controllers/templates/categories_controller.erb +10 -0
  47. data/lib/generators/hancock/faq/controllers/templates/questions_controller.erb +10 -0
  48. data/lib/generators/hancock/faq/models/all_generator.rb +28 -0
  49. data/lib/generators/hancock/faq/models/category_generator.rb +43 -0
  50. data/lib/generators/hancock/faq/models/decorators_generator.rb +24 -0
  51. data/lib/generators/hancock/faq/models/question_generator.rb +34 -0
  52. data/lib/generators/hancock/faq/models/templates/category.erb +36 -0
  53. data/lib/generators/hancock/faq/models/templates/question.erb +37 -0
  54. data/lib/hancock/faq/admin.rb +6 -0
  55. data/lib/hancock/faq/admin/category.rb +128 -0
  56. data/lib/hancock/faq/admin/question.rb +104 -0
  57. data/lib/hancock/faq/configuration.rb +53 -0
  58. data/lib/hancock/faq/controllers/categories.rb +88 -0
  59. data/lib/hancock/faq/controllers/questions.rb +174 -0
  60. data/lib/hancock/faq/engine.rb +7 -0
  61. data/lib/hancock/faq/models/category.rb +50 -0
  62. data/lib/hancock/faq/models/mongoid/category.rb +33 -0
  63. data/lib/hancock/faq/models/mongoid/question.rb +72 -0
  64. data/lib/hancock/faq/models/question.rb +85 -0
  65. data/lib/hancock/faq/routes.rb +83 -0
  66. data/lib/hancock/faq/version.rb +5 -0
  67. data/lib/hancock_cms_faq.rb +31 -0
  68. data/release.sh +6 -0
  69. metadata +159 -0
@@ -0,0 +1,53 @@
1
+ module Hancock::Faq
2
+ include Hancock::PluginConfiguration
3
+
4
+ def self.config_class
5
+ Configuration
6
+ end
7
+
8
+ class Configuration
9
+ attr_accessor :author_name_required
10
+
11
+ attr_accessor :default_answer_author_name
12
+
13
+ attr_accessor :captcha
14
+ attr_accessor :captcha_error_message
15
+
16
+ attr_accessor :recaptcha_support
17
+ attr_accessor :simple_captcha_support
18
+
19
+ attr_accessor :seo_support
20
+ attr_accessor :cache_support
21
+
22
+ attr_accessor :breadcrumbs_on_rails_support
23
+
24
+ attr_accessor :localize
25
+
26
+ attr_accessor :model_settings_support
27
+ attr_accessor :user_abilities_support
28
+ attr_accessor :ra_comments_support
29
+
30
+ def initialize
31
+ @author_name_required = true
32
+
33
+ @default_answer_author_name = "Администрация сайта"
34
+
35
+ @captcha_error_message = "Код с картинки введен неверно"
36
+
37
+ @recaptcha_support = !!defined?(Recaptcha)
38
+ @simple_captcha_support = !!defined?(SimpleCaptcha)
39
+ @captcha = @recaptcha_support || @simple_captcha_support
40
+
41
+ @seo_support = !!defined?(Hancock::Seo)
42
+ @cache_support = !!defined?(Hancock::Cache)
43
+
44
+ @breadcrumbs_on_rails_support = !!defined?(BreadcrumbsOnRails)
45
+
46
+ @localize = Hancock.config.localize
47
+
48
+ @model_settings_support = !!defined?(RailsAdminModelSettings)
49
+ @user_abilities_support = !!defined?(RailsAdminUserAbilities)
50
+ @ra_comments_support = !!defined?(RailsAdminComments)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,88 @@
1
+ module Hancock::Faq
2
+ module Controllers
3
+ module Categories
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ def index
9
+ @categories = category_class.enabled.sorted.page(params[:page]).per(per_page)
10
+ @root_categories = category_class.enabled.roots.sorted.all
11
+ # index_crumbs
12
+ end
13
+
14
+ def show
15
+ @category = category_class.enabled.find(params[:id])
16
+ if !@category.text_slug.blank? and @category.text_slug != params[:id]
17
+ redirect_to hancock_faq_category_path(@category), status_code: 301
18
+ return
19
+ end
20
+ @seo_parent_page = find_seo_page(hancock_faq_categories_path)
21
+
22
+ @children = @category.children.enabled.sorted.all
23
+ @questions = @category.questions.enabled.sorted.all.page(params[:page]).per(questions_per_page)
24
+
25
+ # index_crumbs
26
+ # category_crumbs
27
+ end
28
+
29
+ def page_title
30
+ if @category
31
+ @category.page_title
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ private
38
+ def category_class
39
+ Hancock::Faq::Category
40
+ end
41
+ def question_class
42
+ Hancock::Faq::Question
43
+ end
44
+
45
+ def per_page
46
+ 10
47
+ end
48
+ def questions_per_page
49
+ 10
50
+ end
51
+
52
+ # def index_crumbs
53
+ # if @seo_parent_page
54
+ # catalog_title = Settings.ns('breadcrumbs').catalog_title(default: "Каталог", label: "'Каталог' в breadcrumbs")
55
+ # _crumb = catalog_title
56
+ # _crumb = @seo_parent_page.name if _crumb.blank?
57
+ # _crumb = @seo_parent_page.title if _crumb.blank?
58
+ # _crumb = @seo_parent_page.h1 if _crumb.blank?
59
+ # add_crumb _crumb, @seo_parent_page.fullpath
60
+ # else
61
+ # catalog_title = Settings.ns('breadcrumbs').catalog_title(default: "Каталог", label: "'Каталог' в breadcrumbs")
62
+ # _crumb = catalog_title
63
+ # add_crumb _crumb, item_categories_path
64
+ # end
65
+ # end
66
+ #
67
+ # def category_crumbs
68
+ # if @item_category
69
+ # _parent = @item_category.parent
70
+ # if _parent
71
+ # _crumb = _parent.name if _crumb.blank?
72
+ # _crumb = _parent.title if _crumb.blank?
73
+ # _crumb = _parent.h1 if _crumb.blank?
74
+ # add_crumb _crumb, item_category_path(_parent)
75
+ # _crumb = nil
76
+ # end
77
+ # _crumb = @item_category.name if _crumb.blank?
78
+ # _crumb = @item_category.title if _crumb.blank?
79
+ # _crumb = @item_category.h1 if _crumb.blank?
80
+ # add_crumb _crumb, item_category_path(@item_category)
81
+ # end
82
+ # end
83
+
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,174 @@
1
+ module Hancock::Faq
2
+ module Controllers
3
+ module Questions
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ helper_method :hancock_faq_update_captcha_path
9
+
10
+ def index
11
+ if Hancock::Faq.config.breadcrumbs_on_rails_support
12
+ add_breadcrumb I18n.t('hancock.breadcrumbs.faq'), :hancock_faq_path
13
+ end
14
+
15
+ @questions = question_class.enabled.sorted.page(params[:page]).per(per_page)
16
+ # index_crumbs
17
+ after_initialize
18
+ render locals: locals unless xhr_checker
19
+ end
20
+
21
+ def show
22
+ if Hancock::Faq.config.breadcrumbs_on_rails_support
23
+ add_breadcrumb I18n.t('hancock.breadcrumbs.faq'), :hancock_faq_path
24
+ end
25
+
26
+ @question = question_class.enabled.find(params[:id])
27
+ if !@question.text_slug.blank? and @question.text_slug != params[:id]
28
+ redirect_to hancock_faq_question_path(@question), status_code: 301
29
+ return
30
+ end
31
+ @parent_seo_page = find_seo_page(hancock_faq_categories_path) if @seo_page.blank?
32
+ # item_crumbs
33
+ end
34
+
35
+ def page_title
36
+ if @question
37
+ @question.page_title
38
+ else
39
+ super
40
+ end
41
+ end
42
+
43
+ def create
44
+ @question = question_class.new(question_params)
45
+
46
+ if Hancock::Faq.config.captcha
47
+ if Hancock::Faq.config.recaptcha_support
48
+ if verify_recaptcha
49
+ meth = :save
50
+ else
51
+ meth = :valid?
52
+ @recaptcha_error = I18n.t('hancock.errors.faq.recaptcha')
53
+ end
54
+
55
+ elsif Hancock::Faq.config.simple_captcha_support
56
+ meth = :save_with_captcha
57
+
58
+ else
59
+ meth = :save
60
+ end
61
+ else
62
+ meth = :save
63
+ end
64
+
65
+ if @question.send(meth)
66
+ after_create
67
+ if request.xhr? && process_ajax
68
+ ajax_success
69
+ else
70
+ redirect_after_done
71
+ end
72
+ else
73
+ render_faq_error
74
+ end
75
+ end
76
+
77
+ def update_captcha
78
+ render layout: false
79
+ end
80
+
81
+ def hancock_faq_question_update_captcha_path
82
+ url_for(action: :update_captcha, time: Time.new.to_i, only_path: true)
83
+ end
84
+ def is_cache_fields
85
+ cache_fields?
86
+ end
87
+ def cache_fields?
88
+ ['new', 'index'].include? action_name
89
+ end
90
+ def cache_key
91
+ 'hancock_faq_question_fields'.freeze
92
+ end
93
+ def fields_partial
94
+ "hancock/faq/questions/#{(Hancock::Faq.config.model_settings_support ? 'fields' : 'fields_with_settings')}".freeze
95
+ end
96
+ def settings_scope
97
+ if Hancock::Faq.config.model_settings_support
98
+ question_class.settings
99
+ elsif defined?(Settings)
100
+ Settings.ns('FAQ')
101
+ else
102
+ nil
103
+ end
104
+ end
105
+ def recaptcha_options
106
+ {}
107
+ end
108
+ def locals
109
+ {
110
+ is_cache_fields: is_cache_fields,
111
+ cache_key: cache_key,
112
+ fields_partial: fields_partial,
113
+ settings_scope: settings_scope,
114
+ recaptcha_options: recaptcha_options
115
+ }
116
+ end
117
+
118
+ private
119
+ def render_faq_error
120
+ if request.xhr? && process_ajax
121
+ render partial: form_partial, status: 422
122
+ # render json: {errors: @contact_message.errors}, status: 422
123
+ else
124
+ flash.now[:alert] = @question.errors.full_messages.join("\n")
125
+ render action: Hancock::Faq.configuration.recreate_contact_message_action, status: 422
126
+ end
127
+ end
128
+ def process_ajax
129
+ true
130
+ end
131
+ def ajax_success
132
+ render partial: success_partial
133
+ # render json: {ok: true}
134
+ end
135
+ def redirect_after_done
136
+ redirect_to action: :sent
137
+ end
138
+ def xhr_checker
139
+ if request.xhr?
140
+ render layout: false, locals: locals
141
+ return true
142
+ end
143
+ end
144
+ def after_initialize
145
+ end
146
+ def after_create
147
+ # overrideable hook for updating message
148
+ end
149
+ def form_partial
150
+ "hancock/faq/questions/form"
151
+ end
152
+ def success_partial
153
+ "hancock/faq/questions/success"
154
+ end
155
+ def question_params
156
+ params[:hancock_faq_question].permit(:question_text, :author_name, :author_email, :captcha, :captcha_key)
157
+ end
158
+
159
+ def category_class
160
+ Hancock::Faq::Category
161
+ end
162
+ def question_class
163
+ Hancock::Faq::Question
164
+ end
165
+
166
+ def per_page
167
+ 10
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,7 @@
1
+ module Hancock
2
+ module Faq
3
+ class Engine < ::Rails::Engine
4
+ # isolate_namespace Hancock::Faq
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ module Hancock::Faq
2
+ module Models
3
+ module Category
4
+ extend ActiveSupport::Concern
5
+ include Hancock::Model
6
+ include Hancock::Enableable
7
+
8
+ if Hancock::Faq.config.seo_support
9
+ include Hancock::Seo::Seoable
10
+ include Hancock::Seo::SitemapDataField
11
+ end
12
+ include ManualSlug
13
+
14
+ if Hancock::Pages.config.cache_support
15
+ include Hancock::Cache::Cacheable
16
+ end
17
+
18
+ include Hancock::Faq.orm_specific('Category')
19
+
20
+ included do
21
+ if Hancock::Feedback.config.model_settings_support
22
+ include RailsAdminModelSettings::ModelSettingable
23
+ end
24
+
25
+ manual_slug :name
26
+
27
+ def self.manager_can_add_actions
28
+ ret = [:nested_set]
29
+ ret << :model_settings if Hancock::Faq.config.model_settings_support
30
+ # ret << :model_accesses if Hancock::Faq.config.user_abilities_support
31
+ ret << :hancock_touch if Hancock::Faq.config.cache_support
32
+ ret += [:comments, :model_comments] if Hancock::Faq.config.ra_comments_support
33
+ ret.freeze
34
+ end
35
+ def self.rails_admin_add_visible_actions
36
+ ret = [:nested_set]
37
+ ret << :model_settings if Hancock::Faq.config.model_settings_support
38
+ ret << :model_accesses if Hancock::Faq.config.user_abilities_support
39
+ ret << :hancock_touch if Hancock::Faq.config.cache_support
40
+ ret += [:comments, :model_comments] if Hancock::Faq.config.ra_comments_support
41
+ ret.freeze
42
+ end
43
+ end
44
+
45
+ def question_class
46
+ Hancock::Faq::Question
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module Hancock::Faq
2
+ module Models
3
+ module Mongoid
4
+ module Category
5
+ extend ActiveSupport::Concern
6
+
7
+ include Hancock::HtmlField
8
+
9
+ included do
10
+ index({enabled: 1, lft: 1}, {background: true})
11
+ index({parent_id: 1}, {background: true})
12
+
13
+ field :name, type: String, localize: Hancock::Faq.configuration.localize
14
+
15
+ acts_as_nested_set
16
+ scope :sorted, -> { order_by([:lft, :asc]) }
17
+
18
+ hancock_cms_html_field :excerpt, type: String, localize: Hancock::Faq.configuration.localize, default: ""
19
+ hancock_cms_html_field :content, type: String, localize: Hancock::Faq.configuration.localize, default: ""
20
+ end
21
+
22
+ def questions
23
+ question_class.in(category_ids: self.id)
24
+ end
25
+
26
+ def all_questions
27
+ question_class.any_in(category_ids: self.and_descendants.map(&:id))
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,72 @@
1
+ module Hancock::Faq
2
+ module Models
3
+ module Mongoid
4
+ module Question
5
+ extend ActiveSupport::Concern
6
+
7
+ include Hancock::HtmlField
8
+
9
+ included do
10
+ index({main_category_id: 1}, {background: true})
11
+ index({enabled: 1, lft: 1}, {background: true})
12
+ index({category_ids: 1}, {background: true})
13
+ index({answered: 1, answered_time: 1}, {background: true})
14
+ index({created_at: 1}, {background: true})
15
+
16
+ field :question_text
17
+ hancock_cms_html_field :question_text_after_editing, localize: Hancock::Faq.configuration.localize
18
+ field :author_name
19
+ field :author_name_text_after_editing, localize: Hancock::Faq.configuration.localize
20
+ field :author_email
21
+
22
+ field :answered, type: Boolean, default: false
23
+ hancock_cms_html_field :answer_text, localize: Hancock::Faq.configuration.localize
24
+ field :answered_time, type: Time
25
+ field :answer_author_name, default: Hancock::Faq.configuration.default_answer_author_name
26
+
27
+ has_and_belongs_to_many :categories, class_name: "Hancock::Faq::Category", inverse_of: nil
28
+
29
+ acts_as_nested_set
30
+ scope :sorted, -> { order_by([:lft, :asc]) }
31
+
32
+ scope :after_now, -> { where(:created_at.lt => Time.now) }
33
+ scope :by_date, -> { desc(:created_at) }
34
+ scope :by_answered_date, -> { desc(:answered_time) }
35
+ scope :answered, -> { where(answered: true) }
36
+ scope :not_answered, -> { where(answered: false) }
37
+
38
+ scope :recent, ->(count = 5) { enabled.after_now.by_date.limit(count) }
39
+
40
+
41
+ def category
42
+ self.categories.enabled.sorted.first
43
+ end
44
+
45
+ def question_text_output
46
+ self.question_text_after_editing.blank? ? self.question_text : self.question_text_after_editing
47
+ end
48
+
49
+ def author_name_output
50
+ self.author_name_text_after_editing.blank? ? self.author_name : self.author_name_text_after_editing
51
+ end
52
+
53
+
54
+ if Hancock.rails5?
55
+ if relations.has_key?("updater") and defined?(::Mongoid::History)
56
+ belongs_to :updater, class_name: ::Mongoid::History.modifier_class_name, optional: true, validate: false
57
+ _validators.delete(:updater)
58
+ _validate_callbacks.each do |callback|
59
+ if callback.raw_filter.respond_to?(:attributes) and callback.raw_filter.attributes.include?(:updater)
60
+ _validate_callbacks.delete(callback)
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+
69
+ end
70
+ end
71
+ end
72
+ end