Загрузка книг в формате FB2 и создание из них нод в Drupal

За загрузку файлов и последующий их разбор будет отвечать модуль «FB2Upload». Вот его .info файл:

name = FB2Upload
description = Creating nodes from uploaded *.fb2 books. You must have content type "Book".
core = 7.x
version = 7.x-1.x-dev
package = FB2

Загрузка книги производится аналогично загрузке любого другого файла. За нее отвечают 3 хука:
fb2upload_page_form — собственно, сама форма загрузки.
fb2upload_page_form_validate — проверка переданных пользователем данных.
fb2upload_page_form_submit — разбор FB2 и создание ноды.

Так как FB2 — это обычный XML, будем использовать для его разбора DOM парсер. Вот весь код модуля:

< ?php
function fb2upload_menu() {
  $items = array();
  $items['fb2upload'] = array(
    'title' => 'FB2 Upload',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('fb2upload_page_form'),
    'access callback' => TRUE,
  );
  return $items;
}
 
function fb2upload_page_form()
{
  $form = array();
  $form['file'] = array(
    '#type' => 'file',
    '#title' => 'Книга',
    '#description' => 'Выберете файл электронной книги формата FB2 (*.fb2) для загрузки',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Отправить',
  );
  return $form;
}
 
function fb2upload_page_form_validate($form, &$form_state) {
  $validators = array(
    'file_validate_extensions' => array('fb2'), // Проверка на расширения
    'file_validate_size' => array(2 * 1024 * 1024), // Проверка на размер файла (максимум 2mb)
  );
  // Загружаем файл в sites/default/files (по умолчанию)
  if ($file = file_save_upload('file', $validators, 'public://')) {
    $form_state['values']['file'] = $file; // передаём информацию о файле в ф-ю fb2upload_form_submit()
  }
  else {
    form_set_error('file', 'Файл не был загружен');
  }
}
function fb2upload_page_form_submit($form, &$form_state) {
  $file = $form_state['values']['file'];
  $file->status = FILE_STATUS_PERMANENT; // Изменяем статус файла на "Постоянный"
  file_save($file); // Сохраняем новый статус
  $book = new DOMDocument();
  $book->strictErrorChecking = false;
  $book->recover = true;
  $load = $book->load($file->uri,LIBXML_NOERROR);
  //Создаем ноду
  $new_node = new StdClass();
  $new_node->type = 'book';
  $new_node->status = 1;
  $new_node->promote = 1;
  $new_node->title = $book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $new_node->comment = 0;
  $new_node->sticky = 0;
  $new_node->created = time();
  $new_node->changed = time();
  $new_node->language = 'ru';
  $new_node->body['und'][0]['value'] = $book->getElementsByTagName('annotation')->item(0)->nodeValue;
  $new_node->body['und'][0]['format'] = 'full_html';
  global $user;
  $new_node->uid = $user->uid;
  $new_node->field_file['und'][0]['fid'] = $file->fid;
  $new_node->field_file['und'][0]['display'] = 1;
  $new_node->field_file['und'][0]['alt'] = 'Скачать книгу '.$book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $new_node->field_file['und'][0]['title'] = $book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $title_info = $book->getElementsByTagName('title-info')->item(0);
  $authors_list = $title_info->getElementsByTagName('author');
  foreach ($authors_list as $element) {
    $authors[] =  $element->getElementsByTagName('first-name')->item(0)->nodeValue." ".
      $element->getElementsByTagName('middle-name')->item(0)->nodeValue." ".
      $element->getElementsByTagName('last-name')->item(0)->nodeValue." ";
  }
  $new_node->field_autor['und'][0]['value'] = implode(", ", $authors);
  node_save($new_node);
  drupal_set_message('Книга загружена: ');
}

Все самое интересное происходит в хуке обработки формы fb2upload_page_form_submit, а именно: мы создаем новый элемент DOM $book и вытаскиваем с его помощью нужные нам данные. Затем строкой $new_node = new StdClass(); мы создаем новую ноду и на следующей строке задаем ей тип «book». Этот тип содержимого придется создавать вручную в админке друпала, определив ему дополнительные поля «autor» и «file». Затем указываем остальные параметры ноды, а именно:
$new_node->type — тип материала
$new_node->title — Заголовок материала
$new_node->status — 1 (Опубликовано), 0 (Неопубликовано)
$new_node->promote — 1 (Закреплено на главной), 0 (Не закреплено на главной)
$new_node->comment — 0 (Запрещено комментировать), 1 (Только чтение комментариев), 2 (Разрешено комментировать)
$new_node->sticky — 1 (Закреплять вверху списков), 0 (Не закреплять)
$new_node->created — Таймштамп создания ноды
$new_node->changed — Таймштамп последнего обновления ноды
$new_node->body[‘und’][0][‘value’] — Содержимое материала
$new_node->uid — ID пользователя, который будет считаться автором. Если поставить 0, то автором будеть считатья «Гость».
$new_node->language — язык материала.
$new_node->body[‘und’][0][‘format’] — Формат ввода, рекомендую всегда явно указывать, иначе HMTL код может необработаться и выдаваться простым текстом.
Созданные дополнительно поля «file» и «autor» заполняются аналогично. Таким же способом можно извлечь и записать в ноду и другие данные книги, например, ее жанр.

2 комментария

  1. Hmm is anyone else having problems with the images on this blog loading?

    I’m trying to figure out if its a problem on my end or if it’s the blog.

    Any feed-back would be greatly appreciated.

  2. Hey! This is kind of off topic but I need some help from an established blog.
    Is it difficult to set up your own blog?
    I’m not very techincal but I can figure things out pretty quick.
    I’m thinking about setting up my own but I’m
    not sure where to begin. Do you have any points or suggestions?
    Thank you

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *