How to create a social networking website in 5 minutes

Hello Friends,

Social media is the way to go now-a-days. After Orkut, Facebook and My Space we saw hundreds of social networking site making their mark in the market. However now a days socialness is not only restricted to social networking sites. Now every company wants to include some amount of socialness into their website, product or whatever it is.

However the features which any of the social networking site provide are same and restricted to a certain extent. 3 of the sites which I have developed so far, all have socialness as a base component. (Gtalkbots, Altertunes, IITG Alumni) However after I saw Elgg a few days back, I was just wondering how much time I wasted in building social features in all the 3 sites. I just wish I could have found this before.

Here in 5 minutes we will see how to build a full fledged social networking site using Elgg:

  1. Download Elgg setup from the download page here or directly using this link http://elgg.org/getelgg.php?forward=elgg1.1.zip
  2. Lets name our social networking site as Snizr.
  3. Extract the downloaded zip file in your Apache Document Root and name the folder as snizr. In my case it is C:Workspacesnizr 
  4. Now just open the url http://localhost/snizr and you will see a page like this:

  5. Create a database named snizr in mysql and enter the details in the form above. Press enter and you will come to the system settings page. If for some reasons this configuration page doesn’t take you to the system settings page, manually go to engine/settings.example.php and rename it to engine/settings.php and enter the details inside.

  6. Now enter the details of your social network here. Create a upload folder outside the installation directory e.g. C:Workspacesnizr-uploads . You will be asked to enter this path in the system settings above.
  7. After you are done you are taken to the registration page. The first registered user is admin by default.

  8. Thats it. You have a full social networking available for you. After registration you come to the login page and after loggin in you come to your dashboard.

Features provided by Elgg:
You just got a feel of how easy it is and its not even 5 minutes as per my watch. Still 2 min to go 😉 .
Quickly lets see what else does Elgg offer.

  1. Click on Administration link at the top navigation bar and you will be amazed to see the kind of admin panel it provides.
  2. Next go to Tool Administration and you can see about 10 plugins at your service. From Blog, API, Bookmarks, Friends, Groups, Messages, Status, UserValidationByEmail and what not.
  3. Enable a few and go to your profile pages to see them being reflected immediately.

Now I will leave to explore rest of it yourself. 5 minutes are almost over 😉

I hope you enjoyed discovering Elgg.

How does PHP echo’s a “Hello World”? – Behind the scene

Have you ever wondered how PHP echo’s a “Hello World” for you on the browser? Even I didn’t until I read about the PHP internals and extensions. I thought may be a few out there will be interested in exploring the other side of PHP, so here we go.

In my last post I discussed in brief “How your browser reaches to my server when you type http://abhinavsingh.com in address bar?”. Read through if you have missed out on that. Here I will discuss in brief “How does PHP churns out the content requested on the webpage?”

An Overview
Here is what happens step-wise:

  1. We never start any PHP daemon or anything by ourself. When we start Apache, it starts the PHP interpreter along itself
  2. PHP is linked to Apache (In general term SAPI i.e. a Server API) using mod_php5.so module
  3. PHP as a whole consists of 3 modules (Core PHP, Zend Engine and Extension Layer)
  4. Core PHP is the module which handles the requests, file streams, error handling and other such operations
  5. Zend Engine(ZE) is the one which converts human readable code into machine understandable tokens/op-codes. Then it executes this generate code into a Virtual Machine.
  6. Extensions are a bunch of functions, classes, streams made available to the PHP scripts, which can be used to perform certain tasks. For example, we need mysql extension to connect to MySQL database using PHP.
  7. While Zend Engine executes the generated code, the script might require access to a few extensions. Then ZE passes the control to the extension module/layer which transfer back the control to ZE after completion of tasks.
  8. Finally Zend Engine returns back the result to PHP Core, which gives that to SAPI layer, and finally which displays it on your browser.

A Step Deeper
But wait! This is still not over yet. Above was just a high level flow diagram. Lets dig a step deeper and see what more is happening behind the scenes:

  1. When we start Apache, it also starts PHP interpreter along itself
  2. PHP startup happens in 2 steps
  3. 1st step is to perform initial setup of structures and values that persists for the life of SAPI
  4. 2nd step is for transient settings that only last for a single page request

