custom_validations 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+
5
+ class BrCnpjValidator < ActiveModel::EachValidator
6
+ BLACK_LIST = %w(00000000000000 11111111111111 22222222222222 33333333333333
7
+ 44444444444444 55555555555555 66666666666666 77777777777777
8
+ 88888888888888 99999999999999)
9
+
10
+ def validate_each(record, attribute, value)
11
+ return if value.to_s.blank? # it doesn't validate presence
12
+ record.errors.add(attribute, :br_cnpj, options) unless valid_cnpj?(value.to_s)
13
+ end
14
+
15
+ def valid_cnpj? cnpj
16
+
17
+ begin
18
+ cnpj = (cnpj.is_a?(String) ? cnpj : cnpj.to_s)
19
+ rescue Exception => exc
20
+ return false
21
+ end
22
+
23
+ # could be 13 or 14 digits or with mask 99.999.999/9999-99
24
+ if cnpj !~ /^\d{13,14}$|\d{2}\.\d{3}\.\d{3}\/\d{4}\-\d{2}$/
25
+ return false
26
+ end
27
+
28
+ cnpj = cnpj.scan(/\d/).collect(&:to_i)
29
+ cnpj.unshift(0) if cnpj.length == 13
30
+
31
+ # filter black list
32
+ if BLACK_LIST.include? cnpj.join
33
+ return false
34
+ end
35
+
36
+ # calculate first digit
37
+ factor = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
38
+
39
+ sum = (0..11).inject(0) do |sum, i|
40
+ sum + cnpj[i] * factor[i]
41
+ end
42
+
43
+ result = sum % 11
44
+ result = result < 2 ? 0 : 11 - result
45
+
46
+ if result != cnpj[12]
47
+ return false
48
+ end
49
+
50
+ # calculate second digit
51
+ factor.unshift 6
52
+
53
+ sum = (0..12).inject(0) do |sum, i|
54
+ sum + cnpj[i] * factor[i]
55
+ end
56
+
57
+ result = sum % 11
58
+ result = result < 2 ? 0 : 11 - result
59
+
60
+ result == cnpj[13]
61
+ end
62
+ end
63
+
64
+
65
+ module HelperMethods
66
+ def validates_br_cnpj_of(*attr_names)
67
+ validates_with BrCnpjValidator, _merge_attributes(attr_names)
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,69 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+
5
+ class BrCpfValidator < ActiveModel::EachValidator
6
+ BLACK_LIST = %w(12345678909 11111111111 22222222222 33333333333 44444444444
7
+ 55555555555 66666666666 77777777777 88888888888 99999999999
8
+ 00000000000)
9
+
10
+ def validate_each(record, attribute, value)
11
+ return if value.to_s.blank? # it doesn't validate presence
12
+ record.errors.add(attribute, :br_cpf, options) unless valid_cpf?(value.to_s)
13
+ end
14
+
15
+ def valid_cpf? cpf
16
+ begin
17
+ cpf = (cpf.is_a?(String) ? cpf : cpf.to_s)
18
+ rescue
19
+ return false
20
+ end
21
+
22
+ # could be 10 or 11 digits or with mask 999.999.999-99
23
+ if cpf !~ /^\d{10,11}$|\d{3}\.\d{3}\.\d{3}-\d{2}$/
24
+ return false
25
+ end
26
+
27
+ cpf = cpf.scan(/\d/).collect(&:to_i)
28
+ cpf.unshift(0) if cpf.length == 10
29
+
30
+ # filter black list
31
+ if BLACK_LIST.include? cpf.join
32
+ return false
33
+ end
34
+
35
+ # calculate first digit
36
+ sum = (0..8).inject(0) do |sum, i|
37
+ sum + cpf[i] * (10 - i)
38
+ end
39
+
40
+ result = sum % 11
41
+ result = result < 2 ? 0 : 11 - result
42
+
43
+ if result != cpf[9]
44
+ return false
45
+ end
46
+
47
+ # calculate second digit
48
+ sum = (0..8).inject(0) do |sum, i|
49
+ sum + cpf[i] * (11 - i)
50
+ end
51
+
52
+ sum += cpf[9] * 2
53
+
54
+ result = sum % 11
55
+ result = result < 2 ? 0 : 11 - result
56
+
57
+ result == cpf[10]
58
+ end
59
+ end
60
+
61
+
62
+ module HelperMethods
63
+ def validates_br_cpf_of(*attr_names)
64
+ validates_with BrCpfValidator, _merge_attributes(attr_names)
65
+ end
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,25 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+
5
+ class BrPostalCodeValidator < ActiveModel::EachValidator
6
+
7
+ REGEX = /^\d{5}\-?\d{3}$/
8
+
9
+ def validate_each(record, attribute, value)
10
+ return if value.to_s.blank? # it doesn't validate presence
11
+ unless value.to_s =~ REGEX
12
+ record.errors.add(attribute, :br_postal_code, options)
13
+ end
14
+ end
15
+ end
16
+
17
+
18
+ module HelperMethods
19
+ def validates_br_postal_code_of(*attr_names)
20
+ validates_with BrPostalCodeValidator, _merge_attributes(attr_names)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ module ClientSideValidations::Middleware
2
+ class Url < Base
3
+
4
+ class URLValidationClass
5
+ include ActiveModel::Validations
6
+ attr_accessor :url
7
+ validates_url_of :url
8
+ end
9
+
10
+ class URLAsHostValidationClass
11
+ include ActiveModel::Validations
12
+ attr_accessor :url
13
+ validates_url_of :url, as_host: true
14
+ end
15
+
16
+ def response
17
+
18
+ if request.params[:as_host] == 'true'
19
+ obj = URLAsHostValidationClass.new
20
+ else
21
+ obj = URLValidationClass.new
22
+ end
23
+
24
+ obj.url = request.params[:value]
25
+ obj.valid?
26
+
27
+ if obj.errors.has_key? :url
28
+ self.status = 400
29
+ self.body = {message: obj.errors[:url].first}.to_json
30
+ else
31
+ self.status = 200
32
+ self.body = 'true'
33
+ end
34
+
35
+ super
36
+ end
37
+ end
38
+ end
@@ -3,4 +3,9 @@ en:
3
3
  # The values :model, :attribute and :value are always available for interpolation
