load call details on finished calls, too
[auerswald-callnotifier.git] / src / callnotifier / CallMonitor / Detailler / OpenGeoDb.php
index 1260438e95f85ff399af7c53b7c3c60d71481ab7..46711b08baae3dfe29a403a51d0f74581de41cdb 100644 (file)
@@ -1,16 +1,53 @@
 <?php
 namespace callnotifier;
 
+/**
+ * Fetch location name from OpenGeoDb.
+ * In case of mobile phone numbers, the provider is named.
+ *
+ * It uses a custom table "my_orte" that can be created with
+ * docs/opengeodb-create-my_orte.sql
+ *
+ * Sets "toLocation" or "fromLocation", depending on call type
+ *
+ * @link http://opengeodb.org/
+ */
 class CallMonitor_Detailler_OpenGeoDb implements CallMonitor_Detailler
 {
     protected $db;
+    protected static $mobile = array(
+        '0151' => 'Telekom',
+        '0152' => 'Vodafone D2',
+        '0157' => 'E-Plus',
+        '0159' => 'O2',
+        '0160' => 'Telekom',
+        '0162' => 'Vodafone D2',
+        '0163' => 'E-Plus',
+        '0164' => 'Cityruf (e*message)',
+        '0170' => 'Telekom',
+        '0171' => 'Telekom',
+        '0172' => 'Vodafone D2',
+        '0173' => 'Vodafone D2',
+        '0174' => 'Vodafone D2',
+        '0175' => 'Telekom',
+        '0176' => 'O2',
+        '0177' => 'E-Plus',
+        '0178' => 'E-Plus',
+        '0179' => 'O2',
+    );
 
-    public function __construct()
+    /**
+     * Create new detailler object
+     *
+     * @param string $dsn      PDO connection string, for example
+     *                         'mysql:host=dojo;dbname=opengeodb'
+     * @param string $username Database username
+     * @param string $password Database password
+     */
+    public function __construct($dsn, $username, $password)
     {
         $this->db = new \PDO(
-            'mysql:host=dojo;dbname=opengeodb',
-            'opengeodb-read',
-            'opengeodb',
+            $dsn, $username, $password,
             array(
                 \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
                 \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
@@ -21,52 +58,49 @@ class CallMonitor_Detailler_OpenGeoDb implements CallMonitor_Detailler
     public function loadCallDetails(CallMonitor_Call $call)
     {
         if ($call->type == CallMonitor_Call::INCOMING) {
-            $call->fromLocation = $this->loadLocation($call->from);
+            if (!isset($call->fromLocation) || $call->fromLocation === null) {
+                $call->fromLocation = $this->loadLocation($call->from);
+            }
         } else {
-            $call->toLocation = $this->loadLocation($call->to);
+            if (!isset($call->toLocation) || $call->toLocation === null) {
+                $call->toLocation = $this->loadLocation($call->to);
+            }
         }
     }
 
     protected function loadLocation($number)
     {
-        //area codes in germany can be 3 to 6 numbers
-        //FIXME: what about international numbers?
-        for ($n = 3; $n <= 6; $n++) {
-            $areacode = substr($number, 0, $n);
-            $name = $this->getNameForAreaCode($areacode);
-            if ($name !== null) {
-                return $name;
+        if (substr($number, 0, 2) == '01') {
+            //special number
+            $prefix = substr($number, 0, 4);
+            if (isset(self::$mobile[$prefix])) {
+                return 'Handy: ' . self::$mobile[$prefix];
             }
+            return null;
         }
 
-        return null;
-    }
-
-    protected function getNameForAreaCode($areacode)
-    {
+        //FIXME: what about international numbers?
+        //area codes in germany can be 3 to 6 numbers
         $stm = $this->db->query(
-            'SELECT loc_id FROM geodb_textdata'
-            . ' WHERE text_type = "500400000"'//area code
-            . ' AND text_val = ' . $this->db->quote($areacode)
+            'SELECT name FROM my_orte'
+            . ' WHERE vorwahl = ' . $this->db->quote(substr($number, 0, 3))
+            . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 4))
+            . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 5))
+            . ' OR vorwahl = ' . $this->db->quote(substr($number, 0, 6))
+            . ' ORDER BY einwohner DESC'
         );
-        $res = $stm->fetch();
-        if ($res === false) {
-            //area code does not exist
-            return null;
+        if ($stm === false) {
+            throw new \Exception(
+                implode(' - ', $this->db->errorInfo())
+            );
         }
 
-        $locId = $res['loc_id'];
-        $stm = $this->db->query(
-            'SELECT text_val FROM geodb_textdata'
-            . ' WHERE text_type = "500100000"'//name
-            . ' AND loc_id = ' . $this->db->quote($locId)
-        );
         $res = $stm->fetch();
         if ($res === false) {
             return null;
         }
 
-        return $res['text_val'];
+        return $res['name'];
     }
 
 }