Professional Documents
Culture Documents
Or:
How I learned to stop worrying and love the
framework.
Part 1: Setting up
Preparing Zend Framework
●
Download ZF1.9
– svn co
http://framework.zend.com/svn/framework/standard/tags/release-1.9.1/library/Zend
●
Add directory containing Zend to php.ini as part of
the path.
●
Alternately, check out the framework into your pear
directory.
Preparing ZF Contd.
●
Check out bin (Zend Tool)
– svn co
http://framework.zend.com/svn/framework/standard/tags/release-1.9.1/
bin
●
Copy zf.php and zf.sh to a directory in your path
(/usr/bin)
●
Rename zf.sh to zf and make it executable
Using Zend_Tool to set up your project
●
Create a directory to house your projects
– mkdir projects
●
Enter directory
– cd projects
●
Create a project using the zf script
– zf create project {projectname}
Add project to apache
●
This can vary widely with OS and version, so
you're mostly on your own.
●
Make the DocumentRoot the “public” directory
within your {projectname} directory.
●
After reloading apache, you should be able to go to
the site you just set up and see the default zend
framework page!
Normal Application Setup
●
Normally we would have the domain set up to point
directly to the “public” directory
– Keeps php code from being directly accessible
– NO php should go in public folder unless it’s simple
and framework is overkill for it
●
Except for index.php
Directory Structure
●
/application
– application files…more in a moment
●
/library
– framework files ( /library/Zend )
– Extra classes/libraries used by the app
●
/public
– index.php, html/js/images/etc, anything that should
be directly accessible by the browser
●
/tests
– unit tests… another time maybe
Application Directory
●
Bootstrap.php
– Specific application – framework setup
●
configs
– Application .ini file (soon)
●
controllers
– Holds controller classes (gasp!)
●
models
– Holds model classes (double-gasp!)
●
views
– You get one guess what goes in here…
– Wrong, not classes, simple php+html files.
index.php
●
Prepares include path
●
Specifies application configuration
●
Load & run bootstrap
Create a database/table
●
Use whatever tools you're used to
CREATE TABLE `user` (
`user_id` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR( 255 ) NOT NULL ,
`email` VARCHAR( 128 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL ,
`salt` VARCHAR( 32 ) NOT NULL ,
`api_key` VARCHAR( 32 ) NOT NULL ,
`api_secret` VARCHAR( 32 ) NOT NULL ,
`user_type` TINYINT NOT NULL ,
PRIMARY KEY ( `user_id` ),
UNIQUE KEY `username` (`username`)
)
Add database to app config
●
Edit application/configs/application.ini
# Database
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "zfclass"
resources.db.params.password = "zfclass"
resources.db.params.dbname =
"zfclass_{yourname}"
resources.db.isDefaultTableAdapter = true
application.ini
●
Note that application.ini has multiple sections
– Production, Staging, Development
– Defined in .htaccess
– Can be used to specify different databases for
different environments
Configuring the layout
●
What's a layout?
– 2-step way of providing “overall” layout to your app
– View result html will be placed as “content” in
layout
– Layout can house dynamic links for header js, css,
etc
– Easily reached from controller or view.
Layout Contd.
●
Create directory application/layouts and
application/layouts/scripts
●
Add the following to your application.ini:
#layout
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
Module Layouts
●
We're making an admin module
●
Let's load a specific admin layout for it
application/plugins/ModuleLayout.php
if ($layout->getMvcEnabled())
{
switch($module) {
case 'default':
break;
default:
$layout->setLayoutPath(APPLICATION_PATH .
'/modules/' . $module . '/layouts/scripts');
break;
}
}
}
}
Enable the plugin
●
Edit application/Bootstrap.php
public function _initLayouts() {
Zend_Layout::startMvc();
$this->getPluginResource('frontcontroller')
->getFrontController()
->registerPlugin(new Plugin_ModuleLayout());
}
Application general layout
●
applications/layouts/scripts/layout.phtml
<?php echo $this->doctype() ?>
<html>
<head>
<?php echo $this->headTitle() ?>
<?php echo $this->headLink() ?>
<?php echo $this->headStyle() ?>
<?php echo $this->headScript() ?>
</head>
<body>
<?php echo $this->layout()->content ?>
</body>
</html>
Create a User model
●
application/models/DbTable/User.php
<?php
class Model_DbTable_User extends Zend_Db_Table
{
protected $_name = 'user';
protected $_primary = 'user_id';
User Model Cont'd
$data = array(
'username' => $username,
'email' => $email,
'password' => $hashed_pwd,
'salt' => $salt,
'user_type' => $user_type
);
return $this->insert($data);
}
User Model...
function updateUser($id, $email, $password=null, $user_type=1)
{
$where = array('user_id = ?' => (int)$id);
$data = array('email' => $email,'user_type'=>$user_type);
if ($password !== null){
// generate unique id (again) for the password salt
$salt = strtolower(uniqid(rand(), true));
$hashed_pwd = strtolower(md5($password . $salt));
$data['salt']=$salt;
$data['password']=$hashed_pwd;
}
$this->update($data, $where);
}
} // End class
Autoloader
●
Allow us to call our model class without having to
include it manually
– In application/Bootstrap.php
public function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(
array(
'namespace'=>'',
'basePath'=>APPLICATION_PATH
)
);
return $autoloader;
}
Database Profiling in Firebug!
●
Still in Bootstrap.php
public function _initDbprofile() {
if($this->getEnvironment() == 'development') {
$profiler = new Zend_Db_Profiler_Firebug('All DB
Queries');
$db = $this->getPluginResource('db');
$db = $db->getDbAdapter();
$profiler->setEnabled(true);
$db->setProfiler($profiler);
}
}
URL Structure
●
Defaults to Index controller & Index action
– /public/{controller}/{action}
– /public/{module}/{controller}/{action}
– /public/{controller} (assumes Index action)
– /public/{controller}/{action}/{key}/{value}/{key2}/
{value2}
– /public/admin/user/edit/user_id/3 (admin = module)
URL Routing
●
You can create your own url structures using
Zend_Controller_Router_*
– Many options
●
Static
●
Regex
●
Hostname
●
Chain
– http://framework.zend.com/manual/en/zend.controller.router.html
Create Admin Module
●
Use zf tool
– zf create module admin
●
Enable module in application.ini
– Add to [production] area
– resources.frontController.moduleDirectory
= APPLICATION_PATH “/modules”
● Copy application/layout/scripts/layout.phtml to
application/modules/admin/layouts/scripts/layout.phtml
Create User Controller
if($request->isPost()) {
if($form->isValid($request->getPost())) {
$data = $form->getValues();
$user = new Model_DbTable_User();
if($user->addUser(
$data['username'],
$data['email'],
$data['password'],2)) // 2 for admin
{
$this->view->message = 'User created';
} else {
$this->view->message = 'Something bad happened.';
}
}
}
$this->view->form = $form;
} // End function
Create View
application/modules/admin/views/scripts/user/createuser.php
<?php
if(isset($this->message)) {
?><h1><?=$this->message ?></h1><?php
}
?>
Create your new user.
<?php
$this->form->setAction($this->url());
echo $this->form;
?>
Create your user!
●
You should now be able to head to
http://{yoursite}/admin/user/createuser
●
Try it out!
Create a login action
●
Close the user controller file in your editor
● zf create action login user 1 admin
●
Open it back up and find the loginAction method
public function loginAction()
{
$form = new Zend_Form();
$form->setMethod('post');
$form->addElement('text','username', array(
'label' =>'User name',
'required'=>true,
'filters'=>array('StringTrim')
));
$form->addElement('password','password',array(
'label'=>'Password',
'required'=>true,
'filters'=>array('StringTrim')
));
$form->addElement('submit','submit',array(
'label'=>'Login',
'ignore'=>true
));
$request = $this->getRequest();
$data = $request->getPost();
if($request->isPost() && $form->isValid($data)) {
$u = new Model_DbTable_User();
$auth = new Zend_Auth_Adapter_DbTable($u->getAdapter()
,'user','username','password',
"MD5(CONCAT(?,salt)) AND user_type=2"
);
$auth->setIdentity($data['username'])->setCredential(
$data['password']
);
$mainauth = Zend_Auth::getInstance();
$result = $mainauth->authenticate($auth);
if($result->isValid()) {
$this->view->message = 'You are now logged in.';
} else {
$m = $result->getMessages();
$this->view->message = $m[0];
}
}
$this->view->form = $form;
}// End function
Create a logout action
●
Try the initial part yourself to create the action
method.
public function logoutAction() {
$auth=Zend_Auth::getInstance();
$auth->clearIdentity();
$this->_redirect('/admin/user/login');
}
Create a login “helper”
Edit application/modules/admin/views/helpers/LoginLink.php
<?php
class Admin_View_Helper_LoginLink extends Zend_View_Helper_Abstract {
public function loginLink() {
$auth = Zend_Auth::getInstance();
$front = Zend_Controller_Front::getInstance();
if($auth->hasIdentity()) {
$username = $auth->getIdentity();
return "Hello, $username [<a href='".$front->getBaseUrl().
"/admin/user/logout'>Logout</a>]";
} else {
return '[<a href="'.$front->getBaseUrl().
'/admin/user/login">Login</a>]';
}
}
}
Add login helper to layout
●
Edit application/modules/admin/layouts/scripts/layout.phtml
Add before echo content:
<div id="login">
<?php echo $this->loginLink();?>
</div>
This calls the LoginLink helper we created before.
Try it out: http://{yoursite}/admin/user/login
Enough for now
●
If we got this far at the meeting, I'm amazed.
●
If not, I can continue at the next meeting.