blog-header

Words with a View

Tuesday, May 23, 2006

A Quick & Dirty Guide to understanding Symfony Minimally !

Why this guide when the documentation at symfony site is complete? The answer to this question is that i tried reading the documentation at symfony site, but as always when i am reading any tech books( to me tech books are not thrillers like usual suspects nor unputdownable novels like godfather ), i got bored after a 20 couple of pages ( or 20 page clicks ).Then I decided to write my own write ups based on what i read/understand every day and update it on my blog.These writeups does'nt follow any order nor 100% complete for a particular topic rather it is composed of very loosely coupled information on how to use this particular framework.

1 The symfony framework is a set of files written in PHP using the MVC standard based on Mojavi, ORM using Propel, DB abstraction using Creole.
2 Install using PEAR.
3 Initiate your project structure.

First you must have a project folder, say "projects", if not create the directory.
cd to that "projects" directory and type
$ symfony init-project projects

A file structure similar to this will be created under projects
apps/
batch/
cache/
config/
data/
doc/
lib/
log/
test/
web/

4 Next you need to create your applications under apps directory,
for that type
$ symfony init-app musicSite

A file structure similar to this will be created under apps/musicSite
apps/
musicSite/
config/

i18n/
lib/
modules/
templates/

Root Structure

The batch directory - usually crons are put here.
The cache directory - each application will have a subdirectory here where the preprocessed HTML and configuration files are kept.
The config directory - general configuration files are kept here.
The data directory - used to store the db schema or table creator sql code here in the sql subdirectory.
The doc directory - stores the project docs in the api subdirectory.
The lib directory - stores the foreign classes or libraries where all apps can share common code.
The log directory - stores the log files generated directly by symfony or by web server or database server.
The test directory - contains unit tests written in PHP .
The web directory - contains css, images, js, user uploaded files under particular subdirectories.
web/
css/
images/
js/
uploads/

Finally the app directory - contains one directory for each application of the project, here we have one app right now called musicSite.

App Structure

The config directory - a set of YAML configuration files and other settings used through out the application.
The i18n directory - contains files used for the internationalization of the application.
The lib directory - contains classes and libraries that are specific to the application.
The modules directory - contains all the modules that contain the features of the application.
The templates directory - contains all the global templates of the application.

Module Structure

Each application contains one or more modules named as a subdirectory under modules, say shopping in my modules folder.
This is done by typing
$ symfony init-module musicSite shopping
ie., under
projects/
apps/
musicSite/
modules/
shopping/
actions/

actions.class.php
config/
lib/
templates/
indexSuccess.php
validate/

The actions directory - Under the actions directory a class called actions.class.php contains all the actions of the module.
The config directory - contains custom configuration files with local parameters for the module.
The lib directory - contains classes and libraries that are specific to the module.
The templates directory - contains the templates corresponding to the actions of the module.
The validate directory - contains configuration files used for form validation.

Note: for the above 3 symfony commands you must be in the symfony project directory, which is projects in this case.
5 Web server setup for adding virtual host and URL rewriting.

Symfony MVC architecture

Model represents the persistent data, namely the database .
View renders the model into a web page for the end user presentation.
Controller responds to user actions, and invokes changes on the model or view as appropriate.

In symfony, the Controller is separated in different parts, namely a front controller and a set of actions.

Actions are located inside
musicSite/frontEnd/modules/buyMusic/actions/ directory,
where the action class is named as action.class.php.

In order to call an action you need to pass the parameter 'module/action' to the front controller(FC):

http://myapp.example.com/index.php/module_name/action_name/
param-name/param-value


The FC is usually index.php located in myApp/web directory which is the unique entry point to the whole application.What it does is it will call the controller and dispatch the user request ( after any filter requests) to the particular module/action described above.The action process the requests ie., by accessing the Model, ( which can be a database select or update or delete ) and executes the appropriate view after the end of the execution of the action.

The different kind of action returns are

return sfView::TYPE; where TYPE can be

SUCCESS - which is the default view to call and most common
ERROR - which is the error view to call
NONE - which is the no view to call

You can also chain multiple actions by using
$this->forward('otherModule', 'index');

and can also redirect to another module by using
$this->redirect('/otherModule/index');

Always use redirect when the form action is "POST" for avoiding possible resubmitting the request accidently.

More about Super Models..Ahem

