Ben
Ben

Reputation: 62394

How to structure models for Multilingual use

I'm curious what a good model structure is for a multilingual environment. I'll use a products database as an example....

products
----------------------------------------------------------------
    products_id  |   products_customizer_id  |  date_added

products_description
----------------------------------------------------------------
    id  |  language_id  |  sku  |   description

I'd like to use getters and setters... I'm stuck with the question of, should I have 1 product model, or one for the description and other for products?

update To be clear, I am forced to use this databse structure... I'm wondering how to setup my php models... I'd like to be able to do...

$product->setCustomizerId(4);
$product->setSku('BJKDJ423');
$product->setDescription('A spanish walrus');

$product->save();

And have it intelligently save each field in each database.... is this a good/bad idea, why or why not?

Upvotes: 2

Views: 289

Answers (2)

CD001
CD001

Reputation: 8472

That's not too far off how I'd do it... I tend to stick to a format though like having all language specific tabled suffixed with _lang. So I'd have the 3 tables (using InnoDB with foreign keys for referential integrity).

product
----------------------------------------------------------------
id | ... fields ...


language
----------------------------------------------------------------
id | ... fields ...


product_lang
----------------------------------------------------------------
language_id | product_id | name | description | ... etc ...

I'd probably use an ISO string for the language id, for example en-GB and an autoincremented INT for the product id. The primary key in the product_lang table would be a compound key created from the language_id and product_id fields - that way you avoid an unnecessary field and any INT constraints that would have.

Otherwise yeah, you're pretty much there.

---- EDIT TO REFLECT UPDATED QUESTION ----

OK - the model...

Your model should reflect how you'll be using it in a business sense rather than a database sense... I'd have a product model that wraps the data as you'll use it so something like:

class MyProduct {
  private $_id;
  private $_sku;
  private $_name;
  private $_description;
  ...

  public function setId($iId) {
    $this->_id = (int) $iId;
  }

  public function getId() {
    return $this->_id;
  }

  ... and so on ...
}

I'd set the language in the database connector, probably statically if you're not changing it often, and have that pull the relevant data from the tables to propagate your object... I'm not a huge believer in active records - create object models that map business objects and a database that holds the data in a relational, normalised form. Use a database abstraction layer to convert one to the other.

Aside on loading in the i18n settings

Generally I'd store certain site-wide variables in a Singleton application object that's loaded up on every page - that's where I'd store the language id and all the application bootup stuff, so it'll connect to the database, start the session, instantiate a user object, assign them a cart and so on and so forth - everything that's used globally.

Since the language will be set in that MyApp object and that object will also hold your database connector - you can simply have that object set the static MyDBConnector::setLang($sLang) parameter automatically on instantiation.

This way, to kick up the entire application on any page, you need simply do something like

require_once '/path/to/app.ini.php';
$oApp = MyApp::getInstance();

Upvotes: 1

Mathieu Dumoulin
Mathieu Dumoulin

Reputation: 12244

I use a completly flexible model structure that exposes the description, name, title as an array in my models such as:

class Models_Product {

public function getNames(){ return $this->names; }
public function getName($lang){ return $this->name[$lang]; }

}

Wash rince and repeat for all properties.

Note: There is little use to setup a "setNames(array $values)" version, only a setName($lang, $value) should be created IMO.

Upvotes: 0

Related Questions