You are here

organigrams.module in Organigrams 8

Same filename and directory in other branches
  1. 8.2 organigrams.module
  2. 7 organigrams.module

Extends Taxonomy to create organigrams.

File

organigrams.module
View source
<?php

/**
 * @file
 * Extends Taxonomy to create organigrams.
 */
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\Entity\FieldConfig;
use Drupal\organigrams\Controller\OrganigramsController;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;

/**
 * Implements hook_help().
 */
function organigrams_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.organigrams':
      $help = t('Organigrams represent visualizations of hierarchies in organizations. An organigram contains multiple items which can be related in various ways to each other.');
      $help .= '<p>';
      $help .= t('Organigrams have multiple display options:');
      $help .= '<ol>';
      $help .= '<li>' . t('<strong>Dedicated page</strong><br />A dedicated page is available at <i>/organigram/%machine_name</i>.') . '</li>';
      $help .= '<li>' . t('<strong>Block</strong><br />The organigram blocks can be found on the <a href=":blocks">blocks administration page</a>.', [
        ':blocks' => Url::fromRoute('block.admin_display')
          ->toString(),
      ]) . '</li>';
      $help .= '<li>' . t('<strong>Token</strong> (requires <a href="@token_filter">Token filter</a>)<br />Tokens can be used to insert organigrams in content fields. The token names are displayed beneath the names in this list and look like this: <i>[organigrams:%machine_name]</i>. Just copy and paste this token in your content to insert the organigram.', [
        '@token_filter' => 'https://www.drupal.org/project/token_filter',
      ]) . '</li>';
      $help .= '</ol></p>';
      return '<p>' . $help . '</p>';
  }
}

/**
 * Implements hook_form_alter().
 */
function organigrams_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Alter the vocabulary form.
  if ($form_id == 'taxonomy_vocabulary_form') {

    // Get the vocabulary.
    $vocabulary = $form_state
      ->getFormObject()
      ->getEntity();

    // Get its organigrams settings if they exist.
    $organigram = $vocabulary
      ->getThirdPartySettings('organigrams');

    // Check if the current page is a vocabulary add form and if there are
    // organigrams settings.
    if (\Drupal::routeMatch()
      ->getRouteName() == 'entity.vocabulary.add_organigram_form' || !empty($organigram)) {

      // Add our own submit function to the submit button.
      foreach (array_keys($form['actions']) as $action) {
        if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
          $form['actions'][$action]['#submit'][] = 'organigrams_vocabulary_form_submit';
        }
      }

      // Change the form title when adding and editing.
      if (!empty($organigram)) {
        $form['#title'] = t('Edit organigram vocabulary');
      }
      else {
        $form['#title'] = t('Add organigram vocabulary');
      }

      // Add organigrams settings fields to the form.
      organigrams_vocabulary_settings_form($form, $organigram);
    }
  }
}

/**
 * Helper function adding custom fields to the vocabulary add form.
 *
 * @param array $form
 *   Contains the vocabulary add form.
 * @param array $organigram_settings
 *   Contains the organigrams settings.
 */
function organigrams_vocabulary_settings_form(array &$form, array $organigram_settings) {

  // Set the config path of the vocabulary fields.
  $config_path = drupal_get_path('module', 'organigrams') . '/config/vocabulary_fields';

  // Get the field config files.
  $files = \Drupal::service('file_system')
    ->scanDirectory($config_path, '/^.*\\.yml$/i', [
    'key' => 'filename',
  ]);

  // Check if there are any files.
  if (!empty($files)) {

    // Iterate through the files.
    foreach ($files as $file) {

      // Get the file content which is yaml.
      $yaml = file_get_contents($file->uri);

      // Decode the yaml.
      $field_config = Yaml::decode($yaml);

      // Check if a field group is set and if so, add it to the form.
      if (!empty($field_config['field_group']) && !isset($form[$field_config['field_group']])) {
        $form[$field_config['field_group']] = [
          '#type' => 'fieldset',
          '#title' => t($field_config['field_group']),
          '#weight' => $field_config['field_group_weight'],
        ];
      }

      // Add the field to the field group.
      $form[$field_config['field_group']][$field_config['field_name']] = [
        '#type' => $field_config['type'],
        '#title' => t($field_config['label']),
        '#description' => t($field_config['description']),
        '#weight' => $field_config['weight'],
      ];

      // Check if it is required.
      if (isset($field_config['required'])) {
        $form[$field_config['field_group']][$field_config['field_name']]['#required'] = $field_config['required'];
      }

      // Check if there are options in case it's a select element.
      if (isset($field_config['options'])) {
        $form[$field_config['field_group']][$field_config['field_name']]['#options'] = $field_config['options'];
      }

      // Set a default value.
      if (isset($organigram_settings[$field_config['field_name']])) {
        $form[$field_config['field_group']][$field_config['field_name']]['#default_value'] = $organigram_settings[$field_config['field_name']];
      }
      elseif (isset($field_config['default'])) {
        $form[$field_config['field_group']][$field_config['field_name']]['#default_value'] = $field_config['default'];
      }
    }
  }
}

/**
 * Custom submit function for the vocabulary add form.
 *
 * @param array $form
 *   Contains the vocabulary add form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Contains the form state of the vocabulary add form.
 */
