Category: Classes

Michael Andrew Davidson writes; So you have discovered ZendServerGateway and you are like, “Wow, this makes web services easy”. However, you quickly discover that there is a little magic behind the scenes, and that this add-on works best within the context of Zend Server 6. That can be a little frustrating, especially if you or your organization does not use Zend Server 6. Never fear, there is a way around this “implied” requirement. In just a moment I will walk the reader through setting up the embedded PHP 5.4 webserver to utilize the ZendServerGateway. All the steps should easily translate to whatever environment you use for serving your PHP pages. I am going to assume a Window environment for development.

Rob Allen as usual writes useful stuff; One thing that is different between Zend_Config_Xml and Zend_Config_Ini is that with Zend_Config_Xml you can pass in an XML string as the first parameter of the constructor and it will work. This doesn’t work with Zend_Config_Ini as we use parse_ini_file() under the hood.

With PHP 5.3 however there is is a new function called parse_ini_string() which will allow us to load arbitrary ini string into Zend_Config objects. This can’t go into Zend Framework 1 though due to our PHP 5.2.4 minimum version requirement.

As I needed this for a project, I extended Zend_Config_Ini to support this feature, which means simply overloading a single method

Rob Allen writes; A while ago I needed to ask a user for their date of birth on a Zend_Form. The design showed three separate select elements to do this:

Screen shot of a 3 select boxes for a date on a form

A little bit of googling found this site http://codecaine.co.za/posts/compound-elements-with-zend-form which has not unfortunately disappeared, so the code in this article owes a lot of the author of that article.

