Zend Framework Routes and Navigation

March 10th, 2010

Having spent a few hours attempting to work out why Zend_Navigation was refusing to place the built-in “active” css class onto my navigation elements while being in the correct module/controller/action I finally resolved the issue:

It came down the custom routes!

If you have custom routes and you find your navigation is not correctly highlighting  it’s probably because you haven’t tied in your route to your navigation elements.

It requires very explicit setting to work.

Below is an example of how it should be structured:

 Read the rest of this entry »

SVN using Tags and Merging – Part 1.

October 29th, 2009

I’m going to make a few assumptions before I start this tutorial.

  1. You have windows (2000+)
  2. You have TortoiseSVN client
  3. You are familiar with the basics of SVN, i.e. you have checked out a trunk onto your local machine.
  4. You SVN repository is available over HTTP, e.g. http://svn.yourdomain.com/svn

For the setup I am going to be working with example directories, in this case “C:/dev” is your development directory on your local machine. You can of course make this whatever you choose but all other paths in this tutorial will need to reflect that change you have made. So i’m now going to checkout a project into my development environment at “C:/dev/example-svn”. If the person responsible for setting up your SVN repository has done their job properly you should see 3 directories, “trunk” (containing the latest code changes), “tags”, and “branches”. Your setup may differ from this, but i’ll assume you can translate that to whatever you environment is.

Now a little word about what “Tags” and “Branching” are:

By the method with which SVN operates, essentially both tags and branches are the same thing, i.e. a snapshot of the trunk that you are working with. Thus when you create a tag/branch you are creating a copy of a particular revision of your trunk code (it could be a branch of a branch etc, but lets not go down that road just yet). Doing this allows you to have 2 or more simultaneous code copies that can be altered separately, but merged back together at any time (covered in Part 2).

It’s worth noting that SVN doesn’t actually create a copy of the code base, it merely creates files that represent the differences between the trunk and the tag that was created. Nothing for you to worry about really, but basically stops your hard drive space from being used up with lots of different copies.

How to do it:

  1. Using your TortoiseSVN client navigate to your trunk directory (e.g. C:/dev/example-svn/trunk)
  2. Right click inside the directory (do NOT select a folder inside this directory, just some blank space).
  3. Select TortoiseSVN > Branch/tag
  4. Change the “To URL” to “http://svn.yourdomain.com/svn/tags/stable/0.1″
  5. Select either the “HEAD” or pick a revision number (you can browse revisions)
  6. Add a comment
  7. Hit “Ok”

Note in the above, for the tagged URL I chose a structure inside tags to represent a “stable” release, and a meaningful version number “0.1″.

Now, once you’ve done this you will need to head into “C:/dev/example-svn/tags”, Right-Click, and choose “SVN Update”. This should pull out the tagged release code we just have created.

Now if you perform any changes inside the tag or the trunk and commit them you will see they are only contained within their respective directories.

Why would you do this:

  1. You want to have a “production”, or series of “stable” releases.
  2. The tagged versions can be modified with fixes (for production release) and not be affected by any changes in the trunk
  3. You wish to perform fixes against a production code state, and test them against the last production release, and then re-merge them into the trunk (merging will be covered shortly in part 2).

AMFPHP Cake constructor arguments causing NetConnection.Call.BadVersion

October 10th, 2009

So… you’re seeing “NetConnection.Call.BadVersion” from Flash while attempting to talk to CPAMF or AMFPHP.
Well my friend, there’s a good probability that something is wrong.
Here are some suggestions:

  1. Fatal Error
  2. Redirect

What I tracked my problem down to was the fact that the following happens when AMFPHP receives a Flash remote object (using remoting):

  1. AMFPHP receives an AMF stream
  2. AMFPHP inteprets the stream byte by byte
  3. AMFPHP decides what sort of “thing” that Flash has attempted to send back
  4. AMFPHP attempts to “find” the relevant PHP class, defined by the class alias that has been sent in Flash.
    e.g. Flash object is "com.org.my.namespace.path.MyClass"
    and interprets that as com/org/my/namespace/path/MyClass.php (or MyClass.class.php) based on the base classMappingPath you sent in the service gateway, $gateway->setClassMappingsPath( '/absolute/path/to/vo/models' );
    attempts to include it, and instantiate an object of MyClass (therefore your filename MUST match your class name).
    i.e. $clazz = new $classname;

So I realised a problem. Constructors, both in Flash and PHP MUST at all costs have default values for them, i.e. the constructor variables are optional, because AMFPHP and Flash don’t use the sent objects, they literally convert them to their relevant objects on each side.

