Aaron Saray

open source programmer,
web developer

entrepreneur, author
and musician

My Blog

contains PHP, Web and business/entrepreneurial related content. Please join in the conversation!

Zend Filter Presentation

Thanks to Zend and their community organizers for the opportunity to do a webinar today.

I have uploaded my slides from the presentation here: Zend Filter Presentation

Posted in zend framework | Tagged | 1 Comment

Adding Subdomain Routes for all URLs in Zend Framework

All the examples I’ve seen for pulling information from subdomains are from the hostname router directly correlating one subdomain as a value to a single controller/action combo. This means they map username.website.com to something that basically looks internally like website.com/user/profile/var1/username. This is cool for simple one off tasks – however, what if you’re creating a multiple controller/action solution? For my example, I’m creating a CMS that will have a shared code base. However, on every page, I need to know exactly which site this is.

Enter Chaining!

So far, all the examples have shown how to chain a hostname route to a single other route. Like I mentioned, this solves the singular subdomain->action connection. However, now I need to apply it to all of my routes.

In my example, I’m going to make sure that the following code is at the very end of adding all of my other standard routes. If someone adds a route AFTER this code, it will not work correctly for their routes.

Use the following code:

1
2
3
4
5
6
7
8
$router = Zend_Controller_Front::getInstance()->getRouter();

$hostnameRoute = new Zend_Controller_Router_Route_Hostname(":sitename.example.com");

$router->addDefaultRoutes();
foreach ($router->getRoutes() as $key=>$route) {
  $router->addRoute('hostname' . $key, $hostnameRoute->chain($route));
}

First, the router is retrieved again. Next, the hostname route is created. In this case, our domain is example.com. I want to have a parameter called sitename in my controllers. Next, I force the router to add its default routes right now. Normally this is done after custom routes. Finally, each route that now exists, the default routes, the custom ones you’ve written, etc, are all looped through. A new route is added which is basically named after that route with the prefix of ‘hostname’. The route is a chained version of the original with the hostname.

Now, when visiting site1.example.com/blog/add, the parameters array in the controller will be:

'sitename'=>'site1',
'controller'=>'blog',
'action'=>'add'
'module'=>'default'
Posted in zend framework | Tagged | Leave a comment

Zend Framework: to include or not to include

There are two ways of working with Zend Framework as a library in your project. These are including it in your project repository and using a shared copy on the server (like PEAR). Let us discuss both:

Including Zend Framework In Your Project

The first method is to include the Zend Framework library folder in your zend framework project’s library folder (uh….). So, for each project on your server that is built on Zend Framework, the following path has a copy of Zend Framework: /root/to/your/app/library/Zend. This means each project has at least the entire size of the Zend Framework in it. Pros/Cons?

  • Pro: Can control the exact version of Zend Framework with this project. A server zend-framework upgrade won’t potentially hose up your project.
  • Con: Have to update ZF in each project on the server when an update comes.
  • Con: Takes up considerable space in the code base.
  • Pro: Easier IDE configuration. It can find all the code easily in this project (true: you could configure your IDE to use other libraries that aren’t in the project)
  • Pro: Migrating to a new server, just one less thing to consider when setting up. Code with the ZF in it is fully contained and deployable anywhere.

Using Zend Framework as a server wide install

Like PEAR, Zend Framework can be installed on the server in a shared location. You may install your Zend Framework Library folder into a different path, for example: /root/to/shared/code/Zend. Then, your PHP has to be configured to have that in its include path. Pros/Cons?

  • Pro: Any project at any location on your server has access to Zend Framework. As you know, you can only pick pieces of ZF to use, like the PDF functionality. May make it easier to transition project from legacy code to ZF.
  • Pro: When an update comes, it can be applied only one time to the shared location.
  • Con: Updating shared code could break an application – all need to be tested with new code.
  • Pro: Save code space in your code repository.

Currently, I’m going with including it each project as a point of preference. I think the risks outweigh the possible time/storage savings. So, what are your thoughts?

Posted in zend framework | Tagged | 4 Comments

Forcing UTF-8 in Zend Framework with PDO

