Spiga

‘ Programing ’ category archive

Install Error: Missing Dependency: perl(URI) >= 1.17 is needed by package subversion

December 29, 08 by Gabi Solomon

Today i finally decided to go ahead with installing subversion, after a bit of reading i opened a ssh session and input :

[root@servername ~]# yum install subversion

But to my surprise i got an error :(

Error: Missing Dependency: perl(URI) >= 1.17 is needed by package subversion

After a bit of googling i managed to find a solution on a forum and i thought to post it here, maybe other will find it faster :D

First we need to download the perl(URI) with version greater than 1.17 using the following command.

wget http://yum.trixbox.org/centos/5/RPMS/perl-URI-1.35-3.noarch.rpm

Then to install the perl package :

rpm -i perl-URI-1.35-3.noarch.rpm

That is it, you can now install and configure subversion as normal.

Cheers.

Multilanguage database design approach

December 26, 08 by Gabi Solomon

Preinfo

Before you go right to the comment section and recommend gettext or other similar ways, know that i am talking about content that is manageable from an admin panel or is added by the user

Also this article is based on personal experience and is not necessary the best way to do this.

Building a metalanguage website poses a lot of problems, and one of them is how you store the content in the database for each language.

If you do a google search you will find little resources about it, and most of the are on forums. This seem a bit strange to me, so after i had decided on a database schema for a metalanguage website i decided to post it here in the hope that other people might find it useful and save them some googling time.

As far as i searched there are more or less 4 databases schemas for metalanguage website.

1. Column approach

This approach is very common and basically it duplicates the column of content for each language.

table pages
-- id (int)
-- title_en (varchar)
-- title_es (varchar)
-- content_en (varchar)
-- content_es (varchar)

The way you would query it is by automatically selecting the right columns according to the language chosen:

SQL:
  1. SELECT `id`, `title_en` AS `title`, `content_en` AS `content` FROM `pages`

Or you could select all and do the column selection from php :

PHP:
  1. echo $rowPage['title' . $_SESSION['currentLanguage']];

Advantages

  • It doesn't have duplicate content, since there is only one row for each record, and only the language columns are duplicated
  • Easy to implement

Disadvantages

  • You need to build the watch what column you are working with depending on the language
  • Hard to maintain. Although this is a easy way for 2-3 languages its becomes a real drag when you have a lot of columns or a lot of languages
  • Hard to add a new language

2. Multirow approach

Another approach that i saw but i have never worked with it. It is simillar to the one above but instead of duplicating the content in columns it does it in rows.

table pages
-- id (int)
-- language_id (int)
-- title (varchar)
-- content (varchar)

So you will basically have 3 rows for the same page if you have 3 languages. The main problem i see with this approach is that it would be a bit tricky to know witch id you will use for the table relations.

Sorry but since i dont really have experience with this i cant show you sql & php examples.

Advantages

  • Ease in adding a new language

Disadvantages

  • Need to watch the table relations
  • A lot of duplicate content. You will have duplicate content for all the columns that are not translated

3. Single Translation table approach

This is an approach that becomes a little more complex then the other 2, but it is more suited for dinamic websites and which have a large number of languages or which intend to add a new language in the future and want to do it with ease.

table languages
-- id (int)
-- name (varchar)

table pages
-- id (int)
-- language_id (int)
-- title (int fk)
-- content (int fk)

table translation
-- id (int)

table translation_entry
-- translation_id (int)
-- language_id (int)
-- content (text)

In this approach you would store the id from the translation table in the title and content columns from the pages table, and then do a join with the translation_entry table based on the language id.

Advantages

  • Proper normalization
  • Ease in adding a new language

Disadvantages

  • Longer joins and query to get the content
  • All the translated content goes into one table
  • For me it just looks hard to work with and maintain

4. Coupled Translation table approach [my aproach :D ]

This is a variation of the above approach that to me seems easier to maintain and work with.
Instead of having just one translation table, you have one for each table. and you move the columns from the pages that need to be translated to the translation table.

table languages
-- id (int)
-- name (varchar)

table pages
-- id (int)

table pages_translation
-- id (int)
-- page_id (int)
-- language_id (int)
-- title (text)
-- content (text)

To get your data you just do a simple join:

SQL:
  1. SELECT * FROM `pages` JOIN `pages_translation` ON `pages`.`id` = `pages_translation`.`page_id` WHERE `map_landmarks_translation`.`language_id`='1'

Advantages

  • Proper normalization
  • Ease in adding a new language
  • Easy to query
  • Columns keep there names

Disadvantages

  • You have to create translation tables for all your tables that have columns that need to be translated

Conclusion

I am sure that there are other methods of doing a multilingual website, this are just the ones that i thought are most commonly used. My solution is the best, its just the best for me, because it works for my project and its easier for me to work with compared to other approaches.
In the end the best approach is the one that is the best for you. The one that you find the most easier to work with and maintain.

Cheers,
and good coding.

using Zend Framework Language component

December 15, 08 by Gabi Solomon

Today i will continue the series of articles on the zend framework and i am going to talk about how i come to use the language component from zend.

The way i decided to go with it is by having a controller plugin that starts the language component and also detects the language.

But first thing first. We need to make the url to allow us to change the language. And to do that i added a new rule in the bootstrap file:

PHP:
  1. $route = new Zend_Controller_Router_Route(
  2.             ':language/:controller/:action/*',
  3.                 array(
  4.                     'language'   => 'en',
  5.                     'module'     => 'default',
  6.                     'controller' => 'index',
  7.                     'action'     => 'index'
  8.                 )
  9.             );
  10.         $router->addRoute('lang_default', $route);

This rule will produce urls like:

http://www.domain.com/en/controller/action

http://www.domain.com/es/controller/action

I decided to go with this type of URL instead of caching or storing the language in the session to not have google consider our pages as duplicate content. I have read that it better to go with subdomains (ex: http://en.domain.com/controller/action ) that with directories but for now i will do it this way.

Now that we are still in the bootstrapfile, we will also add our plugin:

PHP:
  1. Zend_Controller_Front::getInstance()->registerPlugin(new GSD_Controller_Plugin_Language());

ANd now for the final touch the plugin:

PHP:
  1. <?php
  2.  
  3.  
  4.  
  5. /**
  6. * Front Controller Plugin
  7. *
  8. * @uses       Zend_Controller_Plugin_Abstract
  9. * @category   GSD
  10. * @package    GSD_Controller
  11. * @subpackage Plugins
  12. */
  13. class GSD_Controller_Plugin_Language extends Zend_Controller_Plugin_Abstract
  14. {
  15.        
  16.     public function routeShutdown(Zend_Controller_Request_Abstract $request)
  17.     {
  18.        
  19.         $locale = new Zend_Locale();
  20.        
  21.         $options = array('scan' => Zend_Translate::LOCALE_FILENAME);
  22.         $translate = new Zend_Translate('gettext', Zend_Registry::get('siteRootDir') . '/application/languages/', 'auto', $options);
  23.        
  24.         $requestParams = $this->getRequest()->getParams();
  25.         $language = (isset($requestParams['language'])) ? $requestParams['language'] : false;
  26.                 if ($language == false) {
  27.                      $language = ($translate->isAvailable($locale->getLanguage())) ? $locale->getLanguage() : 'en';
  28.                 }   
  29.         if (!$translate->isAvailable($language)) {
  30.             throw new Zend_Controller_Action_Exception('This page dont exist',404);
  31.         } else {
  32.        $locale->setLocale($language);
  33.             $translate->setLocale($locale);
  34.             
  35.             Zend_Form::setDefaultTranslator($translate);                                
  36.    
  37.            
  38.             setcookie('lang', $locale->getLanguage(), null, '/');
  39.             
  40.             Zend_Registry::set('Zend_Locale', $locale);
  41.             Zend_Registry::set('Zend_Translate', $translate);
  42.         }
  43.     }
  44. }

A few explanations on the code.
I am using gettext adapter with auto mode ... witch will basically crawl the language directory to detect what languages can you support. I also use it conjunction with Zend Locale and at the end i store the in the Registry.
Storing Zend translate in the registry will enable you to use it in the view in a very easy way using a built in helper.

Using translate in you controllers

PHP:
  1. $this->view->title = $this->view->translate('default-register-index-title');

Using translate in you views

PHP:
  1. <?php echo $this->translate('default-register-index-title'); ?>

As a note i am not using the full text for translate i am using keys that have a naming conventions like "module-controller-action-message". I find it much more easier then putting the whole string and also much more easier to maintain. Imagine if you misspelled a string, or want to modify it ? you will then have to modify it every in your code.

That is basically it.
Cheers

Update:
I have also published this plugin on phpclasses, you can find it here.

determining the application root path and url in php

December 13, 08 by Gabi Solomon

If you buid any web application you will eventually need to find a way to specify the application root path and URL. This is inevitable if you don't build your links in a relative way ( by unsing ./ and ../ combinations ), and also if you want to have a way of keeping things organized and working even if you move script to a new server or in a folder.

Well there are several ways you can do this. The first one would be to write them in a config file by hand, and edit them as you move the project.

PHP:
  1. define('ROOT_PATH', '/home/user/public_html/folder/');
  2. define('PROJECT_DIR', '/folder/');
  3. define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . PROJECT_DIR);

But even if that works well, it will give a bit of work when you move the application since you have to edit them by hand.
So the next method would be to have them be generated automatically. The ROOT_PATH is relatively easy to determine . What i do is have a directory called config in wich i place my config files, in it i have one called main_config.php which includes the rest of the config files. One of them is called paths.php.
Now to determine the root_path i use a function called dirname() and the __FILE__ constant.

PHP:
  1. define('ROOT_PATH', dirname(dirname(__FILE__)));
  2. define('PROJECT_DIR', '/folder/');
  3. define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . PROJECT_DIR);

