VMOSS Calendar Example

Line 374: Line 374:
* It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the  DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.
* It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the  DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.
Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.
Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.
-
<pre>
 
-
class CalendarController extends CalendarView implements Controller {
 
-
function controlHandler($getvars) {
 
-
global $dao, $global;
 
-
 
-
//first authorize the user
 
-
$ac = new AccessController($getvars);
 
-
if(!$ac->isAuthorized())
 
-
return;
 
-
 
-
switch($getvars['vm_action']) {
 
-
case 'display_appointments':
 
-
if($getvars['add_appointment'] == 'Y') {
 
-
echo 'hello';
 
-
$dao->addAppointment($getvars['name'], $getvars['date']);
 
-
}
 
-
$this->displayAppointments($dao->getAppointments());
 
-
break;
 
-
}
 
-
}
 
-
}
 
-
</pre>
 
-
7. Modify ''shn_vm_default()'' in ''main.inc'' to dispatch control to the ''CalendarController'' if a match for ''$getvars['act'] == 'project''' is not found.
 
-
<pre>
 
-
else if ($_GET['act'] =='calendar' && $_SESSION['logged_in']){
 
-
    $controller =new CalendarController();
 
-
    $controller->controlHandler($_REQUEST);
 
-
} else...
 
-
</pre>
 
-
 
-
In main.inc add the include statatement for the classes you added.
 
-
<pre>
 
-
require_once('controller/CalendarView.php');
 
-
require_once('controller/CalendarController.php');
 
-
</pre>
 
-
 
-
8. Finally, in the menu.inc file, in the ''shn_vm_mainmenu()'' function, add the following line to display the menu item for the appointment form (add before the menu is closed;):
 
-
 
-
<pre>
 
-
$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));
 
-
</pre>
 
-
 
-
To simplify the procedure somewhat, this design avoids creating a calendar model class.
 
-
 
-
<h2>Appointments</h2>
 
-
 
-
{php}
 
-
shn_form_fopen('calendar&amp;vm_action=display_appointments');
 
-
shn_form_fsopen('Add Appointment');
 
-
shn_form_hidden(array('add_appointment' => 'Y'));
 
-
shn_form_text('Name', 'name');
 
-
shn_form_date('Date', 'date');
 
-
shn_form_fsclose();
 
-
shn_form_submit("Submit");
 
-
shn_form_fclose();
 
-
{/php}
 
-
 
-
<table border="0">
 
-
<thead>
 
-
<tr>
 
-
<td>Name</td>
 
-
<td>Date</td>
 
-
</tr>
 
-
</thead>
 
-
<tbody>
 
-
{foreach $appointments as $app}
 
-
<tr>
 
-
<td>{$app.name}</td>
 
-
<td>{$app.date}</td>
 
-
</tr>
 
-
{/foreach}
 
-
</tbody>
 
-
</table>
 
-
</pre>
 
-
5. Create a ''CalendarView'' class that extends the main ''View'' class. This class contains a single function called ''displayAppointments($appointments)'', which would expect an array of arrays that is returned from the ''DAO::getAppointments()'' function. This function should assign the result to the templating engine and display the template.
 
-
<pre>
 
-
class CalendarView extends View {
 
-
    function displayAppointments($appointments) {
 
-
        $this->engine->assign('appointments', $appointments);
 
-
$this->engine->display('calendar/display_appointments.tpl');
 
-
    }
 
-
}
 
-
</pre>
 
-
6. Create a ''CalendarController'' class that extends ''CalendarView'' and implements the ''Controller'' interface.
 
-
* It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the  DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.
 
