Projet

Général

Profil

Paste
Statistiques
| Branche: | Révision:

ryxeo-glpi-git / inc / rulesengine.class.php @ b67d8923

Historique | Voir | Annoter | Télécharger (67,9 ko)

1
<?php
2
/*
3
 * @version $Id: rulesengine.class.php 7901 2009-01-26 17:32:14Z remi $
4
 -------------------------------------------------------------------------
5
 GLPI - Gestionnaire Libre de Parc Informatique
6
 Copyright (C) 2003-2009 by the INDEPNET Development Team.
7

8
 http://indepnet.net/   http://glpi-project.org
9
 -------------------------------------------------------------------------
10

11
 LICENSE
12

13
 This file is part of GLPI.
14

15
 GLPI is free software; you can redistribute it and/or modify
16
 it under the terms of the GNU General Public License as published by
17
 the Free Software Foundation; either version 2 of the License, or
18
 (at your option) any later version.
19

20
 GLPI is distributed in the hope that it will be useful,
21
 but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 GNU General Public License for more details.
24

25
 You should have received a copy of the GNU General Public License
26
 along with GLPI; if not, write to the Free Software
27
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
 --------------------------------------------------------------------------
29
 */
30

    
31
// ----------------------------------------------------------------------
32
// Original Author of file: Walid Nouh
33
// Purpose of file:
34
// ----------------------------------------------------------------------
35
if (!defined('GLPI_ROOT')){
36
        die("Sorry. You can't access directly to this file");
37
        }
38

    
39

    
40
class SingletonRuleList {
41
        /// Items list
42
        var $list;
43
        /// Items loaded ?
44
        var $load;        
45
        
46
        /**
47
         * Constructor
48
        **/
49
        function SingletonRuleList () {
50
                $this->list = array();
51
                $this->load = 0;
52
        }
53
         
54
}
55

    
56
/**
57
 * get a unique instance of a SingletonRuleList for a type of RuleCollection
58
 * 
59
 * Not member of SingletonRuleList because PHP 5 need 'static function'
60
 * 
61
 * @param $type of the Rule listed
62
 * @return unique instance of an object
63
 */
