You are here

scheduled_publish.module in Scheduled Publish 8.3

Same filename and directory in other branches
  1. 8 scheduled_publish.module
  2. 8.2 scheduled_publish.module

File

scheduled_publish.module
View source
<?php

/**
 * @file
 * Contains scheduled_publish.module.
 */
use Drupal\Core\Database\Database;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\scheduled_publish\Service\ScheduledPublishCron;
use Drupal\workflows\Entity\Workflow;

/**
 * Implements hook_help().
 */
function scheduled_publish_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the scheduled_publish module.
    case 'help.page.scheduled_publish':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('This module allows the user to create a scheduler for content moderation') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_cron().
 */
function scheduled_publish_cron() {

  /**
   * @var ScheduledPublishCron $scheduledPublishUpdate
   */
  $scheduledPublishUpdate = \Drupal::service('scheduled_publish.update');
  $scheduledPublishUpdate
    ->doUpdate();
}

/**
 * Get all scheduled publish fields of nodes.
 */
function scheduled_publish_get_node_fields() {
  $fields = \Drupal::service('entity_field.manager')
    ->getFieldStorageDefinitions('node');
  $scheduledFields = [];
  foreach ($fields as $fieldName => $field) {
    if (strpos($fieldName, 'field_') !== FALSE) {
      if ($field
        ->getType() === 'scheduled_publish') {
        $scheduledFields[] = $fieldName;
      }
    }
  }
  return $scheduledFields;
}

/**
 * Get all node workflow states.
 */
function scheduled_publish_get_node_workflow_states() {
  $states = [];
  $workflow_objects = Workflow::loadMultipleByType('content_moderation');
  foreach ($workflow_objects as $workflow) {
    $type_settings = $workflow
      ->get('type_settings');
    if (isset($type_settings['entity_types']['node']) && $type_settings['entity_types']['node']) {
      foreach ($type_settings['states'] as $key => $val) {
        $states[$key] = $val['label'];
      }
    }
  }
  return $states;
}

/**
 * Implements hook_views_data_alter().
 */
function scheduled_publish_views_data_alter(array &$data) {

  // Create a dynamic data entry for Views based on the
  // first available scheduled publishing field.
  $fields = scheduled_publish_get_node_fields();
  if ($fields && isset($data['node__' . $fields[0]])) {
    $field = array_shift($fields);
    $field_table = 'node__' . $field;
    $state_field = $field . '_moderation_state';
    $value_field = $field . '_value';

    // Results from the base table.
    $db_connection = Database::getConnection();
    $query = $db_connection
      ->select($field_table, 'ft');
    $query
      ->fields('ft');

    // Add results from other field tables via union.
    foreach ($fields as $key => $f_name) {
      $union = $db_connection
        ->select('node__' . $f_name, 'ft' . $key);
      $union
        ->fields('ft' . $key);
      $query
        ->union($union);
    }

    // Change values to make this have a static configuration
    // and titles different from the base entry.
    $data['scheduled_publish_dynamic']['table'] = $data[$field_table]['table'];
    unset($data['scheduled_publish_dynamic']['table']['join']['node_field_data']['table']);
    $data['scheduled_publish_dynamic']['table']['join']['node_field_data']['table formula'] = $query;
    $data['scheduled_publish_dynamic']['sp_dynamic'] = $data[$field_table][$field];
    $data['scheduled_publish_dynamic']['sp_dynamic']['title'] = 'Scheduled publish dynamic';
    $data['scheduled_publish_dynamic']['sp_dynamic']['title short'] = 'SP dynamic';
    $data['scheduled_publish_dynamic']['sp_dynamic_moderation_state'] = $data[$field_table][$state_field];
    $data['scheduled_publish_dynamic']['sp_dynamic_moderation_state']['title'] = 'Scheduled publish dynamic (moderation state)';
    $data['scheduled_publish_dynamic']['sp_dynamic_moderation_state']['title short'] = 'SP dynamic (moderation state)';
    if (isset($data[$field_table]['delta'])) {
      $data['scheduled_publish_dynamic']['delta'] = $data[$field_table]['delta'];
      $data['scheduled_publish_dynamic']['delta']['title'] = 'Scheduled publish dynamic (delta)';
      $data['scheduled_publish_dynamic']['delta']['title short'] = 'SP dynamic (delta)';
    }
    $data['scheduled_publish_dynamic']['sp_dynamic_value'] = $data[$field_table][$value_field];
    $data['scheduled_publish_dynamic']['sp_dynamic_value']['title'] = 'Scheduled publish dynamic (value)';
    $data['scheduled_publish_dynamic']['sp_dynamic_value']['title short'] = 'SP dynamic (value)';
  }
}

/**
 * Implements hook_entity_display_build_alter().
 */
function scheduled_publish_entity_display_build_alter(&$build, $context) {

  // This is necessary to display field values included in
  // scheduled_publish_views_data_alter via union.
  if ($context['view_mode'] === '_custom') {
    $fields = scheduled_publish_get_node_fields();
    $first_field = array_shift($fields);
    $components = $context['display']
      ->getComponents();
    if (isset($components[$first_field]) && !isset($build[$first_field])) {
      foreach ($fields as $field) {
        if ($context['entity']
          ->hasField($field)) {

          // Based on Drupal\Core\Entity\Entity buildMultiple() method.
          $context['display']
            ->setComponent($field, $components[$first_field]);
          $formatter = $context['display']
            ->getRenderer($field);
          $items = $context['entity']
            ->get($field);
          $items
            ->filterEmptyItems();
          $grouped_items[$context['entity']
            ->id()] = $items;
          $formatter
            ->prepareView($grouped_items);
          $field_access = $items
            ->access('view', NULL, TRUE);
          if ($context['entity'] instanceof TranslatableInterface && $context['entity']
            ->isTranslatable()) {
            $view_langcode = $context['entity']
              ->language()
              ->getId();
          }
          else {
            $view_langcode = NULL;
          }
          $build[$first_field] = $field_access
            ->isAllowed() ? $formatter
            ->view($items, $view_langcode) : [];
        }
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function scheduled_publish_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Turn scheduled publish view moderation state filter
  // into a select with available options from node workflows.
  $view = $form_state
    ->getStorage('view');
  if ($view['view']
    ->id() == 'scheduled_publish') {
    if (isset($form['moderation_state'])) {
      $options = [
        '' => t('- Any -'),
      ];
      $options = array_merge($options, scheduled_publish_get_node_workflow_states());
      $form['moderation_state']['#type'] = 'select';
      $form['moderation_state']['#options'] = $options;
      unset($form['moderation_state']['#size']);
    }
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function scheduled_publish_preprocess_views_view_table(&$variables) {

  // Adjust moderation state display to be more user-friendly.
  if ($variables['view']
    ->id() == 'scheduled_publish') {
    $states = scheduled_publish_get_node_workflow_states();
    foreach ($variables['rows'] as $key => $row) {
      if (isset($row['columns']['sp_dynamic_1']['content'][0]['field_output']['#markup'])) {
        $val = $row['columns']['sp_dynamic_1']['content'][0]['field_output']['#markup']
          ->__toString();
        if (isset($states[$val])) {
          $new_val = $states[$val] . ' (' . $val . ')';
          $variables['rows'][$key]['columns']['sp_dynamic_1']['content'][0]['field_output']['#markup'] = Markup::create($new_val);
        }
      }
    }
  }
}