source: trunk/workflow/inc/class.bo_monitors.inc.php @ 795

Revision 795, 55.8 KB checked in by viani, 15 years ago (diff)

Ticket #488 - Inclusão do módulo workflow no ramo trunk do repositório Expresso.

  • Property svn:executable set to *
Line 
1<?php
2/**************************************************************************\
3* eGroupWare                                                                       *
4* http://www.egroupware.org                                                *
5* --------------------------------------------                             *
6*  This program is free software; you can redistribute it and/or modify it *
7*  under the terms of the GNU General Public License as published by the   *
8*  Free Software Foundation; either version 2 of the License, or (at your  *
9*  option) any later version.                                              *
10\**************************************************************************/
11
12require_once('class.bo_ajaxinterface.inc.php');
13
14require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'GUI' . SEP . 'GUI.php');
15require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'ProcessManager.php');
16require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'ActivityManager.php');
17require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'InstanceManager.php');
18require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessManager' . SEP . 'RoleManager.php');
19require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'ProcessMonitor' . SEP . 'ProcessMonitor.php');
20require_once(GALAXIA_LIBRARY . SEP . 'src' . SEP . 'API' . SEP . 'Instance.php');
21require_once('class.workflow_acl.inc.php');
22require_once('class.bo_adminaccess.inc.php');
23require_once('class.powergraphic.inc.php');
24
25/**
26 * @package Workflow
27 * @license http://www.gnu.org/copyleft/gpl.html GPL
28 * @author Sidnei Augusto Drovetto Jr. - drovetto@gmail.com
29 */
30class bo_monitors extends bo_ajaxinterface
31{
32        /* permissions index */
33
34        /**
35         * @var integer $IP_CHANGE_PRIORITY
36         * @access public
37         */
38        var $IP_CHANGE_PRIORITY = 0;
39        /**
40         * @var integer $IP_CHANGE_USER
41         * @access public
42         */
43        var $IP_CHANGE_USER = 1;
44        /**
45         * @var integer $IP_CHANGE_STATUS
46         * @access public
47         */
48        var $IP_CHANGE_STATUS = 2;
49        /**
50         * @var integer $IP_CHANGE_NAME
51         * @access public
52         */
53        var $IP_CHANGE_NAME = 3;
54        /**
55         * @var integer $IP_CHANGE_ACTIVITY
56         * @access public
57         */
58        var $IP_CHANGE_ACTIVITY = 4;
59        /**
60         * @var integer $IP_VIEW_PROPERTIES
61         * @access public
62         */
63        var $IP_VIEW_PROPERTIES = 5;
64        /**
65         * @var integer $IP_CHANGE_PROPERTIES
66         * @access public
67         */
68        var $IP_CHANGE_PROPERTIES = 6;
69        /**
70         * @var integer $IP_VIEW_STATISTICS
71         * @access public
72         */
73        var $IP_VIEW_STATISTICS = 7;
74        /**
75         * @var integer $IP_REMOVE_COMPLETED_INSTANCES
76         * @access public
77         */
78        var $IP_REMOVE_COMPLETED_INSTANCES = 8;
79        /**
80         * @var integer $IP_REPLACE_USER
81         * @access public
82         */
83        var $IP_REPLACE_USER = 9;
84        /**
85         * @var integer $IP_SEND_EMAILS
86         * @access public
87         */
88        var $IP_SEND_EMAILS = 10;
89        /**
90         * @var object $processManager
91         * @access public
92         */
93        var $processManager;
94        /**
95         * @var object $activityManager
96         * @access public
97         */
98        var $activityManager;
99        /**
100         * @var object $instanceManager
101         * @access public
102         */
103        var $instanceManager;
104        /**
105         * @var object $roleManager
106         * @access public
107         */
108        var $roleManager;
109        /**
110         * @var integer $userID
111         * @access public
112         */
113        var $userID;
114
115        /**
116         * @var bool $isWorkflowAdmin
117         * @access public
118         */
119        var $isWorkflowAdmin;
120
121        /**
122         * @var object $processMonitor
123         * @access public
124         */
125        var $processMonitor;
126
127        /**
128         * Construtor da classe bo_monitors
129         *
130         * @access public
131         * @return object
132         */
133        function bo_monitors()
134        {
135                parent::bo_ajaxinterface();
136                $GLOBALS['ajax']->gui   = new GUI($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
137                $this->userID                   = $_SESSION['phpgw_info']['workflow']['account_id'];
138                $this->isWorkflowAdmin  = $GLOBALS['ajax']->acl->checkWorkflowAdmin($this->userID);
139                $this->processManager   = new ProcessManager($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
140                $this->activityManager  = new ActivityManager($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
141                $this->instanceManager  = new InstanceManager($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
142                $this->roleManager              = new RoleManager($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
143                $this->processMonitor   = new ProcessMonitor($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
144        }
145
146        /**
147         * Verifica se o usuário logado possui acesso ao Monitoramento
148         *
149         * @param int $processID O ID do processo que se está tentando monitorar
150         * @param array $requiredLevel Permissões necessárias
151         * @return bool true se o usuário tiver permissão ou false caso contrário
152         * @access private
153         */
154        private function checkAccess($processID, $requiredLevel = null)
155        {
156                if ($this->isWorkflowAdmin)
157                        return true;
158
159                return $GLOBALS['ajax']->acl->checkUserGroupAccessToResource('MON', $this->userID, (int) $processID, $requiredLevel);
160        }
161
162        /**
163         * Converte os filtros utilizados na interface de monitoramento para código SQL
164         *
165         * @param string $filters Uma string contendo dados, serializados, sobre os filtros selecionados
166         * @return array Uma array onde cada elemento corresponde a um condicional de um filtro
167         * @access private
168         */
169        private function convertFiltersToSQL($filters)
170        {
171                require_once 'nano/JSON.php';
172
173                /* desserializa os dados */
174                $JSON = new Services_JSON();
175                /* desserializa a array principal, depois desserializa cada elemento desta array e, por fim, converte os elementos (que estão em forma de objeto) para array associativa */
176                $filters = array_map('get_object_vars', array_map(array($JSON, 'decode'), $JSON->decode($filters)));
177                $sqlFilters = array();
178
179                /* gera o SQL de acordo com o filtro selecionado */
180                foreach ($filters as $filter)
181                {
182                        /* verifica se existe o ID do filtro */
183                        if (!isset($filter['id']))
184                                continue;
185
186                        switch ($filter['id'])
187                        {
188                                case 'activityDate':
189                                        $sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gia.wf_started || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
190                                        break;
191
192                                case 'instanceName':
193                                        $sqlFilters[] = '(gi.wf_name ILIKE \'%' . addslashes($filter['name']) . '%\')';
194                                        break;
195
196                                case 'instanceID':
197                                        $sqlFilters[] = '(gi.wf_instance_id ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' ' . addslashes($filter['number']) . ')';
198                                        break;
199
200                                case 'instancePriority':
201                                        $sqlFilters[] = '(gi.wf_priority ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' ' . addslashes($filter['priority']) . ')';
202                                        break;
203
204                                case 'instanceDate':
205                                        $sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gi.wf_started || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
206                                        break;
207
208                                case 'instanceEndDate':
209                                        $sqlFilters[] = '(DATE_TRUNC(\'DAY\', \'EPOCH\'::TIMESTAMP + (gi.wf_ended || \' SECONDS\')::INTERVAL) ' . (($filter['operator'] == 'EQ') ? '=' : (($filter['operator'] == 'LT') ? '<' : '>')) . ' TO_DATE(\'' . addslashes($filter['date']) . '\', \'DD/MM/YYYY\'))';
210                                        break;
211
212                                case 'instanceStatus':
213                                        $sqlFilters[] = '(gi.wf_status = \'' . addslashes($filter['status']) . '\')';
214                                        break;
215
216                                case 'instanceActivity':
217                                        $sqlFilters[] = '(gia.wf_activity_id = \'' . addslashes($filter['activity']) . '\')';
218                                        break;
219
220                                case 'instanceUser':
221                                        $sqlFilters[] = '(gia.wf_user = \'' . addslashes($filter['user']) . '\')';
222                                        break;
223
224                                case 'instanceOwner':
225                                        $sqlFilters[] = '(gi.wf_owner = \'' . addslashes($filter['owner']) . '\')';
226                                        break;
227                        }
228                }
229
230                return $sqlFilters;
231        }
232
233        /**
234         * Lista os processos do usuario
235         *
236         * @access public
237         * @return array lista de processos
238         */
239        function listProcesses()
240        {
241                if ($this->isWorkflowAdmin)
242                {
243                        $permissions = $this->processManager->list_processes(0, -1, 'wf_p_id__ASC');
244                        $permissions = array_map(create_function('$a', 'return $a[\'wf_p_id\'];'), $permissions['data']);
245                }
246                else
247                {
248                        $permissions = $GLOBALS['ajax']->acl->getUserGroupPermissions('MON', $this->userID);
249                }
250                $processes = array();
251                foreach ($permissions as $pid)
252                {
253                        $process = $this->processManager->get_process($pid);
254                        if ($process)
255                        {
256                                $processes['data'][] = $process;
257                                if ($this->isWorkflowAdmin)
258                                        $processes['permissions'][$pid] = array(
259                                                'number' => 4294967295,
260                                                'bits' => array_fill(0, 32, true)
261                                        );
262                                else
263                                        $processes['permissions'][$pid] = $GLOBALS['ajax']->acl->getUserGroupAdminLevel('MON', $this->userID, $pid);
264                        }
265                }
266
267                usort($processes['data'], create_function('$a,$b', 'return strnatcasecmp($a[\'wf_name\'],$b[\'wf_name\']);'));
268                return $processes;
269        }
270        /**
271         * Lista as instancias ativas de um processo
272         *
273         * @param array $params Parâmetros advindos da chamada Ajax
274         * @param bool $completeData Informa se devem ser retornados todos os dados ou somente aqueles necessários para a construção da listagem de instâncias ativas da interface de monitoramento. false por padrão
275         * @access public
276         * @return array lista de instancias
277         */
278        function listInstances($params, $completeData = false)
279        {
280                $output = array();
281
282                /* check if the user has the proper right to list the instances of this process */
283                if (!$this->checkAccess($params['pid']))
284                        return "Você não tem permissão para executar este procedimento!";
285
286                /* check for filters */
287                if ($params['filters'])
288                        $filters = $this->convertFiltersToSQL($params['filters']);
289                else
290                        $filters = array();
291
292                if(empty($params['srt']))
293                        $params['srt'] = 2;
294                if(empty($params['ord']))
295                {
296                        $params['ord'] = "__ASC";
297                }
298                else
299                {
300
301                        // being sure that the prefix "__DESC" or "__ASC" exists, preventing SQL injections
302                        $isOrdOK = false;
303                        if($params['ord'] == "__DESC") $isOrdOK = true;
304                        if($params['ord'] == "__ASC") $isOrdOK = true;
305
306                        if(!$isOrdOK) $params['ord'] = "__ASC";
307                }
308
309                switch($params['srt'])
310                {
311                        case 1:
312                                $order = "wf_instance_id".$params['ord'];
313                                break;
314                        case 2:
315                                $order = "wf_activity_name".$params['ord'];
316                                break;
317                        case 3:
318                                $order = "wf_instance_name".$params['ord'];
319                                break;
320                        case 4:
321                                $order = "wf_priority".$params['ord'];
322                                break;
323                        case 5:
324                                $order = "wf_user".$params['ord'];
325                                break;
326                        case 6:
327                                $order = "wf_status".$params['ord'];
328                                break;
329                        default:
330                                $order = "wf_activity_name".$params['ord'];
331                                break;
332                }
333
334                $filters[] = '(gp.wf_p_id = ' . $params['pid'] . ')';
335                $filters[] = '(gia.wf_user IS NOT NULL)';
336
337                $ldap = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
338                if (!$completeData)
339                {
340                        $paging = $GLOBALS['workflow']['factory']->newInstance('Paging', 500, $_POST);
341                        $tmp = $this->processMonitor->monitor_list_instances($paging->nextItem, $paging->itemsPerPage, $order, '', implode(' AND ', $filters));
342                        $output['data'] = $paging->restrictItems(array_values($tmp['data']), $tmp['cant']);
343                        $output['instanceCount'] = $tmp['cant'];
344                        $output['pagingData'] = $paging->commonLinks();
345                }
346                else
347                {
348                        $tmp = $this->processMonitor->monitor_list_instances(0, -1, $order, '', implode(' AND ', $filters));
349                        $output['data'] = array_values($tmp['data']);
350                }
351
352                $userMapping = array('*' => '*');
353                $activityMapping = array();
354                $instanceCount = count($output['data']);
355                $cachedLDAP = &$GLOBALS['workflow']['factory']->getInstance('CachedLDAP');
356                for ($i = 0; $i < $instanceCount; $i++)
357                {
358                        /* get the user name */
359                        $currentInstanceUser = $output['data'][$i]['wf_user'];
360                        if (!isset($userMapping[$currentInstanceUser]))
361                        {
362                                if (substr($currentInstanceUser, 0, 1) == 'p')
363                                {
364                                        $role = $this->roleManager->get_role($output['data'][$i]['wf_p_id'], substr($currentInstanceUser, 1));
365                                        $userMapping[$currentInstanceUser] = 'Perfil: ' . $role['wf_name'];
366                                }
367                                else
368                                {
369                                        $name = $ldap->getName($currentInstanceUser);
370                                        if (empty($name))
371                                        {
372                                                $userInfo = $cachedLDAP->getEntryByID($currentInstanceUser);
373                                                if ($userInfo)
374                                                        $name = "ID: {$currentInstanceUser} - {$userInfo['cn']} (excluído)";
375                                                else
376                                                        $name = "ID: {$currentInstanceUser}";
377                                        }
378
379                                        $userMapping[$currentInstanceUser] = $name;
380                                }
381                        }
382
383                        if ($completeData)
384                        {
385                                $currentInstanceOwner = $output['data'][$i]['wf_owner'];
386                                if (!isset($userMapping[$currentInstanceOwner]))
387                                        $userMapping[$currentInstanceOwner] = $ldap->getName($currentInstanceOwner);
388                        }
389
390                        /* get the activity names */
391                        if (!isset($activityMapping[$output['data'][$i]['wf_activity_id']]))
392                                $activityMapping[$output['data'][$i]['wf_activity_id']] = $output['data'][$i]['wf_activity_name'];
393
394                        /* remove unused elements */
395                        if (!$completeData)
396                                unset(
397                                        $output['data'][$i]['wf_is_interactive'],
398                                        $output['data'][$i]['wf_proc_normalized_name'],
399                                        $output['data'][$i]['wf_owner'],
400                                        $output['data'][$i]['wf_procname'],
401                                        $output['data'][$i]['wf_version'],
402                                        $output['data'][$i]['wf_activity_name'],
403                                        $output['data'][$i]['wf_type'],
404                                        $output['data'][$i]['wf_started'],
405                                        $output['data'][$i]['wf_ended'],
406                                        $output['data'][$i]['wf_act_status'],
407                                        $output['data'][$i]['wf_act_started']
408                                );
409                }
410                $output['userMapping'] = $userMapping;
411                $output['activityMapping'] = $activityMapping;
412
413                $output['params'] = $params;
414                return $output;
415        }
416
417        /**
418         * Lista as instancias finalizadas de um processo
419         *
420         * @param array $params Parâmetros advindos da chamada Ajax
421         * @param bool $completeData Informa se devem ser retornados todos os dados ou somente aqueles necessários para a construção da listagem de instâncias finalizadas da interface de monitoramento. false por padrão
422         * @access public
423         * @return array lista de instancias
424         */
425        function listCompletedInstances($params, $completeData = false)
426        {
427                $params['pid'] = (int) $params['pid'];
428                $output = array();
429
430                /* check if the user has the proper right to list the instances of this process */
431                if (!$this->checkAccess($params['pid']))
432                        return "Você não tem permissão para executar este procedimento!";
433
434                /* check for filters */
435                if ($params['filters'])
436                        $filters = $this->convertFiltersToSQL($params['filters']);
437                else
438                        $filters = array();
439
440                if(empty($params['sort']))
441                        $params['sort'] = 1;
442
443                if(empty($params['ord']) || ($params['ord'] != '__DESC'))
444                        $params['ord'] = '__ASC';
445
446                /* define the sorting criteria */
447                switch($params['sort'])
448                {
449                        case 1:
450                                $order = 'wf_instance_id';
451                                break;
452                        case 2:
453                                $order = 'wf_instance_name';
454                                break;
455                        case 3:
456                                $order = 'wf_owner';
457                                break;
458                        case 4:
459                                $order = 'wf_priority';
460                                break;
461                        case 5:
462                                $order = 'wf_started';
463                                break;
464                        case 6:
465                                $order = 'wf_ended';
466                                break;
467                        case 7:
468                                $order = 'wf_status';
469                                break;
470                        default:
471                                $order = 'wf_instance_id';
472                                break;
473                }
474                $order .= $params['ord'];
475
476                /* load the data */
477                $filters[] = '(gp.wf_p_id = ' . $params['pid'] . ')';
478                $ldap = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
479                if (!$completeData)
480                {
481                        $paging = $GLOBALS['workflow']['factory']->newInstance('Paging', 500, $_POST);
482                        $tmp = $this->processMonitor->monitor_list_completed_instances($paging->nextItem, $paging->itemsPerPage, $order, '', implode(' AND ', $filters));
483                        $output['data'] = $paging->restrictItems(array_values($tmp['data']), $tmp['cant']);
484                        $output['instanceCount'] = $tmp['cant'];
485                        $output['pagingData'] = $paging->commonLinks();
486                }
487                else
488                {
489                        $tmp = $this->processMonitor->monitor_list_completed_instances(0, -1, $order, '', implode(' AND ', $filters));
490                        $output['data'] = array_values($tmp['data']);
491                }
492
493                $cachedLDAP = &$GLOBALS['workflow']['factory']->getInstance('CachedLDAP');
494                $userMapping = array();
495                $instanceCount = count($output['data']);
496                for ($i = 0; $i < $instanceCount; $i++)
497                {
498                        /* get the user name */
499                        $currentInstanceOwner = $output['data'][$i]['wf_owner'];
500                        {
501                                $name = $ldap->getName($currentInstanceOwner);
502                                if (empty($name))
503                                {
504                                        $userInfo = $cachedLDAP->getEntryByID($currentInstanceOwner);
505                                        if ($userInfo)
506                                                $name = "ID: {$currentInstanceOwner} - {$userInfo['cn']} (excluído)";
507                                        else
508                                                $name = "ID: {$currentInstanceOwner}";
509                                }
510
511                                $userMapping[$currentInstanceOwner] = $name;
512                        }
513
514                        /* format the data */
515                        $output['data'][$i]['wf_started'] = date('d/m/Y H:i', $output['data'][$i]['wf_started']);
516                        $output['data'][$i]['wf_ended'] = date('d/m/Y H:i', $output['data'][$i]['wf_ended']);
517
518                        /* remove unused elements */
519                        if (!$completeData)
520                                unset(
521                                        $output['data'][$i]['wf_proc_normalized_name'],
522                                        $output['data'][$i]['wf_procname'],
523                                        $output['data'][$i]['wf_version']
524                                );
525                }
526                $output['userMapping'] = $userMapping;
527
528                $output['params'] = $params;
529                return $output;
530        }
531
532        /**
533         * Lista as atividades da instancia
534         * @param array $params Parâmetros advindos da chamada Ajax
535         * @access public
536         * @return array
537         */
538        function listActivities($params)
539        {
540                $pid = (int) $params['pid'];
541                /* check if the user has the proper right to list the activities of this process */
542                if (!$this->checkAccess($pid))
543                        return "Você não tem permissão para executar este procedimento!";
544
545                /* retrieve all the activities */
546                $activities = $this->activityManager->list_activities($pid, 0, -1, 'wf_name__asc', '', '');
547
548                /* format the output */
549                $output['params'] = $params;
550                $output['data'] = array();
551                foreach ($activities['data'] as $activity)
552                        if (($activity['wf_type'] != 'view') && ($activity['wf_type'] != 'standalone') && ($activity['wf_type'] != 'start') && ($activity['wf_is_interactive'] == 'y'))
553                                $output['data'][] = array('id' => $activity['wf_activity_id'], 'name' => $activity['wf_name']);
554
555                return $output;
556        }
557        /**
558         * Lista os usuarios da instancia
559         * @param array $params Parâmetros advindos da chamada Ajax
560         * @access public
561         * @return array lista de usuarios
562         */
563        function listUsers($params)
564        {
565                /* check if the user has the right to view all users from this instance */
566                $instance = $this->instanceManager->get_instance($params['iid']);
567                if ((!$this->checkAccess($params['pid'])) || ($instance['wf_p_id'] != $params['pid']))
568                        return 'Você não tem permissão para executar este procedimento!';
569
570                /* retrieve all the users from the activity */
571                $users = $this->roleManager->list_mapped_users($params['pid'], true, array('wf_activity_id' => $params['aid']));
572                asort($users);
573
574                $roles = $this->activityManager->get_activity_roles($params['aid']);
575                usort($roles, create_function('$a,$b', 'return strcasecmp($a[\'wf_name\'],$b[\'wf_name\']);'));
576                $usersOutput['data'] = array();
577                $usersOutput['data'][] = array('id' => '-1', 'name' => 'TODOS');
578                foreach ($roles as $role)
579                        $usersOutput['data'][] = array('id' => 'p' . $role['wf_role_id'], 'name' => 'Perfil: ' . $role['wf_name']);
580
581                /* format the output */
582                $usersOutput['params'] = $params;
583                foreach ($users as $id => $name)
584                        $usersOutput['data'][] = array('id' => $id, 'name' => $name);
585
586                return $usersOutput;
587        }
588        /**
589         * Realiza o Update da prioridade de uma instancia
590         * @param array $params Parâmetros advindos da chamada Ajax
591         * @access public
592         * @return array parametros?
593         */
594        function updatePriority($params)
595        {
596                /* check if the user has the right to update the priority of the instance */
597                $instance = $this->instanceManager->get_instance($params['iid']);
598                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PRIORITY))) || ($instance['wf_p_id'] != $params['pid']))
599                        return "Você não tem permissão para executar este procedimento!";
600
601                $this->instanceManager->set_instance_priority($params['iid'], $params['np']);
602                return $params;
603        }
604
605        /**
606         * Realiza o update do usuario atual da instancia
607         * @param array $params Parâmetros advindos da chamada Ajax
608         * @return array
609         * @access public
610         */
611        function updateUser($params)
612        {
613                /* check if the user has the right to update the current user of this instance */
614                $instance = $this->instanceManager->get_instance($params['iid']);
615                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_USER))) || ($instance['wf_p_id'] != $params['pid']))
616                        return "Você não tem permissão para executar este procedimento!";
617
618                $output = $params;
619                $user = ($params['user'] == -1) ? '*' : $params['user'];
620                if ($user == '*')
621                        $output['fullname'] = '*';
622                else
623                        if (substr($user, 0, 1) == 'p')
624                        {
625                                $role = $this->roleManager->get_role($instance['wf_p_id'], substr($user, 1));
626                                $output['fullname'] = 'Perfil: ' . $role['wf_name'];
627                        }
628                        else
629                                $output['fullname'] = $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP')->getName($user);
630
631                $this->instanceManager->set_instance_user($params['iid'], $params['aid'], $user);
632
633                return $output;
634        }
635        /**
636         * Realiza o update do status da instancia
637         * @param array $params Parâmetros advindos da chamada Ajax
638         * @return array
639         * @access public
640         */
641        function updateStatus($params)
642        {
643                /* check if the user has the right to update the status of the instance */
644                $instance = $this->instanceManager->get_instance($params['iid']);
645                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_STATUS))) || ($instance['wf_p_id'] != $params['pid']))
646                        return "Você não tem permissão para executar este procedimento!";
647
648                if ($params['ns'] == 'aborted')
649                {
650                        $realInstance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
651                        $realInstance->getInstance($params['iid']);
652                        if (!empty($realInstance->instanceId))
653                        {
654                                if (!$realInstance->abort())
655                                {
656                                        unset($realInstance);
657                                        return 'Ocorreu um erro ao abortar a instância selecionada';
658                                }
659                        }
660                        else
661                        {
662                                unset($realInstance);
663                                return 'Não foi possível abortar a instância selecionada';
664                        }
665                }
666                else
667                        $this->instanceManager->set_instance_status($params['iid'], $params['ns']);
668
669                return $params;
670        }
671
672        /**
673         * Realiza o update de uma atividade da instancia
674         * @param array $params Parâmetros advindos da chamada Ajax
675         * @return array
676         * @access public
677         */
678        function updateActivity($params)
679        {
680                /* check if the user has the right to update change the activity of the instance */
681                $instance = $this->instanceManager->get_instance($params['iid']);
682                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_ACTIVITY))) || ($instance['wf_p_id'] != $params['pid']))
683                        return "Você não tem permissão para executar este procedimento!";
684
685                /* use next user or * for the new instance */
686                $realInstance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
687                $realInstance->getInstance($params['iid'], false, false);
688                $user = $realInstance->getNextUser($params['aid']);
689                $user = ($user == '') ? '*' : $user;
690                $this->instanceManager->set_instance_destination($params['iid'], $params['aid'], $user);
691                $result = $this->activityManager->get_activity($params['aid']);
692                $output = $params;
693                $output['name'] = $result['wf_name'];
694                return $output;
695        }
696
697        /**
698         * Realiza o update do nome da instancia
699         * @param array $params Parâmetros advindos da chamada Ajax
700         * @return array
701         * @access public
702         */
703        function updateName($params)
704        {
705                /* check if the user has the right to update the status of the instance */
706                $instance = $this->instanceManager->get_instance($params['iid']);
707                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_NAME))) || ($instance['wf_p_id'] != $params['pid']))
708                        return "Você não tem permissão para executar este procedimento!";
709
710                $this->instanceManager->set_instance_name($params['iid'], $params['nn']);
711                return $params;
712        }
713
714        /**
715         * Remove instâncias finalizadas
716         * @param array $params Parâmetros advindos da chamada Ajax
717         * @return int O número de instâncias removidas
718         * @access public
719         */
720        function removeCompletedInstances($params)
721        {
722                /* check if the user has the proper right to remove the completed instances of this process */
723                if (!$this->checkAccess($params['pid'], array($this->IP_REMOVE_COMPLETED_INSTANCES)))
724                        return array('error' => 'Você não tem permissão para executar este procedimento!');
725
726                /* load the instances */
727                $rawData = $this->listCompletedInstances($params, true);
728
729                /* remove the instances */
730                $instanceCount = 0;
731                if (!empty($rawData['data']))
732                        foreach ($rawData['data'] as $instance)
733                                if ($this->processMonitor->remove_instance($instance['wf_instance_id']))
734                                        $instanceCount++;
735                return $instanceCount;
736        }
737
738
739        /**
740         * Lista as propriedades de uma instancia
741         * @param array $params Parâmetros advindos da chamada Ajax
742         * @return array
743         * @access public
744         */
745        function listInstanceProperties($params)
746        {
747                /* check if the user has the right to view the  instance properties */
748                $instanceInfo = $this->instanceManager->get_instance($params['iid']);
749                if (((!$this->checkAccess($params['pid'], array($this->IP_VIEW_PROPERTIES))) && (!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES)))) || ($instanceInfo['wf_p_id'] != $params['pid']))
750                        return "Você não tem permissão para executar este procedimento!";
751
752                $maximumDisplaySize = 100;
753                $instance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
754                $instance->getInstance($params['iid']);
755
756                $output = array();
757                $output['params'] = $params;
758                foreach ($instance->properties as $name => $value)
759                {
760                        $complete = 1;
761                        if (strlen($value) > $maximumDisplaySize)
762                        {
763                                $value = substr($value, 0, $maximumDisplaySize-3) . "...";
764                                $complete = 0;
765                        }
766                        $output[] = array ("name" => $name, "value" => htmlentities($value), "complete" => $complete);
767                }
768                return $output;
769        }
770
771        /**
772         * Retorna o valor de uma propriedade
773         *
774         * @param array $params Parâmetros advindos da chamada Ajax
775         * @return array
776         * @access public
777         */
778        function getCompletePropertyValue($params)
779        {
780                /* check if the user has the right to edit the instance properties */
781                $instanceInfo = $this->instanceManager->get_instance($params['iid']);
782                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
783                        return "Você não tem permissão para executar este procedimento!";
784
785                $instance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
786                $instance->getInstance($params['iid']);
787                $output = $params;
788                $output['value'] = $instance->properties[$params['name']];
789                return $output;
790        }
791
792        /**
793         * Realiza o update de uma propriedade de uma instancia
794         * @param array $params Parâmetros advindos da chamada Ajax
795         * @access public
796         */
797        function updateProperty($params)
798        {
799                /* check if the user has the right to edit the instance properties */
800                $instanceInfo = $this->instanceManager->get_instance($params['iid']);
801                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
802                        return "Você não tem permissão para executar este procedimento!";
803
804                $maximumDisplaySize = 100;
805
806                $instance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
807                $instance->getInstance($params['iid']);
808                $instance->set($params['name'], $params['value']);
809                $instance->sync();
810
811                $output = array();
812                if (strlen($params['value']) > $maximumDisplaySize)
813                {
814                        $params['value'] = substr($params['value'], 0, $maximumDisplaySize-3) . "...";
815                        $output['complete'] = 0;
816                }
817                else
818                $output['complete'] = 1;
819                $output['value'] = htmlentities($params['value']);
820
821                return $output;
822        }
823
824        /**
825         * Remove uma propriedade da instancia
826         * @param array $params Parâmetros advindos da chamada Ajax
827         * @return array
828         * @access public
829         */
830        function removeProperty($params)
831        {
832                /* check if the user has the right to remove a property of the instance */
833                $instanceInfo = $this->instanceManager->get_instance($params['iid']);
834                if ((!$this->checkAccess($params['pid'], array($this->IP_CHANGE_PROPERTIES))) || ($instanceInfo['wf_p_id'] != $params['pid']))
835                        return "Você não tem permissão para executar este procedimento!";
836
837                $instance = new Instance($GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID);
838                $instance->getInstance($params['iid']);
839                $instance->clear($params['name']);
840                $instance->sync();
841
842                $output = $params;
843                return $output;
844        }
845
846        /**
847         * Mostra as estatisticas
848         * @param array $params Parâmetros advindos da chamada Ajax
849         * @return array
850         * @access public
851         */
852        function showStatistics($params)
853        {
854                if (!$this->checkAccess($params['pid'], array($this->IP_VIEW_STATISTICS)))
855                        return "Você não tem permissão para executar este procedimento!";
856
857                /* common configuration */
858                $output = array();
859                $urlPrefix = 'workflow/inc/class.powergraphic.inc.php?';
860                $powergraphic = new powergraphic;
861                $powergraphic->graphic_1 = $params['pid'];
862                $powergraphic->skin = 1;
863                $powergraphic->credits = 0;
864
865                /* number of instances per month */
866                $powergraphic->type = 4;
867                $powergraphic->title = 'Quantidade de Instancias x Mes';
868                $powergraphic->axis_x = 'Mes';
869                $powergraphic->axis_y = 'No. de Instancias';
870                $aux = $this->processMonitor->stats_instances_per_month($params['pid']);
871                $index = 0;
872                foreach ($aux as $date => $count)
873                {
874                        list($year, $month) = explode('-', $date);
875                        $powergraphic->x[$index] = $month . '/' . substr($year, -2);
876                        $powergraphic->y[$index++] = $count;
877                }
878                if (count($aux) > 0)
879                        $output[] = $powergraphic->create_query_string();
880
881                /* number of instances per activity */
882                $powergraphic->x = $powergraphic->y = array();
883                $powergraphic->type = 5;
884                $powergraphic->title = 'Instancias x Atividade';
885                $powergraphic->axis_x = 'Atividade';
886                $powergraphic->axis_y = 'No. de Instancias';
887                $aux = $this->processMonitor->stats_instances_activities($params['pid']);
888                $index = 0;
889                foreach ($aux as $info)
890                {
891                        $powergraphic->x[$index] = $info['wf_name'] . " ({$info['count']})";
892                        $powergraphic->y[$index++] = $info['count'];
893                }
894                if (count($aux) > 0)
895                        $output[] = $powergraphic->create_query_string();
896
897                /* number of instances per user */
898                $powergraphic->x = $powergraphic->y = array();
899                $powergraphic->type = 5;
900                $powergraphic->title = 'Instancias x Usuario';
901                $powergraphic->axis_x = 'Usuario';
902                $powergraphic->axis_y = 'No. de Instancias';
903                $aux = $this->processMonitor->stats_instances_per_user($params['pid']);
904                /* prepare the data */
905                $aux2 = array();
906                $ldap = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
907                foreach ($aux as $user => $count)
908                        $aux2[] = array(
909                                'user' => $ldap->getName($user) . " ({$count})",
910                                'count' => $count
911                        );
912                usort($aux2, create_function('$a,$b', 'return strcasecmp($a[\'user\'],$b[\'user\']);'));
913                $index = 0;
914                foreach ($aux2 as $info)
915                {
916                        $powergraphic->x[$index] = $info['user'];
917                        $powergraphic->y[$index++] = $info['count'];
918                }
919                if (count($aux) > 0)
920                        $output[] = $powergraphic->create_query_string();
921
922                /* number of instances per status */
923                $translateStatus = array(
924                        'completed' => 'Completada',
925                        'active' => 'Ativa',
926                        'aborted' => 'Abortada',
927                        'exception' => 'Em exceção');
928                $powergraphic->x = $powergraphic->y = array();
929                $powergraphic->type = 5;
930                $powergraphic->title = 'Instancias x Status';
931                $powergraphic->axis_x = 'Status';
932                $powergraphic->axis_y = 'No. de Instancias';
933                $aux = $this->processMonitor->stats_instances_per_status($params['pid']);
934                $index = 0;
935                foreach ($aux as $status => $count)
936                {
937                        $powergraphic->x[$index] = $translateStatus[$status] . " ({$count})";
938                        $powergraphic->y[$index++] = $count;
939                }
940                if (count($aux) > 0)
941                        $output[] = $powergraphic->create_query_string();
942
943                foreach ($output as $key => $value)
944                        $output[$key] = $urlPrefix . $value;
945                return $output;
946        }
947
948        /**
949         * Pega os usuários de instâncias ativas de um determinado processo
950         * @param array $params Parâmetros advindos da chamada Ajax
951         * @return array Contendo o nome/id dos usuários
952         * @access public
953         */
954        function getUsersInInstances($params)
955        {
956                $pid = (int) $params['pid'];
957                /* check if the user has the proper right to list the users of this process */
958                if (!$this->checkAccess($pid))
959                        return "Você não tem permissão para executar este procedimento!";
960
961                /* initialize some variables */
962                $users = array();
963                $roles = array();
964                $specialUsers = array();
965
966                /* load the users */
967                $activities = $this->activityManager->get_process_activities($pid);
968                if (!empty($activities))
969                        $users = $this->processMonitor->monitor_list_users('wf_activity_id IN (' . implode(',', array_map(create_function('$a', 'return $a[\'wf_activity_id\'];'), $activities)) . ')');
970
971                /* remove the '*' user */
972                if (($asteriskPosition = array_search('*', $users)) !== false)
973                        unset($users[$asteriskPosition]);
974
975                /* separate roles from users */
976                foreach ($users as $key => $user)
977                {
978                        if (substr($user, 0, 1) == 'p')
979                        {
980                                $roles[] = $user;
981                                unset($users[$key]);
982                        }
983                }
984
985                /* load LDAP info and sort the result */
986                $foundUsers = $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP')->getNames($users);
987                usort($foundUsers, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
988
989
990                /* special treatment for  users not found in LDAP */
991                if (count($users) > count($foundUsers))
992                {
993                        $cachedLDAP = &$GLOBALS['workflow']['factory']->getInstance('CachedLDAP');
994                        $foundUsersID = array_map(create_function('$a', 'return $a[\'id\'];'), $foundUsers);
995                        $missingUsers = array_diff($users, $foundUsersID);
996                        foreach ($missingUsers as $missingUser)
997                        {
998                                $userInfo = $cachedLDAP->getEntryByID($missingUser);
999                                if ($userInfo)
1000                                        $name = "ID: {$missingUser} - {$userInfo['cn']} (excluído)";
1001                                else
1002                                        $name = "ID: {$missingUser}";
1003                                $specialUsers[] = array('id' => $missingUser, 'name' => $name);
1004                        }
1005                }
1006
1007                /* load roles info */
1008                foreach ($roles as $role)
1009                {
1010                        $roleInfo = $this->roleManager->get_role($pid, substr($role, 1));
1011                        $specialUsers[] = array('id' => $role, 'name' => 'Perfil: ' . $roleInfo['wf_name']);
1012                }
1013
1014                /* sort the special users */
1015                usort($specialUsers, create_function('$a,$b', 'return strnatcasecmp($a[\'name\'],$b[\'name\']);'));
1016
1017                /* define the output (merging the ordinary users with the "special" ones) */
1018                $output = $params;
1019                $output['users'] = array_merge($specialUsers, $foundUsers);
1020
1021                return $output;
1022        }
1023
1024        /**
1025         * Pega os proprietários de instâncias ativas ou inativas de um determinado processo
1026         * @param array $params Parâmetros advindos da chamada Ajax
1027         * @return array Contendo o nome/id dos proprietários
1028         * @access public
1029         */
1030        function getInstancesOwners($params)
1031        {
1032                $pid = (int) $params['pid'];
1033
1034                /* check if the user has the proper right to list the owners of this process */
1035                if (!$this->checkAccess($pid))
1036                        return 'Você não tem permissão para executar este procedimento!';
1037
1038                $output = $params;
1039                $output['owners'] = array();
1040
1041                /* load the instances (active ou completed ones) */
1042                if ($params['currentList'] == 'active')
1043                        $instances = $this->listInstances($params, true);
1044                else
1045                        $instances = $this->listCompletedInstances($params, true);
1046
1047                /* get the owners */
1048                if (count($instances['userMapping']) > 0)
1049                {
1050                        if ($params['currentList'] == 'completed')
1051                        {
1052                                foreach ($instances['userMapping'] as $id => $name)
1053                                        $output['owners'][] = array('id' => $id, 'name' => $name);
1054                        }
1055                        else
1056                        {
1057                                foreach ($instances['data'] as $instance)
1058                                        if (!isset($output['owners'][$instance['wf_owner']]))
1059                                                $output['owners'][$instance['wf_owner']] = array('id' => $instance['wf_owner'], 'name' => $instances['userMapping'][$instance['wf_owner']]);
1060                                $output['owners'] = array_values($output['owners']);
1061                        }
1062                }
1063
1064                /* sort the owners */
1065                usort($output['owners'], create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
1066
1067                return $output;
1068        }
1069
1070        /**
1071         * Pega as atividades das instâncias de um determinado usuário
1072         * @param array $params Parâmetros advindos da chamada Ajax
1073         * @return array Contendo o nome/id das atividades
1074         * @access public
1075         */
1076        function getUserActivities($params)
1077        {
1078                $pid = (int) $params['pid'];
1079                $user = (int) $params['user'];
1080                /* check if the user has the proper right to list the instances of this process */
1081                if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
1082                        return "Você não tem permissão para executar este procedimento!";
1083
1084                $instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$user}' AND gp.wf_p_id = {$pid}");
1085                $activities = array_map('unserialize', array_unique(array_map(create_function('$a', 'return serialize(array(\'id\' => $a[\'wf_activity_id\'], \'name\' => $a[\'wf_activity_name\']));'), $instances['data'])));
1086                usort($activities, create_function('$a,$b', 'return strcasecmp($a[\'name\'],$b[\'name\']);'));
1087
1088                $output = $params;
1089                $output['activities'] = $activities;
1090
1091                return $output;
1092        }
1093
1094        /**
1095         * Verifica se o novo dono das instâncias já está em todos os perfis necessários. Caso não esteja, envia uma lista com sugestões de perfis
1096         * @param array $params Parâmetros advindos da chamada Ajax
1097         * @return array Contendo informações e sugestões de perfis para adicionar o novo dono das instâncias
1098         * @access public
1099         */
1100        function checkUserRoles($params)
1101        {
1102                $pid = (int) $params['pid'];
1103                $oldUser = (int) $params['oldUser'];
1104                $newUser = (int) $params['newUser'];
1105                $activity = (int) $params['activity'];
1106
1107                /* check if the user has the proper right to list the instances of this process */
1108                if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
1109                        return "Você não tem permissão para executar este procedimento!";
1110
1111                $activities = array();
1112                if ($activity == 0)
1113                {
1114                        $instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$oldUser}' AND gp.wf_p_id = {$pid}");
1115                        $activities = array_values(array_map('unserialize', array_unique(array_map(create_function('$a', 'return serialize(array(\'id\' => $a[\'wf_activity_id\'], \'name\' => $a[\'wf_activity_name\']));'), $instances['data']))));
1116                }
1117                else
1118                {
1119                        $activityInfo = $this->activityManager->get_activity($activity);
1120                        $activities[] = array('id' => $activity, 'name' => $activityInfo['wf_name']);
1121                }
1122
1123                $userRoles = $this->roleManager->getUserRoles($newUser, $pid);
1124                foreach ($activities as $key => $value)
1125                {
1126                        $roles = $this->activityManager->get_activity_roles($value['id']);
1127                        $userExistsInRoles = false;
1128                        foreach ($roles as $role)
1129                        {
1130                                if (in_array($role['wf_role_id'], $userRoles))
1131                                {
1132                                        $userExistsInRoles = true;
1133                                        break;
1134                                }
1135                                else
1136                                        $activities[$key]['possibleRoles'][] = array('id' => $role['wf_role_id'], 'name' => $role['wf_name']);
1137                        }
1138                        if ($userExistsInRoles)
1139                        {
1140                                unset($activities[$key]);
1141                                continue;
1142                        }
1143                }
1144                $output = $params;
1145                $output['roles'] = array_values($activities);
1146
1147                return $output;
1148        }
1149
1150        /**
1151         * Adiciona um usuário ao perfil indicado
1152         * @param array $params Parâmetros advindos da chamada Ajax
1153         * @return array Contém a saída do método 'checkUserRoles'
1154         * @access public
1155         */
1156        function addUserToRole($params)
1157        {
1158                $pid = (int) $params['pid'];
1159                $newUser = (int) $params['newUser'];
1160                $role = (int) $params['role'];
1161
1162                /* check if the user has the proper right to list the instances of this process */
1163                if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
1164                        return "Você não tem permissão para executar este procedimento!";
1165
1166                /* get the process roles */
1167                $processRoles = $this->roleManager->list_roles($pid, 0, -1, 'wf_p_id__ASC', null);
1168                $processRoles = array_map(create_function('$a', 'return $a[\'wf_role_id\'];'), $processRoles['data']);
1169
1170                /* check if the role belongs to the process */
1171                if (!in_array($role, $processRoles))
1172                        return 'Os dados fornecidos estão incorretos.';
1173                $this->roleManager->map_user_to_role($pid, $newUser, $role, 'u');
1174
1175                return $this->checkUserRoles($params);
1176        }
1177
1178        /**
1179         * Troca os usuários das instâncias (de acordo com filtro de atividade e usuário original)
1180         * @param array $params Parâmetros advindos da chamada Ajax
1181         * @return array Contém estatísticas sobre as instâncias alteradas
1182         * @access public
1183         */
1184        function replaceUser($params)
1185        {
1186                $pid = (int) $params['pid'];
1187                $oldUser = (int) $params['oldUser'];
1188                $newUser = (int) $params['newUser'];
1189                $activity = (int) $params['activity'];
1190
1191                /* check if the user has the proper right to list the instances of this process */
1192                if (!$this->checkAccess($pid, array($this->IP_REPLACE_USER)))
1193                        return "Você não tem permissão para executar este procedimento!";
1194
1195                $instances = $this->processMonitor->monitor_list_instances(0, -1, 'wf_activity_name__ASC', null, "gia.wf_user = '{$oldUser}' AND gp.wf_p_id = {$pid}");
1196                $activities = array();
1197                if ($activity == 0)
1198                        $activities = array_unique(array_map(create_function('$a', 'return $a[\'wf_activity_id\'];'), $instances['data']));
1199                else
1200                        $activities[] = $activity;
1201
1202                $OKCount = 0;
1203                $errorCount = 0;
1204                foreach ($instances['data'] as $instance)
1205                {
1206                        if (in_array($instance['wf_activity_id'], $activities))
1207                        {
1208                                if ($this->instanceManager->set_instance_user($instance['wf_instance_id'], $instance['wf_activity_id'], $newUser))
1209                                        $OKCount++;
1210                                else
1211                                        $errorCount++;
1212                        }
1213                }
1214                $output = $params;
1215                $output['OKCount'] = $OKCount;
1216                $output['errorCount'] = $errorCount;
1217
1218                return $output;
1219        }
1220
1221        /**
1222         * Gera os e-mails enviados para alertar sobre determinadas instâncias
1223         * @param array $params Parâmetros repassados por outros métodos e que são advindos de uma chamada Ajax
1224         * @return array Uma array seqüencial onde cada elemento corresponde a uma array contendo as informações de: nome do destinatário, e-mail do destinatário, ID do destinatário, corpo do e-mail e assunto do e-mail
1225         * @access public
1226         */
1227        function generateEmails($params)
1228        {
1229                /* define the type */
1230                $type = ($params['emailType'] == 'user') ? 'user' : 'instance';
1231
1232                /* load the instances and add the username */
1233                $rawData = $this->listInstances($params, true);
1234                $list = array();
1235                foreach ($rawData['data'] as $element)
1236                        if (($element['wf_user'] != '*') && (substr($element['wf_user'], 0, 1) != 'p'))
1237                                $list[] = array_merge($element, array('wf_user_name' => $rawData['userMapping'][$element['wf_user']]));
1238
1239                /* check if there is at least one instance */
1240                $output = array();
1241                if (count($list) === 0)
1242                        return $output;
1243
1244                $BOUserInterface = &$GLOBALS['workflow']['factory']->getInstance('bo_userinterface');
1245
1246                /* initialize some variables */
1247                $translationArray = array();
1248                $emailBody = $params['emailBody'];
1249                $emailSubject = $params['emailSubject'];
1250
1251                /* if the developer decided to send only one e-mail per user */
1252                if ($type === 'user')
1253                {
1254                        /* split the e-mail according to definition */
1255                        ereg('(.*)%inicio_loop%(.*)%fim_loop%(.*)', $emailBody, $records);
1256                        if (($records == null) || (count($records) != 4))
1257                                return array('error' => 'Formato de e-mail inválido');
1258
1259                        /* prepare the list */
1260                        $userList = array();
1261                        foreach ($list as $element)
1262                                $userList[$element['wf_user']][] = $element;
1263
1264                        /* construct the e-mails */
1265                        foreach ($userList as $user => $instances)
1266                        {
1267                                /* add the e-mail header */
1268                                $email = $records[1];
1269                                $totalInstances = count($instances);
1270                                $currentInstance = 1;
1271                                foreach ($instances as $instance)
1272                                {
1273                                        /* prepare the translation array */
1274                                        $url = sprintf('%s/index.php?menuaction=workflow.run_activity.go&activity_id=%d&iid=%d', $_SESSION['phpgw_info']['workflow']['server']['webserver_url'], $instance['wf_activity_id'], $instance['wf_instance_id']);
1275                                        $translationArray = array(
1276                                                '%atividade%' => $instance['wf_activity_name'],
1277                                                '%usuario%' => $instance['wf_user_name'],
1278                                                '%processo%' => $instance['wf_procname'],
1279                                                '%identificador%' => $instance['wf_instance_name'],
1280                                                '%tempo_atividade%' => $BOUserInterface->time_diff(mktime() - $instance['wf_act_started']),
1281                                                '%tempo_instancia%' => $BOUserInterface->time_diff(mktime() - $instance['wf_started']),
1282                                                '%prioridade%' => $instance['wf_priority'],
1283                                                '%quantidade_instancia%' => $totalInstances,
1284                                                '%atual_instancia%' => $currentInstance++,
1285                                                '%inicio_atividade%' => date('d/m/Y H\hi', $instance['wf_act_started']),
1286                                                '%inicio_instancia%' => date('d/m/Y H\hi', $instance['wf_started']),
1287                                                '%url%' => $url,
1288                                                '%link%' => sprintf('<a href="%s" target="_blank">%s</a>', $url, $url)
1289                                        );
1290
1291                                        $email .= str_replace(array_keys($translationArray), array_values($translationArray), $records[2]);
1292                                }
1293
1294                                /* add the e-mail footer */
1295                                $email .= $records[3];
1296
1297                                /* replace, once again, any %variable% (also for the subject) */
1298                                $email = str_replace(array_keys($translationArray), array_values($translationArray), $email);
1299                                $subject = str_replace(array_keys($translationArray), array_values($translationArray), $emailSubject);
1300
1301                                /* construct the final e-mail array */
1302                                $output[] = array(
1303                                        'emailBody' => $email,
1304                                        'emailSubject' => $subject,
1305                                        'user' => $user
1306                                );
1307                        }
1308                }
1309
1310                if ($type === 'instance')
1311                {
1312                        /* construct the e-mails */
1313                        foreach ($list as $instance)
1314                        {
1315                                $url = sprintf('%s/index.php?menuaction=workflow.run_activity.go&activity_id=%d&iid=%d', $_SESSION['phpgw_info']['workflow']['server']['webserver_url'], $instance['wf_activity_id'], $instance['wf_instance_id']);
1316                                $translationArray = array(
1317                                        '%atividade%' => $instance['wf_activity_name'],
1318                                        '%usuario%' => $instance['wf_user_name'],
1319                                        '%processo%' => $instance['wf_procname'],
1320                                        '%identificador%' => $instance['wf_instance_name'],
1321                                        '%tempo_atividade%' => $BOUserInterface->time_diff(mktime() - $instance['wf_act_started']),
1322                                        '%tempo_instancia%' => $BOUserInterface->time_diff(mktime() - $instance['wf_started']),
1323                                        '%prioridade%' => $instance['wf_priority'],
1324                                        '%quantidade_instancia%' => 1,
1325                                        '%atual_instancia%' => 1,
1326                                        '%inicio_atividade%' => date('d/m/Y H\hi', $instance['wf_act_started']),
1327                                        '%inicio_instancia%' => date('d/m/Y H\hi', $instance['wf_started']),
1328                                        '%url%' => $url,
1329                                        '%link%' => sprintf('<a href="%s" target="_blank">%s</a>', $url, $url)
1330                                );
1331
1332                                /* replace any %variable% for its correspondence (also for the subject) */
1333                                $email = str_replace(array_keys($translationArray), array_values($translationArray), $emailBody);
1334                                $subject = str_replace(array_keys($translationArray), array_values($translationArray), $emailSubject);
1335
1336                                /* construct the final e-mail array */
1337                                $output[] = array(
1338                                        'emailBody' => $email,
1339                                        'emailSubject' => $subject,
1340                                        'user' => $instance['wf_user']
1341                                );
1342                        }
1343                }
1344
1345                /* load the recipient e-mail */
1346                $ldap = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
1347                foreach ($output as $key => $value)
1348                {
1349                        $userData = $ldap->getUserInfo($value['user']);
1350                        $output[$key]['to'] = $userData['mail'];
1351                        $output[$key]['username'] = $userData['cn'];
1352                }
1353
1354                return $output;
1355        }
1356
1357        /**
1358         * Gera um preview do e-mail que será enviado
1359         * @param array $params Parâmetros advindos da chamada Ajax
1360         * @return string O corpo do primeiro e-mail que seria enviado caso a ação "Enviar" fosse disparada
1361         * @access public
1362         */
1363        function previewEmail($params)
1364        {
1365                /* check if the user has the proper right to send e-mails related to this process */
1366                $pid = (int) $params['pid'];
1367                if (!$this->checkAccess($pid, array($this->IP_SEND_EMAILS)))
1368                        return array('error' => 'Você não tem permissão para executar este procedimento!');
1369
1370                $output = $this->generateEmails($params);
1371                if (!isset($output['error']))
1372                        return array('emailBody' => $output[0]['emailBody'], 'emailCount' => count($output));
1373                else
1374                        return $output;
1375        }
1376
1377        /**
1378         * Envia e-mails para os usuários das instâncias selecionadas
1379         * @param array $params Parâmetros advindos da chamada Ajax
1380         * @return int O número de e-mails enviados
1381         * @access public
1382         */
1383        function sendMail($params)
1384        {
1385                /* check if the user has the proper right to send e-mails related to this process */
1386                $pid = (int) $params['pid'];
1387                if (!$this->checkAccess($pid, array($this->IP_SEND_EMAILS)))
1388                        return array('error' => 'Você não tem permissão para executar este procedimento!');
1389
1390                /* generate the e-mails */
1391                $emails = $this->generateEmails($params);
1392
1393                /* check for errors */
1394                if (isset($emails['error']) || (count($emails) == 0))
1395                        return $emails;
1396
1397                /* prepare the environment to load some configuration values from other module */
1398                $GLOBALS['phpgw']->db = &$GLOBALS['workflow']['workflowObjects']->getDBExpresso();
1399                $GLOBALS['phpgw']->common = CreateObject('phpgwapi.common');
1400                $GLOBALS['phpgw']->session = CreateObject('phpgwapi.sessions');
1401                function lang($a){return $a;};
1402
1403                /* get the required configuration */
1404                $BOEmailAdmin = $GLOBALS['workflow']['factory']->newForeignInstance('emailadmin', 'bo');
1405                $profileList = $BOEmailAdmin->getProfileList();
1406                $profile = $BOEmailAdmin->getProfile($profileList[0]['profileID']);
1407
1408                /* configure the PHPMailer class to send the e-mails */
1409                require_once '../expressoMail1_2/inc/class.phpmailer.php';
1410                $phpMailer = new PHPMailer();
1411                $phpMailer->SMTPDebug = false;
1412                $phpMailer->IsSMTP();
1413                $phpMailer->Host = $profile['smtpServer'];
1414                $phpMailer->Port = $profile['smtpPort'];
1415                $phpMailer->From = 'no-reply@' . $profile['defaultDomain'];
1416                $phpMailer->FromName = 'Workflow Expresso';
1417
1418                /* send the e-mails */
1419                $count = 0;
1420                foreach ($emails as $email)
1421                {
1422                        $phpMailer->ClearAllRecipients();
1423                        $phpMailer->IsHTML(true);
1424                        $phpMailer->Subject = $email['emailSubject'];
1425                        $phpMailer->Body = $email['emailBody'];
1426                        $phpMailer->AddAddress($email['to'], $email['username']);
1427                        if ($phpMailer->Send())
1428                                $count++;
1429                }
1430                return $count;
1431        }
1432
1433        /**
1434         * Lista instâncias inconsistentes.
1435         * @param array $params Parâmetros advindos da chamada Ajax
1436         * @return array Uma array contendo as instâncias de acordo com suas inconsistências
1437         * @access public
1438         */
1439        function loadInconsistentInstances($params)
1440        {
1441                $processID = (int) $params['pid'];
1442                /* check if the user has the proper right to send e-mails related to this process */
1443                if (!$this->checkAccess($processID))
1444                        return "Você não tem permissão para executar este procedimento!";
1445
1446                $output = array(
1447                        'instances' => array(),
1448                        'names' => array(),
1449                        'params' => $params
1450                );
1451
1452                $output['instances'][] = array(
1453                        'name' => 'Usuários Removidos',
1454                        'description' => 'Quando uma instância está atribuída a um usuário que não está mais no LDAP.',
1455                        'items' => $this->inconsistentInstancesRemovedUser($processID)
1456                );
1457
1458                $output['instances'][] = array(
1459                        'name' => 'Usuários sem Autorização',
1460                        'description' => 'Quando o usuário que está com a instância não pertence a nenhum dos perfis da atividade desta instância.',
1461                        'items' => $this->inconsistentInstancesUnauthorizedUsers($processID)
1462                );
1463
1464                $output['instances'][] = array(
1465                        'name' => 'Instâncias Falhas',
1466                        'description' => 'Quando uma instância encontra-se em uma atividade não-interativa.',
1467                        'items' => $this->inconsistentInstancesFailedInstances($processID)
1468                );
1469
1470                $output['instances'][] = array(
1471                        'name' => 'Instâncias Finalizadas Vinculadas a uma Atividade',
1472                        'description' => 'Quando uma instância finalizada ou abortada ainda está vinculada a uma atividade.',
1473                        'items' => $this->inconsistentInstancesUnfinishedActivity($processID)
1474                );
1475
1476                $userIDs = array();
1477                foreach ($output['instances'] as $inconsistencyTypes)
1478                        foreach ($inconsistencyTypes['items'] as $instance)
1479                                $userIDs[$instance['wf_user']] = '';
1480
1481                $output['names'] = $this->getNames(array_keys($userIDs), $processID);
1482
1483                return $output;
1484        }
1485
1486        /**
1487         * Carrega os nomes de usuários/perfis
1488         * @param array $userIDs Uma array contendo os IDs dos usuários/perfis.
1489         * @param int $processID O ID do processo de onde os nomes dos perfis serão extraídos
1490         * @return array Uma array associativa no formato ID => Nome
1491         * @access public
1492         */
1493        private function getNames($userIDs, $processID)
1494        {
1495                $output = array();
1496                $cachedLDAP = &$GLOBALS['workflow']['factory']->getInstance('CachedLDAP');
1497                $ldap = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
1498                foreach ($userIDs as $userID)
1499                {
1500                        if (!isset($output[$userID]))
1501                        {
1502                                if ($userID == '*')
1503                                {
1504                                        $output['*'] = '*';
1505                                        continue;
1506                                }
1507
1508                                if (substr($userID, 0, 1) == 'p')
1509                                {
1510                                        $role = $this->roleManager->get_role($processID, substr($userID, 1));
1511                                        $output[$userID] = 'Perfil: ' . $role['wf_name'];
1512                                }
1513                                else
1514                                {
1515                                        $name = $ldap->getName($userID);
1516                                        if (empty($name))
1517                                        {
1518                                                $userInfo = $cachedLDAP->getEntryByID($userID);
1519                                                if ($userInfo)
1520                                                        $name = "ID: {$userID} - {$userInfo['cn']} (excluído)";
1521                                                else
1522                                                        $name = "ID: {$userID}";
1523                                        }
1524
1525                                        $output[$userID] = $name;
1526                                }
1527                        }
1528                }
1529                return $output;
1530        }
1531
1532        /**
1533         * Lista as instâncias inconsistentes: instâncias que estão com usuários que foram removidos do LDAP
1534         * @param int $processID O ID do processo
1535         * @return array Lista das instâncias que satisfazem o critério de inconsistência
1536         * @access public
1537         */
1538        private function inconsistentInstancesRemovedUser($processID)
1539        {
1540                $filters = array();
1541                $filters[] = "(gp.wf_p_id = {$processID})";
1542                $filters[] = '(gia.wf_user IS NOT NULL)';
1543
1544                $cachedLDAP = &$GLOBALS['workflow']['factory']->newInstance('CachedLDAP');
1545                $cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_LDAP);
1546                $output = array();
1547                $instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
1548
1549                $userIDs = array();
1550                foreach ($instanceList['data'] as $instance)
1551                {
1552                        if (substr($instance['wf_user'], 0, 1) == 'p')
1553                                continue;
1554
1555                        if ($instance['wf_user'] == '*')
1556                                continue;
1557
1558                        $userIDs[$instance['wf_user']] = true;
1559                }
1560
1561                $validUsers = $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP')->getNames(array_keys($userIDs));
1562                array_walk($validUsers, create_function('&$a', '$a = $a[\'id\'];'));
1563
1564                foreach ($instanceList['data'] as $instance)
1565                {
1566                        if (substr($instance['wf_user'], 0, 1) == 'p')
1567                                continue;
1568
1569                        if ($instance['wf_user'] == '*')
1570                                continue;
1571
1572                        if (!in_array($instance['wf_user'], $validUsers))
1573                                $output[] = $instance;
1574                }
1575
1576                return $output;
1577        }
1578
1579        /**
1580         * Lista as instâncias inconsistentes: instâncias que estão com usuários que não estão em nenhum dos perfis da atividade em que a instância se encontra
1581         * @param int $processID O ID do processo
1582         * @return array Lista das instâncias que satisfazem o critério de inconsistência
1583         * @access public
1584         */
1585        private function inconsistentInstancesUnauthorizedUsers($processID)
1586        {
1587                $output = array();
1588                $roleIDs = array();
1589                $roles = $this->roleManager->list_roles($processID, 0, -1, 'wf_role_id__ASC', '');
1590                foreach ($roles['data'] as $role)
1591                        $roleIDs[] = $role['wf_role_id'];
1592                $activities = $this->activityManager->list_activities($processID, 0, -1, 'wf_name__asc', '', '');
1593                $activityUsers = array();
1594                foreach ($activities['data'] as $activity)
1595                {
1596                        if ($activity['wf_is_interactive'] == 'y')
1597                        {
1598                                $userList = $this->roleManager->list_mapped_users($processID, true, array('wf_activity_id' => $activity['wf_activity_id']));
1599                                if (!isset($activityUsers[$activity['wf_activity_id']]))
1600                                        $activityUsers[$activity['wf_activity_id']] = array();
1601                                $activityUsers[$activity['wf_activity_id']] += array_keys($userList);
1602                        }
1603                }
1604
1605                $filters = array();
1606                $filters[] = "(gp.wf_p_id = {$processID})";
1607                $filters[] = "(ga.wf_is_interactive = 'y')";
1608                $filters[] = '(gia.wf_user IS NOT NULL)';
1609                $instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
1610                foreach ($instanceList['data'] as $instance)
1611                {
1612                        if ($instance['wf_user'] == '*')
1613                                continue;
1614
1615                        if (substr($instance['wf_user'], 0, 1) == 'p')
1616                                if (in_array(substr($instance['wf_user'], 1), $roleIDs))
1617                                        continue;
1618
1619                        if (in_array($instance['wf_user'], $activityUsers[$instance['wf_activity_id']]))
1620                                continue;
1621
1622                        $output[] = $instance;
1623                }
1624
1625                return $output;
1626        }
1627
1628        private function inconsistentInstancesFailedInstances($processID)
1629        {
1630                $filters = array();
1631                $filters[] = "(gp.wf_p_id = {$processID})";
1632                $filters[] = "(ga.wf_is_interactive = 'n')";
1633                $filters[] = '(gia.wf_started < ' . (date('U') - 60). ')';
1634                $instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
1635
1636                return $instanceList['data'];
1637        }
1638
1639        /**
1640         * Lista as instâncias inconsistentes: instâncias que estão paradas em atividades não-interativas há mais de um minuto
1641         * @param int $processID O ID do processo
1642         * @return array Lista das instâncias que satisfazem o critério de inconsistência
1643         * @access public
1644         */
1645        private function inconsistentInstancesUnfinishedActivity($processID)
1646        {
1647                $filters = array();
1648                $filters[] = "(gp.wf_p_id = {$processID})";
1649                $filters[] = "(gi.wf_status IN ('aborted', 'completed'))";
1650                $filters[] = '(gia.wf_activity_id IS NOT NULL)';
1651                $instanceList = $this->processMonitor->monitor_list_instances(0, -1, 'wf_instance_id__ASC', '', implode(' AND ', $filters));
1652
1653                return $instanceList['data'];
1654        }
1655}
1656?>
Note: See TracBrowser for help on using the repository browser.