Step 1 of PHP Startup
Confused over what’s step 1 and 2 ? No worries, next we will discuss the same in a bit more detail. Lets first see step 1, which is basically the main stuff.
Remember step 1 happens even before any page request is being made.

  1. As we start Apache, it starts PHP interpreter
  2. PHP calls MINIT method of each extension, which is being enabled. View your php.ini file to see the modules which are being enabled by default
  3. MINIT refers to Module Initialization. Each Module Initialization method initializes and define a set of functions, classes which will be used by future page requests

A typical MINIT method looks like:

      PHP_MINIT_FUNCTION(extension_name) {

          /* Initialize functions, classes etc */

      }

Step 2 of PHP Startup

  1. When a page request is being made, SAPI layer gives control to PHP layer. PHP then set up an environment to execute the PHP page requested. In turn it also create a symbol table which will store various variables being used while executing this page.
  2. PHP then calls the RINIT method of each module. RINIT refers to Request Initialization Module. Classic example of RINIT module implementation is the Session’s module. If enabled in php.ini, the RINIT method of Sessions module will pre-populate the $_SESSION variable and save in the symbol table.
  3. RINIT method can be thought as an auto_prepend_file directive, which is pre-appended to every PHP script before execution.

A typical RINIT method looks like:

      PHP_RINIT_FUNCTION(extension_name) {

          /* Initialize session variables, pre-populate variables, redefine global variables etc */

      }

Step 1 of PHP Shutdown
Just like PHP startup, shutdown also happens in 2 steps.

  1. After the page execution is complete either by reaching the end of the script or by call of any exit() or die() function, PHP starts the cleanup process. In turn it calls RSHUTDOWN method of every extension. RSHUTDOWN can be thought as auto_append_file directive to every PHP script, which no matter what happens, is always executed.
  2. RSHUTDOWN method, destroys the symbols table (memory management) by calling unset() on all variables in the symbols table

A typical RSHUTDOWN method looks like:

      PHP_RSHUTDOWN_FUNCTION(extension_name) {

          /* Do memory management, unset all variables used in the last PHP call etc */

      }

Step 2 of PHP Shutdown
Finally when all requests has been made and SAPI is ready to shutdown, PHP call its 2nd step of shutdown process.

  1. PHP calls the MSHUTDOWN method of every extension, which is basically the last chance for every extension to unregister handlers and free any persistent memory allocated during the MINIT cycle.

A typical RSHUTDOWN method looks like:

      PHP_MSHUTDOWN_FUNCTION(extension_name) {

          /* Free handlers and persistent memory etc */

      }

And that brings us to the end of what we can call as PHP Lifecycle. Important point to note is that Step 1 of Startup and Step 2 of Shutdown happens when no request is being made to the web servers.

I hope this post will clear many doubts and un-answered questions which you might have.

Do leave a comment and feedbacks.

What happens before you finally viewed this page?

Since past 1 week or so I am trying to make a small tiny light weight web server of my own, and for the same I have been referring to dozens of papers, websites, people and what not. I still haven’t finished making one, I am still toggling between Java and Python, since both seems to satisfy my needs and unfortunately I am master in none. While I was digging deep into the theory of how can I make a web server, I cleared many other concepts of mine, which finally leads to this post.

“What happens before you finally viewed this page/post of mine ?” – Many of you might know behind the scene stories and many like me might have a vague idea. But for the good of all those who don’t know and for people like me who needs a reference, I thought of better penning it down.

