Advanced Zend_Form usage Invisible to the eye

Zend_Form is the component of Zend Framework that I enjoy the most: it implements reusable forms and inputs as classes and objects, with automatic reinsertion of values during server-side validation; validation that is shared among all the instances and is provided out of the box by Zend_Validate. If you have ever duplicated a form for editing and adding a new entity to your application, or have felt the pain to manually populate text inputs, you now know being able to reuse a form is a killer feature and in fact many php frameworks provide a form library.
Today I have gathered from my experience some know-how I have learnt while taking the Zend_Form component to its limits.

Ignored elements
Every Zend_Form_Element instance has a method setIgnore(). Also you can pass a flag ‘ignore’ equal to True in the $options array parameter in the constructor, respecting the framework convention, to obtain the same result.
The purpose of this option is to exclude the value assumed by this input from the result returned by getValues(), even if you pass to isValid() the entire POST request (which contains a value for this specific element since it was present on the client side and filled for other purposes). This option comes handy when using Zend_Form_Element_Captcha or Zend_Form_Element_Submit.

$button = new Zend_Form_Element_Submit('submitButton', array('ignore' => true, 'label' => 'Send!'));

Decorators
Both elements and forms (descendants of Zend_Form_Element and Zend_Form respectively) support a stack of decorators used for rendering themselves. The first decorator, ViewHelper, calls a view helper defined by the element or form to produce the basic html and this string result is passed to the subsequent decorators in a chain, each of them working on the previous one output.
This design is an unconventional implementation of the Decorator Pattern, and allow decorators to be reused troughout every kind of form element. The standard decorators cover a vast variety of cases and allow you to produce custom html for your forms. You can even write your own ones by extending Zend_Form_Decorator_Abstract.

$element = new Zend_Form_Element_Text();
$element->addDecorators(array(
    'ViewHelper',
    'Errors',
    array('Description', array('tag' => 'div', 'class' => 'description')),
    array('HtmlTag', array('tag' => 'dd')),
    array('Label', array('tag' => 'dt'))
));

