3, 'path' => drupal_get_path('module', 'tripal_ds') . '/includes/views', ); } /** * Implements hook_menu(). * Defines all menu items needed by Tripal DS * */ function tripal_ds_menu() { $items = array(); // Adds a +Apply Tripal Display Suite option to 'Tripal Content Types' page. $items['admin/structure/bio_data/manage/%/display/apply'] = array( 'title' => 'Apply Default Tripal Layout (will reset current layout)', 'description' => t('Apply the Tripal Display Suite settings to this content type.'), 'page callback' => 'drupal_get_form', 'access arguments' => array('administer tripal'), 'page arguments' => array('tripal_ds_update_layout_form', 4), 'type' => MENU_LOCAL_ACTION, ); // Adds a +Add Tripal Pane button to 'Tripal Content Types' page. $items['admin/structure/bio_data/manage/%/display/create'] = array( 'title' => 'Create an empty Tripal Pane', 'description' => t('Create a new empty tripal pane.'), 'page callback' => 'drupal_get_form', 'access arguments' => array('administer tripal'), 'page arguments' => array('tripal_ds_pane_addition_button_form', 4), 'type' => MENU_LOCAL_ACTION, ); return $items; } /** * Implements hook_bundle_postcreate(). * * This is a Triapl defined hook and is called in the TripalBundle::create() * function to allow modules to perform tasks when a bundle is created. * * @param $bundle */ function tripal_ds_bundle_postcreate($bundle) { $bundle_name = $bundle->name; $bundle_data_table = $bundle->data_table; $instances = field_info_instances('TripalEntity', $bundle_name); if($bundle_data_table == 'pub'){ _ds_layout_pub_settings_info($bundle_name, $instances); } else { _ds_layout_settings_info($bundle_name, $instances); } } /** * Update the tripal_ds table when a tripal pane is deleted. This will remove * the link from the table of contents block. * * @param $bundle */ function tripal_ds_table_column_delete($bundle){ $bundle_name = $bundle->name; db_delete('tripal_ds') ->condition('bundle', $bundle_name, '=') ->execute(); } /** * Trigger the update to the tripal_ds table when a tripal pane is deleted. * * @param $bundle */ function tripal_ds_bundle_delete($bundle){ tripal_ds_table_column_delete($bundle); } /** * Implements hook_ds_field_settings_alter() * * Upon save field groups are reviewed so that the tripal_ds table is update and * thus the table of contents block is be updated. * * @param $field_settings * @param $form * @param $form_state */ function tripal_ds_ds_field_settings_alter(&$field_settings, $form, $form_state){ // Get the form info from the bundle about to be saved. $tripal_entity_object = $form_state['build_info']['args']['1']; // Grab the bundle. $bundle_id = $tripal_entity_object->name; // Grab the field groups from the bundle. $updated_field_groups = $form_state['field_group']; // Grab the fields from the bundle. $fields = $form_state['values']['fields']; // Delete the menu items associated with the bundle id. db_delete('tripal_ds') ->condition('bundle', $bundle_id, '=') ->execute(); // Traverse the updated field_groups grabbing the tripal pane items. $tripal_pane_field_groups = array(); $i = 0; foreach($updated_field_groups as $updated_field_group){ if($updated_field_group->format_type == 'tripalpane'){ $tripal_pane_field_groups += [ $i => $updated_field_group->group_name]; $i++; } } // Now grab the labels of the tripalpane. foreach($updated_field_groups as $updated_field_group){ foreach($tripal_pane_field_groups as $tripal_pane_field_group){ if($updated_field_group->group_name == $tripal_pane_field_group){ if($fields[$tripal_pane_field_group]['region'] !== 'hidden'){ tripal_ds_bundle_menu_item($bundle_id, $updated_field_group->label, $tripal_pane_field_group, 'tripalentity'); } } } } // Update the menu items weight. tripal_ds_toc_order($bundle_id, $form_state['values']['fields']); } /** * * Trigger the update to the tripal_ds table when a tripal pane is deleted. * * @param $bundle_name * @param $field_label * @param $field_name * @param $entity_type */ function tripal_ds_bundle_menu_item($bundle_name, $field_label, $field_name, $entity_type){ //Check the record does not already exist $tripal_ds_rows = db_select('tripal_ds', 'ds') ->fields('ds', array('tripal_ds_field_name', 'tripal_ds_field_label')) ->condition('bundle', $bundle_name, '=') ->condition('tripal_ds_field_label', $field_label, '=') ->condition('tripal_ds_field_name', $field_name, '=') ->execute()->fetchAll(); if(!empty($tripal_ds_rows)){ foreach ($tripal_ds_rows as $tripal_ds_row){ if(($field_label == $tripal_ds_row->tripal_ds_field_label) && ($field_name == $tripal_ds_row->tripal_ds_field_name) && ($bundle_name == $tripal_ds_rows->bundle)) { // Do not write the field to the table drupal_set_message("Could not update the bundle menu because that field already exists.", 'error'); } } } else { //Write to the tripal_ds table to record the new tripal pane. $field_for_table = new stdClass(); $field_for_table->tripal_ds_field_name = $field_name; $field_for_table->tripal_ds_field_label = $field_label; $field_for_table->entity_type = $entity_type; $field_for_table->bundle = $bundle_name; drupal_write_record('tripal_ds', $field_for_table); } } /** * Implements hook_ds_layout_info() to define layouts from code in a module for * display suite. * * Defines the Tripal Feature Layout option. * */ function tripal_ds_ds_layout_info() { $path = drupal_get_path('module', 'tripal_ds'); $layouts = array( 'tripal_ds_feature' => array( 'label' => t('Tripal Feature Layout'), 'path' => $path . '/theme/templates', 'regions' => array( 'left' => t('Left'), 'right' => t('Right'), ), 'css' => TRUE, ), ); return $layouts; } /** * Implements hook_form() * * Adds a confirmation message to applying default layout option in 'Manage * Display'. * * @param $form * @param $form_state * @param $bundle_name * * @return mixed */ function tripal_ds_update_layout_form($form, &$form_state, $bundle_name) { $form = array(); $form['bundle_name'] = array( '#type' => 'value', '#value' => $bundle_name, ); $bundle = tripal_load_bundle_entity(array('name' => $bundle_name)); $bundle_label = $bundle->label; return confirm_form($form, t('Please confirm you would like to apply this layout: ' . $bundle_label), 'admin/structure/bio_data/manage/' . $bundle_name . '/display', t('This action cannot be undone.'), t('Yes, apply layout'), t('No, cancel') ); } /** * Implements hook_form_submit() * * Deletes all existing settings associated with a bundle's display settings * so that the default layout is applied cleanly. * * @param $form_state * @param $form */ function tripal_ds_update_layout_form_submit($form, &$form_state) { $bundle_name = $form_state['build_info']['args'][0]; $bundle = tripal_load_bundle_entity(array('name' => $bundle_name)); //Build the identifier to check against ds_layout_settings. $ds_identifier = 'TripalEntity|'.$bundle_name.'|default'; //Check to see if the layout already exists. $result = db_select('ds_layout_settings', 'ds') ->fields('ds') ->condition('id', $ds_identifier, '=') ->execute() ->fetchField(); //Check to see if there are any field groups associated with the bundle. $result_fg = db_select('field_group', 'fg') ->fields('fg') ->condition('bundle', $bundle_name, '=') ->execute() ->fetchField(); //Check to see if there are any tripal ds fields associated with the bundle. $result_tds = db_select('tripal_ds', 'tds') ->fields('tds') ->condition('bundle', $bundle_name, '=') ->execute(); //Check to see if there are any field settings associated with the bundle. $result_fs = db_select('ds_field_settings', 'fs') ->fields('fs') ->condition('bundle', $bundle_name, '=') ->execute(); //If the layout exists, delete it. if(!empty($result)) { db_delete('ds_layout_settings') ->condition('id', $ds_identifier, '=') ->execute(); } //Then delete the field_group_fields associated with the identifier. if(!empty($result_fg)) { db_delete('field_group') ->condition('bundle', $bundle_name, '=') ->execute(); } //Then delete the ds_field_settings associated with the identifier. if(!empty($result_tds)) { db_delete('ds_field_settings') ->condition('bundle', $bundle_name, '=') ->execute(); } //Then delete the tripal_ds menu item. if(!empty($result_fs)) { db_delete('tripal_ds') ->condition('bundle', $bundle_name, '=') ->execute(); } //Now you can build the layout fresh. $instances = field_info_instances('TripalEntity', $bundle_name); $bundle_data_table = $bundle->data_table; if($bundle_data_table == 'pub'){ $success = _ds_layout_pub_settings_info($bundle_name, $instances); } else { $success = _ds_layout_settings_info($bundle_name, $instances); } if ($success) { drupal_set_message("Layout applied successfully and saved."); } else { drupal_set_message("Could not apply layout.", 'error'); } drupal_goto("admin/structure/bio_data/manage/$bundle_name/display"); } /** * Implements hook_form() * * Creates the button that creates an empty tripal pane. * * @param $form * @param $form_state * @param $bundle_name * @return mixed */ function tripal_ds_pane_addition_button_form($form, &$form_state, $bundle_name) { $form = array(); $form['bundle_name'] = array( '#type' => 'value', '#value' => $bundle_name, ); $form['field_name'] = array( '#type' => 'textfield', '#title' => t('Tripal Panel Label'), '#required' => TRUE, '#description' => "Please enter the label for the new Tripal Pane", '#size' => 20, '#maxlength' => 50, ); $bundle = tripal_load_bundle_entity(array('name' => $bundle_name)); $bundle_label = $bundle->label; return confirm_form($form, t('Please confirm you would like to create a new field for: ' . $bundle_label), 'admin/structure/bio_data/manage/' . $bundle_name . '/display', t('Create new Tripal Pane'), t('Yes'), t('No, cancel') ); } /** * Implements hook_form_submit() * * @param $form_state * @param $form */ function tripal_ds_pane_addition_button_form_submit($form, &$form_state) { $bundle_name = $form_state['build_info']['args'][0]; //Build the rest of the passed variables. $field_name = $form_state['input']['field_name']; $field_label = $form_state['input']['field_name']; tripal_ds_create_field($field_label, $field_name, $bundle_name); drupal_goto("admin/structure/bio_data/manage/$bundle_name/display"); } /** * When called the function will add field_groups to the existing tripal_ds * layout in the correct regions. * * @param $bundle_name * The name of the bundle the pane is being added to. * @param $field_name * The machine name for the field. * @param $tripal_pane_name * The machine name for the tripal pane. */ function tripal_ds_update_ds_layout($bundle_name, $field_name, $tripal_pane_name) { //Build the identifier to check against ds_layout_settings. $ds_identifier = 'TripalEntity|'.$bundle_name.'|default'; //Check to see if the layout already exists. $result = db_select('ds_layout_settings', 'ds') ->fields('ds', array('settings')) ->condition('ds.id', $ds_identifier, '=') ->execute() ->fetchObject(); //If the layout exists unserialize it. if(!empty($result)) { $layout_info = $result->settings; $layout_info = unserialize($layout_info); //Count the number of rows in the region and add the field to the region. $index = count($layout_info['regions']['right']); //Now add the tripal pane and field to the right region and field array. if(!empty($field_name)){ $layout_info['regions']['right'][$index] = $field_name; $incremented_index = $index++; $layout_info['fields'][$field_name] = 'right'; } if(!empty($tripal_pane_name)){ if(!empty($incremented_index)){ $layout_info['regions']['right'][$incremented_index] = $tripal_pane_name; $layout_info['fields'][$tripal_pane_name] = 'right'; } else { $layout_info['regions']['right'][$index] = $tripal_pane_name; $layout_info['fields'][$tripal_pane_name] = 'right'; } } //Update the ds_layout_settings table with the new layout info. drupal_write_record('ds_layout_settings', $layout_info); } } /* * Code for the view of the menu items //get tripal entity id from url then run it against tripal entity db //and grab the bundle id, then pass bundle id to view $url = current_path(); $url_exploded = explode("/", $url); $tripal_entity_id = (int)$url_exploded[1]; $result = db_select('tripal_entity', 'te') ->fields('te', array('bundle')) ->condition('id', $tripal_entity_id, '=') ->execute() ->fetchField(); */ /** * Implements hook_field_display_alter(). * Alters the display settings of a field before it gets displayed. * * Hides the empty tripal panes if the content type has been set to hide empty * fields. This option is found in the edit tab of the tripal content type with * a title 'Field Display'. * * @param $display * @param $context */ function tripal_ds_field_display_alter(&$display, $context){ if ($context['entity_type'] == 'TripalEntity') { $field_name = $context['field']['field_name']; $bundle = $context['entity']->bundle; $bundle_info = tripal_load_bundle_entity(array('name' => $bundle)); $hide_variable = tripal_get_bundle_variable('hide_empty_field', $bundle_info->id, 'hide'); if ($field_name && ($hide_variable == 'hide')) { $item = field_get_items('TripalEntity', $context['entity'], $field_name); $field = field_info_field($field_name); if ($item) { if (tripal_field_is_empty($item[0], $field)) { $parent_field_info = tripal_ds_find_field_group_parent($field_name, 'TripalEntity', $bundle, $context); if (!empty($parent_field_info)) { foreach ($parent_field_info as $parent_key => $parent_field){ // We want to use JavaScript to remove the fields rather than // CSS to hide them so that when users theme the table of // contents using CSS they aren't theming empty rows. drupal_add_js('jQuery(document).ready(function () { jQuery("#' . $parent_field_info[$parent_key] . '").parents(".views-row").remove() });', 'inline'); } } } } } } } /** * Identifies field_group parents to find tripal_panes and return that * information to the function that calls it. * * @param $field_name * @param $entity_type * @param $bundle * * @return array */ function tripal_ds_find_field_group_parent($field_name, $entity_type, $bundle, $context){ $field_groups_to_hide = array(); $increment = 0; // Get the field groups associated with this bundle. $fg_for_bundle = db_select('field_group', 'fg') ->fields('fg') ->condition('bundle', $bundle, '=') ->condition('entity_type', $entity_type, '=') ->execute()->fetchAll(); // Run through the field groups looking for the provided $field_name foreach ($fg_for_bundle as $field_groups => $field_group) { $field_group_data = unserialize($field_group->data); // There is a separate function to deal with tables, so disregard. if ($field_group_data['format_type'] == 'table'){ // Do nothing } elseif (!empty($field_group_data['children'][0])) { $children = $field_group_data['children']; //If there is more than one child all need to be checked. if (count($children) > 1) { foreach ($children as $kids => $child) { // Now check if each child if empty. $item = field_get_items('TripalEntity', $context['entity'], $child); $field = field_info_field($child); if(!tripal_field_is_empty($item[0], $field)){ //If any of the fields are not empty do not add the parent. break 2; } else { continue; } } $field_groups_to_hide[$increment] = $field_group->group_name; } elseif($children[0] == $field_name) { $field_groups_to_hide[$increment] = $field_group->group_name; } } $increment++; } // Remove duplicate values. $field_groups_to_hide = array_unique($field_groups_to_hide); return $field_groups_to_hide; } /** * Updates the tripal_ds table with weight information of field_groups on * save of "manage display' of content type. Weight is what is used to order * the menu items. * * @param $bundle * @param array $fields */ function tripal_ds_toc_order($bundle, $fields = array()){ // Find all menu items associated with the bundle id. $menu_items = db_select('tripal_ds', 'ds') ->fields('ds') ->condition('bundle', $bundle, '=') ->execute()->fetchAll(); // Now find all menu items in the $fields array foreach ($menu_items as $menu_items => $menu_item) { $toc_field_name = $menu_item->tripal_ds_field_name; // Compare the field name from the table with the fields in the array. if (array_key_exists($toc_field_name, $fields)) { $weight = $fields[$toc_field_name]['weight']; //If a weight is returned update the tripal_ds table. if(!empty($weight)){ db_update('tripal_ds') ->fields(array( 'weight' => $weight, )) ->condition('bundle', $bundle, '=') ->condition('tripal_ds_field_name', $toc_field_name, '=') ->execute(); } } } } /** * Imports all of the Tripal_DS API into scope. * * */ function tripal_ds_import_api() { module_load_include('inc', 'tripal_ds', 'api/tripal_ds.pane.api'); }