RSForm! Pro не работает при включенном кэше Joomla

Некоторое время назад столкнулся со странностями на одном сайтов, сделанных на Joomla. Странность заключалась в следующем: на одной из страниц в текст материала была вставлена форма компонента RSForm. Эта форма прекрасно отображалась, но при попытке ее отправить в браузере клиента просто снова открывалась эта же страница, никакого сообщения об удачной отправки данных не появлялось. Письма администратору и клиенту так же не отправлялись, и в БД не было вообще никаких упоминаний о том, что эта форма когда-либо была заполнена.
После небольшого гугления выяснилось, что во всем виновато кэширование. Вот что по этому поводу говорится на официальном сайте компонента RS Form:

Чтобы понять, почему так происходит, нужно разобрать, как работает кэш Joomla (для примера будем использовать случай, когда форма встроена в текст статьи):

  • Загружается статья;
  • Плагин RSForm запускается и заменяет плейсхолдер в тексте статьи на соответствующую форму;
  • Система кэширования Joomla «запоминает», как выглядит страница и сохраняет это представление в кэше.
  • При следующих обращениях к этой странице первые два этапа пропускаются, и страница сразу загружается из кэша. Это ускоряет работу сайта, но так же это значит, что страница не будет загружать плагин RSForm. Форма будет отображаться на странице, так как ее внешний вид сохранен в кэше, но ее функционал — нет.

Единственное решение, которое предлагается — отключить кэширование.

Однако, как быть, если совсем отключать кэширование нельзя? Ведь при этом может сильно возрасти нагрузка на хостинг.  Мне известны следующие варианты:

  • Добавить в index.php шаблона строки
    $cache = &JFactory::getCache('com_rsform');
    $cache->clean();

    В таком случае при каждом обращении к сайту будет происходить очистка кэша RSForm. На мой взгляд, это не очень оптимальный метод, ведь форма все рано будет кэшироваться, а потом каш будет очищаться — получаем лишние действия. Еще один минус: этот код сработает только в том случае, когда доступ к форме осуществляется по адресу вида index.php?option=com_rsform.Если на сайте используются SEF-ссылки, этот метод не сработает.

  • Более сложный вариант, найденный мной у «ИТ Осминогов»: в файле /plugins/system/cache.php в каждой функции добавили условие, которое запрещает выполнение, если запрошена страница, содержащая форму (для проверки страницы использовался $_SERVER[‘REQUEST_URI’] ). Этот вариант более предпочтительный, однако требует некоторых знаний PHP и принципов работы CMS Joomla.

Вывод содержание загруженной FB2 книги в Drupal

Продолжаю цикл статей о создании электронной библиотеки на Drupal 7. В прошлой статье я рассказал о модуле, который позволяет загружать на сайт книги в формате FB2 и создает из них ноды. Сегодня же я покажу, как можно вывести содержание загруженной тем модулем книги.
Кому интересно, прошу под кат.

Создание ноды в Drupal по загруженной FB2 книге.

Потихоньку работаю над проектом электронной библиотеки книг в формате FB2, и решил использовать для нее Drupal. Собственно, вся логика библиотеки будет заключаться в пакете модулей «FB2». Модули пишу строго под нужды конкретного проекта, поэтому пока не планирую выкладывать их целиком, а лишь опишу принцип их работы и приведу наиболее интересные и важные участки кода.
А первым на очереди у нас модуль, который позволяет пользователям загружать на сайт файлы FB2, разбирает их и создает соответствующие ноды, где заголовок ноды — это название книги а тело ноды — аннотация. Плюс, дополнительно созданные поля «autor» и «file» для хранения авторов книги и ссылки на сам FB2.
Узнать подробнее можно по ссылке: Загрузка книг в формате FB2 и создание из них нод в Drupal

Валидация форм на HTML5 по pattern и AJAX.

Как известно, HTML5 предоставляет нам много новых плюшек для контроля вводимых пользователем данных в текстовые поля форм. Это позволило сильно облегчить JS-валидацию форм в нашей системе интернет-банкинга. Однако, столкнулся с досадным моментом: каждый браузер по своему изменяет внешний вид полей при неправильном вводе. Кроме того, основная валидация происходит при вызове метода Submit формы. У нас же так исторически сложилось, что данные передаются в виде JSON’а через AJAX по нажатию на обычный button. В результате чего родилась вот такая функция:

function ChkHTMLValidation(obj)
{
	var field = document.getElementById(obj);
	if(!field.checkValidity()){
		document.getElementByID(obj).classList.add('StateError');
		document.getElementByID('button_next').disabled=true;
	}else{
		document.getElementByID(obj).classList.remove('StateError');
		document.getElementByID('button_next').disabled=false;
	}
}

На вход функция получает ИД текстового input’а, у которого определен pattern, и проверяет корректность введенных в него данных. Если данные некорректны, на поле навешивается CSS-класс ошибки и отключается кнопка отправки формы. Если же данные корректны — CSS-класс ошибки удаляется и кнопка включается.

Отправка XML методом POST в C#

Ох, что-то давно я ничего не писал… Дедлайн ближе — посты реже 🙂

В процессе прикручивания к интернет-банку платежной системы QIWI возникла необходимость слать XML POST-запросом на определенные URL и смотреть, что приходит в ответ. Чтобы не ворочать ради этого всю систему интернет-банкинга и не собирать нужную информацию по текстовым логам сервера, склепал на .Net небольшую софтинку в пару строк кода, которая шлет на указанный URL переданный XML методом POST используя класс WebRequest и выводит все, что получает в ответ. Исходник проекта берем тут.

P.S.: тулза писалась для личного использования в буквальном смысле на коленке, и по хорошему в нее надо добавить проверку ошибок (неправильный URL, URL не найден, ошибка DNS и т.д.).

Вычисляем Internet Explorer 11 или почему Jquery распознает его как Mozilla Firefox 11

В пятницу вечером обновился до IE 11 и ушел с работы. Дома для веб-серфинга пользуюсь только Firefox’ом. Сегодня утром, придя на работу, продолжил изменять интерфейс нашего интернет-банкинга. В свежих версиях Firefox, Opera и Chrome все было отлично, а вот при попытке залогинится через IE 11 получил сообщение «Браузер Mozilla Firefox 11 не поддерживается.». Для проверки версии браузера на клиенте используется Jquery.browser, и почему-то $.browser.mozilla при IE 11 равен true.

Взглянем на USER-AGEN STRING нового IE11:

Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko

Заметили, что больше нет слова «MSIE»? Зато появилось «like Gecko». В общем, похоже, jQuery  не находит слова «MSIE», зато находит «Mozilla», и думает, что браузер — Mozilla Firefox. А версия — 11.

Мой способ решения не особо оригинальный, да и вообще, пора уже переходить на jQuery 2. Но пока этого еще не произошло, я решил искать в USER-AGENT явное упоминание движка IE:

1
2
3
var UserAgentString = navigator.userAgent;
 
if(UserAgentString.indexOf('Trident/7.0') + 1){alert("Hello, IE11 !");}

Получаем локальный IP и Mac посетителя на сайте

Возникла задача: необходимо записать в лог, с какого локального (внутреннего) IP и MAC (на случай включенного DHCP внутри подсетки)  адресов клиент зашел на сайт. Если разбирать заголовки запроса на сервере, то мы получим лишь его внешний IP. Если пользователь сидит за NAT’ом, то это нам практически ничего не даст.  Что же делать? Запускать что-то на клиенте, что обратится к его сетевой карте и получит все необходимые сведения, а затем передаст на сервер. Первым в голову приходит JavaScript, но вот беда — из-за ограничений безопасности браузера JS не может получить доступа к железу. Значит, будем пробовать реализовать это на JAVA, добавив в страничку невидимый апплет.

Continue reading ‘Получаем локальный IP и Mac посетителя на сайте’ »

wp-cron.php грузит процессор

В выходные зашел на один из своих сайтов кое-чего подправить, и заметил жуткие тормоза в его работе, (даже несмотря на то, что он практически полностью кэшируется в memchached). Озадаченный этим, полез в админку хостера и обнаружил, что мой аккаунт полностью грузит процессор, при этом нагрузка на БД минимальна. В логах использования ЦП часто встречались строчки типа «charmlab.ru/wp-cron.php?doing_wp_cron=1369560421.321949005126953125000».

cpu_usage_log

Оказалось, что это известная проблема WordPress’а, и не раз уже поднималась в интернете. Однако, практически везде предлагают одно и то же решение: добавить в wp-config.php строчку «define(‘DISABLE_WP_CRON’, true);«. Я сделал тоже самое, но видимого результата почему-то не получил 🙁 (Как оказалось, не один я).

