Class: Article

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

Defined Under Namespace

Classes: Factory

Instance Attribute Summary collapse

Attributes included from ContentBase

#just_changed_published_status

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ConfigManager

append_features, #canonicalize

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, #html_preprocess, included, #really_send_notifications, #send_notification_to_user, #text_filter

Instance Attribute Details

#draftObject

Returns the value of attribute draft.



47
48
49
# File 'app/models/article.rb', line 47

def draft
  @draft
end

#keywordsObject

Returns the value of attribute keywords.



47
48
49
# File 'app/models/article.rb', line 47

def keywords
  @keywords
end

Class Method Details

.last_draft(article_id) ⇒ Object



98
99
100
101
102
# File 'app/models/article.rb', line 98

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



158
159
160
161
# File 'app/models/article.rb', line 158

def self.publication_months
  result = select("published_at").where("published_at is not NULL").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



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

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])
    article = published.find_by(req_params)
    return article if article
  end
end

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

Fulltext searches the body of published articles



185
186
187
188
189
190
191
192
193
194
# File 'app/models/article.rb', line 185

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



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

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)


261
262
263
# File 'app/models/article.rb', line 261

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

#add_comment(params) ⇒ Object



257
258
259
# File 'app/models/article.rb', line 257

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

#allow_comments?Boolean

Returns:

  • (Boolean)


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

def allow_comments?
  return allow_comments unless allow_comments.nil?

  blog.default_allow_comments
end

#allow_pings?Boolean

Returns:

  • (Boolean)


271
272
273
274
275
# File 'app/models/article.rb', line 271

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–>”.



237
238
239
240
241
242
243
# File 'app/models/article.rb', line 237

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.



247
248
249
250
251
# File 'app/models/article.rb', line 247

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

#comment_urlObject



132
133
134
# File 'app/models/article.rb', line 132

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

#comments_closed?Boolean

Returns:

  • (Boolean)


208
209
210
# File 'app/models/article.rb', line 208

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

#content_fieldsObject



230
231
232
# File 'app/models/article.rb', line 230

def content_fields
  [:body, :extended]
end

#feed_url(format) ⇒ Object



140
141
142
# File 'app/models/article.rb', line 140

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

#has_child?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'app/models/article.rb', line 88

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

#html_urlsObject



212
213
214
215
216
217
218
# File 'app/models/article.rb', line 212

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)


225
226
227
228
# File 'app/models/article.rb', line 225

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



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

def interested_users
  User.where(notify_on_new_articles: true)
end

#keywords_to_tagsObject



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

def keywords_to_tags
  Tag.create_from_article!(self)
end

#nextObject



144
145
146
147
# File 'app/models/article.rb', line 144

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

#notify_user_via_email(user) ⇒ Object



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

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

#password_protected?Boolean

Returns:

  • (Boolean)


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

def password_protected?
  password.present?
end

FIXME: Use keyword params to clean up call sites.



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

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)


220
221
222
# File 'app/models/article.rb', line 220

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

#post_typeObject



92
93
94
95
96
# File 'app/models/article.rb', line 92

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

#preview_comment_urlObject



136
137
138
# File 'app/models/article.rb', line 136

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

#previousObject



149
150
151
152
# File 'app/models/article.rb', line 149

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

#publication_monthObject



154
155
156
# File 'app/models/article.rb', line 154

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

#published_commentsObject



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

def published_comments
  comments.published.oldest_first
end

#published_feedbackObject



285
286
287
# File 'app/models/article.rb', line 285

def published_feedback
  feedback.published.oldest_first
end

#published_trackbacksObject



281
282
283
# File 'app/models/article.rb', line 281

def published_trackbacks
  trackbacks.published.oldest_first
end

#save_attachment!(file) ⇒ Object



128
129
130
# File 'app/models/article.rb', line 128

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

#save_attachments!(files) ⇒ Object



123
124
125
126
# File 'app/models/article.rb', line 123

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


82
83
84
85
86
# File 'app/models/article.rb', line 82

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

  self.permalink = title.to_permalink
end