Now we have the root_path solved and base_url to some extend, but need to specify the project directory.
We can solve that too automatically.

PHP:
  1. define('ROOT_PATH', '/home/user/public_html/folder/');
  2. $projectDir = implode('/', array_intersect(explode('/', $_SERVER["REQUEST_URI"]), explode('/', str_replace('\\', '/', ROOT_PATH))));
  3. if ($projectDir[strlen($projectDir)-1] != '/') {
  4.         $projectDir .= '/';
  5. }
  6. define('PROJECT_DIR', $projectDir);
  7. define('BASE_URL', 'http://' . $_SERVER['HTTP_HOST'] . PROJECT_DIR);

What that code does is take the ROOT_PATH that we defined and the REQUEST_URI from the server global variable and do an intersection of them to determine the project dir.

Hope this small snippet helped you.
Cheers

Zend Framework View Helper for Smarty Cycle

December 09, 08 by Gabi Solomon

As i stated in a recent post i am now starting to learn Zend Framework. And with all new things that you learn, you try to find the old ways ( at least i do :D ).

So today i was trying to find a method of creating a zebra table. The old way i used to this back when i was using smarty is by using the cycle custom function. Basically it will just alternate through a set of values to create the effect.

PHP:
  1. {section name=rows loop=$data}
  2. <tr bgcolor="{cycle values="#eeeeee,#d0d0d0"}">
  3.    <td>{$data[rows]}</td>
  4. </tr>
  5. {/section}

