Doctrine2 ninja with the HIDDEN keyword

Doctrine2 ninja with the HIDDEN keyword

I recently came to find a nice hidden feature of Doctrine2, the well named HIDDEN keyword.
I first needed to find the feature because I wanted to use functions in an order by clause.

The problem

Let’s say you want to get your user ordered by sum of comments and likes. You will write this kind of DQL:

SELECT u
FROM BCCModelBundle:User u
ORDER BY u.commentNumber + u.likeNumber

Sadly, for interoperability reasons, such a statement is not possible using doctrine2. You cannot have an arithmetic expression in the ORDER BY clause. This goes also with the GROUP BY

The solution: the HIDDEN keyword

Hopefully, you can use the HIDDEN keyword. This idea is to declare a new field in the SELECT clause and mark it hidden to avoid the ORM fetching it:

SELECT
	u,
	u.commentNumber + u.likeNumber AS HIDDEN score
FROM BCCModelBundle:User u
ORDER BY score

Now, you have a score field which is compatible with the ORDER BY clause. I am sure you will find it very useful, especially when you will starting to have heavy DQL with complex ORDER BY clause.

EDIT: Please note that this feature is available on Doctrine 2.2+.

Advertisements

Welcome the BCCCronManagerBundle, the Symfony2 bundle that helps you managing your crons

Welcome the BCCCronManagerBundle, the Symfony2 bundle that helps you managing your crons

One thing I don’t like to do when maintaining a website, is having to pull out ssh on a daily basis in order to check that everything is running fine. A basic use case is scheduling and watching crons.

So I recently came out with the idea of building a web interface wrapping the use of the crontab command with some tools for watching associated log files.

And thus, the BCCCronManagerBundle was born.

A quick presentation

The BCCCronManagerBundle can already do some nice things:

  • display the cron entries of the cron table, parsing time expression, command, output file, error file and comment
  • guess the last execution time and status
  • display log files
  • add, edit and remove cron entries

The bundle is localized in english and french. The forms also include some shortcuts t easily build common time expression, launch a symfony command or log in the symfony log directory.

The cron list
The cron list
The cron form
The cron form
A cron log file
A cron log file


How it works

Actually, the architecture is quite simple. Everything relies on two classes: CronManager and Cron.

The CronManager launches the [cci]crontab -l[/cci] command in constructor, then extracting each lines in order to build a collection of Cron instance. It has get, add and remove methods in order to access the Cron collection. A raw method build up the cron table string based on the Cron collection and a write method puts it into a temporary file before launching the [cci]crontab $file[/cci] command.

The Cron class is instantiated using the parse static method. Its job is to parse a cron line from the cron table and extract the time expression, command, output, error output and comment (if defined). Based on the output files it can guess if the cron has already been runned (one of the output files is present) and if it was successful or not (the error file is empty). A getExpression method can build the time expression and the _toString is overriden in order to give the cron representation for the cron table.

The interface is quite neat, thanks to Sam. He helped me implementing the twitter bootstrap which is very powerfull and elegant. I also decided to make use of the jQuery plugin that is quite impressive and can easily replace jQueryUI on some points.

Wrap up

You can download and install the bundle on the github : https://github.com/michelsalib/BCCCronManagerBundle.
I also welcome contributions for any improvement, such as a better cron table parsing, more options for cron definition (such as log files), better support of multi platforms, or translations.

BCCExtraToolsBundle for Symfony2 now includes new features

BCCExtraToolsBundle for Symfony2 now includes new features

The purpose of this blog post is to review the last features that have been included into the BCCExtraToolsBundle.
As you may know, its current main feature is a command that extract translation string from your template and dump them into your translation files. It has been so popular that the code has been adapted and merged it into the code Framework a few months ago with the help of the community.
Sadly, I will eventually remove this functionality from the bundle when the 2.1 version will come out. Hopefully, I recently add new cool stuffs into the Bundle recently that you may find useful.

A date parser

You may know that the Bundle currently includes a date formatter that provides you a nice way to localize your dates directly with a twig filter.
I reviewed the code recently to provide a way to make the operation working the other way. You can now do such things :

[cc_php]
get(‘bcc_extra_tools.date_formatter’);

// obtain a datetime instance for a normally formated string
$date = $dateFormatter->parse(‘November 1, 2011’);

// obtain a datetime instance using a defined locale
$date = $dateFormatter->parse(‘1 Novembre 2011, 20;14’, ‘fr’);

// obtains a datetime instance with a uncommon string
$date = $dateFormatter->parse(‘Nov. 2011);

[/cc_php]

Basically, the code is trying every parsing it can using the formats available for the formatter (more information here http://www.michelsalib.com/2011/07/a-twig-extension-that-translates-countries-and-dates/) and more so that it can parse almost anything.
Of course it can be very handy when you consume some weird API using nonstandard datetime formatting.

A unit converter

About consuming API. I can be very annoying to find some values in a unit don’t want to use. The unit formatter is here to help you:

[cc_php]

get(‘bcc_extra_tools.unit_converter’);

// transform a value knowing the source and destination units
echo $unitConverter->convert(1000, ‘m’, ‘km’); // echoes : 1

// transform a value knowing only the destination units
echo $unitConverter->guessConvert(‘1h’, ‘m’); // echoes : 60

[/cc_php]

To do such work, your value will go through different phases::
– A chain unit converter will try to convert using its DI registered unit converters
– A ratio unit converter which converts units that are strictly proportional will take care of most your conversion
– The ratio unit converter supports different kind of units registered using DI, such as length, weight, speed, time… those are called ratio unit providers
– Ratio units providers defines units and ratios related to a specific unit kind. It includes also the locale where the unit is applicable and the prefixes that can be associated to the unit. For instance, the computer capacity unit kind will define the octet, the bit and the byte with their corresponding conversion ratio and the applicable prefixes (k, M, G…).

With such a structure, the converter insure you that any prefix is taken into account, that the conversion is done between coherent units (it won’t try to convert time into money… sadly), and it also takes into account your current locale (the ‘metre’ is the french unit for the ‘meter’).

I’ll try to add more units and documentation in the coming posts.

Wrap up

The BCCExtraToolsBundle continues to provide useful features to the developers. Get the code of the datetime parser and the unit converter on the BCCExtraToolsBundle github : https://github.com/michelsalib/BCCExtraToolsBundle. Don’t hesitate to report issues, feedback and improve the code 🙂

Introduce the BCCAutoMapperBundle for Symfony2

Introduce the BCCAutoMapperBundle for Symfony2

One of my favorite tools with my .NET developments is definitely AutoMapper. It allows to easily mapping objects to other objects by generating default maps for graph of objects base on the name of the different members.

I found it quite a shame that such a tool did not exist on the PHP platform. So I started a new Symfony2 bundle to palliate this lack.

How the AutoMapperBundle works

You can find it here: https://github.com/michelsalib/BCCAutoMapperBundle.

As a quick example here to show you how you can map objects together. Here is your model:

[cc_php]
name = $name;
$this->description = $description;
$this->author = new SourceAuthor($author);
}

public getName() {
return $this->name;
}

public getDescription() {
return $this->description;
}

public getAuthor() {
return $this->author;
}
}

class SourceAuthor {
private $name;

public __construct($name) {
$this->name = $name;
}

public getName() {
return $this->name;
}
}

class DestinationPost {
private $title;
private $description;
private $author;

public getTitle() {
return $this->title;
}

public setTitle($title) {
$this->title = title;
}

public getDescription() {
return $this->description;
}

public setDescription($description) {
$this->description = description;
}

public getAuthor() {
return $this->author;
}

public setAuthor($author) {
$this->author = author;
}
}
[/cc_php]

Then, in you application:

[cc_php]
get(‘bcc_auto_mapper.mapper’);
// create default map and route members
$mapper->createMap(‘MySourcePost’, ‘MyDestinationPost’)
->route(‘title’, ‘name’)
->route(‘author’, ‘author.name’);

// create objects
$source = new SourcePost(‘AutoMapper Bundle’, ‘A great bundle’, ‘Michel’);

// map
$destination = $mapper->map($source, $new DestinationPost());

echo $destination->getTitle(); // outputs ‘AutoMapper Bundle’
echo $destination->getDescription(); // outputs ‘A great bundle’
echo $destination->getAuthor(); // outputs ‘Michel’
[/cc_php]

