Перейти к содержанию

Блоги

Джентельменский набор модулей

Все модули в списке проверенные временем! Имейте ввиду, шаблон это шаблон - морда сайта , А модули это функционал! Общие: Сборка ocStore на opencart  - актуальная v2.3.0.2.3 - от  сообщества OpenCartForum >  тут . Сборка OpencartPRO - платная   >  тут . ***Сборка под оптовые продажи на основе ocStore v2.3.0.2.3 - подробности в ЛС. Скрытие категорий от групп покупателей   >  тут . Определение города по IP  - (Geo IP)    >  тут . Всплывающие окона (формы) + Торги с покупателем - Конструктор  >  тут . SEO PRO oc3x - сео про для опенкарт 3х  ко мне в ЛС . Robots noindex  -  >  тут .  404  страница  >  тут . Автоматическое заполнение SEO_URL   >  тут .  URL генератор для 3.0    >  тут . Seo Keyword Manager  -  тут . SEO - Title и Мета Description для страниц Акций, Производителей и т.д.   > тут . SEO мультиязык   >  тут . Убираем грубую SEO ошибку проверки входящих данных - SEO DATAFIX  >  тут . Корректный перенос Opencart на HTTPS протокол - SEO HTTPS FIX PRO   >  тут .  Дополнительные мультиязычные вкладки в карточку товара   >  тут . Обратный звонок PRO  >  тут .  Jivosite - Онлайн консультант (чат)   >  тут .  Функционал - Запомнить меня при авторизации пользователя   >  тут .     АДМИНКА: Защита админки от вирусов и хакеров >  тут . Логирование действий пользователей админки    >  тут . Исправленный модификатор для установки модулей без надобности включения FTP в настройках  >  тут .  АОП - Парсер \ Импорт \ Экспорт - Автоматическая обработка прайс-листов  >  тут .
        ----- Журнал работы модуля "Автоматическая обработка прайс-листов"   >  тут . Batch Editor - Пакетное редактирование товаров  -   > тут . Закупочная цена товаров - CostPrice   >  тут . Почтовая рассылка PRO    >  тут . Заметки администратора    >  тут  . TOTAL AMOUNT - Общая сумма всех заказов покупателя в списках  >  тут .   Чистильщик кэша и логов  >  тут  .       Карточки Товаров Куча различных модификаторов для опций  >  тут . Выбор опции по умолчанию  >  тут . BTN link | Произвольные мультиязычные ссылки вместо кнопки купить   >  тут . HYPER KIT SERIES  Комплекты серий товаров - наборы товара   >  тут . Подсказка для атрибутов, групп атрибутов, опций и их значений   >  тут . Похожие товары по атрибутам  >  тут . Автоматический подбор рекомендуемых  >  тут . Уведомление о поступлении товара >  тут . Купить в 1 клик / Быстрый заказ - PRO  >  тут . Метки | Поиск продуктов - уникальные мета-теги, ЧПУ - SEO CMS PAGES  > тут . Crear : (File Downloads) - Файлы для скачивания  > тут . Load more – кнопка “показать еще”   >  тут . Архивный товар / Снят с производства  >  тут  . Вы   Корзина и Одно страничное оформление заказа   Одно страничное оформление заказа и корзина Simple   >   тут .   Управление доставкой и оплатой  >  тут .   CART CACHE - кэширование корзины   >  тут . Брошенная корзина + вечная корзина + редактор корзин  >  тут .   Заказы Расширенный редактор заказов - OrderPro   >   тут . Менеджер заказов >  тут . Автоматическое изменение статуса заказа и уведомление    >  тут . Шаблоны писем при оформлении заказа и изменении статусов заказа и т.д. >  тут .
                                                                  -  шаблоны  тут >   http://beautiful-email-newsletters.com/
                                                                  - и тут >  http://htmlemailgallery.com/ Выгрузка заказов в EXCEL, PDF, CSV, распечатать список заказов  >  тут . Комментарии к заказу и покупателям   >  тут  .  Исправление транзакций   >  тут  .     Шаблоны Платные  >  тут . Бесплатные  >  тут .   Лояльность, Акции, Скидки и т.д. Товар дня - Акция    >  тут . Скидки - Пользовательские, Накопительные, Количественные, Комплектные, Оптовые\Групповые цены, Акции и т.д. -  >  тут . Комплекты (вместе дешевле) PRO версия  >  тут . Цепляем уходящих клиентов  >  тут .     Блоги Блог | Новости | Отзывы | Галерея | Формы SEO CMS TOP 2    >   тут .     Дизайн: Персонализированные шаблоны - от   >  тут . HYPER Positions +70 позиций модулей   >  тут  .  ...   Доставка   Модуль Shiptor - агрегатор доставки    >  тут .   Яндекс доставка     >  тут .  Оценка доставки на страницах магазина и в карточках товара   >  тут .     Оплата \ Платежные системы Огромное количество модулей оплат   >  тут .     Прочее Торговая площадка    >  тут .     Аудит Экспресс аудит сайта   >  тут .     Оптимизация Layout Type, ускорение мобильной версии    >  тут  . SiteMap кому нужно смотрите  по ссылке  >  тут . Google Remarketing Feed Generator   >  тут .  Оптимизация полная и скорость ИМ - от  @snastik  >  тут .  Оптимизация полная и скорость ИМ - от @markimax   >  тут .     Продвижение  - SEO, СММ, Контекст       -  Пишите мне в лс есть шикарная команда   Тексты, описания, статьи, рерайты, копирайты и т.д. и журналисты тож есть скайп  pishemvsevastopol   Нормальный хостинг тут . позже ещё добавлю по своему усмотрению..
Предлагать мне добавлять сюда свои модули не нужно!
Если всё подряд начну добавлять это будет каша а не набор! Если в списке чего то вашего нет, то не нужно лепить минусы - просто идите мимо и не позорьтесь, всё то, что выше это исключительно мой выбор!   P.S.
***Реализация интернет магазина под оптовые продажи, отдельный каталог товаров прайс листами с взаимосвязанной корзиной, доработка корзины и необходимых модулей под оптовые продажи.
Подробности спрашиваем в личные сообщения.

AWARO

AWARO

 

Поиск по номеру телефона

Вариант поиска для тех, у кого нет форматирования телефонов перед добавлением их в базу. Можно искать как заказы, так и покупателей, или чего-угодно, где есть это поле.   Пример для поиска заказов if (!empty($data['filter_telephone'])) { $telephone = preg_replace('/\D+/', '', $data['filter_telephone']); $sql .= " AND (TRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(o.telephone, ' ', ''), '(', ''), ')', ''), '-', ''), '/', ''), '+', '')) LIKE '%" . $this->db->escape($telephone) . "%' OR " . $this->db->escape($telephone) . " LIKE CONCAT('%', TRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(o.telephone, ' ', ''), '(', ''), ')', ''), '-', ''), '/', ''), '+', '')), '%'))"; } Какие номера находит:    +38(050)123-45-67  501234567  (050)123-45-67  050 123 45 67  0501234567  (050)1234567   или любое вхождение в них.

SooR

SooR

Интересная загадка

Вы хотите послать своей любимой посылку с бриллиантовым колье. При этом единственный способ — воспользоваться почтой. Можно повесить на посылку любое количество замков. Допустим, открыть замок без ключа никто не может, как и вскрыть посылку. Но вы ни при каких обстоятельствах не хотите рисковать и посылать по почте ключи.
Как вам быть абсолютно уверенным, что ваша любимая получит подарок (и сможет открыть посылку)?   Напишите свой ответ в комментариях.

smartcoder

smartcoder

 

Откуда можно качать модули?

Порой пользователи OpenCart (особенно начинающие) сталкиваются со всякими «мутными» ресурсами, где им предлагают скачать различные модули и шаблоны, либо купить их по привлекательной цене. К сожалению, владельцы таких ресурсов все больше наглеют и пытаются зарабатывать на своих посетителях, пользуясь их неосведомленностью. Для этого они делают свои веб-сайты похожими на легальные площадки, поэтому неопытному человеку очень легко запутаться среди всех этих ресурсов.   Предлагаю решить проблему неосведомленности пользователей о том, можно ли доверять какому-то ресурсу, с помощью создания некой базы опасных ресурсов, распространяющих вредоносное ПО. Родилась идея сделать простой проверочный сервис Copyright Check.   Данный веб-сайт предназначен для того, чтобы помочь пользователям OpenCart отличать легальные ресурсы, где выкладываются подлинные модули и шаблоны для OpenCart, от варезников, где распространяется взломанное и вредоносное программное обеспечение под видом легального.   Понять, что вы столкнулись с варезником, не так уж сложно, если знать их характерные черты: В разделах с дополнениями вы видите слова «nulled», «cracked», «без ioncube», «складчина» На веб-сайте есть т.н. «подписки», «vip-аккаунты» и прочие платные механизмы, которые открывают доступ ко всем дополнениям На странице дополнения от вас требуют совершить какое-то действие, чтобы его скачать (поставить лайк, подписаться) Загрузка дополнений ограничена для тех, кто недавно зарегистрировался, но эти ограничения снимаются за отдельную плату Все дополнения загружены одними и теми же пользователями и имеют одного автора с логином «admin» или с названием ресурса Ссылка на загрузку дополнения лежит под спойлером (хайдом), для раскрытия нужно заплатить администрации На дополнения организовываются «складчины», т.е. групповая покупка одного дополнения После скачивания дополнения вы обнаруживаете, что архив запаролен, а чтобы узнать пароль, нужно заплатить администрации У ресурса отсутствует какая-либо юридическая информация, а из контактов указан только скайп или электронка Ссылки на загрузку дополнений ведут на бесплатные файлообменники, но не на сервер самого ресурса   Конечно, это не все признаки того, что ресурс однозначно представляет опасность, поэтому если вы не уверены, с каким именно ресурсом имеете дело, воспользуйтесь этим сайтом и просто введите адрес подозрительного ресурса в поле ввода. Если нам что-либо известно об указанном ресурсе, вы сразу получите информацию.   Никаких рекламных целей я не преследую и на сайте никаких ссылок куда-либо, кроме документации PHP и специальной почты opencart.check@gmail.com, нет, но если кто-то сомневается в прозрачности моих намерений или думает, что я таким образом решил себя пиарить - сделайте и распространяйте свои аналоги, это совсем не сложно и на это потребуется 1 вечер, а польза от существования таких сайтов будет для абсолютно каждого пользователя или разработчика.   UPD: На сегодня (15 февраля 2019 года) в базу добавлено 53 ресурса и этот список продолжает расти, спасибо всем неравнодушным, кто помогает с наполнением базы!

