Pagination in symfony without criteria

November 28, 2009 1 comment

I have created a news aggregator and needed to paginate the results. I had the ‘feed’ object having an array of ‘feeditems’ objects in my actions. So, I could not use sfPropelPager as it needs a criteria object to pull objects from the database. The solution which worked for me is presented here. Disclaimer: This is a complete rip-off from the snippets section on symfony site, modified slightly to work with the latest version of symfony and php. I will add another post to paginate in sfFeed2Plugin when I have time.

Add this class to lib/helper or anywhere in lib and include it in the file you need to use pagination.

myArrayPager.class.php

<?php
class myArrayPager extends sfPager
{
protected $resultsArray = null;

public function __construct($class = null, $maxPerPage = 10)
{
parent::__construct($class, $maxPerPage);
}

public function init()
{
$this->setNbResults(count($this->resultsArray));

if (($this->getPage() == 0 || $this->getMaxPerPage() == 0))
{
$this->setLastPage(0);
} else {
$this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
}
}

public function setResultArray($array)
{
$this->resultsArray = $array;
}

public function getResultArray()
{
return $this->resultsArray;
}

public function retrieveObject($offset) {
return $this->resultsArray[$offset];
}

public function getResults()
{
return array_slice($this->resultsArray, ($this->getPage() – 1) * $this->getMaxPerPage(), $this->maxPerPage);
}
}
?>

In the action, instead of setting an object holding array of items, set the pager.

$empager = new myArrayPager(null, 10); //10 items per page
$empager->setResultArray($this->feed->getItems()); //my object is ‘feed’ which has ‘items’ array
$empager->setPage($request->getParameter(‘page’, 1));
$empager->init();

$this->pager = $empager;

Implementation of view is exactly the same as with sfPropelPager or the equivalent doctrine pager.

Enjoy!

Advertisements

Sorting and pagination with symfony

November 1, 2009 Leave a comment

It took me a couple of days to figure out how to display sorted, paginated results in PHP using symfony. While both pagination and sorting are easy, combining them (along with using routing framework of symfony) does produce some difficult-to-find bugs. Here is what worked for me. Note: the code needs some refactoring.

Lets say, I have a table named t_job.

project/config/schema.yml

t_job:
  id: ~
  name: { type: VARCHAR, size: ’45’, required: true }
  description: { type: VARCHAR, size: ‘255’ }
  popularity: { type: INTEGER }
  starts_at: { type: TIMESTAMP }
  expires_at: { type: TIMESTAMP }
  is_active: { type: BOOLEAN, default: 0 }
  created_at: ~
  updated_at: ~

Build sql, insert sql, build model, create module called job with symfony. My model classes are TJob and TJobPeer. At this step, you should be able to add, edit, delete a job. Remember to __toString methods to each of your model classes for default print outputs.

I am using all default routing for the sake of simplicity. You may add/modify those later to show pretty urls.

Open TJobPeer and add these static methods to create criteria objects. I have used separate methods for each criteria so that I can mix-and-match in different modules.

project/lib/model/TJobPeer.php

class TJobPeer extends BaseTJobPeer
{
static public function getActiveJobs(Criteria $criteria = null)
{
if (is_null($criteria))
{
$criteria = new Criteria();
}
$max=sfConfig::get(‘app_max_jobs_on_page’);   //need to add this constant in app.yml, required to determine the number of jobs to be displayed per page for pagination
$criteria->setLimit($max);
return self::doSelect($criteria);
}

static public function countActiveJobs(Criteria $criteria = null)
{
return self::doCount($criteria);
}

static public function addActiveJobsCriteria(Criteria $criteria = null)
{
if (is_null($criteria))
{
$criteria = new Criteria();
}
$criteria->addDescendingOrderByColumn(self::EXPIRES_AT);
$criteria->add(self::IS_ACTIVE, true);
return $criteria;
}

static public function addSortAscendingCriteria(Criteria $criteria = null)
{
if (is_null($criteria))
{
$criteria = new Criteria();
}
$criteria->addAscendingOrderByColumn(self::NAME);
return $criteria;
}

static public function addSortPopularityCriteria(Criteria $criteria = null)
{
if (is_null($criteria))
{
$criteria = new Criteria();
}
$criteria->addAscendingOrderByColumn(self::POPULARITY);
return $criteria;
}

static public function addSortNewestCriteria(Criteria $criteria = null)
{
if (is_null($criteria))
{
$criteria = new Criteria();
}
$criteria->addDescendingOrderByColumn(self::STARTS_AT);
return $criteria;
}
}

