.
3 февраля 2014

Делаем отзывы для Joomla — jcomments

Обращаются за помощью люди с сайтам на самых разнообразных CMS.
Сегодня вот понадобился инструмент Отзывы на сайте с движком Joomla.

Решение — использование модуля jcomments.
Качаем с оф.сайта последнюю stable версию, создаём меню, материал, вешаем его на менюшку (всё как обычно).
И материал подключаем jcomments — вставкой тега {jcomments on}.

Вуаля — отзывы готовы.
Правда в моём случае ещё пришлось немного поковыряться с css дабы в дизайн сайта подошло.

рубрики: CMS, Joomla | Комментарии (3)

12 сентября 2013

Парсинг XML формата CommerceML средствами PHP

Очередная задача — синхронизация цен на сайте по файлу-выгрузке из 1С 8.2.
В движке решил не копаться — найти цены в БД и напрямую их корректировать — ИМХО так будет проще, чем искать какие то сторонние спец.модули.
Вроде всё ясно — берём файл, парсим, апдейтим.
Как всегда не обошлось без НО.
Файл-выгрузка оказался в формате «CommerceML» в формате xml version="1.0" encoding="UTF-16" с кириллицей везде — даже в наименованиях секций.
В общем первые попытки парсинга с помощью simplexml и DomDocument не увенчались успехом, а вот XMLReader, как раз рассчитанный на обработку файлов больших объёмов (что нам и нужно — прайсы, как правило имеют особенность безгранично расти).

Пока не забыл — порекомендую отличнейшую статейку, найденную в процессе реализации задачи — XML для PHP-разработчиков: Часть 2. Расширенные методы парсинга XML — различные методы работы с XML, всё с примерами и описанием.

Далее: ... так как порядок в файле всегда идёт АРТИКУЛ и далее ЦЕНА, то особенно заморачиваться с обработкой вложений я не стал ... в итоге получился такой код:

open("price.xml");

$art="";
$cost=0;
$arr = array();

while ($reader->read()) {
	switch ($reader->nodeType) {
		case (XMLREADER::ELEMENT):
			if ($reader->localName == "Артикул") {
				$reader->read();
				$art = $reader->value;
				if ($art!=""&&$cost!=0)	$arr[$art]=$cost;
			}
			if ($reader->localName == "ЦенаЗаЕдиницу") {
				$reader->read();
				$cost = $reader->value;
				if ($art!=""&&$cost!=0)	$arr[$art]=$cost;
			}
   		}
}

// посмотрим что получилось
foreach($arr as $name=>$val) {
	echo $name." = ".$val."
"; // сюда добавлю код по обновлению цен в БД } ?>

рубрики: CMS, Полезности, Программирование | Комментарии (0)

5 сентября 2013

Битрикс. Учет скачиваний файла пользователями

Итак, почти реализовал небольшое ТЗ — возможно кому-то пригодятся мои наработки...

Допустим, на сайте под управлением CMS Bitrix, необходимо определённому списку пользователей дать возможность скачивать определенный файл и фиксировать количество скачиваний.
Создаём группу для юзеров, которым можно скачивать (у меня получился ID=9)
На пользователей, вешаем пользовательское поле UF_CNT — куда будем складировать количество скачиваний файла.

Собственно — привожу содержимое скрипта, непосредственно «отдающего» нужный файл:

 $USER->GetID());
 $arParams["SELECT"] = array("UF_CNT");
 $arRes = CUser::GetList($by = 'ID', $order = 'ASC', $arFilter,$arParams);
 if($res = $arRes->Fetch()) {
    $plex_cnt = $res["UF_CNT"]+1;
 }

// обновляем
 $user = new CUser;
 $user->Update($USER->GetID(), array("UF_CNT" => $plex_cnt) );

// отдаём файл
 $filename = 'file-info.zip';
 header("Pragma: public");
 header("Expires: 0");
 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
 header("Cache-Control: private", false); // нужен для некоторых браузеров
 header("Content-Type: application/force-download");
 header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
 header("Content-Transfer-Encoding: binary");
 header("Content-Length: ".filesize($filename));
 readfile("$filename");
 exit();
}

header('Location: ............'); 