Read the doc on the github to find more explanation and more functionalities: https://github.com/michelsalib/BCCAutoMapperBundle.

This is a very light implementation and some cases are not covered yet (such as dynamic graph creation). Please, don’t hesitate to fork me and provide feedback.

Meet Readr7: A new Google Reader client for windows phone 7

Meet Readr7: A new Google Reader client for windows phone 7

As you may know, I am currently developing a Github client for windows phone 7, named Gi7. It is not complete yet even if it is functional. During that development, a friend of mine asked me for a Google Reader client.

As long as I am also using Google Reader and there is not really nice free app that is better than the mobile website, I decided to take au pause in the development of Gi7 to start a new app named Readr7. Hopefully the app is smaller and I shall continue the development of Gi7 soon.

What it does

Stream
Stream

The Readr7 app just does what a light Google Reader client should do.
– You can login and logout from your Google account.
– Then you have all your unread items with abstracts. They are automatically marked as read when scrolling the feed.
– You can of course access a configuration panel to selected folder and choose to see also marked as read items.
– Just tap on an item to open IE or make a long tap to manually mark as read/unread.
– Last but not least, if you pin the app to your home, the tile will be updated every 30 minutes with your unread items count.

About the development

As usual, I published the code to Github here. It shares some stuffs and concepts with the Gi7 app. You can of course get the code and contribute to the repo.

The code is almost finished. I just need to review some design (get a logo for instance), and bugs. About the last point, it is very important for me to get some external feedback, especially from developers who may run into error I did not though about and thus help be debug some issues.

About Google Reader, the bad thing is that it doesn’t have any official API. You can find some doc, but things may change without any advance notice. Whatever, the best doc I found is here: http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI.

As usual, I used my favorite tools:
RestSharp for fast access to the Google Reader API with easy json deserialization
MVVM light toolkit for easy use of the MVVM pattern
Silverlight Toolkit for Windows Phone that I recompiled for mango

Last but not least, I add a post build instruction to copy the xap file to the root of the solution so that you can directly download the last app version on github.

Meet Gi7 : A new github app for Windows Phone 7

Meet Gi7 : A new github app for Windows Phone 7

As you may know, I am not only a Symfony2 developer. I also enjoy a lot coding C#, especially Silverlight on the Windows Phone platform. Most of the time, I try to keep working on both technologies because they bring me complementary knowledge about good practices and design patterns. Also it prevents me from getting bored too fast on a project.
I am currently finishing my internship where I have a Silverlight 4 project using RIA Services, Prism and other cool stuffs. Thus I am looking into a new Silverlight project which is a Windows Phone 7 application called Gi7.

Gi7, the project

Gi7 is a github client for windows phone 7 that is also hosted on github.
As a matter of fact, I hope to get some help, feedback about some part of the code. I tried to make of the best practices I know, but I know things are still not perfect. Also I am not a so good UI designer, and I could use some help on the subject.
What it does
Github 7 intends to be a complete mobile application view of github. You should consult everything you need, but also post comments, accept pull request, follow users, edit a repo or a file…
It should also have a non logged part (which is not the case right know) to browse the gits and users.
For the moment you can do some nice things:
– Login/logout
– Read your news feed, get your stats, followers, followings, owned and watched repos

Homepage - newsfeed
Homepage - newsfeed
Homepage - profile
Homepage - profile



– Consult another’s user profile, with stats, followers, followings and repos

User - details
User - details
User - repos
User - repos

User - users
User - users



– Consult a repo with stats, commits, pull requests and issues

Repo - details
Repo - details
Repo - commits
Repo - commits
Repo - pull requests
Repo - pull requests



– Read a commit (in heavy dev)

The development

Actually I started the development last week on my free time, and it is going at a fast pace. I intend to have an almost full featured application around the end of august.
The application is built for the 7.1 version of windows phone 7 (aka. Mango) so that it already supports all the features of the new sdk. I make use of the MVVM light Toolkit and the RestSharp library.
Technically, I heavily make use of the MVVM design pattern with some Dependency Injection. I intend to make Gi7 a cutting-edge project while keeping things lightweight.
The Gi7 app has already nice development features, such as:
– auto caching of images.
– a Github client that automatically cache every requests and provide a very easy way to de-serialize the json api responses. Also the clients interface is very easy to bind to a view model.

