What is MVC?

The MVC design pattern separates business logic from user interface

Model–View–Controller is a design pattern or a software engineering concept that separates the model, the view and the controller from each others, thus dividing the labour in your application in such a way that:

The model is the brain, the knowledge, or simply data and means to using it:

  • it knows where data is, how to access it and how to change it
  • it responds to requests about data state
  • it responds to instructions to change data state

The view holds the presentation logic like templating and caching, in a PHP MVC application it may range from a few  html templates with PHP tags for inserting request specific data to a bunch of templates using a templating engine such as Smarty.

The controller acts as the mediator, like a  front desk agent or the guy that takes your order and serves your dish at a McDonald’s:

  • it receives the client (visitor’s browser) input in the form of GET or POST requests
  • it could possibly verify and validate user input
  • it instructs a the model to execute a specific action depending on the input it received

The Key benefits of using MVC

Separation of concerns

By separating the data logic (the model), the presentation logic (the view) and the application logic (the controller) you make sure that there is no interference between the three allowing you to work on and optimize each one dependently from the other two.

Let’s assume a scenario where we have a data driven website that we made with MVC in mind, this website needs a graphical redesign, we’ll simply hire an excellent web designer, which happens to be not so good at programming but we don’t care, all he will see is the website template files (our views).

Now we heard that PostgreSQL offers better performance and we want to switch from X to PostgreSQL, fine, all we have to do is migrate our database and modify our model, of course we will not modify a single line on the controller or view logic.

Code reuse

Data returned by the model  is “pure” data, free from any formatting or presentation, when you need to present data to the user you write a view or more if you are offering the same data in many formats (HTML, XML, file for download…). The model is written only once and is reused by the views, there is no code duplication and you don’t waste your time rewriting code that does the same or almost the same thing.

By using MVC, you will end up having a library of well organized components that you can reuse on the same application and in other applications as well, this will drastically increase your productivity.

PHP code to remove breadcrumbs in a Drupal page

Sometimes you want to hide the breadcrumbs in a single page an keep it in the others, either using a module or inside a node.

You can remove the breadcrumb from a Drupal page with this line of code:

This is how I do it:

drupal_set_breadcrumb(array());

Drupal Views: Show count

The view results count is stored in the view object and you can display it by adding a PHP header or footer to your view. In order to have PHP in views you need the module Views PHP, so install it first then add a header or footer with this code.

<?php
// Dispaly count
$view = views_get_current_view();
echo '

'.$view->total_rows.' result(s)'.'

'; ?>

Drupal: Send email

This is a quick and easy solution to send an email from Drupal using PHP, i.e a custom module. you will do it in 2 steps (I assume your module is called “mod”):

  • Define mod_mail() (implementing hook_mail() ), this function will prepare the email
  • Send the email using drupal_mail()

Define mod_mail()

/**
 * Implementation of hook_mail.
 */
function mod_mail($key, &$message, $params) {
  switch ($key) {
    case 'basic':
      $message['subject'] = t('Greetings');
      $message['body'] = array(t('I just wanted to say hello!'));
      break;
    case 'advanced':
      $message['subject'] = t('Hello @username', array('@username' => $params['username']));
      $message['body'] = array(t('Thank you for joining @site_name!', array('@site_name' => $params['site_name'])));
      break;
    default:
      ; /* Do nothing */
  }
}

Sending the email

In order to send the email you need to decide on 2 parameters (optionally, a 3rd):

  1. The recipent (email address)
  2. The key, in this example this would be ‘basic’ or ‘advanced’
  3. The $params to pass to mod_mail(), in our example it’s only needed if we are using the key ‘advanced’
// Basic example ($key = 'basic')
$email = "someone@example.com";
drupal_mail('mod', 'basic', $email, language_default());


// Advanced example ($key = 'advanced')
$email = "someone@example.com";
$params = array(
  'username' = 'Someone',
  'site_name' = variable_get('site_name'),
);
drupal_mail('mod', 'advanced', $email, language_default(), $params);