RGB

RGB

Как составить ТЗ для программиста?

Что такое ТЗ? Техническое задание - это документ, который служит для описание того, что заказчик хочет получить в конечном виде. Техническое задание, как правило, прилагается к основному договору и включает полный перечень работ обязательного выполнения.   Зачем нужно техническое задание? Любые разработки должны сопровождаться техническим заданием. Вы скажите, это формальности для чего они нужны, достаточно сплошным текстом написать и все и так поймут. К большому разочарованию, программисты пока еще не экстрасенсы и не всегда понимают заказчика, что ему необходимо. Так же как и заказчик, составляя ТЗ узнает, что именно ему нужно. Для этого и составляются четкие задачи, сроки и методы выполнения. В дальнейшем это будет документ, с помощью которого решаются все спорные моменты.    Как составить ТЗ для программиста? Правильное формирование ТЗ экономит время для заказчика и для программиста, лучше 1 раз написать, чтобы 100 раз вас переспрашивали, как вы точно хотите видеть готовый проект. Точные данные, вместо догадок позволяют экономить время не только заказчика, но и программиста, который возможно у вас работает по-часовой оплате.    Один из важных параметров - время исполнения, если вы располагаете временем, не стоит писать, что работу нужно выполнить за 1-2 дня, от этого соответсвенно будет и сумма другая "за срочность", так как вполне возможно исполнителю нужно будет подключать дополнительных программистов для быстрого исполнения вашей задачи.   При составлении задач по пунктам, возможно распределить нагрузку между несколькими исполнителями, вполне возможно что исполнитель не занимался некоторым типом работ, и ему нужно изучить документацию, в то время как другой программист постоянно занимается именно этим пунктом и может все сделать быстрее и соответственно дешевле.   Если ваши подчиненные, так же будут пользоваться созданным приложением, постарайтесь самостоятельно объяснить особенности работы с приложением, это избавит IT специалиста от необходимости разъяснять одно и то же.   После составления ТЗ, необходимо обсудить написанное с исполнителем, все ли ему понятно, как он понял этот проект, внимательно прислушивайтесь к ответу собеседника. Не стоит забывать, что вы свою сферу знаете лучше и только вы можете объяснить, какой вам инструмент нужен для работы.   Оформление технического задания Оформление технического задания, как правило состоит из пунктов и подпунктов. Составление структуры технического задания облегчит понимание вашей задачи как и для вас (клиента), так и для программиста. Возможно при формировании пунктов у вас отпадут некоторые вопросы, которые будут включены в другие пункты или подпункты.   Техническое задание не должно быть слишком расплывчатым - ведь исполнитель может не верно его понять или не так, как требуется заказчику. В то же время техническое задание не должно быть слишком подробным, в любом проекте должно быть место творчеству. Кроме того, если вы досконально все знаете, как должен выглядеть ваш сайт, что мешает сделать это вам самому?     Что должно содержать техническое задание? цель - задача, которую мы решим, реализуя данное техническое задание описание - изложение предстоящий разработок способ реализации - если вы не владеете терминами программиста, лучше всего описывать максимально свою задачу в цели и в описании, если вы владеете же знаниями, то пишите использование внешних библиотек (jquery, bootstrap) либо использование фреймворков (Angular, Vue, Ember, Laravel, YII и другие) оценка работы - один из самых важных пунктов, если вы не оценили стоимость работы, не пишите, потому как вы отфильтруете профессионалов и вполне вероятно получите не качественную работу. Посмотрите несколько предложений исполнителей, сравните цену. Цена не должна быть очень низкая, у исполнителя должен быть рейтинг и отзывы, если вы выберете самое дешевое предложение, вполне вероятно вы и получите такой результат.     Безусловно, правильное написание технического задания не избавит вас от возможных проблем, но оно позволит отношениям с IT-отделом перейти в единую сферу сотрудничества, позволит заказчику повысить свою техническую грамотность и получить требуемое, а работников IT-отдела избавит от ряда проблем и не нужных вопросов.

smartcoder

smartcoder

Топ-10 SEO-модулей от NeoSeo – маст хэв в каждом Интернет-магазине на OpenCart

Топ-10 SEO-модулей от NeoSeo – маст хэв в каждом Интернет-магазине на OpenCart   Все мы, когда нам нужно найти необходимую информацию, заходим на сайты поисковых систем Google или Яндекс, чтобы получить от всемогущих ответ. Поисковики, конечно же, пытаются как можно лучше нам в этом помочь, представляя в результатах поиска самые релевантные (наиболее подходящие запросу), на их взгляд, страницы. Вы, как владелец Интернет-магазина на OpenCart, конечно же, не отказались бы от бесплатного, органического трафика по своей тематике. Отсюда вопрос: как сделать так, чтобы поисковая система решила, что именно страницы вашего Интернет-магазина являются наиболее подходящими для запросов покупателей, чтобы появляться в их результатах поиска?   Ответ простой – нужно как минимум провести все работы, которые относятся к базовой SEO-оптимизации, ну и конечно же работать в направлении создания полезного для покупателей контента, улучшая по дороге, показатели ссылочного веса. Всем известно (за что и ругают во многом OpenCart), что "голый OpenCart", который можно скачать и использовать для создания собственного Интернет-магазина бесплатно, созданный недостаточно хорошо с точки зрения даже базовой поисковой оптимизации. А куда ж сегодня без базового SEO, когда стоимость клика в контекстной рекламе Google Adwords или Яндекс.Директ постоянно увеличивается, а в определенных категориях уже достигает 10$ и выше, а конкуренция продолжает расти? Правильно, никуда, в этом направлении стоит работать и начинать лучше поздно, чем никогда.   Для того, чтобы вы провели элементарную, хотя бы базовую SEO-оптимизацию Интернет-магазин на OpenCart вам пригодится подборка ТОП-10 SEO-модулей от нашей веб-студии. SEO-модули для OpenCart помогут вам значительно упростить и автоматизировать процессы, чтобы не писать код с нуля. Конечно же, одних только модулей недостаточно для того, чтобы занять позиции лидера в поисковой выдаче, однако, они являются той основой, с которой необходимо начинать. Рассмотрим основные моменты базовой SEO-оптимизации и наши программные решения, которые мы сами используем для продвижения проектов наших Клиентов (эти модули стоят уже в наших сборках SEO-Магазина по-умолчанию, но не только они...) 1. SEO-структура интернет-магазина Решение: Модуль Фильтр товаров {SEO-фильтр} для OpenCart – создание фильтров и посадочных страниц.   Правильная SEO-структура сайта необходима для получения высоких позиций по средне и низкочастотным запросам. Чтобы поисковые роботы выдавали ваш Интернет-магазин по обширному, очень широкому количеству запросов вашей тематики, они должны определить и признать такие страницы вашего сайта наиболее подходящими к пользовательским запросам (наиболее релевантными). Если для каждой семантической группы товаров создавать отдельную посадочную страницу, то можно удовлетворить как поискового робота, так и потребность клиента, и тем самым обеспечить высокие продажи. Модуль SEO-фильтр даёт возможность создания любых, необходимых вам посадочных страниц. С его помощью вы можете создавать тысячи посадочных страниц, объединяя необходимые значения фильтров (по цвету, по виду, по классу, по производителю и т.д.) и значения категорий. То есть, для любого возможного сочетания фильтров и категорий будет создана наиболее релевантная посадочная страница с человеко-понятным адресом (ЧПУ URL), для которой будет возможность прописать и метатеги. Подробнее здесь. 2. Быстрая индексация сайта Решение: Модуль Карта сайта для OpenCart – автоматизированная генерация Карты сайта   Для того, чтобы про все ваши новинки роботы узнавали оперативно, нужно давать им соответствующую информацию в рекомендованном ними формате. Именно в карте сайта мы говорим роботам, какую страницу и когда нужно проиндексировать, с какой периодичностью им стоит это делать и т.д. Чтобы эту информацию не вносить руками менеджеру магазина мы создали этот модуль, который делает всё это автоматически. Для достижения большей скорости отдачи данных, разработана возможность разбивать группы товаров по 10000 ед. Модуль Карта сайта для OpenCart, самостоятельно генерирует и отдаёт поисковикам всю необходимую им информацию и вносит изменения после любых обновлений в Интернет-магазине: добавлений новых категорий, посадочных страниц, карточек товаров, статей в блоге и т.д..     3. Правильная индексация нужных страниц Решение: Модуль Генератор robots.txt для OpenCart – автоматизированная генерация файла с указанием "разрешенных" и "запрещенных" директив.   После того, как вы создали множество посадочных страниц, определили, что и когда нужно индексировать с помощью карты сайта, нужно указать, что именно индексировать нужно, а что вообще закрыть от поисковых роботов, чтобы роботы не тратили т.н. краулинговых бюджет вашего Интернет-магазина на OpenCart. Это очень важно для Интернет-магазинов с большим количеством товаров. Так, при сочетании фильтров в разной очередности, но одинаковой комбинации, могут возникнуть страницы с идентичным контентом (дубли страниц). Это, в свою очередь, негативно влияет на уникальность – важную характеристику сайта. Также от ботов нужно закрывать страницы, которые не нужны пользователю (html-файлы с информацией, страницы с архивами, скрипты и другие маловажные ресурсы). Автоматически формировать файл robots.txt можно с помощью модуля Генератор robots.txt, наполняя его необходимым ссылками в административной панели сайта. 4. SEO-URL, H1, метатеги Решение: Модуль Генератор ЧПУ и метаданных для OpenCart – предоставление URL-адресам страниц сайта человекопонятного вида и генерация метатегов по указанному шаблону с возможностью добавлять забавные EMOJI.   Человекопонятный вид URL положительно влияет на ранжирование сайта при поисковой выдаче. То есть, у сайтов с SEO-URL больше шансов попасть на высокие позиции в поисковой выдаче, когда URL адреса выглядят так, чтобы их можно было прочитать в транслитерации. Это удобно и покупателям, когда на вашу ссылку будут указывать кросс-ссылки с других сайтов или в сниппетах, пользователям будет понятно, что именно содержится на сайте после перехода по указанному адресу. SEO-оптимизированные метаданные упрощают поисковым работам процесс считывания и понимания информации с вашего сайта. Если правильно указать заголовок, Title и Description для каждой страницы (а они, в идеале, должны быть уникальными), поисковые роботы, скорее всего проиндексируют вас быстрее и качественнее (давая вам преимущество над сайтами, которіе об єтом не позаботились). Модуль Генератор ЧПУ и метаданных автоматически приводит URL к ЧПУ виду, а, задав правильные шаблоны, формирует все необходимые метаданные.   5. Оперативное обнаруживание битых, 404-х страниц Решение: Модуль Отслеживание битых ссылок для OpenCart – автоматический поиск и обнаружение несуществующих и / или 404-х страниц.   Показатель отказов сайта также довольно весомый фактор для поисковых роботов, который они берут во внимание, когда определяют качество страницы глазами пользователя. Страницы с ошибкой 404 могут возникнуть, если вы удалили или переместили страницу, если изменили URL или же, если пользователь допустил ошибку. Первые два пункта могут быть полностью под вашим контролем с помощью модуля Отслеживание битых ссылок. Такое программное решение формирует файл со списком таких страниц, и вы легко можете исправить эту ситуацию. Например, создать перенаправление на релевантную страницу, что минимизирует количество 404-х ошибок и сохраняет ссылочный вес, который также является важным фактором при определении позиций вашего Интернет-магазина на OpenCart в поисковой выдаче. Зачем терять покупателей и вес? Просто вовремя делайте редиректы! 6. Сохранение ссылочного веса и трафика со старых URL Решение: Модуль Менеджер редиректов для OpenCart – перенаправление запросов, веса и трафика на актуальные страницы.   Среди причин, когда необходимо делать редирект, можно выделить: склеивания домена с www и без www; изменения домена со старого на новый; перенос страницы: поисковики и посетители переходят на новую страницу вместо неработающей. удалили категорию, статью или товар и появилась 404-я страница Как можно заметить, редирект полезен как для пользователей, так и для поисковых роботов. Также он сочетает показатели страниц и позволяет не терять позиции в поисковой выдаче. Автоматизирует этот процесс модуль Менеджер редиректов. Он просто незаменим, если на сайте много позиций, а вручную сделать эту работу чрезвычайно трудно.   7. Только актуальная информация на сайте, но не теряем трафик из поиска для хорошо проранжированных карточек товара Решение: Модуль Архивный товар для OpenCart – присвоение неактуальному товару статуса "архивный".   С течением времени много товаров в Интернет-магазине становятся неактуальными, и не знающие менеджеры и администраторы таких Интернет-магазинов их просто берут и удаляют. В результате возникают несуществующие страницы с 404-й ошибкой, негативное влияние которых мы рассмотрели выше. Также возникает негативное последствие, когда пользователи сохранили ваш товар или ссылку, а при переходе на него получили 404-ю страницу. Для того, чтобы сохранить клиентов и не потерять ссылочный вес, можно использовать модуль Архивный товар. Он перенесет товар в категорию “архивных”, тем самым сохранит возможность для клиента перейти на сайт с поисковой выдачи или по прямой ссылке, хотя такой товар не будет отображаться при поиске на самом сайте. Если вы сохранили такого посетителя, вероятно, когда он увидит, что товара нет в наличии, он перейдет на похожий товар или выберет интересную ему категорию, т.е. останется на сайте и таким образом, вы сохраняете шансы на то, что пользователь совершит покупку, а не просто закроет страницу браузера. 8. Эффективный Интернет-маркетинг, анализ покупок по трафику Решение: Модуль Источник заказ для OpenCart – мониторинг источников переходов клиента перед покупкой.   Для того, чтобы вести эффективную рекламную кампанию и понимать, какой доход вы получаете от рекламы по разным источникам (в т.ч., чтобы увеличивать бюджет для эффективных), нужно четко понимать, какие инструменты продвижения дают результат. Клиенты, конечно же, могут приходить из разных источников. Это может быть: органическая выдача; контекстная реклама; социальные сети; маркетплейсы и прайсагрегаторы; ссылки с других ресурсов. Для того, чтобы определить, какой способ наиболее эффективен для вас, нужно установить модуль Источник заказа, и проследить, откуда к вам пришел клиент. В будущем вы сможете усиливать присутствие и продвижение в тех источниках, которые приносят наибольший доход. 9. Аналитика от Google Решение: Модуль Google Analytics для OpenCart – сбор статистики для построения стратегии продвижения сайта.   Google Analytics является более совершенным инструментом для определения поведения пользователей и анализа расходования рекламных бюджетов, чем предыдущий модуль. С помощью этого сервиса можно формировать множество отчетов, что очень эффективно для анализа и определения способов продвижения сайта. Модуль Google Analytics упрощает подключение скрипта и настройку электронной коммерции в вашем Интернет-магазине. То есть, вам нужно будет скопировать и вставить в соответствующее поле только (ID) Google аналитики. Сам скрипт будет создан автоматически. Среди преимуществ программного решения можно выделить: большую гибкость и удобство в использовании сведений аналитики; автоматическое формирование тегов ремаркетинга и настройка рекламной кампании без дополнительных усилий; возможность настроить электронную коммерцию и получать данные по каждой трансакции, в т.ч. и по каждому источнику трафика. 10. Продвижение в поисковой сети Yandex Решение: Модуль Подключение Yandex Metrika для OpenCart – сбор статистики для построения стратегии продвижения сайта.   Как и Google Analytics, Yandex Metrika – это система, которая собирает данные о посещаемости вашего сайта и формирует их в удобном для восприятия виде. Модуль Yandex Metrika обеспечивает похожую функциональность, что и модуль Google Analytics, но здесь можно ещё и посмотреть за поведением покупателя на сайте с помощью веб-визора. Настройка и установка не занимает много времени, но даёт много пищи для размышлений, в т.ч. вы сможете понять, насколько вашим покупателям удобно пользоваться вашим Интернет-магазином.           РЕЗЮМЕ. Если вас не устраивают показатели посещения вашего Интернет-магазина из органической поисковой выдачи – рано или поздно вам придётся заняться поисковой оптимизацией. Наша подборка, это маст хэв для проведения базового SEO, с чего и рекомендуем начать процесс оптимизации вашего сайта. С ее помощью вы можете как комплексно осуществить оптимизацию, так и постепенно по пунктам, шаг за шагом улучшать сайт в глазах поисковиков.
  Желаем вам хороших результатов, Команда NeoSeo
   

