James Gordon's blog

I like Zend Framework 1. Forms are a little awkward, but have robust validation and reasonable formatting options. Plug-ins and helpers are a bit of a pain, as there seems to be several different approaches/conventions depending on what kind of plug-in you are using. Zend_Pdf rocks, as does the auto-WSDL generation.

Zend Framework 2 is a good framework. I say this based on having attended the very first public Zend Framework 2 training in 2012, having sat through several ZF2 sessions at ZendCon2012 and having also spoken to Matthew (the project lead) and a few other contributors about the design philosophy and approaches used in ZF2. It is a well-engineered framework that definitely fits in well with Zend’s product range and overall strategy.

And yet, despite all that, I will probably never use ZF2.

Because I have discovered Laravel.

And Laravel rocks!

Well, it rocks for me anyway. My recent projects have required rapid development of some new web front-ends to existing databases, with old requirements changing and new requirements emerging during the course of each project. Using a combination of Laravel and Bootstrap I have been able to produce responsive pages with beautifully formatted, standards-compliant HTML very quickly. The views are easy to read (layouts and partials are very simple), the forms are clear and easy to validate and the database access is very streamlined.

If you’re an OO purist, you might want to steer clear of Laravel. It makes much use of supposedly evil statics and does some other trickery to keep the syntax nice and clear. If OO idealism is your thing, use ZF2 instead. ZF2 is a really good example of great object-oriented design and programming, which, as well as being one of its strengths, is also, in my opinion, its Achilles heel, as the investment required up-front to learn the framework is much, much larger than Laravel. And, more importantly, the amount of time it will take the average developer to become proficient with ZF2, such that they can rapidly adapt their project to changing requirements and identify and rectify problems quickly, will be much, much longer than with Laravel.

I’m currently using Laravel 3, which still seems to be getting some love on guthub. Laravel 4 is in beta and is scheduled for realease some time this month, so if you’re about to make the jump to Laravel, I would probably recommend jumping straight on the Laravel 4 bandwagon.

Some time ago I started getting the following error in Zend Studio 9.0.3 whenever I tried to update it or use the “Welcome” screen to activate installed features:

'Discovering available features' has encountered a problem.

An internal error occurred during: "Discovering available features".

Here’s a pretty version of the error:


Discovering available features has encountered a problem

During my search for an answer I found that many Eclipse users had hit the same issue.

Today I finally bit the bullet and decided to solve the problem once and for all. I started by examining the log file, which is located in:

/path/to/your/workspace/.metadata/.log

The error starts off with this:

java.lang.ExceptionInInitializerError
at org.eclipse.ecf.provider.filetransfer.httpclient.HttpClientBrowseFileTransferFactory$1.
sendBrowseRequest(HttpClientBrowseFileTransferFactory.java:53)

After spending a few minutes investigating potential networking issues (firewall, proxy settings, etc), I realised that I was looking at the wrong end of the exception stack - d’oh!

Reading a little further down the exception stack I came across the following:

Caused by: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: No suitable Log constructor [Ljava.lang.Class;@1c6fed0 for org.apache.commons.logging.impl.Log4JLogger (Caused by java.lang.NoClassDefFoundError: org/apache/log4j/Category)

Now that I had the true source of the problem it was pretty easy to Google up the answer, which is that Commons Logging didn’t know which logging class to use.

So the solution, then, was to tell it which logging class to use, which is done by adding the following line to your ZendStudio.ini or eclipse.ini file:

-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

I have no idea what I might have changed on my system (OS X Snow Leopard) that could have caused this problem. I don’t have any obscure Java stuff installed, either inside or outside of Eclipse, nor do I carry out any development work in Java that may have screwed up the classpath or some such thing. So if anybody has any ideas on the true cause of this problem, I’d be very grateful if you could drop a comment below.

If you’re looking to create Powerpoint files using PHP there’s a good chance you’ll end up using the PHPPowerPoint library. Having just spent a few days converting a complex PDF report to PPTX format using this library, I learned a few things that I thought I should share with the world.

Getting Started

Once you’ve downloaded and unpacked the zip file, you’ll probably need to:

  1. Rename the PHPPowerpoint folder to PHPPowerPoint
  2. Rename the PHPPowerpoint.php file to PHPPowerPoint.php

If you are running on a machine that has a case-insensitive file system and you don’t rename the above files, you will have trouble with the require_once() statements.

Positioning System

After some experimentation I figured out that PHPPowerPoint creates slides in Powerpoint’s default size, which is “4:3 Screen Layout”. The actual positioning system is as follows:

  1. 0,0 is top left corner
  2. 959, 719 is bottom right corner
  3. Total size is 960 x 720

Interestingly, I did find some slight alignment issues when adding images that went all the way from one edge to the other. Depending on the image, sometimes they would appear slightly too wide or slightly too narrow. Other images would end up perfectly aligned. Weird.

Functionality

With PHPPowerPoint you can do the following things:

1. Create a new PHPPowerPoint object (which, by default, will already contain one slide)

2. Add and delete slides

3. Add shapes to slides

4. Save the whole lot as a PPTX file

Unfortunately you cannot read in an existing PPTX file and modify it.

Shapes

Although the Powerpoint application supports a large range of shapes, PHPPowerPoint supports only two (but they are two pretty important ones!):

  1. Drawing Shapes - You can create drawing shapes in memory using GD library and add them to a slide or you can add an image from disk.
  2. Text Shapes - You can set the font name, size, colour and the horizontal/vertical alignment when writing text. You can also set the size of the box that the text is being placed in, which makes it easy, for example, to write text in the center of the page.

You can obviously control the size and placement of both kinds of shapes and you can add a shadow effect as well. The test scripts included with the library are very helpful and provide examples of everything that can be done with the library.

Order of Operations Gotcha

I’m not sure why this happens, but if you add any drawing objects to a slide after you’ve added text objects, the resulting PPTX file will not open in Powerpoint. I tested this by swapping the order in which the text and drawing objects are added to the slide in the 01simple.php example script and the resulting file failed to open on Powerpoint 2003 and 2007 for Windows and Powerpoint 2008 for Mac.

Depending on your situation, this constraint may or may not be an issue. In my case, I was planning to write a wrapper around PHPPowerPoint and pass the resulting object into an class that expects a generic “renderer” object. However, the object using the renderer was obviously not written with this constraint in mind and assumed it could add any kind of shape in any order, so this constraint was a huge limitation for me. Thankfully, it wasn’t too hard to fix. Although there may have been a more “correct” way to resolve this issue, in the interest of getting something working quickly, I came up with a very low impact change that fixed it.

Each instance of the Slide class uses an ArrayObject called _slideCollection to store the objects that have been added to the slide. When the save() method is called, each Slide object iterates through its _shapeCollection from start to finish, writing the appropriate XML to the output file. So to solve the problem I needed to ensure that each _shapeCollection was sorted such that all drawing objects came before all text objects. Rather than doing the sort at the time save() was called, I opted to sort the shapes as they were added.

In order to achieve this, I added the following code to the top of the Slide.php:

class CustomArrayObject extends ArrayObject
{
    private $images = 0;
    private $others = 1000;

    public function append( $thing )
    {
        if ( $thing instanceof PHPPowerPoint_Shape_Drawing ||
         $thing instanceof PHPPowerPoint_Shape_MemoryDrawing )
        {
            $this->offsetSet( $this->images++, $thing );
        }
        else
        {
            $this->offsetSet( $this->others++, $thing );
        }

        $this->ksort();
    }
}

Then I simply changed the following line in the Slide constructor:

From this:

    $this->_shapeCollection = new ArrayObject();

To this:

    $this->_shapeCollection = new CustomArrayObject();

And voila! Shapes can now be added to a slide in any order and the resulting PPTX file will still open successfully.

Yes, it’s a hack. But as I mentioned earlier, it was the fastest (to code), least intrusive solution that I could come up with quickly. If you have any other hints to using PHPPowerPoint, feel free to pop a comment below.