Recent News

PunBB modification - Implementing iconized categories for forum topics

Posted by Anis Ahmad on November 13th, 2008

PunBB is one of the fastest and minimal forum softwares powered by PHP. PunBB says about itself:

PunBB is a fast and lightweight PHP-powered discussion board. It is released under the GNU General Public License. Its primary goals are to be faster, smaller and less graphically intensive as compared to other discussion boards. PunBB has fewer features than many other discussion boards, but is generally faster and outputs smaller, semantically correct XHTML-compliant pages.

You can see a detailed review about PunBB from forum-software.org.

What’s the purpose this mod?

PunBB has categories for forum. But there is no categorization for Topics like many other forums. This mod implements an iconized category for topics. The end result of this mod is -

  • It will add an excellent looking “Category Icons” fieldset in “Post new topic” form. (see Image#1)
  • Users can (optionally) select a topic category while posting a topic.
  • The category icon will be displayed beside the topic title in forum index page, topic detail page, search result etc. (see Image#2 and Image#3)
  • Clicking on a category icon will show all topics under that category.(see Image#4)

Lets see some screenshot of this modification :

Category icons in "Post new topic" form

Image#1:  Category icons in Post new topic form

Category icons before topic title in forum page

Image#2: Category icons before topic title in forum page

FireShot Pro capture #5 - 'User Contributed Deals _ Television is poluting our culture' - local_deals_com_forum_viewtopic_php_id=5

Image#3: Category icon in topic page

FireShot Pro capture #7 - 'User Contributed Deals _ Search results' - local_deals_com_forum_search_php_search_id=1345131291

Image#4: Filtering by category

Let’s start

I am assuming the objective and the screenshots have eluded you if you are reading up to this, so let’s start. It’s assumed that you’ve at least some working experience on PHP (don’t mind if you’re a guru) and already installed PunBB. So, now we will start straight from modifying our working PunBB. First of all, download necessary files from below and extract it.

Download files : Topic categories for PunBB

This zip file contains -

  1. PHP file to modify database : install_topic_category.php file
  2. Sql file for sample data : sample_data.sql file
  3. Sample category icons : cat-icons folder
  4. Edited files : modified-files folder

Note: sample icons are taken from http://forums.slickdeals.net/. Thanks to slickdeals.

Now we will complete the modification in 6 easy steps. The files in modified-files folder of the downloaded package are taken from PunBB 1.2.2 just after implementing this modification. It will be easier to find and modify if you keep open the modified  file when changing your copy.

1. Modify database

After extracting files, copy the install_topic_category.php to your PunBB root folder and go to http://<path_of_punbb_root>/install_topic_category.php from browser. It will create new table <db_prefix>topic_categories and new field cat_id in <db_prefix>topics table. To insert sample topic categories, run the queries of sample_data.sql.  Then copy the cat-icons folder to <punbb_root>/img.

Note : Before executing the queries, change the word <table_prefix> as your table prefix.

Note : All your category icons should keep in <punbb_root>/img/cat-icons folder.

2. Add categories field to “Post new topic” form

Open post.php file.

Find this line (line: 35)

$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;

Add this line below

$topic_category = isset($_POST['t_cat_id']) ? intval($_POST['t_cat_id']) : 0;
Find this query (line 289):
else if ($fid)
        {
            // Create the topic
            $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error());
and replace the query with this line:
            $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id, cat_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.', '.$topic_category.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error());
Now add the fieldset in form. Find this line (line: 505)
$checkboxes = array();
if (!$pun_user['is_guest'])
{

Add this code just above the “$checkboxes = array();”

if ($fid): ?>
                <fieldset>
                    <legend>Category(optional)</legend>
                    <div class="infldset">
                        You may choose a category icon for your message from the following list:<br>
                        <div class="rbox">
                            <?php
                            $cat_result = $db->query('SELECT * FROM '.$db->prefix.'topic_categories') or error('Unable to fetch topic category list', __FILE__, __LINE__, $db->error());
                            while ($cur_topic_cat = $db->fetch_assoc($cat_result)):
                            ?>
                            <span class="topic-cat">
                                <input type="radio" value='<?php echo $cur_topic_cat['id']?>' name="t_cat_id">
                                <img src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic_cat['cat_icon'] ?>" alt="<?php echo $cur_topic_cat['cat_name']?>" align="top"">
                            </span>
                            <?php endwhile; ?>
                            <div style="clear:both; height: 0px">&nbsp;</div>
                        </div>
                    </div>
                </fieldset>
<?php
endif;

Almost done. Just add this css to your template’s css file or put in header.php after line 80. Use <style> tag to add this in header.php

DIV.cat-icon {
    width: 47;
    height: 16;
    margin: 0px 5px;
    FLOAT: left;
    DISPLAY: block;
    border: none;
}
span.topic-cat{
    display: block;
    float: left;
    width: 100px;
    padding: 2px;
}
span.topic-cat input{
    margin-right: 2px;
}
span.topic-cat img{
    @margin-top: 3px;
}

Now you should see a fieldset in your form like Image#1.

Verify this change: Go to “Post new topic” page and see if their is a fieldset containing  category icons. Post a topic with selecting the category “Media”. Check the <prefix>topics table in database. ‘11′ should be the value of cat_id field for last topic.

3. Display category icon in topic list

To display category icons in topic list, we have to modify 3 lines in viewforum.php.

Open the viewforum.php and find this lines (line:110)

if ($pun_user['is_guest'] || $pun_config['o_show_dot'] == '0')
{
    // Without "the dot"
    $sql = 'SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];

Change the query of line 113 with this:

$sql = 'SELECT  t.id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to,
                tc.id as t_cat_id, tc.cat_name, tc.cat_icon
          FROM  '.$db->prefix.'topics as t
                LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id
         WHERE  forum_id='.$id.'
         ORDER  BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC
         LIMIT  '.$start_from.', '.$pun_user['disp_topics'];

And, Just after 7 lines of this change, the query below “‘case ‘mysqli’:” change with this one:

$sql = 'SELECT  p.poster_id AS has_posted,
                t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to,
                tc.id as t_cat_id, tc.cat_name, tc.cat_icon
        FROM    '.$db->prefix.'topics AS t
                LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$pun_user['id'].'
                LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id
         WHERE  t.forum_id='.$id.'
         GROUP  BY t.id
         ORDER  BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC
         LIMIT  '.$start_from.', '.$pun_user['disp_topics'];

If your database is sqlite, you have to change the query below “case ’sqlite’:” instead of the above.

Now find this line: (line: 221 originally/226 after applying changes above.)

<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>

Add this lines below

<?php if(!empty($cur_topic['cat_icon'])): ?>
<div class="cat-icon">
    <a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $cur_topic['t_cat_id'] ?>"><img src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic['cat_icon'] ?>" alt="<?php echo $cur_topic['cat_name']?>" title="<?php echo $cur_topic['cat_name']?>"></a>
</div>
<?php endif; ?>

Ok, Done. Now if you go to index of a forum, you should see category icons at the left side of topics(for whose category icon was selected) as shown in image#2.

Verify this change: Go to the forum index in which you have posted a new topic in previous step. See if there is an icon of media before the new topic title.

4. Display category icon in Topic details page

Now we will change in viewtopic.php to show icons in topic page.

Open the file and go to this line (line: 96)

// Fetch some info about the topic
if (!$pun_user['is_guest'])
There is two queries at line 98 and line 100. First, replace the query of line 98 with this:
$result = $db->query('SELECT  t.subject, t.closed, t.num_replies, t.sticky,
                              f.id AS forum_id, f.forum_name, f.moderators,
                              fp.post_replies,
                              s.user_id AS is_subscribed,
                              tc.id as t_cat_id, tc.cat_name, tc.cat_icon
                        FROM  '.$db->prefix.'topics AS t
                              INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id
                              LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].')
                              LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')
                              LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id
                       WHERE  (fp.read_forum IS NULL OR fp.read_forum=1)
                              AND t.id='.$id.'
                              AND t.moved_to IS NULL')
or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());

And replace the other query (used for else) with the query below:

$result = $db->query('SELECT  t.subject, t.closed, t.num_replies, t.sticky,
                              f.id AS forum_id, f.forum_name, f.moderators,
                              fp.post_replies, 0,
                              tc.id as t_cat_id, tc.cat_name, tc.cat_icon
                        FROM  '.$db->prefix.'topics AS t
                              INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id
                              LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')
                              LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id
                       WHERE  (fp.read_forum IS NULL OR fp.read_forum=1)
                              AND t.id='.$id.'
                              AND t.moved_to IS NULL')
or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());

Find this line (Line: 315 originally/ 339 after applying the changes above)

<h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?>&nbsp;</span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>

Replace with this lines:

<h2>
    <span>
        <span class="conr">#<?php echo ($start_from + $post_count) ?>&nbsp;</span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a>
        <?php if(!isset($category_printed) && !empty($cur_topic['cat_icon'])): ?>
            <a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $cur_topic['t_cat_id'] ?>"><img align="top" src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic['cat_icon'] ?>" alt="<?php echo $cur_topic['cat_name']?>" title="<?php echo $cur_topic['cat_name']?>"></a>
        <?php
        $category_printed = true;
        endif;
        ?>
    </span>
</h2>

You will see the category icon after the posting time in topic details page after applying the changes above as shown in Image#3.

Verify this change: Click on a the topic title which you posted in step 2. In the details page of the topic, check there is an icon of media after posting time of first post of topic.

5. Display category icon in search result

Here we will change the search.php so that icons appears in the listing of search result. First open the search.php and go to line 462. Replace the query of else block with:

$sql = 'SELECT  t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id,
                            tc.id as t_cat_id, tc.cat_name, tc.cat_icon
                      FROM  '.$db->prefix.'topics AS t
                            LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id
                     WHERE  t.id IN('.$search_results.')
                     ORDER  BY '.$sort_by_sql;

Find this line of search.php  (line: 644 originally/650 after applying changes above.)

<div class="tclcon">
Add the following snippet  above this line:
<div class="cat-icon">
    <a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $search_set[$i]['t_cat_id'] ?>"><img src="<?php echo PUN_ROOT . 'img/cat-icons/' . $search_set[$i]['cat_icon'] ?>" alt="<?php echo $search_set[$i]['cat_name']?>" title="<?php echo $search_set[$i]['cat_name']?>"></a>
</div>

Ok. Now you should see Category Icons in search result as other pages.

6. Filtering (or displaying) by category

At last, we will make icons enable for filtering. After completing this step, if you click on a category icon, it will show all topics which were posted under this topic category. This change will also happen in search.php.

Find this line in search.php (line 85)

// If it's a user search (by id)
else if ($action == 'show_user')

Add the following elseif block after ending of this elseif :

else if ($action == 'show_cat')
{
    $topic_cat_id = intval($_GET['t_cat_id']);
    if ($topic_cat_id < 1)
        message($lang_common['Bad request']);
}

Find this line (Line: 321 originally/ 327 after applying the changes above)

else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered')

And replace with this line:

else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered' || $action == 'show_cat')

Find this line (Line: 344 originally/ 350 after applying the changes above)

// If it's a search for posts by a specific user ID
else if ($action == 'show_user')

Add the following elseif block after closing of this elseif :

else if ($action == 'show_cat')
{
    $result = $db->query('SELECT  t.id
                            FROM  '.$db->prefix.'topics AS t
                                  INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id
                                  LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')
                           WHERE  (fp.read_forum IS NULL OR fp.read_forum=1)
                                  AND t.cat_id='.$topic_cat_id.' GROUP BY t.id')
                   or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    $num_hits = $db->num_rows($result);

    if (!$num_hits)
        message($lang_search['No user posts']);
}

Everything is done. Now your icons are enabled to filtering topics.

Verify this change : Post 3 topics under 3 different forum with same topic category. And, from anywhere click on this category icon. Now you should see these 3 topics together as image#4.

We’re finished implementing Topic categories for PunBB. You can ask me anything about this modification. I will try my best to reply. Thanks a lot for staying this l-o-n-g time with ajaxray.

Image manipulation in Zend Framework using PHP Thumbnailer Class v2.0

Posted by Anis Ahmad on September 12th, 2008

In the huge set of library, Zend Framework have no options for manipulating image. There is a proposal for Zend_Image which aimed to provides easier image manipulation using GD. But the proposal was not considered. Bill Karwin of ZF said,

Proposal not being considered

This proposal has been reviewed. The proposal describes functionality that is very similar to the existing PHP interfaces for ImageMagick or GD.

We are not considering this for inclusion in the Zend Framework at this time.

So, what to do when we need to make image thumbnail, resizeing or cropping image etc in Zend Framework?

The Solution

Zend Framework has the extensive power of integrating any library. So, we can use ImageMagick or GD library or any wrapper class using this libraries for manipulating image.

Here, I am explaining creating image thumbnail using PHP Thumbnailer Class v2.0 in 2 easy steps. I am assuming that, you are using Zend’s MVC with common directory structure and you’ve GD library with your PHP installation.

Step 1 - Create a Model for image manipulation :

Download the PHP5 version of PHP Thumbnailer Class v2.0 and put the class file “thumbnail.inc.php” in your model directory. Now change the file name to “Thumbnail.php” as it’s class name. Now your model is ready for action.

Step 2 - Use this model in Controller :

In your Controller, write a function to make thumbnails using this model. For example, you can use this function below:

   1: /**
   2:  * Create thumbnail of an image
   3:  * 
   4:  * @author    Anis uddin Ahmad (http://www.ajaxray.com)
   5:  * @param     string    Path of source image
   6:  * @param     string    Destination path of thumbnail
   7:  * @param     number    Width of thumbnail
   8:  * @param     number    Height of thumbnail
   9:  * @param     number    (optional) thumbnail image quality 
  10:  */
  11: private function _createThumbnail($sourcePath, $destPath, $w, $h, $q = 100)
  12:  {
  13:     $thumb = new Thumbnail($sourcePath);
  14:     $thumb->resize($w, $h);
  15:     $thumb->save($destPath, $q);
  16:  }

Done. Now you can use this function to resize/make thumbnail of an image. To resize an image with keeping it’s original name, pass the $sourcePath again in $destPath parameter. Then it will overwrite the existing image.

So, was it so though to manipulate image in ZF?

Join Problems with Zend_Paginator and Zend_Db_Select objects

Posted by Anis Ahmad on August 24th, 2008

Zend_Paginator is one of the newest members of Zend framework family. It’s surely a rich addition with Zend’s power. Moreover, It’s handling the main data of pagination, not only pagination links. Which I didn’t found in any other pagination library.

But, when I (and many other developers) start to working with this library, found many problems/bugs. The matter is, they are being solved very fast and hope to get a bullet-proof pagination library soon. For example, here is tow important fixings about Zend_Paginator and Zend_Db_Table_Select.

I had to face a problem with Zend_Paginator when using Join in Zend_Db_Select object. I am explaining here how the problem arises and how to solve it.

The Problem

One of the 4 Adapters for Zend_Paginator is DbSelect which uses a Zend_Db_Select instance. Now, the problem occurred if I need to have some calculative data from other tables and use join with the Zend_Db_Select object for them. For example, I am retrieving data from `deals` table and collecting number of comments from `comments` table and total votes from `votes` table. So, with other conditions, I had to add this lines with select object:

   1: $select->joinLeft(array('c' => 'comments'), 'deals.id = c.deal_id', array('total_comments'=> 'count(c.id)') );
   2: $select->joinLeft(array('v' => 'votes'),    'delas.id = v.deal_id', array('total_votes'   => 'count(v.id)') );
   3: $select->group($this->_name . '.id');

 

Now, the Zend_Paginator will always calculate the TotalRows as 1. That means, $this->totalItemCount; will always print 1 in “view partial“.

Why it happens?

Let’s take a look to the count function of DbSelect Adaptor of Zend_Paginator:

   1: public function count()
   2: {
   3:     if ($this->_rowCount === null) {
   4:         $expression = new Zend_Db_Expr('COUNT(*) AS ' . self::ROW_COUNT_COLUMN);
   5:         
   6:         $rowCount   = clone $this->_select;
   7:         $rowCount->reset(Zend_Db_Select::COLUMNS)
   8:                  ->reset(Zend_Db_Select::ORDER)
   9:                  ->reset(Zend_Db_Select::LIMIT_OFFSET)
  10:                  ->columns($expression);
  11:                  
  12:         $this->setRowCount($rowCount);
  13:     }
  14:  
  15:     return $this->_rowCount;
  16: }

Here, at line 7, the column list is being removed. But we have a `Group By` clause in our select object which is not cleared by this function and the result is always 1. At this point, if we add “->reset(Zend_Db_Select::GROUP)” after line 9, the calculation will get rid from always being 1. But there will arise another problem. That is, joined tables are still remaining in `From` clause. You can see them by adding “die(print_r($rowCount->getPart(Zend_Db_Select::FROM)));” after line 10. This join tables will make the calculation inconsistence because there is no expression columns now to summarize their result.

The Solution

Just alter this function as following to prevent this problem:

   1: public function count()
   2: {
   3:     if ($this->_rowCount === null) {
   4:         $expression = new Zend_Db_Expr('COUNT(*) AS ' . self::ROW_COUNT_COLUMN);
   5:        
   6:         $rowCount   = clone $this->_select;
   7:         $rowCount->reset(Zend_Db_Select::FROM);
   8:         
   9:         foreach($this->_select->getPart(Zend_Db_Select::FROM) as $name => $table)
  10:         {
  11:             if(empty($table['joinCondition']))        
  12:             {
  13:                 $rowCount->from(array($name => $table['tableName']));
  14:             }
  15:             elseif($table['joinType'] == 'inner join')        
  16:             {
  17:                 $rowCount->join(array($name => $table['tableName']), $table['joinCondition']);
  18:             }
  19:         }
  20:         
  21:         $rowCount->reset(Zend_Db_Select::COLUMNS)
  22:                  ->reset(Zend_Db_Select::ORDER)
  23:                  ->reset(Zend_Db_Select::GROUP)
  24:                  ->reset(Zend_Db_Select::LIMIT_OFFSET)
  25:                  ->columns($expression);
  26:  
  27:         $this->setRowCount($rowCount);
  28:     }
  29:  
  30:     return $this->_rowCount;
  31: }

At line 9, I am running a foreach which will remove the `from` clause and again assign only the main table and inner join tables. And, at line 23, just removing the `Group By` clause from query. Now, this function will provide right calculation even when there is some joins like this. But, if you use inner join in your Zend_Db_Select object (which is very rare for pagination), this function may not serve properly.

If there is any mistake in this alternation or any other way can make it better, please let me know. And… let’s meet power with simplicity.

UPDATE [26/08/08] : The function is updated and hopefully it will work fine for inner joins too.

UPDATE [24/09/08] : This issue is solved in ZF 1.6. Jurrien Stutterheim has reported about this post in Zend Framework Issue tracker and worked on it. After the release of 1.6, he requested me to check if this issue still exist. I’ve checked and found it solved. Thanks to Jurriën Stutterheim.

My Bookmarks - A Wordpress plugin to show your valuable bookmarks on sidebar

Posted by Anis Ahmad on August 8th, 2008

If you are using delicious or simpy as your bookmarking tool, this plugin is for you. This will help a wordpress user to show his valuable bookmarks on sidebar. Just install this plugin and set your options in plugins settings page - you are done. When you add or update links on your bookmarking site, this section will be automatically updated.

my_bookmarks

The settings page of My Bookmarks in wordpress admin panel

Download

Click here to download the My Bookmarks Wordpress plugin (80.3 KB).

Downloaded : 507 times

To see a live demo, see the “My Bookmarks” section of sidebar of this blog.

Installation

Installation of this plugin is very easy. First, be sure that you are using latest(2.6) version of wordpress. Then follow this 3 easy steps.

  1. Extract and upload the `MyBookmarks` directory to the `/wp-content/plugins/` directory.
  2. Activate the plugin through the Plugins menu in WordPress.
  3. Go to Settings > My Bookmarks page and make it yours.

Upcoming features

I’ve planned to add some more feature in next version of this plugin. Your comment about any modification or feature request is very mush welcome.

  1. Add caching to store link information in your server. So that, no need to fetch from feeds every time.
  2. Allow more bookmark sites like digg, netvouz, etc.
  3. Adding additional links with parsed feed.
  4. Make independent about enabling blogroll.
  5. ……….. and more.

For any Question/Suggestion please contact me at admin@ajaxray.com

Happy bookmarking, Happy blogging!

Developing web application with PHP-MySql-Apache in Ubuntu Linux

Posted by Anis Ahmad on July 5th, 2008

I have started using Ubuntu 8.04 in few days ago and found it Great. So, now I’ve moved my development environment from windows and working in Ubuntu. Here I am just explaining what steps I had to take for this jump. Also have a listing of some development related softwares/tools which I am using as replacement of windows applications.

Installing Apache, Php5, MySql in Ubuntu:

You can install Apache, Php, Mysql and other applications from Synaptic Package Manager. Go to System > Administration > Synaptic Package Manager and search with your desired application name. When found, double-click on package name. The package will be marked for installation along with it’s dependences. Now click on apply button to install the package. In this post, the red+bold texts are the name of software package which can be installed from Synaptic Package Manager.

To make your system ready for PHP development, you have to install more or less this packages: apache2.2-common, apache2-utils, php5, mysql-server-5.0, mysql-client-5.0, mysql-query-browser etc. You may also require some common php extensions which may not installed automatically with PHP installation. Most of them also will be found in Synaptic Package Manager as php5-gd, php5-curl, php5-mysql, php-pear etc.

Paths of important directories

One of the major differences I find here is the file system. All the directory paths I’ve been using in windows are changed here. I m listing here some PHP-MySql related paths here. But they may differ on your installation.

  • Apache configation files: /etc/apache2/
  • localhost root directory: /var/www/
  • PHP ini file: /etc/php5/apache2/
  • PHP extensions configuration files : /etc/php5/conf.d
  • MySql Data files: /var/lib/mysql/mysql
  • MySql Configuration files: /etc/mysql/

PHP Editors for Ubuntu

Gedit is the default text editor of Ubuntu and it support syntax coloring for many languages including PHP. But If you want an advanced editor for programming, you can try Geany or Screem. But, I am sure, who’ve been using advanced IDEs like PHPEd or PHPDesigner in windows, none of this can satisfy him. Don’t worry, the great open source IDE eclips has PHP-Development-Tool. It’s surely one of the best PHP IDE.

Subversion in Ubuntu

Subversion maintains current and historical versions of source code and documentation. It’s very important for distributed application development. RapidSVN is a graphical client for the subversion revision control system (svn) for linux. If you want to use svn from command line, install subversion.

File Difference and Merging Tools for Ubuntu

I have been using WinMerge in windows as file comparison and merging tool along with TortoiseSVN. Now using TkDiff as it’s alternative in linux. TkDiff has advanced functionalities and graphical interface. It provides file-merge and change-summary facilities, line number toggling (for easier cut & paste) and support for Subversion, RCS, CVS and SCCS. To use from command line, diff is may be the simplest file comparison tool.

Ftp and SSH

Ubuntu installs its default programs for FTP, SSH and many other internet applications. But, I’ve liked gFTP as FTP application because of it’s interface is similar to SmartFTP. And for working with SSH, required nothing. Just open the terminal and use ssh command. Write something like ssh username@example.com and press ENTER.

Testing in IE

One of the important (and painful to me) issue of web development is testing the output in IE. Though IE has no version for Linux, you can install it through wine. Wine is a application that crates a virtual environment for installing windows applications in Linux. After installing wine, you can install any available version of IE from http://www.tatanka.com.br/ies4linux/page/Installation:Ubuntu.

When witting this post, my aim was to help a developer who is thinking to switch to Ubuntu Linux or a newcomer here. You are welcome to add your valuable comment/suggestion for the same purpose.

PHP Universal Feed Parser - lightweight PHP class for parsing RSS and ATOM feeds.

Posted by Anis Ahmad on May 2nd, 2008

After the PHP Universal Feed Generator, I’ve written the PHP Universal Feed Parser for Orchid Framework. It’s a RSS and ATOM parser written in PHP5. Though there are many feed parsers over Internet, none of those was serving the basic focuses of Orchid: pure object orientation, being lightweight etc. So, I had to write a new one.

UPDATE(15th May, 2008) : cURL support added. Where url fopen() is disabled, the class will use cURL to load the RSS/ATOM content.

Features:

  • Parses all channels and feed item tags and sub tags.
  • Serve the parsed data as associative array.
  • Enough documented and easy to understand code.
  • Many ways to get parsed information.
  • Parsing includes attributes too.
  • No regular expression used.
  • Parsed by XML Parser extension of PHP.
  • Pure PHP5 objected oriented.
  • Enable to parse all commonly used feed versions.

Supported versions: I tried to include all stable and commonly used feed versions. Currently it’s being used to parse the following versions:

  • RSS 1.0
  • RSS 2.0
  • ATOM 1.0

Download:

  • Click Here to get the class file with example. (downloaded 1283 times)
  • Download from phpclasses.org.

How to use:

It’s dead simple to use this class. Just follow this 3 steps:

1. Include the file

include(’FeedParser.php’);

2. Create an object of FeedParser class

$Parser = new FeedParser();

3. Parse the URL you want to featch

$Parser->parse(’http://www.sitepoint.com/rss.php’);

Done.

Now you can use this functions to get various information of parsed feed:

  • $Parser->getChannels() - To get all channel elements as array
  • $Parser->getItems() - To get all feed elements as array
  • $Parser->getChannel($name) - To get a channel element by name
  • $Parser->getItem($index) - To get a feed element as array by it’s index
  • $Parser->getTotalItems() - To get the number of total feed elements
  • $Parser->getFeedVersion() - To get the detected version of parsed feed
  • $Parser->getParsedUrl() - To get the parsed feed URL

A simple example:

Here is a simple example of using this Feed Parser class. Click here to see is the output of this example.

<?php 
include('FeedParser.php'); 
$Parser     = new FeedParser();
$Parser->parse('http://www.sitepoint.com/rss.php');
 
$channels   = $Parser->getChannels();     
$items      = $Parser->getItems();        
?>
<h1 id="title"><a href="<?php echo $channels['LINK']; ?>"><?php echo $channels['TITLE']; ?></a></h1>
<p id="description"><?php echo $channels['DESCRIPTION']; ?> </p>
 
<?php foreach($items as $item): ?>
    <a class="feed-title" href="<?php echo $item['LINK']; ?>"><?php echo $item['TITLE']; ?></a>
    <p class="feed-description"><?php echo $item['DESCRIPTION']; ?></p>
<?php endforeach;?>

I hope, this class is so easy that, anyone who have general knowledge about PHP5 can use it. Whatever it is, Feel free to ask me anything, anytime.

PHP Universal Feed Generator (supports RSS 1.0, RSS 2.0 and ATOM)

Posted by Anis Ahmad on March 8th, 2008

It’s been a while since I’ve planned on developing a RSS writer that fulfills most my needs by supporting the various feed formats. Although the necessity was the prime force behind it, a discussion with Hasin and Emran has put the actual fire in. We were discussing about what can be added next in the Orchid - “PHP framework for the rest of us” and suddenly it hit me. At last, it’s finally complete and I’ve named it "PHP Universal Feed Generator", as it generates both ATOM and RSS feeds.

Supported versions:

  • RSS 1.0 (which officially obsoleted RSS 0.90)
  • RSS 2.0 (which officially obsoleted RSS 0.91, 0.92, 0.93 and 0.94)
  • ATOM 1.0

Download: 

Features:

  • Generates RSS 1.0, RSS 2.0 and ATOM 1.0 feeds
  • All feeds are are validated by feed validator.
  • Supports all possible feed elements.
  • Simple and easy to define channel and feed items
  • Implements appropriate namespaces for different versions.
  • Automatically converts date formats.
  • Generates UUID for ATOM feeds.
  • Enables usage of subtags and attributes. (example: image and encloser tags)
  • Completely Object oriented in PHP5 class structure.
  • Handles CDATA encoding for required tags.
  • Nearly same code for generating all kinds of feed

A minimum example

It’s a minimum example of using this class. I am generating a RSS 2.0 feed from retrieved data from a MySQL database. There are more examples in the download package for different versions.

<?php
  // This is a minimum example of using the Universal Feed Generator Class
  include("FeedWriter.php");