You are here

swagger_ui_formatter.module in Swagger UI Field Formatter 8.2

Main module file for Swagger UI Field Formatter.

File

swagger_ui_formatter.module
View source
<?php

/**
 * @file
 * Main module file for Swagger UI Field Formatter.
 */
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\DomCrawler\Crawler;

/**
 * Swagger UI library path related cache ID.
 */
const SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID = 'swagger_ui_formatter:library_path';

/**
 * Swagger UI SVG definition related cache ID.
 */
const SWAGGER_UI_FORMATTER_SVG_DEFINITION_CID = 'swagger_ui_formatter:svg_definition';

/**
 * Implements hook_theme().
 */
function swagger_ui_formatter_theme($existing, $type, $theme, $path) {
  return [
    'swagger_ui_field_item' => [
      'variables' => [
        'field_name' => NULL,
        'delta' => NULL,
      ],
    ],
  ];
}

/**
 * Implements hook_library_info_build().
 */
function swagger_ui_formatter_library_info_build() {
  $libraries = [];
  if ($library_path = _swagger_ui_formatter_get_library_path()) {

    // Library definition for required Swagger UI files.
    $libraries['swagger_ui_formatter.swagger_ui'] = [
      'version' => _swagger_ui_formatter_get_library_version(),
      'css' => [
        'theme' => [
          $library_path . '/dist/swagger-ui.css' => [
            'minified' => TRUE,
          ],
        ],
      ],
      'js' => [
        $library_path . '/dist/swagger-ui-bundle.js' => [
          'minified' => TRUE,
        ],
        $library_path . '/dist/swagger-ui-standalone-preset.js' => [
          'minified' => TRUE,
        ],
      ],
    ];

    // Library definition for Swagger UI integration.
    $libraries['swagger_ui_formatter.swagger_ui_integration'] = [
      'version' => '1.0',
      'js' => [
        'js/swagger-ui-formatter.js' => [],
      ],
      'dependencies' => [
        'core/drupal',
        'core/jquery',
        'core/jquery.once',
        'core/drupalSettings',
      ],
    ];
  }
  return $libraries;
}

/**
 * Helper function to determine the Swagger UI library path.
 *
 * @return string|bool
 *   Returns the library path or FALSE if the library is not found.
 */
function _swagger_ui_formatter_get_library_path() {
  if ($cache = \Drupal::cache()
    ->get(SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID)) {
    return $cache->data;
  }
  else {
    foreach ([
      '/libraries/swagger-ui',
      '/libraries/swagger_ui',
    ] as $library_dir) {
      if (_swagger_ui_formatter_is_library_directory($library_dir)) {
        \Drupal::cache()
          ->set(SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID, $library_dir, CacheBackendInterface::CACHE_PERMANENT, [
          SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID,
        ]);
        return $library_dir;
      }
    }
    return FALSE;
  }
}

/**
 * Helper function to check where the Swagger UI library is installed.
 *
 * @param string $library_dir
 *   The directory name which contains the Swagger UI library.
 *
 * @return bool
 *   Returns TRUE if the Swagger UI library is installed under the given
 *   directory. Returns FALSE otherwise.
 */
function _swagger_ui_formatter_is_library_directory($library_dir) {
  $files_to_check = [
    'package.json',
    'dist/swagger-ui.css',
    'dist/swagger-ui-bundle.js',
    'dist/swagger-ui-standalone-preset.js',
  ];
  foreach ($files_to_check as $file) {
    if (!file_exists(DRUPAL_ROOT . $library_dir . '/' . $file)) {
      return FALSE;
    }
  }
  return TRUE;
}

/**
 * Gets Swagger UI library version information.
 *
 * @return string
 *   The library version or an empty string if the version cannot be determined.
 */
function _swagger_ui_formatter_get_library_version() {
  if ($library_path = _swagger_ui_formatter_get_library_path()) {
    $file = DRUPAL_ROOT . $library_path . '/package.json';
    if (!file_exists($file)) {
      return '';
    }
    $content = file_get_contents($file);
    if (!$content) {
      return '';
    }
    $data = Json::decode($content);
    if (isset($data['version'])) {
      return $data['version'];
    }
  }
  return '';
}

/**
 * Gets Swagger UI related SVG definition.
 *
 * Since Swagger UI v3.13.4 there is no need to include the <svg> tag in HTML.
 *
 * @see https://github.com/swagger-api/swagger-ui/releases/tag/v3.13.4
 *
 * @return string|null
 *   The required <svg> tag as a HTML string or NULL if it doesn't exist.
 */
function _swagger_ui_formatter_get_svg_definition() {
  if ($cache = \Drupal::cache()
    ->get(SWAGGER_UI_FORMATTER_SVG_DEFINITION_CID)) {
    return $cache->data;
  }
  $library_path = _swagger_ui_formatter_get_library_path();
  if ($library_path && file_exists(DRUPAL_ROOT . $library_path . '/dist/index.html')) {
    $dom_crawler = new Crawler(file_get_contents(DRUPAL_ROOT . $library_path . '/dist/index.html'));
    $dom_crawler = $dom_crawler
      ->filterXPath('descendant-or-self::body/svg');
    if ($domElement = $dom_crawler
      ->getNode(0)) {
      $svg = $domElement->ownerDocument
        ->saveHTML($domElement);
      \Drupal::cache()
        ->set(SWAGGER_UI_FORMATTER_SVG_DEFINITION_CID, $svg);
      return $svg;
    }
  }
  return NULL;
}

/**
 * Implements hook_help().
 */
function swagger_ui_formatter_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.swagger_ui_formatter':
      $readme = file_get_contents(__DIR__ . '/README.txt');
      $output = '';

      // If the Markdown module is installed, use it to render the README.
      if ($readme && \Drupal::moduleHandler()
        ->moduleExists('markdown') === TRUE) {
        $filter_manager = \Drupal::service('plugin.manager.filter');
        $settings = \Drupal::configFactory()
          ->get('markdown.settings')
          ->getRawData();
        $filter = $filter_manager
          ->createInstance('markdown', [
          'settings' => $settings,
        ]);
        $output = $filter
          ->process($readme, 'en');
      }
      elseif ($readme) {
        $output = '<pre>' . $readme . '</pre>';
      }

      // Add a link to the Drupal.org project.
      $output .= '<p>';
      $output .= t('Visit the <a href=":project_link">project page</a> on Drupal.org for more information.', [
        ':project_link' => 'https://www.drupal.org/project/swagger_ui_formatter',
      ]);
      $output .= '</p>';
      return $output;
  }
}

/**
 * Implements hook_cache_flush().
 */
function swagger_ui_formatter_cache_flush() {
  \Drupal::cache()
    ->invalidate(SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID);
  \Drupal::cache()
    ->invalidate(SWAGGER_UI_FORMATTER_SVG_DEFINITION_CID);
}

Functions

Namesort descending Description
swagger_ui_formatter_cache_flush Implements hook_cache_flush().
swagger_ui_formatter_help Implements hook_help().
swagger_ui_formatter_library_info_build Implements hook_library_info_build().
swagger_ui_formatter_theme Implements hook_theme().
_swagger_ui_formatter_get_library_path Helper function to determine the Swagger UI library path.
_swagger_ui_formatter_get_library_version Gets Swagger UI library version information.
_swagger_ui_formatter_get_svg_definition Gets Swagger UI related SVG definition.
_swagger_ui_formatter_is_library_directory Helper function to check where the Swagger UI library is installed.

Constants

Namesort descending Description
SWAGGER_UI_FORMATTER_LIBRARY_PATH_CID Swagger UI library path related cache ID.
SWAGGER_UI_FORMATTER_SVG_DEFINITION_CID Swagger UI SVG definition related cache ID.