neoseo

neoseo

 

Простое подключение элементов формы

Пишете модули с большими формами настроек и заколебались копипастить их элементы? Для себя нашел простое и правильное (на мой взгляд) решение, которое не требует говнокодить шаблонами в php.   Шаблон необходимого элемента. Например, это типичный флаг конфига (1/0). admin/view/template/extension/module/my_module_pro_control_bool.tpl <?php if ($true) { ?> <label class="btn btn-default active"> <input type="radio" name="<?php echo $name; ?>" value="1" checked="checked" /> <?php echo $text_true; ?> </label> <label class="btn btn-default"> <input type="radio" name="<?php echo $name; ?>" value="0" /> <?php echo $text_false; ?> </label> <?php } else { ?> <label class="btn btn-default"> <input type="radio" name="<?php echo $name; ?>" value="1" /> <?php echo $text_true; ?> </label> <label class="btn btn-default active"> <input type="radio" name="<?php echo $name; ?>" value="0" checked="checked" /> <?php echo $text_false; ?> </label> <?php } ?> Рендерить и выводить этот шаблон мы будем с помощью PHP замыканий. Данный код можно поместить в контроллер модуля или другое место с вашими helper методами. admin/controller/extension/module/my_module_pro.php public function getBoolControl($template, $language_path) { $language = $this->load->language($language_path); return function($name, $status, $text_mode = 'e/d') use($template, $language) { $data = array(); if ($text_mode == 'e/d') { $data['text_true'] = $language['text_enabled']; $data['text_false'] = $language['text_disabled']; } else if ($text_mode == 'y/n') { $data['text_true'] = $language['text_yes']; $data['text_false'] = $language['text_no']; } $data['name'] = $name; $data['true'] = $status; if (version_compare(VERSION, '2.2', '<') == true) { $template .= '.tpl'; } echo $this->load->view($template, $data); }; } Присваиваем результат метода getBoolControl (то есть анонимную функцию) переменной контроллера для вывода в шаблон $data['control_bool'] = $this->getBoolControl('extension/module/my_module_pro_control_bool', 'extension/module/my_module_pro'); Осталось использовать это в шаблоне формы admin/view/template/extension/module/my_module_pro.tpl <div class="form-group"> <label class="col-sm-3 control-label"><?php echo $entry_status; ?></label> <div class="col-sm-9"> <div class="btn-group" data-toggle="buttons"> <?php $control_bool('status', $status, 'e/d'); ?> </div> </div> </div><!-- /.form-group --> Вот и все.  При желании можно расширить метод, сделать его универсальным либо разбить на части с разными элементами формы.   Вот так можно выводить элементы переключателей: <div class="btn-group" data-toggle="buttons"> <?php $control_radio('some_radio_group', $some_radio_group, [ [ 'btn' => 'default', 'icon' => 'fa-sort-alpha-asc', 'value' => 'alpha', 'text' => $text_alpha ], [ 'btn' => 'primary', 'icon' => 'fa-sort-amount-desc', 'value' => 'amount', 'text' => $text_amount ], [ 'btn' => 'danger', 'icon' => 'fa-sort-numeric-asc', 'value' => 'numeric', 'text' => $text_numeric ], ]); ?> </div>  

SooR

SooR

 

JS Tricks

#1 Управляем классами элемента по hover'у $('body').on('mouseenter mouseleave', '[data-hover-class]', function(e) { var $this = $(this), $target = $this, rules = $this.attr('data-hover-class').split(' '), over = (e.type == 'mouseenter'); if ($this.attr('data-target')) { $target = $this.find($this.attr('data-target')); } rules.map(function(rule) { if (rule.charAt(0) == '+') { $target.toggleClass(rule.substring(1), over); } else if (rule.charAt(0) == '-') { $target.toggleClass(rule.substring(1), !over); } else if (/\>/.test(rule)) { $target.toggleClass(rule.slice(0, rule.indexOf('>')), !over); $target.toggleClass(rule.slice(rule.indexOf('>') + 1), over); } }); }); Атрибуты data-hover-class="foo>bar -baz +qwe" При наведении foo сменится на bar, удалится baz и добавится qwe При потере курсора (mouseleave) правила инвертируются: bar меняется на foo, добавляется baz и удаляется qwe data-target="[any-child-selector]" Можно указать над каким дочерним элементом производить смену классов. Атрибут необязательный.   Использование <button type="button" class="btn btn-sm btn-link text-muted" data-hover-class="fa-heart>fa-times-circle -text-warning" data-target=">i" data-toggle="tooltip" data-placement="top" title="Удалить из закладок"> <i class="fas fa-fw fa-heart text-warning text-danger"></i> <span class="d-none d-sm-inline">В закладках</span> </button> При наведении на <button> у его вложенного <i> класс fa-heart сменится на fa-times-circle и удалится класс text-warning

