0
votes

Designer: tableName: designers actAs: I18n: fields: [name] columns: id: type: integer(2) unsigned: true primary: true autoincrement: true name: type: string(30) notnull: true

While default I18n behavior must be used like this

$d = Doctrine_Query::create()
                ->select('id, t.name')
                ->from('Designer d')
                ->leftJoin('d.Translation t')
                ->where("t.lang = 'en'")
                ->execute();

I would be faaar more convenient to set some constant to the current language, say en, and have every i18nable field correspond to it, thus having such query

$d = Doctrine_Query::create()
            ->select('id, name')
            ->from('Designer d')
            ->execute();

equivalent to the above one.

I'm trying to make a new behavior, extending the default one, which could provide such things, but I need your help.

Getting the needed language is easy, so let's just say there is define('LANGUAGE', 'en'). The basic behavior class is

class TransparentI18N extends Doctrine_Template
{
    private $_translation = NULL;

    public function setUp()
    {
        $this->addListener(new TransparentI18NListener());

        $this->actAs(new Doctrine_Template_I18n($this->_options));
    }
}

So the idea is to add a listener, that would modify the query to set joins and select needed fields whenever such fields are present in the select clause. The TransparentI18NListener contains the preDqlSelect, which receives the Doctrine_Event object. And I can get the relevant Doctrine_Query and even getDqlPart('select') works, but the latter returns the raw select string, like id, t.name, how can I get, to which table each clause corresponds?

Then I'd have to set fields of the Doctrine_Record instance. Is it possible without making models extend some custom class which would give such functionality? I'm really reluctant to add such a class, but in case everything other fails, I should be able to make it save these fields and override the __get method to show translated fields if they are requested.

I was too scared to think about the insert/update/delete part, but hopefully if I deal with the above problems, I'd be able to add hooks to dql and get the job done.

Do you think such a think is possible in general without messing with core doctrine libraries? Having to use it in the default way would be a huge pain in the *...

1
Did you manage to complete this template??? I'm looking for the exact same thing - ZolaKt

1 Answers

0
votes

I don't have a good, non-hacky solution for your actual problem but have an alternative to try.

You could put all your find/get queries in the models corresponding table class.
So you still have to do the Translation-Joints but all you queries are at one place and are easy to maintain.

class DesignerTable extends Doctrine_Table
{
    protected $_lang = LANGUAGE;

    public function findAll()
    {
        return Doctrine_Query::create()
                ->select('id, t.name')
                ->from('Designer d')
                ->leftJoin('d.Translation t')
                ->where("t.lang = ?", $this->_lang)
                ->execute();
    }

    public function findOneById($id)
    {
        return Doctrine_Query::create()
                ->select('id, t.name')
                ->from('Designer d')
                ->leftJoin('d.Translation t')
                ->where('.lang = ?', $this->_lang)
                ->andWhere('id = ?', $id) 
                ->execute();
    }
    ...
}

// In your controllers:

// Find all designers
$designers = Doctrine_Core::getTable('Designer')->findAll();

// Find one designer by id
$designers = Doctrine_Core::getTable('Designer')->findOneById(13);