I have been trying to work with zendframework 1.8 and now with 1.9 . I have created a simple blog application using zend framework ( You may call it as a zend framework tutorial
. Changing name from "A simple Blog tutorial using Zend framework 1.9" to Zendframework tutorial : Developing a blog for some search engine optimization technique ) . When I say a blog application with zend framework , never expect it , something like wordpress . Its a simple application which can add posts , add comments , can fetch albums from Picasa now , which I developed to learn Zend framework .
As I am new to zendframework and MVC , I know there is errors and some are for my convienience I have placed as it is I am new to unit testing , so have not written any code for test data too . sorry . I know the drawbacks of this application and the database itself is not proper . But I am publishing it if this helps some one to understand Zend_ACL , Zend_Auth , Zend_Form etc. I have added a gallery to get the albums , photos from picasa using the Zend_Gdata API . Thinking to implement to add photos through admin side . Need to implement the feature in admin . Will do it if I get some time 
I have looked various blogs and some are upto date applications and some are not . I am using the Zend Toolkit as I love to work in command line rather than GUI . I have added the link to download the complete zend framework 1.9 blog application example . Feel free to grab the complete working example code of the zend framework 1.9 from github to which a link is given to the last of the document .
Development Environment :
1 ) LAMP or WAMP or MAMP
2 ) Zendframework 1.9 configured .
3 ) I am using eclipse , netbeans and zend studio i5 . If you are using zend studio i5 , there is no need to look the command line, many are already in it .
I hope you have configured the first two . Now lets move to command line to create project , controllers and actions . The dollar ( $ ) symbol represents the command prompt .
$ zf create project blog
This will create the zend framework directory structure > 1.8 . Change the directory . ie cd <projectname>
hari@hari-laptop:/var/www/blog$ zf show profile
ProjectDirectory
ProjectProfileFile
ApplicationDirectory
ConfigsDirectory
ApplicationConfigFile
ControllersDirectory
ControllerFile
ActionMethod
ControllerFile
ModelsDirectory
ViewsDirectory
ViewScriptsDirectory
ViewControllerScriptsDirectory
ViewScriptFile
ViewControllerScriptsDirectory
ViewScriptFile
ViewHelpersDirectory
BootstrapFile
LibraryDirectory
PublicDirectory
PublicIndexFile
HtaccessFile
TestsDirectory
TestPHPUnitConfigFile
TestApplicationDirectory
TestApplicationBootstrapFile
TestLibraryDirectory
TestLibraryBootstrapFile
This is how the directory structure will appear .
zf create controller posts
Creating a controller at //var/www/blog/application/controllers/PostsController.php
Creating an index action method in controller posts
Creating a view script for the index action method at //var/www/blog/application/views/scripts/posts/index.phtml
Creating a controller test file at //var/www/blog/tests/application/controllers/PostsControllerTest.php
Updating project profile '//var/www/blog/.zfproject.xml'
zf create action view posts
Creating an action named view inside controller at //var/www/blog/application/controllers/PostsController.php
Updating project profile '//var/www/blog/.zfproject.xml'
Creating a view script for the view action method at //var/www/blog/application/views/scripts/posts/view.phtml
Updating project profile '//var/www/blog/.zfproject.xml'
zf create action edit posts
Creating an action named edit inside controller at //var/www/blog/application/controllers/PostsController.php
Updating project profile '//var/www/blog/.zfproject.xml'
Creating a view script for the edit action method at //var/www/blog/application/views/scripts/posts/edit.phtml
Updating project profile '//var/www/blog/.zfproject.xml'
zf create action add posts
Creating an action named add inside controller at //var/www/blog/application/controllers/PostsController.php
Updating project profile '//var/www/blog/.zfproject.xml'
Creating a view script for the add action method at //var/www/blog/application/views/scripts/posts/add.phtml
Updating project profile '//var/www/blog/.zfproject.xml'
zf create action login index
Creating an action named login inside controller at //var/www/blog/application/controllers/IndexController.php
Updating project profile '//var/www/blog/.zfproject.xml'
Creating a view script for the login action method at //var/www/blog/application/views/scripts/index/login.phtml
Updating project profile '//var/www/blog/.zfproject.xml'
zf create action logout index
Creating an action named logout inside controller at //var/www/blog/application/controllers/IndexController.php
Updating project profile '//var/www/blog/.zfproject.xml'
Creating a view script for the logout action method at //var/www/blog/application/views/scripts/index/logout.phtml
Updating project profile '//var/www/blog/.zfproject.xml'
Create a database and add the tables users , comments and posts .
CREATE TABLE IF NOT EXISTS `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `Post_id` int(11) NOT NULL, `Description` varchar(300) NOT NULL, `Name` varchar(200) NOT NULL, `Email` varchar(250) NOT NULL, `Webpage` varchar(200) NOT NULL, `Postedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `posts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `Title` varchar(250) NOT NULL, `Description` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `Username` varchar(200) NOT NULL, `Password` varchar(250) NOT NULL, `Role` varchar(10) NOT NULL, `Name` varchar(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Add the code to Bootstrap.php so the other classes can be autoloaded . Same like __autoload() .
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH));
return $moduleLoader;
}
[ pagebreak ]
Part 2
Add the layout and db connection details in application/configs/application.ini . The complete code is kept below
[production] phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 includePaths.library = APPLICATION_PATH "/../library" bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts" resources.view[] = resources.db.adapter = PDO_MYSQL resources.db.params.host = localhost resources.db.params.username = root resources.db.params.password = resources.db.params.dbname = hari_zendblog [staging : production] [testing : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 [development : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1
Add application/layouts/scripts/layout.phtml file with the code below
<?php
echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Bloggers turns to developers</title>
<?php echo $this->headLink()->appendStylesheet('/quickstart/public/css/global.css') ?>
<?php echo $this->headLink()->prependStylesheet($this->baseUrl().'/css/main.css'); ?>
</head>
<body>
<div id="header" style="background-color: #EEEEEE; height: 30px;">
<div id="header-logo" style="float: left">
<b><a href="<?php echo $this->baseurl(); ?>">ZF Quickstart Application</a></b>
<a href="<?php
if( Zend_Auth::getInstance()->hasIdentity() ) {
$str = "/index/logout";
$log = "Logout";
} else {
$str = "/index/login";
$log = "Login";
}
echo $this->baseurl().$str; ?>"><?php echo $log; ?></a>
</div>
</div>
<div><?php echo $this->layout()->content ?></div>
</body>
</html>
You can insert sample datas through the phpmyadmin or what ever way you like . So we can show some posts in the front . Add the below code to indexActon of IndexController .
public function indexAction()
{
// action body
$posts = new Model_DbTable_Posts();
$result = $posts->getPosts();
/* The below line is for pagination */
$page = $this->_getParam('page',1);
$paginator = Zend_Paginator::factory($result);
$paginator->setItemCountPerPage(2);
/* Number of items in a page . I have kept 2 so you can easily see the pagination when there is 3 items inserted to posts table . */
$paginator->setCurrentPageNumber($page);
$this->view->paginator = $paginator;
}The complete code of IndexController.php is given below .
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
$posts = new Model_DbTable_Posts();
$result = $posts->getPosts();
$page = $this->_getParam('page',1);
$paginator = Zend_Paginator::factory($result);
$paginator->setItemCountPerPage(2);
$paginator->setCurrentPageNumber($page);
$this->view->paginator = $paginator;
}
public function loginAction()
{
$loginForm = new Form_Login();
$redirect = $this->getRequest()->getParam('redirect', 'index/index');
$loginForm->setAttrib('redirect', $redirect );
$auth = Zend_Auth::getInstance();
if(Zend_Auth::getInstance()->hasIdentity()) {
$this->_redirect('/index/hello');
} else if ($this->getRequest()->isPost()) {
if ( $loginForm->isValid($this->getRequest()->getPost()) ) {
$username = $this->getRequest()->getPost('username');
$pwd = $this->getRequest()->getPost('pass');
$authAdapter = new Model_AuthAdapter($username, $pwd);
$result = $auth->authenticate($authAdapter);
if(!$result->isValid()) {
switch ($result->getCode()) {
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
$this->view->errors = 'user credentials not found';
}
} else {
//Successfully logged in
$this->_redirect( $redirect );
}
}
}
$this->view->loginForm = $loginForm;
// $this->_redirect($redirectUrl);
}
public function logoutAction()
{
$auth = Zend_Auth::getInstance();
$auth->clearIdentity();
$this->_redirect('/');
}
}
Forgot to add the post controller . Added after seeing the comment . Thanks for notifying me .
<?php
class PostsController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
}
public function viewAction()
{
// action body
$postid = (int)$this->_getParam('id');
if( empty($postid) ) {
}
$post = new Model_DbTable_Posts();
$result = $post->getPost($postid);
$this->view->post = $result;
$commentsObj = new Model_DbTable_Comments();
$request = $this->getRequest();
$commentsForm = new Form_Comments();
/*
* Check the comment form has been posted
*/
if ($this->getRequest()->isPost()) {
if ($commentsForm->isValid($request->getPost())) {
$model = new Model_DbTable_Comments();
$model->saveComment($commentsForm->getValues());
$commentsForm->reset();
}
}
$data = array( 'id'=> $postid );
$commentsForm->populate( $data );
$this->view->commentsForm = $commentsForm;
$comments = $commentsObj->getComments($postid);
$this->view->comments = $comments;
$this->view->edit = '/posts/edit/id/'.$postid;
}
public function commentsAction()
{
// action body
}
public function addAction()
{
// action body
if(!Zend_Auth::getInstance()->hasIdentity()) {
$this->_redirect('index/index');
}
$acl = new Model_Acl();
$identity = Zend_Auth::getInstance()->getIdentity();
if( $acl->isAllowed( $identity['Role'] ,'posts','add') ) {
$request = $this->getRequest();
$postForm = new Form_Post();
if ($this->getRequest()->isPost()) {
if ($postForm->isValid($request->getPost())) {
$model = new Model_DbTable_Posts();
$model->savePost($postForm->getValues());
$this->_redirect('index/index');
}
}
$this->view->postForm = $postForm;
}
}
public function editAction()
{
// action body
$request = $this->getRequest();
$postid = (int)$request->getParam('id');
if(!Zend_Auth::getInstance()->hasIdentity()) {
$this->_redirect('posts/view/id/'.$postid);
}
$identity = Zend_Auth::getInstance()->getIdentity();
$acl = new Model_Acl();
if( $acl->isAllowed( $identity['Role'] ,'posts','edit') ) {
$postForm = new Form_Post();
$postModel = new Model_DbTable_Posts();
if ($this->getRequest()->isPost()) {
if ($postForm->isValid($request->getPost())) {
$postModel->updatePost($postForm->getValues());
$this->_redirect('posts/view/id/'.$postid);
}
} else {
$result = $postModel->getPost($postid);
$postForm->populate( $result );
}
$this->view->postForm = $postForm;
} else {
var_dump( $identity['Role'] );
//$this->_redirect('posts/view/id/'.$postid);
}
}
}
Now you need to create a connection to posts table so that we can do insertion , edit etc . Keep the file in application/Models/DbTable/Posts.php
<?php
class Model_DbTable_Posts extends Zend_Db_Table_Abstract
{
protected $_name = 'posts';
public function getPosts()
{
$orderby = array('id DESC');
$result = $this->fetchAll('1', $orderby );
return $result->toArray();
}
public function getPost( $id )
{
$id = (int)$id;
$row = $this->fetchRow('id = ' . $id);
if (!$row) {
throw new Exception("Count not find row $id");
}
return $row->toArray();
}
/*
* Add new posts
*/
public function savePost( $post )
{
$data = array( 'Title'=> $post['Title'],
'Description'=> $post['Description']);
$this->insert($data);
}
/*
* Update old posts
*/
public function updatePost( $post )
{
$data = array(
'id'=> $post['id'],
'Title'=> $post['Title'],
'Description'=> $post['Description']);
$where = 'id = '.$post['id'];
$this->update($data , $where );
}
}[ pagebreak ]
Create application/Models/DbTable/Users.php
<?php
class Model_DbTable_Users extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
public function findCredentials($username, $pwd)
{
$select = $this->select()->where('username = ?', $username)
->where('password = ?', $this->hashPassword($pwd));
$row = $this->fetchRow($select);
if($row) {
return $row;
}
return false;
}
protected function hashPassword($pwd)
{
return md5($pwd);
}
}Create application/Models/DbTable/Comments.php
<?php
class Model_DbTable_Comments extends Zend_Db_Table_Abstract
{
protected $_name = 'comments';
public function getComments( $postid )
{
$result = $this->fetchAll( "post_id = '$postid'" );
return $result->toArray();
}
public function saveComment( $commentForm )
{
$data = array('post_id' => $commentForm['id'] ,
'Description' => $commentForm['comment'],
'Name' => $commentForm['name'],
'Email' => $commentForm['email'],
'Webpage' => $commentForm['webpage'] );
$this->insert($data);
}
}Now lets create a login form in /application/forms/Login.php directory .
<?php
class Form_Login extends Zend_Form
{
public function __construct()
{
parent::__construct($options);
$this->setName('UserLogin');
$username = new Zend_Form_Element_Text('username');
$username->setLabel('User Name')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$pass = new Zend_Form_Element_Password('pass');
$pass->setLabel('Password')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$redirect = new Zend_Form_Element_Hidden('redirect');
$submit->setAttrib('id', 'submitbutton');
$this->addElements( array ( $username, $pass, $submit));
}
}Create a form for posting and commenting
application/forms/posts.php
<?php
class Form_Post extends Zend_Form
{
public function __construct()
{
parent::__construct($options);
$this->setName('Posts');
$id = new Zend_Form_Element_Hidden('id');
$title = new Zend_Form_Element_Text('Title');
$title->setLabel('Title')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$description = new Zend_Form_Element_Textarea('Description');
$description->setLabel('Description')
->setRequired(true)
->setAttrib('rows',20)
->setAttrib('cols',50)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', 'submitbutton');
$this->addElements( array( $id, $title, $description, $submit ));
}
}Create a comments form application/forms/Comments.php for adding comments
<?php
class Form_Comments extends Zend_Form
{
public function __construct()
{
$acl = new Model_Acl();
$identity = Zend_Auth::getInstance()->getIdentity();
/*
* Check whether they have permission to add comments
*/
if( Zend_Auth::getInstance()->hasIdentity()
&& $acl->isAllowed( $identity['role'] ,'comments','add') ) {
parent::__construct($options);
$this->setName('Comments');
$id = new Zend_Form_Element_Hidden('id');
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Your Name')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$webpage = new Zend_Form_Element_Text('webpage');
$webpage->setLabel('Webpage')
->setRequired(true)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$comment = new Zend_Form_Element_Textarea('comment');
$comment->setLabel('Comments')
->setRequired(true)
->setAttrib('rows',7)
->setAttrib('cols',30)
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('NotEmpty');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', 'submitbutton');
$this->addElements( array ($id, $name, $email, $webpage, $comment, $submit));
}
}
}Create application/Models/Acl.php
<?php
class Model_Acl extends Zend_Acl
{
public function __construct()
{
/*
* Add a new role called "guest"
* Guest can view contents of the site
*/
$this->addRole(new Zend_Acl_Role('guest'));
/*
* Add a role called user, which inherits from guest
* Users can post comments in site
*/
$this->addRole(new Zend_Acl_Role('user'), 'guest');
/*
* Add a role called blogger, which inherits from user
* Bloggers can post contents
*/
$this->addRole(new Zend_Acl_Role('blogger'), 'user');
/*
* Add a role for admin which inherits blogger
* With every privilages
*/
$this->addRole(new Zend_Acl_Role('admin'), 'blogger');
//Add a resource called posts
$this->add(new Zend_Acl_Resource('posts'));
//Add a resource called edit, which inherits posts
//$this->add(new Zend_Acl_Resource('edit'), 'posts');
//Add a resource called edit
//$this->add(new Zend_Acl_Resource('add'), 'posts');
//Finally, we want to allow guests to view pages
$this->allow('guest', 'posts', 'view');
// Bloggers can add, edit posts
$this->allow('blogger', 'posts', 'edit');
$this->allow('blogger', 'posts', 'add');
}
}Create application/Models/AuthAdapter.php
<?php
class 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 Model_DbTable_Users();
}
public function authenticate()
{
$match = $this->user->findCredentials($this->username, $this->password);
//var_dump($match);
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;
}
}Create application/views/helpers/BaseUrl.php
<?php
class Zend_View_Helper_BaseUrl {
function baseUrl() {
$fc = Zend_Controller_Front::getInstance();
return $fc->getBaseUrl();
}
}
?>Create application/views/helpers/LinkTo.php
<?php
class Zend_View_Helper_LinkTo
{
protected static $baseUrl = null;
public function linkTo($path)
{
if (self::$baseUrl === null) {
$request = Zend_Controller_Front::getInstance()->getRequest();
$root = '/' . trim($request->getBaseUrl(), '/');
if ($root == '/') {
$root = '';
}
self::$baseUrl = $root . '/';
}
return self::$baseUrl . ltrim($path, '/');
}
}[ pagebreak ]
Create application/views/helpers/LoggedInUser.php
<?php
class Zend_View_Helper_LoggedInUser
{
protected $_view;
function setView($view)
{
$this->_view = $view;
}
function loggedInUser()
{
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity())
{
$logoutUrl = $this->_view->linkTo('auth/logout');
$user = $auth->getIdentity();
$username = $this->_view->escape(ucfirst($user->username));
$string = 'Logged in as ' . $username . ' | <a href="' .
$logoutUrl . '">Log out</a>';
} else {
$loginUrl = $this->_view->linkTo('auth/identify');
$string = '<a href="'. $loginUrl . '">Log in</a>';
}
return $string;
}
}
Change the contents of application/views/scripts/index/index.phtml with
<?php if (count($this->paginator)): ?> <?php foreach ($this->paginator as $post ): ?> <div class="post"> <div class="title"><a href="<?php echo $this->baseUrl()."/posts/view/id/".$post['id']; ?>"><?php echo $this->escape($post['Title']); ?></a></div> <div class="description"><?php echo nl2br(substr( strip_tags( $post['Description']), 0 , 300)); ?></div> <div class="commentscount">Comments( count )</div> </div> <?php endforeach; ?> <?php endif; ?> <div class="pagination"><?php echo $this->paginationControl($this->paginator, 'Sliding', '/partials/my_pagination_control.phtml'); ?></div>
Change the contents of application/views/scripts/index/login.phtml with
<?php echo $this->errors; ?> <?php echo $this->loginForm; ?>
Change the contents of application/views/scripts/index/logout.phtml with
<div>Successfully Logged out</div>
Create application/views/scripts/partials/my_pagination_control.phtml with ( You can place partials in a different folder too . I forgot to change that )
<?php if ($this->pageCount): ?>
<div class="paginationControl">
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< Previous
</a> |
<?php else: ?>
<span class="disabled">< Previous</span> |
<?php endif; ?>
<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<a href="<?php echo $this->url(array('page' => $page)); ?>">
<?php echo $page; ?>
</a> |
<?php else: ?>
<?php echo $page; ?> |
<?php endif; ?>
<?php endforeach; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
Next >
</a>
<?php else: ?>
<span class="disabled">Next ></span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php
/*
* Drop down paginaton example
*/
/*
?>
<?php if ($this->pageCount): ?>
<select id="paginationControl" size="1">
<?php foreach ($this->pagesInRange as $page): ?>
<?php $selected = ($page == $this->current) ? ' selected="selected"' : ''; ?>
<option value="<?php
echo $this->url(array('page' => $page));?>"<?php echo $selected ?>>
<?php echo $page; ?>
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
</script>
<script type="text/javascript">
$('paginationControl').observe('change', function() {
window.location = this.options[this.selectedIndex].value;
})
</script>
*/?>Change application/views/scripts/posts/add.phtml with
<div><?php echo $this->postForm; ?></div>
Change application/views/scripts/posts/edit.phtml with
<h2>Edit Post</h2> <div><?php echo $this->postForm; ?></div>
Change application/views/scripts/posts/view.phtml with
<div class="title"><?php echo $this->post['Title']; ?></div> <div class="description"><?php echo $this->post['Description']; ?></div> <?php $acl = new Model_Acl(); $identity = Zend_Auth::getInstance()->getIdentity(); if( Zend_Auth::getInstance()->hasIdentity() && $acl->isAllowed( $identity['role'] ,'posts','edit') ) : ?> <div><a href="<?php echo $this->baseurl().$this->edit; ?>">Edit</a></div> <?php endif; ?> <div class="comments"> <?php if( count($this->comments) ) : ?> <?php foreach( $this->comments as $comment ) : ?> <div class="postedby"><a href="<?php echo $comment['Webpage']; ?>" ><?php echo $this->escape( $comment['Name'] ); ?></a> on <span><?php echo $this->escape( date( 'd-m-Y', strtotime($comment['Postedon']) ) ); ?></span></div> <div class="comment"><?php echo $this->escape( $comment['Description'] ); ?></div> <?php endforeach; ?> <?php else : ?> <div>No comments</div> <?php endif; ?> </div> <div class="newcomments"> <?php if( Zend_Auth::getInstance()->hasIdentity() ) : echo $this->commentsForm; else : ?>Login to Post comments<?php endif; ?> </div>
I hope I have not missed any when adding to the blog . If there is any erros do let me know . You can grab the working copy from git , that will be good if there is some errors . I have got many helps from more than 50 blogs . I have made a custom search engine for the zend framework learning too . In the earlier post I have posted .
Thanks and I hope you will enjoy my small blog, and If there is any confusing part let me know it. You can post comments rather than directly mailing to me . You can grab the piece of code from http://github.com/harikt/zendblog and don't be shy as Jon Lembord of http://zendcasts.com says . . Thanks for the wonderful facility provided by github and git .
I have also posted a new post for those who are looking for a module and admin layout. Do check it and get the files from http://www.harikt.com/content/base-files-start-your-zend-framework-project . This may be useful for you to start your zend framework project .


Comments
pretty helpful... thanks for
pretty helpful... thanks for the post...
login and logout are super
login and logout are super good, but I can not show me the post and comments
Thanks and can you make some more clear
@David Thanks for your comment . Many of the things are learned from different blog posts and zend itself .
For the post and comments can you make it clear . I didnot get you .
There are three type of users for now . user , blogger and admin . Have not added much options for admin . I want to work on it to make this some more beautiful .
The user can post comments . The blogger and admin can edit the posts . I hope this is what you was asking .
*I need to work more on it to make everything dynamic . Will update the code to github after completing it .
Password?
I can't find the login password!
You can reset it through PHPMyadmin
Usernames : user , blogger , admin .
Password : 123456
A small bug I am trying to make it clear
Sorry guys I found a small bug on line 7 of view.phtml . Please change the small letter 'u' to caps 'U' so will be baseUrl .
Fixed in the repository :) .
The mysql driver is not currently installed Error Message
Please help!!! I am stuck When I run the tutorial website using the ZendFramework, I am getting this error, "The mysql driver is not currently installed". There are no errors in my Apache error logs. I am using: Apache2.2 PHP5.3 latest ZendFramework version Below is the error I am getting: Error Message: The mysql driver is not currently installed Stack trace: #0 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Adapter\Pdo\Mysql.php(96): Zend_Db_Adapter_Pdo_Abstract->_connect() #1 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Adapter\Abstract.php(448): Zend_Db_Adapter_Pdo_Mysql->_connect() #2 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Adapter\Pdo\Abstract.php(238): Zend_Db_Adapter_Abstract->query('DESCRIBE `album...', Array) #3 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Adapter\Pdo\Mysql.php(156): Zend_Db_Adapter_Pdo_Abstract->query('DESCRIBE `album...') #4 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Abstract.php(814): Zend_Db_Adapter_Pdo_Mysql->describeTable('albums', NULL) #5 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Abstract.php(857): Zend_Db_Table_Abstract->_setupMetadata() #6 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Abstract.php(964): Zend_Db_Table_Abstract->_setupPrimaryKey() #7 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Select.php(100): Zend_Db_Table_Abstract->info() #8 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Select.php(78): Zend_Db_Table_Select->setTable(Object(Model_DbTable_Albums)) #9 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Abstract.php(1000): Zend_Db_Table_Select->__construct(Object(Model_DbTable_Albums)) #10 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Db\Table\Abstract.php(1286): Zend_Db_Table_Abstract->select() #11 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\application\controllers\IndexController.php(16): Zend_Db_Table_Abstract->fetchAll() #12 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Controller\Action.php(513): IndexController->indexAction() #13 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Controller\Dispatcher\Standard.php(289): Zend_Controller_Action->dispatch('indexAction') #14 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Controller\Front.php(946): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #15 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Application\Bootstrap\Bootstrap.php(77): Zend_Controller_Front->dispatch() #16 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\library\Zend\Application.php(346): Zend_Application_Bootstrap_Bootstrap->run() #17 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zf-tutorial\public\index.php(26): Zend_Application->run() #18 {main} Request Parameters: array ( 'controller' => 'index', 'action' => 'index', 'module' => 'default', ) Please help!!
Hi Cany
How did you configured the PHP , MySQL and Apache ?
I think you may have done seperately not like installing WAMP or XAMPP . If so refer the link http://in2.php.net/manual/en/book.pdo.php may need to configure it .
If you are using the WAMP you can activate the pdo driver . I don't exactly have in my machine to tell how you can do . A quick google search may help you in that.
Alternatively you can use XAMPP http://www.apachefriends.org/en/xampp.html which comes with the zend framework already in it . Hope this helps you .
How do i install PDO_MYSQL driver in windows
I installed PHP, Mysql, and Apache separately. I am using windows. I am getting this error, "The mysql driver is not currently installed". How do I installed and configure the PDO MYSQL Driver in windows. I already enable these and other extensions in my PHP.ini file; extension=php_pdo.dll extension=php_mysql.dll extension=php_mysqli.dll extension=php_pdo_mysql.dll extension=php_pdo_sqlite.dll Do I have to do something in phpForApach.ini file?? Help!!!
Have you restarted the Apache and Services after that ?
If you have done the steps ( http://in2.php.net/manual/en/pdo.installation.php ) I hope you have configured it and may not have restarted the apache .
Please consider looking the php.net mannual if you are still having trouble . I am not using Windows in my system . So I am really sorry to tell how it works . Consider installing XAMPP if you still have the trouble or move on to ubuntu or some other distro of GNU/Linux which can install and configure much more easily like XAMPP :). Debain based OS is much more popular and have lots of support .
Problems
Good Tutorial but i get this Error Notice: Undefined variable: options in E:\ab\cd\ef\gh\application\forms\Login.php on line 6
Consider initialising it
I didnot get any error like that . Which version of ZF are you using ?
Consider declaring the $options in the class and passing it to the parent constructor .
I get $option error
I have installed your application and it works fine. Now I am trying to implement the login method and get the eroor "C:\Program Files (x86)\Zend\Apache2\htdocs\Ulferik\application\forms\Login.php on line 6".
Can you tell me where this $option is suppose to come from? I have found it in several places but not where it is declared.
Thank's for sharing this tutorial whit us.
Ulferik
RE: Typo & What version of ZF?
Hey I am following this tutorial and was wondering what version of ZF this works with? Also, if you check line 12 in the application.ini listing, you will see that its actually the title for the list below! :) It makes it kinda difficult to know which file the listing is for!?
Thanks for your comment
Hi Chris ,
I didnot understand one thing from your comment Line 12 . I think its Line 21 what you was talking about . Its always a tedious job to post a big post like this . Even though I have revised it a lot , some errors like this may happen . I am sorry that the code and the text got wrapped . Have corrected the piece of code and Thanks for your comment to notify me .
You may have jumped to the code, and may have forget to read the title of the post itself . I am using ZF 1.9 now and it will works fine in 1.8 too as from 1.8 onwards is ZF command . I don't have used the ZF components below 1.8 .
If you have any trouble understanding any part of it feel free to grab the complete code from github which I have added a link to it . I am adding new features and updating the code . So the code you see in git may be slightly different than the code I have posted . The code in git is always a working example and I hope it will works fine in every system .
Zend_Form has a „init“
Zend_Form has a „init“ method, you don't need „__construct()“ and set the options again!
Great work
Its very helpful for a beginner..Thank you so much for your post.
Hi, First, thank-you very
Hi, First, thank-you very much for your tutorial. It was very helpfull. I´m doing an implementation of your code, but when I try to submit the form, I get the error below. I believe that the problem comes from the "$result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);" and "$result = new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);" in the AuthAdapter.php file. When I comment them, the error below doesn´t happen. Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)' in H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\library\Zend\Controller\Dispatcher\Standard.php:241 Stack trace: #0 H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\library\Zend\Controller\Front.php(936): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\library\Zend\Application\Bootstrap\Bootstrap.php(77): Zend_Controller_Front->dispatch() #2 H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\library\Zend\Application.php(303): Zend_Application_Bootstrap_Bootstrap->run() #3 H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\public\index.php(38): Zend_Application->run() #4 {main} thrown in H:\SERVER_ADER\WEBARCHITECT\HTDOCS\DP_INTRANET\PRODUCAO\library\Zend\Controller\Dispatcher\Standard.php on line 241 What am I doing wrong? Thanks in Advance.
One doubt ..
Hi ,
Thank you man .
For your problem it seems you don't have an error controller . Do you have one ?
How did you start your project ? With the zf create project itself ? Or something different ?
Just another doubt
Hey Hari,
I hope I´m not being a burden, but answering your question I did not create my project using zf.
Instead, I´ve made exactly as they explain at this tutorial http://framework.zend.com/docs/quickstart/create-your-project, but the structure itself I created by hand.
As soon as I created an Error controller, it worked perfectly. So my question is just one thing: why do I need an error controller in this case? Where in the project it would say that it is required, if there´s such parameter? application.ini ? Would it be the "phpSettings.display_startup_errors = 1" ?
Thanks a lot in advance.
hello, Thank you. It is very
hello, Thank you. It is very interesting.
wrong use of headlink()
Hello, first of all great tutorial, I am learning a lot from it. You have a little bug in the HEAD section. headlink() should be echoed only once. In your case the link tags for the css will be duplicated in the output. The correct version would be :
<?php $this->headLink()->appendStylesheet('/quickstart/public/css/global.css') ?> <?php $this->headLink()->prependStylesheet($this->baseUrl().'/css/main.css'); ?> <?php echo $this->headLink(); ?>Friendly regards.Hi, Just curious, why
Hi, Just curious, why does "Change the contents of application/views/scripts/index/logout.phtml with" Appear twice with 2 source code boxes? Is it an error?
Your post is really
Your post is really wonderful..thanks for posting...your post is very informative
Hi, Thanks so much for the
Hi, Thanks so much for the tutorial, the Auth and Acl was especially useful. However I'm confused by two mentions of: Change the contents of application/views/scripts/index/logout.phtml with is that an error?
Thanks for pointing out
Thanks edwardc for poiting me to it . Have corrected it now in the post.
Have a great day .
This may be just a tutorial
This may be just a tutorial for a simple application but the entire code is a mess. I know the Zend Framework is meant to give a modular approach to PHP development but like so many examples I see, this is openly absuive. It's nothing personal, as you are not alone - there is just so much rubbish out there and unfortunately you are only contributing to it.
Great post. I am pretty new
Great post. I am pretty new to zend but I just wanted to know how you retrive the parameters from the ini file and instantiate the database connection. Thank you
Thanks for your comments
Hi Noel Darlow ,
Thanks for your comments . I am new to ZF so there may be many errors . If you can tell me where I am wrong , I can correct it, else till you point me where I am wrong I am right :) . I published this for if there is someone who can learn something from me . I ll never tell I am completely correct as I know that some places I am wrong . So if you have developed something to learn for others please do share it , so others can learn from your great post .
Hi Arash ,
If you are looking to learn how the database connection works , the post by http://akrabat.com/zend-framework-tutorial/ is a good one . I started with quickstart then with the post by him and many other bloggers . In the file application/configs/application.ini
resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = <your username>
resources.db.params.password = <your password>
resources.db.params.dbname = <your db name>
This creates a DB connection .
Hi, Nice tutorials but i cant
Hi, Nice tutorials but i cant seem to view the post, the page itself, after login. it says an error occurred! page not found.
Can you tell more ?
Can you tell me more clearly . Like where you kept the files , the url , the url you got the error , the exact error thrown etc ?
If so I will try to tell where it causes the problem .
Thanks for reporting it too . But I don't find any problem at present for me .
Great post
I like how you explain and show what you did.
I have used this and helped me implement the Zend_ACL , Zend_Auth in my Sudoku site.
on my blog i also talk about zend frame work.
http://roninio.blogspot.com/
cheers and hope to see more of such tutorials.
Sudoku
Very good post, thanks a lot.
Very good post, thanks a lot.
Great tutorial
Thank you.
Happy moments in life
Yes, its really Happy to see the comments .
Some don't write anything even though it may have helped them . But its always some of the Happy moments to read and hear the comments if though it doesn't make a living .
Thank you to all who have commented and helped me to learn ZF and who have pulled me to learn ZF .
PostController
I don't see Post Controller in your post. It is on github, but it would be nice to be here
Seems many have not seen the mistake ;)
Thank you Nexik for notifying me.
Seems many have not seen the mistake ;) .
Hi, there are few bugs. In
Hi,
there are few bugs.
In application/forms/Comments.php on line 13 there should be
$identity['Role']instead of$identity['role']In application/Models/Acl.php you should add
$this->allow('blogger', 'comments', 'add');But still helpfull tut.
Thank you!
Jan
Thank you Jan Tlapák
Thank you for reporting it . First I just made the DB field as 'role' then later changed to 'Role' ie why the mistake . And the other I may have forget to add the role .
Great tutorial but...
great stuff but i have read loads of tutorials about acl and auth but never get shown how to assign a role to a user? how to do it properly, i have found it quite hard searching for acl and auth info for cakephp and zend framework that actually shows all steps...any help or websites would be great! :D thanks
Need to set dynamically
I too have spend a lot of time to understand how the Zend_Acl and Zend_Auth works .
It was really hard to understand atleast for me . But when I learned something , its a wonderful one .
You can set the roles dynamically to assign roles for users.
For eg ( from what i learned , may be wrong : if some one thinks I am wrong please let me know ) : if you are using dynamically you need a table for Roles with role_id , name .
And you can have a table for Resources : resource_id , resource_name , role_id .
Then you can assign these roles and resources . ie it .
Controllers are not passing
hi thanks for ur Blog regarding zend acl perfect blog to start with but i'm new to zend framework every thing is working fine with the index controller but its not taking to other controllers such as Gallery controller as well as the postcontrollers please help me out with some tips ASAP
Its showing error like
Not Found
The requested URL /harikt-zendblog-86859be/public/gallery was not found on this server.
Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.2 with Suhosin-Patch Server at localhost Port 80
please help me out with some tips ASAP
Thanks n Best wishes
File not found ?
With this minimum error "Not found" I guess either you don't have the controllers or the path going from index may be to different .
Have you configured htaccess .
Thanks!
Hi Hari,
I, too, am learning ZF, so I want to say thanks for two things.
1. Thanks for a great sample app. A nice level, not too trivial, not too difficult. Especially the Auth/ACL stuff. Very helpful.
2. Thanks for being so open about your experience. I appreciate your candor that: you are learning; you are doing the best you can; you might make some mistakes, either in code or in design; you welcome the feedback about mistakes and ways to do things better. Your app might not be the most polished out there, but I find your manner to be quite refreshing. It gives me a bit more confidence to simply put myself out there like you are doing.
It would be interesting perhaps to add Routing to the blog app. Perhaps not out of necessity - there is nothing wrong with the current urls of the form "controller/action/k1/v1/k2/v2". But it might be instructive to see an example of how to define routes, some ideas about where to define them, conventions for naming the plugin class and for placing the plugin file in the file-system. All that good stuff.
Again, thanks for an excellent contribution to the ZF community, especially for us noobs.
Cheers!
Hi, Firstly thanks for all
Hi,
Firstly thanks for all the open minded posts you wrote. I read most of them. I still could not figure out how to run this application. I can run the public/index page which lists the items from the database but when i click on an item for detail - on its title it gives me these errors
--->
An error occurred
message ?>
Exception information:
Message: exception->getMessage() ?>
Stack trace:
exception->getTraceAsString() ?>
Request Parameters:
request->getParams()) ?>
<----
I can see the pagination on the first page of public but when i click on anything else its gone. Can you help me out. Thanks. Can it be that your application here is a bit different than on github code.
Thanks,
Mahmood
I didnot know the reason ie why
Hi Mahmood,
Actually I was not able to figure your problem . ie why not replied to it . Have you tried quickstart or any such applications before this ?( Hope you have done it and has no issues :) )
Have you tried the code in github and still facing the same issue ?
Some of the things I can suggest is looking the url and look the controller, action and get request parameters . May be some errors in it .
Thanks
Hi, it is really useful stuff
Hi, it is really useful stuff for beginners, thanks.
I found a little bug in your code:
application/controllers/IndexController in loginAction you have line
$this->view->errors = 'user credentials not found';and in login view there is
<?php echo $this->error; ?>so you should change 'error' to 'errors' in login.phtml file
Thanks Marek
Thanks dude .
hi, i am getting application
hi,
i am getting application error. please advice
Hi Hari, I am not able to
Hi Hari,
I am not able to download code snippet from the url
http://github.com/harikt/zendblog
Thanks,
Hardik
Pages