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