SooR

SooR

 

Opencart - Android - JSON - получаем список товаров в приложении

Всем привет!   Сегодня мы разберем получение товаров из категории Opencart в Android-приложение через JSON. Для начала не будем использовать сторонние библиотеки, а сделаем все нативным образом, чтобы ознакомиться с базовыми принципами обмена данными. Итак, поехали   Сперва нужно определить выдачу массива товаров в JSON-объект из магазина.
Открываем catalog/controller/product/category.php
И в цикле выдачи данных для товаров добавляем свои запросы. Перед $data['products'][] = array( Добавляем // изображение для списка, размер 100х100 if ($result['image']) { $json_image = $this->model_tool_image->resize($result['image'], 100, 100); } else { $json_image = $this->model_tool_image->resize('placeholder.png', 100, 100); } // создаем массив данных для каждого товара // получаем имя, путь изображения, описание и цену $data['json-products'][] = array( 'name' => $result['name'], 'thumb' => $json_image, 'description' => utf8_substr(trim(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8'))), 0, $this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '..', 'price' => $price, ); Дальше ищем response $this->response->setOutput($this->load->view('product/category', $data)); И заменяем на // формируем массив products $data['json_products'] = array( 'products' => $data['json-products'], ); // и отдаем его в json при запросе в адресной строке &json_products // для этого поставим условие запроса if (isset( $this->request->get['json_products'])) { $this->response->setOutput(json_encode($data['json_products'])); } else { $this->response->setOutput($this->load->view('product/category', $data)); } Таким образом, теперь при запросе к сайту по адресу мой-сайт/index.php?route=product/category&path=20&json_products мы будем получать массив данных вида: {"products":[ {"name":"Apple Cinema30'", "thumb":"http:\/\/store.url\/image\/cache\/catalog\/demo\/apple_cinema_30-100x100.jpg", "description":"The 30-inch Apple Cinema HD Display delivers an amazing 2560 x 1600 pixel resolution. Designed speci..", "price":"$100.00"}, {"name":"Canon EOS 5D", "thumb":"http:\/\/store.url\/image\/cache\/catalog\/demo\/canon_eos_5d_1-100x100.jpg", "description":"Canon's press material for the EOS 5D states that it 'defines (a) new D-SLR category', while we're n..", "price":"$100.00"}, . . . , . . . , ]}   С серверной частью закончили, переходим к программной части приложения.   Что мы будем делать? Получим JSON данные из url Разберем эти данные и актуализируем с listView(textView) Скачаем картинки, кешируем их в приложении и актуализируем по позициям в listView(imageView)   Для начала не забудьте дать приложению разрешение на использование сети (в манифесте): <uses-permission android:name="android.permission.INTERNET"/> Также в папку res/drawable мы поместим заглушку для изображений(до того, как они спарсятся)
blank.png (100x100px)   Теперь разметка.
Для простоты будем работать с activity_main и стандартным listView
activity_main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/lv_products" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:context=".MainActivity" /> </RelativeLayout> Здесь все просто - в релятивную разметку мы поместили listView c id=lv_products
Теперь создадим кастомную разметку для этого listView
lv_layout.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/tv_product" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginTop="5dp" android:textColor="#195F74" android:textSize="20sp" android:textStyle="bold" /> <ImageView android:id="@+id/iv_thumb" android:layout_width="100dp" android:layout_height="100dp" android:layout_below="@id/tv_product" android:layout_centerVertical="true" android:contentDescription="@string/str_iv_thumb" android:padding="5dp" android:scaleType="fitXY" /> <TextView android:id="@+id/tv_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_product" android:layout_toRightOf="@id/iv_thumb" android:textSize="16sp" /> <TextView android:id="@+id/tv_price" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/tv_description" android:layout_marginBottom="10dp" android:gravity="right" android:layout_marginRight="5dp" android:textColor="#cc3333" android:textSize="20sp" android:textStyle="bold"/> </RelativeLayout>   С разметкой закончили — приступаем к коду

Создаем файл ProductsJSONParser.java (это и будет класс парсера) package com.opencart.ocproducstlist; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.res.Resources; /** класс парсера JSON данных */ public class ProductsJSONParser { // Получаем JSONObject и возвращаем List public List<HashMap<String, Object>> parse(JSONObject jObject) { JSONArray jProducts = null; try { // Здесь элементы из массива 'products', который мы получаем из контроллера jProducts = jObject.getJSONArray("products"); } catch (JSONException e) { e.printStackTrace(); } // применяем getProducts к массиву объекта JSON // теперь каждый объект - это товар return getProducts(jProducts); } private List<HashMap<String, Object>> getProducts(JSONArray jProducts) { int productCount = jProducts.length(); List<HashMap<String, Object>> productList = new ArrayList<HashMap<String, Object>>(); HashMap<String, Object> product = null; // разбираем товары по одному и добавляем к объекту List for (int i = 0; i < productCount; i++) { try { // вызываем getProduct и парсим, добавляем product = getProduct((JSONObject) jProducts.get(i)); productList.add(product); } catch (JSONException e) { e.printStackTrace(); } } return productList; } // Разбираем JSON-объект product private HashMap<String, Object> getProduct(JSONObject jProduct) { HashMap<String, Object> product = new HashMap<String, Object>(); String name = ""; String thumb = ""; String description = ""; String price = ""; try { // обратите внимание на метод .replaceAll // без него разные "непечатные" символы будут отображаться неправильно name = jProduct.getString("name").replaceAll(""", "\""); thumb = jProduct.getString("thumb"); description = jProduct.getString("description").replaceAll(""", "\"").replaceAll("’", "\'"); price = jProduct.getString("price"); product.put("product", name); // здесь сперва ставим заглушку product.put("thumb", R.drawable.blank); product.put("thumb_path", thumb); product.put("description", description); product.put("price", price); } catch (JSONException e) { e.printStackTrace(); } return product; } }
Ну а теперь MainActivity package com.opencart.ocproducstlist; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.List; import org.json.JSONObject; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { ListView mListView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // URL с нашими JSON-данными String strUrl = "http://мойсайт.com/index.php?route=product/category&path=20&json_products"; // определяем задачу по загрузке // и запускаем ее с нашим url DownloadTask downloadTask = new DownloadTask(); downloadTask.execute(strUrl); // ссылаемся на ListView в activity_main mListView = (ListView) findViewById(R.id.lv_products); } /** метод загрузки данных из url */ private String downloadUrl(String strUrl) throws IOException { String data = ""; InputStream iStream = null; try { URL url = new URL(strUrl); // Создаем http соединение, соединяемся и считываем данные HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); urlConnection.connect(); iStream = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader( iStream)); StringBuffer sb = new StringBuffer(); String line = ""; while ((line = br.readLine()) != null) { sb.append(line); } data = sb.toString(); br.close(); } catch (Exception e) { Log.d("Exception while downloading url", e.toString()); } finally { iStream.close(); } return data; } /** Асинхронно скачиваем json */ private class DownloadTask extends AsyncTask<String, Integer, String> { String data = null; @Override protected String doInBackground(String... url) { try { data = downloadUrl(url[0]); } catch (Exception e) { Log.d("Background Task", e.toString()); } return data; } @Override protected void onPostExecute(String result) { // закончили в non-ui ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask(); // начинаем парсить listViewLoaderTask.execute(result); } } /** Асинхронно парсим данные и кидаем в listView */ private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter> { JSONObject jObject; // парсим в non-ui @Override protected SimpleAdapter doInBackground(String... strJson) { try { jObject = new JSONObject(strJson[0]); ProductsJSONParser productsJsonParser = new ProductsJSONParser(); productsJsonParser.parse(jObject); } catch (Exception e) { Log.d("JSON Exception1", e.toString()); } // Инстанцируем класс парсера ProductsJSONParser productsJsonParser = new ProductsJSONParser(); // Список для сохранения List<HashMap<String, Object>> products = null; try { // Получаем спарсеные данные в List (наш список) products = productsJsonParser.parse(jObject); } catch (Exception e) { Log.d("Exception", e.toString()); } // Ключи, которые используем в hashMap String[] from = { "product", "thumb", "description", "price" }; // и айдишники, используемые в listView int[] to = { R.id.tv_product, R.id.iv_thumb, R.id.tv_description, R.id.tv_price }; // задаем адаптер // и закидываем ключи в айдишники SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), products, R.layout.lv_layout, from, to); return adapter; } /** doInBackground выполнен - займемся картинками */ @Override protected void onPostExecute(SimpleAdapter adapter) { // Задаем адаптер для listview mListView.setAdapter(adapter); for (int i = 0; i < adapter.getCount(); i++) { HashMap<String, Object> hm = (HashMap<String, Object>) adapter .getItem(i); String imgUrl = (String) hm.get("thumb_path"); ImageLoaderTask imageLoaderTask = new ImageLoaderTask(); HashMap<String, Object> hmDownload = new HashMap<String, Object>(); hm.put("thumb_path", imgUrl); hm.put("position", i); // запускаем ImageLoaderTask для скачивания // и актуализации картинок в listview imageLoaderTask.execute(hm); } } } /** Асинхронно качаем картинки и помещаем в listView */ private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>> { @Override protected HashMap<String, Object> doInBackground( HashMap<String, Object>... hm) { InputStream iStream = null; String imgUrl = (String) hm[0].get("thumb_path"); int position = (Integer) hm[0].get("position"); URL url; try { url = new URL(imgUrl); // создаем соединение и подключаемся HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); urlConnection.connect(); // считываем данные iStream = urlConnection.getInputStream(); // директория кеширования File cacheDirectory = getBaseContext().getCacheDir(); // временно сохраняем картинку в кеш-дир File tmpFile = new File(cacheDirectory.getPath() + "/ocpl_" + position + ".png"); // поток в кеш-файл FileOutputStream fOutStream = new FileOutputStream(tmpFile); // из потока в картинку Bitmap b = BitmapFactory.decodeStream(iStream); // пишем файл в темп (png) b.compress(Bitmap.CompressFormat.PNG, 100, fOutStream); // сбрасываем и закрываем поток fOutStream.flush(); fOutStream.close(); // создаем hashMap для передачи картинки // в listview, в соответствии с позицией HashMap<String, Object> hmBitmap = new HashMap<String, Object>(); // сохраняем путь к картинке // и позицию картинки в listview hmBitmap.put("thumb", tmpFile.getPath()); hmBitmap.put("position", position); // возвращаем объект с картинкой и позицией return hmBitmap; } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(HashMap<String, Object> result) { // теперь получаем путь и позицию String path = (String) result.get("thumb"); int position = (Integer) result.get("position"); // задаем адаптер SimpleAdapter adapter = (SimpleAdapter) mListView.getAdapter(); // забираем объекты из hashMap // с соответствующей позицией в listview HashMap<String, Object> hm = (HashMap<String, Object>) adapter .getItem(position); // заменяем текущий путь (сейчас "заглушка" - res/drawable/blank.png) hm.put("thumb", path); // и сообщаем listView об изенении содержимого adapter.notifyDataSetChanged(); } } } Запускаем приложение и любуемся результатом:   До новых встреч  

ocdroid

ocdroid

Выигрыш в Лотерее, реально ли?

Испытываем теорию вероятности на деле.   В последнее время живу в Италии и тут популярны очень лотереи. Не сказать, что все люди помешаны на лотерее, возможно это я просто азартный. Вообще проводятся разные лотереи 3 раза в неделю. Была в начале января самая  главная лотерея - "Лотерея Италия", которая проводится раз в год. Я указал цифры в случайном порядке, к сожалению на новый год не удалось выиграть приз.   Я задумался с математической точки зрения, какие могут выпасть цифры. С точки зрения теории вероятности. Лотерея 7 цифр из 90. Если вы угадаете 7 цифр, вы выиграете около 90 млн евро.   Существует архив лотереи, где вы можете посмотреть все выигрыши по ссылке: https://www.superenalotto.net/ru/rezultaty/2018 Так есть архив по каждому году, 3 раза в неделю, значит 12 раз в месяц и 244 раза в год.  То есть 39 000 чисел, которые когда-либо выпадали.    Переходим к цифрам     1. Рассмотрим самые популярные цифры Сделаем массив с данными, в который мы впишем все числа, которые выпадали за 2 года (если вы хотите, можете сделать это за 20 лет, но я сделал за 2 года).   $array = array (1,19,26,44,61,89,5,19,28,43,58,82,15,18,24,33,48,64,8,69,70,84,88,90,3,25,28,37,71,82,2,10,41,49,56,71,9,29,51,53,74,76,29,43,46,50,85,86,27,48,50,74,76,84,2,5,24,32,47,62,15,38,48,52,66,71,5,24,68,72,78,85,22,39,47,49,77,89,20,45,51,63,85,89,1,8,19,28,34,87,4,8,16,35,36,74,24,25,30,43,47,90,7,31,35,57,88,89,3,11,38,53,70,71,5,17,34,40,78,82,5,17,37,40,55,79,17,25,52,55,67,75,9,40,45,70,76,81,10,44,48,62,68,83,48,56,66,83,86,89,9,23,57,72,77,82,2,19,62,74,81,83,12,36,45,46,67,75,22,50,52,65,66,89,11,15,42,64,82,84,19,33,42,65,78,85,2,13,17,31,45,69,7,35,52,85,88,90,9,20,33,43,44,48,20,23,29,37,39,72,2,24,42,62,66,81,10,16,35,63,73,83,11,15,32,35,52,56,1,6,7,9,45,79,30,45,47,49,71,90,7,27,55,63,73,77,3,20,47,55,81,83,27,35,46,68,72,82,8,28,34,38,47,54,1,10,31,44,58,80,12,23,39,54,72,73,5,17,20,44,62,80,11,43,68,72,79,85,31,41,44,67,75,82,44,52,64,66,67,71,2,25,41,42,74,87,6,10,26,47,60,75,9,19,31,39,77,82,6,14,19,59,79,81,17,18,41,57,58,75,41,62,77,79,81,84,29,49,50,56,64,78,3,10,38,52,65,71,16,33,34,74,79,80,40,51,55,56,74,81,12,13,19,37,62,72,1,27,31,58,83,87,20,27,32,55,69,90,19,28,42,49,68,83,9,57,64,66,69,86,45,56,66,74,77,88,6,10,11,21,71,75,33,39,47,64,67,76,13,32,41,51,61,86,1,12,31,33,44,50,5,37,51,65,79,81,2,9,15,22,47,65,1,7,25,40,68,75,6,11,37,42,58,62,4,17,29,55,67,70,2,6,37,39,51,86,28,36,55,76,81,89,9,13,23,32,45,54,28,33,38,41,66,72,11,19,27,41,61,83,3,51,55,64,77,79,27,41,50,60,63,81,3,13,18,24,74,89,2,9,14,19,27,77,30,35,44,60,72,76,11,38,47,71,76,77,22,36,38,56,59,67,7,29,37,43,72,79,21,34,53,72,80,84,10,19,47,67,68,75,23,32,49,53,61,85,5,6,41,44,65,74,23,39,53,56,64,84,11,18,21,23,55,66,31,32,46,54,73,90,14,57,73,79,82,84,21,43,45,57,67,83,2,10,12,21,22,50,7,14,27,66,70,81,2,16,30,39,51,79,14,23,32,34,40,80,42,44,54,68,69,81,1,26,39,43,73,89,16,28,29,55,63,69,1,4,19,23,55,68,18,25,47,51,70,83,2,23,34,52,76,87,7,25,32,39,59,86,59,61,63,65,71,84,16,23,29,49,57,76,3,26,34,61,84,87,2,24,31,42,47,55,15,18,56,67,72,74,12,16,29,45,82,85,17,24,57,64,70,89,21,37,46,56,65,77,34,54,77,80,81,87,3,7,18,47,64,82,15,30,72,79,86,90,27,28,33,75,77,78,10,36,49,53,77,85,20,23,39,50,62,68,14,36,39,46,55,59,8,13,25,50,65,72,16,23,50,73,80,88,4,14,27,38,89,90,6,30,49,56,64,81,10,21,24,26,29,89,3,12,35,51,59,80,38,40,43,59,67,72,23,35,40,79,86,87,8,36,39,40,48,50,4,16,24,42,51,84,11,15,20,27,45,59,9,15,20,46,50,84,7,15,22,31,46,50,6,12,34,36,40,66,3,5,38,53,54,82,3,9,43,48,61,83,15,24,28,34,56,73,30,38,63,68,77,80,6,12,15,30,31,89,6,22,27,36,62,76,7,16,33,54,80,84,6,31,37,47,71,78,10,30,44,45,47,49,7,37,52,73,87,88,6,17,32,38,47,90,7,9,12,21,30,41,5,23,36,42,47,79,39,61,68,69,70,86,11,49,58,71,76,89,4,14,16,51,64,88,12,19,36,42,77,87,36,43,44,49,78,82,24,37,46,49,62,71,9,12,27,32,45,77,1,7,21,27,39,78,2,8,62,79,81,88,1,9,22,25,58,84,14,16,30,34,52,73,12,17,24,45,67,84,16,44,49,57,60,81,32,51,74,79,80,81,6,55,63,68,76,80,63,67,74,77,83,85,43,48,49,51,60,75,9,13,15,51,73,74,14,15,16,43,49,77,11,27,56,57,64,66,13,18,34,51,62,81,2,21,38,74,79,83,18,25,35,38,45,75,6,9,11,32,63,83,9,14,19,35,48,65,13,17,26,33,60,78,7,13,24,36,37,86,4,22,36,60,66,90,9,11,21,37,86,90,11,17,40,69,84,85,19,22,44,45,71,76,34,37,52,58,65,89,2,11,26,51,64,87,8,19,28,33,71,89,4,17,39,40,50,58,3,6,46,48,63,76,16,21,53,74,79,80,16,21,31,62,69,85,14,41,60,74,79,80,32,35,58,63,76,79,25,39,48,74,86,89,3,50,60,64,85,86,3,6,20,54,72,90,5,16,40,70,74,76,8,46,68,70,76,86,3,16,29,34,37,57,15,16,21,24,53,89,4,6,27,76,80,86,5,57,59,69,81,86,16,24,56,69,85,87,6,20,35,36,55,59,18,29,52,74,76,88,3,14,52,67,72,82,1,4,9,10,36,79,8,17,28,35,74,82,8,27,54,62,82,83,8,14,25,41,79,84,28,43,59,60,78,80,15,20,33,39,65,75,57,60,73,77,82,86,3,25,63,70,75,78,19,37,45,51,82,83,4,15,21,22,44,77,29,38,75,79,80,90,1,19,47,61,70,87,6,37,46,53,73,78,10,18,23,34,61,75,10,33,40,42,46,77,16,34,57,64,65,78,21,26,35,59,66,70,7,15,27,37,56,58,2,22,36,77,83,90,7,12,26,46,56,70,11,28,32,48,54,59,19,54,56,57,67,69,41,50,69,71,77,81,6,24,28,32,78,83,45,48,71,75,80,83,38,46,54,76,82,86,9,18,24,42,59,71,2,18,20,23,30,75,9,14,62,64,78,82,16,19,38,40,58,79,15,20,45,59,81,85,21,37,58,75,81,85,36,37,46,48,51,74,6,8,32,54,80,82,6,12,38,42,49,83,2,11,26,62,74,78,27,37,44,47,73,86,17,34,42,47,75,85,22,32,45,60,61,80,6,22,26,33,51,88,4,29,30,47,52,59,5,15,52,60,77,84,5,11,58,75,78,81,1,8,28,54,82,90,20,25,39,49,69,71,14,19,50,69,75,90,17,24,33,41,63,66,3,5,24,41,48,80,6,17,32,40,44,67,34,44,46,47,64,88,22,28,46,52,69,86,18,29,34,47,48,60,34,46,50,52,67,86,40,45,54,72,85,88,28,29,36,54,55,68,21,23,54,73,84,88,5,29,32,33,72,89,2,49,57,60,71,77,7,12,66,68,73,76,11,29,64,68,70,85,29,39,49,56,83,85,7,10,25,26,37,68,18,25,29,30,33,69,22,35,36,55,63,86,38,45,46,55,65,73,13,16,27,48,67,77,8,46,48,69,72,81,13,18,19,46,58,60,6,15,39,68,80,89,7,12,21,22,39,90,6,21,38,48,79,90,14,33,48,61,65,80,14,17,35,37,55,83,4,26,52,65,66,72,9,16,19,35,41,59,2,13,50,75,85,90,10,17,30,55,62,78,16,17,58,66,71,72,21,22,31,32,33,81,6,45,47,61,74,80,14,38,43,57,65,72,7,11,17,28,32,79,19,24,35,69,80,89,11,31,46,48,65,68,6,7,8,38,45,78,2,6,34,69,77,86,8,12,41,42,46,51,16,31,33,51,75,80,1,11,40,45,46,57,2,12,16,26,51,73,3,16,24,27,44,88,32,40,41,47,56,72,14,38,40,51,53,64,16,20,22,42,54,62,27,28,48,61,87,88,5,17,19,33,43,63,4,12,25,27,35,69,10,34,45,63,81,83,14,15,65,68,82,85,21,24,48,51,60,82,2,30,44,52,58,69,25,33,39,59,72,74,3,7,53,65,66,73,24,55,71,73,85,90,22,39,43,65,77,89,12,25,50,59,67,88,35,39,48,71,88,89,10,28,33,43,50,80,6,17,23,46,52,53); $totals = array_count_values($array); arsort( $totals ); echo "<pre>"; print_r($totals) Запустим просчет и выведем на экран самые часто-выпадаемые числа.   Array ( [6] => 31 [16] => 29 [77] => 28 [80] => 27 [45] => 26 [81] => 26 [46] => 26 [79] => 26 [47] => 26 [19] => 26   Поясняем, что у нас получилось. Самое популярное число за 2года, оказалась цифра 6, она выпадала 31 раз в лотереях за 2 года. На втором месте число 16 - оно выпадало 29 раз На третьем число [77] => 28 раз и так далее..   То есть есть большая вероятность того, что выпадают именно эти числа.   2. Сделаем такой же просчет, только по вертикальной линейке. В данном варианте, будем рассматривать только первое число, которое выпадает на лохотроне. На первой картинке начинается массив [1,5] и т.д. Добавим код к существующему массиву. $totals_strings = array_chunk($array, 6); $first_vals = ''; foreach ($totals_strings as $key => $value) { $first_vals .= $value[0].','; } $first_row = explode(",", $first_vals); $totals_first_row = array_count_values($first_row); arsort( $totals_first_row ); echo "<pre>"; print_r($totals_first_row); В результате мы получаем следующее Array ( [2] => 24 [6] => 24 [3] => 20 [7] => 17 [1] => 15 [9] => 15 [5] => 14 [11] => 13 [16] => 13 [14] => 12 [4] => 12 [10] => 11 [8] => 11 [21] => 8 Цифра 2 и цифра 6 выпадали 24 раза, цифра 3 выпадала 20 раз.   Так проделываем по всем столбцам и получаем ряд чисел. 2 17 46 51 77 89 6 12 52 42 67 90 3 16 32 74 81 83 7 25 47 47 80 86 1 15 39 68 72 80   Данные числа можно менять по вертикали и составлять из данного вашу комбинацию.   Напоследок немного о лотереях. К сожалению точного математической последовательности вы не выявите. Лохотроны как правило постоянно меняют, шары, которые выпадают - имеют разный вес, потому как на на шарах выбиты числа, имеющие разную площадь. Однако вы можете проставлять часто выпадающие числа, либо числа, которые давно не выпадали, и возможно, вам повезет!   Играйте в лото, но не будьте зависимы! Буду рад комментариям и другим примерам просчета.

smartcoder

smartcoder

 

BS #1

За месяц использования Bootstrap 4 накопилось немного фиксов и решений. Публикую как минимум для себя, в текстовиках уже надоело хранить.   1. Упрощенная реализация валидации форм на JQ $('body').on('submit', 'form.needs-validation', function(e) { if (this.checkValidity() === false) { e.preventDefault(); e.stopPropagation(); } $(this).addClass('was-validated'); }); 2. Инициализация Popover с возможностью указания контейнера границ и контента $('[data-toggle="popover"]').each(function(i) { var $element = $(this), options = $element.data(); if ($element.attr('data-content-element')) { options.html = true; options.content = function() { return $($(this).attr('data-content-element')).html(); }; } if ($element.attr('data-boundary-element')) { options.boundary = $($(this).attr('data-boundary-element')).get(0); } $element.popover(options); }); <a href="#" class="text-dark" data-toggle="popover" data-content-element="#popover-cart" data-boundary-element="#content">Корзина</a> <div id="#popover-cart"> ... </div> 3. Скрытие popover блока при клике вне его зоны с триггером click $('body').on('click', function(e) { $('[data-toggle="popover"], [aria-describedby^="popover"]').each(function() { if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) { $(this).popover('hide'); } }); }); 4. Делаем кнопку × в контенте popover'a для его скрытия $('body').on('click', '[data-dismiss="popover"]', function(e) { $('[aria-describedby="' + $(this).closest('.popover').attr('id') + '"]').popover('hide'); }); <button type="button" class="close text-dark" data-dismiss="popover"><i class="fas fa-times"></i></button> 5. Плавное изменение высоты (контента) при переключении слайдов карусели $('.carousel').on('slide.bs.carousel', function(e) { var nextH = $(e.relatedTarget).height(); $(this).find('.carousel-item.active').parent().animate({ height: nextH }, 250); }); 6. Делаем возможным выход контента за границы активного слайда карусели  По умолчанию контент слайда имеет правило overflow: hidden и, например, если вы решите сделать увеличение элемента при hover с выходом за границы, то он обрежется. Чтобы это предотвратить оставим правило overflow: hidden только при смене слайдов. $(document).on({ // start 'slide.bs.carousel': function() { $(this).find('.carousel-inner').removeClass('o-visible'); }, // end 'slid.bs.carousel': function() { $(this).find('.carousel-inner').addClass('o-visible'); } }, '.carousel'); .o-visible { overflow: visible!important; } <div id="carousel-product-items" class="carousel slide" data-ride="carousel" data-interval="false" data-wrap="false"> <div class="carousel-inner o-visible" role="listbox"> ... </div> </div> 7. Возвращаем $.button из BS 3 в BS 4 Не понимаю кому мешал этот скромный, но полезный плагин Вызов будет доступен в таком виде  $('button[type="submit"]').btnState('loading');  

SooR

SooR

 

Redirect с POST данными

Всем привет. Это буде короткая запись но очень полезная.
Тема данной публикации: Как сделать redirect в PHP и отправить POST данные.    Кто сталкивался тот знает в чем проблема. Давайте посмотрим основные варианты которые предлагают на форумах.
  1) Создать форму и отправить ее. Суть заключается в том что бы на лету сгенерировать html форму и отправить ее. 
Пример кода function redirect_post($url, array $data) { ?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script type="text/javascript"> function closethisasap() { document.forms["redirectpost"].submit(); } </script> </head> <body onload="closethisasap();"> <form name="redirectpost" method="post" action="<? echo $url; ?>"> <?php if ( !is_null($data) ) { foreach ($data as $k => $v) { echo '<input type="hidden" name="' . $k . '" value="' . $v . '"> '; } } ?> </form> </body> </html> <?php exit; } Как на меня довольно страшно выглядит тай костыль костылем.   2) Сохранить данные в Session Думаю пример кода делать не нужно и там понятно как работает.  
Тут я скажу что это один из самых адекватных способов, хотя влечет за собою несколько лишних действий. (Проверка, удаление и так далее).   Другое. 
Примеров еще много начиная от Curl проксированния заканчивая fopen. Думаю дальнейшие приведение примеров лишние.

