2013-10-25 44 views
1

我想在模塊中擴展KOHANA的i18n類,以便在查找默認文件結構之前先查找數據庫以查找翻譯。問題是我想重寫的方法是靜態的。擴展一個具有靜態方法的類

原始類別有一個方法get()所以我打電話給我的班級:Appointedd_I18n::get('Term goes here...'),該方法調用load()。這是我想重寫的方法,但是因爲它是靜態的,所以不會加載MY方法,而是加載原始方法。

這裏是我的模塊/類:

<?php defined('SYSPATH') or die('No direct script access.'); 

/** 
* Extends the Kohana translation code to include a db lookup. 
* 
*/ 

class Appointedd_I18n extends Kohana_I18n { 

    /** 
    * Returns the translation table for a given language. 
    * 
    *  // Get all defined Spanish messages 
    *  $messages = I18n::load('es-es'); 
    * 
    * @param string $lang language to load 
    * @return array 
    */ 
    public static function load($lang) 
    { 
     die('think I\'ll look up the db'); // to test this method is being called 
     if (isset(I18n::$_cache[$lang])) 
     { 
      return I18n::$_cache[$lang]; 
     } 

     // New translation table 
     $table = array(); 

     // Split the language: language, region, locale, etc 
     $parts = explode('-', $lang); 

     do 
     { 
      // Create a path for this set of parts 
      $path = implode(DIRECTORY_SEPARATOR, $parts); 

      if ($files = Kohana::find_file('i18n', $path, NULL, TRUE)) 
      { 
       $t = array(); 
       foreach ($files as $file) 
       { 
        // Merge the language strings into the sub table 
        $t = array_merge($t, Kohana::load($file)); 
       } 

       // Append the sub table, preventing less specific language 
       // files from overloading more specific files 
       $table += $t; 
      } 

      // Remove the last part 
      array_pop($parts); 
     } 
     while ($parts); 

     // Cache the translation table locally 
     return I18n::$_cache[$lang] = $table; 
    } 

} // END class Appointedd_i18n 

這裏是KOHANA_I18n類:

<?php defined('SYSPATH') or die('No direct script access.'); 
/** 
* Internationalization (i18n) class. Provides language loading and translation 
* methods without dependencies on [gettext](http://php.net/gettext). 
* 
* Typically this class would never be used directly, but used via the __() 
* function, which loads the message and replaces parameters: 
* 
*  // Display a translated message 
*  echo __('Hello, world'); 
* 
*  // With parameter replacement 
*  echo __('Hello, :user', array(':user' => $username)); 
* 
* @package Kohana 
* @category Base 
* @author  Kohana Team 
* @copyright (c) 2008-2012 Kohana Team 
* @license http://kohanaframework.org/license 
*/ 
class Kohana_I18n { 

    /** 
    * @var string target language: en-us, es-es, zh-cn, etc 
    */ 
    public static $lang = 'en-us'; 

    /** 
    * @var string source language: en-us, es-es, zh-cn, etc 
    */ 
    public static $source = 'en-us'; 

    /** 
    * @var array cache of loaded languages 
    */ 
    protected static $_cache = array(); 

    /** 
    * Get and set the target language. 
    * 
    *  // Get the current language 
    *  $lang = I18n::lang(); 
    * 
    *  // Change the current language to Spanish 
    *  I18n::lang('es-es'); 
    * 
    * @param string $lang new language setting 
    * @return string 
    * @since 3.0.2 
    */ 
    public static function lang($lang = NULL) 
    { 
     if ($lang) 
     { 
      // Normalize the language 
      I18n::$lang = strtolower(str_replace(array(' ', '_'), '-', $lang)); 
     } 

     return I18n::$lang; 
    } 

    /** 
    * Returns translation of a string. If no translation exists, the original 
    * string will be returned. No parameters are replaced. 
    * 
    *  $hello = I18n::get('Hello friends, my name is :name'); 
    * 
    * @param string $string text to translate 
    * @param string $lang target language 
    * @return string 
    */ 
    public static function get($string, $lang = NULL) 
    { 
     if (! $lang) 
     { 
      // Use the global target language 
      $lang = I18n::$lang; 
     } 

     // Load the translation table for this language 
     $table = I18n::load($lang); 

     // Return the translated string if it exists 
     return isset($table[$string]) ? $table[$string] : $string; 
    } 

