my_forum 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +12 -1
  3. data/Rakefile +4 -3
  4. data/{test/dummy/public/favicon.ico → app/assets/javascripts/my_forum/admin/categories.js.coffee} +0 -0
  5. data/app/assets/javascripts/my_forum/admin/dashboard.js.coffee +0 -0
  6. data/app/assets/javascripts/my_forum/admin/forums.js.coffee +0 -0
  7. data/app/assets/javascripts/my_forum/admin/roles.js +2 -0
  8. data/app/assets/javascripts/my_forum/admin/users.js +2 -0
  9. data/app/assets/javascripts/my_forum/application.js +6 -0
  10. data/app/assets/javascripts/my_forum/forums.js.coffee +0 -0
  11. data/app/assets/javascripts/my_forum/jquery.scrollTo.min.js +7 -0
  12. data/app/assets/javascripts/my_forum/jquery.selection.js +354 -0
  13. data/app/assets/javascripts/my_forum/my_forum.js.coffee +118 -0
  14. data/app/assets/javascripts/my_forum/posts.js.coffee +20 -0
  15. data/app/assets/javascripts/my_forum/topics.js.coffee +0 -0
  16. data/app/assets/javascripts/my_forum/users.js.coffee +0 -0
  17. data/app/assets/javascripts/my_forum/welcome.js.coffee +0 -0
  18. data/app/assets/stylesheets/my_forum/admin/categories.css.scss +0 -0
  19. data/app/assets/stylesheets/my_forum/admin/dashboard.css.scss +3 -0
  20. data/app/assets/stylesheets/my_forum/admin/forums.css.scss +7 -0
  21. data/app/assets/stylesheets/my_forum/admin/roles.css +4 -0
  22. data/app/assets/stylesheets/my_forum/admin/users.css +4 -0
  23. data/app/assets/stylesheets/my_forum/application.css.scss +80 -0
  24. data/app/assets/stylesheets/my_forum/forums.css.scss +31 -0
  25. data/app/assets/stylesheets/my_forum/posts.css.scss +138 -0
  26. data/app/assets/stylesheets/my_forum/private_messages.css.scss +11 -0
  27. data/app/assets/stylesheets/my_forum/topics.css.scss +16 -0
  28. data/app/assets/stylesheets/my_forum/users.css.scss +3 -0
  29. data/app/assets/stylesheets/my_forum/welcome.css.scss +73 -0
  30. data/app/controllers/my_forum/admin/categories_controller.rb +36 -0
  31. data/app/controllers/my_forum/admin/dashboard_controller.rb +13 -0
  32. data/app/controllers/my_forum/admin/emoticons_controller.rb +65 -0
  33. data/app/controllers/my_forum/admin/forums_controller.rb +35 -0
  34. data/app/controllers/my_forum/admin/mail_controller.rb +31 -0
  35. data/app/controllers/my_forum/admin/roles_controller.rb +38 -0
  36. data/app/controllers/my_forum/admin/users_controller.rb +14 -0
  37. data/app/controllers/my_forum/application_controller.rb +81 -0
  38. data/app/controllers/my_forum/attachments_controller.rb +30 -0
  39. data/app/controllers/my_forum/forums_controller.rb +39 -0
  40. data/app/controllers/my_forum/images_controller.rb +7 -0
  41. data/app/controllers/my_forum/posts_controller.rb +96 -0
  42. data/app/controllers/my_forum/private_messages_controller.rb +73 -0
  43. data/app/controllers/my_forum/topics_controller.rb +96 -0
  44. data/app/controllers/my_forum/users_controller.rb +145 -0
  45. data/app/controllers/my_forum/welcome_controller.rb +30 -0
  46. data/app/helpers/my_forum/admin/dashboard_helper.rb +4 -0
  47. data/app/helpers/my_forum/admin/forums_helper.rb +4 -0
  48. data/app/helpers/my_forum/admin/roles_helper.rb +4 -0
  49. data/app/helpers/my_forum/admin/users_helper.rb +4 -0
  50. data/app/helpers/my_forum/application_helper.rb +43 -0
  51. data/app/helpers/my_forum/emoticons_helper.rb +7 -0
  52. data/app/helpers/my_forum/forums_helper.rb +44 -0
  53. data/app/helpers/my_forum/posts_helper.rb +76 -0
  54. data/app/helpers/my_forum/private_messages_helper.rb +25 -0
  55. data/app/helpers/my_forum/topics_helper.rb +18 -0
  56. data/app/helpers/my_forum/users_helper.rb +33 -0
  57. data/app/helpers/my_forum/welcome_helper.rb +4 -0
  58. data/app/mailers/application_mailer.rb +4 -0
  59. data/app/mailers/my_forum/user_mailer.rb +31 -0
  60. data/app/models/my_forum/attachment.rb +12 -0
  61. data/app/models/my_forum/avatar.rb +11 -0
  62. data/app/models/my_forum/category.rb +7 -0
  63. data/app/models/my_forum/category_permission.rb +6 -0
  64. data/app/models/my_forum/emoticon.rb +6 -0
  65. data/app/models/my_forum/forum.rb +50 -0
  66. data/app/models/my_forum/image.rb +5 -0
  67. data/app/models/my_forum/log_read_mark.rb +4 -0
  68. data/app/models/my_forum/post.rb +26 -0
  69. data/app/models/my_forum/private_message.rb +8 -0
  70. data/app/models/my_forum/role.rb +6 -0
  71. data/app/models/my_forum/topic.rb +41 -0
  72. data/app/models/my_forum/user.rb +71 -0
  73. data/app/models/my_forum/user_group.rb +13 -0
  74. data/app/models/my_forum/user_group_link.rb +6 -0
  75. data/app/models/my_forum/user_roles.rb +6 -0
  76. data/app/views/layouts/mailer.html.erb +5 -0
  77. data/app/views/layouts/mailer.text.erb +1 -0
  78. data/app/views/layouts/my_forum/_guest_navbar.html.haml +4 -0
  79. data/app/views/layouts/my_forum/_user_navbar.html.haml +19 -0
  80. data/app/views/layouts/my_forum/admin_application.haml +29 -0
  81. data/app/views/layouts/my_forum/application.haml +23 -0
  82. data/app/views/my_forum/admin/categories/edit.haml +9 -0
  83. data/app/views/my_forum/admin/categories/new.haml +5 -0
  84. data/app/views/my_forum/admin/dashboard/index.haml +0 -0
  85. data/app/views/my_forum/admin/emoticons/edit.haml +4 -0
  86. data/app/views/my_forum/admin/emoticons/index.haml +15 -0
  87. data/app/views/my_forum/admin/emoticons/new.haml +5 -0
  88. data/app/views/my_forum/admin/forums/index.haml +47 -0
  89. data/app/views/my_forum/admin/forums/new.haml +6 -0
  90. data/app/views/my_forum/admin/mail/index.haml +9 -0
  91. data/app/views/my_forum/admin/roles/index.haml +12 -0
  92. data/app/views/my_forum/admin/roles/new.haml +22 -0
  93. data/app/views/my_forum/admin/users/index.haml +10 -0
  94. data/app/views/my_forum/forums/_topic_subject.html.haml +16 -0
  95. data/app/views/my_forum/forums/show.haml +29 -0
  96. data/app/views/my_forum/posts/edit.html.haml +31 -0
  97. data/app/views/my_forum/private_messages/_sidebar.haml +10 -0
  98. data/app/views/my_forum/private_messages/inbox.haml +26 -0
  99. data/app/views/my_forum/private_messages/new.haml +21 -0
  100. data/app/views/my_forum/private_messages/show.haml +10 -0
  101. data/app/views/my_forum/shared/_post_preview.haml +15 -0
  102. data/app/views/my_forum/shared/_upload_photo.haml +45 -0
  103. data/app/views/my_forum/shared/post_preview.js.coffee +4 -0
  104. data/app/views/my_forum/topics/_post.haml +29 -0
  105. data/app/views/my_forum/topics/_profile_popover.haml +47 -0
  106. data/app/views/my_forum/topics/_quick_answer.haml +34 -0
  107. data/app/views/my_forum/topics/_topic_header.haml +4 -0
  108. data/app/views/my_forum/topics/_user_info.haml +9 -0
  109. data/app/views/my_forum/topics/new.haml +38 -0
  110. data/app/views/my_forum/topics/show.haml +60 -0
  111. data/app/views/my_forum/user_mailer/custom_email.text.erb +1 -0
  112. data/app/views/my_forum/user_mailer/ping_from_post.haml +8 -0
  113. data/app/views/my_forum/user_mailer/ping_from_post.text.erb +6 -0
  114. data/app/views/my_forum/user_mailer/pm_notification.text.erb +6 -0
  115. data/app/views/my_forum/user_mailer/reset_password_email.haml +1 -0
  116. data/app/views/my_forum/user_mailer/reset_password_email.text.erb +1 -0
  117. data/app/views/my_forum/users/edit.haml +36 -0
  118. data/app/views/my_forum/users/forgot_password.haml +10 -0
  119. data/app/views/my_forum/users/new.haml +14 -0
  120. data/app/views/my_forum/users/signin.haml +14 -0
  121. data/app/views/my_forum/users/signout.haml +0 -0
  122. data/app/views/my_forum/welcome/index.haml +37 -0
  123. data/config/initializers/will_paginate.rb +24 -0
  124. data/config/locales/en.yml +68 -0
  125. data/config/locales/ru.yml +198 -0
  126. data/config/routes.rb +48 -0
  127. data/db/migrate/20141117122725_create_my_forum_forums.rb +12 -0
  128. data/db/migrate/20141117122742_create_my_forum_topics.rb +17 -0
  129. data/db/migrate/20141117122751_create_my_forum_posts.rb +11 -0
  130. data/db/migrate/20141118081021_create_my_forum_categories.rb +8 -0
  131. data/db/migrate/20141118131215_create_my_forum_users.rb +34 -0
  132. data/db/migrate/20141222094522_create_my_forum_roles.rb +10 -0
  133. data/db/migrate/20141222094538_create_my_forum_user_roles.rb +9 -0
  134. data/db/migrate/20150202115250_create_my_forum_log_read_marks.rb +10 -0
  135. data/db/migrate/20150215200453_create_my_forum_user_groups.rb +15 -0
  136. data/db/migrate/20150215204852_create_my_forum_user_group_links.rb +9 -0
  137. data/db/migrate/20150215212443_create_my_forum_category_permissions.rb +9 -0
  138. data/db/migrate/20150227210814_create_my_forum_private_messages.rb +16 -0
  139. data/db/migrate/20151012095554_create_my_forum_images.rb +12 -0
  140. data/db/migrate/20151218135729_add_is_deleted.rb +6 -0
  141. data/db/migrate/20151220121140_create_my_forum_emoticons.rb +10 -0
  142. data/db/migrate/20151221203243_my_forum_rename_user_avatar.rb +5 -0
  143. data/db/migrate/20151221205045_my_forum_change_user_avatar.rb +5 -0
  144. data/db/migrate/20160122202142_add_latest_post_info_for_topic.rb +24 -0
  145. data/db/migrate/20160210130805_add_indexes_for_topics.rb +7 -0
  146. data/db/migrate/20160214085201_add_edited_by_for_post.rb +5 -0
  147. data/lib/my_forum/engine.rb +31 -0
  148. data/lib/my_forum/version.rb +1 -1
  149. data/lib/tasks/my_forum_tasks.rake +155 -4
  150. data/spec/controllers/my_forum/admin/emoticons_controller_spec.rb +7 -0
  151. data/spec/controllers/my_forum/admin/mail_controller_spec.rb +7 -0
  152. data/spec/controllers/my_forum/private_messages_controller_spec.rb +7 -0
  153. data/spec/controllers/my_forum/users_controller_spec.rb +76 -0
  154. data/{test → spec}/dummy/README.rdoc +0 -0
  155. data/{test → spec}/dummy/Rakefile +0 -0
  156. data/{test → spec}/dummy/app/assets/javascripts/application.js +1 -1
  157. data/{app/assets/stylesheets/my_forum → spec/dummy/app/assets/stylesheets}/application.css +1 -1
  158. data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
  159. data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
  160. data/{test → spec}/dummy/app/views/layouts/application.html.erb +0 -0
  161. data/{test → spec}/dummy/bin/bundle +0 -0
  162. data/{test → spec}/dummy/bin/rails +0 -0
  163. data/{test → spec}/dummy/bin/rake +0 -0
  164. data/{test → spec}/dummy/config/application.rb +0 -0
  165. data/{test → spec}/dummy/config/boot.rb +0 -0
  166. data/{test → spec}/dummy/config/database.yml +0 -0
  167. data/{test → spec}/dummy/config/environment.rb +0 -0
  168. data/{test → spec}/dummy/config/environments/development.rb +0 -0
  169. data/{test → spec}/dummy/config/environments/production.rb +1 -1
  170. data/{test → spec}/dummy/config/environments/test.rb +1 -1
  171. data/{test → spec}/dummy/config/initializers/assets.rb +0 -0
  172. data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
  173. data/{test → spec}/dummy/config/initializers/cookies_serializer.rb +0 -0
  174. data/{test → spec}/dummy/config/initializers/filter_parameter_logging.rb +0 -0
  175. data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
  176. data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
  177. data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
  178. data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
  179. data/{test → spec}/dummy/config/locales/en.yml +0 -0
  180. data/{test → spec}/dummy/config/routes.rb +0 -0
  181. data/{test → spec}/dummy/config/secrets.yml +0 -0
  182. data/{test → spec}/dummy/config.ru +0 -0
  183. data/spec/dummy/db/development.sqlite3 +0 -0
  184. data/spec/dummy/db/schema.rb +159 -0
  185. data/spec/dummy/db/test.sqlite3 +0 -0
  186. data/spec/dummy/log/development.log +12 -0
  187. data/{test → spec}/dummy/public/404.html +0 -0
  188. data/{test → spec}/dummy/public/422.html +0 -0
  189. data/{test → spec}/dummy/public/500.html +0 -0
  190. data/spec/dummy/public/favicon.ico +0 -0
  191. data/spec/helpers/my_forum/posts_helper_spec.rb +24 -0
  192. data/spec/helpers/my_forum/private_messages_helper_spec.rb +17 -0
  193. data/spec/models/my_forum/emoticon_spec.rb +7 -0
  194. data/spec/models/my_forum/private_message_spec.rb +7 -0
  195. data/spec/models/my_forum/user_spec.rb +13 -0
  196. data/spec/rails_helper.rb +52 -0
  197. data/spec/spec_helper.rb +87 -0
  198. metadata +356 -83
  199. data/app/views/layouts/my_forum/application.html.erb +0 -14
  200. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  201. data/test/integration/navigation_test.rb +0 -10
  202. data/test/my_forum_test.rb +0 -7
  203. data/test/test_helper.rb +0 -15
