[dev] Filters match all/any

Atif Ghaffar aghaffar@developer.ch
Sat, 08 Jun 2002 18:45:15 +0200


This is a multi-part message in MIME format.
---------------------- multipart/mixed attachment


Jan Schneider wrote:
> 
> A patch would be nice.
> 

As requested, please find the patch attached.

best regards


-- 
Atif Ghaffar
---------------------------.
           +41 78 845 31 64 ¦ tel
     aghaffar@developer.ch  ¦ email
     http://atifghaffar.com ¦ www
                    8206786 ¦ icq


---------------------- multipart/mixed attachment
Index: filters.php
===================================================================
RCS file: /home/cvs/horde/imp/filters.php,v
retrieving revision 2.40
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r2.40 filters.php
--- filters.php	27 May 2002 21:45:54 -0000	2.40
+++ filters.php	8 Jun 2002 16:28:50 -0000
@@ -27,54 +27,58 @@ $preamble = IMP::preambleString();
 $errormsg = '';
 $actionID = Horde::getFormData('actionID');
 
+//Atif. Function to create Filter.
+//Returns a filter hash
+function makeFilter(){
+   $fields = array ("to", "cc", "subject", "from", "body");
+   $this_filter=array();
+   $this_filter["action"] = Horde::getFormData('action');
+   $this_filter["matchingrule"] = Horde::getFormData('matchingrule');
+   foreach ($fields as $field){
+      if (!preg_match('/^\s*$/', Horde::getFormData($field))) {
+        $this_filter['fields'][$field] = chop(trim(Horde::getFormData($field)));
+      }
+   }
+   
+   if (Horde::getFormData('action') == 'move') {
+      if (Horde::getFormData('folder')){
+          $this_filter['folder'] = Horde::getFormData('folder');
+      } else {
+         $notification->push(_("no folder selected"), 'horde.error');
+         $errorRaised = true;
+      }
+   }
+   return $this_filter;
+}
+//Atif. End Function
+
 /* Run through the action handlers */
 if (isset($actionID)) {
     switch ($actionID) {
 
     case FILTER_CREATE:
-        $fields = Horde::getFormData('fields');
-        if (is_array($fields) && Horde::getFormData('text') && Horde::getFormData('action') && !preg_match('/^\s*$/', Horde::getFormData('text'))) {
-            $filters = @unserialize($prefs->getValue('filters'));
-            if (Horde::getFormData('action') == 'delete') {
-                $filters[] = array('fields' => Horde::getFormData('fields'), 'text' => chop(trim(Horde::getFormData('text'))), 'action' => 'delete');
-            } elseif (Horde::getFormData('action') == 'move' && Horde::getFormData('folder')) {
-                $filters[] = array('fields' => Horde::getFormData('fields'), 'text' => chop(trim(Horde::getFormData('text'))), 'action' => 'move', 'folder' => Horde::getFormData('folder'));
-            } else {
-                $notification->push(_("no folder selected"), 'horde.error');
-                $errorRaised = true;
-            }
-
-            $prefs->setValue('filters', serialize($filters));
-            $prefs->store();
+        //Atif. Modified this case.
+        if (Horde::getFormData('action') ) {
+           $filters = @unserialize($prefs->getValue('filters'));
+           $filters[] = makeFilter();
+           $prefs->setValue('filters', serialize($filters));
+           $prefs->store();
         }
         else {
-            $notification->push(_("please fill in the text and choose a field and an action"), 'horde.error');
-            $errorRaised = true;
+           $notification->push(_("please fill in the text and choose a field and an action"), 'horde.error');
+           $errorRaised = true;
         }
         break;
 
     case FILTER_MODIFY:
-        $fields = Horde::getFormData('fields');
+        //Atif. Modified this case.
         if (Horde::getFormData('number', -1) != -1) {
-            if (Horde::getFormData('text') && !preg_match('/^\s*$/', Horde::getFormData('text'))) {
-                $filters = @unserialize($prefs->getValue('filters'));
-                if (Horde::getFormData('action') == 'delete') {
-                    $filters[Horde::getFormData('number')] = array('fields' => Horde::getFormData('fields'), 'text' => chop(trim(Horde::getFormData('text'))), 'action' => 'delete');
-                } elseif (Horde::getFormData('action') == 'move' && Horde::getFormData('folder')) {
-                    $filters[Horde::getFormData('number')] = array('fields' => Horde::getFormData('fields'), 'text' => chop(trim(Horde::getFormData('text'))), 'action' => 'move', 'folder' => Horde::getFormData('folder'));
-                } else {
-                    $notification->push(_("no folder selected"), 'horde.error');
-                    $errorRaised = true;
-                }
-
-                $prefs->setValue('filters', serialize($filters));
-                $prefs->store();
-            } else {
-                $notification->push(_("no text specified"), 'horde.error');
-                $errorRaised = true;
-            }
+           $filters = @unserialize($prefs->getValue('filters'));
+           $filters[Horde::getFormData('number')]=makeFilter(); // Get the filter from the function
+           $prefs->setValue('filters', serialize($filters));
+           $prefs->store();
         } else {
-            $notification->push(_("no rule selected"), 'horde.error');
+           $notification->push(_("no rule selected"), 'horde.error');
         }
         break;
 
@@ -134,6 +138,50 @@ require IMP_BASE . '/status.php';
 
 $filters = @unserialize($prefs->getValue('filters'));
 
+
+//Atif. code to convert old filters to new filter format
+//Its duplicate . Also in mailbox.php. Should be in just one file
+
+
+$new_filters=array();
+$convert=false;
+foreach ($filters as $filter) {
+   $new_filter=array();
+   
+   if (isset($filter["text"]) && isset($filter["fields"]) && !isset($filter["matchingrule"])) {
+      $convert=true;
+      //copy the current filter
+      $new_filter=$filter;
+      unset ($new_filter["text"]);
+      unset ($new_filter["fields"]);
+
+
+      $new_filter["matchingrule"]="any";
+      $new_filter["action"]=$filter["action"];
+      if (isset($filter["folder"])) {
+         $new_filter["folder"]=$filter["folder"];
+      }
+      
+      foreach ($filter['fields'] as $field) {
+         $new_filter['fields'][$field]=$filter["text"];
+         print "setting fields[$field] to " . $filter["text"] . "<br>\n";
+      }
+
+
+   }
+   $new_filters[]=$new_filter;
+}
+
+if ($convert){
+   $filters=$new_filters;
+   $prefs->setValue('filters', serialize($filters));
+   $prefs->store();
+}
+
+// End convert code
+
+
+
 $filterLabels = array('to'      => _("To:"),
                       'cc'      => _("Cc:"),
                       'from'    => _("From:"),
@@ -143,12 +191,15 @@ $filterLabels = array('to'      => _("To
 $fieldsDisplay = array();
 for ($i = 0; $i < count($filters); $i++) {
     $fieldsDisplay[$i] = '';
-    for ($j = 0; $j < count($filters[$i]['fields']); $j++) {
-        $fieldsDisplay[$i] .= ' <b>' . $filterLabels[$filters[$i]['fields'][$j]] . '</b> ';
-        if ($j < count($filters[$i]['fields']) - 1) {
-            $fieldsDisplay[$i] .= _("or");
-        }
+    //Atif: Changing this to match the new filters format
+    foreach ($filters[$i]['fields'] as $field => $text) {
+       // get the field label if known
+       $fieldLabel= (isset($filterLabels[$field])) ? $filterLabels[$field] : $field;
+       $display[$i][] = "<b> " . $fieldLabel . "</b> matches <b>$text</b> <br>";
     }
+
+    $fieldsDisplay[$i] = implode (($filters[$i]['matchingrule']=="all")?" and ": " or ", $display[$i]);
+
 }
 
 $apply_js = 'window.location = \'' . Horde::url('mailbox.php?actionID=' . FILTER, true) . '\';';
@@ -164,6 +215,10 @@ $fieldsList['body'] = 4;
 
 $actionsList['delete'] = 0;
 $actionsList['move'] = 1;
+
+//Atif: Adding matchingruleset for javascript
+$matchingrulesList['any'] = 0;
+$matchingrulesList['all'] = 1;
 
 require IMP_TEMPLATES . '/filters/javascript.inc';
 require IMP_TEMPLATES . '/filters/list.inc';
Index: mailbox.php
===================================================================
RCS file: /home/cvs/horde/imp/mailbox.php,v
retrieving revision 2.327
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r2.327 mailbox.php
--- mailbox.php	27 Jan 2002 05:07:56 -0000	2.327
+++ mailbox.php	8 Jun 2002 16:34:03 -0000
@@ -161,7 +161,7 @@ switch ($actionID) {
          if (isset($h->from[0])) {
              $ob = $h->from[0];
              $addr = Mime::trimEmailAddress(imap_rfc822_write_address($ob->mailbox, $ob->host, ''));
-             $filters[] = array('fields' => array('from'), 'text' => chop(trim($addr)), 'action' => 'delete');
+             $filters[] = array('matchingrule' => 'any' , 'fields' => array('from' => chop(trim($addr))), 'action' => 'delete');
          }
      }
      $prefs->setValue('filters', serialize($filters));
@@ -328,12 +328,59 @@ switch ($actionID) {
 
  case FILTER:
      $filters = @unserialize($prefs->getValue('filters'));
-     if (is_array($filters) && count($filters) && !strstr($imp['protocol'], 'pop3')) {
+      // Atif. start code to convert old filters to new filter format
+     $new_filters=array();
+     $convert=false;
+     foreach ($filters as $filter) {
+        $new_filter=array();
+        if (isset($filter["text"]) && isset($filter["fields"]) && !isset($filter["matchingrule"])) {
+           $convert=true;
+           //copy the current filter
+           $new_filter=$filter;
+           unset ($new_filter["text"]);
+           unset ($new_filter["fields"]);
+           $new_filter["matchingrule"]="any";
+           $new_filter["action"]=$filter["action"];
+           if (isset($filter["folder"])) {
+              $new_filter["folder"]=$filter["folder"];
+           }
+           foreach ($filter['fields'] as $field) {
+              //set each field (to,cc etc) to the value of text
+              $new_filter['fields'][$field]=$filter["text"];
+           }
+        }
+        $new_filters[]=$new_filter;
+     }
+      
+      if ($convert){
+         $filters=$new_filters;
+         $prefs->setValue('filters', serialize($filters));
+         $prefs->store();
+      }
+      //Atif. End code to convert old filters
+     
+      if (is_array($filters) && count($filters) && !strstr($imp['protocol'], 'pop3')) {
          include_once IMP_BASE . '/lib/Folder.php';
          $baseQuery = 'UNDELETED ';
+         $applied = array();
+         //Atif. Make imap AND / OR Query. 
          for ($i = 0; $i < count($filters); $i++) {
-             for ($j = 0; $j < count($filters[$i]['fields']); $j++) {
-                 $query = $baseQuery . strtoupper($filters[$i]['fields'][$j]) . ' "' . $filters[$i]['text'] . '"';
+            $queries=array();
+            if ($filters[$i]["matchingrule"] == "all") {
+               $query = $baseQuery ;
+               foreach ($filters[$i]['fields'] as $field => $text) {
+                   $query.= strtoupper($field) . ' "' . $text . '" ';
+               }
+               $queries[0]=$query;
+            } else {
+               foreach ($filters[$i]['fields'] as $field => $text) {
+                   $query= $baseQuery  . strtoupper($field) . ' "' . $text . '" ';
+                   $queries[]=$query;
+               }
+            }
+            //Atif. End Make imap AND / OR Query. 
+            //Pass the queries array to the loop
+            foreach ($queries as $query) {  
                  $indices = imap_search($imp['stream'], $query, SE_UID);
                  if (isset($indices) && is_array($indices)) {
                      if ($filters[$i]['action'] == 'delete') {
Index: message.php
===================================================================
RCS file: /home/cvs/horde/imp/message.php,v
retrieving revision 2.305
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r2.305 message.php
--- message.php	8 May 2002 08:02:53 -0000	2.305
+++ message.php	8 Jun 2002 16:34:15 -0000
@@ -289,7 +289,7 @@ switch ($actionID) {
      if (isset($h->from[0])) {
          $ob = $h->from[0];
          $addr = Mime::trimEmailAddress(imap_rfc822_write_address($ob->mailbox, $ob->host, ''));
-         $filters[] = array('fields' => array('from'), 'text' => trim($addr), 'action' => 'delete');
+         $filters[] = array('matchingrule' => 'any' , 'fields' => array('from' => chop(trim($addr))), 'action' => 'delete');
      }
      $prefs->setValue('filters', serialize($filters));
      $prefs->store();
Index: templates/filters/javascript.inc
===================================================================
RCS file: /home/cvs/horde/imp/templates/filters/javascript.inc,v
retrieving revision 1.12
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r1.12 javascript.inc
--- templates/filters/javascript.inc	23 Jan 2002 18:06:34 -0000	1.12
+++ templates/filters/javascript.inc	8 Jun 2002 16:35:32 -0000
@@ -4,28 +4,33 @@
 var fields = new Array(<?php
 for ($i = 0; $i < count($filters); $i++) {
     if ($i > 0) { echo ', '; }
-    echo 'new Array(';
-    for ($j = 0; $j < count($filters[$i]['fields']); $j++) {
-        if ($j > 0) { echo ', '; }
-        echo '"' . $fieldsList[$filters[$i]['fields'][$j]] . '"';
+    echo  'new Array(';
+    
+    $field_array=array();
+    foreach ($fieldsList as $field => $x){
+        if (isset($filters[$i]['fields'][$field])){
+                $field_array[] = sprintf ("new Array('%s', '%s')", $field, addslashes($filters[$i]['fields'][$field]));
+        }
     }
+    echo implode (", ", $field_array);
     echo ')';
 }
 ?>
 );
 
-var strings = new Array(<?php
+
+var actions = new Array(<?php
 for ($i = 0; $i < count($filters); $i++) {
     if ($i > 0) { echo ', '; }
-    echo '"' . addslashes($filters[$i]['text']) . '"';
+    echo '"' . $actionsList[$filters[$i]['action']] . '"';
 }
 ?>
 );
 
-var actions = new Array(<?php
+var matchingrules = new Array(<?php
 for ($i = 0; $i < count($filters); $i++) {
     if ($i > 0) { echo ', '; }
-    echo '"' . $actionsList[$filters[$i]['action']] . '"';
+    echo '"' . $matchingrulesList[$filters[$i]['matchingrule']] . '"';
 }
 ?>
 );
@@ -41,17 +46,15 @@ for ($i = 0; $i < count($filters); $i++)
 
 function selectRule(num)
 {
-    for (var i = 0; i < document.filters.elements['fields[]'].length; i++) {
-        document.filters.elements['fields[]'][i].checked = false;
-    }
-
-    for (var i = 0; i < fields[num].length; i++) {
-        document.filters.elements['fields[]'][fields[num][i]].checked = true;
+    for (var i=0; i<fields[num].length; i++){
+            //alert(fields[num][i][0] + "=" + fields[num][i][1]);
+            document.filters.elements[fields[num][i][0]].value = fields[num][i][1];
     }
-
-    document.filters.text.value = strings[num];
+    
     document.filters.action[actions[num]].checked = true;
 
+    document.filters.matchingrule[matchingrules[num]].checked = true;
+    
     if (folders[num] && document.filters.folder) {
         for (i = 0; i < document.filters.folder.length; i++) {
             if (document.filters.folder[i].value == folders[num]) {
@@ -63,6 +66,7 @@ function selectRule(num)
     else if (document.filters.folder) {
         document.filters.folder.selectedIndex = 0;
     }
+
     
     document.filters.button.value = '<?= _("Modify") ?>';
     document.filters.actionID.value = '<?= FILTER_MODIFY ?>';
Index: templates/filters/list.inc
===================================================================
RCS file: /home/cvs/horde/imp/templates/filters/list.inc,v
retrieving revision 1.14
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r1.14 list.inc
--- templates/filters/list.inc	23 Jan 2002 18:06:34 -0000	1.14
+++ templates/filters/list.inc	8 Jun 2002 16:37:29 -0000
@@ -39,7 +39,7 @@
 <?php else: ?>
         <?= sprintf(_("Move messages to the <b>%s</b> folder"), IMP::displayFolder($filters[$i]['folder'])) ?>
 <?php endif; ?>
-        <?= sprintf(_("where the %s field contains <b>%s</b>"), $fieldsDisplay[$i], $filters[$i]['text']) ?>
+<?= sprintf(_("where <br>  %s"), $fieldsDisplay[$i]) ?>
     </td>
 </tr>
 </table>
Index: templates/filters/manage.inc
===================================================================
RCS file: /home/cvs/horde/imp/templates/filters/manage.inc,v
retrieving revision 1.20
diff -u -3 -p -u -I$Horde -I$Revision -I$Date -r1.20 manage.inc
--- templates/filters/manage.inc	23 Jan 2002 18:06:34 -0000	1.20
+++ templates/filters/manage.inc	8 Jun 2002 16:41:22 -0000
@@ -4,20 +4,34 @@
     <td align="left" class="header" colspan="2" nowrap="nowrap"><b><?= _("Rule Definition") ?></b></td>
 </tr>
 <tr>
-    <td class="light" align="right"><b><?= _("Field") ?>&nbsp;</b></td>
+    <td class="light" align="right"><b><?= _("Match") ?>&nbsp;</b></td>
     <td class="item" align="left">
 
 <table border="0" width="100%" cellpadding="0">
 <tr>
     <td align="left">
-        <input class="item" type="checkbox" name="fields[]" value="to" /><b><?= _("To:") ?></b>&nbsp;&nbsp;
-        <input class="item" type="checkbox" name="fields[]" value="cc" /><b><?= _("Cc:") ?></b>&nbsp;&nbsp;
-        <input class="item" type="checkbox" name="fields[]" value="from" /><b><?= _("From:") ?></b>&nbsp;&nbsp;
-        <input class="item" type="checkbox" name="fields[]" value="subject" /><b><?= _("Subject:") ?></b>&nbsp;&nbsp;
-        <input class="item" type="checkbox" name="fields[]" value="body" /><b><?= _("Body") ?></b>&nbsp;&nbsp;
+        <b>any</b> <input type="radio" class="fixed" name="matchingrule" value='any'/>
+        <b>all</b> <input type="radio" class="fixed" name="matchingrule" value='all'/>
+    </td>
+    <td align="right"><?= Help::link('imp', 'filters-matchingrule') ?></td>
+</tr>
+</table> 
+ 
+ </td>
+</tr>
+
+
+<tr>
+    <td class="light" align="right"><b><?= _("To:") ?>&nbsp;</b></td>
+    <td class="item" align="left">
+
+        <table border="0" width="100%" cellpadding="0">
+        <tr>
+            <td align="left">
+                <input type="text" class="fixed" size="50" name="to" />
     </td>
 <?php if ($conf['user']['online_help'] && $browser->hasFeature('javascript')): ?>
-    <td align="right"><?= Help::link('imp', 'filters-field') ?></td>
+    <td align="right"><?= Help::link('imp', 'filters-text') ?></td>
 <?php else: ?>
     <td>&nbsp;</td>
 <?php endif; ?>
@@ -27,13 +41,75 @@
     </td>
 </tr>
 <tr>
-    <td class="light" align="right"><b><?= _("Text") ?>&nbsp;</b></td>
+    <td class="light" align="right"><b><?= _("Cc:") ?>&nbsp;</b></td>
     <td class="item" align="left">
 
 <table border="0" width="100%" cellpadding="0">
 <tr>
     <td align="left">
-        <input type="text" class="fixed" size="50" name="text" />
+                <input type="text" class="fixed" size="50" name="cc" />
+            </td>
+        <?php if ($conf['user']['online_help'] && $browser->hasFeature('javascript')): ?>
+            <td align="right"><?= Help::link('imp', 'filters-text') ?></td>
+        <?php else: ?>
+            <td>&nbsp;</td>
+        <?php endif; ?>
+        </tr>
+        </table> 
+         
+    </td>
+</tr>
+
+
+<tr>
+    <td class="light" align="right"><b><?= _("From:") ?>&nbsp;</b></td>
+    <td class="item" align="left">
+
+        <table border="0" width="100%" cellpadding="0">
+        <tr>
+            <td align="left">
+                <input type="text" class="fixed" size="50" name="from" />
+            </td>
+        <?php if ($conf['user']['online_help'] && $browser->hasFeature('javascript')): ?>
+            <td align="right"><?= Help::link('imp', 'filters-text') ?></td>
+        <?php else: ?>
+            <td>&nbsp;</td>
+        <?php endif; ?>
+        </tr>
+        </table> 
+         
+    </td>
+</tr>
+
+
+<tr>
+    <td class="light" align="right"><b><?= _("Subject:") ?>&nbsp;</b></td>
+    <td class="item" align="left">
+
+        <table border="0" width="100%" cellpadding="0">
+        <tr>
+            <td align="left">
+                <input type="text" class="fixed" size="50" name="subject" />
+            </td>
+        <?php if ($conf['user']['online_help'] && $browser->hasFeature('javascript')): ?>
+            <td align="right"><?= Help::link('imp', 'filters-text') ?></td>
+        <?php else: ?>
+            <td>&nbsp;</td>
+        <?php endif; ?>
+        </tr>
+        </table> 
+         
+    </td>
+</tr>
+
+<tr>
+    <td class="light" align="right"><b><?= _("Body:") ?>&nbsp;</b></td>
+    <td class="item" align="left">
+
+        <table border="0" width="100%" cellpadding="0">
+        <tr>
+            <td align="left">
+                <input type="text" class="fixed" size="50" name="body" />
     </td>
 <?php if ($conf['user']['online_help'] && $browser->hasFeature('javascript')): ?>
     <td align="right"><?= Help::link('imp', 'filters-text') ?></td>

---------------------- multipart/mixed attachment--