Pull to refresh

Работа с CCK Filefield. Вставка и отображение Flash

Reading time 13 min
Views 1.9K
imageИногда бывает необходимо отобразить на сайте файл не просто ссылкой, а как-нибудь иначе. Видео и аудиофайлы хочется отображать плеером, с возможностью просмотра (прослушивания), swf — сразу отображать на странице. Для прикрепления файлов к материалам есть отличный модуль Filefield, однако выбор форматтеров для него невелик. Файл можно отобразить просто ссылкой. Немного расширяют его функционал другие модули, например Imagefield позволяет отображать картинки. Я попытаюсь доступно объяснить как добавить возможность отображения Flash контента на примере модуля SWFfield.

Далее будет много кода, мало картинок и вообще всё скучно и уныло...

Начало


Создаем в директории модулей новый каталог swffield.
Как и для любого модуля нам потребуется файл .info, в нашем случае — swffield.info
Copy Source | Copy HTML
  1. name = SwfField
  2. description = Добавляет поле Flash в CCK.
  3. dependencies[] = content
  4. dependencies[] = filefield
  5. package = CCK
  6. core = 6.x
  7. version = "6.x-1.1"


Также, нам необходим файл swffield.install
Copy Source | Copy HTML
  1. // hook_install (установка модуля)
  2. function swffield_install() {
  3.     // Подгружаем модуль content
  4.     drupal_load('module', 'content');
  5.     // Сообщаем CCK об установке нового модуля
  6.     content_notify('install', 'swffield');
  7. }
  8.  
  9. // hook_uninstall (удаление модуля)
  10. function swffield_uninstall() {
  11.     drupal_load('module', 'content');
  12.     // Сообщаем CCK об удалении нового модуля
  13.     content_notify('uninstall', 'swffield');
  14. }
  15.  
  16. // hook_enable (включение модуля)
  17. function swffield_enable() {
  18.     drupal_load('module', 'content');
  19.     // Сообщаем CCK о включении нового модуля
  20.     content_notify('enable', 'swffield');
  21. }
  22.  
  23. // hook_disable (отключение модуля)
  24. function swffield_disable() {
  25.     drupal_load('module', 'content');
  26.     // Сообщаем CCK об отключении нового модуля
  27.     content_notify('disable', 'swffield');
  28. }

Модуль


Создадим файлы swffield.module, swffield.render.inc (вынесем сюда весь код, связанный с отображением контента пользователю) и swffield.widget.inc (отображение поля в админке). В принципе, весь код можно писать в swffield.module — работать будет.

swffield.module
Copy Source | Copy HTML
  1. // Подключаем необходимые файлы
  2. module_load_include('inc', 'swffield', 'swffield.render');
  3. module_load_include('inc', 'swffield', 'swffield.widget');
  4.  
  5. // Инициализация. Проверяем, есть ли Filefield, если нету, отключаем модуль.
  6. function swffield_init() {
  7.     if (!module_exists('filefield')) {
  8.         module_disable(array('swffield'));
  9.         return;
  10.     }
  11. }
  12.  
  13. // Задаем форму ввода данных виджета и способ ее обработки.
  14. // Наше поле ничем не отличается от поля Filefield
  15. function swffield_elements() {
  16.     $filefield_elements = module_invoke('filefield', 'elements');
  17.     $elements['swffield_widget'] = $filefield_elements['filefield_widget'];
  18.  
  19.     return $elements;
  20. }
  21.  
  22. // Сообщаем CCK информацию о форматтере
  23. function swffield_field_formatter_info() {
  24.     $formatters = array(
  25.         'swffield_flash' => array(
  26.             'label' => t('Flash'),
  27.             'field types' => array('filefield'),
  28.             'description' => t('Displays Flash content'),
  29.         ),
  30.     );
  31.     return $formatters;
  32. }
  33.  
  34. // Указываем стандартное значение поля такое же как и у Filefield
  35. function swffield_default_value(&$form, &$form_state, $field, $delta) {
  36.     return filefield_default_value($form, $form_state, $field, $delta);
  37. }
  38.  
  39. // Указываем, когда считать поле пустым
  40. function swffield_content_is_empty($item, $field) {
  41.     return filefield_content_is_empty($item, $field);
  42. }
  43.  
  44. // Добавляем еще один обработчик для сохранения настроек поля
  45. function swffield_form_content_field_overview_form_alter(&$form, &$form_state) {
  46.     $form['#submit'][] = 'swffield_form_content_field_overview_submit';
  47. }
  48.  
  49. // Обработчик сохранения настроек поля
  50. function swffield_form_content_field_overview_submit(&$form, &$form_state) {
  51.     // Если добавляем новое поле к материалу
  52.     if (isset($form_state['fields_added']['_add_new_field']) && isset($form['#type_name'])) {
  53.         // Тип поля
  54.         $new_field = $form_state['fields_added']['_add_new_field'];
  55.         // Тип материала
  56.         $node_type = $form['#type_name'];
  57.         // Массив с данными о поле
  58.         $field = content_fields($new_field, $node_type);
  59.         // Если поле добавляется нашим модулем
  60.         if ($field['widget']['module'] == 'swffield') {
  61.             foreach ($field['display_settings'] as $display_type => $display_settings) {
  62.                 if ($field['display_settings'][$display_type]['format'] == 'default') {
  63.                     // Устанавливаем отображение поля "swffield_flash"
  64.                     $field['display_settings'][$display_type]['format'] = 'swffield_flash';
  65.                 }
  66.             }
  67.             // Обновляем поле
  68.             content_field_instance_update($field);
  69.         }
  70.     }
  71. }

