cotonti.com : Зоопарк с окончаниями https://www.cotonti.com Последние сообщения в теме Cotonti en Mon, 06 Oct 2025 11:35:57 -0000 Boss Там она действительно уже встроена. Да и причем не только в названный плагин, а вообще в системный файл. В форуме отрабатываются тоже численные. Молодцы!]]> вс, 12 июл 2009 11:32:08 -0000 Spuner сб, 11 июл 2009 23:26:19 -0000 Boss сб, 11 июл 2009 23:16:37 -0000 Spuner выдает к примеру: Найдено 17 Array

вот то что в search.php:
			// Making the output array
			$t->assign(array(
				"PLUGIN_FORUM_FOUND" => $L['plu_found']." ".($items == $cfg['plugin']['search']['maxitems_ext'] ? $L['plu_moreres'].' ' : '').sed_declension($items,$L['plu_match'])
			));
в search.ru.lang.php:
$L['plu_match'] = array('совпадение','совпадения','совпадений');

поправьте меня пожалуйста.]]>
чт, 09 июл 2009 19:39:27 -0000
Kort Хорошо. Один только проблемный момент может быть из-за удаления языковых строк: эти строки могут использоваться не только в ядре и не только для множественного числа, но и сами по себе, так что лучше их оставить. Или даже для declensions использовать отдельные строки, вроде $L['Days_auto']. Так и получилось :)
Сейчас в main.lang вместо
$L['Day'] = 'День';
$L['Days'] = 'Дни';
стоит
$L['Days'] = array('день','дня','дней');
а вот
$L['Member'] = 'Участник';
$L['Members'] = 'Участники';
по понятной причине так и осталось. Days вроде как нигде не используется (хотя никто никого и не спрашивал), а вот members -- сплошь и рядом. Получается как-то нелогично. При этом в скине уже невозможно реализовать ни
{PHP.L.Day}
, ни
{PHP.L.Days}
Глобально использовать склоняемые формы всех локализуемых имен существительных, мне кажется, пока не получится. Идея хорошая, но копать глубоко надоть...]]>
ср, 15 апр 2009 23:57:30 -0000
dervan
Сюда
	else
	{
	$i = preg_replace('#\D+#', '', $digit);
	}
хорошо бы добавить
	else
	{
	$is_frac = false;
	$i = preg_replace('#\D+#', '', $digit);
	}

А сюда
        case 'en':
        case 'de':
        case 'nl':
        case 'se':
            return ($plural == 1) ? 1 : 0;
хорошо бы добавить
        case 'en':
        case 'de':
        case 'nl':
        case 'se':
        case 'us':
            return ($plural == 1) ? 1 : 0;

И добавить в шапку к sed_get_plural():
* @param int $plural Numeric value
* @param string $lang Target language code
* @param bool $is_frac true if numeric value is fraction, otherwise false
* @return int]]>
вс, 15 фев 2009 17:43:34 -0000
Ratibor
/**
 * Makes correct plural forms of words
 * 
 * @global string $lang Current language
 * @param int $digit Numeric value
 * @param string $expr Word or expression
 * @param bool $onlyword Return only words, without numbers
 * @param bool $canfrac - Numeric value can be Decimal Fraction
 * @return string 
 */
function sed_declension($digit, $expr, $onlyword = false, $canfrac = false)
{
    if (!is_array($expr))
    {
        return trim(($onlyword ? '' : "$digit ") . $expr);
    }

    global $lang;

	if ($canfrac)
	{
	$is_frac = floor($digit) != $digit;
	$i = $digit;
	}
	else
	{
	$i = preg_replace('#\D+#', '', $digit);
	}

    $plural = sed_get_plural($i, $lang, $is_frac);
    $cnt = count($expr);
    return trim(($onlyword ? '' : "$digit ") . (($cnt > 0 && $plural < $cnt) ? $expr[$plural] : ''));
}

/**
 * Used in sed_declension to get rules for concrete languages
 * 
 * @param int $plural Numeric value
 * @param string $lang Target language code
 * @return int 
 */
