formol 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +147 -0
- data/Rakefile +29 -0
- data/app/assets/images/formol/read.png +0 -0
- data/app/assets/images/formol/unread.png +0 -0
- data/app/assets/javascripts/formol/admin/categories.js.coffee +55 -0
- data/app/assets/javascripts/formol/admin/forums.js +2 -0
- data/app/assets/javascripts/formol/application.js +9 -0
- data/app/assets/javascripts/formol/categories.js +2 -0
- data/app/assets/javascripts/formol/forums.js +2 -0
- data/app/assets/javascripts/formol/poll_votes.js +2 -0
- data/app/assets/javascripts/formol/posts.js.coffee +9 -0
- data/app/assets/javascripts/formol/preferences.js +2 -0
- data/app/assets/javascripts/formol/subscriptions.js.coffee +13 -0
- data/app/assets/javascripts/formol/topics.js.coffee +54 -0
- data/app/assets/javascripts/lib/jquery.prevent_double_submit.js.coffee +11 -0
- data/app/assets/javascripts/markitup/jquery.markitup.js +593 -0
- data/app/assets/javascripts/markitup/sets/markdown/set.js +53 -0
- data/app/assets/stylesheets/form_struct.css.scss +39 -0
- data/app/assets/stylesheets/formol/admin/categories.css.scss +30 -0
- data/app/assets/stylesheets/formol/admin/forums.css +4 -0
- data/app/assets/stylesheets/formol/categories.css.scss +3 -0
- data/app/assets/stylesheets/formol/development.css +4 -0
- data/app/assets/stylesheets/formol/forums.css.scss +3 -0
- data/app/assets/stylesheets/formol/mixins/after_clear.css.scss +7 -0
- data/app/assets/stylesheets/formol/partials/breadcrumb.css.scss +9 -0
- data/app/assets/stylesheets/formol/partials/categories/list.css.scss +101 -0
- data/app/assets/stylesheets/formol/partials/formol_lists.css.scss +6 -0
- data/app/assets/stylesheets/formol/partials/forums/list.css.scss +97 -0
- data/app/assets/stylesheets/formol/partials/polls/poll.css.scss +9 -0
- data/app/assets/stylesheets/formol/partials/posts/post.css.scss +116 -0
- data/app/assets/stylesheets/formol/posts.css.scss +8 -0
- data/app/assets/stylesheets/formol/topics.css.scss +42 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/block_code.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/bold.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/code.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h1.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h2.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h3.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h4.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h5.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/h6.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/italic.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/link.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/list-bullet.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/list-numeric.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/picture.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/preview.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/images/quotes.png +0 -0
- data/app/assets/stylesheets/markitup/sets/markdown/style.css +57 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-container.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-bbcode.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-dotclear.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-html.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-json.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-markdown.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-textile.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-wiki.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor-xml.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/bg-editor.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/handle.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/menu.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/images/submenu.png +0 -0
- data/app/assets/stylesheets/markitup/skins/markitup/style.css +147 -0
- data/app/assets/stylesheets/markitup/skins/simple/images/handle.png +0 -0
- data/app/assets/stylesheets/markitup/skins/simple/images/menu.png +0 -0
- data/app/assets/stylesheets/markitup/skins/simple/images/submenu.png +0 -0
- data/app/assets/stylesheets/markitup/skins/simple/style.css +118 -0
- data/app/assets/stylesheets/pygments/autumn.css +58 -0
- data/app/assets/stylesheets/pygments/borland.css +46 -0
- data/app/assets/stylesheets/pygments/bw.css +34 -0
- data/app/assets/stylesheets/pygments/colorful.css +61 -0
- data/app/assets/stylesheets/pygments/default.css +62 -0
- data/app/assets/stylesheets/pygments/emacs.css +61 -0
- data/app/assets/stylesheets/pygments/friendly.css +61 -0
- data/app/assets/stylesheets/pygments/fruity.css +70 -0
- data/app/assets/stylesheets/pygments/manni.css +61 -0
- data/app/assets/stylesheets/pygments/murphy.css +61 -0
- data/app/assets/stylesheets/pygments/native.css +70 -0
- data/app/assets/stylesheets/pygments/pastie.css +60 -0
- data/app/assets/stylesheets/pygments/perldoc.css +58 -0
- data/app/assets/stylesheets/pygments/tango.css +69 -0
- data/app/assets/stylesheets/pygments/trac.css +59 -0
- data/app/assets/stylesheets/pygments/vim.css +70 -0
- data/app/assets/stylesheets/pygments/vs.css +33 -0
- data/app/controllers/formol/admin/admin_controller.rb +11 -0
- data/app/controllers/formol/admin/categories_controller.rb +60 -0
- data/app/controllers/formol/admin/forums_controller.rb +56 -0
- data/app/controllers/formol/application_controller.rb +47 -0
- data/app/controllers/formol/categories_controller.rb +21 -0
- data/app/controllers/formol/forums_controller.rb +19 -0
- data/app/controllers/formol/poll_votes_controller.rb +23 -0
- data/app/controllers/formol/posts_controller.rb +71 -0
- data/app/controllers/formol/preferences_controller.rb +32 -0
- data/app/controllers/formol/subscriptions_controller.rb +29 -0
- data/app/controllers/formol/topics_controller.rb +91 -0
- data/app/helpers/formol/admin/categories_helper.rb +4 -0
- data/app/helpers/formol/admin/forums_helper.rb +4 -0
- data/app/helpers/formol/application_helper.rb +35 -0
- data/app/helpers/formol/categories_helper.rb +15 -0
- data/app/helpers/formol/forums_helper.rb +19 -0
- data/app/helpers/formol/poll_votes_helper.rb +4 -0
- data/app/helpers/formol/posts_helper.rb +27 -0
- data/app/helpers/formol/preferences_helper.rb +4 -0
- data/app/helpers/formol/subscriptions_helper.rb +4 -0
- data/app/helpers/formol/topics_helper.rb +27 -0
- data/app/mailers/formol/subscription_mailer.rb +13 -0
- data/app/models/formol/category.rb +42 -0
- data/app/models/formol/forum.rb +77 -0
- data/app/models/formol/poll/option.rb +20 -0
- data/app/models/formol/poll/vote.rb +32 -0
- data/app/models/formol/poll.rb +107 -0
- data/app/models/formol/post.rb +162 -0
- data/app/models/formol/post_observer.rb +9 -0
- data/app/models/formol/topic/subscription.rb +16 -0
- data/app/models/formol/topic/track.rb +57 -0
- data/app/models/formol/topic.rb +185 -0
- data/app/models/formol/tracking.rb +45 -0
- data/app/models/formol/user_preference.rb +18 -0
- data/app/views/formol/admin/categories/_category.html.erb +9 -0
- data/app/views/formol/admin/categories/_form.html.erb +8 -0
- data/app/views/formol/admin/categories/edit.html.erb +3 -0
- data/app/views/formol/admin/categories/index.html.erb +3 -0
- data/app/views/formol/admin/categories/new.html.erb +3 -0
- data/app/views/formol/admin/forums/_form.html.erb +9 -0
- data/app/views/formol/admin/forums/_forum.html.erb +12 -0
- data/app/views/formol/admin/forums/edit.html.erb +3 -0
- data/app/views/formol/admin/forums/new.html.erb +3 -0
- data/app/views/formol/categories/_category.html.erb +5 -0
- data/app/views/formol/categories/index.html.erb +5 -0
- data/app/views/formol/categories/show.html.erb +3 -0
- data/app/views/formol/forums/_forum.html.erb +13 -0
- data/app/views/formol/forums/_list.html.erb +16 -0
- data/app/views/formol/forums/show.html.erb +18 -0
- data/app/views/formol/poll/options/_form.html.erb +1 -0
- data/app/views/formol/poll_votes/_form.html.erb +8 -0
- data/app/views/formol/polls/_form.html.erb +14 -0
- data/app/views/formol/polls/_poll.html.erb +24 -0
- data/app/views/formol/posts/_form.html.erb +7 -0
- data/app/views/formol/posts/_last_post.html.erb +9 -0
- data/app/views/formol/posts/_list.html.erb +3 -0
- data/app/views/formol/posts/_post.html.erb +47 -0
- data/app/views/formol/posts/edit.html.erb +10 -0
- data/app/views/formol/posts/new.html.erb +14 -0
- data/app/views/formol/preferences/show.html.erb +11 -0
- data/app/views/formol/subscription_mailer/topic_reply.en.html.erb +8 -0
- data/app/views/formol/subscription_mailer/topic_reply.fr.html.erb +8 -0
- data/app/views/formol/topics/_form.html.erb +20 -0
- data/app/views/formol/topics/_list.html.erb +16 -0
- data/app/views/formol/topics/_topic.html.erb +13 -0
- data/app/views/formol/topics/edit.html.erb +5 -0
- data/app/views/formol/topics/new.html.erb +5 -0
- data/app/views/formol/topics/show.html.erb +25 -0
- data/app/views/layouts/formol/mail.html.erb +9 -0
- data/config/locales/en.yml +3 -0
- data/config/locales/formol/views/forums/en.yml +13 -0
- data/config/locales/formol/views/forums/fr.yml +13 -0
- data/config/locales/formol/views/poll_votes/en.yml +5 -0
- data/config/locales/formol/views/polls/en.yml.yml +5 -0
- data/config/locales/formol/views/posts/en.yml +23 -0
- data/config/locales/formol/views/posts/fr.yml +20 -0
- data/config/locales/formol/views/topics/en.yml +23 -0
- data/config/locales/formol/views/topics/fr.yml +20 -0
- data/config/routes.rb +31 -0
- data/db/migrate/20111221101158_create_formol_categories.rb +7 -0
- data/db/migrate/20111221111417_create_formol_forums.rb +10 -0
- data/db/migrate/20111221121010_create_formol_topics.rb +9 -0
- data/db/migrate/20111221123515_create_formol_posts.rb +9 -0
- data/db/migrate/20111221151653_add_index_on_tables.rb +15 -0
- data/db/migrate/20120103163438_add_user_to_models.rb +13 -0
- data/db/migrate/20120104132631_add_counter_cache_to_models.rb +12 -0
- data/db/migrate/20120104163741_add_pinned_to_topics.rb +7 -0
- data/db/migrate/20120105133522_add_position_to_categories.rb +7 -0
- data/db/migrate/20120105190708_add_position_to_forums.rb +7 -0
- data/db/migrate/20120105212559_add_lock_to_topics.rb +7 -0
- data/db/migrate/20120106130944_add_first_post_and_last_post_to_topics.rb +8 -0
- data/db/migrate/20120106192951_change_forum_description_to_string.rb +9 -0
- data/db/migrate/20120107012517_add_last_post_to_forum.rb +7 -0
- data/db/migrate/20120107122921_add_missing_indexes.rb +12 -0
- data/db/migrate/20120107123654_add_default_on_forum_counters.rb +10 -0
- data/db/migrate/20120108114030_add_views_to_topics.rb +7 -0
- data/db/migrate/20120108131533_create_formol_topic_tracks.rb +13 -0
- data/db/migrate/20120109115141_create_formol_topic_subscriptions.rb +10 -0
- data/db/migrate/20120109220633_create_formol_user_preferences.rb +11 -0
- data/db/migrate/20120109223624_add_display_signature_to_posts.rb +7 -0
- data/db/migrate/20120109233054_add_display_signatures_and_avatars_to_user_preferences.rb +8 -0
- data/db/migrate/20120110152548_create_formol_polls.rb +14 -0
- data/db/migrate/20120110152618_create_formol_poll_options.rb +11 -0
- data/db/migrate/20120110152632_create_formol_poll_votes.rb +12 -0
- data/lib/formol/config.rb +12 -0
- data/lib/formol/controllers/auth.rb +9 -0
- data/lib/formol/controllers/nested/has_parent_category.rb +11 -0
- data/lib/formol/controllers/nested/has_parent_forum.rb +11 -0
- data/lib/formol/controllers/nested/has_parent_topic.rb +11 -0
- data/lib/formol/controllers.rb +5 -0
- data/lib/formol/engine.rb +18 -0
- data/lib/formol/formatters/redcarpet/formatter.rb +36 -0
- data/lib/formol/formatters/redcarpet/syntax_highlighter.rb +23 -0
- data/lib/formol/formatters.rb +2 -0
- data/lib/formol/generators/install/install_generator.rb +94 -0
- data/lib/formol/generators/install/templates/config/formol.yml +29 -0
- data/lib/formol/generators/install/templates/initializer/formol.rb.erb +21 -0
- data/lib/formol/generators/install/templates/lib/permissions/special_rights.rb +24 -0
- data/lib/formol/generators/install/templates/migrations/add_formol_profile_to_users.rb.erb +7 -0
- data/lib/formol/generators/install/templates/migrations/add_posts_count_to_user.rb.erb +7 -0
- data/lib/formol/generators.rb +1 -0
- data/lib/formol/integration/user.rb +76 -0
- data/lib/formol/integration.rb +1 -0
- data/lib/formol/permissions/controllers.rb +30 -0
- data/lib/formol/permissions/manager.rb +29 -0
- data/lib/formol/permissions/profile.rb +24 -0
- data/lib/formol/permissions/profiles.rb +44 -0
- data/lib/formol/permissions/user.rb +29 -0
- data/lib/formol/permissions.rb +5 -0
- data/lib/formol/rails/engine.rb +81 -0
- data/lib/formol/rails.rb +1 -0
- data/lib/formol/version.rb +10 -0
- data/lib/formol/view_helpers/assets_helper.rb +11 -0
- data/lib/formol/view_helpers/format_helper.rb +12 -0
- data/lib/formol/view_helpers.rb +2 -0
- data/lib/formol/will_paginate/list_link_renderer.rb +29 -0
- data/lib/formol/will_paginate.rb +1 -0
- data/lib/formol.rb +61 -0
- data/lib/formol_.rb +13 -0
- data/lib/tasks/formol_tasks.rake +0 -0
- metadata +348 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module Formol
|
2
|
+
class Admin::CategoriesController < Admin::AdminController
|
3
|
+
respond_to :html, :except => [:sort]
|
4
|
+
respond_to :js, :only => [:sort]
|
5
|
+
|
6
|
+
def index
|
7
|
+
categories
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
category
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
if category.save
|
16
|
+
respond_with(category, :status => :created, :location => admin_categories_path)
|
17
|
+
else
|
18
|
+
respond_with(category, :status => :unprocessable_entity) do |format|
|
19
|
+
format.html { render :new }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
category
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
if category.update_attributes(params[:category])
|
30
|
+
respond_with(category, :location => admin_categories_path)
|
31
|
+
else
|
32
|
+
respond_with(category) do |format|
|
33
|
+
format.html { render :edit }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
category.destroy
|
40
|
+
|
41
|
+
respond_with(category, :location => admin_categories_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def sort
|
45
|
+
Formol::Category.sort(params[:categories])
|
46
|
+
|
47
|
+
render :nothing => true, :status => :ok
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def categories
|
53
|
+
@categories ||= Formol::Category.ready_for_listing.all
|
54
|
+
end
|
55
|
+
|
56
|
+
def category
|
57
|
+
@category ||= (params[:id].present? ? Formol::Category.find(params[:id]) : Formol::Category.new(params[:category]))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Formol
|
2
|
+
class Admin::ForumsController < Admin::AdminController
|
3
|
+
include Controllers::Nested::HasParentCategory
|
4
|
+
|
5
|
+
respond_to :html, :except => [:reorganize]
|
6
|
+
respond_to :js, :only => [:reorganize]
|
7
|
+
|
8
|
+
def new
|
9
|
+
forum
|
10
|
+
|
11
|
+
respond_with(forum)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
if forum.save
|
16
|
+
respond_with(forum, :status => :created, :location => admin_categories_path)
|
17
|
+
else
|
18
|
+
respond_with(forum, :status => :unprocessable_entity) do |format|
|
19
|
+
format.html { render :new }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
forum
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
if forum.update_attributes(params[:forum])
|
30
|
+
respond_with(forum, :location => admin_categories_path)
|
31
|
+
else
|
32
|
+
respond_with(forum) do |format|
|
33
|
+
format.html { render :edit }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
forum.destroy
|
40
|
+
|
41
|
+
respond_with(forum, :location => admin_categories_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def reorganize
|
45
|
+
Formol::Forum.reorganize(params[:forums], params[:category_id])
|
46
|
+
|
47
|
+
render :nothing => true, :status => :ok
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def forum
|
53
|
+
@forum ||= (params[:id].present? ? category.forums.find(params[:id]) : category.forums.new(params[:forum]))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Formol
|
2
|
+
class ApplicationController < ::ApplicationController
|
3
|
+
def per_page
|
4
|
+
25
|
5
|
+
end
|
6
|
+
|
7
|
+
helper_method :per_page
|
8
|
+
helper_method :current_formol_user
|
9
|
+
|
10
|
+
def topic_post_page_number(topic, post)
|
11
|
+
#topic.posts.index is maybe not the most optimized
|
12
|
+
((topic.posts(true).index(post) + 1).to_f / per_page.to_f).ceil
|
13
|
+
end
|
14
|
+
|
15
|
+
def paginated_forum_topic_post_path(forum, topic, post)
|
16
|
+
opts = {
|
17
|
+
:anchor => "formol_post_#{post.id}"
|
18
|
+
}
|
19
|
+
|
20
|
+
page = topic_post_page_number(topic, post)
|
21
|
+
|
22
|
+
opts[:page] = page if page > 1
|
23
|
+
|
24
|
+
forum_topic_path(forum, topic, opts)
|
25
|
+
end
|
26
|
+
|
27
|
+
helper_method :paginated_forum_topic_post_path
|
28
|
+
|
29
|
+
def topic_last_page_number(topic)
|
30
|
+
(topic.posts_count.to_f / per_page.to_f).ceil
|
31
|
+
end
|
32
|
+
|
33
|
+
def last_page_forum_topic_path(forum, topic, post)
|
34
|
+
opts = {
|
35
|
+
:anchor => "formol_post_#{post.id}"
|
36
|
+
}
|
37
|
+
|
38
|
+
page = topic_last_page_number(topic)
|
39
|
+
|
40
|
+
opts[:page] = page if page > 1
|
41
|
+
|
42
|
+
forum_topic_path(forum, topic, opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
helper_method :last_page_forum_topic_path
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Formol
|
2
|
+
class CategoriesController < ApplicationController
|
3
|
+
respond_to :html
|
4
|
+
|
5
|
+
def index
|
6
|
+
formol_authorize!(current_formol_user, :read_category)
|
7
|
+
|
8
|
+
@categories = Formol::Category.ready_for_listing
|
9
|
+
|
10
|
+
respond_with(@categories)
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
formol_authorize!(current_formol_user, :read_category)
|
15
|
+
|
16
|
+
@category = Formol::Category.find(params[:id])
|
17
|
+
|
18
|
+
respond_with(@category)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Formol
|
2
|
+
class ForumsController < ApplicationController
|
3
|
+
respond_to :html
|
4
|
+
|
5
|
+
def show
|
6
|
+
formol_authorize!(current_formol_user, :read_forum)
|
7
|
+
|
8
|
+
@topics = forum.topics.ready_for_listing.page(params[:page]).per_page(per_page)
|
9
|
+
|
10
|
+
respond_with(forum)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def forum
|
16
|
+
@forum ||= Formol::Forum.find(params[:id])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Formol
|
2
|
+
class PollVotesController < ApplicationController
|
3
|
+
include Controllers::Nested::HasParentTopic
|
4
|
+
|
5
|
+
def create
|
6
|
+
formol_authorize!(current_formol_user, :vote_poll, topic)
|
7
|
+
|
8
|
+
poll.vote(current_formol_user, params['poll']['poll_vote_ids'])
|
9
|
+
rescue Formol::Poll::PollException => e
|
10
|
+
flash[:error] = t(e.message)
|
11
|
+
ensure
|
12
|
+
respond_to do |format|
|
13
|
+
format.html { redirect_to [topic.forum, topic] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def poll
|
20
|
+
@poll ||= topic.poll
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Formol
|
2
|
+
class PostsController < ApplicationController
|
3
|
+
include Controllers::Nested::HasParentTopic
|
4
|
+
|
5
|
+
respond_to :html
|
6
|
+
|
7
|
+
def show
|
8
|
+
formol_authorize!(current_formol_user, :read_topic)
|
9
|
+
|
10
|
+
post
|
11
|
+
|
12
|
+
#respond_with location doesn't work here :/
|
13
|
+
respond_with(post) do |format|
|
14
|
+
format.html { redirect_to paginated_forum_topic_post_path(post.topic.forum, post.topic, post) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
formol_authorize!(current_formol_user, :create_post, topic)
|
20
|
+
|
21
|
+
post(:quote_id => params[:quote], :user => current_formol_user)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create
|
25
|
+
formol_authorize!(current_formol_user, :create_post, topic)
|
26
|
+
|
27
|
+
post(:user => current_formol_user)
|
28
|
+
|
29
|
+
if post.save
|
30
|
+
#post.topic(true) needed to handle counter increment
|
31
|
+
respond_with(post, :status => :created, :location => last_page_forum_topic_path(topic.forum, post.topic(true), post))
|
32
|
+
else
|
33
|
+
respond_with(post, :status => :unprocessable_entity) do |format|
|
34
|
+
format.html { render :new }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def edit
|
40
|
+
formol_authorize!(current_formol_user, :edit_post, post)
|
41
|
+
|
42
|
+
post
|
43
|
+
end
|
44
|
+
|
45
|
+
def update
|
46
|
+
formol_authorize!(current_formol_user, :edit_post, post)
|
47
|
+
|
48
|
+
if post.update_attributes(params[:post])
|
49
|
+
respond_with(post, :location => paginated_forum_topic_post_path(topic.forum, topic, post))
|
50
|
+
else
|
51
|
+
respond_with(post) do |format|
|
52
|
+
format.html { render :edit }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def destroy
|
58
|
+
formol_authorize!(current_formol_user, :destroy_post)
|
59
|
+
|
60
|
+
post.destroy
|
61
|
+
|
62
|
+
respond_with(post, :location => [topic.forum, topic])
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def post(attrs = {})
|
68
|
+
@post ||= (params[:id].present? ? topic.posts.find(params[:id]) : topic.posts.new(attrs.merge(params[:post] || {})))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Formol
|
2
|
+
class PreferencesController < ApplicationController
|
3
|
+
respond_to :html
|
4
|
+
|
5
|
+
def show
|
6
|
+
preference
|
7
|
+
|
8
|
+
respond_with(preference)
|
9
|
+
end
|
10
|
+
|
11
|
+
def update
|
12
|
+
if preference.update_attributes(params[:user_preference])
|
13
|
+
respond_with(preference) do |format|
|
14
|
+
format.html { redirect_to preference_path }
|
15
|
+
end
|
16
|
+
# No wrong case to test for now
|
17
|
+
# just lower coverage
|
18
|
+
#
|
19
|
+
#else
|
20
|
+
# respond_with(preference) do |format|
|
21
|
+
# format.html { render :show }
|
22
|
+
# end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def preference
|
29
|
+
@preference ||= current_formol_user.preference
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Formol
|
2
|
+
class SubscriptionsController < ApplicationController
|
3
|
+
include Formol::Controllers::Nested::HasParentTopic
|
4
|
+
|
5
|
+
def create
|
6
|
+
formol_authorize!(current_formol_user, :subscribe_topic)
|
7
|
+
|
8
|
+
topic.register_subscriber(current_formol_user)
|
9
|
+
|
10
|
+
respond_to do |format|
|
11
|
+
format.js { render :nothing => true, :status => :ok }
|
12
|
+
end
|
13
|
+
rescue ActiveRecord::RecordInvalid
|
14
|
+
respond_to do |format|
|
15
|
+
format.js { render :nothing => true, :status => :unprocessable_entity }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy
|
20
|
+
formol_authorize!(current_formol_user, :subscribe_topic)
|
21
|
+
|
22
|
+
topic.unregister_subscriber(current_formol_user)
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
format.js { render :nothing => true, :status => :ok }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Formol
|
2
|
+
class TopicsController < ApplicationController
|
3
|
+
include Controllers::Nested::HasParentForum
|
4
|
+
|
5
|
+
respond_to :html
|
6
|
+
|
7
|
+
def show
|
8
|
+
formol_authorize!(current_formol_user, :read_topic)
|
9
|
+
|
10
|
+
topic.view!
|
11
|
+
topic.track_for_user!(current_formol_user)
|
12
|
+
|
13
|
+
@posts = topic.posts.ready_for_listing.page(params[:page]).per_page(per_page)
|
14
|
+
|
15
|
+
respond_with(topic)
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
formol_authorize!(current_formol_user, :create_topic)
|
20
|
+
|
21
|
+
topic.posts.build(:register_user_as_subscriber => true)
|
22
|
+
|
23
|
+
unless topic.poll
|
24
|
+
topic.build_poll
|
25
|
+
topic.poll.options.build
|
26
|
+
end
|
27
|
+
|
28
|
+
respond_with(topic)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
formol_authorize!(current_formol_user, :create_topic)
|
33
|
+
|
34
|
+
topic.user = current_formol_user
|
35
|
+
|
36
|
+
if topic.save
|
37
|
+
respond_with(topic, :location => [forum, topic])
|
38
|
+
else
|
39
|
+
unless topic.poll
|
40
|
+
topic.build_poll
|
41
|
+
topic.poll.options.build
|
42
|
+
end
|
43
|
+
|
44
|
+
respond_with(topic, :status => :unprocessable_entity) do |format|
|
45
|
+
format.html { render :new }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def edit
|
51
|
+
formol_authorize!(current_formol_user, :edit_topic, topic)
|
52
|
+
|
53
|
+
respond_with(topic)
|
54
|
+
end
|
55
|
+
|
56
|
+
def update
|
57
|
+
formol_authorize!(current_formol_user, :edit_topic, topic)
|
58
|
+
|
59
|
+
if topic.update_attributes(params[:topic])
|
60
|
+
respond_with(topic, :location => [forum, topic])
|
61
|
+
else
|
62
|
+
respond_with(topic) do |format|
|
63
|
+
format.html { render :edit }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def destroy
|
69
|
+
formol_authorize!(current_formol_user, :destroy_topic)
|
70
|
+
|
71
|
+
topic.destroy
|
72
|
+
|
73
|
+
respond_with(topic, :location => forum)
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def topic
|
79
|
+
@topic ||= if params[:id].present?
|
80
|
+
if request.get?
|
81
|
+
forum.topics.ready_for_breadcrumb.includes(:poll => { :options => :votes }).find(params[:id])
|
82
|
+
else
|
83
|
+
# never eager load anything for update (brokes validates on associations)
|
84
|
+
forum.topics.find(params[:id])
|
85
|
+
end
|
86
|
+
else
|
87
|
+
forum.topics.new(params[:topic])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Formol
|
2
|
+
module ApplicationHelper
|
3
|
+
def breadcrumb_for(record)
|
4
|
+
items = [[t('home'), root_path]]
|
5
|
+
|
6
|
+
klass = record.class.to_s
|
7
|
+
|
8
|
+
case klass
|
9
|
+
when 'Formol::Category'
|
10
|
+
items << [record.label, category_path(record)]
|
11
|
+
when 'Formol::Forum'
|
12
|
+
items << [record.category.label, category_path(record.category)]
|
13
|
+
items << [record.label, forum_path(record)]
|
14
|
+
when 'Formol::Topic'
|
15
|
+
items << [record.forum.category.label, category_path(record.forum.category)]
|
16
|
+
items << [record.forum.label, forum_path(record.forum)]
|
17
|
+
items << [record.title, forum_topic_path(record.forum, record)]
|
18
|
+
end
|
19
|
+
|
20
|
+
content_tag(:ul, :class => 'breadcrumb') do
|
21
|
+
items.each do |(text, path)|
|
22
|
+
concat(content_tag(:li, :class => 'item'){ link_to(text, path) })
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# When you want to link to last post, you don't need to calculate position
|
28
|
+
# of last post (wich need to load all topic's posts).
|
29
|
+
# Last post is obviously on last page, you can rely then on posts_count in
|
30
|
+
# topic object
|
31
|
+
def link_to_last_post(forum, topic, post, text = nil)
|
32
|
+
link_to (text || '>'), last_page_forum_topic_path(forum, topic, post), :title => t('formol.posts.last_post.go_to_last')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Formol
|
2
|
+
module CategoriesHelper
|
3
|
+
def formol_forum_klass(forum, user)
|
4
|
+
klasses = []
|
5
|
+
|
6
|
+
if user.present?
|
7
|
+
klasses << (user.has_read_forum?(forum) ? 'read' : 'unread')
|
8
|
+
else
|
9
|
+
klasses << 'read'
|
10
|
+
end
|
11
|
+
|
12
|
+
klasses.join(' ')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Formol
|
2
|
+
module ForumsHelper
|
3
|
+
def formol_topic_klass(topic, user)
|
4
|
+
klasses = []
|
5
|
+
|
6
|
+
klasses << 'pinned' if topic.pinned
|
7
|
+
klasses << 'locked' if topic.locked
|
8
|
+
|
9
|
+
unless user.blank?
|
10
|
+
klasses << (user.has_read_topic?(topic) ? 'read' : 'unread')
|
11
|
+
else
|
12
|
+
klasses << 'read'
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
klasses.join(' ')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Formol
|
2
|
+
module PostsHelper
|
3
|
+
def link_to_post_position(post, index)
|
4
|
+
idx = ((params[:page] || 1) - 1) * per_page + index + 1
|
5
|
+
|
6
|
+
return link_to "##{idx}", "#formol_post_#{post.id}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def link_to_last_fives_post_position(post, topic, index)
|
10
|
+
idx = topic.posts_count - index
|
11
|
+
|
12
|
+
return link_to "##{idx}", "#formol_post_#{post.id}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def display_avatars?(user)
|
16
|
+
return true unless user
|
17
|
+
|
18
|
+
user.preference.display_avatars?
|
19
|
+
end
|
20
|
+
|
21
|
+
def display_signatures?(user, post)
|
22
|
+
s = post.display_signature? && !post.user.preference.signature.blank?
|
23
|
+
|
24
|
+
(s && user ? user.preference.display_signatures? : s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Formol
|
2
|
+
module TopicsHelper
|
3
|
+
include PostsHelper
|
4
|
+
|
5
|
+
def link_to_subscription(topic, user)
|
6
|
+
subscriber = topic.subscriber?(user)
|
7
|
+
method = subscriber ? :delete : :post
|
8
|
+
text = t('formol.topics.show.' + (subscriber ? 'unsubscribe' : 'subscribe'))
|
9
|
+
switch_text = t('formol.topics.show.' + (subscriber ? 'subscribe' : 'unsubscribe'))
|
10
|
+
|
11
|
+
link_to text, topic_subscriptions_path(topic), :method => method,
|
12
|
+
:remote => true,
|
13
|
+
:'data-switch-text' => switch_text
|
14
|
+
end
|
15
|
+
|
16
|
+
def attach_poll_checkbox(topic)
|
17
|
+
%{<input type="checkbox" name="topic[attach_poll]" id="topic_attach_poll" value="1" #{'checked="checked"' if topic.attach_poll} />}.html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
def display_poll_form?(poll, topic, user)
|
21
|
+
!poll.expired? &&
|
22
|
+
!topic.locked? &&
|
23
|
+
formol_authorized?(user, :vote_poll, topic) &&
|
24
|
+
!poll.voted?(user)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Formol
|
2
|
+
class SubscriptionMailer < ActionMailer::Base
|
3
|
+
default :from => Formol.config.email_from
|
4
|
+
|
5
|
+
def topic_reply(post, subscriber)
|
6
|
+
@post = post
|
7
|
+
|
8
|
+
mail( :to => subscriber.email,
|
9
|
+
:subject => "New reply: #{post.topic.title}",
|
10
|
+
:layout => 'formol/mail')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Formol
|
2
|
+
class Category < ActiveRecord::Base
|
3
|
+
#Modules
|
4
|
+
include RankedModel
|
5
|
+
|
6
|
+
#Associations
|
7
|
+
has_many :forums, :dependent => :destroy,
|
8
|
+
:order => 'formol_forums.position'
|
9
|
+
|
10
|
+
#Validations
|
11
|
+
validates :label, :presence => true,
|
12
|
+
:length => { :in => 3..32,
|
13
|
+
:allow_blank => true },
|
14
|
+
:uniqueness => { :case_sensitive => false,
|
15
|
+
:allow_blank => true }
|
16
|
+
|
17
|
+
#Normalization
|
18
|
+
normalize_attributes :label, :with => [:squish, :blank]
|
19
|
+
|
20
|
+
#Sorting
|
21
|
+
ranks :position
|
22
|
+
|
23
|
+
#Scopes
|
24
|
+
class << self
|
25
|
+
# return categories conveniently ordered and eager-loaded for listing
|
26
|
+
def ready_for_listing
|
27
|
+
includes(:forums => { :last_post => [:user, :topic] }).rank(:position)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#Business
|
32
|
+
class << self
|
33
|
+
# Sorts categories from an array of ids
|
34
|
+
def sort(category_ids)
|
35
|
+
#TODO: should maybe optimize this?
|
36
|
+
(category_ids || []).each_with_index do |category_id, index|
|
37
|
+
find(category_id).update_attribute(:position, index)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|