<pre>
<pre>
class CalendarController extends CalendarView implements Controller {
class CalendarController extends CalendarView implements Controller {

Revision as of 04:01, 14 February 2008

VMOSS (Volunteer Management Open Source Software) is currently under development as a standalone implementation of the Sahana Volunteer Management module.

Back to outline

Contents

Code Structure

VMOSS uses the same file structure as Sahana. The majority of the files located in the /mod/vm directory.

Architecture

VMOSS uses a Model-View-Controller (MVC) architecture to manage the interaction between the user and the system. According to this design pattern, the system's data (the model) is separated from the user interface (the view), so that these two aspects of the system can be dealt with independently. Changes to the data will not affect the user interface and vice versa. Interaction between the model and view is managed by the controller, which contains the program's control logic.


UML

The following UML diagram gives a detailed break-down of the design, including the function names and attributes currently implemented in VMOSSDemo.

VM design

Data Scmema

The following diagram shows how VM module interacts with the Sahana framework.

Volunteer Management Database Schema as of June 25th 2007,RC2


Documentation

VMOSS Documentation hosted on Sourceforge


Back to outline

VMOSS Exercise

Problem Statement. Add a new menu named Calendar to the VMOSS menu that when selected brings up page containing a simple appointment form that includes two fields, appointment name and date. When submitted the appointment is added to an appointment table in the database and the returned page displays an updated list of appointments in a table format.

Design. We will create a new entity in VMOSS for the calendar, which means that create calendar subclasses of the model, view, and controller.

Procedure

1. In PhpMyAdmin, make database changes so that the access controller recognizes the new page.

INSERT INTO vm_access_request (request_id, act, vm_action, description) VALUES
(101, 'calendar', 'display_appointments', 'Display Calendar - Show Appointments');

INSERT INTO vm_access_request_role (fk_access_request, fk_role) VALUES
(101, 0),
(101, 1),
(101, 2),
(101, 3),
(101, 4);

2. In PhpMyAdmin, create a table on the VMOSS database to store all appointments:

CREATE TABLE vm_appointment (
  id    INTEGER(11) AUTO_INCREMENT,
  name  VARCHAR(255),
  date  DATE,
  PRIMARY KEY(id)
);

3. Create a function in the DAO to retrieve all appointments called getAppointments(), and return an array of arrays. Each array in this list would have entries from id, name, and date.

function getAppointments() {
    $result = $this->execute("SELECT id, name, date FROM vm_appointment");
    $appointments = array();
    while(!$result->EOF) {
        $appointments[] = $result->fields;
	$result->moveNext();
    }
    return $appointments;
}

Create another function in the DAO to add an appointment called addAppointment($name, $date).

function addAppointment($name, $date) {
    $this->execute("INSERT INTO vm_appointment (name, date) VALUES ('$name', '$date')");
}

4. In Eclipse, create a template file called 'display_appointments.tpl' in a new calendar directory in the templates directory. This template can expect to get a array of appointment information to display. It should also output the form to add a new appointment. In order to use one page for both input and outpu, we use a hidden form element add_appointment and value 'Y'.

<h2>Appointments</h2>

{php}
shn_form_fopen('calendar&vm_action=display_appointments');
shn_form_fsopen('Add Appointment');
	shn_form_hidden(array('add_appointment' => 'Y'));
	shn_form_text('Name', 'name');
	shn_form_date('Date', 'date');
shn_form_fsclose();
shn_form_submit("Submit");
shn_form_fclose();
{/php}

<table border="0">
	<thead>
		<tr>
			<td>Name</td>
			<td>Date</td>
		</tr>
	</thead>
	<tbody>
	{foreach $appointments as $app}
	<tr>
		<td>{$app.name}</td>
		<td>{$app.date}</td>
	</tr>
	{/foreach}
	</tbody>
</table>

5. Create a CalendarView class that extends the main View class. This class contains a single function called displayAppointments($appointments), which would expect an array of arrays that is returned from the DAO::getAppointments() function. This function should assign the result to the templating engine and display the template. Put this class definition in a file called 'CalendarView.php' in the 'view' directory.

class CalendarView extends View {
    function displayAppointments($appointments) {
        $this->engine->assign('appointments', $appointments);
	$this->engine->display('calendar/display_appointments.tpl');
    }
}

6. Create a CalendarController class that extends CalendarView and implements the Controller interface.

  • It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.

Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.

class CalendarController extends CalendarView implements Controller {
	function controlHandler($getvars) {
		global $dao, $global;

		//first authorize the user
 		$ac = new AccessController($getvars);
		if(!$ac->isAuthorized())
			return;

		switch($getvars['vm_action']) {
			case 'display_appointments':
				if($getvars['add_appointment'] == 'Y') {
					$dao->addAppointment($getvars['name'], $getvars['date']);
				}
				$this->displayAppointments($dao->getAppointments());
			break;
		}
	}
}

7. Modify shn_vm_default() in main.inc to dispatch control to the CalendarController if a match for $getvars['act'] == 'project' is not found.

else if ($_GET['act'] =='calendar'){
    $controller =new CalendarController();
    $controller->controlHandler($_REQUEST);
} else...

In main.inc add the include statatement for the classes you added.

require_once('view/CalendarView.php');
require_once('controller/CalendarController.php');

8. Finally, in the menu.inc file, in the shn_vm_mainmenu() function, add the following line to display the menu item for the appointment form (add before the menu is closed;):

$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));

To simplify the procedure somewhat, this design avoids creating a calendar model class.

Appointments

{php} shn_form_fopen('calendar&vm_action=display_appointments'); shn_form_fsopen('Add Appointment'); shn_form_hidden(array('add_appointment' => 'Y')); shn_form_text('Name', 'name'); shn_form_date('Date', 'date'); shn_form_fsclose(); shn_form_submit("Submit"); shn_form_fclose(); {/php}

