【问题标题】:translate behavior and associated model translation翻译行为和相关的模型翻译
【发布时间】:2013-09-16 15:34:11
【问题描述】:

我在网上搜索了 1000000000000000 次,但找不到干净的解决方案

这是我的 CertificateType 模型翻译部分:

public $actsAs = array('Translate'=>array('title','description')) ;

和证书模型:

public $actsAs=array('Translate'=>array('filename')) ;

    public $belongsTo = array(
    'CertificateType' => array(
        'className' => 'CertificateType',
        'foreignKey' => 'certificate_type_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    ) ,
   );

但在获取时,所属模型不会翻译:

    public function admin_index() {
    $this->Certificate->locale = $this->Session->read('Config.language');
    $this->Certificate->CertificateType->locale =  $this->Session->read('Config.language');
    $this->Certificate->recursive = 0;
    $this->set('certificates', $this->paginate());
    debug($this->Certificate->paginate()) ;
}

为什么?

【问题讨论】:

  • 有些笨蛋只是把他们看不懂的分数减掉!

标签: cakephp translate


【解决方案1】:

我为获取当前语言做了更改,并与 cacke 2.4.3 完美配合

public function getTranslatedModelField($id = 0, $field) {
    // retrieve active language

    $locale = $this->locale ;// gets the current assigned locale

    $res = false;
    $translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";

    $db = $this->getDataSource();
    $tmp = $db->fetchAll(
        "SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
        array($this->alias, $locale , $id, $field)
    );
    if (!empty($tmp)) {
        $res = $tmp[0][$translateTable]['content'];
    }
    return $res;
}   

public function afterFind($results, $primary = false) {

    if($primary == false && array_key_exists('Translate', $this->actsAs)) {
        foreach ($results as $key => $val) {
            if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
                foreach($this->actsAs['Translate'] as $translationfield) {  
                    $results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $translationfield);
                }
            } else if($key == 'id' && is_numeric($val)) {
                foreach($this->actsAs['Translate'] as $translationfield) {  
                    $results[$translationfield] = $this->getTranslatedModelField($val, $translationfield);
                }                   
            }
         }
    }

    return $results;
}

