CakePHP - как применить поведение перевода к существующей базе данных? - PullRequest
4 голосов
/ 08 января 2010

У меня есть и существующее приложение в CakePHP с базой данных. Задача состоит в том, чтобы применить поведение translate к своим моделям. Проблема в том, что скрипт i18n.php просто создает таблицу _i18n, но не копирует существующие данные в эту таблицу. Разве вы не знаете сценарий, который мог бы сделать это? Спасибо за любую помощь.

Ответы [ 4 ]

3 голосов
/ 26 октября 2013

Я расширил ответы от Aziz и MarcoB и создал из них еще более общий CakeShell.

В методе _execute() просто установите что-то вроде:

$this->_regenerateI18n('BlogPosts', array('title'), 'deu');

И все записи для Model BlogPosts для заголовка столбца на языке deu будут созданы в таблице i18n.

Это CakePHP 2.4 совместимый!

<?php 

class SetuptranslationsShell extends AppShell {

    public function main() {
        $selection = $this->in('Start to create translated entries?', array('y', 'n', 'q'), 'y');
        if (strtolower($selection) === 'y') {
            $this->out('Creating entries in i18n table...');
            $this->_execute();
        }
    }

    function _execute() {
        $this->_regenerateI18n('BlogPosts', array('title'), 'deu');
        $this->_regenerateI18n('BlogTags',  array('name'),  'deu');
    }

    /**
     * See http://stackoverflow.com/q/2024407/22470
     * 
     */
    function _regenerateI18n($Model, $fields = array(), $targetLocale) {

        $this->out('Create entries for "'.$Model.'":');

        if (!isset($this->$Model)) {
            $this->{$Model} = ClassRegistry::init($Model);
        }

        $this->{$Model}->Behaviors->disable('Translate'); 
        $out = $this->{$Model}->find('all', array(
                                                    'recursive' => -1, 
                                                    'order'     => $this->{$Model}->primaryKey, 
                                                    'fields'    => array_merge(array($this->{$Model}->primaryKey), $fields))
                                                    );

        $this->I18nModel = ClassRegistry::init('I18nModel');

        $t = 0;
        foreach ($out as $v) {

            foreach ($fields as $field) {
                $data = array(
                    'locale'        => $targetLocale,
                    'model'         => $this->{$Model}->name,
                    'foreign_key'   => $v[$Model][$this->{$Model}->primaryKey],
                    'field'         => $field,
                    'content'       => $v[$Model][$field],
                );


                $check_data = $data;
                unset($check_data['content']);
                if (!$this->I18nModel->find('first', array('conditions' => $check_data))) {
                    if ($this->I18nModel->create($data) AND $this->I18nModel->save($data)) {
                        echo '.';
                        $t++;
                    }
                }
            }
        }
        $this->out($t." entries written");
    }
}
1 голос
/ 19 февраля 2010

попробуй использовать

function regenerate()
{
    $this->Article->Behaviors->disable('Translate'); 
    $out = $this->Article->find('all', array('recursive'=>-1, 'order'=>'id'));
    $t = $b = 0;
    foreach($out as $v){
        $title['locale'] = 'aze';
        $title['model'] = 'Article';
        $title['foreign_key'] = $v['Article']['id'];
        $title['field'] = 'title';
        $title['content'] = $v['Article']['title'];
        if($this->Article->I18n->create($title) && $this->Article->I18n->save($title)){
            $t++;
        }
        $body['locale'] = 'aze';
        $body['model'] = 'Article';
        $body['foreign_key'] = $v['Article']['id'];
        $body['field'] = 'body';
        $body['content'] = $v['Article']['body'];
        if($this->Article->I18n->create($body) && $this->Article->I18n->save($body)){
            $b++;
        }
    }
}
1 голос
/ 19 июля 2013

Спасибо, Азиз. Я изменил ваш код, чтобы использовать его внутри Cakeshell
(CakePHP 2.3.8)

function execute() {
    $this->out('CORE_PATH: '. CORE_PATH. "\n");
    $this->out('CAKEPHP_SHELL: '. CAKEPHP_SHELL. "\n");

    $this->out('Migrate BlogPosts');
    $this->regenerateI18n('BlogPost', 'title', 'BlogPostI18n');
}
/**
 * @param string $Model 
 * @param string $Field
 * @param string $ModelI18n
 */
function regenerateI18n($Model = null, $Field = null, $ModelI18n = null)
{
    if(!isset($this->$Model))
        $this->$Model = ClassRegistry::init($Model);
    if(!isset($this->$ModelI18n))
        $this->$ModelI18n = ClassRegistry::init($ModelI18n);

    $this->$Model->Behaviors->disable('Translate'); 
    $out = $this->$Model->find('all', array('recursive'=>-1, 'order'=>'id'));
    $t = 0;
    foreach($out as $v){
        $data = array(
            'locale' => 'deu',
            'model' => $this->$Model->name,
            'foreign_key' => $v[$Model]['id'],
            'field' => $Field,
            'content' => $v[$Model][$Field],
        );
        if($this->$ModelI18n->create($data) && $this->$ModelI18n->save($data)){
            echo '.';
            $t++;
        }
    }
    $this->out($t." Entries written");
}
1 голос
/ 08 января 2010

Насколько я знаю, нет способа сделать это. Более того, из-за того, что таблица i18n настроена на работу, я думаю, что есть лучшее решение. Некоторое время назад я написал патч для TranslateBehavior, который избавит вас от необходимости копировать существующие данные в таблицу i18n (это показалось мне безумно избыточным и стало огромным препятствием для реализации i18n). Если в таблице i18n нет записи для этой модели, она просто прочитает саму запись модели как запасной вариант.

К сожалению, команда Cake, похоже, перенесла все на новые системы, поэтому я больше не могу найти ни билет, ни патч, который я отправил. Моя исправленная копия TranslateBehavior находится в моем репозитории Codaset по адресу http://codaset.com/robwilkerson/scratchpad/source/master/blob/cakephp/behaviors/translatable.php.

Как и следовало ожидать, применяются все обычные предупреждения. Запатентованный файл был разработан для 1.2.x и работает для моих нужд, YMMV .

...