64
function &getInstanceOfSingletonRuleList($type) {
65
        static $instances = array();
66
        
67
        if (!isset($instances[$type])) {
68
                $instances[$type] = new SingletonRuleList();
69
                // echo("++ getInstance($type) : created\n");
70
        }
71
        // else        echo("++ getInstance($type) : reused\n");
72
        
73
        return $instances[$type];
74
}
75

    
76
class RuleCollection {
77
        /// Rule type
78
        var $rule_type;
79
        /// Name of the class used to rule
80
        var $rule_class_name="Rule";
81
        /// process collection stop on first matched rule
82
        var $stop_on_first_match=false;
83
        /// Right needed to use this rule collection
84
        var $right="config";
85
        /// field used to order rules
86
        var $orderby="ranking";
87
        /// Processing several rules : use result of the previous one to computer the current one
88
        var $use_output_rule_process_as_next_input=false;
89
        
90
        /// Rule collection can be replay (for dictionnary)
91
        var $can_replay_rules=false;
92
        /// List of rules of the rule collection
93
        var $RuleList=NULL;
94
        
95
        /**
96
        * Constructor
97
        * @param rule_type the rule type used for the collection
98
        **/
99
        function RuleCollection($rule_type){
100
                $this->rule_type = $rule_type;
101
        }
102

    
103
        /**
104
        * Get Collection Size : retrieve the number of rules
105
        * 
106
        * @return : number of rules
107
        **/
108
        function getCollectionSize(){
109

    
110
                return countElementsInTable("glpi_rules_descriptions", "rule_type=".$this->rule_type);
111
        }
112
        
113
        /**
114
        * Get Collection Part : retrieve descriptions of a range of rules
115
        * 
116
        * @param $start : first rule (in the result set)
117
        * @param $limit : max number of rules ti retrieve
118
        **/
119
        function getCollectionPart($start=0,$limit=0){
120
                global $DB;
121
                
122
                $this->RuleList = new SingletonRuleList($this->rule_type);
123
                $this->RuleList->list = array();
124
                        
125
                //Select all the rules of a different type
126
                $sql = "SELECT * FROM glpi_rules_descriptions WHERE rule_type='" . $this->rule_type . "' ORDER by `".$this->orderby."` ASC";
127
                if ($limit) {
128
                        $sql .= " LIMIT $start,$limit";
129
                }
130

    
131
                $result = $DB->query($sql);
132
                if ($result){
133
                         while ($data=$DB->fetch_assoc($result)) {
134
                                 //For each rule, get a Rule object with all the criterias and actions
135
                                $tempRule= $this->getRuleClass();
136
                                $tempRule->fields = $data;
137
                                $this->RuleList->list[] = $tempRule;
138
                        }
139
                }
140
        }
141

    
142
        /**
143
        * Get Collection Datas : retrieve descriptions and rules
144
        * @param $retrieve_criteria Retrieve the criterias of the rules ?
145
        * @param $retrieve_action Retrieve the action of the rules ?
146
        **/
147
        function getCollectionDatas($retrieve_criteria=0,$retrieve_action=0){
148
                global $DB;
149
                
150
                if ($this->RuleList === NULL)
151
                        $this->RuleList = getInstanceOfSingletonRuleList($this->rule_type);
152
                        
153
                $need = 1+($retrieve_criteria?2:0)+($retrieve_action?4:0);
154

    
155
                // check if load required
156
                if (($need & $this->RuleList->load) != $need) {
157

    
158
                        //Select all the rules of a different type
159
                        $sql = "SELECT ID FROM glpi_rules_descriptions WHERE rule_type='".$this->rule_type."' ORDER by `".$this->orderby."` ASC";
160
                         $result = $DB->query($sql);
161
                        if ($result){
162
                                $this->RuleList->list = array();
163
                                 while ($rule=$DB->fetch_array($result)) {
164
                                         //For each rule, get a Rule object with all the criterias and actions
165
                                        $tempRule= $this->getRuleClass();
166
                                        if ($tempRule->getRuleWithCriteriasAndActions($rule["ID"],$retrieve_criteria,$retrieve_action)){
167
                                                //Add the object to the list of rules
168
                                                $this->RuleList->list[] = $tempRule;
169
                                        }
170
                                }
171
                                $this->RuleList->load = $need;
172
                        }
173
                }
174
        }
175

    
176
        /**
177
         * Get a instance of the class to manipulate rule of this collection
178
         * 
179
        **/
180
        function getRuleClass(){
181
                return new $this->rule_class_name();
182
        }
183

    
184
        /**
185
         * Is a confirmation needed before replay on DB ?
186
         * If needed need to send 'replay_confirm' in POST 
187
         * @param $target filename : where to go when done
188
         * @return  true if confirmtion is needed, else false
189
        **/
190
        function warningBeforeReplayRulesOnExistingDB($target){
191
                return false;
192
        }
193

    
194
        /**
195
         * Replay Collection on DB
196
         * @param $offset  first row to work on
197
         * @param $maxtime float : max system time to stop working 
198
         * @param $items   array containg items to replay. If empty -> all
199
         * @param $params  additional parameters if needed
200
         * 
201
         * @return -1 if all rows done, else offset for next run
202
        **/
203
        function replayRulesOnExistingDB($offset=0,$maxtime=0, $items=array(),$params=array()){
204

    
205
        }
206

    
207
        /**
208
        * Get title used in list of rules
209
        * @return Title of the rule collection
210
        **/        
211
        function getTitle(){
212
                global $LANG;
213
                return $LANG["rulesengine"][29];
214
        }
215

    
216
        /**
217
        * Show the list of rules
218
        * @param $target  
219
        * @return nothing
220
        **/
221
        function showForm($target){
222
                global $CFG_GLPI, $LANG;
223
                        
224
                $canedit = haveRight($this->right, "w");
225

    
226
                //Display informations about the how the rules engine process the rules
227
                if ($this->stop_on_first_match){
228
                        //The engine stop on the first matched rule
229
                        echo "<span class='center'><strong>".$LANG["rulesengine"][120]."</strong></span><br>";
230
                } else {
231
                        //The engine process all the rules
232
                        echo "<span class='center'><strong>".$LANG["rulesengine"][121]."</strong></span><br>";
233
                }
234
                if ($this->use_output_rule_process_as_next_input){
235
                        //The engine keep the result of a rule to be processed further
236
                        echo "<span class='center'><strong>".$LANG["rulesengine"][122]."</strong></span><br>";
237
                }
238

    
239
                $nb = $this->getCollectionSize();
240
                $start = (isset($_GET["start"]) ? $_GET["start"] : 0);
241
                if ($start >= $nb) {
242
                        $start = 0;
243
                }
244
                $limit = $_SESSION["glpilist_limit"];
245

    
246
                $this->getCollectionPart($start,$limit);
247
                
248
                printPager($start,$nb,$_SERVER['PHP_SELF'],"");
249
                
250
                echo "<br><form name='ruleactions_form' id='ruleactions_form' method='post' action=\"$target\">\n";
251
                echo "<div class='center'>"; 
252
                echo "<table class='tab_cadrehov'>";
253

    
254
                echo "<tr><th colspan='6'><div class='relative'><span><strong>" . $this->getTitle() . "</strong></span>";
255
                if ($canedit){
256
                        echo "<span style='  position:absolute; right:0; margin-right:5px; font-size:10px;'><a href=\"".ereg_replace(".php",".form.php",$target)."\"><img src=\"".$CFG_GLPI["root_doc"]."/pics/plus.png\" alt='+' title='".$LANG["buttons"][8]."'></a></span>";
257
                }
258

    
259
                echo "</div></th></tr>";
260
                echo "<tr>";
261
                echo "<td class='tab_bg_2'></td>";
262
                echo "<td class='tab_bg_2'>".$LANG["common"][16]."</td>";
263
                echo "<td class='tab_bg_2'>".$LANG["joblist"][6]."</td>";
264
                echo "<td class='tab_bg_2'>".$LANG["common"][60]."</td>";
265
                echo "<td class='tab_bg_2' colspan='2'></td>";
266
                echo "</tr>";
267
                
268
                //foreach ($this->RuleList->list as $rule){
269
                for ($i=$start,$j=0 ; isset($this->RuleList->list[$j]) ; $i++,$j++) {
270
                        $this->RuleList->list[$j]->showMinimalForm($target,$i==0,$i==$nb-1);
271
                }
272
                echo "</table>";
273
                echo "</div>";
274
                if ($canedit&&$nb>0) {
275
                        echo "<div class='center'>";
276
                        echo "<table width='80%'>";
277
                        
278
                        echo "<tr><td><img src=\"" . $CFG_GLPI["root_doc"] . "/pics/arrow-left.png\" alt=''></td><td class='center'><a onclick= \"if ( markAllRows('entityaffectation_form') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?select=all'>" . $LANG["buttons"][18] . "</a></td>";
279

    
280
                        echo "<td>/</td><td class='center'><a onclick= \"if ( unMarkAllRows('entityaffectation_form') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?select=none'>" . $LANG["buttons"][19] . "</a>";
281
                        echo "</td><td align='left' width='80%'>";
282
                        echo "<select name=\"massiveaction\" id='massiveaction'>";
283
                        echo "<option value=\"-1\" selected>-----</option>";
284
                        echo "<option value=\"delete\">".$LANG["buttons"][6]."</option>";
285
                        if ($this->orderby=="ranking"){
286
                                echo "<option value=\"move_rule\">".$LANG["buttons"][20]."</option>";
287
                        }
288
                        echo "<option value=\"activate_rule\">".$LANG["buttons"][41]."</option>";
289
                        echo "</select>";
290

    
291
                        $params=array('action'=>'__VALUE__',
292
                                        'type'=>RULE_TYPE,
293
                                        'rule_type'=>$this->rule_type,
294
                                        );
295
                        
296
                        ajaxUpdateItemOnSelectEvent("massiveaction","show_massiveaction",$CFG_GLPI["root_doc"]."/ajax/dropdownMassiveAction.php",$params);
297
                
298
                        echo "<span id='show_massiveaction'>&nbsp;</span>\n";                        
299

    
300
                        echo "</td>";
301
                        if ($this->can_replay_rules){
302
                                echo "<td><input type='submit' name='replay_rule' value=\"" . $LANG["rulesengine"][76] . "\" class='submit'></td>";
303
                        }
304
                        echo "</tr>";
305
                        
306
                        echo "</table>";
307
                        echo "</div>";
308
                } 
309
                
310
                echo "<span class='center'><a href='#' onClick=\"var w=window.open('".$CFG_GLPI["root_doc"]."/front/popup.php?popup=test_all_rules&amp;rule_type=".$this->rule_type."&amp' ,'glpipopup', 'height=400, width=1000, top=100, left=100, scrollbars=yes' );w.focus();\">".$LANG["rulesengine"][84]."</a></span>"; 
311
                echo "</form>";
312

    
313

    
314
                $this->showAdditionalInformationsInForm($target);
315

    
316
        }
317

    
318
        /**
319
        * Show the list of rules
320
        * @param $target  
321
        * @return nothing
322
        **/
323
        function showAdditionalInformationsInForm($target){
324
        }        
325

    
326
        /**
327
        * Complete reorder the rules
328
        **/
329
        /* // NOT_USED
330
        function completeReorder(){
331
                global $DB;
332
                $rules = array();
333
                $i=0;
334
                $sql ="SELECT ID FROM glpi_rules_descriptions WHERE rule_type = '".$this->rule_type."' ORDER BY ranking ASC";
335
                
336
                if ($result = $DB->query($sql)){
337
                        //Reorder rules : we reaffect ranking for each rule of type $type
338
                        while ($data=$DB->fetch_array($result)){
339
                                $sql = "UPDATE glpi_rules_descriptions SET ranking='".$i."' WHERE ID='".$data["ID"]."'";
340
                                $DB->query($sql);                                
341
                                $i++;
342
                        }
343
                }
344
        }
345
        */
346

    
347
        /**
348
        * Modify rule's ranking and automatically reorder all rules
349
        * @param $ID the rule ID whose ranking must be modified
350
        * @param $action up or down
351
        **/
352
        function changeRuleOrder($ID,$action){
353
                global $DB;
354
                //$sql ="SELECT ID FROM glpi_rules_descriptions WHERE rule_type =".$this->rule_type." ORDER BY ranking ASC";
355
                $sql ="SELECT ranking FROM glpi_rules_descriptions WHERE ID ='$ID'";
356
                if ($result = $DB->query($sql)){
357
                        if ($DB->numrows($result)==1){
358
                                
359
                                $current_rank=$DB->result($result,0,0);
360
                                // Search rules to switch
361
                                $sql2="";
362
                                switch ($action){
363
                                        case "up":
364
                                                $sql2 ="SELECT ID,ranking FROM glpi_rules_descriptions WHERE rule_type ='".$this->rule_type."' AND ranking < '$current_rank' ORDER BY ranking DESC LIMIT 1";
365
                                        break;
366
                                        case "down":
367
                                                $sql2="SELECT ID,ranking FROM glpi_rules_descriptions WHERE rule_type ='".$this->rule_type."' AND ranking > '$current_rank' ORDER BY ranking ASC LIMIT 1";
368
                                        break;
369
                                        default :
370
                                                return false;
371
                                        break;
372
                                }
373
                                if ($result2 = $DB->query($sql2)){
374
                                        if ($DB->numrows($result2)==1){
375
                                                list($other_ID,$new_rank)=$DB->fetch_array($result2);
376
                                                $query="UPDATE glpi_rules_descriptions SET ranking='$new_rank' WHERE ID ='$ID'";
377
                                                $query2="UPDATE glpi_rules_descriptions SET ranking='$current_rank' WHERE ID ='$other_ID'";
378
                                                return ($DB->query($query)&&$DB->query($query2));
379
                                        }
380
                                }
381
                        }
382
                        return false;
383
                }
384
        }
385
        
386
        /**
387
         * Update Rule Order when deleting a rule
388
         * 
389
         * @param $ranking rank of the deleted rule
390
         * 
391
         * @return true if all ok
392
        **/
393
        function deleteRuleOrder($ranking){
394
                global $DB;
395
                $rules = array();
396
                $sql ="UPDATE glpi_rules_descriptions SET ranking=ranking-1 WHERE rule_type ='".$this->rule_type."' AND ranking > '$ranking' ";
397
                return $DB->query($sql);
398
        }
399
        
400
        /**
401
         * Move a rule in an ordered collection
402
         * 
403
         * @param $ID of the rule to move
404
         * @param $ref_ID of the rule position  (0 means all, so before all or after all)
405
         * @param $type of move : after or before
406
         * 
407
         * @return true if all ok
408
         * 
409
        **/
410
        function moveRule($ID,$ref_ID,$type='after'){
411
                global $DB;
412

    
413
                $ruleDescription = new Rule;
414
                
415
                // Get actual ranking of Rule to move
416
                $ruleDescription->getFromDB($ID);
417
                $old_rank=$ruleDescription->fields["ranking"];
418
                
419
                // Compute new ranking
420
                if ($ref_ID) { // Move after/before an existing rule
421
                        $ruleDescription->getFromDB($ref_ID);
422
                        $rank=$ruleDescription->fields["ranking"];        
423
                        
424
                } else if ($type == "after") {
425
                        // Move after all                         
426
                        $query = "SELECT MAX(ranking) AS maxi FROM glpi_rules_descriptions  " .
427
                                        " WHERE rule_type ='".$this->rule_type."' ";
428
                        $result = $DB->query($query);
429
                        $ligne = $DB->fetch_array($result);
430
                        $rank = $ligne['maxi'];
431
                } else { 
432
                        // Move before all
433
                        $rank=0;
434
                }        
435

    
436
                // Move others rules in the collection
437
                if ($old_rank < $rank) {
438
                        if ($type=="before") $rank--;
439

    
440
                        // Move back all rules between old and new rank
441
                        $query = "UPDATE glpi_rules_descriptions SET ranking=ranking-1 " .
442
                                        " WHERE rule_type ='".$this->rule_type."' " .
443
                                        " AND ranking > '$old_rank' AND ranking <= '$rank'";
444
                        $result = $DB->query($query);
445
                        
446
                } else if ($old_rank > $rank) {
447
                        if ($type=="after") $rank++;
448
                        
449
                        // Move forward all rule  between old and new rank 
450
                        $query = "UPDATE glpi_rules_descriptions SET ranking=ranking+1 " .
451
                                        " WHERE rule_type ='".$this->rule_type."' " .
452
                                        " AND ranking >= '$rank' AND ranking < '$old_rank'";
453
                        $result = $DB->query($query);
454

    
455
                } else { // $old_rank == $rank : nothing to do
456
                        $result = false;
457
                }
458
                
459
                // Move the rule
460
                if ($result && $old_rank != $rank) {        
461
                        $query = "UPDATE glpi_rules_descriptions SET ranking='$rank' " .
462
                                        " WHERE ID='$ID' ";
463
                        $result = $DB->query($query);
464
                } 
465
                return ($result ? true : false);
466
        }
467
        
468
        /**
469
         * Process all the rules collection
470
        * @param input the input data used to check criterias
471
        * @param output the initial ouput array used to be manipulate by actions
472
        * @param params parameters for all internal functions
473
        * @return the output array updated by actions
474

475
        **/
476
        function processAllRules($input=array(),$output=array(),$params=array()){        
477
                // Get Collection datas
478
                $this->getCollectionDatas(1,1);
479
                $input=$this->prepareInputDataForProcess($input,$params);
480

    
481
                if (count($this->RuleList->list)){
482

    
483
                        foreach ($this->RuleList->list as $rule){
484
                                //If the rule is active, process it
485
                                if ($rule->fields["active"]){
486
                                        $output["_rule_process"]=false;
487
                                        $rule->process($input,$output,$params);
488
                                        if ($output["_rule_process"]&&$this->stop_on_first_match){
489
                                                unset($output["_rule_process"]);
490
                                                $output["_ruleid"]=$rule->fields["ID"];
491
                                                return $output;
492
                                        }
493
                                }
494
                                if ($this->use_output_rule_process_as_next_input){
495
                                        $input=$output;
496
                                }
497
                        }
498
                }
499
                return $output;
500
        }
501

    
502

    
503
        /**
504
         * Show form displaying results for rule collection preview
505
         * @param $target where to go
506
         * @param $values data array
507
         **/
508
        function showRulesEnginePreviewCriteriasForm($target,$values){
509

    
510
                global $DB, $LANG,$RULES_CRITERIAS,$RULES_ACTIONS; 
511

    
512
                $input = $this->prepareInputDataForTestProcess();
513

    
514
                if (count($input)){
515
                        echo "<form name='testrule_form' id='testrulesengine_form' method='post' action=\"$target\">\n";
516
                        echo "<div class='center'>";
517
                        echo "<table class='tab_cadre_fixe'>"; 
518
                        echo "<tr><th colspan='2'>" . $LANG["rulesengine"][6] . "</th></tr>"; 
519
                        
520
                         //Brower all criterias 
521
                        foreach ($input as $criteria){
522
                                echo "<tr class='tab_bg_1'>"; 
523

    
524
                                if (isset($RULES_CRITERIAS[$this->rule_type][$criteria])){
525
                                        $criteria_constants = $RULES_CRITERIAS[$this->rule_type][$criteria];
526
                                        echo "<td>".$criteria_constants["name"].":</td>";
527
                                }else{
528
                                        echo "<td>".$criteria.":</td>";
529
                                }
530
                                echo "<td>";
531

    
532
                                $rule = getRuleClass($this->rule_type);
533
                                $rule->displayCriteriaSelectPattern($criteria,$criteria,PATTERN_IS,isset($values[$criteria])?$values[$criteria]:'');
534
                                echo "</td>";
535
                                echo "</tr>"; 
536
                        }
537
                        $rule->showSpecificCriteriasForPreview($_POST);
538

    
539
                        echo "<tr><td class='tab_bg_2' colspan='2' align='center'>"; 
540
                        echo "<input type='submit' name='test_all_rules' value=\"" . $LANG["buttons"][50] . "\" class='submit'>";
541
                        echo "<input type='hidden' name='rule_type' value=\"" . $this->rule_type . "\">"; 
542
                        echo "</td></tr>"; 
543
                        echo "</table>";
544
                        echo "</div>";
545
                        echo "</form>";
546
                } else {
547
                        echo '<br><div class="center"><strong>'.$LANG["rulesengine"][97].'</strong></div>';
548
                }                
549
                return $input;
550
        }
551

    
552

    
553
        /**
554
        * Test all the rules collection
555
        * @param input the input data used to check criterias
556
        * @param output the initial ouput array used to be manipulate by actions
557
        * @param params parameters for all internal functions
558
        * @return the output array updated by actions
559
        **/
560
        function testAllRules($input=array(),$output=array(),$params=array()){        
561
                // Get Collection datas
562
                $this->getCollectionDatas(1,1);
563
                
564
                if (count($this->RuleList->list)){
565

    
566
                        foreach ($this->RuleList->list as $rule){
567
                                //If the rule is active, process it
568
                                if ($rule->fields["active"]){
569
                                        $output["_rule_process"]=false;
570
                                        $output["result"][$rule->fields["ID"]]["ID"]=$rule->fields["ID"];
571
                                        
572
                                        $rule->process($input,$output,$params);
573
                                        if ($output["_rule_process"]&&$this->stop_on_first_match){
574
                                                unset($output["_rule_process"]);
575
                                                $output["result"][$rule->fields["ID"]]["result"]=1;
576
                                                $output["_ruleid"]=$rule->fields["ID"];
577
                                                return $output;
578
                                        }elseif ($output["_rule_process"]){
579
                                                $output["result"][$rule->fields["ID"]]["result"]=1;
580
                                        }else{
581
                                                $output["result"][$rule->fields["ID"]]["result"]=0;
582
                                        }
583
                                }else{
584
                                        //Rule is inactive
585
                                        $output["result"][$rule->fields["ID"]]["result"]=2;
586
                                }
587
                        }
588
                }
589
                return $output;
590
        }
591

    
592

    
593

    
594
        /**
595
        * Prepare input datas for the rules collection
596
        * @param $input the input data used to check criterias
597
        * @param $params parameters
598
        * @return the updated input datas
599
        **/
600
        function prepareInputDataForProcess($input,$params){
601
                return $input;
602
        }
603

    
604
        /**
605
        * Prepare input datas for the rules collection
606
        * @return the updated input datas
607
        **/
608
        function prepareInputDataForTestProcess(){
609
                global $DB;
610
                $input = array();
611
                
612
                $res = $DB->query("SELECT DISTINCT grc.criteria as criteria FROM glpi_rules_criterias as grc, glpi_rules_descriptions grd WHERE grc.FK_rules=grd.ID AND grd.rule_type='".$this->rule_type."'");
613
                while ($data = $DB->fetch_array($res))
614
                        $input[]=$data["criteria"];
615
                return $input;
616
        }        
617

    
618
        /**
619
         * Show form displaying results for rule engine preview
620
         * @param $target where to go
621
         * @param $input data array
622
         **/
623
        function showRulesEnginePreviewResultsForm($target,$input){
624
                global $LANG,$RULES_ACTIONS;
625
                $output = array();
626

    
627
                $output = $this->testAllRules($input,array(),array());
628
                $rule = getRuleClass($this->rule_type);
629

    
630
                echo "<div class='center'>"; 
631
                
632
                if (isset($output["result"])){
633
                        echo "<table class='tab_cadrehov'>";
634
                        echo "<tr><th colspan='4'>" . $LANG["rulesengine"][82] . "</th></tr>";
635

    
636
                        foreach ($output["result"] as $ID=>$rule_result){
637
                                echo "<tr  class='tab_bg_2'>";
638
                                $rule->getFromDB($ID);
639
                                echo "<td class='tab_bg_2'>";
640
                                echo $rule->fields["name"];
641
                                echo "</td>";
642
                                
643
                                echo "<td class='tab_bg_2'>";
644
                                switch ($rule_result["result"]){
645
                                        case 0 : 
646
                                                echo "<strong>".$LANG["choice"][0]."</strong>";
647
                                        break;
648
                                        case 1 : 
649
                                                echo "<strong>".$LANG["choice"][1]."</strong>";
650
                                        break;
651
                                        case 2 : 
652
                                                echo "<strong>".$LANG["rulesengine"][107]."</strong>";
653
                                        break;
654
                                        
655
                                }
656
                                echo "</td>";
657
                                echo "</tr>";
658
                        }
659
                        echo "</table>";
660
                }
661
                
662
                $output = $this->cleanTestOutputCriterias($output);
663
                unset($output["result"]);                        
664

    
665
                $global_result =(count($output)?1:0);
666
                
667
                echo "<br><table class='tab_cadrehov'>";
668
                $this->showTestResults($rule,$output,$global_result);
669
                echo "</table></div>";
670
                
671
        }
672
        
673
        /**
674
         * Unset criterias from the rule's ouput results (begins by _)
675
         * @param $output clean output array to clean
676
         * @return cleaned array
677
         **/
678
        function cleanTestOutputCriterias($output){
679
                //If output array contains keys begining with _ : drop it
680
                foreach($output as $criteria => $value){
681
                        if ($criteria[0]=='_'){
682
                                unset($output[$criteria]);
683
                        }
684
                }
685
                return $output;                        
686
        }
687
        
688
        /**
689
         * Show test results for a rule
690
         * @param $rule rule object
691
         * @param $output Output data array
692
         * @param $global_result boolean : global result 
693
         * @return cleaned array
694
         **/
695
        function showTestResults($rule,$output,$global_result){
696
                global $LANG,$RULES_ACTIONS;
697
                echo "<tr><th colspan='4'>" . $LANG["rulesengine"][81] . "</th></tr>";
698
                echo "<tr  class='tab_bg_2'>";
699
                echo "<td class='tab_bg_2' colspan='4' align='center'>".$LANG["rulesengine"][41]." : <strong> ".getYesNo($global_result)."</strong></td>";
700

    
701
                foreach ($output as $criteria => $value){
702
                        echo "<tr  class='tab_bg_2'>";
703
                        echo "<td class='tab_bg_2'>";
704
                        echo $RULES_ACTIONS[$this->rule_type][$criteria]["name"];
705
                        echo "</td>";
706
                        echo "<td class='tab_bg_2'>";
707
                        echo $rule->getActionValue($criteria,$value);
708
                        echo "</td>";
709
                        echo "</tr>";
710
                }
711
                echo "</tr>";
712
        }
713
}
714

    
715
/**
716
 * Rule class store all informations about a GLPI rule :
717
 *   - description
718
 *   - criterias
719
 *   - actions
720
**/
721
class Rule extends CommonDBTM{
722

    
723
        ///Actions affected to this rule
724
        var $actions = array();
725

    
726
        ///Criterias affected to this rule
727
        var $criterias = array();
728
        /// Rule type
729
        var $rule_type;
730
        /// Right needed to use this rule
731
        var $right="config";
732
        /// Rules can be sorted ?
733
        var $can_sort;
734
        /// field used to order rules
735
        var $orderby="ranking";
736

    
737
        /**
738
        * Constructor
739
        * @param rule_type the rule type used for the collection
740
        **/
741
        function Rule($rule_type=0) {
742
                $this->table = "glpi_rules_descriptions";
743
                $this->type = -1;
744
                $this->rule_type=$rule_type;
745
                $this->can_sort=false;
746
        }
747

    
748
        function post_getEmpty () {
749
                $this->fields['active']=0;
750
        }
751

    
752
        /**
753
        * Get additional header for rule
754
        * @param $target where to go if link needed
755
        * @return nothing display
756
        **/        
757
        function getTitleRule($target){
758
        }
759
        
760
        /**
761
        * Get title used in rule
762
        * @return Title of the rule
763
        **/        
764
        function getTitle(){
765
                global $LANG;
766
                return $LANG["rulesengine"][8];        
767
        }
768
        
769
        /**
770
        * Show the rule
771
        * @param $target  
772
        * @param $ID ID of the rule  
773
        * @param $withtemplate 
774
        * @return nothing
775
        **/
776
        function showForm($target,$ID,$withtemplate=''){
777
                global $CFG_GLPI, $LANG;
778

    
779
                $canedit=haveRight($this->right,"w");
780

    
781
                $new=false;
782
                if (!empty($ID)&&$ID>0){
783
                        $this->getRuleWithCriteriasAndActions($ID,1,1);
784
                } else {
785
                        $this->getEmpty();
786
                        $new=true;
787
                }
788
                        
789
                $this->getTitleRule($target);
790

    
791
                $this->showOnglets($ID, $new,$_SESSION['glpi_onglet'],"rule_type='".$this->rule_type."'",$this->orderby);
792
                echo "<form name='rule_form'  method='post' action=\"$target\">\n";
793

    
794
                echo "<div class='center'>"; 
795
                echo "<table class='tab_cadre_fixe'>";
796
                echo "<tr><th colspan='4'>" . $this->getTitle() . "</th></tr>";
797
                echo "<tr>";
798
                echo "<td class='tab_bg_2'>".$LANG["common"][16]."</td>";
799
                echo "<td class='tab_bg_2'>";
800
                autocompletionTextField("name",$this->table,"name",$this->fields["name"] ,25);
801
                echo "</td>";
802
                echo "<td class='tab_bg_2'>".$LANG["joblist"][6]."</td>";
803
                echo "<td class='tab_bg_2'>";
804
                autocompletionTextField("description",$this->table,"description",$this->fields["description"] ,25);
805
                echo "</td></tr>";
806

    
807
                echo "<tr>";
808
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][9]."</td>";
809
                echo "<td class='tab_bg_2'>";
810
                $this->dropdownRulesMatch("match",$this->fields["match"]);
811
                echo "</td>";
812
                        
813
                echo "<td class='tab_bg_2'>".$LANG["common"][60]."</td>";
814
                echo "<td class='tab_bg_2'>";
815
                dropdownYesNo("active",$this->fields["active"]);
816
                echo"</td></tr>";
817

    
818
                echo "<tr>";
819
                echo "<td class='tab_bg_2'>".$LANG["common"][25]."</td>";
820
                echo "<td class='tab_bg_2' valign='middle' colspan='3'>";
821
                echo "<textarea  cols='50' rows='3' name='comments' >".$this->fields["comments"]."</textarea>";
822
                echo"</td></tr>";
823
                        
824
                if ($canedit){
825
                        if ($new){
826
                                echo "<tr><td class='tab_bg_2' align='center' colspan='4'>";
827
                                echo "<input type='hidden' name='rule_type' value='".$this->rule_type."'>";
828
                                echo "<input type='submit' name='add_rule' value=\"" . $LANG["buttons"][8] . "\" class='submit'>";
829
                                echo "</td></tr>";
830
                                
831
                        } else {
832
                                echo "<tr><td class='tab_bg_2' align='center' colspan='2'>";
833
                                echo "<input type='hidden' name='ID' value='".$ID."'>";
834
                                echo "<input type='hidden' name='ranking' value='".$this->fields["ranking"]."'>";
835
                                echo "<input type='submit' name='update_rule' value=\"" . $LANG["buttons"][7] . "\" class='submit'></td>";
836
                                echo "<td class='tab_bg_2' align='center' colspan='2'>";
837
                                echo "<input type='submit' name='delete_rule' value=\"" . $LANG["buttons"][6] . "\" class='submit'></td>";
838
                                echo "</tr>";
839

    
840
                                echo "<tr><td class='tab_bg_2' align='center' colspan='4'>";
841
                                echo "<a href='#' onClick=\"var w=window.open('".$CFG_GLPI["root_doc"]."/front/popup.php?popup=test_rule&amp;rule_type=".$this->rule_type."&amp;rule_id=".$this->fields["ID"]."' ,'glpipopup', 'height=400, width=1000, top=100, left=100, scrollbars=yes' );w.focus();\">".$LANG["buttons"][50]."</a>"; 
842
                                echo "</td></tr>";
843
                        }
844
                }                        
845
                echo "</table></div></form>";
846
        }