swffield.widget.inc
Copy Source | Copy HTML
  1. // Сообщаем CCK информацию о виджете
  2. function swffield_widget_info() {
  3.     return array(
  4.         'swffield_widget' => array(
  5.             'label' => t('Flash'),
  6.             'field types' => array('filefield'),
  7.             'multiple values' => CONTENT_HANDLE_CORE,
  8.             'callbacks' => array('default value' => CONTENT_CALLBACK_CUSTOM),
  9.             'description' => 'Flash content',
  10.         ),
  11.     );
  12. }
  13.  
  14. // Этот хук будет вызываться каждый раз, когда наше поле добавляется в форму
  15. function swffield_widget(&$form, &$form_state, $field, $items, $delta =  0) {
  16.     $element = filefield_widget($form, $form_state, $field, $items, $delta);
  17.  
  18.     return $element;
  19. }
  20.  
  21. // Настройки виджета (поля)
  22. function swffield_widget_settings($op, $widget) {
  23.     switch ($op) {
  24.         case 'form':
  25.             return swffield_widget_settings_form($widget);
  26.         case 'validate':
  27.             return swffield_widget_settings_validate($widget);
  28.         case 'save':
  29.             return swffield_widget_settings_save($widget);
  30.     }
  31. }
  32.  
  33. // Форма настроек поля
  34. function swffield_widget_settings_form($widget) {
  35.     $form = module_invoke('filefield', 'widget_settings', 'form', $widget);
  36.     // По умолчанию CCK подставляет тип файла txt
  37.     // Заменим его на swf
  38.     if ($form['file_extensions']['#default_value'] == 'txt') {
  39.         $form['file_extensions']['#default_value'] = 'swf';
  40.     }
  41.     // Поле "Ширина" для указания ширины отображаемого контента
  42.     $form['width'] = array(
  43.         '#type' => 'textfield',
  44.         '#title' => 'Ширина',
  45.         '#default_value' => $widget['width'] ? $widget['width'] : 470,
  46.         '#size' => 15,
  47.         '#maxlength' => 5,
  48.         '#description' => 'Ширина flash контента',
  49.         '#weight' => 2.1,
  50.     );
  51.     // Аналогично "Высота"
  52.     $form['height'] = array(
  53.         '#type' => 'textfield',
  54.         '#title' => 'Высота',
  55.         '#default_value' => $widget['height'] ? $widget['height'] : 350,
  56.         '#size' => 15,
  57.         '#maxlength' => 5,
  58.         '#description' => 'Высота flash контента',
  59.         '#weight' => 2.2,
  60.     );
  61.     // Настройки альтернативного текста, если у пользователя отключен Javascript или нет Flash Player'а
  62.     $form['alt_text'] = array(
  63.         '#type' => 'textarea',
  64.         '#title' => 'Альтернативный текст',
  65.         '#default_value' => $widget['alt_text'] ? $widget['alt_text'] : 'Дорогие друзья!<br />В связи с тем, что технология работы нашего сайта требует предустановленного Adobe Flash Player, мы настоятельно рекомендуем Вам установить последнюю версию плагина для вашего браузера с сайта <a href="http://www.adobe.com/go/getflashplayer">Adobe.com</a>.',
  66.         '#description' => 'Этот текст будет отображаться, если у пользователя не установлен Flash плеер',
  67.         '#weight' => 2.3,
  68.     );
  69.     return $form;
  70. }
  71.  
  72. // Валидатор формы настроек
  73. function swffield_widget_settings_validate($widget) {
  74.     $extensions = array_filter(explode(' ', $widget['file_extensions']));
  75.     $flash_extensions = array('swf');
  76.     // Проверяем расширение файла
  77.     if (count(array_diff($extensions, $flash_extensions))) {
  78.         form_set_error('file_extensions', 'Поддерживается только формат SWF');
  79.     }
  80.     // Проверяем ширирну и высоту
  81.     foreach (array('width', 'height') as $resolution) {
  82.         if (empty($widget[$resolution]) || !preg_match('/^[0-9]+$/', $widget[$resolution])) {
  83.             form_set_error($resolution, 'Указан неверный размер контента.');
  84.         }
  85.     }
  86.     return module_invoke('filefield', 'widget_settings', 'validate', $widget);
  87. }
  88.  
  89. // Сохраняем настройки поля
  90. function swffield_widget_settings_save($widget) {
  91.     $filefield_settings = module_invoke('filefield', 'widget_settings', 'save', $widget);
  92.     return array_merge($filefield_settings, array('width', 'height', 'alt_text'));
  93. }