Then when i moved on and stop using smarty, i wrote a similar function for my template engine.

So now i am looking for a similar solution on Zend Framework. Luckily for me some bright fellows have already thought of me :D .
In the zend wiki there is a Zend_View_Helper_Cycle Component Proposal that does exacly what i was wishing for :D .

Heres an example of how you can use it:

PHP:
  1. <?php $cycle=$this->cycle(array("#F0F0F0","#FFFFFF"));?>
  2. <?php foreach ($this->books as $book):?>
  3.   <tr  style="background-color:<?=$cycle->next()?>">
  4.   <td><?=$this->escape($book['author']) ?></td>
  5. </tr>
  6. <?php endforeach;?>

The proposal has been approved for development in standard/incubator.
You can download it from here.

Cheers.

[php class] Open Inviter – Get contacts of friends of different networks

December 01, 08 by Gabi Solomon

Yet another great class found on the php classes website.
This one has been in my draft folder for a while (the place i keep my articles ideas ), and finally it came time to write about it (manage to put my laziness away and write it).

The class is called open Inviter and has received the rank of november 2008 Nominee for Innovation Award. I personally hope it will win it, i think it really deserves it.

Describtion

This package can be use to get the contacts of friends of different e-mail providers and social networks.

It can access the Web services servers of different networks to retrieve the contacts of friends of a given user.