Modify the executeIndex function of actions.class.php as below:

project/apps/frontend/modules/job/actions.class.php

public function executeIndex(sfWebRequest $request)
{
$criteria = new Criteria();
$criteria = TJobPeer::addActiveJobsCriteria();
$this->setVar(‘sortoption’, ”, true);
if($request->getParameter(‘sortoption’) == ‘normal’){
$criteria = TJobPeer::addSortAscendingCriteria();
$this->setVar(‘sortoption’, ‘normal’, true);
}
if($request->getParameter(‘sortoption’) == ‘popularity’){
$criteria = TJobPeer::addSortPercentCriteria();
$this->setVar(‘sortoption’, ‘popularity’, true);
}
if($request->getParameter(‘sortoption’) == ‘newest’){
$criteria = TJobPeer::addSortNewestCriteria();
$this->setVar(‘sortoption’, ‘newest’, true);
}

$this->t_job_list = TJobPeer::getActiveJobs($criteria);

//These lines take care of pagination
$this->pager = new sfPropelPager(‘TJob’, sfConfig::get(‘app_max_jobs_on_page’));
$this->pager->setPage($request->getParameter(‘page’, 1));
$this->pager->setCriteria($criteria);
$this->pager->init();
}

Now the view. I have used a partial to reuse it elsewhere and I have removed my decoration in the following view file to make it understandable.

project/apps/frontend/modules/job/templates/indexSuccess.php

<a href=”<?php echo url_for(‘job/index?sortoption=normal’) ?>”>All</a>
<a href=”<?php echo url_for(‘job/index?sortoption=popularity’) ?>”>Popularity</a>
<a href=”<?php echo url_for(‘job/index?sortoption=newest’) ?>”>Latest</a>

<?php include_partial(‘job/list’, array(‘job_list’ => $pager->getResults())) ?>

<?php include_partial(‘job/paginate’, array(‘item’ => $t_job_list, ‘pager’ => $pager, ‘module’ => ‘job’, ‘sortpath’=> $sortoption )) ?>

And the partials:

project/apps/frontend/modules/job/templates/_list.php

<?php foreach ($job_list as $t_job): ?>

<div class=”job_listing”>
<h1><a href=”<?php echo url_for(‘show_job’, $t_job) ?>”><?php echo $t_job->getName() ?></a></h1>
</div>
<h1>up to <?php echo $t_job->getPopularity() ?>%</h1>
<div class=”clear”></div>

<div class=”job_listing”>
<p><?php echo $t_job->getDescription() ?></p>
</div>

<?php endforeach;?>

project/apps/frontend/modules/job/templates/_paginate.php

