Class: Page

Inherits:
KitIndexed show all
Defined in:
app/models/page.rb

Direct Known Subclasses

BlogPost, StaticPage

Constant Summary collapse

@@index_def =
[
{:name=>:id, :index=>:not_analyzed, :include_in_all=>false},
{:name=>:system_id, :index=>:not_analyzed, :include_in_all=>false},
{:name=>:name, :boost=>100, :user=>true},
{:name=>:title, :boost=>50, :user=>true},
{:name=>:tags, :boost=>20},
{:name=>:full_path, :boost=>50},
{:name=>:meta_description, :boost=>20, :user=>true},
{:name=>:meta_keywords, :boost=>20, :user=>true},
{:name=>:notes},
{:name=>:terms, :as=>"concatenated_terms", :user=>true},
{:name=>:created_by, :as=>"user.email"},
{:name=>:updated_at, :type=>'date', :include_in_all=>false},
{:name=>:status, :as=>"status.name.downcase", :index=>:not_analyzed},
{:name=>:is_deleted, :index=>:not_analyzed},
{:name=>:content, :as=>"concatenated_content(:current)", :user=>true},
{:name=>:old_content, :as=>"concatenated_content(:old)", :include_in_all=>false},
{:name=>:draft_content, :as=>"concatenated_content(:draft)", :include_in_all=>false},
{:name=>:autosave_content, :as=>"concatenated_content(:autosave)", :include_in_all=>false}
]
@@per_page =
10

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from KitIndexed

do_indexing, indexed_columns, paginate

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object



505
506
507
508
509
510
511
512
513
# File 'app/models/page.rb', line 505

def method_missing(meth, *args, &block)
  if meth.to_s =~ /^content_(.+)$/
    load_field($1, *args)
  elsif meth.to_s =~ /^value_(.+)$/
    load_field($1, *args).value
  else
    super
  end
end

Instance Attribute Details

#copy_ofObject

Returns the value of attribute copy_of.



165
166
167
# File 'app/models/page.rb', line 165

def copy_of
  @copy_of
end

#draftObject

Returns the value of attribute draft.



166
167
168
# File 'app/models/page.rb', line 166

def draft
  @draft
end

#editableObject



161
162
163
# File 'app/models/page.rb', line 161

def editable
  @editable || false
end

#pageObject

Returns the value of attribute page.



178
179
180
# File 'app/models/page.rb', line 178

def page
  @page
end

#skip_historyObject

Returns the value of attribute skip_history.



167
168
169
# File 'app/models/page.rb', line 167

def skip_history
  @skip_history
end

Class Method Details

.children_of(category) ⇒ Object



410
411
412
# File 'app/models/page.rb', line 410

def self.children_of(category)
  Page.where(:category_id=>category.id).all
end

.field_matches(sid, field_name, field_value, page_template_ids = nil, only_published_and_visible = true, version = 0) ⇒ Object



494
495
496
497
498
499
500
501
502
503
# File 'app/models/page.rb', line 494

def Page.field_matches(sid, field_name, field_value,  page_template_ids = nil, only_published_and_visible = true, version = 0) 
  ps = Page
  ps = ps.where("pages.page_template_id in (#{page_template_ids.join ','})") if page_template_ids
  ps = ps.where("pages.is_deleted = 0 and pages.status_id = #{Page.published_status(sid).id}") if only_published_and_visible
  ps = ps.joins(:page_contents).where("page_contents.version = #{version}")
  ps = ps.where("page_contents.field_name = '#{field_name}'")
  pc_table = PageContent.arel_table
  ps = ps.where(pc_table[:value].eq(field_value))
  ps.all
end

.field_values(sid, field_name, page_template_ids = nil, only_published_and_visible = true, version = 0) ⇒ Object



487
488
489
490
491
492
# File 'app/models/page.rb', line 487

