Questions and discussion about developing processes and programming in PHP, JavaScript, web services & REST API.
Forum rules: Please search to see if a question has already asked before creating a new topic. Please don't post the same question in multiple forums.
By marcosfpa
#795850
Hello, in my intranet I have created an interface to interact with the Processmaker task list using the APIs. I am able to list the tasks, pause, pause, etc ...
But there is one item I am not getting: pass to the processmaker via API that the task was started. In the processmaker is when we access the task via 2 clicks on it ...
Any idea?
#795851
When a task in a case is opened, nothing happens to the case until the first step (DynaForm, Input Document or Output Document) in the task is submitted. Then the APP_STATUS changes from 'TO_DO' to 'DRAFT'. If you want to cause that status change, then create a trigger with this code:
Code: Select all
$c = new Cases();
$aCaseInfo = $c->LoadCase(@@APPLICATION, @%INDEX);
$aCaseInfo['APP_STATUS'] = 'DRAFT';
$c->updateCase(@@APPLICATION, $aCaseInfo); 
Then execute this trigger with /cases/{app_uid}/execute-trigger/{tri_uid}
#795861
Well, you could create a custom REST endpoint with this code:
Code: Select all
$c = new Cases();
$aCaseInfo = $c->LoadCase($caseId, $delIndex);
$aCaseInfo['APP_STATUS'] = 'DRAFT';
$c->updateCase(@@APPLICATION, $aCaseInfo);
or you could first set the case variables @@caseId and @@delIndex in the case with REST POST cases/{app_uid}/variables and then call execute-trigger.
#795916
marcosfpa wrote:I do not understand very well, should I create a plugin that creates a custom API, would it?
Let me try to explain better. One option is to create a custom REST endpoint with this code:
Code: Select all
$c = new Cases();
$aCaseInfo = $c->LoadCase($caseId, $delIndex);
$aCaseInfo['APP_STATUS'] = 'DRAFT';
$c->updateCase($caseId, $aCaseInfo);
Where $caseId and $delIndex are passed by your REST endpoint either as POST variables or as GET variables in the URL.

The second option is probably easier. Create a process which is only used to reset the status of cases which has a case which never closes:
looparoundProcess.png
looparoundProcess.png (6.66 KiB) Viewed 15546 times
Then, add this trigger to the process:
Code: Select all
if (empty(@@caseId)) {
   throw new Exception("The caseId variable was not set!");
}

$c = new Cases();
$aCaseInfo = $c->LoadCase(@@caseId, @@delIndex);
$aCaseInfo['APP_STATUS'] = 'DRAFT';
$c->updateCase(@@caseId, $aCaseInfo);
 
Then start a case in this process and copy its case ID, which you can use forever in your script code.

When you want to change the status of a case from "TO_DO" to "DRAFT", then use a script like this:
Code: Select all
$permanentCaseId = 'XXXXXXXXXXXXXXXXXXXXXXX'; //set to the ID of the case that never closes

//set to the ID and delegation index of the case whose status should be changed:
$aVars = array(
   "caseId"    => '78484118955bbd5fc39e5c5072875367',                      
   "delIndex"=> 2
);

//first set the case variables:
$url = "/api/1.0/workflow/cases/$permanentCaseId/variable";
$oRet = pmRestRequest("PUT", $url, $aVars, $oToken->access_token);
if ($oRet->status != 200) {
   throw new Exception("Error setting variables in case.");
}

//then execute the trigger:
$triggerId = '37823572555ba5891041136049273220';
$url = "/api/1.0/workflow/cases/$permanentCaseId/execute-trigger/$triggerId";
$oRet = pmRestRequest('PUT', $url, null, $oToken->access_token);
#795979
It worked.
But I came up with another question, I was able to capture and handle tasks with REST API in my internal portal, also access dynaform normally ... But how could I access via API the process map of the case?
Screenshot_1.png
Screenshot_1.png (32.08 KiB) Viewed 15513 times
#795983
There is no way to display the process map for a case with REST.

What you can do is login with web services, then use the session ID from your login to access the URL for displaying the process map:
http://example.com/sysworkflow/en/neocl ... SESSION-ID>

You can display this in an iframe in your external web page. Here is a code example:
Code: Select all
<?php
ini_set("soap.wsdl_cache_enabled", "0");
ini_set('error_reporting', E_ALL); //uncomment to debug
ini_set('display_errors', True);  //uncomment to debug
     
