devportal-8.x-2.0-alpha10/modules/api_reference/devportal_api_reference.install
modules/api_reference/devportal_api_reference.install
<?php
/**
* @file
* Install, update, and uninstall functions for devportal_api_reference module.
*/
use Drupal\devportal_api_reference\Exception\RuntimeException;
use Drupal\file\Entity\File;
use Drupal\filter\Entity\FilterFormat;
use Drupal\views\Entity\View;
const API_REFERENCE_FIELD_CHECK_ALLOW_REQUIRED = ['title'];
/**
* Implements hook_install().
*/
function devportal_api_reference_install(): void {
// Enable the github_flavored_markdown filter format.
// FilterFormat::load() doesn't work if using config_installer!
$config = \Drupal::configFactory()
->getEditable('filter.format.github_flavored_markdown');
$status = $config->get('status');
if ($status === FALSE) {
$config->set('status', TRUE)->save();
}
}
/**
* Implements hook_uninstall().
*/
function devportal_api_reference_uninstall() {
// Disable the github_flavored_markdown filter format.
FilterFormat::load('github_flavored_markdown')->disable()->save();
}
/**
* Implements hook_requirements().
*/
function devportal_api_reference_requirements(string $phase): array {
$requirements = [];
if ($phase !== 'runtime') {
return $requirements;
}
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
$field_manager = \Drupal::service('entity_field.manager');
/** @var \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions */
$field_definitions = $field_manager->getFieldDefinitions('node', 'api_reference');
/** @var \Drupal\devportal_api_reference\ReferenceTypeManager $reference_manager */
$reference_manager = \Drupal::service('plugin.manager.reference');
// The devportal_api_reference_fields hook take out the value of the fields
// from the submitted file. $fields is the array of the fields of an empty API
// Reference content type.
$fields = \Drupal::moduleHandler()->invokeAll(
'devportal_api_reference_fields', [
$reference_manager->createInstance('empty'),
new stdClass(),
File::create([]),
NULL,
]);
// Loop through the field definitions of the API Reference content type to check
// whether it has required fields or not. If a field is required then the label
// of the required field will be the next value of the $required_fields array.
$required_fields = [];
foreach ($field_definitions as $field_definition) {
// If the field definition is the Title then skip it, because it is the only
// required field.
// On whitelist, will be ignored anyway.
if (in_array($field_definition->getName(), API_REFERENCE_FIELD_CHECK_ALLOW_REQUIRED, TRUE)) {
continue;
}
// If the field definition isn't amongst the fields of the API Reference
// content type, so it isn't used by the api reference module then skip it.
if (!array_key_exists($field_definition->getName(), $fields)) {
continue;
}
// If the field definition is required then put its label to the
// $required_fields array.
if ($field_definition->isRequired()) {
$required_fields[] = $field_definition->getLabel();
}
}
// The API Reference content type can't have required fields, because of the
// 'Fill in the values manually' option.
$ok = count($required_fields) === 0;
$requirements['devportal_api_reference_required'] = [
'title' => t('API Reference fields are not required.'),
'value' => $ok ? t('Ok') : t('Required fields: @field_list', [
'@field_list' => implode(', ', $required_fields),
]),
'severity' => $ok ? REQUIREMENT_OK : REQUIREMENT_ERROR,
];
return $requirements;
}
/**
* Change API_Reference.Source_file field's view display to use Swagger UI.
*/
function devportal_api_reference_update_8001(): ?string {
$database = \Drupal::database();
$entity_type_manager = \Drupal::entityTypeManager();
// Start a DB transaction in order to have some hopefully meaningful rollback
// option if anything goes wrong.
$transaction = $database->startTransaction();
try {
// Dig up the entity view display settings for the API Reference CT.
/** @var \Drupal\Core\Entity\Entity\EntityViewDisplay $view_config */
$view_config = $entity_type_manager->getStorage('entity_view_display')
->load('node.api_reference.default');
$view_config_content = $view_config->get('content');
// Bail out early if Swagger UI is already being used.
if ($view_config_content['field_source_file']['type'] === 'swagger_ui_file') {
return t('No need to set Swagger UI for API Reference nodes as it was already set.');
}
// Enable the swagger_ui_formatter module in order to have the appropriate
// plugins available. TRUE stands for "also enable dependencies".
\Drupal::service('module_installer')->install(['swagger_ui_formatter'], TRUE);
// Only the Source_file field's config needs to be changed.
$view_config_content['field_source_file']['type'] = 'swagger_ui_file';
$view_config_content['field_source_file']['settings'] = [
'validator' => 'default',
'validator_url' => '',
'doc_expansion' => 'list',
'supported_submit_methods' => [
'get' => 'get',
'put' => 'put',
'post' => 'post',
'delete' => 'delete',
'options' => 'options',
'head' => 'head',
'patch' => 'patch',
],
'show_top_bar' => 0,
'sort_tags_by_name' => 0,
];
// Store the updated settings into config.
$view_config->set('content', $view_config_content);
// Update dependencies.
$dependencies = $view_config->get('dependencies');
if (!in_array('swagger_ui_formatter', $dependencies['module'], TRUE)) {
$dependencies['module'][] = 'swagger_ui_formatter';
}
$key = array_search('file', $dependencies['module'], TRUE);
if ($key !== FALSE) {
unset($dependencies['module'][$key]);
}
$view_config->set('dependencies', $dependencies);
$view_config->save();
}
// Catch any exceptions that are thrown. So we can fail somewhat nicely if a
// display plugin isn't found.
catch (\Exception $e) {
$transaction->rollBack();
\Drupal::messenger()->addError(t('@message', ['@message' => $e->getMessage()]));
watchdog_exception('devportal_api_reference', $e);
}
return t('Swagger UI enabled for API Reference nodes.');
}
/**
* Change machine name of the display of the Devportal API Reference view.
*/
function devportal_api_reference_update_8002(): ?string {
$database = \Drupal::database();
// Start a DB transaction in order to have some hopefully meaningful rollback
// option if anything goes wrong.
$transaction = $database->startTransaction();
$view_id = 'devportal_api_reference';
try {
$view = View::load($view_id);
if ($view) {
// Rename page_1 display to admin_api_reference_list.
$displays = $view->get('display');
$displays['admin_api_reference_list'] = $displays['page_1'];
unset($displays['page_1']);
$displays['admin_api_reference_list']['id'] = 'admin_api_reference_list';
$view->set('display', $displays);
$view->save();
}
else {
throw new RuntimeException("View not found: {$view_id}");
}
}
catch (Exception $e) {
// Catch any exceptions that are thrown.
$transaction->rollBack();
\Drupal::messenger()->addError($e->getMessage());
watchdog_exception($view_id, $e);
}
return t('Fixed machine name of the display of the Devportal API Reference view.');
}
