WED stands for Web Event Dispatcher. Pages that have WED are able to behave differently depending on incoming GET / POST / PI parameters. There are two types of events depending on their composition:
Web_Event_Simple - simple web event, i.e. corresponding to a single GET / POST / PI parameter. Such events are triggered when parameter is present in the GET / POST / PI. For example following URL will trigger simple event http://somedomain123.com/index.php?number=21 that is defined to capture GET parameter with name "number".Web_Event_Coposite - composite web event, composed by two or more simple web events. Such events are triggered when all of their simple web events are triggered. URL example that (may) trigger composite event http://somedomain123.com/index.php?number=21&user=2WED's job is to:
http://somedomain123.com/index.php?number=21)default_event()
An event is defined by creating object of type Web_Event_Simple or Web_Event_Simple_Int. A simple event represents one GET / POST / PI parameter. For example: following URL has one GET parameter (number) and will trigger simple event: http://somedomain123.com/index.php?number=21.
Example 9.1. Creating object of Web_Event_Simple_Int type (in init() method)
$number_event = new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number');
class Web_Event_Simple {
__constructor ( string $name, unsigned integer $type, string $capture )
}
Tangra_Parameter_Method. Example: Tangra_Parameter_Method::GETNote: Most of the time values of parameter name and parameter capture are the same. That is not a mandatory requirement. It is made just for developer's convenience.
Web_Event_Simple_Int is created the same way. The difference between Web_Event_Simple and Web_Event_Simple_Int is that Web_Event_Simple_Int accepts only integer values (and throws exception if non-integer value is detected). Web_Event_Simple_Int is convenient way to protect yourself from SQL injection and other URL manipulation attacks.
In order event to be "operational" you have to add it to WED. Each WED page has its own WED in its $this->wed property (which is created transparently for you when page constructor is executed). Adding an event is done by calling WED's method add_wed_event_action_pair.
Example 9.2. Adding event to WED (in init() method)
$this->wed->add_wed_event_action_pair($number_event, 'number_event');
Web_Event_Simple.Web_Event_Composite) that have overlapping conditions.When WED detects trigger condition of given event it calls target method which have to be defined in the page class. Such methods have to be with "protected" access type and to accept one parameter.
Example 9.3. Defining event handling method
protected function method_name($param) {
...
$view = $this->get_view('default'); // "default" view used in this example. You may return other previously defined view.
return $view;
}
Where method_name is the same as target_method parameter passed to add_wed_event_action_pair. When WED calls your event handling method it will pass captured GET / POST / PI value in $param.
Each event handling method MUST return object of type Web_Page_View.
Let's create WED page called my_wed_page that accepts single GET parameter "number" (using POST and PI parameters is basically the same).
You will have to create following files:
/htdocs/my_wed_page.php
To get content for the interceptor file open /hidden/src_templates/page_template.php and copy the content in your newly created /htdocs/my_page.php. Change it so it looks like:
<?php
require_once('boot.inc.php');
boot('my_site');
require_once($WSC->get_site_inc_dir().'pages/my_wed_page_wp.class.php');
session_start();
$page = new My_WED_Page_WP('my_wed_page');
$SITE->run($page, new Web_Context);
/hidden/inc/pages/my_wed_page_wp.php
Open /hidden/src_templates/page_template_wp_wed.class.php and copy its content into /hidden/inc/pages/my_wed_page_wp.php. Change it so it looks like (just change the class name):
<?php
// $Id$
require_once($WSC->get_site_inc_dir().'site_web_page_wed.class.php');
class My_WED_Page_WP extends Site_Web_Page_WED {
public function init() {
parent::init();
$v = new Site_Web_Page_View($this);
$this->add_view($v);
$number_event = new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number');
$this->wed->add_wed_event_action_pair($number_event, 'number_event');
}
protected function number_event($param) { // adding method that will handle situation when there is GET parameter "number" passed
$this->export('number', $param); // param holds the value of passed parameter.
$view = $this->get_view('default');
return $view;
}
protected function default_event() { // handles "default" event when no GET parameter is passed
$view = $this->get_view('default');
return $view;
}
}
Above code does the following:
init() method an event is defined with new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number'). Depending on the accepted values there are (by now) two types of events: Web_Event_Simple which accepts all kind of values and Web_Event_Simple_Int which accepts only integer values (and throws exception if if value is not integer).$this->wed->add_wed_event_action_pair() where 'number_event' is the name of event handling method. Please note that if you add event but not define corresponding event handling method - exception will be thrown when trying to execute the page.number_event()/hidden/tpl/pages/my_wed_page.tpl
Put following in /hidden/tpl/pages/my_wed_page.tpl:
{if $number}
Incomming GET parameter number = {$number}
{else}
No incomming parameter!
{/if}
Open your new page in your browser and try it. If your don't pass GET parameter it will behave like "simple page" and the output will be No incomming parameter!. If you pass GET parameter for example tft.myhost/my_wed_page.php?number=42 output will be Incomming GET parameter number = 42
Note: Plase note that these "strange" tags in the TPL file that are enclosed in figure brackets are not feature of the Tangra framework itself. They are feature of » Smarty template engine. You will have to reat its documentation in order to learn how to use them.
In many cases given page is ment to work properly only if some parameter is passed. For example if you have page show_user_details.php and you defined in init() that you are expecting user_id parameter it is not good idea to leave default_event() with default code because this page cannot properly work without user_id. In such cases it is recommended to declare explicitly that there is no default behaviour like this:
protected function default_event() {
throw new Tangra_User_Exception('Unexpected parameters');
}
That way you not only may help yourself during the development (i.e. exception will be thrown if something is messed up and page does not receive expected set of parameters) but also you are making your site more secure because you are making it immune to hacker attepts of messing manualy with GET parameters.
Creating WED page with multiple parameters is vary similar to creating WED page with one parameter. For definining multiple parameters Web_Event_Composite class is used. Composite events are just aggregators of simple events.
Lets create a WED page that accepts GET parameters "number" and "user", i.e. handles request like: http://somedomain123.com/my_wedm_page.php?number=21&user=4.
You will have to create following files:
/htdocs/my_wedm_page.php
<?php
require_once('boot.inc.php');
boot('my_site');
require_once($WSC->get_site_inc_dir().'pages/my_wedm_page_wp.class.php');
session_start();
$page = new My_WEDM_Page_WP('my_wed_page');
$SITE->run($page, new Web_Context);
/hidden/inc/pages/my_wedm_page_wp.php
<?php
// $Id$
<?php
// $Id$
require_once($WSC->get_site_inc_dir().'site_web_page_wed.class.php');
class My_WEDM_Page_WP extends Site_Web_Page_WED {
public function init() {
parent::init();
$v = new Site_Web_Page_View($this);
$this->add_view($v);
// defining simple events
$number_event = new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number');
$user_event = new Web_Event_Simple_Int('user', Tangra_Parameter_Method::GET, 'user');
$comp_event = new Web_Event_Composite('my_composite'); //defining composite event
// adding simple events to composite
$comp_event->add_web_event_simple($number_event);
$comp_event->add_web_event_simple($user_event);
// adding composite event to WED
$this->wed->add_wed_event_action_pair($comp_event, 'my_composite_event');
}
//defining event handling function
protected function my_composite_event($params) {
/*
$params will contain:
array(
['number'] => 21,
['user'] => 4
)
*/
$this->export('number', $params['number']);
$this->export('user', $params['user']);
$view = $this->get_view('default');
return $view;
}
protected function default_event() {
throw new Tangra_User_Exception('Unexpected parameters');
}
}
Above code does the following:
init(). new Web_Event_Composite('my_composite');add_wed_event_action_pair()(there is short alias add_wes() but here we are using full name version for more readability) to the composite event./hidden/tpl/pages/my_wed_page.tpl
Number: {$number}<br />
User: {$user}
Point your browser to your new page using tft.myhost/my_wedm_page.php?number=21&user=4. You should see:
Number: 21
User: 4
Sometimes web pages accept different set of parameters. For example: we may have page that need to handle both single parameter like number=21 and two parameters like number=21&user=4. To handle such case we have to use something like this:
public function init() {
parent::init();
$v = new Site_Web_Page_View($this);
$this->add_view($v);
// defining simple events
$number_event = new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number');
$user_event = new Web_Event_Simple_Int('user', Tangra_Parameter_Method::GET, 'user');
// adding number_event to WED
$this->wed->add_wed_event_action_pair($number_event, 'number_event');
$comp_event = new Web_Event_Composite('my_composite'); //defining composite event
// adding simple events to composite
$comp_event->add_web_event_simple($number_event);
$comp_event->add_web_event_simple($user_event);
// adding composite event to WED
$this->wed->add_wed_event_action_pair($comp_event, 'my_composite_event');
}
Here we see overlaping condition (GET parameter "number") and question arises: which event handling method will be called if we have request like: http://somedomain123.com/my_wedm_page.php?number=21&user=4? Conditions for both events are satisfied and it seems that result is undefined. To resolve such situation we can use third parameter of WED's add_wed_event_action_pair $order:
public function init() {
parent::init();
$v = new Site_Web_Page_View($this);
$this->add_view($v);
// defining simple events
$number_event = new Web_Event_Simple_Int('number', Tangra_Parameter_Method::GET, 'number');
$user_event = new Web_Event_Simple_Int('user', Tangra_Parameter_Method::GET, 'user');
// adding number_event to WED with order value
$this->wed->add_wed_event_action_pair($number_event, 'number_event', 20);
$comp_event = new Web_Event_Composite('my_composite'); //defining composite event
// adding simple events to composite
$comp_event->add_web_event_simple($number_event);
$comp_event->add_web_event_simple($user_event);
// adding composite event to WED with order value = 10, i.e. smaller than order value of number_event
$this->wed->add_wed_event_action_pair($comp_event, 'my_composite_event', 10);
}
$order parameter defines order of checking the events for match. WED sorts all events in ascending order based on their $order value and checks them one by one until firts match is found. That way in above example where we have parameters number=21&user=4 first my_composite will be checked (because it has lower $order value) and because its contition is satisfied event handling method my_composite_event will be called. Please note that after a match is found WED does NOT check the remaining events.
In future it is possible that WED will be made smart enough to detect overlaping conditions and to handle them automatically but until then it is your resposibility to order events properly, i.e. more general events to be checked after more specific events.