Lets see what possibly is going in the background:

  1. Suppose you type in http://www.yahoo.com in your web browser or clicked this link on some other page.
  2. Your browser see’s the above URL, and identifies it as a HTTP protocol.
  3. Then it breaks the URL into Protocol, Domain Name, File Name (in above case no file name is specified)
  4. Browser contacts its default DNS (Domain Name Server), which helps it with an IP Address. DNS is a huge distributed database which contains mapping of URL’s to IP Address. Your browser’s default DNS might or might not have the required mapping of URL to IPAddress.
  5. If it don’t have the IPAddress corresponding to http://www.yahoo.com , it will try to contact other root name servers for the required IPAddress.
  6. If it already have the IPAddress corresponding to http://www.yahoo.com (which is possible if a similar request has already been made recently) it will provide the required IPAddress to your browser.

And finally your browser then connects to the IPAddress it received and servers you the page returned back by Yahoo!. If you are still not clear about the process, following practical example might help you.

  1. I thought of starting a website and decided to name it as http://gtalkbots.com
  2. Firstly, I needed to register domain name with a registrant. For e.g. In my case I blocked the domain name gtalkbots.com with godaddy.com.
  3. Secondly, I needed to have a machine i.e. a place where I can have all my HTML, PHP files. So I bought a VPS (Virtual Private Server)
  4. Thirdly, I had to link the above two i.e. when someone types in http://gtalkbots.com in his browser, it should come to my VPS where I have my HTML files.
  5. For linking the domain name and my VPS, I simply make an ARecord entry at godaddy, telling it the IPAddress of my VPS. In turn when you type in http://gtalkbots.com in your browser, GoDaddy redirects you to my VPS. (Google for ARecord and CNAME for more details)
  6. Last 4 entries in the image above are for linking my gtalkbots.com domain with my google apps account, so that I can send and receive my gtalkbots.com email on google apps.

There is a lot more to it, however the info above is more than sufficient to understand the basics of
“What happens before you finally viewed this page/post of mine ?”

Symfony model layer tips and tricks – A PHP Framework – Part 3

I had a tough time searching for examples over the net for all kind of symfony queries. Though symfony is well documented here, I didn’t find enough examples there.

If you have landed up on this post straight and are new to symfony, you may want to first read previous posts:
Getting started with Symfony – A PHP Framework – Part 1
How to build a login-registration system using Symfony – A PHP Framework – Part 2

If you are well equipped with the basics, read on

Select Query:
Lets start with the few basic example queries.

  1. Extract list of all users from the users table

    $c = new Criteria();
    $this->resultSet = UsersPeer::doSelect($c);

    Now lets see how can we use this $resultset within the model layer and in the template files.
    To use the resultset within model layer, we can do something like this:

    foreach($this->resultset as $rs) {
        $uid = $ps->getId();
        $fname = $ps->getFirstName();
        $lname = $ps->getLastName();
    }

    To use the resultset in template files (viewer layer), we can do something like this:

    foreach($resultset as $rs) {
        $uid = $ps->getId();
        $fname = $ps->getFirstName();
        $lname = $ps->getLastName();
    }

  2. Extract list of first 10 users only

    $c = new Criteria();
    $c->setLimit(10);
    $this->resultSet = UsersPeer::doSelect($c);

  3. Extract list of 10 users starting from 100th user

    $c = new Criteria();
    $c->setOffset(100);
    $c->setLimit(10);
    $this->resultSet = UsersPeer::doSelect($c);

  4. Extract user data where username = ‘imoracle’

    $c = new Criteria();
    $c->add(UsersPeer::USERNAME,”imoracle”);           // Note USERNAME is all in caps, even if your column name is in small case
    $this->resultSet = UsersPeer::doSelect($c);

  5. Another approach to do a select query

    $c = new Criteria();
    $c->add(UsersPeer::USERNAME,”imoracle”);
    $resultSet = UsersPeer::doSelectRS($c);

    To access this resultset in the model layer itself, we can do something like this:

    while($resultSet->next()) {
        $uid = $resultSet->get(1);
        $fname = $resultSet->get(2);
        $lname = $resultSet->get(3);
    }

    Where get(1) fetches the 1st column for you of the resultset. Hence $resultSet->get(n) will fetch you the nth column of the resultSet.