А теперь Самое адекватное и правильное решение. Заключается оно в том что бы использовать 307 код редиректа. 307 - редирект это временое перенаправление - так сказано в первых 4 силках в Google по запросу 307 Redirect. А теперь главный нюанс "Если указать данный код то с редиректом будут отпрвленны данные из переменой $_POST"   Реализация PHP <?php $_POST['firstName'] = 'Maykl'; $_POST['lastName'] = 'Yatsyshyn'; header("Location: <URL>", true, 307); ?> Использование в Opencart и сборках <?php // $this->request->post = &$_POST; $this->request->post['firstName'] = 'Maykl'; $this->request->post['lastName'] = 'YATSYSHYN'; $this->response->redirect($URL, 307); ?> Замечание вместе с данными которые вы записали (firstName, lastName) будут отправлены все данные которые уже били в $_POST это может пригодится когда вам нужно перенаправить данные с формы на другой обработчик или же назад на форму.

konorws

konorws

 

Как сделать нагруженный скрипт, не отъедая память у клиентов и не покупая сервер как в Пентагоне.

Господа, все мы сталкиваемся с ситуацией, когда необходимо сформировать большой набор данных, сайтмап, yandex-market фид, и любая подобная задача, требует всегда очень много ресурсов. 
Большинство авторов таких дополнений слыхом не слыхивали ни про CLI-PHP, ни про возможность органично выделять ресурсы исключительно под собственные скрипты, не затрагивая общие настройки сервера. Про то, как делать CLI скрипты, я расскажу позднее, а сейчас поговорим про лимиты памяти, и почему нельзя пахабно относиться к ресурсам серверов клиентов.   Приведу пример, который произошел буквально на днях. Обратились ко мне старые друзья с просьбой посмотреть, почему падает магазин. Да они добавили 30 региональных поддоменов, увеличилась нагрузка, но это не повод, чтобы 4гб памяти и 4гб SWAP забивались за 10 минут.
Смотрим в настройки php_memory_limit 1gb. Система работает в связке nginx+php-fmp, и менеджер fpm резирвирует под каждый поток гиг памяти. Но нам то надо максимум 256МБ, для генерации любой страницы. Ок меняем настройки, немножко вносим тюнинг в конфиг php-fpm, все заработало, ресурсов хватает запас есть. Но из-за нехватки памяти отвалилась генерация YML, от одного известного автора.  И Яндекс-маркет блочит магазин. Новый год, продажи стоят.
Что делать?   Писать автору, скорее всего бесполезно. Я думаю, что любой автор сказал - увеличивайте ресурсы сервера, у вас нехватка памяти, вы сами виноваты, у вас большой магазин. 
Я даже уверен, что 99% авторов дополнений  так бы сделали.   Но послушайте. Ну есть же возможность задавать настройки "на лету" прямо из выполняемого скрипта. И просто достаточно было добавить в код генерации яндекс-фида одну строку:   ini_set("memory_limit",-1);   И все.. Для всех скриптов, которые приходят на web-сервер у нас 256мб лимит, и наших 4 гигабайт хватает с головой обслужить весь входящий трафик и ботов. 
И без вопросов у нас генерится YML, которому мы разрешили использовать память безлимитно.   Простейшая же задача как 2+2. Но продав более 1000 копий своего дополнения, автор даже не задумывался о подобных проблемах. 
Не будьте как автор!   И еще. Не стесняйтесь вместо формирования каких то супермассивов, сразу писать все в файл. Вместо какого нить  $thisoutYML->addItem($item), ведь очень просто делать $thisYmlSaveItemTofile($item).
  Ну и практически все фиды можно отдавать в .gz экономя место и время.