847

    
848
        /**
849
        * Display a dropdown with all the rule matching
850
        * @param $name dropdown name
851
        * @param $value default value
852
        **/
853
        function dropdownRulesMatch($name,$value=''){
854
                global $LANG;
855

    
856
                $elements[AND_MATCHING] = $LANG["rulesengine"][42];
857
                $elements[OR_MATCHING] = $LANG["rulesengine"][43];
858
                return dropdownArrayValues($name,$elements,$value);
859
        }
860

    
861
        /**
862
         * Get all criterias for a given rule
863
         * @param $ID the rule_description ID
864
         * @param $withcriterias 1 to retrieve all the criterias for a given rule
865
         * @param $withactions  1 to retrive all the actions for a given rule
866
         **/
867
        function getRuleWithCriteriasAndActions($ID, $withcriterias = 0, $withactions = 0) {
868
                if ($ID == ""){
869
                        return $this->getEmpty();
870
                } else {
871
                        if ($ret=$this->getFromDB($ID)){
872
                                if ($withactions){
873
                                        $RuleAction = new RuleAction;
874
                                        $this->actions = $RuleAction->getRuleActions($ID);
875
                                }        
876
                                if ($withcriterias){
877
                                        $RuleCriterias = new RuleCriteria;
878
                                        $this->criterias = $RuleCriterias->getRuleCriterias($ID);
879
                                }
880
                                return true;
881
                        }
882
                }
883
                return false;
884
        }
