From c03279de817f303588aa2f458e40c23d5bdd06bd Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Tue, 18 Aug 2015 21:36:12 -0500
Subject: [PATCH] filter: Implement "Add Rule" button

Drop the 25 rule limit
---
 include/class.filter.php     | 48 ++++++++-------------
 include/staff/filter.inc.php | 84 ++++++++++++++++++++++++++----------
 2 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/include/class.filter.php b/include/class.filter.php
index ada35a259..0febfb896 100644
--- a/include/class.filter.php
+++ b/include/class.filter.php
@@ -176,20 +176,6 @@ class Filter {
         return $this->ht['rules'];
     }
 
-    function getFlatRules() { //Format used on html... I'm ashamed
-
-        $info=array();
-        if(($rules=$this->getRules())) {
-            foreach($rules as $k=>$rule) {
-                $i=$k+1;
-                $info["rule_w$i"]=$rule['w'];
-                $info["rule_h$i"]=$rule['h'];
-                $info["rule_v$i"]=$rule['v'];
-            }
-        }
-        return $info;
-    }
-
     function addRule($what, $how, $val,$extra=array()) {
         $errors = array();
 
@@ -410,36 +396,36 @@ class Filter {
         $types = array_keys(self::getSupportedMatchTypes());
 
         $rules=array();
-        for($i=1; $i<=25; $i++) { //Expecting no more than 25 rules...
-            if($vars["rule_w$i"] || $vars["rule_h$i"]) {
+        foreach ($vars['rules'] as $i=>$rule) {
+            if($rule["w"] || $rule["h"]) {
                 // Check for REGEX compile errors
-                if (in_array($vars["rule_h$i"], array('match','not_match'))) {
-                    $wrapped = "/".$vars["rule_v$i"]."/iu";
-                    if (false === @preg_match($vars["rule_v$i"], ' ')
+                if (in_array($rule["h"], array('match','not_match'))) {
+                    $wrapped = "/".$rule["v"]."/iu";
+                    if (false === @preg_match($rule["v"], ' ')
                             && (false !== @preg_match($wrapped, ' ')))
-                        $vars["rule_v$i"] = $wrapped;
+                        $rule["v"] = $wrapped;
                 }
 
-                if(!$vars["rule_w$i"] || !in_array($vars["rule_w$i"],$matches))
+                if(!$rule["w"] || !in_array($rule["w"],$matches))
                     $errors["rule_$i"]=__('Invalid match selection');
-                elseif(!$vars["rule_h$i"] || !in_array($vars["rule_h$i"],$types))
+                elseif(!$rule["h"] || !in_array($rule["h"],$types))
                     $errors["rule_$i"]=__('Invalid match type selection');
-                elseif(!$vars["rule_v$i"])
+                elseif(!$rule["v"])
                     $errors["rule_$i"]=__('Value required');
-                elseif($vars["rule_w$i"]=='email'
-                        && $vars["rule_h$i"]=='equal'
-                        && !Validator::is_email($vars["rule_v$i"]))
+                elseif($rule["w"]=='email'
+                        && $rule["h"]=='equal'
+                        && !Validator::is_email($rule["v"]))
                     $errors["rule_$i"]=__('Valid email required for the match type');
-                elseif (in_array($vars["rule_h$i"], array('match','not_match'))
-                        && (false === @preg_match($vars["rule_v$i"], ' ')))
+                elseif (in_array($rule["h"], array('match','not_match'))
+                        && (false === @preg_match($rule["v"], ' ')))
                     $errors["rule_$i"] = sprintf(__('Regex compile error: (#%s)'),
                         preg_last_error());
 
 
                 else //for everything-else...we assume it's valid.
-                    $rules[]=array('what'=>$vars["rule_w$i"],
-                        'how'=>$vars["rule_h$i"],'val'=>trim($vars["rule_v$i"]));
-            }elseif($vars["rule_v$i"]) {
+                    $rules[]=array('what'=>$rule["w"],
+                        'how'=>$rule["h"],'val'=>trim($rule["v"]));
+            }elseif($rule["v"]) {
                 $errors["rule_$i"]=__('Incomplete selection');
             }
         }
diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php
index 3a165d4bf..8767a0ec8 100644
--- a/include/staff/filter.inc.php
+++ b/include/staff/filter.inc.php
@@ -9,14 +9,16 @@ if($filter && $_REQUEST['a']!='add'){
     $title=__('Update Filter');
     $action='update';
     $submit_text=__('Save Changes');
-    $info=array_merge($filter->getInfo(),$filter->getFlatRules());
+    $info=array_merge($filter->getInfo());
     $info['id']=$filter->getId();
+    $info['rules'] = $filter->getRules();
     $qs += array('id' => $filter->getId());
 }else {
     $title=__('Add New Filter');
     $action='add';
     $submit_text=__('Add Filter');
     $info['isactive']=isset($info['isactive'])?$info['isactive']:0;
+    $info['rules'] = array();
     $qs += array('a' => $_REQUEST['a']);
 }
 $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
@@ -127,7 +129,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                     </th>
                 </tr>
             </thead>
-            <tbody>
+            <tbody id="rules">
                 <tr>
                     <td colspan=2>
                        <em><?php echo __('Rules Matching Criteria');?>:</em>
@@ -147,50 +149,75 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                     </td>
                 </tr>
                 <?php
-                $n=($filter?$filter->getNumRules():0)+2; //2 extra rules of unlimited.
-                for($i=1; $i<=$n; $i++){ ?>
-                <tr id="r<?php echo $i; ?>">
+                foreach ($info['rules'] as $i=>$rule) { ?>
+                <tr>
                     <td colspan="2">
-                        <div>
-                            <select style="max-width: 200px;" name="rule_w<?php echo $i; ?>">
-                                <option value="">&mdash; <?php echo __('Select One');?> &mdash;</option>
+                        <select style="max-width: 200px;" name="rules[<?php echo $i; ?>][w]">
+                            <option value="">&mdash; <?php echo __('Select One');?> &mdash;</option>
                                 <?php
                                 foreach ($matches as $group=>$ms) { ?>
                                     <optgroup label="<?php echo __($group); ?>"><?php
                                     foreach ($ms as $k=>$v) {
-                                        $sel=($info["rule_w$i"]==$k)?'selected="selected"':'';
+                                        $sel=($rule["w"]==$k)?'selected="selected"':'';
                                         echo sprintf('<option value="%s" %s>%s</option>',
                                             $k,$sel,__($v));
                                     } ?>
                                 </optgroup>
                                 <?php } ?>
                             </select>
-                            <select name="rule_h<?php echo $i; ?>">
+                            <select name="rules[<?php echo $i; ?>][h]">
                                 <option value="0">&mdash; <?php echo __('Select One');?> &mdash;</option>
                                 <?php
                                     foreach($match_types as $k=>$v){
-                                    $sel=($info["rule_h$i"]==$k)?'selected="selected"':'';
+                                    $sel=($rule["h"]==$k)?'selected="selected"':'';
                                     echo sprintf('<option value="%s" %s>%s</option>',
                                         $k,$sel,$v);
                                 }
                                 ?>
                             </select>&nbsp;
-                            <input class="ltr" type="text" size="60" name="rule_v<?php echo $i; ?>" value="<?php echo $info["rule_v$i"]; ?>">
-                            &nbsp;<span class="error">&nbsp;<?php echo $errors["rule_$i"]; ?></span>
-                        <?php
-                        if($info["rule_w$i"] || $info["rule_h$i"] || $info["rule_v$i"]){ ?>
-                        <div class="pull-right" style="padding-right:20px;"><a href="#" class="clearrule">(<?php echo __('clear');?>)</a></div>
-                        <?php
-                        } ?>
-                        </div>
+                            <input type="text" size="60" name="rules[<?php echo $i; ?>][v]" value="<?php echo $rule["v"]; ?>">
+                        <div class="pull-right" style="padding-right:20px;"><a href="#" class="clearrule"
+                            onclick="javascript: $(this).closest('tr').remove();">(<?php echo __('clear');?>)</a></div>
+                        <div class="error"><?php echo $errors["rule_$i"]; ?></div>
                     </td>
                 </tr>
-                <?php
-                    if($i>=25) //Hardcoded limit of 25 rules...also see class.filter.php
-                       break;
+<?php           $maxi = max($maxi ?: 0, $i+1);
                 } ?>
             </tbody>
+            <tbody class="hidden" id="new-rule-template">
+                <tr>
+                    <td colspan="2">
+                        <select style="max-width: 200px;" data-name="rulew">
+                            <option value="">&mdash; <?php echo __('Select One');?> &mdash;</option>
+                            <?php
+                            foreach ($matches as $group=>$ms) { ?>
+                                <optgroup label="<?php echo __($group); ?>"><?php
+                                foreach ($ms as $k=>$v) {
+                                    echo sprintf('<option value="%s">%s</option>',
+                                        $k,__($v));
+                                } ?>
+                            </optgroup>
+                            <?php } ?>
+                        </select>
+                        <select data-name="ruleh">
+                            <option value="0">&mdash; <?php echo __('Select One');?> &mdash;</option>
+                            <?php
+                                foreach($match_types as $k=>$v){
+                                echo sprintf('<option value="%s">%s</option>',
+                                    $k,$v);
+                            }
+                            ?>
+                        </select>&nbsp;
+                        <input type="text" size="60" data-name="rulev">
+                    </td>
+                </tr>
+            </tbody>
         </table>
+        <div style="padding: 5px">
+            <button class="green button" type="button" id="add-rule">
+                <i class="icon-plus-sign"></i> <?php echo __('Add Rule'); ?>
+            </button>
+        </div>
     </div>
     <!-- ======================= FILTER ACTIONS ========================= -->
     <div class="tab_content hidden" id="filter_actions">
@@ -313,5 +340,16 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
       });
       return ui;
    };
-   $('#dynamic-actions').sortable({helper: fixHelper, opacity: 0.5});
+   $(function() {
+     $('#dynamic-actions').sortable({helper: fixHelper, opacity: 0.5});
+     var next = <?php echo $maxi; ?>;
+     $('#add-rule').click(function() {
+       var clone = $('#new-rule-template tr').clone();
+       clone.find('[data-name=rulew]').attr('name', 'rules['+next+'][w]');
+       clone.find('[data-name=ruleh]').attr('name', 'rules['+next+'][h]');
+       clone.find('[data-name=rulev]').attr('name', 'rules['+next+'][v]');
+       clone.appendTo('#rules');
+       next++;
+     });
+   });
 </script>
-- 
GitLab