<?php if ($pager->haveToPaginate()): ?>
<div class=”pagination”>
<?php if(is_null($sortpath) or $sortpath==”): ?>
<a href=”<?php echo url_for($module, $item) ?>page=1″>First</a>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getPreviousPage() ?>”>Previous</a>
<?php foreach ($pager->getLinks() as $page): ?>
<?php if ($page == $pager->getPage()): ?>
<span class=”disabled”><?php echo $page ?></span>
<?php else: ?>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $page ?>”><?php echo $page ?></a>
<?php endif; ?>
<?php endforeach; ?>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getNextPage() ?>”>Next</a>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getLastPage() ?>”>Last</a>
<?php else: ?>
<a href=”<?php echo url_for($module, $item) ?>page=1&sortoption=<?php echo $sortpath ?>”>First</a>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getPreviousPage() ?>&sortoption=<?php echo $sortpath ?>”>Previous</a>
<?php foreach ($pager->getLinks() as $page): ?>
<?php if ($page == $pager->getPage()): ?>
<span class=”disabled”><?php echo $page ?></span>
<?php else: ?>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $page ?>&sortoption=<?php echo $sortpath ?>”><?php echo $page ?></a>
<?php endif; ?>
<?php endforeach; ?>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getNextPage() ?>&sortoption=<?php echo $sortpath ?>”>Next</a>
<a href=”<?php echo url_for($module, $item) ?>page=<?php echo $pager->getLastPage() ?>&sortoption=<?php echo $sortpath ?>”>Last</a>
<?php endif;?>
</div>
<?php endif; ?>

Thats it. Done! Enter test values in the database and point your browser to the module home path. Warning: I have modified table, column, model and other names and may have introduced a typo.