885
        
886
        /**
887
         * display title for action form
888
         * @param $target where to go if action
889
        **/
890
        function getTitleAction($target){
891
        }
892

    
893
        /**
894
         * display title for criteria form
895
         * @param $target where to go if action
896
        **/
897
        function getTitleCriteria($target){
898
        }
899

    
900
        /**
901
         * Get maximum number of Actions of the Rule (0 = unlimited)
902
         * @return the maximum number of actions
903
        **/
904
        function maxActionsCount(){
905
                // Unlimited
906
                return 0;
907
        }
908

    
909
        /**
910
         * Display all rules actions
911
         * @param $target  where to go for action
912
         * @param $rule_id  rule ID
913
        **/
914
        function showActionsList($target,$rule_id){
915
                global $CFG_GLPI, $LANG;
916
                        
917
                $canedit = haveRight($this->right, "w");
918
                
919
                $this->getTitleAction($target);        
920

    
921
                if (($this->maxActionsCount()==0 || sizeof($this->actions) < $this->maxActionsCount()) && $canedit){
922
                        echo "<form name='actionsaddform' method='post' action=\"$target\">\n";
923
                        $this->addActionForm($rule_id);
924
                        echo "</form>";
925
                }
926
                
927
                echo "<form name='actionsform' id='actionsform' method='post' action=\"$target\">\n";
928
                                
929
                echo "<div class='center'>"; 
930
                echo "<table class='tab_cadrehov'>";
931
                echo "<tr><th colspan='".($canedit?" 4 ":"3")."'>" . $LANG["rulesengine"][7] . "</th></tr>";
932
                echo "<tr  class='tab_bg_2'>";
933
                if ($canedit){
934
                        echo "<td class='tab_bg_2'>&nbsp;</td>";
935
                }
936
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][12]."</td>";
937
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][11]."</td>";
938
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][13]."</td>";
939
                echo "</tr>";
940

    
941
                $nb=count($this->actions);
942
                foreach ($this->actions as $action){
943
                        $this->showMinimalActionForm($action->fields,$canedit);
944
                }
945
                echo "</table></div>";
946
                                
947
                if ($canedit&&$nb>0) {
948
                        echo "<div class='center'>";
949
                        echo "<table  width='80%'>";
950
                        echo "<tr><td><img src=\"" . $CFG_GLPI["root_doc"] . "/pics/arrow-left.png\" alt=''></td><td class='center'><a onclick= \"if ( markAllRows('actionsform') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?select=all'>" . $LANG["buttons"][18] . "</a></td>";
951

    
952
                        echo "<td>/</td><td class='center'><a onclick= \"if ( unMarkAllRows('actionsform') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?select=none'>" . $LANG["buttons"][19] . "</a>";
953
                        echo "</td><td align='left' width='80%'>";
954
                        echo "<input type='submit' name='delete_action' value=\"" . $LANG["buttons"][6] . "\" class='submit'>";
955
                        echo "<input type='hidden' name='rule_id' value='" . $rule_id . "'>";
956
                        echo "</td></tr></table>";
957
                        echo "</div>";
958
                }                         
959
                echo "</form>";
960

    
961
        }
962

    
963
        /**
964
         * Display the add action form
965
         * @param $rule_id rule ID
966
        **/
967
        function addActionForm($rule_id) {
968
                global $LANG,$CFG_GLPI;
969
                echo "<div class='center'>";
970
                echo "<table  class='tab_cadre_fixe'>";
971
                echo "<tr class='tab_bg_1'><th colspan='4'>" . $LANG["rulesengine"][7] . ":</tr>";
972
                echo "<tr  class='tab_bg_2' align='center'><td>";
973
                echo $LANG["rulesengine"][30] . ":";
974
                echo "</td><td>";
975
                $val=$this->dropdownActions(getAlreadyUsedActionsByRuleID($rule_id,$this->rule_type));
976
                echo "</td><td align='left' width='500px'>";
977
                echo "<span id='action_span'>\n";
978
                $_POST["rule_type"]=$this->rule_type;
979
                $_POST["field"]=$val;
980
                include (GLPI_ROOT."/ajax/ruleaction.php");
981
                echo "</span>\n";        
982

    
983
                echo "</td><td>";
984
                echo "<input type=hidden name='FK_rules' value=\"" . $this->fields["ID"] . "\">";
985
                echo "<input type='submit' name='add_action' value=\"" . $LANG["buttons"][8] . "\" class='submit'>";
986
                echo "<input type='hidden' name='rule_id' value='" . $rule_id . "'>";
987
                
988
                echo "</td></tr>";
989

    
990
                echo "</table></div><br>";
991
        }
992

    
993
        /**
994
         * Display the add criteria form
995
         * @param $rule_id rule ID
996
         */
997
        function addCriteriaForm($rule_id) {
998
                global $LANG,$CFG_GLPI,$RULES_CRITERIAS;
999
                echo "<div class='center'>";
1000
                echo "<table  class='tab_cadre_fixe'>";
1001
                echo "<tr class='tab_bg_1'><th colspan='4'>" . $LANG["rulesengine"][16] . ":</tr>";
1002
                echo "<tr class='tab_bg_2' align='center'><td>";
1003
                echo $LANG["rulesengine"][16] . ":";
1004
                echo "</td><td>";
1005
                $val=$this->dropdownCriterias();
1006
                echo "</td><td align='left' width='500px'>";
1007
                
1008
                echo "<span id='criteria_span'>\n";
1009
                $_POST["rule_type"]=$this->rule_type;
1010
                $_POST["criteria"]=$val;
1011
                include (GLPI_ROOT."/ajax/rulecriteria.php");
1012
                echo "</span>\n";        
1013

    
1014
                echo "</td><td>";
1015

    
1016

    
1017
                        
1018
                echo "<input type=hidden name='FK_rules' value=\"" . $this->fields["ID"] . "\">";
1019
                echo "<input type='submit' name='add_criteria' value=\"" . $LANG["buttons"][8] . "\" class='submit'>";
1020
                echo "<input type='hidden' name='rule_id' value='" . $rule_id . "'>";
1021
                echo "</td></tr>";
1022

    
1023
                echo "</table></div><br>";
1024
        }
1025
        /**
1026
         * Get maximum number of criterias of the Rule (0 = unlimited)
1027
        * @return the maximum number of criterias
1028
         */
1029
        function maxCriteriasCount(){
1030
                // Unlimited
1031
                return 0;
1032
        }
1033
        
1034
        /**
1035
         * Display all rules criterias
1036
         * @param $target
1037
         * @param $rule_id
1038
         */
1039
        function showCriteriasList($target,$rule_id)
1040
        {
1041
                global $CFG_GLPI, $LANG;
1042
                        
1043
                $canedit = haveRight($this->right, "w");
1044

    
1045
                
1046
                
1047
                $this->getTitleCriteria($target);
1048
                if (($this->maxCriteriasCount()==0 || sizeof($this->criterias) < $this->maxCriteriasCount()) && $canedit){
1049
                        echo "<form name='criteriasaddform'method='post' action=\"$target\">\n";
1050
                        $this->addCriteriaForm($rule_id);
1051
                        echo "</form>";        
1052
                }
1053
                
1054
                echo "<form name='criteriasform' id='criteriasform' method='post' action=\"$target\">\n";
1055
                echo "<div class='center'>"; 
1056
                echo "<table class='tab_cadrehov'>";
1057
                echo "<tr><th colspan='".($canedit?" 4 ":"3")."'>" . $LANG["rulesengine"][6] . "</th></tr>\n";
1058
                echo "<tr>";
1059
                if ($canedit){
1060
                        echo "<td class='tab_bg_2'>&nbsp;</td>";
1061
                }
1062
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][16]."</td>\n";
1063
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][14]."</td>\n";
1064
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][15]."</td>\n";
1065
                echo "</tr>";
1066
                        
1067
                $maxsize = sizeof($this->criterias);
1068
                foreach ($this->criterias as $criteria){
1069
                        $this->showMinimalCriteriaForm($criteria->fields,$canedit);
1070
                }
1071
                echo "</table></div>";
1072
                if ($canedit&&$maxsize>0) {
1073
                        echo "<div class='center'>\n";
1074
                        echo "<table width='80%'>\n";
1075
                        echo "<tr><td><img src=\"" . $CFG_GLPI["root_doc"] . "/pics/arrow-left.png\" alt=''></td><td class='center'><a onclick= \"if ( markAllRows('criteriasform') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?ID=".$this->fields["ID"]."&amp;select=all'>" . $LANG["buttons"][18] . "</a></td>";
1076

    
1077
                        echo "<td>/</td><td class='center'><a onclick= \"if ( unMarkAllRows('criteriasform') ) return false;\" href='" . $_SERVER['PHP_SELF'] . "?ID=".$this->fields["ID"]."&amp;select=none'>" . $LANG["buttons"][19] . "</a>";
1078
                        echo "</td><td align='left' width='80%'>";
1079
                        echo "<input type='submit' name='delete_criteria' value=\"" . $LANG["buttons"][6] . "\" class='submit'>";
1080
                        echo "<input type='hidden' name='rule_id' value='" . $rule_id . "'>";
1081
                        echo "</td></tr>";
1082
                        echo "</table>";
1083
                        echo "</div>";
1084
                }                 
1085
                echo "</form>";
1086

    
1087
        }        
1088

    
1089
        /**
1090
         * Display the dropdown of the criterias for the rule
1091
         */
1092
        function dropdownCriterias(){
1093
                global $CFG_GLPI;
1094
                $items=array();
1095
                foreach ($this->getCriterias() as $ID => $crit){
1096
                        $items[$ID]=$crit['name'];
1097
                }
1098
                $rand=dropdownArrayValues("criteria", $items);
1099

    
1100
                $params=array('criteria'=>'__VALUE__',
1101
                                'rule_type'=>$this->rule_type,
1102
                );
1103
                ajaxUpdateItemOnSelectEvent("dropdown_criteria$rand","criteria_span",$CFG_GLPI["root_doc"]."/ajax/rulecriteria.php",$params,false);
1104
                ajaxUpdateItem("criteria_span",$CFG_GLPI["root_doc"]."/ajax/rulecriteria.php",$params,false,"dropdown_criteria$rand");
1105

    
1106
                return key($items);
1107
        }
1108

    
1109
        /**
1110
         * Display the dropdown of the actions for the rule
1111
         * @param $used already used actions
1112
         */
1113
        function dropdownActions($used=array()){
1114
                global $CFG_GLPI;
1115

    
1116
                $items=array();
1117
                foreach ($this->getActions() as $ID => $act){
1118
                        $items[$ID]=$act['name'];
1119
                }
1120

    
1121
                $rand=dropdownArrayValues("field", $items,'',$used);
1122
                $params=array('field'=>'__VALUE__',
1123
                                'rule_type'=>$this->rule_type
1124
                );
1125
                ajaxUpdateItemOnSelectEvent("dropdown_field$rand","action_span",$CFG_GLPI["root_doc"]."/ajax/ruleaction.php",$params,false);
1126
                ajaxUpdateItem("action_span",$CFG_GLPI["root_doc"]."/ajax/ruleaction.php",$params,false,"dropdown_field$rand");
1127
        }
1128

    
1129
        /**
1130
         * Get the criterias array definition
1131
         * @return the criterias array
1132
        **/
