Class: Article

Inherits:
Content
  • Object
show all
Includes:
AASM, ConfigManager, PublifyGuid
Defined in:
app/models/article.rb

Defined Under Namespace

Classes: Factory

Constant Summary

Constants included from StringLengthLimit

StringLengthLimit::STRING_LIMIT

Instance Attribute Summary collapse

Attributes included from ContentBase

#just_changed_published_status

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ConfigManager

#canonicalize, included

Methods included from PublifyGuid

#create_guid

Methods inherited from Content

#author=, #author_name, find_already_published, #rss_description, #short_url, #shorten_url, #whiteboard

Methods included from ContentBase

#default_text_filter, #excerpt_text, #generate_html, #html, #html_map, #html_postprocess, included, #really_send_notifications, #send_notification_to_user, #text_filter

Instance Attribute Details

#draftObject

Returns the value of attribute draft.



45
46
47
# File 'app/models/article.rb', line 45

def draft
  @draft
end

#keywordsObject

Returns the value of attribute keywords.



45
46
47
# File 'app/models/article.rb', line 45

def keywords
  @keywords
end

Class Method Details

.last_draft(article_id) ⇒ Object



96
97
98
99
100
# File 'app/models/article.rb', line 96

def self.last_draft(article_id)
  article = Article.find(article_id)
  article = Article.child_of(article.id).first while article.has_child?
  article
end

.publication_monthsObject



156
157
158
159
# File 'app/models/article.rb', line 156

def self.publication_months
  result = select("published_at").where.not(published_at: nil).where(type: "Article")
  result.map { |it| [it.publication_month] }.uniq
end

.requested_article(params) ⇒ Object

Finds one article which was posted on a certain date and matches the supplied dashed-title params is a Hash



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/models/article.rb', line 163

def self.requested_article(params)
  date_range = PublifyTime.delta(params[:year], params[:month], params[:day])

  req_params = {}
  req_params[:permalink] = params[:title] if params[:title]
  req_params[:published_at] = date_range if date_range

  return if req_params.empty? # no search if no params send

  article = published.find_by(req_params)
  return article if article

  if params[:title]
    req_params[:permalink] = CGI.escape(params[:title])
    published.find_by(req_params)
  end
end

.search(query, args = {}) ⇒ Object

Fulltext searches the body of published articles



182
183
184
185
186
187
188
189
190
191
# File 'app/models/article.rb', line 182

def self.search(query, args = {})
  query_s = query.to_s.strip
  if !query_s.empty? && args.empty?
    Article.searchstring(query)
  elsif !query_s.empty? && !args.empty?
    Article.searchstring(query).page(args[:page]).per(args[:per])
  else
    []
  end
end

.search_with(params) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'app/models/article.rb', line 102

def self.search_with(params)
  params ||= {}
  scoped = super(params)
  if %w(no_draft drafts published withdrawn pending).include?(params[:state])
    scoped = scoped.send(params[:state])
  end

  scoped.order("created_at DESC")
end

Instance Method Details

#access_by?(user) ⇒ Boolean

Returns:

  • (Boolean)


254
255
256
# File 'app/models/article.rb', line 254

def access_by?(user)
  user.admin? || user_id == user.id
end

#add_comment(params) ⇒ Object



250
251
252
# File 'app/models/article.rb', line 250

def add_comment(params)
  comments.build(params)
end

#allow_comments?Boolean

Returns:

  • (Boolean)


258
259
260
261
262
# File 'app/models/article.rb', line 258

def allow_comments?
  return allow_comments unless allow_comments.nil?

  blog.default_allow_comments
end

#allow_pings?Boolean

Returns:

  • (Boolean)


264
265
266
267
268
# File 'app/models/article.rb', line 264

def allow_pings?
  return allow_pings unless allow_pings.nil?

  blog.default_allow_pings
end

#body_and_extendedObject

The web interface no longer distinguishes between separate “body” and “extended” fields, and instead edits everything in a single edit field, separating the extended content using “<!–more–>”.



230
231
232
233
234
235
236
# File 'app/models/article.rb', line 230

def body_and_extended
  if extended.blank?
    body
  else
    "#{body}\n<!--more-->\n#{extended}"
  end
end

#body_and_extended=(value) ⇒ Object

Split apart value around a “<!–more–>” comment and assign it to our #body and #extended fields.



240
241
242
243
244
# File 'app/models/article.rb', line 240

def body_and_extended=(value)
  parts = value.split(/\n?<!--more-->\n?/, 2)
  self.body = parts[0]
  self.extended = parts[1] || ""
