OSDN Git Service

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