【讨论】:

    【解决方案2】:

    我用过这个,效果很好!

    在 AppModel.php 中我写了这些代码:

        public function getTranslatedModelField($id = 0, $field) {
        // retrieve active language
        $ActiveLanguageCatalog=CakeSession::read('Config.ActiveLanguageCatalog') ;
        $res = false;
        $translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
    
        $db = $this->getDataSource();
        $tmp = $db->fetchAll(
            "SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
            array($this->alias, $ActiveLanguageCatalog['locale'], $id, $field)
        );
        if (!empty($tmp)) {
            $res = $tmp[0][$translateTable]['content'];
        }
        return $res;
    }   
    
    public function afterFind($results, $primary = false) {
    
        if($primary == false && array_key_exists('Translate', $this->actsAs)) {
            foreach ($results as $key => $val) {
                if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
                    foreach($this->actsAs['Translate'] as $translationfield) {  
                        $results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $translationfield);
                    }
                } else if($key == 'id' && is_numeric($val)) {
                    foreach($this->actsAs['Translate'] as $translationfield) {  
                        $results[$translationfield] = $this->getTranslatedModelField($val, $translationfield);
                    }                   
                }
             }
        }
    
        return $results;
    }
    

    【讨论】:

      【解决方案3】:

      感谢 Vahid Alimohamadi 的剪辑。我必须修改它才能在我的项目中正常工作。

      public function getTranslatedModelField($id = 0, $field) {
          // retrieve active language
          //$ActiveLanguageCatalog=CakeSession::read('Config.ActiveLanguageCatalog') ;
          $locale = Configure::read('Config.language');
          $res = false;
          $translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
      
          $db = $this->getDataSource();
          $tmp = $db->fetchAll(
              "SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
              array($this->alias, $locale/*$ActiveLanguageCatalog['locale']*/, $id, $field)
              );
          if (!empty($tmp)) {
              $res = $tmp[0][$translateTable]['content'];
          }
          return $res;
      }
      
      public function afterFind($results, $primary = false) {
      
          if($primary == false && array_key_exists('Translate', $this->actsAs)) {
              foreach ($results as $key => $val) {
                  if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
                      //HERE ADDED $field => $translationfield AND PASS IT TO THE getTranslatedModelField
                      foreach($this->actsAs['Translate'] as $field => $translationfield) {
                          $results[$key][$this->name][$field] = $this->getTranslatedModelField($val[$this->name]['id'], $field);
                      }
                  } else if($key == 'id' && is_numeric($val)) {
                      //HERE ADDED $field => $translationfield AND PASS IT TO THE getTranslatedModelField
                      foreach($this->actsAs['Translate'] as $field => $translationfield) {
                          $results[$field] = $this->getTranslatedModelField($val, $field);
                      }
                  }
              }
          }
      
          return $results;
      }
      

      【讨论】:

        【解决方案4】:

        我对使用 cakephp 2.5 有一些更新。它现在对我有用。希望能帮上忙。

        公共函数 getTranslatedModelField($id = 0, $field) {

            $res = false;
            $translateTable = (isset($this->translateTable))?$this->translateTable:"i18n";
        
            $db = $this->getDataSource();
            $tmp = $db->fetchAll(
                "SELECT content from {$translateTable} WHERE model = ? AND locale = ? AND foreign_key = ? AND field = ? LIMIT 1",
                array($this->alias, $this->locale , $id, $field)
            );
        
            if (!empty($tmp)) {
                $res = $tmp[0][$translateTable]['content'];
            }
            return $res;
        }
        
        public function afterFind($results, $primary = false) {
        
            if($primary == false && array_key_exists('Translate', $this->actsAs)) {
                foreach ($results as $key => $val) {
                    if (isset($val[$this->name]) && isset($val[$this->name]['id'])) {
                        foreach($this->actsAs['Translate'] as $k =>  $translationfield) {
                            $results[$key][$this->name][$translationfield] = $this->getTranslatedModelField($val[$this->name]['id'], $k);
                        }
                    } else if($key == 'id' && is_numeric($val)) {
                        foreach($this->actsAs['Translate'] as $k =>  $translationfield) {
                            $results[$translationfield] = $this->getTranslatedModelField($val, $k);
                        }
                    }
                }
            }
        
            return $results;
        }
        

        【讨论】:

          【解决方案5】:

          通过使用 Model->SubModel->Behaviors->load(...) 以 Cake 的方式为相关模型启用翻译行为非常容易

          $this->Certificate->CertificateType->Behaviors->load(
              'Translate',
               array('title','description')
               );
          

          看看http://book.cakephp.org/2.0/en/models/behaviors.html

          【讨论】:

            【解决方案6】:

            最简单的解决方案是获取关联模型项的 id 并进行另一次搜索,如下所示:

                        $ids = array();
                foreach ($wpage['Widget'] as &$widget):
                    $ids[] = $widget['id'];
                endforeach;
            
                $widgets = $this->Wpage->Widget->find('all', array(
                    'conditions' => array('Widget.id' => $ids)
                ));
            
                $this->set(compact('wpage', 'widgets'));    
            

            谢谢, 阿里斯

            【讨论】:

              【解决方案7】:

              将以下代码添加到 AppModel:

              public function afterFind($results, $primary = false) {
                  if(!empty($this->hasMany)) {
                      foreach($this->hasMany as $model => $settings) {
                          if(isset($this->{$model}->actsAs['Translate'])) {
                              if(!empty($results[0][$model])) {
                                  foreach($results[0][$model] as $row => $result) {
                                      $supplement = $this->{$model}->find('first', array(
                                          'conditions' => array(
                                              $model .'.id' => $result['id']),
                                          'fields' => $this->{$model}->actsAs['Translate'],
                                          'recursive' => -1));
              
                                      if(!empty($supplement)) {
                                          $results[0][$model][$row] = array_merge($results[0][$model][$row], array_diff($supplement[$model], $result));
                                      }
                                  }
                              }
                          }
                      }
                  }
              
                  if(!empty($this->belongsTo)) {
                      foreach($this->belongsTo as $model => $settings) {
                          if(isset($this->{$model}->actsAs['Translate'])) {
                              if(!empty($results[0][$model])) {
                                  foreach($results[0][$model] as $row => $result) {
                                      $supplement = $this->{$model}->find('first', array(
                                          'conditions' => array(
                                              $model .'.id' => $result),
                                          'fields' => $this->{$model}->actsAs['Translate'],
                                          'recursive' => -1));
              
                                      if(!empty($supplement)) {
                                          $results[0][$model] = array_merge($results[0][$model], $supplement[$model]);
                                      }
                                  }
                              }
                          }
                      }
                  }
              
                  return $results;
              } 
              

              这适用于关系 hasMany 和 belongsTo

              【讨论】:

              • Certificate 和 CertificateTypes 是对 CertificateAppModel 的扩展。 CertificateAppModel 扩展了 AppModel。所有这些都使得证书插件
              • $this->Certificate->CertificateType->locale='fr' ; debug($this->Certificate->CertificateType->find('all')) ;没有其他所有内容,不应该检索已翻译的 CertificateType?
              • 我从不在 Cake 中使用插件,但这段代码在 2.4 的 appModel 中运行良好。清除缓存文件夹 tmp/ 并重试
              • 在“ if(isset($this->{$model}->actsAs['Translate'])) { ”中删除 {$model} 并在主结构中展开插件,它起作用了!我为 cake 团队发送了一张支持票,Mark Story 说这个问题在 cakePHP 2.x 中无法解决 温馨的问候 kicaj
              • 显示票的链接:)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-06-03
              • 1970-01-01
              • 2016-11-18
              • 2013-09-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多