The Flow Script
Warning
This part of Paloose is completely different from Cocoon
— so please study carefully.
The aim is to provide a means of navigating a series of linked forms to provide a
coherent whole. It is done by producing a PHP script which allows this movement between the
pages. It allows us to check for data and give the user an opportunity to change their mind
before finally submitting the data. The overall structure of this flow class is:
context://resources/scripts/AddUserTest.php
<?php
require_once( PHP_DIR . "/flows/Continuations.php" );
class AddUserTest extends Continuations {
/** Logger instance for this class */
private $gLogger;
private $gAddFormTestModel = array (
"username" => "",
"password" => "",
"passwordCheck" => "",
"fullname" => "",
);
function __construct()
{
$this->gLogger =& LoggerManager::getLogger( __CLASS__ );
parent::__construct( $this->gAddFormTestModel );
}
...
}
?>
The class is based on the Paloose class Continuations which
provides the basis of the flow control. The data model declared as the array, $gAddFormTestModel stores the data that will be collected from the
form (similar to the Cocoon data model approach). The construct method sets up a logger
(optional) and registers the data model with the Continuations
class.
Warning
Do not use any id starting with "__", these are reserved for Paloose.
Also do not have "." within the field names as they get changed when the form is sent via
POST.
For each operation that the flow does we need to add a class which is referenced within
the sitemap pipeline. In this case it is the add method, whose
basic structure is:
context://resources/scripts/AddUserTest.php
public function add()
{
global $gModules;
$requestParameterModule = $gModules[ 'request-param' ];
$finished = false;
while ( !$finished ) {
$errors = false;
switch ( $this->gContinuation ) {
case 0 :
$this->sendPage(
"addUserTest-1.html", // The page to send to the client
$this->gAddFormTestModel, // The current data model to send
++$this->gContinuation, // The continuation link for the next stage
$this->gViolations ); // Array of errors (keyed by data model keys)
$finished = true;
break;
case 1 :
// Send next page
break;
case 2 :
// Send next page
break;
case 3 :
// Send next page
break;
...
}
}
}
The method sendPage( $inPage, &$inFormModel, $inContinuation,
$inViolations ) is a method in the Continuations
class which is used to send a page to the client. The parameters are
- $inPage — the page to send.
- $inFormModel — the data model (passed by
reference).
- $inContinuation — the continuation id,
used by the switch statement.
- $inViolations — an array of entry errors
(keyed by the data model keys (see below).
In order to use this script it must be declared in the site:
context://documentation/sitemap.xmap
<map:flow language="php">
<map:script src="context://resources/scripts/AddUserTest.php"/>
</map:flow>
We will also need the PXTemplateGenerator:
context://documentation/sitemap.xmap
<map:components>
<map:generators default="file">
<map:generator name="px" src="resource://lib/generation/PXTemplateGenerator"/>
</map:generators>
...
</map:components>
The pipeline entry consists of two parts. The first matches to the start of the whole
process:
context://documentation/sitemap.xmap
<map:pipeline>
<map:match pattern="addUserTest.html">
<map:call function="AddUserTest::add"/>
</map:match>
It has a single pipeline component that calls the function AddUserTest::add, which is the method add in the
class AddUserTest which we declared above. When the match is
made it starts of the flow process and returns the page addUserTest-1.html since the continuation id is "0".
The second pipeline entry is to match the continuations which is done by the
following:
context://documentation/sitemap.xmap
<map:match pattern="addUserTest.kont">
<map:call function="AddUserTest::add"/>
</map:match>
</map:pipeline>
Sending the page addUserTest-1.html requires an internal
pipeline to build the page:
context://documentation/sitemap.xmap
<map:pipeline internal-only="true">
<map:match pattern="addUserTest-*.html">
<map:aggregate element="root">
...
<map:part src="cocoon:/addUserTest-{1}.px" element="content" strip-root="true"/>
</map:aggregate>
<map:transform src="resource://resources/transforms/pforms-violations.xsl"
label="pforms-violations">
<map:parameter name="formViolations" value="{session:__violations}"/>
</map:transform>
<map:transform src="resource://resources/transforms/pforms-default.xsl"/>
<map:transform src="resource://resources/transforms/pforms2html.xsl"/>
<map:call resource="outputPage"/>
</map:match>
<map:match pattern="**.px">
<map:generate type="px" src="context://documentation/{1}.xml"/>
<map:serialize/>
</map:match>
</map:pipeline>
There are several things to note here:
- The page XML is generated using a PXTemplateGenerator to expand the Paloose variables which are used in
back/forward progress of the flow.
- After the page is built (in the aggregate) the Pforms are processed.
- Even though there is no login there is still a session running.
Running this will produce a form similar to:
The next page
describes the next stage and checking for errors.
Copyright 2006 – 2017 Hugh Field-Richards. All Rights
Reserved.