Each network is accessed by the means of plug-in classes. Some plug-ins support sending invitation messages to friends to be added to the user contacts.

The class currently comes with plug-ins that support :
* AOL
* GMail
* GMX.net
* Windows Live (Hotmail)
* Katamail
* Lycos
* Mail.com
* Mail.ru
* Rambler.ru
* Rediff
* Yahoo!
* Yandex
* Facebook
* Hi5
* LinkedIn
* MySpace
* Orkut
* Twitter

The class is very easy to use, and comes with a very detailed example of how you can implement it.

[Class full description & download link]

Hope it helps you in your development.

Cheers.

Zend Framework modular directory structure

by Gabi Solomon

After a lot of thinking and going back and forth about this idea, i finally decided to start using ( learning at first ) zend framework.

The main decision was to go with an already built framework or an inhouse one. And although i really like reinventing the wheel sometimes, i said i will not do the same this time.

After deciding i wanted to use an exiting framework, i had 2 candidates in mind : CodeIgniter or zend framework. The plus for codeigniter was the fact that it went with a more familiar approach to MVC, and the plus for zend was the company behind it. The downside about zend, was for me at least, the size of it, and the fact that it seemed a lot to learn.

But i decided to take a chance and learn Zend. The main problem i had was how to start ( as all things are :D ). Because the have such a freedom in development, i was a little puzzled on how to structure my application.

The only thing i knew was that i wanted to go with a modular structure. From there i did a lot of googling, read and watched a few presentation about this topic and finaly came up with a structure wich is bassed much on Wil Sinclair proposal.

My Zend modular structure

I will try to explain it, why i chose it this way and what each folder contains.

1. Application

The main aplication folder
1.1 Config - Contains application configuration files ( ex: mysql details )
1.2 Controllers - General Controllers, that are common in all modules
1.3 Languages - Holds the language files
1.4 Layouts - This directory is for MCV based layouts.
1.5 Models - This directory holds the application models ( in put them here instead of the modules directory since i belive there are common to all application and its more better this way )
1.6 Modules - I really liked the idea of modules that zend used because it enables you to organize your controllers and views much better in a separate folder for different sections of a website ( for example the main website, editors area and admin panel )
1.7 Views - I also included a views folder in the main application because i though i could use it to store common views for the 3 modules.

2. Data

This folder holds various information that is temporary, like cache, session data etc.

3. Docs

This directory is for documentation automatically generated or hand written.

4. Library

This directory holds the library Zend Framework files and also other folders for your own library (extended from Zend or not). I have one called GSD that extends some zend classes.

5. Public

This directory would contain the public files for your application: index.php. index.php ( this will include the bootstrap.php file from your application/ directory) and the front end assets (css, javascript, images, flash etc )

6. Tests

This directory would hold the application tests. This is a cool feature about Zend that it has support for writing application tests to better test your code during development.

Final Words