Symphony uses OO abstraction a.k.a., Object Relational Mapping so that you can access the database as objects and also without writting any SQL queries as such.To start ORM in your application, u have to first initialise the data model by editing the file schema.xml located in the config directory directly under the main application.

A sample partial schema.xml is given at the top of this post for your preservance of sanity.The above XML probably looks familiar to mysql users and is mostly intuitive.

The name of the database is specified in the db connection cofiguration databases.yml located under the apps/frontEnd/config directory.

Next is the generation of OM files which are essentially PHP classes needed to interact with the database by typing
$ symfony propel-build-model after cding into musicSite directory. At this point of time you should be aware that propel is using Phing to generate the above mentioned classes and phing ( which is a type of XML build file much like the likes of Apache Ant ).The catch is that since pear is used to install phing, the makers of symfony have to integrate PEAR into the picture.

The base data access classes will be automatically created in the musicSite/lib/model/om/ directory.

BaseCds.php :: Base class for representing a row from the "Cds" table.
BaseCdsPeer.php :: Peer class, a static class for performing operations on "Cds" table.

The map classes will be automatically created in the musicSite/lib/model/map/ directory.

CdsMapBuilder.php :: Map class that creates a metadata represention of "Cds" table.

Also creates empty stub classes for the object and peer classes which is where you can put custom and override functionality.

Cds.php :: Empty subclass for custom methods & overriding methods
CdsPeer.php :: Empty peer subclass for custom methods & overriding methods

Thus for every table in the database, Propel creates 5 PHP classes.

Now how to perform basic C.R.U.D. (Create, Retrieve, Update, Delete) operations on your database.

Create

$cd = new Cds();
$cd->setName($name);
$cd->setDescription($this->getRequestParameter('description'));
$cd->setReleaseYear($year);
$cd->save();

The save() will generate the INSERT INTO sql command. Propel also support multiple inserts and automatic foriegn key inserts when new objects has other related objects added to it.

$cd = new Cds();
$cd->setName($name);
$cd->setDescription($this->getRequestParameter('description'));
$cd->setReleaseYear($year);
// note: we don't save this yet

$bands = new Bands();
$bands ->setName($name);
$bands ->setDescription($description);
$bands ->setReleaseYear($year);
$bands ->setCds($cd);
$bands ->save(); // saves all 2 objects!

Retrieve

By using the Peer classes you can select rows related to a particular table by using methods in the mentioned class.
Select or retrieve by PK ( However, I have never issued a query for selecting a row based on primary Key though )

$firstCd = CdsPeer::retrieveByPK(1);

To select simple multiple rows by criterias other than primaryKey , you can use the Criteria object ( which is a faint port on Apache Torque ) on the Peer class of the object.

For instance, to retrieve all cds which is equivalent to SELECT *, type:

$crite = new Criteria();
$cds = CdsPeer::doSelect($crite);

Now to access each Cd info

foreach ($cds as $cd){
echo $cd ->getName();
echo $cd ->getDescription();
echo $cd ->getReleaseYear();
}

To select rows with where, orderBy, notEqual to etc you can use the following methods on Criteria object

// Find all bands with name Pink or Pearl but
// year not 1992.
// u see i love Pink Floyd and Pearl Jam
$crit = new Criteria();
$crit ->add(BandsPeer::NAME, "Pink");
$c->addOr(BandsPeer::NAME, "Pearl");
$crit ->add(BandsPeer::YEAR, "1992", Criteria::NOT_EQUAL);
$crit ->addAscendingOrderByColumn(BandsPeer::YEAR);
$crit ->setLimit(10);
$crit->setIgnoreCase(true);
$bands = BandsPeer::doSelect($crit);


// Find all bands with name of Pink Floyd, Deep Purple, or Eagles
$crit2 = new Criteria();
$crit2->add(BandsPeer::NAME, array("Pink Floyd", "Deep Purple", "Eagles"), Criteria::IN);
$crit2 ->addAscendingOrderByColumn(BandsPeer::YEAR);
$bands = BandsPeer::doSelect($crit2);

It is actually too daunting to write rules on Criteria object when your query gets more complex such as using multiple tables and multiple Joins or even subqueries, more over the logic becomes unintelligible or unmaintainable.So Propel actually does'nt force you to use Criteria object every time u want to access some data from the table.IMHO it is better to use raw SQL queries than to use the Criteria Object to add rules.