Ну и ссылочку на данный скрипт отдаём только «правильным» пользователям. Проверка та-же if ( CSite::InGroup ( array ($gID))) { ... }

Да, ещё момент — прямое скачивание файла file-info.zip нужно запретить в конфе nginx-а, т.к. именно он отвечает за отдачу статики location = /paht/file-info.zip { deny all }
(далеко не сразу этот момент вспомнил когда не мог понять — почему не работает запрет на скачивание именно этого файла установленный мной в .htaccess при правильной обработке в нём других правил)

рубрики: Bitrix, CMS | Комментарии (1)

18 июня 2013

Правильный перенос работающего сайта на WebAsyst на новый сервер

Итак, задача:
Имеется работающий интернет магазин, всё крутиться на одном серваке — необходимо без потерь заказов перетащить всё на другой сервер.

Схема следующая:
1. Перетаскиваем файло и БД на новый сервер
2. На старом сервере настраиваем работу на MYSQL на новый (по IP)
3. Переключаем DNS на новый

За основу (куда тащим) у меня в распоряжении оказалась виртуальная машина VM Битрикс.
Соответственно, сначала заводим юзера с правами зацепляться отовсюду,в настройках /etc/my.cnf убираем привязку bind_adress и разрешаем в фаерволе входящие по порту 3306 (либо руками, либо можно webmin поставить). Всё это после окончательного переноса нужно будет возвратить для большей секъюрности в прежние значения.
Далее проверяем возможность зацепиться к базе со старого сервака простым скриптиком через mysql_connect
Ура — всё ок!

Далее чего пишу-то: меняю настройки в системе — а нифига! не цепляется
Помогли на официальном форуме.

настройки хоста в \kernel\wbs.xml , замените везде localhost

Ну и кэш всё таки в инсталлере почистить не помешает!

Ещё момент — на сайте откуда перетаскивали mysql был регистронезависим по отношению к названию таблиц, а на хостинге куда — регистрозависим.
Соответственно, пришлось переименовывать таблицы

