DataObjects/Core_notify_server.php
[Pman.Core] / DataObjects / Core_notify_server.php
1 <?php
2 /**
3  * Table Definition for core_notify_server
4  */
5 class_exists('DB_DataObject') ? '' : require_once 'DB/DataObject.php';
6
7 class Pman_Core_DataObjects_Core_notify_server extends DB_DataObject 
8 {
9     ###START_AUTOCODE
10     /* the code below is auto generated do not remove the above tag */
11
12     public $__table = 'core_notify_server';    // table name
13     public $id;                              // int(11)  not_null primary_key auto_increment
14     public $hostname;
15     public $helo;
16     public $poolname;
17     public $is_active;
18     public $last_send;
19     
20     // most services should call this first..
21     
22     function getCurrent($notify)
23     {
24         static $current = false;;
25         
26         if ($current !== false) {
27             return $current;
28         }
29         
30         $ns = DB_DataObject::factory('core_notify_server');
31         $ns->poolname = $notify->poolname;
32         $ns->is_active = 1;
33         $ns->hostname = gethostname();
34         if (!$ns->count()) {
35             $notify->jerr("Server not found for this server " .  gethostname() . " in core_notify_server" );
36         }
37         $ns->find(true);
38         $current = $ns;
39         return $ns;
40     }
41     
42     // called on current server.
43     function assignQueues($notify)
44     {
45          
46         
47         $servers = $this->availableServers();
48         $ids = array();
49         foreach($servers as $s) {
50             $ids[] = $s->id;
51         }
52         
53         
54         if (empty($ids)) {
55             $notify->jerr("no configured servers in core_notify_server for poolname = {$notify->poolname}");
56             
57         }
58          
59         // only run this on the first server...
60         if ($this->id != $ids[0]) {
61             return; 
62         }
63         foreach($ids as $rn) {
64             $up[$rn]  = array();
65         }
66         
67         $num_servers = count($ids);
68         
69         if ($num_servers == 1) {
70             $p = DB_DataObject::factory($notify->table);
71             $p->query("
72                 UPDATE
73                     {$notify->table}
74                 SET
75                     server_id = {$ids[0]}
76                 WHERE
77                     sent < '2000-01-01'
78                     and
79                     event_id = 0
80                     and
81                     act_start < NOW() +  INTERVAL 3 HOUR 
82                     and
83                     server_id < 0
84             ");
85             return;
86         }
87         
88         // ((@row_number := CASE WHEN @row_number IS NULL THEN 0 ELSE @row_number END  +1) % {$num_servers})
89         
90         
91         
92         $p = DB_DataObject::factory($notify->table);
93         $p->whereAdd("
94                 sent < '2000-01-01'
95                 and
96                 event_id = 0
97                 and
98                 act_start < NOW() +  INTERVAL 3 HOUR 
99                 and
100                 server_id < 0"
101             
102         );
103         if ($p->count() < 1) {
104             return;
105         }
106         
107         $p->selectAdd();
108         $p->selectAdd("id, ((@row_number := CASE WHEN @row_number IS NULL THEN 0 ELSE @row_number END  +1) % {$num_servers})  as rn");
109         $kv = $p->fetchAll('id,rn');
110         foreach($kv as $id => $r) {
111             $up[ $ids[$r] ][] = $id;
112         }
113         foreach($up as $sid => $nids) {
114             $p = DB_DataObject::factory($notify->table);
115             $p->query("
116                 UPDATE
117                     {$this->table}
118                 SET
119                     server_id = $sid
120                 WHERE
121                     id IN (". implode(",', $nids"). ')'
122             );
123         }
124          
125         DB_DataObject::factory("core_notify_blacklist")->prune();
126         
127     }
128         // called on current server.
129
130     function availableServers()
131     {
132         $ns = DB_DataObject::factory('core_notify_server');
133         $ns->poolname = $this->poolname;
134         $ns->is_active = 1;
135         $ns->orderBy('id ASC');
136         return  $ns->fetchAll();
137         
138     }
139     
140     function updateNotifyToNextServer( $cn , $when = false, $allow_same = false)
141     {
142         // fixme - this should take into account blacklisted - and return false if no more servers are available
143         $email = empty($cn->to_email) ? ($cn->person() ? $cn->person()->email : $cn->to_email) : $cn->to_email;
144
145         $w = DB_DataObject::factory($cn->tableName());
146         $w->get($cn->id);
147         
148         $servers = $this->availableServerIds();
149         $start = 0;
150         foreach($servers as $i => $s) {
151             if ($s->id == $this->id) {
152                 $start = $i;
153             }
154         }
155         
156         $offset = ($start + 1)  % count($ids);
157         $good = false;
158         while ($offset  != $start) {
159             $s = $servers[$offset];
160             if (!$s->isBlacklisted($email)) {
161                 $good = $s;
162                 break;
163             }
164         }
165         if ($good == false && $allow_same) {
166             $good = $this;
167         }
168         
169         if ($good == false) {
170             return false;
171         }
172         
173         
174         // next server..
175         $pp = clone($w);
176         $w->server_id = $good->id;   
177         $w->act_when = $when === false ? $w->sqlValue('NOW() + INTERVAL 1 MINUTE') : $when;
178         $w->update($pp);
179         return true;
180     }
181     
182     
183     function isBlacklisted($email)
184     {
185         // return current server id..
186         static $cache = array();
187         
188         // get the domain..
189         $ea = explode('@',$email);
190         $dom = strtolower(array_pop($ea));
191         if (isset($cache[$dom])) {
192             return $cache[$dom];
193         }
194         
195         $cd = DB_DataObject::factory('core_domain')->loadOrCreate($dom);
196         
197         $bl = DB_DataObject::factory('core_notify_blacklist');
198         $bl->server_id = $this->id;
199         $bl->domain_id = $cd->id;
200         if ($bl->count()) {
201             $cache[$dom] = true;
202             return true;
203         }
204         
205         return ralse; 
206     }
207     function initHelo()
208     {
209         
210         $ff->Mail['helo'] = $this->helo;
211         
212     }
213     function checkSmtpResponse($errmsg, $core_domain)
214     {
215         $bl = DB_DataObject::factory('core_notify_blacklist');
216         $bl->server_id = $this->id;
217         $bl->domain_id = $core_domain->id;
218         if ($bl->count()) {
219             return;
220         }
221         // dont have it..
222         if (!$bl->messageIsBlacklisted($errmsg)) {
223             return;
224         }
225         $bl->added_dt = $bl->sqlValue("NOW()");
226         $bl->insert();
227         
228         
229     }
230     
231 }