function sed_get_plural($plural, $lang, $is_frac = false)
{
    switch ($lang)
    {
        case 'en':
        case 'de':
        case 'nl':
        case 'se':
            return ($plural == 1) ? 1 : 0;
 
        case 'fr':
        case 'uk':
            return ($plural > 1) ? 0 : 1;
 
        case 'ru':
        case 'ua':
			if ($is_frac)
			{
				return 1;
			}
            $plural %= 100;
            return (5 <= $plural && $plural <= 20) ? 2 : ((1 == ($plural %= 10)) ? 0 : ((2 <= $plural && $plural <= 4) ? 1 : 2));

        default:
            return 0;
    }
}
]]>
вс, 15 фев 2009 17:09:34 -0000
Sergeich вс, 15 фев 2009 07:50:53 -0000 Ratibor # esclkm : вроде так если верить тому что мне рассказал яша. коль что киландор дорисует.
Тогда ок, завтра все доработаю на свежую голову,
а то уже четвертый час ночи :)]]>
вс, 15 фев 2009 06:18:46 -0000
esclkm вс, 15 фев 2009 06:14:30 -0000 Ratibor для uk все что больше 1 пишется в множественном, а в остальных случаях в единственном,
для en 1 в единственном, все остальное в множественном.

Правильно ?
Если так, то им вообще правила дорабатывать не надо :)]]>
вс, 15 фев 2009 05:50:22 -0000
dervan Ratibor, кстати добавь в группу где
case 'en':
ещё и
case 'us':
с этим сомнений нет, а из штатов народу на сайте хватает.]]>
вс, 15 фев 2009 05:48:43 -0000
Ratibor esclkm :
Оттуда вычитал:
Существительное, которое следует за десятичной дробью, стоит в единственном числе, если в дробном количестве нет целых единиц, и во множественном числе, если в дробном количестве есть целые единицы:
Это для en или для uk ?]]>
вс, 15 фев 2009 05:37:08 -0000
dervan
Слушай, а ты до этого про что говорил - как сделать отдельную от sed_declension() функцищу? А то если ты про то, как поправить
$is_frac = strpos($plural, '.') !== false;
так там просто:
$is_frac = floor($plural) != $plural;
и при этом числа типа 5.0 не будут считаться дробью. И ещё там можно регулярками побаловаться, если жизнь заставит.]]>
вс, 15 фев 2009 05:35:31 -0000
esclkm http://www.trilinguis.ru/linguistic/english/numerals.htm (в самом низу)
оттуда я понял что до единицы это единственное число, в противном случе plural]]>
вс, 15 фев 2009 05:31:53 -0000
Ratibor # dervan : Разве это обязательно? Раз дробь стоит, значит она произносится Ну давай это дробью будем считать, не столь важно.
Главное нам осталось с двумя группами разобраться, с en и с uk.
Что им возвращать ?
Или пошли они в баню, пусть сами голову ломают над дробями :-)
Переделать только саму функцию и правило для русского языка, а также русский ланг файл,
а англичане если это им надо сами пусть свой ланг файл переделывают и правило для своего языка :-)]]>
вс, 15 фев 2009 05:25:15 -0000
dervan # Ratibor : Но правильней Сгенерирована за 5.0 секунд или Сгенерирована за 2.0 секунды,
т.е. если .0, то 0 опускается.
Разве это обязательно? Раз дробь стоит, значит она произносится, никакой ошибки в этом нет.]]>
вс, 15 фев 2009 05:19:10 -0000
Ratibor # dervan : "две целых ноль десятых" - всё равно 2, как ни крути. Если стрингом, то да :-)

Но правильней Сгенерирована за 5.0 секунд или Сгенерирована за 2.0 секунды,
т.е. если .0, то 0 опускается.

в общем с русским мы разобрались более-менее,
теперь осталось разобраться с en и uk, что им возвращать если число не целое ?
Кто у нас тут хорошо знает английский и американский английский ?]]>
вс, 15 фев 2009 05:00:56 -0000
dervan # Ratibor : а для 2.0 должно 1 вернуться :-)
В общем лучше зделать чтото типа:
$x = $x - floor($x);
или
fmod($x,1);
"две целых ноль десятых" - всё равно 2, как ни крути. А как делать - так это сам решай, что тебе больше нравится. :)]]>
вс, 15 фев 2009 04:36:46 -0000
Ratibor # dervan : Не знаю, но если даже и так, то для фразы "пять целых ноль десятых" sed_declension() всё равно должен вернуть 2.
а для 2.0 должно 1 вернуться :-)
В общем лучше зделать чтото типа:
$x = $x - floor($x);
или
fmod($x,1);