Yoda

Yoda

 

Полезное для разработчика.

Полезное:      1) Рефакторинг и Паттерны проектирования       Безопасность:      1) Проверка подлинности модуля или шаблона.       Самоорганизация:      1) Доска задач       Шпаргалки:      1) jquery карта функций.      2) Могу ли я использовать.        Сервисы:      1) Конструктор и библиотека регулярок.      2) Оффлайн шпаргалка по регуляркам.       Оптимизация:      1) Сжатие изображений.       Разное:      1) https://github.com/      2) https://bitbucket.org/       Тоже полезно:      1) https://www.chess.com/ru   В планах расширить, исправить, доработать!

Sha

Sha

Улучшаем GooglePageSpeed | ImageCompressor своими руками за пять минут и общие советы по приведению изображений в порядок.

Как говорит народная мудрость - не все то золото, что блестит. В нашем деле, я бы сказал, не каждый шаблон продающий, который продающий. Но мы не про шаблоны, а про оптимизацию изображений.   Как вы все уже знаете, Гугл обновил алгоритм оценки скорости работы сайтов и начал учитывать  массу новых факторов, и повысил требование к старым.
Одним из наиболее важных критериев оценки является размер, количество и вес изображений.
Одним из способов облегчить этот процесс является технология LazyLoad - это просто и утилитарно, благо есть прекрасная библиотека на гитхабе для этой реализации, а если вам нужен lazyload в каруселях, то owl-карусель умеет это с пеленок.   Также, необходимо обратить внимание, что картинки должны соответствовать физическому размеру на экране, поэтому как раньше отдать баннер шириной 1920 точек на экран мобильника с физическим размером в 480 точек не получится. Точнее отобразить то вы можете, но Гуглу это не нравится, и правильным вариантом будет использование либо библиотеки mobile_detect, которая будет определять тип устройства и в зависимости от типа вы уже сможете включить в верстку мобильной версии уменьшенное изображение, либо использование Responsive Image разметки и атрибута srcset и опять же изначальной подготовки нескольких превью под разные типы экрана.      Lazy - это хорошо, но что делать с физическим размером изображений, ведь увеличение сжатия картинок в стандартной библиотеке opencart  существенно снижает качество изображений. Выхода два. Либо покупать какой нибудь ОООЧЕНЬ ПОЛЕЗНЫЙ МОДУЛЬ, от которого будет больше вреда чем пользы, так как все подобные модули работают "на лету", тем самым тратят ценнейшие ресурсы для генерации страницы. Либо же все сделать своими руками за 10 минут, при условии, что у вас на хостинге установлены библиотеки jpegoptim и optipng.
Если таковые не установлены, поинтересуйтесь, может ли хостер вам их установить, а если у вас свой VPS, то самостоятельно они устанавливаются из консоли в два счета.   Установка для Debian/Ubuntu 
  sudo apt-get install jpegoptim sudo apt-get install optipng   Для RH/Centos
  yum install jpegoptim yum install optipng