Subforms
Subforms are instances of Zend_Form which are incorporated in a parent form, providing reusability of logic groups of elements. Generally I prefer to use Zend_Form instances with the adequate decorators instead of Zend_Form_SubForm ones, which is also a subclass of it.
Not only you can reutilize forms as fieldsets of a bigger one, but you can encanpsulate the values of this subform’s elements transforming the main result in a recursive array.

        $form->setDecorators(array(
                    'FormElements',
                    array('HtmlTag', array('tag' => 'dl')),
                    'FieldSet');
$form->setElementsBelongTo('my_key'); // call this after all elements have already been inserted
// ...
if ($form->isValid($postData)) {
    $values = $form->getValues();
    // $values['my_key'] is an array containing the values of subform's elements
}

Dojo
The Zend_Dojo component contains form elements which extends or substitutes the standard Zend_Form ones, augmenting their capabilities with the Dojo Toolkit widgets.
To set up the right plugin path, simply make your form a subclass of Zend_Dojo_Form instead of Zend_Form, or pass the form instance to the Zend_Dojo::enableForm() static method. Also make sure you are outputting the $this->dojo() view helper in your layout or view script, to print the mandatory script tags.
For instance you can create a real-time filtered select:

$element = $form->createElement('FilteringSelect', 'nameOfelement');
$element->setMultiOptions(array('yellow' => 'Light Yellow', 'blue'   => 'Blue', ...);

This type of elements can also work with a remote data store, just in case you have one million select options and you want to lazy load them. There is even a configurable WYSIWYG editor in the dojo component, available via CDN without having to upload a single js file to your server.

Captchas
With Zend_Form_Element_Captcha, you can create different types of captcha to insert in your forms for the sake of stopping spammers bots to submit them. A captcha not correctly answered will invalidate the form result during the call to Zend_form::isValid(). Though you can specify ascii art as captchas and even on-the-fly generated images, this is the fastest way to include a captcha in a form:

$element = new Zend_Form_Element_Captcha();
$element->setCaptcha('Dumb')
              ->setIgnore(true);

You may be worried about how to automatically test the submit of a form which contains a captcha, since it is built with the purpose of avoid being answered by a machine like your test runner. However, there is a trick that accesses session variables to find the right answer for the captcha during the test method run.

I hope this quick panoramic of functionalities satisfies you. Zend_Form is a complex component but the learning curve is really worth the benefits it gives to your applications. You can even use it in isolation, without the ZF Mvc stack, since the only requirement is a Zend_View object that every element and form instance needs to render itself.
With Zend_Dojo_Form not even uploading javascript plugins is needed for improving the user experience: dojo is loaded remotely via Google or Aol servers. Zend_Form is a complete open source, liberally licensed, object-oriented solution for managing forms and inputs, the most powerful choice I have ever seen in php and one of the top components of Zend Framework.

Basic AJAX Example for Zend Framework | Squico

I recently needed to port some existing php code which used Ajax over to the Zend Framework. While there are several tutorials out there with lots of details, I didn’t find a simple example that would just get me started with how to work Ajax calls into the MVC framework architecture. Eventually, I figured things out by referring to several different tutorials and doing a good amount of Googling. I decided it might be useful to have a very simple example of porting an existing Ajax app to the Zend Framework.

Warning: this app is very simplistic … it is solely designed to show minimum ‘hello world’ type of Ajax functionality, and how to fit that into the Zend Framework. There are plenty of more advanced tutorials out there, but this can get you started and show you how to make an Ajax call and respond to it with a Zend controller action. To simplify things even further, I’m using the prototype Javascript library, which makes life a lot easier by, among other things, providing a cross-browser means of creating and sending Ajax requests.

Versions: I wrote this against Prototype 1.5.1.1 and Zend Framework 1.0.1 (now updated for ZF v. 1.5)

Assumptions: I assume this is running on Apache, as I will include some .htaccess files to deal with url rewriting in the Zend version. I assume you’re familiar with Ajax … if not, there are tons of tutorials out there available via Google. I also assume you have some basic familiarity with the Zend Framework. If not, I recommend Rob Allen’s great introductory tutorial. And if you need to run the tutorial on Oracle instead of Mysql, well, of course, I recommend this blog post;)

If you want the code, download the zip file, which contains both the Zend app (ajax101_zend directory) and the non-Zend app (ajax101 directory). Both directories also contain the version of prototype that I used. Earlier versions of the download also contained Zend Framework v1.0.1, but I removed this at the same time I updated the code to work with ZF v1.5. I wrote the code on Windows, so be aware of that if you have any problems with the files on other platforms …

Okay, on to the code. First, the non-Zend version. I created three files (index.html, boxy.css, and server_script.php) and put them in the same directory on my webserver, along with the prototype.js file. Here’s the index.html, with a couple of Javascript functions to handle the Ajax call and response (we’ll factor those out to a separate file in the Zend version):

————————————————————————————

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title>Ajax 101</title>
<link rel=”stylesheet” href=”boxy.css”>
<script type=”text/javascript” src=”prototype.js”></script>

<script language=’javascript’>

//handle the Ajax response …
function handleResponse(transport)
{
$(’hello’).innerHTML = transport.responseText;
}

//creates a prototype Ajax object, sends a request, and registers the callback function ‘handleResponse’
function callAjax(s)
{
var myAjax = new Ajax.Request(’server_script.php’,
{method: ‘get’, parameters: {state: s},
onComplete: handleResponse});
}

</script>

</head>
<body>
<p>
<span id=’hover_span’ onmouseover=”callAjax(’do’)” onmouseout=”callAjax(’undo’)”> <b>Hover here to trigger Ajax call:</b> </span>
</p>

<span id=’hello’> boring pre-Ajax-call text … </span>

</body>
</html>

————————————————————————————

Here’s the simple stylesheet used:

————————————————————————————

#hover_span
{
font-size: 12pt;
}

#hover_span:hover
{
cursor: crosshair;
background-color: yellow;
}

————————————————————————————

And here is the php server-side script which simply echoes some text back depending on the ’state’ parameter passed in the request:

————————————————————————————

<?php

$state = $_REQUEST[‘state’];

if ($state == ‘do’)
{
echo ‘<h1>exciting text retrieved from server!</h1>’;
}
else if ($state == ‘undo’)
{
echo ‘reset to boring …’;
}
else
{
echo ‘unknown state parameter passed to server!!’;
}

————————————————————————————

So, if you trace through what happens, when you hover over the text at the top of the index.html page, Hover here to trigger Ajax call, the mouseover event fires, sending an Ajax request with a ’state’ parameter of ‘do’ to the server. The server responds with the text exciting text retrieved from server! enclosed in h1 tags. When the mouse leaves the text at the top of the page, the mouseout event fires, sending an Ajax request with a ’state’ parameter of ‘undo’ to the server, which responds with the text reset to boring …

Pretty simple, nothing exciting or difficult … just a super-basic example of doing something with Ajax. Okay, so how do we move that into the Zend Framework?

The first thing that is going to change is the directory structure. As I mentioned, for the simple ‘Ajax 101′ app, I just put all the files in the same directory on my webserver. For Zend, I’m going to need to separate things out, which is a good thing. I’m following a typical Zend Framework directory structure here, so it will look like this:

docroot
–app
—-controllers
—-views
——scripts
–library
–public
—-scripts
—-styles

You may have noticed the lack of a model directory. That’s because in this very simplistic example, there are no models.

Okay, so what next? Well, first we need to install the framework. Download the latest version of the framework (I used v1.5.1 in the latest work I did on this). Once you’ve extracted it, copy the library/Zend directory to your docroot/library directory.

Next we need a bootstrap file for the framework. This will be pretty simple for this example, since we’re not doing much, so we won’t be loading a bunch of Zend classes, setting up database connections, etc. All we’ll really be doing is some basic settings, like error reporting, include paths, and setting up the controller. This is in the index.php file in the docroot:

————————————————————————————

<?php

error_reporting(E_ALL | E_STRICT);
date_default_timezone_set(’America/Chicago’);

set_include_path(’.’ . PATH_SEPARATOR . ‘./library’ . PATH_SEPARATOR . get_include_path());

include “Zend/Loader.php”;

//setup controller
Zend_Loader::loadClass(’Zend_Controller_Front’);
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory(’./app/controllers’);

//run
$frontController->dispatch();

————————————————————————————

Next we’ll set up a simple controller, and put the code that was in the server_script.php file inside a controller action. This is the IndexController.php file in the docroot/app/controllers directory:

————————————————————————————

<?php

class IndexController extends Zend_Controller_Action
{
function init()
{
$this->initView();
$this->view->baseUrl = $this->_request->getBaseUrl();
Zend_Loader::loadClass(’Zend_Debug’);
}

function indexAction()
{
//echo “<p>in IndexController::indexAction()</p>”;
$this->view->title = “Zend Ajax 101″;
}

function getDataAction()
{
$this->_helper->viewRenderer->setNoRender();

$state = $_REQUEST[‘state’];

if ($state == ‘do’)
{
echo ‘<h1>exciting text retrieved from server!</h1>’;
}
else if ($state == ‘undo’)
{
echo ‘reset to boring …’;
}
else
{
echo ‘unknown state parameter passed to server!!’;
}
}
}

————————————————————————————

The only difference between our initial php script and the code in the getDataAction() method is the crucial first line:

$this->_helper->viewRenderer->setNoRender();

This tells Zend that this particular action method is not going to result in the re-rendering of the view.

Next, here’s our index.phtml, which is just slightly altered from the index.html of the non-Zend app, and is saved in the docroot/app/views/scripts/index directory:

————————————————————————————

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<head>
<title><?php echo $this->title ?></title>
<link rel=”stylesheet” href=”public/styles/boxy.css”>
<script type=”text/javascript” src=”public/scripts/prototype.js”></script>
<script type=”text/javascript” src=”public/scripts/ajax_funcs.js”></script>

</head>
<body>
<p>
<span id=’hover_span’ onmouseover=”callAjax(’do’)” onmouseout=”callAjax(’undo’)”> <b>Hover here to trigger Ajax call:</b> </span>
</p>

<span id=’hello’> boring pre-Ajax-call text … </span>

</body>
</html>

————————————————————————————

You’ll notice that we’ve factored the javascript functions out to a separate file, as I said we would do. Here is that file, docroot/public/scripts/ajax_funcs.js:

————————————————————————————

//handle the Ajax response …
function handleResponse(transport)
{
$(’hello’).innerHTML = transport.responseText;
}

//creates a prototype Ajax object, sends a request, and registers the callback function ‘handleResponse’
function callAjax(s)
{

//remember to put a word separator between elements of the camelcase action name, per the ZF manual:
var myAjax = new Ajax.Request(’index/get-data’,
{method: ‘get’, parameters: {state: s},
onComplete: handleResponse});
}

————————————————————————————

The stylesheet is the same as the previous app, so I won’t repeat it here. Just note that it is saved in docroot/public/styles.

Finally, there are some .htaccess files we’ll need, since we need to handle rewrite rules and exceptions. In the docroot, here’s what you need in your .htaccess:

————————————————————————————

RewriteEngine on
RewriteCond %{REQUEST_URI} !/public.*

RewriteRule .* index.php

php_flag magic_quotes_gpc off
php_flag register_globals off

————————————————————————————

And for the docroot/public directory:

————————————————————————————

RewriteEngine off

————————————————————————————

Okay, that’s it! If all has gone well, you should see the same behavior in the Zend Framework version as you did in the non-Zend one. Hopefully, this will give you a jumping off point for more advanced Ajax work with the Zend Framework.

Zend FrameWork: [fw-db] Something fishy with adapters in Zend_Db

OOP design of the adapters mecanism in Zend_Db. Since Zend_Db is not using
interfaces, we have Zend_Db_Adapter_Pdo_Ibm_Db2 which derives or
implements… nothing. We then have Zend_Db_Adapter_Pdo_Ibm which internally
creates a Zend_Db_Adapter_Pdo_Ibm_Db2 and wraps the methods, but doesn’t
really enforce any interface or base class. Zend_Db_Adapter_Pdo_Ibm is an
adapter which wraps fake adapters… and we can’t use
Zend_Db_Adapter_Pdo_Ibm_Db2 directly, since it doesn’t derive from anything
so we can’t pass it to Zend_Db_Table for example. We also can’t reuse code
or implement an interface in Zend_Db_Adapter_Pdo_Ibm_Db2.

I hope that Zend_Db interfaces will be added and enforced in Zend Framework
2.0, or we’ll be stuck with this frankensteinized OOP 😉

View this message in context: http://www.nabble.com/Something-fishy-with-adapters-in-Zend_Db-tp25388420p25388420.html
Sent from the Zend DB mailing list archive at Nabble.com.

WebDevNoobs » Blog Archive » Easy PHP Websites with the Zend Framework

Recently revised for Zend Framework 1.9!

Combining over 300 pages of instruction with access to almost 5 hours of online video, Easy PHP Websites with the Zend Framework is the ultimate learning guide to building powerful websites with the world’s most popular Web development language.

Written by popular PHP author W. Jason Gilmore, you’ll master the Zend Framework by following along with the creation of a community website for video gamers. Among other topics, you’ll learn how to:

* Manage Web Forms: Create web forms, and validate user-provided data

* Send E-mails: Send unformatted and HTML e-mails through your website

* Create Community Features: Register users, manage logins, and recover forgotten passwords

* Extend Your Network: Integrate with popular online services such as Google Maps, Amazon Web Services, the Facebook Platform, and PayPal

All readers are provided with access to the EasyPHPWebsites.com website, including access to almost five hours of online video, direct communication with the author, forum access, and a regularly updated DRM-Free PDF!

About the Author

W. Jason Gilmore is founder of a W.J. Gilmore, LLC, a publishing and consulting firm based out of Columbus, Ohio. Formerly Apress’ open source editor, Jason fostered the development of more than 60 books, along the way helping to transform their open source line into one of the industry’s most respected publishing programs. He’s the author of several books, including the best-selling “Beginning PHP and MySQL: From Novice to Professional”(currently in its third edition), “Beginning PHP and PostgreSQL: From Novice to Professional”, and “Beginning PHP and Oracle: From Novice to Professional”.

Jason is cofounder of CodeMash, a nonprofit organization tasked with hosting an annual namesake developer’s conference, and was a member of the 2008 MySQL Conference speaker selection board.

Jason has over 100 articles to his credit within prominent publications such as Developer.com, Linux Magazine, and TechTarget.