Module: CommentsHelper

Defined in:
app/helpers/comments_helper.rb

Overview

Helpers related to comments.

Instance Method Summary collapse

Instance Method Details

Get a link to the specified comment, accounting for deleted comments.

Parameters:

Returns:

  • (String)


7
8
9
10
11
12
13
14
# File 'app/helpers/comments_helper.rb', line 7

def comment_link(comment)
  if comment.deleted
    comment_thread_url(comment.comment_thread_id, show_deleted_comments: 1, anchor: "comment-#{comment.id}",
                       host: comment.community.host)
  else
    comment_thread_url(comment.comment_thread_id, anchor: "comment-#{comment.id}", host: comment.community.host)
  end
end

#comment_rate_limited?(user, post, create_audit_log: true) ⇒ Array(Boolean, String)

Is the specified user comment rate limited for the specified post?

Parameters:

  • user (User)

    The user to check.

  • post (Post)

    The post on which the user proposes to comment.

  • create_audit_log (Boolean) (defaults to: true)

    Whether to create an AuditLog if the user is rate limited.

Returns:

  • (Array(Boolean, String))

    2-tuple: boolean indicating if the user is rate-limited, and a string containing a rate limit message if the user is rate-limited.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'app/helpers/comments_helper.rb', line 107

def comment_rate_limited?(user, post, create_audit_log: true)
  # Comments created by the current user in the last 24 hours, excluding comments on own posts and responses to them.
  recent_comments = Comment.where(created_at: 24.hours.ago..DateTime.now, user: user).where \
                           .not(post: Post.includes(:parent).where(parents_posts: { user_id: user.id })) \
                           .where.not(post: Post.where(user_id: user.id)).count
  max_comments_per_day = SiteSetting[user.privilege?('unrestricted') ? 'RL_Comments' : 'RL_NewUserComments']

  if post.user_id != user.id && post.parent&.user_id != user.id
    if !user.privilege?('unrestricted')
      message = 'As a new user, you can only comment on your own posts and on answers to them.'
      if create_audit_log
        AuditLog.rate_limit_log(event_type: 'comment', related: post, user: user,
                                comment: "limit: #{max_comments_per_day}")
      end
      [true, message]
    elsif recent_comments >= max_comments_per_day
      message = "You have used your daily comment limit of #{recent_comments} comments. Come back tomorrow to " \
                'continue commenting. Comments on your own posts and on answers to own posts are exempt.'
      if create_audit_log
        AuditLog.rate_limit_log(event_type: 'comment', related: post, user: user,
                                comment: "limit: #{max_comments_per_day}")
      end
      [true, message]
    else
      [false, nil]
    end
  else
    [false, nil]
  end
end

#get_pingable(thread) ⇒ Array<Integer>

Get a list of user IDs who should be pingable in a specified comment thread. This combines the post author, answer authors, recent history event authors, recent comment authors on the post (in any thread), and all thread followers.

Parameters:

Returns:

  • (Array<Integer>)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/helpers/comments_helper.rb', line 77

def get_pingable(thread)
  post = thread.post

  # post author +
  # answer authors +
  # last 500 history event users +
  # last 500 comment authors +
  # all thread followers
  query = <<~END_SQL
    SELECT posts.user_id FROM posts WHERE posts.id = #{post.id}
    UNION DISTINCT
    SELECT DISTINCT posts.user_id FROM posts WHERE posts.parent_id = #{post.id}
    UNION DISTINCT
    SELECT DISTINCT ph.user_id FROM post_histories ph WHERE ph.post_id = #{post.id}
    UNION DISTINCT
    SELECT DISTINCT comments.user_id FROM comments WHERE comments.post_id = #{post.id}
    UNION DISTINCT
    SELECT DISTINCT tf.user_id FROM thread_followers tf WHERE tf.comment_thread_id = #{thread.id || '-1'}
  END_SQL

  ActiveRecord::Base.connection.execute(query).to_a.flatten
end

#render_comment_helpers(comment_text, user = current_user) ⇒ String

Process comment text and convert helper links (like [help] and [flags]) into real links.

Parameters:

  • comment_text (String)

    The text of the comment to process.

  • user (User) (defaults to: current_user)

    Specify a user whose pages to link to from user-related helpers.

Returns:

  • (String)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/helpers/comments_helper.rb', line 41

def render_comment_helpers(comment_text, user = current_user)
  comment_text.gsub!(/\[(help( center)?)\]/, "<a href=\"#{help_center_url}\">\\1</a>")

  unless user.nil?
    comment_text.gsub!(/\[(votes?)\]/, "<a href=\"#{my_vote_summary_url}\">\\1</a>")
    comment_text.gsub!(/\[(flags?)\]/, "<a href=\"#{flag_history_url(user)}\">\\1</a>")
  end

  comment_text.gsub!(/\[category:(.+?)\]/) do |match|
    val = Regexp.last_match(1).gsub('&amp;', '&').downcase
    cat = Category.by_lowercase_name(val)
    if cat
      "<a href=\"#{category_url(cat)}\">#{cat.name}</a>"
    else
      match
    end
  end

  comment_text.gsub!(/\[category\#([0-9]+)\]/) do |match|
    val = Regexp.last_match(1).to_i
    cat = Category.by_id(val)
    if cat
      "<a href=\"#{category_url(cat)}\">#{cat.name}</a>"
    else
      match
    end
  end

  comment_text
end

#render_pings(comment, pingable: nil) ⇒ ActiveSupport::SafeBuffer

Process a comment and convert ping-strings (i.e. @#1234) into links.

Parameters:

  • comment (String)

    The text of the comment to process.

  • pingable (Array<Integer>, nil) (defaults to: nil)

    A list of user IDs that should be pingable in this comment. Any user IDs not present in the list will be displayed as ‘unpingable’.

Returns:

  • (ActiveSupport::SafeBuffer)


22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'app/helpers/comments_helper.rb', line 22

def render_pings(comment, pingable: nil)
  comment.gsub(/@#\d+/) do |id|
    u = User.where(id: id[2..-1].to_i).first
    if u.nil?
      id
    else
      was_pung = pingable.present? && pingable.include?(u.id)
      classes = "ping #{u.id == current_user&.id ? 'me' : ''} #{was_pung ? '' : 'unpingable'}"
      user_link u, class: classes, dir: 'ltr',
                title: was_pung ? '' : 'This user was not notified because they have not participated in this thread.'
    end
  end.html_safe
end