detect country from the string entered
# File lib/phone.rb, line 122 def self.detect_country(string) detected_country = nil # find if the number has a country code Country.all.each_pair do |country_code, country| if string =~ country.country_code_regexp detected_country = country end end detected_country end
detect format (from FORMATS) of input string
# File lib/phone.rb, line 144 def self.detect_format(string_with_number, country) arr = [] formats(country).each_pair do |format, regexp| arr << format if string_with_number =~ regexp end # raise "Detected more than 1 format for #{string_with_number}" if arr.size > 1 if arr.length > 1 # puts %Q{detect_format: more than one format found - #{arr.inspect}} return :really_short end arr.first end
pull off anything that look like an extension
TODO: refactor things so this doesn't change string as a side effect
# File lib/phone.rb, line 166 def self.extract_extension(string) return nil if string.nil? if string.sub! /[ ]*(ext|ex|x|xt|#|:)+[^0-9]*\(*([-0-9]{1,})\)*#?$/, '' extension = $2 return extension end # # We already returned any recognizable extension. # However, we might still have extra junk to the right # of the phone number proper, so just chop it off. # idx = string.rindex(/[0-9]/) return nil if idx.nil? return nil if idx == (string.length - 1) # at the end string.slice!((idx+1)..-1) # chop it return nil end
# File lib/phone.rb, line 133 def self.formats(country) area_code_regexp = country.area_code || DEFAULT_AREA_CODE { # 047451588, 013668734 :short => Regexp.new('^0?(' + area_code_regexp + ')' + NUMBER), # 451588 :really_short => Regexp.new('^' + NUMBER) } end
# File lib/phone.rb, line 38 def initialize(*hash_or_args) if hash_or_args.first.is_a?(Hash) hash_or_args = hash_or_args.first keys = {:number => :number, :area_code => :area_code, :country_code => :country_code, :extension => :extension} else keys = {:number => 0, :area_code => 1, :country_code => 2, :extension => 3} end self.number = hash_or_args[ keys[:number] ] self.area_code = hash_or_args[ keys[:area_code] ] || self.default_area_code self.country_code = hash_or_args[ keys[:country_code] ] || self.default_country_code self.extension = hash_or_args[ keys[:extension] ] raise "Must enter number" if self.number.blank? raise "Must enter area code or set default area code" if self.area_code.blank? raise "Must enter country code or set default country code" if self.country_code.blank? end
fix string so it's easier to parse, remove extra characters etc.
# File lib/phone.rb, line 159 def self.normalize(string_with_number) string_with_number.gsub("(0)", "").gsub(/[^0-9+]/, '').gsub(/^00/, '+').gsub(/^\+00/, '+').gsub(/^\+0/, '+') end
create a new phone number by parsing a string the format of the string is detect automatically (from FORMATS)
# File lib/phone.rb, line 58 def self.parse(string, options={}) if string.present? Country.load extension = extract_extension(string) string = normalize(string) options[:country_code] ||= self.default_country_code options[:area_code] ||= self.default_area_code parts = split_to_parts(string, options) pn = Phone.new(parts) if parts if pn.present? and extension.present? pn.extension = extension end return pn end end
split string into hash with keys :country_code, :area_code and :number
# File lib/phone.rb, line 87 def self.split_to_parts(string, options = {}) country = detect_country(string) if country options[:country_code] = country.country_code string = string.gsub(country.country_code_regexp, '0') else if options[:country_code] country = Country.find_by_country_code options[:country_code] end end if country.nil? if options[:country_code].nil? raise "Must enter country code or set default country code" else raise "Could not find country with country code #{options[:country_code]}" end end format = detect_format(string, country) return nil if format.nil? parts = string.match formats(country)[format] case format when :short {:number => parts[2], :area_code => parts[1], :country_code => options[:country_code]} when :really_short {:number => parts[1], :area_code => options[:area_code], :country_code => options[:country_code]} end end
comparison of 2 phone objects
# File lib/phone.rb, line 240 def ==(other) methods = [:country_code, :area_code, :number, :extension] methods.all? { |method| other.respond_to?(method) && send(method) == other.send(method) } end
Formats the phone number.
if the method argument is a String, it is used as a format string, with the following fields being interpolated:
%c - country_code (385)
%a - area_code (91)
%A - area_code with leading zero (091)
%n - number (5125486)
%f - first @@n1_length characters of number (configured through Phone.n1_length), default is 3 (512)
%l - last characters of number (5486)
%x - entire extension
if the method argument is a Symbol, it is used as a lookup key for a format String in Phone.named_formats
pn.format(:europe)
# File lib/phone.rb, line 215 def format(fmt) if fmt.is_a?(Symbol) raise "The format #{fmt} doesn't exist'" unless named_formats.has_key?(fmt) format_number named_formats[fmt] else format_number(fmt) end end
does this number belong to the default area code?
# File lib/phone.rb, line 235 def has_default_area_code? area_code == self.class.default_area_code end
does this number belong to the default country code?
# File lib/phone.rb, line 230 def has_default_country_code? country_code == self.class.default_country_code end
first n characters of :number
# File lib/phone.rb, line 191 def number1 number[0...self.class.n1_length] end
Generated with the Darkfish Rdoc Generator 2.