1<?php
2/**
3 *
4 *
5 * @author giggsey
6 * @created: 02/10/13 16:52
7 * @project libphonenumber-for-php
8 */
9
10namespace libphonenumber;
11
12use Giggsey\Locale\Locale;
13use libphonenumber\prefixmapper\PrefixFileReader;
14
15class PhoneNumberToCarrierMapper
16{
17    /**
18     * @var PhoneNumberToCarrierMapper[]
19     */
20    protected static $instance = array();
21
22    const MAPPING_DATA_DIRECTORY = '/carrier/data/';
23
24    /**
25     * @var PhoneNumberUtil
26     */
27    protected $phoneUtil;
28    /**
29     * @var PrefixFileReader
30     */
31    protected $prefixFileReader;
32
33    protected function __construct($phonePrefixDataDirectory)
34    {
35        $this->prefixFileReader = new PrefixFileReader(__DIR__ . DIRECTORY_SEPARATOR . $phonePrefixDataDirectory);
36        $this->phoneUtil = PhoneNumberUtil::getInstance();
37    }
38
39    /**
40     * Gets a {@link PhoneNumberToCarrierMapper} instance to carry out international carrier lookup.
41     *
42     * <p> The {@link PhoneNumberToCarrierMapper} is implemented as a singleton. Therefore, calling
43     * this method multiple times will only result in one instance being created.
44     *
45     * @param string $mappingDir
46     * @return PhoneNumberToCarrierMapper
47     */
48    public static function getInstance($mappingDir = self::MAPPING_DATA_DIRECTORY)
49    {
50        if (!array_key_exists($mappingDir, static::$instance)) {
51            static::$instance[$mappingDir] = new static($mappingDir);
52        }
53
54        return static::$instance[$mappingDir];
55    }
56
57    /**
58     * Returns a carrier name for the given phone number, in the language provided. The carrier name
59     * is the one the number was originally allocated to, however if the country supports mobile
60     * number portability the number might not belong to the returned carrier anymore. If no mapping
61     * is found an empty string is returned.
62     *
63     * <p>This method assumes the validity of the number passed in has already been checked, and that
64     * the number is suitable for carrier lookup. We consider mobile and pager numbers possible
65     * candidates for carrier lookup.
66     *
67     * @param PhoneNumber $number a valid phone number for which we want to get a carrier name
68     * @param string $languageCode the language code in which the name should be written
69     * @return string a carrier name for the given phone number
70     */
71    public function getNameForValidNumber(PhoneNumber $number, $languageCode)
72    {
73        $languageStr = Locale::getPrimaryLanguage($languageCode);
74        $scriptStr = '';
75        $regionStr = Locale::getRegion($languageCode);
76
77        return $this->prefixFileReader->getDescriptionForNumber($number, $languageStr, $scriptStr, $regionStr);
78    }
79
80
81    /**
82     * Gets the name of the carrier for the given phone number, in the language provided. As per
83     * {@link #getNameForValidNumber(PhoneNumber, Locale)} but explicitly checks the validity of
84     * the number passed in.
85     *
86     * @param PhoneNumber $number The phone number  for which we want to get a carrier name
87     * @param string $languageCode Language code for which the description should be written
88     * @return string a carrier name for the given phone number, or empty string if the number passed in is
89     *     invalid
90     */
91    public function getNameForNumber(PhoneNumber $number, $languageCode)
92    {
93        $numberType = $this->phoneUtil->getNumberType($number);
94        if ($this->isMobile($numberType)) {
95            return $this->getNameForValidNumber($number, $languageCode);
96        }
97        return '';
98    }
99
100    /**
101     * Gets the name of the carrier for the given phone number only when it is 'safe' to display to
102     * users. A carrier name is considered safe if the number is valid and for a region that doesn't
103     * support
104     * {@linkplain http://en.wikipedia.org/wiki/Mobile_number_portability mobile number portability}.
105     *
106     * @param $number PhoneNumber the phone number for which we want to get a carrier name
107     * @param $languageCode String the language code in which the name should be written
108     * @return string a carrier name that is safe to display to users, or the empty string
109     */
110    public function getSafeDisplayName(PhoneNumber $number, $languageCode)
111    {
112        if ($this->phoneUtil->isMobileNumberPortableRegion($this->phoneUtil->getRegionCodeForNumber($number))) {
113            return '';
114        }
115
116        return $this->getNameForNumber($number, $languageCode);
117    }
118
119    /**
120     * Checks if the supplied number type supports carrier lookup.
121     * @param int $numberType A PhoneNumberType int
122     * @return bool
123     */
124    protected function isMobile($numberType)
125    {
126        return ($numberType === PhoneNumberType::MOBILE ||
127            $numberType === PhoneNumberType::FIXED_LINE_OR_MOBILE ||
128            $numberType === PhoneNumberType::PAGER
129        );
130    }
131}
132