def Page.field_values(sid, field_name,  page_template_ids = nil, only_published_and_visible = true, version = 0) 
  pcs = PageContent.where(:field_name=>field_name).where(:version=>version)
  pcs = pcs.joins(:page).where("pages.page_template_id in (#{page_template_ids.join ','})") if page_template_ids
  pcs = pcs.joins(:page).where("pages.is_deleted = 0 and pages.status_id = #{Page.published_status(sid).id}") if only_published_and_visible
  pcs.all.map { |pc| pc.value }
end

.index_defObject



28
29
30
# File 'app/models/page.rb', line 28

def self.index_def
  @@index_def
end

.mercury_region(field_type) ⇒ Object



388
389
390
391
392
393
394
395
396
# File 'app/models/page.rb', line 388

def self.mercury_region(field_type)
  if field_type=='text'
    return 'editable'
  elsif field_type=='line'
    return 'editable'
  else
    return 'editable'
  end
end

.published_status(sid) ⇒ Object



87
88
89
# File 'app/models/page.rb', line 87

def self.published_status(sid)
  Status.published_status(sid)
end

.update_all_paths(sid) ⇒ Object



242
243
244
245
246
247
# File 'app/models/page.rb', line 242

def Page.update_all_paths(sid)
  Page.sys(sid).find_each do |p|
    p.skip_history = true
    p.save!
  end
end

Instance Method Details

#add_term(page_term, value) ⇒ Object



584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
# File 'app/models/page.rb', line 584

def add_term(page_term, value)
  new_terms = []

  return new_terms if value == nil

  if value.instance_of?(String)
    new_terms << save_term(page_term, value) if value.not_blank?
  elsif value.instance_of?(HashWithIndifferentAccess)
    value.each do |name, val|
      new_terms << save_term(page_term, val) if val.not_blank?
    end  
  end

  return new_terms
end

#autosave_contentObject



65
66
67
# File 'app/models/page.rb', line 65

def autosave_content
  self.page_contents.where(:version=>-2)
end

#autotitleObject



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'app/models/page.rb', line 422

def autotitle
  i = 1
  ok = false
  existing = Page.sys(self.system_id).where(:category_id => self.category_id).all
  until ok
    found = false
    existing.each do |p|
      if p.title == "Page #{i}"
        found = true
        break
      end
    end
    if found==false
      ok = true
    else
      i += 1
    end  
  end
  self.title = "Page #{i}"
end

#by_idObject



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

def by_id
  self.page = Page.find_sys_id(self.system_id, self.id)
  return self.page
end

#change_full_pathObject



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

def change_full_path
  self.full_path = make_full_path
end

#clear_auto_saveObject



249
250
251
# File 'app/models/page.rb', line 249

def clear_auto_save
  ActiveRecord::Base.connection.execute("delete from page_contents where version = -2 and page_id = #{self.id}")
end

#clear_cacheObject



215
216
217
# File 'app/models/page.rb', line 215

def clear_cache
  Category.clear_cache(self.system_id)
end

#concatenated_content(type = :current) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'app/models/page.rb', line 77

def concatenated_content(type = :current)
  method = type.to_s+"_content"
  if self.respond_to?(method)
    contents = self.send(method)
    contents.map {|c| c.value}.join(" ")
  else
    ""
  end
end

#concatenated_termsObject



49
50
51
# File 'app/models/page.rb', line 49

def concatenated_terms
  self.terms.map { |term| term.value ? term.value.downcase : "" }.join(',')
end

#copy_content_from(page) ⇒ Object



539
540
541
542
543
544
545
546
# File 'app/models/page.rb', line 539

def copy_content_from(page) 
  page.page_contents.each do |pc|
    self.page_contents << pc.dup
  end
  page.block_instances.each do |ps|
    self.block_instances << ps.dup
  end
end

#copy_to(cat) ⇒ Object



548
549
550
551
552
553
554
555
556
557
558
# File 'app/models/page.rb', line 548

def copy_to(cat)
  page = self.dup
  page.category = cat
  page.change_full_path
  if page.save
    page.copy_content_from(self)
    return page.id
  else
    return nil
  end
end

#crawl(force = false) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'app/models/page.rb', line 140