function organigrams_vocabulary_form_submit(array $form, FormStateInterface $form_state) {

  // Get the vocabulary id.
  $vid = $form_state
    ->getValue('vid');

  // Create taxonomy fields.
  organigrams_create_term_fields($vid);

  // Get the vocabulary entity.
  $vocabulary = $form_state
    ->getFormObject()
    ->getEntity();

  // Check if it exists.
  if (!empty($vocabulary)) {

    // Get the form values and iterate through them.
    $form_values = $form_state
      ->getValues();
    foreach ($form_values as $key => $value) {

      // Add the field and value to the third party settings if the prefix
      // is 'organigrams_'.
      if (substr($key, 0, 12) == 'organigrams_') {
        $vocabulary
          ->setThirdPartySetting('organigrams', $key, $value);
      }
    }

    // Save the entity.
    $vocabulary
      ->save();
  }
}

/**
 * Create taxonomy fields.
 *
 * @param int $vid
 *   Contains a vocabulary id.
 */
function organigrams_create_term_fields($vid) {

  // Set the config path to the taxonomy fields.
  $config_path = drupal_get_path('module', 'organigrams') . '/config/taxonomy_fields';

  // Get the field config files.
  $files = \Drupal::service('file_system')
    ->scanDirectory($config_path, '/^.*\\.yml$/i', [
    'key' => 'filename',
  ]);

  // Check if we have files and iterate through them.
  if (!empty($files)) {
    foreach ($files as $file) {

      // The field name is the file name.
      $field_name = $file->name;

      // Try to load the field config..
      $field = FieldConfig::loadByName('taxonomy_term', $vid, $field_name);

      // If it doesn't exists, create it.
      if (!empty($field)) {
        continue;
      }

      // Get the taxonomy_term field storage.
      $field_storage = FieldStorageConfig::loadByName('taxonomy_term', $field_name);

      // Skip if not found.
      if (empty($field_storage)) {
        continue;
      }

      // Get the file content which is yaml.
      $yaml = file_get_contents($file->uri);

      // Decode the yaml.
      $field_config = Yaml::decode($yaml);

      // Add the field storage and vocabulary id to the field config.
      $field_config['field_storage'] = $field_storage;
      $field_config['bundle'] = $vid;

      // Create and save the field config.
      $field = FieldConfig::create($field_config);
      $field
        ->save();

      // Get the display repository.
      $display_repository = \Drupal::service('entity_display.repository');

      // Assign widget settings for the default form mode to display our fields.
      $display_repository
        ->getFormDisplay('taxonomy_term', $vid)
        ->setComponent($field_name, [
        'type' => $field_config['widget_type'],
        'weight' => $field_config['weight'],
      ])
        ->save();
    }
  }
}

/**
 * Implements hook_entity_type_alter().
 *
 * Add our own class to the vocabulary overview to highlight organigrams.
 */
function organigrams_entity_type_alter(array &$entity_types) {
  $entity_types['taxonomy_vocabulary']
    ->setListBuilderClass('Drupal\\organigrams\\OrganigramsListBuilder');
}

/**
 * Implements hook_token_info().
 *
 * Add organigrams as tokens.
 */
function organigrams_token_info() {
  $info = [];

  // Create new token type.
  $info['types']['organigrams'] = [
    'name' => t('Organigrams'),
    'description' => t('Token related to organigrams.'),
  ];

  // Get all vocabularies and iterate through them.
  $vocabularies = \Drupal::entityTypeManager()
    ->getStorage('taxonomy_vocabulary')
    ->loadMultiple();
  foreach ($vocabularies as $id => $vocabulary) {

    // Create a token for each vocabulary.
    $info['tokens']['organigrams'][$id] = [
      'name' => $vocabulary
        ->label(),
      'description' => t('Display the organigram :organigram', [
        ':organigram' => $vocabulary
          ->label(),
      ]),
    ];
  }
  return $info;
}

/**
 * Implements hook_tokens().
 *
 * Add content to the organigrams tokens.
 */
function organigrams_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];

  // Check if the type is organigrams.
  if ($type == 'organigrams') {

    // Iterate through the tokens.
    foreach ($tokens as $name => $original) {

      // Load the vocabulary.
      $vocabulary = \Drupal::entityTypeManager()
        ->getStorage('taxonomy_vocabulary')
        ->load($name);

      // Load the taxonomy term tree service.
      $taxonomyTermTree = \Drupal::getContainer()
        ->get('organigrams.taxonomy_term_tree');

      // Create the organigram.
      $organigramsController = new OrganigramsController($taxonomyTermTree);
      $organigram = $organigramsController
        ->viewOrganigram($vocabulary);

      // Put the organigram as value in this token.
      $replacements[$original] = render($organigram);
    }
  }
  return $replacements;
}

Functions

Namesort descending Description
organigrams_create_term_fields Create taxonomy fields.
organigrams_entity_type_alter Implements hook_entity_type_alter().
organigrams_form_alter Implements hook_form_alter().
organigrams_help Implements hook_help().
organigrams_tokens Implements hook_tokens().
organigrams_token_info Implements hook_token_info().
organigrams_vocabulary_form_submit Custom submit function for the vocabulary add form.
organigrams_vocabulary_settings_form Helper function adding custom fields to the vocabulary add form.