1133
        
1134
        function getCriterias(){
1135
                global $RULES_CRITERIAS;
1136

    
1137
                if (isset($RULES_CRITERIAS[$this->rule_type])){
1138
                        return $RULES_CRITERIAS[$this->rule_type];
1139
                } else {
1140
                        return array();
1141
                }
1142
        }
1143

    
1144
        /**
1145
         * Get the actions array definition
1146
         * @return the actions array
1147
         */
1148
        function getActions(){
1149
                global $RULES_ACTIONS;
1150
                if (isset($RULES_ACTIONS[$this->rule_type])){
1151
                        return $this->filterActions($RULES_ACTIONS[$this->rule_type]);
1152
                } else {
1153
                        return array();
1154
                }
1155
        }
1156

    
1157
        /**
1158
         * Filter actions if needed
1159
        *  @param $actions the actions array
1160
         * @return the filtered actions array
1161
         */
1162
        function filterActions($actions){
1163
                return $actions;
1164
        }
1165
        /**
1166
         * Get a criteria description by his ID
1167
         * @param $ID the criteria's ID
1168
         * @return the criteria array
1169
        **/
1170
        function getCriteria($ID)
1171
        {
1172
                $criterias=$this->getCriterias();
1173

    
1174
                if (isset($criterias[$ID])){
1175
                        return $criterias[$ID];
1176
                } else {
1177
                        return array();
1178
                }
1179
        }
1180

    
1181
        /**
1182
         * Get a action description by his ID
1183
         * @param $ID the action's ID
1184
         * @return the action array
1185
        **/
1186
        function getAction($ID)
1187
        {
1188
                $actions=$this->getActions();
1189
                if (isset($actions[$ID])){
1190
                        return $actions[$ID];
1191
                } else {
1192
                        return array();
1193
                }
1194
        }
1195

    
1196
        /**
1197
         * Get a criteria description by his ID
1198
         * @param $ID the criteria's ID
1199
         * @return the criteria's description
1200
        **/
1201
        
1202
        function getCriteriaName($ID)
1203
        {
1204
                $criteria=$this->getCriteria($ID);
1205
                if (isset($criteria['name'])){
1206
                        return $criteria['name'];
1207
                } else {
1208
                        return "&nbsp;";
1209
                }
1210
        }
1211

    
1212
        /**
1213
         * Get a action description by his ID
1214
         * @param $ID the action's ID
1215
         * @return the action's description
1216
         */
1217
        function getActionName($ID)
1218
        {
1219
                $action=$this->getAction($ID);
1220
                if (isset($action['name'])){
1221
                        return $action['name'];
1222
                } else {
1223
                        return "&nbsp;";
1224
                }
1225
        }
1226

    
1227
        /**
1228
        * Process the rule
1229
        * @param $input the input data used to check criterias
1230
        * @param $output the initial ouput array used to be manipulate by actions
1231
        * @param $params parameters for all internal functions
1232
        * @return the output array updated by actions. If rule matched add field _rule_process to return value
1233
        */
1234
        function process(&$input,&$output,&$params)
1235
        {
1236
                if (count($this->criterias))        
1237
                {
1238
                        $regex_result=array();
1239
                        
1240
                        $input=$this->prepareInputDataForProcess($input,$params);
1241

    
1242
                         if ($this->checkCriterias($input,$regex_result)){
1243
                                $output=$this->executeActions($output,$params,$regex_result);
1244
        
1245
                                //Hook 
1246
                                $hook_params["rule_type"]=$this->rule_type; 
1247
                                $hook_params["ruleid"]=$this->fields["ID"]; 
1248
                                $hook_params["input"]=$input; 
1249
                                $hook_params["output"]=$output; 
1250
                                doHook("rule_matched",$hook_params); 
1251
                                $output["_rule_process"]=true;
1252
                        }                        
1253
                }
1254
        }
1255

    
1256
        /**
1257
         * Check criterias
1258
         * @param $input the input data used to check criterias
1259
         * @param $regex_result
1260
         * @return boolean if criterias match
1261
        **/
1262
        function checkCriterias($input,&$regex_result){
1263
                $doactions=false;
1264
                reset($this->criterias);
1265
                if ($this->fields["match"]==AND_MATCHING){
1266
                        $doactions=true;                        
1267
                        foreach ($this->criterias as $criteria){
1268
                                $doactions &= $this->checkCriteria($criteria,$input,$regex_result);
1269
                                if (!$doactions) break;
1270
                        }
1271
                } else { // OR MATCHING
1272
                        $doactions=false;
1273
                        foreach ($this->criterias as $criteria){
1274
                                $doactions |= $this->checkCriteria($criteria,$input,$regex_result);
1275
                                if ($doactions) break;
1276
                        }
1277
                }
1278
                return $doactions;
1279
        }
1280

    
1281
        /**
1282
        * Check criterias
1283
        * @param $input the input data used to check criterias
1284
        * @param $regex_result
1285
        * @param $check_results
1286
        * @return boolean if criterias match
1287
        */
1288
        function testCriterias($input,&$regex_result,&$check_results){
1289
                reset($this->criterias);
1290
                
1291
                foreach ($this->criterias as $criteria){
1292
                        $result = $this->checkCriteria($criteria,$input,$regex_result);
1293
                        
1294
                        $check_results[$criteria->fields["ID"]]["name"]=$criteria->fields["criteria"];
1295
                        $check_results[$criteria->fields["ID"]]["value"]=$criteria->fields["pattern"];
1296
                        $check_results[$criteria->fields["ID"]]["result"]=((!$result)?0:1);
1297
                        $check_results[$criteria->fields["ID"]]["ID"]=$criteria->fields["ID"];
1298
                }
1299
        }
1300

    
1301
        /**
1302
         * Process a criteria of a rule
1303
         * @param $criteria criteria to check
1304
         * @param $input the input data used to check criterias
1305
         * @param $regex_result
1306
        **/
1307
        function checkCriteria(&$criteria,&$input,&$regex_result)
1308
        {
1309
                // Undefine criteria field : set to blank
1310
                if (!isset($input[$criteria->fields["criteria"]])){
1311
                        $input[$criteria->fields["criteria"]]='';
1312
                }
1313
                //If the value is not an array
1314
                if (!is_array($input[$criteria->fields["criteria"]])){
1315

    
1316
                        $value=$this->getCriteriaValue($criteria->fields["criteria"],$criteria->fields["condition"],$input[$criteria->fields["criteria"]]);
1317

    
1318
                        // TODO Store value in temp array : $criteria->fields["criteria"] / $criteria->fields["condition"] -> value
1319
                        // TODO : Clean on update action
1320
                        $res = matchRules($value,$criteria->fields["condition"],$criteria->fields["pattern"],$regex_result);
1321
                } else        {
1322
                        //If the value if, in fact, an array of values
1323
                        // Negative condition : Need to match all condition (never be)
1324
                        if (in_array($criteria->fields["condition"],array(PATTERN_IS_NOT,PATTERN_NOT_CONTAIN,REGEX_NOT_MATCH))){
1325
                                $res = true;
1326
                                foreach($input[$criteria->fields["criteria"]] as $tmp){
1327
                                        $value=$this->getCriteriaValue($criteria->fields["criteria"],$criteria->fields["condition"],$tmp);
1328

    
1329
                                        $res &= matchRules($value,$criteria->fields["condition"],$criteria->fields["pattern"],$regex_result);
1330
                                        if (!$res) break;
1331
                                }
1332
                
1333
                        // Positive condition : Need to match one
1334
                         } else {
1335
                                $res = false;
1336
                                foreach($input[$criteria->fields["criteria"]] as $tmp){
1337
                                        $value=$this->getCriteriaValue($criteria->fields["criteria"],$criteria->fields["condition"],$tmp);
1338

    
1339
                                        $res |= matchRules($value,$criteria->fields["condition"],$criteria->fields["pattern"],$regex_result);
1340
                                        if ($res) break;
1341
                                }
1342
        
1343
                        }
1344
                }
1345
                return $res;        
1346
        }
1347

    
1348
        /**
1349
        * Specific prepare input datas for the rule
1350
        * @param $input the input data used to check criterias
1351
        * @param $params parameters
1352
        * @return the updated input datas
1353
        */
1354
        function prepareInputDataForProcess($input,$params){
1355
                return $input;
1356
        }
1357

    
1358
        /**
1359
        * Execute the actions as defined in the rule
1360
        * @param $output the fields to manipulate
1361
        * @param $params parameters
1362
        * @param $regex_results 
1363
        * @return the $output array modified
1364
        */
1365
        function executeActions($output,$params,$regex_results)
1366
        {
1367
                if (count($this->actions)){
1368
                        foreach ($this->actions as $action){
1369
                                switch ($action->fields["action_type"]){
1370
                                        case "assign" :
1371
                                                
1372
                                                $output[$action->fields["field"]] = $action->fields["value"];
1373
                                        break;
1374
                                        case "regex_result":
1375
                                        case "append_regex_result":
1376
                                                //Regex result : assign value from the regex
1377
                                                //Append regex result : append result from a regex
1378
                                                if ($action->fields["action_type"] == "append_regex_result")
1379
                                                        $res=(isset($params[$action->fields["field"]])?$params[$action->fields["field"]]:"");
1380
                                                else
1381
                                                        $res="";        
1382
                                                        
1383
                                                $res .= getRegexResultById($action->fields["value"],$regex_results);
1384
                                                if ($res != null) 
1385
                                                        $output[$action->fields["field"]]=$res;
1386
                                        break;
1387
                                }
1388
                        }
1389
                }
1390
                return $output;
1391
        }
1392

    
1393
        
1394
        function cleanDBonPurge($ID){
1395
                // Delete a rule and all associated criterias and actions
1396
                global $DB;
1397
                $sql = "DELETE FROM glpi_rules_actions WHERE FK_rules='".$ID."'";
1398
                $DB->query($sql);
1399

    
1400
                $sql = "DELETE FROM glpi_rules_criterias WHERE FK_rules='".$ID."'";
1401
                $DB->query($sql);
1402
        }
1403

    
1404
        /**
1405
         * Show the minimal form for the rule
1406
        * @param $target link to the form page
1407
        * @param $first is it the first rule ?
1408
        * @param $last is it the last rule ?
1409
         */
1410
        function showMinimalForm($target,$first=false,$last=false){
1411
                global $LANG,$CFG_GLPI;
1412
                        
1413
                $canedit = haveRight($this->right,"w");
1414
                        
1415
                echo "<tr class='tab_bg_1'>";
1416
                                
1417
                if ($canedit) {
1418
                        echo "<td width='10'>";
1419
                        $sel = "";
1420
                        if (isset ($_GET["select"]) && $_GET["select"] == "all"){
1421
                                $sel = "checked";
1422
                        }
1423
                        echo "<input type='checkbox' name='item[" . $this->fields["ID"] . "]' value='1' $sel>";
1424
                        echo "</td>";
1425
                }
1426
                else
1427
                        echo "<td></td>";
1428
                                
1429
                echo "<td><a href=\"".ereg_replace(".php",".form.php",$target)."?ID=".$this->fields["ID"]."&amp;onglet=1\">" . $this->fields["name"] . "</a> ";
1430
                if (!empty($this->fields["comments"])) {
1431
                        echo "<img alt='' src='".$CFG_GLPI["root_doc"]."/pics/aide.png' onmouseout=\"cleanhide('comments_rules".$this->fields["ID"]."')\" onmouseover=\"cleandisplay('comments_rules".$this->fields["ID"]."')\" >";
1432
                        echo "<span class='over_link' id='comments_rules".$this->fields["ID"]."'>".nl2br($this->fields["comments"])."</span>";                        
1433
                }
1434
                echo "</td>";
1435
                                        
1436
                echo "<td>".$this->fields["description"]."</td>";
1437
                if ($this->fields["active"])
1438
                        echo "<td>".$LANG["choice"][1]."</td>";
1439
                else
1440
                        echo "<td>".$LANG["choice"][0]."</td>";
1441
                                
1442
                if ($this->can_sort && !$first && $canedit){
1443
                        echo "<td><a href=\"".$target."?type=".$this->fields["rule_type"]."&amp;action=up&amp;ID=".$this->fields["ID"]."\"><img src=\"".$CFG_GLPI["root_doc"]."/pics/deplier_up.png\" alt=''></a></td>";
1444
                } else {
1445
                        echo "<td>&nbsp;</td>";
1446
                }
1447
                if ($this->can_sort && !$last && $canedit){
1448
                        echo "<td><a href=\"".$target."?type=".$this->fields["rule_type"]."&amp;action=down&amp;ID=".$this->fields["ID"]."\"><img src=\"".$CFG_GLPI["root_doc"]."/pics/deplier_down.png\" alt=''></a></td>";
1449
                } else {
1450
                        echo "<td>&nbsp;</td>";
1451
                }
1452

    
1453
                echo "</tr>";
1454
        }
