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