Ok this is about it so far. I am still a beginer with zend, and this structure is what i have thought off so far, and it doesn't have some real application testing. Use it at your own expense :) )
I am sure as i start developing using zend that it will be modified.

Another bad thing about zend is that there aren't so much resources and real examples about it, this is why i will write about my journey with zend here. Hopefully somebody will benefit from it. :)

Cheers

Automated Model-Based Testing of Web Applications

November 23, 08 by Gabi Solomon

If you are a developer than you are well aware of the importance of testing your applications, and i dont mean testing it your self since that is really not going to be very helpful beyond the development stage.

Since you ( or your team ) have build this application you will not be tester, since you already know how the application will perform. The best thing to do is to do a test with more subjects, of all knowledge levels if possible and give them a series of events and tasks to perform to see how the application handles and how easy it is for them to perform those tasks.

I found that in all test groups there is always a "bird brain" (as the speaker in the presentation reffered to it) that will execute a series of actions that will crash your application (usually things you havent thought of anybody doing). Although some developers hate those type of testers ( how the F did you managed to get there) i like them. At my old job i used to have a secretary that would find any bug i might have overlooked in a matter of minutes, just by clicking around :) ).

Anyway, the point i was trying to make ( beside the fact that testing is important ) is that human driven tests although very creative at times, have a few limitations and will not managed to test the full amount of possibilities. And above this will take quite a few resources ( human and financially ) to execute this tests, and they cant be reused if the application changes.

So there are some really smart persons that are looking into making an automated system for testing web applications. Some the research in this field are also done by microsoft ( this is a small inside info for all those microsoft haters :-P ).

I am not going to go into much more details and let you watch the presentation.
Enjoy.

Connection Interrupted

November 16, 08 by Gabi Solomon

A few weeks ago as i was working on a project i got a message in firefox that said :

Connection Interrupted
The connection to the server was reset while the page was loading.
The network link was interrupted while negotiating a connection. Please try again.

I was a little puzzled since i never saw this one before. So i did a little googling search and debugging i find out the cause :D

There was a infinite loop in my code.

I know silly me, but hope you manage to stumble upon this when you get in the same situation.
cheers.

[php class review] Relink – Rewrite URLs based on mod_rewrite configuration

November 02, 08 by Gabi Solomon

view this article in romanian

I have an email subscription to phpclasses email newsletter, and read it to see what new classes have been added to the site. And once in a while i will find interesting and innovative classes. Like today when between the classes that won the Innovation award was one that caught my attention.

The class developed by Benjamin Falk that he called Relink is a very interesting and useful tool in my opinion.

Lets say that you have a website and after you build it you want to make some SEO for it. That usually involves modifying all the links in the website. And that is quite a task. But what if you are like me and know a few things about SEO but are no expert, and somewhere down the line you either hire a SEO expert or receive an expert advice and want to change all those links ? Another time spent on tedious task of find and replace. And if we are talking about a larger project than that could be quite a big time.

Well what this class enables you to do is to make your links dynamically generated based on your .htaccess configuration. Let be more specific, first you must initialize the class

PHP:
  1. require_once 'class.relink.php';
  2.  
  3. $htaccessFile    = './htaccess-example';
  4. $c_relink        = new RELINK($htaccessFile);
  5.  
  6. // If you leave the $htaccessFile empty it will automatically take the .htaccess file from the current directory.

Then everywhere in the script where you have a link you will put something like

PHP:
  1. echo '<a href="'.$c_relink-&gt;replaceLink('?page=blog').'">View blog</a> | ';
  2. echo '<a href="'.$c_relink-&gt;replaceLink('?page=blog&amp;mode=edit').'">Edit Blog</a> | ';
  3. echo '<a href="'.$c_relink-&gt;replaceLink('?info&amp;value=all').'">Show all information</a>';

I didn't use it in any projects so far but I think i will do it on my next project.
Hope this new class is as interesting to you as it was to me.

Cheers