OSDN Git Service

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