t_category:
id: ~
name: { type: VARCHAR, size: ’45’, required: true }
description: { type: VARCHAR, size: ’45’ }
slug: { type: varchar(255), required: true, index: unique }
parent_category_id: { type: INTEGER, foreignTable: t_category, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
created_at: ~
updated_at: ~

Open Source apps galore!

October 9, 2009 Leave a comment

I am trying to create a new website, I have a business idea in mind, I am not a hardcore techie. But I am willing to get my hands dirty as much as I can, within the limits forced on me by my lower-than-the-bespectacled-geek’s brain-to-body ratio and my half-used, ageing brain cells. What do I do? This is what I did…

I must say I am the more curious type. The first thing I always try, is to find out if I can build a system form raw components and leave a lot of room for customisation to myself. But I wanted to try out open source apps only. One must remember the weak points of using open source technologies before deciding on using them:

  1. The dev team usually does not provide complete support for installation/use/bugs etc. Although, this varies a lot between various open source projects depending on the scale at which the project is undertaken and who is/are the investor(s)/stakeholder(s). A few projects actually wind up and the users may be left on their own.
  2. The apps are meant to be used by users who intend not to spend much money on licensed, non open-source products. Hence, these OS (Open Source) apps are tested primarily 0n other freely available technology stack (server, database, operating system etc.) If you intend to use those on non-OS servers and databases, you may have to do the porting job yourself.

Considering all this in mind, I started with analyzing (reading documentations, if available, installing and running) various OS apps. The number of apps in PHP is definitely more than those developed in any other language. Since I am from JAVA background, I was very keen on finding JAVA-based apps. A good source of information about such apps is java-source.net. Two of the good apps I found were Jforum for adding a nice forum to your existing website and Roller to add a weblog. Both of these can be attached to your existing websites with minimal configuration. But I am looking to build a website from scratch. Thats where I need a content management system (CMS). A blog is a simple example of a CMS. WordPress is a great tool for a blog-type website. But a CMS can do much more:

  1. It keeps your website well organized and comprehensive,
  2. Its easy to create, easy to maintain with minimal technical knowledge,
  3. It increases the data security, and
  4. It greatly reduces your time and costs.

Here’s a list of top open source ones in news right now. These are, by no means, my choice as I haven’t tested them. The best source of feature set comparison and discussions are http://cmsreport.com and http://www.packtpub.com/award.

In no particular order:

Mambo

Mambo is a full-featured, award-winning content management system that can be used for everything from simple websites to complex corporate applications. It is used all over the world to power government portals, corporate intranets and extranets, ecommerce sites, nonprofit outreach, schools, church, and community sites. Mambo’s “power in simplicity” also makes it the CMS of choice for many small businesses and personal sites.

Joomla

Joomla is an award-winning content management system (CMS), which enables you to build Web sites and powerful online applications. Many aspects, including its ease-of-use and extensibility, have made Joomla the most popular Web site software available.

Drupal

Drupal is a free software package that allows an individual or a community of users to easily publish, manage and organize a wide variety of content on a website.

The built-in functionality, combined with dozens of freely available add-on modules, will enable features such as:

  • Electronic commerce
  • Blogs
  • Collaborative authoring environments
  • Forums
  • Peer-to-peer networking
  • Newsletters
  • Podcasting
  • Picture galleries
  • File uploads and downloads

DotNetNuke

DotNetNuke is a web content management system (WCM or CMS) and application development framework which enables businesses to quickly build and deploy feature-rich, interactive web sites and applications in Microsoft .NET. An intuitive, menu-driven interface allows even non-technical users to easily create new sites or extend the functionality and features of their existing web site.

SilverStripe

SilverStripe is an open source content management system. It’s simple to use, standards compliant, and offers great usability. The standout feature for me is the templating system, which uses simple placeholders within standard HTML to build the pages. Common functions — like menu systems — are built in and automatically generated, yet still offer full control over the styling.

phpNuke

Pligg

e107

mojoPortal

WordPress

…………and many more. There are a number of things to note before picking any of these for creating your website:

  1. Feature-set and robustness of the framework
  2. The size of the community – Drupal and Joomla in particular have large community
  3. Security provided by the framework
  4. Your level and type of technical knowledge – You may occasionally, need to integrate your own code to the existing CMS resources. Hence, if you know .Net, you may like to choose dotnetnuke and so on.
  5. Unique features in a CMS suitable for a particular purpose – WordPress may be more suitable for a simple blogging site and Pligg for a community site.

Considering all the above mentioned factors, coupled with my own online research, I decided to try out Drupal and Joomla. Once I am done with the trials, I’ll have something more to write.

CAPM preparation: A quick guide

October 4, 2009 Leave a comment

While PMP (Project Management Professional) certification, sponsored by the Project Management Institute (PMI), is the most recognized and respected certification credential in the field of project management, CAPM credential recognizes a demonstrated understanding of the fundamental knowledge, processes and terminology as defined in A Guide to the Project Management Body of Knowledge (PMBOK® Guide) that are needed for effective project management performance. To achieve CAPM credential, each candidate must satisfy a set of educational and experiential requirements established by PMI, agree to adhere to a code of professional conduct, and must demonstrate an acceptable and valid level of understanding and knowledge of project management. For more information, check the certification page on the PMI Web site. The next section describes easy steps to prepare for CAPM based on my personal experiences. (I was certified last month after preparing for about a month at my own relaxed pace.

Before I start on the 3 easy steps, let me emphasise that the most important help in your preparation will be your prior hands-on project management experience. I found it very easy to relate the course material to the practical cases I have witnessed in my 7 years of career in the IT industry. That knowledge gained on the job floor is the most valuable tool. So, if you think you lack that experience, at the same time feel confident of tackling the exam purely on the basis of reading literature, think again. Take a practice test (there are few available online for free), if you score below 50%, you will need a lot of time for preparation.

So, here are the 3 easy steps:

1) Read the PMBOK guide

2) Take a prep course

3) Practise tests before the actual exam

Now the details.

A few successful candidates in their post-exam retrospective analyses recommend reading the PMBOK guide 4-5 times. How do they manage to do that is beyond my understanding. I found the guide to be informative, but poorly organised with no element of humour or any intention of the writer(s) toward making the content interesting. With previous on-the-job experiences, you may know most of the stuff. After going through the first couple of chapters, I had to toil and drag with extra doses of caffiene to keep myself awake and pretend to read. Still, there is no escape. Every serious candidate must read it at least once to know the exact syllabus.

