hancock_cms_faq 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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