4
4
  # The value :count is available when applicable. Can be used for pluralization.
5
5
  messages:
6
- email: "not an email address"
6
+ br_cpf: "is not a valid brazilian CPF"
7
+ br_cnpj: "is not a valid brazilian CNPJ"
8
+ br_postal_code: "is not a valid brazilian postal code"
9
+ email: "is not an email address"
10
+ url: "is an invalid url"
11
+ url_as_host: "is an invalid url (specify only the domain, without http and /)"
@@ -0,0 +1,52 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+
5
+ class UrlValidator < ActiveModel::EachValidator
6
+
7
+ def initialize(options)
8
+ options[:as_host] = false if options[:as_host].blank?
9
+ super
10
+ end
11
+
12
+ def validate_each(record, attribute, value)
13
+ return if value.to_s.blank? # it doesn't validate presence
14
+
15
+ valid = begin
16
+ uri = URI.parse(value)
17
+ uri.kind_of?(URI::HTTP) and !uri.host.to_s.match /^\./
18
+ rescue URI::InvalidURIError
19
+ false
20
+ end
21
+
22
+
23
+ if options[:as_host] and uri.kind_of?(URI::Generic)
24
+ if uri.scheme.present? or value.match(/\?|\/|\:|^\s*\./)
25
+ record.errors.add(attribute, :url_as_host, options)
26
+ end
27
+
28
+ elsif !valid
29
+ record.errors.add(attribute, :url, options)
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+
36
+ module HelperMethods
37
+ def validates_url_of(*attr_names)
38
+ validates_with UrlValidator, _merge_attributes(attr_names)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ #
46
+ # URL validation is very difficult to perform. There are several points of view
47
+ # on what is a valid URL and what URLs should be considered in validations.
48
+ # We will do a pragmatic validation here. If the URL is parsable, then it's valid.
49
+ # See the tests to learn what we have considered as valid and invalid urls.
50
+ # Nice discussion here:
51
+ # http://stackoverflow.com/questions/7167895/whats-a-good-way-to-validate-links-urls-in-rails-3
52
+ #
@@ -1,3 +1,3 @@
1
1
  module CustomValidations