Fortunately for me, my online course prep material came to my rescue. I had taken Rita Mulcahy‘s PMP course material for preparation, intented for preparing candidates for PMP over 6 months period. The course is consice, lucidly written (and shown as videos) and to-the-point, no-nonsense prep material. Its an excellent material to fill gaps in your knowledge. More importantly, it keeps you interested in the subject. I went through the whole material once and partially revised at least twice. Again, I don’t like re-reading anything and so, I must give credit to Rita and team for coming up with this interesting course.

Practice tests – I took 2 of those from Rita’s course and a couple more from online sources. I wish, I had some more. I would advice anybody to take tests till he/she is comfortable taking long tests, its not easy concentrating for long hours.

Tips for exam day: You will get all your accessories during the exam – pencils, earplugs, sheets of paper to sketch anything you want. There is enough time, move at a constant pace. Go for breaks after every hour or take more if you like. I had no trouble concentrating and with sufficient time, was never stressed. Do not get bogged down on a question for which you may not be sure of the answer, just mark it and move ahead. You can get back at the marked questions later.

A disappointment for me was the absence of situational questions. I find those very easy and I hope, I’ll find more of those in the PMP exam. Taking cues from your actual PM experiences, its easy to tackle such questions. However, a careful reading of Rita’s course can also help you understand the PM perspective and a PM’s methods of responding to management problems.

If you have any specific questions, drop me a line. Good luck for your exam!

Trials and tribulations of setting up LAMP on Ubuntu

October 2, 2009 1 comment

I started with a quick assessment of available web frameworks/architectures (assume either, not delving into semantics). I have worked extensively in J2EE, used Hibernate for ORM along with Spring for dependency injection, reduce mundane coding…blah, blah…struts and AJAX. After scanning the “experts” views on many available web frameworks/architectures on the internet, I narrowed down to Ruby-on-Rails (RoR) and LAMP for trials.

Btw, moving over to Linux was something I had been contemplating for some time. Ubuntu seemed the obvious choice to me. I decided to give up Windows XP completely, by far, the best OS Microsoft has had to offer. Some reviewers have said Windows 7 scores over the rest but I refuse to pay $119.00 for a “few improvements” (rather fixes on Windows Vista) when Ubuntu provides all updates for free. And yes, I am prepared to wait and test Chrome OS which again, will be free.

Moving on, my assessment of RoR: It is a vast improvement over an OO language like JAVA. Coding is very intuitive, neat and most of all, cuts down heavily on extremely verbose language that is JAVA. Rails as a framework, is ok (I didn’t investigate enough to comment more on it). However, after 3 days of poking and playing with RoR, printing “Hello World” et. al., creating silly recursive loops with “blocks” (a good selling point of Ruby), I decided to move on. Reasons – 1) The documentation for RoR is limited 2) I had a feeling that code in Ruby could ultimately become complex to read and manage. 3) PHP community is vast and so is the number of resources for PHP-related stuff.

Setting up LAMP on Ubuntu has not been easy, even with all the references and help available from online community. But after 4 days, I am ready with my first full (sample) application in PHP. List of software/frameworks/tools I have used:

1) Ubuntu 9.04 Desktop edition
2) PHP Version 5.2.6
3) Apache Web Server
4) Eclipse PDT 2.1 for IDE
5) Mysql 5.1
6) Symfony 1.2.9
7) Subversion (SVN for version control)
8) Others in the process of installing 1-7

Basic considerations: Open source, free but without compromising significantly on quality.  I will point to a few online resources I have been using for the benefit of any newbie like me.

1) Things to do after installing Ubuntu
2) Basic PHP tutorial : very nicely written for beginners
2) Ubuntu documentation: first point of reference for OS problems. great community
3) Ubuntu LAMP for newbies, ApacheMySQLPHP, Installations with SSL : installation instructions
4) Propel (for database abstraction, and required by Symfony)
5) Symfony as a complete MVC framework for PHP

…will add more to the list.

I wish I could recall the numerous problems I faced reaching up to this point, mainly because I am new to Linux…was just too excited to keep moving ahead. Finally, I have a PHP application up and running 🙂

Categories: Programming Tags: , , , , , ,