phonelib 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/{README.rdoc → README.md} +116 -75
  3. data/data/extended_data.dat +0 -0
  4. data/data/libphonenumber/FALSEHOODS.md +16 -0
  5. data/data/libphonenumber/FAQ.md +8 -0
  6. data/data/libphonenumber/README.md +1 -1
  7. data/data/libphonenumber/cpp/src/phonenumbers/alternate_format.cc +108 -100
  8. data/data/libphonenumber/cpp/src/phonenumbers/lite_metadata.cc +10070 -10016
  9. data/data/libphonenumber/cpp/src/phonenumbers/metadata.cc +10938 -10884
  10. data/data/libphonenumber/cpp/src/phonenumbers/short_metadata.cc +2481 -2455
  11. data/data/libphonenumber/java/carrier/pom.xml +26 -4
  12. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/255_en +0 -0
  13. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/374_en +0 -0
  14. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/374_ru +0 -0
  15. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/421_en +0 -0
  16. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/66_en +0 -0
  17. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/91_en +0 -0
  18. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/93_fa +0 -0
  19. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/973_en +0 -0
  20. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/98_fa +0 -0
  21. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/992_en +0 -0
  22. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/994_en +0 -0
  23. data/data/libphonenumber/java/carrier/src/com/google/i18n/phonenumbers/carrier/data/config +0 -0
  24. data/data/libphonenumber/java/demo/pom.xml +6 -6
  25. data/data/libphonenumber/java/geocoder/pom.xml +26 -4
  26. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1747_en +0 -0
  27. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/1934_en +0 -0
  28. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/371_en +0 -0
  29. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/44_en +0 -0
  30. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/504_en +0 -0
  31. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_bg +0 -0
  32. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_ca +0 -0
  33. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_el +0 -0
  34. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_es +0 -0
  35. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_fi +0 -0
  36. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_hi +0 -0
  37. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_hu +0 -0
  38. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_iw +0 -0
  39. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_ja +0 -0
  40. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/82_tr +0 -0
  41. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/91_en +0 -0
  42. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/93_en +0 -0
  43. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/93_fa +0 -0
  44. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/98_en +0 -0
  45. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/98_fa +0 -0
  46. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/992_en +0 -0
  47. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/994_en +0 -0
  48. data/data/libphonenumber/java/geocoder/src/com/google/i18n/phonenumbers/geocoding/data/config +0 -0
  49. data/data/libphonenumber/java/internal/prefixmapper/pom.xml +25 -3
  50. data/data/libphonenumber/java/libphonenumber/pom.xml +23 -2
  51. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/MetadataLoader.java +2 -1
  52. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/MultiFileMetadataSourceImpl.java +63 -70
  53. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberAlternateFormatsProto_595 +0 -0
  54. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_AZ +0 -0
  55. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BD +0 -0
  56. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BG +0 -0
  57. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_BH +0 -0
  58. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CI +0 -0
  59. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_CN +0 -0
  60. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HK +0 -0
  61. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_HN +0 -0
  62. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN +0 -0
  63. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KN +0 -0
  64. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_KW +0 -0
  65. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_LV +0 -0
  66. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PY +0 -0
  67. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SK +0 -0
  68. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_SN +0 -0
  69. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TC +0 -0
  70. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TH +0 -0
  71. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TJ +0 -0
  72. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_TZ +0 -0
  73. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_US +0 -0
  74. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AE +0 -0
  75. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_AR +0 -0
  76. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_BR +0 -0
  77. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_GB +0 -0
  78. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_IN +0 -0
  79. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_NO +0 -0
  80. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_SK +0 -0
  81. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/ShortNumberMetadataProto_ZA +0 -0
  82. data/data/libphonenumber/java/libphonenumber/src/com/google/i18n/phonenumbers/data/SingleFilePhoneNumberMetadataProto +0 -0
  83. data/data/libphonenumber/java/libphonenumber/test/com/google/i18n/phonenumbers/MultiFileMetadataSourceImplTest.java +25 -5
  84. data/data/libphonenumber/java/pom.xml +2 -2
  85. data/data/libphonenumber/java/release_notes.txt +45 -0
  86. data/data/libphonenumber/javascript/i18n/phonenumbers/demo-compiled.js +72 -70
  87. data/data/libphonenumber/javascript/i18n/phonenumbers/metadata.js +38 -32
  88. data/data/libphonenumber/javascript/i18n/phonenumbers/metadatalite.js +38 -32
  89. data/data/libphonenumber/resources/PhoneNumberAlternateFormats.xml +16 -0
  90. data/data/libphonenumber/resources/PhoneNumberMetadata.xml +232 -96
  91. data/data/libphonenumber/resources/ShortNumberMetadata.xml +188 -44
  92. data/data/libphonenumber/resources/carrier/en/255.txt +2 -0
  93. data/data/libphonenumber/resources/carrier/en/374.txt +3 -3
  94. data/data/libphonenumber/resources/carrier/en/421.txt +1 -0
  95. data/data/libphonenumber/resources/carrier/en/66.txt +1 -0
  96. data/data/libphonenumber/resources/carrier/en/91.txt +419 -253
  97. data/data/libphonenumber/resources/carrier/en/973.txt +1 -0
  98. data/data/libphonenumber/resources/carrier/en/992.txt +1 -0
  99. data/data/libphonenumber/resources/carrier/en/994.txt +3 -0
  100. data/data/libphonenumber/resources/carrier/fa/93.txt +24 -0
  101. data/data/libphonenumber/resources/carrier/fa/98.txt +30 -0
  102. data/data/libphonenumber/resources/carrier/ru/374.txt +28 -0
  103. data/data/libphonenumber/resources/geocoding/bg/82.txt +34 -0
  104. data/data/libphonenumber/resources/geocoding/ca/82.txt +34 -0
  105. data/data/libphonenumber/resources/geocoding/el/82.txt +28 -0
  106. data/data/libphonenumber/resources/geocoding/en/1.txt +2 -0
  107. data/data/libphonenumber/resources/geocoding/en/371.txt +3 -0
  108. data/data/libphonenumber/resources/geocoding/en/44.txt +19 -1
  109. data/data/libphonenumber/resources/geocoding/en/504.txt +19 -0
  110. data/data/libphonenumber/resources/geocoding/en/91.txt +1 -5
  111. data/data/libphonenumber/resources/geocoding/en/93.txt +52 -0
  112. data/data/libphonenumber/resources/geocoding/en/98.txt +0 -2
  113. data/data/libphonenumber/resources/geocoding/en/992.txt +77 -0
  114. data/data/libphonenumber/resources/geocoding/en/994.txt +98 -0
  115. data/data/libphonenumber/resources/geocoding/es/82.txt +33 -0
  116. data/data/libphonenumber/resources/geocoding/fa/93.txt +53 -0
  117. data/data/libphonenumber/resources/geocoding/fa/98.txt +0 -2
  118. data/data/libphonenumber/resources/geocoding/fi/82.txt +34 -0
  119. data/data/libphonenumber/resources/geocoding/hi/82.txt +36 -0
  120. data/data/libphonenumber/resources/geocoding/hu/82.txt +35 -0
  121. data/data/libphonenumber/resources/geocoding/iw/82.txt +37 -0
  122. data/data/libphonenumber/resources/geocoding/ja/82.txt +35 -0
  123. data/data/libphonenumber/resources/geocoding/tr/82.txt +35 -0
  124. data/data/libphonenumber/tools/java/common/pom.xml +2 -0
  125. data/data/libphonenumber/tools/java/cpp-build/pom.xml +4 -0
  126. data/data/libphonenumber/tools/java/data/pom.xml +1 -11
  127. data/data/libphonenumber/tools/java/java-build/pom.xml +2 -0
  128. data/data/phone_data.dat +0 -0
  129. data/lib/phonelib.rb +7 -6
  130. data/lib/phonelib/core.rb +116 -68
  131. data/lib/phonelib/data_importer.rb +23 -19
  132. data/lib/phonelib/data_importer_helper.rb +16 -16
  133. data/lib/phonelib/phone.rb +47 -137
  134. data/lib/phonelib/phone_analyzer.rb +27 -25
  135. data/lib/phonelib/phone_analyzer_helper.rb +16 -9
  136. data/lib/phonelib/phone_extended_data.rb +27 -17
  137. data/lib/phonelib/phone_formatter.rb +131 -0
  138. data/lib/phonelib/version.rb +2 -3
  139. data/lib/tasks/phonelib_tasks.rake +0 -2
  140. data/lib/validators/phone_validator.rb +24 -14
  141. metadata +42 -3
