Commit 76e29aed97e98044fede7f4a280abc96b80d58a6
1 parent
f678092a
Exists in
profile_api_improvements
and in
1 other branch
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