OSDN Git Service

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