From c7d41e5bea4a5f96979a08da9cc9f79355edfe70 Mon Sep 17 00:00:00 2001
From: wei <>
Date: Sun, 16 Jul 2006 06:19:36 +0000
Subject: Update Time Tracker demo.
---
demos/time-tracker/protected/APP_CODE/BaseDao.php | 27 ++++
.../time-tracker/protected/APP_CODE/DaoManager.php | 126 ++++++++++++++++
demos/time-tracker/protected/APP_CODE/Project.php | 18 +++
.../time-tracker/protected/APP_CODE/ProjectDao.php | 23 ++-
.../protected/APP_CODE/TimeTrackerException.php | 19 +++
.../protected/APP_CODE/TimeTrackerUser.php | 51 ++++---
.../APP_CODE/TimeTrackerUserTypeHandler.php | 54 +++++++
demos/time-tracker/protected/APP_CODE/UserDao.php | 155 +++++++++++++++++++
.../protected/APP_CODE/UserManager.php | 68 +++++++++
.../time-tracker/protected/APP_CODE/exceptions.txt | 6 +-
.../protected/App_Data/time_tracker.db | Bin 0 -> 16384 bytes
demos/time-tracker/protected/data/time_tracker.db | Bin 16384 -> 0 bytes
.../protected/pages/Docs/TopicList.tpl | 2 +-
.../protected/pages/Docs/WritingUnitTest.page | 43 ++++--
demos/time-tracker/protected/pages/Docs/config.xml | 12 +-
demos/time-tracker/protected/pages/Docs/db.png | Bin 26879 -> 26521 bytes
.../protected/pages/TimeTracker/Login.page | 38 +++++
.../protected/pages/TimeTracker/Login.php | 53 +++++++
.../protected/pages/TimeTracker/Logout.page | 0
.../protected/pages/TimeTracker/Logout.php | 34 +++++
.../protected/pages/TimeTracker/MainLayout.php | 7 +
.../protected/pages/TimeTracker/MainLayout.tpl | 40 +++++
.../protected/pages/TimeTracker/SiteMap.php | 8 +
.../protected/pages/TimeTracker/SiteMap.tpl | 43 ++++++
.../protected/pages/TimeTracker/UserCreate.page | 65 ++++++++
.../protected/pages/TimeTracker/UserCreate.php | 78 ++++++++++
.../protected/pages/TimeTracker/UserList.page | 3 +
.../protected/pages/TimeTracker/config.xml | 24 +++
demos/time-tracker/protected/pages/Welcome.page | 168 +++++++++++++++++++++
29 files changed, 1124 insertions(+), 41 deletions(-)
create mode 100644 demos/time-tracker/protected/APP_CODE/DaoManager.php
create mode 100644 demos/time-tracker/protected/APP_CODE/TimeTrackerUserTypeHandler.php
create mode 100644 demos/time-tracker/protected/APP_CODE/UserDao.php
create mode 100644 demos/time-tracker/protected/APP_CODE/UserManager.php
create mode 100644 demos/time-tracker/protected/App_Data/time_tracker.db
delete mode 100644 demos/time-tracker/protected/data/time_tracker.db
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/Login.page
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/Login.php
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/Logout.page
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/Logout.php
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/MainLayout.php
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/SiteMap.php
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/UserCreate.page
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/UserCreate.php
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/UserList.page
create mode 100644 demos/time-tracker/protected/pages/TimeTracker/config.xml
create mode 100644 demos/time-tracker/protected/pages/Welcome.page
(limited to 'demos/time-tracker/protected')
diff --git a/demos/time-tracker/protected/APP_CODE/BaseDao.php b/demos/time-tracker/protected/APP_CODE/BaseDao.php
index f9146b59..63b91def 100644
--- a/demos/time-tracker/protected/APP_CODE/BaseDao.php
+++ b/demos/time-tracker/protected/APP_CODE/BaseDao.php
@@ -1,14 +1,41 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+/**
+ * Base DAO class.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
class BaseDao
{
+ /**
+ * @var TSqlMapper sqlmap client.
+ */
private $_connection;
+ /**
+ * @param TSqlMapper sqlmap client.
+ */
public function setConnection($connection)
{
$this->_connection = $connection;
}
+ /**
+ * @return TSqlMapper sqlmap client.
+ */
protected function getConnection()
{
return $this->_connection;
diff --git a/demos/time-tracker/protected/APP_CODE/DaoManager.php b/demos/time-tracker/protected/APP_CODE/DaoManager.php
new file mode 100644
index 00000000..b8ac55af
--- /dev/null
+++ b/demos/time-tracker/protected/APP_CODE/DaoManager.php
@@ -0,0 +1,126 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * DaoManager class.
+ *
+ * A Registry for Dao and an implementation of that type.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class DaoManager extends TModule
+{
+ /**
+ * @var TSqlMapper sqlmap client
+ */
+ private $_connection;
+ /**
+ * @var boolean if the module has been initialized
+ */
+ private $_initialized=false;
+ /**
+ * @var array registered list of dao
+ */
+ private $_dao=array();
+ /**
+ * Initializes the module.
+ * This method is required by IModule and is invoked by application.
+ * It loads dao information from the module configuration.
+ * @param TXmlElement module configuration
+ */
+ public function init($config)
+ {
+ if($this->_connection === null)
+ throw new TimeTrackerException('daomanager_connection_required');
+ $app = $this->getApplication();
+ if(is_string($this->_connection))
+ {
+ if(($conn=$app->getModule($this->_connection)->getClient())===null)
+ throw new TimeTrackerException('daomanager_undefined_connection',$this->_connection);
+ if(!($conn instanceof TSqlMapper))
+ throw new TimeTrackerException('daomanager_invalid_connection', $this->_connection);
+ $this->_connection = $conn;
+ }
+ $this->includeDaoImplementation($config->getElementsByTagName('dao'));
+ $this->_initialized = true;
+ }
+
+ /**
+ * Register the dao type and implementation class names.
+ * @param array list of TXmlDocument nodes.
+ */
+ protected function includeDaoImplementation($nodes)
+ {
+ foreach($nodes as $node)
+ {
+ $id = $node->getAttribute('id');
+ $class = $node->getAttribute('class');
+ $this->_dao[$id] = array('class' => $class);
+ }
+ }
+
+ /**
+ * @return array list of registered Daos
+ */
+ public function getDaos()
+ {
+ return $this->_dao;
+ }
+
+ /**
+ * Returns an implementation of a Dao type, implements the Registery
+ * pattern. Multiple calls returns the same Dao instance.
+ * @param string Dao type to find.
+ * @return object instance of the Dao implementation.
+ */
+ public function getDao($class)
+ {
+ if(isset($this->_dao[$class]))
+ {
+ if(!isset($this->_dao[$class]['instance']))
+ {
+ $dao = Prado::createComponent($this->_dao[$class]['class']);
+ $dao->setConnection($this->getConnection());
+ $this->_dao[$class]['instance'] = $dao;
+ }
+ return $this->_dao[$class]['instance'];
+ }
+ else
+ throw TimeTrackerException('daomanager_undefined_dao', $class);
+ }
+
+ /**
+ * @return TSqlMapper sqlmap client instance
+ */
+ public function getConnection()
+ {
+ return $this->_connection;
+ }
+
+ /**
+ * Sets the connection for all Daos registered.
+ * @param string|TSqlMapper sqlmap client module id or TSqlMapper instance.
+ */
+ public function setConnection($client)
+ {
+ if($this->_initialized)
+ throw new TimeTrackerException('daomanager_unchangeable');
+ if(!is_string($client) && !($client instanceof TSqlMapper))
+ throw new TConfigurationException('daomanager_invalid_connection',$client);
+ $this->_connection = $client;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/Project.php b/demos/time-tracker/protected/APP_CODE/Project.php
index ad9f7d19..660fad04 100644
--- a/demos/time-tracker/protected/APP_CODE/Project.php
+++ b/demos/time-tracker/protected/APP_CODE/Project.php
@@ -1,5 +1,23 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+/**
+ * Time Tracker Project class.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
class Project
{
public $ActualDuration = 0;
diff --git a/demos/time-tracker/protected/APP_CODE/ProjectDao.php b/demos/time-tracker/protected/APP_CODE/ProjectDao.php
index 25a2845d..81902e0c 100644
--- a/demos/time-tracker/protected/APP_CODE/ProjectDao.php
+++ b/demos/time-tracker/protected/APP_CODE/ProjectDao.php
@@ -1,10 +1,26 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
-Prado::using('Application.APP_CODE.BaseDao');
-
+/**
+ * Project DAO class.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
class ProjectDao extends BaseDao
{
- public function createNewProject($project)
+/* public function createNewProject($project)
{
$sqlmap = $this->getConnection();
$creator = $sqlmap->queryForObject('GetUserByName', $project->CreatorUserName);
@@ -71,6 +87,7 @@ class ProjectDao extends BaseDao
return $sqlmap->insert('AddUserToProject', $param);
}
}
+*/
}
?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/TimeTrackerException.php b/demos/time-tracker/protected/APP_CODE/TimeTrackerException.php
index d715eefa..64b11405 100644
--- a/demos/time-tracker/protected/APP_CODE/TimeTrackerException.php
+++ b/demos/time-tracker/protected/APP_CODE/TimeTrackerException.php
@@ -1,5 +1,24 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+/**
+ * Generic time tracker application exception. Exception messages are saved in
+ * "exceptions.txt"
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
class TimeTrackerException extends TException
{
/**
diff --git a/demos/time-tracker/protected/APP_CODE/TimeTrackerUser.php b/demos/time-tracker/protected/APP_CODE/TimeTrackerUser.php
index 4b6987bd..99ac1209 100644
--- a/demos/time-tracker/protected/APP_CODE/TimeTrackerUser.php
+++ b/demos/time-tracker/protected/APP_CODE/TimeTrackerUser.php
@@ -1,31 +1,48 @@
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+/**
+ * Import TUser and TUserManager
+ */
Prado::using('System.Security.TUser');
Prado::using('System.Security.TUserManager');
+/**
+ * User class for Time Tracker application.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
class TimeTrackerUser extends TUser
{
- private $_ID;
+ private $_emailAddress;
- public function __construct()
+ /**
+ * @param string user email address
+ */
+ public function setEmailAddress($value)
{
- parent::__construct(new TUserManager());
+ $this->_emailAddress = $value;
}
-
- public function getID(){ return $this->_ID; }
- public function setID($value)
- {
- if(is_null($this->_ID))
- $this->_ID = $value;
- else
- throw new TimeTrackerUserException(
- 'timetracker_user_readonly_id');
- }
-}
-
-class TimeTrackerUserException extends TimeTrackerException
-{
+ /**
+ * @return string user email address
+ */
+ public function getEmailAddress()
+ {
+ return $this->_emailAddress;
+ }
}
?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/TimeTrackerUserTypeHandler.php b/demos/time-tracker/protected/APP_CODE/TimeTrackerUserTypeHandler.php
new file mode 100644
index 00000000..07c46acc
--- /dev/null
+++ b/demos/time-tracker/protected/APP_CODE/TimeTrackerUserTypeHandler.php
@@ -0,0 +1,54 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * SQLMap type handler for TimeTrackerUser.
+ * The TimeTrackerUser requires an instance of IUserManager in constructor.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class TimeTrackerUserTypeHandler implements ITypeHandlerCallback
+{
+ /**
+ * Not implemented.
+ */
+ public function getParameter($object)
+ {
+ throw new TimeTrackerException('Not implemented');
+ }
+
+ /**
+ * Not implemented.
+ */
+ public function getResult($string)
+ {
+ throw new TimeTrackerException('Not implemented');
+ }
+
+ /**
+ * Creates a new instance of TimeTrackerUser
+ * @param array result data
+ * @return TimeTrackerUser new user instance
+ */
+ public function createNewInstance($row=null)
+ {
+ $manager = Prado::getApplication()->getModule('users');
+ if(is_null($manager))
+ $manager = new UserManager();
+ return new TimeTrackerUser($manager);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/UserDao.php b/demos/time-tracker/protected/APP_CODE/UserDao.php
new file mode 100644
index 00000000..4dc39b2b
--- /dev/null
+++ b/demos/time-tracker/protected/APP_CODE/UserDao.php
@@ -0,0 +1,155 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * UserDao class list, create, find and delete users.
+ * In addition, it can validate username and password, and update
+ * the user roles. Furthermore, a unique new token can be generated,
+ * this token can be used to perform persistent cookie login.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class UserDao extends BaseDao
+{
+ /**
+ * @param string username
+ * @return TimeTrackerUser find by user name, null if not found or disabled.
+ */
+ public function getUserByName($username)
+ {
+ $sqlmap = $this->getConnection();
+ return $sqlmap->queryForObject('GetUserByName', $username);
+ }
+
+ /**
+ * @return array list of all enabled users.
+ */
+ public function getAllUsers()
+ {
+ $sqlmap = $this->getConnection();
+ return $sqlmap->queryForList('GetAllUsers');
+ }
+
+ /**
+ * @param TimeTrackerUser new user details.
+ * @param string new user password.
+ */
+ public function addNewUser($user, $password)
+ {
+ $sqlmap = $this->getConnection();
+ $param['user'] = $user;
+ $param['password'] = md5($password);
+ $sqlmap->insert('AddNewUser', $param);
+ if(count($user->getRoles()) > 0)
+ $this->updateUserRoles($user);
+ }
+
+ /**
+ * @param string username to delete
+ */
+ public function deleteUserByName($username)
+ {
+ $sqlmap = $this->getConnection();
+ $sqlmap->delete('DeleteUserByName', $username);
+ }
+
+ /**
+ * Updates the user profile details, including user roles.
+ * @param TimeTrackerUser updated user details.
+ * @param string new user password, null to avoid updating password.
+ */
+ public function updateUser($user,$password=null)
+ {
+ $sqlmap = $this->getConnection();
+ if($password !== null)
+ {
+ $param['user'] = $user;
+ $param['password'] = md5($password);
+ $sqlmap->update('UpdateUserDetailsAndPassword', $param);
+ }
+ else
+ {
+ $sqlmap->update('UpdateUserDetails', $user);
+ }
+ $this->updateUserRoles($user);
+ }
+
+ /**
+ * @param string username to be validated
+ * @param string matching password
+ * @return boolean true if the username and password matches.
+ */
+ public function validateUser($username, $password)
+ {
+ $sqlmap = $this->getConnection();
+ $param['username'] = $username;
+ $param['password'] = md5($password);
+ return $sqlmap->queryForObject('ValidateUser', $param);
+ }
+
+ /**
+ * @param string unique persistent session token
+ * @return TimeTrackerUser user details if valid token, null otherwise.
+ */
+ public function validateSignon($token)
+ {
+ $sqlmap = $this->getConnection();
+ $sqlmap->update('UpdateSignon', $token);
+ return $sqlmap->queryForObject('ValidateAutoSignon', $token);
+ }
+
+ /**
+ * @param TimeTrackerUser user details to generate the token
+ * @return string unique persistent login token.
+ */
+ public function createSignonToken($user)
+ {
+ $sqlmap = $this->getConnection();
+ $param['username'] = $user->getName();
+ $param['token'] = md5(microtime().$param['username']);
+ $sqlmap->insert('RegisterAutoSignon', $param);
+ return $param['token'];
+ }
+
+ /**
+ * @param TimeTrackerUser deletes all signon token for given user, null to delete all
+ * tokens.
+ */
+ public function clearSignonTokens($user=null)
+ {
+ $sqlmap = $this->getConnection();
+ if($user !== null)
+ $sqlmap->delete('DeleteAutoSignon', $user->getName());
+ else
+ $sqlmap->delete('DeleteAllSignon');
+ }
+
+ /**
+ * @param TimeTrackerUser user details for updating the assigned roles.
+ */
+ public function updateUserRoles($user)
+ {
+ $sqlmap = $this->getConnection();
+ $sqlmap->delete('DeleteUserRoles', $user);
+ foreach($user->getRoles() as $role)
+ {
+ $param['username'] = $user->getName();
+ $param['role'] = $role;
+ $sqlmap->update('AddUserRole', $param);
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/UserManager.php b/demos/time-tracker/protected/APP_CODE/UserManager.php
new file mode 100644
index 00000000..1327dc3c
--- /dev/null
+++ b/demos/time-tracker/protected/APP_CODE/UserManager.php
@@ -0,0 +1,68 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * User manager module class for time tracker application.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class UserManager extends TModule implements IUserManager
+{
+ /**
+ * @return string name for a guest user.
+ */
+ public function getGuestName()
+ {
+ return 'Guest';
+ }
+
+ /**
+ * Returns a user instance given the user name.
+ * @param string user name, null if it is a guest.
+ * @return TUser the user instance, null if the specified username is not in the user database.
+ */
+ public function getUser($username=null)
+ {
+ if($username===null)
+ {
+ $user=new TUser($this);
+ $user->setIsGuest(true);
+ return $user;
+ }
+ else
+ {
+ $daos = $this->getApplication()->getModule('daos');
+ $userDao = $daos->getDao('UserDao');
+ $user = $userDao->getUserByName($username);
+ $user->setIsGuest(false);
+ return $user;
+ }
+ }
+
+ /**
+ * Validates if the username and password are correct.
+ * @param string user name
+ * @param string password
+ * @return boolean true if validation is successful, false otherwise.
+ */
+ public function validateUser($username,$password)
+ {
+ $daos = $this->getApplication()->getModule('daos');
+ $userDao = $daos->getDao('UserDao');
+ return $userDao->validateUser($username, $password);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/APP_CODE/exceptions.txt b/demos/time-tracker/protected/APP_CODE/exceptions.txt
index e948f4d0..6568cc72 100644
--- a/demos/time-tracker/protected/APP_CODE/exceptions.txt
+++ b/demos/time-tracker/protected/APP_CODE/exceptions.txt
@@ -1,3 +1,7 @@
timetracker_user_readonly_id = Time tracker user ID is read-only.
invalid_creator_and_manager = Unable to find time tracker usernames '{1}' and '{2}' for project '{0}'.
-project_exists = Project '{0}' already exists.
\ No newline at end of file
+project_exists = Project '{0}' already exists.
+daomanager_connection_required = An TSqlMapper connection is required by Dao Manager.
+daomanager_undefined_connection = Connection '{0}' for Dao Manager is undefined.
+daomanager_invalid_connection = Connection '{0}' does not appear to ba a TSqlMapper in Dao Manager.
+daomanager_undefined_dao = Dao class '{0}' is not registered.
\ No newline at end of file
diff --git a/demos/time-tracker/protected/App_Data/time_tracker.db b/demos/time-tracker/protected/App_Data/time_tracker.db
new file mode 100644
index 00000000..03fe9156
Binary files /dev/null and b/demos/time-tracker/protected/App_Data/time_tracker.db differ
diff --git a/demos/time-tracker/protected/data/time_tracker.db b/demos/time-tracker/protected/data/time_tracker.db
deleted file mode 100644
index 03fe9156..00000000
Binary files a/demos/time-tracker/protected/data/time_tracker.db and /dev/null differ
diff --git a/demos/time-tracker/protected/pages/Docs/TopicList.tpl b/demos/time-tracker/protected/pages/Docs/TopicList.tpl
index 5fa2adb5..53243578 100644
--- a/demos/time-tracker/protected/pages/Docs/TopicList.tpl
+++ b/demos/time-tracker/protected/pages/Docs/TopicList.tpl
@@ -14,7 +14,7 @@
Testing Business Code
- Create Business Code
+ Database Design
Using SQLMap Data Mapper
User Class and Exceptions
More Tests
diff --git a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page b/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
index 32c7bc79..77bdcbe6 100644
--- a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
+++ b/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
@@ -1,13 +1,19 @@
Writing a Unit Test
+Before we begin to write our business logic and code, we shall
+proceed with the path of test driven development (TDD), or at least take
+some part of that process.
+
Unit testing is a useful tool when we want to start to test
our individual business logic classes.
- The tests/unit directory will be used to hold the unit test cases and tests/functional directory
-to hold the function test cases.
+ The tests/unit directory will be used to hold the unit test
+ cases and tests/functional directory
+ to hold the function test cases.
Write a unit test case
-We will start be writing a very simple unit test case.
+We will start be writing a very simple unit test case. Notice
+that we are writing the test case first .
<?php
class ProjectTestCase extends UnitTestCase
@@ -29,14 +35,16 @@ directory.
Figure 1: Unit test runner
-Clicking on the ProjectTestCase.php like, you should see
+
Clicking on the ProjectTestCase.php link, you should see
Figure 2: Unit test failure
Smallest step to make the test pass.
-Obviously, we need create the class Project , so lets define the class.
+Since we only wrote the test case and nothing else we expected
+that the test case will fail at some point. Obviously, we need create
+a class Project , so lets define the Project class.
<?php
class Project
@@ -44,15 +52,11 @@ class Project
}
?>
-Save the above code as time-tracker/protected/pages/APP_CODE/Project.php .
- Where the APP_CODE directory will contain most of your business logic code for the Time Tracker application.
-We also need to add the following line in our test case so as to include the Project class file when running the tests.
-
-
-The statement Prado::using('Application.APP_CODE.Project') basically
-loads the Project.php class file. It assumes that a class name Project has filename Project.php .
-For futher details regarding Prado::using can be found in Prado Namespaces documentation.
-
+We save the above code as time-tracker/protected/pages/APP_CODE/Project.php .
+ Where the APP_CODE directory will contain most of the business logic code
+ for the Time Tracker application.
+Now, we also need to add the following line in our test case so as to
+include the Project class file when running the tests.
<?php
@@ -63,11 +67,20 @@ class ProjectTestCase extends UnitTestCase
}
?>
+
+Info:
+The statement
Prado::using('Application.APP_CODE.Project') basically
+loads the
Project.php class file. It assumes that a class name
Project has filename
Project.php .
+For futher details regarding
Prado::using can be found in
Prado Namespaces documentation.
+
+
Run the unit test runner again, we see that the test has passed.
Figure 3: Unit test success
-Later on, we shall write more test cases. See the SimpleTest documentation for detailed tutorial on writing test cases.
+Later on, we shall write more test cases. See the
+SimpleTest documentation
+for detailed tutorial on writing test cases.
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Docs/config.xml b/demos/time-tracker/protected/pages/Docs/config.xml
index da4d3bfc..e8fdc3fe 100644
--- a/demos/time-tracker/protected/pages/Docs/config.xml
+++ b/demos/time-tracker/protected/pages/Docs/config.xml
@@ -1,8 +1,12 @@
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Docs/db.png b/demos/time-tracker/protected/pages/Docs/db.png
index f2209ef4..efdcc1e5 100644
Binary files a/demos/time-tracker/protected/pages/Docs/db.png and b/demos/time-tracker/protected/pages/Docs/db.png differ
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Login.page b/demos/time-tracker/protected/pages/TimeTracker/Login.page
new file mode 100644
index 00000000..dbc16de1
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Login.page
@@ -0,0 +1,38 @@
+<%@ Title="My Company - Time Tracker - Site Logon" %>
+
+Time Tracker Website Login
+
+User Login
+
+
+ *
+
+
+
+
+
+ *
+
+
+
+
+
+
+
+
+
+
+
+
Create New User
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Login.php b/demos/time-tracker/protected/pages/TimeTracker/Login.php
new file mode 100644
index 00000000..376953a5
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Login.php
@@ -0,0 +1,53 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Login page class.
+ *
+ * Validate the user credentials and redirect to requested page
+ * if successful.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class Login extends TPage
+{
+ /**
+ * Validates the username and password.
+ * @param TControl custom validator that created the event.
+ * @param TServerValidateEventParameter validation parameters.
+ */
+ public function validateUser($sender, $param)
+ {
+ $authManager=$this->Application->getModule('auth');
+ if(!$authManager->login($this->username->Text,$this->password->Text))
+ $param->IsValid=false;;
+ }
+
+ /**
+ * Redirect to the requested page if login is successful.
+ * @param TControl button control that created the event.
+ * @param TEventParameter event parameters.
+ */
+ public function doLogin($sender, $param)
+ {
+ if($this->Page->IsValid)
+ {
+ $auth = $this->Application->getModule('auth');
+ $this->Response->redirect($auth->getReturnUrl());
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Logout.page b/demos/time-tracker/protected/pages/TimeTracker/Logout.page
new file mode 100644
index 00000000..e69de29b
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Logout.php b/demos/time-tracker/protected/pages/TimeTracker/Logout.php
new file mode 100644
index 00000000..08fdfaf6
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Logout.php
@@ -0,0 +1,34 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Logout page class.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class Logout extends TPage
+{
+ /**
+ * Logs out the current user and redirect to default page.
+ */
+ function onLoad($param)
+ {
+ $this->Application->getModule('auth')->logout();
+ $url = $this->Service->constructUrl($this->Service->DefaultPage);
+ $this->Response->redirect($url);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php
new file mode 100644
index 00000000..253d6c03
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl
new file mode 100644
index 00000000..2d8bad44
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+ Service->constructUrl('TimeTracker.Login') %>
+ Visible=<%= $this->User->getIsGuest() %> />
+ Service->constructUrl('TimeTracker.Logout') %>
+ Visible=<%= !$this->User->getIsGuest() %> />
+
+
+
+
+
+User->getIsGuest() %> />
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php
new file mode 100644
index 00000000..0b71eb68
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl
new file mode 100644
index 00000000..48187b52
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Event.OnLoad(function()
+ {
+ menuitems = $$(".menuitem");
+ menuitems.each(function(el)
+ {
+ Event.observe(el, "mouseover", function(ev)
+ {
+ menuitems.each(function(item)
+ {
+ Element.removeClassName(item.parentNode, "active");
+ });
+ Element.addClassName(Event.element(ev).parentNode, "active");
+ });
+ });
+ });
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page
new file mode 100644
index 00000000..fda7ba9b
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page
@@ -0,0 +1,65 @@
+
+Create New User
+
+User Details
+ Sign Up for Your New Account
+
+
+ *
+
+
+
+
+
+
+ *
+
+
+
+
+
+
+ *
+
+
+
+
+
+ *
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php
new file mode 100644
index 00000000..b337bfca
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php
@@ -0,0 +1,78 @@
+
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Create new user page class. Validate that the usernames are unique
+ * and set the new user credentials as the current application credentials.
+ *
+ * @author Wei Zhuo
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class UserCreate extends TPage
+{
+ /**
+ * Verify that the username is not taken.
+ * @param TControl custom validator that created the event.
+ * @param TServerValidateEventParameter validation parameters.
+ */
+ public function checkUsername($sender, $param)
+ {
+ $userDao = $this->Application->Modules['daos']->getDao('UserDao');
+ $user = $userDao->getUserByName($this->username->Text);
+ if(!is_null($user))
+ {
+ $param->IsValid = false;
+ $sender->ErrorMessage =
+ "The user name is already taken, try '{$user->Name}01'";
+ }
+ }
+
+ /**
+ * Create a new user if all data entered are valid.
+ * The default user roles are obtained from "config.xml". The new user
+ * details is saved to the database and the new credentials are used as the
+ * application user. The user is redirected to the requested page.
+ * @param TControl button control that created the event.
+ * @param TEventParameter event parameters.
+ */
+ public function createNewUser($sender, $param)
+ {
+ if($this->IsValid)
+ {
+ $newUser = new TimeTrackerUser($this->User->Manager);
+ $newUser->EmailAddress = $this->email->Text;
+ $newUser->Name = $this->username->Text;
+ $newUser->IsGuest = false;
+ $newUser->Roles = $this->Application->Parameters['NewUserRoles'];
+
+ //save the user
+ $userDao = $this->Application->Modules['daos']->getDao('UserDao');
+ $userDao->addNewUser($newUser, $this->password->Text);
+
+ //update the user
+ $auth = $this->Application->getModule('auth');
+ $auth->updateSessionUser($newUser);
+ $this->Application->User = $newUser;
+
+ //return to requested page
+ $this->Response->redirect($auth->getReturnUrl());
+
+ //goto default page.
+ //$url = $this->Service->constructUrl($this->Service->DefaultPage);
+ //$this->Response->redirect($url);
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserList.page b/demos/time-tracker/protected/pages/TimeTracker/UserList.page
new file mode 100644
index 00000000..48b2bbc7
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserList.page
@@ -0,0 +1,3 @@
+
+List Users
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/config.xml b/demos/time-tracker/protected/pages/TimeTracker/config.xml
new file mode 100644
index 00000000..dac6465d
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/config.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Welcome.page b/demos/time-tracker/protected/pages/Welcome.page
new file mode 100644
index 00000000..65ada02d
--- /dev/null
+++ b/demos/time-tracker/protected/pages/Welcome.page
@@ -0,0 +1,168 @@
+
+
+
+ Welcome
+
+
+
+ Time Tracker Starter Kit
+
+ Welcome to your new Time Tracker sample application. The key features are:
+
+ Projects. Define project information like due dates, hours to complete,
+ project resources, and more.
+ Track Time. Track time spent each day by category and project.
+ Reports. Generate progress and team resource reports across multiple projects.
+
+
+ The Time Tracker site is ready to run! No changes are needed.
+
+
+
+ Site Members and Roles
+
+ Your Time Tracker Web site allows visitors to register as members and then log in.
+ Members have specific privileges defined by roles such as administrator or guest.
+ Each Time Tracker Web site defines site-specific roles.
+ The following table describes what features are available to visitors in different roles.
+
+
+ Visitor
+ Privileges
+ Default Login
+
+
+
+ Not logged in
+
+ No privileges.
+
+
+
+ Logged in
+
+ No privileges. All members must be associated at least with the role Consultant .
+ N/A
+
+
+ Logged in as
+ Consultant
+ May log time entries only.
+ username: consultant
+ password: consultant
+
+
+
+ Logged in as
+ Project Manager
+
+ May additionally edit all projects and view reports.
+ username: manager
+ password: manager
+
+
+
+ Logged in as
+ Project Administrator
+
+ May additionally view the list of all users.
+ username: admin
+ password: admin
+
+
+
+ Be sure to create a user name for yourself and assign yourself to a role (such as administrator) that can manage the site.
+
+ Visitors can register by clicking the Create new user link on the home page.
+ New members are activated automatically, and are assigned to a role as specified in the application.xml file.
+ You can manage users (for example, assign them to a role) when login as administrator.
+ For details, see Appendix A .
+
+
+
+ Projects and Time Entries
+ To add a project and categories
+
+ Log in to the site as a member in the role Project Manager or Project Administrator .
+ Click the Projects tab and then click Create New Project .
+ Specify a project name, project manager, estimated complete date, estimated duration, and description.
+ Under Specify Project Members , select a resource. You must select at least one resource.
+ Click Save . A category pane is displayed on the right.
+ Specify a category name, category abbreviation, and duration.
+ Click Add . The new category is displayed in the categories list.
+ Repeat steps 6 and 7 to create additional categories.
+
+ Log a Time Entry
+
+ Log in to the site as a consultant (member in the role Consultant ).
+ Click the Log tab.
+ Under Log your hours , choose a project and a category and fill in the day, hours, and description.
+ Make sure the correct consultant is selected in the Time Sheet For list.
+ Click Add Entry .
+
+
+
+
+ Reports
+ To create a project report
+
+ Log in to the site as a member in the role Project Manager or Project Administrator .
+ Click the Reports tab and then click Project Reports .
+ Under Select a project , choose one or more projects.
+ Click Generate Report .
+
+ To create a resource report
+
+ Log in to the site as a member in the role Project Manager or Project Administrator .
+ Click the Reports tab and then click Resources Report .
+ Select one or more projects, select one or more resources, and then specify a date range.
+ Click Generate Report .
+
+
+
+
+
+ Appendix A - Manually Managing Members and Roles
+
+ Your Time Tracker Web site allows visitors to register as members.
+ Members have specific privileges defined by a role you assign to them.
+ A special administrative role has rights to perform all functions in the site.
+
+ To create a user (member):
+
+ Login as administrator, click Create New User .
+
+ ...
+
+
+ To modify an existing member's role:
+
+ Login as administrator, click List Users .
+
+ ...
+
+
+
+
+ Appendix B - Publishing Your Site
+
+ When you are ready to share the Web site with others, you can copy it to your Web server.
+ You need to know the File Transfer Protocol (FTP) address of your server, and if required, the user name and password assigned to you.
+
+ ...
+
+
+
--
cgit v1.2.3