    /** 
    * Returns the translation table for a given language. 
    * 
    *  // Get all defined Spanish messages 
    *  $messages = I18n::load('es-es'); 
    * 
    * @param string $lang language to load 
    * @return array 
    */ 
    public static function load($lang) 
    { 
     if (isset(I18n::$_cache[$lang])) 
     { 
      return I18n::$_cache[$lang]; 
     } 

     // New translation table 
     $table = array(); 

     // Split the language: language, region, locale, etc 
     $parts = explode('-', $lang); 

     do 
     { 
      // Create a path for this set of parts 
      $path = implode(DIRECTORY_SEPARATOR, $parts); 

      if ($files = Kohana::find_file('i18n', $path, NULL, TRUE)) 
      { 
       $t = array(); 
       foreach ($files as $file) 
       { 
        // Merge the language strings into the sub table 
        $t = array_merge($t, Kohana::load($file)); 
       } 

       // Append the sub table, preventing less specific language 
       // files from overloading more specific files 
       $table += $t; 
      } 

      // Remove the last part 
      array_pop($parts); 
     } 
     while ($parts); 

     // Cache the translation table locally 
     return I18n::$_cache[$lang] = $table; 
    } 

} // End I18n 

if (! function_exists('__')) 
{ 
    /** 
    * Kohana translation/internationalization function. The PHP function 
    * [strtr](http://php.net/strtr) is used for replacing parameters. 
    * 
    * __('Welcome back, :user', array(':user' => $username)); 
    * 
    * [!!] The target language is defined by [I18n::$lang]. 
    * 
    * @uses I18n::get 
    * @param string $string text to translate 
    * @param array $values values to replace in the translated text 
    * @param string $lang source language 
    * @return string 
    */ 
    function __($string, array $values = NULL, $lang = 'en-us') 
    { 
     if ($lang !== I18n::$lang) 
     { 
      // The message and target languages are different 
      // Get the translation for this message 
      $string = I18n::get($string); 
     } 

     return empty($values) ? $string : strtr($string, $values); 
    } 
} 

有沒有一種方法,我擴大Kohana_I18n包括無需編輯系統類DB更新?

回答

1

「有沒有一種方法可以擴展Kohana_I18n以包含數據庫更新,而無需編輯系統類?」 是的。

聽起來好像你不熟悉Kohana的層疊文件系統,你不明白在這種情況下它可能是有用的,或者你不想因任何原因改變I18n的行爲。

如果最後不是這種情況,只需將Appointedd_I18n重命名爲I18n並相應地更改文件名。 SYSPATH/classes/I18n.php只包含class I18n extends Kohana_I18n {}的文件。如果你看看SYSPATH/classes/Kohana/I18n.php你會看到selfKohana_I18n永遠不會用於調用任何東西。 他們一直在Kohana_I18n類中使用I18n,因此您可以'替換'I18n類並更改其行爲。

+0

謝謝你。是的,我沒有意識到級聯文件系統。我已經將''''Appointedd_I18n'''改成'''I18n''',但是現在調用'''__('string')''或甚至''I18n :: get('string') '''我的覆蓋沒有被調用。不過他們在使用'''Appointedd_I18n :: get('string')'''的時候。我的文件結構是modules/appointedd-i18n/classes/appointd/I18n.php。任何想法爲什麼我的課不覆蓋默認? – iamjonesy

+0

不要把'I18n'的定義放在'classes/appointd/I18n.php'中。 1)Kohana 3.2.x及更低版本需要小寫'i'。 Kohana 3.3.x需要一個大寫的'A'。在Windows上這並不重要,但其他操作系統區分大小寫。 2)當你只使用'I18n'時,Kohana永遠不會試圖「要求」所述文件。它不會奇蹟般地知道你把I18n類放在classes/Appointedd/I18n.php中而不是classes/I18n.php中。自動加載器遵循慣例,如果你想與自動加載器相處,也應遵循慣例。 – Darsstar

+0

好的。我試圖通過使用模塊來覆蓋它。我現在只是將文件放在'''application/classes/i18n.php'''中,而現在它可以工作。謝謝 – iamjonesy

1

由於Kohana_I18n ::得到()調用的I18n ::負載(),所有你需要做的就是重寫Kohana_I18n :: get()方法,使其調用Appointedd_I18n :: load()方法。

class Appointedd_I18n extends Kohana_I18n { 

    ... 

    public static function get($string, $lang = NULL) 
    { 
     if (! $lang) 
     { 
      // Use the global target language 
      $lang = I18n::$lang; 
     } 

     // Load the translation table for this language 
     $table = self::load($lang); 

     // Return the translated string if it exists 
     return isset($table[$string]) ? $table[$string] : $string; 
    } 

    ... 
} 
相關問題