$con = Propel::getConnection();
$sql = "SELECT cds.* FROM cds WHERE NOT EXISTS (SELECT id FROM bands WHERE cds_id = cds.id)";
$stmt = $con->createStatement();
$rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);
$cds = CdsPeer::populateObjects($rs);

UPDATE

Update in Propel is retrieve it first,change, and then saving back.

$cd = CdsPeer::retrieveByPK(1);
$cd ->setName("A Momentary Lapse of Reason");
$cd->save();


DELETE

$cd = CdsPeer::retrieveByPK(1);
CdsPeer::doDelete($cd);

All these code lies in the action.class.php on the respective module folder.

You see I got bored now, maybe soon i will update or add something related to

scaffolding Or View Or.......

Check back this area soon for another minimalistic understanding of symfony.. is that music to your ears..Bye.



Friday, February 17, 2006

Should I GET or should I POST ?

( title inspired by : Should I Stay or Should I Go - The Clash)

Usually in PHP/HTML if you want to submit a form to the server, you can basically use two methods: you can either use the GET method or the POST method.

form enctype="application/x-www-form-urlencoded" action="processRequest.php" method="GET" name="frm1"
input value="testMe" name="txtBox" type="text"
input value="send" name="submit" type="submit"
/form

Below is the resulting request that would be sent to the web server when the form was submitted using GET.
(it is appended to the URL).

GET /processRequest.php?txtBox=testMe&submit=send HTTP/1.1
Host: mysite.com
and you can access the variables in PHP using
if($_SERVER['REQUEST_METHOD']=='GET'){
$txtBox=$_GET['txtBox'];
$submit=$_GET['submit'];
//process request
}

form enctype="multipart/form-data" action="processRequest.php" method="post" name="frm2"
input value="testMe" name="txtBox" type="text"
input value="send" name="submit" type="submit"
/form

Below is the resulting request that would be sent to the web server when the form was submitted using POST.
(it is appended to the actual content portion along with the length of the content rather than appended to the URL).

POST /processRequest.php HTTP/1.1
Host: mysite.com
Content-length: 32
txtBox=testMe&submit=send
and you can access the variables in PHP using
if($_SERVER['REQUEST_METHOD']=='POST'){
$txtBox=$_POST['txtBox'];
$submit=$_POST['submit'];

//process request
}

So what's the difference?
Read On...

* if you specify the method as GET or you don't specify anything, the browser appends the data onto the URL.
http://mysite.com/products/getProductInfo.php?id=123
&type=hardware
* if you specify the method as POST the data is sent as standard input.
http://mysite.com/products/getProductInfo.php

You can use the GET method in the following scenarios:

# when you just want to get ( pun intended ) some data such as a query to list all products ( eg; a SELECT query).
# you used pagination and can use GET to get to the second page from a list of all pages.
1 2 3 4 5 6 7 8 9 10 Next 10
http://mysite.com/products/getProductInfo.php?id=123
&type=hardware&page=2

# to confirm registration for a subscription service such as newsletter, the service provider will mail you a confirmation mail back to you once you shows interests in thier service after entering say, your mailaddress.This URL where you have to confirm is a url appended with the variables.
http://www.myService.com/basePage.php?confirmationCode=mhtkhg
&confirmationEmail=fakemail%40rediffmail.com

See the variables does'nt even have to come from a form itself.

Pros:
# U can bookmark this and can also be used to paste this link in some other page or can use this specific information on social bookmarking sites such as digg.com or delicious.com for other users to jump directly into the specified page without any form submission.
# The variables can be changed directly from the location bar of the browser and has nothing to do with the form values.
# GET request is often cacheable.
Cons:
# Maximum URL length cannot be greater than 2,000 characters in that case you have to resort to POST.

You can use the POST method in the following scenarios:

# when you just want to update( changing values in a database, such as a DML statement), order a product( invovling a cash transaction).
# when sending mails or whenever your enctype is multipart/form-data for eg; in case of image or a file upload; ie, sending any non-ASCII characters to the server.

# when subscribing to a service such as newsletter, when first entering your eg: emailId or other unique values.
# when you don't want to let the user see what is submitted to the server.

Pros:
# actual form values can be greater than 2000
characters.
Cons:
# you can't cut and paste the information into a link.
# POST requests is only possible by using a form tag.


So have your say, Should I GET or should I POST???



Monday, October 10, 2005

Your Online Buddy

