mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-08 09:04:53 +01:00
Galaxia workflow api port for egroupware
This commit is contained in:
parent
6322ce9832
commit
52a3cae790
3
phpgwapi/inc/galaxia_workflow/compiler/_shared_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/_shared_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code shared by all activities (pos)
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/_shared_pre.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/_shared_pre.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code shared by all the activities (pre)
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/activity_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/activity_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after an activity
|
||||
?>
|
20
phpgwapi/inc/galaxia_workflow/compiler/activity_pre.php
Normal file
20
phpgwapi/inc/galaxia_workflow/compiler/activity_pre.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//Code to be executed before an activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId)) {
|
||||
// This activity needs an instance to be passed to
|
||||
// be started, so get the instance into $instance.
|
||||
if(isset($_REQUEST['iid'])) {
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// defined in lib/Galaxia/config.php
|
||||
galaxia_show_error("No instance indicated");
|
||||
die;
|
||||
}
|
||||
}
|
||||
// Set the current user for this activity
|
||||
if(isset($user) && !empty($instance->instanceId) && !empty($activity->activityId)) {
|
||||
$instance->setActivityUser($activity->activityId,$user);
|
||||
}
|
||||
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/end_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/end_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after the end activity
|
||||
?>
|
20
phpgwapi/inc/galaxia_workflow/compiler/end_pre.php
Normal file
20
phpgwapi/inc/galaxia_workflow/compiler/end_pre.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//Code to be executed before the end activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId)) {
|
||||
// This activity needs an instance to be passed to
|
||||
// be started, so get the instance into $instance.
|
||||
if(isset($_REQUEST['iid'])) {
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// defined in lib/Galaxia/config.php
|
||||
galaxia_show_error("No instance indicated");
|
||||
die;
|
||||
}
|
||||
}
|
||||
// Set the current user for this activity
|
||||
if(isset($user) && !empty($instance->instanceId) && !empty($activity->activityId)) {
|
||||
$instance->setActivityUser($activity->activityId,$user);
|
||||
}
|
||||
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/join_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/join_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after a join activity
|
||||
?>
|
20
phpgwapi/inc/galaxia_workflow/compiler/join_pre.php
Normal file
20
phpgwapi/inc/galaxia_workflow/compiler/join_pre.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//Code to be executed before a join activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId)) {
|
||||
// This activity needs an instance to be passed to
|
||||
// be started, so get the instance into $instance.
|
||||
if(isset($_REQUEST['iid'])) {
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// defined in lib/Galaxia/config.php
|
||||
galaxia_show_error("No instance indicated");
|
||||
die;
|
||||
}
|
||||
}
|
||||
// Set the current user for this activity
|
||||
if(isset($user) && !empty($instance->instanceId) && !empty($activity->activityId)) {
|
||||
$instance->setActivityUser($activity->activityId,$user);
|
||||
}
|
||||
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/split_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/split_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after a split activity
|
||||
?>
|
20
phpgwapi/inc/galaxia_workflow/compiler/split_pre.php
Normal file
20
phpgwapi/inc/galaxia_workflow/compiler/split_pre.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//Code to be executed before a split activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId)) {
|
||||
// This activity needs an instance to be passed to
|
||||
// be started, so get the instance into $instance.
|
||||
if(isset($_REQUEST['iid'])) {
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// defined in lib/Galaxia/config.php
|
||||
galaxia_show_error("No instance indicated");
|
||||
die;
|
||||
}
|
||||
}
|
||||
// Set the current user for this activity
|
||||
if(isset($user) && !empty($instance->instanceId) && !empty($activity->activityId)) {
|
||||
$instance->setActivityUser($activity->activityId,$user);
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after a standalone activity
|
||||
?>
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed before a standalone activity
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/start_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/start_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after a start activity
|
||||
?>
|
11
phpgwapi/inc/galaxia_workflow/compiler/start_pre.php
Normal file
11
phpgwapi/inc/galaxia_workflow/compiler/start_pre.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
//Code to be executed before a start activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId) && isset($_REQUEST['iid'])) {
|
||||
// in case we're looping back to a start activity, we need to retrieve the instance
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// otherwise we'll create an instance when this activity is completed
|
||||
}
|
||||
|
||||
?>
|
3
phpgwapi/inc/galaxia_workflow/compiler/switch_pos.php
Normal file
3
phpgwapi/inc/galaxia_workflow/compiler/switch_pos.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
//Code to be executed after a switch activity
|
||||
?>
|
20
phpgwapi/inc/galaxia_workflow/compiler/switch_pre.php
Normal file
20
phpgwapi/inc/galaxia_workflow/compiler/switch_pre.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
//Code to be executed before a switch activity
|
||||
// If we didn't retrieve the instance before
|
||||
if(empty($instance->instanceId)) {
|
||||
// This activity needs an instance to be passed to
|
||||
// be started, so get the instance into $instance.
|
||||
if(isset($_REQUEST['iid'])) {
|
||||
$instance->getInstance($_REQUEST['iid']);
|
||||
} else {
|
||||
// defined in lib/Galaxia/config.php
|
||||
galaxia_show_error("No instance indicated");
|
||||
die;
|
||||
}
|
||||
}
|
||||
// Set the current user for this activity
|
||||
if(isset($user) && !empty($instance->instanceId) && !empty($activity->activityId)) {
|
||||
$instance->setActivityUser($activity->activityId,$user);
|
||||
}
|
||||
|
||||
?>
|
125
phpgwapi/inc/galaxia_workflow/config.egw.inc.php
Normal file
125
phpgwapi/inc/galaxia_workflow/config.egw.inc.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Configuration of the Galaxia Workflow Engine for E-Groupware
|
||||
*/
|
||||
|
||||
// Common prefix used for all database table names, e.g. galaxia_
|
||||
if (!defined('GALAXIA_TABLE_PREFIX')) {
|
||||
define('GALAXIA_TABLE_PREFIX', 'egw_wf_');
|
||||
}
|
||||
|
||||
// Directory containing the Galaxia library, e.g. lib/Galaxia
|
||||
if (!defined('GALAXIA_LIBRARY')) {
|
||||
define('GALAXIA_LIBRARY', dirname(__FILE__));
|
||||
}
|
||||
|
||||
// filesystem Operations
|
||||
$GLOBALS['phpgw']->vfs = createobject('phpgwapi.vfs');
|
||||
|
||||
// check if basedir exists
|
||||
$test=$GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
|
||||
if($test[mime_type]!='Directory')
|
||||
{
|
||||
die(lang('Base directory does not exist, please ask adminstrator to check the global configuration'));
|
||||
}
|
||||
|
||||
// check if /workflow exists
|
||||
$test = @$GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/workflow', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
|
||||
if($test[mime_type]!='Directory')
|
||||
{
|
||||
// if not, create it
|
||||
$GLOBALS['phpgw']->vfs->override_acl = 1;
|
||||
$GLOBALS['phpgw']->vfs->mkdir(array(
|
||||
'string' => '/workflow',
|
||||
'relatives' => array(RELATIVE_NONE)
|
||||
));
|
||||
$GLOBALS['phpgw']->vfs->override_acl = 0;
|
||||
|
||||
// test one more time
|
||||
$test = $GLOBALS['phpgw']->vfs->get_real_info(array('string' => '/workflow', 'relatives' => array(RELATIVE_NONE), 'relative' => False));
|
||||
if($test[mime_type]!='Directory')
|
||||
{
|
||||
die(lang('/workflow directory does not exist and could not be created, please ask adminstrator to check the global configuration'));
|
||||
}
|
||||
}
|
||||
|
||||
// Directory where the Galaxia processes will be stored, e.g. lib/Galaxia/processes
|
||||
if (!defined('GALAXIA_PROCESSES'))
|
||||
{
|
||||
// Note: this directory must be writeable by the webserver !
|
||||
define('GALAXIA_PROCESSES', $GLOBALS['phpgw']->vfs->basedir.SEP.'workflow');
|
||||
}
|
||||
|
||||
// Directory where a *copy* of the Galaxia activity templates will be stored, e.g. templates
|
||||
// Define as '' if you don't want to copy templates elsewhere
|
||||
if (!defined('GALAXIA_TEMPLATES')) {
|
||||
// Note: this directory must be writeable by the webserver !
|
||||
define('GALAXIA_TEMPLATES', '');
|
||||
}
|
||||
|
||||
// Default header to be added to new activity templates
|
||||
if (!defined('GALAXIA_TEMPLATE_HEADER')) {
|
||||
define('GALAXIA_TEMPLATE_HEADER', '');
|
||||
}
|
||||
|
||||
// File where the ProcessManager logs for Galaxia will be saved, e.g. lib/Galaxia/log/pm.log
|
||||
// Define as '' if you don't want to use logging
|
||||
if (!defined('GALAXIA_LOGFILE')) {
|
||||
// Note: this file must be writeable by the webserver !
|
||||
//define('GALAXIA_LOGFILE', GALAXIA_LIBRARY . '/log/pm.log');
|
||||
define('GALAXIA_LOGFILE', '');
|
||||
}
|
||||
|
||||
// Directory containing the GraphViz 'dot' and 'neato' programs, in case
|
||||
// your webserver can't find them via its PATH environment variable
|
||||
if (!defined('GRAPHVIZ_BIN_DIR')) {
|
||||
define('GRAPHVIZ_BIN_DIR', '');
|
||||
//define('GRAPHVIZ_BIN_DIR', 'd:/wintools/ATT/GraphViz/bin');
|
||||
}
|
||||
|
||||
// language function
|
||||
function tra($msg, $m1='', $m2='', $m3='', $m4='')
|
||||
{
|
||||
return lang($msg, $m1, $m2, $m3, $m4);
|
||||
}
|
||||
|
||||
// Specify how error messages should be shown
|
||||
if (!function_exists('galaxia_show_error')) {
|
||||
function galaxia_show_error($msg)
|
||||
{
|
||||
die("Error: $msg");
|
||||
}
|
||||
}
|
||||
|
||||
// Specify how to execute a non-interactive activity (for use in src/API/Instance.php)
|
||||
if (!function_exists('galaxia_execute_activity')) {
|
||||
function galaxia_execute_activity($activityId = 0, $iid = 0, $auto = 1)
|
||||
{
|
||||
// Now execute the code for the activity but we are in a method!
|
||||
// so just use an fopen with http mode
|
||||
|
||||
/* $parsed = parse_url($_SERVER["REQUEST_URI"]);
|
||||
$URI = 'http'.((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$parsed["path"];
|
||||
$parts = explode('/',$URI);
|
||||
$parts[count($parts)-1] = "index.php?sessionid=".SID."&menuaction=workflow.run_activity&activityId=$activityId&iid=$iid&auto=$auto";
|
||||
$URI = implode('/',$parts);
|
||||
|
||||
$fp = fopen($URI,"r");
|
||||
$data = '';
|
||||
if (!$fp) {
|
||||
trigger_error(tra("Fatal error: cannot execute automatic activity $activityId"),E_USER_WARNING);
|
||||
die;
|
||||
}
|
||||
while (!feof($fp)) {
|
||||
$data.=fread($fp,8192);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
*/
|
||||
$run_activity = CreateObject('workflow.run_activity.go');
|
||||
$data = $run_activity->go($activityId, $iid, $auto);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
218
phpgwapi/inc/galaxia_workflow/src/API/BaseActivity.php
Normal file
218
phpgwapi/inc/galaxia_workflow/src/API/BaseActivity.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
include_once (GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Abstract class representing activities
|
||||
//! An abstract class representing activities
|
||||
/*!
|
||||
This class represents activities, and must be derived for
|
||||
each activity type supported in the system. Derived activities extending this
|
||||
class can be found in the activities subfolder.
|
||||
This class is observable.
|
||||
*/
|
||||
class BaseActivity extends Base {
|
||||
var $name;
|
||||
var $normalizedName;
|
||||
var $description;
|
||||
var $isInteractive;
|
||||
var $isAutoRouted;
|
||||
var $roles=Array();
|
||||
var $outbound=Array();
|
||||
var $inbound=Array();
|
||||
var $pId;
|
||||
var $activityId;
|
||||
var $type;
|
||||
|
||||
function setDb($db)
|
||||
{
|
||||
$this->db=$db;
|
||||
}
|
||||
|
||||
function BaseActivity($db)
|
||||
{
|
||||
$this->db=$db;
|
||||
$this->type='base';
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Factory method returning an activity of the desired type
|
||||
loading the information from the database.
|
||||
*/
|
||||
function getActivity($activityId)
|
||||
{
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?";
|
||||
$result = $this->query($query,array($activityId));
|
||||
if(!$result->numRows()) return false;
|
||||
$res = $result->fetchRow();
|
||||
switch($res['type']) {
|
||||
case 'start':
|
||||
$act = new Start($this->db);
|
||||
break;
|
||||
case 'end':
|
||||
$act = new End($this->db);
|
||||
break;
|
||||
case 'join':
|
||||
$act = new Join($this->db);
|
||||
break;
|
||||
case 'split':
|
||||
$act = new Split($this->db);
|
||||
break;
|
||||
case 'standalone':
|
||||
$act = new Standalone($this->db);
|
||||
break;
|
||||
case 'switch':
|
||||
$act = new SwitchActivity($this->db);
|
||||
break;
|
||||
case 'activity':
|
||||
$act = new Activity($this->db);
|
||||
break;
|
||||
default:
|
||||
trigger_error('Unknown activity type:'.$res['type'],E_USER_WARNING);
|
||||
}
|
||||
|
||||
$act->setName($res['name']);
|
||||
$act->setProcessId($res['pId']);
|
||||
$act->setNormalizedName($res['normalized_name']);
|
||||
$act->setDescription($res['description']);
|
||||
$act->setIsInteractive($res['isInteractive']);
|
||||
$act->setIsAutoRouted($res['isAutoRouted']);
|
||||
$act->setActivityId($res['activityId']);
|
||||
$act->setType($res['type']);
|
||||
|
||||
//Now get forward transitions
|
||||
|
||||
//Now get backward transitions
|
||||
|
||||
//Now get roles
|
||||
$query = "select `roleId` from `".GALAXIA_TABLE_PREFIX."activity_roles` where `activityId`=?";
|
||||
$result=$this->query($query,array($res['activityId']));
|
||||
while($res = $result->fetchRow()) {
|
||||
$this->roles[] = $res['roleId'];
|
||||
}
|
||||
$act->setRoles($this->roles);
|
||||
return $act;
|
||||
}
|
||||
|
||||
/*! Returns an Array of roleIds for the given user */
|
||||
function getUserRoles($user) {
|
||||
$query = "select `roleId` from `".GALAXIA_TABLE_PREFIX."user_roles` where `user`=?";
|
||||
$result=$this->query($query,array($user));
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['roleId'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*! Returns an Array of asociative arrays with roleId and name
|
||||
for the given user */
|
||||
function getActivityRoleNames() {
|
||||
$aid = $this->activityId;
|
||||
$query = "select gr.`roleId`, `name` from `".GALAXIA_TABLE_PREFIX."activity_roles` gar, `".GALAXIA_TABLE_PREFIX."roles` gr where gar.`roleId`=gr.`roleId` and gar.`activityId`=?";
|
||||
$result=$this->query($query,array($aid));
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*! Returns the normalized name for the activity */
|
||||
function getNormalizedName() {
|
||||
return $this->normalizedName;
|
||||
}
|
||||
|
||||
/*! Sets normalized name for the activity */
|
||||
function setNormalizedName($name) {
|
||||
$this->normalizedName=$name;
|
||||
}
|
||||
|
||||
/*! Sets the name for the activity */
|
||||
function setName($name) {
|
||||
$this->name=$name;
|
||||
}
|
||||
|
||||
/*! Gets the activity name */
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/*! Sets the activity description */
|
||||
function setDescription($desc) {
|
||||
$this->description=$desc;
|
||||
}
|
||||
|
||||
/*! Gets the activity description */
|
||||
function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/*! Sets the type for the activity - this does NOT allow you to change the actual type */
|
||||
function setType($type) {
|
||||
$this->type=$type;
|
||||
}
|
||||
|
||||
/*! Gets the activity type */
|
||||
function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/*! Sets if the activity is interactive */
|
||||
function setIsInteractive($is) {
|
||||
$this->isInteractive=$is;
|
||||
}
|
||||
|
||||
/*! Returns if the activity is interactive */
|
||||
function isInteractive() {
|
||||
return $this->isInteractive == 'y';
|
||||
}
|
||||
|
||||
/*! Sets if the activity is auto-routed */
|
||||
function setIsAutoRouted($is) {
|
||||
$this->isAutoRouted = $is;
|
||||
}
|
||||
|
||||
/*! Gets if the activity is auto routed */
|
||||
function isAutoRouted() {
|
||||
return $this->isAutoRouted == 'y';
|
||||
}
|
||||
|
||||
/*! Sets the processId for this activity */
|
||||
function setProcessId($pid) {
|
||||
$this->pId=$pid;
|
||||
}
|
||||
|
||||
/*! Gets the processId for this activity*/
|
||||
function getProcessId() {
|
||||
return $this->pId;
|
||||
}
|
||||
|
||||
/*! Gets the activityId */
|
||||
function getActivityId() {
|
||||
return $this->activityId;
|
||||
}
|
||||
|
||||
/*! Sets the activityId */
|
||||
function setActivityId($id) {
|
||||
$this->activityId=$id;
|
||||
}
|
||||
|
||||
/*! Gets array with roleIds asociated to this activity */
|
||||
function getRoles() {
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
/*! Sets roles for this activities, shoule receive an
|
||||
array of roleIds */
|
||||
function setRoles($roles) {
|
||||
$this->roles = $roles;
|
||||
}
|
||||
|
||||
/*! Checks if a user has a certain role (by name) for this activity,
|
||||
e.g. $isadmin = $activity->checkUserRole($user,'admin'); */
|
||||
function checkUserRole($user,$rolename) {
|
||||
$aid = $this->activityId;
|
||||
return $this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."activity_roles` gar, `".GALAXIA_TABLE_PREFIX."user_roles` gur, `".GALAXIA_TABLE_PREFIX."roles` gr where gar.`roleId`=gr.`roleId` and gur.`roleId`=gr.`roleId` and gar.`activityId`=? and gur.`user`=? and gr.`name`=?",array($aid, $user, $rolename));
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
655
phpgwapi/inc/galaxia_workflow/src/API/Instance.php
Normal file
655
phpgwapi/inc/galaxia_workflow/src/API/Instance.php
Normal file
@ -0,0 +1,655 @@
|
||||
<?php
|
||||
include_once (GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Instance
|
||||
//! A class representing a process instance.
|
||||
/*!
|
||||
This class represents a process instance, it is used when any activity is
|
||||
executed. The $instance object is created representing the instance of a
|
||||
process being executed in the activity or even a to-be-created instance
|
||||
if the activity is a start activity.
|
||||
*/
|
||||
class Instance extends Base {
|
||||
var $properties = Array();
|
||||
var $owner = '';
|
||||
var $status = '';
|
||||
var $started;
|
||||
var $nextActivity;
|
||||
var $nextUser;
|
||||
var $ended;
|
||||
/// Array of asocs(activityId,status,started,user)
|
||||
var $activities = Array();
|
||||
var $pId;
|
||||
var $instanceId = 0;
|
||||
/// An array of workitem ids
|
||||
var $workitems = Array();
|
||||
|
||||
function Instance($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/*!
|
||||
Method used to load an instance data from the database.
|
||||
*/
|
||||
function getInstance($instanceId) {
|
||||
// Get the instance data
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."instances` where `instanceId`=?";
|
||||
$result = $this->query($query,array((int)$instanceId));
|
||||
if(!$result->numRows()) return false;
|
||||
$res = $result->fetchRow();
|
||||
|
||||
//Populate
|
||||
$this->properties = unserialize($res['properties']);
|
||||
$this->status = $res['status'];
|
||||
$this->pId = $res['pId'];
|
||||
$this->instanceId = $res['instanceId'];
|
||||
$this->owner = $res['owner'];
|
||||
$this->started = $res['started'];
|
||||
$this->ended = $res['ended'];
|
||||
$this->nextActivity = $res['nextActivity'];
|
||||
$this->nextUser = $res['nextUser'];
|
||||
// Get the activities where the instance is (ids only is ok)
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$result = $this->query($query,array((int)$instanceId));
|
||||
while($res = $result->fetchRow()) {
|
||||
$this->activities[]=$res;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the next activity to be executed, if the current activity is
|
||||
a switch activity the complete() method will use the activity setted
|
||||
in this method as the next activity for the instance.
|
||||
Note that this method receives an activity name as argument. (Not an Id)
|
||||
*/
|
||||
function setNextActivity($actname) {
|
||||
$pId = $this->pId;
|
||||
$actname=trim($actname);
|
||||
$aid = $this->getOne("select `activityId` from `".GALAXIA_TABLE_PREFIX."activities` where `pId`=? and `name`=?",array($pId,$actname));
|
||||
if(!$this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=? and `pId`=?",array($aid,$pId))) {
|
||||
trigger_error(tra('Fatal error: setting next activity to an unexisting activity'),E_USER_WARNING);
|
||||
}
|
||||
$this->nextActivity=$aid;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `nextActivity`=? where `instanceId`=?";
|
||||
$this->query($query,array((int)$aid,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
This method can be used to set the user that must perform the next
|
||||
activity of the process. this effectively "assigns" the instance to
|
||||
some user.
|
||||
*/
|
||||
function setNextUser($user) {
|
||||
$pId = $this->pId;
|
||||
$this->nextUser = $user;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `nextUser`=? where `instanceId`=?";
|
||||
$this->query($query,array($user,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Creates a new instance.
|
||||
This method is called in start activities when the activity is completed
|
||||
to create a new instance representing the started process.
|
||||
*/
|
||||
function _createNewInstance($activityId,$user) {
|
||||
// Creates a new instance setting up started,ended,user
|
||||
// and status
|
||||
$pid = $this->getOne("select `pId` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array((int)$activityId));
|
||||
$this->status = 'active';
|
||||
$this->nextActivity = 0;
|
||||
$this->setNextUser('');
|
||||
$this->pId = $pid;
|
||||
$now = date("U");
|
||||
$this->started=$now;
|
||||
$this->owner = $user;
|
||||
$props=serialize($this->properties);
|
||||
$query = "insert into `".GALAXIA_TABLE_PREFIX."instances`(`started`,`ended`,`status`,`pId`,`owner`,`properties`) values(?,?,?,?,?,?)";
|
||||
$this->query($query,array($now,0,'active',$pid,$user,$props));
|
||||
$this->instanceId = $this->getOne("select max(`instanceId`) from `".GALAXIA_TABLE_PREFIX."instances` where `started`=? and `owner`=?",array((int)$now,$user));
|
||||
$iid=$this->instanceId;
|
||||
|
||||
// Now update the properties!
|
||||
$props = serialize($this->properties);
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `properties`=? where `instanceId`=?";
|
||||
$this->query($query,array($props,(int)$iid));
|
||||
|
||||
// Then add in ".GALAXIA_TABLE_PREFIX."instance_activities an entry for the
|
||||
// activity the user and status running and started now
|
||||
$query = "insert into `".GALAXIA_TABLE_PREFIX."instance_activities`(`instanceId`,`activityId`,`user`,`started`,`status`) values(?,?,?,?,?)";
|
||||
$this->query($query,array((int)$iid,(int)$activityId,$user,(int)$now,'running'));
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets a property in this instance. This method is used in activities to
|
||||
set instance properties. Instance properties are inemdiately serialized.
|
||||
*/
|
||||
function set($name,$value) {
|
||||
$this->properties[$name] = $value;
|
||||
$props = serialize($this->properties);
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `properties`=? where `instanceId`=?";
|
||||
$this->query($query,array($props,$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the value of an instance property.
|
||||
*/
|
||||
function get($name) {
|
||||
if(isset($this->properties[$name])) {
|
||||
return $this->properties[$name];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns an array of asocs describing the activities where the instance
|
||||
is present, can be more than one activity if the instance was "splitted"
|
||||
*/
|
||||
function getActivities() {
|
||||
return $this->activities;
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the instance status can be
|
||||
'completed', 'active', 'aborted' or 'exception'
|
||||
*/
|
||||
function getStatus() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the instance status , the value can be:
|
||||
'completed', 'active', 'aborted' or 'exception'
|
||||
*/
|
||||
function setStatus($status) {
|
||||
$this->status = $status;
|
||||
// and update the database
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `status`=? where `instanceId`=?";
|
||||
$this->query($query,array($status,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the instanceId
|
||||
*/
|
||||
function getInstanceId() {
|
||||
return $this->instanceId;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the processId for this instance
|
||||
*/
|
||||
function getProcessId() {
|
||||
return $this->pId;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the user that created the instance
|
||||
*/
|
||||
function getOwner() {
|
||||
return $this->owner;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the instance creator user
|
||||
*/
|
||||
function setOwner($user) {
|
||||
$this->owner = $user;
|
||||
// save database
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `owner`=? where `instanceId`=?";
|
||||
$this->query($query,array($owner,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the user that must execute the activity indicated by the activityId.
|
||||
Note that the instance MUST be present in the activity to set the user,
|
||||
you can't program who will execute an activity.
|
||||
*/
|
||||
function setActivityUser($activityId,$theuser) {
|
||||
if(empty($theuser)) $theuser='*';
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
$this->activities[$i]['user']=$theuser;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `user`=? where `activityId`=? and `instanceId`=?";
|
||||
|
||||
$this->query($query,array($theuser,(int)$activityId,(int)$this->instanceId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the user that must execute or is already executing an activity
|
||||
wherethis instance is present.
|
||||
*/
|
||||
function getActivityUser($activityId) {
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
return $this->activities[$i]['user'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the status of the instance in some activity, can be
|
||||
'running' or 'completed'
|
||||
*/
|
||||
function setActivityStatus($activityId,$status) {
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
$this->activities[$i]['status']=$status;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `status`=? where `activityId`=? and `instanceId`=?";
|
||||
$this->query($query,array($status,(int)$activityId,(int)$this->instanceId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Gets the status of the instance in some activity, can be
|
||||
'running' or 'completed'
|
||||
*/
|
||||
function getActivityStatus($activityId) {
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
return $this->activities[$i]['status'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Resets the start time of the activity indicated to the current time.
|
||||
*/
|
||||
function setActivityStarted($activityId) {
|
||||
$now = date("U");
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
$this->activities[$i]['started']=$now;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `started`=? where `activityId`=? and `instanceId`=?";
|
||||
$this->query($query,array($now,(int)$activityId,(int)$this->instanceId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the Unix timstamp of the starting time for the given activity.
|
||||
*/
|
||||
function getActivityStarted($activityId) {
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
return $this->activities[$i]['started'];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Gets an activity from the list of activities of the instance
|
||||
*/
|
||||
function _get_instance_activity($activityId) {
|
||||
for($i=0;$i<count($this->activities);$i++) {
|
||||
if($this->activities[$i]['activityId']==$activityId) {
|
||||
return $this->activities[$i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the time where the instance was started.
|
||||
*/
|
||||
function setStarted($time) {
|
||||
$this->started=$time;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `started`=? where `instanceId`=?";
|
||||
$this->query($query,array((int)$time,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the time where the instance was started (Unix timestamp)
|
||||
*/
|
||||
function getStarted() {
|
||||
return $this->started;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the end time of the instance (when the process was completed)
|
||||
*/
|
||||
function setEnded($time) {
|
||||
$this->ended=$time;
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `ended`=? where `instanceId`=?";
|
||||
$this->query($query,array((int)$time,(int)$this->instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the end time of the instance (when the process was completed)
|
||||
*/
|
||||
function getEnded() {
|
||||
return $this->ended;
|
||||
}
|
||||
|
||||
/*!
|
||||
Completes an activity, normally from any activity you should call this
|
||||
function without arguments.
|
||||
The arguments are explained just in case.
|
||||
$activityId is the activity that is being completed, when this is not
|
||||
passed the engine takes it from the $_REQUEST array,all activities
|
||||
are executed passing the activityId in the URI.
|
||||
$force indicates that the instance must be routed no matter if the
|
||||
activity is auto-routing or not. This is used when "sending" an
|
||||
instance from a non-auto-routed activity to the next activity.
|
||||
$addworkitem indicates if a workitem should be added for the completed
|
||||
activity.
|
||||
YOU MUST NOT CALL complete() for non-interactive activities since
|
||||
the engine does automatically complete automatic activities after
|
||||
executing them.
|
||||
*/
|
||||
function complete($activityId=0,$force=false,$addworkitem=true) {
|
||||
global $user;
|
||||
global $__activity_completed;
|
||||
|
||||
$__activity_completed = true;
|
||||
|
||||
if(empty($user)) {$theuser='*';} else {$theuser=$user;}
|
||||
|
||||
if($activityId==0) {
|
||||
$activityId=$_REQUEST['activityId'];
|
||||
}
|
||||
|
||||
// If we are completing a start activity then the instance must
|
||||
// be created first!
|
||||
$type = $this->getOne("select `type` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array((int)$activityId));
|
||||
if($type=='start') {
|
||||
$this->_createNewInstance((int)$activityId,$theuser);
|
||||
}
|
||||
|
||||
// Now set ended
|
||||
$now = date("U");
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `ended`=? where `activityId`=? and `instanceId`=?";
|
||||
$this->query($query,array((int)$now,(int)$activityId,(int)$this->instanceId));
|
||||
|
||||
//Add a workitem to the instance
|
||||
$iid = $this->instanceId;
|
||||
if($addworkitem) {
|
||||
$max = $this->getOne("select max(`orderId`) from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?",array((int)$iid));
|
||||
if(!$max) {
|
||||
$max=1;
|
||||
} else {
|
||||
$max++;
|
||||
}
|
||||
$act = $this->_get_instance_activity($activityId);
|
||||
if(!$act) {
|
||||
//Then this is a start activity ending
|
||||
$started = $this->getStarted();
|
||||
$putuser = $this->getOwner();
|
||||
} else {
|
||||
$started=$act['started'];
|
||||
$putuser = $act['user'];
|
||||
}
|
||||
$ended = date("U");
|
||||
$properties = serialize($this->properties);
|
||||
$query="insert into `".GALAXIA_TABLE_PREFIX."workitems`(`instanceId`,`orderId`,`activityId`,`started`,`ended`,`properties`,`user`) values(?,?,?,?,?,?,?)";
|
||||
$this->query($query,array((int)$iid,(int)$max,(int)$activityId,(int)$started,(int)$ended,$properties,$putuser));
|
||||
}
|
||||
|
||||
//Set the status for the instance-activity to completed
|
||||
$this->setActivityStatus($activityId,'completed');
|
||||
|
||||
//If this and end actt then terminate the instance
|
||||
if($type=='end') {
|
||||
$this->terminate();
|
||||
return;
|
||||
}
|
||||
|
||||
//If the activity ending is autorouted then send to the
|
||||
//activity
|
||||
if ($type != 'end') {
|
||||
if (($force) || ($this->getOne("select `isAutoRouted` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array($activityId)) == 'y')) {
|
||||
// Now determine where to send the instance
|
||||
$query = "select `actToId` from `".GALAXIA_TABLE_PREFIX."transitions` where `actFromId`=?";
|
||||
$result = $this->query($query,array((int)$activityId));
|
||||
$candidates = Array();
|
||||
while ($res = $result->fetchRow()) {
|
||||
$candidates[] = $res['actToId'];
|
||||
}
|
||||
if($type == 'split') {
|
||||
$first = true;
|
||||
foreach ($candidates as $cand) {
|
||||
$this->sendTo($activityId,$cand,$first);
|
||||
$first = false;
|
||||
}
|
||||
} elseif($type == 'switch') {
|
||||
if (in_array($this->nextActivity,$candidates)) {
|
||||
$this->sendTo((int)$activityId,(int)$this->nextActivity);
|
||||
} else {
|
||||
trigger_error(tra('Fatal error: nextActivity does not match any candidate in autorouting switch activity'),E_USER_WARNING);
|
||||
}
|
||||
} else {
|
||||
if (count($candidates)>1) {
|
||||
trigger_error(tra('Fatal error: non-deterministic decision for autorouting activity'),E_USER_WARNING);
|
||||
} else {
|
||||
$this->sendTo((int)$activityId,(int)$candidates[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Aborts an activity and terminates the whole instance. We still create a workitem to keep track
|
||||
of where in the process the instance was aborted
|
||||
*/
|
||||
function abort($activityId=0,$theuser = '',$addworkitem=true) {
|
||||
if(empty($theuser)) {
|
||||
global $user;
|
||||
if (empty($user)) {$theuser='*';} else {$theuser=$user;}
|
||||
}
|
||||
|
||||
if($activityId==0) {
|
||||
$activityId=$_REQUEST['activityId'];
|
||||
}
|
||||
|
||||
// If we are completing a start activity then the instance must
|
||||
// be created first!
|
||||
$type = $this->getOne("select `type` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array((int)$activityId));
|
||||
if($type=='start') {
|
||||
$this->_createNewInstance((int)$activityId,$theuser);
|
||||
}
|
||||
|
||||
// Now set ended
|
||||
$now = date("U");
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `ended`=? where `activityId`=? and `instanceId`=?";
|
||||
$this->query($query,array((int)$now,(int)$activityId,(int)$this->instanceId));
|
||||
|
||||
//Add a workitem to the instance
|
||||
$iid = $this->instanceId;
|
||||
if($addworkitem) {
|
||||
$max = $this->getOne("select max(`orderId`) from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?",array((int)$iid));
|
||||
if(!$max) {
|
||||
$max=1;
|
||||
} else {
|
||||
$max++;
|
||||
}
|
||||
$act = $this->_get_instance_activity($activityId);
|
||||
if(!$act) {
|
||||
//Then this is a start activity ending
|
||||
$started = $this->getStarted();
|
||||
$putuser = $this->getOwner();
|
||||
} else {
|
||||
$started=$act['started'];
|
||||
$putuser = $act['user'];
|
||||
}
|
||||
$ended = date("U");
|
||||
$properties = serialize($this->properties);
|
||||
$query="insert into `".GALAXIA_TABLE_PREFIX."workitems`(`instanceId`,`orderId`,`activityId`,`started`,`ended`,`properties`,`user`) values(?,?,?,?,?,?,?)";
|
||||
$this->query($query,array((int)$iid,(int)$max,(int)$activityId,(int)$started,(int)$ended,$properties,$putuser));
|
||||
}
|
||||
|
||||
//Set the status for the instance-activity to aborted
|
||||
// TODO: support 'aborted' if we keep activities after termination some day
|
||||
//$this->setActivityStatus($activityId,'aborted');
|
||||
|
||||
// terminate the instance with status 'aborted'
|
||||
$this->terminate('aborted');
|
||||
}
|
||||
|
||||
/*!
|
||||
Terminates the instance marking the instance and the process
|
||||
as completed. This is the end of a process.
|
||||
Normally you should not call this method since it is automatically
|
||||
called when an end activity is completed.
|
||||
*/
|
||||
function terminate($status = 'completed') {
|
||||
//Set the status of the instance to completed
|
||||
$now = date("U");
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `status`=?, `ended`=? where `instanceId`=?";
|
||||
$this->query($query,array($status,(int)$now,(int)$this->instanceId));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$this->query($query,array((int)$this->instanceId));
|
||||
$this->status = $status;
|
||||
$this->activities = Array();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Sends the instance from some activity to another activity.
|
||||
You should not call this method unless you know very very well what
|
||||
you are doing.
|
||||
*/
|
||||
function sendTo($from,$activityId,$split=false) {
|
||||
//1: if we are in a join check
|
||||
//if this instance is also in
|
||||
//other activity if so do
|
||||
//nothing
|
||||
$type = $this->getOne("select `type` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array((int)$activityId));
|
||||
|
||||
// Verify the existance of a transition
|
||||
if(!$this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."transitions` where `actFromId`=? and `actToId`=?",array($from,(int)$activityId))) {
|
||||
trigger_error(tra('Fatal error: trying to send an instance to an activity but no transition found'),E_USER_WARNING);
|
||||
}
|
||||
|
||||
//try to determine the user or *
|
||||
//Use the nextUser
|
||||
if($this->nextUser) {
|
||||
$putuser = $this->nextUser;
|
||||
} else {
|
||||
$candidates = Array();
|
||||
$query = "select `roleId` from `".GALAXIA_TABLE_PREFIX."activity_roles` where `activityId`=?";
|
||||
$result = $this->query($query,array((int)$activityId));
|
||||
while ($res = $result->fetchRow()) {
|
||||
$roleId = $res['roleId'];
|
||||
$query2 = "select `user` from `".GALAXIA_TABLE_PREFIX."user_roles` where `roleId`=?";
|
||||
$result2 = $this->query($query2,array((int)$roleId));
|
||||
while ($res2 = $result2->fetchRow()) {
|
||||
$candidates[] = $res2['user'];
|
||||
}
|
||||
}
|
||||
if(count($candidates) == 1) {
|
||||
$putuser = $candidates[0];
|
||||
} else {
|
||||
$putuser = '*';
|
||||
}
|
||||
}
|
||||
//update the instance_activities table
|
||||
//if not splitting delete first
|
||||
//please update started,status,user
|
||||
if(!$split) {
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=? and `activityId`=?";
|
||||
$this->query($query,array((int)$this->instanceId,$from));
|
||||
}
|
||||
$now = date("U");
|
||||
$iid = $this->instanceId;
|
||||
$query="delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=? and `activityId`=?";
|
||||
$this->query($query,array((int)$iid,(int)$activityId));
|
||||
$query="insert into `".GALAXIA_TABLE_PREFIX."instance_activities`(`instanceId`,`activityId`,`user`,`status`,`started`) values(?,?,?,?,?)";
|
||||
$this->query($query,array((int)$iid,(int)$activityId,$putuser,'running',(int)$now));
|
||||
|
||||
//we are now in a new activity
|
||||
$this->activities=Array();
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$result = $this->query($query,array((int)$iid));
|
||||
while ($res = $result->fetchRow()) {
|
||||
$this->activities[]=$res;
|
||||
}
|
||||
|
||||
if ($type == 'join') {
|
||||
if (count($this->activities)>1) {
|
||||
// This instance will have to wait!
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if the activity is not interactive then
|
||||
//execute the code for the activity and
|
||||
//complete the activity
|
||||
$isInteractive = $this->getOne("select `isInteractive` from `".GALAXIA_TABLE_PREFIX."activities` where `activityId`=?",array((int)$activityId));
|
||||
if ($isInteractive=='n') {
|
||||
|
||||
// Now execute the code for the activity (function defined in lib/Galaxia/config.php)
|
||||
galaxia_execute_activity($activityId, $iid , 1);
|
||||
|
||||
// Reload in case the activity did some change
|
||||
$this->getInstance($this->instanceId);
|
||||
$this->complete($activityId);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets a comment for this instance
|
||||
*/
|
||||
function get_instance_comment($cId) {
|
||||
$iid = $this->instanceId;
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."instance_comments` where `instanceId`=? and `cId`=?";
|
||||
$result = $this->query($query,array((int)$iid,(int)$cId));
|
||||
$res = $result->fetchRow();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
Inserts or updates an instance comment
|
||||
*/
|
||||
function replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment) {
|
||||
if (!$user) {
|
||||
$user = 'Anonymous';
|
||||
}
|
||||
$iid = $this->instanceId;
|
||||
if ($cId) {
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_comments` set `title`=?,`comment`=? where `instanceId`=? and `cId`=?";
|
||||
$this->query($query,array($title,$comment,(int)$iid,(int)$cId));
|
||||
} else {
|
||||
$hash = md5($title.$comment);
|
||||
if ($this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."instance_comments` where `instanceId`=? and `hash`=?",array($iid,$hash))) {
|
||||
return false;
|
||||
}
|
||||
$now = date("U");
|
||||
$query ="insert into `".GALAXIA_TABLE_PREFIX."instance_comments`(`instanceId`,`user`,`activityId`,`activity`,`title`,`comment`,`timestamp`,`hash`) values(?,?,?,?,?,?,?,?)";
|
||||
$this->query($query,array((int)$iid,$user,(int)$activityId,$activity,$title,$comment,(int)$now,$hash));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes an instance comment
|
||||
*/
|
||||
function remove_instance_comment($cId) {
|
||||
$iid = $this->instanceId;
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_comments` where `cId`=? and `instanceId`=?";
|
||||
$this->query($query,array((int)$cId,(int)$iid));
|
||||
}
|
||||
|
||||
/*!
|
||||
Lists instance comments
|
||||
*/
|
||||
function get_instance_comments() {
|
||||
$iid = $this->instanceId;
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."instance_comments` where `instanceId`=? order by ".$this->convert_sortmode("timestamp_desc");
|
||||
$result = $this->query($query,array((int)$iid));
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
76
phpgwapi/inc/galaxia_workflow/src/API/Process.php
Normal file
76
phpgwapi/inc/galaxia_workflow/src/API/Process.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
include_once (GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Process.php
|
||||
//! A class representing a process
|
||||
/*!
|
||||
This class representes the process that is being executed when an activity
|
||||
is executed. You can access this class methods using $process from any activity.
|
||||
No need to instantiate a new object.
|
||||
*/
|
||||
class Process extends Base {
|
||||
var $name;
|
||||
var $description;
|
||||
var $version;
|
||||
var $normalizedName;
|
||||
var $pId = 0;
|
||||
|
||||
function Process($db) {
|
||||
$this->db=$db;
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads a process form the database
|
||||
*/
|
||||
function getProcess($pId) {
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."processes` where `pId`=?";
|
||||
$result = $this->query($query,array($pId));
|
||||
if(!$result->numRows()) return false;
|
||||
$res = $result->fetchRow();
|
||||
$this->name = $res['name'];
|
||||
$this->description = $res['description'];
|
||||
$this->normalizedName = $res['normalized_name'];
|
||||
$this->version = $res['version'];
|
||||
$this->pId = $res['pId'];
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the normalized name of the process
|
||||
*/
|
||||
function getNormalizedName() {
|
||||
return $this->normalizedName;
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the process name
|
||||
*/
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the process version
|
||||
*/
|
||||
function getVersion() {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets information about an activity in this process by name,
|
||||
e.g. $actinfo = $process->getActivityByName('Approve CD Request');
|
||||
if ($actinfo) {
|
||||
$some_url = 'tiki-g-run_activity.php?activityId=' . $actinfo['activityId'];
|
||||
}
|
||||
*/
|
||||
function getActivityByName($actname) {
|
||||
// Get the activity data
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."activities` where `pId`=? and `name`=?";
|
||||
$pId = $this->pId;
|
||||
$result = $this->query($query,array($pId,$actname));
|
||||
if(!$result->numRows()) return false;
|
||||
$res = $result->fetchRow();
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
12
phpgwapi/inc/galaxia_workflow/src/API/Role.php
Normal file
12
phpgwapi/inc/galaxia_workflow/src/API/Role.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
include_once (GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Role.php
|
||||
//! A class representing a role.
|
||||
/*!
|
||||
Not yet implemented.
|
||||
*/
|
||||
//\todo Implement this class
|
||||
class Role extends Base {
|
||||
|
||||
}
|
||||
?>
|
16
phpgwapi/inc/galaxia_workflow/src/API/Workitem.php
Normal file
16
phpgwapi/inc/galaxia_workflow/src/API/Workitem.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
include_once (GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Workitem.php
|
||||
//! A class representing workitems
|
||||
/*!
|
||||
Not yet implemented
|
||||
*/
|
||||
class Workitem extends Base {
|
||||
var $instance;
|
||||
var $properties=Array();
|
||||
var $started;
|
||||
var $ended;
|
||||
var $activity;
|
||||
|
||||
}
|
||||
?>
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! Activity
|
||||
//!
|
||||
/*!
|
||||
This class handles activities of type 'activity'
|
||||
*/
|
||||
class Activity extends BaseActivity {
|
||||
function Activity($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
14
phpgwapi/inc/galaxia_workflow/src/API/activities/End.php
Normal file
14
phpgwapi/inc/galaxia_workflow/src/API/activities/End.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! End
|
||||
//! End class
|
||||
/*!
|
||||
This class handles activities of type 'end'
|
||||
*/
|
||||
class End extends BaseActivity {
|
||||
function End($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Join.php
Normal file
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Join.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! Join
|
||||
//! Join class
|
||||
/*!
|
||||
This class handles activities of type 'join'
|
||||
*/
|
||||
class Join extends BaseActivity {
|
||||
function Join($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Split.php
Normal file
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Split.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! Split
|
||||
//! Split class
|
||||
/*!
|
||||
This class handles activities of type 'split'
|
||||
*/
|
||||
class Split extends BaseActivity {
|
||||
function Split($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! Standalone
|
||||
//! Standalone class
|
||||
/*!
|
||||
This class handles activities of type 'standalone'
|
||||
*/
|
||||
class Standalone extends BaseActivity {
|
||||
function Standalone($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Start.php
Normal file
14
phpgwapi/inc/galaxia_workflow/src/API/activities/Start.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! Start
|
||||
//! Start class
|
||||
/*!
|
||||
This class handles activities of type 'start'
|
||||
*/
|
||||
class Start extends BaseActivity {
|
||||
function Start($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/BaseActivity.php');
|
||||
//!! SwitchActivity
|
||||
//! SwitchActivity class
|
||||
/*!
|
||||
This class handles activities of type 'switch'
|
||||
*/
|
||||
class SwitchActivity extends BaseActivity {
|
||||
function SwitchActivity($db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
}
|
||||
?>
|
315
phpgwapi/inc/galaxia_workflow/src/GUI/GUI.php
Normal file
315
phpgwapi/inc/galaxia_workflow/src/GUI/GUI.php
Normal file
@ -0,0 +1,315 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! GUI
|
||||
//! A GUI class for use in typical user interface scripts
|
||||
/*!
|
||||
This class provides methods for use in typical user interface scripts
|
||||
*/
|
||||
class GUI extends Base {
|
||||
|
||||
/*!
|
||||
List user processes, user processes should follow one of these conditions:
|
||||
1) The process has an instance assigned to the user
|
||||
2) The process has a begin activity with a role compatible to the
|
||||
user roles
|
||||
3) The process has an instance assigned to '*' and the
|
||||
roles for the activity match the roles assigned to
|
||||
the user
|
||||
The method returns the list of processes that match this
|
||||
and it also returns the number of instances that are in the
|
||||
process matching the conditions.
|
||||
*/
|
||||
function gui_list_user_processes($user,$offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
// FIXME: this doesn't support multiple sort criteria
|
||||
//$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
$sort_mode = str_replace("_"," ",$sort_mode);
|
||||
|
||||
$mid = "where gp.isActive=? and gur.user=?";
|
||||
$bindvars = array('y',$user);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid .= " and ((gp.name like ?) or (gp.description like ?))";
|
||||
$bindvars[] = $findesc;
|
||||
$bindvars[] = $findesc;
|
||||
}
|
||||
if($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
|
||||
$query = "select distinct(gp.pId),
|
||||
gp.isActive,
|
||||
gp.name as procname,
|
||||
gp.normalized_name as normalized_name,
|
||||
gp.version as version
|
||||
from ".GALAXIA_TABLE_PREFIX."processes gp
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.pId=ga.pId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gr.roleId
|
||||
$mid order by $sort_mode";
|
||||
$query_cant = "select count(distinct(gp.pId))
|
||||
from ".GALAXIA_TABLE_PREFIX."processes gp
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.pId=ga.pId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gr.roleId
|
||||
$mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
// Get instances per activity
|
||||
$pId=$res['pId'];
|
||||
$res['activities']=$this->getOne("select count(distinct(ga.activityId))
|
||||
from ".GALAXIA_TABLE_PREFIX."processes gp
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.pId=ga.pId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gr.roleId
|
||||
where gp.pId=? and gur.user=?",
|
||||
array($pId,$user));
|
||||
$res['instances']=$this->getOne("select count(distinct(gi.instanceId))
|
||||
from ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."instance_activities gia ON gi.instanceId=gia.instanceId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gia.activityId=gar.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gar.roleId=gur.roleId
|
||||
where gi.pId=? and ((gia.user=?) or (gia.user=? and gur.user=?))",
|
||||
array($pId,$user,'*',$user));
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
function gui_list_user_activities($user,$offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
// FIXME: this doesn't support multiple sort criteria
|
||||
//$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
$sort_mode = str_replace("_"," ",$sort_mode);
|
||||
|
||||
$mid = "where gp.isActive=? and gur.user=?";
|
||||
$bindvars = array('y',$user);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid .= " and ((ga.name like ?) or (ga.description like ?))";
|
||||
$bindvars[] = $findesc;
|
||||
$bindvars[] = $findesc;
|
||||
}
|
||||
if($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
|
||||
$query = "select distinct(ga.activityId),
|
||||
ga.name,
|
||||
ga.type,
|
||||
gp.name as procname,
|
||||
ga.isInteractive,
|
||||
ga.isAutoRouted,
|
||||
ga.activityId,
|
||||
gp.version as version,
|
||||
gp.pId,
|
||||
gp.isActive
|
||||
from ".GALAXIA_TABLE_PREFIX."processes gp
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.pId=ga.pId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gr.roleId
|
||||
$mid order by $sort_mode";
|
||||
$query_cant = "select count(distinct(ga.activityId))
|
||||
from ".GALAXIA_TABLE_PREFIX."processes gp
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gp.pId=ga.pId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."roles gr ON gr.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gr.roleId
|
||||
$mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
// Get instances per activity
|
||||
$res['instances']=$this->getOne("select count(distinct(gi.instanceId))
|
||||
from ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."instance_activities gia ON gi.instanceId=gia.instanceId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gia.activityId=gar.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gar.roleId=gur.roleId
|
||||
where gia.activityId=? and ((gia.user=?) or (gia.user=? and gur.user=?))",
|
||||
array($res['activityId'],$user,'*',$user));
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
function gui_list_user_instances($user,$offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
// FIXME: this doesn't support multiple sort criteria
|
||||
//$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
$sort_mode = str_replace("_"," ",$sort_mode);
|
||||
|
||||
$mid = "where (gia.user=? or (gia.user=? and gur.user=?))";
|
||||
$bindvars = array($user,'*',$user);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid .= " and ((ga.name like ?) or (ga.description like ?))";
|
||||
$bindvars[] = $findesc;
|
||||
$bindvars[] = $findesc;
|
||||
}
|
||||
if($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
|
||||
$query = "select distinct(gi.instanceId),
|
||||
gi.started,
|
||||
gi.owner,
|
||||
gia.user,
|
||||
gi.status,
|
||||
gia.status as actstatus,
|
||||
ga.name,
|
||||
ga.type,
|
||||
gp.name as procname,
|
||||
ga.isInteractive,
|
||||
ga.isAutoRouted,
|
||||
ga.activityId,
|
||||
gp.version as version,
|
||||
gp.pId
|
||||
from ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."instance_activities gia ON gi.instanceId=gia.instanceId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gia.activityId = ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gia.activityId=gar.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."processes gp ON gp.pId=ga.pId
|
||||
$mid order by $sort_mode";
|
||||
$query_cant = "select count(distinct(gi.instanceId))
|
||||
from ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."instance_activities gia ON gi.instanceId=gia.instanceId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activities ga ON gia.activityId = ga.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gia.activityId=gar.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gur.roleId=gar.roleId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."processes gp ON gp.pId=ga.pId
|
||||
$mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
// Get instances per activity
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Abort an instance - this terminates the instance with status 'aborted', and removes all running activities
|
||||
*/
|
||||
function gui_abort_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
// Users can only abort instances they're currently running, or instances that they're the owner of
|
||||
if(!$this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities gia, ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
where gia.instanceId=gi.instanceId and activityId=? and gia.instanceId=? and (user=? or owner=?)",
|
||||
array($activityId,$instanceId,$user,$user)))
|
||||
return false;
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/Instance.php');
|
||||
$instance = new Instance($this->db);
|
||||
$instance->getInstance($instanceId);
|
||||
if (!empty($instance->instanceId)) {
|
||||
$instance->abort($activityId,$user);
|
||||
}
|
||||
unset($instance);
|
||||
}
|
||||
|
||||
/*!
|
||||
Exception handling for an instance - this sets the instance status to 'exception', but keeps all running activities.
|
||||
The instance can be resumed afterwards via gui_resume_instance().
|
||||
*/
|
||||
function gui_exception_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
// Users can only do exception handling for instances they're currently running, or instances that they're the owner of
|
||||
if(!$this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities gia, ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
where gia.instanceId=gi.instanceId and activityId=? and gia.instanceId=? and (user=? or owner=?)",
|
||||
array($activityId,$instanceId,$user,$user)))
|
||||
return false;
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instances
|
||||
set status=?
|
||||
where instanceId=?";
|
||||
$this->query($query, array('exception',$instanceId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Resume an instance - this sets the instance status from 'exception' back to 'active'
|
||||
*/
|
||||
function gui_resume_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
// Users can only resume instances they're currently running, or instances that they're the owner of
|
||||
if(!$this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities gia, ".GALAXIA_TABLE_PREFIX."instances gi
|
||||
where gia.instanceId=gi.instanceId and activityId=? and gia.instanceId=? and (user=? or owner=?)",
|
||||
array($activityId,$instanceId,$user,$user)))
|
||||
return false;
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instances
|
||||
set status=?
|
||||
where instanceId=?";
|
||||
$this->query($query, array('active',$instanceId));
|
||||
}
|
||||
|
||||
|
||||
function gui_send_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
if(!
|
||||
($this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities
|
||||
where activityId=? and instanceId=? and user=?",
|
||||
array($activityId,$instanceId,$user)))
|
||||
||
|
||||
($this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities gia
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=gia.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gar.roleId=gur.roleId
|
||||
where gia.instanceId=? and gia.activityId=? and gia.user=? and gur.user=?",
|
||||
array($instanceId,$activityId,'*',$user)))
|
||||
) return false;
|
||||
include_once(GALAXIA_LIBRARY.'/src/API/Instance.php');
|
||||
$instance = new Instance($this->db);
|
||||
$instance->getInstance($instanceId);
|
||||
$instance->complete($activityId,true,false);
|
||||
unset($instance);
|
||||
}
|
||||
|
||||
function gui_release_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
if(!$this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities
|
||||
where activityId=? and instanceId=? and user=?",
|
||||
array($activityId,$instanceId,$user))) return false;
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instance_activities
|
||||
set user=?
|
||||
where instanceId=? and activityId=?";
|
||||
$this->query($query, array('*',$instanceId,$activityId));
|
||||
}
|
||||
|
||||
function gui_grab_instance($user,$activityId,$instanceId)
|
||||
{
|
||||
// Grab only if roles are ok
|
||||
if(!$this->getOne("select count(*)
|
||||
from ".GALAXIA_TABLE_PREFIX."instance_activities gia
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."activity_roles gar ON gar.activityId=gia.activityId
|
||||
INNER JOIN ".GALAXIA_TABLE_PREFIX."user_roles gur ON gar.roleId=gur.roleId
|
||||
where gia.instanceId=? and gia.activityId=? and gia.user=? and gur.user=?",
|
||||
array($instanceId,$activityId,'*',$user))) return false;
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instance_activities
|
||||
set user=?
|
||||
where instanceId=? and activityId=?";
|
||||
$this->query($query, array($user,$instanceId,$activityId));
|
||||
}
|
||||
}
|
||||
?>
|
33
phpgwapi/inc/galaxia_workflow/src/Observers/Logger.php
Normal file
33
phpgwapi/inc/galaxia_workflow/src/Observers/Logger.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/common/Observer.php');
|
||||
//!! Logger
|
||||
//! Log
|
||||
/*!
|
||||
|
||||
blah....
|
||||
*/
|
||||
class Logger extends Observer {
|
||||
var $_filename;
|
||||
|
||||
function Logger($filename) {
|
||||
$this->_filename = $filename;
|
||||
$fp = fopen($this->_filename,"a");
|
||||
if(!$fp) {
|
||||
trigger_error("Logger cannot append to log file: ".$this->filename,E_USER_WARNING);
|
||||
}
|
||||
if($fp) {
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function notify($event,$msg) {
|
||||
// Add a line to the log file.
|
||||
$fp = fopen($this->_filename,"a");
|
||||
$date = date("[d/m/Y h:i:s]");
|
||||
$msg=trim($msg);
|
||||
fputs($fp,$date." ".$msg."\n");
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,842 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/ProcessManager/BaseManager.php');
|
||||
//!! ActivityManager
|
||||
//! A class to maniplate process activities and transitions
|
||||
/*!
|
||||
This class is used to add,remove,modify and list
|
||||
activities used in the Workflow engine.
|
||||
Activities are managed in a per-process level, each
|
||||
activity belongs to some process.
|
||||
*/
|
||||
class ActivityManager extends BaseManager {
|
||||
var $error='';
|
||||
|
||||
/*!
|
||||
Constructor takes a PEAR::Db object to be used
|
||||
to manipulate activities in the database.
|
||||
*/
|
||||
function ActivityManager($db) {
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to activityManager constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
function get_error() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Asociates an activity with a role
|
||||
*/
|
||||
function add_activity_role($activityId, $roleId) {
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."activity_roles` where `activityId`=? and `roleId`=?";
|
||||
$this->query($query,array($activityId, $roleId));
|
||||
$query = "insert into `".GALAXIA_TABLE_PREFIX."activity_roles`(`activityId`,`roleId`) values(?,?)";
|
||||
$this->query($query,array($activityId, $roleId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets the roles asociated to an activity
|
||||
*/
|
||||
function get_activity_roles($activityId) {
|
||||
$query = "select activityId,roles.roleId,roles.name
|
||||
from ".GALAXIA_TABLE_PREFIX."activity_roles gar, ".GALAXIA_TABLE_PREFIX."roles roles
|
||||
where roles.roleId = gar.roleId and activityId=?";
|
||||
$result = $this->query($query,array($activityId));
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes a role from an activity
|
||||
*/
|
||||
function remove_activity_role($activityId, $roleId)
|
||||
{
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."activity_roles
|
||||
where activityId=$activityId and roleId=$roleId";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
/*!
|
||||
Checks if a transition exists
|
||||
*/
|
||||
function transition_exists($pid,$actFromId,$actToId)
|
||||
{
|
||||
return($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."transitions where pId=$pid and actFromId=$actFromId and actToId=$actToId"));
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a transition
|
||||
*/
|
||||
function add_transition($pId, $actFromId, $actToId)
|
||||
{
|
||||
// No circular transitions allowed
|
||||
if($actFromId == $actToId) return false;
|
||||
|
||||
// Rule: if act is not spl-x or spl-a it can't have more than
|
||||
// 1 outbound transition.
|
||||
$a1 = $this->get_activity($pId, $actFromId);
|
||||
$a2 = $this->get_activity($pId, $actToId);
|
||||
if(!$a1 || !$a2) return false;
|
||||
if($a1['type'] != 'switch' && $a1['type'] != 'split') {
|
||||
if($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."transitions where actFromId=$actFromId")) {
|
||||
$this->error = tra('Cannot add transition only split activities can have more than one outbound transition');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Rule: if act is standalone no transitions allowed
|
||||
if($a1['type'] == 'standalone' || $a2['type']=='standalone') return false;
|
||||
// No inbound to start
|
||||
if($a2['type'] == 'start') return false;
|
||||
// No outbound from end
|
||||
if($a1['type'] == 'end') return false;
|
||||
|
||||
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."transitions` where `actFromId`=? and `actToId`=?";
|
||||
$this->query($query,array($actFromId, $actToId));
|
||||
$query = "insert into `".GALAXIA_TABLE_PREFIX."transitions`(`pId`,`actFromId`,`actToId`) values(?,?,?)";
|
||||
$this->query($query,array($pId, $actFromId, $actToId));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes a transition
|
||||
*/
|
||||
function remove_transition($actFromId, $actToId)
|
||||
{
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."transitions where actFromId=$actFromId and actToId=$actToId";
|
||||
$this->query($query);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes all the activity transitions
|
||||
*/
|
||||
function remove_activity_transitions($pId, $aid)
|
||||
{
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."transitions where pId=$pId and (actFromId=$aid or actToId=$aid)";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns all the transitions for a process
|
||||
*/
|
||||
function get_process_transitions($pId,$actid=0)
|
||||
{
|
||||
if(!$actid) {
|
||||
$query = "select a1.name as actFromName, a2.name as actToName, actFromId, actToId from ".GALAXIA_TABLE_PREFIX."transitions gt,".GALAXIA_TABLE_PREFIX."activities a1, ".GALAXIA_TABLE_PREFIX."activities a2 where gt.actFromId = a1.activityId and gt.actToId = a2.activityId and gt.pId = $pId";
|
||||
} else {
|
||||
$query = "select a1.name as actFromName, a2.name as actToName, actFromId, actToId from ".GALAXIA_TABLE_PREFIX."transitions gt,".GALAXIA_TABLE_PREFIX."activities a1, ".GALAXIA_TABLE_PREFIX."activities a2 where gt.actFromId = a1.activityId and gt.actToId = a2.activityId and gt.pId = $pId and (actFromId = $actid)";
|
||||
}
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
Indicates if an activity is autoRouted
|
||||
*/
|
||||
function activity_is_auto_routed($actid)
|
||||
{
|
||||
return($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where activityId=$actid and isAutoRouted='y'"));
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns all the activities for a process as
|
||||
an array
|
||||
*/
|
||||
function get_process_activities($pId)
|
||||
{
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
Builds the graph
|
||||
*/
|
||||
//\todo build the real graph
|
||||
function build_process_graph($pId)
|
||||
{
|
||||
$attributes = Array(
|
||||
|
||||
);
|
||||
$graph = new Process_GraphViz(true,$attributes);
|
||||
$pm = new ProcessManager($this->db);
|
||||
$name = $pm->_get_normalized_name($pId);
|
||||
$graph->set_pid($name);
|
||||
|
||||
// Nodes are process activities so get
|
||||
// the activities and add nodes as needed
|
||||
$nodes = $this->get_process_activities($pId);
|
||||
|
||||
foreach($nodes as $node)
|
||||
{
|
||||
if($node['isInteractive']=='y') {
|
||||
$color='blue';
|
||||
} else {
|
||||
$color='black';
|
||||
}
|
||||
$auto[$node['name']] = $node['isAutoRouted'];
|
||||
$graph->addNode($node['name'],array('URL'=>"foourl?activityId=".$node['activityId'],
|
||||
'label'=>$node['name'],
|
||||
'shape' => $this->_get_activity_shape($node['type']),
|
||||
'color' => $color
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Now add edges, edges are transitions,
|
||||
// get the transitions and add the edges
|
||||
$edges = $this->get_process_transitions($pId);
|
||||
foreach($edges as $edge)
|
||||
{
|
||||
if($auto[$edge['actFromName']] == 'y') {
|
||||
$color = 'red';
|
||||
} else {
|
||||
$color = 'black';
|
||||
}
|
||||
$graph->addEdge(array($edge['actFromName'] => $edge['actToName']), array('color'=>$color));
|
||||
}
|
||||
|
||||
|
||||
// Save the map image and the image graph
|
||||
$graph->image_and_map();
|
||||
unset($graph);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Validates if a process can be activated checking the
|
||||
process activities and transitions the rules are:
|
||||
0) No circular activities
|
||||
1) Must have only one a start and end activity
|
||||
2) End must be reachable from start
|
||||
3) Interactive activities must have a role assigned
|
||||
4) Roles should be mapped
|
||||
5) Standalone activities cannot have transitions
|
||||
6) Non intractive activities non-auto routed must have some role
|
||||
so the user can "send" the activity
|
||||
*/
|
||||
function validate_process_activities($pId)
|
||||
{
|
||||
$errors = Array();
|
||||
// Pre rule no cricular activities
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."transitions where pId=$pId and actFromId=actToId");
|
||||
if($cant) {
|
||||
$errors[] = tra('Circular reference found some activity has a transition leading to itself');
|
||||
}
|
||||
|
||||
// Rule 1 must have exactly one start and end activity
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and type='start'");
|
||||
if($cant < 1) {
|
||||
$errors[] = tra('Process does not have a start activity');
|
||||
}
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and type='end'");
|
||||
if($cant != 1) {
|
||||
$errors[] = tra('Process does not have exactly one end activity');
|
||||
}
|
||||
|
||||
// Rule 2 end must be reachable from start
|
||||
$nodes = Array();
|
||||
$endId = $this->getOne("select activityId from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and type='end'");
|
||||
$aux['id']=$endId;
|
||||
$aux['visited']=false;
|
||||
$nodes[] = $aux;
|
||||
|
||||
$startId = $this->getOne("select activityId from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and type='start'");
|
||||
$start_node['id']=$startId;
|
||||
$start_node['visited']=true;
|
||||
|
||||
while($this->_list_has_unvisited_nodes($nodes) && !$this->_node_in_list($start_node,$nodes)) {
|
||||
for($i=0;$i<count($nodes);$i++) {
|
||||
$node=&$nodes[$i];
|
||||
if(!$node['visited']) {
|
||||
$node['visited']=true;
|
||||
$query = "select actFromId from ".GALAXIA_TABLE_PREFIX."transitions where actToId=".$node['id'];
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$aux['id'] = $res['actFromId'];
|
||||
$aux['visited']=false;
|
||||
if(!$this->_node_in_list($aux,$nodes)) {
|
||||
$nodes[] = $aux;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->_node_in_list($start_node,$nodes)) {
|
||||
// Start node is NOT reachable from the end node
|
||||
$errors[] = tra('End activity is not reachable from start activity');
|
||||
}
|
||||
|
||||
//Rule 3: interactive activities must have a role
|
||||
//assigned.
|
||||
//Rule 5: standalone activities can't have transitions
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId = $pId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$aid = $res['activityId'];
|
||||
if($res['isInteractive'] == 'y') {
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activity_roles where activityId=".$res['activityId']);
|
||||
if(!$cant) {
|
||||
$errors[] = tra('Activity').': '.$res['name'].tra(' is interactive but has no role assigned');
|
||||
}
|
||||
} else {
|
||||
if( $res['type'] != 'end' && $res['isAutoRouted'] == 'n') {
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activity_roles where activityId=".$res['activityId']);
|
||||
if(!$cant) {
|
||||
$errors[] = tra('Activity').': '.$res['name'].tra(' is non-interactive and non-autorouted but has no role assigned');
|
||||
}
|
||||
}
|
||||
}
|
||||
if($res['type']=='standalone') {
|
||||
if($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."transitions where actFromId=$aid or actToId=$aid")) {
|
||||
$errors[] = tra('Activity').': '.$res['name'].tra(' is standalone but has transitions');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Rule4: roles should be mapped
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."roles where pId = $pId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."user_roles where roleId=".$res['roleId']);
|
||||
if(!$cant) {
|
||||
$errors[] = tra('Role').': '.$res['name'].tra(' is not mapped');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// End of rules
|
||||
|
||||
// Validate process sources
|
||||
$serrors=$this->validate_process_sources($pId);
|
||||
$errors = array_merge($errors,$serrors);
|
||||
|
||||
$this->error = $errors;
|
||||
|
||||
|
||||
|
||||
$isValid = (count($errors)==0) ? 'y' : 'n';
|
||||
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."processes set isValid='$isValid' where pId=$pId";
|
||||
$this->query($query);
|
||||
|
||||
$this->_label_nodes($pId);
|
||||
|
||||
return ($isValid=='y');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Validate process sources
|
||||
Rules:
|
||||
1) Interactive activities (non-standalone) must use complete()
|
||||
2) Standalone activities must not use $instance
|
||||
3) Switch activities must use setNextActivity
|
||||
4) Non-interactive activities cannot use complete()
|
||||
*/
|
||||
function validate_process_sources($pid)
|
||||
{
|
||||
$errors=Array();
|
||||
$procname= $this->getOne("select normalized_name from ".GALAXIA_TABLE_PREFIX."processes where pId=$pid");
|
||||
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId=$pid";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$actname = $res['normalized_name'];
|
||||
$source = GALAXIA_PROCESSES."/$procname/code/activities/$actname".'.php';
|
||||
if (!file_exists($source)) {
|
||||
continue;
|
||||
}
|
||||
$fp = fopen($source,'r');
|
||||
$data='';
|
||||
while(!feof($fp)) {
|
||||
$data.=fread($fp,8192);
|
||||
}
|
||||
fclose($fp);
|
||||
if($res['type']=='standalone') {
|
||||
if(strstr($data,'$instance')) {
|
||||
$errors[] = tra('Activity '.$res['name'].' is standalone and is using the $instance object');
|
||||
}
|
||||
} else {
|
||||
if($res['isInteractive']=='y') {
|
||||
if(!strstr($data,'$instance->complete()')) {
|
||||
$errors[] = tra('Activity '.$res['name'].' is interactive so it must use the $instance->complete() method');
|
||||
}
|
||||
} else {
|
||||
if(strstr($data,'$instance->complete()')) {
|
||||
$errors[] = tra('Activity '.$res['name'].' is non-interactive so it must not use the $instance->complete() method');
|
||||
}
|
||||
}
|
||||
if($res['type']=='switch') {
|
||||
if(!strstr($data,'$instance->setNextActivity(')) {
|
||||
$errors[] = tra('Activity '.$res['name'].' is switch so it must use $instance->setNextActivity($actname) method');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/*!
|
||||
Indicates if an activity with the same name exists
|
||||
*/
|
||||
function activity_name_exists($pId,$name)
|
||||
{
|
||||
$name = addslashes($this->_normalize_name($name));
|
||||
return $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and normalized_name='$name'");
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Gets a activity fields are returned as an asociative array
|
||||
*/
|
||||
function get_activity($pId, $activityId)
|
||||
{
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and activityId=$activityId";
|
||||
$result = $this->query($query);
|
||||
$res = $result->fetchRow();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
Lists activities at a per-process level
|
||||
*/
|
||||
function list_activities($pId,$offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
$sort_mode = str_replace("_"," ",$sort_mode);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid=" where pId=? and ((name like ?) or (description like ?))";
|
||||
$bindvars = array($pId,$findesc,$findesc);
|
||||
} else {
|
||||
$mid=" where pId=? ";
|
||||
$bindvars = array($pId);
|
||||
}
|
||||
if($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities $mid order by $sort_mode";
|
||||
$query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."activities $mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$res['roles'] = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activity_roles where activityId=?",array($res['activityId']));
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Removes a activity.
|
||||
*/
|
||||
function remove_activity($pId, $activityId)
|
||||
{
|
||||
$pm = new ProcessManager($this->db);
|
||||
$proc_info = $pm->get_process($pId);
|
||||
$actname = $this->_get_normalized_name($activityId);
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and activityId=$activityId";
|
||||
$this->query($query);
|
||||
$query = "select actFromId,actToId from ".GALAXIA_TABLE_PREFIX."transitions where actFromId=$activityId or actToId=$activityId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$this->remove_transition($res['actFromId'], $res['actToId']);
|
||||
}
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."activity_roles where activityId=$activityId";
|
||||
$this->query($query);
|
||||
// And we have to remove the user and compiled files
|
||||
// for this activity
|
||||
$procname = $proc_info['normalized_name'];
|
||||
unlink(GALAXIA_PROCESSES."/$procname/code/activities/$actname".'.php');
|
||||
if (file_exists(GALAXIA_PROCESSES."/$procname/code/templates/$actname".'.tpl')) {
|
||||
@unlink(GALAXIA_PROCESSES."/$procname/code/templates/$actname".'.tpl');
|
||||
}
|
||||
unlink(GALAXIA_PROCESSES."/$procname/compiled/$actname".'.php');
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Updates or inserts a new activity in the database, $vars is an asociative
|
||||
array containing the fields to update or to insert as needed.
|
||||
$pId is the processId
|
||||
$activityId is the activityId
|
||||
*/
|
||||
function replace_activity($pId, $activityId, $vars)
|
||||
{
|
||||
$TABLE_NAME = GALAXIA_TABLE_PREFIX."activities";
|
||||
$now = date("U");
|
||||
$vars['lastModif']=$now;
|
||||
$vars['pId']=$pId;
|
||||
$vars['normalized_name'] = $this->_normalize_name($vars['name']);
|
||||
|
||||
$pm = new ProcessManager($this->db);
|
||||
$proc_info = $pm->get_process($pId);
|
||||
|
||||
|
||||
foreach($vars as $key=>$value)
|
||||
{
|
||||
$vars[$key]=addslashes($value);
|
||||
}
|
||||
|
||||
if($activityId) {
|
||||
$oldname = $this->_get_normalized_name($activityId);
|
||||
// update mode
|
||||
$first = true;
|
||||
$query ="update $TABLE_NAME set";
|
||||
foreach($vars as $key=>$value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)) $value="'".$value."'";
|
||||
$query.= " $key=$value ";
|
||||
$first = false;
|
||||
}
|
||||
$query .= " where pId=$pId and activityId=$activityId ";
|
||||
$this->query($query);
|
||||
|
||||
$newname = $vars['normalized_name'];
|
||||
// if the activity is changing name then we
|
||||
// should rename the user_file for the activity
|
||||
// remove the old compiled file and recompile
|
||||
// the activity
|
||||
|
||||
$user_file_old = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/activities/'.$oldname.'.php';
|
||||
$user_file_new = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/activities/'.$newname.'.php';
|
||||
rename($user_file_old, $user_file_new);
|
||||
|
||||
$user_file_old = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/templates/'.$oldname.'.tpl';
|
||||
$user_file_new = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/templates/'.$newname.'.tpl';
|
||||
if ($user_file_old != $user_file_new) {
|
||||
@rename($user_file_old, $user_file_new);
|
||||
}
|
||||
|
||||
|
||||
$compiled_file = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/compiled/'.$oldname.'.php';
|
||||
unlink($compiled_file);
|
||||
$this->compile_activity($pId,$activityId);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
// When inserting activity names can't be duplicated
|
||||
if($this->activity_name_exists($pId, $vars['name'])) {
|
||||
return false;
|
||||
}
|
||||
unset($vars['activityId']);
|
||||
// insert mode
|
||||
$first = true;
|
||||
$query = "insert into $TABLE_NAME(";
|
||||
foreach(array_keys($vars) as $key) {
|
||||
if(!$first) $query.= ',';
|
||||
$query.= "$key";
|
||||
$first = false;
|
||||
}
|
||||
$query .=") values(";
|
||||
$first = true;
|
||||
foreach(array_values($vars) as $value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)) $value="'".$value."'";
|
||||
$query.= "$value";
|
||||
$first = false;
|
||||
}
|
||||
$query .=")";
|
||||
$this->query($query);
|
||||
$activityId = $this->getOne("select max(activityId) from $TABLE_NAME where pId=$pId and lastModif=$now");
|
||||
$ret = $activityId;
|
||||
if(!$activityId) {
|
||||
print("select max(activityId) from $TABLE_NAME where pId=$pId and lastModif=$now");
|
||||
die;
|
||||
}
|
||||
// Should create the code file
|
||||
$procname = $proc_info["normalized_name"];
|
||||
$fw = fopen(GALAXIA_PROCESSES."/$procname/code/activities/".$vars['normalized_name'].'.php','w');
|
||||
fwrite($fw,'<'.'?'.'php'."\n".'?'.'>');
|
||||
fclose($fw);
|
||||
|
||||
if($vars['isInteractive']=='y') {
|
||||
$fw = fopen(GALAXIA_PROCESSES."/$procname/code/templates/".$vars['normalized_name'].'.tpl','w');
|
||||
if (defined('GALAXIA_TEMPLATE_HEADER') && GALAXIA_TEMPLATE_HEADER) {
|
||||
fwrite($fw,GALAXIA_TEMPLATE_HEADER . "\n");
|
||||
}
|
||||
fclose($fw);
|
||||
}
|
||||
|
||||
$this->compile_activity($pId,$activityId);
|
||||
|
||||
}
|
||||
// Get the id
|
||||
return $activityId;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets if an activity is interactive or not
|
||||
*/
|
||||
function set_interactivity($pId, $actid, $value)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."activities set isInteractive='$value' where pId=$pId and activityId=$actid";
|
||||
$this->query($query);
|
||||
// If template does not exist then create template
|
||||
$this->compile_activity($pId,$actid);
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets if an activity is auto routed or not
|
||||
*/
|
||||
function set_autorouting($pId, $actid, $value)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."activities set isAutoRouted='$value' where pId=$pId and activityId=$actid";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Compiles activity
|
||||
*/
|
||||
function compile_activity($pId, $activityId)
|
||||
{
|
||||
$act_info = $this->get_activity($pId,$activityId);
|
||||
$actname = $act_info['normalized_name'];
|
||||
$pm = new ProcessManager($this->db);
|
||||
$proc_info = $pm->get_process($pId);
|
||||
$compiled_file = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/compiled/'.$act_info['normalized_name'].'.php';
|
||||
$template_file = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/templates/'.$actname.'.tpl';
|
||||
$user_file = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/activities/'.$actname.'.php';
|
||||
$pre_file = GALAXIA_LIBRARY.'/compiler/'.$act_info['type'].'_pre.php';
|
||||
$pos_file = GALAXIA_LIBRARY.'/compiler/'.$act_info['type'].'_pos.php';
|
||||
$fw = fopen($compiled_file,"wb");
|
||||
|
||||
// First of all add an include to to the shared code
|
||||
$shared_file = GALAXIA_PROCESSES.'/'.$proc_info['normalized_name'].'/code/shared.php';
|
||||
|
||||
fwrite($fw, '<'."?php include_once('$shared_file'); ?".'>'."\n");
|
||||
|
||||
// Before pre shared
|
||||
$fp = fopen(GALAXIA_LIBRARY.'/compiler/_shared_pre.php',"rb");
|
||||
while (!feof($fp)) {
|
||||
$data = fread($fp, 4096);
|
||||
fwrite($fw,$data);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
// Now get pre and pos files for the activity
|
||||
$fp = fopen($pre_file,"rb");
|
||||
while (!feof($fp)) {
|
||||
$data = fread($fp, 4096);
|
||||
fwrite($fw,$data);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
// Get the user data for the activity
|
||||
$fp = fopen($user_file,"rb");
|
||||
while (!feof($fp)) {
|
||||
$data = fread($fp, 4096);
|
||||
fwrite($fw,$data);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
// Get pos and write
|
||||
$fp = fopen($pos_file,"rb");
|
||||
while (!feof($fp)) {
|
||||
$data = fread($fp, 4096);
|
||||
fwrite($fw,$data);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
// Shared pos
|
||||
$fp = fopen(GALAXIA_LIBRARY.'/compiler/_shared_pos.php',"rb");
|
||||
while (!feof($fp)) {
|
||||
$data = fread($fp, 4096);
|
||||
fwrite($fw,$data);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
fclose($fw);
|
||||
|
||||
//Copy the templates
|
||||
|
||||
if($act_info['isInteractive']=='y' && !file_exists($template_file)) {
|
||||
$fw = fopen($template_file,'w');
|
||||
if (defined('GALAXIA_TEMPLATE_HEADER') && GALAXIA_TEMPLATE_HEADER) {
|
||||
fwrite($fw,GALAXIA_TEMPLATE_HEADER . "\n");
|
||||
}
|
||||
fclose($fw);
|
||||
}
|
||||
if($act_info['isInteractive']!='y' && file_exists($template_file)) {
|
||||
@unlink($template_file);
|
||||
if (GALAXIA_TEMPLATES && file_exists(GALAXIA_TEMPLATES.'/'.$proc_info['normalized_name']."/$actname.tpl")) {
|
||||
@unlink(GALAXIA_TEMPLATES.'/'.$proc_info['normalized_name']."/$actname.tpl");
|
||||
}
|
||||
}
|
||||
if (GALAXIA_TEMPLATES && file_exists($template_file)) {
|
||||
@copy($template_file,GALAXIA_TEMPLATES.'/'.$proc_info['normalized_name']."/$actname.tpl");
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Returns activity id by pid,name (activity names are unique)
|
||||
*/
|
||||
function _get_activity_id_by_name($pid,$name)
|
||||
{
|
||||
$name = addslashes($name);
|
||||
if($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pid and name='$name'")) {
|
||||
return($this->getOne("select activityId from ".GALAXIA_TABLE_PREFIX."activities where pId=$pid and name='$name'"));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\private Returns the activity shape
|
||||
*/
|
||||
function _get_activity_shape($type)
|
||||
{
|
||||
switch($type) {
|
||||
case "start":
|
||||
return "circle";
|
||||
case "end":
|
||||
return "doublecircle";
|
||||
case "activity":
|
||||
return "box";
|
||||
case "split":
|
||||
return "triangle";
|
||||
case "switch":
|
||||
return "diamond";
|
||||
case "join":
|
||||
return "invtriangle";
|
||||
case "standalone":
|
||||
return "hexagon";
|
||||
default:
|
||||
return "egg";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\private Returns true if a list contains unvisited nodes
|
||||
list members are asoc arrays containing id and visited
|
||||
*/
|
||||
function _list_has_unvisited_nodes($list)
|
||||
{
|
||||
foreach($list as $node) {
|
||||
if(!$node['visited']) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private Returns true if a node is in a list
|
||||
list members are asoc arrays containing id and visited
|
||||
*/
|
||||
function _node_in_list($node,$list)
|
||||
{
|
||||
foreach($list as $a_node) {
|
||||
if($node['id'] == $a_node['id']) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Normalizes an activity name
|
||||
*/
|
||||
function _normalize_name($name)
|
||||
{
|
||||
$name = str_replace(" ","_",$name);
|
||||
$name = preg_replace("/[^A-Za-z_]/",'',$name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Returns normalized name of an activity
|
||||
*/
|
||||
function _get_normalized_name($activityId)
|
||||
{
|
||||
return $this->getOne("select normalized_name from ".GALAXIA_TABLE_PREFIX."activities where activityId=$activityId");
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Labels nodes
|
||||
*/
|
||||
function _label_nodes($pId)
|
||||
{
|
||||
|
||||
|
||||
///an empty list of nodes starts the process
|
||||
$nodes = Array();
|
||||
// the end activity id
|
||||
$endId = $this->getOne("select activityId from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId and type='end'");
|
||||
// and the number of total nodes (=activities)
|
||||
$cant = $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId");
|
||||
$nodes[] = $endId;
|
||||
$label = $cant;
|
||||
$num = $cant;
|
||||
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."activities set flowNum=$cant+1 where pId=$pId";
|
||||
$this->query($query);
|
||||
|
||||
$seen = array();
|
||||
while(count($nodes)) {
|
||||
$newnodes = Array();
|
||||
foreach($nodes as $node) {
|
||||
// avoid endless loops
|
||||
if (isset($seen[$node])) continue;
|
||||
$seen[$node] = 1;
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."activities set flowNum=$num where activityId=$node";
|
||||
$this->query($query);
|
||||
$query = "select actFromId from ".GALAXIA_TABLE_PREFIX."transitions where actToId=".$node;
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$newnodes[] = $res['actFromId'];
|
||||
}
|
||||
}
|
||||
$num--;
|
||||
$nodes=Array();
|
||||
$nodes=$newnodes;
|
||||
|
||||
}
|
||||
|
||||
$min = $this->getOne("select min(flowNum) from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId");
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."activities set flowNum=flowNum-$min where pId=$pId";
|
||||
$this->query($query);
|
||||
|
||||
//$query = "update ".GALAXIA_TABLE_PREFIX."activities set flowNum=0 where flowNum=$cant+1";
|
||||
//$this->query($query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! Abstract class representing the base of the API
|
||||
//! An abstract class representing the API base
|
||||
/*!
|
||||
This class is derived by all the API classes so they get the
|
||||
database connection, database methods and the Observable interface.
|
||||
*/
|
||||
class BaseManager extends Base {
|
||||
|
||||
// Constructor receiving an ADODB database object.
|
||||
function BaseManager($db)
|
||||
{
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to BaseManager constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
} //end of class
|
||||
|
||||
?>
|
465
phpgwapi/inc/galaxia_workflow/src/ProcessManager/GraphViz.php
Normal file
465
phpgwapi/inc/galaxia_workflow/src/ProcessManager/GraphViz.php
Normal file
@ -0,0 +1,465 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PEAR :: Image :: GraphViz |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2002 Sebastian Bergmann <sb@sebastian-bergmann.de> and |
|
||||
// | Dr. Volker Göbbels <vmg@arachnion.de>. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.00 of the PHP License, |
|
||||
// | that is available at http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* PEAR::Image_GraphViz
|
||||
*
|
||||
* Purpose
|
||||
*
|
||||
* Allows for the creation of and the work with directed
|
||||
* and undirected graphs and their visualization with
|
||||
* AT&T's GraphViz tools. These can be found at
|
||||
* http://www.research.att.com/sw/tools/graphviz/
|
||||
*
|
||||
* Example
|
||||
*
|
||||
* require_once 'Image/GraphViz.php';
|
||||
* $graph = new Image_GraphViz();
|
||||
*
|
||||
* $graph->addNode('Node1', array('URL' => 'http://link1',
|
||||
* 'label' => 'This is a label',
|
||||
* 'shape' => 'box'
|
||||
* )
|
||||
* );
|
||||
* $graph->addNode('Node2', array('URL' => 'http://link2',
|
||||
* 'fontsize' => '14'
|
||||
* )
|
||||
* );
|
||||
* $graph->addNode('Node3', array('URL' => 'http://link3',
|
||||
* 'fontsize' => '20'
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* $graph->addEdge(array('Node1' => 'Node2'), array('label' => 'Edge Label'));
|
||||
* $graph->addEdge(array('Node1' => 'Node2'), array('color' => 'red'));
|
||||
*
|
||||
* $graph->image();
|
||||
*
|
||||
* @author Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
* Dr. Volker Göbbels <vmg@arachnion.de>
|
||||
* @package Image
|
||||
*/
|
||||
class Process_GraphViz {
|
||||
/**
|
||||
* Path to GraphViz/dot command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $dotCommand = 'dot';
|
||||
|
||||
var $pid;
|
||||
|
||||
/**
|
||||
* Path to GraphViz/neato command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $neatoCommand = 'neato';
|
||||
|
||||
/**
|
||||
* Representation of the graph
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $graph;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param boolean Directed (true) or undirected (false) graph.
|
||||
* @param array Attributes of the graph
|
||||
* @access public
|
||||
*/
|
||||
function Process_GraphViz($directed = true, $attributes = array()) {
|
||||
$this->setDirected($directed);
|
||||
$this->setAttributes($attributes);
|
||||
if (defined('GRAPHVIZ_BIN_DIR') && GRAPHVIZ_BIN_DIR) {
|
||||
$this->dotCommand = GRAPHVIZ_BIN_DIR.'/'.$this->dotCommand;
|
||||
$this->neatoCommand = GRAPHVIZ_BIN_DIR.'/'.$this->neatoCommand;
|
||||
}
|
||||
}
|
||||
|
||||
function set_pid($pid)
|
||||
{
|
||||
$this->pid = $pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output image of the graph in a given format.
|
||||
*
|
||||
* @param string Format of the output image.
|
||||
* This may be one of the formats supported by GraphViz.
|
||||
* @access public
|
||||
*/
|
||||
function image($format = 'png') {
|
||||
if ($file = $this->saveParsedGraph()) {
|
||||
$outputfile = $file . '.' . $format;
|
||||
$outputfile2 = $file . '.' . 'map';
|
||||
$command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
|
||||
$command .= " -T$format -o$outputfile $file";
|
||||
|
||||
@`$command`;
|
||||
$command = $this->dotCommand;
|
||||
$command.= " -Tcmap -o$outputfile2 $file";
|
||||
@`$command`;
|
||||
$fr = fopen($outputfile2,"r");
|
||||
$map = fread($fr,filesize($outputfile2));
|
||||
fclose($fr);
|
||||
@unlink($file);
|
||||
|
||||
switch ($format) {
|
||||
case 'gif':
|
||||
case 'jpg':
|
||||
case 'png':
|
||||
case 'svg':
|
||||
case 'wbmp': {
|
||||
header('Content-Type: image/' . $format);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pdf': {
|
||||
header('Content-Type: application/pdf');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
header('Content-Length: ' . filesize($outputfile));
|
||||
|
||||
$fp = fopen($outputfile, 'rb');
|
||||
|
||||
if ($fp) {
|
||||
echo fread($fp, filesize($outputfile));
|
||||
fclose($fp);
|
||||
@unlink($outputfile);
|
||||
}
|
||||
@unlink($outputfile2);
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
function image_and_map($format = 'png') {
|
||||
if ($file = $this->saveParsedGraph()) {
|
||||
$outputfile = $file . '.' . $format;
|
||||
$outputfile2 = $file . '.' . 'map';
|
||||
if(!isset($this->graph['directed'])) $this->graph['directed']=true;
|
||||
$command = $this->graph['directed'] ? $this->dotCommand : $this->neatoCommand;
|
||||
$command .= " -T$format -o $outputfile $file";
|
||||
@`$command`;
|
||||
|
||||
$command = $this->dotCommand;
|
||||
$command.= " -Tcmap -o $outputfile2 $file";
|
||||
@`$command`;
|
||||
@unlink($file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function map() {
|
||||
if ($file = $this->saveParsedGraph()) {
|
||||
|
||||
$outputfile2 = $file . '.' . 'map';
|
||||
|
||||
$command = $this->dotCommand;
|
||||
$command.= " -Tcmap -o$outputfile2 $file";
|
||||
@`$command`;
|
||||
$fr = fopen($outputfile2,"r");
|
||||
$map = fread($fr,filesize($outputfile2));
|
||||
fclose($fr);
|
||||
|
||||
@unlink($outputfile2);
|
||||
@unlink($file);
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cluster to the graph.
|
||||
*
|
||||
* @param string ID.
|
||||
* @param array Title.
|
||||
* @access public
|
||||
*/
|
||||
function addCluster($id, $title) {
|
||||
$this->graph['clusters'][$id] = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a note to the graph.
|
||||
*
|
||||
* @param string Name of the node.
|
||||
* @param array Attributes of the node.
|
||||
* @param string Group of the node.
|
||||
* @access public
|
||||
*/
|
||||
function addNode($name, $attributes = array(), $group = 'default') {
|
||||
$this->graph['nodes'][$group][$name] = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a node from the graph.
|
||||
*
|
||||
* @param Name of the node to be removed.
|
||||
* @access public
|
||||
*/
|
||||
function removeNode($name, $group = 'default') {
|
||||
if (isset($this->graph['nodes'][$group][$name])) {
|
||||
unset($this->graph['nodes'][$group][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an edge to the graph.
|
||||
*
|
||||
* @param array Start and End node of the edge.
|
||||
* @param array Attributes of the edge.
|
||||
* @access public
|
||||
*/
|
||||
function addEdge($edge, $attributes = array()) {
|
||||
if (is_array($edge)) {
|
||||
$from = key($edge);
|
||||
$to = $edge[$from];
|
||||
$id = $from . '_' . $to;
|
||||
|
||||
if (!isset($this->graph['edges'][$id])) {
|
||||
$this->graph['edges'][$id] = $edge;
|
||||
} else {
|
||||
$this->graph['edges'][$id] = array_merge(
|
||||
$this->graph['edges'][$id],
|
||||
$edge
|
||||
);
|
||||
}
|
||||
|
||||
if (is_array($attributes)) {
|
||||
if (!isset($this->graph['edgeAttributes'][$id])) {
|
||||
$this->graph['edgeAttributes'][$id] = $attributes;
|
||||
} else {
|
||||
$this->graph['edgeAttributes'][$id] = array_merge(
|
||||
$this->graph['edgeAttributes'][$id],
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an edge from the graph.
|
||||
*
|
||||
* @param array Start and End node of the edge to be removed.
|
||||
* @access public
|
||||
*/
|
||||
function removeEdge($edge) {
|
||||
if (is_array($edge)) {
|
||||
$from = key($edge);
|
||||
$to = $edge[$from];
|
||||
$id = $from . '_' . $to;
|
||||
|
||||
if (isset($this->graph['edges'][$id])) {
|
||||
unset($this->graph['edges'][$id]);
|
||||
}
|
||||
|
||||
if (isset($this->graph['edgeAttributes'][$id])) {
|
||||
unset($this->graph['edgeAttributes'][$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add attributes to the graph.
|
||||
*
|
||||
* @param array Attributes to be added to the graph.
|
||||
* @access public
|
||||
*/
|
||||
function addAttributes($attributes) {
|
||||
if (is_array($attributes)) {
|
||||
$this->graph['attributes'] = array_merge(
|
||||
$this->graph['attributes'],
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attributes of the graph.
|
||||
*
|
||||
* @param array Attributes to be set for the graph.
|
||||
* @access public
|
||||
*/
|
||||
function setAttributes($attributes) {
|
||||
if (is_array($attributes)) {
|
||||
$this->graph['attributes'] = $attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set directed/undirected flag for the graph.
|
||||
*
|
||||
* @param boolean Directed (true) or undirected (false) graph.
|
||||
* @access public
|
||||
*/
|
||||
function setDirected($directed) {
|
||||
if (is_bool($directed)) {
|
||||
$this->graph['directed'] = $directed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load graph from file.
|
||||
*
|
||||
* @param string File to load graph from.
|
||||
* @access public
|
||||
*/
|
||||
function load($file) {
|
||||
if ($serialized_graph = implode('', @file($file))) {
|
||||
$this->graph = unserialize($serialized_graph);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save graph to file.
|
||||
*
|
||||
* @param string File to save the graph to.
|
||||
* @return mixed File the graph was saved to, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function save($file = '') {
|
||||
$serialized_graph = serialize($this->graph);
|
||||
|
||||
if (empty($file)) {
|
||||
$file = tempnam('temp', 'graph_');
|
||||
}
|
||||
|
||||
if ($fp = @fopen($file, 'w')) {
|
||||
@fputs($fp, $serialized_graph);
|
||||
@fclose($fp);
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the graph into GraphViz markup.
|
||||
*
|
||||
* @return string GraphViz markup
|
||||
* @access public
|
||||
*/
|
||||
function parse() {
|
||||
$parsedGraph = "digraph G {\n";
|
||||
|
||||
if (isset($this->graph['attributes'])) {
|
||||
foreach ($this->graph['attributes'] as $key => $value) {
|
||||
$attributeList[] = $key . '="' . $value . '"';
|
||||
}
|
||||
|
||||
if (!empty($attributeList)) {
|
||||
$parsedGraph .= implode(',', $attributeList) . ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->graph['nodes'])) {
|
||||
foreach($this->graph['nodes'] as $group => $nodes) {
|
||||
if ($group != 'default') {
|
||||
$parsedGraph .= sprintf(
|
||||
"subgraph \"cluster_%s\" {\nlabel=\"%s\";\n",
|
||||
|
||||
$group,
|
||||
isset($this->graph['clusters'][$group]) ? $this->graph['clusters'][$group] : ''
|
||||
);
|
||||
}
|
||||
|
||||
foreach($nodes as $node => $attributes) {
|
||||
unset($attributeList);
|
||||
|
||||
foreach($attributes as $key => $value) {
|
||||
$attributeList[] = $key . '="' . $value . '"';
|
||||
}
|
||||
|
||||
if (!empty($attributeList)) {
|
||||
$parsedGraph .= sprintf(
|
||||
"\"%s\" [ %s ];\n",
|
||||
addslashes(stripslashes($node)),
|
||||
implode(',', $attributeList)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($group != 'default') {
|
||||
$parsedGraph .= "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->graph['edges'])) {
|
||||
foreach($this->graph['edges'] as $label => $node) {
|
||||
unset($attributeList);
|
||||
|
||||
$from = key($node);
|
||||
$to = $node[$from];
|
||||
|
||||
foreach($this->graph['edgeAttributes'][$label] as $key => $value) {
|
||||
$attributeList[] = $key . '="' . $value . '"';
|
||||
}
|
||||
|
||||
$parsedGraph .= sprintf(
|
||||
'"%s" -> "%s"',
|
||||
addslashes(stripslashes($from)),
|
||||
addslashes(stripslashes($to))
|
||||
);
|
||||
|
||||
if (!empty($attributeList)) {
|
||||
$parsedGraph .= sprintf(
|
||||
' [ %s ]',
|
||||
implode(',', $attributeList)
|
||||
);
|
||||
}
|
||||
|
||||
$parsedGraph .= ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $parsedGraph . "}\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Save GraphViz markup to file.
|
||||
*
|
||||
* @param string File to write the GraphViz markup to.
|
||||
* @return mixed File to which the GraphViz markup was
|
||||
* written, false on failure.
|
||||
* @access public
|
||||
*/
|
||||
function saveParsedGraph($file = '') {
|
||||
$parsedGraph = $this->parse();
|
||||
if (!empty($parsedGraph)) {
|
||||
|
||||
$file = GALAXIA_PROCESSES.'/'.$this->pid.'/graph/'.$this->pid;
|
||||
if ($fp = @fopen($file, 'w')) {
|
||||
@fputs($fp, $parsedGraph);
|
||||
@fclose($fp);
|
||||
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/ProcessManager/BaseManager.php');
|
||||
//!! InstanceManager
|
||||
//! A class to maniplate instances
|
||||
/*!
|
||||
This class is used to add,remove,modify and list
|
||||
instances.
|
||||
*/
|
||||
class InstanceManager extends BaseManager {
|
||||
|
||||
/*!
|
||||
Constructor takes a PEAR::Db object to be used
|
||||
to manipulate roles in the database.
|
||||
*/
|
||||
function InstanceManager($db)
|
||||
{
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to InstanceManager constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
function get_instance_activities($iid)
|
||||
{
|
||||
$query = "select ga.type,ga.isInteractive,ga.isAutoRouted,gi.pId,ga.activityId,ga.name,gi.instanceId,gi.status,gia.activityId,gia.user,gi.started,gia.status as actstatus from ".GALAXIA_TABLE_PREFIX."activities ga,".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where ga.activityId=gia.activityId and gi.instanceId=gia.instanceId and gi.instanceId=$iid";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
// Number of active instances
|
||||
$ret[] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function get_instance($iid)
|
||||
{
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."instances gi where instanceId=$iid";
|
||||
$result = $this->query($query);
|
||||
$res = $result->fetchRow();
|
||||
$res['workitems']=$this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."workitems where instanceId=$iid");
|
||||
return $res;
|
||||
}
|
||||
|
||||
function get_instance_properties($iid)
|
||||
{
|
||||
$prop = unserialize($this->getOne("select properties from ".GALAXIA_TABLE_PREFIX."instances gi where instanceId=$iid"));
|
||||
return $prop;
|
||||
}
|
||||
|
||||
function set_instance_properties($iid,&$prop)
|
||||
{
|
||||
$props = addslashes(serialize($prop));
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instances set properties='$props' where instanceId=$iid";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
function set_instance_owner($iid,$owner)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instances set owner='$owner' where instanceId=$iid";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
function set_instance_status($iid,$status)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instances set status='$status' where instanceId=$iid";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
function set_instance_destination($iid,$activityId)
|
||||
{
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."instance_activities where instanceId=$iid";
|
||||
$this->query($query);
|
||||
$query = "insert into ".GALAXIA_TABLE_PREFIX."instance_activities(instanceId,activityId,user,status)
|
||||
values($iid,$activityId,'*','running')";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
function set_instance_user($iid,$activityId,$user)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."instance_activities set user='$user', status='running' where instanceId=$iid and activityId=$activityId";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,720 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/ProcessManager/BaseManager.php');
|
||||
//!! ProcessManager
|
||||
//! A class to maniplate processes.
|
||||
/*!
|
||||
This class is used to add,remove,modify and list
|
||||
processes.
|
||||
*/
|
||||
class ProcessManager extends BaseManager {
|
||||
var $parser;
|
||||
var $tree;
|
||||
var $current;
|
||||
var $buffer;
|
||||
|
||||
/*!
|
||||
Constructor takes a PEAR::Db object to be used
|
||||
to manipulate roles in the database.
|
||||
*/
|
||||
function ProcessManager($db)
|
||||
{
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to ProcessManager constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets a process as active
|
||||
*/
|
||||
function activate_process($pId)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."processes set isActive='y' where pId=$pId";
|
||||
$this->query($query);
|
||||
$msg = sprintf(tra('Process %d has been activated'),$pId);
|
||||
$this->notify_all(3,$msg);
|
||||
}
|
||||
|
||||
/*!
|
||||
De-activates a process
|
||||
*/
|
||||
function deactivate_process($pId)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."processes set isActive='n' where pId=$pId";
|
||||
$this->query($query);
|
||||
$msg = sprintf(tra('Process %d has been deactivated'),$pId);
|
||||
$this->notify_all(3,$msg);
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates an XML representation of a process.
|
||||
*/
|
||||
function serialize_process($pId)
|
||||
{
|
||||
// <process>
|
||||
$out = '<process>'."\n";
|
||||
$proc_info = $this->get_process($pId);
|
||||
$procname = $proc_info['normalized_name'];
|
||||
$out.= ' <name>'.htmlspecialchars($proc_info['name']).'</name>'."\n";
|
||||
$out.= ' <isValid>'.htmlspecialchars($proc_info['isValid']).'</isValid>'."\n";
|
||||
$out.= ' <version>'.htmlspecialchars($proc_info['version']).'</version>'."\n";
|
||||
$out.= ' <isActive>'.htmlspecialchars($proc_info['isActive']).'</isActive>'."\n";
|
||||
$out.=' <description>'.htmlspecialchars($proc_info['description']).'</description>'."\n";
|
||||
$out.= ' <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['lastModif']).'</lastModif>'."\n";
|
||||
$out.= ' <sharedCode><![CDATA[';
|
||||
$fp=fopen(GALAXIA_PROCESSES."/$procname/code/shared.php","r");
|
||||
while(!feof($fp)) {
|
||||
$line=fread($fp,8192);
|
||||
$out.=$line;
|
||||
}
|
||||
fclose($fp);
|
||||
$out.= ' ]]></sharedCode>'."\n";
|
||||
// Now loop over activities
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId";
|
||||
$result = $this->query($query);
|
||||
$out.=' <activities>'."\n";
|
||||
$am = new ActivityManager($this->db);
|
||||
while($res = $result->fetchRow()) {
|
||||
$name = $res['normalized_name'];
|
||||
$out.=' <activity>'."\n";
|
||||
$out.=' <name>'.htmlspecialchars($res['name']).'</name>'."\n";
|
||||
$out.=' <type>'.htmlspecialchars($res['type']).'</type>'."\n";
|
||||
$out.=' <description>'.htmlspecialchars($res['description']).'</description>'."\n";
|
||||
$out.=' <lastModif>'.date("d/m/Y [h:i:s]",$res['lastModif']).'</lastModif>'."\n";
|
||||
$out.=' <isInteractive>'.$res['isInteractive'].'</isInteractive>'."\n";
|
||||
$out.=' <isAutoRouted>'.$res['isAutoRouted'].'</isAutoRouted>'."\n";
|
||||
$out.=' <roles>'."\n";
|
||||
|
||||
$roles = $am->get_activity_roles($res['activityId']);
|
||||
foreach($roles as $role) {
|
||||
$out.=' <role>'.htmlspecialchars($role['name']).'</role>'."\n";
|
||||
}
|
||||
$out.=' </roles>'."\n";
|
||||
$out.=' <code><![CDATA[';
|
||||
$fp=fopen(GALAXIA_PROCESSES."/$procname/code/activities/$name.php","r");
|
||||
while(!feof($fp)) {
|
||||
$line=fread($fp,8192);
|
||||
$out.=$line;
|
||||
}
|
||||
fclose($fp);
|
||||
$out.=' ]]></code>';
|
||||
if($res['isInteractive']=='y') {
|
||||
$out.=' <template><![CDATA[';
|
||||
$fp=fopen(GALAXIA_PROCESSES."/$procname/code/templates/$name.tpl","r");
|
||||
while(!feof($fp)) {
|
||||
$line=fread($fp,8192);
|
||||
$out.=$line;
|
||||
}
|
||||
fclose($fp);
|
||||
$out.=' ]]></template>';
|
||||
}
|
||||
$out.=' </activity>'."\n";
|
||||
}
|
||||
$out.=' </activities>'."\n";
|
||||
$out.=' <transitions>'."\n";
|
||||
$transitions = $am->get_process_transitions($pId);
|
||||
foreach($transitions as $tran) {
|
||||
$out.=' <transition>'."\n";
|
||||
$out.=' <from>'.htmlspecialchars($tran['actFromName']).'</from>'."\n";
|
||||
$out.=' <to>'.htmlspecialchars($tran['actToName']).'</to>'."\n";
|
||||
$out.=' </transition>'."\n";
|
||||
}
|
||||
$out.=' </transitions>'."\n";
|
||||
$out.= '</process>'."\n";
|
||||
//$fp = fopen(GALAXIA_PROCESSES."/$procname/$procname.xml","w");
|
||||
//fwrite($fp,$out);
|
||||
//fclose($fp);
|
||||
return $out;
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a process PHP data structure from its XML
|
||||
representation
|
||||
*/
|
||||
function unserialize_process($xml)
|
||||
{
|
||||
// Create SAX parser assign this object as base for handlers
|
||||
// handlers are private methods defined below.
|
||||
// keep contexts and parse
|
||||
$this->parser = xml_parser_create();
|
||||
xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0);
|
||||
xml_set_object($this->parser, $this);
|
||||
xml_set_element_handler($this->parser, "_start_element_handler", "_end_element_handler");
|
||||
xml_set_character_data_handler($this->parser, "_data_handler");
|
||||
$aux=Array(
|
||||
'name'=>'root',
|
||||
'children'=>Array(),
|
||||
'parent' => 0,
|
||||
'data'=>''
|
||||
);
|
||||
$this->tree[0]=$aux;
|
||||
$this->current=0;
|
||||
if (!xml_parse($this->parser, $xml, true)) {
|
||||
$error = sprintf("XML error: %s at line %d",
|
||||
xml_error_string(xml_get_error_code($this->parser)),
|
||||
xml_get_current_line_number($this->parser));
|
||||
trigger_error($error,E_USER_WARNING);
|
||||
}
|
||||
xml_parser_free($this->parser);
|
||||
// Now that we have the tree we can do interesting things
|
||||
//print_r($this->tree);
|
||||
$process=Array();
|
||||
$activities=Array();
|
||||
$transitions=Array();
|
||||
for($i=0;$i<count($this->tree[1]['children']);$i++) {
|
||||
// Process attributes
|
||||
$z=$this->tree[1]['children'][$i];
|
||||
$name = trim($this->tree[$z]['name']);
|
||||
if($name=='activities') {
|
||||
for($j=0;$j<count($this->tree[$z]['children']);$j++) {
|
||||
$z2 = $this->tree[$z]['children'][$j];
|
||||
// this is an activity $name = $this->tree[$z2]['name'];
|
||||
if($this->tree[$z2]['name']=='activity') {
|
||||
for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
|
||||
$z3 = $this->tree[$z2]['children'][$k];
|
||||
$name = trim($this->tree[$z3]['name']);
|
||||
$value= trim($this->tree[$z3]['data']);
|
||||
if($name=='roles') {
|
||||
$roles=Array();
|
||||
for($l=0;$l<count($this->tree[$z3]['children']);$l++) {
|
||||
$z4 = $this->tree[$z3]['children'][$l];
|
||||
$name = trim($this->tree[$z4]['name']);
|
||||
$data = trim($this->tree[$z4]['data']);
|
||||
$roles[]=$data;
|
||||
}
|
||||
} else {
|
||||
$aux[$name]=$value;
|
||||
//print("$name:$value<br/>");
|
||||
}
|
||||
}
|
||||
$aux['roles']=$roles;
|
||||
$activities[]=$aux;
|
||||
}
|
||||
}
|
||||
} elseif($name=='transitions') {
|
||||
for($j=0;$j<count($this->tree[$z]['children']);$j++) {
|
||||
$z2 = $this->tree[$z]['children'][$j];
|
||||
// this is an activity $name = $this->tree[$z2]['name'];
|
||||
if($this->tree[$z2]['name']=='transition') {
|
||||
for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
|
||||
$z3 = $this->tree[$z2]['children'][$k];
|
||||
$name = trim($this->tree[$z3]['name']);
|
||||
$value= trim($this->tree[$z3]['data']);
|
||||
if($name == 'from' || $name == 'to') {
|
||||
$aux[$name]=$value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$transitions[] = $aux;
|
||||
}
|
||||
} else {
|
||||
$value = trim($this->tree[$z]['data']);
|
||||
//print("$name is $value<br/>");
|
||||
$process[$name]=$value;
|
||||
}
|
||||
}
|
||||
$process['activities']=$activities;
|
||||
$process['transitions']=$transitions;
|
||||
return $process;
|
||||
}
|
||||
|
||||
/*!
|
||||
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.
|
||||
*/
|
||||
function import_process($data)
|
||||
{
|
||||
//Now the show begins
|
||||
$am = new ActivityManager($this->db);
|
||||
$rm = new RoleManager($this->db);
|
||||
// First create the process
|
||||
$vars = Array(
|
||||
'name' => $data['name'],
|
||||
'version' => $data['version'],
|
||||
'description' => $data['description'],
|
||||
'lastModif' => $data['lastModif'],
|
||||
'isActive' => $data['isActive'],
|
||||
'isValid' => $data['isValid']
|
||||
);
|
||||
$pid = $this->replace_process(0,$vars,false);
|
||||
//Put the shared code
|
||||
$proc_info = $this->get_process($pid);
|
||||
$procname = $proc_info['normalized_name'];
|
||||
$fp = fopen(GALAXIA_PROCESSES."/$procname/code/shared.php","w");
|
||||
fwrite($fp,$data['sharedCode']);
|
||||
fclose($fp);
|
||||
$actids = Array();
|
||||
// Foreach activity create activities
|
||||
foreach($data['activities'] as $activity) {
|
||||
$vars = Array(
|
||||
'name' => $activity['name'],
|
||||
'description' => $activity['description'],
|
||||
'type' => $activity['type'],
|
||||
'lastModif' => $activity['lastModif'],
|
||||
'isInteractive' => $activity['isInteractive'],
|
||||
'isAutoRouted' => $activity['isAutoRouted']
|
||||
);
|
||||
$actname=$am->_normalize_name($activity['name']);
|
||||
|
||||
$actid = $am->replace_activity($pid,0,$vars);
|
||||
$fp = fopen(GALAXIA_PROCESSES."/$procname/code/activities/$actname".'.php',"w");
|
||||
fwrite($fp,$activity['code']);
|
||||
fclose($fp);
|
||||
if($activity['isInteractive']=='y') {
|
||||
$fp = fopen(GALAXIA_PROCESSES."/$procname/code/templates/$actname".'.tpl',"w");
|
||||
fwrite($fp,$activity['template']);
|
||||
fclose($fp);
|
||||
}
|
||||
$actids[$activity['name']] = $am->_get_activity_id_by_name($pid,$activity['name']);
|
||||
$actname = $am->_normalize_name($activity['name']);
|
||||
$now = date("U");
|
||||
|
||||
foreach($activity['roles'] as $role) {
|
||||
$vars = Array(
|
||||
'name' => $role,
|
||||
'description' => $role,
|
||||
'lastModif' => $now,
|
||||
);
|
||||
if(!$rm->role_name_exists($pid,$role)) {
|
||||
$rid=$rm->replace_role($pid,0,$vars);
|
||||
} else {
|
||||
$rid = $rm->get_role_id($pid,$role);
|
||||
}
|
||||
if($actid && $rid) {
|
||||
$am->add_activity_role($actid,$rid);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($data['transitions'] as $tran) {
|
||||
$am->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]);
|
||||
}
|
||||
// FIXME: recompile activities seems to be needed here
|
||||
foreach ($actids as $name => $actid) {
|
||||
$am->compile_activity($pid,$actid);
|
||||
}
|
||||
// create a graph for the new process
|
||||
$am->build_process_graph($pid);
|
||||
unset($am);
|
||||
unset($rm);
|
||||
$msg = sprintf(tra('Process %s %s imported'),$proc_info['name'],$proc_info['version']);
|
||||
$this->notify_all(2,$msg);
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a new process based on an existing process
|
||||
changing the process version. By default the process
|
||||
is created as an unactive process and the version is
|
||||
by default a minor version of the process.
|
||||
*/
|
||||
///\todo copy process activities and so
|
||||
function new_process_version($pId, $minor=true)
|
||||
{
|
||||
$oldpid = $pId;
|
||||
$proc_info = $this->get_process($pId);
|
||||
$name = $proc_info['name'];
|
||||
if(!$proc_info) return false;
|
||||
// Now update the version
|
||||
$version = $this->_new_version($proc_info['version'],$minor);
|
||||
while($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."processes where name='$name' and version='$version'")) {
|
||||
$version = $this->_new_version($version,$minor);
|
||||
}
|
||||
// Make new versions unactive
|
||||
$proc_info['version'] = $version;
|
||||
$proc_info['isActive'] = 'n';
|
||||
// create a new process, but don't create start/end activities
|
||||
$pid = $this->replace_process(0, $proc_info, false);
|
||||
// And here copy all the activities & so
|
||||
$am = new ActivityManager($this->db);
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activities where pId=$oldpid";
|
||||
$result = $this->query($query);
|
||||
$newaid = array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$oldaid = $res['activityId'];
|
||||
$newaid[$oldaid] = $am->replace_activity($pid,0,$res);
|
||||
}
|
||||
// create transitions
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."transitions where pId=$oldpid";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
if (empty($newaid[$res['actFromId']]) || empty($newaid[$res['actToId']])) {
|
||||
continue;
|
||||
}
|
||||
$am->add_transition($pid,$newaid[$res['actFromId']],$newaid[$res['actToId']]);
|
||||
}
|
||||
// create roles
|
||||
$rm = new RoleManager($this->db);
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."roles where pId=$oldpid";
|
||||
$result = $this->query($query);
|
||||
$newrid = array();
|
||||
while($res = $result->fetchRow()) {
|
||||
if(!$rm->role_name_exists($pid,$res['name'])) {
|
||||
$rid=$rm->replace_role($pid,0,$res);
|
||||
} else {
|
||||
$rid = $rm->get_role_id($pid,$res['name']);
|
||||
}
|
||||
$newrid[$res['roleId']] = $rid;
|
||||
}
|
||||
// map users to roles
|
||||
if (count($newrid) > 0) {
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."user_roles where pId=$oldpid";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
if (empty($newrid[$res['roleId']])) {
|
||||
continue;
|
||||
}
|
||||
$rm->map_user_to_role($pid,$res['user'],$newrid[$res['roleId']]);
|
||||
}
|
||||
}
|
||||
// add roles to activities
|
||||
if (count($newaid) > 0 && count($newrid ) > 0) {
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."activity_roles where activityId in (" . join(', ',array_keys($newaid)) . ")";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
if (empty($newaid[$res['activityId']]) || empty($newrid[$res['roleId']])) {
|
||||
continue;
|
||||
}
|
||||
$am->add_activity_role($newaid[$res['activityId']],$newrid[$res['roleId']]);
|
||||
}
|
||||
}
|
||||
|
||||
//Now since we are copying a process we should copy
|
||||
//the old directory structure to the new directory
|
||||
$oldname = $proc_info['normalized_name'];
|
||||
$newname = $this->_get_normalized_name($pid);
|
||||
$this->_rec_copy(GALAXIA_PROCESSES."/$oldname",GALAXIA_PROCESSES."/$newname");
|
||||
|
||||
// create a graph for the new process
|
||||
$am->build_process_graph($pid);
|
||||
return $pid;
|
||||
}
|
||||
|
||||
/*!
|
||||
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
|
||||
create new versions of an existing process. The application must use this
|
||||
method to ensure that processes have unique names.
|
||||
*/
|
||||
function process_name_exists($name,$version)
|
||||
{
|
||||
$name = addslashes($this->_normalize_name($name,$version));
|
||||
return $this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."processes where normalized_name='$name'");
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Gets a process by pId. Fields are returned as an asociative array
|
||||
*/
|
||||
function get_process($pId)
|
||||
{
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."processes where pId=$pId";
|
||||
$result = $this->query($query);
|
||||
if(!$result->numRows()) return false;
|
||||
$res = $result->fetchRow();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
Lists processes (all processes)
|
||||
*/
|
||||
function list_processes($offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid=" where ((name like ?) or (description like ?))";
|
||||
$bindvars = array($findesc,$findesc);
|
||||
} else {
|
||||
$mid="";
|
||||
$bindvars = array();
|
||||
}
|
||||
if($where) {
|
||||
if($mid) {
|
||||
$mid.= " and ($where) ";
|
||||
} else {
|
||||
$mid.= " where ($where) ";
|
||||
}
|
||||
}
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."processes $mid order by $sort_mode";
|
||||
$query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."processes $mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Marks a process as an invalid process
|
||||
*/
|
||||
function invalidate_process($pid)
|
||||
{
|
||||
$query = "update ".GALAXIA_TABLE_PREFIX."processes set isValid='n' where pId=$pid";
|
||||
$this->query($query);
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes a process by pId
|
||||
*/
|
||||
function remove_process($pId)
|
||||
{
|
||||
$this->deactivate_process($pId);
|
||||
$name = $this->_get_normalized_name($pId);
|
||||
$aM = new ActivityManager($this->db);
|
||||
// Remove process activities
|
||||
$query = "select activityId from ".GALAXIA_TABLE_PREFIX."activities where pId=$pId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$aM->remove_activity($pId,$res['activityId']);
|
||||
}
|
||||
|
||||
// Remove process roles
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."roles where pId=$pId";
|
||||
$this->query($query);
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."user_roles where pId=$pId";
|
||||
$this->query($query);
|
||||
|
||||
// Remove the directory structure
|
||||
if (!empty($name) && is_dir(GALAXIA_PROCESSES."/$name")) {
|
||||
$this->_remove_directory(GALAXIA_PROCESSES."/$name",true);
|
||||
}
|
||||
if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES."/$name")) {
|
||||
$this->_remove_directory(GALAXIA_TEMPLATES."/$name",true);
|
||||
}
|
||||
// And finally remove the proc
|
||||
$query = "delete from ".GALAXIA_TABLE_PREFIX."processes where pId=$pId";
|
||||
$this->query($query);
|
||||
$msg = sprintf(tra('Process %s removed'),$name);
|
||||
$this->notify_all(5,$msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Updates or inserts a new process in the database, $vars is an asociative
|
||||
array containing the fields to update or to insert as needed.
|
||||
$pId is the processId
|
||||
*/
|
||||
function replace_process($pId, $vars, $create = true)
|
||||
{
|
||||
$TABLE_NAME = GALAXIA_TABLE_PREFIX."processes";
|
||||
$now = date("U");
|
||||
$vars['lastModif']=$now;
|
||||
$vars['normalized_name'] = $this->_normalize_name($vars['name'],$vars['version']);
|
||||
foreach($vars as $key=>$value)
|
||||
{
|
||||
$vars[$key]=addslashes($value);
|
||||
}
|
||||
|
||||
if($pId) {
|
||||
// update mode
|
||||
$old_proc = $this->get_process($pId);
|
||||
$first = true;
|
||||
$query ="update $TABLE_NAME set";
|
||||
foreach($vars as $key=>$value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
|
||||
$query.= " $key=$value ";
|
||||
$first = false;
|
||||
}
|
||||
$query .= " where pId=$pId ";
|
||||
$this->query($query);
|
||||
// Note that if the name is being changed then
|
||||
// the directory has to be renamed!
|
||||
$oldname = $old_proc['normalized_name'];
|
||||
$newname = $vars['normalized_name'];
|
||||
if ($newname != $oldname) {
|
||||
rename(GALAXIA_PROCESSES."/$oldname",GALAXIA_PROCESSES."/$newname");
|
||||
}
|
||||
$msg = sprintf(tra('Process %s has been updated'),$vars['name']);
|
||||
$this->notify_all(3,$msg);
|
||||
} else {
|
||||
unset($vars['pId']);
|
||||
// insert mode
|
||||
$name = $this->_normalize_name($vars['name'],$vars['version']);
|
||||
$this->_create_directory_structure($name);
|
||||
$first = true;
|
||||
$query = "insert into $TABLE_NAME(";
|
||||
foreach(array_keys($vars) as $key) {
|
||||
if(!$first) $query.= ',';
|
||||
$query.= "$key";
|
||||
$first = false;
|
||||
}
|
||||
$query .=") values(";
|
||||
$first = true;
|
||||
foreach(array_values($vars) as $value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
|
||||
$query.= "$value";
|
||||
$first = false;
|
||||
}
|
||||
$query .=")";
|
||||
$this->query($query);
|
||||
$pId = $this->getOne("select max(pId) from $TABLE_NAME where lastModif=$now");
|
||||
// Now automatically add a start and end activity
|
||||
// unless importing ($create = false)
|
||||
if($create) {
|
||||
$aM= new ActivityManager($this->db);
|
||||
$vars1 = Array(
|
||||
'name' => 'start',
|
||||
'description' => 'default start activity',
|
||||
'type' => 'start',
|
||||
'isInteractive' => 'y',
|
||||
'isAutoRouted' => 'y'
|
||||
);
|
||||
$vars2 = Array(
|
||||
'name' => 'end',
|
||||
'description' => 'default end activity',
|
||||
'type' => 'end',
|
||||
'isInteractive' => 'n',
|
||||
'isAutoRouted' => 'y'
|
||||
);
|
||||
|
||||
$aM->replace_activity($pId,0,$vars1);
|
||||
$aM->replace_activity($pId,0,$vars2);
|
||||
}
|
||||
$msg = sprintf(tra('Process %s has been created'),$vars['name']);
|
||||
$this->notify_all(4,$msg);
|
||||
}
|
||||
// Get the id
|
||||
return $pId;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Gets the normalized name of a process by pid
|
||||
*/
|
||||
function _get_normalized_name($pId)
|
||||
{
|
||||
$info = $this->get_process($pId);
|
||||
return $info['normalized_name'];
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Normalizes a process name
|
||||
*/
|
||||
function _normalize_name($name, $version)
|
||||
{
|
||||
$name = $name.'_'.$version;
|
||||
$name = str_replace(" ","_",$name);
|
||||
$name = preg_replace("/[^0-9A-Za-z\_]/",'',$name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Generates a new minor version number
|
||||
*/
|
||||
function _new_version($version,$minor=true)
|
||||
{
|
||||
$parts = explode('.',$version);
|
||||
if($minor) {
|
||||
$parts[count($parts)-1]++;
|
||||
} else {
|
||||
$parts[0]++;
|
||||
for ($i = 1; $i < count($parts); $i++) {
|
||||
$parts[$i] = 0;
|
||||
}
|
||||
}
|
||||
return implode('.',$parts);
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Creates directory structure for process
|
||||
*/
|
||||
function _create_directory_structure($name)
|
||||
{
|
||||
// Create in processes a directory with this name
|
||||
mkdir(GALAXIA_PROCESSES."/$name",0770);
|
||||
mkdir(GALAXIA_PROCESSES."/$name/graph",0770);
|
||||
mkdir(GALAXIA_PROCESSES."/$name/code",0770);
|
||||
mkdir(GALAXIA_PROCESSES."/$name/compiled",0770);
|
||||
mkdir(GALAXIA_PROCESSES."/$name/code/activities",0770);
|
||||
mkdir(GALAXIA_PROCESSES."/$name/code/templates",0770);
|
||||
if (GALAXIA_TEMPLATES) {
|
||||
mkdir(GALAXIA_TEMPLATES."/$name",0770);
|
||||
}
|
||||
// Create shared file
|
||||
$fp = fopen(GALAXIA_PROCESSES."/$name/code/shared.php","w");
|
||||
fwrite($fp,'<'.'?'.'php'."\n".'?'.'>');
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/*!
|
||||
\private
|
||||
Removes a directory recursively
|
||||
*/
|
||||
function _remove_directory($dir,$rec=false)
|
||||
{
|
||||
// Prevent a disaster
|
||||
if(trim($dir) == '/'|| trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates/') return false;
|
||||
$h = opendir($dir);
|
||||
while(($file = readdir($h)) != false) {
|
||||
if(is_file($dir.'/'.$file)) {
|
||||
@unlink($dir.'/'.$file);
|
||||
} else {
|
||||
if($rec && $file != '.' && $file != '..') {
|
||||
$this->_remove_directory($dir.'/'.$file, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($h);
|
||||
@rmdir($dir);
|
||||
@unlink($dir);
|
||||
}
|
||||
|
||||
function _rec_copy($dir1,$dir2)
|
||||
{
|
||||
@mkdir($dir2,0777);
|
||||
$h = opendir($dir1);
|
||||
while(($file = readdir($h)) !== false) {
|
||||
if(is_file($dir1.'/'.$file)) {
|
||||
copy($dir1.'/'.$file,$dir2.'/'.$file);
|
||||
} else {
|
||||
if($file != '.' && $file != '..') {
|
||||
$this->_rec_copy($dir1.'/'.$file, $dir2.'/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($h);
|
||||
}
|
||||
|
||||
function _start_element_handler($parser,$element,$attribs)
|
||||
{
|
||||
$aux=Array('name'=>$element,
|
||||
'data'=>'',
|
||||
'parent' => $this->current,
|
||||
'children'=>Array());
|
||||
$i = count($this->tree);
|
||||
$this->tree[$i] = $aux;
|
||||
|
||||
$this->tree[$this->current]['children'][]=$i;
|
||||
$this->current=$i;
|
||||
}
|
||||
|
||||
|
||||
function _end_element_handler($parser,$element)
|
||||
{
|
||||
//when a tag ends put text
|
||||
$this->tree[$this->current]['data']=$this->buffer;
|
||||
$this->buffer='';
|
||||
$this->current=$this->tree[$this->current]['parent'];
|
||||
}
|
||||
|
||||
|
||||
function _data_handler($parser,$data)
|
||||
{
|
||||
$this->buffer.=$data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
213
phpgwapi/inc/galaxia_workflow/src/ProcessManager/RoleManager.php
Normal file
213
phpgwapi/inc/galaxia_workflow/src/ProcessManager/RoleManager.php
Normal file
@ -0,0 +1,213 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/ProcessManager/BaseManager.php');
|
||||
//!! RoleManager
|
||||
//! A class to maniplate roles.
|
||||
/*!
|
||||
This class is used to add,remove,modify and list
|
||||
roles used in the Workflow engine.
|
||||
Roles are managed in a per-process level, each
|
||||
role belongs to some process.
|
||||
*/
|
||||
|
||||
/*!TODO
|
||||
Add a method to check if a role name exists in a process (to be used
|
||||
to prevent duplicate names)
|
||||
*/
|
||||
|
||||
class RoleManager extends BaseManager {
|
||||
|
||||
/*!
|
||||
Constructor takes a PEAR::Db object to be used
|
||||
to manipulate roles in the database.
|
||||
*/
|
||||
function RoleManager($db)
|
||||
{
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to RoleManager constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
function get_role_id($pid,$name)
|
||||
{
|
||||
$name = addslashes($name);
|
||||
return ($this->getOne("select roleId from ".GALAXIA_TABLE_PREFIX."roles where name='$name' and pId=$pid"));
|
||||
}
|
||||
|
||||
/*!
|
||||
Gets a role fields are returned as an asociative array
|
||||
*/
|
||||
function get_role($pId, $roleId)
|
||||
{
|
||||
$query = "select * from `".GALAXIA_TABLE_PREFIX."roles` where `pId`=? and `roleId`=?";
|
||||
$result = $this->query($query,array($pId, $roleId));
|
||||
$res = $result->fetchRow();
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
Indicates if a role exists
|
||||
*/
|
||||
function role_name_exists($pid,$name)
|
||||
{
|
||||
$name = addslashes($name);
|
||||
return ($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."roles where pId=$pid and name='$name'"));
|
||||
}
|
||||
|
||||
/*!
|
||||
Maps a user to a role
|
||||
*/
|
||||
function map_user_to_role($pId,$user,$roleId)
|
||||
{
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."user_roles` where `roleId`=? and `user`=?";
|
||||
$this->query($query,array($roleId, $user));
|
||||
$query = "insert into `".GALAXIA_TABLE_PREFIX."user_roles`(`pId`, `user`, `roleId`) values(?,?,?)";
|
||||
$this->query($query,array($pId,$user,$roleId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes a mapping
|
||||
*/
|
||||
function remove_mapping($user,$roleId)
|
||||
{
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."user_roles` where `user`=? and `roleId`=?";
|
||||
$this->query($query,array($user, $roleId));
|
||||
}
|
||||
|
||||
/*!
|
||||
List mappings
|
||||
*/
|
||||
function list_mappings($pId,$offset,$maxRecords,$sort_mode,$find) {
|
||||
$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
if($find) {
|
||||
// no more quoting here - this is done in bind vars already
|
||||
$findesc = '%'.$find.'%';
|
||||
$query = "select `name`,`gr`.`roleId`,`user` from `".GALAXIA_TABLE_PREFIX."roles` gr, `".GALAXIA_TABLE_PREFIX."user_roles` gur where `gr`.`roleId`=`gur`.`roleId` and `gur`.`pId`=? and ((`name` like ?) or (`user` like ?) or (`description` like ?)) order by $sort_mode";
|
||||
$result = $this->query($query,array($pId,$findesc,$findesc,$findesc), $maxRecords, $offset);
|
||||
$query_cant = "select count(*) from `".GALAXIA_TABLE_PREFIX."roles` gr, `".GALAXIA_TABLE_PREFIX."user_roles` gur where `gr`.`roleId`=`gur`.`roleId` and `gur`.`pId`=? and ((`name` like ?) or (`user` like ?) or (`description` like ?))";
|
||||
$cant = $this->getOne($query_cant,array($pId,$findesc,$findesc,$findesc));
|
||||
} else {
|
||||
$query = "select `name`,`gr`.`roleId`,`user` from `".GALAXIA_TABLE_PREFIX."roles` gr, `".GALAXIA_TABLE_PREFIX."user_roles` gur where `gr`.`roleId`=`gur`.`roleId` and `gur`.`pId`=? order by $sort_mode";
|
||||
$result = $this->query($query,array($pId), $maxRecords, $offset);
|
||||
$query_cant = "select count(*) from `".GALAXIA_TABLE_PREFIX."roles` gr, `".GALAXIA_TABLE_PREFIX."user_roles` gur where `gr`.`roleId`=`gur`.`roleId` and `gur`.`pId`=?";
|
||||
$cant = $this->getOne($query_cant,array($pId));
|
||||
}
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Lists roles at a per-process level
|
||||
*/
|
||||
function list_roles($pId,$offset,$maxRecords,$sort_mode,$find,$where='')
|
||||
{
|
||||
$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
if($find) {
|
||||
// no more quoting here - this is done in bind vars already
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid=" where pId=? and ((name like ?) or (description like ?))";
|
||||
$bindvars = array($pId,$findesc,$findesc);
|
||||
} else {
|
||||
$mid=" where pId=? ";
|
||||
$bindvars = array($pId);
|
||||
}
|
||||
if($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."roles $mid order by $sort_mode";
|
||||
$query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."roles $mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Removes a role.
|
||||
*/
|
||||
function remove_role($pId, $roleId)
|
||||
{
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."roles` where `pId`=? and `roleId`=?";
|
||||
$this->query($query,array($pId, $roleId));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."activity_roles` where `roleId`=?";
|
||||
$this->query($query,array($roleId));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."user_roles` where `roleId`=?";
|
||||
$this->query($query,array($roleId));
|
||||
}
|
||||
|
||||
/*!
|
||||
Updates or inserts a new role in the database, $vars is an asociative
|
||||
array containing the fields to update or to insert as needed.
|
||||
$pId is the processId
|
||||
$roleId is the roleId
|
||||
*/
|
||||
function replace_role($pId, $roleId, $vars)
|
||||
{
|
||||
$TABLE_NAME = GALAXIA_TABLE_PREFIX."roles";
|
||||
$now = date("U");
|
||||
$vars['lastModif']=$now;
|
||||
$vars['pId']=$pId;
|
||||
|
||||
foreach($vars as $key=>$value)
|
||||
{
|
||||
$vars[$key]=addslashes($value);
|
||||
}
|
||||
|
||||
if($roleId) {
|
||||
// update mode
|
||||
$first = true;
|
||||
$query ="update $TABLE_NAME set";
|
||||
foreach($vars as $key=>$value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)) $value="'".$value."'";
|
||||
$query.= " $key=$value ";
|
||||
$first = false;
|
||||
}
|
||||
$query .= " where pId=$pId and roleId=$roleId ";
|
||||
$this->query($query);
|
||||
} else {
|
||||
$name = $vars['name'];
|
||||
if ($this->getOne("select count(*) from ".GALAXIA_TABLE_PREFIX."roles where pId=$pId and name='$name'")) {
|
||||
return false;
|
||||
}
|
||||
unset($vars['roleId']);
|
||||
// insert mode
|
||||
$first = true;
|
||||
$query = "insert into $TABLE_NAME(";
|
||||
foreach(array_keys($vars) as $key) {
|
||||
if(!$first) $query.= ',';
|
||||
$query.= "$key";
|
||||
$first = false;
|
||||
}
|
||||
$query .=") values(";
|
||||
$first = true;
|
||||
foreach(array_values($vars) as $value) {
|
||||
if(!$first) $query.= ',';
|
||||
if(!is_numeric($value)) $value="'".$value."'";
|
||||
$query.= "$value";
|
||||
$first = false;
|
||||
}
|
||||
$query .=")";
|
||||
$this->query($query);
|
||||
$roleId = $this->getOne("select max(roleId) from $TABLE_NAME where pId=$pId and lastModif=$now");
|
||||
}
|
||||
// Get the id
|
||||
return $roleId;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/common/Base.php');
|
||||
//!! ProcessMonitor
|
||||
//! ProcessMonitor class
|
||||
/*!
|
||||
This class provides methods for use in typical monitoring scripts
|
||||
*/
|
||||
class ProcessMonitor extends Base {
|
||||
|
||||
function monitor_stats() {
|
||||
$res = Array();
|
||||
$res['active_processes'] = $this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."processes` where `isActive`=?",array('y'));
|
||||
$res['processes'] = $this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."processes`");
|
||||
$result = $this->query("select distinct(`pId`) from `".GALAXIA_TABLE_PREFIX."instances` where `status`=?",array('active'));
|
||||
$res['running_processes'] = $result->numRows();
|
||||
// get the number of instances per status
|
||||
$query = "select status, count(*) as num_instances from ".GALAXIA_TABLE_PREFIX."instances group by status";
|
||||
$result = $this->query($query);
|
||||
$status = array();
|
||||
while($info = $result->fetchRow()) {
|
||||
$status[$info['status']] = $info['num_instances'];
|
||||
}
|
||||
$res['active_instances'] = isset($status['active']) ? $status['active'] : 0;
|
||||
$res['completed_instances'] = isset($status['completed']) ? $status['completed'] : 0;
|
||||
$res['exception_instances'] = isset($status['exception']) ? $status['exception'] : 0;
|
||||
$res['aborted_instances'] = isset($status['aborted']) ? $status['aborted'] : 0;
|
||||
return $res;
|
||||
}
|
||||
|
||||
function update_instance_status($iid,$status) {
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instances` set `status`=? where `instanceId`=?";
|
||||
$this->query($query,array($status,$iid));
|
||||
}
|
||||
|
||||
function update_instance_activity_status($iid,$activityId,$status) {
|
||||
$query = "update `".GALAXIA_TABLE_PREFIX."instance_activities` set `status`=? where `instanceId`=? and `activityId`=?";
|
||||
$this->query($query,array($status,$iid,$activityId));
|
||||
}
|
||||
|
||||
function remove_instance($iid) {
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
}
|
||||
|
||||
function remove_aborted() {
|
||||
$query="select `instanceId` from `".GALAXIA_TABLE_PREFIX."instances` where `status`=?";
|
||||
$result = $this->query($query,array('aborted'));
|
||||
while($res = $result->fetchRow()) {
|
||||
$iid = $res['instanceId'];
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
}
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `status`=?";
|
||||
$this->query($query,array('aborted'));
|
||||
}
|
||||
|
||||
function remove_all($pId) {
|
||||
$query="select `instanceId` from `".GALAXIA_TABLE_PREFIX."instances` where `pId`=?";
|
||||
$result = $this->query($query,array($pId));
|
||||
while($res = $result->fetchRow()) {
|
||||
$iid = $res['instanceId'];
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instance_activities` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?";
|
||||
$this->query($query,array($iid));
|
||||
}
|
||||
$query = "delete from `".GALAXIA_TABLE_PREFIX."instances` where `pId`=?";
|
||||
$this->query($query,array($pId));
|
||||
}
|
||||
|
||||
|
||||
function monitor_list_processes($offset,$maxRecords,$sort_mode,$find,$where='') {
|
||||
$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid=" where ((name like ?) or (description like ?))";
|
||||
$bindvars = array($findesc,$findesc);
|
||||
} else {
|
||||
$mid="";
|
||||
$bindvars = array();
|
||||
}
|
||||
if($where) {
|
||||
if($mid) {
|
||||
$mid.= " and ($where) ";
|
||||
} else {
|
||||
$mid.= " where ($where) ";
|
||||
}
|
||||
}
|
||||
// get the requested processes
|
||||
$query = "select * from ".GALAXIA_TABLE_PREFIX."processes $mid order by $sort_mode";
|
||||
$query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."processes $mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$pId = $res['pId'];
|
||||
// Number of active instances
|
||||
$res['active_instances'] = 0;
|
||||
// Number of exception instances
|
||||
$res['exception_instances'] = 0;
|
||||
// Number of completed instances
|
||||
$res['completed_instances'] = 0;
|
||||
// Number of aborted instances
|
||||
$res['aborted_instances'] = 0;
|
||||
$res['all_instances'] = 0;
|
||||
// Number of activities
|
||||
$res['activities'] = 0;
|
||||
$ret[$pId] = $res;
|
||||
}
|
||||
if (count($ret) < 1) {
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
// get number of instances and timing statistics per process and status
|
||||
$query = "select pId, status, count(*) as num_instances,
|
||||
min(ended - started) as min_time, avg(ended - started) as avg_time, max(ended - started) as max_time
|
||||
from ".GALAXIA_TABLE_PREFIX."instances where pId in (" . join(', ', array_keys($ret)) . ") group by pId, status";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$pId = $res['pId'];
|
||||
if (!isset($ret[$pId])) continue;
|
||||
switch ($res['status']) {
|
||||
case 'active':
|
||||
$ret[$pId]['active_instances'] = $res['num_instances'];
|
||||
$ret[$pId]['all_instances'] += $res['num_instances'];
|
||||
break;
|
||||
case 'completed':
|
||||
$ret[$pId]['completed_instances'] = $res['num_instances'];
|
||||
$ret[$pId]['all_instances'] += $res['num_instances'];
|
||||
$ret[$pId]['duration'] = array('min' => $res['min_time'], 'avg' => $res['avg_time'], 'max' => $res['max_time']);
|
||||
break;
|
||||
case 'exception':
|
||||
$ret[$pId]['exception_instances'] = $res['num_instances'];
|
||||
$ret[$pId]['all_instances'] += $res['num_instances'];
|
||||
break;
|
||||
case 'aborted':
|
||||
$ret[$pId]['aborted_instances'] = $res['num_instances'];
|
||||
$ret[$pId]['all_instances'] += $res['num_instances'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// get number of activities per process
|
||||
$query = "select pId, count(*) as num_activities
|
||||
from ".GALAXIA_TABLE_PREFIX."activities
|
||||
where pId in (" . join(', ', array_keys($ret)) . ")
|
||||
group by pId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
$pId = $res['pId'];
|
||||
if (!isset($ret[$pId])) continue;
|
||||
$ret[$pId]['activities'] = $res['num_activities'];
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function monitor_list_activities($offset,$maxRecords,$sort_mode,$find,$where='') {
|
||||
$sort_mode = $this->convert_sortmode($sort_mode);
|
||||
if($find) {
|
||||
$findesc = '%'.$find.'%';
|
||||
$mid=" where ((ga.name like ?) or (ga.description like ?))";
|
||||
$bindvars = array($findesc,$findesc);
|
||||
} else {
|
||||
$mid="";
|
||||
$bindvars = array();
|
||||
}
|
||||
if($where) {
|
||||
$where = preg_replace('/pId/', 'ga.pId', $where);
|
||||
if($mid) {
|
||||
$mid.= " and ($where) ";
|
||||
} else {
|
||||
$mid.= " where ($where) ";
|
||||
}
|
||||
}
|
||||
$query = "select gp.`name` as `procname`, gp.`version`, ga.*
|
||||
from ".GALAXIA_TABLE_PREFIX."activities ga
|
||||
left join ".GALAXIA_TABLE_PREFIX."processes gp on gp.pId=ga.pId
|
||||
$mid order by $sort_mode";
|
||||
$query_cant = "select count(*) from ".GALAXIA_TABLE_PREFIX."activities ga $mid";
|
||||
$result = $this->query($query,$bindvars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$bindvars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
// Number of active instances
|
||||
$aid = $res['activityId'];
|
||||
$res['active_instances']=$this->getOne("select count(gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.instanceId=gia.instanceId and gia.activitYId=$aid and gi.status='active' and pId=".$res['pId']);
|
||||
// activities of completed instances are all removed from the instance_activities table for some reason, so we need to look at workitems
|
||||
$res['completed_instances']=$this->getOne("select count(distinct gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."workitems gw where gi.instanceId=gw.instanceId and gw.activityId=$aid and gi.status='completed' and pId=".$res['pId']);
|
||||
// activities of aborted instances are all removed from the instance_activities table for some reason, so we need to look at workitems
|
||||
$res['aborted_instances']=$this->getOne("select count(distinct gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."workitems gw where gi.instanceId=gw.instanceId and gw.activityId=$aid and gi.status='aborted' and pId=".$res['pId']);
|
||||
$res['exception_instances']=$this->getOne("select count(gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.instanceId=gia.instanceId and gia.activityId=$aid and gi.status='exception' and pId=".$res['pId']);
|
||||
$res['act_running_instances']=$this->getOne("select count(gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.instanceId=gia.instanceId and gia.activityId=$aid and gia.status='running' and pId=".$res['pId']);
|
||||
// completed activities are removed from the instance_activities table unless they're part of a split for some reason, so this won't work
|
||||
// $res['act_completed_instances']=$this->getOne("select count(gi.instanceId) from ".GALAXIA_TABLE_PREFIX."instances gi,".GALAXIA_TABLE_PREFIX."instance_activities gia where gi.instanceId=gia.instanceId and gia.activityId=$aid and gia.status='completed' and pId=".$res['pId']);
|
||||
$res['act_completed_instances'] = 0;
|
||||
$ret[$aid] = $res;
|
||||
}
|
||||
if (count($ret) < 1) {
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
$query = "select activityId, count(distinct instanceId) as num_instances, min(ended - started) as min_time, avg(ended - started) as avg_time, max(ended - started) as max_time
|
||||
from ".GALAXIA_TABLE_PREFIX."workitems
|
||||
where activityId in (" . join(', ', array_keys($ret)) . ")
|
||||
group by activityId";
|
||||
$result = $this->query($query);
|
||||
while($res = $result->fetchRow()) {
|
||||
// Number of active instances
|
||||
$aid = $res['activityId'];
|
||||
if (!isset($ret[$aid])) continue;
|
||||
$ret[$aid]['act_completed_instances'] = $res['num_instances'] - $ret[$aid]['aborted_instances'];
|
||||
$ret[$aid]['duration'] = array('min' => $res['min_time'], 'avg' => $res['avg_time'], 'max' => $res['max_time']);
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function monitor_list_instances($offset,$maxRecords,$sort_mode,$find,$where='',$wherevars='') {
|
||||
if($find) {
|
||||
$findesc = $this->qstr('%'.$find.'%');
|
||||
$mid=" where (`properties` like $findesc)";
|
||||
} else {
|
||||
$mid="";
|
||||
}
|
||||
if($where) {
|
||||
if($mid) {
|
||||
$mid.= " and ($where) ";
|
||||
} else {
|
||||
$mid.= " where ($where) ";
|
||||
}
|
||||
}
|
||||
$query = "select gp.`pId`, ga.`isInteractive`, gi.`owner`, gp.`name` as `procname`, gp.`version`, ga.`type`,";
|
||||
$query.= " ga.`activityId`, ga.`name`, gi.`instanceId`, gi.`status`, gia.`activityId`, gia.`user`, gi.`started`, gi.`ended`, gia.`status` as actstatus ";
|
||||
$query.=" from `".GALAXIA_TABLE_PREFIX."instances` gi LEFT JOIN `".GALAXIA_TABLE_PREFIX."instance_activities` gia ON gi.`instanceId`=gia.`instanceId` ";
|
||||
$query.= "LEFT JOIN `".GALAXIA_TABLE_PREFIX."activities` ga ON gia.`activityId` = ga.`activityId` ";
|
||||
$query.= "LEFT JOIN `".GALAXIA_TABLE_PREFIX."processes` gp ON gp.`pId`=gi.`pId` $mid order by ".$this->convert_sortmode($sort_mode);
|
||||
|
||||
$query_cant = "select count(*) from `".GALAXIA_TABLE_PREFIX."instances` gi LEFT JOIN `".GALAXIA_TABLE_PREFIX."instance_activities` gia ON gi.`instanceId`=gia.`instanceId` ";
|
||||
$query_cant.= "LEFT JOIN `".GALAXIA_TABLE_PREFIX."activities` ga ON gia.`activityId` = ga.`activityId` LEFT JOIN `".GALAXIA_TABLE_PREFIX."processes` gp ON gp.`pId`=gi.`pId` $mid";
|
||||
$result = $this->query($query,$wherevars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$wherevars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$iid = $res['instanceId'];
|
||||
$res['workitems']=$this->getOne("select count(*) from `".GALAXIA_TABLE_PREFIX."workitems` where `instanceId`=?",array($iid));
|
||||
$ret[$iid] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
function monitor_list_all_processes($sort_mode = 'name_asc', $where = '') {
|
||||
if (!empty($where)) {
|
||||
$where = " where ($where) ";
|
||||
}
|
||||
$query = "select `name`,`version`,`pId` from `".GALAXIA_TABLE_PREFIX."processes` $where order by ".$this->convert_sortmode($sort_mode);
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$pId = $res['pId'];
|
||||
$ret[$pId] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function monitor_list_all_activities($sort_mode = 'name_asc', $where = '') {
|
||||
if (!empty($where)) {
|
||||
$where = " where ($where) ";
|
||||
}
|
||||
$query = "select `name`,`activityId` from `".GALAXIA_TABLE_PREFIX."activities` $where order by ".$this->convert_sortmode($sort_mode);
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$aid = $res['activityId'];
|
||||
$ret[$aid] = $res;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function monitor_list_statuses() {
|
||||
$query = "select distinct(`status`) from `".GALAXIA_TABLE_PREFIX."instances`";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['status'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function monitor_list_users() {
|
||||
$query = "select distinct(`user`) from `".GALAXIA_TABLE_PREFIX."instance_activities`";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['user'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function monitor_list_wi_users() {
|
||||
$query = "select distinct(`user`) from `".GALAXIA_TABLE_PREFIX."workitems`";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['user'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function monitor_list_owners() {
|
||||
$query = "select distinct(`owner`) from `".GALAXIA_TABLE_PREFIX."instances`";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['owner'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function monitor_list_activity_types() {
|
||||
$query = "select distinct(`type`) from `".GALAXIA_TABLE_PREFIX."activities`";
|
||||
$result = $this->query($query);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$ret[] = $res['type'];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function monitor_get_workitem($itemId) {
|
||||
$query = "select gw.`orderId`,ga.`name`,ga.`type`,ga.`isInteractive`,gp.`name` as `procname`,gp.`version`,";
|
||||
$query.= "gw.`itemId`,gw.`properties`,gw.`user`,`started`,`ended`-`started` as duration ";
|
||||
$query.= "from `".GALAXIA_TABLE_PREFIX."workitems` gw,`".GALAXIA_TABLE_PREFIX."activities` ga,`".GALAXIA_TABLE_PREFIX."processes` gp where ga.`activityId`=gw.`activityId` and ga.`pId`=gp.`pId` and `itemId`=?";
|
||||
$result = $this->query($query, array($itemId));
|
||||
$res = $result->fetchRow();
|
||||
$res['properties'] = unserialize($res['properties']);
|
||||
return $res;
|
||||
}
|
||||
|
||||
// List workitems per instance, remove workitem, update_workitem
|
||||
function monitor_list_workitems($offset,$maxRecords,$sort_mode,$find,$where='',$wherevars=array()) {
|
||||
$mid = '';
|
||||
if ($where) {
|
||||
$mid.= " and ($where) ";
|
||||
}
|
||||
if($find) {
|
||||
$findesc = $this->qstr('%'.$find.'%');
|
||||
$mid.=" and (`properties` like $findesc)";
|
||||
}
|
||||
// TODO: retrieve instance status as well
|
||||
$query = "select `itemId`,`ended`-`started` as duration,ga.`isInteractive`, ga.`type`,gp.`name` as procname,gp.`version`,ga.`name` as actname,";
|
||||
$query.= "ga.`activityId`,`instanceId`,`orderId`,`properties`,`started`,`ended`,`user` from `".GALAXIA_TABLE_PREFIX."workitems` gw,`".GALAXIA_TABLE_PREFIX."activities` ga,`".GALAXIA_TABLE_PREFIX."processes` gp ";
|
||||
$query.= "where gw.`activityId`=ga.`activityId` and ga.`pId`=gp.`pId` $mid order by gp.`pId` desc,".$this->convert_sortmode($sort_mode);
|
||||
$query_cant = "select count(*) from `".GALAXIA_TABLE_PREFIX."workitems` gw,`".GALAXIA_TABLE_PREFIX."activities` ga,`".GALAXIA_TABLE_PREFIX."processes` gp where gw.`activityId`=ga.`activityId` and ga.`pId`=gp.`pId` $mid";
|
||||
$result = $this->query($query,$wherevars,$maxRecords,$offset);
|
||||
$cant = $this->getOne($query_cant,$wherevars);
|
||||
$ret = Array();
|
||||
while($res = $result->fetchRow()) {
|
||||
$itemId = $res['itemId'];
|
||||
$ret[$itemId] = $res;
|
||||
}
|
||||
$retval = Array();
|
||||
$retval["data"] = $ret;
|
||||
$retval["cant"] = $cant;
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
130
phpgwapi/inc/galaxia_workflow/src/common/Base.php
Normal file
130
phpgwapi/inc/galaxia_workflow/src/common/Base.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
include_once(GALAXIA_LIBRARY.'/src/common/Observable.php');
|
||||
//!! Abstract class representing the base of the API
|
||||
//! An abstract class representing the API base
|
||||
/*!
|
||||
This class is derived by all the API classes so they get the
|
||||
database connection, database methods and the Observable interface.
|
||||
*/
|
||||
class Base extends Observable {
|
||||
var $db; // The ADODB object used to access the database
|
||||
var $num_queries = 0;
|
||||
|
||||
// Constructor receiving a ADODB database object.
|
||||
function Base($db)
|
||||
{
|
||||
if(!$db) {
|
||||
die("Invalid db object passed to Base constructor");
|
||||
}
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
// copied from tikilib.php
|
||||
function query($query, $values = null, $numrows = -1, $offset = -1, $reporterrors = true) {
|
||||
$this->convert_query($query);
|
||||
if ($numrows == -1 && $offset == -1)
|
||||
$result = $this->db->Execute($query, $values);
|
||||
else
|
||||
$result = $this->db->SelectLimit($query, $numrows, $offset, $values);
|
||||
if (!$result && $reporterrors)
|
||||
$this->sql_error($query, $values, $result);
|
||||
$this->num_queries++;
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getOne($query, $values = null, $reporterrors = true) {
|
||||
$this->convert_query($query);
|
||||
$result = $this->db->SelectLimit($query, 1, 0, $values);
|
||||
if (!$result && $reporterrors)
|
||||
$this->sql_error($query, $values, $result);
|
||||
|
||||
$res = $result->fetchRow();
|
||||
$this->num_queries++;
|
||||
if ($res === false)
|
||||
return (NULL); //simulate pears behaviour
|
||||
list($key, $value) = each($res);
|
||||
return $value;
|
||||
}
|
||||
|
||||
function sql_error($query, $values, $result) {
|
||||
global $ADODB_LASTDB;
|
||||
|
||||
trigger_error($ADODB_LASTDB . " error: " . $this->db->ErrorMsg(). " in query:<br/>" . $query . "<br/>", E_USER_WARNING);
|
||||
// only for debugging.
|
||||
print_r($values);
|
||||
//echo "<br/>";
|
||||
die;
|
||||
}
|
||||
|
||||
// functions to support DB abstraction
|
||||
function convert_query(&$query) {
|
||||
global $ADODB_LASTDB;
|
||||
|
||||
switch ($ADODB_LASTDB) {
|
||||
case "oci8":
|
||||
$query = preg_replace("/`/", "\"", $query);
|
||||
// convert bind variables - adodb does not do that
|
||||
$qe = explode("?", $query);
|
||||
$query = '';
|
||||
for ($i = 0; $i < sizeof($qe) - 1; $i++) {
|
||||
$query .= $qe[$i] . ":" . $i;
|
||||
}
|
||||
$query .= $qe[$i];
|
||||
break;
|
||||
case "postgres7":
|
||||
case "sybase":
|
||||
$query = preg_replace("/`/", "\"", $query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function convert_sortmode($sort_mode) {
|
||||
global $ADODB_LASTDB;
|
||||
|
||||
switch ($ADODB_LASTDB) {
|
||||
case "pgsql72":
|
||||
case "postgres7":
|
||||
case "oci8":
|
||||
case "sybase":
|
||||
// Postgres needs " " around column names
|
||||
//preg_replace("#([A-Za-z]+)#","\"\$1\"",$sort_mode);
|
||||
$sort_mode = str_replace("_", "\" ", $sort_mode);
|
||||
$sort_mode = "\"" . $sort_mode;
|
||||
break;
|
||||
case "mysql3":
|
||||
case "mysql":
|
||||
default:
|
||||
$sort_mode = str_replace("_", "` ", $sort_mode);
|
||||
$sort_mode = "`" . $sort_mode;
|
||||
break;
|
||||
}
|
||||
return $sort_mode;
|
||||
}
|
||||
|
||||
function convert_binary() {
|
||||
global $ADODB_LASTDB;
|
||||
|
||||
switch ($ADODB_LASTDB) {
|
||||
case "pgsql72":
|
||||
case "oci8":
|
||||
case "postgres7":
|
||||
return;
|
||||
break;
|
||||
case "mysql3":
|
||||
case "mysql":
|
||||
return "binary";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function qstr($string, $quoted = null)
|
||||
{
|
||||
if (!isset($quoted)) {
|
||||
$quoted = get_magic_quotes_gpc();
|
||||
}
|
||||
return $this->db->qstr($string,$quoted);
|
||||
}
|
||||
|
||||
} //end of class
|
||||
|
||||
?>
|
81
phpgwapi/inc/galaxia_workflow/src/common/Observable.php
Normal file
81
phpgwapi/inc/galaxia_workflow/src/common/Observable.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
//!! Observable
|
||||
//! An abstract class implementing observable objects
|
||||
/*!
|
||||
\abstract
|
||||
Methods to override: NONE
|
||||
This class implements the Observer design pattern defining Observable
|
||||
objects, when a class extends Observable Observers can be attached to
|
||||
the class listening for some event. When an event is detected in any
|
||||
method of the derived class the method can call notifyAll($event,$msg)
|
||||
to notify all the observers listening for event $event.
|
||||
The Observer objects must extend the Observer class and define the
|
||||
notify($event,$msg) method.
|
||||
*/
|
||||
class Observable {
|
||||
var $_observers=Array();
|
||||
|
||||
function Observable() {
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
This method can be used to attach an object to the class listening for
|
||||
some specific event. The object will be notified when the specified
|
||||
event is triggered by the derived class.
|
||||
*/
|
||||
function attach($event, &$obj)
|
||||
{
|
||||
if (!is_object($obj)) {
|
||||
return false;
|
||||
}
|
||||
$obj->_observerId = uniqid(rand());
|
||||
$this->_observers[$event][$obj->_observerId] = &$obj;
|
||||
}
|
||||
|
||||
/*!
|
||||
Attaches an object to the class listening for any event.
|
||||
The object will be notified when any event occurs in the derived class.
|
||||
*/
|
||||
function attach_all(&$obj)
|
||||
{
|
||||
if (!is_object($obj)) {
|
||||
return false;
|
||||
}
|
||||
$obj->_observerId = uniqid(rand());
|
||||
$this->_observers['all'][$obj->_observerId] = &$obj;
|
||||
}
|
||||
|
||||
/*!
|
||||
Detaches an observer from the class.
|
||||
*/
|
||||
function dettach(&$obj)
|
||||
{
|
||||
if (isset($this->_observers[$obj->_observerId])) {
|
||||
unset($this->_observers[$obj->_observerId]);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\protected
|
||||
Method used to notify objects of an event. This is called in the
|
||||
methods of the derived class that want to notify some event.
|
||||
*/
|
||||
function notify_all($event, $msg)
|
||||
{
|
||||
//reset($this->_observers[$event]);
|
||||
if(isset($this->_observers[$event])) {
|
||||
foreach ($this->_observers[$event] as $observer) {
|
||||
$observer->notify($event,$msg);
|
||||
}
|
||||
}
|
||||
if(isset($this->_observers['all'])) {
|
||||
foreach ($this->_observers['all'] as $observer) {
|
||||
$observer->notify($event,$msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
27
phpgwapi/inc/galaxia_workflow/src/common/Observer.php
Normal file
27
phpgwapi/inc/galaxia_workflow/src/common/Observer.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
//!! Observer
|
||||
//! An abstract class implementing observer objects
|
||||
/*!
|
||||
\abstract
|
||||
Methods to override: notify($event, $msg)
|
||||
This implements the Observer design pattern defining the Observer class.
|
||||
Observer objects can be "attached" to Observable objects to listen for
|
||||
a specific event.
|
||||
Example:
|
||||
|
||||
$log = new Logger($logfile); //Logger extends Observer
|
||||
$foo = new Foo(); //Foo extends Observable
|
||||
$foo->attach('moo',$log); //Now $log observers 'moo' events in $foo class
|
||||
// of
|
||||
$foo->attach_all($log); // Same but all events are listened
|
||||
*/
|
||||
|
||||
class Observer {
|
||||
///This will be assigned by an observable object when attaching.
|
||||
var $_observerId='';
|
||||
|
||||
function notify($event, $msg) {
|
||||
// do something...
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user