NotifySend.php
[Pman.Core] / NotifySend.php
1 <?php
2 require_once 'Pman.php';
3
4 /**
5  * notification script sender
6  *
7  * called with an id of a core_notify element
8  *
9  * uses core_notify - to find an event to object and person.
10  *
11  * uses Events table to log failures
12  * 
13  * 
14  * calls $object->toEmail($person,$last_send) to generate an email struct with
15  *  array (
16  *      headers =>
17  *      recipients =>
18  *      body =>
19  *  )
20  * 
21  * 
22  */
23
24
25 class Pman_Core_NotifySend extends Pman
26 {
27     
28     var $table = 'core_notify';
29     function getAuth()
30     {
31         $ff = HTML_FlexyFramework::get();
32         if (!$ff->cli) {
33             die("access denied");
34         }
35         //HTML_FlexyFramework::ensureSingle(__FILE__, $this);
36         return true;
37         
38     }
39     
40     var $pool = array();
41     
42     function get($id)    
43     {
44         DB_DataObject::debugLevel(1);
45         //date_default_timezone_set('UTC');
46         // phpinfo();exit;
47         
48         $w = DB_DataObject::factory($this->table);
49         
50         if (!$w->get($id) || strtotime($w->act_when) < strtotime($w->sent)) {
51             die("invalid id or time");
52         }
53          
54         $o = $w->object();
55         $p = $w->person();
56         
57         // let's work out the last notification sent to this user..
58         $l = DB_DataObject::factory($this->table);
59         $l->setFrom( array(
60                 'ontable' => $w->ontable,
61                 'onid' => $w->onid,
62                 'person_id' => $w->person_id,
63         ));        
64         $l->whereAdd('id != '. $w->id);
65         $l->orderBy('sent DESC');
66         $l->limit(1);
67         $ar = $l->fetchAll('sent');
68         $last = empty($ar) ? date('Y-m-d H:i:s', 0) : $ar[0];
69         
70         // find last event..
71         $ev = DB_DataObject::factory('Events');
72         $ev->on_id = $w->id;                           // int(11)
73         $ev->od_table = $this->table;
74         $ev->limit(1);
75         $ev->orderBy('event_when DESC');
76         $ar = $ev->fetchAll('event_when');
77         $last_event = empty($ar) ? 0 : $ar[0];
78         $next_try_min = 5;
79         if ($last_event) {
80             $next_try_min = floor((time() - strtotime($last_event)) / 60) * 2;
81         }
82         $next_try = $next_try_min . ' MINUTES';
83         
84         
85         $email = $o->toEmail($p,$last);
86         // should we fetch the watch that caused it.. - which should contain the method to call..
87         $dom = array_pop(explode('@', $p->email));
88         
89         $mxs = $this->mxs($dom);
90         $ww = clone($w);
91         
92         $fail = false;
93         
94         
95         foreach($mxs as $dom) {
96             
97             $mailer = Mail::factory('smtp', array( 'host'         => $dom ));
98             $res = $mailer->send($email['recipients'], $email['headers'], $email['body']);
99             if ($res === true) {
100                 // success....
101                 
102                 $w->sent = date('Y-m-d H:i:s');
103                 $w->msgid = $email['headers']['Message-Id'];
104                 $w->event_id = -1; // sent ok.. - no need to record it..
105                 $w->update($ww);
106                 die("SENT");
107             }
108             // what type of error..
109             list($code, $response) = $mailer->_smtp->getResponse();
110             if ($code < 0) {
111                 continue; // try next mx... ??? should we wait??? - nope we did not even connect..
112             }
113             // give up after 2 days..
114             if ($code == 451 && $next_try_min < (2*24*60)) {
115                 // try again later..
116                 // check last event for this item..
117                 $this->addEvent('NOTIFY', $w, 'GREYLISTED');
118                 $w->act_when = date('Y-m-d H:i:s', strtotime('NOW + 5 MINUTES'));
119                 $w->update($ww);
120                 die("GREYLISTED");
121             }
122             $fail = true;
123             break;
124         }
125         if ($fail || $next_try_min > (2*24*60)) {
126         // fail.. = log and give up..
127             $id = $this->addEvent('NOTIFY', $w, 'FAILED - '. $fail ? $res->toString() : "RETRY TIME EXCEEDED");
128             $w->sent = date('Y-m-d H:i:s');
129             $w->msgid = '';
130             $w->event_id = $id;
131             $w->update($ww);
132             die("DONE");
133         }
134         
135         $this->addEvent('NOTIFY', $w, 'NO HOST CAN BE CONTACTED');
136         $w->act_when = date('Y-m-d H:i:s', strtotime('NOW + 5 MINUTES'));
137         $w->update($ww);
138         die("NO HOST AVAILABLE");
139
140         
141     }
142     function mxs($fqdn)
143     {
144         $mx_records = array();
145         $mx_weight = array();
146         $mxs = array();
147         if (!getmxrr($fqdn, $mx_records, $mx_weight)) {
148             return araray($fqdn);
149         }
150         
151         asort($mx_weight,SORT_NUMERIC);
152         
153         foreach($mx_weight as $k => $weight) {
154             $mxs[] = $mx_records[$k];
155         }
156         return $mxs;
157     }
158     
159     
160 }