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.
- checksums.yaml +4 -4
- data/README.rdoc +12 -1
- data/Rakefile +4 -3
- data/{test/dummy/public/favicon.ico → app/assets/javascripts/my_forum/admin/categories.js.coffee} +0 -0
- data/app/assets/javascripts/my_forum/admin/dashboard.js.coffee +0 -0
- data/app/assets/javascripts/my_forum/admin/forums.js.coffee +0 -0
- data/app/assets/javascripts/my_forum/admin/roles.js +2 -0
- data/app/assets/javascripts/my_forum/admin/users.js +2 -0
- data/app/assets/javascripts/my_forum/application.js +6 -0
- data/app/assets/javascripts/my_forum/forums.js.coffee +0 -0
- data/app/assets/javascripts/my_forum/jquery.scrollTo.min.js +7 -0
- data/app/assets/javascripts/my_forum/jquery.selection.js +354 -0
- data/app/assets/javascripts/my_forum/my_forum.js.coffee +118 -0
- data/app/assets/javascripts/my_forum/posts.js.coffee +20 -0
- data/app/assets/javascripts/my_forum/topics.js.coffee +0 -0
- data/app/assets/javascripts/my_forum/users.js.coffee +0 -0
- data/app/assets/javascripts/my_forum/welcome.js.coffee +0 -0
- data/app/assets/stylesheets/my_forum/admin/categories.css.scss +0 -0
- data/app/assets/stylesheets/my_forum/admin/dashboard.css.scss +3 -0
- data/app/assets/stylesheets/my_forum/admin/forums.css.scss +7 -0
- data/app/assets/stylesheets/my_forum/admin/roles.css +4 -0
- data/app/assets/stylesheets/my_forum/admin/users.css +4 -0
- data/app/assets/stylesheets/my_forum/application.css.scss +80 -0
- data/app/assets/stylesheets/my_forum/forums.css.scss +31 -0
- data/app/assets/stylesheets/my_forum/posts.css.scss +138 -0
- data/app/assets/stylesheets/my_forum/private_messages.css.scss +11 -0
- data/app/assets/stylesheets/my_forum/topics.css.scss +16 -0
- data/app/assets/stylesheets/my_forum/users.css.scss +3 -0
- data/app/assets/stylesheets/my_forum/welcome.css.scss +73 -0
- data/app/controllers/my_forum/admin/categories_controller.rb +36 -0
- data/app/controllers/my_forum/admin/dashboard_controller.rb +13 -0
- data/app/controllers/my_forum/admin/emoticons_controller.rb +65 -0
- data/app/controllers/my_forum/admin/forums_controller.rb +35 -0
- data/app/controllers/my_forum/admin/mail_controller.rb +31 -0
- data/app/controllers/my_forum/admin/roles_controller.rb +38 -0
- data/app/controllers/my_forum/admin/users_controller.rb +14 -0
- data/app/controllers/my_forum/application_controller.rb +81 -0
- data/app/controllers/my_forum/attachments_controller.rb +30 -0
- data/app/controllers/my_forum/forums_controller.rb +39 -0
- data/app/controllers/my_forum/images_controller.rb +7 -0
- data/app/controllers/my_forum/posts_controller.rb +96 -0
- data/app/controllers/my_forum/private_messages_controller.rb +73 -0
- data/app/controllers/my_forum/topics_controller.rb +96 -0
- data/app/controllers/my_forum/users_controller.rb +145 -0
- data/app/controllers/my_forum/welcome_controller.rb +30 -0
- data/app/helpers/my_forum/admin/dashboard_helper.rb +4 -0
- data/app/helpers/my_forum/admin/forums_helper.rb +4 -0
- data/app/helpers/my_forum/admin/roles_helper.rb +4 -0
- data/app/helpers/my_forum/admin/users_helper.rb +4 -0
- data/app/helpers/my_forum/application_helper.rb +43 -0
- data/app/helpers/my_forum/emoticons_helper.rb +7 -0
- data/app/helpers/my_forum/forums_helper.rb +44 -0
- data/app/helpers/my_forum/posts_helper.rb +76 -0
- data/app/helpers/my_forum/private_messages_helper.rb +25 -0
- data/app/helpers/my_forum/topics_helper.rb +18 -0
- data/app/helpers/my_forum/users_helper.rb +33 -0
- data/app/helpers/my_forum/welcome_helper.rb +4 -0
- data/app/mailers/application_mailer.rb +4 -0
- data/app/mailers/my_forum/user_mailer.rb +31 -0
- data/app/models/my_forum/attachment.rb +12 -0
- data/app/models/my_forum/avatar.rb +11 -0
- data/app/models/my_forum/category.rb +7 -0
- data/app/models/my_forum/category_permission.rb +6 -0
- data/app/models/my_forum/emoticon.rb +6 -0
- data/app/models/my_forum/forum.rb +50 -0
- data/app/models/my_forum/image.rb +5 -0
- data/app/models/my_forum/log_read_mark.rb +4 -0
- data/app/models/my_forum/post.rb +26 -0
- data/app/models/my_forum/private_message.rb +8 -0
- data/app/models/my_forum/role.rb +6 -0
- data/app/models/my_forum/topic.rb +41 -0
- data/app/models/my_forum/user.rb +71 -0
- data/app/models/my_forum/user_group.rb +13 -0
- data/app/models/my_forum/user_group_link.rb +6 -0
- data/app/models/my_forum/user_roles.rb +6 -0
- data/app/views/layouts/mailer.html.erb +5 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/layouts/my_forum/_guest_navbar.html.haml +4 -0
- data/app/views/layouts/my_forum/_user_navbar.html.haml +19 -0
- data/app/views/layouts/my_forum/admin_application.haml +29 -0
- data/app/views/layouts/my_forum/application.haml +23 -0
- data/app/views/my_forum/admin/categories/edit.haml +9 -0
- data/app/views/my_forum/admin/categories/new.haml +5 -0
- data/app/views/my_forum/admin/dashboard/index.haml +0 -0
- data/app/views/my_forum/admin/emoticons/edit.haml +4 -0
- data/app/views/my_forum/admin/emoticons/index.haml +15 -0
- data/app/views/my_forum/admin/emoticons/new.haml +5 -0
- data/app/views/my_forum/admin/forums/index.haml +47 -0
- data/app/views/my_forum/admin/forums/new.haml +6 -0
- data/app/views/my_forum/admin/mail/index.haml +9 -0
- data/app/views/my_forum/admin/roles/index.haml +12 -0
- data/app/views/my_forum/admin/roles/new.haml +22 -0
- data/app/views/my_forum/admin/users/index.haml +10 -0
- data/app/views/my_forum/forums/_topic_subject.html.haml +16 -0
- data/app/views/my_forum/forums/show.haml +29 -0
- data/app/views/my_forum/posts/edit.html.haml +31 -0
- data/app/views/my_forum/private_messages/_sidebar.haml +10 -0
- data/app/views/my_forum/private_messages/inbox.haml +26 -0
- data/app/views/my_forum/private_messages/new.haml +21 -0
- data/app/views/my_forum/private_messages/show.haml +10 -0
- data/app/views/my_forum/shared/_post_preview.haml +15 -0
- data/app/views/my_forum/shared/_upload_photo.haml +45 -0
- data/app/views/my_forum/shared/post_preview.js.coffee +4 -0
- data/app/views/my_forum/topics/_post.haml +29 -0
- data/app/views/my_forum/topics/_profile_popover.haml +47 -0
- data/app/views/my_forum/topics/_quick_answer.haml +34 -0
- data/app/views/my_forum/topics/_topic_header.haml +4 -0
- data/app/views/my_forum/topics/_user_info.haml +9 -0
- data/app/views/my_forum/topics/new.haml +38 -0
- data/app/views/my_forum/topics/show.haml +60 -0
- data/app/views/my_forum/user_mailer/custom_email.text.erb +1 -0
- data/app/views/my_forum/user_mailer/ping_from_post.haml +8 -0
- data/app/views/my_forum/user_mailer/ping_from_post.text.erb +6 -0
- data/app/views/my_forum/user_mailer/pm_notification.text.erb +6 -0
- data/app/views/my_forum/user_mailer/reset_password_email.haml +1 -0
- data/app/views/my_forum/user_mailer/reset_password_email.text.erb +1 -0
- data/app/views/my_forum/users/edit.haml +36 -0
- data/app/views/my_forum/users/forgot_password.haml +10 -0
- data/app/views/my_forum/users/new.haml +14 -0
- data/app/views/my_forum/users/signin.haml +14 -0
- data/app/views/my_forum/users/signout.haml +0 -0
- data/app/views/my_forum/welcome/index.haml +37 -0
- data/config/initializers/will_paginate.rb +24 -0
- data/config/locales/en.yml +68 -0
- data/config/locales/ru.yml +198 -0
- data/config/routes.rb +48 -0
- data/db/migrate/20141117122725_create_my_forum_forums.rb +12 -0
- data/db/migrate/20141117122742_create_my_forum_topics.rb +17 -0
- data/db/migrate/20141117122751_create_my_forum_posts.rb +11 -0
- data/db/migrate/20141118081021_create_my_forum_categories.rb +8 -0
- data/db/migrate/20141118131215_create_my_forum_users.rb +34 -0
- data/db/migrate/20141222094522_create_my_forum_roles.rb +10 -0
- data/db/migrate/20141222094538_create_my_forum_user_roles.rb +9 -0
- data/db/migrate/20150202115250_create_my_forum_log_read_marks.rb +10 -0
- data/db/migrate/20150215200453_create_my_forum_user_groups.rb +15 -0
- data/db/migrate/20150215204852_create_my_forum_user_group_links.rb +9 -0
- data/db/migrate/20150215212443_create_my_forum_category_permissions.rb +9 -0
- data/db/migrate/20150227210814_create_my_forum_private_messages.rb +16 -0
- data/db/migrate/20151012095554_create_my_forum_images.rb +12 -0
- data/db/migrate/20151218135729_add_is_deleted.rb +6 -0
- data/db/migrate/20151220121140_create_my_forum_emoticons.rb +10 -0
- data/db/migrate/20151221203243_my_forum_rename_user_avatar.rb +5 -0
- data/db/migrate/20151221205045_my_forum_change_user_avatar.rb +5 -0
- data/db/migrate/20160122202142_add_latest_post_info_for_topic.rb +24 -0
- data/db/migrate/20160210130805_add_indexes_for_topics.rb +7 -0
- data/db/migrate/20160214085201_add_edited_by_for_post.rb +5 -0
- data/lib/my_forum/engine.rb +31 -0
- data/lib/my_forum/version.rb +1 -1
- data/lib/tasks/my_forum_tasks.rake +155 -4
- data/spec/controllers/my_forum/admin/emoticons_controller_spec.rb +7 -0
- data/spec/controllers/my_forum/admin/mail_controller_spec.rb +7 -0
- data/spec/controllers/my_forum/private_messages_controller_spec.rb +7 -0
- data/spec/controllers/my_forum/users_controller_spec.rb +76 -0
- data/{test → spec}/dummy/README.rdoc +0 -0
- data/{test → spec}/dummy/Rakefile +0 -0
- data/{test → spec}/dummy/app/assets/javascripts/application.js +1 -1
- data/{app/assets/stylesheets/my_forum → spec/dummy/app/assets/stylesheets}/application.css +1 -1
- data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
- data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
- data/{test → spec}/dummy/app/views/layouts/application.html.erb +0 -0
- data/{test → spec}/dummy/bin/bundle +0 -0
- data/{test → spec}/dummy/bin/rails +0 -0
- data/{test → spec}/dummy/bin/rake +0 -0
- data/{test → spec}/dummy/config/application.rb +0 -0
- data/{test → spec}/dummy/config/boot.rb +0 -0
- data/{test → spec}/dummy/config/database.yml +0 -0
- data/{test → spec}/dummy/config/environment.rb +0 -0
- data/{test → spec}/dummy/config/environments/development.rb +0 -0
- data/{test → spec}/dummy/config/environments/production.rb +1 -1
- data/{test → spec}/dummy/config/environments/test.rb +1 -1
- data/{test → spec}/dummy/config/initializers/assets.rb +0 -0
- data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
- data/{test → spec}/dummy/config/initializers/cookies_serializer.rb +0 -0
- data/{test → spec}/dummy/config/initializers/filter_parameter_logging.rb +0 -0
- data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
- data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
- data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
- data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
- data/{test → spec}/dummy/config/locales/en.yml +0 -0
- data/{test → spec}/dummy/config/routes.rb +0 -0
- data/{test → spec}/dummy/config/secrets.yml +0 -0
- data/{test → spec}/dummy/config.ru +0 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +159 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +12 -0
- data/{test → spec}/dummy/public/404.html +0 -0
- data/{test → spec}/dummy/public/422.html +0 -0
- data/{test → spec}/dummy/public/500.html +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/helpers/my_forum/posts_helper_spec.rb +24 -0
- data/spec/helpers/my_forum/private_messages_helper_spec.rb +17 -0
- data/spec/models/my_forum/emoticon_spec.rb +7 -0
- data/spec/models/my_forum/private_message_spec.rb +7 -0
- data/spec/models/my_forum/user_spec.rb +13 -0
- data/spec/rails_helper.rb +52 -0
- data/spec/spec_helper.rb +87 -0
- metadata +356 -83
- data/app/views/layouts/my_forum/application.html.erb +0 -14
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/integration/navigation_test.rb +0 -10
- data/test/my_forum_test.rb +0 -7
- 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,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
|
@@ -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, '→'.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, '→'.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,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
|