И потом проверить на 0]]>
вс, 15 фев 2009 04:32:00 -0000
dervan
function sed_declension($digit, $expr, $onlyword = false, $canfrac = false)
{

...

	$i = preg_replace($canfrac ? '#[^.\d]+#' : '#\D+#', '', $digit);
Плюс переделки sed_get_plural(), о которых было выше.

А с setlocale IMHO лучше не связываться - сильно от системы зависит, оно надо?

# Ratibor : У тебя ошибка, ты проверяешь просто точку,
а если будет 5.0 ?
Или после phpшных фукнций так не может получится ?
Не знаю, но если даже и так, то для фразы "пять целых ноль десятых" sed_declension() всё равно должен вернуть 2.]]>
вс, 15 фев 2009 04:22:44 -0000
esclkm вс, 15 фев 2009 04:12:43 -0000 Ratibor # dervan : Так я тебя сразу и спросил - а что считать дробью? И точки, и запятые могут ставиться в числе по разным причинам.

А в sed_declention() можно добавить параметр, считать ли число с точкой дробью, по умолчанию - не считать.
Ну это наверное наилучший вариант.
И что там с сетлокалью ?
Всмысле если в ен это точка, а в ру запятая, то как тогда ?

dervan
У тебя ошибка, ты проверяешь просто точку,
а если будет 5.0 ?
Или после phpшных фукнций так не может получится ?]]>
вс, 15 фев 2009 04:08:41 -0000
esclkm вс, 15 фев 2009 04:08:23 -0000 dervan setlocale.]]> вс, 15 фев 2009 04:06:24 -0000 esclkm вс, 15 фев 2009 04:01:45 -0000 dervan
А в sed_declention() можно добавить параметр, считать ли число с точкой дробью, по умолчанию - не считать.

# Ratibor : В тех местах где может получится дробное число, как в примере с генерацией страницы, ...
function sed_declension($digit, $expr, $onlyword = false, $frac = false)

И в таких местах вызывать:
sed_declension($digit, $expr, false, true)

И не надо дополнительных функцищ.]]>
вс, 15 фев 2009 03:52:34 -0000
Ratibor
Откуда могут взятся дробные числа ?
Правильно, только после какой либо специфичной функции.
И там число может быть только с точкой и в чистом виде, без всяких тэгов.

Дак вот надо проверку на дробность вносить не в функцию sed_declension,
а зделать отдельной функцией.

В тех местах где может получится дробное число, как в примере с генерацией страницы,
мы отправляем в эту новую функцию, там проверяем, если не дробное, то отправляем в sed_declension, если дробное, то присваиваем 2 и отправляем в sed_declension.
но это справедливо для русского языка, а как быть с другими ?

dervan
как ты предложил изменить функцию sed_declension с одной стороны правильно,
а с другой так делать нельзя.
Эта функция должна работать не только с чистыми числами, а с любыми,
в том числе и обрамленными тэгами.
И что будет если пользователь введет такое число 1.035.034 ?
Правильно, фигня :)
Вот потому то и нельзя трогать функцию sed_declension]]>
вс, 15 фев 2009 03:46:19 -0000
dervan $i = preg_replace('#\D+#', '', $digit);
Так в нём же нет точек или запятых - всё кроме цифр поел preg_replace().

Вопрос про то, что есть признак дрообного числа - ключевой. Если считать, что число с точкой - дробное, тогда всё просто. Меняем
	$i = preg_replace('#\D+#', '', $digit);
на
	$i = preg_replace('#[^.\d]+#', '', $digit);

И добавляем так
function sed_get_plural($plural, $lang)
{
	$is_frac = strpos($plural, '.') !== false;

	switch ($lang)
		case 'ru':
		case 'ua':
			if ($is_frac)
			{
				return 2;
			}
			$plural %= 100;
И для остальных языковых групп тогда тоже надо добавлять по такому же принципу
		case '@$%':
			if ($is_frac)
			{
				return #;
			}
]]>
вс, 15 фев 2009 03:45:55 -0000
Ratibor # dervan : А что считать признаком дробного числа? А что php посчитает признаком, то и будет :)
можно зделать так:
$x = abs($x) - floor(abs($x));
и если $x не равно 0, то число дробное.

можно зделать так:
if fmod(y,1)>=0

