SU-SWS/stanford_publication

View on GitHub
stanford_publication.module

Summary

Maintainability
Test Coverage
<?php

/**
 * @file
 * stanford_publication.module
 */

use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
use Drupal\stanford_publication\Entity\CitationInterface;
use Drupal\views\ViewExecutable;
use Symfony\Component\Finder\Finder;

/**
 * Implements hook_library_info_build().
 */
function stanford_publication_library_info_build() {
  $libraries = [];
  $module_path = drupal_get_path('module', 'stanford_publication');

  // Find all css files in the dist/css directory.
  $finder = new Finder();
  $finder->in("$module_path/dist/css")
    ->files()
    ->name('/.css$/');

  foreach ($finder->getIterator() as $file) {
    $local_path = str_replace("$module_path/", '', $file->getPath());

    $path_parts = explode('/', $local_path);
    // Remove `dist` and `css` parts.
    unset($path_parts[0], $path_parts[1]);

    // This is the directory the file lives in.
    $library_level = reset($path_parts);
    $bucket = next($path_parts);
    $lib = basename($file->getFilename(), '.css');

    // Build the library definition.
    $libraries[trim("$bucket.$lib", '. ')] = [
      'css' => [
        $library_level => [
          "$local_path/{$file->getFileName()}" => [],
        ],
      ],
    ];
  }
  return $libraries;
}

/**
 * Implements hook_entity_extra_field_info().
 */
function stanford_publication_entity_extra_field_info() {
  $extra['node']['stanford_publication']['display']['citation_type'] = [
    'label' => t('Publication Type'),
    'visible' => FALSE,
  ];

  return $extra;
}

/**
 * Implements hook_entity_view().
 */
