deim

Баги при выключении русского языка в чистом ocStore 2.3.0.2

Рекомендуемые сообщения

deim    241

При попытке отключить русский язык в чистом ocStore 2.3.0.2 без удаления файлов получаем несколько неприятных багов

Описание в теме релиза https://opencartforum.com/topic/67981-%D1%80%D0%B5%D0%BB%D0%B8%D0%B7-ocstore-2302/page-11#entry647087

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

В продолжение к уже перечисленным добавлю только что найденные

 

Итак, условия:

Чистый ocStore 2.3.0.2, для каталога и админки указан английский язык в настройках магазина, после чего в локализации русский язык отключаем

 

Баги:

1. Товары

Заходим в список товаров, созданных при установке. Открываем любой и видим, что в редактировании от нас потребует заполнять всё на обоих языках

Удаляем все товары

2. Неудаляемые Атрибуты

Заходим в список атрибутов.

Удаляем все атрибуты.

Заходим в список групп атрибутов и не можем удалить ни одной, так как к ним привязаны атрибуты.

Возвращаемся в список атрибутов. Тут пусто.

Проверяем в базе таблицы _attribute и _attribute_description и видим, что атрибуты действительно существуют.

В _attribute_description видим, что все атрибуты лишились своих описаний на английском языке, при этом описания на русском там остались.

 

Итог: атрибуты есть, их не видно, группы атрибутов удалить нельзя

 

Почему так происходит с атрибутами я честно говоря не понял. Ведь в контроллере админки в атрибутах для удаления в public function delete() вызывается 

$this->model_catalog_attribute->deleteAttribute($attribute_id);

которая, как можете заметить, не содержит никаких упоминаний об language_id

Проверил на всякий случай в модели

public function deleteAttribute($attribute_id) {
   $this->db->query("DELETE FROM " . DB_PREFIX . "attribute WHERE attribute_id = '" . (int)$attribute_id . "'");
   $this->db->query("DELETE FROM " . DB_PREFIX . "attribute_description WHERE attribute_id = '" . (int)$attribute_id . "'");
}
Изменено пользователем deim

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

С атрибутами разобрался

Виноват файл

ocStore-2.3.0.2\upload\install\opencart.sql

INSERT INTO `oc_attribute_description` (`attribute_id`, `language_id`, `name`) VALUES
(1, 1, 'Description'),
(2, 1, 'No. of Cores'),
(4, 1, 'test 1'),
(5, 1, 'test 2'),
(6, 1, 'test 3'),
(7, 1, 'test 4'),
(8, 1, 'test 5'),
(9, 1, 'test 6'),
(10, 1, 'test 7'),
(11, 1, 'test 8'),
(3, 1, 'Clockspeed');

В нем просто напросто изначально отсутствуют названия атрибутов на английском языке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

Собственно вопрос:
почему в oc_language в code и в locale записано en-gb, а не en-us?

catalog\controller\startup\startup.php

// Language
		$code = '';
		
		$this->load->model('localisation/language');
		
		$languages = $this->model_localisation_language->getLanguages();
		
		if (isset($this->session->data['language'])) {
			$code = $this->session->data['language'];
		}
				
		if (isset($this->request->cookie['language']) && !array_key_exists($code, $languages)) {
			$code = $this->request->cookie['language'];
		}
		
		// Language Detection
		if (!empty($this->request->server['HTTP_ACCEPT_LANGUAGE']) && !array_key_exists($code, $languages)) {
			$detect = '';
			
			$browser_languages = explode(',', $this->request->server['HTTP_ACCEPT_LANGUAGE']);
			
			// Try using local to detect the language
			foreach ($browser_languages as $browser_language) {
				foreach ($languages as $key => $value) {
					if ($value['status']) {
						$locale = explode(',', $value['locale']);
						
						if (in_array($browser_language, $locale)) {
							$detect = $key;
							break 2;
						}
					}
				}	
			}			
			
			if (!$detect) { 
				// Try using language folder to detect the language
				foreach ($browser_languages as $browser_language) {
					if (array_key_exists(strtolower($browser_language), $languages)) {
						$detect = strtolower($browser_language);
						
						break;
					}
				}
			}
			
			$code = $detect ? $detect : '';
		}
		
		if (!array_key_exists($code, $languages)) {
			$code = $this->config->get('config_language');
		}

 
