Тот самый момент, когда чужие мысли входят в резонанс с твоими собственными
Иногда бывают задачи когда нужно реализовать обертку для работы с API некоторого сервиса для нужд заказчика и сделать подобною задачу в основном довольно просто, но в сервиса не всегда есть этот API, либо возникает мысль что лучше бы его не было
Знаете что самое интересное в работе с Magento? Можно излазить эту CMS вдоль и поперёк и всё равно нет-нет, а нарвёшься на какую-нибудь неизвестную деталь.
Вот так и случилось c модулем CouponUsage. При выводе списка купонов хотелось сделать прямо в гриде ссылки на заказ и использованное правило с купоном. Ничего сложного — дополнительный блок рендера, параметр «renderer» в описании колонки и готово. И всё было бы хорошо если бы не экспорт отчёта в csv и xml. При экспорте используется тот же блок грида что и при выводе в админке. Данные, само собой, точно так же проходят через рендерер и в итоге получаем в файле экспорта не номер заказа и название правила, а нечитаемый хтмл вида
<a href="http://example.com/index.php/admin/sales_order/view/order_id/193/">100000193</a>
Раз есть такая проблема — думаем логически. Раз есть отдельный метод в контроолере для обработки экспорта, значит, можно там как-то дать понять системе какой формат данных нам нужен. Первое решение «в лоб» показалось самым простым и правильным. Передать в блок свою переменную no_renderer и по ней уже определять подключать рендерер или нет.
Смущало только что такого подхода не встречал. My bad. Совсем бегло родительские классы проглядывал. Оказалось, всё вообще банально и просто. В классе Mage_Adminhtml_Block_Widget_Grid есть уже готовый флаг $_isExport как раз переключающийся при вызове экспорта.
Такая вот работа над ошибками, да. На гитхабе, разумеется, уже обновлённая версия.
Вот такой, оказывается, есть ролик об инженерах премьер поддержки. Прям Брюс Уэйн и Тони Старк в одном флаконе.
Ну, что тут можно сказать. Интересное мероприятие, не однозначное. Организаторы, несомненно, проделали колоссальную работу. Секции достаточно разнообразные, широкий спектр тем. Именитые докладчики. Конференция однозначно удалась.
На этом, в принципе, можно было бы и закончить, но так же не интересно, правда? Я отлично понимаю, что конференция, с большего, от маркетологов и для маркетологов. Посетить абсолютно все доклады, разумеется, было невозможно. Но после того что я видел не могу задать вопрос: «Ребята, а большинство из вас может же лучше, да?». Возможно, я не совсем понял основное направление конференции, нарисовал сам себе какую-то идеальную картинку и сам же в неё поверил. Но «крупнейшее оффлайновое мероприятие, посвященное интернету и проводимое в Беларуси с 2006 года» должно было бы уже задрать планку до небес. Ну, я так, по крайней мере, думаю, что должно было. Раньше как-то слабо интересовался байнетом, и прошлые конференции прошли мимо. Возможно, кто-нибудь просвятит по этому поводу и сравнит.
Выступали-то у нас менеджеры, люди, представляющие свои компании, не последние люди в профессии, а драйва, куража нет. Страннно, да? Я не говорю что это общая проблема, были, разумеется, и отличные выступления. Цели детально разбирать каждый отдельный доклад я не ставлю, просто описываю собственные ощущения. Кто был крут, тот и сам об этом знает. А мы здесь о тенденциях.
Доклады. Повторюсь, возможно, я и ошибаюсь, но цель доклада, как мне кажется, — рассказать что-то новое, систематизировать ранее накопленые знания или продвинуть технологию. А как охарактеризовать пересказ своими словами достаточно общей статью из первых результатов поисковой выдачи?
— Знаете что такое CPA?
— Да
— Хорошо, сейчас я расскажу вам что такое CPA
Утрирую, конечно, но пример показательный :-).
Читали про громкость близоруких у Людвига? Так вот, я один из тех вечно недовольных, мечтающих о больших шрифтах и межстрочных интервалах. И знаете, я не одинок. Так почему же люди стремятся запихнуть в один слайд презентации как можно больше информации? Тезисы, там должны быть тезисы. Один слайд — один-два тезиса, не больше. Это же не сложно. Графики и диаграммы должны быть контрастными. Сбои цветопередачи проектора всегда возможны. Почему бы не подстраховаться? Дизайнера, в конце концов, можно привлечь. Выступление, в итоге, забудется, а вот качественная презентация разойдётся уймой копий по интернету. Вы же не откажетесь от бесплатной брэндовой рекламы?
Ещё пару мелочей и заканчиваю. К сожалению, секция Big Data прошла мимо большинства участников конференции. Очень советую обратить внимание на материалы докладов после их публикации. Это было шикарно.
И кто-нибудь, пожалуйста, объясните в чём заключалась фишка пинать ногами трупики корпоративных и государственных сайтов на секции Usability? КВН получился отменный, не спорю, а смысл?
В целом мероприятие получилось на славу. Хороший праздник, хорошая организация. Никто же не виноват, что чукча — ругатель :-)
Мировые тренды говорят, что интеренет-магазины должны быть адаптированы для мобильных пользователей. Споры так это или нет оставим без внимания. Точно так же обойдём стороной методы реализации: мобильные и адаптивные темы, приложения, отдельные сайты. Просто договоримся на сегодня: покупателю с мобильным устройством должно быть так же удобно пользоваться магазином, как и его коллеге перед десктопом.
Итак, договорились — мобильные темы нужны. Теперь давайте выясним кто же проводит в интеренет-магазине больше всего времени. Привередливый покупатель? Конкурент? Налоговые органы? Вы совершенно правы — больше всего времени на сайте проводит администратор! Однако, как сильно мы заботимся об удобстве покупателей, так же бездумно мы оставляем на произвол судьбы наших менеджеров. Я не хочу сказать что разработчики не думают об удобстве админки. Большинство разделов достаточно логично расположены и спланированы. Просто люди, работающие на десктопах и ноутбуках, проектируют админку для себя. Всё, кажется, справедливо. Только админу, попытавшемуся во время поездки проверить как идут дела в магазине, от такой справедливости не легче.
Пример админки в телефоне
Вообще, изменения темы админки описано слабо. Готовых решений ещё меньше. По сути, Magento, при всей её гибкости в настройке фронтенда, не предоставляет никаких инструментов для измененния админки. А раз нам чего-то не хватает — добавим это. Благо, принципы рендеренга админки те же самые, что и для фронтенда.
Итак, наша цель —указать отдельную тему для администраторов зашедших с мобильных устройств. Как водится, содаём модуль.
config.xml:
<?xml version="1.0"?> <config> <modules> <Belvg_AdminTheme> <version>1.0.0</version> </Belvg_AdminTheme> </modules> <global> <models> <admintheme> <class>Belvg_AdminTheme_Model</class> </admintheme> </models> </global> <adminhtml> <events> <adminhtml_controller_action_predispatch_start> <observers> <themeoverride_observer> <type>singleton</type> <class>Belvg_AdminTheme_Model_Observer</class> <method>getAdminTheme</method> </themeoverride_observer> </observers> </adminhtml_controller_action_predispatch_start> </events> </adminhtml> <default> <design> <admin> <theme>default</theme> </admin> </design> </default> </config>
Главная часть модуля — событие adminhtml_controller_action_predispatch_start, в котором мы должны сравнить User Agent клиента, подобрать соответствующую тему и заменить тему default на нашу.
Belvg_AdminTheme_Model_Observer:
<?php class Belvg_AdminTheme_Model_Observer { const DEFAULT_THEME = 'design/admin/theme'; const REGEX_PATH = 'design/admin/ua_regexp'; const AREA = 'adminhtml'; public function getAdminTheme() { $configValueSerialized = Mage::getStoreConfig(self::REGEX_PATH); if (!$configValueSerialized) { return $this; } $regexps = @unserialize($configValueSerialized); if (empty($regexps)) { return $this; } $_theme = Mage_Core_Model_Design_Package::getPackageByUserAgent($regexps, self::REGEX_PATH); $_theme = $_theme ? $_theme : Mage::getStoreConfig(self::DEFAULT_THEME); Mage::getDesign()->setArea(self::AREA)->setTheme($_theme); return $this; } }
Метод getAdminTheme() напоминает поведение класса Mage_Core_Model_Design_Package, отвечающего за выбор пакета и темы для фронтенда.
N.B. для педентов: подавление ошибок @unserialize($configValueSerialized) не моё, смотреть в Mage_Core_Model_Design_Package::_checkUserAgentAgainstRegexps() :)
И, собственно, самая важная для конечного пользователя часть — вывод дополнительной настройки в конфигурации.
system.xml:
<?xml version="1.0"?> <config> <sections> <design> <groups> <admin translate="label"> <label>Admin Theme</label> <frontend_type>text</frontend_type> <sort_order>1</sort_order> <show_in_default>1</show_in_default> <expanded>1</expanded> <fields> <theme translate="label comment"> <label>Default Admin Theme</label> <frontend_type>text</frontend_type> <sort_order>1</sort_order> <show_in_default>1</show_in_default> </theme> <ua_regexp translate="comment"> <label>Add expression</label> <frontend_model>adminhtml/system_config_form_field_regexceptions</frontend_model> <backend_model>adminhtml/system_config_backend_design_exception</backend_model> <sort_order>2</sort_order> <show_in_default>1</show_in_default> <comment>Match expressions in the same order as displayed in the configuration.</comment> </ua_regexp> </fields> </admin> </groups> </design> </sections> </config>
В Magento админка представляет из себя отдельный стор (store_id=0). Все остальные сторы представляют собой фронтенд. Благодаря событию adminhtml_controller_action_predispatch_start мы вызываем наш обсервер только при загрузке админки. Так что все параметры в нашем конфиге я сделал глобальными, независящими от выбранного для конфигурации стора.
И вот что же у нас получилось в итоге:
Осталось только добавить в исключения правила для мобильных браузеров (например, iPhone|iPod|BlackBerry|Palm|Googlebot-Mobile|mobile|mobi|Windows Mobile|Safari Mobile|Android|Opera Mini|Fennec) и, собственно, создать ту самую мобильну тему для админки.
P.S. в качестве примера конечного решения приведу наш «Tablet Dashboard» — достаточно удобный инструмент для работы с заказами для мобильных администраторов.
Как это ни печально, но не смотря на всю развитую систему маркетинга, до сих пор основным методом привлечения клиентов и повышения продаж являются всякие промо-акции, скидки и системы купонов. Magento, конечно, и так предоставляет достаточно богатый функционал для анализа и статистики. Но много инструментов не бывает (лишь бы рук хватило). Так что сделаем нашим менеджерам по продажам очередной подарочек.
В принципе, существует и стандартный отчёт об использованных купоках в Reports - Sales - Coupons. Но мы пойдём дальше. Для начала создадим модуля с кастомным гридом (подробней о создании модуля).
Рассмотрим только основную часть — создание грида.
/** * Prepare grid collection * * @return Mage_Adminhtml_Block_Widget_Grid */ protected function _prepareCollection() { $collection = Mage::getModel('sales/order')->getCollection(); $collection->addAttributeToFilter('coupon_code', array('notnull' => TRUE)); $collection->addAttributeToFilter('coupon_code', array('neq' => '')); $collection->getSelect()->joinLeft( array('salesrule_coupon'=>$collection->getTable('salesrule/coupon')), 'main_table.coupon_code = salesrule_coupon.code', array('salesrule_coupon.rule_id')); $collection->getSelect()->joinLeft( array('salesrule_rule'=>$collection->getTable('salesrule/rule')), 'salesrule_coupon.rule_id = salesrule_rule.rule_id', array('salesrule_rule.name')); $this->setCollection($collection); return parent::_prepareCollection(); }
Основной запрос — найти все заказы у которых указан coupon_code. Это нам сразу же даёт номер, сумму, статус заказа и, собственно, сам использованный купон. Однако, код купона недостаточно информативен. Добавим так же название купона — просто джойним модели salesrule/coupon и salesrule/rule и получаем информацию об использованнм правиле.
Кажется, уже достаточно информативно и функционально:
На этом, собственно, можно было бы и остановиться, если бы не классический вопрос нашего времени: «и что теперь с этим делать?». Добавим возможность сразу перейти на страницы заказа и купона.
Чтобы не перепечатывать весь листинг приведу пример для название правила. Укажем в блоке грида свой рендерер:
$this->addColumn('name', array( 'header' => Mage::helper('salesrule')->__('Rule Name'), 'align' => 'left', 'index' => 'name', 'renderer' => $this->getNoRenderer()?'':'belvg_couponusage/adminhtml_couponsusage_grid_renderer_rule', 'filter_index' => 'salesrule_rule.name' ));
На этом, пожалуй, действительно всё. Посмотрим, как модуль пройдёт обкатку в боевых условиях.
Весь модуль на гитхабе: CouponUsage
Россия такая страна, где всем нужна халява, и магазин тоже)) никогда не понимал эту страну)
У русских есть традиция, купить модуль и дать его своему другу, или выложить где-нибудь бесплатно.
Первоисточники на русском форуме Prestashop.
Вот сижу и думаю: правы товарищи — nulled форумов тьма-тьмущая, вакансий вида «выпилить лицензию» не меньше. Посмотришь — кругом враги, все пираты и мошенники.
И видятся на фоне этой беспросветной отечественной безнадёги забугорные клиенты этакими рыцарями без страха и упрёка. Все соблюдают лицензионные соглашения, вовремя оплачивают лицензии и никогда не используют ворованный софт.
Думаю вот, значит, и понимаю — какая-то ерунда получается. Варезниками-то пользуются далеко не все. Многим знакомым уже просто лень тратить время на поиск кряка, когда можно за сравнительно небольшие деньги приобрести гарантированно рабочую версию (да и в саппорт сходить не проблема, ежели что). Большинство знакомых продуктовиков, работающих на СНГ пространстве, как-то уже года 2 как не жалуются на пиратов. Всё в пределах нормы.
С другой стороны не всё так уж радужно с забугорными клиентами. Варезных буржуйских сайтов не меньше, чем у нас (их быстрее закрывают, конечно, но тут же появляются новые). Накупить пачку модулей, все их установить и потребовать рефанд, использовать одну лицензию модуля в десятке проектов, перепродать ранее купленные модули — постоянно ловим кого-то за руку. И здесь нет чёткой статистики по национальности. Французы, немцы, американцы, бразильцы, индусы — все стремятся схитрить и сэкономить.
Получается, что эти ужасные русские ничем не отличаются от цивилизованных европейцев и американцев. Ситуация везде одинаковая и страна пиратов, хакеров, воров и мошенников — не более, чем стереотип.
Возможно, с активным продвижением нашей русской сборки Magento моё мнение и изменится, но на данный момент я не вижу причин так однозначно клеймить позором СНГ сообщество.