1455

    
1456
        function prepareInputForAdd($input){
1457
                // Before adding, add the ranking of the new rule        
1458
                $input["ranking"] = $this->getNextRanking();
1459
                return $input;
1460
        }
1461

    
1462
        /**
1463
         * Get the next ranking for a specified rule
1464
         */
1465
        function getNextRanking()
1466
        {
1467
                global $DB;
1468
                $sql = "SELECT max(ranking) as rank FROM glpi_rules_descriptions WHERE rule_type='".$this->rule_type."'";
1469
                $result = $DB->query($sql);
1470
                if ($DB->numrows($result) > 0)
1471
                {
1472
                        $datas = $DB->fetch_assoc($result);
1473
                        return $datas["rank"] + 1;
1474
                } else {
1475
                        return 0;
1476
                }
1477
        }
1478

    
1479
        /**
1480
         * Show the minimal form for the action rule
1481
        * @param $fields datas used to display the action
1482
        * @param $canedit can edit the actions rule ?
1483
         */        
1484
        function showMinimalActionForm($fields,$canedit)
1485
        {
1486
                echo "<tr class='tab_bg_1'>";
1487
                                
1488
                if ($canedit) {
1489
                        echo "<td width='10'>";
1490
                        $sel = "";
1491
                        if (isset ($_GET["select"]) && $_GET["select"] == "all"){
1492
                                $sel = "checked";
1493
                        }
1494
                        echo "<input type='checkbox' name='item[" . $fields["ID"] . "]' value='1' $sel>";
1495
                        echo "</td>";
1496
                }
1497
                        
1498
                $this->showMinimalAction($fields,$canedit);
1499
                echo "</tr>";
1500
        }
1501

    
1502
        /**
1503
         * Show preview result of a rule
1504
        * @param $target where to go if action
1505
        * @param $input input data array
1506
        * @param $params params used (see addSpecificParamsForPreview)
1507
         */        
1508
        function showRulePreviewResultsForm($target,$input,$params){
1509
                global $LANG,$RULES_ACTIONS;
1510
                $regex_results = array();
1511
                $check_results = array();
1512
                $output = array();
1513
                
1514
                //Test all criterias, without stopping at the first good one
1515
                $this->testCriterias($input,$regex_results,$check_results);
1516

    
1517
                //Process the rule
1518
                $this->process($input,$output,$params,false);
1519

    
1520
                $criteria = new RuleCriteria;
1521

    
1522
                echo "<div class='center'>"; 
1523
                echo "<table class='tab_cadrehov'>";
1524
                echo "<tr><th colspan='4'>" . $LANG["rulesengine"][82] . "</th></tr>";
1525
                
1526
                echo "<tr class='tab_bg_2'>";
1527
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][16]."</td>";
1528
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][14]."</td>";
1529
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][15]."</td>";
1530
                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][41]."</td>";
1531
                echo "</tr>";
1532

    
1533
                foreach ($check_results as $ID=>$criteria_result){
1534
                        echo "<tr  class='tab_bg_2'>";
1535
                        $criteria->getFromDB($criteria_result["ID"]);
1536
                        $this->showMinimalCriteria($criteria->fields);
1537
                        echo "<td class='tab_bg_2'>";
1538
                        echo "<strong>".getYesNo($criteria_result["result"])."</strong>";
1539
                        echo "</td>";
1540
                }
1541
                echo "</table>";
1542

    
1543
                $global_result =(isset($output["_rule_process"])?1:0);
1544
                
1545
                echo "<br><table class='tab_cadrehov'>";
1546
                echo "<tr><th colspan='4'>" . $LANG["rulesengine"][81] . "</th></tr>";
1547
                echo "<tr  class='tab_bg_2'>";
1548
                echo "<td class='tab_bg_2' colspan='4' align='center'>".$LANG["rulesengine"][41]." : <strong> ".getYesNo($global_result)."</strong></td>";
1549

    
1550
                //If output array contains keys begining with _ : drop it
1551
                foreach($output as $criteria => $value){
1552
                        if ($criteria[0]=='_'){
1553
                                unset($output[$criteria]);
1554
                        }
1555
                }
1556
                        
1557
                
1558
                foreach ($output as $criteria => $value){
1559
                        echo "<tr  class='tab_bg_2'>";
1560
                        echo "<td class='tab_bg_2'>";
1561
                        echo $RULES_ACTIONS[$this->rule_type][$criteria]["name"];
1562
                        echo "</td>";
1563
                        echo "<td class='tab_bg_2'>";
1564
                        echo $this->getActionValue($criteria,$value);
1565
                        echo "</td>";
1566
                        echo "</tr>";
1567
                }
1568

    
1569
                //If a regular expression was used, and matched, display the results
1570
                if (count($regex_results))
1571
                {
1572
                                echo "<tr  class='tab_bg_2'>";
1573
                                echo "<td class='tab_bg_2'>".$LANG["rulesengine"][85]."</td>";
1574
                                echo "<td class='tab_bg_2'>";
1575
                                printCleanArray($regex_results);
1576
                                echo "</td>";
1577
                                echo "</tr>";
1578
                }
1579

    
1580
                echo "</tr>";
1581
                
1582
                echo "</table></div>";
1583
        }
1584

    
1585
        /**
1586
         * Show the minimal form for the criteria rule
1587
        * @param $fields datas used to display the criteria
1588
        * @param $canedit can edit the criterias rule ?
1589
         */        
1590
        function showMinimalCriteriaForm($fields,$canedit)
1591
        {
1592
                echo "<tr class='tab_bg_1'>";
1593
                                
1594
                if ($canedit) {
1595
                        echo "<td width='10'>";
1596
                        $sel = "";
1597
                        if (isset ($_GET["select"]) && $_GET["select"] == "all"){
1598
                                $sel = "checked";
1599
                        }
1600
                        echo "<input type='checkbox' name='item[" . $fields["ID"] . "]' value='1' $sel>";
1601
                        echo "</td>";
1602
                }
1603
                $this->showMinimalCriteria($fields);        
1604
                echo "</tr>";
1605
        }
1606

    
1607
        /**
1608
         * Show the minimal infos for the criteria rule
1609
        * @param $fields datas used to display the criteria
1610
         */        
1611
        function showMinimalCriteria($fields){
1612
                echo "<td>" . $this->getCriteriaName($fields["criteria"]) . "</td>";
1613
                echo "<td>" . getConditionByID($fields["condition"]) . "</td>";
1614
                echo "<td>" . $this->getCriteriaDisplayPattern($fields["criteria"],$fields["condition"],$fields["pattern"]) . "</td>";
1615
        }        
1616

    
1617
        /**
1618
         * Show the minimal infos for the action rule
1619
        * @param $fields datas used to display the action
1620
        * @param $canedit right to edit ?
1621
         */
1622
        function showMinimalAction($fields,$canedit){
1623
                echo "<td>" . $this->getActionName($fields["field"]) . "</td>";
1624
                echo "<td>" . getActionByID($fields["action_type"]) . "</td>";
1625
                echo "<td>" . stripslashes($this->getActionValue($fields["field"],$fields["value"])) . "</td>";
1626
                
1627
        }        
1628
        
1629
        /**
1630
         * Return a value associated with a pattern associated to a criteria to display it
1631
         * @param $ID the given criteria
1632
        * @param $condition condition used
1633
         * @param $pattern the pattern
1634
         */
1635
         function getCriteriaDisplayPattern($ID,$condition,$pattern){
1636
                $crit=$this->getCriteria($ID);
1637
                if (!isset($crit['type'])){
1638
                        return $pattern;
1639
                } else {
1640
                        switch ($crit['type']){
1641
                                case "dropdown":
1642
                                        if ($condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1643
                                                return getDropdownName($crit["table"],$pattern);
1644
                                        }
1645
                                        break;
1646
                                case "dropdown_users":
1647
                                        if ($condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1648
                                                
1649
                                                return getUserName($pattern);
1650
                                        }
1651
                                        break;
1652
                                case "dropdown_request_type":
1653
                                        if ($condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1654
                                                return getRequestTypeName($pattern);
1655
                                        }
1656
                                        break;
1657
                                case "dropdown_tracking_device_type":
1658
                                        if ($condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1659
                                                $ci =new CommonItem();
1660
                                                $ci->setType($pattern);
1661
                                                return $ci->getType($pattern);
1662
                                        }
1663
                                        break;
1664
                                case "dropdown_priority":
1665
                                        if ($condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1666
                                                return getPriorityName($pattern);
1667
                                        } 
1668
                                        break;
1669
                        }
1670
                        return $pattern;
1671
                }
1672
        }
1673

    
1674
        /**
1675
         * Display item used to select a pattern for a criteria
1676
        * @param $name criteria name
1677
         * @param $ID the given criteria
1678
        * @param $condition condition used
1679
         * @param $value the pattern
1680
        * @param $test Is to test rule ?
1681
         */
1682
         function displayCriteriaSelectPattern($name,$ID,$condition,$value="",$test=false){
1683
                global $CFG_GLPI;
1684

    
1685
                $crit=$this->getCriteria($ID);
1686

    
1687
                $display=false;
1688
                if (isset($crit['type'])){
1689
                        switch ($crit['type']){
1690
                                case "dropdown":
1691
                                        if ($test||$condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1692
                                                dropdownValue($crit['table'],$name,$value);
1693
                                                $display=true;
1694
                                        }
1695
                                        break;
1696
                                case "dropdown_users":
1697
                                        if ($test||$condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1698
                                                dropdownAllUsers($name,$value);
1699
                                                $display=true;
1700
                                        }
1701
                                        break;
1702
                                case "dropdown_request_type":
1703
                                        if ($test||$condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1704
                                                dropdownRequestType($name,$value);
1705
                                                $display=true;
1706
                                        }
1707
                                        break;
1708
                                case "dropdown_tracking_device_type":
1709
                                        if ($test||$condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1710
                                                dropdownDeviceTypes($name,0,$CFG_GLPI["helpdesk_types"]);
1711
                                                $display=true;
1712
                                        }
1713
                                        break;
1714
                                case "dropdown_priority":
1715
                                        if ($test||$condition==PATTERN_IS||$condition==PATTERN_IS_NOT){
1716
                                                dropdownPriority($name,$value);
1717
                                                $display=true;
1718
                                        } 
1719
                                        break;
1720
                        }
1721
                } 
1722
                if (!$display){
1723
                        autocompletionTextField($name, "glpi_rules_criterias", "pattern", $value, 30);
1724
                }
1725
        }