Вот этот кусочек на мой взгляд косячит

$browser_languages = explode(',', $this->request->server['HTTP_ACCEPT_LANGUAGE']);

В результате которого $browser_language получает у меня значение для хрома
Array ( [0] => ru-RU [1] => ru;q=0.8 [2] => en-US;q=0.6 [3] => en;q=0.4 ) 
И для firefox
Array ( [0] => ru-RU [1] => ru;q=0.8 [2] => en-US;q=0.5 [3] => en;q=0.3 )

 

это мой аргумент в пользу en-us вместо en-gb

 
После чего в строке 63 у нас будет разбиваться на массив значение locale из oc_language 

en_US.UTF-8,en_US,en-gb,english

Как видите, шансов на совпадение между элементами из $browser_language и explode(',', $value['locale']) нет ни малейших
Собственно для русского тоже 

ru_RU.UTF-8,ru_RU,russian

Вероятно есть смысл проверять наличие ; в $browser_language и разбивать повторно на массив.

Тогда после explode(';',$browser_language) у нас хотя бы будет шанс правильно определять и русский и английский в строчках 73-82 (для en-us вместо en-gb)

 

Потому что иначе весь этот кусок кода при включенном русском языке будет цепляться в 76 строке только за ru-RU и сразу ставить русский язык дефолтом в шаблон вместо указанного в настройках админки (строка 88)

 

Я уже сонный. Если в чем-то ошибся, то прошу поправить :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

Кстати, с баннерами тот же косяк, что и с атрибутами

У них при установке не указаны английские названия

В итоге они скрываются из шаблона при выборе английского языка.

Баг или фича? Точно не фича, так как validateForm() не пропустит банер с title меньше 2 символов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

В admin\language\en-gb\en-gb.php

пропущена $_['lang']

в результате в 

admin\controller\catalog\category.php

получаем ошибку вот тут

$this->document->addScript('view/javascript/summernote/lang/summernote-' . $this->language->get('lang') . '.js');

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
deim    241

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

 

admin\controller\catalog\category.php

$this->load->model('localisation/language');

$data['languages'] = $this->model_localisation_language->getLanguages();

Вот код model_localisation_language->getLanguages()

			$language_data = $this->cache->get('language');

			if (!$language_data) {
				$language_data = array();

				$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "language ORDER BY sort_order, name");

				foreach ($query->rows as $result) {
					$language_data[$result['code']] = array(
						'language_id' => $result['language_id'],
						'name'        => $result['name'],
						'code'        => $result['code'],
						'locale'      => $result['locale'],
						'image'       => $result['image'],
						'directory'   => $result['directory'],
						'sort_order'  => $result['sort_order'],
						'status'      => $result['status']
					);
				}

				$this->cache->set('language', $language_data);
			}

			return $language_data;

То есть нет никакой проверки включен ли язык или отключен.

А учитывая строчку с кэшем в начале мы получаем русскую рулетку.

Иногда оно может просить все языки, иногда только включенные.

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

Например от каталога.

Просто посетитель заходит на сайт и языки в кэш попадают только включенные. И именно они отобразятся в админке. Если же кэша нет или он устарел, то языки в админке будут требоваться вообще ВСЕ

В итоге потом в шаблоне админки получаем недоразумение с требованием заполнять описание на отключенных языках (так как в шаблоне тоже не проверяется включен ли язык)

На примере всё тех же категорий

admin\view\template\catalog\category_form.tpl

<?php foreach ($languages as $language) { ?>
                <div class="tab-pane" id="language<?php echo $language['language_id']; ?>">
                  <div class="form-group required">
                    <label class="col-sm-2 control-label" for="input-name<?php echo $language['language_id']; ?>"><?php echo $entry_name; ?></label>
                    <div class="col-sm-10">
                      <input type="text" name="category_description[<?php echo $language['language_id']; ?>][name]" value="<?php echo isset($category_description[$language['language_id']]) ? $category_description[$language['language_id']]['name'] : ''; ?>" placeholder="<?php echo $entry_name; ?>" id="input-name<?php echo $language['language_id']; ?>" class="form-control" />
                      <?php if (isset($error_name[$language['language_id']])) { ?>
                      <div class="text-danger"><?php echo $error_name[$language['language_id']]; ?></div>
                      <?php } ?>
                    </div>
                  </div>

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу