如何在教条中制作幽灵场?

时间:2010-07-28 15:28:13

标签: php internationalization doctrine

设计:       tableName:设计师       充当:         国际化:           字段:[名称]       列:         ID:           类型:整数(2)           unsigned:true           主要:真实           autoincrement:true         名称:           类型:字符串(30)           notnull:是的

虽然必须像这样使用默认I18n行为

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

我会更方便的是为当前语言设置一些常量,比如说en,并且每个i18nable字段都对应它,因此有这样的查询

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

相当于上面的那个。

我正在尝试制作新的行为,扩展默认行为,这可以提供这样的东西,但我需要你的帮助。

获得所需的语言很简单,所以我们只说define('LANGUAGE', 'en')。基本行为类是

class TransparentI18N extends Doctrine_Template
{
    private $_translation = NULL;

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

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

所以我们的想法是添加一个监听器,它会修改查询以设置连接,并在select子句中出现这些字段时选择所需的字段。 TransparentI18NListener包含preDqlSelect,它接收Doctrine_Event个对象。我可以获得相关的Doctrine_Query甚至getDqlPart('select')作品,但后者返回原始选择字符串,如id, t.name我该如何获得,每个子句对应哪个表

然后我必须设置Doctrine_Record实例的字段。 是否有可能不使模型扩展一些可以提供此类功能的自定义类?我真的不愿意添加这样的类,但是如果其他一切都失败了,我应该能够保存它们字段并覆盖__get方法,以便在请求时显示已翻译的字段。

我太害怕考虑插入/更新/删除部分,但希望如果我处理上述问题,我将能够为dql添加钩子并完成工作。

你是否认为这种想法一般可以在不搞乱核心学说库的情况下进行?必须以默认方式使用它将是* ...

中的巨大痛苦

1 个答案:

答案 0 :(得分:0)

我对你的实际问题没有一个好的,非hacky的解决方案,但我可以选择尝试。

您可以将所有查找/获取查询放在模型对应的表类中 所以你仍然需要做翻译关节,但你所有的查询都在一个地方并且易于维护。

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);