Further info on problems and debugging NetConnection.Call.BedVersion in Flash and AMFPHP can be found by google of course.

Cpamf accepting VO objects in service calls as parameters

October 5th, 2009

Here’s the status:
Cake implementation of AMFPHP via the plugin cpamf appears to be lacking some particular documentation regarding “accepting” flash objects in calls.
i.e.
Flash -> PHP object conversion.

Sure you can send back flash objects no problem, and there are plenty of documented places that tell you how to send flash objects back from PHP using class mapping and there was even some information on the reverse using AMFPHP on how to map VO’s from Flex to PHP using AMFPHP, but what seemed to be lacking was some particular documentation on how to get CPAMF, cake’s own brand of AMFPHP working with Flex VO to PHP. Begin investigation:

I am indeed hoping that I can get my controllers to accept objects instead of parameters or arrays. Allowing the flash app to pass through an object instead of having to decide what parameters or format it should be returning each time.

e.g.
Controller | Method | Parameter
TestController->test(StandardVO $vo)

As cake does; it likes to have controllers and models for everything it does. Aren’t you a nice cake! *grumble*
So it’s written it’s own CakeGateway.php class to extend the PHPAMF Gateway class, overriding action calls for the gateway. Aside from overriding them all and not calling the parent::registerActionChain() that seems to be fine.
A little hunt through the documentation/notes and general settings in globals.php seems to indicate that you can set the directory for controllers and vo classes. Great I think; changing these values should resolve my problem. If only!

The CakeGateway class appears to initialise the gateway with it’s own set of parameters for the controllers, sensibly (for a change) reading cake’s default controllers folder. Thus, all appears to be working within the /cpamf/browser , but still without the ability to pass objects, DOH!
The voPath mapping that appears to be set from the original globals file points to “services/vo”, i’m assuming this is supposed to indicate the current directory is the base and the services/vo folder is the one containing the vo’s. Thus, following some logical thinking I begin to stuck some classes in various folders that cake might just be reading.
In goes a StandardVo class, in the models/ directory and also inside the plugins/cpamf/vendors/amfphp/services/vo directory, try again. Nope still not recognising my object.
Ok, I know Cake’s naming convention is totally crap, lets try naming the file standard_vo.php instead of StandardVo.php . Still nothing, despite being implemented in both directories.

