Web Entry
|
|
|
Web Entry allows anonymous, external users to initiate new cases from an external web page, without the necessity of manually logging into ProcessMaker. Web Entry provides a web link or the HTML code to a DynaForm in the first task of a process. The user fills out this DynaForm and submits the data back to ProcessMaker through WSDL Web Services, which can either be called automatically or manually.
Web Entry is useful when offering services directly to clients through your organization's web page. For instance, a school could use Web Entry to allow prospective students to apply by filling out a ProcessMaker DynaForm embedded in its web page. Likewise, a company could use Web Entry to provide its clients with an order form for its services.
Web Entry provides the "PHP pages with web services" option to generate an external web link to a DynaForm in the initial step of a process. This link can be used in an HTML <a href> in an external web page or can be embedded inside an external web page through an HTML <frame> or <iframe>.
For ambitious web developers who want greater control, Web Entry also offers the "Single HTML" option to generate the HTML code for a DynaForm. That code can be incorporated directly into an organization's web page, but ProcessMaker's WSDL Web Services have to be manually called to remotely login and create a new case with the data filled in the DynaForm. If filling out a form for an existing case, send the data to the case with the sendVariables() web service.
Create a Web Entry
First, create the DynaForm which will be displayed in a Web Entry and assign it as a step in an initial task in the process. Then, open the process and right click on a blank area of the process map. Select the option Web Entry from the drop down menu.
At the top of the list of Web Entries, click on the New link to create a new Web Entry.
Define the following Web Entry properties:
- Initial Task: Select the task in which the case will start. Only tasks which have a Starting Task routing rule can be selected.
- Initial Dynaform: Select which DynaForm in the initial task will be used for the Web Entry. Only DynaForms assigned as a step in the Initial Task can be selected.
- Method: Select whether the Web Entry form will be based upon:
- PHP pages with Web Services: If this option is selected, then the fields to enter a Web Services User and Password will appear below.
- Single HTML: This option only generates the HTML code for the DynaForm, so it is not necessary to enter a Web Services User and Password.
- Input Documents Access: If the Web Entry form has a file field which is associated with an Input Document, this option configures whether the external user can upload input documents with No Restriction (the default option) or access is Restricted to Process Permissions for the Web Services User entered below.
- Web Services User: Enter the name of a ProcessMaker user who will login to ProcessMaker using Web Services and will be assigned to the first task for any cases which are created using Web Entry. This user must be assigned to the selected Initial Task and have a status of "ACTIVE".
- Web Services Password: Enter the password for the Web Services User.
After defining the web entry properties, click on Test Configuration to verify that the selected properties and the user are valid. If valid, the Generate Web Entry Page button will be activated.
Click on Generate Web Entry Page to create the new Web Entry.
Note: Due to the fact that a normal user may change his/her password and thus break the Web Entry, it is good idea to create a dummy user whose password will never change for the purpose of creating new cases with Web Entry. However, it is only a good idea to use a dummy user if the Web Entry form is the last step in the initial task and the case will automatically be routed onto the second task in the process. Otherwise, someone will have to log into the dummy user's account in ProcessMaker in order to work on the cases.
PHP pages with Web Services
If the PHP Pages with Web Services option was selected when creating the Web Entry, then a link to the Web Entry form will be added to the list of available Web Entries:
This is a link to the initial DynaForm to start a case with Web Entry. This link can be inserted in an external web page or sent as a link in an email. When the external user fills out and submits the DynaForm, web services will automatically be called to login into ProcessMaker and start a new case with the data filled into the DynaForm. The new case will be automatically assigned to the user defined for the web entry and its status will be set to "DRAFT".
Any triggers set to fire after the DynaForm will be automatically fired when the user submits the DynaForm. If the DynaForm is the last step in the task, then the case will be automatically routed to the next task in the process and its status will be set to "TO DO". Any triggers associated with routing and case assignment will be automatically fired.
Note that the PHP page with web services option can only be used with cases whose initial task have Cyclical Assignment of users.
Single HTML
If the Single HTML option was selected when defining the Web Entry, then a dialog box will appear with the HTML code for the selected DynaForm in the initial task.
This code can be pasted into separate HTML page or inserted into the HTML code for a existing page in an external web site. If creating a separate HTML page, it can can be linked to with an anchor (<a href="...">) or a frame (<frame src="...">). Note that this HTML code will does not support Dependent Fields, nor DynaForm Conditions. If pasting the Web Entry's HTML code into an existing page, copy the code between the <head>...</head> tags into the existing page's head and copy the code between the <body>...</body> tags part into the existing page's body.
The Single HTML option has a number of limitations, but to use it, see the code examples at Manually Implementing Web Entry.
Inserting Web Entries into Web Pages
The easiest way to insert a Web Entry form into an external web page is to simply add a link (anchor) to the Web Entry form in the web page.
For example, a web entry generated with the "PHP Pages with Web Services" option has the link:
- http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php
Then, a link to the Web Entry form could be added to a web page:
<html> <head> </head> </body> <p><img src="acmelogo.png"><big>Acme title text</big></p> <p>Apply to work at Acme Inc: <a href="http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php">Application Form</a></p> <p>Acme footer text</p> </body> </html>
To link to the same Web Entry form by clicking on an image:
<a href="http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php"><img src="applyGraphic.png"></a>A Web Entry form can be embedded inside an existing web page through the use of HTML frames.
For example, the same web entry form can be embedded in a HTML frameset like this:
<html> <head> </head> <frameset border="0" frameborder="0" framespacing="0" rows="20%,*"> <frame src="title.html"> <frameset border="0" frameborder="0" framespacing="0" cols="30%,*"> <frame src="menu.html"> <frame src="http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php"> </frameset> </html>
Likewise, the same web entry form could be embedded in an <iframe>:
<html> <head> </head> </body> <p><img src="acmelogo.png"><big>Acme title text</big></p> <iframe src="http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php" width="100%" height="800"> <p>No iframe support, so click on the <a href="http://acme.com/sysworkflow/en/classic/447CEAF7BE6AEB/Application_Form.php">Application Form Link</a></p> </iframe> <p>Acme footer text</p> </body> </html>
If the Web Entry form was generated with the Single HTML option, then it just generates the HTML code. Paste that code into an HTML file and save the file in a public place in the web server, so it can be used as the src for the frame.
Manually Implementing Web Entry
If using the Single HTML option, a new case will need to be created and the form's data will have to be sent to the ProcessMaker server using WSDL Web Services. The newCase() or newCaseImpersonate() web service can be used to create the case with data filled out in the Web Entry form.
For example, a school has an application form to apply for a course in its web page:
When a web entry with Single HTML option is created for the above DynaForm, it generates the following code:
<html> <head> <script type="text/javascript" src="http://example.com/jscore/labels/en.js"></script> <script type="text/javascript" src="http://example.com/js/maborak/core/maborak.js"></script> <script type="text/javascript" src="http://example.com/js/jscalendar/lang/calendar-en.js"></script> <script type="text/javascript" src="http://example.com/jsform/gulliver/dynaforms_Options.js"></script> <script type="text/javascript" src="http://example.com/jsform/8020012184e556501ceecf6014729518/4878024044e556511de9fe9093783949.js"></script> <script type="text/javascript"> var leimnud = new maborak(); leimnud.make(); leimnud.Package.Load("panel,validator,app,rpc,fx,drag,drop,dom,abbr",{ Instance:leimnud,Type:"module" }); leimnud.exec(leimnud.fix.memoryLeak); if(leimnud.browser.isIphone) { leimnud.iphone.make(); } leimnud.event.add(window,"load",function(){ loadForm_YTVOaW5HQ2tabUdvcUphaXFtdHVvbUxRbU1pVDBtYWpaV1NucG1xaXBtMW9wbW1rYTVOaW9HQ25hSldscVdlaXBtYWQxMnJUbUp4Z3BXT3FiR09wcUdxYjdhS2w___("http://example.com/sysworkflow/en/classic/gulliver/defaultAjaxDynaform")}); </script> <script type="text/javascript"> var aux1 = window.location.href.split("?"); if(aux1[1]){ if(aux1[1]!=""){ var aux2 = aux1[1].split("&"); for(var i=0; i<=aux2.length; i++){ if(aux2[i]=="__flag__=1"){ alert("Request sent!"); } } } } </script> </head> <body> <form id="YTVOaW5HQ2tabUdvcUphaXFtdHVvbUxRbU1pVDBtYWpaV1NucG1xaXBtMW9wbW1rYTVOaW9HQ25hSldscVdlaXBtYWQxMnJUbUp4Z3BXT3FiR09wcUdxYjdhS2w___" name="8020012184e556501ceecf6014729518_4878024044e556511de9fe9093783949" action="http://example.com/sysworkflow/en/classic/services/cases_StartExternal.php" class="formDefault" method="post" encType="multipart/form-data" style="margin:0px;" onsubmit="return validateForm('[{%27name%27:%27appFirstName%27,%27type%27:%27text%27,%27label%27:%27First Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appLastName%27,%27type%27:%27text%27,%27label%27:%27Last Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appID%27,%27type%27:%27text%27,%27label%27:%27ID Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appPhone%27,%27type%27:%27text%27,%27label%27:%27Phone Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appAddress%27,%27type%27:%27textarea%27,%27label%27:%27Address%27,%27validate%27:%27%27,%27required%27:%270%27},{%27name%27:%27appCourse%27,%27type%27:%27dropdown%27,%27label%27:%27Name of Course%27,%27validate%27:%27%27,%27required%27:%270%27}]');"> <div class="borderForm" style="width:500; padding-left:0; padding-right:0; border-width:1;"> <div class="boxTop"><div class="a"></div><div class="b"></div><div class="c"></div></div> <div class="content" style="height:100%;" > <table width="99%"> <tr> <td valign='top'> <input type="hidden" class="notValidateThisFields" name="__notValidateThisFields__" id="__notValidateThisFields__" value="[{%27name%27:%27appFirstName%27,%27type%27:%27text%27,%27label%27:%27First Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appLastName%27,%27type%27:%27text%27,%27label%27:%27Last Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appID%27,%27type%27:%27text%27,%27label%27:%27ID Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appPhone%27,%27type%27:%27text%27,%27label%27:%27Phone Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appAddress%27,%27type%27:%27textarea%27,%27label%27:%27Address%27,%27validate%27:%27%27,%27required%27:%270%27},{%27name%27:%27appCourse%27,%27type%27:%27dropdown%27,%27label%27:%27Name of Course%27,%27validate%27:%27%27,%27required%27:%270%27}]" /> <input type="hidden" name="DynaformRequiredFields" id="DynaformRequiredFields" value="[{%27name%27:%27appFirstName%27,%27type%27:%27text%27,%27label%27:%27First Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appLastName%27,%27type%27:%27text%27,%27label%27:%27Last Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appID%27,%27type%27:%27text%27,%27label%27:%27ID Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appPhone%27,%27type%27:%27text%27,%27label%27:%27Phone Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appAddress%27,%27type%27:%27textarea%27,%27label%27:%27Address%27,%27validate%27:%27%27,%27required%27:%270%27},{%27name%27:%27appCourse%27,%27type%27:%27dropdown%27,%27label%27:%27Name of Course%27,%27validate%27:%27%27,%27required%27:%270%27}]" /> <table cellspacing="0" cellpadding="0" border="0" width="100%"> <tr> <td class='FormTitle' colspan="2" align=""><span id='form[appTitle]' name='form[appTitle]' >School Application Form</span></td> </tr> <tr> <td class='FormLabel' width="40%">First Name</td> <td class='FormFieldContent' width='450' ><input class="module_app_input___gray" id="form[appFirstName]" name="form[appFirstName]" type="text" size="30" maxlength="64" value="" style="" onkeypress="" /></td> </tr> <tr> <td class='FormLabel' width="40%">Last Name</td> <td class='FormFieldContent' width='450' ><input class="module_app_input___gray" id="form[appLastName]" name="form[appLastName]" type="text" size="30" maxlength="64" value="" style="" onkeypress="" /></td> </tr> <tr> <td class='FormLabel' width="40%">ID Number</td> <td class='FormFieldContent' width='450' ><input class="module_app_input___gray" id="form[appID]" name="form[appID]" type="text" size="15" maxlength="64" value="" style="" onkeypress="" /></td> </tr> <tr> <td class='FormLabel' width="40%">Phone Number</td> <td class='FormFieldContent' width='450' ><input class="module_app_input___gray" id="form[appPhone]" name="form[appPhone]" type="text" size="20" maxlength="64" value="" style="" onkeypress="" /></td> </tr> <tr> <td class='FormLabel' width="40%">Address</td> <td class='FormFieldContent' width='450' ><textarea id="form[appAddress]" name="form[appAddress]" wrap="hard" cols="32" rows="2" style="" wrap="OFF" class="module_app_input___gray" ></textarea></td> </tr> <tr> <td class='FormLabel' width="40%">Name of Course </td> <td class='FormFieldContent' width='450' ><select class="module_app_input___gray" id="form[appCourse]" name="form[appCourse]" pm:label="Name of Course " pm:dependent="0" ><option value="accounting" >Intro. to Accounting</option><option value="operating_systems" >Intro to Operating Systems</option></select></td> </tr> <tr> <td class='FormButton' colspan="2" align=""><input style="" class='module_app_button___gray ' id="form[appSubmit]" name="form[appSubmit]" type='submit' value="Submit" /></td> </tr> </table> </td> </tr> </table> </div> <div class="boxBottom"><div class="a"></div><div class="b"></div><div class="c"></div></div> </div> <script type="text/javascript"> try { dynaformSetFocus();}catch(e){} </script> <input type="hidden" name="PRO_UID" value="8020012184e556501ceecf6014729518"> <input type="hidden" name="TASKS" value="9217522174e5566d0cdf6d9080799970"> <input type="hidden" name="DYNAFORM" value="4878024044e556511de9fe9093783949"> <!--Insert custom scripts here--> </form></body> </html>
Modifying the HTML Code
Paste the HTML code for the web entry into a publicly-accessible file named "applicationForm.html" and edit it. The submission of the form will be processed by a custom code file named "wsApplicationForm.php", so change line 35 from:
<form id="YTVOaW5HQ2tabUdvcUphaXFtdHVvbUxRbU1pVDBtYWpaV1NucG1xaXBtMW9wbW1rYTVOaW9HQ25hSldscVdlaXBtYWQxMnJUbUp4Z3BXT3FiR09wcUdxYjdhS2w___" name="8020012184e556501ceecf6014729518_4878024044e556511de9fe9093783949" action="http://192.168.1.76:2031/sysworkflow/en/classic/services/cases_StartExternal.php" class="formDefault" method="post" encType="multipart/form-data" style="margin:0px;" onsubmit="return validateForm('[{%27name%27:%27appFirstName%27,%27type%27:%27text%27,%27label%27:%27First Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appLastName%27,%27type%27:%27text%27,%27label%27:%27Last Name%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appID%27,%27type%27:%27text%27,%27label%27:%27ID Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appPhone%27,%27type%27:%27text%27,%27label%27:%27Phone Number%27,%27validate%27:%27Any%27,%27required%27:%270%27},{%27name%27:%27appAddress%27,%27type%27:%27textarea%27,%27label%27:%27Address%27,%27validate%27:%27%27,%27required%27:%270%27},{%27name%27:%27appCourse%27,%27type%27:%27dropdown%27,%27label%27:%27Name of Course%27,%27validate%27:%27%27,%27required%27:%270%27}]');"> <div class="borderForm" style="width:500; padding-left:0; padding-right:0; border-width:1;">
To:
<form id="appForm" name="appForm" action="wsApplicationForm.php" class="formDefault" method="post" encType="multipart/form-data" style="margin:0px;"> <div class="borderForm" style="width:500; padding-left:0; padding-right:0; border-width:1;">
To add any extra JavaScript code to the form (such as showing/hiding fields or verification of input), insert that code at the end of the form inside <script>...</script> tags. For example, to verify that the ID field is not left blank when the user clicks on the submit button:
... <input type="hidden" name="DYNAFORM" value="4878024044e556511de9fe9093783949"> <!--Insert custom scripts here--> <script type="text/javascript"> getField("appSubmit").onclick = function() { if (getValueById("appID") == "") { alert("The ID field can not be left blank. Please enter a valid ID"); return false; } return true; //return true to allow the form to be submitted. } </script> </form></body> </html>
The following two <script> in the head can be deleted from the code, since they aren't necessary:
<script type="text/javascript"> var leimnud = new maborak(); leimnud.make(); leimnud.Package.Load("panel,validator,app,rpc,fx,drag,drop,dom,abbr",{ Instance:leimnud,Type:"module" }); leimnud.exec(leimnud.fix.memoryLeak); if(leimnud.browser.isIphone) { leimnud.iphone.make(); } leimnud.event.add(window,"load",function(){ loadForm_YTVOaW5HQ2tabUdvcUphaXFtdHVvbUxRbU1pVDBtYWpaV1NucG1xaXBtMW9wbW1rYTVOaW9HQ25hSldscVdlaXBtYWQxMnJUbUp4Z3BXT3FiR09wcUdxYjdhS2w___("http://example.com/sysworkflow/en/classic/gulliver/defaultAjaxDynaform")}); </script> <script type="text/javascript"> var aux1 = window.location.href.split("?"); if(aux1[1]){ if(aux1[1]!=""){ var aux2 = aux1[1].split("&"); for(var i=0; i<=aux2.length; i++){ if(aux2[i]=="__flag__=1"){ alert("Request sent!"); } } } } </script>
Server-side Code to Start a Case
Then, create a server-side script to process the Web Entry when it is submitted and use web services to start a case in ProcessMaker. This code can be written in any language which supports WSDL web services which are used to call ProcessMaker's login() and newCase() web services.
For example, create a PHP file named "wsApplicationForm.php" on the web server (which is not publicly readable for security reasons) to process the application form when it is submitted by the user and call the newCase() web service. The data in the input fields "appFirstName", "appLastName", "appID", "appPhone", "appAddress", "appCourse" from applicationForm.html will be saved as a POST variable in an associative array named "form". In PHP it can be accessed as $_POST['form']['field-name']. A new case will be created using the newCase() web service. The form's input fields will be passed as an array of objects to the newCase() web service, so the new case will have case variables for each input field.
The code for the "wsApplicationForm.php" file is:
<?php //check if the form was submitted. If not then redisplay the form: if (!isset($_POST['form'])) { print '<p><font color="red">Please fill out the form and click on the "Submit" button.</color></p>'; print file_get_contents('applicationForm.html'); die(); } //login to web services as a dummy user with the username "webEntryUser": $client = new SoapClient('http://192.168.1.76:2031/sysworkflow/en/green/services/wsdl2'); $pass = 'md5:' . md5('p4s5w0rd'); $params = array(array('userid'=>'webEntryUser', 'password'=>$pass)); $result = $client->__SoapCall('login', $params); if ($result->status_code == 0) $sessionId = $result->message; else exit("Unable to connect to ProcessMaker.\nError Number: $result->status_code\n" . "Error Message: $result->message\n"); class variableStruct { public $name; public $value; } $aVars = array(); //array of variables to pass to the new case //loop through $_POST['form'] associative array, which has the form's fields foreach ($_POST['form'] as $fieldName=>$fieldValue) { //if an array, it could be a checkgroup, listbox or a grid if (is_array($_POST['form'][$fieldName])) { //if an associative array of associative arrays, then it is a grid and it needs to be //serialized to be passed to the new case as a string variable if (isset($_POST['form'][$fieldName][1]) and is_array($_POST['form'][$fieldName][1])) $fieldValue = serialize($_POST['form'][$fieldName]); //else a checkgroup or listbox, so concatenate multiple values separated by "|" else { $val = ''; foreach ($_POST['form'][$fieldName] as $option) $val .= ($val != '' ? '|' : '') . $option; $fieldValue = $val; } } $obj = new variableStruct(); $obj->name = $fieldName; $obj->value = $fieldValue; $aVars[] = $obj; } $params = array(array('sessionId'=>$sessionId, 'processId'=>$_POST['PRO_UID'], 'taskId'=>$_POST['TASKS'], 'variables'=>$aVars)); $result = $client->__SoapCall('newCase', $params); if ($result->status_code == 0) print "<html><body>Thank you for submitting your Application.<br>" . "Your Application Number: {$result->caseNumber}</body></html>"; else die("<html><body><font color=\"red\">Error submitting application:<br>" . "{$result->message}<br><br>" . "Please resubmit the application or call 776-654-6554.</font></body></html>"); ?>
Handling Specific Input Fields
The above code will generically process all the input fields in any submitted DynaForm. To only pass specific input fields to the new case, replace the foreach loop with code that manually populates the $aVars array by referencing specific input fields. For example:
... $aVars = array(); //array of variables to pass to the new case $firstName = new variableStruct(); $firstName->name = 'appFirstName'; $firstName->value = $_POST['form']['appFirstName']; $aVars[] = $firstName; $lastName = new variableStruct(); $lastName->name = 'appLastName'; $lastName->value = $_POST['form']['appLastName']; $aVars[] = $lastName; $id = new variableStruct(); $id->name = 'appID'; $id->value = $_POST['form']['appID']; $aVars[] = $id; ...
Handling Grids
Grids are stored as an associative array of associative arrays, but only strings can be passed to a case with the newCase() web service, so the above script serializes the grid as a string. Therefore, any grids from the web entry form will need to be unserialized (i.e., converted back into an associative array of associative arrays). Create a trigger in the process to unserialize the grid, so it can be used normally in subsequent tasks and steps.
For example, if the Web Entry form has a grid named "contactsGrid", then use PHP's unserialize() function in a trigger to convert from a string to an array, but first check if the "contactsGrid variable exists and if it is a string. If the case was started inside ProcessMaker and not by a web entry, then the grid will already be in its proper format and doesn't need to be unserialized:
if (isset(@=contactsGrid) and is_string(@=contactsGrid)) @=contactsGrid = unserialize(@=contactsGrid);
This trigger can be set to fire before the step that follows the Web Entry form in the process. Another alternative is to not set the trigger to fire at any point, but to fire the trigger with the executeTrigger() web service in the external script which processes the Web Entry form.
For example, the following code could be added to the end of the script in the above example:
... //The caseId is returned by newCase() //The delIndex should be 1 if first task in process //Lookup the triggerIndex in the database or at ADMIN > Web Services Test > triggerList() $params = array(array('sessionId'=>$sessionId, 'caseId'=>$result->caseId, 'triggerIndex'='0123456789abcde01232456789abcde' 'delIndex'=>1)); $triggerResult = $client->__SoapCall('executeTrigger', $params); if ($triggerResult->status_code != 0) die("<html><body><font color=\"red\">Error executing trigger:<br>" . "{$triggerResult->message}<br><br>" . "Please call 776-654-6554.</font></body></html>"); ...
Routing (Derivating) the Case
If the web entry form is the last step in the first task, then add code at the end of the script to use the [[1]] web service to route (derivate) the case to the second task in the process. The unique ID for the new case should have been returned by the newCase() web service and the delegation index of the case should be 1, since it is the first task in the process:
... $params = array(array('sessionId'=>$sessionId, 'caseId'=>$result->caseId, 'delIndex'=>1)); $routeResult = $client->__SoapCall('routeCase', $params); if ($routeResult->status_code != 0) die("<html><body><font color=\"red\">Error routing application:<br>" . "{$result->message}<br><br>" . "Please call 776-654-6554.</font></body></html>"); ?>
Web Entry with Multiple DynaForms
If needing to display multiple DynaForms, then generate the HTML code for each DynaForm with the Single HTML option and paste that code into separate files. The server-side script which processes all the forms can create a session where the data entered into the forms will be saved. Based upon the data which is already saved for the session, the script will know which is the next form to display to the user. If the session expires (which happens by default after 24 minutes in PHP), then the data will be lost and the user will start over with the first DynaForm.
The script can be written in any language which supports WSDL web services, but if using PHP, the session_start() and session_destroy() functions can be used to manage the session and the forms' data can be saved in the $_SESSION superglobal variable.
For example, this web entry has three forms named form1.html, form2.html and form3.html. The data from the first two forms are saved as the session variables $_SESSION['form1'] and $_SESSION['form2']. When the third form is processed, the data from $_SESSION['form1'] and $_SESSION['form2'] is also passed to the newCase() web service to start the case.
<?php if (!isset($_POST['form'])) { //if no submitted data, then start over with form1 header("location: form1.html"); die(); } //if no stored form1 data and fieldX from form1 is not set, then lost session and should start over elseif (!isset($_SESSION['form1'] and !isset($_POST['form']['fieldX'])) { header("location: form1.html"); die(); } //if fieldX from form1 is set, then start session and save data from form1 elseif (isset($_POST['form']['fieldX'])) { session_start(); $_SESSION['form1'] = $_POST['form']; header("location: form2.html"); die(); } //if fieldY from form2 is set, then save data from form2 elseif (isset($_POST['form']['fieldY'])) { $_SESSION['form2'] = $_POST['form']; header("location: form2.html"); die(); } //if fieldZ from form3 is not set, then some error in logic elseif (!isset($_POST['form']['fieldZ')) { die("Error in your script!"); } //login to web services as a dummy user with the username "webEntryUser": $client = new SoapClient('http://192.168.1.76:2031/sysworkflow/en/green/services/wsdl2'); $pass = 'md5:' . md5('p4s5w0rd'); $params = array(array('userid'=>'webEntryUser', 'password'=>$pass)); $result = $client->__SoapCall('login', $params); if ($result->status_code == 0) $sessionId = $result->message; else exit("Unable to connect to ProcessMaker.\nError Number: $result->status_code\n" . "Error Message: $result->message\n"); class variableStruct { public $name; public $value; } $aFormFields = array_merge($_SESSION['form1'], $_SESSION['form2'], $_POST['form']); unset($_SESSION['form1']); unset($_SESSION['form2']); $aVars = array(); //array of variables to pass to the new case foreach ($aFormFields as $fieldName=>$fieldValue) { //if an array, it could be a checkgroup, listbox or a grid if (is_array($aFormFields[$fieldName])) { //if an associative array of associative arrays, then it is a grid and it needs to be //serialized to be passed to the new case as a string variable if (isset($aFormFields[$fieldName][1]) and is_array($aFormFields[$fieldName][1])) $fieldValue = serialize($aFormFields[$fieldName]); //else a checkgroup or listbox, so concatenate multiple values separated by "|" else { $val = ''; foreach ($aFormFields[$fieldName] as $option) $val .= ($val != '' ? '|' : '') . $option; $fieldValue = $val; } } $obj = new variableStruct(); $obj->name = $fieldName; $obj->value = $fieldValue; $aVars[] = $obj; } $params = array(array('sessionId'=>$sessionId, 'processId'=>$_POST['PRO_UID'], 'taskId'=>$_POST['TASKS'], 'variables'=>$aVars)); $result = $client->__SoapCall('newCase', $params); if ($result->status_code == 0) print "<html><body>Thank you for submitting your Application.<br>" . "Your Application Number: {$result->caseNumber}</body></html>"; else die("<html><body><font color=\"red\">Error submitting application:<br>" . "{$result->message}<br><br>" . "Please resubmit the application or call 776-654-6554.</font></body></html>"); //If the application form was the last step in the first task, then route (derivate) //the case to the second task in the process to evaluate the application: //The delIndex for the first task is generally 1 $params = array(array('sessionId'=>$sessionId, 'caseId'=>$result->caseId, 'delIndex'=>1)); $routeResult = $client->__SoapCall('routeCase', $params); if ($routeResult->status_code != 0) die("<html><body><font color=\"red\">Error routing application:<br>" . "{$result->message}<br><br>" . "Please call 776-654-6554.</font></body></html>"); ?>
Web Entry in the Middle of a Process
To display a DynaForm from the middle of a Process to an external user, first generate the HTML code for the form using the Single HTML option for Web Entry.
Note: A Web Entry can not be created for a DynaForm which is not a step in an initial task in the process. To get around this, temporarily mark the task as an initial task and generate the web entry. Then, change the task back.
Paste the HTML code into a publically accessible file on the web server and modify the code as in the example above so that the form will be processed by your custom script. Give the external user a link to the form which has a GET variable for the unique ID of the case. (Note: this introduces security issues, so you might want to do this with a SSL connection and check that the data seems reasonable.) In the custom script file which processes the form, login to ProcessMaker with a user who is a Process Supervisor with rights to write to the DynaForm and the use the sendVariables() web service to send the data from the form to the case.
For example, the HTML file is named "customerForm.html" and its script is named "wsCustomerForm.php". A email is sent to the customer which contains a link like:
Please fill out the following form: https://www.acme.inc/customerForm.html?case=8326e27ab4692c178dc2356ac3452b3e
The case unique ID can be inserted in the email template using the @#APPLICATION system variable:
Please fill out the following form: https://www.acme.inc/customerForm.html?case=@#APPLICATION
The form is processed just like a normal web entry form, but instead of using the newCase() web service, it uses the sendVariables() web service with the case ID from the GET variable:
... $params = array(array('sessionId'=>$sessionId, 'caseId'=>$_GET['case'], 'variables'=>$aVars)); $result = $client->__SoapCall('sendVariables', $params); if ($result->status_code != 0) print "Error: $result->message \n"; ?>
Customizing Web Entry
The PHP page with web services option generates three files in the public directory for the current workspace, which is generally located at:
- Linux/UNIX:
- /opt/processmaker/shared/sites/<WORKSPACE>/public/<PROCESS-UID>/
- Windows, ProcessMaker version 1.6-4260 and later:
- <INSTALL-DIRECTORY>\processmaker\shared\sites\<WORKSPACE>\public\<PROCESS-UID>\
- Windows, before ProcessMaker version 1.6-4260:
- C:\Program Files\ProcessMaker\apps\processmaker\shared\sites\<WORKSPACE>\public\<PROCESS-UID>\
The generated files are:
shared/sites/<WORKSPACE>/public/<PROCESS-UID>/
wsClient.php
<DYNAFORM-NAME>_Form.php
<DYNAFORM-NAME>_FormPost.php
These 3 files interact with ProcessMaker's WSDL web services. The wsClient.php file defines the functions required to login and initiate a new case (and route it to the second task if necessary). The <DYNAFORM-NAME>_Form.php file contains the code to populate the $_SESSION superglobal variable and display the DynaForm.
The <DYNAFORM-NAME>_FormPost.php file determines what content is displayed to the user after the DynaForm is submitted. This code can be edited to display different information. By default, web entry displays the case number, the case unique ID, and who the case is assigned to:
To display different information edit the line:
54 $aMessage['MESSAGE'] = "Case created in ProcessMaker<br/>Case Number:$caseNr <br/>Case Id:$caseId<br/>Case derivated to: $assign";
For example, to display only the case number:
54 $aMessage['MESSAGE'] = "Case created in ProcessMaker<br/>Case Number:$caseNr";
The code can be altered to redirect to a custom web page, instead of the ProcessMaker screen. For example to redirect to the address http://mycompany.com/customerConfirmation.html after submitting the DynaForm, change these lines:
69 $G_PUBLISH = new Publisher;
70 $G_PUBLISH->AddContent('xmlform', 'xmlform', 'login/showInfo', '', $aMessage );
71 G::RenderPage( 'publish', 'blank' );
72 }
To:
69 G::header( 'Location: http://mycompany.com/customerConfirmation.html' ); 70 }






