2 require_once 'MTrackWeb.php';
4 // is this used currently - it's supposed to be for sending out notificatios on changes?
6 class MTrackWeb_Cron_Notify extends MTrackWeb
11 $ff = HTML_FlexyFramework::get();
15 HTML_FlexyFramework::ensureSingle(__FILE__, $this);
22 //DB_DataObject::debugLevel(1);
23 date_default_timezone_set('UTC');
25 // what's the baserul..
28 $MAX_DIFF = 200 * 1024;
29 $USE_BATCHING = false;
32 $e= DB_DataObject::factory('Events');
33 $e->action = 'MTRACK.NOTIFY';
35 $e->selectAdd('MAX(event_when) as event_when');
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..
43 //stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
44 //stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
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');
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.
64 // should be like a list of tickets
65 foreach ($messages as $m=>$ar) {
67 $lr = explode(':', $m);
68 $o = DB_DataObject::Factory($lr[0]);
71 if (!isset($cache[implode(',', $ar)])) {
73 $cs->whereAddIn('mtrack_change.id', $ar, 'int');
75 $cache[implode(',', $ar)] = $cs->fetchAll();
77 $u = DB_DataObject::factory('Person');
79 $method = 'notify_'. $lr[0] ;
80 if (method_exists($this,$method)) {
81 $this->$method($o, $cache[implode(',', $ar)], $u);
92 // print_R($messages);
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.)
104 * For the wiki repo, group by file so that serial edits within the batch
105 * period show up as a single email.
113 * - from (system or a specific user.)
118 function calcAddress($ticket, $changes, $user)
120 $ff = HTML_FlexyFramework::get();
124 foreach($changes as $c) {
125 if ($change->person_id == $user->id) {
128 if (in_array($change->person_id_name, $changers)) {
131 $changers[] = $change->person_id_name;
134 $fromname = '"'. addslashes($project->toEventString()). '"';
135 if (count($changers) == 1) {
136 $fromname = '"'. addslashes($changers[0]). '"';
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...
144 //if (count($from) > 1) {
146 // array_shift($from);
147 // foreach ($from as $email) {
148 // $rep[] = make_email($email[0], $email[1]);
151 $headers['Reply-To'] = $ff->MTrackWeb['email_address'];
157 * convert notification into an email..
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..
165 function notify_mtrack_ticket($ticket, $changes, $user)
168 $ff = HTML_FlexyFramework::get();
175 // from is always the system.. ??
176 // unless all the changers are the same..
177 $headers = $this->calcAddress($ticket, $changes, $user);
180 //$headers['To'] = '"'. addslashes($user->name). '" <' . $user->email .'>';
181 //$headers['From'] = make_email($from[0][0], $from[0][1]);
182 //if (count($from) > 1) {
184 // array_shift($from);
185 // foreach ($from as $email) {
186 // $rep[] = make_email($email[0], $email[1]);
188 //$headers['Reply-To'] = join(', ', $rep);
192 'MIME-Version' => '1.0',
193 'Content-Type' => 'text/plain; charset="UTF-8"',
194 'Content-Transfer-Encoding' => 'quoted-printable',
198 $mid = $ticket->id . '@' . php_uname('n');
204 // $headers['Message-ID'] = "<$mid>";
206 //$headers['Message-ID'] = "<$T->updated.$mid>";
207 //$headers['In-Reply-To'] = "<$mid>";
208 //$headers['References'] = "<$mid>";
210 /* find related project(s) */
211 $p = $ticket->project();
213 $subj = "[" . $p->code . ' - ' . $p->name . "] ";
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;
224 $headers['Subject'] = sprintf("%s#%s %s (%s %s)",
225 $subj, $ticket->id, $ticket->summary,
226 $ticket->status_name, $ticket->classification_id_name);
228 $owner = $ticket->owner_id ? $ticket->owner_id_name : 'nobody';
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) .
235 //sprintf("Milestone: %s\n", join(', ', $T->getMilestones()));
236 //sprintf("Component: %s\n", join(', ', $T->getComponents()));
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;
245 foreach ($changes as $change) {
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;
252 $ar = $change->cachedAudit();
253 foreach($ar as $audit) {
255 switch($audit->field()) {
257 continue; //??? ignore?
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;
266 $value = $T->getComponents();
267 $field = 'Component';
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;
279 $value = $T->getMilestones();
280 $field = 'Milestone';
288 $value = $T->getKeywords();
295 $oldvalue = $audit->oldvalue($this);
296 $value = $audit->oldvalue($this);
297 if (!strlen($oldvalue)) {
298 $body .= "Set {$audit->field()} to: {$value}\n";
302 if (!strlen($value)) {
303 $body .= "Removed {$audit->field()} - was: {$oldvalue}\n";
306 $body .= "Changed {$audit->field()} from :{$oldvalue} -> {$value}\n";
312 $body .= sprintf("%s/Ticket.php/%s\n\n", $ff->MTrackWeb['url'], $ticket->id);
316 // send_mail($udata['email'], $plain);
322 class CanonicalLineEndingFilter extends php_user_filter {
323 function filter($in, $out, &$consumed, $closing)
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);
333 class UnixLineEndingFilter extends php_user_filter {
334 function filter($in, $out, &$consumed, $closing)
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);