@@ -1,5 +1,5 @@
1
1
  module Phonelib
2
- # phone analyzing methods module
2
+ # @private phone analyzing methods module
3
3
  module PhoneAnalyzer
4
4
  # extending with helper methods for analyze
5
5
  include Phonelib::PhoneAnalyzerHelper
@@ -7,8 +7,8 @@ module Phonelib
7
7
  # array of types not included for validation check in cycle
8
8
  NOT_FOR_CHECK = [:general_desc, :fixed_line, :mobile, :fixed_or_mobile]
9
9
 
10
- # parses provided phone if it is valid for country data and returns result of
11
- # analyze
10
+ # parses provided phone if it is valid for country data and
11
+ # returns result of analyze
12
12
  #
13
13
  # ==== Attributes
14
14
  #
@@ -20,7 +20,9 @@ module Phonelib
20
20
 
21
21
  result = try_to_parse_single_country(phone, country)
22
22
  # if previous parsing failed, trying for all countries
23
- if passed_country.nil? && (result.nil? || result.empty? || result.values.first[:valid].empty?)
23
+ if passed_country.nil? && \
24
+ (result.nil? || result.empty? || result.values.first[:valid].empty?)
25
+
24
26
  detected = detect_and_parse phone
25
27
  result = detected.empty? ? result || {} : detected