Drupal 7: Get files public directory path

We used to get the files directory using file_directory_path() in Drupal 5 and 6, the function was removed with Drupal 7 but you can still get the files public directory like this:


echo variable_get('file_public_path', conf_path() . '/files');

// Outputs: sites/default/files

Drupal : Get path and verify if it’s an alias

This is how I get the current path and/or alias in Drupal:
After this code has been executed:
$path will hold the internal drupal path
$alias will hold that path alias if the path in the url is actually an alias, otherwise FALSE;

$path_from_url = isset($_GET['q']) ? $_GET['q'] : '';
$path = drupal_get_normal_path($path_from_url);
if($path === $path_from_url) 
  $alias = FALSE;
else 
  $alias = $path_from_url;

Fix “xyz.widget is not a function” when jQuerying in Drupal

The error looks like:

c.widget is not a function

Or:

d.widget is not a function

I get this error when I do theming or module development for Drupal. Basically this tells you that the file jquery.ui.widget.js is missing. check the code you were writting and add that file to Drupal like this:

drupal_add_js('misc/ui/jquery.ui.widget.min.js');

Super key / Alt+F2 not working in Ubuntu 11.10

This happened to me in Ubuntu 11.10 (Oneiric Ocelot) when I was playing with some Compiz settings. To have your shortcuts back, go to the CompizConfig Settings Manager, to do that bring up a terminal window with the shortcut ctrl+alt+t the type ccsm:

imame@meta:~$ ccsm

If you are using Unity open Desktop > Ubuntu Unity Plugin but if you are using Gnome shell choose General > Gnome Compatibily – anyways, choose whichever is already checked, one the next window check that the shortcuts are enabled and configured correctly

Compiz > Unity
Compiz > Unity
Compiz > Gnome Compatibility
Compiz > Gnome Compatibility

Classical Gnome in Ubuntu 11.10 (Oneiric Ocelot)

Install necessary packages

In order to have Gnome classical appearance on Ubuntu 11.10 you need to install gnome-shell and gnome-panel, a following reboot -from my experience – is preferable.

imame@meta:~$ sudo apt-get install gnome-shell gnome-panel
imame@meta:~$ # blabla while packages are being installed
imame@meta:~$ sudo reboot

Log in using Gnome Classical

Before opening your session, clear the gear next to your name and choose Gnome Classical.

Tweak with Gnome Tweak Tool

You can personalize you desktop with the Gnome Tweak Tool:

imame@meta:~$ sudo apt-get install gnome-tweak-tool

The launcher is located here: Applications > Others > Advanced Settings

Where is “Add to panel” and others?

Now in order to have the penel related options a simple right click won’t work, you need to Alt+ right click

Thanks for reading!

Age from date of birth in Drupal 7

In this tutorial I’m gonna show you how to calculate and display properly the age from a date CCK field the simplest way. The method I’m about to show you doesn’t need the Views module and if you use Views you’ll find that it’s totally compatible without adding any PHP code.

Requirements

Before starting I want you to meet the following requirements in order to follow this tutorial:

  • Install and enable the Computed_field module
  • Install and enable the Date module (Date API, Date & Date popup)
  • Install and enable the Rules module
  • Enable the core PHP filter module
  • Add a date field to an existing content type (let’s call it field_dob)

For the purpose of this tutorial I created a very simple content type named Candidate with only 2 fields:

  • I changed the title from Title to Full name and removed the Body field
  • I added a Date field and named it field_dob

Add a computed field

Now let’s add a new field with Age as a label and field_age as a name and Computed as a field type.
In the next screen we will set the field settings:

  • Computed Code (PHP):
    $entity_field[0]['value'] = ( time() - strtotime($entity->field_dob[LANGUAGE_NONE][0]['value']) ) / 86400 / 365.25;
    
  • Display Code (PHP):
    $display_output = floor($entity_field_item['value']);
  • Data type: Decimal
  • Decimal Scale (decimal): 3

Add content and test

Now let’s add a few items and see if it works as we expected, I added a couple of entries and tested:

  • Old KADIMI (born on 1 Jan 1990) => Age computed 21
  • Young KADIMI (born on 2 Jan 1990) => Age computed 21

Sorting with Views

You may want to use the Views module to accommodate the output to your needs, one of the features of the Views module is that it enable you to sort results.

So what if we wanted to sort our candidates by age, Both KADIMI brothers (Old and Young) are 21 years old but Old is 1 day older that Young, for Drupal they have the same age and the result of the sorting may be inaccurate, actually we already fixed this issue by storing the age as a decimal number with 3 decimal points and displaying it as an integer (by using floor), by looking into the database table field_data_field_age with phpMyAdmin:

  • Young KADIMI is 21.570 years old
  • Old KADIMI is 21.573 yeas old

Update age

In order to recompute a candidate age we must re-save that candidate node, one way to do this is using Rules and Drupal cron

  • Visit /admin/config/workflow/rules/reaction/add to add a rule, give it a descriptive name like “Re-save candidates nodes”
    Set React on event to: Cron maintenance tasks are performed
  • Add a new action
    Set Select the action to add to: Execute custom PHP code
    Set the PHP code to:

    $old   = '1 day';      # Content is considered outdated if older than {$old}
    $type  = 'candidate';  # Apply to nodes of type {$type}
    $limit = 20;           # Update {$limit} nodes per cron
     
    $old = strtotime("now - $old");
    
    $sql = '
      SELECT n.nid FROM {node} n
      WHERE n.type = :type
        AND n.changed  < :old
      ORDER BY n.changed ASC
      LIMIT :limit
    ';
    
    $sql_vars = [
      ':type' => $type,
      ':old' => $old,
      ':limit' => $limit,
    ];
    
    $nids = db_query($sql, $sql_vars);
     
    foreach ($nids as $nid){
       $node = node_load($nid);
       node_save($node);
    }

    Tweak the 3 parameters in a way that suits your needs and that’s it!

Need help?

If you found this tutorial difficult and couldn’t follow the instructions you can ask for help on the comments section or you can hire me and I will take care of this for you.

PHP: remove an array item by value

It isn’t quite obvious to remove an array item when all you know is the value of that item, – i.e. you don’t now the item index.

Remove items without preserving original indexes

$the_array = array_values(array_diff($the_array,array($the_value)));
// Example
$the_array = array('A', 'B', 'B', 'C');
$the_array = array_values(array_diff($the_array,array('B')));
/* 
Original array:
     [0] => A
     [1] => B
     [2] => B
     [3] => C
After removing 'B':
     [0] => A
     [1] => C
*/

Remove items and preserve indexes

Based on Tobias code

while($key = array_search($the_value, $the_array)){unset( $the_array[$key]);}
// Example
$the_array = array('A', 'B', 'B', 'C');
while($key = array_search('B', $the_array)){unset( $the_array[$key]);}
/* 
Original array:
     [0] => A
     [1] => B
     [2] => B
     [3] => C
After removing 'B':
     [0] => A
     [3] => C
*/

Drupal : Add classes to $body_class

$body_classes variable and how it’s used

By default, Drupal provides Drupal themes coders with a variable $body_classes which contains a list of space separated keywords that you can use to style your page depending on different factors including the user status (logged in or not), the page he is viewing (frontpage, node, page, story…).

Make use of $body_classes on your theme like this

<body class="<?php print $body_classes; ?>">

Here are a few exmaples of $body_classes for different visitors:

  • $body_styles: front not-logged-in page-node no-sidebars
  • $body_styles: not-front logged-in page-node node-type-blog no-sidebars

You can easily tell that the first line corresponds to a user not logged in, he is viewing the frontpage, the 2nd line is from a user who is logged in and is probably reading a blog post. Both visitors are viewing a page with no sidebars (the admin of the site decided so)

