OSDN Git Service

fix read permission for element
[pettanr/pettanr.git] / lib / peta / leaf.rb
1 module Peta
2   class Leaf < Content
3     self.abstract_class = true
4     
5     # Dynamic ClassMethods
6     
7     def self.load_manifest
8       super
9       # Class Methods
10       pm = Manifest.manifest.models[self.my_peta.parent_model_name].classify
11       define_singleton_method("parent_model") do 
12         pm
13       end
14       # Instance Methods
15     end
16     
17     def self.element?
18       true
19     end
20     
21     def self.root_model
22       self.parent_model
23     end
24     
25     def root
26       self.__send__ self.class.root_model.item_name
27     end
28     
29     def visible? operators
30       return false unless super
31       self.root.visible? operators
32     end
33     
34     def self.play_list_where cid
35       ['scroll_panels.scroll_id = ?', cid]
36     end
37     
38     def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size
39       ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit)
40     end
41     
42     def self.play_sheet_where sid
43       ['story_sheets.story_id = ?', sid]
44     end
45     
46     def self.play_sheet story, operators, page = 1
47       ss = StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).order('story_sheets.t').offset(page -1).limit(1).first
48       if ss 
49         if ss.sheet
50           Sheet.show(ss.sheet.id, operators)
51         else
52           nil
53         end
54       else
55         nil
56       end
57     end
58     
59     def self.play_paginate story, page
60       Kaminari.paginate_array(Array.new(StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).count, nil)).page(page).per(1)
61     end
62     
63     def self.new_t binder_id
64       r = ScrollPanel.max_t(binder_id)
65       r.blank? ? 0 : r.to_i + 1
66     end
67     
68     def self.max_t binder_id
69       self.class..maximum(:t, :conditions => ['scroll_id = ?', binder_id])
70     end
71     
72     def self.find_t binder_id, t
73       self.class.find(:first, :conditions => ['scroll_id = ? and t = ?', binder_id, t])
74     end
75     
76     def self.collect_t scroll_panel
77       r = self.class.find(:all, :conditions => ['scroll_id = ?', scroll_panel.scroll_id], :order => 't')
78       r.map {|sp| sp.t}
79     end
80     
81     def self.top_sheet story, author
82       StorySheet.play_list(story, author).first
83     end
84     
85     def self.collect_t story_sheet
86       r = StorySheet.find(:all, :conditions => ['story_id = ?', story_sheet.story_id], :order => 't')
87       r.map {|sp| sp.t}
88     end
89     
90     def self.serial? ary
91       i = 0
92       ary.compact.sort.each do |t|
93         break false unless t == i
94         i += 1
95       end
96       ary.compact.size == i
97     end
98     
99     def self.validate_t scroll_panel
100       ScrollPanel.serial?(ScrollPanel.collect_t(scroll_panel))
101     end
102     
103     def insert_shift
104       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and t >= ?', self.scroll_id, self.t])
105     end
106     
107     def lesser_shift old_t
108       self.t = 0 if self.t < 0
109       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and (t >= ? and t < ?)', self.scroll_id, self.t, old_t])
110     end
111     
112     def higher_shift old_t
113       nf = ScrollPanel.find_t(self.scroll_id, self.t)
114       max_t = ScrollPanel.max_t(self.scroll_id).to_i
115       self.t = max_t if self.t > max_t
116       ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ? and t <= ?)', self.scroll_id, old_t, self.t])
117     end
118     
119     def update_shift old_t
120       if self.t > old_t
121         higher_shift old_t
122       else
123         lesser_shift old_t
124       end
125     end
126     
127     def rotate old_t = nil
128       if self.new_record?
129         if self.t.blank?
130           self.t = ScrollPanel.new_t self.scroll_id
131         else
132           self.insert_shift
133         end
134       else
135         if self.t.blank?
136         else
137           self.update_shift old_t
138         end
139       end
140     end
141     
142     def allow? operators
143       return nil if self.scroll_id == nil or self.panel_id == nil
144       self.scroll.own?(operators) and self.panel.usable?(operators)
145     end
146     
147     def destroy_and_shorten
148       res = false
149       ScrollPanel.transaction do
150         ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ?)', self.scroll_id, self.t])
151         raise ActiveRecord::Rollback unless self.destroy
152         res = true
153       end
154       res
155     end
156     
157   end
158 end
159