lib/cms/behaviors/connecting.rb
module Cms
module Behaviors
module Connecting
def self.default_naming_for(klass)
klass.name.demodulize.titleize
end
def self.included(model_class)
model_class.extend(MacroMethods)
end
module MacroMethods
def connectable?
!!@is_connectable
end
def is_connectable(options={})
@is_connectable = true
extend ClassMethods
include InstanceMethods
attr_accessor :connect_to_page_id, :connect_to_container, :connected_page
#attr_accessible :connect_to_page_id, :connect_to_container,:connected_page
has_many :connectors, :as => :connectable, :class_name => 'Cms::Connector'
attr_accessor :updated_by_page
after_create :connect_to_page
after_save :update_connected_pages, :unless => :skip_callbacks
end
end
module ClassMethods
def content_block_type
::ActiveModel::Naming.singular(self)
end
def display_name
Connecting.default_naming_for(self)
end
def display_name_plural
display_name.pluralize
end
end
module InstanceMethods
# Returns a machine readable key that identifies the type of content this is.
# Should match the key passed to ContentType.find_by_key
def content_name
class_name = self.class.name
if class_name.starts_with?("Cms::")
class_name.demodulize.underscore
else
class_name.underscore
end
end
def connected_pages
return @connected_pages if @connected_pages
@connected_pages = Page.connected_to(self)
end
def connected_page_count
Page.currently_connected_to(self).count
end
def content_block_type
self.class.content_block_type
end
def display_name
self.class.display_name
end
def display_name_plural
self.class.display_name_plural
end
def connect_to_page
unless connect_to_page_id.blank? || connect_to_container.blank?
#Note that we are setting connected_page so that page can look at that
#to determine if the page should be published
self.connected_page = Page.find(connect_to_page_id)
connected_page.create_connector(self, connect_to_container)
end
true
end
# By default, all content types will support inline editing. Subclasses can override this.
def supports_inline_editing?
true
end
#
# After blocks are updated, all pages they are connected to should also be updated,
# connecting the page to the new version of the block, as well as putting the pages into
# draft status if necessary.
#
def update_connected_pages
# If this is versioned, then we need make new versions of all the pages this is connected to
if self.class.versioned?
#logger.info "..... Updating connected pages for #{self.class} #{id} v#{version}"
#Get all the pages the previous version of this connectable was connected to
draft_version = draft.version
connected_pages = Page.connected_to(:connectable => self, :version => (draft_version - 1)).to_a
# puts "Found #{connected_pages}"
connected_pages.each do |p|
# This is needed in the case of updating page,
# which updates this object, so as not to create a loop
if p != updated_by_page
#This just creates a new version of the page
action = deleted? ? "Deleted" : "Edited"
p.update_attributes(:version_comment => "#{self.class.name.demodulize} ##{id} was #{action}", :publish_on_save => false)
#The previous step will copy over a connector pointing to the previous version of this connectable
#We need to change that to point at the new version of this connectable
connectors_for_page = p.connectors
# puts "cfp #{connectors_for_page}"
page_draft_version = p.draft.version
cnn = connectors_for_page.for_page_version(page_draft_version)
# puts "Connectors for page version #{page_draft_version} are #{cnn.all}"
connectors = cnn.for_connectable(self)
# puts "Found connectors #{connectors.all}"
connectors.each do |con|
con.update_attribute(:connectable_version, draft_version)
end
end
end
end
true
end
end
end
end
end