<thead> </thead> <tbody> {foreach $appointments as $app} {/foreach} </tbody>
Name Date
{$app.name} {$app.date}

</pre> 5. Create a CalendarView class that extends the main View class. This class contains a single function called displayAppointments($appointments), which would expect an array of arrays that is returned from the DAO::getAppointments() function. This function should assign the result to the templating engine and display the template. Put this class definition in a file called 'CalendarView.php' in the 'view' directory.

class CalendarView extends View {
    function displayAppointments($appointments) {
        $this->engine->assign('appointments', $appointments);
	$this->engine->display('calendar/display_appointments.tpl');
    }
}

6. Create a CalendarController class that extends CalendarView and implements the Controller interface.

  • It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.

Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.

class CalendarController extends CalendarView implements Controller {
	function controlHandler($getvars) {
		global $dao, $global;

		//first authorize the user
 		$ac = new AccessController($getvars);
		if(!$ac->isAuthorized())
			return;

		switch($getvars['vm_action']) {
			case 'display_appointments':
				if($getvars['add_appointment'] == 'Y') {
					echo 'hello';
					$dao->addAppointment($getvars['name'], $getvars['date']);
				}
				$this->displayAppointments($dao->getAppointments());
			break;
		}
	}
}

7. Modify shn_vm_default() in main.inc to dispatch control to the CalendarController if a match for $getvars['act'] == 'project' is not found.

else if ($_GET['act'] =='calendar'){
    $controller =new CalendarController();
    $controller->controlHandler($_REQUEST);
} else...

In main.inc add the include statatement for the classes you added.

require_once('view/CalendarView.php');
require_once('controller/CalendarController.php');

8. Finally, in the menu.inc file, in the shn_vm_mainmenu() function, add the following line to display the menu item for the appointment form (add before the menu is closed;):

$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));

To simplify the procedure somewhat, this design avoids creating a calendar model class.

Appointments

{php} shn_form_fopen('calendar&vm_action=display_appointments'); shn_form_fsopen('Add Appointment'); shn_form_hidden(array('add_appointment' => 'Y')); shn_form_text('Name', 'name'); shn_form_date('Date', 'date'); shn_form_fsclose(); shn_form_submit("Submit"); shn_form_fclose(); {/php}

<thead> </thead> <tbody> {foreach $appointments as $app} {/foreach} </tbody>
Name Date
{$app.name} {$app.date}

</pre> 5. Create a CalendarView class that extends the main View class. This class contains a single function called displayAppointments($appointments), which would expect an array of arrays that is returned from the DAO::getAppointments() function. This function should assign the result to the templating engine and display the template. Put this class definition in a file called 'CalendarView.php' in the 'view' directory.

class CalendarView extends View {
    function displayAppointments($appointments) {
        $this->engine->assign('appointments', $appointments);
	$this->engine->display('calendar/display_appointments.tpl');
    }
}

6. Create a CalendarController class that extends CalendarView and implements the Controller interface.

  • It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.

Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.

class CalendarController extends CalendarView implements Controller {
	function controlHandler($getvars) {
		global $dao, $global;

		//first authorize the user
 		$ac = new AccessController($getvars);
		if(!$ac->isAuthorized())
			return;

		switch($getvars['vm_action']) {
			case 'display_appointments':
				if($getvars['add_appointment'] == 'Y') {
					echo 'hello';
					$dao->addAppointment($getvars['name'], $getvars['date']);
				}
				$this->displayAppointments($dao->getAppointments());
			break;
		}
	}
}

7. Modify shn_vm_default() in main.inc to dispatch control to the CalendarController if a match for $getvars['act'] == 'project' is not found.

else if ($_GET['act'] =='calendar'){
    $controller =new CalendarController();
    $controller->controlHandler($_REQUEST);
} else...

In main.inc add the include statatement for the classes you added.

require_once('controller/CalendarView.php');
require_once('controller/CalendarController.php');

8. Finally, in the menu.inc file, in the shn_vm_mainmenu() function, add the following line to display the menu item for the appointment form (add before the menu is closed;):

$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));

To simplify the procedure somewhat, this design avoids creating a calendar model class.

Appointments

{php} shn_form_fopen('calendar&vm_action=display_appointments'); shn_form_fsopen('Add Appointment'); shn_form_hidden(array('add_appointment' => 'Y')); shn_form_text('Name', 'name'); shn_form_date('Date', 'date'); shn_form_fsclose(); shn_form_submit("Submit"); shn_form_fclose(); {/php}

