OSDN Git Service

t#31779:element lib
[pettanr/pettanr.git] / app / models / panel.rb
1 #コマ
2 class Panel < ActiveRecord::Base
3   belongs_to :author
4   belongs_to :resource_picture
5   has_many :stories
6   has_many :panel_pictures, :dependent => :destroy
7   has_many :speech_balloons, :dependent => :destroy
8   has_many :ground_pictures, :dependent => :destroy
9   has_many :ground_colors, :dependent => :destroy
10   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
11   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
12   accepts_nested_attributes_for :ground_pictures, :allow_destroy => true
13   accepts_nested_attributes_for :ground_colors, :allow_destroy => true
14
15   validates :width, :presence => true, :numericality => true, :natural_number => true
16   validates :height, :presence => true, :numericality => true, :natural_number => true
17   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
18   validates :x, :numericality => {:allow_blank => true}
19   validates :y, :numericality => {:allow_blank => true}
20   validates :z, :numericality => {:allow_blank => true, :greater_than => 0}
21   validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
22   validates :publish, :presence => true, :numericality => true
23   
24   before_validation :valid_encode
25   
26   def valid_encode
27     ['caption'].each do |a|
28       next if attributes[a] == nil
29       raise Pettanr::BadRequest unless attributes[a].valid_encoding?
30     end
31   end
32   
33   def self.each_element_class_names
34     Pettanr::Application.elements.each do |k, n|
35       yield k
36     end
37   end
38   
39   def self.class_name_to_class k
40     Object.const_get k
41   end
42   
43   def self.each_element_classes
44     self.each_element_class_names do |k|
45       e = self.class_name_to_class k
46       yield e
47     end
48   end
49   
50   def elements_by_class_name class_name
51     self.__send__ class_name.tableize
52   end
53   
54   def supply_default
55     self.border = 2
56     self.publish = 0
57   end
58   
59   def overwrite au
60     self.author_id = au.id
61   end
62   
63   def own? roles
64     roles = [roles] unless roles.respond_to?(:each)
65     au = Panel.get_author_from_roles roles
66     return false unless au
67     self.author_id == au.id
68   end
69   
70   def visible? roles
71     if MagicNumber['run_mode'] == 0
72       return false unless guest_role_check(roles)
73     else
74       return false unless reader_role_check(roles)
75     end
76     return true if self.own?(roles)
77     self.publish?
78   end
79   
80   def usable? au
81     visible? au
82   end
83   
84   def publish?
85     self.publish > 0
86   end
87   
88   def tag_id
89     'panel' + self.tag_panel_id
90   end
91   
92   def tag_panel_id
93     self.new_record? ? '0' : self.id.to_s
94   end
95   
96   def field_tag_id f
97     self.tag_id + f.to_s
98   end
99   
100   def field_tree f
101     'panels-' + tag_panel_id + '-' + f.to_s
102   end
103   
104   def self.default_page_size
105     25
106   end
107   
108   def self.max_page_size
109     100
110   end
111   
112   def self.page prm = nil
113     page = prm.to_i
114     page = 1 if page < 1
115     page
116   end
117   
118   def self.page_size prm = self.default_page_size
119     page_size = prm.to_i
120     page_size = self.max_page_size if page_size > self.max_page_size
121     page_size = self.default_page_size if page_size < 1
122     page_size
123   end
124   
125   def self.list_where
126     'panels.publish > 0'
127   end
128   
129   def self.mylist_where au
130     ['panels.author_id = ?', au.id]
131   end
132   
133   def self.himlist_where au
134     ['panels.author_id = ? and panels.publish > 0', au.id]
135   end
136   
137   def self.list page = 1, page_size = self.default_page_size
138     Panel.where(self.list_where()).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
139   end
140   
141   def self.mylist au, page = 1, page_size = Author.default_panel_page_size
142     Panel.where(self.mylist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
143   end
144   
145   def self.himlist au, page = 1, page_size = Author.default_panel_page_size
146     Panel.where(self.himlist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
147   end
148   
149   def self.list_paginate page = 1, page_size = self.default_page_size
150     Kaminari.paginate_array(Array.new(Panel.where(self.list_where()).count, nil)).page(page).per(page_size)
151   end
152   
153   def self.mylist_paginate au, page = 1, page_size = Author.default_panel_page_size
154     Kaminari.paginate_array(Array.new(Panel.where(self.mylist_where(au)).count, nil)).page(page).per(page_size)
155   end
156   
157   def self.himlist_paginate au, page = 1, page_size = Author.default_panel_page_size
158     Kaminari.paginate_array(Array.new(Panel.where(self.himlist_where(au)).count, nil)).page(page).per(page_size)
159   end
160   
161   def self.list_opt
162     r = {
163       :author => {}
164     }
165     self.each_element_classes do |e|
166       r.merge!(e.list_opt_for_panel)
167     end
168     r
169   end
170   
171   def self.show rid, roles
172     opt = {}
173     opt.merge!(Panel.show_opt)
174     res = Panel.find(rid, opt)
175     raise ActiveRecord::Forbidden unless res.visible?(roles)
176     res
177   end
178   
179   def self.edit rid, au
180     opt = {}
181     opt.merge!(Panel.show_opt)
182     res = Panel.find(rid, opt)
183     raise ActiveRecord::Forbidden unless res.own?(au)
184     res
185   end
186   
187   def self.show_opt
188     r = {
189       :author => {}
190     }
191     self.each_element_classes do |e|
192       r.merge!(e.show_opt_for_panel)
193     end
194     {:include => r}
195   end
196   
197   def parts_element
198     r = []
199     self.class.each_element_class_names do |k|
200       r += (self.elements_by_class_name(k) || [])
201     end
202     r
203   end
204   
205   def zorderd_elements
206     res = []
207     self.parts_element.each do |e|
208       res[e.z-1] = e
209     end
210     res
211   end
212   
213   def panel_elements
214     res = []
215     self.parts_element.each do |e|
216       res[e.t] = e
217     end
218     res
219   end
220   
221   def elements
222     self.panel_elements.map {|e|
223       #(-_-;)<... kore wa hidoi
224       JSON.parse e.to_json({:include => e.class.json_opt_for_panel})
225     }
226   end
227   
228   def panel_elements_as_json
229     self.to_json({:include => {:author => {}}, :methods => :elements})
230   end
231   
232   def self.list_as_json_text ary
233     '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']'
234   end
235   
236   def new_t
237     self.panel_elements.size
238   end
239   
240   def new_z
241     self.panel_elements.size + 1
242   end
243   
244   def scenario
245     panel_elements.map { |e|
246       e.scenario
247     }.join
248   end
249   
250   def plain_scenario
251     panel_elements.map { |e|
252       e.plain_scenario
253     }.join
254   end
255   
256   def licensed_pictures
257     r = {}
258     self.panel_elements.each do |elm|
259       next unless elm.class.has_picture?
260       r[elm.picture_id] = elm.picture unless r[elm.picture_id]
261     end
262     r
263   end
264   
265   def self.visible_count
266     Panel.count
267   end
268   
269   def self.collect_element_value elements, name
270     elements.map {|e|
271       e.map {|o|
272         if o['_destroy'] or o[:_destroy]
273           nil
274         else
275           o[name]
276         end
277       }.compact
278     }.flatten
279   end
280   
281   def self.validate_serial ary, offset = 0
282     i = offset
283     ary.compact.sort.each do |n|
284       break false unless n == i
285       i += 1
286     end
287     ary.compact.size == i - offset
288   end
289   
290   def self.validate_element_serial elements, name, offset = 0
291     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
292   end
293   
294   def self.validate_elements_serial c
295     c.map {|conf|
296       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
297     }.compact.empty?
298   end
299   
300   def validate_serial_list
301     l = []
302     self.class.each_element_class_names do |k|
303       l << self.elements_by_class_name(k)
304     end
305     [
306       {:elements => l, :name => :t, :offset => 0}, 
307       {:elements => l, :name => :z, :offset => 1}
308     ]
309   end
310   def validate_child
311 #    r1 = Panel.validate_elements_id validate_id_list
312     Panel.validate_elements_serial validate_serial_list
313   end
314   
315   def store attr, au
316     if attr == false
317       self.errors.add :base, I18n.t('errors.invalid_json')
318       return false
319     end
320     self.attributes = attr
321     self.overwrite au
322     res = false
323     Panel.transaction do
324       res = self.save
325       unless validate_child
326         res = false
327         self.errors.add :base, I18n.t('errors.invalid_t')
328         raise ActiveRecord::Rollback
329       end
330     end
331     res
332   end
333   
334   def remove_element target, au
335     ct = target.t
336     cz = target.z
337     panel_attributes = {}
338     self.panel_elements.each do |elm|
339       attr = elm.attributes
340       if elm == target
341         attr['_destroy'] = true
342       end
343       if elm.t > ct
344         attr['t']  -= 1 
345       end
346       if elm.z > cz
347         attr['z']  -= 1 
348       end
349       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
350       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
351     end
352     self.store(panel_attributes, au)
353   end
354   
355   def destroy_with_elements
356     res = false
357     Panel.transaction do
358       self.parts_element.each do |element|
359         raise ActiveRecord::Rollback unless element.destroy
360       end
361       raise ActiveRecord::Rollback unless self.destroy
362       res = true
363     end
364     res
365   end
366   
367   def copy
368     attr = self.copy_attributes
369     attr.merge! PanelPicture.panelize(self.panel_pictures.map {|elm|  elm.copy_attributes})
370     attr.merge! SpeechBalloon.panelize(self.speech_balloons.map {|elm|  elm.copy_attributes})
371     attr.merge! GroundPicture.panelize(self.ground_pictures.map {|elm|  elm.copy_attributes})
372     attr.merge! GroundColor.panelize(self.ground_colors.map {|elm|  elm.copy_attributes})
373     p attr
374     attr
375   end
376   
377   def copy_attributes
378     r = self.attributes
379     r.delete 'id'
380     r.delete 'author_id'
381     r.delete 'created_at'
382     r.delete 'updated_at'
383     r
384   end
385   
386   def self.panelize panel
387     attr = panel.attributes
388     attr.delete 'id'
389     attr
390   end
391   
392   
393 =begin
394   def self.validate_id ary, pid
395     ary.map {|v|
396       if pid
397         (v == pid or v == nil) ? nil : false
398       else
399         v ? false : nil
400       end
401     }.compact.empty?
402   end
403   
404   def self.validate_element_id elements, name, pid
405     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
406   end
407   
408   def self.validate_elements_id c
409     c.map {|conf|
410       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
411     }.compact.empty?
412   end
413   
414   def validate_id_list
415     r = self.speech_balloons.map {|sb|
416       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
417     }
418     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
419     r
420   end
421 =end
422   
423 end