I’m just putting this up so I don’t forget, if someone finds it useful awesome. When i upgraded to PHP5.3 a lot of thing that were enabled by default in previous version were disabled. When I install XDebug I expect to see my pretty orange tables with errors and a stack trace. That feature has also been disabled.

To enable it just find the the line

html_errors=Off

and change it to

html_errors=On

“Function overloading or method overloading is a feature found in various programming languages such as Ada, C#, VB.NET, C++, D and Java that allows the creation of several methods with the same name which differ from each other in terms of the type of the input and the type of the output of the function.” — Wikipedia(http://en.wikipedia.org/wiki/Function_overloading)

I’m sure by now you have realised that PHP does not natively support function overloading. It can get annoying, especially if like me you are from a Java(Or whatever Full OO language you’re from) background. I doubt its coming to PHP anytime soon, haven’t really looked at the road map but from first glance it would be too big a change and render function like __call(), __get(), __set() a bit useless. So what is a developer with too much time in his hands to do? Well come up with a way to simulate this behavior of cause :)

Lets have a quick look at a scenario:

So you write a function to add two numbers and return the sum. Lets call it sum():

function sum($a, $b){
return $a + $b;
}
echo sum(3,5); //8 :) works

And then you decide you want a function to “add”(concatenate) two strings, lets call it concatenate():

function concatenate($a, $b){
return $a . $b;
}
echo concatenate("Hello ", "World"); //Hello World

So now we have out two awesome functions that do exactly what we expect them to do. But now you figure you should just have one function, lets call it add() to do those two tasks depending on the parameters submitted. That’s where the problems begin with PHP. In Java for example you could just define two function with same name but that take different parameters. e.g: int function add(int a, int b) and another string function add(string a, string b). In PHP we need to do some heavy lifting ourselves:

So the solution lies in the native functions func_get_args() and func_num_args(). PHP Lets you declare functions that take an arbitrary number of arguments/parameters and use func_get_args() and func_num_args() to retrieve and count the arguments respectively.

The solution:

function add(){
  //Make sure that exactly two parameters are sumitted
  if(func_num_args() == 2){
    $args = func_get_args();
    $a = $args[0];
    $b = $args[1];
  }else{
    trigger_error("Incorrect parameter count for function " . __FUNCTION__ . "()", E_USER_ERROR);
  }
  /** Check if two integers where submitted **/
  if(is_int($a) && is_int($b)){
    return sum($a, $b);
  }elseif(is_string($a) && is_string($b)){
    /** Check if two strigns where submitted **/
    return concatenate($a, $b);
  }else{
    /** Otherwise give an error **/
    trigger_error("Incorrect parameter type for " . __FUNCTION__ . "()", E_USER_ERROR);
  }
}
echo add("Hello ", "World"); //Hello World
echo add(5, 4); //9
echo add("Hello", 3);//Error
echo add(3, "World");//Error
echo add("HELLO", NULL);//Error

I don’t think i’d ever use it really. Seems like a lot of work for something that you could do other quicker ways. But use it, don’t use it :)
The function above is commented so just follow the comments if you don’t understand anything.

Came across a very interesting post on “Quality” by Paul-M-Jones post via the phpdeveloper.org feed(That you should subscribe to). Here a little extract from the post below. Read the full post.

While the above analysis may be true, I realized later that I was approaching the problem from the wrong angle. It’s not that one cares more about quality than the other. Instead, it is that they have two different definitions regarding project quality.

  • The programmer’s “quality” relates to the what he sees and works with regularly and is responsible for over time (the code itself).
  • The payer’s “quality” relates to the what he and the customers see and work with regularly and are responsible for over time (what is produced by running the code; i.e., the product, not the program).

Read the full post…

Hey all, welcome to part 2, a continuation of the Hello World module in Drupal 6 – Part 1 I know what you’re thinking: “A full 8 months later? wtf?”. If you werent thinking that then you are now. Or something along those lines. I apologise for the delay(if you can even call it that). Blah blah blah

{begin: excuse}
//TODO: enter excuses here
{end: excuse}

Now that we’ve got that out of the way, Shall we then get to the Semicontacts Module tutorial. Right.