К сожалению, на выходных я так и не смог разобраться в первопричине такого поведения, поэтому просто переименовал wp-cron.php. Нагрузка сразу же спала, но, конечно, WordPress потерял возможность выполнять задания по расписанию.

Валидация даты на JavaScript

Для ввода дат на сайтах я обычно использую замечательный плагин Jquery Datepicker, выставляя текстовому полю, к которому он привязан, режим readonly. Таким образом, я точно знаю, в каком формате введенная дата придет на сервер, и как ее там обработать (но не забываю о проверке введенных данных на стороне сервера!). Однако, недавно возникла задача разрешить ручной ввод даты в текстовом поле в формате дд.мм.гггг. Конечно, можно разрешить писать в текстовое поле все, что угодно и проверять валидность введенных данных на сервере. Однако, на мой взгляд, было бы удобней проверить данные сразу на стороне клиента, и если данные введены неверно — принять нужные меры.
Итак, вот как будет работать наша система: при клике на поле для ввода даты будет отображаться стандартный Jquery Datepicker. Если же пользователь хочет ввести дату вручную, он может написать ее прямо в этом текстовом поле. Для облегчения этого добавим к полю маску ввода Jquery Masked Input. Если введенная дата валидна, включаем кнопку сабмита и подсвечиваем поле зеленым. Если дата не валидна — подсвечиваем поле красным и отключаем кнопку сабмита.
Проверить валидность даты можно при помощи Jquery Validate, но я решил написать для этого свой велосипед на нативном JS, так что представленная ниже функция валидации может быть использована без каких-либо JS фреймворков (или в связке с любым из них :)).
Собственно, вот исходник моей функции:

function ValidateDate(date_fl){
str=date_fl.value;
function TstDate(){
str2=str.split(".");
if(str2.length!=3){return false;}
//Границы разрешенного периода. Нельзя ввести дату до 1990-го года и позднее 2020-го.
if((parseInt(str2[2], 10)< =1990)||(parseInt(str2[2], 10)>=2020)) {return false;}
str2=str2[2] +'-'+ str2[1]+'-'+ str2[0];
if(new Date(str2)=='Invalid Date'){return false;}
return str;
}
var S=TstDate()
if(S)
{
//Дата валидна
date_fl.className='date_ok';
document.getElementById("submit").disabled = false;
}
else
{
//Дата не валидна
date_fl.className='date_err';
document.getElementById("submit").disabled = true;
}
}

Немного поясню принцип ее работы: функция принимает на вход объект, в который производится ввод даты. Затем введенное значение разбивается на массив по точке в качестве разделителя и приводится в формат гггг-мм-дд, после чего происходит попытка создания на его основе объекта типа Date. Таким образом проверяется не просто соответствие записи форме xx.xx.xxxx, а именно возможность существования такой даты (31-е февраля не прокатит). Если все отлично — присваиваем полю ввода CSS-класс ‘date_ok’ и включаем кнопку сабмита. Если произошла ошибка — присваиваем класс ‘date_err’ и отключаем кнопку. Конечно, ничто не мешает вам произвести какие-то свои действия.
Ну и в конце архив с примером использования.

Сказ о том, как крутой программист не мог Windows с флэшки поставить

Некоторое время назад стал "счастливым" обладателем ноутбука фирмы DNS. Практически сразу на него была поставлена Ubuntu и поднят LAMP. Однако все течет, все меняется, и в итоге мне понадобилось разработать довольно крупное приложение на ASP.NET, а для этого нужна ОС Windows.

Привычным движением записал на стационарном компе программой UltraISO образ новенькой 8-ки на флэшку, пихнул в USB ноута и… и ничего. Ноут с нее не грузился. Флэшка прекрасно виделась в BIOS, но при попытке с нее загрузится ноут просто не реагировал. Мигал курсором на девственно-чистом черном экране, и все 🙁 

Долго я думал, много мануалов перечитал, и в итоге надумал: форматнул флэшку в FAT32 (до этого она в NTFS была), и записал по новой на нее образ из UltraISO. В итоге система встала без каких-либо проблем. 

Стоит так же заметить, что на других компах с этой же флэшкой проблем не возникало и при NTFS. Почему ноутбук DNS захотел именно FAT, остается только догадываться.