Changeset 1263


Ignore:
Timestamp:
08/04/09 10:23:16 (15 years ago)
Author:
gbisotto
Message:

Ticket #603 - Removido o pattern Observer da engine do Workflow

Location:
sandbox/workflow/2.0/inc/engine/src
Files:
2 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • sandbox/workflow/2.0/inc/engine/src/ProcessManager/ProcessManager.php

    r795 r1263  
    44 * Adds, removes, modifies and lists processes. 
    55 * Most of the methods acts directly in database level, bypassing Project object methods 
    6  *  
     6 * 
    77 * @todo Fix multiple non checked fopen ==> infinite loops in case of problems with filesystem 
    88 * @package Galaxia 
    9  * @license http://www.gnu.org/copyleft/gpl.html GPL  
     9 * @license http://www.gnu.org/copyleft/gpl.html GPL 
    1010 */ 
    1111class ProcessManager extends BaseManager { 
    12    
    13   /** 
    14    * @var resource $parser xml parser 
    15    * @access public 
    16    */ 
    17   var $parser; 
    18    
    19   /** 
    20    * @var array $tree data struture 
    21    * @access public 
    22    */ 
    23   var $tree; 
    24    
    25   /** 
    26    * @var $current current element 
    27    * @access public 
    28    */ 
    29   var $current; 
    30    
    31   /** 
    32    * @var $buffer buffer for data 
    33    * @access public 
    34    */ 
    35   var $buffer; 
    36    
    37   /** 
    38    * @var object $Process Process 
    39    * @access public 
    40    */ 
    41   var $Process; 
    42    
    43   /** 
    44    * @var object $activity_manager Activity Manager 
    45    * @access public 
    46    */ 
    47   var $activity_manager; 
    48  
    49   /** 
    50    * @var object $jobManager Job Manager object 
    51    * @access public 
    52    */ 
    53   var $jobManager; 
    54     
    55   /** 
    56    * @var object $role_manager Role Manager 
    57    * @access public 
    58    */ 
    59   var $role_manager; 
    60    
    61   /** 
    62    * Constructor 
    63    *  
    64    * @param object &$db ADOdb  
    65    * @return object ProcessManager 
    66    * @access public 
    67    */ 
    68   function ProcessManager(&$db)  
    69   { 
    70     parent::BaseManager($db); 
    71     $this->child_name = 'ProcessManager'; 
    72     require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'ActivityManager.php'); 
    73     require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'JobManager.php'); 
    74     // $this->activity_manager is not set here to avoid objects loading object A loading object B loading object A, etc 
    75     //$this->role_manager will only be loaded when needed as well 
    76   } 
    77  
    78   /** 
    79   * Collect errors from all linked objects which could have been used by this object. 
    80   * Each child class should instantiate this function with her linked objetcs, calling get_error(true) 
    81   * 
    82   * @param bool $debug False by default, if true debug messages can be added to 'normal' messages 
    83   * @param string $prefix Appended to the debug message 
    84   * @return void  
    85   * @access public 
    86   */ 
    87   function collect_errors($debug=false, $prefix = '') 
    88   { 
    89     parent::collect_errors($debug, $prefix); 
    90     if (isset($this->activity_manager)) $this->error[] = $this->activity_manager->get_error(false, $debug, $prefix); 
    91     if (isset($this->role_manager)) $this->error[] = $this->role_manager->get_error(false, $debug, $prefix); 
    92   } 
    93  
    94   /** 
    95    * Activates a process 
    96    *  
    97    * @param int $pId Process id 
    98    * @return void  
    99    * @access public 
    100    */ 
    101   function activate_process($pId) 
    102   { 
    103     $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?'; 
    104     $this->query($query, array('y',$pId));   
    105     $msg = sprintf(tra('Process %d has been activated'),$pId); 
    106     $this->notify_all(3,$msg); 
    107     $this->error[] = $msg; 
    108   } 
    109    
    110   /** 
    111    * Deactivates a process 
    112    *  
    113    * @param int $pId Process id 
    114    * @return void  
    115    * @access public 
    116    */ 
    117   function deactivate_process($pId) 
    118   { 
    119     $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?'; 
    120     $this->query($query, array('n',$pId));   
    121     $msg = sprintf(tra('Process %d has been deactivated'),$pId); 
    122     $this->notify_all(3,$msg); 
    123     $this->error[] = $msg; 
    124   } 
    125    
    126   /** 
    127    * Creates an XML representation of a process 
    128    *  
    129    * @param int $pId Process id 
    130    * @return string  
    131    * @access public 
    132    */   
    133   function serialize_process($pId) 
    134   { 
    135     if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
    136     // <process> 
    137     $out = '<process>'."\n"; 
    138     //we retrieve config values with the others process data 
    139     $proc_info =& $this->get_process($pId, true); 
    140     $wf_procname = $proc_info['wf_normalized_name']; 
    141     $out.= '  <name>'.htmlspecialchars($proc_info['wf_name']).'</name>'."\n"; 
    142     $out.= '  <isValid>'.htmlspecialchars($proc_info['wf_is_valid']).'</isValid>'."\n"; 
    143     $out.= '  <version>'.htmlspecialchars($proc_info['wf_version']).'</version>'."\n"; 
    144     $out.= '  <isActive>'.htmlspecialchars($proc_info['wf_is_active']).'</isActive>'."\n"; 
    145     $out.='   <description>'.htmlspecialchars($proc_info['wf_description']).'</description>'."\n"; 
    146     $out.= '  <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['wf_last_modif']).'</lastModif>'."\n"; 
    147  
    148     //Shared code 
    149     $out.= '  <sharedCode><![CDATA['; 
    150     $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."shared.php","r"); 
    151     while(!feof($fp)) { 
    152       $line=fread($fp,8192); 
    153       $out.=$line; 
    154     } 
    155     fclose($fp); 
    156     $out.= '  ]]></sharedCode>'."\n"; 
    157  
    158     //Loop on config values 
    159     $out.='  <configs>'."\n"; 
    160     foreach($proc_info['config'] as $res) {       
    161       $name = $res['wf_config_name']; 
    162       $value_int = $res['wf_config_value_int']; 
    163       $value = $res['wf_config_value']; 
    164       $out.='    <config>'."\n"; 
    165       $out.='      <wf_config_name>'.htmlspecialchars($name).'</wf_config_name>'."\n"; 
    166       $out.='      <wf_config_value>'.htmlspecialchars($value).'</wf_config_value>'."\n"; 
    167       $out.='      <wf_config_value_int>'.htmlspecialchars($value_int).'</wf_config_value_int>'."\n"; 
    168       $out.='    </config>'."\n"; 
    169     } 
    170     $out.='  </configs>'."\n"; 
    171  
    172     // Now loop over activities 
    173     $query = "select * from ".GALAXIA_TABLE_PREFIX."activities where wf_p_id=$pId"; 
    174     $result = $this->query($query); 
    175     $out.='  <activities>'."\n"; 
    176     while($res = $result->fetchRow()) {       
    177       $name = $res['wf_normalized_name']; 
    178       $out.='    <activity>'."\n"; 
    179       $out.='      <name>'.htmlspecialchars($res['wf_name']).'</name>'."\n"; 
    180       $out.='      <type>'.htmlspecialchars($res['wf_type']).'</type>'."\n"; 
    181       $out.='      <description>'.htmlspecialchars($res['wf_description']).'</description>'."\n"; 
    182       $out.='      <lastModif>'.date("d/m/Y [h:i:s]",$res['wf_last_modif']).'</lastModif>'."\n"; 
    183       $out.='      <isInteractive>'.$res['wf_is_interactive'].'</isInteractive>'."\n"; 
    184       $out.='      <isAutoRouted>'.$res['wf_is_autorouted'].'</isAutoRouted>'."\n"; 
    185       $out.='      <roles>'."\n"; 
    186       //loop on activity roles 
    187       $actid = $res['wf_activity_id']; 
    188       $roles =& $this->activity_manager->get_activity_roles($actid); 
    189       foreach($roles as $role) { 
    190         if ($role['wf_readonly']) 
    191         { 
    192           $out.='        <role readonly="true">'.htmlspecialchars($role['wf_name']).'</role>'."\n"; 
    193         } 
    194         else 
    195         { 
    196           $out.='        <role>'.htmlspecialchars($role['wf_name']).'</role>'."\n"; 
    197         } 
    198       }   
    199       $out.='      </roles>'."\n"; 
    200       $out.='      <agents>'."\n"; 
    201       //loop on activity agents 
    202       $agents =& $this->activity_manager->get_activity_agents($actid); 
    203       foreach($agents as $agent) { 
    204         $out.='        <agent>'."\n"; 
    205         $out.='           <agent_type>'.htmlspecialchars($agent['wf_agent_type']).'</agent_type>'."\n"; 
    206         //loop on agent datas 
    207         $agent_data =& $this->activity_manager->get_activity_agent_data($actid,$agent['wf_agent_type']); 
    208         $out.='           <agent_datas>'."\n"; 
    209         foreach($agent_data as $key => $value) 
    210         { 
    211           if (!($key=='wf_agent_id')) 
    212           { 
    213             $out.='               <agent_data>'."\n"; 
    214             $out.='                   <name>'.htmlspecialchars($key).'</name>'."\n"; 
    215             $out.='                   <value>'.htmlspecialchars($value).'</value>'."\n"; 
    216             $out.='               </agent_data>'."\n"; 
    217           } 
    218         } 
    219         $out.='           </agent_datas>'."\n"; 
    220         $out.='        </agent>'."\n"; 
    221       }   
    222       $out.='      </agents>'."\n"; 
    223  
    224       //the code 
    225       $out.='      <code><![CDATA['; 
    226       $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."activities".SEP."$name.php","r"); 
    227       while(!feof($fp)) { 
    228         $line=fread($fp,8192); 
    229         $out.=$line; 
    230       } 
    231       fclose($fp); 
    232       $out.='      ]]></code>'; 
    233       if($res['wf_is_interactive']=='y') { 
    234         $out.='      <template><![CDATA['; 
    235         $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."templates".SEP."$name.tpl","r"); 
    236         while(!feof($fp)) { 
    237           $line=fread($fp,8192); 
    238           $out.=$line; 
    239         } 
    240         fclose($fp); 
    241         $out.='      ]]></template>'; 
    242       } 
    243       $out.='    </activity>'."\n";     
    244     } 
    245     $out.='  </activities>'."\n"; 
    246     $out.='  <transitions>'."\n"; 
    247     //loop on transitions 
    248     $transitions = $this->activity_manager->get_process_transitions($pId); 
    249     foreach($transitions as $tran) { 
    250       $out.='     <transition>'."\n"; 
    251       $out.='       <from>'.htmlspecialchars($tran['wf_act_from_name']).'</from>'."\n"; 
    252       $out.='       <to>'.htmlspecialchars($tran['wf_act_to_name']).'</to>'."\n"; 
    253       $out.='     </transition>'."\n"; 
    254     }      
    255     $out.='  </transitions>'."\n"; 
    256     $out.= '</process>'."\n"; 
    257     //$fp = fopen(GALAXIA_PROCESSES."/$wf_procname/$wf_procname.xml","w"); 
    258     //fwrite($fp,$out); 
    259     //fclose($fp); 
    260     return $out; 
    261   } 
    262    
    263   /** 
    264    * Creates  a process PHP data structure from its XML representation 
    265    *  
    266    * @param string &$xml XML document 
    267    * @return array Process data structure 
    268    * @access public 
    269    */ 
    270   function unserialize_process(&$xml)  
    271   { 
    272     // Create SAX parser assign this object as base for handlers 
    273     // handlers are private methods defined below. 
    274     // keep contexts and parse 
    275     $this->parser = xml_parser_create();  
    276     xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0); 
    277     //xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE, 1); 
    278     xml_set_object($this->parser, $this); 
    279     xml_set_element_handler($this->parser, '_start_element_handler', '_end_element_handler'); 
    280     xml_set_character_data_handler($this->parser, '_data_handler');  
    281     $aux=Array( 
    282       'name'=>'root', 
    283       'children'=>Array(), 
    284       'parent' => 0, 
    285       'data'=>'',  
    286       'attribs' => Array(), 
    287     ); 
    288     $this->tree[0]=$aux; 
    289     $this->current=0; 
    290          
    291          
    292     if (!xml_parse($this->parser, $xml, true)) { 
    293        $error = sprintf("XML error: %s at line %d", 
    294                     xml_error_string(xml_get_error_code($this->parser)), 
    295                     xml_get_current_line_number($this->parser)); 
    296        trigger_error($error,E_USER_WARNING); 
    297        $this->error[] = $error; 
    298     } 
    299     xml_parser_free($this->parser);    
    300     // Now that we have the tree we can do interesting things 
    301      
    302     $process=Array(); 
    303     $activities=Array(); 
    304     $transitions=Array(); 
    305     for($i=0;$i<count($this->tree[1]['children']);$i++) { 
    306       // Process attributes 
    307       $z=$this->tree[1]['children'][$i]; 
    308       $name = trim($this->tree[$z]['name']); 
    309        
    310       //config values 
    311       if ($name=='configs') { 
    312         for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
    313           $z2 = $this->tree[$z]['children'][$j]; 
    314           // this is a config $name = $this->tree[$z2]['name']; 
    315           $aux = Array(); 
    316           if($this->tree[$z2]['name']=='config') { 
    317             for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
    318               $z3 = $this->tree[$z2]['children'][$k]; 
    319               $name = trim($this->tree[$z3]['name']); 
    320               $value= trim($this->tree[$z3]['data']); 
    321               $aux[$name]=$value; 
    322             } 
    323             $configs[]=$aux; 
    324           } 
    325         }       
    326       } 
    327       //activities 
    328       elseif($name=='activities') { 
    329         for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
    330           $z2 = $this->tree[$z]['children'][$j]; 
    331           // this is an activity $name = $this->tree[$z2]['name']; 
    332           $aux = Array(); 
    333           if($this->tree[$z2]['name']=='activity') { 
    334             for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
    335               $z3 = $this->curre[$z2]['children'][$k]; 
    336               $name = trim($this->tree[$z3]['name']); 
    337               $value= trim($this->tree[$z3]['data']); 
    338               if($name=='roles') { 
    339                 $roles=Array(); 
    340                 for($l=0;$l<count($this->tree[$z3]['children']);$l++) { 
    341                   $z4 = $this->tree[$z3]['children'][$l]; 
    342                   $name = trim($this->tree[$z4]['name']); 
    343                   $data = trim($this->tree[$z4]['data']); 
    344                   $attribs = $this->tree[$z4]['attribs']; 
    345                   $readonly = false; 
    346                   if ( (isset($attribs['readonly'])) && ($attribs['readonly'])) 
    347                   { 
    348                     //role in read-only 
    349                     $readonly = true; 
    350                   } 
    351                   $roles[]=array( 
    352                     'name'      => $data, 
    353                     'readonly'  => $readonly, 
    354                   ); 
    355                 } 
    356               }  
    357               elseif ($name=='agents')  
    358               { 
    359                 $agents=Array(); 
    360                 for($l=0;$l<count($this->tree[$z3]['children']);$l++)  
    361                 { 
    362                   $z4 = $this->tree[$z3]['children'][$l]; 
    363                   //$name is agent 
    364                   $name = trim($this->tree[$z4]['name']); 
    365                   if ($name = 'agent') 
    366                   { 
    367                     $agent = array(); 
    368                     for($m=0;$m<count($this->tree[$z4]['children']);$m++) 
    369                     { 
    370                       $z5 = $this->tree[$z4]['children'][$m]; 
    371                       //$name is agent_type or agent_datas 
    372                       $name = trim($this->tree[$z5]['name']); 
    373                       // data will be the agent_type or an array for agent_datas 
    374                       $data = trim($this->tree[$z5]['data']); 
    375                       if ($name=='agent_type')  
    376                       { 
    377                         $agent['wf_agent_type']=$data; 
    378                       }  
    379                       elseif ($name=='agent_datas')  
    380                       { 
    381                         for($n=0;$n<count($this->tree[$z5]['children']);$n++) 
    382                         { 
    383                           $z6 = $this->tree[$z5]['children'][$n]; 
    384                           //$name is agent_data $val is an array 
    385                           $name = trim($this->tree[$z6]['name']); 
    386                           $val = trim($this->tree[$z6]['data']); 
    387                           if ($name=='agent_data') 
    388                           { 
    389                             for($o=0;$o<count($this->tree[$z6]['children']);$o++) 
    390                             { 
    391                               $z7 = $this->tree[$z6]['children'][$o]; 
    392                               //$name is agent_data $val is 'name' or 'value' 
    393                               $name = trim($this->tree[$z7]['name']); 
    394                               $content = trim($this->tree[$z7]['data']); 
    395                               //echo "<br>z7 name $name content: $content"; 
    396                               if ($name=='name') 
    397                               { 
    398                                 $agent_data_name = $content; 
    399                               } 
    400                               elseif ($name=='value') 
    401                               { 
    402                                 $agent_data_value =& $content; 
    403                               } 
    404                             } 
    405                             //echo "<br>associate $agent_data_name to $agent_data_value <hr>"; 
    406                             $agent[$agent_data_name] = $agent_data_value; 
    407                           } 
    408                         } 
    409                       } 
    410                     } 
    411                     $agents[]=$agent; 
    412                   } 
    413                 } 
    414               } else { 
    415                 $aux[$name]=$value; 
    416                 //print("$name:$value<br/>"); 
    417               } 
    418             } 
    419             $aux['agents']=$agents; 
    420             $aux['roles']=$roles; 
    421             $activities[]=$aux; 
    422           } 
    423         } 
    424       } elseif($name=='transitions') { 
    425         for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
    426           $z2 = $this->tree[$z]['children'][$j]; 
    427           // this is an activity $name = $this->tree[$z2]['name']; 
    428           $aux=Array(); 
    429           if($this->tree[$z2]['name']=='transition') { 
    430             for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
    431               $z3 = $this->tree[$z2]['children'][$k]; 
    432               $name = trim($this->tree[$z3]['name']); 
    433               $value= trim($this->tree[$z3]['data']); 
    434               if($name == 'from' || $name == 'to') { 
    435                 $aux[$name]=$value; 
    436               } 
    437             } 
    438           } 
    439           $transitions[] = $aux; 
    440         } 
    441       } else { 
    442         $value = trim($this->tree[$z]['data']); 
    443         //print("$name is $value<br/>"); 
    444         $process[$name]=$value; 
    445       } 
    446     } 
    447     $process['configs']=$configs; 
    448     $process['activities']=$activities; 
    449     $process['transitions']=$transitions; 
    450     return $process; 
    451   } 
    452  
    453   /** 
    454    * Creates a process from the process data structure, if you want to convert an XML to a process then use first unserialize_process and then this method. 
    455    *  
    456    * @access public 
    457    * @param string &$data 
    458    * @return bool 
    459    */ 
    460   function import_process(&$data) 
    461   { 
    462     //Now the show begins 
    463     if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
    464     if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db); 
    465     if (!isset($this->jobManager)) 
    466       $this->jobManager = new JobManager($this->db); 
    467  
    468     // First create the process. Always inactive and inactive first. 
    469     $vars = Array( 
    470       'wf_name' => trim($data['name']), 
    471       'wf_version' => $data['version'], 
    472       'wf_description' => $data['description'], 
    473       'wf_last_modif' => $data['lastModif'], 
    474       'wf_is_active' => false, 
    475       'wf_is_valid' => false, 
    476       'config' => $data['configs'], 
    477     ); 
    478  
    479     if (empty($vars['wf_name'])) 
    480     { 
    481       $msg = tra('invalid name specified'); 
    482       $this->notify_all(2,$msg); 
    483       $this->error[] = $msg; 
    484       return false; 
    485     } 
    486  
    487     if (ereg('^[0-9]{1,2}\.[0-9]{1,2}$', $vars['wf_version']) === false) 
    488     { 
    489       $msg = tra('invalid version specified'); 
    490       $this->notify_all(2,$msg); 
    491       $this->error[] = $msg; 
    492       return false; 
    493     } 
    494  
    495     if ($this->process_name_exists($vars['wf_name'], $vars['wf_version'])) 
    496     { 
    497       $msg = sprintf(tra('Process %s %s already exists, the import process was aborted'),$vars['wf_name'],$vars['wf_version']); 
    498       $this->notify_all(2,$msg); 
    499       $this->error[] = $msg; 
    500       return false; 
    501     } 
    502     $pid = $this->replace_process(0,$vars,false); 
    503     //Put the shared code  
    504     $proc_info = $this->get_process($pid); 
    505     $wf_procname = $proc_info['wf_normalized_name']; 
    506     $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'shared.php',"w"); 
    507     fwrite($fp, $data['sharedCode']); 
    508     fclose($fp); 
    509     $actids = Array(); 
    510      
    511     // Foreach activity create activities 
    512     foreach($data['activities'] as $activity) { 
    513                  
    514       $vars = Array( 
    515         'wf_name' => $activity['name'], 
    516         'wf_description' => $activity['description'], 
    517         'wf_type' => $activity['type'], 
    518         'wf_menu_path' => $activity['menuPath'], 
    519         'wf_last_modif' => $activity['lastModif'], 
    520         'wf_is_interactive' => $activity['isInteractive'], 
    521         'wf_is_autorouted' => $activity['isAutoRouted'] 
    522       );     
    523       $actname=$this->activity_manager->_normalize_name($activity['name']); 
    524       $actid = $this->activity_manager->replace_activity($pid,0,$vars); 
    525            
    526       $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php',"w"); 
    527       fwrite($fp, $activity['code']); 
    528       fclose($fp); 
    529       if($activity['isInteractive']=='y') { 
    530         $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl',"w"); 
    531         fwrite($fp,$activity['template']); 
    532         fclose($fp); 
    533       } 
    534       $actids[$activity['name']] = $this->activity_manager->_get_activity_id_by_name($pid, $activity['name']); 
    535       $actname = $this->activity_manager->_normalize_name($activity['name']); 
    536       $now = date("U"); 
    537       //roles 
    538           if( is_array($activity['roles']) && count($activity['roles']) > 0 ) 
    539           { 
    540               foreach($activity['roles'] as $role)  
    541               { 
    542                 $rolename = $role['name']; 
    543                 $vars = Array( 
    544                   'wf_name' => $rolename, 
    545                   'wf_description' => $rolename, 
    546                   'wf_last_modif' => $now, 
    547                 ); 
    548                 if(!$this->role_manager->role_name_exists($pid,$rolename)) { 
    549                   $rid=$this->role_manager->replace_role($pid,0,$vars); 
    550                 } else { 
    551                   $rid = $this->role_manager->get_role_id($pid,$rolename); 
    552                 } 
    553                 if($actid && $rid) { 
    554                   $this->activity_manager->add_activity_role($actid,$rid,$role['readonly']); 
    555                 } 
    556               } 
    557           } 
    558       //agents 
    559       if( is_array($activity['agents']) && count($activity['agents']) > 0 ) 
    560       { 
    561         foreach($activity['agents'] as $agent) 
    562         { 
    563             if (empty($agent['wf_agent_type'])) 
    564             { 
    565               $this->error[] = lang('empty agent type'); 
    566             } 
    567             else 
    568             { 
    569               //create a new agent of the same type for the new activity 
    570               $agentid = $this->activity_manager->add_activity_agent($actid,$agent['wf_agent_type']); 
    571               //save values of this new agent 
    572               $bindvars = Array(); 
    573               $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$agent['wf_agent_type'].' 
    574                         set '; 
    575               //we wont need the old type anymore 
    576               unset($agent['wf_agent_type']); 
    577               $countfields = 0; 
    578               foreach ($agent as $key => $value) 
    579               { 
    580                 if ($key) 
    581                 { 
    582                   $countfields++; 
    583                   $query .= "$key = ? ,"; 
    584                   $bindvars[] = $value; 
    585                 } 
    586               } 
    587               $query = substr($query,'0',-1); 
    588               $query .= ' where wf_agent_id = ?'; 
    589               $bindvars[] = $agentid; 
    590               if ($countfields) $this->query($query, $bindvars); 
    591             } 
    592         } 
    593       } 
    594     } 
    595     //transitions 
    596     foreach($data['transitions'] as $tran)  
    597     { 
    598       $this->activity_manager->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]);   
    599     } 
    600  
    601     foreach ($data['jobs'] as $job) 
    602     { 
    603       $this->jobManager->replaceJob($pid, 0, $job); 
    604     } 
    605  
    606     // create a graph for the new process 
    607     $this->activity_manager->build_process_graph($pid); 
    608     //Test the final process 
    609     $this->activity_manager->validate_process_activities($pid); 
    610  
    611     $msg = sprintf(tra('Process %s %s imported'),$proc_info['wf_name'],$proc_info['wf_version']); 
    612     $this->notify_all(2,$msg); 
    613     $this->error[] = $msg; 
    614     return true; 
    615   } 
    616  
    617   /** 
    618    * Creates a new process based on an existing process changing the process version.  
    619    * By default the process is created as an unactive process and the version is by default a minor version of the process 
    620    *  
    621    * @param int $pId Process id 
    622    * @param bool $minor Process previous version 
    623    * @return int Process id 
    624    * @access public 
    625    */ 
    626   function new_process_version($pId, $minor=true) 
    627   { 
    628     if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
    629     $oldpid = $pId; 
    630     //retrieve process info with config rows 
    631     $proc_info = $this->get_process($pId, true); 
    632     if(!($proc_info) || (count($proc_info)==0)) return false; 
    633     $name = $proc_info['wf_name']; 
    634  
    635     // Now update the version 
    636     $version = $this->_new_version($proc_info['wf_version'],$minor); 
    637     while($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_name=? and wf_version=?',array($name,$version)))  
    638     { 
    639       $version = $this->_new_version($version,$minor); 
    640     } 
    641     $oldname = $proc_info['wf_normalized_name']; 
    642  
    643     // Make new versions unactive 
    644     $proc_info['wf_version'] = $version; 
    645     $proc_info['wf_is_active'] = 'n'; 
    646     // create a new process, but don't create start/end activities 
    647     $pid = $this->replace_process(0, $proc_info, false); 
    648     if (!pid) return false; 
    649  
    650     //Since we are copying a process we should copy 
    651     //the old directory structure to the new directory 
    652     //oldname was saved a few lines before 
    653     $newname = $this->_get_normalized_name($pid); 
    654     $this->_rec_copy(GALAXIA_PROCESSES.SEP.$oldname.SEP.'code',GALAXIA_PROCESSES.SEP.$newname.SEP.'code'); 
    655     // And here copy all the activities & so 
    656     $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 
    657     $result = $this->query($query, array($oldpid)); 
    658     $newaid = array(); 
    659     while($res = $result->fetchRow()) {     
    660       $oldaid = $res['wf_activity_id']; 
    661       // the false tell the am not to create activities source files 
    662       $newaid[$oldaid] = $this->activity_manager->replace_activity($pid,0,$res, false); 
    663     } 
    664     // create transitions 
    665     $query = 'select * from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=?'; 
    666     $result = $this->query($query, array($oldpid)); 
    667  
    668     /* create the jobs */ 
    669     $query = "INSERT INTO " . GALAXIA_TABLE_PREFIX . "jobs (wf_process_id, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, active) (SELECT {$pid}, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, FALSE FROM " . GALAXIA_TABLE_PREFIX . "jobs WHERE wf_process_id = ?)"; 
    670     $this->query($query, array($oldpid)); 
    671  
    672     while($res = $result->fetchRow()) {  
    673       if (empty($newaid[$res['wf_act_from_id']]) || empty($newaid[$res['wf_act_to_id']])) { 
    674         continue; 
    675       } 
    676       $this->activity_manager->add_transition($pid,$newaid[$res['wf_act_from_id']],$newaid[$res['wf_act_to_id']]); 
    677     } 
    678     // create roles 
    679     if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db); 
    680     $query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 
    681     $result = $this->query($query, array($oldpid)); 
    682     $newrid = array(); 
    683     while($res = $result->fetchRow()) { 
    684       if(!$this->role_manager->role_name_exists($pid,$res['wf_name'])) { 
    685         $rid=$this->role_manager->replace_role($pid,0,$res); 
    686       } else { 
    687         $rid = $this->role_manager->get_role_id($pid,$res['wf_name']); 
    688       } 
    689       $newrid[$res['wf_role_id']] = $rid; 
    690     } 
    691     // map users to roles 
    692     if (count($newrid) > 0) { 
    693       $query = 'select * from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 
    694       $result = $this->query($query, array($oldpid)); 
    695       while($res = $result->fetchRow()) { 
    696         if (empty($newrid[$res['wf_role_id']])) { 
    697           continue; 
    698         } 
    699         $this->role_manager->map_user_to_role($pid,$res['wf_user'],$newrid[$res['wf_role_id']], $res['wf_account_type']); 
    700       } 
    701     } 
    702     // add roles to activities 
    703     if (count($newaid) > 0 && count($newrid ) > 0) { 
    704       $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id in (' . join(', ',array_keys($newaid)) . ')'; 
    705       $result = $this->query($query); 
    706       while($res = $result->fetchRow()) { 
    707         if (empty($newaid[$res['wf_activity_id']]) || empty($newrid[$res['wf_role_id']])) { 
    708           continue; 
    709         } 
    710         $this->activity_manager->add_activity_role($newaid[$res['wf_activity_id']],$newrid[$res['wf_role_id']], $res['wf_readonly']); 
    711       } 
    712     } 
    713  
    714     //create agents 
    715     //get the list of agents used by the old process 
    716     $query = 'select gaa.* from '.GALAXIA_TABLE_PREFIX.'activity_agents gaa 
    717                 INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities gac ON gaa.wf_activity_id = gac.wf_activity_id 
    718                 where gac.wf_p_id=?'; 
    719     $result = $this->query($query, array($oldpid)); 
    720     if (!(empty($result))) 
    721     { 
    722       while ($res = $result->fetchRow())  
    723       { 
    724           //create a new agent of the same type for the new activity 
    725           $agentid = $this->activity_manager->add_activity_agent($newaid[$res['wf_activity_id']],$res['wf_agent_type']); 
    726           //save values of this new agents, taking the old ones, we make a simple copy 
    727           $old_activity_agent_data =& $this->activity_manager->get_activity_agent_data($res['wf_activity_id'],$res['wf_agent_type']); 
    728           //we wont need the old id and type 
    729           unset($old_activity_agent_data['wf_agent_id']); 
    730           unset($old_activity_agent_data['wf_agent_type']); 
    731           $bindvars = Array(); 
    732           $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].' 
    733                       set '; 
    734           $countfields = 0; 
    735           foreach ($old_activity_agent_data as $key => $value) 
    736           { 
    737             if ($key) 
    738             { 
    739               $countfields++; 
    740               $query .= "$key = ? ,"; 
    741               $bindvars[] = $value; 
    742             } 
    743           } 
    744           $query = substr($query,'0',-1); 
    745           $query .= ' where wf_agent_id = ?'; 
    746           $bindvars[] = $agentid; 
    747           if ($countfields) $this->query($query, $bindvars); 
    748       } 
    749     } 
    750  
    751     // create a graph for the new process 
    752     $this->activity_manager->build_process_graph($pid); 
    753      
    754     return $pid; 
    755   } 
    756    
    757   /** 
    758    * This function can be used to check if a process name exists, note that this is NOT used by replace_process since that function can be used to 
    759    * create new versions of an existing process. The application must use this method to ensure that processes have unique names. 
    760    *  
    761    * @param string $name Process name 
    762    * @param string $version Process version 
    763    * @return bool  
    764    * @access public 
    765   */ 
    766   function process_name_exists($name,$version) 
    767   { 
    768     $name = addslashes($this->_normalize_name($name,$version)); 
    769     return $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_normalized_name=?',array($name)); 
    770   } 
    771    
    772    
    773   /** 
    774    * Gets a process by pId. Fields are returned as an associative array.  
    775    * If withConfig is set (false by default), the configuration options are returned as well the ['config'] key is then an array containing the config data with type distinction 
    776    *  
    777    * @param int $pId Process id 
    778    * @param bool $withConfig Configuration options 
    779    * @return bool 
    780    * @access public 
    781    */ 
    782   function get_process($pId, $withConfig=false) 
    783   { 
    784     $query = 'select * from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 
    785     $result = $this->query($query, array($pId)); 
    786     if((empty($result)) || (!$result->numRows())) return false; 
    787     $res = $result->fetchRow(); 
    788     if ($withConfig) 
    789     { 
    790       // by setting true we force this function to keep type distinction on config values 
    791       $res['config'] = $this->getConfigValues($res['wf_p_id'], true); 
    792     } 
    793     return $res; 
    794   } 
    795    
    796   /** 
    797    * Lists all processes 
    798    *  
    799    * @param int $offset Resultset starting row 
    800    * @param int $maxRecords Max number of resulting rows 
    801    * @param string $sort_mode Sorting mode 
    802    * @param string $find Search query string 
    803    * @param string $where Condition query string 
    804    * @return bool  
    805    * @access public 
    806    */ 
    807   function list_processes($offset,$maxRecords,$sort_mode,$find='',$where='') 
    808   { 
    809     $sort_mode = $this->convert_sortmode($sort_mode); 
    810     if($find) { 
    811       $findesc = '%'.$find.'%'; 
    812       $mid=' where ((wf_name like ?) or (wf_description like ?))'; 
    813       $bindvars = array($findesc,$findesc); 
    814     } else { 
    815       $mid=''; 
    816       $bindvars = array(); 
    817     } 
    818     if($where) { 
    819       if($mid) { 
    820         $mid.= " and ($where) "; 
    821       } else { 
    822         $mid.= " where ($where) "; 
    823       } 
    824     } 
    825     $query = 'select * from '.GALAXIA_TABLE_PREFIX."processes $mid"; 
    826     $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."processes $mid"; 
    827     $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode); 
    828     $cant = $this->getOne($query_cant,$bindvars); 
    829     $ret = Array(); 
    830     if (isset($result)) 
    831     { 
    832       while($res = $result->fetchRow())  
    833       { 
    834         $ret[] = $res; 
    835       } 
    836     } 
    837     $retval = Array(); 
    838     $retval['data'] = $ret; 
    839     $retval['cant'] = $cant; 
    840     return $retval; 
    841   } 
    842    
     12 
     13        /** 
     14         * @var resource $parser xml parser 
     15         * @access public 
     16         */ 
     17        var $parser; 
     18 
     19        /** 
     20         * @var array $tree data struture 
     21         * @access public 
     22         */ 
     23        var $tree; 
     24 
     25        /** 
     26         * @var $current current element 
     27         * @access public 
     28         */ 
     29        var $current; 
     30 
     31        /** 
     32         * @var $buffer buffer for data 
     33         * @access public 
     34         */ 
     35        var $buffer; 
     36 
     37        /** 
     38         * @var object $Process Process 
     39         * @access public 
     40         */ 
     41        var $Process; 
     42 
     43        /** 
     44         * @var object $activity_manager Activity Manager 
     45         * @access public 
     46         */ 
     47        var $activity_manager; 
     48 
     49        /** 
     50         * @var object $jobManager Job Manager object 
     51         * @access public 
     52         */ 
     53        var $jobManager; 
     54 
     55        /** 
     56         * @var object $role_manager Role Manager 
     57         * @access public 
     58         */ 
     59        var $role_manager; 
     60 
     61        /** 
     62         * Constructor 
     63         * 
     64         * @param object &$db ADOdb 
     65         * @return object ProcessManager 
     66         * @access public 
     67         */ 
     68        function ProcessManager(&$db) 
     69        { 
     70                parent::BaseManager($db); 
     71                $this->child_name = 'ProcessManager'; 
     72                require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'ActivityManager.php'); 
     73                require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'JobManager.php'); 
     74                // $this->activity_manager is not set here to avoid objects loading object A loading object B loading object A, etc 
     75                //$this->role_manager will only be loaded when needed as well 
     76        } 
     77 
     78        /** 
     79         * Collect errors from all linked objects which could have been used by this object. 
     80         * Each child class should instantiate this function with her linked objetcs, calling get_error(true) 
     81         * 
     82         * @param bool $debug False by default, if true debug messages can be added to 'normal' messages 
     83         * @param string $prefix Appended to the debug message 
     84         * @return void 
     85         * @access public 
     86         */ 
     87        function collect_errors($debug=false, $prefix = '') 
     88        { 
     89                parent::collect_errors($debug, $prefix); 
     90                if (isset($this->activity_manager)) $this->error[] = $this->activity_manager->get_error(false, $debug, $prefix); 
     91                if (isset($this->role_manager)) $this->error[] = $this->role_manager->get_error(false, $debug, $prefix); 
     92        } 
     93 
     94        /** 
     95         * Activates a process 
     96         * 
     97         * @param int $pId Process id 
     98         * @return void 
     99         * @access public 
     100         */ 
     101        function activate_process($pId) 
     102        { 
     103                $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?'; 
     104                $this->query($query, array('y',$pId)); 
     105                $msg = sprintf(tra('Process %d has been activated'),$pId); 
     106                $this->error[] = $msg; 
     107        } 
     108 
     109        /** 
     110         * Deactivates a process 
     111         * 
     112         * @param int $pId Process id 
     113         * @return void 
     114         * @access public 
     115         */ 
     116        function deactivate_process($pId) 
     117        { 
     118                $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?'; 
     119                $this->query($query, array('n',$pId)); 
     120                $msg = sprintf(tra('Process %d has been deactivated'),$pId); 
     121                $this->error[] = $msg; 
     122        } 
     123 
     124        /** 
     125         * Creates an XML representation of a process 
     126         * 
     127         * @param int $pId Process id 
     128         * @return string 
     129         * @access public 
     130         */ 
     131        function serialize_process($pId) 
     132        { 
     133                if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
     134                // <process> 
     135                $out = '<process>'."\n"; 
     136                //we retrieve config values with the others process data 
     137                $proc_info =& $this->get_process($pId, true); 
     138                $wf_procname = $proc_info['wf_normalized_name']; 
     139                $out.= '  <name>'.htmlspecialchars($proc_info['wf_name']).'</name>'."\n"; 
     140                $out.= '  <isValid>'.htmlspecialchars($proc_info['wf_is_valid']).'</isValid>'."\n"; 
     141                $out.= '  <version>'.htmlspecialchars($proc_info['wf_version']).'</version>'."\n"; 
     142                $out.= '  <isActive>'.htmlspecialchars($proc_info['wf_is_active']).'</isActive>'."\n"; 
     143                $out.='   <description>'.htmlspecialchars($proc_info['wf_description']).'</description>'."\n"; 
     144                $out.= '  <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['wf_last_modif']).'</lastModif>'."\n"; 
     145 
     146                //Shared code 
     147                $out.= '  <sharedCode><![CDATA['; 
     148                $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."shared.php","r"); 
     149                while(!feof($fp)) { 
     150                        $line=fread($fp,8192); 
     151                        $out.=$line; 
     152                } 
     153                fclose($fp); 
     154                $out.= '  ]]></sharedCode>'."\n"; 
     155 
     156                //Loop on config values 
     157                $out.='  <configs>'."\n"; 
     158                foreach($proc_info['config'] as $res) { 
     159                        $name = $res['wf_config_name']; 
     160                        $value_int = $res['wf_config_value_int']; 
     161                        $value = $res['wf_config_value']; 
     162                        $out.='    <config>'."\n"; 
     163                        $out.='      <wf_config_name>'.htmlspecialchars($name).'</wf_config_name>'."\n"; 
     164                        $out.='      <wf_config_value>'.htmlspecialchars($value).'</wf_config_value>'."\n"; 
     165                        $out.='      <wf_config_value_int>'.htmlspecialchars($value_int).'</wf_config_value_int>'."\n"; 
     166                        $out.='    </config>'."\n"; 
     167                } 
     168                $out.='  </configs>'."\n"; 
     169 
     170                // Now loop over activities 
     171                $query = "select * from ".GALAXIA_TABLE_PREFIX."activities where wf_p_id=$pId"; 
     172                $result = $this->query($query); 
     173                $out.='  <activities>'."\n"; 
     174                while($res = $result->fetchRow()) { 
     175                        $name = $res['wf_normalized_name']; 
     176                        $out.='    <activity>'."\n"; 
     177                        $out.='      <name>'.htmlspecialchars($res['wf_name']).'</name>'."\n"; 
     178                        $out.='      <type>'.htmlspecialchars($res['wf_type']).'</type>'."\n"; 
     179                        $out.='      <description>'.htmlspecialchars($res['wf_description']).'</description>'."\n"; 
     180                        $out.='      <lastModif>'.date("d/m/Y [h:i:s]",$res['wf_last_modif']).'</lastModif>'."\n"; 
     181                        $out.='      <isInteractive>'.$res['wf_is_interactive'].'</isInteractive>'."\n"; 
     182                        $out.='      <isAutoRouted>'.$res['wf_is_autorouted'].'</isAutoRouted>'."\n"; 
     183                        $out.='      <roles>'."\n"; 
     184                        //loop on activity roles 
     185                        $actid = $res['wf_activity_id']; 
     186                        $roles =& $this->activity_manager->get_activity_roles($actid); 
     187                        foreach($roles as $role) { 
     188                                if ($role['wf_readonly']) 
     189                                { 
     190                                        $out.='        <role readonly="true">'.htmlspecialchars($role['wf_name']).'</role>'."\n"; 
     191                                } 
     192                                else 
     193                                { 
     194                                        $out.='        <role>'.htmlspecialchars($role['wf_name']).'</role>'."\n"; 
     195                                } 
     196                        } 
     197                        $out.='      </roles>'."\n"; 
     198                        $out.='      <agents>'."\n"; 
     199                        //loop on activity agents 
     200                        $agents =& $this->activity_manager->get_activity_agents($actid); 
     201                        foreach($agents as $agent) { 
     202                                $out.='        <agent>'."\n"; 
     203                                $out.='           <agent_type>'.htmlspecialchars($agent['wf_agent_type']).'</agent_type>'."\n"; 
     204                                //loop on agent datas 
     205                                $agent_data =& $this->activity_manager->get_activity_agent_data($actid,$agent['wf_agent_type']); 
     206                                $out.='           <agent_datas>'."\n"; 
     207                                foreach($agent_data as $key => $value) 
     208                                { 
     209                                        if (!($key=='wf_agent_id')) 
     210                                        { 
     211                                                $out.='               <agent_data>'."\n"; 
     212                                                $out.='                   <name>'.htmlspecialchars($key).'</name>'."\n"; 
     213                                                $out.='                   <value>'.htmlspecialchars($value).'</value>'."\n"; 
     214                                                $out.='               </agent_data>'."\n"; 
     215                                        } 
     216                                } 
     217                                $out.='           </agent_datas>'."\n"; 
     218                                $out.='        </agent>'."\n"; 
     219                        } 
     220                        $out.='      </agents>'."\n"; 
     221 
     222                        //the code 
     223                        $out.='      <code><![CDATA['; 
     224                        $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."activities".SEP."$name.php","r"); 
     225                        while(!feof($fp)) { 
     226                                $line=fread($fp,8192); 
     227                                $out.=$line; 
     228                        } 
     229                        fclose($fp); 
     230                        $out.='      ]]></code>'; 
     231                        if($res['wf_is_interactive']=='y') { 
     232                                $out.='      <template><![CDATA['; 
     233                                $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."templates".SEP."$name.tpl","r"); 
     234                                while(!feof($fp)) { 
     235                                        $line=fread($fp,8192); 
     236                                        $out.=$line; 
     237                                } 
     238                                fclose($fp); 
     239                                $out.='      ]]></template>'; 
     240                        } 
     241                        $out.='    </activity>'."\n"; 
     242                } 
     243                $out.='  </activities>'."\n"; 
     244                $out.='  <transitions>'."\n"; 
     245                //loop on transitions 
     246                $transitions = $this->activity_manager->get_process_transitions($pId); 
     247                foreach($transitions as $tran) { 
     248                        $out.='     <transition>'."\n"; 
     249                        $out.='       <from>'.htmlspecialchars($tran['wf_act_from_name']).'</from>'."\n"; 
     250                        $out.='       <to>'.htmlspecialchars($tran['wf_act_to_name']).'</to>'."\n"; 
     251                        $out.='     </transition>'."\n"; 
     252                } 
     253                $out.='  </transitions>'."\n"; 
     254                $out.= '</process>'."\n"; 
     255                //$fp = fopen(GALAXIA_PROCESSES."/$wf_procname/$wf_procname.xml","w"); 
     256                //fwrite($fp,$out); 
     257                //fclose($fp); 
     258                return $out; 
     259        } 
     260 
     261        /** 
     262         * Creates  a process PHP data structure from its XML representation 
     263         * 
     264         * @param string &$xml XML document 
     265         * @return array Process data structure 
     266         * @access public 
     267         */ 
     268        function unserialize_process(&$xml) 
     269        { 
     270                // Create SAX parser assign this object as base for handlers 
     271                // handlers are private methods defined below. 
     272                // keep contexts and parse 
     273                $this->parser = xml_parser_create(); 
     274                xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0); 
     275                //xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE, 1); 
     276                xml_set_object($this->parser, $this); 
     277                xml_set_element_handler($this->parser, '_start_element_handler', '_end_element_handler'); 
     278                xml_set_character_data_handler($this->parser, '_data_handler'); 
     279                $aux=Array( 
     280                        'name'=>'root', 
     281                        'children'=>Array(), 
     282                        'parent' => 0, 
     283                        'data'=>'', 
     284                        'attribs'       => Array(), 
     285                ); 
     286                $this->tree[0]=$aux; 
     287                $this->current=0; 
     288 
     289 
     290                if (!xml_parse($this->parser, $xml, true)) { 
     291                        $error = sprintf("XML error: %s at line %d", 
     292                                xml_error_string(xml_get_error_code($this->parser)), 
     293                                xml_get_current_line_number($this->parser)); 
     294                        trigger_error($error,E_USER_WARNING); 
     295                        $this->error[] = $error; 
     296                } 
     297                xml_parser_free($this->parser); 
     298                // Now that we have the tree we can do interesting things 
     299 
     300                $process=Array(); 
     301                $activities=Array(); 
     302                $transitions=Array(); 
     303                for($i=0;$i<count($this->tree[1]['children']);$i++) { 
     304                        // Process attributes 
     305                        $z=$this->tree[1]['children'][$i]; 
     306                        $name = trim($this->tree[$z]['name']); 
     307 
     308                        //config values 
     309                        if ($name=='configs') { 
     310                                for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
     311                                        $z2 = $this->tree[$z]['children'][$j]; 
     312                                        // this is a config $name = $this->tree[$z2]['name']; 
     313                                        $aux = Array(); 
     314                                        if($this->tree[$z2]['name']=='config') { 
     315                                                for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
     316                                                        $z3 = $this->tree[$z2]['children'][$k]; 
     317                                                        $name = trim($this->tree[$z3]['name']); 
     318                                                        $value= trim($this->tree[$z3]['data']); 
     319                                                        $aux[$name]=$value; 
     320                                                } 
     321                                                $configs[]=$aux; 
     322                                        } 
     323                                } 
     324                        } 
     325                        //activities 
     326                        elseif($name=='activities') { 
     327                                for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
     328                                        $z2 = $this->tree[$z]['children'][$j]; 
     329                                        // this is an activity $name = $this->tree[$z2]['name']; 
     330                                        $aux = Array(); 
     331                                        if($this->tree[$z2]['name']=='activity') { 
     332                                                for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
     333                                                        $z3 = $this->curre[$z2]['children'][$k]; 
     334                                                        $name = trim($this->tree[$z3]['name']); 
     335                                                        $value= trim($this->tree[$z3]['data']); 
     336                                                        if($name=='roles') { 
     337                                                                $roles=Array(); 
     338                                                                for($l=0;$l<count($this->tree[$z3]['children']);$l++) { 
     339                                                                        $z4 = $this->tree[$z3]['children'][$l]; 
     340                                                                        $name = trim($this->tree[$z4]['name']); 
     341                                                                        $data = trim($this->tree[$z4]['data']); 
     342                                                                        $attribs = $this->tree[$z4]['attribs']; 
     343                                                                        $readonly = false; 
     344                                                                        if ( (isset($attribs['readonly'])) && ($attribs['readonly'])) 
     345                                                                        { 
     346                                                                                //role in read-only 
     347                                                                                $readonly = true; 
     348                                                                        } 
     349                                                                        $roles[]=array( 
     350                                                                                'name'  => $data, 
     351                                                                                'readonly'      => $readonly, 
     352                                                                        ); 
     353                                                                } 
     354                                                        } 
     355                                                        elseif ($name=='agents') 
     356                                                        { 
     357                                                                $agents=Array(); 
     358                                                                for($l=0;$l<count($this->tree[$z3]['children']);$l++) 
     359                                                                { 
     360                                                                        $z4 = $this->tree[$z3]['children'][$l]; 
     361                                                                        //$name is agent 
     362                                                                        $name = trim($this->tree[$z4]['name']); 
     363                                                                        if ($name = 'agent') 
     364                                                                        { 
     365                                                                                $agent = array(); 
     366                                                                                for($m=0;$m<count($this->tree[$z4]['children']);$m++) 
     367                                                                                { 
     368                                                                                        $z5 = $this->tree[$z4]['children'][$m]; 
     369                                                                                        //$name is agent_type or agent_datas 
     370                                                                                        $name = trim($this->tree[$z5]['name']); 
     371                                                                                        // data will be the agent_type or an array for agent_datas 
     372                                                                                        $data = trim($this->tree[$z5]['data']); 
     373                                                                                        if ($name=='agent_type') 
     374                                                                                        { 
     375                                                                                                $agent['wf_agent_type']=$data; 
     376                                                                                        } 
     377                                                                                        elseif ($name=='agent_datas') 
     378                                                                                        { 
     379                                                                                                for($n=0;$n<count($this->tree[$z5]['children']);$n++) 
     380                                                                                                { 
     381                                                                                                        $z6 = $this->tree[$z5]['children'][$n]; 
     382                                                                                                        //$name is agent_data $val is an array 
     383                                                                                                        $name = trim($this->tree[$z6]['name']); 
     384                                                                                                        $val = trim($this->tree[$z6]['data']); 
     385                                                                                                        if ($name=='agent_data') 
     386                                                                                                        { 
     387                                                                                                                for($o=0;$o<count($this->tree[$z6]['children']);$o++) 
     388                                                                                                                { 
     389                                                                                                                        $z7 = $this->tree[$z6]['children'][$o]; 
     390                                                                                                                        //$name is agent_data $val is 'name' or 'value' 
     391                                                                                                                        $name = trim($this->tree[$z7]['name']); 
     392                                                                                                                        $content = trim($this->tree[$z7]['data']); 
     393                                                                                                                        //echo "<br>z7 name $name content: $content"; 
     394                                                                                                                        if ($name=='name') 
     395                                                                                                                        { 
     396                                                                                                                                $agent_data_name = $content; 
     397                                                                                                                        } 
     398                                                                                                                        elseif ($name=='value') 
     399                                                                                                                        { 
     400                                                                                                                                $agent_data_value =& $content; 
     401                                                                                                                        } 
     402                                                                                                                } 
     403                                                                                                                //echo "<br>associate $agent_data_name to $agent_data_value <hr>"; 
     404                                                                                                                $agent[$agent_data_name] = $agent_data_value; 
     405                                                                                                        } 
     406                                                                                                } 
     407                                                                                        } 
     408                                                                                } 
     409                                                                                $agents[]=$agent; 
     410                                                                        } 
     411                                                                } 
     412                                                        } else { 
     413                                                                $aux[$name]=$value; 
     414                                                                //print("$name:$value<br/>"); 
     415                                                        } 
     416                                                } 
     417                                                $aux['agents']=$agents; 
     418                                                $aux['roles']=$roles; 
     419                                                $activities[]=$aux; 
     420                                        } 
     421                                } 
     422                        } elseif($name=='transitions') { 
     423                                for($j=0;$j<count($this->tree[$z]['children']);$j++) { 
     424                                        $z2 = $this->tree[$z]['children'][$j]; 
     425                                        // this is an activity $name = $this->tree[$z2]['name']; 
     426                                        $aux=Array(); 
     427                                        if($this->tree[$z2]['name']=='transition') { 
     428                                                for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 
     429                                                        $z3 = $this->tree[$z2]['children'][$k]; 
     430                                                        $name = trim($this->tree[$z3]['name']); 
     431                                                        $value= trim($this->tree[$z3]['data']); 
     432                                                        if($name == 'from' || $name == 'to') { 
     433                                                                $aux[$name]=$value; 
     434                                                        } 
     435                                                } 
     436                                        } 
     437                                        $transitions[] = $aux; 
     438                                } 
     439                        } else { 
     440                                $value = trim($this->tree[$z]['data']); 
     441                                //print("$name is $value<br/>"); 
     442                                $process[$name]=$value; 
     443                        } 
     444                } 
     445                $process['configs']=$configs; 
     446                $process['activities']=$activities; 
     447                $process['transitions']=$transitions; 
     448                return $process; 
     449        } 
     450 
     451        /** 
     452         * Creates a process from the process data structure, if you want to convert an XML to a process then use first unserialize_process and then this method. 
     453         * 
     454         * @access public 
     455         * @param string &$data 
     456         * @return bool 
     457         */ 
     458        function import_process(&$data) 
     459        { 
     460                //Now the show begins 
     461                if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
     462                if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db); 
     463                if (!isset($this->jobManager)) 
     464                        $this->jobManager = new JobManager($this->db); 
     465 
     466                // First create the process. Always inactive and inactive first. 
     467                $vars = Array( 
     468                        'wf_name' => trim($data['name']), 
     469                        'wf_version' => $data['version'], 
     470                        'wf_description' => $data['description'], 
     471                        'wf_last_modif' => $data['lastModif'], 
     472                        'wf_is_active' => false, 
     473                        'wf_is_valid' => false, 
     474                        'config' => $data['configs'], 
     475                ); 
     476 
     477                if (empty($vars['wf_name'])) 
     478                { 
     479                        $msg = tra('invalid name specified'); 
     480                        $this->error[] = $msg; 
     481                        return false; 
     482                } 
     483 
     484                if (ereg('^[0-9]{1,2}\.[0-9]{1,2}$', $vars['wf_version']) === false) 
     485                { 
     486                        $msg = tra('invalid version specified'); 
     487                        $this->error[] = $msg; 
     488                        return false; 
     489                } 
     490 
     491                if ($this->process_name_exists($vars['wf_name'], $vars['wf_version'])) 
     492                { 
     493                        $msg = sprintf(tra('Process %s %s already exists, the import process was aborted'),$vars['wf_name'],$vars['wf_version']); 
     494                        $this->error[] = $msg; 
     495                        return false; 
     496                } 
     497                $pid = $this->replace_process(0,$vars,false); 
     498                //Put the shared code 
     499                $proc_info = $this->get_process($pid); 
     500                $wf_procname = $proc_info['wf_normalized_name']; 
     501                $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'shared.php',"w"); 
     502                fwrite($fp, $data['sharedCode']); 
     503                fclose($fp); 
     504                $actids = Array(); 
     505 
     506                // Foreach activity create activities 
     507                foreach($data['activities'] as $activity) { 
     508 
     509                        $vars = Array( 
     510                                'wf_name' => $activity['name'], 
     511                                'wf_description' => $activity['description'], 
     512                                'wf_type' => $activity['type'], 
     513                                'wf_menu_path' => $activity['menuPath'], 
     514                                'wf_last_modif' => $activity['lastModif'], 
     515                                'wf_is_interactive' => $activity['isInteractive'], 
     516                                'wf_is_autorouted' => $activity['isAutoRouted'] 
     517                        ); 
     518                        $actname=$this->activity_manager->_normalize_name($activity['name']); 
     519                        $actid = $this->activity_manager->replace_activity($pid,0,$vars); 
     520 
     521                        $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php',"w"); 
     522                        fwrite($fp, $activity['code']); 
     523                        fclose($fp); 
     524                        if($activity['isInteractive']=='y') { 
     525                                $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl',"w"); 
     526                                fwrite($fp,$activity['template']); 
     527                                fclose($fp); 
     528                        } 
     529                        $actids[$activity['name']] = $this->activity_manager->_get_activity_id_by_name($pid, $activity['name']); 
     530                        $actname = $this->activity_manager->_normalize_name($activity['name']); 
     531                        $now = date("U"); 
     532                        //roles 
     533                        if( is_array($activity['roles']) && count($activity['roles']) > 0 ) 
     534                        { 
     535                                foreach($activity['roles'] as $role) 
     536                                { 
     537                                        $rolename = $role['name']; 
     538                                        $vars = Array( 
     539                                                'wf_name' => $rolename, 
     540                                                'wf_description' => $rolename, 
     541                                                'wf_last_modif' => $now, 
     542                                        ); 
     543                                        if(!$this->role_manager->role_name_exists($pid,$rolename)) { 
     544                                                $rid=$this->role_manager->replace_role($pid,0,$vars); 
     545                                        } else { 
     546                                                $rid = $this->role_manager->get_role_id($pid,$rolename); 
     547                                        } 
     548                                        if($actid && $rid) { 
     549                                                $this->activity_manager->add_activity_role($actid,$rid,$role['readonly']); 
     550                                        } 
     551                                } 
     552                        } 
     553                        //agents 
     554                        if( is_array($activity['agents']) && count($activity['agents']) > 0 ) 
     555                        { 
     556                                foreach($activity['agents'] as $agent) 
     557                                { 
     558                                        if (empty($agent['wf_agent_type'])) 
     559                                        { 
     560                                                $this->error[] = lang('empty agent type'); 
     561                                        } 
     562                                        else 
     563                                        { 
     564                                                //create a new agent of the same type for the new activity 
     565                                                $agentid = $this->activity_manager->add_activity_agent($actid,$agent['wf_agent_type']); 
     566                                                //save values of this new agent 
     567                                                $bindvars = Array(); 
     568                                                $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$agent['wf_agent_type'].' 
     569                                                        set '; 
     570                                                //we wont need the old type anymore 
     571                                                unset($agent['wf_agent_type']); 
     572                                                $countfields = 0; 
     573                                                foreach ($agent as $key => $value) 
     574                                                { 
     575                                                        if ($key) 
     576                                                        { 
     577                                                                $countfields++; 
     578                                                                $query .= "$key = ? ,"; 
     579                                                                $bindvars[] = $value; 
     580                                                        } 
     581                                                } 
     582                                                $query = substr($query,'0',-1); 
     583                                                $query .= ' where wf_agent_id = ?'; 
     584                                                $bindvars[] = $agentid; 
     585                                                if ($countfields) $this->query($query, $bindvars); 
     586                                        } 
     587                                } 
     588                        } 
     589                } 
     590                //transitions 
     591                foreach($data['transitions'] as $tran) 
     592                { 
     593                        $this->activity_manager->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]); 
     594                } 
     595 
     596                foreach ($data['jobs'] as $job) 
     597                { 
     598                        $this->jobManager->replaceJob($pid, 0, $job); 
     599                } 
     600 
     601                // create a graph for the new process 
     602                $this->activity_manager->build_process_graph($pid); 
     603                //Test the final process 
     604                $this->activity_manager->validate_process_activities($pid); 
     605 
     606                $msg = sprintf(tra('Process %s %s imported'),$proc_info['wf_name'],$proc_info['wf_version']); 
     607                $this->error[] = $msg; 
     608                return true; 
     609        } 
     610 
     611        /** 
     612         * Creates a new process based on an existing process changing the process version. 
     613         * By default the process is created as an unactive process and the version is by default a minor version of the process 
     614         * 
     615         * @param int $pId Process id 
     616         * @param bool $minor Process previous version 
     617         * @return int Process id 
     618         * @access public 
     619         */ 
     620        function new_process_version($pId, $minor=true) 
     621        { 
     622                if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
     623                $oldpid = $pId; 
     624                //retrieve process info with config rows 
     625                $proc_info = $this->get_process($pId, true); 
     626                if(!($proc_info) || (count($proc_info)==0)) return false; 
     627                $name = $proc_info['wf_name']; 
     628 
     629                // Now update the version 
     630                $version = $this->_new_version($proc_info['wf_version'],$minor); 
     631                while($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_name=? and wf_version=?',array($name,$version))) 
     632                { 
     633                        $version = $this->_new_version($version,$minor); 
     634                } 
     635                $oldname = $proc_info['wf_normalized_name']; 
     636 
     637                // Make new versions unactive 
     638                $proc_info['wf_version'] = $version; 
     639                $proc_info['wf_is_active'] = 'n'; 
     640                // create a new process, but don't create start/end activities 
     641                $pid = $this->replace_process(0, $proc_info, false); 
     642                if (!pid) return false; 
     643 
     644                //Since we are copying a process we should copy 
     645                //the old directory structure to the new directory 
     646                //oldname was saved a few lines before 
     647                $newname = $this->_get_normalized_name($pid); 
     648                $this->_rec_copy(GALAXIA_PROCESSES.SEP.$oldname.SEP.'code',GALAXIA_PROCESSES.SEP.$newname.SEP.'code'); 
     649                // And here copy all the activities & so 
     650                $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 
     651                $result = $this->query($query, array($oldpid)); 
     652                $newaid = array(); 
     653                while($res = $result->fetchRow()) { 
     654                        $oldaid = $res['wf_activity_id']; 
     655                        // the false tell the am not to create activities source files 
     656                        $newaid[$oldaid] = $this->activity_manager->replace_activity($pid,0,$res, false); 
     657                } 
     658                // create transitions 
     659                $query = 'select * from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=?'; 
     660                $result = $this->query($query, array($oldpid)); 
     661 
     662                /* create the jobs */ 
     663                $query = "INSERT INTO " . GALAXIA_TABLE_PREFIX . "jobs (wf_process_id, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, active) (SELECT {$pid}, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, FALSE FROM " . GALAXIA_TABLE_PREFIX . "jobs WHERE wf_process_id = ?)"; 
     664                $this->query($query, array($oldpid)); 
     665 
     666                while($res = $result->fetchRow()) { 
     667                        if (empty($newaid[$res['wf_act_from_id']]) || empty($newaid[$res['wf_act_to_id']])) { 
     668                                continue; 
     669                        } 
     670                        $this->activity_manager->add_transition($pid,$newaid[$res['wf_act_from_id']],$newaid[$res['wf_act_to_id']]); 
     671                } 
     672                // create roles 
     673                if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db); 
     674                $query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 
     675                $result = $this->query($query, array($oldpid)); 
     676                $newrid = array(); 
     677                while($res = $result->fetchRow()) { 
     678                        if(!$this->role_manager->role_name_exists($pid,$res['wf_name'])) { 
     679                                $rid=$this->role_manager->replace_role($pid,0,$res); 
     680                        } else { 
     681                                $rid = $this->role_manager->get_role_id($pid,$res['wf_name']); 
     682                        } 
     683                        $newrid[$res['wf_role_id']] = $rid; 
     684                } 
     685                // map users to roles 
     686                if (count($newrid) > 0) { 
     687                        $query = 'select * from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 
     688                        $result = $this->query($query, array($oldpid)); 
     689                        while($res = $result->fetchRow()) { 
     690                                if (empty($newrid[$res['wf_role_id']])) { 
     691                                        continue; 
     692                                } 
     693                                $this->role_manager->map_user_to_role($pid,$res['wf_user'],$newrid[$res['wf_role_id']], $res['wf_account_type']); 
     694                        } 
     695                } 
     696                // add roles to activities 
     697                if (count($newaid) > 0 && count($newrid ) > 0) { 
     698                        $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id in (' . join(', ',array_keys($newaid)) . ')'; 
     699                        $result = $this->query($query); 
     700                        while($res = $result->fetchRow()) { 
     701                                if (empty($newaid[$res['wf_activity_id']]) || empty($newrid[$res['wf_role_id']])) { 
     702                                        continue; 
     703                                } 
     704                                $this->activity_manager->add_activity_role($newaid[$res['wf_activity_id']],$newrid[$res['wf_role_id']], $res['wf_readonly']); 
     705                        } 
     706                } 
     707 
     708                //create agents 
     709                //get the list of agents used by the old process 
     710                $query = 'select gaa.* from '.GALAXIA_TABLE_PREFIX.'activity_agents gaa 
     711                        INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities gac ON gaa.wf_activity_id = gac.wf_activity_id 
     712                        where gac.wf_p_id=?'; 
     713                $result = $this->query($query, array($oldpid)); 
     714                if (!(empty($result))) 
     715                { 
     716                        while ($res = $result->fetchRow()) 
     717                        { 
     718                                //create a new agent of the same type for the new activity 
     719                                $agentid = $this->activity_manager->add_activity_agent($newaid[$res['wf_activity_id']],$res['wf_agent_type']); 
     720                                //save values of this new agents, taking the old ones, we make a simple copy 
     721                                $old_activity_agent_data =& $this->activity_manager->get_activity_agent_data($res['wf_activity_id'],$res['wf_agent_type']); 
     722                                //we wont need the old id and type 
     723                                unset($old_activity_agent_data['wf_agent_id']); 
     724                                unset($old_activity_agent_data['wf_agent_type']); 
     725                                $bindvars = Array(); 
     726                                $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].' 
     727                                        set '; 
     728                                $countfields = 0; 
     729                                foreach ($old_activity_agent_data as $key => $value) 
     730                                { 
     731                                        if ($key) 
     732                                        { 
     733                                                $countfields++; 
     734                                                $query .= "$key = ? ,"; 
     735                                                $bindvars[] = $value; 
     736                                        } 
     737                                } 
     738                                $query = substr($query,'0',-1); 
     739                                $query .= ' where wf_agent_id = ?'; 
     740                                $bindvars[] = $agentid; 
     741                                if ($countfields) $this->query($query, $bindvars); 
     742                        } 
     743                } 
     744 
     745                // create a graph for the new process 
     746                $this->activity_manager->build_process_graph($pid); 
     747 
     748                return $pid; 
     749        } 
     750 
     751        /** 
     752         * This function can be used to check if a process name exists, note that this is NOT used by replace_process since that function can be used to 
     753         * create new versions of an existing process. The application must use this method to ensure that processes have unique names. 
     754         * 
     755         * @param string $name Process name 
     756         * @param string $version Process version 
     757         * @return bool 
     758         * @access public 
     759         */ 
     760        function process_name_exists($name,$version) 
     761        { 
     762                $name = addslashes($this->_normalize_name($name,$version)); 
     763                return $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_normalized_name=?',array($name)); 
     764        } 
     765 
     766 
     767        /** 
     768         * Gets a process by pId. Fields are returned as an associative array. 
     769         * If withConfig is set (false by default), the configuration options are returned as well the ['config'] key is then an array containing the config data with type distinction 
     770         * 
     771         * @param int $pId Process id 
     772         * @param bool $withConfig Configuration options 
     773         * @return bool 
     774         * @access public 
     775         */ 
     776        function get_process($pId, $withConfig=false) 
     777        { 
     778                $query = 'select * from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 
     779                $result = $this->query($query, array($pId)); 
     780                if((empty($result)) || (!$result->numRows())) return false; 
     781                $res = $result->fetchRow(); 
     782                if ($withConfig) 
     783                { 
     784                        // by setting true we force this function to keep type distinction on config values 
     785                        $res['config'] = $this->getConfigValues($res['wf_p_id'], true); 
     786                } 
     787                return $res; 
     788        } 
     789 
     790        /** 
     791         * Lists all processes 
     792         * 
     793         * @param int $offset Resultset starting row 
     794         * @param int   $maxRecords Max number of resulting rows 
     795         * @param string $sort_mode Sorting mode 
     796         * @param string $find Search query string 
     797         * @param string $where Condition query string 
     798         * @return bool 
     799         * @access public 
     800         */ 
     801        function list_processes($offset,$maxRecords,$sort_mode,$find='',$where='') 
     802        { 
     803                $sort_mode = $this->convert_sortmode($sort_mode); 
     804                if($find) { 
     805                        $findesc = '%'.$find.'%'; 
     806                        $mid=' where ((wf_name like ?) or (wf_description like ?))'; 
     807                        $bindvars = array($findesc,$findesc); 
     808                } else { 
     809                        $mid=''; 
     810                        $bindvars = array(); 
     811                } 
     812                if($where) { 
     813                        if($mid) { 
     814                                $mid.= " and ($where) "; 
     815                        } else { 
     816                                $mid.= " where ($where) "; 
     817                        } 
     818                } 
     819                $query = 'select * from '.GALAXIA_TABLE_PREFIX."processes $mid"; 
     820                $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."processes $mid"; 
     821                $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode); 
     822                $cant = $this->getOne($query_cant,$bindvars); 
     823                $ret = Array(); 
     824                if (isset($result)) 
     825                { 
     826                        while($res = $result->fetchRow()) 
     827                        { 
     828                                $ret[] = $res; 
     829                        } 
     830                } 
     831                $retval = Array(); 
     832                $retval['data'] = $ret; 
     833                $retval['cant'] = $cant; 
     834                return $retval; 
     835        } 
     836 
    843837  /*! 
    844838   Marks a process as an invalid process 
    845   */ 
    846   function invalidate_process($pid) 
    847   { 
    848     $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?'; 
    849     $this->query($query, array('n',$pid)); 
    850   } 
    851    
    852   /**  
    853    * Removes a process by pId 
    854    *  
    855    * @param int $pId Process id 
    856    * @return bool  
    857    * @access public 
    858839   */ 
    859   function remove_process($pId) 
    860   { 
    861     if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
    862     if (!isset($this->jobManager)) 
    863       $this->jobManager = new JobManager($this->db); 
    864     $this->deactivate_process($pId); 
    865     $name = $this->_get_normalized_name($pId); 
    866      
    867     // start a transaction 
    868     $this->db->StartTrans(); 
    869         $this->jobManager->removeJobsByProcessID($pId); 
    870      
    871     // Remove process activities 
    872     $query = 'select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 
    873     $result = $this->query($query, array($pId)); 
    874     while($res = $result->fetchRow()) { 
    875       //we add a false parameter to prevent the ActivityManager from opening a new transaction 
    876       $this->activity_manager->remove_activity($pId,$res['wf_activity_id'], false); 
    877     } 
    878  
    879     // Remove process roles 
    880     $query = 'delete from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 
    881     $this->query($query, array($pId)); 
    882     $query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 
    883     $this->query($query, array($pId)); 
    884  
    885         // Remove process instances 
    886         $query = 'delete from '.GALAXIA_TABLE_PREFIX.'instances where wf_p_id=?'; 
    887     $this->query($query, array($pId)); 
    888      
    889     // Remove the directory structure 
    890     if (!empty($name) && is_dir(GALAXIA_PROCESSES.SEP.$name)) { 
    891       $this->_remove_directory(GALAXIA_PROCESSES.SEP.$name,true); 
    892     } 
    893     if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES.SEP.$name)) { 
    894       $this->_remove_directory(GALAXIA_TEMPLATES.SEP.$name,true); 
    895     } 
    896      
    897     // Remove configuration data 
    898     $query = 'delete from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 
    899     $this->query($query, array($pId)); 
    900      
    901     // And finally remove the proc 
    902     $query = 'delete from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 
    903     $this->query($query, array($pId)); 
    904     $msg = sprintf(tra('Process %s removed'),$name); 
    905     $this->notify_all(5,$msg); 
    906     $this->error[] = $msg; 
    907      
    908     // perform commit (return true) or Rollback (return false) 
    909     return $this->db->CompleteTrans(); 
    910      
    911   } 
    912    
    913   /** 
    914    * Updates or inserts a new process in the database, $vars is an associative array containing the fields to update or to insert as needed. 
    915    * Configuration options should be in an array associated with the 'config' key 
    916    * this config array should contain 'wf_config_name', 'wf_config_value' and 'wf_config_value_int' keys. 
    917    * $pId is the processI. If $pId is 0 then we create a new process, else we are in edit mode. 
    918    * if $create is true start and end activities will be created (when importing use $create=false) 
    919    *  
    920    * @param int $pId Process id, if 0 then we create a new process, else we are in edit mode 
    921    * @param array &$vars Associative containing the fields to update or to insert as needed 
    922    * @param bool $create If true, start and end activities will be created (when importing use $create=false). 
    923    * @return int Process id 
    924    * @access public 
    925    */ 
    926   function replace_process($pId, &$vars, $create = true) 
    927   { 
    928     if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
    929     $TABLE_NAME = GALAXIA_TABLE_PREFIX.'processes'; 
    930     $now = date("U"); 
    931     $vars['wf_last_modif']=$now; 
    932     $vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 
    933     $config_array = array(); 
    934          
    935     foreach($vars as $key=>$value) 
    936     { 
    937       if ($key=='config') 
    938       { 
    939         $config_array_init =& $value;  
    940         // rebuild a nice config_array with type of config and value 
    941         if( is_array($config_array_init) && count($config_array_init) > 0 ) 
    942         { 
    943                 foreach($config_array_init as $config) 
    944                 { 
    945                   if (isset($config['wf_config_value_int']) && (!($config['wf_config_value_int']==''))) 
    946                   { 
    947                     $config_array[$config['wf_config_name']] = array('int' => $config['wf_config_value_int']); 
    948                   } 
    949                   else 
    950                   { 
    951                     if (isset($config['wf_config_value']))  
    952                     { 
    953                       $config_array[$config['wf_config_name']] = array('text' => $config['wf_config_value']); 
    954                     } 
    955                   } 
    956                 } 
    957         } 
    958         //no need to keep it in the vars array, this array is used in queries 
    959         unset($vars['config']); 
    960       } 
    961       else // not config, it's just process's fields values 
    962       { 
    963         $vars[$key]=addslashes($value); 
    964       } 
    965     } 
    966    
    967     if($pId) { 
    968       // update mode 
    969       $old_proc = $this->get_process($pId); 
    970       $first = true; 
    971       $query ="update $TABLE_NAME set"; 
    972       foreach($vars as $key=>$value) { 
    973         if(!$first) $query.= ','; 
    974         if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 
    975         $query.= " $key=$value "; 
    976         $first = false; 
    977       } 
    978       $query .= " where wf_p_id=$pId "; 
    979       $this->query($query); 
    980        
    981       //set config values 
    982       $this->setConfigValues($pId,$config_array); 
    983        
    984       // Note that if the name is being changed then 
    985       // the directory has to be renamed! 
    986       $oldname = $old_proc['wf_normalized_name']; 
    987       $newname = $vars['wf_normalized_name']; 
    988       if ($newname != $oldname) { 
    989           rename(GALAXIA_PROCESSES.SEP."$oldname",GALAXIA_PROCESSES.SEP."$newname"); 
    990       } 
    991       $msg = sprintf(tra('Process %s has been updated'),$vars['wf_name']);      
    992       $this->notify_all(3,$msg); 
    993       $this->error[] = $msg; 
    994     } else { 
    995       unset($vars['wf_p_id']); 
    996       // insert mode 
    997       $name = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 
    998       $this->_create_directory_structure($name); 
    999       $first = true; 
    1000       $query = "insert into $TABLE_NAME("; 
    1001       foreach(array_keys($vars) as $key) { 
    1002         if(!$first) $query.= ',';  
    1003         $query.= "$key"; 
    1004         $first = false; 
    1005       }  
    1006       $query .=") values("; 
    1007       $first = true; 
    1008       foreach(array_values($vars) as $value) { 
    1009         if(!$first) $query.= ',';  
    1010         if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 
    1011         $query.= "$value"; 
    1012         $first = false; 
    1013       }  
    1014       $query .=")"; 
    1015       $this->query($query); 
    1016       //FIXME: this query seems to be quite sure to get a result, I would prefer something 
    1017       // more sure to get the right result everytime 
    1018       $pId = $this->getOne("select max(wf_p_id) from $TABLE_NAME where wf_last_modif=$now");  
    1019        
    1020       //set config values 
    1021       $this->setConfigValues($pId,$config_array); 
    1022        
    1023       // Now automatically add a start and end activity  
    1024       // unless importing ($create = false) 
    1025       if($create) { 
    1026         $vars1 = Array( 
    1027           'wf_name' => 'start', 
    1028           'wf_description' => 'default start activity', 
    1029           'wf_type' => 'start', 
    1030           'wf_is_interactive' => 'y', 
    1031           'wf_is_autorouted' => 'y' 
    1032         ); 
    1033         $vars2 = Array( 
    1034           'wf_name' => 'end', 
    1035           'wf_description' => 'default end activity', 
    1036           'wf_type' => 'end', 
    1037           'wf_is_interactive' => 'n', 
    1038           'wf_is_autorouted' => 'y' 
    1039         ); 
    1040    
    1041         $this->activity_manager->replace_activity($pId,0,$vars1); 
    1042         $this->activity_manager->replace_activity($pId,0,$vars2); 
    1043       } 
    1044     $msg = sprintf(tra('Process %s has been created'),$vars['wf_name']);      
    1045     $this->notify_all(4,$msg); 
    1046     $this->error[] = $msg; 
    1047     } 
    1048     // Get the id 
    1049     return $pId; 
    1050   } 
    1051     
    1052   /** 
    1053    * Gets the normalized name of a process by pid 
    1054    *  
    1055    * @param int $pId Process id 
    1056    * @access private 
    1057    * @return string  
    1058    */ 
    1059   function _get_normalized_name($pId) 
    1060   { 
    1061     $info = $this->get_process($pId); 
    1062     return $info['wf_normalized_name']; 
    1063   } 
    1064     
    1065   /** 
    1066    * Normalizes a process name 
    1067    *  
    1068    * @param string $name Process name to be normalized 
    1069    * @param string $version Process version 
    1070    * @access private 
    1071    * @return string Process normalized name 
    1072    */ 
    1073   function _normalize_name($name, $version) 
    1074   { 
    1075     $name = $name.'_'.$version; 
    1076     $name = str_replace(" ","_",$name); 
    1077     $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name); 
    1078     return $name; 
    1079   } 
    1080     
    1081   /** 
    1082    * Generates a new minor version number 
    1083    *  
    1084    * @param string $version Current process version 
    1085    * @param bool $minor Generate minor version 
    1086    * @access private 
    1087    * @return string  
    1088    */ 
    1089   function _new_version($version,$minor=true) 
    1090   { 
    1091     $parts = explode('.',$version); 
    1092     if($minor) { 
    1093       $parts[count($parts)-1]++; 
    1094     } else { 
    1095       $parts[0]++; 
    1096       for ($i = 1; $i < count($parts); $i++) { 
    1097         $parts[$i] = 0; 
    1098       } 
    1099     } 
    1100     return implode('.',$parts); 
    1101   } 
    1102     
    1103   /** 
    1104    * Creates directory structure for process 
    1105    *  
    1106    * @param string $name Dir name in process repository 
    1107    * @access private 
    1108    * @return bool  
    1109    */ 
    1110   function _create_directory_structure($name) 
    1111   { 
    1112     $path = GALAXIA_PROCESSES.SEP.$name; 
    1113     if (!file_exists($path)) mkdir($path,0770); 
    1114     $path = GALAXIA_PROCESSES.SEP.$name.SEP."resources"; 
    1115     if (!file_exists($path)) mkdir($path,0770); 
    1116     $path = GALAXIA_PROCESSES.SEP.$name.SEP."graph"; 
    1117     if (!file_exists($path)) mkdir($path,0770); 
    1118     $path = GALAXIA_PROCESSES.SEP.$name.SEP."code"; 
    1119     if (!file_exists($path)) mkdir($path,0770); 
    1120     $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."activities"; 
    1121     if (!file_exists($path)) mkdir($path,0770); 
    1122     $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."templates"; 
    1123     if (!file_exists($path)) mkdir($path,0770); 
    1124     $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."jobs"; 
    1125     if (!file_exists($path)) mkdir($path,0770); 
    1126     $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty"; 
    1127     if (!file_exists($path)) mkdir($path,0770); 
    1128     $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."cache"; 
    1129     if (!file_exists($path)) mkdir($path,0770); 
    1130     $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."compiled"; 
    1131     if (!file_exists($path)) mkdir($path,0770); 
    1132     if (GALAXIA_TEMPLATES) { 
    1133       $path = GALAXIA_TEMPLATES.SEP.$name; 
    1134       if (!file_exists($path)) mkdir($path,0770); 
    1135     } 
    1136     // Create shared file 
    1137     $file = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php"; 
    1138     if (!file_exists($file)) 
    1139     { 
    1140       $fp = fopen(GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php","w"); 
    1141       if (!fp) return false; 
    1142       fwrite($fp,'<'.'?'.'php'."\n".'?'.'>'); 
    1143       fclose($fp); 
    1144     } 
    1145   } 
    1146     
    1147   /** 
    1148    * Removes a directory recursively  
    1149    * 
    1150    * @param string $dir Dir name to be erased 
    1151    * @param bool $rec Recursive mode 
    1152    * @access private 
    1153    * @return void  
    1154    */ 
    1155   function _remove_directory($dir,$rec=false) 
    1156   { 
    1157     // Prevent a disaster 
    1158     if(trim($dir) == SEP || trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates'.SEP) return false; 
    1159     $h = opendir($dir); 
    1160     while(($file = readdir($h)) != false) { 
    1161       if(is_file($dir.SEP.$file)) { 
    1162         @unlink($dir.SEP.$file); 
    1163       } else { 
    1164         if($rec && $file != '.' && $file != '..') { 
    1165           $this->_remove_directory($dir.SEP.$file, true); 
    1166         } 
    1167       } 
    1168     } 
    1169     closedir($h);    
    1170     @rmdir($dir); 
    1171     @unlink($dir); 
    1172   } 
    1173    
    1174   /** 
    1175    * Copies a directory recursively  
    1176    * 
    1177    * @param string $dir1 Dir name to be copied 
    1178    * @param string $dir2 Generated destination dir 
    1179    * @access private 
    1180    * @return void  
    1181    */ 
    1182   function _rec_copy($dir1,$dir2) 
    1183   { 
    1184     @mkdir($dir2,0777); 
    1185     $h = opendir($dir1); 
    1186     while(($file = readdir($h)) !== false) { 
    1187       if(is_file($dir1.SEP.$file)) { 
    1188         copy($dir1.SEP.$file,$dir2.SEP.$file); 
    1189       } else { 
    1190         if($file != '.' && $file != '..') { 
    1191           $this->_rec_copy($dir1.SEP.$file, $dir2.SEP.$file); 
    1192         } 
    1193       } 
    1194     } 
    1195     closedir($h);    
    1196   } 
    1197  
    1198   /** 
    1199    * XML parser start element handler 
    1200    *  
    1201    * @param resource $parser Parser handle 
    1202    * @param string $element XML tag 
    1203    * @param array $attribs XML tag attributes 
    1204    * @access private 
    1205    * @return void  
    1206    */ 
    1207   function _start_element_handler($parser, $element, $attribs) 
    1208   { 
    1209     $aux=Array('name'=>$element, 
    1210                'data'=>'', 
    1211                'parent' => $this->current, 
    1212                'children'=>Array(), 
    1213                'attribs' => $attribs); 
    1214                             
    1215     $i = count($this->tree);            
    1216     $this->tree[$i] = $aux; 
    1217  
    1218     $this->tree[$this->current]['children'][]=$i; 
    1219     $this->current=$i; 
    1220   } 
    1221  
    1222   /** 
    1223    * XML parser end element handler 
    1224    *  
    1225    * @param resource $parser Parser handle 
    1226    * @param string $element XML tag 
    1227    * @param array $attribs XML tag attributes 
    1228    * @access private 
    1229    * @return void  
    1230    */ 
    1231   function _end_element_handler($parser, $element) 
    1232   { 
    1233     //when a tag ends put text 
    1234     $this->tree[$this->current]['data']=$this->buffer;            
    1235     $this->buffer=''; 
    1236     $this->current=$this->tree[$this->current]['parent']; 
    1237   } 
    1238  
    1239   /** 
    1240    * XML parser element data handler 
    1241    *  
    1242    * @param resource $parser Parser handle 
    1243    * @param string $element XML tag 
    1244    * @param string $data XML tag content 
    1245    * @access private 
    1246    * @return void  
    1247    */ 
    1248   function _data_handler($parser, $data) 
    1249   { 
    1250           $this->buffer .= $data; 
    1251   } 
    1252  
    1253   /** 
    1254    * This getConfigValues differs from the Process::getConfigValues because requires only process id. 
    1255    * This method gets the items defined in process_config table for this process, in fact this admin function bypass 
    1256    * the process behaviour and is just showing you the basic content of the table.  
    1257    * All config items are returned as a function result.         
    1258    *  
    1259    * @param int $pId Process id 
    1260    * @param bool $distinct_types If the distinct_type is set the returned array will follow the format: 
    1261    * * 0        =>('wf_config_name'=> 'foo') 
    1262    *            =>('wf_config_value'=>'bar') 
    1263    *            =>('wf_config_vale_int'=>null) 
    1264    * * 1        =>('wf_config_name' => 'toto') 
    1265    *            =>('wf_config_value'=>'') 
    1266    *            =>('wf_config_vale_int'=>15) 
    1267    * if set to false (default) the result array will be (note that this is the default result if having just the $pId): 
    1268    * * 'foo'=>'bar' 
    1269    * * 'toto'=>15 
    1270    * @param bool $askProcessObject If the askProcessObject is set to true (false by default) then the ProcessManager will load a process 
    1271    * object to run directly Process->getConfigValues($config_ask_array) this let you use this ProcessManager 
    1272    * getConfigValues the same way you would use $process->getConfigValues, with initialisation of default values. 
    1273    * you should then call this function this way: $conf_result=$pm->getConfigValues($pId,true,true,$my_conf_array) 
    1274    * @param array $config_array 
    1275    * @access public 
    1276    * @return array  
    1277    */ 
    1278   function getConfigValues($pId, $distinct_types=false, $askProcessObject=false, $config_array=array()) 
    1279   { 
    1280     if (!$askProcessObject) 
    1281     { 
    1282       $query = 'select * from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 
    1283       $result = $this->query($query, array($pId)); 
    1284       $result_array=array(); 
    1285       while($res = $result->fetchRow()) 
    1286       { 
    1287         if ( (!$distinct_types) ) 
    1288         {// we want a simple array 
    1289           if ($res['wf_config_value_int']==null) 
    1290           { 
    1291             $result_array[$res['wf_config_name']] = $res['wf_config_value']; 
    1292             } 
    1293           else 
    1294           { 
    1295             $result_array[$res['wf_config_name']] = $res['wf_config_value_int']; 
    1296           } 
    1297         } 
    1298         else 
    1299         {// build a more complex result array, which is just the table rows 
    1300           $result_array[] = $res; 
    1301         } 
    1302       } 
    1303     } 
    1304     else //we'll load a Process object and let him work for us 
    1305     { 
    1306       //Warning: this means you have to include the Process.php from the API 
    1307       $this->Process = new Process($this->db); 
    1308       $this->Process->getProcess($pId); 
    1309       $result_array = $this->Process->getConfigValues($config_array); 
    1310       unset ($this->Process); 
    1311     } 
    1312     return $result_array; 
    1313   } 
    1314    
    1315   /** 
    1316    * Calls a process object to save his new config values by taking a process Id as first argument and simply call  
    1317    * this process's setConfigValues method. We let the process define the better way to store the data given as second arg. 
    1318    *  
    1319    * @param int $pId Process id 
    1320    * @param array &$config_array 
    1321    * @return void  
    1322    * @access public 
    1323    */ 
    1324   function setConfigValues($pId, &$config_array) 
    1325   { 
    1326     //Warning: this means you have to include the Process.php from the API 
    1327     $this->Process = new Process($this->db); 
    1328     $this->Process->getProcess($pId); 
    1329     $this->Process->setConfigValues($config_array); 
    1330     unset ($this->Process); 
    1331   } 
    1332    
    1333   /** 
    1334    * Gets available agents list 
    1335    *  
    1336    * @return array 
    1337    * @access public 
    1338    */ 
    1339   function get_agents() 
    1340   { 
    1341     return galaxia_get_agents_list(); 
    1342   } 
    1343  
    1344   /** 
    1345    * Gets the view activity id avaible for a given process 
    1346    *  
    1347    * @param int $pId Process Id 
    1348    * @return bool False if no view activity is avaible for the process, return the activity id if there is one 
    1349    * @access public 
    1350    */ 
    1351   function get_process_view_activity($pId) 
    1352   { 
    1353     $mid = 'where gp.wf_p_id=? and ga.wf_type=?'; 
    1354     $bindvars = array($pId,'view'); 
    1355     $query = 'select ga.wf_activity_id 
    1356         from '.GALAXIA_TABLE_PREFIX.'processes gp 
    1357         INNER JOIN '.GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id 
    1358         $mid"; 
    1359     $result = $this->query($query,$bindvars); 
    1360     $ret = Array(); 
    1361     $retval = false; 
    1362     if (!(empty($result))) 
    1363     { 
    1364       while($res = $result->fetchRow())  
    1365       { 
    1366         $retval = $res['wf_activity_id']; 
    1367       } 
    1368     } 
    1369     return $retval; 
    1370   } 
     840        function invalidate_process($pid) 
     841        { 
     842                $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?'; 
     843                $this->query($query, array('n',$pid)); 
     844        } 
     845 
     846        /** 
     847         * Removes a process by pId 
     848         * 
     849         * @param int $pId Process id 
     850         * @return bool 
     851         * @access public 
     852         */ 
     853        function remove_process($pId) 
     854        { 
     855                if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
     856                if (!isset($this->jobManager)) 
     857                        $this->jobManager = new JobManager($this->db); 
     858                $this->deactivate_process($pId); 
     859                $name = $this->_get_normalized_name($pId); 
     860 
     861                // start a transaction 
     862                $this->db->StartTrans(); 
     863                $this->jobManager->removeJobsByProcessID($pId); 
     864 
     865                // Remove process activities 
     866                $query = 'select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 
     867                $result = $this->query($query, array($pId)); 
     868                while($res = $result->fetchRow()) { 
     869                        //we add a false parameter to prevent the ActivityManager from opening a new transaction 
     870                        $this->activity_manager->remove_activity($pId,$res['wf_activity_id'], false); 
     871                } 
     872 
     873                // Remove process roles 
     874                $query = 'delete from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 
     875                $this->query($query, array($pId)); 
     876                $query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 
     877                $this->query($query, array($pId)); 
     878 
     879                // Remove process instances 
     880                $query = 'delete from '.GALAXIA_TABLE_PREFIX.'instances where wf_p_id=?'; 
     881                $this->query($query, array($pId)); 
     882 
     883                // Remove the directory structure 
     884                if (!empty($name) && is_dir(GALAXIA_PROCESSES.SEP.$name)) { 
     885                        $this->_remove_directory(GALAXIA_PROCESSES.SEP.$name,true); 
     886                } 
     887                if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES.SEP.$name)) { 
     888                        $this->_remove_directory(GALAXIA_TEMPLATES.SEP.$name,true); 
     889                } 
     890 
     891                // Remove configuration data 
     892                $query = 'delete from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 
     893                $this->query($query, array($pId)); 
     894 
     895                // And finally remove the proc 
     896                $query = 'delete from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 
     897                $this->query($query, array($pId)); 
     898                $msg = sprintf(tra('Process %s removed'),$name); 
     899                $this->error[] = $msg; 
     900 
     901                // perform commit (return true) or Rollback (return false) 
     902                return $this->db->CompleteTrans(); 
     903 
     904        } 
     905 
     906        /** 
     907         * Updates or inserts a new process in the database, $vars is an associative array containing the fields to update or to insert as needed. 
     908         * Configuration options should be in an array associated with the 'config' key 
     909         * this config array should contain 'wf_config_name', 'wf_config_value' and 'wf_config_value_int' keys. 
     910         * $pId is the processI. If $pId is 0 then we create a new process, else we are in edit mode. 
     911         * if $create is true start and end activities will be created (when importing use $create=false) 
     912         * 
     913         * @param int $pId Process id, if 0 then we create a new process, else we are in edit mode 
     914         * @param array &$vars Associative containing the fields to update or to insert as needed 
     915         * @param bool $create If true, start and end activities will be created (when importing use $create=false). 
     916         * @return int Process id 
     917         * @access public 
     918         */ 
     919        function replace_process($pId, &$vars, $create = true) 
     920        { 
     921                if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db); 
     922                $TABLE_NAME = GALAXIA_TABLE_PREFIX.'processes'; 
     923                $now = date("U"); 
     924                $vars['wf_last_modif']=$now; 
     925                $vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 
     926                $config_array = array(); 
     927 
     928                foreach($vars as $key=>$value) 
     929                { 
     930                        if ($key=='config') 
     931                        { 
     932                                $config_array_init =& $value; 
     933                                // rebuild a nice config_array with type of config and value 
     934                                if( is_array($config_array_init) && count($config_array_init) > 0 ) 
     935                                { 
     936                                        foreach($config_array_init as $config) 
     937                                        { 
     938                                                if (isset($config['wf_config_value_int']) && (!($config['wf_config_value_int']==''))) 
     939                                                { 
     940                                                        $config_array[$config['wf_config_name']] = array('int' => $config['wf_config_value_int']); 
     941                                                } 
     942                                                else 
     943                                                { 
     944                                                        if (isset($config['wf_config_value'])) 
     945                                                        { 
     946                                                                $config_array[$config['wf_config_name']] = array('text' => $config['wf_config_value']); 
     947                                                        } 
     948                                                } 
     949                                        } 
     950                                } 
     951                                //no need to keep it in the vars array, this array is used in queries 
     952                                unset($vars['config']); 
     953                        } 
     954                        else // not config, it's just process's fields values 
     955                        { 
     956                                $vars[$key]=addslashes($value); 
     957                        } 
     958                } 
     959 
     960                if($pId) { 
     961                        // update mode 
     962                        $old_proc = $this->get_process($pId); 
     963                        $first = true; 
     964                        $query ="update $TABLE_NAME set"; 
     965                        foreach($vars as $key=>$value) { 
     966                                if(!$first) $query.= ','; 
     967                                if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 
     968                                $query.= " $key=$value "; 
     969                                $first = false; 
     970                        } 
     971                        $query .= " where wf_p_id=$pId "; 
     972                        $this->query($query); 
     973 
     974                        //set config values 
     975                        $this->setConfigValues($pId,$config_array); 
     976 
     977                        // Note that if the name is being changed then 
     978                        // the directory has to be renamed! 
     979                        $oldname = $old_proc['wf_normalized_name']; 
     980                        $newname = $vars['wf_normalized_name']; 
     981                        if ($newname != $oldname) { 
     982                                rename(GALAXIA_PROCESSES.SEP."$oldname",GALAXIA_PROCESSES.SEP."$newname"); 
     983                        } 
     984                        $msg = sprintf(tra('Process %s has been updated'),$vars['wf_name']); 
     985                        $this->error[] = $msg; 
     986                } else { 
     987                        unset($vars['wf_p_id']); 
     988                        // insert mode 
     989                        $name = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 
     990                        $this->_create_directory_structure($name); 
     991                        $first = true; 
     992                        $query = "insert into $TABLE_NAME("; 
     993                        foreach(array_keys($vars) as $key) { 
     994                                if(!$first) $query.= ','; 
     995                                $query.= "$key"; 
     996                                $first = false; 
     997                        } 
     998                        $query .=") values("; 
     999                        $first = true; 
     1000                        foreach(array_values($vars) as $value) { 
     1001                                if(!$first) $query.= ','; 
     1002                                if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 
     1003                                $query.= "$value"; 
     1004                                $first = false; 
     1005                        } 
     1006                        $query .=")"; 
     1007                        $this->query($query); 
     1008                        //FIXME: this query seems to be quite sure to get a result, I would prefer something 
     1009                        // more sure to get the right result everytime 
     1010                        $pId = $this->getOne("select max(wf_p_id) from $TABLE_NAME where wf_last_modif=$now"); 
     1011 
     1012                        //set config values 
     1013                        $this->setConfigValues($pId,$config_array); 
     1014 
     1015                        // Now automatically add a start and end activity 
     1016                        // unless importing ($create = false) 
     1017                        if($create) { 
     1018                                $vars1 = Array( 
     1019                                        'wf_name' => 'start', 
     1020                                        'wf_description' => 'default start activity', 
     1021                                        'wf_type' => 'start', 
     1022                                        'wf_is_interactive' => 'y', 
     1023                                        'wf_is_autorouted' => 'y' 
     1024                                ); 
     1025                                $vars2 = Array( 
     1026                                        'wf_name' => 'end', 
     1027                                        'wf_description' => 'default end activity', 
     1028                                        'wf_type' => 'end', 
     1029                                        'wf_is_interactive' => 'n', 
     1030                                        'wf_is_autorouted' => 'y' 
     1031                                ); 
     1032 
     1033                                $this->activity_manager->replace_activity($pId,0,$vars1); 
     1034                                $this->activity_manager->replace_activity($pId,0,$vars2); 
     1035                        } 
     1036                        $msg = sprintf(tra('Process %s has been created'),$vars['wf_name']); 
     1037                        $this->error[] = $msg; 
     1038                } 
     1039                // Get the id 
     1040                return $pId; 
     1041        } 
     1042 
     1043        /** 
     1044         * Gets the normalized name of a process by pid 
     1045         * 
     1046         * @param int $pId Process id 
     1047         * @access private 
     1048         * @return string 
     1049         */ 
     1050        function _get_normalized_name($pId) 
     1051        { 
     1052                $info = $this->get_process($pId); 
     1053                return $info['wf_normalized_name']; 
     1054        } 
     1055 
     1056        /** 
     1057         * Normalizes a process name 
     1058         * 
     1059         * @param string $name Process name to be normalized 
     1060         * @param string $version Process version 
     1061         * @access private 
     1062         * @return string Process normalized name 
     1063         */ 
     1064        function _normalize_name($name, $version) 
     1065        { 
     1066                $name = $name.'_'.$version; 
     1067                $name = str_replace(" ","_",$name); 
     1068                $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name); 
     1069                return $name; 
     1070        } 
     1071 
     1072        /** 
     1073         * Generates a new minor version number 
     1074         * 
     1075         * @param string $version Current process version 
     1076         * @param bool $minor Generate minor version 
     1077         * @access private 
     1078         * @return string 
     1079         */ 
     1080        function _new_version($version,$minor=true) 
     1081        { 
     1082                $parts = explode('.',$version); 
     1083                if($minor) { 
     1084                        $parts[count($parts)-1]++; 
     1085                } else { 
     1086                        $parts[0]++; 
     1087                        for ($i = 1; $i < count($parts); $i++) { 
     1088                                $parts[$i] = 0; 
     1089                        } 
     1090                } 
     1091                return implode('.',$parts); 
     1092        } 
     1093 
     1094        /** 
     1095         * Creates directory structure for process 
     1096         * 
     1097         * @param string $name Dir name in process repository 
     1098         * @access private 
     1099         * @return bool 
     1100         */ 
     1101        function _create_directory_structure($name) 
     1102        { 
     1103                $path = GALAXIA_PROCESSES.SEP.$name; 
     1104                if (!file_exists($path)) mkdir($path,0770); 
     1105                $path = GALAXIA_PROCESSES.SEP.$name.SEP."resources"; 
     1106                if (!file_exists($path)) mkdir($path,0770); 
     1107                $path = GALAXIA_PROCESSES.SEP.$name.SEP."graph"; 
     1108                if (!file_exists($path)) mkdir($path,0770); 
     1109                $path = GALAXIA_PROCESSES.SEP.$name.SEP."code"; 
     1110                if (!file_exists($path)) mkdir($path,0770); 
     1111                $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."activities"; 
     1112                if (!file_exists($path)) mkdir($path,0770); 
     1113                $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."templates"; 
     1114                if (!file_exists($path)) mkdir($path,0770); 
     1115                $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."jobs"; 
     1116                if (!file_exists($path)) mkdir($path,0770); 
     1117                $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty"; 
     1118                if (!file_exists($path)) mkdir($path,0770); 
     1119                $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."cache"; 
     1120                if (!file_exists($path)) mkdir($path,0770); 
     1121                $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."compiled"; 
     1122                if (!file_exists($path)) mkdir($path,0770); 
     1123                if (GALAXIA_TEMPLATES) { 
     1124                        $path = GALAXIA_TEMPLATES.SEP.$name; 
     1125                        if (!file_exists($path)) mkdir($path,0770); 
     1126                } 
     1127                // Create shared file 
     1128                $file = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php"; 
     1129                if (!file_exists($file)) 
     1130                { 
     1131                        $fp = fopen(GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php","w"); 
     1132                        if (!fp) return false; 
     1133                        fwrite($fp,'<'.'?'.'php'."\n".'?'.'>'); 
     1134                        fclose($fp); 
     1135                } 
     1136        } 
     1137 
     1138        /** 
     1139         * Removes a directory recursively 
     1140         * 
     1141         * @param string $dir Dir name to be erased 
     1142         * @param bool $rec Recursive mode 
     1143         * @access private 
     1144         * @return void 
     1145         */ 
     1146        function _remove_directory($dir,$rec=false) 
     1147        { 
     1148                // Prevent a disaster 
     1149                if(trim($dir) == SEP || trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates'.SEP) return false; 
     1150                $h = opendir($dir); 
     1151                while(($file = readdir($h)) != false) { 
     1152                        if(is_file($dir.SEP.$file)) { 
     1153                                @unlink($dir.SEP.$file); 
     1154                        } else { 
     1155                                if($rec && $file != '.' && $file != '..') { 
     1156                                        $this->_remove_directory($dir.SEP.$file, true); 
     1157                                } 
     1158                        } 
     1159                } 
     1160                closedir($h); 
     1161                @rmdir($dir); 
     1162                @unlink($dir); 
     1163        } 
     1164 
     1165        /** 
     1166         * Copies a directory recursively 
     1167         * 
     1168         * @param string $dir1 Dir name to be copied 
     1169         * @param string $dir2 Generated destination dir 
     1170         * @access private 
     1171         * @return void 
     1172         */ 
     1173        function _rec_copy($dir1,$dir2) 
     1174        { 
     1175                @mkdir($dir2,0777); 
     1176                $h = opendir($dir1); 
     1177                while(($file = readdir($h)) !== false) { 
     1178                        if(is_file($dir1.SEP.$file)) { 
     1179                                copy($dir1.SEP.$file,$dir2.SEP.$file); 
     1180                        } else { 
     1181                                if($file != '.' && $file != '..') { 
     1182                                        $this->_rec_copy($dir1.SEP.$file, $dir2.SEP.$file); 
     1183                                } 
     1184                        } 
     1185                } 
     1186                closedir($h); 
     1187        } 
     1188 
     1189        /** 
     1190         * XML parser start element handler 
     1191         * 
     1192         * @param resource $parser Parser handle 
     1193         * @param string $element XML tag 
     1194         * @param array $attribs XML tag attributes 
     1195         * @access private 
     1196         * @return void 
     1197         */ 
     1198        function _start_element_handler($parser, $element, $attribs) 
     1199        { 
     1200                $aux=Array('name'=>$element, 
     1201                        'data'=>'', 
     1202                        'parent' => $this->current, 
     1203                        'children'=>Array(), 
     1204                        'attribs' => $attribs); 
     1205 
     1206                $i = count($this->tree); 
     1207                $this->tree[$i] = $aux; 
     1208 
     1209                $this->tree[$this->current]['children'][]=$i; 
     1210                $this->current=$i; 
     1211        } 
     1212 
     1213        /** 
     1214         * XML parser end element handler 
     1215         * 
     1216         * @param resource $parser Parser handle 
     1217         * @param string $element XML tag 
     1218         * @param array $attribs XML tag attributes 
     1219         * @access private 
     1220         * @return void 
     1221         */ 
     1222        function _end_element_handler($parser, $element) 
     1223        { 
     1224                //when a tag ends put text 
     1225                $this->tree[$this->current]['data']=$this->buffer; 
     1226                $this->buffer=''; 
     1227                $this->current=$this->tree[$this->current]['parent']; 
     1228        } 
     1229 
     1230        /** 
     1231         * XML parser element data handler 
     1232         * 
     1233         * @param resource $parser Parser handle 
     1234         * @param string $element XML tag 
     1235         * @param string $data XML tag content 
     1236         * @access private 
     1237         * @return void 
     1238         */ 
     1239        function _data_handler($parser, $data) 
     1240        { 
     1241                $this->buffer .= $data; 
     1242        } 
     1243 
     1244        /** 
     1245         * This getConfigValues differs from the Process::getConfigValues because requires only process id. 
     1246         * This method gets the items defined in process_config table for this process, in fact this admin function bypass 
     1247         * the process behaviour and is just showing you the basic content of the table. 
     1248         * All config items are returned as a function result. 
     1249         * 
     1250         * @param int $pId Process id 
     1251         * @param bool $distinct_types If the distinct_type is set the returned array will follow the format: 
     1252         * * 0  =>('wf_config_name'=> 'foo') 
     1253         *              =>('wf_config_value'=>'bar') 
     1254         *              =>('wf_config_vale_int'=>null) 
     1255         * * 1  =>('wf_config_name' => 'toto') 
     1256         *              =>('wf_config_value'=>'') 
     1257         *              =>('wf_config_vale_int'=>15) 
     1258         * if set to false (default) the result array will be (note that this is the default result if having just the $pId): 
     1259         * * 'foo'=>'bar' 
     1260         * * 'toto'=>15 
     1261         * @param bool $askProcessObject If the askProcessObject is set to true (false by default) then the ProcessManager will load a process 
     1262         * object to run directly Process->getConfigValues($config_ask_array) this let you use this ProcessManager 
     1263         * getConfigValues the same way you would use $process->getConfigValues, with initialisation of default values. 
     1264         * you should then call this function this way: $conf_result=$pm->getConfigValues($pId,true,true,$my_conf_array) 
     1265         * @param array $config_array 
     1266         * @access public 
     1267         * @return array 
     1268         */ 
     1269        function getConfigValues($pId, $distinct_types=false, $askProcessObject=false, $config_array=array()) 
     1270        { 
     1271                if (!$askProcessObject) 
     1272                { 
     1273                        $query = 'select * from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 
     1274                        $result = $this->query($query, array($pId)); 
     1275                        $result_array=array(); 
     1276                        while($res = $result->fetchRow()) 
     1277                        { 
     1278                                if ( (!$distinct_types) ) 
     1279                                {// we want a simple array 
     1280                                        if ($res['wf_config_value_int']==null) 
     1281                                        { 
     1282                                                $result_array[$res['wf_config_name']] = $res['wf_config_value']; 
     1283                                        } 
     1284                                        else 
     1285                                        { 
     1286                                                $result_array[$res['wf_config_name']] = $res['wf_config_value_int']; 
     1287                                        } 
     1288                                } 
     1289                                else 
     1290                                {// build a more complex result array, which is just the table rows 
     1291                                        $result_array[] = $res; 
     1292                                } 
     1293                        } 
     1294                } 
     1295                else //we'll load a Process object and let him work for us 
     1296                { 
     1297                        //Warning: this means you have to include the Process.php from the API 
     1298                        $this->Process = new Process($this->db); 
     1299                        $this->Process->getProcess($pId); 
     1300                        $result_array = $this->Process->getConfigValues($config_array); 
     1301                        unset ($this->Process); 
     1302                } 
     1303                return $result_array; 
     1304        } 
     1305 
     1306        /** 
     1307         * Calls a process object to save his new config values by taking a process Id as first argument and simply call 
     1308         * this process's setConfigValues method. We let the process define the better way to store the data given as second arg. 
     1309         * 
     1310         * @param int $pId Process id 
     1311         * @param array &$config_array 
     1312         * @return void 
     1313         * @access public 
     1314         */ 
     1315        function setConfigValues($pId, &$config_array) 
     1316        { 
     1317                //Warning: this means you have to include the Process.php from the API 
     1318                $this->Process = new Process($this->db); 
     1319                $this->Process->getProcess($pId); 
     1320                $this->Process->setConfigValues($config_array); 
     1321                unset ($this->Process); 
     1322        } 
     1323 
     1324        /** 
     1325         * Gets available agents list 
     1326         * 
     1327         * @return array 
     1328         * @access public 
     1329         */ 
     1330        function get_agents() 
     1331        { 
     1332                return galaxia_get_agents_list(); 
     1333        } 
     1334 
     1335        /** 
     1336         * Gets the view activity id avaible for a given process 
     1337         * 
     1338         * @param int $pId Process Id 
     1339         * @return bool False if no view activity is avaible for the process, return the activity id if there is one 
     1340         * @access public 
     1341         */ 
     1342        function get_process_view_activity($pId) 
     1343        { 
     1344                $mid = 'where gp.wf_p_id=? and ga.wf_type=?'; 
     1345                $bindvars = array($pId,'view'); 
     1346                $query = 'select ga.wf_activity_id 
     1347                        from '.GALAXIA_TABLE_PREFIX.'processes gp 
     1348                        INNER JOIN '.GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id 
     1349                        $mid"; 
     1350                $result = $this->query($query,$bindvars); 
     1351                $ret = Array(); 
     1352                $retval = false; 
     1353                if (!(empty($result))) 
     1354                { 
     1355                        while($res = $result->fetchRow()) 
     1356                        { 
     1357                                $retval = $res['wf_activity_id']; 
     1358                        } 
     1359                } 
     1360                return $retval; 
     1361        } 
    13711362 
    13721363} 
  • sandbox/workflow/2.0/inc/engine/src/common/Base.php

    r795 r1263  
    11<?php 
    2 require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Observable.php'); 
    32/** 
    43 * This class is derived by all the API classes so they get the 
    54 * database connection, database methods and the Observable interface 
    6  *  
     5 * 
    76 * @package Galaxia 
    8  * @license http://www.gnu.org/copyleft/gpl.html GPL  
     7 * @license http://www.gnu.org/copyleft/gpl.html GPL 
    98 */ 
    10 class Base extends Observable { 
     9class Base { 
    1110        /** 
    1211         * @var object $db Database abstraction object used to access the database 
     
    1716         * @var int     $num_queries Debugging var 
    1817         * @access private 
    19          */      
     18         */ 
    2019        var $num_queries = 0; 
    2120        /** 
    2221         * @var int     $num_queries_total Debugging var 
    2322         * @access private 
    24          */      
     23         */ 
    2524        var $num_queries_total = 0; 
    2625        /** 
    2726         * @var array  $error Error messages 
    2827         * @access public 
    29          */      
     28         */ 
    3029        var $error= Array(); 
    3130        /** 
     
    3938         */ 
    4039        var $child_name = 'Base'; 
    41    
     40 
    4241  /** 
    4342   * Constructor receiving a database abstraction object 
     
    7271   * Always call this function after failed operations on a workflow object to obtain messages 
    7372   * 
    74    * @param bool $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter  
     73   * @param bool $as_array if true the result will be send as an array of errors or an empty array. Else, if you do not give any parameter 
    7574   * or give a false parameter you will obtain a single string which can be empty or will contain error messages with <br /> html tags 
    7675   * @param bool $debug is false by default, if true you wil obtain more messages 
    7776   * @param string $prefix string appended to the debug message 
    7877   * @return mixed Error and debug messages or an array of theses messages and empty the error messages 
    79    * @access public   
     78   * @access public 
    8079   */ 
    81   function get_error($as_array=false, $debug=false, $prefix='')  
     80  function get_error($as_array=false, $debug=false, $prefix='') 
    8281  { 
    8382    //collect errors from used objects 
     
    9695  /** 
    9796   * Gets warnings recorded by this object 
    98    *  
    99    * @param bool $as_array if true the result will be send as an array of warnings or an empty array. Else, if you do not give any parameter  
     97   * 
     98   * @param bool $as_array if true the result will be send as an array of warnings or an empty array. Else, if you do not give any parameter 
    10099   * or give a false parameter you will obtain a single string which can be empty or will contain warning messages with <br /> html tags 
    101100   * @return mixed Warning messages or an array of theses messages and empty the warning messages 
    102    * @access public   
     101   * @access public 
    103102   */ 
    104   function get_warning($as_array=false)  
     103  function get_warning($as_array=false) 
    105104  { 
    106105    if ($as_array) 
     
    118117   * Collect errors from all linked objects which could have been used by this object 
    119118   * Each child class should instantiate this function with her linked objetcs, calling get_error(true) 
    120    *  
     119   * 
    121120   * @param bool $debug is false by default, if true debug messages can be added to 'normal' messages 
    122121   * @param string $prefix is a string appended to the debug message 
    123122   * @abstract 
    124123   * @access public 
    125    * @return void  
     124   * @return void 
    126125   */ 
    127126  function collect_errors($debug=false, $prefix = '') 
     
    134133        } 
    135134  } 
    136          
     135 
    137136        /** 
    138137         * Performs a query on the AdoDB database object 
    139          *  
     138         * 
    140139         * @param string $query sql query, parameters should be replaced with ? 
    141140         * @param array $values array containing the parameters (going in the ?), use it to avoid security problems. If 
     
    196195 
    197196        /** 
    198          * @see Base::query  
     197         * @see Base::query 
    199198         * @param string $query sql query, parameters should be replaced with ? 
    200199     * @param array $values array containing the parameters (going in the ?), use it to avoid security problems 
     
    224223                if (!$result && $reporterrors ) 
    225224                        $this->sql_error($query, $clean_values, $result); 
    226                 if (!!$result)  
     225                if (!!$result) 
    227226                { 
    228227                        $res = $result->fetchRow(); 
     
    241240        /** 
    242241         * Throws error warnings 
    243          *  
     242         * 
    244243         * @param string $query 
    245244         * @param array $values 
    246245         * @param mixed $result 
    247246         * @access public 
    248          * @return void  
     247         * @return void 
    249248         */ 
    250249        function sql_error($query, $values, $result) { 
     
    252251                // DO NOT DIE, if transactions are there, they will do things in a better way 
    253252        } 
    254          
     253 
    255254        /** 
    256255         * Clean the data before it is recorded on the database 
    257          *  
     256         * 
    258257         * @param $value is a data we want to be stored in the database. 
    259          * If it is an array we'll make a serialize and then an base64_encode  
     258         * If it is an array we'll make a serialize and then an base64_encode 
    260259         * (you'll have to make an unserialize(base64_decode()) 
    261260         * If it is not an array we make an htmlspecialchars() on it 
     
    292291        /** 
    293292         * Supports DB abstraction 
    294          *  
     293         * 
    295294         * @param string &$query 
    296          * @return void  
     295         * @return void 
    297296         * @access public 
    298297         */ 
     
    302301                case "oci8": 
    303302                        $query = preg_replace("/`/", "\"", $query); 
    304                         // convert bind variables - adodb does not do that  
     303                        // convert bind variables - adodb does not do that 
    305304                        $qe = explode("?", $query); 
    306305                        $query = ''; 
     
    318317        /** 
    319318         * Supports DB abstraction 
    320          *  
     319         * 
    321320         * @param string $sort_mode 
    322          * @return string  
     321         * @return string 
    323322         * @access public 
    324323         */ 
     
    330329        /** 
    331330         * Supports DB abstraction 
    332          *  
    333          * @return mixed  
     331         * 
     332         * @return mixed 
    334333         * @access public 
    335334         */ 
Note: See TracChangeset for help on using the changeset viewer.