1726

    
1727
        /*
1728
         * Display item to select a value for criteria
1729
         * @param $type criteria type
1730
        * @param $condition condition used
1731
         
1732
        // NOT_USED
1733
         function displayCriteriaSelectValue($type,$condition){
1734
                $display=false;
1735
        }
1736
        */
1737
        
1738
        /**
1739
         * Return a value associated with a pattern associated to a criteria
1740
         * @param $ID the given action
1741
         * @param $value the value
1742
         */
1743
         function getActionValue($ID,$value)
1744
        {
1745
                global $LANG;
1746
                $action=$this->getAction($ID);
1747

    
1748
                if (!isset($action['type'])){
1749
                        return $value;
1750
                } else {
1751
                        switch ($action['type'])
1752
                        {
1753
                                case "dropdown":
1754
                                        return getDropdownName($action["table"],$value);
1755
                                        break;
1756
                                case "dropdown_status":
1757
                                        return getStatusName($value);
1758
                                        break;
1759
                                case "dropdown_assign":
1760
                                case "dropdown_users":
1761
                                        return getUserName($value);
1762
                                        break;
1763
                                case "yesno":
1764
                                        if ($value) 
1765
                                                return $LANG["choice"][1];
1766
                                        else
1767
                                                return $LANG["choice"][0];        
1768
                                        break;
1769
                                case "dropdown_priority":
1770
                                        return getPriorityName($value);
1771
                                        break;
1772
                                default :
1773
                                        return $value;
1774
                                        break;
1775
                        }
1776
                }
1777
        }
1778

    
1779
        /**
1780
          * Return a value associated with a pattern associated to a criteria to display it
1781
          * @param $ID the given criteria
1782
         * @param $condition condition used
1783
          * @param $value the pattern
1784
          */
1785
        function getCriteriaValue($ID,$condition,$value){
1786
                global $LANG;
1787
                $crit=$this->getCriteria($ID);
1788
                
1789
                if (!isset($crit['type'])){
1790
                        return $value;
1791
                } else {
1792
                        switch ($crit['type']){
1793
                                case "dropdown":
1794
                                        
1795
                                        if ($condition!=PATTERN_IS && $condition!=PATTERN_IS_NOT){
1796
                                                return getDropdownName($crit["table"],$value);
1797
                                        }
1798
                                break;
1799
                                case "dropdown_assign":
1800
                                case "dropdown_users":
1801
                                         if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
1802
                                                 return getUserName($value);
1803
                                         }
1804
                                break;
1805
                                case "yesno":
1806
                                         if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
1807
                                                 if ($value) 
1808
                                                         return $LANG["choice"][1];
1809
                                                 else
1810
                                                         return $LANG["choice"][0];        
1811
                                         }
1812
                                break;
1813
                                case "dropdown_priority":
1814
                                         if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
1815
                                                 return getPriorityName($value);
1816
                                         }
1817
                                break;
1818
                        }
1819
                        return $value;
1820
                }
1821
        }
1822

    
1823
        /**
1824
         * Function used to display type specific criterias during rule's preview
1825
         * @param $fields fields values
1826
         */
1827
        function showSpecificCriteriasForPreview($fields){
1828
                
1829
        }
1830
        
1831
        /**
1832
         ** Function used to add specific params before rule processing
1833
         * @param $fields fields values
1834
         * @param $params parameters
1835
         */
1836
        function addSpecificParamsForPreview($fields,$params){
1837
                return $params;
1838
        }
1839
        
1840
        /**
1841
          * Criteria form used to preview rule
1842
          * @param $target target of the form
1843
         * @param $rule_id ID of the rule
1844
          */
1845
        function showRulePreviewCriteriasForm($target,$rule_id){
1846

    
1847
                global $DB, $LANG,$RULES_CRITERIAS,$RULES_ACTIONS; 
1848
                
1849
                if ($this->getRuleWithCriteriasAndActions($rule_id,1,0)){
1850
                        echo "<form name='testrule_form' id='testrule_form' method='post' action=\"$target\">\n";
1851
                        echo "<div class='center'>";
1852
                        echo "<table class='tab_cadre_fixe'>"; 
1853
                        echo "<tr><th colspan='3'>" . $LANG["rulesengine"][6] . "</th></tr>"; 
1854

    
1855
                        $type_match=($this->fields["match"]==AND_MATCHING?$LANG["rulesengine"][42]:$LANG["rulesengine"][43]);
1856
                        $already_displayed=array(); 
1857
                        $first=true;
1858
                         //Brower all criterias 
1859
                        foreach ($this->criterias as $criteria){
1860
                                
1861
                                //Look for the criteria in the field of already displayed criteria : if present, don't display it again 
1862
                                if (!in_array($criteria->fields["criteria"],$already_displayed)){
1863
                                        $already_displayed[]=$criteria->fields["criteria"];
1864

    
1865
                                        echo "<tr class='tab_bg_1'>"; 
1866
                                        echo "<td>";
1867
                                        if ($first){
1868
                                                echo "&nbsp;";
1869
                                                $first=false;
1870
                                        } else {
1871
                                                echo $type_match;
1872
                                        }
1873
                                        echo "</td>";
1874
                                        
1875
                                        $criteria_constants = $RULES_CRITERIAS[$this->fields["rule_type"]][$criteria->fields["criteria"]];
1876
                                        echo "<td>".$criteria_constants["name"].":</td>";
1877
                                        echo "<td>";
1878
                                        $value="";
1879

    
1880
                                        if (isset($_POST[$criteria->fields["criteria"]])){
1881
                                                $value=$_POST[$criteria->fields["criteria"]];
1882
                                        }        
1883
                                        $this->displayCriteriaSelectPattern($criteria->fields["criteria"],$criteria->fields['criteria'],$criteria->fields['condition'],$value,true);
1884
                                        echo "</td>";
1885
                                        echo "</tr>"; 
1886
                                }
1887
                
1888
                        }
1889
                        $this->showSpecificCriteriasForPreview($_POST);
1890
                
1891

    
1892
                        echo "<tr><td class='tab_bg_2' colspan='3' align='center'>"; 
1893
                        echo "<input type='submit' name='test_rule' value=\"" . $LANG["buttons"][50] . "\" class='submit'>";
1894
                        echo "<input type='hidden' name='rule_id' value=\"" . $rule_id . "\">"; 
1895
                        echo "<input type='hidden' name='rule_type' value=\"" . $this->rule_type . "\">"; 
1896
                        echo "</td></tr>"; 
1897
                        echo "</table>";
1898
                        echo "</div>";
1899
                        echo "</form>";
1900
                }
1901
        }
1902
}
1903

    
1904
class RuleAction extends CommonDBTM {
1905
        /**
1906
         * Constructor
1907
        **/
1908
        function RuleAction() {
1909
                $this->table = "glpi_rules_actions";
1910
                $this->type = -1;
1911
        }
1912
        /**
1913
         * Get all actions for a given rule
1914
         * @param $ID the rule_description ID
1915
         * @return an array of RuleAction objects
1916
        **/
1917
        function getRuleActions($ID) {
1918
                $sql = "SELECT * FROM glpi_rules_actions WHERE FK_rules='" . $ID."'";
1919
                global $DB;
1920

    
1921
                $rules_actions = array ();
1922
                $result = $DB->query($sql);
1923
                while ($rule = $DB->fetch_array($result)){
1924
                        $tmp = new RuleAction;
1925
                        $tmp->fields = $rule;
1926
                        $rules_actions[] = $tmp;
1927
                }
1928
                return $rules_actions;
1929
        }
1930

    
1931
        
1932
        /**
1933
         * Add an action
1934
         * @param $action action type
1935
         * @param $ruleid rule ID
1936
         * @param $field field name
1937
         * @param $value value
1938
        **/
1939
        function addActionByAttributes($action,$ruleid,$field,$value){
1940
                $ruleAction = new RuleAction;
1941
                $input["action_type"]=$action;
1942
                $input["field"]=$field;
1943
                $input["value"]=$value;
1944
                $input["FK_rules"]=$ruleid;
1945
                $ruleAction->add($input);
1946
        }
1947
}
1948

    
1949
/// Criteria Rule class
1950
class RuleCriteria extends CommonDBTM {
1951
        /**
1952
         * Constructor
1953
        **/
1954
        function RuleCriteria() {
1955
                $this->table = "glpi_rules_criterias";
1956
                $this->type = -1;
1957
        }
1958

    
1959
        /**
1960
         * Get all criterias for a given rule
1961
         * @param $ID the rule_description ID
1962
         * @return an array of RuleCriteria objects
1963
        **/
1964
        function getRuleCriterias($ID) {
1965
                global $DB;
1966
                $sql = "SELECT * FROM glpi_rules_criterias WHERE FK_rules='" . $ID."'";
1967

    
1968
                $rules_list = array ();
1969
                $result = $DB->query($sql);
1970
                while ($rule = $DB->fetch_assoc($result)){
1971
                        $tmp = new RuleCriteria;
1972
                        $tmp->fields = $rule;
1973
                        $rules_list[] = $tmp;
1974
                }
1975
                return $rules_list;
1976
        }
1977
        
1978
        /**
1979
         * Process a criteria of a rule
1980
         * @param $input the input data used to check criterias
1981
         * @param $regex_result
1982
        **/
1983
        function process(&$input,&$regex_result){
1984

    
1985
                // Undefine criteria field : set to blank
1986
                if (!isset($input[$this->fields["criteria"]])){
1987
                        $input[$this->fields["criteria"]]='';
1988
                }
1989
                
1990
                //If the value is not an array
1991
                if (!is_array($input[$this->fields["criteria"]])){
1992
                        $value=$this->getValueToMatch($this->fields["condition"],$input[$this->fields["criteria"]]);
1993
                        $res = matchRules($value,$this->fields["condition"],$this->fields["pattern"],$regex_result);
1994
                } else        {
1995
                        //If the value if, in fact, an array of values
1996
                        // Negative condition : Need to match all condition (never be)
1997
                        if (in_array($this->fields["condition"],array(PATTERN_IS_NOT,PATTERN_NOT_CONTAIN,REGEX_NOT_MATCH))){
1998
                                $res = true;
1999
                                foreach($input[$this->fields["criteria"]] as $tmp){
2000
                                        $value=$this->getValueToMatch($this->fields["condition"],$tmp);
2001
                                        $res &= matchRules($value,$this->fields["condition"],$this->fields["pattern"],$regex_result);
2002
                                        if (!$res){
2003
                                                break;
2004
                                        }
2005
                                }
2006
                
2007
                        // Positive condition : Need to match one
2008
                         } else {
2009
                                $res = false;
2010
                                foreach($input[$this->fields["criteria"]] as $tmp){
2011
                                        $value=$this->getValueToMatch($this->fields["condition"],$tmp);
2012
                                        $res |= matchRules($value,$this->fields["condition"],$this->fields["pattern"],$regex_result);
2013
                                        if ($res){
2014
                                                break;
2015
                                        }
2016
                                }        
2017
                        }
2018
                        return $value;
2019
                }
2020
                return $res;        
2021
        }
2022

    
2023
        /**
2024
         * Return a value associated with a pattern associated to a criteria to compare it
2025
         * @param $condition condition used
2026
         * @param $initValue the pattern
2027
        **/
2028
        function getValueToMatch($condition,&$initValue){
2029
                if (empty($this->type)){
2030
                        return $initValue;
2031
                } else {                        
2032
                        switch ($this->type){
2033
                                case "dropdown":
2034
                                        if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
2035
                                                return getDropdownName($this->table,$initValue);
2036
                                        }
2037
                                        break;
2038
                                case "dropdown_users":
2039
                                        if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
2040
                                                return getUserName($initValue);
2041
                                        }
2042
                                        break;
2043
                                case "dropdown_request_type":
2044
                                        if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
2045
                                                return getRequestTypeName($initValue);
2046
                                        }
2047
                                        break;
2048
                                case "dropdown_tracking_device_type":
2049
                                        if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
2050
                                                $ci =new CommonItem();
2051
                                                $ci->setType($initValue);
2052
                                                return $ci->getType($initValue);
2053
                                        }
