Class: PhoneNumber
- Inherits:
-
Object
- Object
- PhoneNumber
- Defined in:
- app/lib/phone_number.rb
Overview
PhoneNumber
Encapsulates parsing, formatting and validation of international phone numbers.
Usage:
phone = PhoneNumber.new("+15551231234")
phone.valid? # => true
phone.format(:e164) # => "+15551231234"
Valid options for format():
:crm - US/Canada numbers formatted as (555) 123-1234, international as +12345678901234
:crm_no_extension - Same as above but without extension
:e164 - International format +12345678901234
:fax_dial - Formatted for dialing a fax machine
:pbx_dial - Raw digits formatted for dialing on a PBX system
Validation functions:
PhoneNumber.valid?(number) - Returns true if number is valid
PhoneNumber.possible?(number) - Returns true if number is possible
Parse and format in one step:
PhoneNumber.parse_and_format(number, format: :e164)
Information about a parsed number:
phone.country # Country
phone.country_iso # Country ISO code
phone.timezone # Timezone
phone.carrier # Carrier
phone.type # Landline, mobile etc
And more - see docs for Phonelib gem for additional info
Constant Summary collapse
- PHONELIB_MUTEX =
Mutex.new
Instance Attribute Summary collapse
-
#country_iso ⇒ Object
readonly
Returns the value of attribute country_iso.
-
#phone ⇒ Object
readonly
Returns the value of attribute phone.
Delegated Instance Attributes collapse
-
#area_code ⇒ Object
Alias for Phone#area_code.
-
#carrier ⇒ Object
Alias for Phone#carrier.
-
#country ⇒ Object
Alias for Phone#country.
-
#extension ⇒ Object
Alias for Phone#extension.
-
#geo_name ⇒ Object
Alias for Phone#geo_name.
-
#original ⇒ Object
Alias for Phone#original.
-
#possible? ⇒ Object
Alias for Phone#possible?.
-
#possible_types ⇒ Object
Alias for Phone#possible_types.
-
#sanitized ⇒ Object
Alias for Phone#sanitized.
-
#timezone ⇒ Object
Alias for Phone#timezone.
-
#type ⇒ Object
Alias for Phone#type.
-
#types ⇒ Object
Alias for Phone#types.
-
#valid? ⇒ Object
Alias for Phone#valid?.
Class Method Summary collapse
- .ensure_phonelib! ⇒ Object
- .parse(phone_string, country_iso: nil, strict: false) ⇒ Object
- .parse_and_format(phone_string, display_format: :e164, country_iso: nil) ⇒ Object
- .possible?(phone_string) ⇒ Boolean
- .shortcode?(phone_string) ⇒ Boolean
- .valid?(phone_string) ⇒ Boolean
Instance Method Summary collapse
- #dial_string ⇒ Object
-
#format(format_type = nil) ⇒ Object
Formats the parsed national number according to our rules.
-
#initialize(phone_string, country_iso = nil) ⇒ PhoneNumber
constructor
You can pass a phone number formatted in any format Additionally, you can feed a country_iso (could be an array of preference too) to help the algorithm figure it out.
-
#shortcode? ⇒ Boolean
US/Canada shortcodes are 5-6 digit numbers used by businesses for SMS marketing and automated messages.
- #to_s ⇒ Object
Constructor Details
#initialize(phone_string, country_iso = nil) ⇒ PhoneNumber
You can pass a phone number formatted in any format
Additionally, you can feed a country_iso (could be an array of preference too)
to help the algorithm figure it out
47 48 49 50 51 52 53 54 55 |
# File 'app/lib/phone_number.rb', line 47 def initialize(phone_string, country_iso = nil) self.class.ensure_phonelib! pn = phone_string.dup.to_s if country_iso.nil? && pn.first != '+' && pn.length == 10 #prepend a 1 which will force this to be parsed as a US/CA number pn.insert(0,'1') end @phone = Phonelib.parse(pn, country_iso) end |
Instance Attribute Details
#country_iso ⇒ Object (readonly)
Returns the value of attribute country_iso.
38 39 40 |
# File 'app/lib/phone_number.rb', line 38 def country_iso @country_iso end |
#phone ⇒ Object (readonly)
Returns the value of attribute phone.
38 39 40 |
# File 'app/lib/phone_number.rb', line 38 def phone @phone end |
Class Method Details
.ensure_phonelib! ⇒ Object
123 124 125 126 127 128 129 130 131 132 |
# File 'app/lib/phone_number.rb', line 123 def self.ensure_phonelib! return if @phonelib_loaded PHONELIB_MUTEX.synchronize do return if @phonelib_loaded require 'phonelib' PhonelibConfig.ensure_configured! @phonelib_loaded = true end end |
.parse(phone_string, country_iso: nil, strict: false) ⇒ Object
98 99 100 101 102 103 104 |
# File 'app/lib/phone_number.rb', line 98 def self.parse(phone_string, country_iso: nil, strict: false) p = new(phone_string, country_iso) # By default we only check for possible, but if strict is passed, we have to pass # the valid check which goes more in depth return nil if !p.possible? || (strict && !p.valid?) p end |
.parse_and_format(phone_string, display_format: :e164, country_iso: nil) ⇒ Object
93 94 95 96 |
# File 'app/lib/phone_number.rb', line 93 def self.parse_and_format(phone_string, display_format: :e164, country_iso: nil) return unless (p = parse(phone_string)) p.format(display_format) end |
.possible?(phone_string) ⇒ Boolean
61 62 63 |
# File 'app/lib/phone_number.rb', line 61 def self.possible?(phone_string) new(phone_string).possible? end |
.shortcode?(phone_string) ⇒ Boolean
117 118 119 |
# File 'app/lib/phone_number.rb', line 117 def self.shortcode?(phone_string) new(phone_string).shortcode? end |
.valid?(phone_string) ⇒ Boolean
57 58 59 |
# File 'app/lib/phone_number.rb', line 57 def self.valid?(phone_string) new(phone_string).valid? end |
Instance Method Details
#area_code ⇒ Object
Alias for Phone#area_code
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#carrier ⇒ Object
Alias for Phone#carrier
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#country ⇒ Object
Alias for Phone#country
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#dial_string ⇒ Object
106 107 108 |
# File 'app/lib/phone_number.rb', line 106 def dial_string format(:pbx_dial) end |
#extension ⇒ Object
Alias for Phone#extension
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#format(format_type = nil) ⇒ Object
Formats the parsed national number according to our rules.
With the crm type, a US or canadian number will format as national (123) 456-3456
please note that this should be adapted based on the user's locale instead
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/lib/phone_number.rb', line 68 def format(format_type = nil) case format_type when :crm @phone.country_code == '1' ? @phone.full_national : @phone.full_e164 when :crm_no_extension @phone.country_code == '1' ? @phone.national : @phone.e164 when :pbx_dial, :e164 @phone.e164 when :fax_dial @phone.international('00').scan(/\d/).join when :strict_10 @phone.national.scan(/\d/).first(10).join else @phone.full_e164 end end |
#geo_name ⇒ Object
Alias for Phone#geo_name
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#original ⇒ Object
Alias for Phone#original
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#possible? ⇒ Object
Alias for Phone#possible?
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#possible_types ⇒ Object
Alias for Phone#possible_types
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#sanitized ⇒ Object
Alias for Phone#sanitized
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#shortcode? ⇒ Boolean
US/Canada shortcodes are 5-6 digit numbers used by businesses for SMS marketing
and automated messages. We cannot send SMS to shortcodes, only receive from them.
112 113 114 115 |
# File 'app/lib/phone_number.rb', line 112 def shortcode? digits = sanitized.to_s.gsub(/\D/, '') digits.length.between?(5, 6) end |
#timezone ⇒ Object
Alias for Phone#timezone
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#to_s ⇒ Object
89 90 91 |
# File 'app/lib/phone_number.rb', line 89 def to_s @phone.full_e164 end |
#type ⇒ Object
Alias for Phone#type
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#types ⇒ Object
Alias for Phone#types
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |
#valid? ⇒ Object
Alias for Phone#valid?
40 41 42 |
# File 'app/lib/phone_number.rb', line 40 delegate :valid?, :possible?, :type, :types, :possible_types, :country, :geo_name, :timezone, :carrier, :area_code, :extension, :sanitized, :original, to: :phone |