swffield.render.inc
Copy Source | Copy HTML
  1. // Хук темизации
  2. // Задаем функции темизации для виджета, форматтера и отображения на сайте
  3. function swffield_theme() {
  4.     $theme = array(
  5.         'swffield_widget' => array(
  6.             'arguments' => array('element' => NULL),
  7.         ),
  8.         'swffield_formatter_swffield_flash' => array(
  9.             'arguments' => array('element' => NULL),
  10.         ),
  11.         'swffield_flash' => array(
  12.             'arguments' => array('item' => NULL, 'attributes' => NULL),
  13.         ),
  14.     );
  15.     return $theme;
  16. }
  17.  
  18. // Темизация виджета такая же как и у любого элемента формы
  19. function theme_swffield_widget($element) {
  20.     return theme('form_element', $element, $element['#children']);
  21. }
  22.  
  23. // Темизация форматтера
  24. function theme_swffield_formatter_swffield_flash($element) {
  25.     // Проверяем, загружен ли файл
  26.     if (empty($element['#item']['fid'])) {
  27.         return '';
  28.     }
  29.  
  30.     $field = content_fields($element['#field_name'], $element['#node']->type);
  31.     $item = $element['#item'];
  32.  
  33.     // Класс для отображения поля
  34.     $class = 'swffield swffield-'. $field['field_name'];
  35.     // Возвращаем темизированный с помощью функции "swffield_flash" вывод
  36.     return theme('swffield_flash', $item, array('class' => $class, 'width' => $field['widget']['width'], 'height' => $field['widget']['height'], 'alt' => $field['widget']['alt_text']));
  37. }
  38.  
  39. // Вспомогательная функция темизации
  40. function theme_swffield_flash($item, $attributes) {
  41.     // Загружаем библиотеку "swfobject.js"
  42.     drupal_add_js(drupal_get_path('module', 'swffield') . "/" . "swfobject.js");
  43.     // Генерируем ID для отображаемого элемента
  44.     $id = "swffield-" . rand(1, 10000);
  45.     // Путь к файлу
  46.     $file = "/" . $item['filepath'];
  47.     // Готовый элемент
  48.     return "<div id='".$id."' class='".$attributes['class']."'>"
  49.           .$attributes['alt']
  50.           ."<script type='text/javascript'>"
  51.           ."var flashvars = {};"
  52.           ."var params = {bgcolor:'#ffffff',allowFullScreen:'false',allowScriptAccess:'always',wmode:'opaque'};"
  53.           ."new swfobject.embedSWF('".$file."', '".$id."', '".$attributes['width']."', '".$attributes['height']."', '9.0.0', false, flashvars, params);"
  54.           ."</script>"
  55.           ."</div>";
  56. }

Здесь используется отличная js библиотека SWFobject. Файл swfobject.js необходимо положить в каталог с нашим модулем.
Еще один тонкий момент. Для каждого отображения нашего элемента на странице необходимо сгенерировать уникальный ID, по которому позднее javascript'ом вставится контент. У меня используется rand(1, 10000). Если есть более адекватный способ, буду рад услышать его в комментариях.

Заключение


Вот собственно и всё, что необходимо для добавления отображения SWF контента на страницах нашего сайта. Аналогичным образом можно например добавить отображение «Видеоплеер» для FLV или «Аудиоплеер» для MP3.

Удачи!
Tags:
Hubs:
+15
Comments 29
Comments Comments 29

Articles