OSDN Git Service

temp
[pettanr/pettanr.git] / app / models / panel.rb
1 #コマ
2 class Panel < Pettanr::Item
3   belongs_to :author
4   has_many :scroll_panels
5   has_many :sheet_panels
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 :author_id, :presence => true, :numericality => true, :existence => {:both => false}
19   validates :publish, :presence => true, :numericality => true
20   
21   def self.singular
22     'Panel'
23   end
24   
25   def self.plural
26     'Panels'
27   end
28   
29   def self.owner_type
30     :author
31   end
32   
33   def self.valid_encode_columns
34     super.merge ['caption']
35   end
36   
37   def self.each_element_class_names
38     Pettanr::Application.manifest.system_resources.elements.each do |k, n|
39       yield k
40     end
41   end
42   
43   def self.class_name_to_class k
44     Object.const_get k
45   end
46   
47   def self.each_element_classes
48     self.each_element_class_names do |k|
49       e = self.class_name_to_class k
50       yield e
51     end
52   end
53   
54   def elements_by_class_name class_name
55     self.__send__ class_name.tableize
56   end
57   
58   def supply_default
59     self.border = 2
60     self.publish = 0
61   end
62   
63   def overwrite au
64     self.author_id = au.id
65   end
66   
67   def own? roles
68     roles = [roles] unless roles.respond_to?(:each)
69     au = Panel.get_author_from_roles roles
70     return false unless au
71     self.author_id == au.id
72   end
73   
74   def visible? roles
75     if MagicNumber['run_mode'] == 0
76       return false unless guest_role_check(roles)
77     else
78       return false unless reader_role_check(roles)
79     end
80     return true if self.own?(roles)
81     return true if self.new_record?
82     self.publish?
83   end
84   
85   def usable? au
86     visible? au
87   end
88   
89   def publish?
90     self.publish > 0
91   end
92   
93   def tag_id c = nil
94     'panel' + self.tag_panel_id + c.to_s
95   end
96   
97   def tag_panel_id
98     self.new_record? ? '0' : self.id.to_s
99   end
100   
101   def field_tag_id f
102     self.tag_id + f.to_s
103   end
104   
105   def tag_attributes column = nil, opt = {}
106     {
107       :id => self.field_tag_id(column), :panel_id => self.tag_panel_id
108     }.merge(opt)
109   end
110   
111   def select_tag_attributes(selected, column, opt = {})
112     [
113       :last, :first, 
114       {:html => {:selected => selected}}, 
115       self.field_tag_attributes(column, opt)
116     ]
117   end
118   
119   def field_tag_attributes column, opt = {}
120     self.tag_attributes(column).merge(
121       {:column => column}
122     ).merge(opt)
123   end
124   
125   def tag_attr column = nil, opt = {}
126     self.tag_attributes(column, opt).to_attr
127   end
128   
129   def field_tag_attr column, no_attr, opt = {}
130     self.field_tag_attributes(column, no_attr, opt).to_attr
131   end
132   
133     def render_count
134       @render_count ||= 1
135     end
136     
137     def rendered
138       @render_count = render_count + 1
139     end
140     
141   def self.default_page_size
142     25
143   end
144   
145   def self.max_page_size
146     100
147   end
148   
149   def self.page prm = nil
150     page = prm.to_i
151     page = 1 if page < 1
152     page
153   end
154   
155   def self.page_size prm = self.default_page_size
156     page_size = prm.to_i
157     page_size = self.max_page_size if page_size > self.max_page_size
158     page_size = self.default_page_size if page_size < 1
159     page_size
160   end
161   
162   def self.list_order
163     'panels.updated_at desc'
164   end
165   
166   def self.list_where
167     'panels.publish > 0'
168   end
169   
170   def self.mylist_where au
171     ['panels.author_id = ?', au.id]
172   end
173   
174   def self.himlist_where au
175     ['panels.author_id = ? and panels.publish > 0', au.id]
176   end
177   
178   def self.list page = 1, page_size = self.default_page_size
179     Panel.where(self.list_where()).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
180   end
181   
182   def self.mylist au, page = 1, page_size = Author.default_panel_page_size
183     Panel.where(self.mylist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
184   end
185   
186   def self.himlist au, page = 1, page_size = Author.default_panel_page_size
187     Panel.where(self.himlist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
188   end
189   
190   def self.list_paginate page = 1, page_size = self.default_page_size
191     Kaminari.paginate_array(Array.new(Panel.where(self.list_where()).count, nil)).page(page).per(page_size)
192   end
193   
194   def self.mylist_paginate au, page = 1, page_size = Author.default_panel_page_size
195     Kaminari.paginate_array(Array.new(Panel.where(self.mylist_where(au)).count, nil)).page(page).per(page_size)
196   end
197   
198   def self.himlist_paginate au, page = 1, page_size = Author.default_panel_page_size
199     Kaminari.paginate_array(Array.new(Panel.where(self.himlist_where(au)).count, nil)).page(page).per(page_size)
200   end
201   
202   def self.list_by_scroll scroll_id, roles, page = 1, page_size = self.default_page_size
203     self.where(ScrollPanel.list_by_scroll_where(scroll_id)).includes(
204       {:scroll_panels => {}}
205     ).order('scroll_panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
206   end
207   
208   def self.list_by_sheet sheet_id, roles, page = 1, page_size = self.default_page_size
209     self.where(SheetPanel.list_by_sheet_where(sheet_id)).includes(
210       {:sheet_panels => {}}
211     ).order('sheet_panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
212   end
213   
214   def self.list_by_speech_balloon_template speech_balloon_template_id, roles, page = 1, page_size = self.default_page_size
215     self.where(SpeechBalloon.list_by_speech_balloon_template_where(speech_balloon_template_id)).includes(
216       {:speech_balloons => {}}
217     ).order('speech_balloons.updated_at desc').offset((page -1) * page_size).limit(page_size)
218   end
219   
220   def self.list_by_author_where author_id
221     ['panels.author_id = ?', author_id]
222   end
223   
224   def self.list_by_author author_id, roles, page = 1, page_size = self.default_page_size
225     self.where(self.list_by_author_where(author_id)).includes(self.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size)
226   end
227   
228   def self.list_opt
229     r = {
230       :author => {}
231     }
232     self.each_element_classes do |e|
233       r.merge!(e.list_opt_for_panel)
234     end
235     r
236   end
237   
238   def self.show rid, roles
239     opt = {}
240     opt.merge!(Panel.show_opt)
241     res = Panel.find(rid, opt)
242     raise ActiveRecord::Forbidden unless res.visible?(roles)
243     res
244   end
245   
246   def self.edit rid, au
247     opt = {}
248     opt.merge!(Panel.show_opt)
249     res = Panel.find(rid, opt)
250     raise ActiveRecord::Forbidden unless res.own?(au)
251     res
252   end
253   
254   def self.show_opt
255     r = {
256       :author => {}
257     }
258     self.each_element_classes do |e|
259       r.merge!(e.show_opt_for_panel)
260     end
261     {:include => r}
262   end
263   
264   def parts_element
265     r = []
266     self.class.each_element_class_names do |k|
267       r += (self.elements_by_class_name(k) || [])
268     end
269     r
270   end
271   
272   def zorderd_elements
273     res = []
274     self.parts_element.each do |e|
275       res[e.z-1] = e
276     end
277     res
278   end
279   
280   def panel_elements
281     res = []
282     self.parts_element.each do |e|
283       res[e.t] = e
284     end
285     res
286   end
287   
288   def elements
289     self.panel_elements.map {|e|
290       #(-_-;)<... kore wa hidoi
291       JSON.parse e.to_json({:include => e.class.json_opt_for_panel})
292     }
293   end
294   
295   def panel_elements_as_json
296     self.to_json({:include => {:author => {}}, :methods => :elements})
297   end
298   
299   def self.list_as_json_text ary
300     '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']'
301   end
302   
303   def new_t
304     self.panel_elements.size
305   end
306   
307   def new_z
308     self.panel_elements.size + 1
309   end
310   
311   def scenario
312     panel_elements.map { |e|
313       e.scenario
314     }.join
315   end
316   
317   def plain_scenario
318     panel_elements.map { |e|
319       e.plain_scenario
320     }.join
321   end
322   
323   def licensed_pictures
324     r = {}
325     self.panel_elements.each do |elm|
326       next unless elm.class.has_picture?
327       r[elm.picture_id] = elm.picture unless r[elm.picture_id]
328     end
329     r
330   end
331   
332   def self.visible_count
333     Panel.count
334   end
335   
336   def self.collect_element_value elements, name
337     elements.map {|e|
338       e.map {|o|
339         if o['_destroy'] or o[:_destroy]
340           nil
341         else
342           o[name]
343         end
344       }.compact
345     }.flatten
346   end
347   
348   def self.validate_serial ary, offset = 0
349     i = offset
350     ary.compact.sort.each do |n|
351       break false unless n == i
352       i += 1
353     end
354     ary.compact.size == i - offset
355   end
356   
357   def self.validate_element_serial elements, name, offset = 0
358     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
359   end
360   
361   def self.validate_elements_serial c
362     c.map {|conf|
363       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
364     }.compact.empty?
365   end
366   
367   def validate_serial_list
368     l = []
369     self.class.each_element_class_names do |k|
370       l << self.elements_by_class_name(k)
371     end
372     [
373       {:elements => l, :name => :t, :offset => 0}, 
374       {:elements => l, :name => :z, :offset => 1}
375     ]
376   end
377   def validate_child
378 #    r1 = Panel.validate_elements_id validate_id_list
379     Panel.validate_elements_serial validate_serial_list
380   end
381   
382   def boost
383     @new_element_index = 0
384     self.panel_elements.each do |elm|
385       if elm.new_record?
386         elm.new_index = @new_element_index
387         @new_element_index += 1
388       end
389     end
390   end 
391   
392   def store attr, au
393     if attr == false
394       self.errors.add :base, I18n.t('errors.invalid_json')
395       return false
396     end
397     self.attributes = attr
398     self.overwrite au
399     res = false
400     Panel.transaction do
401       self.panel_elements.each do |elm|
402         elm.new_panel = self
403         elm.boost
404       end
405 #self.publish = nil
406       res = self.save
407       unless validate_child
408         res = false
409         self.errors.add :base, I18n.t('errors.invalid_t')
410         raise ActiveRecord::Rollback
411       end
412     end
413     res
414   end
415   
416   def remove_element target, au
417     ct = target.t
418     cz = target.z
419     panel_attributes = {}
420     self.panel_elements.each do |elm|
421       attr = elm.attributes
422       if elm == target
423         attr['_destroy'] = true
424       end
425       if elm.t > ct
426         attr['t']  -= 1 
427       end
428       if elm.z > cz
429         attr['z']  -= 1 
430       end
431       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
432       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
433     end
434     self.store(panel_attributes, au)
435   end
436   
437   def destroy_with_elements
438     res = false
439     Panel.transaction do
440       self.parts_element.each do |element|
441         raise ActiveRecord::Rollback unless element.destroy
442       end
443       raise ActiveRecord::Rollback unless self.destroy
444       res = true
445     end
446     res
447   end
448   
449   def copy
450     attr = self.copy_attributes
451     Panel.each_element_class_names do |n|
452       attr.merge! Panel.class_name_to_class(n).panelize(self.elements_by_class_name(n).map {|elm|  elm.copy_attributes})
453     end
454     attr
455   end
456   
457   def copy_attributes
458     r = self.attributes
459     r.delete 'id'
460     r.delete 'author_id'
461     r.delete 'created_at'
462     r.delete 'updated_at'
463     r
464   end
465   
466   def self.panelize panel
467     attr = panel.attributes
468     attr.delete 'id'
469     attr
470   end
471   
472   
473 =begin
474   def self.validate_id ary, pid
475     ary.map {|v|
476       if pid
477         (v == pid or v == nil) ? nil : false
478       else
479         v ? false : nil
480       end
481     }.compact.empty?
482   end
483   
484   def self.validate_element_id elements, name, pid
485     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
486   end
487   
488   def self.validate_elements_id c
489     c.map {|conf|
490       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
491     }.compact.empty?
492   end
493   
494   def validate_id_list
495     r = self.speech_balloons.map {|sb|
496       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
497     }
498     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
499     r
500   end
501 =end
502   
503 end