Class: Cms::Page

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Addressable, Addressable::DeprecatedPageAccessors
Defined in:
app/models/cms/page.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Addressable::DeprecatedPageAccessors

#build_node, #section, #section=, #section_id, #section_id=

Methods included from Addressable::NodeAccessors

#node, #node=

Methods included from Addressable::LeafNode

#access_status

Methods included from Addressable

#ancestors, #cache_parent, #parent, #parent=, #partial_for

Class Method Details

.find_live_by_path(path) ⇒ Object



288
289
290
# File 'app/models/cms/page.rb', line 288

def self.find_live_by_path(path)
  published.not_archived.first(:conditions => {:path => path})
end

Instance Method Details

#actual_path ⇒ Object



3
4
5
# File 'app/models/cms/page.rb', line 3

def actual_path
  path
end

#add_content(connectable, container = :main) ⇒ Object Also known as: create_connector

Adds a Content block to this page.

Parameters:

  • connectable (ContentBlock) —

    The content block to be added

  • container (Symbol) (defaults to: :main) —

    The container to add it in (default :main)



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/cms/page.rb', line 148

def add_content(connectable, container=:main)
  transaction do
    raise "Connectable is nil" unless connectable
    raise "Container is required" if container.blank?
    update_attributes(
        :version_comment => "#{connectable} was added to the '#{container}' container",
        :publish_on_save => (
        published? &&
            connectable.connected_page &&
            (connectable.class.publishable? ? connectable.published? : true)))
    connectors.create(
        :page_version => draft.version,
        :connectable => connectable,
        :connectable_version => connectable.class.versioned? ? connectable.version : nil,
        :container => container)
  end
end

#after_build_new_version(new_version) ⇒ Object



83
84
85
86
87
88
89
90
# File 'app/models/cms/page.rb', line 83

def after_build_new_version(new_version)
  copy_connectors(
      :from_version_number => @copy_connectors_from_version || (new_version.version - 1),
      :to_version_number => new_version.version
  )
  @copy_connectors_from_version = nil
  true
end

#after_publish ⇒ Object

Publish all



93
94
95
96
97
98
99
100
# File 'app/models/cms/page.rb', line 93

def after_publish
  self.reload # Get's the correct version number loaded
  self.connectors.for_page_version(self.version).all(:order => "position").each do |c|
    if c.connectable_type.constantize.publishable? && con = c.connectable
      con.publish
    end
  end
end

#append_leading_slash_to_path ⇒ Object



222
223
224
225
226
227
228
# File 'app/models/cms/page.rb', line 222

def append_leading_slash_to_path
  if path.blank?
    self.path = "/"
  elsif path[0, 1] != "/"
    self.path = "/#{path}"
  end
end

#assigned_to ⇒ Object



313
314
315
# File 'app/models/cms/page.rb', line 313

def assigned_to
  current_task ? current_task.assigned_to : nil
end

#assigned_to?(user) ⇒ Boolean

Returns:

  • (Boolean)


317
318
319
# File 'app/models/cms/page.rb', line 317

def assigned_to?(user)
  assigned_to == user
end

#connectable_count_for_container(container) ⇒ Object

Returns the number of connectables in the given container for this version of this page



284
285
286
# File 'app/models/cms/page.rb', line 284

def connectable_count_for_container(container)
  connectors.for_page_version(version).in_container(container.to_s).count
end

#container_published?(container) ⇒ Boolean

Returns true if the block attached to each connector in the given container are published

Returns:

  • (Boolean)


277
278
279
280
281
# File 'app/models/cms/page.rb', line 277

def container_published?(container)
  connectors.for_page_version(draft.version).in_container(container.to_s).all? do |c|
    c.connectable_type.constantize.publishable? ? c.connectable.live? : true
  end
end

#copy_connectors(options = {}) ⇒ Object

Each time a page is updated, we need to copy all connectors associated with it forward, and save them.



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
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/cms/page.rb', line 104

def copy_connectors(options={})
  logger.debug { "Copying connectors from Page #{id} v#{options[:from_version_number]} to v#{options[:to_version_number]}." }

  c_found = connectors.for_page_version(options[:from_version_number]).all(:order => "#{Cms::Connector.table_name}.container, #{Cms::Connector.table_name}.position")
  logger.debug { "Found connectors #{c_found}" }
  c_found.each do |c|

    # The connector won't have a connectable if it has been deleted
    # Also need to see if the draft has been deleted,
    # in which case we are in the process of deleting it
    if c.should_be_copied?
      logger.debug { "Connector id=>#{c.id} should be copied." }
      connectable = c.connectable_type.constantize.versioned? ? c.connectable.as_of_version(c.connectable_version) : c.connectable
      version = connectable.class.versioned? ? connectable.version : nil

      #If we are copying connectors from a previous version, that means we are reverting this page,
      #in which case we should create a new version of the block, and connect this page to that block.
      #If the connectable is versioned, the connector needs to reference the newly drafted connector
      #that is created during the revert_to method
      if @copy_connectors_from_version && connectable.class.versioned? && (connectable.version != connectable.draft.version)
        connectable = connectable.class.find(connectable.id)
        connectable.updated_by_page = self
        connectable.revert_to(c.connectable_version)
        version = connectable.class.versioned? ? connectable.draft.version : nil
      end

      logger.debug "When copying block #{connectable.inspect} version is '#{version}'"

      new_connector = connectors.create(
        :page_version => options[:to_version_number],
        :connectable => connectable, 
        :connectable_version => version,
        :container => c.container,
        :position => c.position
      )
      logger.debug { "Built new connector #{new_connector}." }
    end
  end
  true