2
- VERSION = '0.0.1'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -4,7 +4,18 @@ require 'active_model'
4
4
  # Require base code
5
5
  require 'custom_validations/version'
6
6
  require 'custom_validations/engine'
7
+
8
+ # Require validators
9
+ require 'custom_validations/br_postal_code_validator'
10
+ require 'custom_validations/br_cpf_validator'
11
+ require 'custom_validations/br_cnpj_validator'
7
12
  require 'custom_validations/email_validator'
13
+ require 'custom_validations/url_validator'
14
+
15
+ # Require ClientSideValidations midlewares
16
+ if defined?(ClientSideValidations)
17
+ require 'custom_validations/client_side_validations_midleware/url'
18
+ end
8
19
 
9
20
  # Load translations
10
21
  require 'active_support/i18n'
@@ -12,12 +12,91 @@
12
12
  (function() {
13
13
 
14
14
  jQuery(function() {
15
- var is_blank, validators;
15
+ var is_blank, validates_cnpj, validates_cpf, validators;
16
16
  is_blank = function(element) {
17
17
  return /^\s*$/.test(element.val() || '');
18
18
  };
19
+ validates_cpf = function(cpf) {
20
+ var i, result, sum;
21
+ cpf = $.trim(cpf).replace(/\.|\-/g, '').split('');
22
+ sum = 0;
23
+ i = 10;
24
+ $.each(cpf.slice(0, 9), function() {
25
+ sum += parseInt(this) * i;
26
+ return i -= 1;
27
+ });
28
+ result = sum % 11;
29
+ if (result < 2) {
30
+ result = 0;
31
+ } else {
32
+ result = 11 - result;
33
+ }
34
+ if (result !== parseInt(cpf[9])) {
35
+ return false;
36
+ }
37
+ sum = 0;
38
+ i = 11;
39
+ $.each(cpf.slice(0, 10), function() {
40
+ sum += parseInt(this) * i;
41
+ return i -= 1;
42
+ });
43
+ result = sum % 11;
44
+ if (result < 2) {
45
+ result = 0;
46
+ } else {
47
+ result = 11 - result;
48
+ }
49
+ return result === parseInt(cpf[10]);
50
+ };
51
+ validates_cnpj = function(cnpj) {
52
+ var sum;
53
+ cnpj = $.trim(cnpj).replace(/[^0-9]/g, '').split('');
54
+ sum = 5 * parseInt(cnpj[0]) + 4 * parseInt(cnpj[1]) + 3 * parseInt(cnpj[2]) + 2 * parseInt(cnpj[3]);
55
+ sum += 9 * parseInt(cnpj[4]) + 8 * parseInt(cnpj[5]) + 7 * parseInt(cnpj[6]) + 6 * parseInt(cnpj[7]);
56
+ sum += 5 * parseInt(cnpj[8]) + 4 * parseInt(cnpj[9]) + 3 * parseInt(cnpj[10]) + 2 * parseInt(cnpj[11]);
57
+ sum = 11 - parseInt(sum % 11);
58
+ if (sum >= 10) {
59
+ sum = 0;
60
+ }
61
+ if (sum !== parseInt(cnpj[12])) {
62
+ return false;
63
+ }
64
+ sum = 6 * parseInt(cnpj[0]) + 5 * parseInt(cnpj[1]) + 4 * parseInt(cnpj[2]) + 3 * parseInt(cnpj[3]);
65
+ sum += 2 * parseInt(cnpj[4]) + 9 * parseInt(cnpj[5]) + 8 * parseInt(cnpj[6]) + 7 * parseInt(cnpj[7]);
66
+ sum += 6 * parseInt(cnpj[8]) + 5 * parseInt(cnpj[9]) + 4 * parseInt(cnpj[10]) + 3 * parseInt(cnpj[11]);
67
+ sum += 2 * parseInt(cnpj[12]);
68
+ sum = 11 - parseInt(sum % 11);
69
+ if (sum >= 10) {
70
+ sum = 0;
71
+ }
72
+ return sum === parseInt(cnpj[13]);
73
+ };
19
74
  validators = window.ClientSideValidations.validators;
20
- return validators.local['email'] = function(element, options) {
75
+ validators.local['br_cpf'] = function(element, options) {
76
+ if (is_blank(element)) {
77
+ return;
78
+ }
79
+ if (!validates_cpf(element.val())) {
80
+ return options.message;
81
+ }
82
+ };
83
+ validators.local['br_cnpj'] = function(element, options) {
84
+ if (is_blank(element)) {
85
+ return;
86
+ }
87
+ if (!validates_cnpj(element.val())) {
88
+ return options.message;
89
+ }
90
+ };
91
+ validators.local['br_postal_code'] = function(element, options) {
92
+ if (is_blank(element)) {
93
+ return;
94
+ }
95
+ if (!/^\d{5}\-?\d{3}$/.test(element.val())) {
96
+ return options.message;
97
+ }
98
+ };
99
+ validators.local['email'] = function(element, options) {
21
100
  if (is_blank(element)) {
22
101
  return;
23
102
  }
@@ -25,6 +104,24 @@
25
104
  return options.message;
26
105
  }
27
106
  };
107
+ return validators.remote['url'] = function(element, options) {
108
+ var response;
109
+ if (is_blank(element)) {
110
+ return;
111
+ }
112
+ response = $.ajax({
113
+ dataType: 'json',
114
+ url: '/validators/url',
115
+ data: {
116
+ value: element.val(),
117
+ as_host: options.as_host
118
+ },
119
+ async: false
120
+ });
121
+ if (response.status === 400) {
122
+ return JSON.parse(response.responseText)['message'];
123
+ }
124
+ };
28
125
  });
29
126
 
30
127
  }).call(this);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: custom_validations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-24 00:00:00.000000000 Z