For some reason, I just had the most horrible time making sure that my connection from my Zend Framework code was speaking UTF8 at my database. Here are the key things to remember that I learned:

  • Make sure to have a collation of UTF8 on your database
  • Set your default charset on your table is UTF8
  • Zend Framework Zend_Db_Mysql uses PDO – so use PDO commands when you create your connection to force UTF8

Ok first thing’s first. Create the database with the proper collation:

1
CREATE SCHEMA `mydatabasename` DEFAULT CHARACTER SET utf8;

Next, define your tables with UTF8 charset:

1
CREATE TABLE `mynewtable` (`a` INT NULL ,`b` INT NULL) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

Finally, if configuring your PDO/MySQL connection in application.ini, after defining the connection parameters, as I have, add the last two lines

resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "user"
resources.db.params.password = "password"
resources.db.params.dbname = "mynewtable"
resources.db.isDefaultTableAdapter = true
resources.db.params.charset = "utf8"
resources.db.params.driver_options.1002 = "SET NAMES utf8;"

I never had a chance to track down the reasons “why” this was happening – so if anyone has any input, that would be great. But now I add this to all of my projects just to force it.

Posted in zend framework | Tagged | Leave a comment

Useful Firebug Tricks with Zend Framework

Zend Framework has a few hooks with the Firebug browser plugin (with the firePHP add-on). The two that I use are writing logs to the console and profiling of database connections.

First thing’s first: Make sure to only enable these settings in your non-production environments.

Zend_Db profiling

One of the most helpful things I do for my database setup is initialize the Zend_Db profiler with firebug in my application.ini file. It is important to have this under the development section and nowhere else. Check out this snippet of my application.ini file:

[development : production]
resources.db.params.profiler.enabled = "true"
resources.db.params.profiler.class = "Zend_Db_Profiler_Firebug"
...

Logging Application Alerts to Firebug Console

I don’t like to check logs while I’m developing. I’d rather have all of these alerts in my face. Luckily, Zend Framework allows a firebug logger to do this for me. In my bootstrap.php file, I will create a method similar to this:

1
2
3
4
5
6
7
8
9
  protected function _initLogs()
  {
    $logger = new Zend_Log();
    if ($this->getEnvironment() != 'production') {
      $writer = new Zend_Log_Writer_Firebug();
    }
    $logger->addWriter($writer);
    return $logger;
  }

With this code, your log-able items can retrieve this bootstrap resource and it will write the messages right to the console. (Side note: Most of my applications actually have another part to that If statement where they define the production logging system including setting priorities).

Do you have any creative uses for Firebug with Zend Framework?

Posted in zend framework | Tagged | Leave a comment

Easy Flash Messenger Messages in Zend Framework

Through reading a few blog posts over the last year and my own trial and error, I’ve developed a way of using the flashMessenger Helper in ZF that works out really well for me. (Note: if anyone knows the original blog post that I got some of the view helper from, please comment!).

Objective

  • Use FlashMessenger to store both success and failure messages and denote them as such.

Using FlashMessenger in the Controller

Now, we’re going to change the way we assign messages in the controller. Make an array of the message with a key of the type, and a value of the message. You may want to use ‘success’ and ‘failure’: in some controller…

1
$this->_helper->flashMessenger->addMessage(array('success'=>'The update was successful'));

Next, create a View Helper

Create the following view helper. I placed mine here: application/views/helpers/FlashMessages.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Zend_View_Helper_FlashMessages extends Zend_View_Helper_Abstract
{
    public function flashMessages()
    {
        $messages = Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger')->getMessages();
        $output = '';
       
        if (!empty($messages)) {
            $output .= '<ul id="messages">';
            foreach ($messages as $message) {
                $output .= '<li class="' . key($message) . '">' . current($message) . '</li>';
            }
            $output .= '</ul>';
        }
       
        return $output;
    }
}

The output is initially blank. This is because we will always ‘blindly’ call this in our layout later. Then, the messages are retrieved from the flash messenger using the getStaticHelper method to retrieve the FlashMessenger helper (and call its getMessages() method). If it has content, output is appended with a UL with an ID of messages (this is for css styling later). Then, each message is looped through and added to an LI element. The ‘type’ is the class of that element, and the message is the content. (Note: since this is an array of single arrays where neither the key nor the value is known, that is the reason to use key() and current()). Finally, output is updated with the closing UL tag.