Insert Query:
Lets see a few quick examples for inserting a new row in a table.

  1. Insert a user entry in user table

    $new_user = new Users();
    $new_user->setUserName($uname);
    $new_user->setFirstName($fname);
    $new_user->setLastName($lname);
    $new_user->setPassword(md5($pass));

    $new_user->save();
    $new_user_id = $new_user->getId();

    Finally we get the last inserted user row id.

Update Query:
Symfony provides nothing special for the update queries. The same above format works for updating a row as well. Symfony is smart enough to analyze whether its a select or update query.

  1. First Method for Update Query (Recommended)

    $c = new Criteria();
    $c->add(UsersPeer::USERNAME,”imoracle”);
    $c->add(UsersPeer::PASSWORD,$newpass);
    $res = UsersPeer::doUpdate($c);

    In the above example we chose to update the password for user with username “imoracle”.

  2. Another Method for Update Query

    $user = new User();
    $user->setNew(false);
    $user->setId($uid);
    $user->setPassword($newpass);
    $user->save();

    Important code in above 5 lines is the 2nd line. Without this line it will add a new row and not update. Also another drawback which I found in this approach is that in third line you need to give the PK (primary key) of the table. Like our 1st method you cannot give username in the third line.

    Finally I haven’t tried and tested this method enough. So I will not recommend this.

Delete Query:
Its basically the same above methods, with change of final call.

  1. Delete a user’s account where username = ‘imoracle’

    $c = new Criteria();
    $c->add(UsersPeer::USERNAME,’imoracle’);
    $res = UsersPeer::doDelete($c);

How to alter a table in symfony?

  1. Method 1 (Non-standard)
    A drawback which I have seen in symfony till now is that, when you try to alter a table by adding new columns in your schema.yml, It flushes the data from the table and gives you an altered table with no data. This is really bad, if you don’t know this behavior and move ahead altering the table. Though Symfony provider propel-dump-data to handle alter tables, but it is still quite buggy and slow for big databases. The clean and smooth way to achieve this is:

    1. Take a mysql dump with following options:
      mysqldump -h hostname -u username -p password -c -t dbname > dbname.sql
      Do not forget to use option -c and -t, without which it can land you in a problem
    2. Update your schema.yml file, with new columns which you want to add and run
      sudo symfony propel-build-all
    3. Restore the database content using following command:
      mysql -h hostname -u username -p password dbname < dbname.sql

    And you have your new altered table without any loss of data.

  2. Method 2 (Standard)
    If you are afraid of your data being flushed by the stupid symfony, then you may choose not to touch your database using propel at all. Here is what you can do in such a case.

    1. Update your schema.yml file and run
      sudo symfony propel-build-model
    2. Then manually go and alter the table in the database.

    Here propel-build-model will only rebuild the ORM layer to incorporate your schema.yml changes. However propel-build-all not only builds the ORM layer, but also actually creates the table in the database (flushing the data)

In future I shall keep adding more SQL queries on this post, as and when I write them using symfony. So keep glued to this one 😉

games@gtalkbots.com – Online gaming enabled on Gtalk

Anagram, many of you might be familiar with it or even played many a times back in school and colleges. Its a simple text based game, where you are given a jumbled word and you need to re-arrange it. E.g. You will be given huldos and you need to quickly identify that as should.

So getting bored back in college or office, add games@gtalkbots.com and type anagram to start gaming. Play and score well. Your score will turn up on the Gtalkbots front page. They have kept this game open for the world i.e. one can play this game even without registering at Gtalkbots.

A few important points:

  1. Add games@gtalkbots.com as your friend in Gtalk Messenger.
  2. Type rules to read them before you start gaming.
  3. Type anagram to start gaming.
  4. You will be given a jumbled word which you needs to rearrange and reply back.
  5. If your answer is correct you get 10 Points.
  6. If your answer is not correct and you are finding it tough to solve it, Type hint to get a clue, and a clue will be sent to all users playing the game.
  7. DO NOT FORGET to type exit when you are finished gaming. If you forget to do so, you will be considered as a part of next round being played and eventually your average score decreases.
  8. If total number of wrong answers = 5 (including all users), the bot will automatically reply back with correct answer and moves to the next word.

So try out and enjoy.