miniShop2 удаляет апостроф, украинские и белорусские буквы
В форме заказа в поле Получатель (receiver) не проходят валидацию такие буквы, как: "ґ", "є", "і", "ї", "ў", а также знак апострофа.
Сейчас в этом поле нельзя написать: O'Brian, Дієго Веласкес,…
Учитывая, что на сегодняшний день, относительно этого вопроса, информации крайне мало, а в мануалах этот вопрос затронут достаточно обобщенно, постараюсь подробно описать решение этой проблемы.
Если вы опытный разработчик на MODX и с miniShop2 на ТЫ, переходите сразу к 2. Валидация поля «receiver»
По умолчанию в miniShop2 за логику и обработку оформления заказа отвечает класс с именем msOrderHandler (файл расположен: core/components/minishop2/model/minishop2/msorderhandler.class.php). А за валидацию полей формы отвечает его метод validate().
Некоторые кулибины лезут прямо в этот файл и делают свои правки, но с первым же обновлением miniShop2 они, скорей всего, начинают больше думать…
____________1. Подключение кастомного обработчика
Итак, для того, чтоб внести свою логику и обработку в оформление заказа, нужно создать и расширить свой класс. Проще говоря, нужно создать свой класс-обработчик, который должен унаследовать класс msOrderHandler.
Для начала надо придумать название нашего класса, например myOrderHandler.
Далее надо создать php файл, в котором будет находиться наш класс-обработчик.
Например, создаем в директории core/components/minishop2/custom/order/ файл myorderhandler.class.php
В нем, пока, просто пишем имя нашего класса (myOrderHandler) и унаследываем дефолтный класс (msOrderHandler):
Теперь нам надо сообщить miniShop2 о том, что хотим использовать свой обработчик заказов (класс).
Это делается в два этапа.
____1-й этап
Чтоб подключить сервис, можно использовать два основных варианта:
________Вариант 1. Создать свой сниппет, например myAddService
в нем написать:
________Вариант 2. Установить замечательный компонент Console (поставщик modx.com), после чего один раз вызвать вышеупомянутый код:
____2-й этап
Сервис подключили, теперь необходимо указать новый класс myOrderHandler в системной настройке ms2_order_handler_class. И как написано в мануалах:
Все, теперь miniShop2 знает, что мы хотим использовать свой обработчик заказов (класс). А учитывая, что наш класс унаследовал все свойства и методы дефолтного класса-обработчика msOrderHandler, то вся логика и обработка заказов магазина осталась нетронутой. Что ж, пора это дело поправить под наши нужды.
____________2. Валидация поля «receiver»
Вносим правки в наш файл myorderhandler.class.php
Вот и все, теперь при заполнении поля «Получатель», срабатывает наш валидатор, который пропускает апостроф, украинские и белорусские буквы.
Кроме того, надеюсь, новичкам станет более ясен процесс кастомизации сервисов miniShop2.
Сейчас в этом поле нельзя написать: O'Brian, Дієго Веласкес,…
Учитывая, что на сегодняшний день, относительно этого вопроса, информации крайне мало, а в мануалах этот вопрос затронут достаточно обобщенно, постараюсь подробно описать решение этой проблемы.
Если вы опытный разработчик на MODX и с miniShop2 на ТЫ, переходите сразу к 2. Валидация поля «receiver»
По умолчанию в miniShop2 за логику и обработку оформления заказа отвечает класс с именем msOrderHandler (файл расположен: core/components/minishop2/model/minishop2/msorderhandler.class.php). А за валидацию полей формы отвечает его метод validate().
Некоторые кулибины лезут прямо в этот файл и делают свои правки, но с первым же обновлением miniShop2 они, скорей всего, начинают больше думать…
____________1. Подключение кастомного обработчика
Итак, для того, чтоб внести свою логику и обработку в оформление заказа, нужно создать и расширить свой класс. Проще говоря, нужно создать свой класс-обработчик, который должен унаследовать класс msOrderHandler.
Для начала надо придумать название нашего класса, например myOrderHandler.
Далее надо создать php файл, в котором будет находиться наш класс-обработчик.
Например, создаем в директории core/components/minishop2/custom/order/ файл myorderhandler.class.php
В нем, пока, просто пишем имя нашего класса (myOrderHandler) и унаследываем дефолтный класс (msOrderHandler):
<?php
class myOrderHandler extends msOrderHandler {
}
Теперь нам надо сообщить miniShop2 о том, что хотим использовать свой обработчик заказов (класс).
Это делается в два этапа.
____1-й этап
Чтоб подключить сервис, можно использовать два основных варианта:
________Вариант 1. Создать свой сниппет, например myAddService
в нем написать:
<?php
if ($miniShop2 = $modx->getService('miniShop2')) {
$miniShop2->addService('order', 'myOrderHandler',
'{core_path}components/minishop2/custom/order/myorderhandler.class.php'
);
}
далее на любой странице один раз вызвать наш сниппет [[!myAddService]], после чего можно смело удалять этот сниппет, так как подключение сервиса уже произошло.________Вариант 2. Установить замечательный компонент Console (поставщик modx.com), после чего один раз вызвать вышеупомянутый код:
<?php
if ($miniShop2 = $modx->getService('miniShop2')) {
$miniShop2->addService('order', 'myOrderHandler',
'{core_path}components/minishop2/custom/order/myorderhandler.class.php'
);
}
____2-й этап
Сервис подключили, теперь необходимо указать новый класс myOrderHandler в системной настройке ms2_order_handler_class. И как написано в мануалах:
Если что то пойдёт не так, то всегда можно вернуть старый класс.
Все, теперь miniShop2 знает, что мы хотим использовать свой обработчик заказов (класс). А учитывая, что наш класс унаследовал все свойства и методы дефолтного класса-обработчика msOrderHandler, то вся логика и обработка заказов магазина осталась нетронутой. Что ж, пора это дело поправить под наши нужды.
____________2. Валидация поля «receiver»
Вносим правки в наш файл myorderhandler.class.php
<?php
class myOrderHandler extends msOrderHandler {
public function validate($key, $value) {
//$value = trim(strip_tags($value)); //Можно смело раскомментировать
if ($key != 'comment') {
$value = preg_replace('/\s+/', ' ', trim($value));
}
$response = $this->ms2->invokeEvent('msOnBeforeValidateOrderValue', array(
'key' => $key,
'value' => $value,
));
$value = $response['data']['value'];
$old_value = isset($this->order[$key]) ? $this->order[$key] : '';
switch ($key) {
case 'receiver':
// Transforms string from "nikolaj - coster--Waldau jr." to "Nikolaj Coster-Waldau Jr."
$tmp = preg_replace(
array('/[^-a-zа-яёЁіїєґў’ʼ`\s\.\']/iu', '/\s+/', '/\-+/', '/\.+/', '/(\'|’|ʼ|`)+/'),
array('', ' ', '-', '.', "'"),
$value
);
$tmp = preg_split('/\s/', $tmp, -1, PREG_SPLIT_NO_EMPTY);
$tmp = array_map(array($this, 'ucfirst'), $tmp);
$value = preg_replace('/\s+/', ' ', implode(' ', $tmp));
if (empty($value)) {
$value = false;
}
break;
// Конечно, также можно переопределить и другие валидаторы
// Если прислано поле, которого тут нет - отправляем в дефолтный класс
default:
return parent::validate($key, $value);
}
$response = $this->ms2->invokeEvent('msOnValidateOrderValue', array(
'key' => $key,
'value' => $value,
));
$value = $response['data']['value'];
return $value;
}
}
Вот и все, теперь при заполнении поля «Получатель», срабатывает наш валидатор, который пропускает апостроф, украинские и белорусские буквы.
Кроме того, надеюсь, новичкам станет более ясен процесс кастомизации сервисов miniShop2.
Комментарии: 13
Вот тут ничего не поломалось?)
$value = preg_match('/^[^@Р°-СЏРђ-РЇ]+@[^@Р°-СЏРђ-РЇ]+(?<!\.)\.[^\.Р°-СЏРђ-РЇ]{2,}$/m', $value)
Нет, не поломалось! Очень даже рабочий вариант. Правда с регулярным выражением пришлось повозиться…
Дело в том, что в эту регулярку нельзя прямо вставить нужные символы, приходится прописывать краказябры, как будто я написал символы в utf-8, а вижу как windows-1251.
Дело в том, что в эту регулярку нельзя прямо вставить нужные символы, приходится прописывать краказябры, как будто я написал символы в utf-8, а вижу как windows-1251.
Вот оно в чём дело, спасибо! =)
Более того, немного расширил проверку на апостроф.
Т.к. апострофы народ пишет кому как удобно…
’, ʼ, ', ` — все это разные символы.
Но теперь, какой бы из этих вариантов пользователь не ввел, автоматом заменит на '.
Т.к. апострофы народ пишет кому как удобно…
’, ʼ, ', ` — все это разные символы.
Но теперь, какой бы из этих вариантов пользователь не ввел, автоматом заменит на '.
Будет лучше кстати перенести статью из Вопросы в Готовые решения.
Только-что перенес.
Хотя, насколько я помню, изначально эту статью не мог занести в раздел «Готовые решения», потому как не хватало рейтинга.
А если это так, то только-что обнаружился баг.
Если вначале создать статью в разделе «Вопросы», то после редактирования можно, не смотря на рейтинг, перенести в раздел «Готовые решения».
(:
Хотя, насколько я помню, изначально эту статью не мог занести в раздел «Готовые решения», потому как не хватало рейтинга.
А если это так, то только-что обнаружился баг.
Если вначале создать статью в разделе «Вопросы», то после редактирования можно, не смотря на рейтинг, перенести в раздел «Готовые решения».
(:
А ещё, после переноса хлебные крошки составляются так как будто тикет остался в разделе «Вопросы» :)
да да (:
Или это все проделки кэша?!
Вполне возможно или, даже, скорей всего.
Насчет рейтинга и переноса…
Это не баг… Оказывается мой рейтинг поднялся, сразу после первого голоса за эту статью.
Это не баг… Оказывается мой рейтинг поднялся, сразу после первого голоса за эту статью.
Спасибо, хорошее решение! Только таким способом вы отрезаете 2 события: msOnBeforeValidateOrderValue и msOnValidateOrderValue, и вызываться, насколько я понимаю, будут эти события у родителя, то есть валидация будет происходить по стандарту в miniShop2. Конечно, это только если использовать это в плагинах, но тем не менее, почему не сделать так?
public function validate($key, $value)
{
if ($key != 'comment') {
$value = preg_replace('/\s+/', ' ', trim($value));
}
$response = $this->ms2->invokeEvent('msOnBeforeValidateOrderValue', array(
'key' => $key,
'value' => $value,
));
$value = $response['data']['value'];
switch ($key) {
case 'receiver':
// Transforms string from "nikolaj - coster--Waldau jr." to "Nikolaj Coster-Waldau Jr."
$tmp = preg_replace(
array('/[^-a-zа-яёЁіїєґў’ʼ`\s\.\']/iu', '/\s+/', '/\-+/', '/\.+/', '/(\'|’|ʼ|`)+/'),
array('', ' ', '-', '.', "'"),
$value
);
$tmp = preg_split('/\s/', $tmp, -1, PREG_SPLIT_NO_EMPTY);
$tmp = array_map(array($this, 'ucfirst'), $tmp);
$value = preg_replace('/\s+/', ' ', implode(' ', $tmp));
if (empty($value)) {
$value = false;
}
break;
default:
return parent::validate($key, $value);
}
$response = $this->ms2->invokeEvent('msOnValidateOrderValue', array(
'key' => $key,
'value' => $value,
));
$value = $response['data']['value'];
return $value;
}
Александр, спасибо за внимательность. Я действительно забыл заменить концовку из мануальной на оригинальную:
Код поправил.
$response = $this->ms2->invokeEvent('msOnValidateOrderValue', array(
'key' => $key,
'value' => $value,
));
$value = $response['data']['value'];
return $value;
P.S.Код поправил.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.