In this tutorial we are going to learn the following

1. How to use the Drupal Database Abstraction Layer.
2. How to use the Drupal Form API to create and validate forms.
3. How to use the Drupal Schema API to create a database table during module installation.

NOTE: Please note that this tutorial is used for educational purposes only.<br />
 It is nowhere near production ready. Also what we are doing here can be done<br />
 without any coding at all using the <a href="http://drupal.org/project/cck">CCK module</a>. This is just meant to show you actual Drupal Code

Our module is an address book much like the one you have on your phone. It will require a first name, last name, phone number. These will then be saved in a database in a table called semicontacts that we will create.

We will also create a page to list all these contacts.

Okay less yada yada more code you say? Say no more. So were going to create module folder and the two required files like in part one.

So now I have a folder in sites/all/modules/ called semicontacts(the name of my module):

-sites/all/modules/semicontacts
—semicontacts.info
—semicontacts.module

Let’s start by telling Drupal about our module in the semicontacts.info file:

; $Id$
name = Semicolon Contacts Module
description = Contact Management Module(CMM 😀 )
core = 6.x
package = Semicolon

Now Drupal knows about our module. If you actually go into modules list you will see this new module.

Now lets edit the semicontacts.module file and add a page(tell Drupal the URL for the module), you will remember we do this by using a hook_menu() hook. If you remember in part 1, hooks naming follows nameofmodule_hookname() what does this mean for us?:

<?php
function semicontacts_menu(){
$items = array();
$items['semicontacts'] = array(
'title' => t('Semicontacts - Form'),
'page callback' => 'semicontacts_page',
 'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
 );
 return $items;
}

As you can see the module will be accessible from the http://mysite.com/semicontacts page. The page call-back is the function that will be called when this URL is accessed. So lets go ahead and create that. This page will contain our form. We will use the Form API to create the form.

function semicontacts_page($argument) {
    $content = "Hello World! Wow It really works
    This is a simple module to save contacts to the database.
    Enter Contact Details.";
    $content .= drupal_get_form('semicontacts_form');
    return $content;
}

There’s our function. So we put a little into text at the top and we add a form to that using the drupal_get_form() function, which takes a form function as a parameter. So we need to create this form function that will return our form.

function semicontacts_form(){
 $form = array();
 //create a text field called firstname with label First Name
 $form['firstname'] = array(
 '#type' => 'textfield',
 '#title' => t('First Nmae'),
 );
 //create a text field called lastname with label Last Name
 $form['lastname'] = array(
 '#type' => 'textfield',
 '#title' => t('Last Name'),
 );
 //create a text field called phonenumber with label Phone Number
 $form['phonenumber'] = array(
 '#type' => 'textfield',
 '#title' => t('Phone Number'),
 );
 //create submit button
 $form['submit'] = array(
 '#type' => 'submit',
 '#value' => t('Save Contact'),
 );
 //return the form
 return $form;
}

The Form API makes creating our form simpler and cleaner. The form is declared as an array of arrays(the fields are themselves arrays). By the ways this function can be called whatever you want. As long you fetch the right form in the page function above.

So now we should have a form. Lets try access the page. Go to http://www.my-site.com/semicontacts You should be greeted with a form which at the moment does absolutely nothing. Try click submit. It should just redirect you to the same page.

Okay. Now lets get to the fun stuff. Lets create a table in our database called semiccontacts to store our contacts:

CREATE TABLE `semicontacts`.`helloworld_contacts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`firstname` VARCHAR( 255 ) NOT NULL ,
`lastname` VARCHAR( 255 ) NOT NULL ,
`phonenumber` VARCHAR( 255 ) NOT NULL
)

Copy sql query above and run in a mysql client(i use phpMyAdmin). Be sure you have already selected your drupal database.

Now we just need to create a function to save our form. We do this by implementing form api’s _submit() function

function semicontacts_form_submit($form_id, &$form_data){
 db_query("INSERT INTO semicontacts (firstname, lastname, phonenumber) VALUES ('%s', '%s', '%s')", $form_data['values']['firstname'], $form_data['values']['lastname'],  $form_data['values']['phonenumber']);
 drupal_set_message(t('Your contact has been saved to the database.'));
}

The data submitted by the form is stored in an array $form_data[‘values’] with field names as keys so to fetch the value of firstname field just $form_data[‘values’][‘firstname’], simple enough right? Yep.

In Drupal 7, We use the db_insert to save our data. The API allows for method chaining, much like RUBY’s active record pattern or Jqeury. Looks better and makes the code easier to follow.

So to save this in drupal 7 we would use:

db_insert('semicontacts')->fields($form_data)->execute();

So now our form should be saving to the database. Try it now. Works? Yes? No? If it doesnt then something went wrong up there. You or i(i hope not) missed something.

Wait don’t we need to validate our form data? We do. Lets. Form validation is done using the form api _validate() function. It means our function will be called semicontacts_validate().

function semicontacts_form_validate($form_id, &$form_data){
 //var_dump($form_value);
 if(!is_string($form_data['values']['firstname'])|| empty($form_data['values']['firstname'])){
 form_set_error('firstname', t("Please Enter a valid First Name"));
 }elseif(!is_string($form_data['values']['lastname']) || empty($form_data['values']['lastname'])){
 form_set_error('lastname', t("Please Enter a valid Last Name"));
 }elseif(!is_numeric($form_data['values']['phonenumber']) || empty($form_data['values']['phonenumber'])){
 form_set_error('phonenumber', t("Please Enter a valid Phone Number"));
 }
}

We used the the form_set_error function to set errors if any for the field we are currently validating. the method takes a fieldname and an error message. You will also notice like the submit function we did not have to call them. This is the beauty of hooks. They’re like that little kid in class with his hand up going “me,me,me, pick me sir”. And the class wont continue until they get picked. I thought that was deep. You should write that down 😉

So hooks break drupal flow of execution cause drupal will first check if there are any relevant hooks in your module before continuing to the next task. So its almost like you modified the Drupal core without really needing to see the core code.

Okay now try submitting without entering any values. You should get the error messages we defined above.

But wait would’nt it be cool if we had a page to list contacts? Lets go ahead and do that.

Remeber that secontacts_menu function up there, the one that defines our modules urls? Yeah that one. Lets add another url there. Say… http://www.my-site.com/semicontacts/list

function semicontacts_menu(){
$items = array();
$items['semicontacts'] = array(
'title' => t('Semicontacts - Form'),
 'page callback' => 'semicontacts_page',
 'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
 );
 $items['semicontacts/list'] = array(
 'title' => t('Semicontacts - List'),
 'page callback' => 'semicontacts_list_page',
 'page arguments' => array("1"),
 'access arguments' => array('access content'),
 'type' => MENU_CALLBACK,
 );
return $items;
}

Easy enough. If at this point you are thinking we need to create the call back function you are indeed correct young grasshoper 😀 Here it is:

function semicontacts_list_page($argument) {
 $content = t("List of contacts<br /><br />");
 $content .= t(l("Add New Contact","semicontacts"));
 $result = db_query('SELECT c.id, c.firstname, c.lastname, c.phonenumber FROM semicontacts c order by
lastname asc');
 $content .= "<ul>";
 while ($contact = db_fetch_object($result)) {
 $content .= "<li>$contact->lastname, $contact->firstname - $contact->phonenumber</li>";// Perform
operations on $node->body, etc. here.
 }
 $content .= "</ul>";
 $content .= l(t("Add New Contact"),"semicontacts");
 return $content;
}

At this point our module is fully functional. But we dont wan’t the end-user to always run a sql command to create the semicontacts table. We need this to happen during module installation. Enter the

semicontacts.install module with the Schema API Create a new file in the semicontacts folder called semicontacts.install with the following contents:

<?php
//$Id
/**
 * Implement hook_schema()
 */
function semicontacts_schema(){
 $schema['semicontacts'] = array(
 'description' => t('Store .'),
 'fields'=>array(
 'id'=>array(
 'type'=>'serial',
 'unsigned'=>TRUE,
 'not null'=>TRUE
 ),
 'firstname'=>array(
 'type'=>'varchar',
 'length'=>255,
 'default' => '',
 'not null'=>TRUE
 ),
 'lastname'=>array(
 'type'=>'varchar',
 'length'=>255,
 'default' => '',
 'not null'=>TRUE
 ),
 'phonenumber'=>array(
 'type'=>'varchar',
 'length'=>255,
 'default' => '',
 'not null'=>TRUE
 ),
 ),
 'primary key'=>array("id"),
 );
 return $schema;
}
/**
 * Implement hook_install()
 */
function semicontacts_install(){
 drupal_install_schema('semicontacts');
}
/**
 * Implement hook_uninstall
 */
function semicontacts_uninstall(){
 drupal_uninstall_schema('semicontacts');
}

This file contains implementation of 3 drupal hooks, hook_install(), hook_uninstall(), hook_schema().

hook_install() is used to run any configuration during install like say creating a database table for our module.

hook_uninstall() is used to run any configuration during install like say deleting a database table for our module.

hook_schema() is where we define our database table. The fields about are clearly self explanatory. Check a full list and description.

To test your new install file you must remove the module from Drupal system table. This makes sure that Drupal will run hook_install() since this only runs the first time a module is installed. To do that I usually just run this query

delete from system where name ="semicontacts"

Not the best way, not even advisable. to execute queries directly on the database, but it should suffice since we are on our localhost.

So now you need to package your module in to a .tar.gz file. If you are on windows download 7zip.
To create the file just right click on the semicontacts folder, go to the 7zip submenu and click on “add to archive”, on the window that pops up,choose “tar” format. you should have a newfile semicontacts.tar. Right click this file and do the same as above but choose gzip as the archive format. Good luck.

Comments welcome positive and negative. I apologise for the lenghth of the tutorial, was just so much stuff to cover. We are going to improve and extend semicontacts in the next tutorial(Part 3)

Download Source Code

1. He/She has a ‘God’ Complex

Web Development by its very nature is a creative field. It’s a field were the developer invests themselves. The Developer looks at a problem and solves it the best way they know how. If anybody dares question how the problem was solved, it is considered as a personal attack on the developer skills. I see this in myself every day. When somebody fails at completing a task with the software, the natural response for a developer is “god you are the most retarded person I know”. But of cause this is not true. Donald Norman in his Book “The Design Of Everyday things” says “If an error is possible, somebody will find a way to make it” (Not a word for word quote, Great book by the way). And it’s not because they are stupid, it’s because your application allows for that error/failure to occur. Design for errors. Developers should never test their own software.

2. He/She worships his/her Code

This one is closely tied to the number one above. Your developer loves his/her code, therefore it is the best code it can be, it will never need re-factoring, if anybody writes it different they are stupid. This sort of attachment leads to low quality work and developers that don’t grow. Be wary of developers that think they write the best code in the world.

3. 70% coding, 30% planning

Most developers get a problem and the first thing they do is start coding. Adding and removing stuff as they go along. Creating new functions as they go along. But the truth is if they took more time in planning, their development time is decreased dramatically. And the quality and structure of their work is improved. So aim for a 70% planning, 30% coding. **This is just my personal opinion.

4. Bad time estimates

Your developer will usually go over their time estimates; the trick is never believe a developer’s time estimate :D, cause we lie. And we don’t lie to you, we lie to ourselves. And we believe it. The lie to you is just a by-product. We over estimate our skills and we live in a purple fluffy world with Smurfs and Teletubbies where everything goes according to plan and there are not unexpected errors or events. Giving time estimates is a skill on its own and a developer does not have that skill as i had to learn it might make them unhappy with their job. Again planning goes a long way. Also be wary of the ‘project managers from hell’ pressurising your developers unnecessarily to score some points with you.

5. No desire to learn new things

A developer should always be growing, improving, finding new/better ways of doing the same stuff he’s been doing for years. And there is nothing worse than a developer who cannot learn new things by themselves. Team work is fine and all, but a developer that cannot learn by themselves is going to cost you time and money and frustrate your development team. I happen to think when it comes to learning a new system, discovering things on your own is the best way to learn, breaking things and fixing them and finding out why they broke, etc. I have my own little list on What a Web Developer should know.

6. You give him unclear instructions

Never tell a web developer “Go build me a rocket please”, you will get a flying saucer. Be specific with what you want. It is best to get a trained business analyst if you cannot do this yourself, someone who will understand the requirements of the users and the desired behaviour and outcomes of the system. So yes your developer sucks because you think you speak ‘developer’ but are you are just human…or are you dancer 😀

7. Being a perfectionist(Thanks James)

I had missed this one but thanks to @jamiebarow for pointing this out. “I am a perfectionist”, Yes it was cute he/she said it in his/her interview. Its great to have great attention to detail, but too much attention to details can cripple a project. Some developers write and re-factor at the same time(I feel an infinite loop coming on). Which sorta takes us back to number 2 above. Code worshipping is blasphemy.

8. He/She has no idea WTF he/she’s doing

Sometimes you just get stuck with a developer that has no idea what they are doing, just good old fashioned ‘stupid’ for lack of a better word. I’m kidding nobody is stupid, but some developers should have been mechanics. Just saying. :P. James says not knowing is fine as long you are willing to learn. True story.

9. Conclusion

Although this sounds like it’s meant for your boss, Its really meant for you. Stop sucking at your job. Be approachable, be sincere, be wrong, be willing to help others get better. Understand you are not perfect and quite possibly might suck. As long as you are willing to learn and driven. I’m still working on some of these things myself. Will keep you posted. I wrote another article on How to become a web developer. Take a look and let me know. Enjoy.

Adios
Tali

Sphinx is a full-text search engine. It currently works with MySQL and PostgreSQL better known as Postgres. The two most popular options when its comes to open source databases if not databases in general. Both MySQL and PostgreSQL have full-text search capabilities. So why bother with sphinx?

  1. Control – With sphinx you get more control over filtering, for example you can set a certain column to have a higher weight by using just one function
  2. Speed – Sphinx is about 40-100 times faster at indexing. It’s also up a 1000 times faster at searching than MySQL and Postgres depending on the data.
  3. Relevance – You get much more relevant results with sphinx. i.e Accuracy is greatly improved
  4. Scalability – Sphinx indexes can be stored on distributed servers. You can also search multiple sites at one go.

Read more…

The PHP header(“Location: /”) function sends a redirect header to the browser. So thing about PHP is that it only sends headers to the browser once the page is parsed on the server. header(); will not stop the execution of code that comes after it. The script will continue to execute until it reaches the end. At which point it will then redirect.

Take this example

//Do stuff
//redirect to another page
if($user_loggedin){
    header("Location:  /login.php");
}
$_SESSION['page_views'] += 1;
/*
Display this page's content
*/

Although its quite clear to a human that if this user is not logged in, we should redirect to login.php, this script will actually continue to execute to the end and then redirect. which means although the page is never really viewed. it will still increment the $_SESSION[‘page_views’] variable.

So the headers are only sent back to the browser once PHP has completed rendering/building the page. At which point the browser redirects to the login.php. So to get the desired effect all you have to do is add a exit() function to stop script execution and force PHP to send the page to the browser as is.

So the code will now look like this:

//Do stuff
//redirect to another page
if($user_loggedin){
    header("Location:  /login.php");
    //stop executing the script
    exit();
}
$_SESSION['page_views'] += 1;
/*
Display this page's content
*/

What I do is just write a function to do both steps like this:

function redirect($url){
        header("Location: $url");
        exit();
}

usage:

redirect("/login.php");

A short tutorial on developing a simple hello world module that prints Hello World on the screen.

1. Create a folder for your module

Create a folder in your modules directory called helloworld ie sites/all/modules/helloworld/. It is good practice to put all custom modules in sites/all/modules/ folder and not the modules/ folder. The modules folder is meant for core modules any “third party” or custom modules should be in sites/all/modules/.

So now that you’ve created the folder sites/all/modules/helloworld/

2. Create the *.info file

Create a file called modulename.info in this case helloworld.info

; $Id$
name = Hello World Module
description = My very first Drupal Module
core = 6.x

This lets Drupal know about your module

3. Create the *.module file

Create a file called modulename.module in this case helloworld.module

We need to let Drupal know what path the module will be accessible from. We do this by using the hook_menu() hook. To implement  hooks follow the following convention: modulename_hookname(). So for our module we must create a function called helloworld_menu(). More info here.

function helloworld_menu(){
$items = array();
$items['helloworld'] = array(
'title' => t('Welcome to the Hello World Module'),
'page callback' => 'helloworld_page',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
  );
  return $items;
}

Break Down

We created $items[‘helloworld’] array item. This lets drupal know about the path we want to use for our module.

title: this is what gets printed at the top of the page. The page title.
page callback: This is the function that gets called when the url is accesed.
page arguments: must be array of arguments that get parsed to the call back function, not required.
access arguments: array of access permissions in this case any role with ‘access content’ permissions can access the page.
type: specifies the menu type check hook_menu() for more details the Drupal hook.

There are more available options than these. The Drupal API is your friend. Use it.

So in a nutshell, when Drupal hits the http://mysite.com/helloworld url it will look for a call back function called helloworld_page(). Simple Enough. Now lets create the helloworld_page() function.

function helloworld_page($argument) {
   return "Hello World!";
}

So your helloworld.module file will contain:

<?php
function helloworld_menu(){
$items = array();
$items['helloworld'] = array(
'title' => t('Welcome to the Hello World Module'),
'page callback' => 'helloworld_page',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
  );
  return $items;
}
function helloworld_page($argument) {
    return "Hello World! Arguments parsed was " . $argument;
}

Note how i did not close the <?php tag. It is considered good practice to no close files that only contain php. Now go to admin>build>modules. Your module should be on the list. Activate it and type in http://mysite.com/helloworld to test it out. Goodluck

I’ll doing a secong part to this tutorial where i will show you how to create an input form and save user the input to the database.

You can download the complete drupal module.

Once done with this easy bit Check out Part 2 of the tutorial

Enjoy

Thanks
Tali

function simple_hello_world_menu(){
  $items = array();
  $items['simple-hello-world'] = array(
    'title' => t('Simple Hello World!'),
    'page callback' => 'simple_hello_world_page',
    'page arguments' => array(1),
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

What do you guys think of the new design?

Let me know. 😉

I think in my time as Web Developer I’ve had my fair share of bad(for lack of a better word) Bosses/Employers. Had my fair share of Bad treatment from people that do not value you. I’ve had Good Jobs, I’ve Bad Jobs.

As a web developer your job hours get a little fuzzy because you are not sitting there lifting boxes with a 10 box quota per day. You have time lines, milestones and ultimately the big deadline on any given project. For each project the project manager will ask you to give a time estimate. Now that’s where the problem starts. Picture this scenario:

Project Manager: So how long do you think it will take you.
You: 5 days
PM: WHAT 5 days just to do that?
You: Go die in a fire. How would you know how long it’ll take me(What you wish you could say)
You: Well, i guess i could do it in 2.5 days(lord knows where you get the 0.5 from) => (What you really say)

And i think we all know how that story ends, you do the project in 2.5 days give or take 0.01 days ;). And a day later you become the ambassador for buggy applications around the world. You win the nobel bug price. And the project manager sits there and looks at you like they have no idea what went wrong.

My point Bad project managers and bad bosses(God forbid your project manager is your boss) have a tendency to second guess developer times. And this second guessing always leads to the developer feeling like he/she is not working fast enough, and every time estimate that the developer gives after that will be to please someone(bad bad bad).

I once worked in company where for about a month i was leaving work at at least 2 in the morning, had no car at the time so you can imagine the amount of money that went to cabs. Don’t get me wrong i am a hard worker. Stop it, i am. I was working on a project that I(me) had given bad times due to the pressure from “above”. A simple project that had i set down and been allowed to do spend a 2 days doing research i would have completed in 2 weeks. DO NOT LET PEOPLE SECOND GUESS YOUR TIME, you end up looking bad.
Always give yourself a 50% buffer i say. So if you know a task will take you 4 days to complete. Always quote 6 days. i.e 4/2 + 4 = 6

Very interesting Article: Evidence Based Schedule

Do NOT be taken for grunted. Do NOT let that Happen. I’m lucky to be working for a great boss, with a great Team. And i thank God for that. My past employers will have to excuse my Rant.

ssss?