$client = new SoapClient('http://localhost:321/sysworkflow/en/neoclassic/services/wsdl2');
$username = 'admin';
$pass = 'md5:' . hash('sha256', 'p4sSw0rD');
$params = array(array('userid'=>$username, 'password'=>$pass));
$result = $client->__SoapCall('login', $params);
 
if ($result->status_code != 0) {
    die("<html><body><pre> Unable to connect to ProcessMaker.\n" .
        "Error Message: $result->message");
}

$sessionId = $result->message;

//can get process and case IDs with REST GET /cases or caseList() web services,
//but using fixed IDs here to simplify example:
$processId = '96964465859d6b6cc7ada25050543907';
$caseId = '50253320659d6d12922c214005232609';

$url = "http://localhost:321/sysworkflow/en/neoclassic/designer?prj_uid=$processId&prj_readonly=true&app_uid=$caseId&sid=$sessionId";

print "<html><body>
<iframe id=\"processMapFrame\" name=\"processMapFrame\" src=\"$url\" 
width=\"100%\" height=\"700px\" frameboarder=\"1px\">
</body>
</html>";
 
#795995
I have not found an API to list user-supervised cases ... can you tell me which REST API is appropriate?
There is no REST endpoint to get the cases list under Home > Review.

To display the case list under Home > Review, you can use this URL:
http://<URL>/sys<WORKSPACE>/<LANG>/<SKIN>/cases/casesListExtJs?action=to_revise&sid=<SESSION-ID>
where <SESSION-ID> was obtained with a web service login.
For example:
http://example.com/sysworkflow/en/neocl ... 67890abcde

If you want to display the case list in own interface, you can create a trigger to retrieve the case list and assign it to a case variable. Then execute the trigger with REST and then retrieve the case variable with REST.

Here would be the trigger code:
Code: Select all
G::LoadClass("applications");

/*In /workflow/engine/classes/class.applications.php
Applications::getAll(
        $userUid,
        $start = null,
        $limit = null,
        $action = null,
        $filter = null,
        $search = null,
        $process = null,
        $status = null,
        $type = null,
        $dateFrom = null,
        $dateTo = null,
        $callback = null,
        $dir = null,
        $sort = "APP_CACHE_VIEW.APP_NUMBER",
        $category = null,
        $configuration = true,
        $paged = true,
        $newerThan = '',
        $oldestThan = ''
    )*/

$oApp = new Applications();
$aList = $oApp->getAll(@@USER_LOGGED, null, null, 'to_revise');
@=reviewCasesList = $aList['data']; 
Similar to the previous example I gave you, create a permanent case for executing this trigger with REST and then retrieve the "reviewCasesList" variable.

Here is the structure of the array in the @=reviewCasesList variable:
Code: Select all
array(2) {
  [0]=>
  array(44) {
    ["APP_UID"]=>
    string(32) "58710999959eec5c40e4650064585027"
    ["DEL_INDEX"]=>
    string(1) "2"
    ["DEL_LAST_INDEX"]=>
    string(1) "1"
    ["APP_NUMBER"]=>
    string(2) "68"
    ["APP_STATUS"]=>
    string(5) "TO_DO"
    ["USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["PREVIOUS_USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["TAS_UID"]=>
    string(32) "68632115059eeb9d11337e8058023548"
    ["PRO_UID"]=>
    string(32) "91274247259eeb7d86ab916042797239"
    ["DEL_DELEGATE_DATE"]=>
    string(19) "2017-10-24 00:47:00"
    ["DEL_INIT_DATE"]=>
    NULL
    ["DEL_FINISH_DATE"]=>
    NULL
    ["DEL_TASK_DUE_DATE"]=>
    string(19) "2017-10-24 17:00:00"
    ["DEL_RISK_DATE"]=>
    string(19) "2017-10-24 15:24:00"
    ["DEL_THREAD_STATUS"]=>
    string(4) "OPEN"
    ["APP_THREAD_STATUS"]=>
    string(4) "OPEN"
    ["APP_TITLE"]=>
    string(3) "#68"
    ["APP_PRO_TITLE"]=>
    string(15) "Check web entry"
    ["APP_TAS_TITLE"]=>
    string(6) "Task 1"
    ["APP_CURRENT_USER"]=>
    string(19) "admin Administrator"
    ["APP_DEL_PREVIOUS_USER"]=>
    string(19) "admin Administrator"
    ["DEL_PRIORITY"]=>
    string(6) "NORMAL"
    ["DEL_DURATION"]=>
    string(1) "0"
    ["DEL_QUEUE_DURATION"]=>
    string(1) "0"
    ["DEL_DELAY_DURATION"]=>
    string(1) "0"
    ["DEL_STARTED"]=>
    string(1) "0"
    ["DEL_FINISHED"]=>
    string(1) "0"
    ["DEL_DELAYED"]=>
    string(1) "0"
    ["APP_CREATE_DATE"]=>
    string(19) "2017-10-24 00:47:00"
    ["APP_FINISH_DATE"]=>
    NULL
    ["APP_UPDATE_DATE"]=>
    string(19) "2017-10-24 00:47:00"
    ["APP_OVERDUE_PERCENTAGE"]=>
    string(1) "0"
    ["USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["USR_LASTNAME"]=>
    string(5) "admin"
    ["USR_USERNAME"]=>
    string(5) "admin"
    ["APPDELCR_APP_TAS_TITLE"]=>
    string(6) "Task 1"
    ["USRCR_USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["USRCR_USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["USRCR_USR_LASTNAME"]=>
    string(5) "admin"
    ["USRCR_USR_USERNAME"]=>
    string(5) "admin"
    ["PREVIOUS_USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["PREVIOUS_USR_LASTNAME"]=>
    string(5) "admin"
    ["PREVIOUS_USR_USERNAME"]=>
    string(5) "admin"
    ["APP_STATUS_LABEL"]=>
    string(5) "To do"
  }
  [1]=>
  array(44) {
    ["APP_UID"]=>
    string(32) "70098586859eec5a747a730036274121"
    ["DEL_INDEX"]=>
    string(1) "2"
    ["DEL_LAST_INDEX"]=>
    string(1) "1"
    ["APP_NUMBER"]=>
    string(2) "67"
    ["APP_STATUS"]=>
    string(5) "TO_DO"
    ["USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["PREVIOUS_USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["TAS_UID"]=>
    string(32) "68632115059eeb9d11337e8058023548"
    ["PRO_UID"]=>
    string(32) "91274247259eeb7d86ab916042797239"
    ["DEL_DELEGATE_DATE"]=>
    string(19) "2017-10-24 00:46:32"
    ["DEL_INIT_DATE"]=>
    NULL
    ["DEL_FINISH_DATE"]=>
    NULL
    ["DEL_TASK_DUE_DATE"]=>
    string(19) "2017-10-24 17:00:00"
    ["DEL_RISK_DATE"]=>
    string(19) "2017-10-24 15:24:00"
    ["DEL_THREAD_STATUS"]=>
    string(4) "OPEN"
    ["APP_THREAD_STATUS"]=>
    string(4) "OPEN"
    ["APP_TITLE"]=>
    string(3) "#67"
    ["APP_PRO_TITLE"]=>
    string(15) "Check web entry"
    ["APP_TAS_TITLE"]=>
    string(6) "Task 1"
    ["APP_CURRENT_USER"]=>
    string(19) "admin Administrator"
    ["APP_DEL_PREVIOUS_USER"]=>
    string(19) "admin Administrator"
    ["DEL_PRIORITY"]=>
    string(6) "NORMAL"
    ["DEL_DURATION"]=>
    string(1) "0"
    ["DEL_QUEUE_DURATION"]=>
    string(1) "0"
    ["DEL_DELAY_DURATION"]=>
    string(1) "0"
    ["DEL_STARTED"]=>
    string(1) "0"
    ["DEL_FINISHED"]=>
    string(1) "0"
    ["DEL_DELAYED"]=>
    string(1) "0"
    ["APP_CREATE_DATE"]=>
    string(19) "2017-10-24 00:46:31"
    ["APP_FINISH_DATE"]=>
    NULL
    ["APP_UPDATE_DATE"]=>
    string(19) "2017-10-24 00:46:31"
    ["APP_OVERDUE_PERCENTAGE"]=>
    string(1) "0"
    ["USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["USR_LASTNAME"]=>
    string(5) "admin"
    ["USR_USERNAME"]=>
    string(5) "admin"
    ["APPDELCR_APP_TAS_TITLE"]=>
    string(6) "Task 1"
    ["USRCR_USR_UID"]=>
    string(32) "00000000000000000000000000000001"
    ["USRCR_USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["USRCR_USR_LASTNAME"]=>
    string(5) "admin"
    ["USRCR_USR_USERNAME"]=>
    string(5) "admin"
    ["PREVIOUS_USR_FIRSTNAME"]=>
    string(13) "Administrator"
    ["PREVIOUS_USR_LASTNAME"]=>
    string(5) "admin"
    ["PREVIOUS_USR_USERNAME"]=>
    string(5) "admin"
    ["APP_STATUS_LABEL"]=>
    string(5) "To do"
  }
}
Here is a sample process:
(25.55 KiB) Downloaded 292 times
#798126
I'm trying to run TRIGGERS on my custom interface via REST API and I'm not getting it. I reasoned for this:
http://wiki.processmaker.com/3.2/Light_ ... s#Triggers

But it gives error, see a piece of my code in dynaform.php, what's wrong?
Code: Select all
<?php
    session_start();
    if (is_null($_SESSION['access_token']))
        header('Location: index.html');
   
    require_once('executeREST.php');
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/activity/'.$_GET['task'].'/steps';
    $steps = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );
  
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/dynaform/'.$steps[0]['step_uid_obj'];
    $dynaform = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );

    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/cases/'.$_GET['app'].'/variables';
    $variables = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );

    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/light/process/'.$_GET['proj'].'/task/'.$_GET['task'].
       '/case/'.$_GET['app'].'/step/'.$steps[0]['step_uid_obj'].'/execute-trigger/before';
    $trigger = executeREST( $url, 'GET', array(), $_SESSION['access_token'] ); 
#798772
marcosfpa wrote:I'm trying to run TRIGGERS on my custom interface via REST API and I'm not getting it. I reasoned for this:
http://wiki.processmaker.com/3.2/Light_ ... s#Triggers

But it gives error, see a piece of my code in dynaform.php, what's wrong?
Code: Select all
<?php
    session_start();
    if (is_null($_SESSION['access_token']))
        header('Location: index.html');
   
    require_once('executeREST.php');
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/activity/'.$_GET['task'].'/steps';
    $steps = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );
  
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/dynaform/'.$steps[0]['step_uid_obj'];
    $dynaform = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );

    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/cases/'.$_GET['app'].'/variables';
    $variables = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );

    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/light/process/'.$_GET['proj'].'/task/'.$_GET['task'].
       '/case/'.$_GET['app'].'/step/'.$steps[0]['step_uid_obj'].'/execute-trigger/before';
    $trigger = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );
I don't see anything wrong with your code, but I can't see all the values you are using in the URLs. To figure out where the error is occurring, put code like this after each REST call until you find where the error occurs:
print "<pre>"; var_dump($steps); die;
#798778
Code: Select all
array (size=1)
  0 => 
    array (size=9)
      'step_uid' => string '67618611859482ab89772a7030661142' (length=32)
      'step_type_obj' => string 'DYNAFORM' (length=8)
      'step_uid_obj' => string '788739539594829b09edde1009188456' (length=32)
      'step_condition' => string '' (length=0)
      'step_position' => int 1
      'step_mode' => string 'EDIT' (length=4)
      'obj_title' => string 'aprovacao' (length=9)
      'obj_description' => string '' (length=0)
      'triggers' => 
        array (size=1)
          0 => 
            array (size=6)
              ...
There was an error: Not Found
#798781
Would it be this?


array (size=33)
'SYS_LANG' => string 'pt' (length=2)
'SYS_SKIN' => string 'neoclassic' (length=10)
'SYS_SYS' => string 'sample' (length=6)
'APPLICATION' => string '33576043259f0e61322fe82091567201' (length=32)
'PROCESS' => string '74598590658a59704455916054657907' (length=32)
'TASK' => string '948553900594829385788c0014908348' (length=32)
'INDEX' => string '4' (length=1)
'USER_LOGGED' => string '00000000000000000000000000000001' (length=32)
'USR_USERNAME' => string 'admin' (length=5)
'senhaCliente' => string '8636bdeb6302589eef8880016870a62e' (length=32)
'senhaCliente_label' => string '8636bdeb6302589eef8880016870a62e' (length=32)
'textVar002' => string '' (length=0)
'textVar002_label' => string '' (length=0)
'prioridade' => string '1' (length=1)
'prioridade_label' => string '1 - Muito Baixa' (length=15)
'arquivos' => null
'ManagerDecision' => string '01' (length=2)
'ManagerDecision_label' => string 'OK' (length=2)
'idtracker' => string '598Q' (length=4)
'idtracker_label' => string '598Q' (length=4)
'taskUser' => string '' (length=0)
'taskUser_label' => string '' (length=0)
'nextSenha' => string '' (length=0)
'nextSenha_label' => string '' (length=0)
'APP_NUMBER' => string '9278' (length=4)
'PIN' => string '598Q' (length=4)
'arqAprovacao' =>
array (size=1)
0 =>
array (size=2)
'appDocUid' => null
'name' => null
'__ERROR__' => string 'This row doesn't exist!' (length=23)
'__VAR_CHANGED__' => string 'envio,APPLICATION' (length=17)
'firstFileId' => null
'firstFilename' => null
'aprovacaoArteFinal' => string '' (length=0)
'envio' => int 1

