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

    + + +
    \ 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 @@ + + + + + + + +

    + My Company + Time Tracker + +

    +
    + +

    Help

    +

    Implementation Guide

    +
    + +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

    + + + +
    \ 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.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VisitorPrivilegesDefault 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

    +
      +
    1. Log in to the site as a member in the role Project Manager or Project Administrator.
    2. +
    3. Click the Projects tab and then click Create New Project.
    4. +
    5. Specify a project name, project manager, estimated complete date, estimated duration, and description.
    6. +
    7. Under Specify Project Members, select a resource. You must select at least one resource.
    8. +
    9. Click Save. A category pane is displayed on the right.
    10. +
    11. Specify a category name, category abbreviation, and duration.
    12. +
    13. Click Add. The new category is displayed in the categories list.
    14. +
    15. Repeat steps 6 and 7 to create additional categories.
    16. +
    +

    Log a Time Entry

    +
      +
    1. Log in to the site as a consultant (member in the role Consultant).
    2. +
    3. Click the Log tab.
    4. +
    5. Under Log your hours, choose a project and a category and fill in the day, hours, and description.
    6. +
    7. Make sure the correct consultant is selected in the Time Sheet For list.
    8. +
    9. Click Add Entry.
    10. +
    + +
    + +

    Reports

    +

    To create a project report

    +
      +
    1. Log in to the site as a member in the role Project Manager or Project Administrator.
    2. +
    3. Click the Reports tab and then click Project Reports.
    4. +
    5. Under Select a project, choose one or more projects.
    6. +
    7. Click Generate Report.
    8. +
    +

    To create a resource report

    +
      +
    1. Log in to the site as a member in the role Project Manager or Project Administrator.
    2. +
    3. Click the Reports tab and then click Resources Report.
    4. +
    5. Select one or more projects, select one or more resources, and then specify a date range.
    6. +
    7. Click Generate Report.
    8. +
    + +
    + + +

    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):

    +
      +
    1. Login as administrator, click Create New User. +
    2. +
    3. ...
    4. +
    +

    + To modify an existing member's role:

    +
      +
    1. Login as administrator, click List Users. +
    2. +
    3. ...
    4. +
    + +
    + +

    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.

    +
      +
    1. ...
    2. +
    + + -- cgit v1.2.3