@@ -0,0 +1,39 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class ForumsController < ApplicationController
5
+ before_filter :find_forum, only: [:show]
6
+
7
+ def show
8
+ check_access_permissions(@forum)
9
+ @forum_topics = @forum.topics_with_latest_post_info(page: params[:page], per_page: Post::PER_PAGE)
10
+ end
11
+
12
+ def unread_topics
13
+ redirect_to root_path and return unless current_user
14
+ @forum_topics = Forum.unread_topics_with_latest_post_info(user_id: current_user_id, page: params[:page], per_page: 30)
15
+
16
+ render action: :show
17
+ end
18
+
19
+ def mark_all_as_read
20
+ redirect_to root_path and return unless current_user
21
+
22
+ Topic.find_in_batches(batch_size: 500) do |topic_group|
23
+ topic_group.each do |topic|
24
+ log = LogReadMark.find_or_create_by(user_id: current_user.id, topic_id: topic.id)
25
+ log.post_id = topic.latest_post_id
26
+ log.save
27
+ end
28
+ end
29
+
30
+ redirect_to root_path
31
+ end
32
+
33
+ private
34
+
35
+ def find_forum
36
+ @forum = Forum.find(params[:id])
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class ImagesController < ApplicationController
5
+
6
+ end
7
+ end
@@ -0,0 +1,96 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class PostsController < ApplicationController
5
+ before_filter :verify_admin, only: [:edit, :update]
6
+ before_filter :find_topic, except: [:show, :preview]
7
+ before_filter :find_forum, except: [:show, :preview]
8
+
9
+ include PostsHelper
10
+
11
+ def create
12
+ unless params[:post].fetch(:text).blank?
13
+ post = @topic.posts.build(post_params)
14
+ post.user = current_user
15
+ post.save
16
+
17
+ process_attachments(post)
18
+ end
19
+
20
+ last_page = (@topic.posts.count.to_f / Post::PER_PAGE).ceil
21
+ last_page = 1 if last_page == 0
22
+
23
+ ping_user params[:post].fetch(:text), last_page
24
+
25
+ redirect_to forum_topic_path(@forum, @topic, page: last_page, go_to_last_post: true)
26
+ end
27
+
28
+ def destroy
29
+ post = Post.find(params[:id])
30
+ post.update(is_deleted: true)
31
+ redirect_to forum_topic_path(post.topic.forum, post.topic)
32
+ end
33
+
34
+ def show
35
+ post = Post.find(params[:id])
36
+ respond_to do |format|
37
+ format.js { render json: { text: post.text, author: post.user.login }.as_json, status: :ok }
38
+ end
39
+ end
40
+
41
+ def edit
42
+ @forum = Forum.find(params[:forum_id])
43
+ @topic = Topic.find(params[:topic_id])
44
+ @post = Post.find(params[:id])
45
+ end
46
+
47
+ def update
48
+ post = Post.find(params[:id])
49
+ post.text = params[:post][:text]
50
+ post.edited_by = current_user.login
51
+ post.save
52
+
53
+ redirect_to forum_topic_path(post.topic.forum, post.topic, page: params[:page])
54
+ end
55
+
56
+ def preview
57
+ preview_html = ActionController::Base.helpers.sanitize format_bbcode(params[:text])
58
+ render '/my_forum/shared/post_preview.js.coffee', layout: false, locals: { preview_html: preview_html }
59
+ end
60
+
61
+ private
62
+
63
+ # Send notification for all users those mentioned in post through '@' symbol
64
+ # Example: Hey, @Steave, go drink some vodka
65
+ # In this case user with 'Steave' login gets notification with link to this post
66
+ def ping_user(post_text, page)
67
+ return unless post_text
68
+
69
+ post_text.scan(/@\S+/).each do |user_login|
70
+ user = User.find_by_login(user_login[1..-1]) # strip @
71
+ UserMailer.ping_from_post(user, @topic, page).deliver_later if user
72
+ end
73
+ end
74
+
75
+ def process_attachments(post)
76
+ return unless matches = post_params.to_s.match(/\[attachment=([0-9]+)\]/i)
77
+
78
+ matches.captures.map(&:to_i).each do |attachment_id|
79
+ attachment = Attachment.where(id: attachment_id).first
80
+ attachment.update(post: post) if attachment and post.user == attachment.user
81
+ end
82
+ end
83
+
84
+ def find_topic
85
+ @topic = Topic.find(params[:topic_id])
86
+ end
87
+
88
+ def find_forum
89
+ @forum = Forum.find(params[:forum_id])
90
+ end
91
+
92
+ def post_params
93
+ params.require(:post).permit(:text)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,73 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class PrivateMessagesController < ApplicationController
5
+
6
+ before_filter :only_for_registered_users
7
+
8
+ def index
9
+ @private_messages = PrivateMessage.inbox_for(current_user).paginate(per_page: 16, page: params[:page])
10
+ render :inbox
11
+ end
12
+
13
+ def inbox
14
+
15
+ end
16
+
17
+ def outbox
18
+
19
+ end
20
+
21
+ def deleted
22
+
23
+ end
24
+
25
+ def new
26
+ @pm = PrivateMessage.new
27
+ @reply_pm = PrivateMessage.find(params[:reply_for_id]) if params[:reply_for_id]
28
+ end
29
+
30
+ def create
31
+ @pm = PrivateMessage.new
32
+ recipient = begin
33
+ User.find_by_login(params[:private_message].delete(:recipient))
34
+ rescue
35
+ #TODO send notification to admin
36
+ nil
37
+ end
38
+
39
+ unless recipient
40
+ @pm.errors.add(:base, t('.cant_find_recipient'))
41
+ render :new
42
+ return
43
+ end
44
+
45
+ @pm.recipient_id = recipient.id
46
+ @pm.recipient_login = recipient.login
47
+ @pm.sender_id = current_user_id
48
+ @pm.sender_login = current_user.login
49
+ @pm.assign_attributes(pm_params)
50
+
51
+ UserMailer.pm_notification(recipient, current_user).deliver_now if @pm.save
52
+
53
+ flash[:notice] = I18n.t('my_forum.pm.sent')
54
+
55
+ redirect_to action: :index
56
+ end
57
+
58
+ def show
59
+ @pm = PrivateMessage.inbox_for(current_user).find(params[:id])
60
+ @pm.update!(unread: false)
61
+ end
62
+
63
+ private
64
+
65
+ def pm_params
66
+ params.require(:private_message).permit(:subject, :body)
67
+ end
68
+
69
+ def only_for_registered_users
70
+ redirect_to root_path unless current_user
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,96 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class TopicsController < ApplicationController
5
+ before_filter :find_forum, only: [:new, :create, :show]
6
+ before_filter :check_is_admin, only: [:pin, :close, :delete]
7
+
8
+ def new
9
+ @topic = @forum.topics.build
10
+ end
11
+
12
+ def show
13
+ @topic = Topic.find(params[:id])
14
+ check_access_permissions(@topic)
15
+
16
+ user_last_page = get_last_readed_user_page
17
+
18
+ @topic_posts = @topic.posts.includes(:user, :topic).paginate(per_page: Post::PER_PAGE, page: (params[:page] || user_last_page))
19
+ @new_post = Post.new #TODO if quick_answer_enabled
20
+
21
+ @topic.mark_as_read(current_user, @topic_posts.last)
22
+ @topic.increment!(:views) if current_user
23
+ end
24
+
25
+ def create
26
+ raise unless current_user
27
+ #TODO !
28
+ topic = @forum.topics.build(topic_params)
29
+ post = topic.posts.build(post_params)
30
+ post.user = current_user
31
+
32
+ topic.save
33
+ post.save
34
+
35
+ topic.mark_as_read(current_user, post)
36
+
37
+ redirect_to forum_path(@forum)
38
+ end
39
+
40
+ def pin
41
+ return unless topic = Topic.find_by_id(params[:topic_id])
42
+ topic.toggle!(:pinned)
43
+
44
+ redirect_to forum_topic_path(topic.forum, topic)
45
+ end
46
+
47
+ def close
48
+ return unless topic = Topic.find_by_id(params[:topic_id])
49
+ topic.toggle!(:closed)
50
+
51
+ redirect_to forum_topic_path(topic.forum, topic)
52
+ end
53
+
54
+ def delete
55
+ return unless topic = Topic.find_by_id(params[:topic_id])
56
+ topic.update!(deleted: true)
57
+
58
+ redirect_to forum_path(topic.forum)
59
+ end
60
+
61
+ private
62
+
63
+ # TODO development in progress
64
+ def get_last_readed_user_page
65
+ return nil if current_user.blank?
66
+ return nil unless params[:page].blank?
67
+ user_last_page = nil
68
+
69
+ latest_readed_post = LogReadMark.where(user_id: current_user.id, topic_id: @topic.id).first
70
+ return nil unless latest_readed_post
71
+
72
+ page_groups = @topic.posts.pluck(:id).in_groups_of(Post::PER_PAGE)
73
+ page_groups.each_with_index { |group, page| user_last_page = page and break if group.include?(latest_readed_post.post_id) }
74
+ user_last_page +=1 if user_last_page
75
+
76
+ user_last_page
77
+ end
78
+
79
+ def check_is_admin
80
+ return unless current_user
81
+ return unless current_user.is_admin?
82
+ end
83
+
84
+ def find_forum
85
+ @forum = Forum.find(params[:forum_id])
86
+ end
87
+
88
+ def topic_params
89
+ params.require(:topic).permit(:name, :description)
90
+ end
91
+
92
+ def post_params
93
+ params.require(:post).permit(:text)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,145 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class UsersController < ApplicationController
5
+
6
+ before_filter :authorize_user, only: [:edit, :update]
7
+
8
+ def new
9
+ @user = User.new
10
+ end
11
+
12
+ def edit
13
+ end
14
+
15
+ def update
16
+ update_password
17
+
18
+ current_user.update!(user_update_params)
19
+
20
+ User::ADDITIONAL_INFO_ATTRS.each do |attr|
21
+ current_user.update(attr => params[:user][attr]) if params[:user][attr]
22
+ end
23
+
24
+ redirect_to edit_user_path(current_user)
25
+ end
26
+
27
+ def create
28
+ @user = User.new(user_params)
29
+ if @user.valid?
30
+ @user.user_groups << UserGroup::MEMBER_GROUP
31
+ @user.save
32
+ session[:user_id] = @user.id
33
+ redirect_to root_path
34
+ else
35
+ render :new
36
+ end
37
+ end
38
+
39
+ def signin
40
+ if request.post?
41
+ if params[:user].blank?
42
+ render :layout => 'signin'
43
+ return
44
+ end
45
+
46
+ user = User.find_by_login(params[:user][:login])
47
+ if user && user.valid_password?(params[:user][:password])
48
+ session[:user_id] = user.id
49
+ redirect_to root_path
50
+ return
51
+ else
52
+ flash[:error] = t('.invalid_login_or_password')
53
+ return
54
+ end
55
+ end
56
+ end
57
+
58
+ def forgot_password
59
+ if request.post?
60
+ return unless user = User.find_by_email(params[:user][:email])
61
+ UserMailer.reset_password_email(user).deliver_now
62
+ flash[:notice] = t('.new_password_sent')
63
+ redirect_to root_path
64
+ end
65
+ end
66
+
67
+ def logout
68
+ session[:user_id] = nil
69
+ redirect_to admin_root_path
70
+ end
71
+
72
+ def authorize_user
73
+ redirect_to root_path unless current_user
74
+ end
75
+
76
+ def autocomplete
77
+ #TODO mysql safe
78
+ search_string = params[:str]
79
+ user_list = MyForum::User.where("login LIKE '%#{search_string}%'").pluck(:login)
80
+
81
+ respond_to do |format|
82
+ format.html { raise 'denied' }
83
+ format.js { render json: user_list }
84
+ end
85
+ end
86
+
87
+ def avatar_update
88
+ if params[:user][:avatar]
89
+ avatar = upload_avatar(params[:user][:avatar])
90
+ current_user.update(avatar_url: File.join(Avatar::URL, current_user.id.to_s, avatar.file_name)) if avatar
91
+ elsif params[:user][:avatar_url]
92
+ current_user.update_columns(avatar_params)
93
+ end
94
+
95
+ redirect_to edit_user_path(current_user)
96
+ end
97
+
98
+ private
99
+
100
+ def avatar_params
101
+ params.require(:user).permit(:avatar_url)
102
+ end
103
+
104
+ def user_params
105
+ params.require(:user).permit(:login, :email, :password)
106
+ end
107
+
108
+ def user_update_params
109
+ params.require(:user).permit(:email)
110
+ end
111
+
112
+ def update_password
113
+ current_password = user_params.delete(:password)
114
+ new_password = params[:user].delete(:new_password)
115
+
116
+ return unless new_password
117
+ return unless current_user.valid_password?(current_password)
118
+ current_user.update_attributes(password: new_password)
119
+ end
120
+
121
+ def upload_avatar(avatar_param)
122
+ return false unless Avatar::ALLOWED_FILE_CONTENT_TYPE.include? avatar_param.content_type
123
+
124
+ current_avatar = current_user.avatar
125
+ upload_path = File.join(Avatar::UPLOAD_PATH, current_user.id.to_s)
126
+
127
+ # Create dir of not exists
128
+ FileUtils::mkdir_p upload_path
129
+
130
+ File.open(File.join(upload_path, avatar_param.original_filename), 'wb') do |file|
131
+ file.write(avatar_param.read)
132
+ end
133
+
134
+ new_avatar = Avatar.create(user_id: current_user.id, file_name: avatar_param.original_filename)
135
+
136
+ if current_avatar and new_avatar
137
+ FileUtils.rm File.join(upload_path, current_avatar.file_name) rescue nil
138
+ current_avatar.destroy
139
+ end
140
+
141
+ new_avatar
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,30 @@
1
+ require_dependency "my_forum/application_controller"
2
+
3
+ module MyForum
4
+ class WelcomeController < ApplicationController
5
+ def index
6
+ @forum_categories = if current_user && current_user.is_admin?
7
+ Category.includes(:forums)
8
+ else
9
+ @forum_categories = Category.includes(:forums, :user_groups).
10
+ reject{|category| (category.user_groups.map(&:name) & (current_user_groups)).blank? }
11
+ end
12
+
13
+
14
+ # Don`r forget permissions
15
+ available_forum_ids = MyForum::Forum.where(category_id: @forum_categories.map(&:id)).pluck(:id)
16
+ @recent_posts = if available_forum_ids.blank?
17
+ []
18
+ else
19
+ Topic.find_by_sql("
20
+ SELECT posts.id, posts.user_id, posts.text, posts.topic_id, posts.updated_at, topics.name as topic_name, topics.forum_id, topics.deleted FROM my_forum_posts AS posts
21
+ LEFT JOIN my_forum_topics AS topics ON posts.topic_id = topics.id
22
+ LEFT JOIN my_forum_forums AS forums ON forums.id = topics.forum_id
23
+ WHERE posts.id IN (SELECT MAX(id) FROM my_forum_posts GROUP BY topic_id) AND posts.is_deleted IS FALSE AND topics.deleted IS FALSE AND forums.id IN (#{available_forum_ids.join(',')})
24
+ ORDER BY posts.id DESC LIMIT 10
25
+ ")
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ module MyForum
2
+ module Admin::DashboardHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MyForum
2
+ module Admin::ForumsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MyForum
2
+ module Admin::RolesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MyForum
2
+ module Admin::UsersHelper
3
+ end
4
+ end
@@ -1,4 +1,47 @@
1
1
  module MyForum
2
2
  module ApplicationHelper
3
+
4
+ def draw_navigation
5
+ html_li = content_tag :li, link_to('Forums', root_path)
6
+
7
+ if @forum
8
+ html_li += content_tag :li, '&rarr;'.html_safe
9
+ html_li += content_tag :li, link_to(@forum.name, forum_path(@forum))
10
+ end
11
+
12
+ if @forum && @topic && !@topic.new_record?
13
+ html_li += content_tag :li, '&rarr;'.html_safe
14
+ html_li += content_tag :li, link_to(@topic.name.html_safe, forum_topic_path(@forum, @topic))
15
+ end
16
+
17
+ html = content_tag :ul, class: 'draw-navigation' do
18
+ html_li
19
+ end
20
+
21
+ html.html_safe
22
+ end
23
+
24
+ def online_users
25
+ User.online.pluck(:login).join(', ')
26
+ end
27
+
28
+ def today_was_users
29
+ User.today_visited.pluck(:login).join(', ')
30
+ end
31
+
32
+ def errors_for(obj)
33
+ return if obj.errors.blank?
34
+
35
+ content_tag :div, obj.errors.full_messages.to_sentence, class: 'errors_for'
36
+ end
37
+
38
+ # TODO deprecate!
39
+ def time(datetime)
40
+ forum_time(datetime)
41
+ end
42
+
43
+ def upload_allowed_extensions
44
+ Attachment::ALLOWED_FILE_EXTENSIONS
45
+ end
3
46
  end
4
47
  end
@@ -0,0 +1,7 @@
1
+ module MyForum
2
+ module EmoticonsHelper
3
+ def emoticon_url_for(emoticon)
4
+ File.join(Emoticon::URL, emoticon.file_name)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,44 @@
1
+ module MyForum
2
+ module ForumsHelper
3
+
4
+ def forum_status_img(forum)
5
+ unread = 'lada_logo_unread.jpg'
6
+ read = 'lada_logo.jpg'
7
+
8
+ display_as = read
9
+ display_as = unread if forum.has_unread_posts?(current_user)
10
+
11
+ image_tag(display_as, width: '66px')
12
+ end
13
+
14
+ def forum_name(forum)
15
+ html = content_tag :strong, link_to(forum.name, forum_path(forum))
16
+ html += content_tag :div, forum.description
17
+ html.html_safe
18
+ end
19
+
20
+ def forum_stat(forum)
21
+ html = content_tag(:div, t('.topics_count', topics_count: forum.topics_count))
22
+ html += content_tag(:div, t('.messages_count', messages_count: forum.posts_count))
23
+ html.html_safe
24
+ end
25
+
26
+ def forum_last_message_info(forum)
27
+ topic = forum.topics.order('latest_post_created_at DESC').first
28
+
29
+ html = content_tag(:div, topic ? (t('.last_answer_from') + topic.latest_post_login) : '-' )
30
+ html += content_tag(:div, topic ? (link_to((t('.in_forum') + topic.name), forum_topic_path(topic.forum_id, topic.id))) : '-' )
31
+ html += content_tag(:div, topic ? forum_time(topic.latest_post_created_at) : '-' )
32
+
33
+ html.html_safe
34
+ end
35
+
36
+ def new_topic_button
37
+ return unless current_user
38
+ return unless @forum
39
+ content_tag :div, class: 'buttons_for_new_topic' do
40
+ link_to t('my_forum.create_new_topic'), new_forum_topic_path(@forum), class: 'btn btn-primary'
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,76 @@
1
+ module MyForum
2
+ module PostsHelper
3
+ def format_post_text(post)
4
+ format_bbcode(post.text)
5
+ end
6
+
7
+ def format_bbcode(text)
8
+ # Line Breask
9
+ text.gsub!(/\r\n/, '<br />')
10
+ text.gsub!(/\n/, '<br />')
11
+
12
+ # Images
13
+ text.gsub!(/\[img\]/i, '<img src="')
14
+ text.gsub!(/\[\/img\]/i, '" />')
15
+
16
+ # Youtube
17
+ text.gsub!(/(?:https?:\/\/)?(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=)?(?<video_code>[\w-]{10,})/i) do |match|
18
+ "<iframe width='560' height='315' src='https://www.youtube.com/embed/#{$~[:video_code]}' frameborder='0' allowfullscreen></iframe>"
19
+ end
20
+
21
+ # Attachments
22
+ text.gsub!(/\[attachment=([0-9]+)\]/i) do |match|
23
+ "<p> <img class='post_attachment' src='#{attachment_img_path($1)}' /> </p>"
24
+ end
25
+
26
+ # Bold text
27
+ text.gsub!(/(\[b\](?<bold_text>.+?)\[\/b\])/i) { |match| "<strong>#{$1}</strong>" }
28
+
29
+ # Italic
30
+ text.gsub!(/(\[i\])(?<italic_text>.*?)(\[\/i\])/i) { |match| "<i>#{$1}</i>" }
31
+
32
+ # Cut
33
+ text.gsub!(/(\[cut\])(?<cut_text>.*?)(\[\/cut\])/i) { |match| "<pre>#{$1}</pre>" }
34
+
35
+ # Color
36
+ text.gsub!(/\[color=(.*?)\](.*?)\[\/color\]/i) { "<span style='color: #{$1}'>#{$2}</span>" }
37
+
38
+ # Size
39
+ text.gsub!(/\[size=(.*?)\](.*?)\[\/size\]/i) { "<span style='font-size: #{$1}'>#{$2}</span>" }
40
+
41
+ # Quote
42
+ #text.gsub!(/\[quote author=(.*?) link=(.*?) date=(.*?)\]/i) { bbquote(author: $1, date: $3) }
43
+ #text.gsub!(/\[\/quote\]/i, '</div>')
44
+ #text.gsub!(/\[quote(.*)\]/i, "<div class='bbqoute'>")
45
+ text.gsub!(/\[quote author=(?<autor>.*)\](?<text>.*)\[\/quote\]/m) do |match|
46
+ "<div class='bbqoute'> <div class='quote_info'>#{$~[:autor]} #{t('my_forum.bbquote.wrote')}:</div> #{$~[:text]} </div>"
47
+ end
48
+
49
+ text.gsub!(/(?<open>\[quote author=(?<autor>(.*?)) (.+)\](?<text>(.+))(?<close>\[\/quote\]))/i) do |match|
50
+ # "<div class='bbqoute'> <div class='quote_info'>#{$~[:autor]} #{t('my_forum.bbquote.wrote')} #{Time.now}:</div> #{$~[:text]} </div>"
51
+ "<div class='bbqoute'> <div class='quote_info'>#{$~[:autor]} #{t('my_forum.bbquote.wrote')}:</div> #{$~[:text]} </div>"
52
+ end
53
+
54
+ # Emoticons (smiles)
55
+ emoticons_list.each do |code, path|
56
+ text.gsub!(/#{Regexp.quote(code)}/) { "<img src='#{path}' class='smile' />" }
57
+ end
58
+
59
+ # Link
60
+ # ActionController::Base.helpers.... - this method uses in controller, which don`t know link_to
61
+ text.gsub!(/\[url=(.*?)\](.*?)\[\/url\]/i) { ActionController::Base.helpers.link_to($2, $1, target: '_blank') }
62
+ text.gsub!(/(http:\/\/[\S]+|www:\/\/[\S]+)/i) { ActionController::Base.helpers.link_to($1, $1, target: '_blank') }
63
+
64
+ # Ping user
65
+ text.gsub!(/@\S+/) { |match| "<span class='badge'>#{match}</span>" }
66
+
67
+
68
+ text.html_safe
69
+ end
70
+
71
+ def bbquote(author:, date:)
72
+ date_time = time(DateTime.strptime(date, '%s')) rescue ''
73
+ "<div class='bbqoute'> <div class='quote_info'>#{author} #{t('my_forum.bbquote.wrote')} #{date_time}:</div> "
74
+ end
75
+ end
76
+ end