2054
                                        break;
2055
                                case "dropdown_priority":
2056
                                        if ($condition!=PATTERN_IS&&$condition!=PATTERN_IS_NOT){
2057
                                                return getPriorityName($initValue);
2058
                                        } 
2059
                                        break;
2060
                        }
2061
                }
2062
                return $initValue;
2063
        }
2064

    
2065
}
2066

    
2067
/// Rule cached class
2068
class RuleCached extends Rule{
2069

    
2070
        // Dummy constructor required for php 5.3.0 
2071
        function RuleCached($rule_type=0) {
2072
                parent::Rule($rule_type);
2073
        }
2074

    
2075
        function getTitleAction($target){
2076
                global $LANG,$CFG_GLPI;
2077
                echo "<div class='center'>"; 
2078
                echo "<table class='tab_cadrehov'>";
2079
                echo "<tr  class='tab_bg_2'>";
2080
                echo "<td width='100%'>";
2081
                echo $LANG["rulesengine"][83];
2082
                echo "</td></tr>";
2083
                echo "</table></div><br>";
2084
        }
2085

    
2086
        /**
2087
        * Delete cache for a rule
2088
        * @param $ID rule ID
2089
        **/
2090
        function deleteCacheByRuleId($ID){
2091
                global $DB;
2092
                $DB->query("DELETE FROM ".getCacheTableByRuleType($this->rule_type)." WHERE rule_id='".$ID."'");
2093
        }
2094

    
2095
        function post_updateItem($input,$updates,$history=1) {
2096
                if(isset($updates['match']))
2097
                        $this->deleteCacheByRuleId($input["ID"]);
2098
        }
2099
        
2100
        /**
2101
        * Show cache statis for a current rule
2102
        * @param $target where to go
2103
        **/
2104
        function showCacheStatusByRule($target){
2105
                global $DB,$LANG;
2106
                echo "<div class='center'>"; 
2107
                echo "<table  class='tab_cadre_fixe'>";
2108

    
2109
                $rulecollection = getRuleCollectionClass($this->rule_type);
2110
                
2111
                $query="SELECT *
2112
                        FROM ".$rulecollection->cache_table.", glpi_rules_descriptions
2113
                        WHERE ".$rulecollection->cache_table.".rule_id=glpi_rules_descriptions.ID 
2114
                        AND ".$rulecollection->cache_table.".rule_id='".$this->fields["ID"]."'
2115
                        ORDER BY name";
2116

    
2117
                $res_count=$DB->query($query);
2118

    
2119
                $this->showCacheRuleHeader();
2120
                
2121
                $total = 0;                
2122
                while ($datas = $DB->fetch_array($res_count)){
2123
                        echo "<tr>";
2124
                        $this->showCacheRuleDetail($datas);
2125
                        echo "</tr>";
2126
                        $total++;
2127
                }
2128
                
2129
                echo "</table></div><br>";
2130
                echo "<center><a href=\"$target\">".$LANG["buttons"][13]."</center>";
2131
                
2132
        }
2133

    
2134
        /// Display Header for cache display
2135
        function showCacheRuleHeader(){
2136
                global $LANG;
2137
                echo "<th colspan='2'>".$LANG["rulesengine"][100]." : ".$this->fields["name"]."</th></tr>";
2138
                echo "<tr>";
2139
                echo "<td class='tab_bg_1'>".$LANG["rulesengine"][104]."</td>";
2140
                echo "<td class='tab_bg_1'>".$LANG["rulesengine"][105]."</td>";
2141
                echo "</tr>";
2142
        }
2143

    
2144
        /**
2145
         * Display a cache item
2146
         * @param $fields data array
2147
        **/
2148
        function showCacheRuleDetail($fields){
2149
                global $LANG;
2150
                echo "<td class='tab_bg_2'>".$fields["old_value"]."</td>";
2151
                echo "<td class='tab_bg_2'>".($fields["new_value"]!=''?$fields["new_value"]:$LANG["rulesengine"][106])."</td>";
2152
        }
2153
                        
2154
}
2155

    
2156

    
2157
/**
2158
 * Specific rule collection for dictionnary : got a function initialize rule's caching system
2159
 * 
2160
**/
2161
class RuleCachedCollection extends RuleCollection{
2162
        
2163
        /// Cache table used
2164
        var $cache_table;
2165
        /// Cache parameters
2166
        var $cache_params;
2167

    
2168
        /**
2169
        * Init a cache rule collection
2170
        * @param $cache_table cache table used
2171
        * @param $input_params Input parameters to store
2172
        * @param $output_params Output parameters to store
2173
        * @return nothing
2174
        **/
2175
        function initCache($cache_table,$input_params=array("name"=>"old_value"),$output_params=array("name"=>"new_value")){
2176
                $this->can_replay_rules=true;
2177
                $this->stop_on_first_match=true;
2178
                $this->cache_table=$cache_table;
2179
                $this->cache_params["input_value"]=$input_params;
2180
                $this->cache_params["output_value"]=$output_params;
2181
        }
2182

    
2183
        /**
2184
        * Show the list of rules
2185
        * @param $target  where to go
2186
        * @return nothing
2187
        **/
2188
        function showAdditionalInformationsInForm($target){
2189
                global $CFG_GLPI,$LANG;
2190
                echo "<span class='center'><a href='#' onClick=\"var w = window.open('".$CFG_GLPI["root_doc"]."/front/popup.php?popup=show_cache&amp;rule_type=".$this->rule_type."' ,'glpipopup', 'height=400, width=1000, top=100, left=100, scrollbars=yes' );w.focus();\">".$LANG["rulesengine"][100]."</a></span>"; 
2191

    
2192
        }        
2193

    
2194

    
2195
        /**
2196
        * Process all the rules collection
2197
        * @param input the input data used to check criterias
2198
        * @param output the initial ouput array used to be manipulate by actions
2199
        * @param params parameters for all internal functions
2200
        * @param force_no_cache don't write rule's result into cache (for preview mode mainly)
2201
        * @return the output array updated by actions
2202
        **/
2203
        function processAllRules($input=array(),$output=array(),$params=array(),$force_no_cache=false){        
2204

    
2205
                //If cache enabled : try to get value from the cache
2206
                $new_values = $this->checkDataInCache($input);
2207

    
2208
                if ($new_values != RULE_NOT_IN_CACHE){
2209
                        $output["_rule_process"]=true;
2210
                        return array_merge($output,$new_values);
2211
                }
2212
                $output=parent::processAllRules($input,$output,$params);
2213

    
2214
                if (!$force_no_cache&&isset($output["_ruleid"])){
2215
                        $this->insertDataInCache($input,$output);
2216
                        unset($output["_ruleid"]);
2217
                }
2218

    
2219
                return $output;
2220
        }
2221

    
2222
        /**
2223
        * Show cache status by rules
2224
        **/
2225
        function showCacheStatusForRuleType(){
2226
                global $DB,$LANG,$CFG_GLPI;
2227
                echo "<div class='center'>"; 
2228
                echo "<table  class='tab_cadre_fixe'>";
2229

    
2230
                $query="SELECT name, rule_id, count(rule_id) as cpt
2231
                                FROM ".$this->cache_table.", glpi_rules_descriptions
2232
                                WHERE ".$this->cache_table.".rule_id=glpi_rules_descriptions.ID GROUP BY rule_id
2233
                                ORDER BY name";
2234
                $res_count=$DB->query($query);
2235

    
2236
                echo "<th colspan='2'>".$LANG["rulesengine"][100]." : ".$this->getTitle()."</th></tr>";
2237
                echo "<tr>";
2238
                echo "<td class='tab_bg_1'>".$LANG["rulesengine"][102]."</td>";
2239
                echo "<td class='tab_bg_1'>".$LANG["rulesengine"][103]."</td>";
2240
                echo "</tr>";
2241
                
2242
                $total = 0;                
2243
                while ($datas = $DB->fetch_array($res_count)){
2244
                        echo "<tr>";                        
2245
                        echo "<td class='tab_bg_2'>";
2246
                        echo "<a href='#' onClick=\"var w = window.open('".$CFG_GLPI["root_doc"]."/front/popup.php?popup=show_cache&amp;rule_type=".$this->rule_type."&rule_id=".$datas["rule_id"]."' ,'glpipopup', 'height=400, width=1000, top=100, left=100, scrollbars=yes' );w.focus();\">";
2247
                        echo $datas["name"];
2248
                        echo "</a></td>";
2249
                        echo "<td class='tab_bg_2'>".$datas["cpt"]."</td>";
2250
                        echo "</tr>";
2251
                        $total+=$datas["cpt"];
2252
                }
2253
                
2254
                echo "<tr>";
2255
                echo "<td class='tab_bg_2'><strong>".$LANG["common"][33]." (".$DB->numrows($res_count).")</strong></td>";
2256
                echo "<td class='tab_bg_2'><strong>".$total."</strong></td>";
2257
                echo "</tr></table></div>";                
2258
        }
2259

    
2260

    
2261
        /**
2262
        * Check if a data is in cache
2263
        * @param input data array to search
2264
        * @return boolean : is in cache ?
2265
        **/
2266
        function checkDataInCache($input){
2267
                global $DB;
2268

    
2269
                $where="";
2270
                $first=true;
2271
                foreach($this->cache_params["input_value"] as $param => $value){
2272
                        if (isset($input[$param])){
2273
                                $where.=(!$first?" AND ":"")." ".$value."='".$input[$param]."'";
2274
                                $first=false;
2275
                        }
2276
                }
2277

    
2278
                $sql = "SELECT * FROM ".$this->cache_table." WHERE ".$where;
2279

    
2280
                if ($res_check = $DB->query($sql)){
2281
                        $output_values=array();
2282
                        if ($DB->numrows($res_check) == 1){
2283
                                $data=$DB->fetch_assoc($res_check);
2284
                                foreach ($this->cache_params["output_value"] as $param => $param_value){
2285
                                        if (isset($data[$param_value])){
2286
                                                $output_values[$param]=$data[$param_value];
2287
                                        }
2288
                                }
2289
                                return $output_values;
2290
                
2291
                        }
2292
                }
2293
                return RULE_NOT_IN_CACHE;
2294
        }
2295

    
2296
        /**
2297
        * Insert data in cache
2298
        * @param input input data array
2299
        * @param $output output data array
2300
        **/
2301
        function insertDataInCache($input,$output){
2302
                global $DB;
2303

    
2304
                $old_values="";
2305
                $into_old="";
2306
                foreach($this->cache_params["input_value"] as $param => $value){
2307
                        $into_old.="`".$value."`, ";
2308
                        $old_values.="\"".$input[$param]."\", ";
2309
                }
2310
                
2311
                $into_new="";
2312
                $new_values="";
2313
                foreach($this->cache_params["output_value"] as $param => $value){
2314
                        if (!isset($output[$param])){
2315
                                $output[$param]="";
2316
                        }
2317
                        $into_new.=", `".$value."`";
2318
                        $new_values.=" ,\"".$output[$param]."\"";
2319
                }
2320
                $sql="INSERT INTO ".$this->cache_table." (".$into_old."`rule_id`".$into_new.") VALUES (".$old_values.$output["_ruleid"].$new_values.")";
2321
                $DB->query($sql);
2322
        }
2323

    
2324
        
2325
/*
2326
        // NOT_USED
2327
        function deleteCache(){
2328
                global $DB;
2329
                $DB->query("TRUNCATE TABLE ".$this->cache_table);
2330
        }        
2331
*/
2332
        
2333
}
2334

    
2335
?>
Redmine Appliance - Powered by TurnKey Linux