После этого необходимо запустить консольные команды, которые сожмут все существующие изображение  в кеше. Путь к папке с изображениями вы можете увидеть в config.php файле. find {полный путь к вашей папке с изображениями}cache/ -type f  -iname "*.jpg" -exec jpegoptim --strip-all --max=80 -P --all-progressive {} \; find {полный путь к вашей папке с изображениями}cache/ -type f -iname "*.png" -exec optipng -o7  -preserve -strip all {} \;
И после этого уже добавить в cron команды для выполнения в ночное время с периодичностью раз в день и разницей во времени в пару часов. find {полный путь к вашей папке с изображениями}cache/ -type f -mtime -1 -iname "*.jpg" -exec jpegoptim --strip-all --max=80 -P --all-progressive {} \; find {полный путь к вашей папке с изображениями}cache/ -type f -mtime -1 -iname "*.png" -exec optipng -o7  -preserve -strip all {} \; В итоге мы получим абсолютно бесплатно качественную оптимизацию изображений, которую будет выполнять не скрипт php, а сервер, которая никак не будет влиять на время генерации страниц и создавать излишнюю нагрузку на систему в рабочее пиковое время.\   И да, если вы не понимаете что здесь написано и как это сделать - отправьте ссылку на этот пост администратору вашего хостинга-сервера, для людей с минимальной квалификацией здесь более чем избыточная инструкция.   Также, если возвращаться к требованиям гугла, не забываем, что теперь увеличено время жизни кеша для картинок и статического контета и рекомендуется его сделать не минимальным в неделю а либо год либо вообщем max.   И напоследок развеем еще один миф про Webp стандарт изображений. В нескольких ветках с пеной у рта, определенные люди рассказывают что это круто и вот тут будет поддержка. Webp - это может быть и круто, но использование его в магазине на сегодня - это не очень. И тому есть очень важная причина. Кроме хрома, нормально, этот стандарт не поддерживают другие бразуеры! До момента нормальной нативной поддержки может пройти еще очень много времени. Структура модулей и кеширования модулей магазина такова, что зачастую невозможно даже определяя поддержку браузера этого типа изображений отдать корректно контент без риска показать покупателю пустые страницы без изображений. Оптимизации изображений вышеприведенными в статье методами на 100% достаточно, для того чтобы выполнить требования гугла. Рисковать внедрением экспериментальных технологий, пусть и шибко разрекламированных - это так же как пытаться лечить смертельные болезни экспериментальынми средствами, может помочь, а может и убить.   На этом на сегодня все, и да пребудут с вами зеленые попугаи!   Небольшой апдейт. Тут пошли вопросы в личку типа: "и что, у нас будет все хорошо после этого"? Нет - сразу не будет - приведение в порядок изображений - это лишь  малая часть, манипуляций, которые необходимо внедрить для получения высокой оценки PageSpeed на мобайл-устройствах.

Yoda

Yoda

 

SEO | Скорость и ранжирования в 2018

Интересная статейка, особенно тех кто думает что СЕО это магия, а оптимизация только для одаренных ...
Скорость загрузки мобильных страниц будет влиять на их рейтинг в поиске
Обновление о скорости загрузки мобильных страниц вступает в силу для всех пользователей.   Google уже учитывает этот критерий при ранжировании веб-страниц, но только предназначенных для обычных компьютеров. С июля 2018 г. позиция мобильного сайта в результатах поиска также будет зависеть от того, с какой скоростью он загружается. Мы ожидаем, что это нововведение повлияет на результаты по незначительному количеству запросов и затронет только самые медленные сайты. Наш новый критерий будет одинаково применяться к любым веб-страницам независимо от того, на какой технологии они основаны. Поскольку для Google очень важен смысл поискового запроса, медленные страницы по-прежнему будут занимать высокие позиции, если содержат интересный и релевантный контент. Мы настоятельно рекомендуем разработчикам уже сейчас задуматься над тем, как скорость загрузки и многие другие факторы влияют на удобство сайта. У нас нет инструмента, который позволит однозначно сказать, изменится ли позиция ваших веб-страниц в результатах поиска, но вам могут помочь перечисленные ниже ресурсы.     Отчет об удобстве пользования браузером Chrome – это общедоступный свод данных о показателях посещаемых сайтов, определяющих удобство их использования в браузере Chrome.     Lighthouse  представляет собой автоматизированное решение, которое входит в состав Инструментов разработчика Chrome. Оно помогает оценивать качество веб-страниц по различным критериям, таким как скорость загрузки и удобство для людей с ограниченными возможностями.     PageSpeed Insights – это инструмент, который позволяет узнать, какие результаты продемонстрирует страница в отчете об удобстве пользования браузером Chrome, и предлагает варианты оптимизации.   Оригинал https://webmaster-ru.googleblog.com/2018/04/skorost-zagruzki-vlijaet-na-reiting-v-poiske.html 

ArtemPitov

ArtemPitov

 

Мой опыт использования модулей в интернет-магазине

Хочу поделится свои опытом реализации интернет-магазина на движке ocStore со стандартным шаблоном и рассказать какие модули я использовал чтобы улучшить взаимодействие покупателей с сайтом.   После установки самого движка и первоначальной настройки: валют, локации, описания магазина и так далее, я установил модуль “SEO CMS TOP 2: Блог | Новости | Отзывы | Галерея | Формы”. Это модуль я настроил на отображение новостей сайта и отзывов к товарам, кстати, при написании отзывов к товару если пользователь совершил покупку,  то будет соответствующая отметка об этом, что очень хорошо сказывается на реакции людей читающих этот отзыв. Также я сделал дополнительные страницы сайта для отображения фото и видео отзывов которые присылают покупатели. Следующий модуль который решает вопрос быстрого поиска нужного товара по характеристикам это Фильтр товаров Go Filter 3.0 - 2.0 SEO keywords для Opencart/Ocstore 3.x, 2.x. Модуль прост в настройке и удобно отображается в мобильной версии, это для меня очень важно, т.к. у меня посетителей с мобильных устройств больше 40%. После мне пришлось искать модуль быстрого просмотра товара, чтобы покупатели не заходили в каждый товар, а прямо из категории могли в пару кликов внести товар в корзину. Выбор пал на модуль “Быстрый просмотр товара PRO oc 15x / 2.x” это единственный модуль который удовлетворил меня по функционалу, но сразу скажу что он не идеален и там есть над чем поработать в плане взаимодействия с ним при наборе большого количества товара в корзину. Для быстрого поиска товара на сайте я выбрал простой модуль “Search suggestion - поиск с автодополнением PRO”, он закрывает вопрос быстрого поиска по артикулу товара у моих клиентов. Для решения вопросов со скидками я выбрал модуль “Разные цены для групп покупателей”, он крайне простой в настройке. Создал несколько групп покупателей с разной скидкой и подключил модуль накопительной скидки с автоматическим переносом покупателя в группу - Customer Group Auto Switcher. Получилось что когда клиент регистрируется на сайте то попадает в группу “обычных покупателей”, и после того как совершает покупки на сайте модуль Customer Group Auto Switcher отслеживает общую сумму совершенных заказов и при наборе определенной суммы переносит клиента в группу с определенной постоянной скидкой и уже тогда модуль Разные цены для групп покупателей задает все цены на сайте со скидкой. На разных этапах взаимодействия покупателей с сайтом я использую автоматические электронные письма клиентам, для этого я установил модуль “Шаблоны писем, v3.0.1”. С помощью этого модуля я настроил шаблоны писем для разных ситуаций, так например при переходе из одной группы клиентов в другую, клиент получает поздравительное письмо о том что у него увеличилась скидка, или при достижении определенного статуса заказа приходит письмо с просьбой оставить отзыв о товаре и интернет-магазине в целом и в этом письме есть ссылки на соцсети и сайты “отзовики”. Для автоматической смены статуса заказа я использую модуль “Автоматический перевод заказов в другой статус по тайм-лимиту, v1.2” этот модуль “закрывает” заказ и переводит его статус через несколько недель в “завершенный” и клиент получает письмо с просьбой написать отзыв о чем я писал выше. Также для усиления “эффекта скидки” я с помощью всё того же SEO CMS TOP 2: Блог | Новости | Отзывы | Галерея | Формы создал в личном кабинете и на сайте информационные сообщения в которых написана текущая скидка и статус клиента, эти сообщения разграничены к показам по группам и меняются от того как клиент переход из одной группы в другую. Это всё создаёт дополнительные связи магазина с клиентом. Что касается наполнения сайта товарам и автоматизации продаж то здесь я использую модуль 1с для сайта от “meteor-it”. Модуль работает с 1с Управление Торговлей 11. В 1с у меня занесен весь товар по категориям и выгружается на сайт уже с описанием и остатками. Также в 1с выгружаются заказы с сайта. И получается что у меня менеджеры вообще не заходят в админку сайта и ведут всё в 1с, что облегчает мне жизнь. У меня бывают товары в которых есть не только опции “размер” но и “цвет”, для того чтобы в 1с товар выгружался корректно пришлось установить модуль “Связанные / зависимые опции Opencart 2.x 1.4.3/2.4.6”. Также я использую модуль для выгрузки клиентов в службу рассылки SendPulse, чтобы потом через него совершать массовые рекламные рассылки, чтобы сервер на котором хостится сайт не попал в спам базы. Вот такой набор модулей и их связок я использую для своих магазинов, так же хочу сказать что на разных этапах развития сайтов я привлекаю программистов для того чтобы доработать какой либо функционал стандартного шаблона и модулей. Буду рад ответить на интересующие вопросы.