Have you ever talk to a (ro) bot intentionally, now is your chance to talk to one.This bot is a 14 year old boy maned Alec and he is sharp in certain areas though he gets bored very easily depending on your type of conservation. Be nice to him and don't use abusive words to him.
( he/she changes his ASL at times though ! )

Now on the other side, it was using collective knowledge compounded by many users ( some 5,958,189 and climbing ), it learns new things each time as it make conversations with us, so please don't put bad 0r false knowledge to it ( oh.. it depends on your knowledge too!) and yes it can even respond in many different languages. ( try " j'aime u " ). Try for yourself the other options such as Correct Me, Correct Yourself etc. Enjoy Yourself.

It would be good that the core developer Rollo Carpenter can make this an Expert System on a chosen field ( for example Introductory Maths, Science, Languages and things like that ) so that it would actually serve some purpose and besides it is a known fact that people tend to learn abusive words first when learning, so it would be good to restrict users from entering these type of words at the client-side itself.

On the technology front, it would be good if the site developers can use some form of remote scripting techniques such as AJAX so that users can have a real feel of conversation rather than waiting. Overall, the design is clean and simple.

So why wait here, go and chat with your friend at jabberwack.
But feel free to post your impressions right here. Bye for now.


Saturday, February 19, 2005

Cold Mountain - A Must See

Hi every one!. been a long time.. been a long time. Yesterday I watched Cold Mountain. To me it was a very satisfying movie to watch. It's been a long time since I saw a good beautiful movie.Yeah, it's a long epic drama ( Love, War....) spanning 2 hours 35 minutes. This is a tale of hope, longing, second chances, and faith.. Far more than a simple love story, it captures the horrors of war for both those fighting it, and for those left behind. You should see it to appreciate the true essence of the film.

The theme is set in the 1860's when Civil War is ravaging in the US. Ada Monroe (Nicole Kidman) accompanies her preacher father (Donald Sutherland) to Cold Mountain, North Carolina. She sees or got casually acquainted with W.P. Inman (Jude Law) -- a wood worker. There was very much love in thier hearts for each other but does'nt had the time to reenforce it. Inman was called to fight for his state and had to leave Ada, promising her that he will be back and she said she will wait for his return. But fate has other plans for them, he got shot on the neck and was in the hospital for many months. Ada's father had already died from his weak heart and she was left alone writing letters to Inman.

Then comes the turning point of the film when we got introduced to the no-nonsense Ruby (Renée Zellweger) , a spitfire who can work the land 27 hours a day and also strengthens Ada emotionally. Meanwhile, wounded Inman has had enough of war and killing, and is slowly working his way back to Ada despite the perils of being a Confederate deserter.

Law and Kidman are genuinely touching as two virtual strangers who invest all of their faith in each other, and Zellweger is astounding as the uncultured but compassionate Ruby. Overall the film has an impressive array of characters and they are all actually larger than the main actors.

This is the best critic review that I read about this film.

N.B: Did you see "The English Patient" starring Ralph Fiennes ?


Monday, November 01, 2004

My Favourite Movies

Film as dream, film as music. No art passes our conscience in the way film does, and goes directly to our feelings, deep down into the dark rooms of our souls. ~Ingmar Bergman

Movies have always been an important part in my life. Whether they be drama, horror, action, comedy, romance, or thrillers, movies have the power to captivate us and transport us to a completely different world.
Good movies will linger in my mind for a while and usually leave a lasting impression on me. I also place importance on quality whether it be quality of acting, plot, direction...
I don't say I am a great critic of films and I don't think I have seen all the good films that's been released in my time. I would like to see nice films not just from Hollywood , but world films from places like Europe, Iran, Far East, China etc..

Here is my list of top 10 movies I have seen (not in any order)

Usual Suspects, ShawShank Redemption, River Wild, Seven, Notting Hill, GodFather I, Cape Fear, The Good The Bad and the Ugly, LA Confidential, Ghost and Legends of the Fall.

Actually the list goes on but this above films are the one that will come to my mind everytime I talk about films. If you haven't seen any of these, I assure you that these are pretty good ones
to watch on a weekend.

Bye for Now .
Next Time I will list some more films I missed here and all my fav actors.

Thursday, October 21, 2004

Intro as Usual

Welcome Every One. I will be posting my thoughts and would like to share my views on Music, Movies, Books, Hobbies, Programming and anything under the moon.
Join me and let's walk on the wonderful world of Blogging.

See ya next time with something to talk about.

Wednesday, October 20, 2004

Words with a View

Words with a View