A few hours later, and after a fair amount of digging around in AMFPHP I came across what looked like some form of include()’ing. Having managed to stop the flash from doing it’s thing an instead die()’ing in certain places, I realised that this part here was responsible for loading in the PHP class to map to (lines 351-396 of /plugins/cpamf/vendors/amfphp/core/amf/io/AMFBaseDeserializer.php). Stepping through the logic I saw it: “$mappedClass = str_replace(’.', ‘/’, $typeIdentifier);”
The mapClass() function was doing the magic; interpreting the type of the flash object (which seemed to resolve to a full package name) into an include. AH HAH! It was also resolving it relative to the customMappingsPath which we saw earlier was set in CakeGateway class (cake_gateway.php).
So it would seem that AMFPHP was expecting to see a full package naming convention for all the Flash Objects it was going to receive.

I headed back to the CakeGateway class and amended the setCllassMappingPath() to

// This is the path to the Vo models!
$gateway->setClassMappingsPath( MODELS . 'vo' );

I then created a “vo” directory inside the cake models directory, and further proceeded to mimic the flash namespace package path.
models/vo/com/test/StandardVo.php , et VOILA! Problem resolved; cpamf now knows which object it is receiving and fills it with the data received from the flash object.

Now back to pulling out some hair over other issues.

CakePHP doesn’t like autoload() with vendor app import!

September 22nd, 2009

So, it would seem that if you decide that you want your vendor plugin to work nicely with cake, by having it conform to Pear folder directory structure and naming convention, and then right yourself a nice autoload() function to register with php (via spl_autoload_register()), you CANNOT use the App::import alongside this.
Why? Because Cake’s lovely App::import does a require() not a require_once()… Go figure!

So here is the problem:
You have App::import()’d your vendor plugin. It registers itself as an autoloader.
You have your 2nd vendor plugin, (which conforms to a Pear style structure also).
You explicitly App::import(’vendor’,'2nd item’,array(’file’=>’path/to/vendor/file.php’));
Cake has a fit and dies saying you “cannot redeclare “.
Brilliant Cake well done! Another reason to use Zend Framework…

As a solution I have altered the cake source code to make sure the require() is in fact a require_once(). I have yet to see the impact of such a change on any other import()’s. See below for alteration:
File: cake/libs/configure.php
Line: 975
Previous: “require($file);”
Change: “require_once($file);”

CakePHP CPAMF flex VO object flash integration

September 21st, 2009

Well thank god for that!

After a few days of stressing and pulling out hair, and with the help of one young dutch genius we managed to resolve the cake cpamf plugin VO integration.

Firstly, things to know about cake:

  1. Cake REQUIRES all models to be in the “models” directory.
  2. CPAMF plugin is installed in in the “plugins” directory.
  3. You can view all controllers/services at /cpamf/browser
  4. The gateway that flash connects to is /cpamf/gateway (not /cpamf/gateway.php as the default seems to think).
  5. CPAMF does NOT use the vendor/services/vo directory that is inside the amfphp part of the plugin.

Flash RemoteClass alias can be any path

e.g.

package
[RemoteClass(alias="org.test.TestOp")]
/**
* @author
*/
public class TestOP
{
public var username:String;
public var password:String;
public var id:int;
public function TestOP( username:String=null, password:String=null, id:int=0) {
this.username = username;
this.password = password;
this.id = id;
}
}
}

This class path MUST be represented in the PHP class using the _explicitType = ‘org.test.TestOp’. Once this is done you can pass back this class through any controller method.

e.g.

class TestOp {
public $_explicitType = 'org.test.TestOp';
public $username;
public $password;
public $id;
}

So, as you can see from the above, the PHP class MUST have the full package path to the flash class, and your class will be “models/test_op.php” as cake has a horrid non-pear style naming convention.

TheJim an SEO failure

February 19th, 2009

So after an SEO review of thejim.me.uk it would appear it’s a rather big disappointment.Where’s my frontpage SEO ranking google? Did you forget about me, or do you just not care? I’ll be investigating your blatant and treacherous googlism!

I have a domain name containing “thejim” and also “thejim” appears in the title of all pages and is the textual content of the <h1> tag. So one would think with all these markings of “TheJim-inism” I’d have a rather higher pagerank.

The peculiar thing of course being that the current google pagerank for TheJim is 3, not great, but hell of a lot better than other places which appears on pages 1-4 of the google search results. (n.b. pagerank is NOT which page you appear on in a google search!)

A quick google search for “thejim” shows that even a wallpaper site makes it higher in that rankings than me, The Real Jim Shady.

So, it made me wonder; does the suffix of “.me.uk” on TheJim had anything to do with it. Perhaps google doesn’t  consider any “.me.uk” to be  an authoratitive domain for information on the subject title? It would appear not. A quick scan of the “thejim” in google search revealed that google appears to have a preference for .org , .com , and .co.uk, quite a few sites of which don’t contain The Jim in their URL link. Yet has no favour with little ol’ “.me.uk”.

So, what to do? Well you’ll all be seeing this Jim VERY soon, very soon indeed!

It seems there are a lot more Jims out there than just this Jim… Beam me up Jimmy!

Eclipse PHP PDT no file extension problem.

December 8th, 2008

So to my surprise recently, Eclipse PHP PDT doesn’t show syntax highlighting for files which don’t have the .php (or variant of that) extension. i.e. it won’t allow a blank extension.

Honestly there is no reason not to use the .php extension if you’re working with a proper MVC framework, however in some recent work i have come across i’ve seen this used to facilitate “pretty” urls, which in turn has a positive influence on SEO ranking of course.

So, the solution is as follows. Read the rest of this entry »

Zend Loader isReadable causing trigger error problem

December 8th, 2008

I noted recently while writing a debugging error logging plugin for the Zend Framework that I was getting some E_WARNING’s logged in the database table it was utilising.

Having analysed the information a little further I realised that the framework was doing something rather funky. I had structured the application to be a modular layout as exemplified by the wiki guide for framework layout. I’d set up the module, controller and view components into their own directory (called “account”) and all was working fine. The Zend_Form was rendering correctly as I expected it to.

Read the rest of this entry »

How to get a better Google snippet description

July 11th, 2008

I suspect you’ve always wondered how google gets the snippet information that it displays with the link to your site in it’s SERPs. Well I have too, and now i’ll let you in on the secret http://googlewebmastercentral.blogspot.com/2007/09/improve -snippets-with-meta-description.html

“We want snippets to accurately represent the web result. We frequently prefer to display meta descriptions of pages (when available) because it gives users a clear idea of the URL’s content.”

So it seems that google does care about meta descriptions after all…

How do we apply this to dynamically generated products then I hear you ask. Well firstly I’m going to imagine that you have your product information stored in a database or flat file format and you know your SQL/parsing queries that will pull the relevant tags.

Read the rest of this entry »