扩展具有静态方法的类

时间:2013-10-25 12:42:38

标签: php oop override kohana extends

我想在模块中扩展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以包含数据库更新而不编辑系统类?

2 个答案:

答案 0 :(得分:1)

由于Kohana_I18n :: get()调用 I18n :: load(),所以你要做的就是覆盖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;
    }

    ...
}

答案 1 :(得分:1)

“有没有办法扩展Kohana_I18n以包含数据库更新而不编辑系统类?” 是。

听起来你不熟悉Kohana的级联文件系统,你不明白它在这种情况下是如何有用的,或者你不想因为某种原因改变I18n的行为。

如果不是最后一个,那么只需将Appointedd_I18n重命名为I18n并相应地更改文件名。 SYSPATH/classes/I18n.php只包含class I18n extends Kohana_I18n {}的文件。如果您查看SYSPATH/classes/Kohana/I18n.php,您会看到selfKohana_I18n从未用于调用任何内容。 他们一直在I18n类中使用Kohana_I18n,以便您可以'替换'I18n类并更改其行为。