26
28
  end
@@ -38,18 +40,18 @@ module Phonelib
38
40
  # * +country+ - country to parse phone with
39
41
  def try_to_parse_single_country(phone, country)
40
42
  data = Phonelib.phone_data[country]
41
- if country && data
42
- # if country was provided and it's a valid country, trying to
43
- # create e164 representation of phone number,
44
- # kind of normalization for parsing
45
- e164 = convert_to_e164 phone, data
46
- # if phone starts with international prefix of provided
47
- # country try to reanalyze without international prefix for
48
- # all countries
49
- return analyze(e164.gsub('+', ''), nil) if e164[0] == '+'
50
- # trying to parse number for provided country
51
- parse_single_country e164, data
52
- end
43
+ return nil unless country && data
44
+
45
+ # if country was provided and it's a valid country, trying to
46
+ # create e164 representation of phone number,
47
+ # kind of normalization for parsing
48
+ e164 = convert_to_e164 phone, data
49
+ # if phone starts with international prefix of provided
50
+ # country try to reanalyze without international prefix for
51
+ # all countries
52
+ return analyze(e164.delete('+'), nil) if e164[0] == '+'
53
+ # trying to parse number for provided country
54
+ parse_single_country e164, data
53
55
  end
54
56
 
55
57
  # method checks if phone is valid against single provided country data
@@ -61,10 +63,10 @@ module Phonelib
61
63
  def parse_single_country(e164, data)
62
64
  valid_match = phone_match_data?(e164, data)
63
65
  if valid_match
64
- get_national_and_data(e164, data, valid_match)
66
+ national_and_data(e164, data, valid_match)
65
67
  else
66
68
  possible_match = phone_match_data?(e164, data, true)
67
- possible_match && get_national_and_data(e164, data, possible_match, true)
69
+ possible_match && national_and_data(e164, data, possible_match, true)
68
70
  end
69
71
  end
70
72
 
@@ -112,14 +114,14 @@ module Phonelib
112
114
  # * +data+ - country data
113
115
  # * +country_match+ - result of match of phone within full regex
114
116
  # * +not_valid+ - specifies that number is not valid by general desc pattern
115
- def get_national_and_data(phone, data, country_match, not_valid = false)
117
+ def national_and_data(phone, data, country_match, not_valid = false)
116
118
  prefix_length = data[Core::COUNTRY_CODE].length
