Quick search:

How to build multi language applications

Build a single language application, but use a code management scheme that supports customization of the application (See how to keep your application code separated from customization code). Put all the code in the abstract superclasses, leave the concrete subclasses empty. When you are finished, create a new application for each additional language. Copy the empty concrete subclasses to their classFolders. Test that each copy is a properly working phpPeanuts application. Then customize each copy to use a different language. For an example of the introduction of a code management scheme and how to customize an application for a different language and locale, see example 10.

Technically this results into a small farm of applications all heavily reusing the code from the original. But your customer will probably see them as a multi language application. IF you fill in the bit we left out of example 10: the multi language database. Your customer might not find it very logical to have all data that is in different languages show up in all applications. You may give each language a database of its own. But he might not find it very logical that he has to enter language independent data, like prices and dates, over and over for each language.

Using a multi language database may lead to a serious refactoring of the application, splitting up objects into language specific and language independent ones, only showing one of those in the user interface and using derived properties to get the data from the other. Or you may decide that this is a matter of renormalizing the database and JOINing it back together before objects are built. I guess you are right, but phpPeanuts does not support that, so in order to do that you will need some serious framework development, not exactly something you can do within the budget of an application development project.

The solution is to be practical: give all objects that only need language specific data a language specific table by overriding getTableName in the concrete subclasses. Override the save methods of mixed objects and generate custom SQL to update several tables. Here you will have to decide weather you want to duplicate the language independent data (easiest) or normalize it into separate tables. If you do the last you will need to fetch some extra data when an object is initialized by its initFromData method. You may define the fieldProperties whose field values you fetch from a different table to be non-persistent from the initPropertyDescriptors method.

Wherever you use multiple tables for a single object, you will also have to override the delete method. You may have to ask your customer about how multi language data should be managed. Same for the creation of data when saving new objects: should you create them in all languages? Can they exist in one language but not in another?

Finally you should take a look at the pages and dialogs of your applications that search the database. If they use filters for their search options (the default ones do) you may miss search options for the properties you previously declared non-persistent. See how to create and use filters if you need those missing seach options.

You think this is all rather complicated? Remember the multi language database normalization depends on domain knowledge, it can probably not be automated. Of course multi language applications would profit from a more powerful (multi table) persistency framework. See how to write your own persistency if you are considering  that direction.