53c393909e9aed024628471d16dd3a9cf21467b5
[web.mtrack] / MTrackWeb / Cron / Notify.php
1 <?php
2 require_once 'MTrackWeb.php';
3
4 class MTrackWeb_Cron_Notify extends MTrackWeb
5 {
6     
7     function getAuth()
8     {
9         $ff = HTML_FlexyFramework::get();
10         if (!$ff->cli) {
11             die("access denied");
12         }
13         HTML_FlexyFramework::ensureSingle(__FILE__, $this);
14         return true;
15         
16     }
17     
18     function get()    
19     {
20         //DB_DataObject::debugLevel(1);
21         date_default_timezone_set('UTC');
22         
23         // what's the baserul..
24     
25         
26         $MAX_DIFF = 200 * 1024;
27         $USE_BATCHING = false;
28         
29          
30         $e= DB_DataObject::factory('Events');
31         $e->action = 'MTRACK.NOTIFY';
32         $e->selectAdd();
33         $e->selectAdd('MAX(event_when) as event_when');
34         $e->find(true);
35         if (empty($e->event_when)) {
36             $e->event_when = date('Y-m-d H:i:s', strtotime("NOW - 2 days")); // should be a long time ago..
37         }
38          
39         
40         
41         //stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
42         //stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
43         
44         $w = DB_DataObject::factory('core_watch');
45         //echo "gather watched";
46        // DB_DataObject::debugLevel(1);
47         // returns a list of user with the objects they are watching..
48         $watches = $w->watched('email');
49         //echo "\nDONE WATCHED\n";
50         $CS = DB_DataObject::factory('mtrack_change');
51         
52         $messages = array();
53         $cache = array();
54         foreach($watches as $uid => $ar) {
55             //echo "gather changes";
56             //print_r($uid); print_r($ar);
57             // we can now query mtrack_change for anything that occured in that list..
58             $messages = $CS->gatherChanges($e->event_when, $uid, $ar);
59             //print_R($messages);exit;
60             // we should cache the emails. = as multiple people might be getting the same email.
61             
62             // should be like a list of tickets
63             foreach ($messages as $m=>$ar) {
64                 
65                 $lr = explode(':', $m);
66                 $o = DB_DataObject::Factory($lr[0]);
67                 $o->autoJoin();
68                 $o->get($lr[1]);
69                 if (!isset($cache[implode(',', $ar)])) {
70                     $cs = clone($CS);
71                     $cs->whereAddIn('mtrack_change.id', $ar, 'int');
72                     $cs->autoJoin();
73                     $cache[implode(',', $ar)] = $cs->fetchAll();
74                 }
75                 $u  = DB_DataObject::factory('Person');
76                 $u->get($uid);
77                 $method =  'notify_'. $lr[0] ;
78                 if (method_exists($this,$method)) {
79                     $this->$method($o,  $cache[implode(',', $ar)], $u);
80                 }
81             }
82             
83             
84             
85             
86             
87             
88             
89         }
90        // print_R($messages);
91         die("done");
92         
93         
94         
95         
96          
97         /* For each watcher, compute the changes.
98          * Group changes by ticket, sending one email per ticket.
99          * Group tickets into batch updates if the only fields that changed are
100          * bulk update style (milestone, assignment etc.)
101          *
102          * For the wiki repo, group by file so that serial edits within the batch
103          * period show up as a single email.
104          */
105          
106     }
107     
108     
109     /**
110      * sets:
111      *   - from (system or a specific user.)
112      *   - replyto (system)
113      *   - to user...
114      *   
115      */
116     function calcAddress($ticket, $changes, $user)
117     {
118         $ff = HTML_FlexyFramework::get();
119         
120         
121         $changers = array();
122         foreach($changes as $c) {
123             if ($change->person_id == $user->id) {
124                 continue;
125             }
126             if (in_array($change->person_id_name, $changers)) {
127                 continue;
128             }
129             $changers[] = $change->person_id_name;
130             
131         }
132         $fromname = '"'. addslashes($project->toEventString()). '"';
133         if (count($changers) == 1) {
134             $fromname = '"'. addslashes($changers[0]).  '"';
135         }
136         
137         $p = $ticket->project();
138         $headers['To'] = '"'. addslashes($user->name). '" <' . $user->email .'>';
139         $headers['From'] = '"'. addslashes($project->toEventString()). '" '. 
140                 $ff->MTrackWeb['email_address']; // could be the user who made the change...
141         
142         //if (count($from) > 1) {
143         //    $rep = array();
144         //    array_shift($from);
145          //       foreach ($from as $email) {
146          // $rep[] = make_email($email[0], $email[1]);
147         // }
148         
149         $headers['Reply-To'] =  $ff->MTrackWeb['email_address'];
150         //}
151         return $headers;
152     }
153     
154     /**
155      * convert notification into an email..
156      *
157      * @param object $ticket the DataObject
158      * @param array $items the ids of the mtrack_change's
159      * @parem object $user DataObject of the user..
160      * 
161      */
162     
163     function notify_mtrack_ticket($ticket, $changes, $user)
164     {
165         //global $MAX_DIFF;
166         $ff = HTML_FlexyFramework::get();
167      
168         
169         
170         
171      
172      
173         // from is always the system.. ??
174         // unless all the changers are the same..
175         $headers = $this->calcAddress($ticket, $changes, $user);
176         
177           
178         //$headers['To'] = '"'. addslashes($user->name). '" <' . $user->email .'>';
179         //$headers['From'] = make_email($from[0][0], $from[0][1]);
180         //if (count($from) > 1) {
181         //    $rep = array();
182         //    array_shift($from);
183          //       foreach ($from as $email) {
184          // $rep[] = make_email($email[0], $email[1]);
185         // }
186         //$headers['Reply-To'] = join(', ', $rep);
187         //}
188      
189         $headers += array(
190             'MIME-Version' => '1.0',
191             'Content-Type' => 'text/plain; charset="UTF-8"',
192             'Content-Transfer-Encoding' => 'quoted-printable',
193         );
194     
195         
196         $mid = $ticket->id . '@' . php_uname('n');
197         
198         
199         
200         
201         //if ($is_initial) {
202         //    $headers['Message-ID'] = "<$mid>";
203         //} else {
204         //$headers['Message-ID'] = "<$T->updated.$mid>";
205         //$headers['In-Reply-To'] = "<$mid>";
206         //$headers['References'] = "<$mid>";
207         //}
208       /* find related project(s) */
209         $p = $ticket->project();
210          
211         $subj = "[" . $p->code . ' - ' . $p->name . "] ";
212     
213         $headers['X-mtrack-project-list'] = $p->code;
214         //foreach ($projects as $pname) {
215         //  $headers["X-mtrack-project-$pname"] = $pname;
216          // $headers['X-mtrack-project'][] = $pname;
217         //}
218         //} else {
219         //$subj = '';
220         // }
221     
222         $headers['Subject'] = sprintf("%s#%s %s (%s %s)",
223           $subj, $ticket->id, $ticket->summary,
224           $ticket->status_name, $ticket->classification_id_name);
225     
226         $owner =  $ticket->owner_id ? $ticket->owner_id_name : 'nobody';
227     
228         $body = 
229             sprintf("%s/Ticket.php/%s\n\n", $ff->MTrackWeb['url'], $ticket->id) .
230             sprintf("#%s: %s (%s %s)\n", $ticket->id, $ticket->summary, $ticket->status_name, $ticket->classification_id_name) .
231             sprintf("Responsible: %s (%s / %s)\n", $owner, $ticket->priority_id_name, $ticket->severity_id_name) .
232     
233             //sprintf("Milestone: %s\n", join(', ', $T->getMilestones()));
234             //sprintf("Component: %s\n", join(', ', $T->getComponents()));
235             "\n";
236     
237       // Display changed fields grouped by the person that last changed them
238         //$who_changed = array();
239         //foreach ($field_changers as $field => $who) {
240         //  $who_changed[$who][] = $field;
241         //}
242         $body.="\n\n";
243         foreach ($changes as $change) {
244             
245             $body .= "{$change->changedate}:  Change by {$change->person_id_name}\n";
246             $body .= str_repeat('-', 80) . "\n";
247             if (!empty($change->reason)) {
248                 $body.= $change->reason;
249             }
250             $ar = $change->cachedAudit();
251             foreach($ar as $audit) {
252                 
253                 switch($audit->field()) {
254                     case 'id':
255                         continue; //??? ignore?
256                     case '@components':
257                         continue;
258                     //  $old = array();
259                     //  foreach (preg_split("/\s*,\s*/", $old_values[$field]) as $id) {
260                      /*   if (!strlen($id)) continue;
261                         $c = get_component($id);
262                         $old[$id] = $c->name;
263                       }
264                       $value = $T->getComponents();
265                       $field = 'Component';
266                       break;
267                      */
268                     case '@milestones':
269                         continue;
270                     //  $old = array();
271                     //  foreach (preg_split("/\s*,\s*/", $old_values[$field]) as $id) {
272                       /*  if (!strlen($id)) continue;
273                         $m = get_milestone($id);
274                         $old[$id] = $m->name;
275                       }
276                       $value = array();
277                       $value = $T->getMilestones();
278                       $field = 'Milestone';
279                       break;
280                       */
281                     case '@keywords':
282                         continue;
283                     /*
284                       $old = array();
285                       $field = 'Keywords';
286                       $value = $T->getKeywords();
287                       break;
288                       */
289                       
290                     //case 'commit?'  
291                       
292                     default:
293                         $oldvalue = $audit->oldvalue($this);
294                         $value = $audit->oldvalue($this);
295                         if (!strlen($oldvalue)) {
296                             $body .= "Set {$audit->field()} to: {$value}\n";
297                             continue;
298                         }
299                         
300                         if (!strlen($value)) {
301                             $body .= "Removed {$audit->field()} - was: {$oldvalue}\n";
302                             continue;
303                         }
304                         $body .= "Changed {$audit->field()} from :{$oldvalue} -> {$value}\n";
305                         continue;  
306                 }
307             }
308         }
309         
310         $body .= sprintf("%s/Ticket.php/%s\n\n", $ff->MTrackWeb['url'], $ticket->id);
311         
312         echo $body;   
313     
314         //  send_mail($udata['email'], $plain);
315     }
316     
317 }
318
319 /*
320 class CanonicalLineEndingFilter extends php_user_filter {
321     function filter($in, $out, &$consumed, $closing)
322     {
323       while ($bucket = stream_bucket_make_writeable($in)) {
324         $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
325         $consumed += $bucket->datalen;
326         stream_bucket_append($out, $bucket);
327       }
328       return PSFS_PASS_ON;
329     }
330     }
331     class UnixLineEndingFilter extends php_user_filter {
332     function filter($in, $out, &$consumed, $closing)
333     {
334       while ($bucket = stream_bucket_make_writeable($in)) {
335         $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
336         $consumed += $bucket->datalen;
337         stream_bucket_append($out, $bucket);
338       }
339       return PSFS_PASS_ON;
340     }
341 }
342 */
343