Seguire le Olimpiadi di Sochi dall’Italia

Gli appassionati italiani di sport invernali non portanno seguire le Olimpiadi Invernali di Sochi sulla RAI. Se non hai SKY e non vuoi perdere neanche una gara ecco come seguire le Olimpiadi dal tuo computer:

  1. Crea un account sul sito http://www.unotelly.com/unodns/signup, cliccando su “try for free”
  2. Per vedere le olimpiadi in Inglese, (BBC2), selezionare United Kingdom nella sezione WDTV Owner
  3. Cliccare su ‘Continue to step 2′
  4. Selezionare il sistema operativo in utilizzo e seguire le istruzioni per impostare  UnoDNS
  5. Accedere al sito http://www.bbc.co.uk/iplayer/tv/bbc_two_england/watchlive

Il servizio sarà gratuito 8 giorni quindi non basterà per coprire l’intera durata delle olimpiadi, alla scadenza del periodo di prova occorrerà pagare secondo questa tabella http://www.unotelly.com/unodns/pricing.

Una volta finite le olimpiadi si consiglia di ripristinare le impostazioni del computer a meno che non si volgia continuare ad utilizzare il servizio UnoDNS.

Buona visione

P.S. per godere di una migliore visione collegate il vostro computer alla televisione.

WordPress Custom Type with Custom Post Field

Last days I’ve been developing a very simple custom post type for WordPress.

The aim was to allow the user to create an event, which in this case consists of:

  1. title
  2. description
  3. date

Title and description are already provided by the wordpress built-in post type, that means we just need to teach wordpress how to manage date.

In order to keep the code clean all the Custom Type’s code is inside a class Event which is inside a folder ‘custom_types’ whithin the theme’s folder.

/theme/custom_types/Event.php

[php]

class Event
{

}

[/php]

Then we add the class methods to WP on the functions.php after including the class itself:

    require(“custom_types/Event.php”);

First of all WP needs to know about our Post Type so that it has to be registered

[php]
public static function create()
{
register_post_type(‘event’,
array
(
‘description’ => __(‘Events’),
‘labels’ => array
(
‘name’                    => __(‘Events’),
‘singular_name’            => __(‘Event’),
‘add_new’                => __(‘Add New’),
‘add_new_item’            => __(‘Add New Event’),
‘edit_item’                => __(‘Edit Event’),
‘new_item’                => __(‘New Event’),
‘view_item’                => __(‘View Event’),
‘search_items’            => __(‘Search Events’),
‘not_found’                => __(‘No events found’),
‘not_found_in_trash’    => __(‘No events found in Trash’),
‘parent_item_colon’        => ”
),
‘supports’ => array(‘title’, ‘editor’),
‘public’ => true,
‘capability_type’ => ‘post’,
‘show_ui’ => true,
‘publicly_queryable’ => true,
‘hierarchical’ => false,
‘menu_position’ => null,
‘query_var’ => true,
‘taxonomies’ => array(‘post_tag’, ‘category’),
‘has_archive’ => true,
‘rewrite’ => array(‘slug’ => ‘events’)
)
);
}
[/php]

we add this method to WP on the functions.php file via:

    //add custom post type to WP
add_action(‘init’, ‘Event::create’, 0);

Making the long story short register_post_type says to WordPress:

‘hey you, here is my custom type and it has the following features’

the meaning of all these features is well explained on the official documentation.

Now i’s time to add our columns

[php]

public static function columns($columns)
{
return array
(
‘title’            => __(‘Title’),
‘event_date’    => __(‘Event Date’),
‘author’        => __(‘Author’),
‘tags’            => __(‘Tags’)
);
}

[/php]

Add to WP:

    //custom columns
add_filter(‘manage_edit-event_columns’ , ‘Event::columns’);

N.B. -event is the name of our custom post type

Here we are defining which columns will be used on the listing table of our custom type, the parameter $custom contains the default post columns, we could decide to unset some of them and add ours or (as shown above) just return an array with the columns we want.

As you can see we return 3 ‘built-in’ columns (title,author,tags) + our custom column (event_date).

WordPress also need to know what to output for each custom columns:

[php]

public static function backend_view($column)
{
global $post;

switch($column)
{
case ‘event_date’ :
{
echo(Event::get_date($post));
break;
}
}
}
[/php]

Add to WP:

    //backend visualization
add_action(‘manage_posts_custom_column’, ‘Event::backend_view’);

here we say: ‘whenever you are rendering something about column event_date, print the Event’s date, we will se later on what’s inside Event::get_date($post), remember Event is the class containing our Custom Post type definition.

At this stage we are ready to find out a new menu point on the admin backend called ‘Events’, the table listing all the events (no one until now) and the page to edit/insert a new Event.

What? there is no ‘event date’ field on the edit page?
Yes, we need to specify a custom post field in order to be able to add this feature to our Events.

Adding the possibility of Managing custom columns

The previous steps don’t provide the feature on inserting/editing our custom column, to fix that point we need to introduce a custom post field:

[php]

public static function editor()
{
add_meta_box(‘event_date_box’, __(‘Event Date’), ‘Event::date_edit’, ‘event’, ‘normal’, ‘low’);
}

public static function date_edit()
{
global $post;
$start = Event::get_date($post);
echo("<label for=’start_date’>Data:</label><input type=’text’ name=’event_date’ class=’event_date’ value='{$start}’ />");
}

public static function date_insert()
{
global $post;

if(!preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/([0-9]{4})$/", $_POST['event_date'], $pieces))
return;
else
update_post_meta($post->ID, ‘event_date’, mktime(0,0,0,$pieces[2],$pieces[1],$pieces[3]));
}

public static function date_delete()
{
global $post;
delete_post_meta($post->ID, ‘event_date’);
}

[/php]

add to WP:

    //add custom fields to the editor
add_action(‘add_meta_boxes’, ‘Event::editor’);
//manage event_date
add_action(‘save_post’, ‘Event::date_insert’);
add_action(‘delete_post’, ‘Event::date_delete’);

add_meta_box add a new box on the post editing page, the third parameter is the one which specify which function will render the box.

As you can see Event::date_edit outputs an input field which our users will insert the date.

We need to define also what WP should do with the user input once the post is saved/deleted.

In the first case we store the input on the database by means of date_insert (actually here we check the date format and if it is valid we turn it into timestamp befora storing).

update_post_meta add/update a custom post field with name ‘event_date’ at the event we are saving.

The custom value is retrieved from the database and shown on he input if the alue itself exists, the methon by which we search for the value is the previously seen ‘Event::get_date':

[php]

private static function get_date($post)
{
$data = get_post_custom_values(‘event_date’, $post->ID);
if(count($data))
return date(‘d/m/Y’,array_shift($data));
else
”;
}

[/php]

Here we search for the custom value on the db, if it exists we turn in back to a human-readable date otherwise just return an empty string.

In case we delete and event we teach wordpress how to delete the custom field ‘event_date’ by means of delete_post_meta.

Now we are done, our brand new Event Custom Type it’s on-line and users has the possibility of inserting the event date.

Anyway we could make the input a little bit more user-friendy with help of jquery…

Adding jQuery to our event date input

we need to include jquery and jqueryUI to the admin:

[php]

public static function add_js()
{
wp_enqueue_script(‘jqueryui’, ‘https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js’);
wp_enqueue_script(‘jquery_i18n’, ‘http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/i18n/jquery-ui-i18n.min.js’);
wp_enqueue_script(‘admin’, WP_CONTENT_URL . ‘/themes/theme/js/admin.js’, array(‘jquery’,’jqueryui’,’jquery_i18n’));
}

[/php]

jquery is already present on WordPress, thet’s why we pick just jqueryUI and all it’s translations from the Google CDN. Then we load our javascript (which is located on the js folder of our theme) setting as dependencies jquery, jqueryUI and its translations.

The same way we load the css styleshit:

[php]

public function add_css()
{
wp_enqueue_style(‘jqueryui’, ‘http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/flick/jquery-ui.css’);
}

[/php]

Add to WP:

    //add javascript support
add_action(‘admin_print_scripts’, ‘Event::add_js’);
//add css style
add_action(‘admin_print_styles’, ‘Event::add_css’);

This way we make WP load all the scripts we need.

Finally we can write the few lines we need to properly add a calendar to our Event Date Input:

[javascript]

jQuery(document).ready(function()
{
jQuery(‘input.event_date’).datepicker({dateFormat: ‘dd/mm/yy’});
jQuery(‘input.event_date’).datepicker(‘option’,jQuery.datepicker.regional["it"]);
//close if opened on page load
jQuery(‘#ui-datepicker-div:visible’).hide();
});

[/javascript]

Here we go, now our custom post type admin interface in ready!

Complete Code

Event.php

[php]

<?php

class Event
{
public static function create()
{
register_post_type(‘event’,
array
(
‘description’ => __(‘Events’),
‘labels’ => array
(
‘name’                    => __(‘Events’),
‘singular_name’            => __(‘Event’),
‘add_new’                => __(‘Add New’),
‘add_new_item’            => __(‘Add New Event’),
‘edit_item’                => __(‘Edit Event’),
‘new_item’                => __(‘New Event’),
‘view_item’                => __(‘View Event’),
‘search_items’            => __(‘Search Events’),
‘not_found’                => __(‘No events found’),
‘not_found_in_trash’    => __(‘No events found in Trash’),
‘parent_item_colon’        => ”
),
‘supports’ => array(‘title’, ‘editor’),
‘public’ => true,
‘capability_type’ => ‘post’,
‘show_ui’ => true,
‘publicly_queryable’ => true,
‘hierarchical’ => false,
‘menu_position’ => null,
‘query_var’ => true,
‘taxonomies’ => array(‘post_tag’, ‘category’),
‘has_archive’ => true,
‘rewrite’ => array(‘slug’ => ‘events’)
)
);
}

public static function columns($columns)
{
return array
(
‘title’            => __(‘Title’),
‘event_date’    => __(‘Event Date’),
‘author’        => __(‘Author’),
‘tags’            => __(‘Tags’)
);
}

public static function backend_view($column)
{
global $post;

switch($column)
{
case ‘event_date’ :
{
echo(Event::get_date($post));
break;
}
}
}

public static function editor()
{
add_meta_box(‘event_date_box’, __(‘Event Date’), ‘Event::date_edit’, ‘event’, ‘normal’, ‘low’);
}

public static function date_edit()
{
global $post;
$start = Event::get_date($post);
echo("<label for=’start_date’>Data:</label><input type=’text’ name=’event_date’ class=’event_date’ value='{$start}’ />");
}

public static function date_insert()
{
global $post;

if(!preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/([0-9]{4})$/", $_POST['event_date'], $pieces))
return;
else
update_post_meta($post->ID, ‘event_date’, mktime(0,0,0,$pieces[2],$pieces[1],$pieces[3]));
}

public static function date_delete()
{
global $post;
delete_post_meta($post->ID, ‘event_date’);
}

public static function add_js()
{
wp_enqueue_script(‘jqueryui’, ‘https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js’);
wp_enqueue_script(‘jquery_i18n’, ‘http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/i18n/jquery-ui-i18n.min.js’);
wp_enqueue_script(‘admin’, WP_CONTENT_URL . ‘/themes/theme/js/admin.js’, array(‘jquery’,’jqueryui’,’jquery_i18n’));
}

public function add_css()
{
wp_enqueue_style(‘jqueryui’, ‘http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/flick/jquery-ui.css’);
}

private static function get_date($post)
{
$data = get_post_custom_values(‘event_date’, $post->ID);
if(count($data))
return date(‘d/m/Y’,array_shift($data));
else
”;
}
}

[/php]

functions.php

[php]

/*
* CUSTOM POST TYPE: EVENTS
*/
require("custom_types/Event.php");
//add custom post type to WP
add_action(‘init’, ‘Event::create’, 0);
//custom columns
add_filter(‘manage_edit-event_columns’ , ‘Event::columns’);
//backend visualization
add_action(‘manage_posts_custom_column’, ‘Event::backend_view’);
//add custom fields to the editor
add_action(‘add_meta_boxes’, ‘Event::editor’);
//manage event_date
add_action(‘save_post’, ‘Event::date_insert’);
add_action(‘delete_post’, ‘Event::date_delete’);
//add javascript support
add_action(‘admin_print_scripts’, ‘Event::add_js’);
//add css style
add_action(‘admin_print_styles’, ‘Event::add_css’);

[/php]

admin.js

[javascript]

jQuery(document).ready(function()
{
/*
* datepicker
*/
jQuery(‘input.event_date’).datepicker({dateFormat: ‘dd/mm/yy’});
jQuery(‘input.event_date’).datepicker(‘option’,jQuery.datepicker.regional["it"]);
//close if opened on page load
jQuery(‘#ui-datepicker-div:visible’).hide();
});

[/javascript]

Common Expenses: Lazy Loading

When developing the POJO classes for mapping the database I set the fetch type to LAZY. At first i didn’t pu much interes on it but then when I was actually fetching the data from DB I had to lern it better.

The target was to display all project’s data on a page, my first idea was to simply retrieve the project from db

[java]
(Project)session.get(Project.class, 1)
[/java]

and then display it:

[html]
<h3>${project.name}</h3>
<p>${project.description}</p>
<ul>
<c:forEach var="expense" items="${project.expenses}">
<li>${expense.name}</li>
</c:forEach>
</ul>
[/html]

But this didn’t worked. When an entity is instanciated all its collelctions are defined but the content is not loaded, infact lazy loading means Hibernate would fill the collenctions when them are requested.

If you try to retrieve all project’s expenses into the EJB there are no problems as an Hibernate session is opened. When we are into the view context (JSP in this case) there are no Hibernate sessions opened that’s why the expense collection could not be retrieved.

If the fetch mode is set to EAGER Hibernate load all entities collection whe the entity itself is istanciated. The view above would display all the data correctly but if we add a new expense it won’t be added to the collection as the main entity has already benn loaded.

The best solution would be create a Filter which open and close an Hibernate session at view context to lazy load the collections whenever are needed but seems like this way-around exists only in Spring Framework.

The fixeed this problem with in a ‘dirty’ way building a emporary container which collect the projects data every time the page is requested. This is not as performant as lazy loading because it fetches all the data at each request. But it finally make the view display all data.

Common Expenses: Design Pattern

This post should have been one of the first actually.

Here is described the design pattern used on Common Expenses, I’ve used MVC as it is very straight forward: separate data management (model), application login (controller) and presentation (view).

As I post earlier the persisten layer is made with Hibernate, then the Businnes Login is implementend via Stateless EJB.

The application controller is a set of Servlet which get requests, work out them and send the result to the presentation layer.

The presentation layer is implemented with JSP.

Here is a schema of the whole application:

MVC
MVC

Common Expenses: EJB

To communicate with POJO entities I’m going to use EJB version 3.1.

As done before I will use annotation instead of a XML configuration file.

I will come back later with a full post on how to couple EJB with Hibernate.

Essentialy we need an Interface for make the bean accessible from other tools (in this case I’ll use Servelt to access EJB):

[java]
@Remote
public interface RegisterBeanRemote
[/java]

Remote means that this is he ‘server‘ class, in this instance our client will be the Servlets but if it would have been another java application we would have to distinguish between Remote and Local.

When the interface is ready we need a class to implement it:

[java]
@Stateless
public class RegisterBean implements RegisterBeanRemote
[/java]

Stateless means that the bean doesn’t keep a ‘memory‘.

There’s no need to use JNDI explixity because annotation will do it for us.

Common Expenses: Hibernate

Here we start coding (finally)!

As I wrote before I’m going to use Hibernate as ORM (Object Relational Mapper).

I very few words Hibernate map database tables to POJO classes to achieve persistency. To make the class map correctly the table we need to add some extra information to the code. This could be done with an XML file for each class (let’s call it Entity from now) or with annotations.

I choose annotations (JPA ones implemented by Hibernate) because I think is better to keep everithing on the same file and I do not have to switch from a Java file to an XML file.

My first idea was to generate that classes automatically and actually i did it with Hibernate Tools for Eclipse, but I was not satisfacted with the generated code, so decided to do the other way round and generate the tables from the classes.

It was not so easy to find out how to achive it but after a deep deep deep digging in google I’ve discovered a great tutorial site with many examples for Hibernate. Moreover the examples on that site are done with the last version of Hibernate.

Here is the code of User POJO class:

[java]

@Entity
@Table(name = "user")
public class User implements java.io.Serializable
{

[/java]

Here we say that User is an Entity bound to the tabe user

[java]
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private int id;
[/java]

The primary key of user table is a generated auto-increment int, the PK column name is id

[java]
@Column(name = "username", unique = true, nullable = false, length = 255)
private String username;

@Column(name = "password", nullable = false, length = 255)
private String password;

@Column(name = "email", unique = true, nullable = false, length = 255)
private String email;

@Temporal(TemporalType.DATE)
@Column(name="meta_ts", nullable=false)
private Date meta_ts = new Date();

@Column(name = "meta_user", nullable = false)
private int meta_user;

[/java]

Each other class variable is bound to the appropriate column on the table

[java]
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<Expense> expenses = new HashSet<Expense>(0);

@OneToMany(fetch = FetchType.LAZY, mappedBy = "meta_user")
private Set<Expense> created_expenses = new HashSet<Expense>(0);

@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<DefaultShare> default_shares = new HashSet<DefaultShare>(0);

@OneToMany(fetch = FetchType.LAZY, mappedBy = "meta_user")
private Set<DefaultShare> created_default_shares = new HashSet<DefaultShare>(0);

@OneToMany(fetch = FetchType.LAZY, mappedBy = "meta_user")
private Set<ExpenseCategory> categories = new HashSet<ExpenseCategory>(0);

@OneToMany(fetch = FetchType.LAZY, mappedBy = "meta_user")
private Set<Project> projects = new HashSet<Project>(0);

[/java]

One to Many relations, we need to proviede the Entity linked to User and also the Foreign Key which refers to the User entity on the other table

Follows auto-generated contructors and setters/getters.

I really like annotations because they are self-explaining and could almost replace comments.

Common Expenses: ER Schema

This is the ER schema for the database of Common Expenses application:

ER Schema
ER Schema

The schema itself should be quite self-explaining anyway here are the main points:

  • meta_ts and meta_user are logging data they represent date and user of tuple creation.
  • OneToMany relationship between Project and Expense
  • OneToMany relationship between User and Share
  • OneToMany relationship between Expense and Share
  • ManyToMany relationship between User and Project, there are a join table (Partecipate) for this relationship which hold also the leader of a project.

I’m going to make Hibernate generate the database form me so I’m quite sure the final schema will be slighty different from the one above.

Common Expenses: Use Case Diagram

Here is the use case diagram of my application:

Use Case Diagram
Use Case Diagram

Basically there are two kinds of user: the project leader and project’s partecipants. Who create a project becomes its leader so an user could be both leader or partecipant depending on the project instance.

The Leader manage a project by setting/editing the basic information (name, description,…) and by managing other users allowing them to join the project and eventually set them default share for expenses.

The Partecipant first has to join a project and wait for leader’s approval, then he can add expense to the project decide which project’s users take part to it. Partecipant can also consults there periodic report of the project (by month, year).

Clearly each user has to register to the application and then log-in to be authorized to perform operation on the system.

Common Expenses: Working Place

Face a new project imply selecting the tools/technologies you’ll be using during developement.

Here is a brief excursus on what I’ll use.

IDE: Eclipse

Eclipse is a very powerfull IDE, I’m using it every day at work for PHP developing that’s why i feel so comfortable with it. Furthermore Eclipse has born for Java developing so i thing this is the right choice.

DBMS: MySQL

Because it’s free and I know it quite well since I’m using it for more than 6 years, I could choose SQL Server (the one we use at work) but since it is not free and I’m developing on a Mac that’s it. Moreover MySQL has MySQL Workbench which is a very usefull tool form designing/managing databases.

ORM: Hibernate

This is a project requirement, but i would have use it the same as it seems the most used out there and i want to learn it.