sync
[web.mtrack] / MTrackWeb / Cron / Notify.php
index 1cb4a0f..313352c 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+require_once 'MTrackWeb.php';
+
+// is this used currently - it's supposed to be for sending out notificatios on changes?
 
 class MTrackWeb_Cron_Notify extends MTrackWeb
 {
@@ -16,7 +19,7 @@ class MTrackWeb_Cron_Notify extends MTrackWeb
     
     function get()    
     {
-    
+        //DB_DataObject::debugLevel(1);
         date_default_timezone_set('UTC');
         
         // what's the baserul..
@@ -25,53 +28,74 @@ class MTrackWeb_Cron_Notify extends MTrackWeb
         $MAX_DIFF = 200 * 1024;
         $USE_BATCHING = false;
         
+         
+        $e= DB_DataObject::factory('Events');
+        $e->action = 'MTRACK.NOTIFY';
+        $e->selectAdd();
+        $e->selectAdd('MAX(event_when) as event_when');
+        $e->find(true);
+        if (empty($e->event_when)) {
+            $e->event_when = date('Y-m-d H:i:s', strtotime("NOW - 2 days")); // should be a long time ago..
+        }
+         
         
-        $db = MTrackDB::get();
         
-        // default to the last 10 minutes, but prefer the last recorded run time
-        $last = MTrackDB::unixtime(time() - 600);
-        foreach (MTrackDB::q('select last_run from last_notification')->fetchAll()
-            as $row) {
-          $last = $row[0];
-        }
-        $LATEST = strtotime($last);
-        if (getenv('DEBUG_TIME')) {
-          $dtime = strtotime(getenv('DEBUG_TIME'));
-          if ($dtime > 0) {
-            $LATEST = $dtime;
-            $last = MTrackDB::unixtime($LATEST);
-            echo "Using $last as last time (specified via DEBUG_TIME var)\n";
-          }
-        }
+        //stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
+        //stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
         
-        class CanonicalLineEndingFilter extends php_user_filter {
-          function filter($in, $out, &$consumed, $closing)
-          {
-            while ($bucket = stream_bucket_make_writeable($in)) {
-              $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
-              $consumed += $bucket->datalen;
-              stream_bucket_append($out, $bucket);
-            }
-            return PSFS_PASS_ON;
-          }
-        }
-        class UnixLineEndingFilter extends php_user_filter {
-          function filter($in, $out, &$consumed, $closing)
-          {
-            while ($bucket = stream_bucket_make_writeable($in)) {
-              $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
-              $consumed += $bucket->datalen;
-              stream_bucket_append($out, $bucket);
+        $w = DB_DataObject::factory('core_watch');
+        //echo "gather watched";
+       // DB_DataObject::debugLevel(1);
+        // returns a list of user with the objects they are watching..
+        $watches = $w->watched('email');
+        //echo "\nDONE WATCHED\n";
+        $CS = DB_DataObject::factory('mtrack_change');
+        
+        $messages = array();
+        $cache = array();
+        foreach($watches as $uid => $ar) {
+            //echo "gather changes";
+            //print_r($uid); print_r($ar);
+            // we can now query mtrack_change for anything that occured in that list..
+            $messages = $CS->gatherChanges($e->event_when, $uid, $ar);
+            //print_R($messages);exit;
+            // we should cache the emails. = as multiple people might be getting the same email.
+            
+            // should be like a list of tickets
+            foreach ($messages as $m=>$ar) {
+                
+                $lr = explode(':', $m);
+                $o = DB_DataObject::Factory($lr[0]);
+                $o->autoJoin();
+                $o->get($lr[1]);
+                if (!isset($cache[implode(',', $ar)])) {
+                    $cs = clone($CS);
+                    $cs->whereAddIn('mtrack_change.id', $ar, 'int');
+                    $cs->autoJoin();
+                    $cache[implode(',', $ar)] = $cs->fetchAll();
+                }
+                $u  = DB_DataObject::factory('core_person');
+                $u->get($uid);
+                $method =  'notify_'. $lr[0] ;
+                if (method_exists($this,$method)) {
+                    $this->$method($o,  $cache[implode(',', $ar)], $u);
+                }
             }
-            return PSFS_PASS_ON;
-          }
+            
+            
+            
+            
+            
+            
+            
         }
-        stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
-        stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
+       // print_R($messages);
+        die("done");
+        
+        
         
-        $watched = MTrackWatch::getWatchedItemsAndWatchers($last, 'email');
-        printf("Got %d watchers\n", count($watched));
         
+         
         /* For each watcher, compute the changes.
          * Group changes by ticket, sending one email per ticket.
          * Group tickets into batch updates if the only fields that changed are
@@ -80,30 +104,242 @@ class MTrackWeb_Cron_Notify extends MTrackWeb
          * For the wiki repo, group by file so that serial edits within the batch
          * period show up as a single email.
          */
+         
+    }
+    
+    
+    /**
+     * sets:
+     *   - from (system or a specific user.)
+     *   - replyto (system)
+     *   - to user...
+     *   
+     */
+    function calcAddress($ticket, $changes, $user)
+    {
+        $ff = HTML_FlexyFramework::get();
+        
+        
+        $changers = array();
+        foreach($changes as $c) {
+            if ($change->person_id == $user->id) {
+                continue;
+            }
+            if (in_array($change->person_id_name, $changers)) {
+                continue;
+            }
+            $changers[] = $change->person_id_name;
+            
+        }
+        $fromname = '"'. addslashes($project->toEventString()). '"';
+        if (count($changers) == 1) {
+            $fromname = '"'. addslashes($changers[0]).  '"';
+        }
+        
+        $p = $ticket->project();
+        $headers['To'] = '"'. addslashes($user->name). '" <' . $user->email .'>';
+        $headers['From'] = '"'. addslashes($project->toEventString()). '" '. 
+                $ff->MTrackWeb['email_address']; // could be the user who made the change...
+        
+        //if (count($from) > 1) {
+        //    $rep = array();
+        //    array_shift($from);
+         //       foreach ($from as $email) {
+         // $rep[] = make_email($email[0], $email[1]);
+        // }
+        
+        $headers['Reply-To'] =  $ff->MTrackWeb['email_address'];
+        //}
+        return $headers;
+    }
+    
+    /**
+     * convert notification into an email..
+     *
+     * @param object $ticket the DataObject
+     * @param array $items the ids of the mtrack_change's
+     * @parem object $user DataObject of the user..
+     * 
+     */
+    
+    function notify_mtrack_ticket($ticket, $changes, $user)
+    {
+        //global $MAX_DIFF;
+        $ff = HTML_FlexyFramework::get();
+     
+        
         
-        foreach ($watched as $user => $objects) {
-          $udata = MTrackAuth::getUserData($user);
         
-          foreach ($objects as $object => $items) {
-            list($otype, $oid) = explode(':', $object, 2);
+     
+     
+        // from is always the system.. ??
+        // unless all the changers are the same..
+        $headers = $this->calcAddress($ticket, $changes, $user);
+        
+          
+        //$headers['To'] = '"'. addslashes($user->name). '" <' . $user->email .'>';
+        //$headers['From'] = make_email($from[0][0], $from[0][1]);
+        //if (count($from) > 1) {
+        //    $rep = array();
+        //    array_shift($from);
+         //       foreach ($from as $email) {
+         // $rep[] = make_email($email[0], $email[1]);
+        // }
+        //$headers['Reply-To'] = join(', ', $rep);
+        //}
+     
+        $headers += array(
+            'MIME-Version' => '1.0',
+            'Content-Type' => 'text/plain; charset="UTF-8"',
+            'Content-Transfer-Encoding' => 'quoted-printable',
+        );
+    
+        
+        $mid = $ticket->id . '@' . php_uname('n');
         
-            $fname = "notify_$otype";
-            if (function_exists($fname)) {
-              call_user_func($fname, $object, $oid, $items, $user, $udata);
-            } else {
-              echo "WARN: no notifier for $otype $oid\n";
+        
+        
+        
+        //if ($is_initial) {
+        //    $headers['Message-ID'] = "<$mid>";
+        //} else {
+        //$headers['Message-ID'] = "<$T->updated.$mid>";
+        //$headers['In-Reply-To'] = "<$mid>";
+        //$headers['References'] = "<$mid>";
+        //}
+      /* find related project(s) */
+        $p = $ticket->project();
+         
+        $subj = "[" . $p->code . ' - ' . $p->name . "] ";
+    
+        $headers['X-mtrack-project-list'] = $p->code;
+        //foreach ($projects as $pname) {
+        //  $headers["X-mtrack-project-$pname"] = $pname;
+         // $headers['X-mtrack-project'][] = $pname;
+        //}
+        //} else {
+        //$subj = '';
+        // }
+    
+        $headers['Subject'] = sprintf("%s#%s %s (%s %s)",
+          $subj, $ticket->id, $ticket->summary,
+          $ticket->status_name, $ticket->classification_id_name);
+    
+        $owner =  $ticket->owner_id ? $ticket->owner_id_name : 'nobody';
+    
+        $body = 
+            sprintf("%s/Ticket.php/%s\n\n", $ff->MTrackWeb['url'], $ticket->id) .
+            sprintf("#%s: %s (%s %s)\n", $ticket->id, $ticket->summary, $ticket->status_name, $ticket->classification_id_name) .
+            sprintf("Responsible: %s (%s / %s)\n", $owner, $ticket->priority_id_name, $ticket->severity_id_name) .
+    
+            //sprintf("Milestone: %s\n", join(', ', $T->getMilestones()));
+            //sprintf("Component: %s\n", join(', ', $T->getComponents()));
+            "\n";
+    
+      // Display changed fields grouped by the person that last changed them
+        //$who_changed = array();
+        //foreach ($field_changers as $field => $who) {
+        //  $who_changed[$who][] = $field;
+        //}
+        $body.="\n\n";
+        foreach ($changes as $change) {
+            
+            $body .= "{$change->changedate}:  Change by {$change->person_id_name}\n";
+            $body .= str_repeat('-', 80) . "\n";
+            if (!empty($change->reason)) {
+                $body.= $change->reason;
             }
-            foreach ($items as $o) {
-              if ($o instanceof MTrackSCMEvent) {
-                $t = strtotime($o->ctime);
-              } else {
-                $t = strtotime($o->changedate);
-              }
-              if ($t > $LATEST) {
-                $LATEST = $t;
-              }
+            $ar = $change->cachedAudit();
+            foreach($ar as $audit) {
+                
+                switch($audit->field()) {
+                    case 'id':
+                        continue; //??? ignore?
+                    case '@components':
+                        continue;
+                    //  $old = array();
+                    //  foreach (preg_split("/\s*,\s*/", $old_values[$field]) as $id) {
+                     /*   if (!strlen($id)) continue;
+                        $c = get_component($id);
+                        $old[$id] = $c->name;
+                      }
+                      $value = $T->getComponents();
+                      $field = 'Component';
+                      break;
+                     */
+                    case '@milestones':
+                        continue;
+                    //  $old = array();
+                    //  foreach (preg_split("/\s*,\s*/", $old_values[$field]) as $id) {
+                      /*  if (!strlen($id)) continue;
+                        $m = get_milestone($id);
+                        $old[$id] = $m->name;
+                      }
+                      $value = array();
+                      $value = $T->getMilestones();
+                      $field = 'Milestone';
+                      break;
+                      */
+                    case '@keywords':
+                        continue;
+                    /*
+                      $old = array();
+                      $field = 'Keywords';
+                      $value = $T->getKeywords();
+                      break;
+                      */
+                      
+                    //case 'commit?'  
+                      
+                    default:
+                        $oldvalue = $audit->oldvalue($this);
+                        $value = $audit->oldvalue($this);
+                        if (!strlen($oldvalue)) {
+                            $body .= "Set {$audit->field()} to: {$value}\n";
+                            continue;
+                        }
+                        
+                        if (!strlen($value)) {
+                            $body .= "Removed {$audit->field()} - was: {$oldvalue}\n";
+                            continue;
+                        }
+                        $body .= "Changed {$audit->field()} from :{$oldvalue} -> {$value}\n";
+                        continue;  
+                }
             }
-          }
         }
+        
+        $body .= sprintf("%s/Ticket.php/%s\n\n", $ff->MTrackWeb['url'], $ticket->id);
+        
+        echo $body;   
+    
+        //  send_mail($udata['email'], $plain);
+    }
+    
+}
+
+/*
+class CanonicalLineEndingFilter extends php_user_filter {
+    function filter($in, $out, &$consumed, $closing)
+    {
+      while ($bucket = stream_bucket_make_writeable($in)) {
+        $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
+        $consumed += $bucket->datalen;
+        stream_bucket_append($out, $bucket);
+      }
+      return PSFS_PASS_ON;
+    }
+    }
+    class UnixLineEndingFilter extends php_user_filter {
+    function filter($in, $out, &$consumed, $closing)
+    {
+      while ($bucket = stream_bucket_make_writeable($in)) {
+        $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
+        $consumed += $bucket->datalen;
+        stream_bucket_append($out, $bucket);
+      }
+      return PSFS_PASS_ON;
     }
-}
\ No newline at end of file
+}
+*/
+    
\ No newline at end of file