root/vendor/plugins/file_column/lib/validations.rb @ 6

Revision 2, 4.6 kB (checked in by falcon, 17 years ago)

added plugins

Line 
1module FileColumn
2  module Validations #:nodoc:
3   
4    def self.append_features(base)
5      super
6      base.extend(ClassMethods)
7    end
8
9    # This module contains methods to create validations of uploaded files. All methods
10    # in this module will be included as class methods into <tt>ActiveRecord::Base</tt>
11    # so that you can use them in your models like this:
12    #
13    #    class Entry < ActiveRecord::Base
14    #      file_column :image
15    #      validates_filesize_of :image, :in => 0..1.megabyte
16    #    end
17    module ClassMethods
18      EXT_REGEXP = /\.([A-z0-9]+)$/
19   
20      # This validates the file type of one or more file_columns.  A list of file columns
21      # should be given followed by an options hash.
22      #
23      # Required options:
24      # * <tt>:in</tt> => list of extensions or mime types. If mime types are used they
25      #   will be mapped into an extension via FileColumn::ClassMethods::MIME_EXTENSIONS.
26      #
27      # Examples:
28      #     validates_file_format_of :field, :in => ["gif", "png", "jpg"]
29      #     validates_file_format_of :field, :in => ["image/jpeg"]
30      def validates_file_format_of(*attrs)
31     
32        options = attrs.pop if attrs.last.is_a?Hash
33        raise ArgumentError, "Please include the :in option." if !options || !options[:in]
34        options[:in] = [options[:in]] if options[:in].is_a?String
35        raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Array
36     
37        validates_each(attrs, options) do |record, attr, value|
38          unless value.blank?
39            mime_extensions = record.send("#{attr}_options")[:mime_extensions]
40            extensions = options[:in].map{|o| mime_extensions[o] || o }
41            record.errors.add attr, "is not a valid format." unless extensions.include?(value.scan(EXT_REGEXP).flatten.first)
42          end
43        end
44     
45      end
46   
47      # This validates the file size of one or more file_columns.  A list of file columns
48      # should be given followed by an options hash.
49      #
50      # Required options:
51      # * <tt>:in</tt> => A size range.  Note that you can use ActiveSupport's
52      #   numeric extensions for kilobytes, etc.
53      #
54      # Examples:
55      #    validates_filesize_of :field, :in => 0..100.megabytes
56      #    validates_filesize_of :field, :in => 15.kilobytes..1.megabyte
57      def validates_filesize_of(*attrs) 
58     
59        options = attrs.pop if attrs.last.is_a?Hash
60        raise ArgumentError, "Please include the :in option." if !options || !options[:in]
61        raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Range
62     
63        validates_each(attrs, options) do |record, attr, value|
64          unless value.blank?
65            size = File.size(value)
66            record.errors.add attr, "is smaller than the allowed size range." if size < options[:in].first
67            record.errors.add attr, "is larger than the allowed size range." if size > options[:in].last
68          end
69        end
70     
71      end 
72
73      IMAGE_SIZE_REGEXP = /^(\d+)x(\d+)$/
74
75      # Validates the image size of one or more file_columns.  A list of file columns
76      # should be given followed by an options hash. The validation will pass
77      # if both image dimensions (rows and columns) are at least as big as
78      # given in the <tt>:min</tt> option.
79      #
80      # Required options:
81      # * <tt>:min</tt> => minimum image dimension string, in the format NNxNN
82      #   (columns x rows).
83      #
84      # Example:
85      #    validates_image_size :field, :min => "1200x1800"
86      #
87      # This validation requires RMagick to be installed on your system
88      # to check the image's size.
89      def validates_image_size(*attrs)     
90        options = attrs.pop if attrs.last.is_a?Hash
91        raise ArgumentError, "Please include a :min option." if !options || !options[:min]
92        minimums = options[:min].scan(IMAGE_SIZE_REGEXP).first.collect{|n| n.to_i} rescue []
93        raise ArgumentError, "Invalid value for option :min (should be 'XXxYY')" unless minimums.size == 2
94
95        require 'RMagick'
96
97        validates_each(attrs, options) do |record, attr, value|
98          unless value.blank?
99            begin
100              img = ::Magick::Image::read(value).first
101              record.errors.add('image', "is too small, must be at least #{minimums[0]}x#{minimums[1]}") if ( img.rows < minimums[1] || img.columns < minimums[0] )
102            rescue ::Magick::ImageMagickError
103              record.errors.add('image', "invalid image")
104            end
105            img = nil
106            GC.start
107          end
108        end
109      end
110    end
111  end
112end
Note: See TracBrowser for help on using the browser.