Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Склонение cлова товары в зависимости от стоящих рядом с ними цифр


Grosso2020

Recommended Posts

Всем привет!

 

Имеется opencart 2.0.3.1.

 

Необходимо решить такую задачу, то есть, чтобы выводилось, в корзине, на главной при добавлении товара  «1 товар», «2 товарА», «5 товарОВ», а не «1 товаров» и «2 товаров» и т.д.

 

Подскажите как реализовать?

Надіслати
Поділитися на інших сайтах


Создаете массив из 10 элементов {'товаров','товар','товара','товара','товара','товаров',...'товаров'}

 

Значение "Стоящие рядом цифры" делите на 10, берете остаток.

 

Остаток используете как индекс массива для извлечения нужного падежа.

 

 

А можно просто выводить строку в виде "Всего товаров в корзине: $столько-то", тогда и заморочки с падежами не нужны. 

Надіслати
Поділитися на інших сайтах


  • 1 month later...

Всем привет!

 

Имеется opencart 2.0.3.1.

 

Необходимо решить такую задачу, то есть, чтобы выводилось, в корзине, на главной при добавлении товара  «1 товар», «2 товарА», «5 товарОВ», а не «1 товаров» и «2 товаров» и т.д.

 

Подскажите как реализовать?

 

в catalog\controller\common\cart.php

$data['text_items'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

прописать код

$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
function getWord($number, $suffix) {
$keys = array(2, 0, 1, 1, 1, 2);
$mod = $number % 100;
$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
return $suffix[$suffix_key];
}
$array = array("товар", "товара", "товаров");
$data['text_items'] = $count .' '. getWord($count, $array);

Только не знаю как сделать для других языков, может кто поможет?

Надіслати
Поділитися на інших сайтах


в catalog\controller\common\cart.php

$data['text_items'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

прописать код

$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
function getWord($number, $suffix) {
$keys = array(2, 0, 1, 1, 1, 2);
$mod = $number % 100;
$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
return $suffix[$suffix_key];
}
$array = array("товар", "товара", "товаров");
$data['text_items'] = $count .' '. getWord($count, $array);

Только не знаю как сделать для других языков, может кто поможет?

так просто в массиве использовать языковые переменные ;)

Надіслати
Поділитися на інших сайтах

в свое время для модуля Statistica делал так:

 

в контроллере

            $total_pro = $this->model_module_statistica->getTotalProducts();
            $total_pro = sprintf(${'total_products'.($this->model_module_statistica->getMorphology($total_pro))}, number_format($total_pro, 0, '', ' '));

в модели

    public function getMorphology($total_pro) {
            $morf = strlen($total_pro) - 1; //номер последнего символа в числе
                        
            $total_pro = (string)$total_pro; // для верного вывода морфологии преобразовать в строку
            
            if (($total_pro[$morf] > 0 && $total_pro[$morf] < 5)  )    {
            
                if (($total_pro < 10) or (strlen($total_pro)!=1 && $total_pro[strlen($total_pro)-2]!=1)) {
                if ($total_pro[$morf] == 1)    {
                    $total_pro = 1;
                }    else    {
                    $total_pro = 2;
                }
                } else    {
                    $total_pro = 3;
                }
            
            }    else    {
                $total_pro = 3;
            }    
        
        return $total_pro;
    }

в языковых файлах

russian

$_['total_products1']    = 'в магазине %s товар';
$_['total_products2']    = 'в магазине %s товара';
$_['total_products3']    = 'в магазине %s товаров';

english

$_['total_products1']    = '%s product in store';
$_['total_products2']    = '%s products in store';
$_['total_products3']    = '%s products in store';

решение может и не самое изящное, но вполне рабочее - результат можно увидеть по ссылке :-)

Надіслати
Поділитися на інших сайтах

вместо

$array = array("товар", "товара", "товаров");

использовать

$total1 = $this->language->get('total1');
$total2 = $this->language->get('total2');
$total3 = $this->language->get('total3');