But when I try var_dump ($ trigger) it does not return anything but the error:
There was an error: Not Found
#798788
You need to use the step_uid, not the step_uid_obj. Try this code:
Code: Select all
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/light/process/'.$_GET['proj'].'/task/'.$_GET['task'].
       '/case/'.$_GET['app'].'/step/'.$steps[0]['step_uid'].'/execute-trigger/before';
    $trigger = executeREST( $url, 'GET', array(), $_SESSION['access_token'] ); 
#798790
I've tried it, it gives the same error ... is there any similar API? I'll have to try something else ...

I found this similar solution, until it executes the first TRIGGER found but soon after gives the error below and does not show the form:
Code: Select all
<?php
    session_start();
    if(is_null($_SESSION['access_token']))
        header('Location: index.html');
   
    require_once('executeREST.php');
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/activity/'.$_GET['task'].'/steps';
    $steps = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );
    
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/dynaform/'.$steps[0]['step_uid_obj'];
    $dynaform = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );

    
    $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/project/'.$_GET['proj'].'/activity/'.$_GET['task'].'/step/'.$steps[0]['step_uid'].'/triggers';
    $tr = executeREST( $url, 'GET', array(), $_SESSION['access_token'] );
    
    if (count($tr) > 0) {
        for($i = 0; $i<=count($tr)-1; $i++) {
            echo $tr[$i]['st_type']."<br/>";
            echo $tr[$i]['tri_uid']."<br/>";
            if($tr[$i]['st_type'] == "BEFORE") {

                $url = $_SESSION['url'].'/api/1.0/'.$_SESSION['ws'].'/cases/'.$_GET['app'].'/execute-trigger/'.$tr[0]['tri_uid'];
                //echo $url;
                $trExec = executeREST( $url, 'PUT', array(), $_SESSION['access_token'] );                            
            } 
        }
    } 
Error:
Houve um erro: Bad Request: It is not possible to execute the query. Please contact your system administrator
#798802
Have you verified that the UID exists in the TRIGGER.TRI_UID field in the database?

Maybe there is an error in your trigger. Have you tried executing a simple trigger like?:
Code: Select all
@@myVar = "hello world";
Post the code of your trigger.
#798807
I have already done these tests, if I leave only 1 TRIGGER it performs normal but gives the error and does not show the form. If I put 2 or more TRIGGERS executes only the first and gives the error and does not show the form. It seems the TRIGGER is not the problem ...
#798830
Is the user who is logged in with REST and executing the trigger also assigned to an open task in the case? (I'm not sure if that is necessary, but I know that PM has added new security restrictions in other REST endpoints.)
#812570
Well, I've created a task list interface in my intranet in a custom way. But when the user accesses the task I call the normal ProcessMaker interface (with steps and dynaforms and everything else). But I have 2 problems that I can not solve:
1- When the user is going to access the task is asked to login to access the processmaker execution window, can I call the window already with sending the user session?
2- After the routing screen to finish the task the user is taken to the original task list of the processmaker and not to mine. In what processmaker file do I find this setting to edit and instead send the user to ../cases/main send to the address of my custom list?
#812572
You can open most URLs inside ProcessMaker by attaching the session ID number. If you want to skip the login screen and go directly to any screen inside processmaker, just add &sid={SESSION-ID} to any URL. If you have already logged in with web services, it should work. See:
http://wiki.processmaker.com/3.0/Proces ... atic_Login

If you want to get the REST access token after login with web services, then use the web service executeTrigger() to execute this trigger:
viewtopic.php?f=44&t=713519&p=795087#p795087

As for redirecting back to the case list, you can edit the code in workflow/engine/methods/cases/cases_Derivate.php.
Change line 296 from:
Code: Select all
    G::header( "location: $loc" );
To:
Code: Select all
    G::header( "location: http://my/special/page" );
Want to create your own meme coin?

In the world of cryptocurrencies, a unique and exc[…]

The market for cryptocurrencies is demonstrating a[…]

What's SAP FICO?

Embarking on a dissertation can be one of the most[…]

Hello. For rental housing, there are software solu[…]