RENAME TABLE accessrights_link TO ACCESSRIGHTS_LINK;
RENAME TABLE appsettings TO APPSETTINGS;
RENAME TABLE cfolder TO CFOLDER;
RENAME TABLE clist TO CLIST;
RENAME TABLE clist_contact TO CLIST_CONTACT;
RENAME TABLE company TO COMPANY;
RENAME TABLE contact TO CONTACT;
RENAME TABLE contactfield TO CONTACTFIELD;
RENAME TABLE contactnote TO CONTACTNOTE;
RENAME TABLE contacttype TO CONTACTTYPE;
RENAME TABLE currency TO CURRENCY;
RENAME TABLE customer TO CUSTOMER;
RENAME TABLE disk_usage TO DISK_USAGE;
RENAME TABLE email_contact TO EMAIL_CONTACT;
RENAME TABLE issue TO ISSUE;
RENAME TABLE issuefilter TO ISSUEFILTER;
RENAME TABLE issuetransitionlog TO ISSUETRANSITIONLOG;
RENAME TABLE issuetransitionschema TO ISSUETRANSITIONSCHEMA;
RENAME TABLE issuetransitiontemplate TO ISSUETRANSITIONTEMPLATE;
RENAME TABLE issuetransitiontemplateschema TO ISSUETRANSITIONTEMPLATESCHEMA;
RENAME TABLE mmaccess TO MMACCESS;
RENAME TABLE mmaccount TO MMACCOUNT;
RENAME TABLE mmcache TO MMCACHE;
RENAME TABLE mmfolder TO MMFOLDER;
RENAME TABLE mmgroupaccess TO MMGROUPACCESS;
RENAME TABLE mmmessage TO MMMESSAGE;
RENAME TABLE mmmsentto TO MMMSENTTO;
RENAME TABLE mmsender TO MMSENDER;
RENAME TABLE mmsent TO MMSENT;
RENAME TABLE paccess TO PACCESS;
RENAME TABLE pgroupaccess TO PGROUPACCESS;
RENAME TABLE project TO PROJECT;
RENAME TABLE projectwork TO PROJECTWORK;
RENAME TABLE sc_aff_commissions TO SC_aff_commissions;
RENAME TABLE sc_aff_payments TO SC_aff_payments;
RENAME TABLE sc_aux_pages TO SC_aux_pages;
RENAME TABLE sc_brends TO SC_brends;
RENAME TABLE sc_categories TO SC_categories;
RENAME TABLE sc_category_product TO SC_category_product;
RENAME TABLE sc_category_product_options__variants TO SC_category_product_options__variants;
RENAME TABLE sc_category__product_options TO SC_category__product_options;
RENAME TABLE sc_config_settings TO SC_config_settings;
RENAME TABLE sc_countries TO SC_countries;
RENAME TABLE sc_currency_types TO SC_currency_types;
RENAME TABLE sc_custgroups TO SC_custgroups;
RENAME TABLE sc_customers TO SC_customers;
RENAME TABLE sc_customer_addresses TO SC_customer_addresses;
RENAME TABLE sc_customer_reg_fields TO SC_customer_reg_fields;
RENAME TABLE sc_customer_reg_fields_values TO SC_customer_reg_fields_values;
RENAME TABLE sc_customer_reg_fields_values_quickreg TO SC_customer_reg_fields_values_quickreg;
RENAME TABLE sc_discount_coupons TO SC_discount_coupons;
RENAME TABLE sc_discussions TO SC_discussions;
RENAME TABLE sc_divisions TO SC_divisions;
RENAME TABLE sc_division_access TO SC_division_access;
RENAME TABLE sc_division_custom_settings TO SC_division_custom_settings;
RENAME TABLE sc_division_interface TO SC_division_interface;
RENAME TABLE sc_htmlcodes TO SC_htmlcodes;
RENAME TABLE sc_interface_interfaces TO SC_interface_interfaces;
RENAME TABLE sc_language TO SC_language;
RENAME TABLE sc_linkexchange_categories TO SC_linkexchange_categories;
RENAME TABLE sc_linkexchange_links TO SC_linkexchange_links;
RENAME TABLE sc_local TO SC_local;
RENAME TABLE sc_localgroup TO SC_localgroup;
RENAME TABLE sc_modules TO SC_modules;
RENAME TABLE sc_module_configs TO SC_module_configs;
RENAME TABLE sc_news_table TO SC_news_table;
RENAME TABLE sc_ordered_carts TO SC_ordered_carts;
RENAME TABLE sc_orders TO SC_orders;
RENAME TABLE sc_orders_discount_coupons TO SC_orders_discount_coupons;
RENAME TABLE sc_order_price_discount TO SC_order_price_discount;
RENAME TABLE sc_order_status TO SC_order_status;
RENAME TABLE sc_order_status_changelog TO SC_order_status_changelog;
RENAME TABLE sc_payment_types TO SC_payment_types;
RENAME TABLE sc_payment_types__shipping_methods TO SC_payment_types__shipping_methods;
RENAME TABLE sc_products TO SC_products;
RENAME TABLE sc_products_opt_val_variants TO SC_products_opt_val_variants;
RENAME TABLE sc_product_list TO SC_product_list;
RENAME TABLE sc_product_list_item TO SC_product_list_item;
RENAME TABLE sc_product_options TO SC_product_options;
RENAME TABLE sc_product_options_set TO SC_product_options_set;
RENAME TABLE sc_product_options_values TO SC_product_options_values;
RENAME TABLE sc_product_pictures TO SC_product_pictures;
RENAME TABLE sc_related_items TO SC_related_items;
RENAME TABLE sc_rpost_zones TO SC_rpost_zones;
RENAME TABLE sc_settings TO SC_settings;
RENAME TABLE sc_settings_groups TO SC_settings_groups;
RENAME TABLE sc_shipping_methods TO SC_shipping_methods;
RENAME TABLE sc_shopping_carts TO SC_shopping_carts;
RENAME TABLE sc_shopping_cart_items TO SC_shopping_cart_items;
RENAME TABLE sc_shopping_cart_items_content TO SC_shopping_cart_items_content;
RENAME TABLE sc_spmodules TO SC_spmodules;
RENAME TABLE sc_spmodules_settings TO SC_spmodules_settings;
RENAME TABLE sc_subscribers TO SC_subscribers;
RENAME TABLE sc_system TO SC_system;
RENAME TABLE sc_tagged_objects TO SC_tagged_objects;
RENAME TABLE sc_tags TO SC_tags;
RENAME TABLE sc_tax_classes TO SC_tax_classes;
RENAME TABLE sc_tax_rates TO SC_tax_rates;
RENAME TABLE sc_tax_rates__zones TO SC_tax_rates__zones;
RENAME TABLE sc_tax_zip TO SC_tax_zip;
RENAME TABLE sc_zones TO SC_zones;
RENAME TABLE sc__courier_rates TO SC__courier_rates;
RENAME TABLE sc__courier_rates2 TO SC__courier_rates2;
RENAME TABLE sc__intershipper_carriers TO SC__intershipper_carriers;
RENAME TABLE sc__module_payment_invoice_jur TO SC__module_payment_invoice_jur;
RENAME TABLE sc__module_payment_invoice_phys TO SC__module_payment_invoice_phys;
RENAME TABLE sc__module_shipping_bycountries_byzones_rates TO SC__module_shipping_bycountries_byzones_rates;
RENAME TABLE sc__module_shipping_bycountries_byzones_rates_percent TO SC__module_shipping_bycountries_byzones_rates_percent;
RENAME TABLE sms_balance TO SMS_BALANCE;
RENAME TABLE sms_credit_history TO SMS_CREDIT_HISTORY;
RENAME TABLE sms_history TO SMS_HISTORY;
RENAME TABLE ugroup TO UGROUP;
RENAME TABLE ugroup_user TO UGROUP_USER;
RENAME TABLE ug_accessrights TO UG_ACCESSRIGHTS;
RENAME TABLE unsubscriber TO UNSUBSCRIBER;
RENAME TABLE user_disk_quota TO USER_DISK_QUOTA;
RENAME TABLE user_settings TO USER_SETTINGS;
RENAME TABLE u_accessrights TO U_ACCESSRIGHTS;
RENAME TABLE wbs_user TO WBS_USER;
RENAME TABLE wg_param TO WG_PARAM;
RENAME TABLE wg_widget TO WG_WIDGET;
RENAME TABLE workassignment TO WORKASSIGNMENT;