117
119
  prefix_length += [1, 2].map { |i| country_match[i].to_s.size }.inject(:+)
118
- result = data.select { |k, v| k != :types && k != :formats }
120
+ result = data.select { |k, _v| k != :types && k != :formats }
119
121
  result[:national] = phone[prefix_length..-1] || ''
120
- result[:format] = get_number_format(result[:national],
121
- data[Core::FORMATS])
122
- result.merge! all_number_types(result[:national], data[Core::TYPES], not_valid)
122
+ result[:format] = number_format(result[:national], data[Core::FORMATS])
123
+ result.merge! all_number_types(result[:national], data[Core::TYPES],
124
+ not_valid)
123
125
  result[:valid] = [] if not_valid
124
126
 
125
127
  { result[:id] => result }
@@ -154,10 +156,10 @@ module Phonelib
154
156
  #
155
157
  # * +national+ - national phone number
156
158
  # * +format_data+ - formatting data from country data
157
- def get_number_format(national, format_data)
159
+ def number_format(national, format_data)
158
160
  format_data && format_data.find do |format|
159
161
  (format[Core::LEADING_DIGITS].nil? \
160
- || national.match(cr("^(#{format[Core::LEADING_DIGITS]})"))) \
162
+ || national.match(cr("^(#{format[Core::LEADING_DIGITS]})"))) \
161
163
  && national.match(cr("^(#{format[Core::PATTERN]})$"))
162
164
  end || Core::DEFAULT_NUMBER_FORMAT
163
165
  end
@@ -1,13 +1,14 @@
1
1
  module Phonelib
2
- # helper methods for analyser
2
+ # @private helper methods for analyser
3
3
  module PhoneAnalyzerHelper
4
4
  private
5
5
 
6
6
  # defines if to validate against single country or not
7
7
  def passed_country(country)
8
- country_code = country_prefix(country)
9
- if @original.start_with?('+') && country_code && !sanitized.start_with?(country_code)
10
- # in case number passed with + but it doesn't start with passed country prefix
8
+ code = country_prefix(country)
9
+ if @original.start_with?('+') && code && !sanitized.start_with?(code)
10
+ # in case number passed with + but it doesn't start with passed
11
+ # country prefix
11
12
  country = nil
12
13
  end
13
14
  country
@@ -16,7 +17,8 @@ module Phonelib
16
17
  # returns country prefix for provided country or nil
17
18
  def country_prefix(country)
18
19
  country = country.to_s.upcase
19
- Phonelib.phone_data[country] && Phonelib.phone_data[country][Core::COUNTRY_CODE]
20
+ Phonelib.phone_data[country] && \
21
+ Phonelib.phone_data[country][Core::COUNTRY_CODE]
20
22
  end
21
23
 
22
24
  # caches regular expression, reusing it for later lookups
@@ -33,8 +35,13 @@ module Phonelib
33
35
  # * +parsed+ - parsed regex match for phone
34
36
  def allows_double_prefix(data, phone, parsed)
35
37
  data[Core::DOUBLE_COUNTRY_PREFIX_FLAG] &&
36
- phone =~ cr("^#{data[Core::COUNTRY_CODE]}") &&
37
- parsed && (parsed[:valid].nil? || parsed[:valid].empty?)
38
+ phone =~ cr("^#{data[Core::COUNTRY_CODE]}") &&
39
+ parsed && (parsed[:valid].nil? || parsed[:valid].empty?)
40
+ end
41
+
42
+ # Returns original number passed if it's a string or empty string otherwise
43
+ def original_string
44
+ @original.is_a?(String) ? @original : ''
38
45
  end
39
46
 
40
47
  # Get country that was provided or default country in needable format
@@ -43,7 +50,7 @@ module Phonelib
43
50
  #
44
51
  # * +country+ - country passed for parsing
45
52
  def country_or_default_country(country)
46
- country = country || Phonelib.default_country
53
+ country ||= (original_string.start_with?('+') ? nil : Phonelib.default_country)
47
54
  country && country.to_s.upcase
