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

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:

  1. The page XML is generated using a PXTemplateGenerator to expand the Paloose variables which are used in back/forward progress of the flow.
  2. After the page is built (in the aggregate) the Pforms are processed.
  3. 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 – 2023 Hugh Field-Richards. All Rights Reserved.