$array = array($total1, $total2, $total3);

$total1, $total2 и $total3 предварительно прописать в нужных языковых файлах

Надіслати
Поділитися на інших сайтах

  • 2 weeks later...

Это не полное решение.

При обновлении аяксом опенкарт использует другие переменные.

Плюс, непонятно, зачем убрали вывод суммы - вроде, ТС этого не просил :-)

Полный вариант

 

В catalog\controller\common\cart.php  заменяем

$data['text_items'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

на

	$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
	function getWord($number, $suffix) {
	$keys = array(2, 0, 1, 1, 1, 2);
	$mod = $number % 100;
	$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
	return $suffix[$suffix_key];
	}
	$text_items1 = $this->language->get('text_items1');
	$text_items2 = $this->language->get('text_items2');
	$text_items5 = $this->language->get('text_items5');
	$array = array($text_items1, $text_items2, $text_items5);
	$currency = $this->currency->format($total);
$data['text_items'] = $count .' '. getWord($count, $array).' - '.$currency;

а в \catalog\language\russian\common\cart.php добавляем

$_['text_items1']	= 'товар';
$_['text_items2']	= 'товара';
$_['text_items5']	= 'товаров';

Теперь аналогично надо сделать для аякс-запросов:

 

в файле \catalog\controller\checkout\cart.php   ДВА раза надо заменить

$json['total'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

на

	$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
	function getWord($number, $suffix) {
	$keys = array(2, 0, 1, 1, 1, 2);
	$mod = $number % 100;
	$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
	return $suffix[$suffix_key];
	}
	$text_items1 = $this->language->get('text_items1');
	$text_items2 = $this->language->get('text_items2');
	$text_items5 = $this->language->get('text_items5');
	$array = array($text_items1, $text_items2, $text_items5);
	$currency = $this->currency->format($total);
$json['total'] = $count .' '. getWord($count, $array).' - '.$currency;

И, соответственно, в \catalog\language\russian\checkout добавляем

$_['text_items1']	= 'товар';
$_['text_items2']	= 'товара';
$_['text_items5']	= 'товаров';

Проверено на ОС 2.102, работает.

Змінено користувачем Shureg
Надіслати
Поділитися на інших сайтах


ТС про сумму и не говорил ничего...

 

Он просил "Подскажите", а не "Дайте готовое и ОБЯЗАТЕЛЬНО ПОЛНОЕ решение".

 

Shureg, чувствуете разницу?

Вам поговорить не с кем? Считаете мой ответ менее полезным, чем ваш?

Надіслати
Поділитися на інших сайтах


Создаете массив из 10 элементов {'товаров','товар','товара','товара','товара','товаров',...'товаров'}

Значение "Стоящие рядом цифры" делите на 10, берете остаток.

@igon, 1 товар, 11 товаров. 2 товара, 12 товаров, 22 товара

Надіслати
Поділитися на інших сайтах


Ну да, поэтому делить нужно на 20. Суть от этого меняется не очень сильно. ИМХО...

Так на 10 или на 20?

Суть очень даже меняется, ИМХО.

Вам тогда и массив надо до 20 увеличивать. Однако, при этом после 30 товаров всё опять испортится, и склонения пойдут какие попало...

Предложите делить на 30? :-D

Надіслати
Поділитися на інших сайтах


Ну да, поэтому делить нужно на 20. Суть от этого меняется не очень сильно. ИМХО...

Остаток от деления на 20 у любого числа меньше 21 будет равен нулю. Кстати, при делении на 10 эта же проблема будет присутствовать. 1 товаров, 2 товаров, 3 товаров...

Если суть - это наличие рабочего алгоритма, то как истинная блондинка, я считаю: он или есть или его нет. Я думал, приведён готовый алгоритм.

Надіслати
Поділитися на інших сайтах


Всем  привет! Да задачи не было показывать сумму, но убирать ее не совсем корректно. То есть задача была склонить слова без ущерба функционала))) Спасибо за решение)))

Змінено користувачем Grosso2020
Надіслати
Поділитися на інших сайтах


Остаток от деления на 20 у любого числа меньше 21 будет равен нулю. Кстати, при делении на 10 эта же проблема будет присутствовать. 1 товаров, 2 товаров, 3 товаров...

Если суть - это наличие рабочего алгоритма, то как истинная блондинка, я считаю: он или есть или его нет. Я думал, приведён готовый алгоритм.

Ну какой тут готовый алгоритм! Всего лишь подсказка, что падежи можно извлекать по индексу массива, а сам индекс получать из остатка от деления.

Надіслати
Поділитися на інших сайтах


Зачем изобретать велосипед?

Для склонения существительных рядом с числительным есть несколько готовых, опробованных алгоритмов.

Желающим ознакомиться - гугл в помощь.

В примере specussa использован один из самых красивых, имхо.

Доработанное готовое решение для opencarta:

Проверено на ОС 2.102, работает.

PS:

Остаток от деления на 20 у любого числа меньше 21 будет равен нулю. Кстати, при делении на 10 эта же проблема будет присутствовать. 1 товаров, 2 товаров, 3 товаров...

деление по модулю в php работает не так, как арифметический остаток. Вывод 2%10 будет не 0, как ожидается математически, а 2.

Змінено користувачем Shureg
Надіслати
Поділитися на інших сайтах


  • 3 weeks later...

Замечательная идея. Для склонения одного слова всего-то и потребуется:

прочитать длинный мануал

установить словари

установить собственно библиотеку

подключить это счастье в индексе опенкарта

откорректировать (согласно длинному мануалу) файлы темы.

:huh:

Надіслати
Поділитися на інших сайтах


кстати вот делал для себя склонение слова "отзыв" в товаре, если кому надо то вот

в файле controller/product/product.php строку

$data['reviews'] = sprintf($this->language->get('text_reviews'), (int)$product_info['reviews']);

заменить на:

$count = (int)$product_info['reviews'];
function getWords($number, $suffix) {
$keys = array(2, 0, 1, 1, 1, 2);
$mod = $number % 100;
$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
return $suffix[$suffix_key];
}
$total1 = $this->language->get('text_reviews1');
$total2 = $this->language->get('text_reviews2');
$total3 = $this->language->get('text_reviews3');

$array = array($total1, $total2, $total3);
            
$data['reviews'] = $count .' '. getWords($count, $array);

ну и соответственно добавить переменные в языки

$_['text_reviews1']                           = 'отзыв';
$_['text_reviews2']                           = 'отзыва';
$_['text_reviews3']                           = 'отзывов';
Надіслати
Поділитися на інших сайтах


  • 1 year later...
В 17.04.2016 в 15:58, ussa сказал:

кстати вот делал для себя склонение слова "отзыв" в товаре, если кому надо то вот

в файле controller/product/product.php строку


$data['reviews'] = sprintf($this->language->get('text_reviews'), (int)$product_info['reviews']);

заменить на:


$count = (int)$product_info['reviews'];
function getWords($number, $suffix) {
$keys = array(2, 0, 1, 1, 1, 2);
$mod = $number % 100;
$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
return $suffix[$suffix_key];
}
$total1 = $this->language->get('text_reviews1');
$total2 = $this->language->get('text_reviews2');
$total3 = $this->language->get('text_reviews3');

$array = array($total1, $total2, $total3);
            
$data['reviews'] = $count .' '. getWords($count, $array);

ну и соответственно добавить переменные в языки


$_['text_reviews1']                           = 'отзыв';
$_['text_reviews2']                           = 'отзыва';
$_['text_reviews3']                           = 'отзывов';

Спасибо, пригодилось)

Надіслати
Поділитися на інших сайтах

  • 1 year later...
В 18.03.2016 в 03:13, Shureg сказал:

Это не полное решение.

При обновлении аяксом опенкарт использует другие переменные.

