Commit 76e29aed97e98044fede7f4a280abc96b80d58a6
1 parent
f678092a
Exists in
staging
and in
12 other branches
concerns: move most lib files models concerns
Showing
55 changed files
with
841 additions
and
831 deletions
Show diff stats
app/mailers/mailing.rb
... | ... | @@ -2,7 +2,8 @@ require_dependency 'mailing_job' |
2 | 2 | |
3 | 3 | class Mailing < ApplicationRecord |
4 | 4 | |
5 | - acts_as_having_settings :field => :data | |
5 | + extend ActsAsHavingSettings::ClassMethods | |
6 | + acts_as_having_settings field: :data | |
6 | 7 | |
7 | 8 | attr_accessible :subject, :body, :data |
8 | 9 | ... | ... |
app/models/article.rb
... | ... | @@ -13,7 +13,9 @@ class Article < ApplicationRecord |
13 | 13 | :image_builder, :show_to_followers, :archived, |
14 | 14 | :author, :display_preview, :published_at, :person_followers |
15 | 15 | |
16 | + extend ActsAsHavingImage::ClassMethods | |
16 | 17 | acts_as_having_image |
18 | + | |
17 | 19 | include Noosfero::Plugin::HotSpot |
18 | 20 | |
19 | 21 | SEARCHABLE_FIELDS = { |
... | ... | @@ -91,7 +93,8 @@ class Article < ApplicationRecord |
91 | 93 | has_many :article_categorizations_including_virtual, :class_name => 'ArticleCategorization' |
92 | 94 | has_many :categories_including_virtual, :through => :article_categorizations_including_virtual, :source => :category |
93 | 95 | |
94 | - acts_as_having_settings :field => :setting | |
96 | + extend ActsAsHavingSettings::ClassMethods | |
97 | + acts_as_having_settings field: :setting | |
95 | 98 | |
96 | 99 | settings_items :display_hits, :type => :boolean, :default => true |
97 | 100 | settings_items :author_name, :type => :string, :default => "" |
... | ... | @@ -242,6 +245,7 @@ class Article < ApplicationRecord |
242 | 245 | acts_as_taggable |
243 | 246 | N_('Tag list') |
244 | 247 | |
248 | + extend ActsAsFilesystem::ActsMethods | |
245 | 249 | acts_as_filesystem |
246 | 250 | |
247 | 251 | acts_as_versioned | ... | ... |
app/models/block.rb
... | ... | @@ -17,6 +17,7 @@ class Block < ApplicationRecord |
17 | 17 | belongs_to :mirror_block, :class_name => "Block" |
18 | 18 | has_many :observers, :class_name => "Block", :foreign_key => "mirror_block_id" |
19 | 19 | |
20 | + extend ActsAsHavingSettings::ClassMethods | |
20 | 21 | acts_as_having_settings |
21 | 22 | |
22 | 23 | scope :enabled, -> { where :enabled => true } | ... | ... |
app/models/blog.rb
app/models/category.rb
... | ... | @@ -21,6 +21,7 @@ class Category < ApplicationRecord |
21 | 21 | |
22 | 22 | scope :on_level, -> parent { where :parent_id => parent } |
23 | 23 | |
24 | + extend ActsAsFilesystem::ActsMethods | |
24 | 25 | acts_as_filesystem |
25 | 26 | |
26 | 27 | has_many :article_categorizations |
... | ... | @@ -35,6 +36,7 @@ class Category < ApplicationRecord |
35 | 36 | has_many :people, :through => :profile_categorizations, :source => :profile, :class_name => 'Person' |
36 | 37 | has_many :communities, :through => :profile_categorizations, :source => :profile, :class_name => 'Community' |
37 | 38 | |
39 | + extend ActsAsHavingImage::ClassMethods | |
38 | 40 | acts_as_having_image |
39 | 41 | |
40 | 42 | before_save :normalize_display_color | ... | ... |
app/models/comment.rb
... | ... | @@ -0,0 +1,265 @@ |
1 | +module ActsAsFilesystem | |
2 | + | |
3 | + module ActsMethods | |
4 | + | |
5 | + # Declares the ActiveRecord model to acts like a filesystem: objects are | |
6 | + # arranged in a tree (liks acts_as_tree), and . The underlying table must | |
7 | + # have the following fields: | |
8 | + # | |
9 | + # * name (+:string+) - the title of the object | |
10 | + # * slug (+:string+)- the title turned in a URL-friendly string (downcased, | |
11 | + # non-ascii chars transliterated into ascii, all sequences of | |
12 | + # non-alphanumericd characters changed into dashed) | |
13 | + # * path (+:text+)- stores the full path of the object (the full path of | |
14 | + # the parent, a "/" and the slug of the object) | |
15 | + # * children_count - a cache of the number of children elements. | |
16 | + def acts_as_filesystem | |
17 | + # a filesystem is a tree | |
18 | + acts_as_tree :counter_cache => :children_count | |
19 | + | |
20 | + extend ClassMethods | |
21 | + include InstanceMethods | |
22 | + if self.has_path? | |
23 | + after_update :update_children_path | |
24 | + before_create :set_path | |
25 | + include InstanceMethods::PathMethods | |
26 | + end | |
27 | + | |
28 | + before_save :set_ancestry | |
29 | + end | |
30 | + | |
31 | + end | |
32 | + | |
33 | + module ClassMethods | |
34 | + | |
35 | + def build_ancestry(parent_id = nil, ancestry = '') | |
36 | + ActiveRecord::Base.transaction do | |
37 | + self.base_class.where(parent_id: parent_id).each do |node| | |
38 | + node.update_column :ancestry, ancestry | |
39 | + | |
40 | + build_ancestry node.id, (ancestry.empty? ? "#{node.formatted_ancestry_id}" : | |
41 | + "#{ancestry}#{node.ancestry_sep}#{node.formatted_ancestry_id}") | |
42 | + end | |
43 | + end | |
44 | + | |
45 | + #raise "Couldn't reach and set ancestry on every record" if self.base_class.where('ancestry is null').count != 0 | |
46 | + end | |
47 | + | |
48 | + def has_path? | |
49 | + (['name', 'slug', 'path'] - self.column_names).blank? | |
50 | + end | |
51 | + | |
52 | + end | |
53 | + | |
54 | + module InstanceMethods | |
55 | + | |
56 | + def ancestry_column | |
57 | + 'ancestry' | |
58 | + end | |
59 | + def ancestry_sep | |
60 | + '.' | |
61 | + end | |
62 | + def has_ancestry? | |
63 | + self.class.column_names.include? self.ancestry_column | |
64 | + end | |
65 | + | |
66 | + def formatted_ancestry_id | |
67 | + "%010d" % self.id if self.id | |
68 | + end | |
69 | + | |
70 | + def ancestry | |
71 | + self[ancestry_column] | |
72 | + end | |
73 | + def ancestor_ids | |
74 | + return nil if !has_ancestry? or ancestry.nil? | |
75 | + @ancestor_ids ||= ancestry.split(ancestry_sep).map{ |id| id.to_i } | |
76 | + end | |
77 | + | |
78 | + def ancestry=(value) | |
79 | + self[ancestry_column] = value | |
80 | + end | |
81 | + def set_ancestry | |
82 | + return unless self.has_ancestry? | |
83 | + if self.ancestry.nil? or (new_record? or parent_id_changed?) or recalculate_path | |
84 | + self.ancestry = self.hierarchy(true)[0...-1].map{ |p| p.formatted_ancestry_id }.join(ancestry_sep) | |
85 | + end | |
86 | + end | |
87 | + | |
88 | + def descendents_options | |
89 | + ["#{self.ancestry_column} LIKE ?", "%#{self.formatted_ancestry_id}%"] | |
90 | + end | |
91 | + def descendents | |
92 | + self.class.where descendents_options | |
93 | + end | |
94 | + | |
95 | + # calculates the level of the record in the records hierarchy. Top-level | |
96 | + # records have level 0; the children of the top-level records have | |
97 | + # level 1; the children of records with level 1 have level 2, and so on. | |
98 | + # | |
99 | + # A level 0 | |
100 | + # / \ | |
101 | + # B C level 1 | |
102 | + # / \ / \ | |
103 | + # E F G H level 2 | |
104 | + # ... | |
105 | + def level | |
106 | + self.hierarchy.size - 1 | |
107 | + end | |
108 | + | |
109 | + # Is this record a top-level record? | |
110 | + def top_level? | |
111 | + self.parent.nil? | |
112 | + end | |
113 | + | |
114 | + # Is this record a leaf in the hierarchy tree of records? | |
115 | + # | |
116 | + # Being a leaf means that this record has no subrecord. | |
117 | + def leaf? | |
118 | + self.children.empty? | |
119 | + end | |
120 | + | |
121 | + def top_ancestor | |
122 | + if has_ancestry? and !ancestry.blank? | |
123 | + self.class.base_class.find_by id: self.top_ancestor_id | |
124 | + else | |
125 | + self.hierarchy.first | |
126 | + end | |
127 | + end | |
128 | + def top_ancestor_id | |
129 | + if has_ancestry? and !ancestry.nil? | |
130 | + self.ancestor_ids.first | |
131 | + else | |
132 | + self.hierarchy.first.id | |
133 | + end | |
134 | + end | |
135 | + | |
136 | + # returns the full hierarchy from the top-level item to this one. For | |
137 | + # example, if item1 has a children item2 and item2 has a children item3, | |
138 | + # then item3's hierarchy would be [item1, item2, item3]. | |
139 | + # | |
140 | + # If +reload+ is passed as +true+, then the hierarchy is reload (usefull | |
141 | + # when the ActiveRecord object was modified in some way, or just after | |
142 | + # changing parent) | |
143 | + def hierarchy(reload = false) | |
144 | + @hierarchy = nil if reload or recalculate_path | |
145 | + | |
146 | + if @hierarchy.nil? | |
147 | + @hierarchy = [] | |
148 | + | |
149 | + if !reload and !recalculate_path and ancestor_ids | |
150 | + objects = self.class.base_class.where(id: ancestor_ids) | |
151 | + ancestor_ids.each{ |id| @hierarchy << objects.find{ |t| t.id == id } } | |
152 | + @hierarchy << self | |
153 | + else | |
154 | + item = self | |
155 | + while item | |
156 | + @hierarchy.unshift(item) | |
157 | + item = item.parent | |
158 | + end | |
159 | + end | |
160 | + end | |
161 | + | |
162 | + @hierarchy | |
163 | + end | |
164 | + | |
165 | + def map_traversal(&block) | |
166 | + result = [] | |
167 | + current_level = [self] | |
168 | + | |
169 | + while !current_level.empty? | |
170 | + result += current_level | |
171 | + ids = current_level.select {|item| item.children_count > 0}.map(&:id) | |
172 | + break if ids.empty? | |
173 | + current_level = self.class.base_class.where(parent_id: ids) | |
174 | + end | |
175 | + block ||= (lambda { |x| x }) | |
176 | + result.map(&block) | |
177 | + end | |
178 | + | |
179 | + def all_children | |
180 | + res = map_traversal | |
181 | + res.shift | |
182 | + res | |
183 | + end | |
184 | + | |
185 | + ##### | |
186 | + # Path methods | |
187 | + # These methods are used when _path_, _name_ and _slug_ attributes exist | |
188 | + # and should be calculated based on the tree | |
189 | + ##### | |
190 | + module PathMethods | |
191 | + # used to know when to trigger batch renaming | |
192 | + attr_accessor :recalculate_path | |
193 | + | |
194 | + # calculates the full path to this record using parent's path. | |
195 | + def calculate_path | |
196 | + self.hierarchy.map{ |obj| obj.slug }.join('/') | |
197 | + end | |
198 | + def set_path | |
199 | + if self.path == self.slug && !self.top_level? | |
200 | + self.path = self.calculate_path | |
201 | + end | |
202 | + end | |
203 | + def explode_path | |
204 | + path.split(/\//) | |
205 | + end | |
206 | + | |
207 | + def update_children_path | |
208 | + if self.recalculate_path | |
209 | + self.children.each do |child| | |
210 | + child.path = child.calculate_path | |
211 | + child.recalculate_path = true | |
212 | + child.save! | |
213 | + end | |
214 | + end | |
215 | + self.recalculate_path = false | |
216 | + end | |
217 | + | |
218 | + # calculates the full name of a record by accessing the name of all its | |
219 | + # ancestors. | |
220 | + # | |
221 | + # If you have this record hierarchy: | |
222 | + # Record "A" | |
223 | + # Record "B" | |
224 | + # Record "C" | |
225 | + # | |
226 | + # Then Record "C" will have "A/B/C" as its full name. | |
227 | + def full_name(sep = '/') | |
228 | + self.hierarchy.map {|item| item.name || '?' }.join(sep) | |
229 | + end | |
230 | + | |
231 | + # gets the name without leading parents. Useful when dividing records | |
232 | + # in top-level groups and full names must not include the top-level | |
233 | + # record which is already a emphasized label | |
234 | + def full_name_without_leading(count, sep = '/') | |
235 | + parts = self.full_name(sep).split(sep) | |
236 | + count.times { parts.shift } | |
237 | + parts.join(sep) | |
238 | + end | |
239 | + | |
240 | + def set_name(value) | |
241 | + if self.name != value | |
242 | + self.recalculate_path = true | |
243 | + end | |
244 | + self[:name] = value | |
245 | + end | |
246 | + | |
247 | + # sets the name of the record. Also sets #slug accordingly. | |
248 | + def name=(value) | |
249 | + self.set_name(value) | |
250 | + unless self.name.blank? | |
251 | + self.slug = self.name.to_slug | |
252 | + end | |
253 | + end | |
254 | + | |
255 | + # sets the slug of the record. Also sets the path with the new slug value. | |
256 | + def slug=(value) | |
257 | + self[:slug] = value | |
258 | + unless self.slug.blank? | |
259 | + self.path = self.calculate_path | |
260 | + end | |
261 | + end | |
262 | + end | |
263 | + end | |
264 | +end | |
265 | + | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +module ActsAsHavingBoxes | |
2 | + | |
3 | + module ClassMethods | |
4 | + def acts_as_having_boxes | |
5 | + has_many :boxes, -> { order :position }, as: :owner, dependent: :destroy | |
6 | + self.send(:include, ActsAsHavingBoxes) | |
7 | + end | |
8 | + end | |
9 | + | |
10 | + module BlockArray | |
11 | + def find(id) | |
12 | + select { |item| item.id == id.to_i }.first | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + def blocks(reload = false) | |
17 | + if (reload) | |
18 | + @blocks = nil | |
19 | + end | |
20 | + if @blocks.nil? | |
21 | + @blocks = boxes.includes(:blocks).inject([]) do |acc,obj| | |
22 | + acc.concat(obj.blocks) | |
23 | + end | |
24 | + @blocks.send(:extend, BlockArray) | |
25 | + end | |
26 | + @blocks | |
27 | + end | |
28 | + | |
29 | + # returns 3 unless the class table has a boxes_limit column. In that case | |
30 | + # return the value of the column. | |
31 | + def boxes_limit layout_template = nil | |
32 | + layout_template ||= self.layout_template | |
33 | + @boxes_limit ||= LayoutTemplate.find(layout_template).number_of_boxes || 3 | |
34 | + end | |
35 | + | |
36 | +end | |
37 | + | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +module ActsAsHavingImage | |
2 | + | |
3 | + module ClassMethods | |
4 | + def acts_as_having_image | |
5 | + belongs_to :image, dependent: :destroy | |
6 | + scope :with_image, -> { where "#{table_name}.image_id IS NOT NULL" } | |
7 | + scope :without_image, -> { where "#{table_name}.image_id IS NULL" } | |
8 | + attr_accessible :image_builder | |
9 | + include ActsAsHavingImage | |
10 | + end | |
11 | + end | |
12 | + | |
13 | + def image_builder=(img) | |
14 | + if image && image.id == img[:id] | |
15 | + image.attributes = img | |
16 | + else | |
17 | + build_image(img) | |
18 | + end unless img[:uploaded_data].blank? | |
19 | + if img[:remove_image] == 'true' | |
20 | + self.image_id = nil | |
21 | + end | |
22 | + end | |
23 | + | |
24 | +end | |
25 | + | ... | ... |
... | ... | @@ -0,0 +1,49 @@ |
1 | +module ActsAsHavingPosts | |
2 | + | |
3 | + module ClassMethods | |
4 | + def acts_as_having_posts(scope = nil) | |
5 | + has_many :posts, -> { | |
6 | + s = order('published_at DESC, id DESC').where('articles.type != ?', 'RssFeed') | |
7 | + s = s.instance_exec(&scope) if scope | |
8 | + s | |
9 | + }, class_name: 'Article', foreign_key: 'parent_id', source: :children | |
10 | + | |
11 | + attr_accessor :feed_attrs | |
12 | + | |
13 | + after_create do |blog| | |
14 | + blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile) | |
15 | + blog.feed = blog.feed_attrs | |
16 | + end | |
17 | + | |
18 | + settings_items :posts_per_page, :type => :integer, :default => 5 | |
19 | + | |
20 | + self.send(:include, ActsAsHavingPosts) | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + def has_posts? | |
25 | + true | |
26 | + end | |
27 | + | |
28 | + def feed | |
29 | + children.where(:type => 'RssFeed').first | |
30 | + end | |
31 | + | |
32 | + def feed=(attrs) | |
33 | + if attrs | |
34 | + if self.feed | |
35 | + self.feed.update(attrs) | |
36 | + else | |
37 | + self.feed_attrs = attrs | |
38 | + end | |
39 | + end | |
40 | + self.feed | |
41 | + end | |
42 | + | |
43 | + def name=(value) | |
44 | + self.set_name(value) | |
45 | + self.slug = self.slug.blank? ? self.name.to_slug : self.slug.to_slug | |
46 | + end | |
47 | + | |
48 | +end | |
49 | + | ... | ... |
... | ... | @@ -0,0 +1,89 @@ |
1 | +# declare missing types | |
2 | +module ActiveRecord | |
3 | + module Type | |
4 | + class Symbol < Value | |
5 | + def cast_value value | |
6 | + value.to_sym | |
7 | + end | |
8 | + end | |
9 | + class Array < Value | |
10 | + def cast_value value | |
11 | + ::Array.wrap(value) | |
12 | + end | |
13 | + end | |
14 | + class Hash < Value | |
15 | + def cast_value value | |
16 | + h = ::Hash[value] | |
17 | + h.symbolize_keys! | |
18 | + h | |
19 | + end | |
20 | + end | |
21 | + end | |
22 | +end | |
23 | + | |
24 | +module ActsAsHavingSettings | |
25 | + | |
26 | + def self.type_cast value, type | |
27 | + # do not cast nil | |
28 | + return value if value.nil? | |
29 | + type.send :cast_value, value | |
30 | + end | |
31 | + | |
32 | + module ClassMethods | |
33 | + | |
34 | + def acts_as_having_settings(*args) | |
35 | + options = args.last.is_a?(Hash) ? args.pop : {} | |
36 | + field = (options[:field] || :settings).to_sym | |
37 | + | |
38 | + serialize field, Hash | |
39 | + class_attribute :settings_field | |
40 | + self.settings_field = field | |
41 | + | |
42 | + class_eval do | |
43 | + def settings_field | |
44 | + self[self.class.settings_field] ||= Hash.new | |
45 | + end | |
46 | + | |
47 | + def setting_changed? setting_field | |
48 | + setting_field = setting_field.to_sym | |
49 | + changed_settings = self.changes[self.class.settings_field] | |
50 | + return false if changed_settings.nil? | |
51 | + | |
52 | + old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field] | |
53 | + new_setting_value = changed_settings.last[setting_field] | |
54 | + old_setting_value != new_setting_value | |
55 | + end | |
56 | + end | |
57 | + | |
58 | + settings_items *args | |
59 | + end | |
60 | + | |
61 | + def settings_items *names | |
62 | + | |
63 | + options = names.extract_options! | |
64 | + default = options[:default] | |
65 | + type = options[:type] | |
66 | + type = if type.present? then ActiveRecord::Type.const_get(type.to_s.camelize.to_sym).new else nil end | |
67 | + | |
68 | + names.each do |setting| | |
69 | + # symbolize key | |
70 | + setting = setting.to_sym | |
71 | + | |
72 | + define_method setting do | |
73 | + h = send self.class.settings_field | |
74 | + val = h[setting] | |
75 | + # translate default value if it is used | |
76 | + if not val.nil? then val elsif default.is_a? String then gettext default else default end | |
77 | + end | |
78 | + | |
79 | + define_method "#{setting}=" do |value| | |
80 | + h = send self.class.settings_field | |
81 | + h[setting] = if type then ActsAsHavingSettings.type_cast value, type else value end | |
82 | + end | |
83 | + end | |
84 | + end | |
85 | + | |
86 | + end | |
87 | + | |
88 | +end | |
89 | + | ... | ... |
... | ... | @@ -0,0 +1,57 @@ |
1 | +module CodeNumbering | |
2 | + module ClassMethods | |
3 | + def code_numbering field, options = {} | |
4 | + class_attribute :code_numbering_field | |
5 | + class_attribute :code_numbering_options | |
6 | + | |
7 | + self.code_numbering_field = field | |
8 | + self.code_numbering_options = options | |
9 | + | |
10 | + before_create :create_code_numbering | |
11 | + | |
12 | + include CodeNumbering::InstanceMethods | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + module InstanceMethods | |
17 | + | |
18 | + def code | |
19 | + self.attributes[self.code_numbering_field.to_s] | |
20 | + end | |
21 | + | |
22 | + def code_scope | |
23 | + scope = self.code_numbering_options[:scope] | |
24 | + case scope | |
25 | + when Symbol | |
26 | + self.send scope | |
27 | + when Proc | |
28 | + instance_exec &scope | |
29 | + else | |
30 | + self.class | |
31 | + end | |
32 | + end | |
33 | + | |
34 | + def code_maximum | |
35 | + self.code_scope.maximum(self.code_numbering_field) || 0 | |
36 | + end | |
37 | + | |
38 | + def create_code_numbering | |
39 | + max = self.code_numbering_options[:start].to_i - 1 if self.code_numbering_options[:start] | |
40 | + max = self.code_maximum | |
41 | + self.send "#{self.code_numbering_field}=", max+1 | |
42 | + end | |
43 | + | |
44 | + def reset_scope_code_numbering | |
45 | + max = self.code_numbering_options[:start].to_i - 1 if self.code_numbering_options[:start] | |
46 | + max ||= 1 | |
47 | + | |
48 | + self.code_scope.order(:created_at).each do |record| | |
49 | + record.update_column self.code_numbering_field, max | |
50 | + max += 1 | |
51 | + end | |
52 | + self.reload | |
53 | + end | |
54 | + | |
55 | + end | |
56 | +end | |
57 | + | ... | ... |
... | ... | @@ -0,0 +1,124 @@ |
1 | +module Customizable | |
2 | + | |
3 | + def self.included(base) | |
4 | + base.attr_accessible :custom_values | |
5 | + base.extend ClassMethods | |
6 | + end | |
7 | + | |
8 | + module ClassMethods | |
9 | + def acts_as_customizable(options = {}) | |
10 | + attr_accessor :custom_values | |
11 | + has_many :custom_field_values, :dependent => :delete_all, :as => :customized | |
12 | + send :include, Customizable::InstanceMethods | |
13 | + after_save :save_custom_values | |
14 | + validate :valid_custom_values? | |
15 | + end | |
16 | + | |
17 | + def active_custom_fields environment | |
18 | + environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.active} | |
19 | + end | |
20 | + | |
21 | + def required_custom_fields environment | |
22 | + environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.required} | |
23 | + end | |
24 | + | |
25 | + def signup_custom_fields environment | |
26 | + environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.signup} | |
27 | + end | |
28 | + | |
29 | + def custom_fields environment | |
30 | + environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type)} | |
31 | + end | |
32 | + | |
33 | + def customized_ancestors_list | |
34 | + current=self | |
35 | + result=[] | |
36 | + while current.instance_methods.include? :custom_value do | |
37 | + result << current.name | |
38 | + current=current.superclass | |
39 | + end | |
40 | + result | |
41 | + end | |
42 | + | |
43 | + end | |
44 | + | |
45 | + module InstanceMethods | |
46 | + | |
47 | + def valid_custom_values? | |
48 | + is_valid = true | |
49 | + parse_custom_values.each do |cv| | |
50 | + unless cv.valid? | |
51 | + name = cv.custom_field.name | |
52 | + errors.add(name, cv.errors.messages[name.to_sym].first) | |
53 | + is_valid = false | |
54 | + end | |
55 | + end | |
56 | + is_valid | |
57 | + end | |
58 | + | |
59 | + def customized_class | |
60 | + current=self.class | |
61 | + while current.instance_methods.include? :custom_fields do | |
62 | + result=current | |
63 | + current=current.superclass | |
64 | + end | |
65 | + result.name | |
66 | + end | |
67 | + | |
68 | + def is_public(field_name) | |
69 | + cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name} | |
70 | + cv.nil? ? false : cv.public | |
71 | + end | |
72 | + | |
73 | + def public_values | |
74 | + self.custom_field_values.select{|cv| cv.public} | |
75 | + end | |
76 | + | |
77 | + def custom_value(field_name) | |
78 | + cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name} | |
79 | + cv.nil? ? default_value_for(field_name) : cv.value | |
80 | + end | |
81 | + | |
82 | + def default_value_for(field_name) | |
83 | + field=self.class.custom_fields(environment).detect {|c| c.name == field_name} | |
84 | + field.nil? ? nil : field.default_value | |
85 | + end | |
86 | + | |
87 | + def parse_custom_values | |
88 | + return_list = [] | |
89 | + return return_list if custom_values.blank? | |
90 | + custom_values.each_pair do |key, value| | |
91 | + custom_field = environment.custom_fields.detect{|cf|cf.name==key} | |
92 | + next if custom_field.blank? | |
93 | + custom_field_value = self.custom_field_values(true).detect{|cv| cv.custom_field.name==key} | |
94 | + | |
95 | + if custom_field_value.nil? | |
96 | + custom_field_value = CustomFieldValue.new | |
97 | + custom_field_value.custom_field = custom_field | |
98 | + custom_field_value.customized = self | |
99 | + end | |
100 | + | |
101 | + if value.is_a?(Hash) | |
102 | + custom_field_value.value = value['value'].to_s | |
103 | + if value.has_key?('public') | |
104 | + is_public = value['public']=="true" || value['public']==true | |
105 | + custom_field_value.public = is_public | |
106 | + else | |
107 | + custom_field_value.public = false | |
108 | + end | |
109 | + else | |
110 | + custom_field_value.value = value.to_s | |
111 | + custom_field_value.public = false | |
112 | + end | |
113 | + return_list << custom_field_value | |
114 | + end | |
115 | + return_list | |
116 | + end | |
117 | + | |
118 | + def save_custom_values | |
119 | + parse_custom_values.each(&:save) | |
120 | + end | |
121 | + | |
122 | + end | |
123 | +end | |
124 | + | ... | ... |
... | ... | @@ -0,0 +1,55 @@ |
1 | +module DelayedAttachmentFu | |
2 | + | |
3 | + module ClassMethods | |
4 | + def delay_attachment_fu_thumbnails | |
5 | + include DelayedAttachmentFu::InstanceMethods | |
6 | + after_create do |file| | |
7 | + if file.thumbnailable? | |
8 | + Delayed::Job.enqueue CreateThumbnailsJob.new(file.class.name, file.id) | |
9 | + end | |
10 | + end | |
11 | + end | |
12 | + end | |
13 | + | |
14 | + module InstanceMethods | |
15 | + # skip processing with RMagick | |
16 | + def process_attachment | |
17 | + end | |
18 | + | |
19 | + def after_process_attachment | |
20 | + save_to_storage | |
21 | + @temp_paths.clear | |
22 | + @saved_attachment = nil | |
23 | + run_callbacks :after_attachment_saved | |
24 | + end | |
25 | + | |
26 | + def create_thumbnails | |
27 | + if thumbnailable? | |
28 | + self.class.with_image(full_filename) do |img| | |
29 | + self.width = img.columns | |
30 | + self.height = img.rows | |
31 | + self.save! | |
32 | + end | |
33 | + self.class.attachment_options[:thumbnails].each do |suffix, size| | |
34 | + self.create_or_update_thumbnail(self.full_filename, suffix, size) | |
35 | + end | |
36 | + self.thumbnails_processed = true | |
37 | + self.save! | |
38 | + end | |
39 | + end | |
40 | + | |
41 | + def public_filename(size=nil) | |
42 | + force, size = true, nil if size == :uploaded | |
43 | + if !self.thumbnailable? || self.thumbnails_processed || force | |
44 | + super size | |
45 | + else | |
46 | + size ||= :thumb | |
47 | + '/images/icons-app/image-loading-%s.png' % size | |
48 | + end | |
49 | + end | |
50 | + | |
51 | + | |
52 | + end | |
53 | +end | |
54 | + | |
55 | + | ... | ... |
app/models/concerns/set_profile_region_from_city_state.rb
0 → 100644
... | ... | @@ -0,0 +1,44 @@ |
1 | +module SetProfileRegionFromCityState | |
2 | + | |
3 | + module ClassMethods | |
4 | + def set_profile_region_from_city_state | |
5 | + before_save :region_from_city_and_state | |
6 | + | |
7 | + include InstanceMethods | |
8 | + alias_method_chain :city=, :region | |
9 | + alias_method_chain :state=, :region | |
10 | + end | |
11 | + end | |
12 | + | |
13 | + module InstanceMethods | |
14 | + include Noosfero::Plugin::HotSpot | |
15 | + | |
16 | + def city_with_region=(value) | |
17 | + self.city_without_region = value | |
18 | + @change_region = true | |
19 | + end | |
20 | + | |
21 | + def state_with_region=(value) | |
22 | + self.state_without_region = value | |
23 | + @change_region = true | |
24 | + end | |
25 | + | |
26 | + def region_from_city_and_state | |
27 | + if @change_region | |
28 | + self.region = nil | |
29 | + state = search_region(State, self.state) | |
30 | + self.region = search_region(City.where(:parent_id => state.id), self.city) if state | |
31 | + end | |
32 | + end | |
33 | + | |
34 | + private | |
35 | + | |
36 | + def search_region(scope, query) | |
37 | + return nil if !query | |
38 | + query = query.downcase.strip | |
39 | + scope.where(['lower(name)=? OR lower(abbreviation)=? OR lower(acronym)=?', query, query, query]).first | |
40 | + end | |
41 | + | |
42 | + end | |
43 | + | |
44 | +end | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +module WhiteListFilter | |
2 | + | |
3 | + def check_iframe_on_content(content, trusted_sites) | |
4 | + if content.blank? || !content.include?('iframe') | |
5 | + return content | |
6 | + end | |
7 | + content.gsub!(/<iframe[^>]*>\s*<\/iframe>/i) do |iframe| | |
8 | + result = '' | |
9 | + unless iframe =~ /src=['"].*src=['"]/ | |
10 | + trusted_sites.each do |trusted_site| | |
11 | + re_dom = trusted_site.gsub('.', '\.') | |
12 | + if iframe =~ /src=["'](https?:)?\/\/(www\.)?#{re_dom}\// | |
13 | + result = iframe | |
14 | + end | |
15 | + end | |
16 | + end | |
17 | + result | |
18 | + end | |
19 | + content | |
20 | + end | |
21 | + | |
22 | + module ClassMethods | |
23 | + def filter_iframes(*opts) | |
24 | + options = opts.last.is_a?(Hash) && opts.pop || {} | |
25 | + white_list_method = options[:whitelist] || :iframe_whitelist | |
26 | + opts.each do |field| | |
27 | + before_validation do |obj| | |
28 | + obj.check_iframe_on_content(obj.send(field), obj.send(white_list_method)) | |
29 | + end | |
30 | + end | |
31 | + end | |
32 | + end | |
33 | + | |
34 | + def self.included(c) | |
35 | + c.send(:extend, WhiteListFilter::ClassMethods) | |
36 | + end | |
37 | +end | ... | ... |
app/models/create_community.rb
... | ... | @@ -12,6 +12,7 @@ class CreateCommunity < Task |
12 | 12 | attr_accessible :environment, :requestor, :target |
13 | 13 | attr_accessible :reject_explanation, :template_id |
14 | 14 | |
15 | + extend ActsAsHavingImage::ClassMethods | |
15 | 16 | acts_as_having_image |
16 | 17 | |
17 | 18 | DATA_FIELDS = Community.fields + ['name', 'closed', 'description'] | ... | ... |
app/models/environment.rb
... | ... | @@ -200,6 +200,7 @@ class Environment < ApplicationRecord |
200 | 200 | # Relationships and applied behaviour |
201 | 201 | # ################################################# |
202 | 202 | |
203 | + extend ActsAsHavingBoxes::ClassMethods | |
203 | 204 | acts_as_having_boxes |
204 | 205 | |
205 | 206 | after_create do |env| |
... | ... | @@ -251,7 +252,8 @@ class Environment < ApplicationRecord |
251 | 252 | # ################################################# |
252 | 253 | |
253 | 254 | # store the Environment settings as YAML-serialized Hash. |
254 | - acts_as_having_settings :field => :settings | |
255 | + extend ActsAsHavingSettings::ClassMethods | |
256 | + acts_as_having_settings field: :settings | |
255 | 257 | |
256 | 258 | # introduce and explain to users something about the signup |
257 | 259 | settings_items :signup_intro, :type => String | ... | ... |
app/models/event.rb
1 | -require 'noosfero/translatable_content' | |
2 | 1 | require 'builder' |
3 | 2 | |
4 | 3 | class Event < Article |
... | ... | @@ -138,7 +137,7 @@ class Event < Article |
138 | 137 | false |
139 | 138 | end |
140 | 139 | |
141 | - include Noosfero::TranslatableContent | |
140 | + include TranslatableContent | |
142 | 141 | include MaybeAddHttp |
143 | 142 | |
144 | 143 | end | ... | ... |
app/models/folder.rb
... | ... | @@ -10,7 +10,8 @@ class Folder < Article |
10 | 10 | errors.add(:parent, "A folder should not belong to a blog.") if parent && parent.blog? |
11 | 11 | end |
12 | 12 | |
13 | - acts_as_having_settings :field => :setting | |
13 | + extend ActsAsHavingSettings::ClassMethods | |
14 | + acts_as_having_settings field: :setting | |
14 | 15 | |
15 | 16 | xss_terminate :only => [ :name, :body ], :with => 'white_list', :on => 'validation' |
16 | 17 | ... | ... |
app/models/forum.rb
app/models/image.rb
... | ... | @@ -23,6 +23,7 @@ class Image < ApplicationRecord |
23 | 23 | |
24 | 24 | validates_attachment :size => N_("{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n |
25 | 25 | |
26 | + extend DelayedAttachmentFu::ClassMethods | |
26 | 27 | delay_attachment_fu_thumbnails |
27 | 28 | |
28 | 29 | postgresql_attachment_fu | ... | ... |
app/models/profile.rb
... | ... | @@ -88,6 +88,8 @@ class Profile < ApplicationRecord |
88 | 88 | } |
89 | 89 | |
90 | 90 | acts_as_accessible |
91 | + | |
92 | + include Customizable | |
91 | 93 | acts_as_customizable |
92 | 94 | |
93 | 95 | include Noosfero::Plugin::HotSpot |
... | ... | @@ -185,6 +187,7 @@ class Profile < ApplicationRecord |
185 | 187 | Person.members_of(self).by_role(roles) |
186 | 188 | end |
187 | 189 | |
190 | + extend ActsAsHavingBoxes::ClassMethods | |
188 | 191 | acts_as_having_boxes |
189 | 192 | |
190 | 193 | acts_as_taggable |
... | ... | @@ -231,7 +234,8 @@ class Profile < ApplicationRecord |
231 | 234 | scrap.nil? ? Scrap.all_scraps(self) : Scrap.all_scraps(self).find(scrap) |
232 | 235 | end |
233 | 236 | |
234 | - acts_as_having_settings :field => :data | |
237 | + extend ActsAsHavingSettings::ClassMethods | |
238 | + acts_as_having_settings field: :data | |
235 | 239 | |
236 | 240 | def settings |
237 | 241 | data |
... | ... | @@ -285,6 +289,7 @@ class Profile < ApplicationRecord |
285 | 289 | |
286 | 290 | has_many :files, :class_name => 'UploadedFile' |
287 | 291 | |
292 | + extend ActsAsHavingImage::ClassMethods | |
288 | 293 | acts_as_having_image |
289 | 294 | |
290 | 295 | has_many :tasks, :dependent => :destroy, :as => 'target' | ... | ... |
app/models/profile_suggestion.rb
... | ... | @@ -17,7 +17,8 @@ class ProfileSuggestion < ApplicationRecord |
17 | 17 | self.class.generate_profile_suggestions(profile_suggestion.person) |
18 | 18 | end |
19 | 19 | |
20 | - acts_as_having_settings :field => :categories | |
20 | + extend ActsAsHavingSettings::ClassMethods | |
21 | + acts_as_having_settings field: :categories | |
21 | 22 | |
22 | 23 | validate :must_be_a_valid_category, :on => :create |
23 | 24 | def must_be_a_valid_category | ... | ... |
app/models/task.rb
... | ... | @@ -11,7 +11,8 @@ |
11 | 11 | # will need to declare <ttserialize</tt> itself). |
12 | 12 | class Task < ApplicationRecord |
13 | 13 | |
14 | - acts_as_having_settings :field => :data | |
14 | + extend ActsAsHavingSettings::ClassMethods | |
15 | + acts_as_having_settings field: :data | |
15 | 16 | |
16 | 17 | module Status |
17 | 18 | # the status of tasks just created | ... | ... |
app/models/text_article.rb
1 | -require 'noosfero/translatable_content' | |
2 | - | |
3 | 1 | # a base class for all text article types. |
4 | 2 | class TextArticle < Article |
5 | 3 | |
... | ... | @@ -9,7 +7,7 @@ class TextArticle < Article |
9 | 7 | _('Article') |
10 | 8 | end |
11 | 9 | |
12 | - include Noosfero::TranslatableContent | |
10 | + include TranslatableContent | |
13 | 11 | |
14 | 12 | def self.icon_name(article = nil) |
15 | 13 | if article && !article.parent.nil? && article.parent.kind_of?(Blog) | ... | ... |
app/models/tiny_mce_article.rb
app/models/uploaded_file.rb
... | ... | @@ -84,6 +84,7 @@ class UploadedFile < Article |
84 | 84 | |
85 | 85 | validates_attachment :size => N_("{fn} of uploaded file was larger than the maximum size of %{size}").sub('%{size}', self.max_size.to_humanreadable).fix_i18n |
86 | 86 | |
87 | + extend DelayedAttachmentFu::ClassMethods | |
87 | 88 | delay_attachment_fu_thumbnails |
88 | 89 | |
89 | 90 | postgresql_attachment_fu | ... | ... |
config/initializers/00_dependencies.rb
... | ... | @@ -16,14 +16,6 @@ end |
16 | 16 | require 'extensions' |
17 | 17 | |
18 | 18 | # locally-developed modules |
19 | -require 'acts_as_filesystem' | |
20 | -require 'acts_as_having_settings' | |
21 | -require 'acts_as_having_boxes' | |
22 | -require 'acts_as_having_image' | |
23 | -require 'acts_as_having_posts' | |
24 | -require 'acts_as_customizable' | |
25 | 19 | require 'route_if' |
26 | 20 | require 'maybe_add_http' |
27 | -require 'set_profile_region_from_city_state' | |
28 | -require 'white_list_filter' | |
29 | 21 | ... | ... |
config/initializers/delayed_attachment_fu.rb
... | ... | @@ -1 +0,0 @@ |
1 | -require 'delayed_attachment_fu' |
db/migrate/20160422163123_enable_products_plugin_on_environments.rb
lib/acts_as_customizable.rb
... | ... | @@ -1,125 +0,0 @@ |
1 | -module Customizable | |
2 | - | |
3 | - def self.included(base) | |
4 | - base.attr_accessible :custom_values | |
5 | - base.extend ClassMethods | |
6 | - end | |
7 | - | |
8 | - module ClassMethods | |
9 | - def acts_as_customizable(options = {}) | |
10 | - attr_accessor :custom_values | |
11 | - has_many :custom_field_values, :dependent => :delete_all, :as => :customized | |
12 | - send :include, Customizable::InstanceMethods | |
13 | - after_save :save_custom_values | |
14 | - validate :valid_custom_values? | |
15 | - end | |
16 | - | |
17 | - def active_custom_fields environment | |
18 | - environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.active} | |
19 | - end | |
20 | - | |
21 | - def required_custom_fields environment | |
22 | - environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.required} | |
23 | - end | |
24 | - | |
25 | - def signup_custom_fields environment | |
26 | - environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type) && cf.signup} | |
27 | - end | |
28 | - | |
29 | - def custom_fields environment | |
30 | - environment.custom_fields.select{|cf| customized_ancestors_list.include?(cf.customized_type)} | |
31 | - end | |
32 | - | |
33 | - def customized_ancestors_list | |
34 | - current=self | |
35 | - result=[] | |
36 | - while current.instance_methods.include? :custom_value do | |
37 | - result << current.name | |
38 | - current=current.superclass | |
39 | - end | |
40 | - result | |
41 | - end | |
42 | - | |
43 | - end | |
44 | - | |
45 | - module InstanceMethods | |
46 | - | |
47 | - def valid_custom_values? | |
48 | - is_valid = true | |
49 | - parse_custom_values.each do |cv| | |
50 | - unless cv.valid? | |
51 | - name = cv.custom_field.name | |
52 | - errors.add(name, cv.errors.messages[name.to_sym].first) | |
53 | - is_valid = false | |
54 | - end | |
55 | - end | |
56 | - is_valid | |
57 | - end | |
58 | - | |
59 | - def customized_class | |
60 | - current=self.class | |
61 | - while current.instance_methods.include? :custom_fields do | |
62 | - result=current | |
63 | - current=current.superclass | |
64 | - end | |
65 | - result.name | |
66 | - end | |
67 | - | |
68 | - def is_public(field_name) | |
69 | - cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name} | |
70 | - cv.nil? ? false : cv.public | |
71 | - end | |
72 | - | |
73 | - def public_values | |
74 | - self.custom_field_values.select{|cv| cv.public} | |
75 | - end | |
76 | - | |
77 | - def custom_value(field_name) | |
78 | - cv = self.custom_field_values.detect{|cv| cv.custom_field.name==field_name} | |
79 | - cv.nil? ? default_value_for(field_name) : cv.value | |
80 | - end | |
81 | - | |
82 | - def default_value_for(field_name) | |
83 | - field=self.class.custom_fields(environment).detect {|c| c.name == field_name} | |
84 | - field.nil? ? nil : field.default_value | |
85 | - end | |
86 | - | |
87 | - def parse_custom_values | |
88 | - return_list = [] | |
89 | - return return_list if custom_values.blank? | |
90 | - custom_values.each_pair do |key, value| | |
91 | - custom_field = environment.custom_fields.detect{|cf|cf.name==key} | |
92 | - next if custom_field.blank? | |
93 | - custom_field_value = self.custom_field_values(true).detect{|cv| cv.custom_field.name==key} | |
94 | - | |
95 | - if custom_field_value.nil? | |
96 | - custom_field_value = CustomFieldValue.new | |
97 | - custom_field_value.custom_field = custom_field | |
98 | - custom_field_value.customized = self | |
99 | - end | |
100 | - | |
101 | - if value.is_a?(Hash) | |
102 | - custom_field_value.value = value['value'].to_s | |
103 | - if value.has_key?('public') | |
104 | - is_public = value['public']=="true" || value['public']==true | |
105 | - custom_field_value.public = is_public | |
106 | - else | |
107 | - custom_field_value.public = false | |
108 | - end | |
109 | - else | |
110 | - custom_field_value.value = value.to_s | |
111 | - custom_field_value.public = false | |
112 | - end | |
113 | - return_list << custom_field_value | |
114 | - end | |
115 | - return_list | |
116 | - end | |
117 | - | |
118 | - def save_custom_values | |
119 | - parse_custom_values.each(&:save) | |
120 | - end | |
121 | - | |
122 | - end | |
123 | -end | |
124 | - | |
125 | -ActiveRecord::Base.include Customizable |
lib/acts_as_filesystem.rb
... | ... | @@ -1,267 +0,0 @@ |
1 | -module ActsAsFileSystem | |
2 | - | |
3 | - module ActsMethods | |
4 | - | |
5 | - # Declares the ActiveRecord model to acts like a filesystem: objects are | |
6 | - # arranged in a tree (liks acts_as_tree), and . The underlying table must | |
7 | - # have the following fields: | |
8 | - # | |
9 | - # * name (+:string+) - the title of the object | |
10 | - # * slug (+:string+)- the title turned in a URL-friendly string (downcased, | |
11 | - # non-ascii chars transliterated into ascii, all sequences of | |
12 | - # non-alphanumericd characters changed into dashed) | |
13 | - # * path (+:text+)- stores the full path of the object (the full path of | |
14 | - # the parent, a "/" and the slug of the object) | |
15 | - # * children_count - a cache of the number of children elements. | |
16 | - def acts_as_filesystem | |
17 | - # a filesystem is a tree | |
18 | - acts_as_tree :counter_cache => :children_count | |
19 | - | |
20 | - extend ClassMethods | |
21 | - include InstanceMethods | |
22 | - if self.has_path? | |
23 | - after_update :update_children_path | |
24 | - before_create :set_path | |
25 | - include InstanceMethods::PathMethods | |
26 | - end | |
27 | - | |
28 | - before_save :set_ancestry | |
29 | - end | |
30 | - | |
31 | - end | |
32 | - | |
33 | - module ClassMethods | |
34 | - | |
35 | - def build_ancestry(parent_id = nil, ancestry = '') | |
36 | - ActiveRecord::Base.transaction do | |
37 | - self.base_class.where(parent_id: parent_id).each do |node| | |
38 | - node.update_column :ancestry, ancestry | |
39 | - | |
40 | - build_ancestry node.id, (ancestry.empty? ? "#{node.formatted_ancestry_id}" : | |
41 | - "#{ancestry}#{node.ancestry_sep}#{node.formatted_ancestry_id}") | |
42 | - end | |
43 | - end | |
44 | - | |
45 | - #raise "Couldn't reach and set ancestry on every record" if self.base_class.where('ancestry is null').count != 0 | |
46 | - end | |
47 | - | |
48 | - def has_path? | |
49 | - (['name', 'slug', 'path'] - self.column_names).blank? | |
50 | - end | |
51 | - | |
52 | - end | |
53 | - | |
54 | - module InstanceMethods | |
55 | - | |
56 | - def ancestry_column | |
57 | - 'ancestry' | |
58 | - end | |
59 | - def ancestry_sep | |
60 | - '.' | |
61 | - end | |
62 | - def has_ancestry? | |
63 | - self.class.column_names.include? self.ancestry_column | |
64 | - end | |
65 | - | |
66 | - def formatted_ancestry_id | |
67 | - "%010d" % self.id if self.id | |
68 | - end | |
69 | - | |
70 | - def ancestry | |
71 | - self[ancestry_column] | |
72 | - end | |
73 | - def ancestor_ids | |
74 | - return nil if !has_ancestry? or ancestry.nil? | |
75 | - @ancestor_ids ||= ancestry.split(ancestry_sep).map{ |id| id.to_i } | |
76 | - end | |
77 | - | |
78 | - def ancestry=(value) | |
79 | - self[ancestry_column] = value | |
80 | - end | |
81 | - def set_ancestry | |
82 | - return unless self.has_ancestry? | |
83 | - if self.ancestry.nil? or (new_record? or parent_id_changed?) or recalculate_path | |
84 | - self.ancestry = self.hierarchy(true)[0...-1].map{ |p| p.formatted_ancestry_id }.join(ancestry_sep) | |
85 | - end | |
86 | - end | |
87 | - | |
88 | - def descendents_options | |
89 | - ["#{self.ancestry_column} LIKE ?", "%#{self.formatted_ancestry_id}%"] | |
90 | - end | |
91 | - def descendents | |
92 | - self.class.where descendents_options | |
93 | - end | |
94 | - | |
95 | - # calculates the level of the record in the records hierarchy. Top-level | |
96 | - # records have level 0; the children of the top-level records have | |
97 | - # level 1; the children of records with level 1 have level 2, and so on. | |
98 | - # | |
99 | - # A level 0 | |
100 | - # / \ | |
101 | - # B C level 1 | |
102 | - # / \ / \ | |
103 | - # E F G H level 2 | |
104 | - # ... | |
105 | - def level | |
106 | - self.hierarchy.size - 1 | |
107 | - end | |
108 | - | |
109 | - # Is this record a top-level record? | |
110 | - def top_level? | |
111 | - self.parent.nil? | |
112 | - end | |
113 | - | |
114 | - # Is this record a leaf in the hierarchy tree of records? | |
115 | - # | |
116 | - # Being a leaf means that this record has no subrecord. | |
117 | - def leaf? | |
118 | - self.children.empty? | |
119 | - end | |
120 | - | |
121 | - def top_ancestor | |
122 | - if has_ancestry? and !ancestry.blank? | |
123 | - self.class.base_class.find_by id: self.top_ancestor_id | |
124 | - else | |
125 | - self.hierarchy.first | |
126 | - end | |
127 | - end | |
128 | - def top_ancestor_id | |
129 | - if has_ancestry? and !ancestry.nil? | |
130 | - self.ancestor_ids.first | |
131 | - else | |
132 | - self.hierarchy.first.id | |
133 | - end | |
134 | - end | |
135 | - | |
136 | - # returns the full hierarchy from the top-level item to this one. For | |
137 | - # example, if item1 has a children item2 and item2 has a children item3, | |
138 | - # then item3's hierarchy would be [item1, item2, item3]. | |
139 | - # | |
140 | - # If +reload+ is passed as +true+, then the hierarchy is reload (usefull | |
141 | - # when the ActiveRecord object was modified in some way, or just after | |
142 | - # changing parent) | |
143 | - def hierarchy(reload = false) | |
144 | - @hierarchy = nil if reload or recalculate_path | |
145 | - | |
146 | - if @hierarchy.nil? | |
147 | - @hierarchy = [] | |
148 | - | |
149 | - if !reload and !recalculate_path and ancestor_ids | |
150 | - objects = self.class.base_class.where(id: ancestor_ids) | |
151 | - ancestor_ids.each{ |id| @hierarchy << objects.find{ |t| t.id == id } } | |
152 | - @hierarchy << self | |
153 | - else | |
154 | - item = self | |
155 | - while item | |
156 | - @hierarchy.unshift(item) | |
157 | - item = item.parent | |
158 | - end | |
159 | - end | |
160 | - end | |
161 | - | |
162 | - @hierarchy | |
163 | - end | |
164 | - | |
165 | - def map_traversal(&block) | |
166 | - result = [] | |
167 | - current_level = [self] | |
168 | - | |
169 | - while !current_level.empty? | |
170 | - result += current_level | |
171 | - ids = current_level.select {|item| item.children_count > 0}.map(&:id) | |
172 | - break if ids.empty? | |
173 | - current_level = self.class.base_class.where(parent_id: ids) | |
174 | - end | |
175 | - block ||= (lambda { |x| x }) | |
176 | - result.map(&block) | |
177 | - end | |
178 | - | |
179 | - def all_children | |
180 | - res = map_traversal | |
181 | - res.shift | |
182 | - res | |
183 | - end | |
184 | - | |
185 | - ##### | |
186 | - # Path methods | |
187 | - # These methods are used when _path_, _name_ and _slug_ attributes exist | |
188 | - # and should be calculated based on the tree | |
189 | - ##### | |
190 | - module PathMethods | |
191 | - # used to know when to trigger batch renaming | |
192 | - attr_accessor :recalculate_path | |
193 | - | |
194 | - # calculates the full path to this record using parent's path. | |
195 | - def calculate_path | |
196 | - self.hierarchy.map{ |obj| obj.slug }.join('/') | |
197 | - end | |
198 | - def set_path | |
199 | - if self.path == self.slug && !self.top_level? | |
200 | - self.path = self.calculate_path | |
201 | - end | |
202 | - end | |
203 | - def explode_path | |
204 | - path.split(/\//) | |
205 | - end | |
206 | - | |
207 | - def update_children_path | |
208 | - if self.recalculate_path | |
209 | - self.children.each do |child| | |
210 | - child.path = child.calculate_path | |
211 | - child.recalculate_path = true | |
212 | - child.save! | |
213 | - end | |
214 | - end | |
215 | - self.recalculate_path = false | |
216 | - end | |
217 | - | |
218 | - # calculates the full name of a record by accessing the name of all its | |
219 | - # ancestors. | |
220 | - # | |
221 | - # If you have this record hierarchy: | |
222 | - # Record "A" | |
223 | - # Record "B" | |
224 | - # Record "C" | |
225 | - # | |
226 | - # Then Record "C" will have "A/B/C" as its full name. | |
227 | - def full_name(sep = '/') | |
228 | - self.hierarchy.map {|item| item.name || '?' }.join(sep) | |
229 | - end | |
230 | - | |
231 | - # gets the name without leading parents. Useful when dividing records | |
232 | - # in top-level groups and full names must not include the top-level | |
233 | - # record which is already a emphasized label | |
234 | - def full_name_without_leading(count, sep = '/') | |
235 | - parts = self.full_name(sep).split(sep) | |
236 | - count.times { parts.shift } | |
237 | - parts.join(sep) | |
238 | - end | |
239 | - | |
240 | - def set_name(value) | |
241 | - if self.name != value | |
242 | - self.recalculate_path = true | |
243 | - end | |
244 | - self[:name] = value | |
245 | - end | |
246 | - | |
247 | - # sets the name of the record. Also sets #slug accordingly. | |
248 | - def name=(value) | |
249 | - self.set_name(value) | |
250 | - unless self.name.blank? | |
251 | - self.slug = self.name.to_slug | |
252 | - end | |
253 | - end | |
254 | - | |
255 | - # sets the slug of the record. Also sets the path with the new slug value. | |
256 | - def slug=(value) | |
257 | - self[:slug] = value | |
258 | - unless self.slug.blank? | |
259 | - self.path = self.calculate_path | |
260 | - end | |
261 | - end | |
262 | - end | |
263 | - end | |
264 | -end | |
265 | - | |
266 | -ActiveRecord::Base.extend ActsAsFileSystem::ActsMethods | |
267 | - |
lib/acts_as_having_boxes.rb
... | ... | @@ -1,38 +0,0 @@ |
1 | -module ActsAsHavingBoxes | |
2 | - | |
3 | - module ClassMethods | |
4 | - def acts_as_having_boxes | |
5 | - has_many :boxes, -> { order :position }, as: :owner, dependent: :destroy | |
6 | - self.send(:include, ActsAsHavingBoxes) | |
7 | - end | |
8 | - end | |
9 | - | |
10 | - module BlockArray | |
11 | - def find(id) | |
12 | - select { |item| item.id == id.to_i }.first | |
13 | - end | |
14 | - end | |
15 | - | |
16 | - def blocks(reload = false) | |
17 | - if (reload) | |
18 | - @blocks = nil | |
19 | - end | |
20 | - if @blocks.nil? | |
21 | - @blocks = boxes.includes(:blocks).inject([]) do |acc,obj| | |
22 | - acc.concat(obj.blocks) | |
23 | - end | |
24 | - @blocks.send(:extend, BlockArray) | |
25 | - end | |
26 | - @blocks | |
27 | - end | |
28 | - | |
29 | - # returns 3 unless the class table has a boxes_limit column. In that case | |
30 | - # return the value of the column. | |
31 | - def boxes_limit layout_template = nil | |
32 | - layout_template ||= self.layout_template | |
33 | - @boxes_limit ||= LayoutTemplate.find(layout_template).number_of_boxes || 3 | |
34 | - end | |
35 | - | |
36 | -end | |
37 | - | |
38 | -ActiveRecord::Base.extend ActsAsHavingBoxes::ClassMethods |
lib/acts_as_having_image.rb
... | ... | @@ -1,27 +0,0 @@ |
1 | -module ActsAsHavingImage | |
2 | - | |
3 | - module ClassMethods | |
4 | - def acts_as_having_image | |
5 | - belongs_to :image, dependent: :destroy | |
6 | - scope :with_image, -> { where "#{table_name}.image_id IS NOT NULL" } | |
7 | - scope :without_image, -> { where "#{table_name}.image_id IS NULL" } | |
8 | - attr_accessible :image_builder | |
9 | - include ActsAsHavingImage | |
10 | - end | |
11 | - end | |
12 | - | |
13 | - def image_builder=(img) | |
14 | - if image && image.id == img[:id] | |
15 | - image.attributes = img | |
16 | - else | |
17 | - build_image(img) | |
18 | - end unless img[:uploaded_data].blank? | |
19 | - if img[:remove_image] == 'true' | |
20 | - self.image_id = nil | |
21 | - end | |
22 | - end | |
23 | - | |
24 | -end | |
25 | - | |
26 | -ActiveRecord::Base.extend ActsAsHavingImage::ClassMethods | |
27 | - |
lib/acts_as_having_posts.rb
... | ... | @@ -1,51 +0,0 @@ |
1 | -module ActsAsHavingPosts | |
2 | - | |
3 | - module ClassMethods | |
4 | - def acts_as_having_posts(scope = nil) | |
5 | - has_many :posts, -> { | |
6 | - s = order('published_at DESC, id DESC').where('articles.type != ?', 'RssFeed') | |
7 | - s = s.instance_exec(&scope) if scope | |
8 | - s | |
9 | - }, class_name: 'Article', foreign_key: 'parent_id', source: :children | |
10 | - | |
11 | - attr_accessor :feed_attrs | |
12 | - | |
13 | - after_create do |blog| | |
14 | - blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile) | |
15 | - blog.feed = blog.feed_attrs | |
16 | - end | |
17 | - | |
18 | - settings_items :posts_per_page, :type => :integer, :default => 5 | |
19 | - | |
20 | - self.send(:include, ActsAsHavingPosts) | |
21 | - end | |
22 | - end | |
23 | - | |
24 | - def has_posts? | |
25 | - true | |
26 | - end | |
27 | - | |
28 | - def feed | |
29 | - children.where(:type => 'RssFeed').first | |
30 | - end | |
31 | - | |
32 | - def feed=(attrs) | |
33 | - if attrs | |
34 | - if self.feed | |
35 | - self.feed.update(attrs) | |
36 | - else | |
37 | - self.feed_attrs = attrs | |
38 | - end | |
39 | - end | |
40 | - self.feed | |
41 | - end | |
42 | - | |
43 | - def name=(value) | |
44 | - self.set_name(value) | |
45 | - self.slug = self.slug.blank? ? self.name.to_slug : self.slug.to_slug | |
46 | - end | |
47 | - | |
48 | -end | |
49 | - | |
50 | -ActiveRecord::Base.extend ActsAsHavingPosts::ClassMethods | |
51 | - |
lib/acts_as_having_settings.rb
... | ... | @@ -1,91 +0,0 @@ |
1 | -# declare missing types | |
2 | -module ActiveRecord | |
3 | - module Type | |
4 | - class Symbol < Value | |
5 | - def cast_value value | |
6 | - value.to_sym | |
7 | - end | |
8 | - end | |
9 | - class Array < Value | |
10 | - def cast_value value | |
11 | - ::Array.wrap(value) | |
12 | - end | |
13 | - end | |
14 | - class Hash < Value | |
15 | - def cast_value value | |
16 | - h = ::Hash[value] | |
17 | - h.symbolize_keys! | |
18 | - h | |
19 | - end | |
20 | - end | |
21 | - end | |
22 | -end | |
23 | - | |
24 | -module ActsAsHavingSettings | |
25 | - | |
26 | - def self.type_cast value, type | |
27 | - # do not cast nil | |
28 | - return value if value.nil? | |
29 | - type.send :cast_value, value | |
30 | - end | |
31 | - | |
32 | - module ClassMethods | |
33 | - | |
34 | - def acts_as_having_settings(*args) | |
35 | - options = args.last.is_a?(Hash) ? args.pop : {} | |
36 | - field = (options[:field] || :settings).to_sym | |
37 | - | |
38 | - serialize field, Hash | |
39 | - class_attribute :settings_field | |
40 | - self.settings_field = field | |
41 | - | |
42 | - class_eval do | |
43 | - def settings_field | |
44 | - self[self.class.settings_field] ||= Hash.new | |
45 | - end | |
46 | - | |
47 | - def setting_changed? setting_field | |
48 | - setting_field = setting_field.to_sym | |
49 | - changed_settings = self.changes[self.class.settings_field] | |
50 | - return false if changed_settings.nil? | |
51 | - | |
52 | - old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field] | |
53 | - new_setting_value = changed_settings.last[setting_field] | |
54 | - old_setting_value != new_setting_value | |
55 | - end | |
56 | - end | |
57 | - | |
58 | - settings_items *args | |
59 | - end | |
60 | - | |
61 | - def settings_items *names | |
62 | - | |
63 | - options = names.extract_options! | |
64 | - default = options[:default] | |
65 | - type = options[:type] | |
66 | - type = if type.present? then ActiveRecord::Type.const_get(type.to_s.camelize.to_sym).new else nil end | |
67 | - | |
68 | - names.each do |setting| | |
69 | - # symbolize key | |
70 | - setting = setting.to_sym | |
71 | - | |
72 | - define_method setting do | |
73 | - h = send self.class.settings_field | |
74 | - val = h[setting] | |
75 | - # translate default value if it is used | |
76 | - if not val.nil? then val elsif default.is_a? String then gettext default else default end | |
77 | - end | |
78 | - | |
79 | - define_method "#{setting}=" do |value| | |
80 | - h = send self.class.settings_field | |
81 | - h[setting] = if type then ActsAsHavingSettings.type_cast value, type else value end | |
82 | - end | |
83 | - end | |
84 | - end | |
85 | - | |
86 | - end | |
87 | - | |
88 | -end | |
89 | - | |
90 | -ActiveRecord::Base.extend ActsAsHavingSettings::ClassMethods | |
91 | - |
lib/code_numbering.rb
... | ... | @@ -1,58 +0,0 @@ |
1 | -module CodeNumbering | |
2 | - module ClassMethods | |
3 | - def code_numbering field, options = {} | |
4 | - class_attribute :code_numbering_field | |
5 | - class_attribute :code_numbering_options | |
6 | - | |
7 | - self.code_numbering_field = field | |
8 | - self.code_numbering_options = options | |
9 | - | |
10 | - before_create :create_code_numbering | |
11 | - | |
12 | - include CodeNumbering::InstanceMethods | |
13 | - end | |
14 | - end | |
15 | - | |
16 | - module InstanceMethods | |
17 | - | |
18 | - def code | |
19 | - self.attributes[self.code_numbering_field.to_s] | |
20 | - end | |
21 | - | |
22 | - def code_scope | |
23 | - scope = self.code_numbering_options[:scope] | |
24 | - case scope | |
25 | - when Symbol | |
26 | - self.send scope | |
27 | - when Proc | |
28 | - instance_exec &scope | |
29 | - else | |
30 | - self.class | |
31 | - end | |
32 | - end | |
33 | - | |
34 | - def code_maximum | |
35 | - self.code_scope.maximum(self.code_numbering_field) || 0 | |
36 | - end | |
37 | - | |
38 | - def create_code_numbering | |
39 | - max = self.code_numbering_options[:start].to_i - 1 if self.code_numbering_options[:start] | |
40 | - max = self.code_maximum | |
41 | - self.send "#{self.code_numbering_field}=", max+1 | |
42 | - end | |
43 | - | |
44 | - def reset_scope_code_numbering | |
45 | - max = self.code_numbering_options[:start].to_i - 1 if self.code_numbering_options[:start] | |
46 | - max ||= 1 | |
47 | - | |
48 | - self.code_scope.order(:created_at).each do |record| | |
49 | - record.update_column self.code_numbering_field, max | |
50 | - max += 1 | |
51 | - end | |
52 | - self.reload | |
53 | - end | |
54 | - | |
55 | - end | |
56 | -end | |
57 | - | |
58 | -ActiveRecord::Base.extend CodeNumbering::ClassMethods |
lib/delayed_attachment_fu.rb
... | ... | @@ -1,56 +0,0 @@ |
1 | -module DelayedAttachmentFu | |
2 | - | |
3 | - module ClassMethods | |
4 | - def delay_attachment_fu_thumbnails | |
5 | - include DelayedAttachmentFu::InstanceMethods | |
6 | - after_create do |file| | |
7 | - if file.thumbnailable? | |
8 | - Delayed::Job.enqueue CreateThumbnailsJob.new(file.class.name, file.id) | |
9 | - end | |
10 | - end | |
11 | - end | |
12 | - end | |
13 | - | |
14 | - module InstanceMethods | |
15 | - # skip processing with RMagick | |
16 | - def process_attachment | |
17 | - end | |
18 | - | |
19 | - def after_process_attachment | |
20 | - save_to_storage | |
21 | - @temp_paths.clear | |
22 | - @saved_attachment = nil | |
23 | - run_callbacks :after_attachment_saved | |
24 | - end | |
25 | - | |
26 | - def create_thumbnails | |
27 | - if thumbnailable? | |
28 | - self.class.with_image(full_filename) do |img| | |
29 | - self.width = img.columns | |
30 | - self.height = img.rows | |
31 | - self.save! | |
32 | - end | |
33 | - self.class.attachment_options[:thumbnails].each do |suffix, size| | |
34 | - self.create_or_update_thumbnail(self.full_filename, suffix, size) | |
35 | - end | |
36 | - self.thumbnails_processed = true | |
37 | - self.save! | |
38 | - end | |
39 | - end | |
40 | - | |
41 | - def public_filename(size=nil) | |
42 | - force, size = true, nil if size == :uploaded | |
43 | - if !self.thumbnailable? || self.thumbnails_processed || force | |
44 | - super size | |
45 | - else | |
46 | - size ||= :thumb | |
47 | - '/images/icons-app/image-loading-%s.png' % size | |
48 | - end | |
49 | - end | |
50 | - | |
51 | - | |
52 | - end | |
53 | -end | |
54 | - | |
55 | -ActiveRecord::Base.extend DelayedAttachmentFu::ClassMethods | |
56 | - |
lib/noosfero/translatable_content.rb
lib/set_profile_region_from_city_state.rb
... | ... | @@ -1,44 +0,0 @@ |
1 | -module SetProfileRegionFromCityState | |
2 | - | |
3 | - module ClassMethods | |
4 | - def set_profile_region_from_city_state | |
5 | - before_save :region_from_city_and_state | |
6 | - | |
7 | - include InstanceMethods | |
8 | - alias_method_chain :city=, :region | |
9 | - alias_method_chain :state=, :region | |
10 | - end | |
11 | - end | |
12 | - | |
13 | - module InstanceMethods | |
14 | - include Noosfero::Plugin::HotSpot | |
15 | - | |
16 | - def city_with_region=(value) | |
17 | - self.city_without_region = value | |
18 | - @change_region = true | |
19 | - end | |
20 | - | |
21 | - def state_with_region=(value) | |
22 | - self.state_without_region = value | |
23 | - @change_region = true | |
24 | - end | |
25 | - | |
26 | - def region_from_city_and_state | |
27 | - if @change_region | |
28 | - self.region = nil | |
29 | - state = search_region(State, self.state) | |
30 | - self.region = search_region(City.where(:parent_id => state.id), self.city) if state | |
31 | - end | |
32 | - end | |
33 | - | |
34 | - private | |
35 | - | |
36 | - def search_region(scope, query) | |
37 | - return nil if !query | |
38 | - query = query.downcase.strip | |
39 | - scope.where(['lower(name)=? OR lower(abbreviation)=? OR lower(acronym)=?', query, query, query]).first | |
40 | - end | |
41 | - | |
42 | - end | |
43 | - | |
44 | -end |
lib/white_list_filter.rb
... | ... | @@ -1,37 +0,0 @@ |
1 | -module WhiteListFilter | |
2 | - | |
3 | - def check_iframe_on_content(content, trusted_sites) | |
4 | - if content.blank? || !content.include?('iframe') | |
5 | - return content | |
6 | - end | |
7 | - content.gsub!(/<iframe[^>]*>\s*<\/iframe>/i) do |iframe| | |
8 | - result = '' | |
9 | - unless iframe =~ /src=['"].*src=['"]/ | |
10 | - trusted_sites.each do |trusted_site| | |
11 | - re_dom = trusted_site.gsub('.', '\.') | |
12 | - if iframe =~ /src=["'](https?:)?\/\/(www\.)?#{re_dom}\// | |
13 | - result = iframe | |
14 | - end | |
15 | - end | |
16 | - end | |
17 | - result | |
18 | - end | |
19 | - content | |
20 | - end | |
21 | - | |
22 | - module ClassMethods | |
23 | - def filter_iframes(*opts) | |
24 | - options = opts.last.is_a?(Hash) && opts.pop || {} | |
25 | - white_list_method = options[:whitelist] || :iframe_whitelist | |
26 | - opts.each do |field| | |
27 | - before_validation do |obj| | |
28 | - obj.check_iframe_on_content(obj.send(field), obj.send(white_list_method)) | |
29 | - end | |
30 | - end | |
31 | - end | |
32 | - end | |
33 | - | |
34 | - def self.included(c) | |
35 | - c.send(:extend, WhiteListFilter::ClassMethods) | |
36 | - end | |
37 | -end |
plugins/analytics/models/analytics_plugin/page_view.rb
plugins/fb_app/models/fb_app_plugin/page_tab.rb
... | ... | @@ -9,6 +9,7 @@ class FbAppPlugin::PageTab < ApplicationRecord |
9 | 9 | |
10 | 10 | belongs_to :owner_profile, foreign_key: :profile_id, class_name: 'Profile' |
11 | 11 | |
12 | + extend ActsAsHavingSettings::ClassMethods | |
12 | 13 | acts_as_having_settings field: :config |
13 | 14 | |
14 | 15 | ConfigTypes = [:profile, :profiles, :query] | ... | ... |
plugins/newsletter/lib/newsletter_plugin/newsletter.rb
plugins/oauth_client/models/oauth_client_plugin/auth.rb
... | ... | @@ -10,6 +10,7 @@ class OauthClientPlugin::Auth < ApplicationRecord |
10 | 10 | validates_presence_of :provider |
11 | 11 | validates_uniqueness_of :profile_id, scope: :provider_id |
12 | 12 | |
13 | + extend ActsAsHavingSettings::ClassMethods | |
13 | 14 | acts_as_having_settings field: :data |
14 | 15 | |
15 | 16 | def expires_in | ... | ... |
plugins/oauth_client/models/oauth_client_plugin/provider.rb
... | ... | @@ -4,7 +4,10 @@ class OauthClientPlugin::Provider < ApplicationRecord |
4 | 4 | |
5 | 5 | validates_presence_of :name, :strategy |
6 | 6 | |
7 | + extend ActsAsHavingImage::ClassMethods | |
7 | 8 | acts_as_having_image |
9 | + | |
10 | + extend ActsAsHavingSettings::ClassMethods | |
8 | 11 | acts_as_having_settings field: :options |
9 | 12 | |
10 | 13 | settings_items :site, type: String |
... | ... | @@ -16,6 +19,4 @@ class OauthClientPlugin::Provider < ApplicationRecord |
16 | 19 | |
17 | 20 | scope :enabled, -> { where enabled: true } |
18 | 21 | |
19 | - acts_as_having_image | |
20 | - | |
21 | 22 | end | ... | ... |
plugins/products/models/products_plugin/product.rb
... | ... | @@ -45,6 +45,7 @@ class ProductsPlugin::Product < ApplicationRecord |
45 | 45 | has_many :qualifiers, through: :product_qualifiers |
46 | 46 | has_many :certifiers, through: :product_qualifiers |
47 | 47 | |
48 | + extend ActsAsHavingSettings::ClassMethods | |
48 | 49 | acts_as_having_settings field: :data |
49 | 50 | |
50 | 51 | track_actions :create_product, :after_create, keep_params: [:name, :url ], if: Proc.new { |a| a.is_trackable? }, custom_user: :action_tracker_user |
... | ... | @@ -129,6 +130,7 @@ class ProductsPlugin::Product < ApplicationRecord |
129 | 130 | image ? image.public_filename(size) : '/images/icons-app/product-default-pic-%s.png' % size |
130 | 131 | end |
131 | 132 | |
133 | + extend ActsAsHavingImage::ClassMethods | |
132 | 134 | acts_as_having_image |
133 | 135 | |
134 | 136 | def save_image | ... | ... |
plugins/shopping_cart/db/migrate/20131226125124_move_shopping_cart_purchase_order_to_orders_plugin_order.rb
... | ... | @@ -2,6 +2,7 @@ OrdersPlugin.send :remove_const, :Item if defined? OrdersPlugin::Item |
2 | 2 | OrdersPlugin.send :remove_const, :Order if defined? OrdersPlugin::Order |
3 | 3 | |
4 | 4 | class ShoppingCartPlugin::PurchaseOrder < ApplicationRecord |
5 | + extend ActsAsHavingSettings::ClassMethods | |
5 | 6 | acts_as_having_settings field: :data |
6 | 7 | |
7 | 8 | module Status | ... | ... |
plugins/video/lib/video_plugin/video.rb
plugins/video/lib/video_plugin/video_gallery.rb
... | ... | @@ -14,7 +14,8 @@ class VideoPlugin::VideoGallery < Folder |
14 | 14 | errors.add(:parent, "A video gallery should not belong to a blog.") if parent && parent.blog? |
15 | 15 | end |
16 | 16 | |
17 | - acts_as_having_settings :field => :setting | |
17 | + extend ActsAsHavingSettings::ClassMethods | |
18 | + acts_as_having_settings field: :setting | |
18 | 19 | |
19 | 20 | xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation' |
20 | 21 | ... | ... |
test/unit/event_test.rb
... | ... | @@ -282,7 +282,7 @@ class EventTest < ActiveSupport::TestCase |
282 | 282 | end |
283 | 283 | |
284 | 284 | should 'be translatable' do |
285 | - assert_kind_of Noosfero::TranslatableContent, Event.new | |
285 | + assert_kind_of TranslatableContent, Event.new | |
286 | 286 | end |
287 | 287 | |
288 | 288 | should 'tiny mce editor is enabled' do | ... | ... |
test/unit/text_article_test.rb
... | ... | @@ -15,7 +15,7 @@ class TextArticleTest < ActiveSupport::TestCase |
15 | 15 | end |
16 | 16 | |
17 | 17 | should 'be translatable' do |
18 | - assert_kind_of Noosfero::TranslatableContent, TextArticle.new | |
18 | + assert_kind_of TranslatableContent, TextArticle.new | |
19 | 19 | end |
20 | 20 | |
21 | 21 | should 'return article icon name' do | ... | ... |
test/unit/translatable_content_test.rb