It turns out to be remarkably simple to create a single Zend Form element that is rendered as multiple form elements. We create an element object and a view helper object and we’re done. Usage then looks like:
< ?php
class Application_Form_Details extends Zend_Form
{
public function init()
{
$this->addPrefixPath('App_Form', 'App/Form/');

Obviously, this form lives in application/forms/Detail.php and is rendered as usual in a view script. In our form definition, we have added an element called ‘date’ and with the addition of the addPrefixPath call have told the form that in addition to using the standard Zend Framework form elements, also look in library/App/Form. (Incidentally, we can also now override any supplied form element by simply dropping a replacement into the libraryApp/Form folder.)

The date form element lives in library/App/Form/Element/Date.php as Zend_Form knows to look in a subfolder for App/Form called Elements for any element objects and will look in the Decorator/ sub folder for decorator objects.

I had a twitter/IRC exchange yesterday with Andries Seutens and Nick Belhomme regarding applications that include widgets within their layout. During the exchange, I told Andriess not to use the action() view helper, and both Andriess and Nick then asked how to implement widgets if they shouldn’t use that helper. While I ended up having an IRC exchange with Nick to give him a general idea on how to accomplish the task, I decided a longer writeup was in order.

Background

The situation all started when Andries tweeted asking about what he considered some mis-behavior on the part of the action() view helper — a situation that turned out not to be an issue, per se, but more a case of bad architecture within Zend Framework. His assumption was that calling action() would fire off another circuit of the front controller’s dispatch loop — which would mean he could rely on plugins he’d established to fire. However, action() does nothing of the sort. It instead pulls the dispatcher from the front controller, and manually calls dispatch() on a new action. As such, action helpers will trigger, but no front controller plugins will. Additionally, if a redirect or “forward” condition is detected, it simply returns an empty string.

The helper was done this way because Zend Framework does not render views a single time — it instead renders after each action, and accumulates views to render in the layout. If we were accumulating view variables and rendering once, and if we were using a finite state machine of some sort, we could probably operate the way one would expect — within the dispatch loop. Since we don’t, any solution around looping over actions (such as the ActionStack action helper/front controller plugin) or rendering the content of executing an action will be a hack. Note: ZF2’s MVC layer may make this possible… though still not necessarily recommended.

There are other reasons to avoid the use of these solutions, though. If you are invoking additional controller actions in order to help populate your view, you’re likely putting domain logic into your controllers. Think about it. The controller should only be responsible for taking the input, funneling it to the correct model or models, and then passing information on to the views

With that in mind, here’s the approach I recommended to Nick and Andries.

The Secret Weapon: Action Helpers

I’ve blogged about actionhelpers before. They’re a built-in mechanism in Zend Framework to allow you to extend your action controllers in a way that uses composition instead of inheritance.

One approach to widgets for Zend Framework makes use of these. Consider the following “user” module:

eschrader writes; So I was sitting here thinking to myself “This is Friday and I’m not getting much of anything done. Maybe I should write another Friday Framework Highlight.” I figured that it was a good idea so I pondered what I should write. I came up blank and so I asked Matthew Weier O’Phinney. “Multiple writers for Zend_Log,” he said. I agreed.

If you were not aware, Zend_Log provides facilities for writing to multiple logs through the same log instance. Additionally, you can do this via configuration options when using a Zend_Applicatin resource plugin. Together those make for very powerful logging mechanisms. “How?” you ask? It’s really easy. Take your application.ini file, which you use to configure your Zend_Application instance, and make it look something like this. I’ll highlight the pertinent parts

What this does is say that “in production, log warnings and above to the log file, but in development, log debug to the log file AND send the log items to FirePHP.” Then, in our index controller we put this:

In production we wouldn’t get anything since this code would filter out debug logging, due to the resources.log.stream.filterParams.priority setting in the production section in application.ini. Simple. Done.

e_schrade wrote a neat way of doing things in the service layer; Let’s take a quick look at something that’s kind of neat in Zend Framework. I’ve been doing some work with Adobe on some articles and one of them was on working with mobile clients with Flash. Well, me being the masochist I did more. What I did was write an example that worked as a full website, an Ajax website, a Flash service and an XML-RPC service.

Looks like a lot, right? Actually there’s not much there. Here’s the logic flow.

Is it an XMLHTTP Request and is it a POST? Create the Json server

Is it an AMF request? Create the AMF server

Is it an XmlRpc request? Create the XmlRpc server

Is it an XMLHTTP Request and is it a GET? Create the Service Map (for JSON-RPC 2.0)

If a service handler has been created add all of the application’s mappers, attach the service handler to the request and redirect to the service action.

And with that you have an application that can serve content for multiple different types of service with almost no effort on your part. At least.. if you copy and paste this code.

This integration requires the latest Doctrine version 1.2.2 to work completely

Get it!

SVN Export or Externals

Github offers SVN Read support for a while now, you can either use svn export or svn:externals to include ZFDoctrine into your project or into your PHP Include Path.svn checkout http://svn.github.com/beberlei/zf-doctrine.git

It uses the application.ini key of resources.db.table_prefix as I couldn’t think of a better one 🙂 and then uses that for the schema_version table’s name and also makes it available in your change objects.

For example, if application.ini contains resources.db.table_prefix = “myapp”, then the manager will create the table myapp_schema_version to store the current version of the schema. In your change classes, you can then do this:

which will create a table called myapp_users. Note that you are responsible for using the prefix property as the change classes cannot enforce what you do within the up() and down() methods. It also follows that you’ll have to ensure that your models also use the correct prefix.

I have also made a change to the provider (Akrabat_Tool_DatabaseSchemaProvider) so that it loads the correct application.ini file based on the data in the project’s profile. This shouldn’t affect anyone using Akrabat_Db_Schema_Manager, except that we no longer define APPLICATION_ENV and APPLICATION_PATH for you.

Matthew Weier O’Phinney writes a very useful article about resource injection; Brandon Savage approached me with an interesting issue regarding ZF bootstrap resources, and accessing them in your action controllers. Basically, he’d like to see any resource initialized by the bootstrap immediately available as simply a public member of his action controller.

So, for instance, if you were using the “DB” resource in your application, your controller could access it via $this->db.

I quickly drafted up a proof of concept for him using an action helper:

In this action helper, you would specify the specific resources you want injected via the $_resources property – which would be values you pass in. Each resource name would then be checked against those available in the bootstrap, and, if found, injected into the action controller as a property of the same name.