summaryrefslogtreecommitdiff
path: root/app/models/node.rb
blob: 31cc347abee74949edd1c9786548e92dbedfd9f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class Node < ActiveRecord::Base
  # Mixins and Plugins
  acts_as_nested_set
  
  # Associations
  has_many    :pages, :order => "revision ASC"
  belongs_to  :head,  :class_name => "Page",  :foreign_key => :head_id
  has_many    :permissions
  
  # Callbacks
  after_create :initialize_empty_page
  
  # Validations
  # validates_length_of :slug, :within => 3..40
  
  # Class methods
  
  # Returns a page for a given node. If no revision is supplied, it returns
  # the last / current one. If a specific revision number is supplied, the 
  # corresponding revision of that page is returned. Get the current / latest 
  # revision with -1. It raises an Argument error if the revision is not a 
  # Fixnum
  def self.find_page path, revision = -1
    unless revision.class == Fixnum
      raise ArgumentError, "revision must be a Fixnum" 
    end

    node = Node.find_by_unique_name(path)
        
    if node
      case revision
      when -1        
        return node.head
      else
        return node.pages.find_by_revision revision
      end
    end
    
    nil
  end
  
  # Instance Methods
  
  # check if there is a page which has a nil :published_at column
  # if there is one - it is considered a draft 
  def draft
    if draft = pages.find_by_published_at(nil)
      draft
    end
  end
  
  def find_or_create_draft user
    if draft && draft.user == user
      draft
    elsif draft && draft.user.nil?
      tmp_draft = draft
      tmp_draft.user = user
      tmp_draft.save
      tmp_draft
    elsif draft && draft.user != user
      raise "Page is locked"
    else
      create_new_draft user
    end
  end
  
  def create_new_draft user
    p = self.pages.create!
    
    p.tag_list = self.head.tag_list.join(", ")
    
    locale_before = I18n.locale.dup
    
    I18n.available_locales.each do |l|
      next if l == :root
      I18n.locale = l 
      
      p.title = self.head.title
      p.abstract = self.head.abstract
      p.body = self.head.body
    end
    
    I18n.locale = locale_before
    p.reload
    p.user = user
    p.save
    p
  end
  
  def publish_draft!
    if self.draft
      self.head = self.draft
      self.save!
      
      self.head.published_at = Time.now
      self.head.save!
    else
      nil
    end
  end
  
  # returns an array with all parts of a unique_name rather than a string
  def unique_path
    unique_name.split("/") rescue unique_name
  end
  
  # returns array with pages up to root excluding root
  def path_to_root
    parent.nil? && [slug] || parent.path_to_root.push(slug)
  end
  
  def update_unique_name
    path = self.path_to_root[1..-1]
    self.unique_name = path.join("/")
    self.save
  end
  
  protected
  
    # Creates an empty page, associates it to the given node and sets its
    # published_at date so it isn't considered a draft. Look up the draft
    # method!
    def initialize_empty_page
      if self.pages.empty?
        self.pages.create!
      end
    end
end