piklas

piklas

Модули для автоматизации интернет-магазина

Для полной автоматизации нужно преобрести всего 4 модуля, которые избавят вас от рутины добавления и обновления товаров поставщиков, и вы сможете наконец-то заняться своими делами.   1. Автоматическая обработка прайс-листов (АОП) Возможности модуля: 1. Обновление/добавление товара из прайс-листов (название, описание, цены, опции, атрибуты и др) 2. Добавление/обновление товара парсингом с сайтов (название, описание, цены, опции, атрибуты и др.) 3. Отслеживание цен конкурентов (назначение своей цены, исходя от цены конкурента) 4. SEO заполнение уникального описания товара 5. Большое количество инструментов, необходимых при работе с товарами. Описание: Модуль Автоматическая обработка прайс-листов - очень сложный, но очень точный инструмент, по работе с товарами. На первый взгляд, совсем ничего не понятно, но стоит немного разобраться, и вы уже можете сами добавлять неограниченное количество товара. Купить модуль: Автоматическая обработка прайс-листов   2. CronSuppler - автоматический запуск по крон планировщику   Возможности дополнения: 1. Запуск файла из папки admin/upload/ 2. Парсинг сайтов по расписанию 3. Обновление остатков товаров по расписанию 4. Обновление цен товаров по расписанию 5. Отправка отчета о загрузке на почту с файлами Reports и Errors   Описание: Модуль CronSuppler необходим для запуска формы поставщика по расписанию на хостинге (в планировщике крон) в модуле Автоматическая обработка прайс листов (АОП). Вы можете настроить автоматическое добавление товаров по расписанию, для этого достаточно вам указать в модуле АОП необходимые параметры. Так же модуль крайне необходим для обновления количества и цен поставщика. Нередко бывает, когда вы только загрузили прайс лист, буквально вчера, а его остатки уже не актуальны. Для этого есть модуль CronSuppler. После выполнения работ, вам отправит система отчет на почту, где вы можете посмотреть какое количество товаров обновилось.   Купить модуль: CronSuppler         3. SupplerMailLink - загрузка прайсов по ссылке либо с почты   Возможности дополнения: 1. Загрузка файла по ссылке в папку admin/upload/ 2. Загрузка файла по почте (через подключение к IMAP) в папку admin/upload/ 3. Планирование загрузки в любое время (раз в минуту, раз в час, или когда захотите) 4. Поддержка форматов XLS, XLSx, csv, xml, YML 5. Конвертация в нужный формат для модуля поставщики в XML или CSV   Описание: SupplerMailLink - это модуль, который поможет вам загружать актуальные прайс-листы поставщиков к вам на сервер. К вам каждый день приходят различные прайс-листы от многих поставщиков, и чтобы их обработать нужно достаточно времени. Так же наличие товара, может сразу закончиться у поставщика, пока вы обработаете его прайс и загрузите себе на сайт. SupplerMailLink - уникальное решение, которое поможет вам избавиться от рутиной работы обработки прайс-листов.    Купить модуль: SupplerMailLink           4. SupplerMaster - быстрые функции для модуля АОП   Возможности дополнения: 1. Быстрое удаление всех опций поставщика 2. Быстрое обнуление остатков всех поставщиков 3. Просмотр информации о прайслисте на сервере 4. Скачивание прайс-листа из папки admin/uploads 5. Просмотр Отчетов Report.tmp прямо из админки. 6. Просмотр Ошибок Errors.tmp прямо из админки. 7. Удаление файла sos.tmp прямо из админки.   Описание: SupplerMaster - дополнение, которые позволяет осуществлять быстрые функции над модулем Автоматическая обработка прайс листов. Для того, чтобы не подключаться по FTP, чтобы посмотреть отчеты об ошибках или о проделанной работе - модуль прекрасно поможет вам все это посмотреть в админ панеле. Так же есть набор функций, который постоянно расширяется и дополняется. Например - быстрое удаление опций поставщика, или быстрое обнуление остатков поставщика, что явно поможет вам быстрее сделать все необходимые процедуры. SupplerMaster - это решение, которое так же поможет вам сэкономить не мало времени.   Купить модуль: SupplerMaster     Как быстро установить модули? Для того, чтобы быстро начать работу - воспользуйтесь услугой установки модулей.   Как быстро наполнить интернет магазин товарами? Для того, чтобы быстро наполнить интернет-магазин товарами - воспользуйтесь услугой профессионалов. Список людей, которые наполняют интернет-магазины, вы можете к ним платно обратиться: @Rubynoid | @Rassol2

smartcoder

smartcoder

Передача переменных с php/tpl в js

Простой вариант реализация гетера   Для начала упаковываем все нужные данные в переменную   $data['data'] = .... Дальше берем div и делаем следующее  <div id="var" class="hidden" data-var="<?= base64_encode(json_encode($data)); ?>"></div> Потом пишем "проксю" на jquery let data = JSON.parse(window.atob($("#var").data('var'))); let proxy = new Proxy({}, { get(target, name) { return typeof data[name] !== undefined ? data[name] : false; } }); Используем, к примеру у нас в наборе есть токен proxy.token  

ArtemPitov

ArtemPitov

Lazy Load на ванильном JavaScript

JS class APLazy { constructor (lazyClass) { if (typeof lazyClass === 'undefined') { this.lazyClass = 'APLazy'; } else { this.lazyClass = lazyClass; } this.lazyArray = []; } setLazy() { this.lazyArray = document.getElementsByClassName(this.lazyClass); } cleanLazy() { this.lazyArray = Array.prototype.filter.call(this.lazyArray, (l) => l.getAttribute('data-src')); } lazyLoad() { for (let element of this.lazyArray) { if (this.isInViewport(element)) { if (element.getAttribute('data-src')) { element.src = element.getAttribute('data-src'); element.removeAttribute('data-src'); } } } this.cleanLazy(); } isInViewport(element) { var rect = element.getBoundingClientRect(); return ( rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth) ); } registerListener(event, func) { if (window.addEventListener) { window.addEventListener(event, func); } else { window.attachEvent('on' + event, func); } } }   Используем JS if (typeof window.APLazy == 'undefined') { window.APLazy = new APLlazy('my-lazy-class'); window.APLazy.setLazy(); window.APLazy.lazyLoad(); window.APLazy.registerListener('scroll', function () { window.APLazy.lazyLoad(); }); window.APLazy.registerListener('resize', function () { window.APLazy.lazyLoad(); }); } else if (typeof window.APLazy == 'object' ) { window.APLazy.setLazy(); window.APLazy.lazyLoad(); }   Используем HTML  <img src="loader.gif" data-src="image.jpg" class="APLazy" />  

ArtemPitov

ArtemPitov

Подсказка внутри Input на jQuery

Простая реализация подсказки внутри input-a   Demo Название   HTML <div class="inputer"> <label>Название</label> <input type="text" name=""> </div> CSS .inputer { border: 1px solid #ddd; position: relative; display: block; width: 100%; max-width: 350px; border-radius: 4px; overflow: hidden; } .inputer label { position: absolute; top: 40%; left: 5px; opacity: 0; transition: all .1s linear; visibility: hidden; font-size: 12px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .inputer label, .inputer input::placeholder { color: #777; font-weight: bold; opacity: .8; } .inputer.active label { opacity: 1; top: 2px; visibility: visible; font-size: 11px; opacity: .8; } .inputer.active input { padding: 16px 5px 2px !important; } .inputer input, .inputer input:hover, .inputer input:focus, .inputer input:active { box-shadow: none; outline: none; border:none; border-radius: 0; display: block; width: 100%; padding: 9px 5px; font-size: 12px; } JS let inputerFn = (el) => { let $el = $(el); $el.parent().toggleClass('active', $el.val().length > 0); }; $('.inputer input').each(function (idx, el) { let $el = $(el); $el.attr('placeholder', $el.siblings('label').text()); inputerFn(el); }).on('input', function () { inputerFn(this); });   .inputer { border: 1px solid #ddd; position: relative; display: block; width: 100%; max-width: 350px; border-radius: 4px; overflow: hidden; } .inputer label { position: absolute; top: 40%; left: 5px; opacity: 0; transition: all .1s linear; visibility: hidden; font-size: 12px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .inputer label, .inputer input::placeholder { color: #777; font-weight: bold; opacity: .8; } .inputer.active label { opacity: 1; top: 2px; visibility: visible; font-size: 11px; opacity: .8; } .inputer.active input { padding: 16px 5px 2px !important; } .inputer input, .inputer input:hover, .inputer input:focus, .inputer input:active { box-shadow: none; outline: none; border:none; border-radius: 0; display: block; width: 100%; padding: 9px 5px; font-size: 12px; }

ArtemPitov

ArtemPitov

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

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

×

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.