phony_rails 0.14.7 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 61c4c27ba9b21ca10478542b5ba5f87112b0566e
4
- data.tar.gz: f081e0772586515e34ff639dc1839152a9a19d62
2
+ SHA256:
3
+ metadata.gz: 9f5029f29270fa190a8d6bb493268065d2abed1652c3bb63622340309018cced
4
+ data.tar.gz: f6f307074a3348693e6ef4bce515b81b3890ff396a35dd4ed343bcefa3476a8a
5
5
  SHA512:
6
- metadata.gz: f24f3dbb6851ae7e5ef4886a9ac78c316aa735632b02e3083a18c0b7966d34e846f212532aca21db4b315c9c0d54837d6c39c9f5d53735081e9280a47b24e25a
7
- data.tar.gz: 67ede59cd91fe43798eefbb839b3bf17f02e817ce9bd779021f33fad736dee1a34a7ab5f97ff5996e3daf924a16f854f5d8c501154e95a3431cedd48bd7caac3
6
+ metadata.gz: 9153aa4dfd473744cd30b227d1429b0766fd27a0b58c8003aba6677e851390adc0f1b8c237d8b77e0f386c5e3c5f05958aff5a1f1f842a495b68caba5511ffe5
7
+ data.tar.gz: 8cc31c41aceec40c3d0ea203a1e8cec344bc9e0e5fbc407bd78456e9a4fe16b020c5b8b4895eedc3a9e19247dd8f55e41e8349283512871a0282289ea825216a
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  coverage/*
7
7
  /.bundle
8
8
  /vendor
9
+ Gemfile.lock
data/.rubocop.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  inherit_from: .rubocop_todo.yml
2
+ require: rubocop-performance
2
3
  AllCops:
3
- TargetRubyVersion: 2.3
4
+ TargetRubyVersion: 2.4
4
5
  Metrics/BlockLength:
5
6
  ExcludedMethods: ['describe', 'context', 'define', 'shared_examples_for']
data/.rubocop_todo.yml CHANGED
@@ -13,6 +13,13 @@ Lint/AssignmentInCondition:
13
13
  - 'lib/phony_rails.rb'
14
14
 
15
15
  # Offense count: 2
16
+ # Cop supports --auto-correct.
17
+ Lint/SendWithMixinArgument:
18
+ Exclude:
19
+ - 'lib/phony_rails.rb'
20
+
21
+ # Offense count: 2
22
+ # Configuration parameters: AllowKeywordBlockArguments.
16
23
  Lint/UnderscorePrefixedVariableName:
17
24
  Exclude:
18
25
  - 'lib/phony_rails.rb'
@@ -46,6 +53,12 @@ Performance/StartWith:
46
53
  Exclude:
47
54
  - 'lib/phony_rails.rb'
48
55
 
56
+ # Offense count: 1
57
+ # Cop supports --auto-correct.
58
+ Performance/RegexpMatch:
59
+ Exclude:
60
+ - 'lib/phony_rails.rb'
61
+
49
62
  # Offense count: 1
50
63
  # Configuration parameters: EnforcedStyle, SupportedStyles.
51
64
  # SupportedStyles: nested, compact
@@ -61,3 +74,6 @@ Style/Documentation:
61
74
  - 'lib/phony_rails.rb'
62
75
  - 'lib/phony_rails/string_extensions.rb'
63
76
  - 'lib/validators/phony_validator.rb'
77
+
78
+ Style/RescueModifier:
79
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,7 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.5
4
- - 2.3.1
3
+ - 2.4.4
4
+ - 2.5.5
5
+ - 2.6.2
6
+ - 3.0.0
5
7
  script:
6
8
  - bundle exec rspec spec
7
9
  - bundle exec rubocop
data/CHANGELOG.md CHANGED
@@ -1,5 +1,88 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.14.13](https://github.com/joost/phony_rails/tree/v0.14.13) (2019-07-03)
4
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.12...v0.14.13)
5
+
6
+ **Closed issues:**
7
+
8
+ - 0.4.11 was the latest release. However the new normalize\_when\_valid has been sitting here for a while... Release? [\#194](https://github.com/joost/phony_rails/issues/194)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Fixing \#195 - Original value should be cached in correct instance var [\#196](https://github.com/joost/phony_rails/pull/196) ([dlikhten](https://github.com/dlikhten))
13
+
14
+ ## [v0.14.12](https://github.com/joost/phony_rails/tree/v0.14.12) (2019-06-21)
15
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.11...v0.14.12)
16
+
17
+ **Closed issues:**
18
+
19
+ - Some German numbers not passing plausible\_numbers? without country\_code [\#193](https://github.com/joost/phony_rails/issues/193)
20
+
21
+ **Merged pull requests:**
22
+
23
+ - Upgrade Ruby versions and Relax dependancies [\#192](https://github.com/joost/phony_rails/pull/192) ([berkos](https://github.com/berkos))
24
+ - Add possibility to return original phone number when is not valid [\#190](https://github.com/joost/phony_rails/pull/190) ([synion](https://github.com/synion))
25
+ - Add UK country\_code. [\#189](https://github.com/joost/phony_rails/pull/189) ([ayghor](https://github.com/ayghor))
26
+
27
+ ## [v0.14.11](https://github.com/joost/phony_rails/tree/v0.14.11) (2018-10-11)
28
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.10...v0.14.11)
29
+
30
+ **Closed issues:**
31
+
32
+ - Problem with normalizing Estonian number [\#187](https://github.com/joost/phony_rails/issues/187)
33
+
34
+ **Merged pull requests:**
35
+
36
+ - Add Korean translation\(including spec\) [\#186](https://github.com/joost/phony_rails/pull/186) ([freelyageha](https://github.com/freelyageha))
37
+
38
+ ## [v0.14.10](https://github.com/joost/phony_rails/tree/v0.14.10) (2018-10-11)
39
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.9...v0.14.10)
40
+
41
+ **Closed issues:**
42
+
43
+ - PhonyRails.default\_country\_code too intrusive in plausible\_number? method [\#179](https://github.com/joost/phony_rails/issues/179)
44
+ - default\_country\_code overrides 00-prefix country code [\#175](https://github.com/joost/phony_rails/issues/175)
45
+ - Valid 260 area code number is reported as invalid [\#168](https://github.com/joost/phony_rails/issues/168)
46
+ - Croatian number not validating as plausible. [\#165](https://github.com/joost/phony_rails/issues/165)
47
+ - phony\_formatted not returning original String for non-digit only strings [\#163](https://github.com/joost/phony_rails/issues/163)
48
+ - should all normalized numbers be valid? [\#162](https://github.com/joost/phony_rails/issues/162)
49
+ - Extensions not working out of the box for validator [\#160](https://github.com/joost/phony_rails/issues/160)
50
+
51
+ **Merged pull requests:**
52
+
53
+ - Remove errant `puts` [\#188](https://github.com/joost/phony_rails/pull/188) ([stevenharman](https://github.com/stevenharman))
54
+ - Close issues [\#185](https://github.com/joost/phony_rails/pull/185) ([joost](https://github.com/joost))
55
+ - Better PhonyRails.plausible\_number? method. Closes \#179. [\#184](https://github.com/joost/phony_rails/pull/184) ([joost](https://github.com/joost))
56
+ - Allow numbers starting with 00 country codes. Closes \#175. [\#183](https://github.com/joost/phony_rails/pull/183) ([joost](https://github.com/joost))
57
+
58
+ ## [v0.14.9](https://github.com/joost/phony_rails/tree/v0.14.9) (2018-09-05)
59
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.7...v0.14.9)
60
+
61
+ **Closed issues:**
62
+
63
+ - Cut new release 0.14.7 to include new extension removal logic [\#177](https://github.com/joost/phony_rails/issues/177)
64
+ - default\_country\_code based on relation [\#174](https://github.com/joost/phony_rails/issues/174)
65
+
66
+ **Merged pull requests:**
67
+
68
+ - Allow brackets. Closes \#170. [\#182](https://github.com/joost/phony_rails/pull/182) ([joost](https://github.com/joost))
69
+ - add lambda support for default country code [\#181](https://github.com/joost/phony_rails/pull/181) ([kimyu92](https://github.com/kimyu92))
70
+ - Add Spanish translation for validation error [\#178](https://github.com/joost/phony_rails/pull/178) ([r-sierra](https://github.com/r-sierra))
71
+
72
+ ## [v0.14.7](https://github.com/joost/phony_rails/tree/v0.14.7) (2018-05-25)
73
+ [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.6...v0.14.7)
74
+
75
+ **Closed issues:**
76
+
77
+ - Country code wrapped in brackets is not recognized [\#170](https://github.com/joost/phony_rails/issues/170)
78
+ - Invalid number in countryCode VN [\#159](https://github.com/joost/phony_rails/issues/159)
79
+
80
+ **Merged pull requests:**
81
+
82
+ - Extension option added to normalize\_number [\#176](https://github.com/joost/phony_rails/pull/176) ([ramaboo](https://github.com/ramaboo))
83
+ - return country from phone number [\#169](https://github.com/joost/phony_rails/pull/169) ([aovertus](https://github.com/aovertus))
84
+ - Fix code example in README to match description [\#167](https://github.com/joost/phony_rails/pull/167) ([mattruzicka](https://github.com/mattruzicka))
85
+
3
86
  ## [v0.14.6](https://github.com/joost/phony_rails/tree/v0.14.6) (2017-06-20)
4
87
  [Full Changelog](https://github.com/joost/phony_rails/compare/v0.14.5...v0.14.6)
5
88
 
data/Gemfile CHANGED
@@ -11,6 +11,4 @@ gem 'guard-rspec' # , '~> 4.2.0'
11
11
  gem 'rake'
12
12
  gem 'rspec' # , '~> 2.14.0'
13
13
  gem 'rubocop'
14
-
15
- # For testing
16
- gem 'sqlite3'
14
+ gem 'rubocop-performance'
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # PhonyRails [![Build Status](https://travis-ci.org/joost/phony_rails.svg?branch=master)](https://travis-ci.org/joost/phony_rails) [![Coverage Status](https://coveralls.io/repos/joost/phony_rails/badge.svg)](https://coveralls.io/r/joost/phony_rails) ![Dependencies Status](https://img.shields.io/gemnasium/joost/phony_rails.svg) ![Gem](https://img.shields.io/gem/v/phony_rails.svg)
1
+ # PhonyRails [![Build Status](https://travis-ci.org/joost/phony_rails.svg?branch=master)](https://travis-ci.org/joost/phony_rails) [![Coverage Status](https://coveralls.io/repos/joost/phony_rails/badge.svg)](https://coveralls.io/r/joost/phony_rails) ![Dependencies Status](https://img.shields.io/gem/v/phony_rails.svg)
2
2
 
3
3
  This small Gem adds useful methods to your Rails app to validate, display and save phone numbers.
4
4
  It uses the super awesome Phony gem (https://github.com/floere/phony).
@@ -7,10 +7,10 @@ Find version information in the [CHANGELOG](CHANGELOG.md).
7
7
 
8
8
  ## Installation
9
9
 
10
- Add this line to your application's Gemfile:
10
+ Add this line to your application's Gemfile (requires Ruby > 2.3):
11
11
 
12
12
  ```ruby
13
- gem 'phony_rails' # Include phony_rails after mongoid (if you use mongoid, see issue #66 on github).
13
+ gem 'phony_rails'
14
14
  ```
15
15
 
16
16
  And then execute:
@@ -66,18 +66,10 @@ class SomeModel
66
66
  end
67
67
  ```
68
68
 
69
- #### Mongoid
69
+ #### Mongoid (DEPRECATED)
70
70
 
71
- For **Mongoid**, in keeping with Mongoid plug-in conventions you must include the `Mongoid::Phony` module:
71
+ WARNING: From v0.15.0 Mongoid support has been removed!
72
72
 
73
- ```ruby
74
- class SomeModel
75
- include Mongoid::Document
76
- include Mongoid::Phony
77
-
78
- # methods are same as ActiveRecord usage
79
- end
80
- ```
81
73
  #### General info
82
74
 
83
75
  The `:default_country_code` options is used to specify a country_code when normalizing.
@@ -114,6 +106,7 @@ In your model use the Phony.plausible method to validate an attribute:
114
106
  ```ruby
115
107
  validates :phone_number, phony_plausible: true
116
108
  ```
109
+
117
110
  or the helper method:
118
111
 
119
112
  ```ruby
@@ -121,8 +114,9 @@ validates_plausible_phone :phone_number
121
114
  ```
122
115
 
123
116
  this method use other validators under the hood to provide:
124
- * presence validation using `ActiveModel::Validations::PresenceValidator`
125
- * format validation using `ActiveModel::Validations::FormatValidator`
117
+
118
+ - presence validation using `ActiveModel::Validations::PresenceValidator`
119
+ - format validation using `ActiveModel::Validations::FormatValidator`
126
120
 
127
121
  so we can use:
128
122
 
@@ -133,7 +127,7 @@ validates_plausible_phone :phone_number, without: /\A\+\d+/
133
127
  validates_plausible_phone :phone_number, presence: true, with: /\A\+\d+/
134
128
  ```
135
129
 
136
- the i18n key is `:improbable_phone`. Languages supported by default: de, en, fr, it, ja, kh, nl, tr, ua and ru.
130
+ the i18n key is `:improbable_phone`. Languages supported by default: de, en, es, fr, it, ja, kh, ko, nl, tr, ua and ru.
137
131
 
138
132
  You can also validate if a number has the correct country number:
139
133
 
@@ -156,13 +150,29 @@ validates_plausible_phone :phone_number_normalized, presence: true, if: :phone_n
156
150
 
157
151
  Validation supports phone numbers with extension, such as `+18181231234 x1234` or `'+1 (818)151-5483 #4312'` out-of-the-box.
158
152
 
153
+ Return original value after validation:
154
+
155
+ The flag normalize_when_valid (disabled by default), allows to return the original phone_number when is the object is not valid. When phone validation fails, normalization is not triggered at all. It could prevent a situation where user fills in the phone number and after validation, he gets back different, already normalized phone number value, even if phone number was wrong.
156
+
157
+ Example usage:
158
+
159
+ ```ruby
160
+ validates_plausible_phone :phone_number
161
+ phony_normalize :phone_number, country_code: :country_code, normalize_when_valid: true
162
+ ```
163
+
164
+ Filling in the number will result with following:
165
+
166
+ When the number is incorrect (e.g. phone_number: `+44 888 888 888` for country_code 'PL'), the original validation behavior is preserved, but if the number is still invalid, the original value is returned.
167
+ When number is valid, it will save the normalized number (e.g. `+48 888 888 888` will be saved as `+48888888888`).
168
+
159
169
  #### Allowing records country codes to not match phone number country codes
160
170
 
161
- You may have a record specifying one country (via a `country_code` attribute) but using a phone number from another country. For example, your record may be from Japan but have a phone number from the Philippines. By default, `phony_rails` will consider your record's `country_code` as part of the validation. If that country doesn't match the country code in the phone number, validation will fail.
171
+ You may have a record specifying one country (via a `country_code` attribute) but using a phone number from another country. For example, your record may be from Japan but have a phone number from the Philippines. By default, `phony_rails` will consider your record's `country_code` as part of the validation. If that country doesn't match the country code in the phone number, validation will fail.
162
172
 
163
173
  Additionally, `phony_normalize` will always add the records country code as the country number (eg. the user enters '+81xxx' for Japan and the records `country_code` is 'DE' then `phony_normalize` will change the number to '+4981'). You can turn this off by adding `enforce_record_country: false` to the validation options. The country_code will then only be added if no country code is specified.
164
174
 
165
- If you want to allow records from one country to have phone numbers from a different one, there are a couple of options you can use: `ignore_record_country_number` and `ignore_record_country_code`. Use them like so:
175
+ If you want to allow records from one country to have phone numbers from a different one, there are a couple of options you can use: `ignore_record_country_number` and `ignore_record_country_code`. Use them like so:
166
176
 
167
177
  ```ruby
168
178
  validates :phone_number, phony_plausible: { ignore_record_country_code: true, ignore_record_country_number: true }
@@ -216,7 +226,6 @@ Extensions are supported (identified by "ext", "ex", "x", "xt", "#", or ":") and
216
226
  "+31 (0)30 1234 123 #999".phony_normalized # => '31301234123 x999'
217
227
  ```
218
228
 
219
-
220
229
  ### Find by normalized number
221
230
 
222
231
  Say you want to find a record by a phone number. Best is to normalize user input and compare to an attribute stored in the db.
@@ -463,6 +463,8 @@ UA:
463
463
  country_code: '380'
464
464
  UG:
465
465
  country_code: '256'
466
+ UK:
467
+ country_code: '44'
466
468
  UM:
467
469
  country_code: ''
468
470
  US:
@@ -0,0 +1,4 @@
1
+ es:
2
+ errors:
3
+ messages:
4
+ improbable_phone: "es un número inválido"
@@ -0,0 +1,4 @@
1
+ ko:
2
+ errors:
3
+ messages:
4
+ improbable_phone: "는 올바른 전화번호가 아닙니다"
@@ -7,6 +7,7 @@ class String
7
7
  # "(0)30 1234 123".phony_normalized(country_code: 'NL') # => '301234123'
8
8
  def phony_normalized(options = {})
9
9
  raise ArgumentError, "Expected options to be a Hash, got #{options.inspect}" unless options.is_a?(Hash)
10
+
10
11
  options = options.dup
11
12
  PhonyRails.normalize_number(self, options)
12
13
  end
@@ -24,21 +25,25 @@ class String
24
25
  # "somestring".phone_formatted(raise: true)
25
26
  def phony_formatted(options = {})
26
27
  raise ArgumentError, "Expected options to be a Hash, got #{options.inspect}" unless options.is_a?(Hash)
28
+
27
29
  options = options.dup
28
30
  normalize_country_code = options.delete(:normalize)
29
31
  s, ext = PhonyRails.extract_extension(self)
30
32
  s = (normalize_country_code ? PhonyRails.normalize_number(s, default_country_code: normalize_country_code.to_s, add_plus: false) : s.gsub(/\D/, ''))
31
33
  return if s.blank?
32
34
  return if options[:strict] && !Phony.plausible?(s)
35
+
33
36
  PhonyRails.format_extension(Phony.format(s, options.reverse_merge(format: :national)), ext)
34
37
  rescue StandardError
35
38
  raise if options[:raise]
39
+
36
40
  s
37
41
  end
38
42
 
39
43
  # The bang method
40
44
  def phony_formatted!(options = {})
41
45
  raise ArgumentError, 'The :strict options is only supported in the phony_formatted (non bang) method.' if options[:strict]
46
+
42
47
  replace(phony_formatted(options))
43
48
  end
44
49
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PhonyRails
4
- VERSION = '0.14.7'
4
+ VERSION = '0.15.0'
5
5
  end
data/lib/phony_rails.rb CHANGED
@@ -44,21 +44,21 @@ module PhonyRails
44
44
  # :extension => Include the extension. (default: true)
45
45
  # This idea came from:
46
46
  # http://www.redguava.com.au/2011/06/rails-convert-phone-numbers-to-international-format-for-sms/
47
- def self.normalize_number(number, options = {})
47
+ def self.normalize_number(number, options = {}, current_instance = nil)
48
48
  return if number.nil?
49
+
49
50
  original_number = number
50
51
  number = number.dup # Just to be sure, we don't want to change the original.
51
52
  number, ext = extract_extension(number)
52
- number.gsub!(/[^\(\)\d\+]/, '') # Strips weird stuff from the number
53
+ number.gsub!(/[^()\d+]/, '') # Strips weird stuff from the number
53
54
  return if number.blank?
55
+
54
56
  if _country_number = options[:country_number] || country_number_for(options[:country_code])
55
57
  options[:add_plus] = true if options[:add_plus].nil?
56
58
  # (Force) add country_number if missing
57
59
  # NOTE: do we need to force adding country code? Otherwise we can share logic with next block
58
- if !Phony.plausible?(number) || _country_number != country_code_from_number(number)
59
- number = "#{_country_number}#{number}"
60
- end
61
- elsif _default_country_number = extract_default_country_number(options)
60
+ number = "#{_country_number}#{number}" if !Phony.plausible?(number) || _country_number != country_code_from_number(number)
61
+ elsif _default_country_number = extract_default_country_number(options, current_instance)
62
62
  options[:add_plus] = true if options[:add_plus].nil?
63
63
  number = normalize_number_default_country(number, _default_country_number)
64
64
  end
@@ -67,8 +67,7 @@ module PhonyRails
67
67
  normalized_number = options[:add_plus] ? "+#{normalized_number}" : normalized_number
68
68
 
69
69
  options[:extension] = true if options[:extension].nil?
70
- normalized_number = options[:extension] ? format_extension(normalized_number, ext) : normalized_number
71
- normalized_number
70
+ options[:extension] ? format_extension(normalized_number, ext) : normalized_number
72
71
  rescue StandardError
73
72
  original_number # If all goes wrong .. we still return the original input.
74
73
  end
@@ -76,7 +75,7 @@ module PhonyRails
76
75
  def self.normalize_number_default_country(number, default_country_number)
77
76
  # We try to add the default country number and see if it is a
78
77
  # correct phone number. See https://github.com/joost/phony_rails/issues/87#issuecomment-89324426
79
- unless number =~ /\A\+/ # if we don't have a +
78
+ unless number =~ /\A\(?(\+|00)/ # if we don't have a + or 00
80
79
  return "#{default_country_number}#{number}" if Phony.plausible?("#{default_country_number}#{number}") || !Phony.plausible?(number) || country_code_from_number(number).nil?
81
80
  # If the number starts with ONE zero (two might indicate a country code)
82
81
  # and this is a plausible number for the default_country
@@ -88,27 +87,40 @@ module PhonyRails
88
87
  number
89
88
  end
90
89
 
91
- def self.extract_default_country_number(options = {})
92
- options[:default_country_number] || country_number_for(options[:default_country_code]) || default_country_number
90
+ def self.extract_default_country_number(options = {}, current_instance = nil)
91
+ country_code = if current_instance.present? && options[:default_country_code].respond_to?(:call)
92
+ options[:default_country_code].call(current_instance) rescue nil
93
+ else
94
+ options[:default_country_code]
95
+ end
96
+ options[:default_country_number] || country_number_for(country_code) || default_country_number
93
97
  end
94
98
 
99
+ # Returns the country dail code (eg. '31') for a number (eg. +31612341234).
100
+ # Should probably be named 'country_number_from_number'.
95
101
  def self.country_code_from_number(number)
96
102
  return nil unless Phony.plausible?(number)
103
+
97
104
  Phony.split(Phony.normalize(number)).first
98
105
  end
99
106
 
107
+ # Returns the country (eg. 'NL') for a number (eg. +31612341234).
100
108
  def self.country_from_number(number)
101
109
  return nil unless Phony.plausible?(number)
110
+
102
111
  country_codes_hash.select { |_country, hash| hash['country_code'] == country_code_from_number(number) }.keys[0]
103
112
  end
104
113
 
105
114
  # Wrapper for Phony.plausible?. Takes the same options as #normalize_number.
106
115
  # NB: This method calls #normalize_number and passes _options_ directly to that method.
116
+ # It uses the 'cc' option for Phony. This was a required param before?
107
117
  def self.plausible_number?(number, options = {})
108
118
  return false if number.blank?
119
+
109
120
  number = extract_extension(number).first
110
121
  number = normalize_number(number, options)
111
122
  country_number = options[:country_number] || country_number_for(options[:country_code]) ||
123
+ country_code_from_number(number) ||
112
124
  options[:default_country_number] || country_number_for(options[:default_country_code]) ||
113
125
  default_country_number
114
126
  Phony.plausible? number, cc: country_number
@@ -116,10 +128,11 @@ module PhonyRails
116
128
  false
117
129
  end
118
130
 
119
- COMMON_EXTENSIONS = /[ ]*(ext|ex|x|xt|#|:)+[^0-9]*\(?([-0-9]{1,})\)?#?$/i
131
+ COMMON_EXTENSIONS = / *(ext|ex|x|xt|#|:)+[^0-9]*\(?([-0-9]{1,})\)?#?$/i.freeze
120
132
 
121
133
  def self.extract_extension(number_and_ext)
122
134
  return [nil, nil] if number_and_ext.nil?
135
+
123
136
  subbed = number_and_ext.sub(COMMON_EXTENSIONS, '')
124
137
  [subbed, Regexp.last_match(2)]
125
138
  end
@@ -136,7 +149,7 @@ module PhonyRails
136
149
 
137
150
  # This methods sets the attribute to the normalized version.
138
151
  # It also adds the country_code (number), eg. 31 for NL numbers.
139
- def set_phony_normalized_numbers(attributes, options = {})
152
+ def set_phony_normalized_numbers(current_instance, attributes, options = {})
140
153
  options = options.dup
141
154
  assign_values_for_phony_symbol_options(options)
142
155
  if respond_to?(:country_code)
@@ -146,8 +159,10 @@ module PhonyRails
146
159
  attributes.each do |attribute|
147
160
  attribute_name = options[:as] || attribute
148
161
  raise("No attribute #{attribute_name} found on #{self.class.name} (PhonyRails)") unless self.class.attribute_method?(attribute_name)
149
- new_value = PhonyRails.normalize_number(send(attribute), options)
150
- send("#{attribute_name}=", new_value) if new_value || attribute_name != attribute
162
+
163
+ cache_original_attribute(current_instance, attribute) if options[:normalize_when_valid]
164
+ new_value = PhonyRails.normalize_number(send(attribute), options, current_instance)
165
+ current_instance.public_send("#{attribute_name}=", new_value) if new_value || attribute_name != attribute
151
166
  end
152
167
  end
153
168
 
@@ -159,7 +174,26 @@ module PhonyRails
159
174
  end
160
175
  end
161
176
 
177
+ def cache_original_attribute(current_instance, attribute)
178
+ attribute_name = "#{attribute}_original"
179
+ current_instance.define_singleton_method("#{attribute_name}=") { |value| instance_variable_set("@#{attribute_name}", value) }
180
+ current_instance.define_singleton_method(attribute_name) { instance_variable_get("@#{attribute_name}") }
181
+ current_instance.public_send("#{attribute}_original=", current_instance.public_send(attribute.to_s))
182
+ end
183
+
162
184
  module ClassMethods
185
+ PHONY_RAILS_COLLECTION_VALID_KEYS = %i[
186
+ add_plus
187
+ as
188
+ country_code
189
+ country_number
190
+ default_country_code
191
+ default_country_number
192
+ enforce_record_country
193
+ if
194
+ normalize_when_valid
195
+ unless
196
+ ].freeze
163
197
  # Use this method on the class level like:
164
198
  # phony_normalize :phone_number, :fax_number, :default_country_code => 'NL'
165
199
  #
@@ -167,10 +201,8 @@ module PhonyRails
167
201
  # you've geocoded before calling this method!
168
202
  def phony_normalize(*attributes)
169
203
  options = attributes.last.is_a?(Hash) ? attributes.pop : {}
170
- options.assert_valid_keys :country_number, :default_country_number, :country_code, :default_country_code, :add_plus, :as, :enforce_record_country, :if, :unless
171
- if options[:as].present?
172
- raise ArgumentError, ':as option can not be used on phony_normalize with multiple attribute names! (PhonyRails)' if attributes.size > 1
173
- end
204
+ options.assert_valid_keys(*PHONY_RAILS_COLLECTION_VALID_KEYS)
205
+ raise ArgumentError, ':as option can not be used on phony_normalize with multiple attribute names! (PhonyRails)' if options[:as].present? && (attributes.size > 1)
174
206
 
175
207
  options[:enforce_record_country] = true if options[:enforce_record_country].nil?
176
208
 
@@ -178,7 +210,7 @@ module PhonyRails
178
210
 
179
211
  # Add before validation that saves a normalized version of the phone number
180
212
  before_validation conditional do
181
- set_phony_normalized_numbers(attributes, options)
213
+ set_phony_normalized_numbers(self, attributes, options)
182
214
  end
183
215
  end
184
216
 
@@ -190,10 +222,12 @@ module PhonyRails
190
222
  main_options.assert_valid_keys :country_code, :default_country_code
191
223
  attributes.each do |attribute|
192
224
  raise(StandardError, "Instance method normalized_#{attribute} already exists on #{name} (PhonyRails)") if method_defined?(:"normalized_#{attribute}")
225
+
193
226
  define_method :"normalized_#{attribute}" do |*args|
194
227
  options = main_options.merge(args.first || {})
195
228
  assign_values_for_phony_symbol_options(options)
196
229
  raise(ArgumentError, "No attribute/method #{attribute} found on #{self.class.name} (PhonyRails)") unless respond_to?(attribute)
230
+
197
231
  options[:country_code] ||= country_code if respond_to?(:country_code)
198
232
  PhonyRails.normalize_number(send(attribute), options)
199
233
  end
@@ -241,12 +275,12 @@ end
241
275
 
242
276
  ActiveModel::Model.send :include, PhonyRails::Extension if defined?(ActiveModel::Model)
243
277
 
244
- if defined?(Mongoid)
245
- module Mongoid::Phony
246
- extend ActiveSupport::Concern
247
- include PhonyRails::Extension
248
- end
249
- end
278
+ # if defined?(Mongoid)
279
+ # module Mongoid::Phony
280
+ # extend ActiveSupport::Concern
281
+ # include PhonyRails::Extension
282
+ # end
283
+ # end
250
284
 
251
285
  Dir["#{File.dirname(__FILE__)}/phony_rails/locales/*.yml"].each do |file|
252
286
  I18n.load_path << file
@@ -4,6 +4,7 @@
4
4
  # Usage:
5
5
  # validate :phone_number, :phony_plausible => true
6
6
  require 'active_model'
7
+
7
8
  class PhonyPlausibleValidator < ActiveModel::EachValidator
8
9
  # Validates a String using Phony.plausible? method.
9
10
  def validate_each(record, attribute, value)
@@ -13,6 +14,8 @@ class PhonyPlausibleValidator < ActiveModel::EachValidator
13
14
  value = PhonyRails.normalize_number(value.dup, default_country_code: normalized_country_code) if normalized_country_code
14
15
  value = PhonyRails.extract_extension(value).first
15
16
  @record.errors.add(attribute, error_message) unless Phony.plausible?(value, cc: country_number)
17
+ @record.public_send("#{attribute}=", @record.public_send("#{attribute}_original")) if @record.respond_to?("#{attribute}_original") &&
18
+ !Phony.plausible?(value, cc: country_number)
16
19
  end
17
20
 
18
21
  private
data/phony_rails.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../lib/phony_rails/version', __FILE__)
3
+ require File.expand_path('lib/phony_rails/version', __dir__)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
  gem.authors = ['Joost Hietbrink']
@@ -16,12 +16,14 @@ Gem::Specification.new do |gem|
16
16
  gem.name = 'phony_rails'
17
17
  gem.require_paths = ['lib']
18
18
  gem.version = PhonyRails::VERSION
19
+ gem.required_ruby_version = '>= 2.4'
19
20
 
20
- gem.post_install_message = 'PhonyRails v0.10.0 changes the way numbers are stored!'
21
- gem.post_install_message = "It now adds a '+' to the normalized number when it starts with a country number!"
21
+ gem.post_install_message = "PhonyRails v0.10.0 changes the way numbers are stored!\nIt now adds a ' + ' to the normalized number when it starts with a country number!"
22
22
 
23
23
  gem.add_runtime_dependency 'activesupport', '>= 3.0'
24
- gem.add_runtime_dependency 'phony', '> 2.15'
24
+ gem.add_runtime_dependency 'phony', '>= 2.18.12'
25
25
  gem.add_development_dependency 'activerecord', '>= 3.0'
26
- gem.add_development_dependency 'mongoid', '>= 3.0'
26
+
27
+ # For testing
28
+ gem.add_development_dependency 'sqlite3', '>= 1.4.0'
27
29
  end