Class: Cms::Page

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Addressable, Addressable::DeprecatedPageAccessors, DefaultAccessible
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



301
302
303
# File 'app/models/cms/page.rb', line 301

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

Instance Method Details

#actual_pathObject



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)



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'app/models/cms/page.rb', line 152

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

Implements Versioning Callback.



87
88
89
90
91
92
93
94
# File 'app/models/cms/page.rb', line 87

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_publishObject

Publish all



97
98
99
100
101
102
103
104
# File 'app/models/cms/page.rb', line 97

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_pathObject



227
228
229
230
231
232
233
# File 'app/models/cms/page.rb', line 227

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

#assigned_toObject



326
327
328
# File 'app/models/cms/page.rb', line 326

def assigned_to
  current_task ? current_task.assigned_to : nil
end

#assigned_to?(user) ⇒ Boolean

Returns:

  • (Boolean)


330
331
332
# File 'app/models/cms/page.rb', line 330

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



297
298
299
# File 'app/models/cms/page.rb', line 297

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)


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

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.



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
144
145
146
147
# File 'app/models/cms/page.rb', line 108

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_taskObject



322
323
324
# File 'app/models/cms/page.rb', line 322

def current_task
  tasks.incomplete.first
end

#delete_connectorsObject

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



203
204
205
# File 'app/models/cms/page.rb', line 203

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

#file_sizeObject

Pages have no size (for the purposes of FCKEditor)



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

def file_size
  "NA"
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)


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'app/models/cms/page.rb', line 271

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(version = :full) ⇒ Object

Return the layout used to render this page. Will be something like: 'templates/subpage'

Parameters:

  • version (Symbol) (defaults to: :full)

    Valid values are :full and :mobile.



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

def layout(version = :full)
  folder = (version == :mobile) ? "mobile" : "templates"
  template_file_name && "#{folder}/#{layout_name}"
end

#layout_nameObject

Return the file name of the template



255
256
257
# File 'app/models/cms/page.rb', line 255

def layout_name
  template_file_name.split('.').first
end

#move_connector(connector, direction) ⇒ Object



172
173
174
175
176
177
178
179
180
# File 'app/models/cms/page.rb', line 172

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_pathObject



305
306
307
308
# File 'app/models/cms/page.rb', line 305

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

#page_titleObject



223
224
225
# File 'app/models/cms/page.rb', line 223

def page_title
  title.blank? ? name : title
end

#path_not_reservedObject



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

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)


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

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

#remove_connector(connector) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/models/cms/page.rb', line 188

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_pathObject

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



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

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



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

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

#templateObject

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



260
261
262
# File 'app/models/cms/page.rb', line 260

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

#template_nameObject



264
265
266
# File 'app/models/cms/page.rb', line 264

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

#top_level_sectionSection

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.



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

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] : Cms::Section.root.first
end