48
55
  end
49
56
 
@@ -143,4 +150,4 @@ module Phonelib
143
150
  [valid && possible, possible]
144
151
  end
145
152
  end
146
- end
153
+ end
@@ -1,8 +1,16 @@
1
1
  module Phonelib
2
2
  # module provides extended data methods for parsed phone
3
3
  module PhoneExtendedData
4
+ # @private keys for extended data
5
+ EXT_KEYS = [
6
+ Phonelib::Core::EXT_GEO_NAME_KEY,
7
+ Phonelib::Core::EXT_TIMEZONE_KEY,
8
+ Phonelib::Core::EXT_CARRIER_KEY
9
+ ]
10
+
4
11
  # Returns geo name of parsed phone number or nil if number is invalid or
5
12
  # there is no geo name specified in db for this number
13
+ # @return [String|nil] geo name for parsed phone
6
14
  def geo_name
7
15
  get_ext_name Phonelib::Core::EXT_GEO_NAMES,
8
16
  Phonelib::Core::EXT_GEO_NAME_KEY
@@ -10,6 +18,7 @@ module Phonelib
10
18
 
11
19
  # Returns timezone of parsed phone number or nil if number is invalid or
12
20
  # there is no timezone specified in db for this number
21
+ # @return [String|nil] timezone for parsed phone
13
22
  def timezone
14
23
  get_ext_name Phonelib::Core::EXT_TIMEZONES,
15
24
  Phonelib::Core::EXT_TIMEZONE_KEY
@@ -17,6 +26,7 @@ module Phonelib
17
26
 
18
27
  # Returns carrier of parsed phone number or nil if number is invalid or
19
28
  # there is no carrier specified in db for this number
29
+ # @return [String|nil] carrier for parsed phone
20
30
  def carrier
21
31
  get_ext_name Phonelib::Core::EXT_CARRIERS,
22
32
  Phonelib::Core::EXT_CARRIER_KEY
@@ -24,7 +34,7 @@ module Phonelib
24
34
 
25
35
  private
26
36
 
27
- # get name from extended phone data by keys
37
+ # @private get name from extended phone data by keys
28
38
  #
29
39
  # ==== Attributes
30
40
  #
@@ -32,37 +42,37 @@ module Phonelib
32
42
  # * +id_key+ - parameter id key in resolved extended data for number
33
43
  #
34
44
  def get_ext_name(names_key, id_key)
35
- if ext_data[id_key] > 0
36
- res = Phonelib.phone_ext_data[names_key][ext_data[id_key]]
37
- res.size == 1 ? res.first : res
38
- end
45
+ return nil unless ext_data[id_key] > 0
46
+
47
+ res = Phonelib.phone_ext_data[names_key][ext_data[id_key]]
48
+ res.size == 1 ? res.first : res
39
49
  end
40
50
 
41
- # returns extended data ids for current number
51
+ # @private returns extended data ids for current number
42
52
  def ext_data
43
53
  return @ext_data if @ext_data
44
54
 
45
- ext_keys = [
46
- Phonelib::Core::EXT_GEO_NAME_KEY,
47
- Phonelib::Core::EXT_TIMEZONE_KEY,
48
- Phonelib::Core::EXT_CARRIER_KEY
49
- ]
50
- result = {}
51
- ext_keys.each { |key| result[key] = 0 }
52
-
55
+ result = default_ext_data
53
56
  return result unless possible?
54
57
 
55
58
  drill = Phonelib.phone_ext_data[Phonelib::Core::EXT_PREFIXES]
56
59
 
57
- e164.gsub('+', '').each_char do |num|
60
+ e164.delete('+').each_char do |num|
58
61
  drill = drill[num.to_i] || break
59
62
 
60
- ext_keys.each do |key|
63
+ EXT_KEYS.each do |key|
61
64
  result[key] = drill[key] if drill[key]
62
65
  end
63
66
  end
64
67
 
65
68
  @ext_data = result
66
69
  end
70
+
71
+ # @private default extended data
72
+ def default_ext_data
73
+ result = {}
74
+ EXT_KEYS.each { |key| result[key] = 0 }
75
+ result
76
+ end
67
77
  end
