Skip to content

07. Process forms and actions

ihofmann edited this page Nov 30, 2014 · 1 revision

Working with Actions

Here we show how to create forms, validate and process them in a so-called "Action Controller". In the following, we will create a page that asks for your name and age and, when entered correctly, brings a success message.

Create a new model

First we create a new module for our new page and call it "hello".

  1. Create a new folder: /modules/hello
  2. Create a new file: /modules/hello/module.xml
  3. Create a new file: /modules/hello/messages_en.xml
  4. Create a new file: /templates/default/views/hello.twig
  5. create a new file: /classes/actions/HelloController.class.php

module.xml

Copy the following content into the file module.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE module SYSTEM "../module.dtd">
<module version="1.0.0">
	
	<pages>
		<page
			id="hello"
			template="hello"
			navitem="true"
			navweight="5"
			role="user" />
	</pages> 
	
	<actions>
		<action id="sayhello" controller="HelloController" role="user" log="true">
			<param id="myname" type="text" required="true" />
			<param id="myage" type="number" required="true" min="18" max="99" />
		</action>
	</actions>
  
</module>

The meaning of the attribute "page" has been explained in the chapter Create new pages. New elements are "actions", "action" and "param". They register the new action controller and indicate that we expect two parameters: "myname" and "myage".

Attributes of the element "action":

  • id: Unique identifier of the action. Must be specified in the form as hidden parameter with name "action".
  • controller: Points to the Action Controller class, that we have just created.
  • role: Specifies which user group(s) may invoke this action. "user" means that only registered users can perform the action. Guests receive an error message.
  • log: If "true", a new user activity record will be created on every successful call (see user profile -> Latest Activities). For the text to display, create a new text message with ID activitylog_{action ID} (For the example above: activitylog_sayhello).

Attributes of the element "param":

  • id: Unique identifier of the parameter. Same as the HTML field name.
  • type: Expected type of the parameter values. It can be one of the following : text, boolean, number, date, email.
  • required: true if the user must enter a value, otherwise false.
  • min/max: Specifies the minimum and maximum value for the input attribute.
  • validator: You can specify the name of a class which executes a special validation. Have a look at the example file /classes/validators/PasswordValidator.class.php.

An error message will appear on the page if the user enters an invalid value.

messages_en.xml

Copy the following content into the file messages_en.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE messages SYSTEM "../messages.dtd">
<messages>
	<message id="hello_navlabel">hello</message>
	<message id="hello_name_label">Your Name</message>
	<message id="hello_age_label">Your Age</message>
	<message id="hello_success">Successfully Edited!</message>
	
	<message id="activitylog_sayhello">%s said hello!</message>
</messages>

hello.twig

We now create our template file:

{% extends "base.twig" %}
{% import "macros/formelements.twig" as formelements %}

{% block page_title %}
{{ i18n.getMessage("hallo_navlabel") }}
{% endblock %}

{% block page_content %}

<form class="form-horizontal" method="post">

	{{ formelements.textfield('myname', i18n.getMessage('hello_name_label'), 
		env.getRequestParameter('myname'), true, validationMsg) }}
	
	{{ formelements.textfield('myage', i18n.getMessage('hello_age_label'), 
		env.getRequestParameter('myage'), true, validationMsg, 'number') }}
	
	<div class="form-actions">
		<button type="submit" 
		class="btn btn-primary">{{ i18n.getMessage('button_save') }}</button>
	</div>
	<input type="hidden" name="page" value="hello"/>
	<input type="hidden" name="action" value="sayhello"/>
</form>

{% endblock %}

Important here are the parameters "page" and "action", which refer to the page to be displayed and the action to be performed.

HelloController.class.php

Controller classes execute the program logic of actions, whereas the parameters must not be tested on the basic properties that we have already specified in module.xml. We can use them directly through the variable $parameters.

class HelloController implements IActionController {
	private $_i18n;
	private $_websoccer;
	private $_db;
	
	public function __construct(I18n $i18n, WebSoccer $websoccer, DbConnection $db) {
		$this->_i18n = $i18n;
		$this->_websoccer = $websoccer;
		$this->_db = $db;
	}
	
	public function executeAction($parameters) {
		$name = $parameters["myname"];
		$age = $parameters["myage"];
		
		// create success message
		$this->_websoccer->addFrontMessage(new FrontMessage(MESSAGE_TYPE_SUCCESS, 
				$this->_i18n->getMessage("hello_success"),
				""));
		
		return null;
	}
	
}

The return value of the method "executeAction()" is here null, which means that after processing the action, the user is taken to the page that is specified in the form parameter "page". You could as well return here a page ID, for instance, "home". Then the user is forwarded to the corresponding page (Note: only if the action was not executed via AJAX).

Publishing the page

Follow the steps below to publish the page online:

  1. Upload the new files to your web server.
  2. Log on as administrator in Admin Center
  3. Click at the top "Clear Cache".

Your new page will appear on the website.

Extension: Pass Data from an action to a model

If you want to see additional information from the action on the resulting page, which are not available in the database, the action can save the additional info in so-called "Context Parameters". It is an array that is kept in the application context (class WebSoccer) and can be read or set at any point. Example: In the above example, the entered age will be displayed on the results page. We store the age as a context parameter and read it later from the model to get it to pass it to the template.

Extension of HelloController:

...
public function executeAction($parameters) {
	...
	$this->_websoccer->addContextParameter("enteredAge", $age);
}
...

And in the model of the results page:

$contextParameters = $this->_websoccer->getContextParameters();
if (isset($contextParameters["enteredAge"])) {
	$enteredAge = $contextParameters["enteredAge"];
}