def crawl(force = false)
  return unless force || self.needs_crawl 
  self.update_attributes(:needs_crawl=>nil)
  PageLink.delete_all("page_id = #{self.id}")
  
  Anemone.crawl(full_url, :depth_limit=>1, :read_timeout=>2, :discard_page_bodies=>true) do |anemone|
    first_page = true
    anemone.on_every_page do |page|
      if first_page
        first_page = false
        next
      end

      uri = URI.parse(page.url.to_s)
      PageLink.create(:page_id=>self.id, :url=>uri.path, :http_status=>page.code, :system_id=>self.system_id)
    end
  end
  self.update_attributes(:updated_crawl=>Time.now) 
end

#current_contentObject



73
74
75
# File 'app/models/page.rb', line 73

def current_content
  self.page_contents.where(:version=>0)
end

#deleted?Boolean

Returns:

  • (Boolean)


406
407
408
# File 'app/models/page.rb', line 406

def deleted?
  self.is_deleted == 1
end

#destroy_draft(user_id) ⇒ Object



286
287
288
289
290
291
292
293
294
# File 'app/models/page.rb', line 286

def destroy_draft(user_id)
  self.page_contents.where(:version=>-1).each do |c|
    c.destroy
  end
  self.block_instances.where(:version=>-1).each do |bi|
    bi.destroy
  end
  PageHistory.record(self, user_id, 'Draft deleted', "")
end

#dif_template(is_mobile) ⇒ Object



266
267
268
269
270
271
272
# File 'app/models/page.rb', line 266

def dif_template(is_mobile)
  if is_mobile && self.mobile_dif==1
    self.mobile_page_template
  else
    return self.page_template
  end
end

#draft_contentObject



69
70
71
# File 'app/models/page.rb', line 69

def draft_content
  self.page_contents.where(:version=>-1)
end

#full_urlObject



129
130
131
# File 'app/models/page.rb', line 129

def full_url
  "#{Preference.get_cached(self.system_id, "host")}#{self.full_path}"
end

#generate_block_instance(block_instance_id, block_id, param_options, user_id) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'app/models/page.rb', line 187

def generate_block_instance(block_instance_id, block_id, param_options, user_id)
  if block_id.is_number?
    block = Block.find_sys_id(self.system_id, block_id)
  else

    block = Block.sys(self.system_id).where(:name=>block_id).first
  end

  if param_options == nil
    options = {}
  elsif param_options.instance_of?(String)
    options = eval(param_options)
  else
    options = param_options
  end

  bi = nil
  if options.size>0
    options.each do |name,value|
      bi = BlockInstance.create(:system_id=>self.system_id, :page_id=>self.id, :block_id=>block.id, :field_name=>name, :field_value=>value, :user_id=>user_id, :instance_id=>block_instance_id)
    end
  else
      bi = BlockInstance.create(:system_id=>self.system_id, :page_id=>self.id, :block_id=>block.id, :field_name=>'no_params', :field_value=>'no_params', :user_id=>user_id, :instance_id=>block_instance_id)
  end

  return bi
end

#generate_block_instances(user_id) ⇒ Object



180
181
182
183
184
185
# File 'app/models/page.rb', line 180

