Как динамически закинуть в локали нужную информацию?

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ответить
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Приветствую!
Возникла такая проблема. В проекте есть некая игровая валюта и хочется отображать ее символ через CNumberFormatter без исправления данных локалей в самом фреймворке. Главная проблема в том, что в CLocale свойство $_data приватное, и соответственно доступное только из этого класса.

Я было уже создал новый класс приложения, чтобы выкидывать наследника CLocale с protected $_data, и нужными функциями для изменения данных локали,
но обнаружил и в CNumberFormatter тоже жестко прописанные вызовы CLocale.

Может имеет смысл добавить какие-то методы для изменения данных локали в саму CLocale, либо в YiiBase добавить статичное свойство, где можно будет указать имя класса, и публичный статичный метод где указывается это самое имя класса локали и путь к файлу, который будет закинут в свойство YiiBase::$classMap

Чтобы не плодить кучу наследников нашел пока единственный способ, это переделать свойство CLocale::$_data в public,
и сделать главный класс контроллера, в котором beforeAction() делает все что мне нужно с данными локали. Но опять же это не в стиле Yii.
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Прицепить поведение не получится по той же причине CLocale::$_data private
Сначала невидимое, затем видимое. И так у всех программистов :)
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Jampire »

$_data это просто содержимое соответствующего файла из framework/i18n/data:

Код: Выделить всё

/**
         * Constructor.
         * Since the constructor is protected, please use {@link getInstance}
         * to obtain an instance of the specified locale.
         * @param string $id the locale ID (e.g. en_US)
         */
        protected function __construct($id)
        {
                $this->_id=self::getCanonicalID($id);
                $dataPath=self::$dataPath===null ? dirname(__FILE__).DIRECTORY_SEPARATOR.'data' : self::$dataPath;
                $dataFile=$dataPath.DIRECTORY_SEPARATOR.$this->_id.'.php';
                if(is_file($dataFile))
                        $this->_data=require($dataFile);
                else
                        throw new CException(Yii::t('yii','Unrecognized locale "{locale}".',array('{locale}'=>$id)));
        } 
Свойство, задающее этот путь, публичное:

Код: Выделить всё

 /**
         * @var string the directory that contains the locale data. If this property is not set,
         * the locale data will be loaded from 'framework/i18n/data'.
         * @since 1.1.0
         */
        public static $dataPath; 
Все, что вам нужно, это создать нужный файлик и указать путь до него.
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Так дело в другом. Мне нужно использовать все Существующие файлы локализаций в framework/i18n/data (чтобы не копировать файлы в свои и не исправлять их) и просто добавить новую пару Валюта=>Символ в каждый из них динамически.

Вопрос более системный. Почему Yii принудительно заставляет использовать CLocale и отсутствует легкая возможность использовать наследников.
Сначала невидимое, затем видимое. И так у всех программистов :)
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Jampire »

Вопрос, наверное, не в том, почему не позволяется создать наследников. Создать наследников-то можно. Вопрос в том, почему нельзя легко изменить файлы локализации? Наверное, потому, что это файлы, как бы так выразится, промышленного стандарта. А менять стандарт не позволено никому. Да и зачем вам локаль в том виде, которая она ест в yii, если ваша валюта на всех языках будет выглядеть одинаково?
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Тогда я не понял для чего нужно свойство public static $dataPath; ? ведь, если его поменять, то изменится каталог с файлами локализаций.

Код: Выделить всё

Вопрос, наверное, не в том, почему не позволяется создать наследников. Создать наследников-то можно. 
тогда придется делать наследников для CWebApplication, CLocale, CNumberFormatter как минимум, потому что там жестко прописан вызов класса CLocale.

Живой пример:

Есть скажем валюта "ABC", и символ у нее (для всех языков) "ǍḆÇ", так вот как вывести это символ через стандартный Yii:app()->getNumberFormatter()->formatCurrency(100, 'ABC') ?
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Вопрос в том, почему нельзя легко изменить файлы локализации? Наверное, потому, что это файлы, как бы так выразится, промышленного стандарта.
Вот так раз ) стандарт это исходник, который каждый может динамически изменять в своем приложении согласно своим нуждам. Не в стиле Yii лезь в папку с фреймворком и менять эти данные, вот это я понимаю ) и кстати символы валют по файлам локализации отличаются... например, английская локализация выведет RUB как RUB, а русская RUB => руб.
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Никто не предложит обходной путь? Тогда может закинуть в предложения, чтобы можно было динамически воздействовать на данные локали по желанию разработчика?
Сначала невидимое, затем видимое. И так у всех программистов :)
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Jampire »

Stepan Selyuk писал(а):Тогда я не понял для чего нужно свойство public static $dataPath; ? ведь, если его поменять, то изменится каталог с файлами локализаций.
Все правильно. И в этом новом каталоге будут лежать ваши измененные файлы. Процедура похожа на создание своего шаблона gii.
Stepan Selyuk писал(а):например, английская локализация выведет RUB как RUB, а русская RUB => руб.
Это не символ. Вот доллар или евро это символ. А это просто сокращение. Естественное, оно будет переводится.
Я кстати, не нашел в английских файлах кода RUB. Он есть только в файлах локализации стран СНГ. Что и правильно. Зачем дяде Сэму из Айвовы знать, сколько стоит заказанный им товар в рублях?
Зачем вам вообще использовать CNumberFormatter, если задача состоит просто в добавлении символа?
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
Аватара пользователя
Stepan Selyuk
Сообщения: 198
Зарегистрирован: 2010.02.03, 05:51
Откуда: Cyprus, Limassol
Контактная информация:

Re: Как динамически закинуть в локали нужную информацию?

Сообщение Stepan Selyuk »

Зачем вам вообще использовать CNumberFormatter, если задача состоит просто в добавлении символа?
потому что по коду уже все это раскидано сотнями раз. Раньше был просто вывод валюты ABC как есть, а сейчас нужно чтобы был символ вместо этого.

Полностью копировать data-файлы локалей и каждый из них менять совсем уж не хочется, к тому же допустим в новой версии Yii что-то добавят, изменят или исправят.
Все же я думаю, что в CLocale должен быть добавлен метод, который выкидывает приватный $_data наружу. Может в новой версии сделают :)
Сначала невидимое, затем видимое. И так у всех программистов :)
Ответить