bcms_ancestry 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +243 -0
- data/app/controllers/application_controller.rb +12 -0
- data/app/controllers/cms/sections_controller.rb +130 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/cms/section_nodes_helper.rb +11 -0
- data/app/models/attachment.rb +177 -0
- data/app/models/legacy_bcms/attachment.rb +193 -0
- data/app/models/legacy_bcms/link.rb +35 -0
- data/app/models/legacy_bcms/page.rb +275 -0
- data/app/models/legacy_bcms/section.rb +155 -0
- data/app/models/legacy_bcms/section_node.rb +93 -0
- data/app/models/link.rb +32 -0
- data/app/models/page.rb +307 -0
- data/app/models/section.rb +177 -0
- data/app/models/section_node.rb +142 -0
- data/app/views/cms/section_nodes/_link.html.erb +11 -0
- data/app/views/cms/section_nodes/_node.html.erb +36 -0
- data/app/views/cms/section_nodes/_page.html.erb +14 -0
- data/app/views/cms/section_nodes/_section.html.erb +13 -0
- data/app/views/cms/section_nodes/_section_node.html.erb +27 -0
- data/app/views/cms/section_nodes/_sitemap.html.erb +99 -0
- data/app/views/cms/section_nodes/index.html.erb +21 -0
- data/db/migrate/20100629162323_create_section_nodes.rb +41 -0
- data/lib/bcms_ancestry.rb +1 -0
- data/lib/bcms_ancestry/routes.rb +7 -0
- data/public/bcms/ancestry/README +1 -0
- data/rails/init.rb +4 -0
- metadata +93 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
class LegacyBcms::Section < ActiveRecord::Base
|
2
|
+
|
3
|
+
flush_cache_on_change
|
4
|
+
|
5
|
+
#The node that links this section to its parent
|
6
|
+
has_one :node, :class_name => "LegacyBcms::SectionNode", :as => :node, :dependent => :destroy
|
7
|
+
|
8
|
+
#The nodes that link this section to its children
|
9
|
+
has_many :child_nodes, :class_name => "LegacyBcms::SectionNode"
|
10
|
+
has_many :child_sections, :class_name => "LegacyBcms::SectionNode", :conditions => ["node_type = ?", "LegacyBcms::Section"], :order => 'section_nodes.position'
|
11
|
+
|
12
|
+
has_many :pages, :through => :child_nodes, :source => :node, :source_type => 'Page', :order => 'section_nodes.position'
|
13
|
+
has_many :sections, :through => :child_nodes, :source => :node, :source_type => 'Section', :order => 'section_nodes.position'
|
14
|
+
|
15
|
+
has_many :group_sections
|
16
|
+
has_many :groups, :through => :group_sections
|
17
|
+
|
18
|
+
named_scope :root, :conditions => ['root = ?', true]
|
19
|
+
named_scope :system, :conditions => {:name => 'system'}
|
20
|
+
|
21
|
+
named_scope :hidden, :conditions => {:hidden => true}
|
22
|
+
named_scope :not_hidden, :conditions => {:hidden => false}
|
23
|
+
|
24
|
+
named_scope :named, lambda{|name| {:conditions => ['sections.name = ?', name]}}
|
25
|
+
named_scope :with_path, lambda{|path| {:conditions => ['sections.path = ?', path]}}
|
26
|
+
|
27
|
+
validates_presence_of :name, :path
|
28
|
+
#validates_presence_of :parent_id, :if => Proc.new {root.count > 0}, :message => "section is required"
|
29
|
+
|
30
|
+
# Disabling '/' in section name for interoperability with FCKEditor file browser
|
31
|
+
validates_format_of :name, :with => /\A[^\/]*\Z/, :message => "cannot contain '/'"
|
32
|
+
|
33
|
+
validate :path_not_reserved
|
34
|
+
|
35
|
+
before_destroy :deletable?
|
36
|
+
|
37
|
+
attr_accessor :full_path
|
38
|
+
|
39
|
+
def visible_child_nodes(options={})
|
40
|
+
children = child_nodes.of_type(["Section", "Page", "Link"]).all(:order => 'section_nodes.position')
|
41
|
+
visible_children = children.select{|sn| sn.visible?}
|
42
|
+
options[:limit] ? visible_children[0...options[:limit]] : visible_children
|
43
|
+
end
|
44
|
+
|
45
|
+
def all_children_with_name
|
46
|
+
child_sections.map do |s|
|
47
|
+
if s.node
|
48
|
+
s.node.full_path = root? ? s.node.name : "#{name} / #{s.node.name}"
|
49
|
+
[s.node] << s.node.all_children_with_name
|
50
|
+
end
|
51
|
+
end.flatten.compact
|
52
|
+
end
|
53
|
+
|
54
|
+
def parent_id
|
55
|
+
parent ? parent.id : nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def parent
|
59
|
+
node ? node.section : nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def parent_id=(sec_id)
|
63
|
+
self.parent = Section.find(sec_id)
|
64
|
+
end
|
65
|
+
|
66
|
+
def parent=(sec)
|
67
|
+
if node
|
68
|
+
node.move_to_end(sec)
|
69
|
+
else
|
70
|
+
build_node(:node => self, :section => sec)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def ancestors(options={})
|
75
|
+
ancs = node ? node.ancestors : []
|
76
|
+
options[:include_self] ? ancs + [self] : ancs
|
77
|
+
end
|
78
|
+
|
79
|
+
def with_ancestors(options = {})
|
80
|
+
options.merge! :include_self => true
|
81
|
+
self.ancestors(options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def move_to(section)
|
85
|
+
if root?
|
86
|
+
false
|
87
|
+
else
|
88
|
+
node.move_to_end(section)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def public?
|
93
|
+
!!(groups.find_by_code('guest'))
|
94
|
+
end
|
95
|
+
|
96
|
+
def empty?
|
97
|
+
child_nodes.reject{|n| n.orphaned?}.empty?
|
98
|
+
end
|
99
|
+
|
100
|
+
def deletable?
|
101
|
+
!root? && empty?
|
102
|
+
end
|
103
|
+
|
104
|
+
def editable_by_group?(group)
|
105
|
+
group.editable_by_section(self)
|
106
|
+
end
|
107
|
+
|
108
|
+
def status
|
109
|
+
public? ? :unlocked : :locked
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.find_by_name_path(name_path)
|
113
|
+
section = Section.root.first
|
114
|
+
children = name_path.split("/")[1..-1] || []
|
115
|
+
children.each do |name|
|
116
|
+
section = section.sections.first(:conditions => {:name => name})
|
117
|
+
end
|
118
|
+
section
|
119
|
+
end
|
120
|
+
|
121
|
+
#The first page that is a decendent of this section
|
122
|
+
def first_page_or_link
|
123
|
+
section_node = child_nodes.of_type(['Link', 'Page']).first(:order => "section_nodes.position")
|
124
|
+
return section_node.node if section_node
|
125
|
+
sections.each do |s|
|
126
|
+
node = s.first_page_or_link
|
127
|
+
return node if node
|
128
|
+
end
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def actual_path
|
133
|
+
if root?
|
134
|
+
"/"
|
135
|
+
else
|
136
|
+
p = first_page_or_link
|
137
|
+
p ? p.path : "#"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def path_not_reserved
|
142
|
+
if Cms.reserved_paths.include?(path)
|
143
|
+
errors.add(:path, "is invalid, '#{path}' a reserved path")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Set which groups are allowed to access this section.
|
149
|
+
# @params [Symbol] code Set of groups to allow (Options :all, :none) Defaults to :none
|
150
|
+
def allow_groups=(code=:none)
|
151
|
+
if code == :all
|
152
|
+
self.groups = Group.all
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class LegacyBcms::SectionNode < ActiveRecord::Base
|
2
|
+
belongs_to :section
|
3
|
+
belongs_to :node, :polymorphic => :true
|
4
|
+
|
5
|
+
acts_as_list :scope => :section
|
6
|
+
|
7
|
+
named_scope :of_type, lambda{|types| {:conditions => ["section_nodes.node_type IN (?)", types]}}
|
8
|
+
|
9
|
+
def visible?
|
10
|
+
return false unless node
|
11
|
+
return false if(node.respond_to?(:hidden?) && node.hidden?)
|
12
|
+
return false if(node.respond_to?(:archived?) && node.archived?)
|
13
|
+
return false if(node.respond_to?(:published?) && !node.published?)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def orphaned?
|
18
|
+
!node || (node.class.uses_soft_delete? && node.deleted?)
|
19
|
+
end
|
20
|
+
|
21
|
+
#Is this node a section
|
22
|
+
def section?
|
23
|
+
node_type == 'Section'
|
24
|
+
end
|
25
|
+
|
26
|
+
#Is this node a page
|
27
|
+
def page?
|
28
|
+
node_type == 'Page'
|
29
|
+
end
|
30
|
+
|
31
|
+
def move_to(sec, pos)
|
32
|
+
#logger.info "Moving Section Node ##{id} to Section ##{sec.id} Position #{pos}"
|
33
|
+
transaction do
|
34
|
+
if section != sec
|
35
|
+
remove_from_list
|
36
|
+
self.section = sec
|
37
|
+
save
|
38
|
+
end
|
39
|
+
|
40
|
+
if pos < 0
|
41
|
+
pos = 0
|
42
|
+
else
|
43
|
+
#This helps prevent the position from getting out of whack
|
44
|
+
#If you pass in a really high number for position,
|
45
|
+
#this just corrects it to the right number
|
46
|
+
node_count = SectionNode.count(:conditions => {:section_id => section_id})
|
47
|
+
pos = node_count if pos > node_count
|
48
|
+
end
|
49
|
+
|
50
|
+
insert_at_position(pos)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def move_before(section_node)
|
55
|
+
if section == section_node.section && position < section_node.position
|
56
|
+
pos = section_node.position - 1
|
57
|
+
else
|
58
|
+
pos = section_node.position
|
59
|
+
end
|
60
|
+
move_to(section_node.section, pos)
|
61
|
+
end
|
62
|
+
|
63
|
+
def move_after(section_node)
|
64
|
+
if section == section_node.section && position < section_node.position
|
65
|
+
pos = section_node.position
|
66
|
+
else
|
67
|
+
pos = section_node.position + 1
|
68
|
+
end
|
69
|
+
move_to(section_node.section, pos)
|
70
|
+
end
|
71
|
+
|
72
|
+
def move_to_beginning(sec)
|
73
|
+
move_to(sec, 0)
|
74
|
+
end
|
75
|
+
|
76
|
+
def move_to_end(sec)
|
77
|
+
#1.0/0 == Infinity
|
78
|
+
move_to(sec, 1.0/0)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ancestors()
|
82
|
+
ancestors = []
|
83
|
+
fn = lambda do |sn|
|
84
|
+
ancestors << sn.section
|
85
|
+
if sn.section && !sn.section.root?
|
86
|
+
fn.call(sn.section.node)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
fn.call(self)
|
90
|
+
ancestors.reverse
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
data/app/models/link.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class Link < SectionNode
|
2
|
+
#acts_as_content_block :connectable => false
|
3
|
+
|
4
|
+
named_scope :named, lambda{|name| {:conditions => ['links.name = ?', name]}}
|
5
|
+
|
6
|
+
# has_one :section_node, :as => :node, :dependent => :destroy
|
7
|
+
is_versioned :version_foreign_key => :ancestry_section_node_id
|
8
|
+
|
9
|
+
validates_presence_of :name
|
10
|
+
|
11
|
+
def section_id
|
12
|
+
self.parent_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def section
|
16
|
+
parent
|
17
|
+
end
|
18
|
+
|
19
|
+
def section_id=(sec_id)
|
20
|
+
parent_id = sec_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def section=(sec)
|
24
|
+
self.parent = sec
|
25
|
+
end
|
26
|
+
|
27
|
+
#needed by menu_helper
|
28
|
+
def path
|
29
|
+
url
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/app/models/page.rb
ADDED
@@ -0,0 +1,307 @@
|
|
1
|
+
class Page < SectionNode
|
2
|
+
|
3
|
+
is_archivable
|
4
|
+
flush_cache_on_change
|
5
|
+
is_hideable
|
6
|
+
is_publishable
|
7
|
+
uses_soft_delete
|
8
|
+
is_userstamped
|
9
|
+
#is_versioned
|
10
|
+
#is_versioned :version_foreign_key => :ancestry_section_node_id
|
11
|
+
|
12
|
+
has_many :connectors, :order => "connectors.container, connectors.position"
|
13
|
+
has_many :page_routes
|
14
|
+
|
15
|
+
named_scope :named, lambda{|name| {:conditions => ['pages.name = ?', name]}}
|
16
|
+
named_scope :with_path, lambda{|path| {:conditions => ['pages.path = ?', path]}}
|
17
|
+
|
18
|
+
is_versioned :version_foreign_key => :ancestry_section_node_id
|
19
|
+
|
20
|
+
# This scope will accept a connectable object or a Hash. The Hash is expect to have
|
21
|
+
# a value for the key :connectable, which is the connectable object, and possibly
|
22
|
+
# a value for the key :version. The Hash contains a versioned connectable object,
|
23
|
+
# it will use the value in :version if present, otherwise it will use the version
|
24
|
+
# of the object. In either case of a connectable object or a Hash, if the object
|
25
|
+
# is not versioned, no version will be used
|
26
|
+
named_scope :connected_to, lambda { |b|
|
27
|
+
if b.is_a?(Hash)
|
28
|
+
obj = b[:connectable]
|
29
|
+
if obj.class.versioned?
|
30
|
+
ver = b[:version] ? b[:version] : obj.version
|
31
|
+
else
|
32
|
+
ver = nil
|
33
|
+
end
|
34
|
+
else
|
35
|
+
obj = b
|
36
|
+
ver = obj.class.versioned? ? obj.version : nil
|
37
|
+
end
|
38
|
+
|
39
|
+
if ver
|
40
|
+
{ :include => :connectors,
|
41
|
+
:conditions => ['connectors.connectable_id = ? and connectors.connectable_type = ? and connectors.connectable_version = ?', obj.id, obj.class.base_class.name, ver] }
|
42
|
+
else
|
43
|
+
{ :include => :connectors,
|
44
|
+
:conditions => ['connectors.connectable_id = ? and connectors.connectable_type = ?', obj.id, obj.class.base_class.name] }
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
#has_one :section_node, :as => :node, :dependent => :destroy
|
49
|
+
|
50
|
+
has_many :tasks
|
51
|
+
|
52
|
+
before_validation :append_leading_slash_to_path
|
53
|
+
before_destroy :delete_connectors
|
54
|
+
|
55
|
+
validates_presence_of :name, :path
|
56
|
+
validates_uniqueness_of :path
|
57
|
+
validate :path_not_reserved
|
58
|
+
|
59
|
+
def after_build_new_version(new_version)
|
60
|
+
copy_connectors(
|
61
|
+
:from_version_number => @copy_connectors_from_version || (new_version.version - 1),
|
62
|
+
:to_version_number => new_version.version
|
63
|
+
)
|
64
|
+
@copy_connectors_from_version = nil
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
# Publish all
|
69
|
+
def after_publish
|
70
|
+
self.reload # Get's the correct version number loaded
|
71
|
+
self.connectors.for_page_version(self.version).all(:order => "position").each do |c|
|
72
|
+
if c.connectable_type.constantize.publishable? && con = c.connectable
|
73
|
+
con.publish
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def copy_connectors(options={})
|
79
|
+
connectors.for_page_version(options[:from_version_number]).all(:order => "connectors.container, connectors.position").each do |c|
|
80
|
+
# The connector won't have a connectable if it has been deleted
|
81
|
+
# Also need to see if the draft has been deleted,
|
82
|
+
# in which case we are in the process of deleting it
|
83
|
+
if c.should_be_copied?
|
84
|
+
connectable = c.connectable_type.constantize.versioned? ? c.connectable.as_of_version(c.connectable_version) : c.connectable
|
85
|
+
|
86
|
+
#If we are copying connectors from a previous version, that means we are reverting this page,
|
87
|
+
#in which case we should create a new version of the block, and connect this page to that block
|
88
|
+
if @copy_connectors_from_version && connectable.class.versioned? && (connectable.version != connectable.draft.version)
|
89
|
+
connectable = connectable.class.find(connectable.id)
|
90
|
+
connectable.updated_by_page = self
|
91
|
+
connectable.revert_to(c.connectable_version)
|
92
|
+
end
|
93
|
+
|
94
|
+
new_connector = connectors.build(
|
95
|
+
:page_version => options[:to_version_number],
|
96
|
+
:connectable => connectable,
|
97
|
+
:connectable_version => connectable.class.versioned? ? connectable.version : nil,
|
98
|
+
:container => c.container,
|
99
|
+
:position => c.position
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_connector(connectable, container)
|
107
|
+
transaction do
|
108
|
+
raise "Connectable is nil" unless connectable
|
109
|
+
raise "Container is required" if container.blank?
|
110
|
+
update_attributes(
|
111
|
+
:version_comment => "#{connectable} was added to the '#{container}' container",
|
112
|
+
:publish_on_save => (
|
113
|
+
published? &&
|
114
|
+
connectable.connected_page &&
|
115
|
+
(connectable.class.publishable? ? connectable.published? : true)))
|
116
|
+
connectors.create(
|
117
|
+
:page_version => draft.version,
|
118
|
+
:connectable => connectable,
|
119
|
+
:connectable_version => connectable.class.versioned? ? connectable.version : nil,
|
120
|
+
:container => container)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def move_connector(connector, direction)
|
125
|
+
transaction do
|
126
|
+
raise "Connector is nil" unless connector
|
127
|
+
raise "Direction is nil" unless direction
|
128
|
+
orientation = direction[/_/] ? "#{direction.sub('_', ' the ')} of" : "#{direction} within"
|
129
|
+
update_attributes(:version_comment => "#{connector.connectable} was moved #{orientation} the '#{connector.container}' container")
|
130
|
+
connectors.for_page_version(draft.version).like(connector).first.send("move_#{direction}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
%w(up down to_top to_bottom).each do |d|
|
135
|
+
define_method("move_connector_#{d}") do |connector|
|
136
|
+
move_connector(connector, d)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def remove_connector(connector)
|
141
|
+
transaction do
|
142
|
+
raise "Connector is nil" unless connector
|
143
|
+
update_attributes(:version_comment => "#{connector.connectable} was removed from the '#{connector.container}' container")
|
144
|
+
|
145
|
+
#The logic of this is to go ahead and let the container get copied forward, then delete the new connector
|
146
|
+
if new_connector = connectors.for_page_version(draft.version).like(connector).first
|
147
|
+
new_connector.destroy
|
148
|
+
else
|
149
|
+
raise "Error occurred while trying to remove connector #{connector.id}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def delete_connectors
|
155
|
+
connectors.for_page_version(version).all.each{|c| c.destroy }
|
156
|
+
end
|
157
|
+
|
158
|
+
#This is done to let copy_connectors know which version to pull from
|
159
|
+
#copy_connectors will get called later as an after_update callback
|
160
|
+
def revert_to(version)
|
161
|
+
@copy_connectors_from_version = version
|
162
|
+
super(version)
|
163
|
+
end
|
164
|
+
|
165
|
+
def file_size
|
166
|
+
"?"
|
167
|
+
end
|
168
|
+
|
169
|
+
def section_id
|
170
|
+
section ? section.id : nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def section
|
174
|
+
section_node ? section_node.section : nil
|
175
|
+
end
|
176
|
+
|
177
|
+
def section_id=(sec_id)
|
178
|
+
self.section = Section.find(sec_id)
|
179
|
+
end
|
180
|
+
|
181
|
+
def section=(sec)
|
182
|
+
if section_node
|
183
|
+
section_node.move_to_end(sec)
|
184
|
+
else
|
185
|
+
build_section_node(:node => self, :section => sec)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# moved to section
|
190
|
+
# def public?
|
191
|
+
# section ? section.public? : false
|
192
|
+
# end
|
193
|
+
|
194
|
+
def page_title
|
195
|
+
title.blank? ? name : title
|
196
|
+
end
|
197
|
+
|
198
|
+
def append_leading_slash_to_path
|
199
|
+
if path.blank?
|
200
|
+
self.path = "/"
|
201
|
+
elsif path[0,1] != "/"
|
202
|
+
self.path = "/#{path}"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def path_not_reserved
|
207
|
+
if Cms.reserved_paths.include?(path)
|
208
|
+
errors.add(:path, "is invalid, '#{path}' a reserved path")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def layout
|
213
|
+
template_file_name && "templates/#{template_file_name.split('.').first}"
|
214
|
+
end
|
215
|
+
|
216
|
+
# This will be nil if it is a file system based template
|
217
|
+
def template
|
218
|
+
PageTemplate.find_by_file_name(template_file_name)
|
219
|
+
end
|
220
|
+
|
221
|
+
def template_name
|
222
|
+
template_file_name && PageTemplate.display_name(template_file_name)
|
223
|
+
end
|
224
|
+
|
225
|
+
def ancestors
|
226
|
+
section_node.ancestors
|
227
|
+
end
|
228
|
+
|
229
|
+
def in_section?(section_or_section_name)
|
230
|
+
sec = section_or_section_name.is_a?(String) ?
|
231
|
+
Section.first(:conditions => {:name => section_or_section_name}) :
|
232
|
+
section_or_section_name
|
233
|
+
fn = lambda{|s| s ? (s == sec || fn.call(s.parent)) : false}
|
234
|
+
fn.call(section)
|
235
|
+
end
|
236
|
+
|
237
|
+
#Returns true if the block attached to each connector in the given container are published
|
238
|
+
def container_published?(container)
|
239
|
+
connectors.for_page_version(draft.version).in_container(container.to_s).all? do |c|
|
240
|
+
c.connectable_type.constantize.publishable? ? c.connectable.live? : true
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Returns the number of connectables in the given container for this version of this page
|
245
|
+
def connectable_count_for_container(container)
|
246
|
+
connectors.for_page_version(version).in_container(container.to_s).count
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.find_live_by_path(path)
|
250
|
+
published.not_archived.first(:conditions => {:path => path})
|
251
|
+
end
|
252
|
+
|
253
|
+
def name_with_section_path
|
254
|
+
a = ancestors
|
255
|
+
(a[1..a.size].map{|a| a.name} + [name]).join(" / ")
|
256
|
+
end
|
257
|
+
|
258
|
+
# This will return the "top level section" for a page, which is the section directly
|
259
|
+
# below the root (a.k.a My Site) that this page is in. If this page is in root,
|
260
|
+
# then this will return root.
|
261
|
+
def top_level_section
|
262
|
+
a = ancestors
|
263
|
+
(a.size > 0 && ancestors[1]) ? ancestors[1] : Section.root.first
|
264
|
+
end
|
265
|
+
|
266
|
+
def current_task
|
267
|
+
tasks.incomplete.first
|
268
|
+
end
|
269
|
+
|
270
|
+
def assigned_to
|
271
|
+
current_task ? current_task.assigned_to : nil
|
272
|
+
end
|
273
|
+
|
274
|
+
def assigned_to?(user)
|
275
|
+
assigned_to == user
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
|
280
|
+
######### proxy ###########
|
281
|
+
|
282
|
+
|
283
|
+
def section_id
|
284
|
+
self.parent_id
|
285
|
+
end
|
286
|
+
|
287
|
+
def section
|
288
|
+
self.parent
|
289
|
+
end
|
290
|
+
|
291
|
+
def section_id=(sec_id)
|
292
|
+
self.parent_id = sec_id
|
293
|
+
end
|
294
|
+
|
295
|
+
def section=(sec)
|
296
|
+
self.parent = sec
|
297
|
+
end
|
298
|
+
|
299
|
+
def status
|
300
|
+
"asd" #public? ? :unlocked : :locked
|
301
|
+
end
|
302
|
+
|
303
|
+
def self.versioned_columns
|
304
|
+
@versioned_columns ||= (self.new.attributes.keys -
|
305
|
+
(%w[ancestry lock_version position version_comment created_at updated_at created_by_id updated_by_id type] + [version_foreign_key]))
|
306
|
+
end
|
307
|
+
end
|