Setting up LAMP and PHPUnit on CentOS for staging.

I needing to setup a staging environment that more or less emulates the platform of your deployment system, i needed to setup a LAMP stack with PHPUnit for testing on the target platform.

Using CentOS and help from my good friend Cordoval (you can check out his cutting edge blog at http://www.craftitonline.com) we setup using Apache, PHP and MySQL.

We used the yum package manager to get things up and running:

First we needed to setup php :

and mysql:

With that done, we needed to then setup PEAR:

Then i followed the guides found here: (http://ulaptech.blogspot.co.uk/2011/07/install-phpunit-in-rhel-centos-or.html)

I will copy the instructions but all credit goes to the link above:

1. Make sure that you’re PEAR is version 1.9.2 or above. 

2. Discover all channels required.

3. Install PHPUnit with all the dependencies

<–

optional, at the time of writing this is beta so I had to force install it

4. Done. Test PHPUNIT.

Symfony2 CLI does not connect to MySQL while browser works fine.

So i had an issue that i am still somewhat unsure of the cause, though i suspect the culprit was an upgrade to a newer version of MAMP.

So when using the Symfony2 project in the browser, everything works fine, however on the CLI i get the following:

[PDOException]
SQLSTATE[HY000] [2002] No such file or directory

[ErrorException]
Warning: PDO::__construct(): [2002] No such file or directory (trying to connect via unix:///var/mysql/mysql.sock) in …htdocs/Symfony/vendor/doctrine-dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php line 36

So i thought it was pretty odd that the CLI would not connect when the browser did just fine. I tried adding this to my parameters.ini:

Though this seems to have made no difference what so ever. It seems SF2 CLI would ignore the sock file location and was only interested in the sock file located in the /private/var/mysql directory. So the solution is to make a symlink to the sock file thus resolving the issue. Do the following to resolve it:

This should resolve the issue.

Git tagging.

Quick cheat sheet for referencing. Tags are a way to bookmark a particular version of your git repository for future referencing. Use them to bookmark stable and dev versions of your project.

Add a tag with inline message (no editor):

Remove a tag:

You can also push tags with a regular push with the tags argument:

Done!

 

Authorisation on Roles in Symfony2

Following a discussion on the IRC room from someone who viewed my post about login/logout handlers in SF2, i wanted to clarify that when dealing with Roles, they should be dealt with in the controller actions.

For off, you need to make sure you got the right hierarchy of roles. In your app/config/security.yml you need something following the structure of:

Where the lowest level of access is at the top and the higher levels of access envelope the last levels of access.

Then you inside your controller actions you would do:

According the order of the role hierarchy if you have the role or higher than specified the controller action will continue, if you have a lower level of access than the minimum required then you will get an AccessDeniedException.

Git workflow.

1) create a branch.

2) add new files and commit.

3) push to github.

4) switch to new branch of github then PR and merge.

5) pull update from github with  merged changes.

Redirecting on login/logout in Symfony2 using LoginHandlers.

Using login handlers or even logout handlers, we can do a number of last minute things before the user is redirected to where they need to go. Being able to intercept the redirect at the last minute and make the user get redirected elsewhere is relatively simple.

Firstly though, i notice a lot of people now who are using Symfony 2 are cheating somewhat by using an EventListener and registering it with the security.interactive_login event listener. This is not the best way to go about this, namely because this event listener is not intended for this purpose. Sometimes event listeners are not the best way to go because they were defined for a specific purpose other than your intention and using them may have undesirable side effects you may not notice right away. Using handlers however allows a little more flexibility in that in all likelihood regardless of changes to Symfony in future revisions, they should still work and were designed specifically for the purposes we will need them for.

Firstly, we need to define our services, personally, i am a fan of YAML, so i define my services as such but feel free to do the same in XML:

Now our services are defined, we need to define the handlers themselves. I like to create a directory named Services in my user bundle for this purpose, then create 2 files. The first file is LoginSuccessHandler, the second is LogoutSuccessHandler. Our handlers will implement the appropriate interface for either our login or logout handlers, which require usually only one method in these instances.

Here is what the login handler should look like:

Note my namespace is CCDNUser, and my bundle is called SecurityBundle, so our service is named ccdn_user_security.component.authentication.handler.login_failure_handler. Change this to your own namespace and bundle name accordingly but ensure to use the same format as used here, underscore your namespace and append the bundle name with an additional underscore without the term ‘bundle’ in it. Failure to get this part correct will mean your namespace will not be loaded and you will get problems later on in this tutorial as exceptions will be thrown regarding the service not existing.

Here is what the logout handler should look like:

Our service definitions inject some of the classes we need to make use of our handlers, namely a Router object and the SecurityContext object, we can store these in member variables for later use. Then we wait for the onAuthenticationSuccess method to be called in our LoginSuccessHandler, once this has happened, we have a request and token interface object at our disposal. Using the security context object we can determine what role they have (i.e; ROLE_USER, ROLE_ADMIN etc) and appropriately redirect them as needed.

I like to redirect members of ROLE_USER role to where they came from prior to logging in. This is achieved by passing the ‘referer’ header into the redirect response object we return. I took this step both in the login and logout handlers.

Last thing we now need to do, is inform our security config that it needs to use these handlers by doing the following:

In this instance i am using FOSUserBundle and extending it in my own UserBundle, though this code is contained in the SecurityBundle. Which is probably the best way to do this. As the handlers used here work in any bundle because they plugin to Symfony2 core and implement their login handlers, and should not be dependant on any user bundle.

You can see a complete implementation of this in my security bundle found on github

Once this is implemented your on your way to a better login/logout system. Enjoy.

Symfony Embedded Forms ‘take 2’

Learnt some new things while working with symfony’s embedded forms, as we know, when they are have relations in the entities that the form is modelled after you want to ensure that when including the other form type that you create an instance of the formType representing the many in the manyToOne relationship. For example in the forum i am working on (which you can find on github here though currently still in development as of the date of this blog entry) a Topic has MANY Posts, as a result, we build our form by instantiating the PostType first and then adding the TopicType to it as a field because the PostType has a related Topic in the database schema.

But following up from the last post, what about when we have unique use cases for our form Types? What if we want to use a PostType without including the TopicType or we wish to conditionally decide wether for the purposes of editing we need to populate the form before presenting it?

To make this easier, in my FormHandlers what i choose to do is pass an array with some options we can use, namely a mode key specifies wether we are to ‘insert’ or ‘update’ an entity, and other keys for holding the entity to populate the form if mode is ‘update’

Here is an example from the top half of my TopicFormHandler:

To view the full source in greater context, explore the source on github here.

Creating embedded forms in Symfony 2.0

If you are looking to create a form from 2 or more entities, like i have been then you probably find the documentation somewhat lacking and confusing. If you follow the guides you can get your form working if you start from the least dependant entity making that the first entity you use to build your form from your controller. I find if you start from the most dependant you usually get all manner of errors.

What i have is a basic forum i am working on, in my current form situation i have 3 entities, Board entity, a Thread entity and a Post entity. If you start by creating your form with Board then chances are it won’t work, i created my forms in separate ‘Type’ classes (PostType.php ThreadType.php and BoardType.php) and then created my PostType form in my controller, which then sorts out its dependencies on its own.

My controller class is very basic and not very polished, but here is what it looks like:

It probably looks somewhat messy as i say, its a rough work in progress, but it works, and here are the FormTypes i used, starting with; PostType.php:

ThreadType.php

And lastly, the BoardType.php

Notice how i added a constructor, this is so we can easily chain feed in from the first object any changes to the form, such as wether we wish to bother including a field or not, we can opt to have any field removed if the form is used under different circumstances such as different access controls for different users with different permissions or if the form is used in another way on the site.

One more thing we need to make sure, is that all the references in our entities make use of the cascade={“persist”} option so that it maintains relations between the relevant forms as new ones get processed, so if say a thread does not exist then when processing the post, it should create one and do the association for us.

Here is an example of a snip from my Post entity class Post.php

Lastly, you will need a formHandler if your not working in your controller, if using my example code then the postFormHandler.php looks like this:

Using WebView in XCode 4.0 with Objective-C

If you are wanting to use the WebView in your XCode/Obj-C project and are a little underwhelmed and confused by Apple’s docs, as i initially was then here i can show you step by step how to get up and running very quickly and very easily.

Firstly, before we begin this little tutorial is from what i have worked out myself, i found the documentation a bit confusing myself, it tends to ramble on a lot and not give the reader much in the way of code examples as i will do here; namely it talks more about Carbon than Cocoa front ends and the example code is very obscure and out of context and fails to mention several key steps for newcomers to Cocoa/Obj-C. The following steps are what i gathered from the documentation plus a little googling.

Chances are, if your reading this then like myself you got an error when trying to run you app after placement of the WebView and further more if you get past compilation you get a runtime error of: “program received signal: SIGABRT” in the code as a sort of fix-it tab and a GDB output of: “Terminating app due to uncaught exception ‘NSInvalidUnarchiveOperationException’, reason: ‘*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (WebView)”.

The 2 most significant steps that the apple docs don’t mention are 1) stating the header file for Webkit, which if your used to working in Windows you would not import the rendering engine for a webview equivalent and may be thrown by that and further more 2) import the webkit framework into the project.

So heres the steps you should take:

1) Create your project, here i created a basic cocoa project called webber.

2) Add the WebKit.framework to your project as shown below:

On the project configuration page click the plus under the "Linked Framework and Libraries" list as shown in the figure above.

search for webkit and select the webkit framework.

The linked frameworks and libraries should look like the figure shown above.

3) Add the webView to your window, in this instance i also added a textbox and a go button:

Add your webView to your project.

4) Drag your IBOutlet connections to your AppDelegate, you will need an outlet for the navigation textbox (navbar) and one for the webView component (webber), and lastly a IBAction for the go button (go). Then at the top of the code add a header for webkit, #import <Webkit/Webkit.h>. You should have something resembling this:

Establish your IBOutlets and IBActions as shown above and add the Webkit header.

5) Now we add the implementation code to your AppDelegate.m file in the go and applicationDidFinishLaunching method:

Add the implementation code.

So the first applicationDidFinishLaunching method will set the homepage of your webView to the apple site initially and after that you can type in a url in the textbox and click go and the browser will take you to the requested site.

Simples! I hope this helped those of you who bothered to read. Good luck and have fun with it.