
Step 1: Directory Structure for Hello Application
Following is the recommended directory structure for the Hello Application. This structure can be modified so long as the include.php file contains the correct paths to the files needed.
/hello /actions /forms /include /models /views
Step 2: Building the Models
The first step in building an application in Phrame is to set up the data models. If errors are generated in the models, Phrame can be notified by registering an error handler in the options.php and triggering an error with the trigger_error() php method. Following is the Person class for the hello application:
<?php
define('MAX', 20);
class Person
{
var $_name;
function Person($name = NULL)
{
$this->_name = $name;
}
function getName()
{
return $this->_name;
}
function setName($name)
{
$isValid = TRUE;
if (strlen($name) > MAX) {
trigger_error('Name > '.MAX.' characters');
$isValid = FALSE;
} else {
$this->_name = $name;
}
return $isValid;
}
}
?>
Also, these models that are created could make connections to whichever database you are using. All data manipulation methods as well as database transaction methods should be owned by these models.
Step 3: Building the Actions
The next step in building the application is to set up the actions for the application. These actions perform all of the business logic required by the application. Following is the Action in this hello application:
<?php
class HelloAction extends Action
{
function perform($actionMapping, $actionForm) {
$person = new Person();
$name = $actionForm->get('name');
//get ActionForward depending on if errors were generated
if ((!$person->setName($name)) || ($_SESSION[_ERRORS])) {
$actionForward = $actionMapping->get('index');
} else {
$actionForward = $actionMapping->get('hello');
//put Person in the session
$_SESSION['person'] = $person;
}
return $actionForward;
}
}
?>
Step 4: Building the Views
This step in building the application is setting up the views for your application. This should include all of the forms that you will need for your application. These can be written using XML/XSLT, PHP, Flash, etc. All views should have a hidden element called action so that the controller knows what action to take when a user does something on a view. Following is a view rendered in XSLT for the Hello Application:
Filename: index.xsl
View Description: This is the view that is initially displayed. It's a basic form that allows you to enter a name. If an error occurs when you submit, this view is shown again with the existing errors shown above the form.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:include href="common.xsl"/> <xsl:template match="hello"> <html> <head> <meta name="generator" content="HTML Tidy, see www.w3.org"/> <title>Phrame - Hello Application</title> </head> <body> <form action="phrame.php" method="post"> <xsl:for-each select="$errors"> <xsl:call-template name="error"/> </xsl:for-each> <p>What is your name?<br/> <input type="text" name="name" value="{$name}"/> <input type="submit" value="OK"/></p> <input type="hidden" name="action" value="sayHello"/><br/> </form> </body> </html> </xsl:template> <xsl:template name="error"> <li><b style="color: red"><xsl:value-of select="value"/></b></li> </xsl:template> </xsl:stylesheet>
Filename: hello.xsl
View Description: This is the result page that is shown if no errors occurred. It prints out "Hello {name}".
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:include href="common.xsl"/> <xsl:template match="hello"> <html> <head> <meta name="generator" content="HTML Tidy, see www.w3.org"/> <title>Phrame - Hello Application</title> </head> <body> <p>Hello <xsl:value-of select="$name"/></p> <a href="index.php">Back</a></body> </html> </xsl:template> </xsl:stylesheet>
Filename: commons.xsl
View Description: This is the common xsl stylesheet that is used in both index.xsl and hello.xsl.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="errors" select="hello/errors/stack/_elements"/> <xsl:variable name="valid" select="hello/models/person/_name"/> <xsl:variable name="invalid" select="hello/forms/helloform/_values/value[@key='name']"/> <xsl:variable name="name" select="$valid[(not($errors))] | $invalid[$errors]"/> </xsl:stylesheet>
Step 5: Building the Form Objects
These objects extend the ActionForm object and are used to validate your application in PHP if for any reason you do not want to use other methods of validation (ex. JavaScript). If you do not need to validate using PHP, then do not worry about creating one of these form objects. Following is the form object in the Hello Application:
<?php
class HelloForm extends ActionForm
{
function validate()
{
$isValid = TRUE;
if (!$this->get('name')) {
trigger_error('Enter your name');
$isValid = FALSE;
}
return $isValid;
}
}
?>
Step 6: Piecing Together the Hello Application
In order to piece together your application, you must also include the following information:
- Mapping Information
- Error Handling Information
- Application Options
- Bootstrap File
- View Handler
- All Application Files
Mapping Information should be located inside the mappings.php file (in the include directory) as follows:
<?php
//build mapping information to pass into controller
$mappings = array(
_ACTION_FORMS => array(
'form' => array(
_TYPE => 'HelloForm'
)
),
_ACTION_MAPPINGS => array(
'sayHello' => array(
_TYPE => 'HelloAction',
_NAME => 'form',
_INPUT => 'index.php?view=views/index.xsl',
_VALIDATE => 1,
_ACTION_FORWARDS => array(
'hello' => array(
_PATH => 'index.php?view=views/hello.xsl',
_REDIRECT => 0
),
'index' => array(
_PATH => 'index.php?view=views/index.xsl',
_REDIRECT => 0
)
)
)
)
);
?>
Error Handling Information should be located inside the errorHandler.php file (in the include directory) as follows:
<?php
function handleError($number, $message, $file, $line, $context)
{
if (!$_SESSION[_ERRORS]) {
$errors = new Stack();
$_SESSION[_ERRORS] = $errors;
}
$errors = &$_SESSION[_ERRORS];
$errors->push($message);
}
?>
Application Options should be located inside the options.php file (in the include directory) as follows:
<?php
//set options for the controller
$options = array(
//Set the _CACHE = 1 for data caching.
_CACHE => 1,
//set to E_ALL to get controller errors (debug use only)
_ERROR_REPORTING => E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE,
//Sets the error handler to the function that you specify
_ERROR_HANDLER => "handleError",
);
?>
Bootstrap file, phrame.php, is where you GET/POST and releases control to the controller for further processing:
<?php
include('include/include.php');
session_start();
//add controller to session if not already cached
if (!$_SESSION[_CONTROLLER]) {
$controller = new ActionController($options);
$_SESSION[_CONTROLLER] = $controller;
}
//release control to controller for further processing
$controller = &$_SESSION[_CONTROLLER];
$controller->process($mappings, $_REQUEST);
?>
View Handler, index.php, enables the usage of XSLT stylesheets to process the XML representations of the response objects:
<?php
include('include/include.php');
session_start();
//build "wrapper" xml to render complete page with errors if they exist
$xml = "<?xml version="1.0"?>/n"
$xml.= "<example>/n"
$xml.= "/t<errors>/n"
if ($_SESSION[_ERRORS]) {
$xml.= Xml::marshal($_SESSION[_ERRORS], 2);
}
$xml.= "/t</errors>/n"
$xml.= "/t<forms>/n"
if ($_SESSION[_FORM]) {
$xml.= Xml::marshal($_SESSION[_FORM], 2);
}
$xml.= "/t</forms>/n"
$xml.= "/t<models>/n"
if ($_SESSION['person']) {
$xml.= Xml::marshal($_SESSION['person'], 2);
}
$xml.= "/t</models>/n"
$xml.= "</example>/n"
$_SESSION[_ERRORS] = NULL;
$_SESSION[_FORM] = NULL;
$_SESSION['person'] = NULL;
//release control to view for final rendering
$xsl = ($_GET[_VIEW]) ? $_GET[_VIEW] : 'views/index.xsl';
$result = Xml::transform($xml, array($xsl), $_GET);
echo $result;
All Application Files that you have created should be included inside the include.php file (in the include directory) as follows:
<?php
//first include all the phrame base classes, then any project subclasses
include('../../include.php');
include('forms/HelloForm.php');
include('actions/HelloAction.php');
include('models/Person.php');
include('errorHandler.php');
include('mappings.php');
include('options.php');
?>