load call details on finished calls, too
[auerswald-callnotifier.git] / src / callnotifier / CallMonitor / Detailler / OpenGeoDb.php
1 <?php
2 namespace callnotifier;
3
4 /**
5  * Fetch location name from OpenGeoDb.
6  * In case of mobile phone numbers, the provider is named.
7  *
8  * It uses a custom table "my_orte" that can be created with
9  * docs/opengeodb-create-my_orte.sql
10  *
11  * Sets "toLocation" or "fromLocation", depending on call type
12  *
13  * @link http://opengeodb.org/
14  */
15 class CallMonitor_Detailler_OpenGeoDb implements CallMonitor_Detailler
16 {
17     protected $db;
18     protected static $mobile = array(
19         '0151' => 'Telekom',
20         '0152' => 'Vodafone D2',
21         '0157' => 'E-Plus',
22         '0159' => 'O2',
23         '0160' => 'Telekom',
24         '0162' => 'Vodafone D2',
25         '0163' => 'E-Plus',
26         '0164' => 'Cityruf (e*message)',
27         '0170' => 'Telekom',
28         '0171' => 'Telekom',
29         '0172' => 'Vodafone D2',
30         '0173' => 'Vodafone D2',
31         '0174' => 'Vodafone D2',
32         '0175' => 'Telekom',
33         '0176' => 'O2',
34         '0177' => 'E-Plus',
35         '0178' => 'E-Plus',
36         '0179' => 'O2',
37     );
38
39     /**
40      * Create new detailler object
41      *
42      * @param string $dsn      PDO connection string, for example
43      *                         'mysql:host=dojo;dbname=opengeodb'
44      * @param string $username Database username
45      * @param string $password Database password
46      */
47     public function __construct($dsn, $username, $password)
48     {
49         $this->db = new \PDO(
50             $dsn, $username, $password,
51             array(
52                 \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
53                 \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
54             )
55         );
56     }
57
58     public function loadCallDetails(CallMonitor_Call $call)
59     {
60         if ($call->type == CallMonitor_Call::INCOMING) {
61             if (!isset($call->fromLocation) || $call->fromLocation === null) {
62                 $call->fromLocation = $this->loadLocation($call->from);
63             }
64         } else {
65             if (!isset($call->toLocation) || $call->toLocation === null) {
66                 $call->toLocation = $this->loadLocation($call->to);
67             }
68         }
69     }
70
71     protected function loadLocation($number)
72     {
73         if (substr($number, 0, 2) == '01') {
74             //special number
75             $prefix = substr($number, 0, 4);
76             if (isset(self::$mobile[$prefix])) {
77                 return 'Handy: ' . self::$mobile[$prefix];
78             }
79             return null;
80         }
81
82         //FIXME: what about international numbers?
83         //area codes in germany can be 3 to 6 numbers
84         $stm = $this->db->query(
85             'SELECT name FROM my_orte'
86             . ' WHERE vorwahl = ' . $this->db->quote(substr($number, 0, 3))
87             . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 4))
88             . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 5))
89             . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 6))
90             . ' ORDER BY einwohner DESC'
91         );
92         if ($stm === false) {
93             throw new \Exception(
94                 implode(' - ', $this->db->errorInfo())
95             );
96         }
97
98         $res = $stm->fetch();
99         if ($res === false) {
100             return null;
101         }
102
103         return $res['name'];
104     }
105
106 }
107
108 ?>