Use this in Your View

I technically put this call in my layout towards the top of my content:

1
echo $this->flashMessages();

I also modify my CSS to have styling of green for the #messages li.success and red for #messages li.failure.

Posted in zend framework | Tagged | 3 Comments

PHPUnit error: No release available for package

One of the steps to install PHPUnit is to execute the following pear commands:

1
2
pear channel-discover pear.phpunit.de
pear install phpunit/PHPUnit

However, after doing that, I got the following error: no release available for package pear.phpunit.de/PHPUnit – and the install failed.

I decided to execute a remote-list command – it was a thought that maybe I could see if maybe my phpunit declaration was wrong – I was just grasping at straws…

1
pear remote-list -c phpunit

This finally gave me a worthwhile error! “The value of the config option cache_dir (/tmp/pear/cache) is not a directory and attempts to creat the directory have failed”

So, I finally was successful after the following two commands:

1
2
mkdir /tmp/pear/cache
pear install phpunit/PHPUnit

Moral of the story: check to make sure PEAR has a cache directory available if you can’t install a PEAR package.

Posted in phpunit | Tagged | 2 Comments

Zend Framework View Helper for QR Codes

Google Charts has a QR code generation service (here are the details). I decided that I wanted to create my own ZF View Helper to display these on my pages. This version that I am going to show just returns the properly formatted URL for the charts API. The view must create the img tag around it.

The Code for Google QR Code

Place the following code in your view helpers location. For example… application/views/helpers/GoogleQRCode.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Zend_View_Helper_GoogleQRCode extends Zend_View_Helper_Abstract
{
    public function googleQRCode($data, $width = 100, $height = 100)
    {
        $url = 'https://chart.googleapis.com/chart?';
        $params = array(
                       'cht'=>'qr',
                       'chs'=>(int)$width . 'x' . (int)$height,
                       'chl'=>$data
                       );
        $url .= http_build_query($params);
        return $url;
    }
}

First thing is the function declaration. It will accept some data to encode. By default, the width and height are 100px. This can be overridden with the helper call. Next, the URL for the Google charts API is defined. Notice that this version is https – just in case its used on SSL websites. Next, the parameters to the API are built. The ‘cht’ or chart type is ‘qr’. The chart size or ‘chs’ is the integer width by the integer height. Finally, the ‘chl’ value is the data. Finally, the URL is appended with the value of the results of http_build_query() of the url parameters. Finally, the URL is returned from the method.

IMPORTANT NOTE: In the spec, it says that the data should be url encoded. The view helper is not doing that when it creates the parameter array. This is handled by http_build_query.

To use this in your view, you may have the following code: application/views/scripts/index/index.phtml

1
2
3
4
echo '<h2>Find Me Online</h2>';
echo '<img src="';
echo $this->googleQRCode('http://aaronsaray.com/contact');
echo '">';

Future options: At some point if I tend to use this more often, I might replace this entire view helper with a more model based application. The view helper will still call the model, but the model will handle retrieving and caching these QR codes. If the Google Charts API is not responding, previously generated QR codes will still be available that way!

Posted in zend framework | Tagged | 1 Comment

Mailchimp Overview Presentation: Waukesha Area Internet Marketing Meetup

I will be presenting at the WAIMM Email Marketing Software meetup today. I plan to cover the basics of Mailchimp for comparison to other services like Constant Contact.

Download the presentation powerpoint here: Mailchimp Overview Presentation

Posted in Misc Web Design | Tagged | Leave a comment

PHPUnit error with Zend_Session

Running a test, I ran into this error:

Zend_Session_Exception: Session must be started before any output has been sent to the browser; output started in /usr/share/php/PHPUnit/Util/Printer.php/173

In order to solve that, I added a line calling ob_start() to my test bootstrap file.

However, there is a better way!!

Instead, add the following line:

1
Zend_Session::$_unitTestEnabled = true;

This works flawlessly.

Posted in phpunit, zend framework | Tagged , | 3 Comments