Get involved, get the app

Again, I am looking for contributors and feedback about the application. Feel free to fork me, report issues, submit pull requests or ask for new functionalities: https://github.com/michelsalib/Gi7.
I intend to submit the app to the marketplace when the mango is officially released.

A twig extension that translates countries and dates

A twig extension that translates countries and dates

For today’s tutorial, we will see how to create a Twig extension that provides two filters that localize countries and dates.

What is wrong
In Symfony2, you might run into this issue. For instance, countries that are saved by form using the CountryType are stored using a two letter code. For instance you can have US for “United States”, UK for “United Kingdom”… The problem is that you cannot use it directly; you need a read string representation. Moreover, this string representation varies depending on the current locale.
Also you will have exactly the same trouble with dates, which can be “January 1rst” in English and “1er Janvier” in French.

What we need
The easiest way to handle this kind of translation is to use a twig filter. At the end we want this syntax:
– [cci]{{ user.coutnry | country }}[/cci]
– [cci]{{ user.birthday | localeDate }}[/cci]

Note that such a translation cannot be done easily without the use of the apache2 intl module. You have to install it on your server before going any further : http://www.php.net/manual/en/book.intl.php.

Create a twig extension
Adding filters into Symfony2 is quite simple. You need to create a new class that override the [cci]Twig_Extension[/cci] class.

Then we can override the [cci]getFilters[/cci] and the [cci]getName[/cci] functions.
[cc_php]
new Twig_Filter_Function(
‘MyVendorMyBundleTwigTwigExtension::countryFilter’
),
‘localeDate’ => new Twig_Filter_Function(
‘MyVendorMyBundleTwigTwigExtension::localeDateFilter’
),
);
}

public function getName()
{
return ‘myExtensionName’;
}
}
[/cc_php]

Note that at this moment the country and the localeDate are defined. When we will use them from a template they will call the defined static functions.

The country filter
The country function will use the list of countries already used by the Symfony2 form component. It is the [cci]SymfonyComponentLocaleLocale[/cci] class:
[cc_php]
<?php
namespace MyVendorMyBundle Twig;

use SymfonyComponentLocaleLocale;

class TwigExtension extends Twig_Extension {

//…

public static function countryFilter($country)
{
$countries = Locale::getDisplayCountries(
Locale::getDefault()
);

return $countries[$country];
}
}
[/cc_php]

The code is pretty straightforward. Just note that to obtain the application locale we use the [cci] Locale::getDefault()[/cci] function, this [cci]Locale[/cci] class is provided by the intl extension. Also when Twig calls the filter, it always sets as first parameter the filtered value.

The localeDate filter
The filter for the date is a little more complicate:
[cc_php]
IntlDateFormatter::NONE,
‘short’ => IntlDateFormatter::SHORT,
‘medium’ => IntlDateFormatter::MEDIUM,
‘long’ => IntlDateFormatter::LONG,
‘full’ => IntlDateFormatter::FULL,
);
$dateFormater = IntlDateFormatter::create(
Locale::getDefault(),
$values[$dateType],
$values[$timeType]
);

return $dateFormater->format($date);
}
}
[/cc_php]

First of all we added two more optional parameters. They will serve to override the kind of rendering we want for the filtered date. We can use them like this :
– [cci]{{ user.createdAt | localeDate(‘long’,’medium’) }}[/cci] for a long date and a medium time representation

Then we create a date formatter which is an instance of [cci]IntlDateFormatter[/cci] parameterized with our format parameters. I used an associative array to translate string parameters to the supported contants.

Then we can simply format the date and return it using the [cci]format[/cci] function.

Activate the twig extension
In order to activate the twig extension, you need to register it as a service to the container. In order for the container to know it is a twig extension, you need to add the [cci]twig.extension [/cci] tag.

Just add to your [cci]config.yml[/cci] file:
[cc]
services:
bcc.twig.extension:
class: MyVendorMyBundleTwigTwigExtension
tags:
– { name: twig.extension }
[/cc]

Wrap up
We build a nice powerful twig extension that provides two filters that helps localize countries and dates.

You simply add the extension to your project by checking out the BCCExtraToolsBundle : https://github.com/michelsalib/BCCExtraToolsBundle.