12
+ date: 2013-02-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -52,9 +52,14 @@ extra_rdoc_files: []
52
52
  files:
53
53
  - custom_validations.gemspec
54
54
  - lib/custom_validations.rb
55
+ - lib/custom_validations/br_cnpj_validator.rb
56
+ - lib/custom_validations/br_cpf_validator.rb
57
+ - lib/custom_validations/br_postal_code_validator.rb
58
+ - lib/custom_validations/client_side_validations_midleware/url.rb
55
59
  - lib/custom_validations/email_validator.rb
56
60
  - lib/custom_validations/engine.rb
57
61
  - lib/custom_validations/locale/en.yml
62
+ - lib/custom_validations/url_validator.rb
58
63
  - lib/custom_validations/version.rb
59
64
  - vendor/assets/javascripts/rails.custom_validations.js
60
65
  homepage: https://github.com/kauplus/custom_validations
@@ -71,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
76
  version: '0'
72
77
  segments:
73
78
  - 0
74
- hash: -2993300514968256952
79
+ hash: 2904212743417297461
75
80
  required_rubygems_version: !ruby/object:Gem::Requirement
76
81
  none: false
77
82
  requirements:
@@ -80,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
85
  version: '0'
81
86
  segments:
82
87
  - 0
83
- hash: -2993300514968256952
88
+ hash: 2904212743417297461
84
89
  requirements: []
85
90
  rubyforge_project:
86
91
  rubygems_version: 1.8.24