end

#current_task ⇒ Object



309
310
311
# File 'app/models/cms/page.rb', line 309

def current_task
  tasks.incomplete.first
end

#delete_connectors ⇒ Object

Pages that get deleted should be 'disconnected' from any blocks they were associated with.



199
200
201
# File 'app/models/cms/page.rb', line 199

def delete_connectors
  connectors.for_page_version(version).all.each { |c| c.destroy }
end

#file_size ⇒ Object



210
211
212
# File 'app/models/cms/page.rb', line 210

def file_size
  "?"
end

#in_section?(section_or_section_name) ⇒ Boolean

Determines if a page is a descendant of a given Section.

Parameters:

  • section_or_section_name (String | Section)

Returns:

  • (Boolean)


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'app/models/cms/page.rb', line 258

def in_section?(section_or_section_name)
  found = false
  ancestors.each do |a|
    if section_or_section_name.is_a?(String)
      if a.name == section_or_section_name
        found = true
        break
      end
    else
      if a == section_or_section_name
        found = true
        break
      end
    end
  end
  found
end

#layout ⇒ Object



242
243
244
# File 'app/models/cms/page.rb', line 242

def layout
  template_file_name && "templates/#{template_file_name.split('.').first}"
end

#move_connector(connector, direction) ⇒ Object



168
169
170
171
172
173
174
175
176
# File 'app/models/cms/page.rb', line 168

def move_connector(connector, direction)
  transaction do
    raise "Connector is nil" unless connector
    raise "Direction is nil" unless direction
    orientation = direction[/_/] ? "#{direction.sub('_', ' the ')} of" : "#{direction} within"
    update_attributes(:version_comment => "#{connector.connectable} was moved #{orientation} the '#{connector.container}' container")
    connectors.for_page_version(draft.version).like(connector).first.send("move_#{direction}")
  end
end

#name_with_section_path ⇒ Object



292
293
294
295
# File 'app/models/cms/page.rb', line 292

def name_with_section_path
  a = ancestors
  (a[1..a.size].map { |a| a.name } + [name]).join(" / ")
end

#page_title ⇒ Object



218
219
220
# File 'app/models/cms/page.rb', line 218

def page_title
  title.blank? ? name : title
end

#path_not_reserved ⇒ Object



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

def path_not_reserved
  if Cms.reserved_paths.include?(path)
    errors.add(:path, "is invalid, '#{path}' a reserved path")
  end
end

#public? ⇒ Boolean

Returns:

  • (Boolean)


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

def public?
  section ? section.public? : false
end

#remove_connector(connector) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'app/models/cms/page.rb', line 184

def remove_connector(connector)
  transaction do
    raise "Connector is nil" unless connector
    update_attributes(:version_comment => "#{connector.connectable} was removed from the '#{connector.container}' container")

    #The logic of this is to go ahead and let the container get copied forward, then delete the new connector
    if new_connector = connectors.for_page_version(draft.version).like(connector).first
      new_connector.destroy
    else
      raise "Error occurred while trying to remove connector #{connector.id}"
    end
  end
end

#remove_trailing_slash_from_path ⇒ Object

remove trailing slash, unless the path is only a slash. uses capture and substition because ruby regex engine does not support lookbehind



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

def remove_trailing_slash_from_path
  self.path.sub!(/(.+)\/+$/, '\1')
end

#revert_to(version) ⇒ Object

This is done to let copy_connectors know which version to pull from copy_connectors will get called later as an after_update callback



205
206
207
208
# File 'app/models/cms/page.rb', line 205

def revert_to(version)
  @copy_connectors_from_version = version
  super(version)
end

#template ⇒ Object

This will be nil if it is a file system based template



247
248
249
# File 'app/models/cms/page.rb', line 247

def template
  Cms::PageTemplate.find_by_file_name(template_file_name)
end

#template_name ⇒ Object



251
252
253
# File 'app/models/cms/page.rb', line 251

def template_name
  template_file_name && Cms::PageTemplate.display_name(template_file_name)
end

#top_level_section ⇒ Section

This will return the "top level section" for this page, which is the section directly below the root (a.k.a My Site) that this page is in. If this page is in root, then this will return root.

Returns:

  • (Section) —

    The first non-root ancestor if available, root otherwise.



302
303
304
305
306
307
# File 'app/models/cms/page.rb', line 302

def top_level_section
  # Cache the results of this since many projects will call it repeatly on current_page in menus.
  return @top_level_section if @top_level_section
  a = ancestors
  @top_level_section = (a.size > 0 && a[1]) ? a[1] : Section.root.first
end