68
- end
78
+ end
@@ -0,0 +1,131 @@
1
+ module Phonelib
2
+ # module includes all formatting methods
3
+ module PhoneFormatter
4
+ # Returns formatted national number
5
+ # @param formatted [Boolean] whether to return numbers only or formatted
6
+ # @return [String] formatted national number
7
+ def national(formatted = true)
8
+ return @national_number unless valid?
9
+ format_match, format_string = formatting_data
10
+
11
+ if format_match
12
+ out = format_string.gsub(/\$\d/) { |el| format_match[el[1].to_i] }
13
+ formatted ? out : out.gsub(/[^0-9]/, '')
14
+ else
15
+ @national_number
16
+ end
17
+ end
18
+
19
+ # Returns the country code from the original phone number.
20
+ # @return [String] matched country phone code
21
+ def country_code
22
+ Phonelib.phone_data[country] && \
23
+ Phonelib.phone_data[country][Core::COUNTRY_CODE]
24
+ end
25
+
26
+ # Returns e164 formatted phone number
27
+ # @param formatted [Boolean] whether to return numbers only or formatted
28
+ # @return [String] formatted international number
29
+ def international(formatted = true)
30
+ return nil if sanitized.nil? || sanitized.empty?
31
+ return "+#{country_prefix_or_not}#{sanitized}" unless valid?
32
+ return "#{country_code}#{@national_number}" unless formatted
33
+
34
+ format = @data[country][:format]
35
+ if (matches = @national_number.match(/#{format[Core::PATTERN]}/))
36
+ fmt = format[:intl_format] || format[:format]
37
+ national = fmt.gsub(/\$\d/) { |el| matches[el[1].to_i] }
38
+ else
39
+ national = @national_number
40
+ end
41
+
42
+ "+#{country_code} #{national}"
43
+ end
44
+
45
+ # returns national formatted number with extension added
46
+ # @return [String] formatted national number with extension
47
+ def full_national
48
+ "#{national}#{formatted_extension}"
49
+ end
50
+
51
+ # returns international formatted number with extension added
52
+ # @return [String] formatted internation phone number with extension
53
+ def full_international
54
+ "#{international}#{formatted_extension}"
55
+ end
56
+
57
+ # returns e164 format of phone with extension added
58
+ # @return [String] phone formatted in E164 format with extension
59
+ def full_e164
60
+ "#{e164}#{formatted_extension}"
61
+ end
62
+
63
+ # Returns e164 unformatted phone number
64
+ # @return [String] phone formatted in E164 format
65
+ def e164
66
+ international = self.international
67
+ international && international.gsub(/[^+0-9]/, '')
68
+ end
69
+
70
+ # returns area code of parsed number
71
+ # @return [String|nil] parsed phone area code if available
72
+ def area_code
73
+ return nil unless area_code_possible?
74
+
75
+ format_match, _format_string = formatting_data
76
+ take_group = 1
77
+ if type == Core::MOBILE && Core::AREA_CODE_MOBILE_TOKENS[country] && \
78
+ format_match[1] == Core::AREA_CODE_MOBILE_TOKENS[country]
79
+ take_group = 2
80
+ end
81
+ format_match[take_group]
82
+ end
83
+
84
+ private
85
+
86
+ # @private defines if phone can have area code
87
+ def area_code_possible?
88
+ return false unless possible?
89
+
90
+ # has national prefix
91
+ return false unless @data[country][Core::NATIONAL_PREFIX] || country == 'IT'
92
+ # fixed or mobile
93
+ return false unless Core::AREA_CODE_TYPES.include?(type)
94
+ # mobile && mexico, argentina, brazil
95
+ return false if type == Core::MOBILE && !Core::AREA_CODE_MOBILE_COUNTRIES.include?(country)
96
+ true
97
+ end
98
+
99
+ # @private defines whether to put country prefix or not
100
+ def country_prefix_or_not
101
+ return '' unless country_code
102
+ sanitized.start_with?(country_code) ? '' : country_code
103
+ end
104
+
105
+ # @private returns extension with separator defined
106
+ def formatted_extension
107
+ return '' if @extension.nil? || @extension.empty?
108
+
109
+ "#{Phonelib.extension_separator}#{@extension}"
110
+ end
111
+
112
+ # @private Get needable data for formatting phone as national number
113
+ def formatting_data
114
+ return @formatting_data if @formatting_data
115
+
116
+ format = @data[country][:format]
117
+ prefix = @data[country][Core::NATIONAL_PREFIX]
118
+ rule = (format[Core::NATIONAL_PREFIX_RULE] ||
119
+ @data[country][Core::NATIONAL_PREFIX_RULE] || '$1')
120
+
121
+ # change rule's constants to values
122
+ rule.gsub!(/(\$NP|\$FG)/, '$NP' => prefix, '$FG' => '$1')
123
+
124
+ # add space to format groups, change first group to rule,
125
+ format_string = format[:format].gsub(/(\d)\$/, '\\1 $').gsub('$1', rule)
126
+
127
+ @formatting_data =
128
+ [@national_number.match(/#{format[Core::PATTERN]}/), format_string]
129
+ end
130
+ end
131
+ end
@@ -1,5 +1,4 @@
1
- # :nodoc:
2
1
  module Phonelib
3
- # :nodoc:
4
- VERSION = '0.6.2'
2
+ # @private
3
+ VERSION = '0.6.3'
5
4
  end
@@ -1,5 +1,4 @@
1
1
  namespace :phonelib do
2
-
3
2
  desc 'Create database for tests in Rails dummy application'
4
3
  task :create_test_db do
5
4
  exit unless defined? Rails
@@ -13,5 +12,4 @@ namespace :phonelib do
13
12
  require 'phonelib/data_importer'
14
13
  Phonelib::DataImporter.import
15
14
  end
16
-
17
15
  end
@@ -36,7 +36,6 @@
36
36
  # validates :mobile, phone: { possible: true, types: :mobile }
37
37
  # end
38
38
  #
39
-
40
39
  class PhoneValidator < ActiveModel::EachValidator
41
40
  # Include all core methods
42
41
  include Phonelib::Core
@@ -46,26 +45,37 @@ class PhoneValidator < ActiveModel::EachValidator
46
45
  return if options[:allow_blank] && value.blank?
47
46
 
48
47
  phone = parse(value)
49
- if options[:types]
50
- method = options[:possible] ? :possible_types : :types
51
- phone_types = phone.send(method)
52
- if (phone_types & [ Phonelib::Core::FIXED_OR_MOBILE ]).size > 0
53
- phone_types += [ Phonelib::Core::FIXED_LINE, Phonelib::Core::MOBILE ]
54
- end
55
- valid = (phone_types & types).size > 0
56
- else
57
- method = options[:possible] ? :possible? : :valid?
58
- valid = phone.send(method)
59
- end
48
+ valid = if simple_validation?
49
+ method = options[:possible] ? :possible? : :valid?
50
+ phone.send(method)
51
+ else
52
+ (phone_types(phone) & types).size > 0
53
+ end
60
54
 
61
55
  record.errors.add(attribute, options[:message] || :invalid) unless valid
62
56
  end
63
57
 
64
58
  private
65
59
 
60
+ # @private
61
+ def simple_validation?
62
+ options[:types].nil?
63
+ end
64
+
65
+ # @private
66
+ # @param phone [Phonelib::Phone] parsed phone
67
+ def phone_types(phone)
68
+ method = options[:possible] ? :possible_types : :types
69
+ phone_types = phone.send(method)
70
+ if (phone_types & [Phonelib::Core::FIXED_OR_MOBILE]).size > 0
71
+ phone_types += [Phonelib::Core::FIXED_LINE, Phonelib::Core::MOBILE]
72
+ end
73
+ phone_types
74
+ end
75
+
76
+ # @private
66
77
  def types
67
78
  types = options[:types].is_a?(Array) ? options[:types] : [options[:types]]
68
- types.map &:to_sym
79
+ types.map(&:to_sym)
69
80
  end
70
-
71
81
  end