Zend Framework 1.8 workshop Zend Framework Presentation Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop About Me: PHP5 Zend Certified Engineer ZF Contributor since 2008 Freelance Consultant PHP Community active member Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Zend Framework • Full Stack Framework • Component Library Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop How to Get It? • Grab it from the download page: http://framework.zend.com/download/latest • Through Subversion: http://framework.zend.com/svn/framework/standard/trunk/ Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop How To Install? Add it to your php.ini include_path directive include_path = .:/usr/local/lib/php:/PathToZendFrameworkLibrary That’s it! Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Starting A New Project With Zend_Tool First requirements: • For *nix environments copy the zf.sh and zf.php from the ZF/bin To the same directory as your PHP binary • For Windows: •copy the zf.php and zf.bat to the same directory as your PHP binary •add the php path to your PATH environment Var: # Right-click My Computer and select |Properties. # Select the Environment page. # In the System Variables area, click on PATH. # Add the php path to the end in the format VALUE1;VALUE2;c:php # Click Apply. # The changes take effect immediately. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Creating the project “MyProject” $ zf create project /path/to/non-existent-dir-called-MyProject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Adding a “MyProject” vhost Testing environment httpd.conf or httpd-vhosts.conf: <VirtualHost *:80> ServerName MyProject DocumentRoot absolute-path-to-MyProject-folder ErrorLog logsMyProject-error.log CustomLog logsMyProject-access.log common <Directory /> Options FollowSymLinks AllowOverride All Order allow,deny Allow from all Satisfy all </Directory> </VirtualHost> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop For windows: Add the following line to the /etc/host file 127.0.0.1 MyProject Restart apache, fire up the browser and go to: http://MyProject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Creating an Action + View Go to the MyProject directory and issue the following command to create the helloAction in the IndexController and corresponding view: $ zf create action hello index For a full list of commands simply visit: http://framework.zend.com/manual/en/zend.tool.project.create-a-project.html Or issue the command: $ zf --help Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Creating a Module and Controller $ zf create module admin $ zf create controller index 1 admin Note: Trying to create a controller that already exists in another Module might result in an error. Depending on the Zend_Tool Verion you have. The solution is to apply the patch from ZF Issue Tracker: http://framework.zend.com/issues/browse/ZF-6853 Note: If you applied this patch, make sure all controller names in the admin module start with Admin_ Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Registering the Module class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoloadModuleAdmin() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'Admin', 'basePath' => APPLICATION_PATH.'/modules/admin', )); return $autoloader; } } The method is called automatically by Zend_Application as it starts with _init. You can choose the remainder of the method name as you like. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Registering the Module myProject/application/configs/application.ini resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Setting up the Mysql Database Add to configs/application.ini [production] =============================== resources.db.adapter = PDO_MYSQL resources.db.params.host = localhost resources.db.params.username = nick resources.db.params.password = 12345 resources.db.params.dbname = myproject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Create the database table CREATE TABLE users ( id int(11) NOT NULL auto_increment, username varchar(100) NOT NULL, pwd varchar(32) NOT NULL, firstname varchar(20) NOT NULL, PRIMARY KEY (id) ); Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Populate the table INSERT INTO users (username, pwd, firstname) VALUES ('NickBelhomme', md5('hello'), 'Nick'), ('ChanieNavez', md5('strong'), 'Chantal'), ('ElvisP', md5('presley'), 'Elvis'); Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Model + DAO Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop myProject/application/modules/admin/models/dao/Interface.php interface Admin_Model_Dao_Interface { public function find($id); public function insert($username, $pwd, $firstname); public function update($id, $username, $pwd, $firstname); public function delete($id); public function findAll(); } Common interface between all DAOs. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop myProject/application/modules/admin/models/dao/UserDB.php class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { protected $_name = 'users'; public function find($id) { Very Simple DAO $id = (int)$id; $row = $this->fetchRow('id = ' . $id); (Data Access Object) if (!$row) { throw new Exception("Count not find row $id"); } return $row; } public function insert($username, $pwd, $firstname) { $data = array( 'username' => $username, 'pwd' => $this->hashPassword($pwd), 'firstname' => $firstname, ); parent::insert($data); } //... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop myProject/application/modules/admin/models/Dao/UserDB.php class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { //… public function update($id, $username, $pwd, $firstname) { $data = array( Very Simple DAO 'username' => $username, 'pwd' => $this->hashPassword($pwd), (Data Access Object) 'firstname' => $firstname, ); parent::update($data, 'id = '. (int)$id); } public function delete($id) { parent::delete('id =' . (int)$id); } public function findAll() { return $this->fetchAll(); } protected function hashPassword($pwd) { return md5($pwd); } } ?> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop myProject/application/modules/admin/models/User.php class Admin_Model_User { const DAO_CLASS = 'Admin_Model_Dao_UserDB'; protected $dao; public function __construct() { $daoClassName = self::DAO_CLASS; $this->dao = new $daoClassName(); The Model } using the DAO. public function find($id) { return $this->dao->find($id); Easy Switching between } Different data resources public function insert($username, $pwd, $firstname) { return $this->dao->insert($username, $pwd, $firstname); } public function update($id, $username, $pwd, $firstname) { return $this->dao->update($id, $username, $pwd, $firstname); } // ... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop myProject/application/modules/admin/models/User.php <?php class Admin_Model_User { The Model // ... using the DAO. public function delete($id) { Easy Switching between return $this->dao->delete($id); Different data resources } public function findAll() { return $this->dao->findAll(); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Actions and Views Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Setting up the admin actions $ zf create action add index 1 admin $ zf create action edit index 1 admin $ zf create action delete index 1 admin Again if you are using a version of Zend_Tool which isn’t fully module Aware you can patch the Zend_Tool_Project_Provider_Action with if (self::hasResource($this->_loadedProfile, $name, $controllerName, $module)) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Admin_IndexController indexAction public function indexAction() { $users = new Admin_Model_User(); $this->view->users = $users->findAll(); } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding index.phtml view script: myProject/application/modules/admin/views/scripts/index/index.phtml <p><a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'add'));?>">Add new user</a></p> <table> <tr> <th>Username</th> <th>First Name</th> <th>&nbsp;</th> </tr> <?php foreach($this->users as $user) : ?> <tr> <td><?php echo $this->escape($user->username);?></td> <td><?php echo $this->escape($user->firstname);?></td> <td> <a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'edit', 'id'=>$user->id));?>">Edit</a> <a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'delete', 'id'=>$user->id));?>">Delete</a> </td> </tr> <?php endforeach; ?> </table> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Admin_IndexController deleteAction REST: public function deleteAction() irreversible { action use if ($this->getRequest()->isPost()) { POST not $del = $this->getRequest()->getPost('del'); GET if ($del == 'Yes') { $id = $this->getRequest()->getPost('id'); $users = new Admin_Model_User(); $users->delete($id); } $this->_redirect('/admin/'); } else { $id = $this->_getParam('id', 0); $users = new Admin_Model_User(); $this->view->user = $users->find($id); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding delete.phtml view script: myProject/application/modules/admin/views/scripts/index/delete.phtml <p>Are you sure that you want to delete '<?php echo $this->escape($this->user['username']); ?>' aka '<?php echo $this->escape($this->user['firstname']); ?>'? </p> <form action="<?php echo $this->url(array('action'=>'delete')); ?>" method="post"> <fieldset> <input type="hidden" name="id" value="<?php echo $this->escape($this->user['id']); ?>" /> <input type="submit" name="del" value="Yes" /> <input type="submit" name="del" value="No" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Admin_IndexController addAction public function addAction() { if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'add') { $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $firstname = $this->getRequest()->getPost('firstname'); $users = new Admin_Model_User(); $users->insert($username, $pwd, $firstname); } $this->_redirect('/admin/'); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding add.phtml view script: myProject/application/modules/admin/views/scripts/index/add.phtml <h2>Add a new User</h2> <form action="<?php echo $this->url(array('action'=>'add')); ?>" method="post"> <fieldset> username: <input type="text" name="username"><br/> password: <input type="password" name="pwd"><br/> firstname: <input type="text" name="firstname"><br/> <input type="submit" name="action" value="add" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The Admin_IndexController editAction public function editAction() { if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'edit') { $id = $this->getRequest()->getPost('id'); $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $firstname = $this->getRequest()->getPost('firstname'); $users = new Admin_Model_User(); $users->update($username, $pwd, $firstname); } $this->_redirect('/admin/'); } else { $id = $this->_getParam('id', 0); $users = new Admin_Model_User(); $this->view->user = $users->find($id); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding edit.phtml view script: myProject/application/modules/admin/views/scripts/index/edit.phtml <h2>Edit User: <?php echo $this->escape($this->user->username); ?></h2> <form action="<?php echo $this->url(array('action'=>'edit')); ?>" method="post"> <fieldset> <input type="hidden" name="id" value="<?php echo $this->escape($this->user->id); ?>"> username: <input type="text" name="username" value="<?php echo $this->escape($this->user->username); ?>"><br/> password: <input type="password" name="pwd"><br/> firstname: <input type="text" name="firstname" value="<?php echo $this->escape($this->user->firstname); ?>"><br/> <input type="submit" name="action" value="edit" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Authentication: Zend_Auth Authentication is loosely defined as determining whether an entity actually is what it purports to be (i.e., identification), based on some set of credentials. http://framework.zend.com/manual/en/zend.auth.html#zend.auth.introduction Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Append the DAO and User Classes interface Admin_Model_Dao_Interface { // … public function findCredentials($username, $pwd); } class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { // … public function findCredentials($username, $pwd) { $select = $this->select()->where('username = ?', $username) ->where('pwd = ?', $this->hashPassword($pwd)); $row = $this->fetchRow($select); if($row) { return $row; } return false; } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Append the DAO and User Classes class Admin_Model_User { // ... public function findCredentials($username, $password) { return $this->dao->findCredentials($username, $password); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Always use a vendor or project prefix And inform the autoloader of library prefixes Prepend the application bootstrap class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoloadModuleDefault() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'Myp', 'basePath' => dirname(__FILE__) )); return $autoloader; } //... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Create an application model: The Auth Adapter myProject/application/models/AuthAdapter.php class Myp_Model_AuthAdapter implements Zend_Auth_Adapter_Interface { protected $username; protected $password; protected $user; public function __construct($username, $password) { $this->username = $username; $this->password = $password; $this->user = new Admin_Model_User(); } public function authenticate() { $match = $this->user->findCredentials($this->username, $this->password); if(!$match) { $result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); } else { $user = current($match); $result = new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user); } return $result; } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The IndexController loginAction $ zf create action login index 1 Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The IndexController loginAction public function loginAction() { $auth = Zend_Auth::getInstance(); if(Zend_Auth::getInstance()->hasIdentity()) { $this->_redirect('/index/hello'); } else if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'login') { $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $authAdapter = new Myp_Model_AuthAdapter($username, $pwd); $result = $auth->authenticate($authAdapter); if(!$result->isValid()) { switch ($result->getCode()) { case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID: $this->view->error = 'user credentials not found'; } } else { $this->_redirect('/index/hello'); } } } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding login.phtml view script: myProject/application/views/scripts/index/login.phtml <h2>Login</h2> <form action="<?php echo $this->url(array('action'=>'login')); ?>" method="post"> <fieldset> username: <input type="text" name="username"><br/> password: <input type="password" name="pwd"><br/> <div><?php echo $this->escape($this->error);?></div> <input type="submit" name="action" value="login" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The IndexController helloAction public function helloAction() { if(Zend_Auth::getInstance()->hasIdentity()) { $this->view->user = Zend_Auth::getInstance()->getIdentity(); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop The corresponding hello.phtml view script: myProject/application/views/scripts/index/hello.phtml <?php if(isset($this->user)):?> welcome <?php echo $this->escape($this->user['firstname']); ?>, to the MyProject application. <?php else: ?> you need to login first. <a href="<?php echo $this->url(array('action' => 'login')); ?>">login</a> <?php endif; ?> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop And that is Authentication. if(Zend_Auth::getInstance()->hasIdentity()) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop What about? •Authorization (Zend_Acl) •Filter Input, Escape Output? •Input Validation (Zend_Validate) •Input filtering (Zend_Filter) •Dynamic Forms (Zend_Form) And all the other great stuff???!!!! Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop There is always next time! 1 hour courses, remember??? ;) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
Zend Framework 1.8 workshop Resources •http://blog.nickbelhomme.com •http://www.slideshare.net/weierophinney/zend-framework-workshop-dpc09 •http://en.wikipedia.org/wiki/Zend_Framework •http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models- are-Misunderstood-and-Unappreciated.html Source code of this workshop available at: http://blog.nickbelhomme.com/wp-content/uploads/workshopzf1.8.zip Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer

Zend Framework 1.8 workshop

  • 1.
    Zend Framework 1.8workshop Zend Framework Presentation Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 2.
    Zend Framework 1.8workshop About Me: PHP5 Zend Certified Engineer ZF Contributor since 2008 Freelance Consultant PHP Community active member Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 3.
    Zend Framework 1.8workshop Zend Framework • Full Stack Framework • Component Library Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 4.
    Zend Framework 1.8workshop How to Get It? • Grab it from the download page: http://framework.zend.com/download/latest • Through Subversion: http://framework.zend.com/svn/framework/standard/trunk/ Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 5.
    Zend Framework 1.8workshop How To Install? Add it to your php.ini include_path directive include_path = .:/usr/local/lib/php:/PathToZendFrameworkLibrary That’s it! Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 6.
    Zend Framework 1.8workshop Starting A New Project With Zend_Tool First requirements: • For *nix environments copy the zf.sh and zf.php from the ZF/bin To the same directory as your PHP binary • For Windows: •copy the zf.php and zf.bat to the same directory as your PHP binary •add the php path to your PATH environment Var: # Right-click My Computer and select |Properties. # Select the Environment page. # In the System Variables area, click on PATH. # Add the php path to the end in the format VALUE1;VALUE2;c:php # Click Apply. # The changes take effect immediately. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 7.
    Zend Framework 1.8workshop Creating the project “MyProject” $ zf create project /path/to/non-existent-dir-called-MyProject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 8.
    Zend Framework 1.8workshop Adding a “MyProject” vhost Testing environment httpd.conf or httpd-vhosts.conf: <VirtualHost *:80> ServerName MyProject DocumentRoot absolute-path-to-MyProject-folder ErrorLog logsMyProject-error.log CustomLog logsMyProject-access.log common <Directory /> Options FollowSymLinks AllowOverride All Order allow,deny Allow from all Satisfy all </Directory> </VirtualHost> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 9.
    Zend Framework 1.8workshop For windows: Add the following line to the /etc/host file 127.0.0.1 MyProject Restart apache, fire up the browser and go to: http://MyProject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 10.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 11.
    Zend Framework 1.8workshop Creating an Action + View Go to the MyProject directory and issue the following command to create the helloAction in the IndexController and corresponding view: $ zf create action hello index For a full list of commands simply visit: http://framework.zend.com/manual/en/zend.tool.project.create-a-project.html Or issue the command: $ zf --help Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 12.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 13.
    Zend Framework 1.8workshop Creating a Module and Controller $ zf create module admin $ zf create controller index 1 admin Note: Trying to create a controller that already exists in another Module might result in an error. Depending on the Zend_Tool Verion you have. The solution is to apply the patch from ZF Issue Tracker: http://framework.zend.com/issues/browse/ZF-6853 Note: If you applied this patch, make sure all controller names in the admin module start with Admin_ Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 14.
    Zend Framework 1.8workshop Registering the Module class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoloadModuleAdmin() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'Admin', 'basePath' => APPLICATION_PATH.'/modules/admin', )); return $autoloader; } } The method is called automatically by Zend_Application as it starts with _init. You can choose the remainder of the method name as you like. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 15.
    Zend Framework 1.8workshop Registering the Module myProject/application/configs/application.ini resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 16.
    Zend Framework 1.8workshop Setting up the Mysql Database Add to configs/application.ini [production] =============================== resources.db.adapter = PDO_MYSQL resources.db.params.host = localhost resources.db.params.username = nick resources.db.params.password = 12345 resources.db.params.dbname = myproject Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 17.
    Zend Framework 1.8workshop Create the database table CREATE TABLE users ( id int(11) NOT NULL auto_increment, username varchar(100) NOT NULL, pwd varchar(32) NOT NULL, firstname varchar(20) NOT NULL, PRIMARY KEY (id) ); Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 18.
    Zend Framework 1.8workshop Populate the table INSERT INTO users (username, pwd, firstname) VALUES ('NickBelhomme', md5('hello'), 'Nick'), ('ChanieNavez', md5('strong'), 'Chantal'), ('ElvisP', md5('presley'), 'Elvis'); Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 19.
    Zend Framework 1.8workshop The Model + DAO Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 20.
    Zend Framework 1.8workshop myProject/application/modules/admin/models/dao/Interface.php interface Admin_Model_Dao_Interface { public function find($id); public function insert($username, $pwd, $firstname); public function update($id, $username, $pwd, $firstname); public function delete($id); public function findAll(); } Common interface between all DAOs. Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 21.
    Zend Framework 1.8workshop myProject/application/modules/admin/models/dao/UserDB.php class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { protected $_name = 'users'; public function find($id) { Very Simple DAO $id = (int)$id; $row = $this->fetchRow('id = ' . $id); (Data Access Object) if (!$row) { throw new Exception("Count not find row $id"); } return $row; } public function insert($username, $pwd, $firstname) { $data = array( 'username' => $username, 'pwd' => $this->hashPassword($pwd), 'firstname' => $firstname, ); parent::insert($data); } //... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 22.
    Zend Framework 1.8workshop myProject/application/modules/admin/models/Dao/UserDB.php class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { //… public function update($id, $username, $pwd, $firstname) { $data = array( Very Simple DAO 'username' => $username, 'pwd' => $this->hashPassword($pwd), (Data Access Object) 'firstname' => $firstname, ); parent::update($data, 'id = '. (int)$id); } public function delete($id) { parent::delete('id =' . (int)$id); } public function findAll() { return $this->fetchAll(); } protected function hashPassword($pwd) { return md5($pwd); } } ?> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 23.
    Zend Framework 1.8workshop myProject/application/modules/admin/models/User.php class Admin_Model_User { const DAO_CLASS = 'Admin_Model_Dao_UserDB'; protected $dao; public function __construct() { $daoClassName = self::DAO_CLASS; $this->dao = new $daoClassName(); The Model } using the DAO. public function find($id) { return $this->dao->find($id); Easy Switching between } Different data resources public function insert($username, $pwd, $firstname) { return $this->dao->insert($username, $pwd, $firstname); } public function update($id, $username, $pwd, $firstname) { return $this->dao->update($id, $username, $pwd, $firstname); } // ... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 24.
    Zend Framework 1.8workshop myProject/application/modules/admin/models/User.php <?php class Admin_Model_User { The Model // ... using the DAO. public function delete($id) { Easy Switching between return $this->dao->delete($id); Different data resources } public function findAll() { return $this->dao->findAll(); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 25.
    Zend Framework 1.8workshop The Actions and Views Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 26.
    Zend Framework 1.8workshop Setting up the admin actions $ zf create action add index 1 admin $ zf create action edit index 1 admin $ zf create action delete index 1 admin Again if you are using a version of Zend_Tool which isn’t fully module Aware you can patch the Zend_Tool_Project_Provider_Action with if (self::hasResource($this->_loadedProfile, $name, $controllerName, $module)) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 27.
    Zend Framework 1.8workshop The Admin_IndexController indexAction public function indexAction() { $users = new Admin_Model_User(); $this->view->users = $users->findAll(); } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 28.
    Zend Framework 1.8workshop The corresponding index.phtml view script: myProject/application/modules/admin/views/scripts/index/index.phtml <p><a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'add'));?>">Add new user</a></p> <table> <tr> <th>Username</th> <th>First Name</th> <th>&nbsp;</th> </tr> <?php foreach($this->users as $user) : ?> <tr> <td><?php echo $this->escape($user->username);?></td> <td><?php echo $this->escape($user->firstname);?></td> <td> <a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'edit', 'id'=>$user->id));?>">Edit</a> <a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'delete', 'id'=>$user->id));?>">Delete</a> </td> </tr> <?php endforeach; ?> </table> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 29.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 30.
    Zend Framework 1.8workshop The Admin_IndexController deleteAction REST: public function deleteAction() irreversible { action use if ($this->getRequest()->isPost()) { POST not $del = $this->getRequest()->getPost('del'); GET if ($del == 'Yes') { $id = $this->getRequest()->getPost('id'); $users = new Admin_Model_User(); $users->delete($id); } $this->_redirect('/admin/'); } else { $id = $this->_getParam('id', 0); $users = new Admin_Model_User(); $this->view->user = $users->find($id); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 31.
    Zend Framework 1.8workshop The corresponding delete.phtml view script: myProject/application/modules/admin/views/scripts/index/delete.phtml <p>Are you sure that you want to delete '<?php echo $this->escape($this->user['username']); ?>' aka '<?php echo $this->escape($this->user['firstname']); ?>'? </p> <form action="<?php echo $this->url(array('action'=>'delete')); ?>" method="post"> <fieldset> <input type="hidden" name="id" value="<?php echo $this->escape($this->user['id']); ?>" /> <input type="submit" name="del" value="Yes" /> <input type="submit" name="del" value="No" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 32.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 33.
    Zend Framework 1.8workshop The Admin_IndexController addAction public function addAction() { if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'add') { $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $firstname = $this->getRequest()->getPost('firstname'); $users = new Admin_Model_User(); $users->insert($username, $pwd, $firstname); } $this->_redirect('/admin/'); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 34.
    Zend Framework 1.8workshop The corresponding add.phtml view script: myProject/application/modules/admin/views/scripts/index/add.phtml <h2>Add a new User</h2> <form action="<?php echo $this->url(array('action'=>'add')); ?>" method="post"> <fieldset> username: <input type="text" name="username"><br/> password: <input type="password" name="pwd"><br/> firstname: <input type="text" name="firstname"><br/> <input type="submit" name="action" value="add" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 35.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 36.
    Zend Framework 1.8workshop The Admin_IndexController editAction public function editAction() { if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'edit') { $id = $this->getRequest()->getPost('id'); $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $firstname = $this->getRequest()->getPost('firstname'); $users = new Admin_Model_User(); $users->update($username, $pwd, $firstname); } $this->_redirect('/admin/'); } else { $id = $this->_getParam('id', 0); $users = new Admin_Model_User(); $this->view->user = $users->find($id); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 37.
    Zend Framework 1.8workshop The corresponding edit.phtml view script: myProject/application/modules/admin/views/scripts/index/edit.phtml <h2>Edit User: <?php echo $this->escape($this->user->username); ?></h2> <form action="<?php echo $this->url(array('action'=>'edit')); ?>" method="post"> <fieldset> <input type="hidden" name="id" value="<?php echo $this->escape($this->user->id); ?>"> username: <input type="text" name="username" value="<?php echo $this->escape($this->user->username); ?>"><br/> password: <input type="password" name="pwd"><br/> firstname: <input type="text" name="firstname" value="<?php echo $this->escape($this->user->firstname); ?>"><br/> <input type="submit" name="action" value="edit" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 38.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 39.
    Zend Framework 1.8workshop Authentication: Zend_Auth Authentication is loosely defined as determining whether an entity actually is what it purports to be (i.e., identification), based on some set of credentials. http://framework.zend.com/manual/en/zend.auth.html#zend.auth.introduction Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 40.
    Zend Framework 1.8workshop Append the DAO and User Classes interface Admin_Model_Dao_Interface { // … public function findCredentials($username, $pwd); } class Admin_Model_Dao_UserDB extends Zend_Db_Table implements Admin_Model_Dao_Interface { // … public function findCredentials($username, $pwd) { $select = $this->select()->where('username = ?', $username) ->where('pwd = ?', $this->hashPassword($pwd)); $row = $this->fetchRow($select); if($row) { return $row; } return false; } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 41.
    Zend Framework 1.8workshop Append the DAO and User Classes class Admin_Model_User { // ... public function findCredentials($username, $password) { return $this->dao->findCredentials($username, $password); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 42.
    Zend Framework 1.8workshop Always use a vendor or project prefix And inform the autoloader of library prefixes Prepend the application bootstrap class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoloadModuleDefault() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'Myp', 'basePath' => dirname(__FILE__) )); return $autoloader; } //... } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 43.
    Zend Framework 1.8workshop Create an application model: The Auth Adapter myProject/application/models/AuthAdapter.php class Myp_Model_AuthAdapter implements Zend_Auth_Adapter_Interface { protected $username; protected $password; protected $user; public function __construct($username, $password) { $this->username = $username; $this->password = $password; $this->user = new Admin_Model_User(); } public function authenticate() { $match = $this->user->findCredentials($this->username, $this->password); if(!$match) { $result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); } else { $user = current($match); $result = new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user); } return $result; } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 44.
    Zend Framework 1.8workshop The IndexController loginAction $ zf create action login index 1 Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 45.
    Zend Framework 1.8workshop The IndexController loginAction public function loginAction() { $auth = Zend_Auth::getInstance(); if(Zend_Auth::getInstance()->hasIdentity()) { $this->_redirect('/index/hello'); } else if ($this->getRequest()->isPost()) { $action = $this->getRequest()->getPost('action'); if ($action == 'login') { $username = $this->getRequest()->getPost('username'); $pwd = $this->getRequest()->getPost('pwd'); $authAdapter = new Myp_Model_AuthAdapter($username, $pwd); $result = $auth->authenticate($authAdapter); if(!$result->isValid()) { switch ($result->getCode()) { case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID: $this->view->error = 'user credentials not found'; } } else { $this->_redirect('/index/hello'); } } } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 46.
    Zend Framework 1.8workshop The corresponding login.phtml view script: myProject/application/views/scripts/index/login.phtml <h2>Login</h2> <form action="<?php echo $this->url(array('action'=>'login')); ?>" method="post"> <fieldset> username: <input type="text" name="username"><br/> password: <input type="password" name="pwd"><br/> <div><?php echo $this->escape($this->error);?></div> <input type="submit" name="action" value="login" /> </fieldset> </form> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 47.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 48.
    Zend Framework 1.8workshop The IndexController helloAction public function helloAction() { if(Zend_Auth::getInstance()->hasIdentity()) { $this->view->user = Zend_Auth::getInstance()->getIdentity(); } } Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 49.
    Zend Framework 1.8workshop The corresponding hello.phtml view script: myProject/application/views/scripts/index/hello.phtml <?php if(isset($this->user)):?> welcome <?php echo $this->escape($this->user['firstname']); ?>, to the MyProject application. <?php else: ?> you need to login first. <a href="<?php echo $this->url(array('action' => 'login')); ?>">login</a> <?php endif; ?> Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 50.
    Zend Framework 1.8workshop Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 51.
    Zend Framework 1.8workshop And that is Authentication. if(Zend_Auth::getInstance()->hasIdentity()) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 52.
    Zend Framework 1.8workshop What about? •Authorization (Zend_Acl) •Filter Input, Escape Output? •Input Validation (Zend_Validate) •Input filtering (Zend_Filter) •Dynamic Forms (Zend_Form) And all the other great stuff???!!!! Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 53.
    Zend Framework 1.8workshop There is always next time! 1 hour courses, remember??? ;) Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer
  • 54.
    Zend Framework 1.8workshop Resources •http://blog.nickbelhomme.com •http://www.slideshare.net/weierophinney/zend-framework-workshop-dpc09 •http://en.wikipedia.org/wiki/Zend_Framework •http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models- are-Misunderstood-and-Unappreciated.html Source code of this workshop available at: http://blog.nickbelhomme.com/wp-content/uploads/workshopzf1.8.zip Nick Belhomme 17 June 2009 PHP5 Zend Certified Engineer