рубрики: CMS, Администрирование, Полезности | Комментарии (2)

10 июня 2013

NGINX ограничиваем доступ к папке

Собственно, нужно правильно средствами NGINXа ограничить доступ к админке сайта.
В данном случае это Joomla и папочка /administrator/ которую последнее время сильно стали тревожить подозрительные запросы ...
Пишу «правильно» т.к. года два назад написал конфиг преследуя эту же цель и «вроде бы» всё работало как надо!
На днях всплыло, что не как надо :)
Итак:

location /administrator/ {
	auth_basic "Hello, please login";
        auth_basic_user_file /site_userpass_path/.htpasswd;
}

Оказалось вообще не верным, т.к. работало только на /administrator/
И пропускало все атаки, переборы и т.д. на /administrator/index.php — которые уходили в секцию обработки скриптов

location ~ \.php$ {

«Правильное» решение, сразу же найденное в сети — использование префикса ^~
то есть

location ^~ /administrator/ { ...

НО! в таком случае правило работает на все файлы находящиеся в /administrator/
и до location обрабатывающего статику а-ля

location ~* ^.+\.(jpg|jpeg|gif|png|ico)$ {

дело не доходит! а т.к. у меня fast-cgi то статика осталась вообще не удел
всё происходит из-за приоритетов обработки location
Правильно обработки папки /administrator/ имеет более высокий приоритет, и после его обработки дальнейшие location не обрабатываются

Подумал я и ничего лучше, чем обработку /administrator/ запихать в регулярку (для выравнивания приоритетов) не придумал
Финальный результат (закоментированные строки убирать специально не стал, т.к. имея статический IP — это самая лучшая защита админки)

location ~* ^/administrator/.+\.php {
#	    allow X.X.X.X;
#	    deny all;

            auth_basic "Hello, please login";
            auth_basic_user_file /site_userpass_path/.htpasswd;	    	    	    	    
	    fastcgi_pass   unix:/tmp/php-fcgi.sock;
	    include        /usr/local/etc/nginx/fastcgi_params;
	    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
	}

Таким образом все php из /administrator/ «пройдут» через секцию с авторизацией, не помешав обработке статики.
Ч.т.д.

рубрики: CMS, NIX, security, Администрирование, Полезности | Комментарии (0)

22 марта 2013

Как выбрать правильную CMS — поучительная история

Обратившись в веб-студию для создания сайта, стоит очень внимательно отнестись к выбору CMS (система управления сайтом).
Так на днях столкнулся с очень интересной и поучительной ситуацией!
Итак, ко мне обратился заказчик с просьбой «навести порядок» в интернет-проекте.
Став разбираться я обнаружил, что проект реализован на самописной CMS к которой разработчики ни коем образом доступ не предоставляют.
Находясь в лёгком шоке я запросил доступ к сайту — ftp, ssh на что так же был получен отказ!
Ну конечно же на просьбу предоставления полного бэкапа сайта для переноса на другой хостинг мне дали понять, что CMS мне не предоставят
(как вы уже поняли — хостинг так же предоставлялся разработчиками под их проекты фактически без какого либо доступа)
Хорошо, хоть доменное имя заказчик догадался оформить на себя ...

В общем, пока не поздно — решили бежать от таких разработчиков — движек перекинем на Битрикс.

Напоследок, несколько смешных цитат разработчиков:

Алексей, вечер добрый.
По переносу проекта, хххххх
Система управления сайтом там клиент-серверная, то есть ядро кода, не подлежит переносу на другую аппаратную платформу.
можем подготовить дамп базы, оригинальный дизайн макет в psd и выгрузку ftp для шаблона верстки.

Во-как! оказывается на клиент-серверных CMS «ядро кода, не подлежит переносу на другую аппаратную платформу.»
Жесть!

Алексей вечер добрый,
это просто клиент-серверное приложение, ядро разработки не передается, клиент подключатся
к серверным разработкам, стоимость проекта входит: фирменный дизайн, наполнение сайта, вертска и стоимость
подключение к сервисам, которые созданы и принадлежат компании на основе авторских прав.
В договоре, изначально было это прописано.

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

Оказывается «Это нормальная практика» :) !!! Ребята отжигают не по-детски!
«В договоре, изначально было это прописано.»

А вот это уже реально серъёзно!
Так, что господа и дамы — чтобы не оказаться на месте клиента в подобной неприятной ситуации — ВНИМАТЕЛЬНО читайте договора!
А то получается — вроде как, сайт Ваш — только вот привязаны Вы к разработчику намертво! и никаких доступов у вас нет!
Если пропал разработчик — хана вашему проекту!
Вот и сидите себе спокойно на бочке с порохом!
А если серъёзно — нужно СРОЧНО забирать всё что предоставят, делать полную выгрузку сайта (например wget-ом) и переносить проект на надёжную, хорошо зарекомендовавшую себя и желательно открытую CMS, вроде Битрикса.

рубрики: CMS, Размышления, Сайтостроение | Комментарии (5)

19 ноября 2012

Перенос форума PHPBB3 на Битрикс

На прошлой неделе обратились с вопросом о переносе форума с PHPBB3 на Битрикс.
Заказчик вышел на меня сам — с оф.сайта Битрикса (приятно, когда работа сама ищёт тебя, а не наоборот).
Собственно, на эту тему у меня уже было пару постов, где я подробно описал процесс миграции:
Bitrix API: конвертация форума с PHPBB
PHPBB 2 Битрикс — личные сообщения
Но в данном случае конечно-же не обошлось без своих ньюансов:
* К сожалению хэш был записан в формате php4 й версии — к Битриксу не подошел, соответственно пароли юзеров придётся им восстанавливать через почтовый ящик
* В данном ТЗ нужно было перетащить прикреплённые к сообщениям файлы:
Выдёргиваем из bb_attachments все прикреплённые файлы и при создании сообщения передаём переменную с массивом прикреплёнок созданных методом CFile::MakeFileArray ()
array =>
0 => array («name», «size», «tmp_name», «type»),
1 => array («name», «size», «tmp_name», «type»),
Код приводить не буду, т.к. в каждой версии phpbb прикреплёнки хранятся по-разному.

В остальном всё прошло по-плану и заказчик остался доволен.

рубрики: Bitrix, CMS, Программирование | Комментарии (3)

Яндекс.Метрика