You are here

lightning_api.module in Lightning API 8.3

Progressive decoupling? No problem.

File

lightning_api.module
View source
<?php

/**
 * @file
 * Progressive decoupling? No problem.
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\views\ViewEntityInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;

/**
 * Implements hook_entity_insert().
 */
function lightning_api_entity_insert(EntityInterface $entity) {
  $allowed = Drupal::config('lightning_api.settings')
    ->get('entity_json');
  if ($entity
    ->getEntityType()
    ->getBundleOf() && $allowed) {
    Drupal::service('router.builder')
      ->rebuild();
    Drupal::service('router.route_provider')
      ->reset();
  }
}

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function lightning_api_view_presave(ViewEntityInterface $view) {
  if (Drupal::isConfigSyncing()) {
    return;
  }
  elseif ($view
    ->id() === 'content' && $view
    ->isNew()) {
    $display =& $view
      ->getDisplay('default');

    // If the Operations field's 'Include destination' switch is enabled, it
    // will force every operation to have the 'destination' query parameter,
    // which breaks JSON API 2.0, causing the 'View JSON' operation to throw a
    // BadRequestHttpException.
    if (isset($display['display_options']['fields']['operations']['destination'])) {
      $display['display_options']['fields']['operations']['destination'] = FALSE;
    }
  }
}

/**
 * Determines the URL of the JSON API representation of an entity.
 *
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   The entity.
 *
 * @return \Drupal\Core\Url
 *   The URL to the JSON API representation of the entity.
 */
function lightning_api_entity_json(EntityInterface $entity) {
  $allowed = \Drupal::config('lightning_api.settings')
    ->get('entity_json');
  $uuid = $entity
    ->uuid();

  /** @var \Drupal\jsonapi\ResourceType\ResourceType $resource_type */
  $resource_type = \Drupal::service('jsonapi.resource_type.repository')
    ->get($entity
    ->getEntityTypeId(), $entity
    ->bundle());
  if ($allowed && $uuid && $resource_type) {
    $route_name = 'jsonapi.' . $resource_type
      ->getTypeName() . '.individual';

    // JSON API routes are built dynamically per entity bundle. If for whatever
    // reason the appropriate route does not exist yet, fail silently.
    // @see lightning_api_entity_insert().
    try {
      Drupal::service('router.route_provider')
        ->getRouteByName($route_name);
      return Url::fromRoute($route_name, [
        'entity' => $uuid,
      ]);
    } catch (RouteNotFoundException $e) {

      // No worries. The route will probably be built soon, most likely during
      // the next general cache rebuild.
    }
  }
}

/**
 * Implements hook_entity_operation().
 */
function lightning_api_entity_operation(EntityInterface $entity) {
  $operations = [];
  $url = lightning_api_entity_json($entity);
  if ($url) {
    $operations['view-json'] = [
      'title' => t('View JSON'),
      'url' => $url,
      'weight' => 50,
    ];
  }
  $bundle_of = $entity
    ->getEntityType()
    ->getBundleOf();
  if ($bundle_of && \Drupal::config('lightning_api.settings')
    ->get('bundle_docs')) {
    $fragment = str_replace(' ', '-', sprintf('tag/%s-%s', \Drupal::entityTypeManager()
      ->getDefinition($bundle_of)
      ->getLabel(), $entity
      ->label()));
    $route_parameters = [
      'openapi_ui' => 'redoc',
      'openapi_generator' => 'jsonapi',
    ];
    $operations['api-documentation'] = [
      'title' => t('View API documentation'),
      'url' => Url::fromRoute('openapi.documentation', $route_parameters, [
        'fragment' => $fragment,
      ]),
      'weight' => 51,
    ];
  }
  return $operations;
}

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

  // The key generation form provided by Simple OAuth doesn't generate unique
  // key names (or allow the user to override the names) and doesn't allow the
  // user to specify the location of the OpenSSL config file. Specifically, the
  // fact that the names are always the same could cause problems on systems
  // where the home directory stores keys for more than one application. So hide
  // the link to that form and users can continue to use the one provided by
  // Lightning API.
  $form['actions']['generate']['keys']['#access'] = FALSE;
}