Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 134 lines (108 sloc) 4.366 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
require 'active_record'

module Newscloud
  module Acts
    module Moderatable

      def self.included(base)
        base.extend ClassMethods
      end

      module ClassMethods
        def acts_as_moderatable
          has_many :flags, :as => :flaggable
          # HACK:: move this out to its own location
          has_many :item_actions, :as => :actionable

          after_save :rescore_item

          scope :active, { :conditions => ["#{self.name.tableize}.is_blocked = false"] }
          scope :inactive, { :conditions => ["#{self.name.tableize}.is_blocked = true"] }
          scope :user_items, { :conditions =>
              "#{self.name.tableize}.user_id not in (select id from users where is_editor = true or is_moderator = true or is_admin = true)" }
          scope :curator_items, { :conditions =>
              "#{self.name.tableize}.user_id in (select id from users where is_editor = true or is_moderator = true or is_admin = true)" }

          include Newscloud::Acts::Moderatable::InstanceMethods
        end
      end

      module InstanceMethods
        def rescore_item
          ItemScore.find_or_create_and_score(self) if self.class.rankable_classes.include?(self.class)
        end

        def moderatable?
          true
        end

        def blockable?
          self.respond_to?('is_blocked') ? true : false
        end

        def featurable?
          self.respond_to?('is_featured') ? true : false
        end

        def blocked?
          return self.is_blocked if self.respond_to?('is_blocked')
          false
        end

        def featured?
          return self.is_featured if self.respond_to?('is_featured')
          false
        end

        def flagged?
          self.flags.present? ? self.flag_count : false
        end

        def flag_count
          self.flags.count
        end

        def flag_item flag_type,current_user
          return false unless Flag.valid_flag_type? flag_type

          @flag = self.flags.build({ :flag_type => flag_type })
          @flag.user = current_user

          return @flag.save
        end

        def toggle_blocked
          self.is_blocked = ! self.is_blocked
          cascade_block self.is_blocked
          self.cascade_block_pfeed_items self.is_blocked
          return self.save ? true : false
        end

        def toggle_featured
          self.is_featured = ! self.is_featured
          self.featured_at = Time.now if self.respond_to?('featured_at')
          return self.save ? true : false
        end

        def cascade_block blocked = nil
          [self.class.reflect_on_all_associations(:has_many), self.class.reflect_on_all_associations(:has_one)].flatten.each do |association|
            if not association.options.include?(:through)
              items = Array(self.send(association.name)).flatten.compact

              items.each do |item|
                if item.moderatable?
                  item.update_attribute(:is_blocked, blocked) unless item.is_blocked == blocked
                  item.expire
                  item.cascade_block blocked if item.respond_to? :cascade_block
                  item.cascade_block_pfeed_items blocked
                end
              end
            end
          end
          return true
        end

        def cascade_block_pfeed_items blocked = nil
          PfeedItem.where(["participant_type = ? and participant_id = ?", self.class.name, self.id]).each do |pitem|
            pitem.update_attribute(:is_blocked, blocked || false)
            pitem.expire
            pitem.participant.cascade_block blocked if pitem.participant.moderatable?
          end
        end

        def verify_cascade blocked = nil
          [self.class.reflect_on_all_associations(:has_many), self.class.reflect_on_all_associations(:has_one)].flatten.each do |association|
            if not association.options.include?(:through)
              items = Array(self.send(association.name)).flatten.compact

              count = 0
              items.each do |item|
                if item.moderatable?
                  raise "Block Discrepancy: #{item.inspect}" unless item.is_blocked == blocked
                  item.verify_cascade blocked if item.respond_to? :verify_cascade
                end
              end
            end
          end
          return true
        end

      end
    end
  end
end
Something went wrong with that request. Please try again.