'#title' => t('Frequency of updating of the data
(in seconds)'),
'#default_value' => variable_get('currencies_list_freq',
3600),
'#maxlength' => 255,
'#description' => t('It is recommended to use value
not less than 3600.'),
);
$form['currencies_list_url'] = array(
'#type' => 'textfield',
'#title' => t('Адрес xml-файла'),
'#default_value' => variable_get('currencies_list_url',
'http://www.cbr.ru/scripts/XML_daily.asp?date_req=
%d/%m/%y'),
'#maxlength' => 255,
'#description' => t('The XML-file address.'),
);
return system_settings_form($form);
}
Как и хуки hook_menu, hook_schema и многие другие хуки Drupal, эта функция должна возвращать ассоциативный массив, на этот раз содержащий информацию о параметрах создаваемой формы. Здесь мы создаем три однострочных текстовых поля (параметр #type имеет значение textfield), значения по умолчанию для которых (параметр #default_value) будут храниться и выбираться из стандартной таблицы variables Drupal при помощи функций variable_set() и variable_get(). Благодаря использованию функций drupal_get_form и system_settings_form нет необходимости заботиться о создании кнопок Submit и Reset, а также о функциях, обрабатывающих и сохраняющих данные формы. В более сложных случаях, которые будут рассмотрены в следующей статье, придется вручную создавать функции проверки введенных пользователем значений и сохранения данных.
Подробное описание типов полей, используемых в формах, можно найти в документации.
Все, мы завершили разработку первой из трех частей нашего модуля – административного интерфейса и переходим к разработке второй его части – инструмента получения данных от удаленного сервера.
Чтобы Drupal периодически выполнял определенные действия, в планировщике задач операционной системы необходимо настроить запуск файла cron.php, который находится в корне каждого Drupal-сайта. При выполнении этого файла будет вызываться хук hook_cron, и в нашем модуле мы напишем его реализацию:
function currencies_cron() {
currencies_contents();
}
Процедура получения и обработки XML-файла, расположенного на удаленном сервере, довольно обычна, поэтому она здесь не приведена. При желании вы можете самостоятельно разобрать логику работы этой функции, изучив исходные коды модуля Currencies, которые есть на диске, прилагаемом к журналу. В результате ее работы формируется массив $result, в котором содержится информация о курсах валют и который передается функции темизации. Функцию currencies_contents() см. в листинге 3. Здесь мы сначала проверяем, нет ли запрашиваемых данных в кэше Drupal, если нет, то происходит соединение с удаленным сервером (его адрес указан через административный интерфейс модуля), получение и обработка XML-файла и формирование массива данных, который передает функции темизации. Функция темизации формирует выходной HTML-код, записываемый в кэш, его время жизни явно указывается исходя из соответствующей настройки, заданной в интерфейсе управления модулем. Drupal автоматически управляет закэшированными данными и при необходимости удаляет устаревшие записи.
function currencies_contents() {
if(!$c = cache_get('currencies')) {
/* здесь пропущен код, отвечающий за получение
и обработку XML-файла */
$output = theme('currencies_block', $result);
$t = variable_get('currencies_list_freq', 3600);
if(!$t || !is_numeric($t)) $t = 3600;
cache_set('currencies', $output, 'cache', time() + $t);
} else {
$output = $c->data;
}
return $output;
}
Функция currencies_contents() будет использоваться не только при запуске cron-задания, но и при формировании блока с данными, который будет показываться пользователю. Таким образом, практически всегда пользователи будут видеть данные, полученные из кэша Drupal, если же на сайте не работает cron и нет закэшированных данных о курсах валют, то произойдет соединение с сервером ЦБ, формирование и запись в кэш необходимых данных.
Теперь подробнее остановимся на функциях темизации (theming; термин не слишком благозвучен, но уже стал общепринятым). Теоретически прямо в коде функции currencies_contents() можно было бы сформировать HTML-код, который в дальнейшем и видел бы посетитель сайта в браузере. Однако такой подход неверен, поскольку при изменении оформления данных пришлось бы менять код модуля, а это влечет за собой две проблемы. Во-первых, модуль могут использовать сторонние разработчики, и им для внесения изменений придется вникнуть в структуру модуля и внести в него изменения, которые могут привести к ошибкам. Во-вторых, часто при разработке крупных проектов версткой и программированием занимаются разные люди. Верстальщик может не иметь представления о том, как работать с языком PHP в целом и модулями Drupal в частности. По этому правильнее вынести все действия, связанные с оформлением данных, в отдельные файлы и функции, для чего и нужны функции темизации.
Функции темизации – это функции, генерирующие HTML-код, который впоследствии показывается пользователю.
Функции темизации – это функции, генерирующие HTML-код, который впоследствии показывается пользователю. Особенность таких функций в том, что, во-первых, они не должны реализовывать никакой бизнес-логики, т. е. в их задачи входит только генерирование HTML-кода на основе полученных аргументов. Во-вторых, эти функции могут быть переопределены разработчиком сайта без редактирования кода модуля, путем изменения файла template.php или создания файла-шаблона.
В нашем случае массив данных формируется функцией currencies_contents(), а HTML-код создается функцией theme_currencies_block(), которую нам сейчас предстоит определить и зарегистрировать. Подчеркну, что вызов любой функции темизации осуществляется через вызов функции-обертки с именем theme(), т. е. функция theme_currencies_block($argument) должна вызываться как theme('currencies_block', $argument). Чем вызвана эта необходимость, я объясню чуть позже.
Для регистрации функций темизации, используемых в модуле, мы должны реализовать hook_theme, который возвращает массив имен применяемых функций темизации и принимаемых ими параметров. В нашем модуле будет использоваться одна функция темизации theme_currencies_block(), которая на вход принимает один обязательный аргумент – массив курсов валют, поэтому реализация хука hook_theme будет выглядеть так:
function currencies_theme() {
return array(
'currencies_block' => array(