def generate_block_instances(user_id)
  # find any instances of:  = kit_editable_block(id, blah blah)
  self.page_template.body.scan(/= ?kit_editable_block\(\'?\"?([^\,\)\'\"]+)\'?\"?\s*,\s*\'?\"?([^\,\)\'\"]+)\'?\"?(?:\s*,\s*(\{.*\}))?\)/) do 
    self.generate_block_instance($1, $2, $3, user_id)
  end
end

#get_block_instances(instance_id, version = 0, field_name = nil, block_id = nil) ⇒ Object

this allows you to get block instances from the page. these block instances might have been eagrly loaded already (which they are in the most common case - i.e. rendering a page using the PageController). If they weren’t loaded they will be when this is called, as they also will if you want something other than version 0



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'app/models/page.rb', line 33

def get_block_instances(instance_id, version = 0, field_name = nil, block_id = nil)
  if version==0
    r = []
    self.block_instances0.each do |block_instance|
      if field_name || block_id
        r << block_instance if block_instance.instance_id == instance_id && block_instance.field_name == field_name && block_instance.block_id == block_id
      else
        r << block_instance if block_instance.instance_id == instance_id
      end
    end
    return r
  else
    self.block_instances.where(:instance_id=>instance_id, :version=>version)
  end
end

#has_draft?Boolean

Returns:

  • (Boolean)


443
444
445
# File 'app/models/page.rb', line 443

def has_draft?
  self.page_contents.where("version < 0").count > 0
end

#has_term_for(page_template_term) ⇒ Object



560
561
562
# File 'app/models/page.rb', line 560

def has_term_for(page_template_term)
  self.terms.where(:page_template_term_id=>page_template_term.id).count > 0
end

#history_endObject



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'app/models/page.rb', line 360

def history_end
  return if self.skip_history

  if @new
    PageHistory.record(self, self.created_by, nil, 'New', 'Initial Creation', false)
    return
  end

  if @changes[:status_id] 
    old_status_name = Status.find(@old_status_id).name
    PageHistory.record(self, self.updated_by, 'Status changed', "From: #{old_status_name} To: #{self.status(true).name}")  
  end

  if @changes[:is_deleted]
    PageHistory.record(self, self.updated_by, 'Deleted status change', "Page is now #{self.is_deleted? ? 'deleted' : 'not deleted'}")
  end

  fields = [ ['name','Name'], ['full_path','Path'], ['tags','Tags'], ['meta_description', 'Meta Description'], ['meta_keywords', 'Meta Keywords'] ]

  fields.each do |field|
    if @changes[field[0].to_sym]
      from = @changes[field[1].to_sym][0] rescue ""

      PageHistory.record(self, nil, "#{field[1].to_sym} changed", "From: #{from}")
    end
  end
end

#history_startObject



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'app/models/page.rb', line 341

def history_start
  return if self.skip_history

  @new = self.new_record?
  @old_status_id = self.status_id_was
  @changes = self.changes
  @changed = self.changed
  if self.changed.include?("status_id")
    if self.status_id == Page.published_status(self.system_id)
      PageHistory.record(self, user_id, 'Published', "")
      self.published_at = Time.now
    elsif @old_status_id == Page.published_status(self.system_id)
      self.published_at = nil
      PageHistory.record(self, user_id, 'Unpublished', "")
    end
  end

end

#is_favourite?(user) ⇒ Boolean

Returns:

  • (Boolean)


333
334
335
# File 'app/models/page.rb', line 333

def is_favourite?(user)
  user.is_favourite_page?(self)
end

#is_home_page?Boolean

Returns:

  • (Boolean)


232
233
234
# File 'app/models/page.rb', line 232

def is_home_page?
  self.id.to_i == Preference.get(self.system_id, 'home_page').to_i rescue false
end

#is_published?Boolean

Returns:

  • (Boolean)


402
403
404
# File 'app/models/page.rb', line 402

def is_published?
  self.status_id == Status.published_status(self.system_id).id
end

#is_readable_anon?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'app/models/page.rb', line 57

def is_readable_anon?
  self.category.is_readable_anon?
end

#is_stub?Boolean

Returns:

  • (Boolean)


398
399
400
# File 'app/models/page.rb', line 398

def is_stub?
  self.status_id == Status.stub_status(self.system_id).id
end


325
326
327
328
329
330
331
# File 'app/models/page.rb', line 325

def link(mode='show', inplace_edit=false)
  if mode=='show'
    return self.full_path + (inplace_edit ? "?edit=1" : "")
  else
    return "/page/#{self.id}/#{mode}"
  end
end

#load_field(field_name, version = 0) ⇒ Object



515
516
517
518
519
520
521
# File 'app/models/page.rb', line 515

def load_field(field_name, version=0)
  if version==0 #&& self.page_contents.loaded?
    self.page_content_version0(field_name) rescue nil
  else
    PageContent.where(:page_id=>self.id).where("version = #{version}").where("field_name = '#{field_name}'").first rescue nil
  end
end

#make_draft(user_id) ⇒ Object



296
297
298
299
300
301
302
303
304
305
# File 'app/models/page.rb', line 296

def make_draft(user_id)
  self.page_contents.where("version=0").each do |content|
    PageContent.create(:system_id=>self.system_id, :page_id=>self.id, :field_name=>content.field_name,  :version=>-1, :value=>content.value, :user_id=>user_id)
  end

  BlockInstance.sys(self.system_id).where(:page_id=>self.id).where(:version=>0).each do |bi|
    BlockInstance.create(:system_id=>self.system_id, :page_id=>self.id, :field_name=>bi.field_name, :field_value=>bi.field_value, :version=>-1, :user_id=>user_id, :block_id=>bi.block_id, :instance_id=>bi.instance_id)
  end
  PageHistory.record(self, user_id, 'Draft created', "")
end

#make_full_pathObject



414
415
416
417
418
419
420
# File 'app/models/page.rb', line 414

def make_full_path
  if self.category.parent_id == 0
    "/" + self.name
  else
    self.category.path + "/" + self.name
  end
end

#make_home_page!Object



236
237
238
239
240
# File 'app/models/page.rb', line 236

def make_home_page!
  PageHistory.record(self, nil, 'Made to be the home page', "")

  Preference.set(self.system_id, 'home_page', self.id, nil)
end


527
528
529
# File 'app/models/page.rb', line 527

def menu_items
  MenuItem.sys(self.system_id).where(:link_url=>self.full_path).includes(:menu).joins(:menu).order("menus.name, menu_items.order_by")
end

#mobile_page_templateObject



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

def mobile_page_template
  PageTemplate.where(:id=>self.page_template.mobile_version_id).first || self.page_template
end

#name_from_titleObject



228
229
230
# File 'app/models/page.rb', line 228

def name_from_title
  self.title.urlise
end

#old_contentObject



61
62
63
# File 'app/models/page.rb', line 61

def old_content
  self.page_contents.where("version > 0")
end

#page_content_version0(field_name) ⇒ Object



531
532
533
534
535
536
537
# File 'app/models/page.rb', line 531

def page_content_version0(field_name)
  self.page_contents_version0.each do |pc|
    return pc if pc.field_name == field_name
  end

  return nil
end

#page_nameObject



53
54
55
# File 'app/models/page.rb', line 53

def page_name
  (Preference.getCached(self.system_id, 'app_name') + self.full_path).gsub('/','_')
end

#path_must_be_uniqueObject



219
220
221
222
223
224
225
226
# File 'app/models/page.rb', line 219

def path_must_be_unique
  full_path = make_full_path

  cnt = Page.sys(self.system_id).where(:full_path=>full_path).where(["id<>?", self.new_record? ? -1 : self.id]).count
  if cnt > 0
    errors.add(:name, "not unique within this category")
  end
end

#publish(user_id) ⇒ Object



278
279
280
281
282
283
284
# File 'app/models/page.rb', line 278

def publish(user_id)
  self.status_id = Page.published_status(self.system_id).id
  self.publish_draft(user_id) if self.draft
  self.published_at = Time.now
  self.save
  PageHistory.record(self, user_id, 'Published', "")
end

#publish_draft(user_id) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
# File 'app/models/page.rb', line 307

def publish_draft(user_id)
  self.page_contents.where("version <> -2").order("id desc").each do |pc|
    pc.version += 1
    pc.save
  end
  self.block_instances.where("version <> -2").order("id desc").each do |bi|
    bi.version += 1
    bi.save
  end
  PageHistory.record(self, user_id, 'Draft Published', "")
end

#queue_crawl(start_crawl = true) ⇒ Object



133
134
135
136
137
138
# File 'app/models/page.rb', line 133

def queue_crawl(start_crawl = true)
  logger.debug "Queueing crawl for page #{self.id}"
  self.needs_crawl = Time.now
  self.save
  Delayed::Job.enqueue PageLinkJob.new(self.system_id), :queue=>self.system_id if start_crawl
end

#recent_threads(count, user) ⇒ Object



319
320
321
322
323
# File 'app/models/page.rb', line 319

def recent_threads(count, user)
  level = user ? user.forum_level : 0

  self.topic_threads.limit(count).order("topic_threads.id desc").includes(:topic).where("topic_threads.is_visible = 1 and topics.is_visible = 1 and topics.read_access_level <= #{level}")
end


523
524
525
# File 'app/models/page.rb', line 523

def related_threads(count,user)
  self.recent_threads(count,user)
end

#render_field(name, version = 0) ⇒ Object



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
# File 'app/models/page.rb', line 447

def render_field(name, version=0)
  value = load_field(name, version).value rescue nil

  return nil unless value
  begin
    value.gsub(/>\[(snippet|block)_([0-9]+)\/([0-9]+)\]</) do |snip|
      block_instance = self.get_block_instances("#{$1}_#{$2}").first
      block_instance.page = self
      r = block_instance ? block_instance.render : "[block missing '#{name}']"
      ">" + r + "<"
    end
  rescue Exception => e
    "[block error: #{e.message}]"
  end
end

#save_term(page_term, value) ⇒ Object



600
601
602
603
604
605
606
607
608
609
# File 'app/models/page.rb', line 600

def save_term(page_term, value)
  new_term = Term.new
  new_term.page_template_term_id = page_term.id
  new_term.value = value
  new_term.metric = 0
  new_term.page_id = self.id
  new_term.system_id = self.system_id
  new_term.save
  return new_term
end

#set_page_template_defaultsObject



576
577
578
579
580
581
582
# File 'app/models/page.rb', line 576

def set_page_template_defaults
  self.skip_history = true
  self.allow_anonymous_comments = self.page_template.allow_anonymous_comments
  self.allow_user_comments = self.page_template.allow_user_comments
  self.save
  self.skip_history = false
end

#stop_edit(user_id) ⇒ Object



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

def stop_edit(user_id)
  PageEdit.delete_all(["page_id = ? and user_id = ?", self.id, user_id]) 
end

#term(term_name) ⇒ Object



564
565
566
# File 'app/models/page.rb', line 564

def term(term_name)
  Term.find_by_sql(["select t.* from terms t, pages p, page_template_terms pt where p.id = #{self.id} and p.page_template_id = pt.page_template_id and pt.name = ? and t.page_template_term_id = pt.id and t.page_id = p.id", term_name])       
end

#term_hierarchy(term_name) ⇒ Object



568
569
570
571
572
573
# File 'app/models/page.rb', line 568

def term_hierarchy(term_name)
  values = term(term_name)
  values.collect { |v|
    v.value.split(':') 
  }
end

#time_nowObject



337
338
339
# File 'app/models/page.rb', line 337

def time_now
  Time.now
end

#update_field(field_name, value, user = nil, field_title = nil, version = 0) ⇒ Object



463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# File 'app/models/page.rb', line 463

def update_field(field_name, value, user=nil, field_title = nil, version = 0)
  old_value = load_field(field_name,version)
  return if old_value && value==old_value.value

  if version == 0
    ActiveRecord::Base.connection.execute("update page_contents set version = version + 1 where page_id = #{self.id} and field_name = '#{field_name}' and version >= 0") 
    field = PageContent.new
    field.system_id = self.system_id
    field.page_id = self.id
    field.version = 0
    field.field_name = field_name
  else
    field = PageContent.where(:page_id=>self.id, :version=>version, :field_name=>field_name).first
    if version==-2 && field==nil
      field = PageContent.new(:system_id=>self.system_id, :page_id=>self.id, :version=>version, :field_name=>field_name)
    end
  end
  field.value = value
  field.user_id = user.id if user
  field.save
  PageHistory.record(self,  user ? user.id : 0, "Updated#{version==-1 ? ' Draft' : ''} content", "'#{field_title}' changed", false, field.id) if version>=-1

end