Как лучше ?]]>
вс, 15 фев 2009 03:11:53 -0000
dervan вс, 15 фев 2009 02:46:01 -0000 Ratibor в tpl строку:
{PHP.L.plu_therescurrently} {WHOSONlINE_VISITORS} {PHP.L.plu_visitors} {WHOSONlINE_MEMBERS} {PHP.L.plu_members}<br />&nbsp;<br />
меняем на :
{PHP.L.plu_therescurrently} {WHOSONlINE_VISITORS} {WHOSONlINE_TEXTVISITORS} {WHOSONlINE_MEMBERS} {WHOSONlINE_TEXTMEMBERS}<br />&nbsp;<br />
а в whosonline.php добавляем:
'WHOSONlINE_TEXTVISITORS' => sed_declension($total2,$L['plu_visitors'],$onlyword=true),
'WHOSONlINE_TEXTMEMBERS' => sed_declension($total1,$L['plu_members'],$onlyword=true),

после строк:
'WHOSONlINE_VISITORS' => $total2,
'WHOSONlINE_MEMBERS' => $total1,
ну и соответственно в ланг файле меняем на:
$L['plu_visitors'] = array(' гость и ',' гостя и ',' гостей и ');
$L['plu_members'] = array(' зарегистрированный пользователь :',' зарегистрированных пользователя :',' зарегистрированных пользователей :');

Тогда все работает прекрасно, проверил.
Ну что, делать такие изменения ?

В общем переделал я whosonline и в плагине и в common.php

Начал исправлять вот это:
Страница сгенерирована за 1.568 секунд(ы) SQL общее время: 1.41 секунд(ы) - SQL запросов: 35 - Среднее время SQL: 0.04028 секунд(ы)
И столкнулся с проблеммой, функция неправльно обрабатывант дробные числа,
вернее она правильно обрабатывает, вот только обрабатывать это не надо :-)
Если число дробное, то окончание всегда будет как для 2.

Страница сгенерирована за 2 секунды
Страница сгенерирована за 1.568 секунды
Страница сгенерирована за 13.568 секунды

Т.е разлаживаем: Страница сгенерирована за 13 целых 568 тысячных секунды.
или Страница сгенерирована за 2 целыe 2 десятые секунды.
В любом случае окончание получается как для 2.

Выходит в функции надо еще зделать проверку целое число или нет,
если целое, то обрабатывать дальше как обычно, если нет, то вернуть значение как для 2.

Либо не заморачиваться с этим и плюнуть на это :)

Либо как то зделать отдельную функцию и вызывать ее до sed_declension.
Ведь дробные числа могут получится очень редко. Других мест в движке я ненашел где могут получится дробные числа.
Какие у кого будут мысли по этому поводу ?]]>
сб, 14 фев 2009 22:23:43 -0000
esclkm сб, 14 фев 2009 22:13:04 -0000 Ratibor потом впишите в function.php строку:
$digit = '';
перед строкой:
$i = preg_replace('#\D+#', '', $digit);

потом вписывайте в этот $digit = ''; нужные вам значения,
к примеру $digit = '11 12 13 14';
заходите в поиск и введите там любое значение и все увидите.

Если вам надо посмотреть как преобразовывается число,
то в function.php добавьте еще строку:
$digit = $i;
но уже после строки:
$i = preg_replace('#\D+#', '', $digit);

# Trustmaster : Хмм, а вот у меня
Я же сказал - это надо переписывать,
просто у меня совпало количество юзеров с окончаниями :-)

С надписью Сейчас на сайте 7 гостей и 12 зарегистрированных пользователей : в плагине whosonline будет посложней, там завязан еще tpl, сейчас буду пробовать :)

В общем напрямую в tpl вписать конструкцию вида:
<?php sed_declension({WHOSONlINE_VISITORS},{PHP.L.plu_visitors}) ?>
неполучается.
В общем можно заменить
{PHP.L.plu_visitors}
на к примеру:
{text_visitors}
а уже внутри whosonline.php
обработать это так:
sed_declension($total2,$L['plu_visitors'],$onlyword=true)

Или все таки можно зделать както обработку php внутри tpl ?]]>
сб, 14 фев 2009 20:55:34 -0000
Trustmaster
whosonline:
There's currently 6 visitor(s) and 12 registered member(s) online.
:-)]]>
сб, 14 фев 2009 20:49:45 -0000
dervan сб, 14 фев 2009 20:44:45 -0000 Ratibor # dervan : А при 11 12 13 14 уже будет неправильно.
Найдено 11 12 13 14 совпадений

Что тут неправильного ?

Разделяем число и получаем:
Найдено 11 миллионов 121 тысяча 314 совпадений

И где ошибка ?]]>
сб, 14 фев 2009 20:40:06 -0000
dervan сб, 14 фев 2009 20:36:33 -0000 esclkm сб, 14 фев 2009 20:34:13 -0000 dervan сб, 14 фев 2009 20:30:42 -0000