<thead> </thead> <tbody> {foreach $appointments as $app} {/foreach} </tbody>
Name Date
{$app.name} {$app.date}

</pre> 5. Create a CalendarView class that extends the main View class. This class contains a single function called displayAppointments($appointments), which would expect an array of arrays that is returned from the DAO::getAppointments() function. This function should assign the result to the templating engine and display the template. Put this class definition in a file called 'CalendarView.php' in the 'view' directory.

class CalendarView extends View {
    function displayAppointments($appointments) {
        $this->engine->assign('appointments', $appointments);
	$this->engine->display('calendar/display_appointments.tpl');
    }
}

6. Create a CalendarController class that extends CalendarView and implements the Controller interface.

  • It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.

Put this class definition in a file called 'CalendarController.php' under the 'controller' directory.

class CalendarController extends CalendarView implements Controller {
	function controlHandler($getvars) {
		global $dao, $global;

		//first authorize the user
 		$ac = new AccessController($getvars);
		if(!$ac->isAuthorized())
			return;

		switch($getvars['vm_action']) {
			case 'display_appointments':
				if($getvars['add_appointment'] == 'Y') {
					echo 'hello';
					$dao->addAppointment($getvars['name'], $getvars['date']);
				}
				$this->displayAppointments($dao->getAppointments());
			break;
		}
	}
}

7. Modify shn_vm_default() in main.inc to dispatch control to the CalendarController if a match for $getvars['act'] == 'project' is not found.

else if ($_GET['act'] =='calendar' && $_SESSION['logged_in']){
    $controller =new CalendarController();
    $controller->controlHandler($_REQUEST);
} else...

In main.inc add the include statatement for the classes you added.

require_once('controller/CalendarView.php');
require_once('controller/CalendarController.php');

8. Finally, in the menu.inc file, in the shn_vm_mainmenu() function, add the following line to display the menu item for the appointment form (add before the menu is closed;):

$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));

To simplify the procedure somewhat, this design avoids creating a calendar model class.


Appointments

{php} shn_form_fopen('calendar&vm_action=display_appointments'); shn_form_fsopen('Add Appointment'); shn_form_hidden(array('add_appointment' => 'Y')); shn_form_text('Name', 'name'); shn_form_date('Date', 'date'); shn_form_fsclose(); shn_form_submit("Submit"); shn_form_fclose(); {/php}

<thead> </thead> <tbody> {foreach $appointments as $app} {/foreach} </tbody>
Name Date
{$app.name} {$app.date}

</pre> 5. Create a CalendarView class that extends the main View class. This class contains a single function called displayAppointments($appointments), which would expect an array of arrays that is returned from the DAO::getAppointments() function. This function should assign the result to the templating engine and display the template.

class CalendarView extends View {
    function displayAppointments($appointments) {
        $this->engine->assign('appointments', $appointments);
	$this->engine->display('calendar/display_appointments.tpl');
    }
}

6. Create a CalendarController class that extends CalendarView and implements the Controller interface.

  • It needs one function called controlHandler($getvars). Within this function, we can switch($getvars['vm_action']) and add a case for 'display_appointments'. For the code, if $getvars['add_appointment'] == 'Y' then we process the addition of an appointment by passing the name and date to the DAO::addAppointment function. No matter what, we call displayAppointments($dao->getAppointments) (which is legal since the controller is a subclass of the view) to show all appointments.
class CalendarController extends CalendarView implements Controller {
	function controlHandler($getvars) {
		global $dao, $global;

		//first authorize the user
 		$ac = new AccessController($getvars);
		if(!$ac->isAuthorized())
			return;

		switch($getvars['vm_action']) {
			case 'display_appointments':
				if($getvars['add_appointment'] == 'Y') {
					echo 'hello';
					$dao->addAppointment($getvars['name'], $getvars['date']);
				}
				$this->displayAppointments($dao->getAppointments());
			break;
		}
	}
}

7. Modify shn_vm_default() in main.inc to dispatch control to the CalendarController if a match for $getvars['act'] == 'project' is not found.

else if ($_GET['act' =='calendar' && $_SESSION['logged_in']){
    $controller =new CalendarController();
    $controller->controlHandler($_REQUEST);'
} else...

In main.inc add the include statatement for the Calender Controller.

require_once('controller/CalendarController.php');

8. Finally, in the menu.inc file, in the shn_vm_mainmenu() function, add the following line to display the menu item for the appointment form (add before the menu is closed;):

$ac->addMenuItem('Calendar', $ac->buildURLParams('calendar', 'display_appointments'));

To simplify the procedurs somewhat, this design avoids creating a calendar model class.