end

#comment_urlObject



130
131
132
# File 'app/models/article.rb', line 130

def comment_url
  blog.url_for("comments?article_id=#{id}", only_path: true)
end

#comments_closed?Boolean

Returns:

  • (Boolean)


205
206
207
# File 'app/models/article.rb', line 205

def comments_closed?
  !(allow_comments? && published? && in_feedback_window?)
end

#feed_url(format) ⇒ Object



138
139
140
# File 'app/models/article.rb', line 138

def feed_url(format)
  "#{permalink_url}.#{format.gsub(/\d/, "")}"
end

#has_child?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'app/models/article.rb', line 86

def has_child?
  Article.exists?(parent_id: id)
end

#html_urlsObject



209
210
211
212
213
214
215
# File 'app/models/article.rb', line 209

def html_urls
  urls = []
  html.gsub(/<a\s+[^>]*>/) do |tag|
    urls.push(Regexp.last_match[2].strip) if tag =~ /\bhref=(["']?)([^ >"]+)\1/
  end
  urls.uniq
end

#in_feedback_window?Boolean

check if time to comment is open or not

Returns:

  • (Boolean)


222
223
224
225
# File 'app/models/article.rb', line 222

def in_feedback_window?
  blog.sp_article_auto_close.zero? ||
    published_at.to_i > blog.sp_article_auto_close.days.ago.to_i
end

#interested_usersObject



197
198
199
# File 'app/models/article.rb', line 197

def interested_users
  User.where(notify_on_new_articles: true)
end

#keywords_to_tagsObject



193
194
195
# File 'app/models/article.rb', line 193

def keywords_to_tags
  Tag.create_from_article!(self)
end

#nextObject



142
143
144
145
# File 'app/models/article.rb', line 142

def next
  Article.where("published_at > ?", published_at).order("published_at asc")
    .limit(1).first
end

#notify_user_via_email(user) ⇒ Object



201
202
203
# File 'app/models/article.rb', line 201

def notify_user_via_email(user)
  EmailNotify.send_article(self, user) if user.notify_via_email?
end

#password_protected?Boolean

Returns:

  • (Boolean)


246
247
248
# File 'app/models/article.rb', line 246

def password_protected?
  password.present?
end

FIXME: Use keyword params to clean up call sites.



113
114
115
116
117
118
119
# File 'app/models/article.rb', line 113

def permalink_url(anchor = nil, only_path = false)
  return unless published?

  @cached_permalink_url ||= {}
  @cached_permalink_url["#{anchor}#{only_path}"] ||=
    blog.url_for(permalink_url_options, anchor: anchor, only_path: only_path)
end

#pings_closed?Boolean

Returns:

  • (Boolean)


217
218
219
# File 'app/models/article.rb', line 217

def pings_closed?
  !(allow_pings? && published? && in_feedback_window?)
end

#post_typeObject



90
91
92
93
94
# File 'app/models/article.rb', line 90

def post_type
  post_type = self[:post_type]
  post_type = "read" if post_type.blank?
  post_type
end

#preview_comment_urlObject



134
135
136
# File 'app/models/article.rb', line 134

def preview_comment_url
  blog.url_for("comments/preview?article_id=#{id}", only_path: true)
end

#previousObject



147
148
149
150
# File 'app/models/article.rb', line 147

def previous
  Article.where("published_at < ?", published_at).order("published_at desc")
    .limit(1).first
end

#publication_monthObject



152
153
154
# File 'app/models/article.rb', line 152

def publication_month
  published_at.strftime("%Y-%m")
end

#published_commentsObject



270
271
272
# File 'app/models/article.rb', line 270

def published_comments
  comments.published.oldest_first
end

#published_feedbackObject



278
279
280
# File 'app/models/article.rb', line 278

def published_feedback
  feedback.published.oldest_first
end

#published_trackbacksObject



274
275
276
# File 'app/models/article.rb', line 274

def published_trackbacks
  trackbacks.published.oldest_first
end

#save_attachment!(file) ⇒ Object



126
127
128
# File 'app/models/article.rb', line 126

def save_attachment!(file)
  resources.create!(upload: file, blog: blog)
end

#save_attachments!(files) ⇒ Object



121
122
123
124
# File 'app/models/article.rb', line 121

def save_attachments!(files)
  files ||= {}
  files.each_value { |f| save_attachment!(f) }
end


80
81
82
83
84
# File 'app/models/article.rb', line 80

def set_permalink
  return if draft? || permalink.present?

  self.permalink = title.to_permalink
end