paragraphs_table.module in Paragraphs table 7
Same filename and directory in other branches
Module file for Paragraph table module.
File
paragraphs_table.moduleView source
<?php
/**
* @file
* Module file for Paragraph table module.
*/
/**
* Implements hook_field_formatter_info().
*/
function paragraphs_table_field_formatter_info() {
return array(
'paragraphs_table_view' => array(
'label' => t('Paragraphs table'),
'field types' => array(
'paragraphs',
),
'settings' => array(
'edit' => t('Edit'),
'delete' => t('Delete'),
'add' => t('Add'),
'duplicate' => t('Duplicate'),
'import' => t('Import'),
'vertical' => FALSE,
'ajax' => FALSE,
'datatables' => FALSE,
'description' => TRUE,
'view_mode' => 'full',
'hide_empty' => TRUE,
'empty' => TRUE,
),
),
);
}
/**
* Implements hook_field_formatter_settings_form().
*/
function paragraphs_table_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = [];
$element['duplicate'] = array(
'#type' => 'textfield',
'#title' => t('Duplicate link title'),
'#description' => t("Leave it empty if you don't want duplicate row"),
'#default_value' => !empty($settings['duplicate']) ? $settings['duplicate'] : '',
);
if (module_exists('quick_data')) {
$element['import'] = [
'#type' => 'textfield',
'#title' => t('Import link title'),
'#description' => t("Leave it blank if you don't want to import csv data"),
'#default_value' => !empty($settings['import']) ? $settings['import'] : '',
];
}
$element['add'] = array(
'#type' => 'textfield',
'#title' => t('Add Link title'),
'#description' => t("Leave the title empty if you don't want add button"),
'#default_value' => !empty($settings['add']) ? $settings['add'] : '',
);
$element['edit'] = array(
'#type' => 'textfield',
'#title' => t('Edit Link title'),
'#description' => t("Leave the title empty if you don't want edit row"),
'#default_value' => !empty($settings['edit']) ? $settings['edit'] : '',
);
$element['delete'] = array(
'#type' => 'textfield',
'#title' => t('Delete Link title'),
'#description' => t("Leave the title empty if you don't want delete row"),
'#default_value' => !empty($settings['delete']) ? $settings['delete'] : '',
);
if ($display['type'] == 'paragraphs_table_view') {
$element['hide_empty'] = array(
'#type' => 'checkbox',
'#title' => t('Hide empty paragraphs'),
'#description' => t('If enabled, nothing will be displayed for an empty paragraphs (not even the add link).'),
'#default_value' => $settings['hide_empty'],
);
$element['empty'] = array(
'#type' => 'checkbox',
'#title' => t('Hide empty columns'),
'#description' => t('If checked, hide empty paragraphs table columns.'),
'#default_value' => $settings['empty'],
);
$element['vertical'] = array(
'#type' => 'checkbox',
'#title' => t('Table vertical'),
'#description' => t('If checked, table data will show in vertical mode.'),
'#default_value' => !empty($settings['vertical']) ? $settings['vertical'] : NULL,
);
$element['ajax'] = array(
'#type' => 'checkbox',
'#title' => t('Use ajax to load'),
'#description' => t('If checked, ajax will load table data.'),
'#default_value' => !empty($settings['ajax']) ? $settings['ajax'] : NULL,
);
if (module_exists('datatables')) {
$element['datatables'] = array(
'#type' => 'checkbox',
'#title' => t('Support datatables'),
'#description' => t('If checked, datatables will load table data.'),
'#default_value' => !empty($settings['datatables']) ? $settings['ajax'] : NULL,
);
}
}
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function paragraphs_table_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$output = '';
if ($display['type'] == 'paragraphs_table_view') {
$output .= '<br>';
$output .= !empty($settings['hide_empty']) ? t('Empty paragraphs: Hidden') : t('Empty paragraphs: Shown');
$output .= '<br>';
$output .= !empty($settings['empty']) ? t('Empty columns: Hidden') : t('Empty columns: Shown');
$output .= '<br>';
$output .= !empty($settings['vertical']) ? t('Table mode: Vertical') : '';
}
return $output;
}
/**
* Implements hook_field_formatter_view().
*/
function paragraphs_table_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
$display_view_mode = empty($display['settings']['view_mode']) ? 'full' : $display['settings']['view_mode'];
$view_mode = empty($instance['display'][$display_view_mode]['settings']['view_mode']) ? $display_view_mode : $instance['display'][$display_view_mode]['settings']['view_mode'];
// Don't display anything for an empty collection.
if (!empty($settings['hide_empty']) && empty($items)) {
return $element;
}
switch ($display['type']) {
case 'paragraphs_table_view':
$header = [
'',
'',
];
$field_names = array();
$item = current($items);
$paragraph = paragraphs_field_get_entity($item);
$fields = field_info_instances('paragraphs_item', $paragraph
->bundle());
$bundle_name = paragraphs_bundle_load($paragraph
->bundle())->name;
foreach ($fields as $field_paragraphs_item) {
$item_view_mode = !empty($field_paragraphs_item['display'][$view_mode]) ? $view_mode : 'default';
if ($field_paragraphs_item['display'][$item_view_mode]['type'] != 'hidden') {
$weight = $field_paragraphs_item['display'][$item_view_mode]['weight'];
$field_names[$weight] = $field_paragraphs_item['field_name'];
if ($field_paragraphs_item['display'][$item_view_mode]['label'] != 'hidden') {
$header[$weight] = array(
'data' => module_exists('i18n_field') ? i18n_field_translate_property($field_paragraphs_item, 'label') : $field_paragraphs_item['label'],
'class' => $field_names[$weight],
);
}
else {
$header[$weight] = '';
}
}
}
if (module_exists('ds')) {
// Add Display Suite fields and settings.
$fields_ds = ds_get_fields('paragraphs_item');
$fields_ds_settings = ds_get_field_settings('paragraphs_item', $field['field_name'], $view_mode);
foreach ($fields_ds_settings as $name => $ds_settings) {
if (isset($fields_ds[$name])) {
$weight = $ds_settings['weight'];
$field_names[$weight] = $name;
$fields[$name]["label"] = $fields_ds[$name]['title'];
$header[$weight] = array(
'data' => $ds_settings['label'] != 'hidden' ? $fields_ds[$name]['title'] : NULL,
'class' => $name,
);
}
if (in_array($name, $field_names)) {
$weight = array_search($name, $field_names);
}
// Allow to override field label using DS field format settings.
if (isset($weight) && isset($ds_settings['formatter_settings']['ft']['lb'])) {
$header[$weight]['data'] = t("@ds_settings", array(
'@ds_settings' => check_plain($ds_settings['formatter_settings']['ft']['lb']),
));
}
}
}
if ($settings['vertical']) {
$header = [
$bundle_name,
'',
];
}
ksort($header);
ksort($field_names);
$rows = array();
$max_row = count($items);
foreach ($items as $delta => $item) {
$field_paragraphs = paragraphs_field_get_entity($item);
if (empty($field_paragraphs)) {
continue;
}
$view = $field_paragraphs
->view($view_mode);
$id = $field_paragraphs
->identifier();
$content = $view['paragraphs_item'][$id];
$column = array();
foreach ($field_names as $field_name) {
if (isset($content[$field_name])) {
$content[$field_name]['#label_display'] = 'hidden';
}
else {
$content[$field_name] = array(
'#markup' => '<span class="empty_field"></span>',
'#empty' => TRUE,
);
}
if (!$settings["vertical"]) {
$column[] = array(
'data' => $content[$field_name],
'class' => drupal_html_class($field_name),
);
}
else {
if ($settings['hide_empty'] && !empty($content[$field_name]["#empty"])) {
continue;
}
$fiels_value = [
[
'data' => $fields[$field_name]["label"],
],
[
'data' => $content[$field_name],
],
];
$rows[] = array(
'data' => $fiels_value,
'class' => array(
'field-paragraphs-item',
),
);
}
}
// Dont show option if in revision mode.
$isrevision = arg(2) == 'revisions' ? TRUE : FALSE;
// @todo add operation
$isrevision = TRUE;
$links = '';
if (!$isrevision) {
$links = array(
'#theme' => 'links',
'#theme_wrapper' => 'item_list',
'#attributes' => array(
'class' => array(
'paragraphs-view-links',
),
),
);
$operation = [
'edit',
'delete',
];
if (!empty($settings['duplicate']) && $settings['duplicate']) {
$operation[] = 'duplicate';
}
foreach ($operation as $op) {
if (!empty($settings[$op]) && entity_access($op == 'edit' ? 'update' : $op, 'paragraphs_item', $field_paragraphs)) {
if (!empty($settings[$op])) {
$setting_op = $settings[$op];
}
else {
$setting_op = $op;
}
$links['#links'][$op] = array(
'title' => t("@setting_op", array(
'@setting_op' => check_plain($setting_op),
)),
'href' => $field_paragraphs
->path() . '/' . $op,
'query' => drupal_get_destination(),
'html' => TRUE,
'attributes' => [
'title' => ucfirst(t('@op', array(
'@op' => $op,
))),
'data-toggle' => "tooltip",
],
);
if ($op == 'duplicate') {
$fied_path = 'paragraphs/' . strtr($content['#bundle'], array(
'_' => '-',
));
$links['#links'][$op]['href'] = $fied_path . '/add/' . $settings['entity_type'] . '/' . $settings['entity_id'] . '/' . $field_paragraphs->item_id;
}
$header['operations'] = t('Operations');
}
}
}
if (!empty($links['#links'])) {
$column[] = array(
'data' => $links,
'class' => "field-operations",
);
}
if ($settings['vertical'] && $delta < $max_row - 1) {
$break = array(
'data' => [
$bundle_name,
$links,
],
'class' => array(
'paragraphs_table_bundle',
),
);
if (empty($links)) {
$break['data'] = [
[
'data' => '<strong>' . $bundle_name . '</strong>',
'colspan' => 2,
],
];
}
$rows[] = $break;
}
$rows[] = array(
'data' => $column,
'class' => array(
'field-paragraphs-item',
),
);
}
// Remove header if all labels are hidden.
if (!array_filter($header)) {
$header = array();
}
$element[0] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#attributes' => array(
'class' => array(
'field-paragraphs-table-view',
drupal_clean_css_identifier('view-mode-' . $view_mode),
),
),
);
if (!empty($settings['import'])) {
$entityHost = $paragraph
->hostEntity();
$variable_link_import = [
$paragraph
->hostEntityType(),
$paragraph->field_name,
$paragraph
->hostEntityId(),
];
$title = t($settings['import']);
$attributes = [
'class' => [
'import',
],
];
global $theme;
$base_theme = drupal_find_base_themes(list_themes(), $theme);
if (!empty($base_theme['bootstrap'])) {
$title = "<i class='glyphicon glyphicon-import'></i> " . t($settings['import']);
$attributes['class'][] = 'btn btn-warning';
}
$options = [
'query' => drupal_get_destination(),
'html' => TRUE,
'attributes' => $attributes,
];
$item_list = [
'#theme' => 'item_list',
'#list_type' => 'ul',
'#items' => [
l($title, 'quick_data/import/paragraphs_item/' . implode('/', $variable_link_import), $options),
],
'#attributes' => [
'class' => [
'action-links',
],
],
];
$element[0]["#suffix"] = drupal_render($item_list);
}
if (!empty($settings['empty'])) {
_paragraphs_table_hide_empty($element[0]);
}
if (!empty($settings['datatables'])) {
drupal_add_js('https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js', 'external');
drupal_add_js('https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap.min.js', 'external');
drupal_add_js('https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js', 'external');
drupal_add_js('https://cdn.datatables.net/buttons/1.5.2/js/buttons.bootstrap.min.js', 'external');
drupal_add_js('https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js', 'external');
drupal_add_js('https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js', 'external');
drupal_add_css('https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap.min.css', 'external');
drupal_add_css('https://cdn.datatables.net/buttons/1.5.2/css/buttons.bootstrap.min.css', 'external');
drupal_add_js(drupal_get_path('module', 'paragraphs_table') . '/js/datatables.js', 'file');
}
if (!empty($settings['ajax'])) {
// @todo
}
break;
}
return $element;
}
/**
* Remove columns that are entirely empty.
*/
function _paragraphs_table_hide_empty(&$variables) {
$rows = $variables['#rows'];
$count = array();
foreach ($rows as $row_delta => $row) {
foreach ($row['data'] as $column_delta => $column) {
if (!isset($count[$column_delta])) {
$count[$column_delta] = 0;
}
if (isset($column['data']['#empty'])) {
$count[$column_delta]++;
}
}
}
foreach ($count as $column_delta => $column) {
if ($column === count($rows)) {
foreach ($rows as $row_delta => $row) {
unset($variables['#rows'][$row_delta]['data'][$column_delta]);
unset($variables['#header'][$column_delta]);
}
}
}
}
/**
* Custom function to get field value.
*/
function _paragraphs_table_get_field_value($paragraph, $field_name, $field_type) {
$items = field_get_items('paragraphs_item', $paragraph, $field_name);
$field_value = '';
if (is_array($items)) {
switch ($field_type) {
case 'taxonomy_term_reference':
foreach ($items as $item) {
$field_view = field_view_value('paragraphs_item', $paragraph, $field_name, $item);
$field_value .= $field_view['#title'] . ' ';
}
break;
case 'list_boolean':
foreach ($items as $item) {
$field_value = $item['value'];
}
break;
default:
foreach ($items as $item) {
$field_view = field_view_value('paragraphs_item', $paragraph, $field_name, $item);
$field_value .= $field_view['#markup'] . ' ';
}
break;
}
return $field_value;
}
}
/**
* Implements hook_field_widget_info().
*/
function paragraphs_table_field_widget_info() {
return array(
'paragraphs_table' => array(
'label' => t('Table'),
'field types' => array(
'paragraphs',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_NONE,
),
'settings' => array(
'nodragging' => FALSE,
'title_on_top' => TRUE,
),
),
);
}
/**
* Implements hook_field_widget_settings_form().
*/
function paragraphs_table_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
if ($widget['type'] == 'paragraphs_table') {
$form['nodragging'] = array(
'#type' => 'checkbox',
'#title' => t('Disable drag and drop'),
'#description' => t('If checked, users cannot rearrange the rows.'),
'#default_value' => $settings['nodragging'],
);
$form['title_on_top'] = array(
'#type' => 'checkbox',
'#title' => t('Display title above table'),
'#description' => t('If checked, field title will appear above the table.'),
'#default_value' => $settings['title_on_top'],
);
}
return $form;
}
/**
* Implements hook_theme().
*/
function paragraphs_table_theme($existing, $type, $theme, $path) {
$base = array(
'file' => 'theme.inc',
'path' => $path . '/theme',
);
return array(
'paragraphs_table_multiple_value_fields' => $base + array(
'render element' => 'element',
),
);
}
/**
* Implements hook_field_widget_form().
*/
function paragraphs_table_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
switch ($instance['widget']['type']) {
case 'paragraphs_table':
$instance['widget']['type'] = 'field_paragraphs_embed';
$element = paragraphs_field_multiple_value_form($field, $instance, $langcode, $items, $form, $form_state, $delta, $element);
break;
}
return $element;
}
/**
* Implements hook_field_widget_form_build().
*/
function paragraphs_table_field_widget_form_build(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$element = paragraphs_field_widget_form_build($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
return $element;
}
/**
* Implements hook_field_widget_WIDGET_TYPE_form_alter().
*/
function paragraphs_table_field_widget_paragraphs_table_form_alter(&$element, &$form_state, $context) {
$element['#theme'] = 'paragraphs_table_multiple_value_fields';
}
/**
* Returns the base path to use for pargraphs items.
*/
function paragraphs_field_get_path($field) {
if (empty($field['settings']['path'])) {
return 'paragraphs/' . strtr($field['field_name'], array(
'_' => '-',
));
}
return $field['settings']['path'];
}
/**
* Implements hook_menu().
*/
function paragraphs_table_menu() {
$items = array();
// Add menu paths for viewing/editing/deleting/duplicate paragraphs items.
foreach (field_info_fields() as $field) {
if ($field['type'] == 'paragraphs') {
$path = paragraphs_field_get_path($field);
$count = count(explode('/', $path));
$items[$path . '/%pharagraphs_item'] = array(
'page callback' => 'pharagraphs_item_page_view',
'page arguments' => array(
$count,
),
'access callback' => 'entity_access',
'access arguments' => array(
'view',
'pharagraphs',
$count,
),
'file' => 'pharagraphs_table.pages.inc',
);
$items[$path . '/%pharagraphs_item/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items[$path . '/%pharagraphs_item/edit'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'pharagraphs_item_form',
$count,
),
'access callback' => 'entity_access',
'access arguments' => array(
'update',
'pharagraphs_item',
$count,
),
'title' => 'Edit',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file' => 'pharagraphs_table.pages.inc',
);
$items[$path . '/%pharagraphs_item/duplicate'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'pharagraphs_item_add',
$count,
),
'access callback' => 'entity_access',
'access arguments' => array(
'update',
'pharagraphs_item',
$count,
),
'title' => 'Edit',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file' => 'pharagraphs_table.pages.inc',
);
$items[$path . '/%pharagraphs_item/delete'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'pharagraphs_item_delete_confirm',
$count,
),
'access callback' => 'entity_access',
'access arguments' => array(
'delete',
'pharagraphs_item',
$count,
),
'title' => 'Delete',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'file' => 'pharagraphs_table.pages.inc',
);
// Add entity type and the entity id as additional arguments.
$items[$path . '/add/%/%'] = array(
'page callback' => 'pharagraphs_item_add',
'page arguments' => array(
$field['field_name'],
$count + 1,
$count + 2,
),
// The pace callback takes care of checking access itself.
'access callback' => TRUE,
'file' => 'pharagraphs_table.pages.inc',
);
// Add menu items for dealing with revisions.
$items[$path . '/%pharagraphs_item/revisions/%pharagraphs_item_revision'] = array(
'page callback' => 'pharagraphs_item_page_view',
'page arguments' => array(
$count + 2,
),
'access callback' => 'entity_access',
'access arguments' => array(
'view',
'pharagraphs_item',
$count + 2,
),
'file' => 'pharagraphs_table.pages.inc',
);
}
}
return $items;
}