It’s very easy, using these classes to present things differently depending on what suits your needs (user status, current node type, sidebars)

You can find more about the logic behind this variable one the Drupal API Reference

Add more classes to $body_classes

Now what if you need more than those default classes, you can think of many examples; I – as the administrator of a Drupal site – want a big red banner to remind me to logout if I’m using my administrator account instead of my normal account.

The proper way to this is by using the theme hook template_preprocess_page like this (replace theme_name), we add the function theme_name_preprocess_page to our template.php file, Drupal will automatically run that code and add the new classes that we want:

<body class="<?php
function theme_name_preprocess_page(&$variables) {
  $body_classes = array($variables['body_classes']);
  // if the user is the admin add the class is_admin
  if ($variables['is_admin']) {
    $body_classes[] = 'is_admin';
  }
  // ... more magic here if you want to add  more classes ...
  $variables['body_classes'] = implode(' ', $body_classes);
}?>">

Now you can add more if clauses to the function to have the classes you need.

MySQL World Cities database installation

MaxMind offers a free cities database, the database contains more than 2.7 mil. locations, you can download it at MaxMind’s website.

Once you have downloaded the compressed database, extract the file worldcitiespop.txt and invoke the MySQL client (preferably from the same directory where the worldcitiespop.txt file resides).

Create the world database and the cities table

Here is the structure for the world database (remove the first two lines if you already have a database):

-- Database: `world`
CREATE DATABASE `world`;
USE `world`;

-- Table: `cities`
CREATE TABLE IF NOT EXISTS `cities` (
  `Country` char(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `City` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `AccentCity` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `Region` char(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `Population` int(10) unsigned NOT NULL,
  `Latitude` float NOT NULL,
  `Longitude` float NOT NULL,
  KEY `AccentCity` (`AccentCity`(5)),
  KEY `City` (`City`(5))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Import cities from worldcitiespop.txt into database

LOAD DATA LOCAL INFILE _path_to_file_
  INTO TABLE `cities`
  FIELDS
    TERMINATED BY ','
  LINES
    TERMINATED BY 'n'
  IGNORE 1 LINES;

_path_the_file_ can be either an absolute path or relative path (relative to the folder from where you invoked the MySQL client), so in case you followed my instructions and invoked the MySQL client from the directory that contains the file worldcitiespop.txt, _path_to_file_ will be worldcitiespop.txt.

The file worldcitiespop.txt is as big as 130 MB so the process may take very much longer than a few seconds

What’s next? up to you…

Now that the database is installed you can use it for your application, I use it on one of my websites where users can choose one or more cities on their profiles, then they get a daily weather forecast for those cities.

Add or Remove a word from Firefox dictionary

Lappy, touchpad, plugin, WordPress, vlog… and many other words are not (yet) recognized by Firefox, each time you use any of them Firefox will underline them in red, it would be better not to be bothered by these lines every time you write a “common” word which is not listed in the dictionary.

Add a Word to Firefox dictionary:

Right click on the word and click “Add to Dictionary” or press “o”.

Remove a Word from Firefox dictionary:

Firefox profile directory

It happens sometimes -specially when using a lappy touchpad, that you add by mistake  misspelled word to your Firefox personal dictionary, this how to remove them:

  1. Locate the file persdict.dat (this manipulation is OS independent):
    • At the top of a Firefox window, on the menu bar, click Help> Troubleshooting Information, if the menu bar is hidden press the alt key once to reveal it.
    • A new page will open, click on the button that says Open Containing Folder, this opens the Profile Directory, the button is located under Application Basics
    • Find the file persdict.dat
  2. Close Firefox, otherwise your changes in step 3 will be lost
  3. Open the file persdict.dat on a text editor, you will see that each word you added to the dictionary  constitutes a line in persdict.dat, remove unwanted lines and save… that’s it