function stanford_publication_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if (
    $entity instanceof NodeInterface &&
    $entity->bundle() == 'stanford_publication' &&
    $display->getComponent('citation_type') &&
    $citation = _stanford_pubs_get_citation_entity($entity)
  ) {
    $citation_type = \Drupal::entityTypeManager()
      ->getStorage('citation_type')
      ->load($citation->bundle());

    $citation_type = $citation_type->label() == 'Other' ? 'Publication' : $citation_type->label();
    $build['citation_type'] = [
      '#type' => 'markup',
      '#markup' => $citation_type,
    ];
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function stanford_publication_form_taxonomy_overview_terms_alter(&$form, FormStateInterface $form_state) {
  if ($form_state->get('taxonomy')['vocabulary']->id() == 'stanford_publication_topics') {
    $form['citation_format'] = [
      '#type' => 'select',
      '#title' => t('Citation Format'),
      '#description' => t('Change the citation format for the publication items displayed on the taxonomy pages.'),
      '#options' => [
        'apa' => 'APA',
        'chicago' => t('Chicago'),
      ],
      '#default_value' => \Drupal::state()->get('stanford_publication.citation_format', 'chicago'),
    ];
    $form['#submit'][] = '_stanford_publication_term_overview_submit';
  }
}

/**
 * Taxonomy term overview form submit to save the citation format value.
 *
 * @param array $form
 *   Complete form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Submitted form state.
 */
function _stanford_publication_term_overview_submit(array $form, FormStateInterface $form_state) {
  $state = \Drupal::state();
  if ($state->get('stanford_publication.citation_format') != $form_state->getValue('citation_format')) {
    $state->set('stanford_publication.citation_format', $form_state->getValue('citation_format'));
    Cache::invalidateTags(['citation_view']);
  }
}

/**
 * Implements hook_entity_view_mode_alter().
 */
function stanford_publication_entity_view_mode_alter(&$view_mode, EntityInterface $entity) {
  if (
    $entity instanceof CitationInterface &&
    \Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical'
  ) {
    // Change the view mode on taxonomy term pages to what the user chose in the
    // term overview page.
    $view_mode = \Drupal::state()
      ->get('stanford_publication.citation_format', $view_mode);
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function stanford_publication_preprocess_node(&$variables) {
  if (!isset($variables['page']) || !$variables['page']) {
    return;
  }

  if (isset($variables['node']) && $variables['node'] instanceof NodeInterface && $variables['node']->bundle() == 'stanford_publication') {
    $variables['#attached']['library'][] = 'stanford_publication/node.stanford_publication';
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function stanford_publication_preprocess_menu__stanford_publication_topics(&$variables) {
  $variables['#attached']['library'][] = 'stanford_publication/menu.taxonomy_menu';
  $variables['#attached']['library'][] = 'stanford_publication/taxonomy_menu';
}

/**
 * Implements hook_views_pre_render().
 */
function stanford_publication_views_pre_render(ViewExecutable $view) {
  if ($view->id() == 'stanford_publications') {
    $view->element['#attached']['library'][] = 'stanford_publication/views.stanford_publication';
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function stanford_publication_node_insert(NodeInterface $entity) {
  _stanford_publication_node_post_save($entity);
}

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function stanford_publication_node_update(NodeInterface $entity) {
  _stanford_publication_node_post_save($entity);
}

/**
 * After the publication node is saved, save some data to the citation entity.
 *
 * @param \Drupal\node\NodeInterface $entity
 *   Node entity object.
 */
function _stanford_publication_node_post_save(NodeInterface $entity) {
  $citation_entity = _stanford_pubs_get_citation_entity($entity);
  $original_title = '';
  if (isset($entity->original) && $entity->original->id()) {
    $original_title = $entity->original->label();
  }

  if (!$citation_entity) {
    return;
  }
  if (empty($citation_entity->label()) || $citation_entity->label() == $original_title) {
    $citation_entity->setLabel($entity->label());
  }
  // Set the entity label to the node label & save the parent entity info.
  $citation_entity->setParentEntity($entity, 'su_publication_citation')
    ->save();
}

/**
 * Implements hook_ENTITY_TYPE_delete().
 */
function stanford_publication_node_delete(NodeInterface $entity) {
  if ($citation_entity = _stanford_pubs_get_citation_entity($entity)) {
    // Clean up nested Citation entity after node deletion.
    $citation_entity->delete();
  }
}

/**
 * Implements hook_field_widget_form_alter().
 */
function stanford_publication_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
  if (!isset($context['items']) || !($context['items'] instanceof FieldItemListInterface)) {
    return;
  }

  // Change the help text on the title field of the citation entity form.
  if (
    $context['items']->getName() == 'title' &&
    $context['items']->getEntity()->getEntityTypeId() == 'citation'
  ) {
    $element['value']['#description'] = t('The title of the Publication');
  }

  if ($context['items']->getName() == 'su_publication_citation') {

    // Tweak the "Add New" button on the inline entity form.
    if (!empty($element['actions']['ief_add'])) {
      /** @var \Drupal\Core\StringTranslation\TranslatableMarkup $button_value */
      $button_value = $element['actions']['ief_add']['#value'];
      $element['actions']['ief_add']['#value'] = t('Add @type_singular', $button_value->getArguments(), $button_value->getOptions());
    }

    // Add the citation bundle name to the top for quick reference.
    if (!empty($element['form']['inline_entity_form'])) {
      $entity_type = $element['form']['inline_entity_form']['#entity_type'];
      $bundle = $element['form']['inline_entity_form']['#bundle'];
      /** @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_service */
      $bundle_service = \Drupal::service('entity_type.bundle.info');
      $bundle_name = $bundle_service->getBundleInfo($entity_type)[$bundle]['label'];
      $element['form']['inline_entity_form']['#prefix'] = "$bundle_name - {$element['#title']}";
    }
  }
}

/**
 * Load the Citation entity from the node that has the citation data.
 *
 * @param \Drupal\node\NodeInterface $node
 *   Node entity.
 *
 * @return \Drupal\stanford_publication\Entity\CitationInterface|null|void
 *   Loaded entity from the node field value.
 *
 * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
 * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
 * @throws \Drupal\Core\TypedData\Exception\MissingDataException
 */
function _stanford_pubs_get_citation_entity(NodeInterface $node) {
  if ($node->bundle() !== 'stanford_publication') {
    return NULL;
  }

  $citation_field = 'su_publication_citation';
  if (
    $node->hasField($citation_field) &&
    $node->get($citation_field)->count()
  ) {
    $value = $node->get($citation_field)->get(0)->getValue();
    $citation_id = $value['target_id'];

    return \Drupal::entityTypeManager()
      ->getStorage('citation')
      ->load($citation_id);
  }
}