Плюс, непонятно, зачем убрали вывод суммы - вроде, ТС этого не просил :-)

Полный вариант

 

В catalog\controller\common\cart.php  заменяем


$data['text_items'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

на


	$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
	function getWord($number, $suffix) {
	$keys = array(2, 0, 1, 1, 1, 2);
	$mod = $number % 100;
	$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
	return $suffix[$suffix_key];
	}
	$text_items1 = $this->language->get('text_items1');
	$text_items2 = $this->language->get('text_items2');
	$text_items5 = $this->language->get('text_items5');
	$array = array($text_items1, $text_items2, $text_items5);
	$currency = $this->currency->format($total);
$data['text_items'] = $count .' '. getWord($count, $array).' - '.$currency;

а в \catalog\language\russian\common\cart.php добавляем


$_['text_items1']	= 'товар';
$_['text_items2']	= 'товара';
$_['text_items5']	= 'товаров';

Теперь аналогично надо сделать для аякс-запросов:

 

в файле \catalog\controller\checkout\cart.php   ДВА раза надо заменить


$json['total'] = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));

на


	$count = $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0);
	function getWord($number, $suffix) {
	$keys = array(2, 0, 1, 1, 1, 2);
	$mod = $number % 100;
	$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
	return $suffix[$suffix_key];
	}
	$text_items1 = $this->language->get('text_items1');
	$text_items2 = $this->language->get('text_items2');
	$text_items5 = $this->language->get('text_items5');
	$array = array($text_items1, $text_items2, $text_items5);
	$currency = $this->currency->format($total);
$json['total'] = $count .' '. getWord($count, $array).' - '.$currency;

И, соответственно, в \catalog\language\russian\checkout добавляем


$_['text_items1']	= 'товар';
$_['text_items2']	= 'товара';
$_['text_items5']	= 'товаров';

Проверено на ОС 2.102, работает.

 

 

Данное решение не работает с модулем - Simple - упрощенная регистрация и заказ.

 

Подскажите пожалуйста как адаптировать этот код для  Simple?

 $minicart = $this->simplecheckout->getSettingValue('minicartText', 'cart');
            
            $text_items = '';
            $language_code = $this->simplecheckout->getCurrentLanguageCode();

            if ($minicart && !empty($minicart[$language_code])) {
                $text_items = $minicart[$language_code];
            }

            if (!$text_items) {
                $this->language->load('checkout/cart');
                $text_items = $this->language->get('text_items');
                $this->language->load('checkout/simplecheckout');
            }

            $this->_templateData['cart_total'] = sprintf($text_items, $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->simplecheckout->formatCurrency($total));
        

 

Змінено користувачем mx928
Надіслати
Поділитися на інших сайтах


  • 8 months later...
В 17.04.2016 в 15:58, ussa сказал:

кстати вот делал для себя склонение слова "отзыв" в товаре, если кому надо то вот

в файле controller/product/product.php строку


$data['reviews'] = sprintf($this->language->get('text_reviews'), (int)$product_info['reviews']);

заменить на:


$count = (int)$product_info['reviews'];
function getWords($number, $suffix) {
$keys = array(2, 0, 1, 1, 1, 2);
$mod = $number % 100;
$suffix_key = ($mod > 7 && $mod < 20) ? 2: $keys[min($mod % 10, 5)];
return $suffix[$suffix_key];
}
$total1 = $this->language->get('text_reviews1');
$total2 = $this->language->get('text_reviews2');
$total3 = $this->language->get('text_reviews3');

$array = array($total1, $total2, $total3);
            
$data['reviews'] = $count .' '. getWords($count, $array);

ну и соответственно добавить переменные в языки


$_['text_reviews1']                           = 'отзыв';
$_['text_reviews2']                           = 'отзыва';
$_['text_reviews3']                           = 'отзывов';

Благодарю! Пригодилось. А как его в рекомендуемые товары прикрутить такое же можно? (catalog/controller/extension/module/featured.php)

Надіслати
Поділитися на інших сайтах


Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.