apigee_api_catalog-8.x-2.4/apigee_api_catalog.module
apigee_api_catalog.module
<?php /** * @file * Copyright 2019 Google Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public * License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** * @file * Module file for Apigee Edge: API Docs. */ use Drupal\apigee_api_catalog\SpecFetcherInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; /** * Implements hook_help(). */ function apigee_api_catalog_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { // Main module help for the apigee_api_catalog module. case 'help.page.apigee_api_catalog': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('Display documentation of your APIs to your developers using OpenAPI documentation.') . '</p>'; return $output; default: } } /** * Implements hook_entity_type_build(). */ function apigee_api_catalog_entity_type_build(array &$entity_types) { if (isset($entity_types['node'])) { // Add the reimport form class and link template. The route access check // makes sure it does not show up for other node types. $entity_types['node']->setFormClass('reimport_spec', '\Drupal\apigee_api_catalog\Entity\Form\ApiDocReimportSpecForm'); $entity_types['node']->setLinkTemplate('reimport-spec-form', '/node/{node}/reimport'); } } /** * Implements hook_entity_bundle_field_info_alter(). */ function apigee_api_catalog_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) { if ($entity_type->id() == 'node' && $bundle == 'apidoc' && !empty($fields['field_apidoc_file_link'])) { $fields['field_apidoc_file_link']->addConstraint('ApiDocFileLink', []); } } /** * Implements hook_ENTITY_TYPE_presave(). */ function apigee_api_catalog_node_presave(EntityInterface $entity) { /* @var \Drupal\node\NodeInterface $entity */ if ($entity->bundle() != 'apidoc') { return; } // Fetch spec file if using URL. if ($entity->get('field_apidoc_spec_file_source')->value === SpecFetcherInterface::SPEC_AS_URL) { \Drupal::service('apigee_api_catalog.spec_fetcher') ->fetchSpec($entity); } // API docs that use the "file" source will still need their md5 updated. if ($entity->get('field_apidoc_spec_file_source')->value === SpecFetcherInterface::SPEC_AS_FILE) { $spec_value = $entity->get('field_apidoc_spec')->isEmpty() ? [] : $entity->get('field_apidoc_spec')->getValue()[0]; if (!empty($spec_value['target_id'])) { /* @var \Drupal\file\Entity\File $file */ $file = \Drupal::entityTypeManager() ->getStorage('file') ->load($spec_value['target_id']); if ($file) { $entity->set('field_apidoc_spec_md5', md5_file($file->getFileUri())); } } } } /** * Implements hook_entity_operation(). */ function apigee_api_catalog_entity_operation(EntityInterface $entity) { $operations = []; if ($entity->bundle() == 'apidoc' && $entity->access('update')) { if ($entity->hasLinkTemplate('reimport-spec-form')) { $operations['reimport_spec'] = [ 'title' => t('Re-import OpenAPI spec'), 'weight' => 100, 'url' => $entity->toUrl('reimport-spec-form')->setOption('query', \Drupal::destination()->getAsArray()), ]; } } return $operations; } /** * Implements hook_ENTITY_TYPE_insert(). */ function apigee_api_catalog_node_insert(EntityInterface $entity) { apigee_api_catalog_node_update($entity); } /** * Implements hook_ENTITY_TYPE_update(). */ function apigee_api_catalog_node_update(EntityInterface $entity) { if ($entity->bundle() == 'apidoc') { $systemPath = '/node/' . $entity->id(); $langCode = $entity->language()->getId(); $exists = \Drupal::service('path_alias.manager')->getAliasByPath($systemPath, $langCode); if ($exists == $systemPath) { \Drupal::entityTypeManager()->getStorage('path_alias')->create([ 'path' => $systemPath, 'alias' => '/api/' . $entity->id(), 'langcode' => $langCode, ]) ->save(); } } } /** * Implements hook_form_FORM_ID_alter(). */ function apigee_api_catalog_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) { $node = $form_state->getFormObject()->getEntity(); if ($node->bundle() != 'apidoc') { return; } $form['field_apidoc_spec']['#states'] = [ 'visible' => [ ':input[name="field_apidoc_spec_file_source"]' => ['value' => SpecFetcherInterface::SPEC_AS_FILE], ], ]; // @todo: #states does not work on managed files. // @see: https://www.drupal.org/project/drupal/issues/2847425 $form['field_apidoc_spec']['widget'][0]['#states'] = [ 'required' => [ ':input[name="field_apidoc_spec_file_source"]' => ['value' => SpecFetcherInterface::SPEC_AS_FILE], ], ]; $form['field_apidoc_file_link']['#states'] = [ 'visible' => [ [':input[name="field_apidoc_spec_file_source"]' => ['value' => SpecFetcherInterface::SPEC_AS_URL]], ], ]; $form['field_apidoc_file_link']['widget'][0]['uri']['#states'] = [ 'required' => [ [':input[name="field_apidoc_spec_file_source"]' => ['value' => SpecFetcherInterface::SPEC_AS_URL]], ], ]; $form['#validate'][] = '_apigee_api_catalog_form_node_form_validate'; } /** * Form validator for the "apidoc" node bundle. * * @param array $form * The form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. */ function _apigee_api_catalog_form_node_form_validate(&$form, FormStateInterface $form_state) { $values = $form_state->getValues(); if (empty($values['field_apidoc_spec_file_source'])) { return; } // Make sure the field_apidoc_spec (file) or field_apidoc_file_link (link) // is not empty, according to what was selected as the file source. $source = $values['field_apidoc_spec_file_source'][0]['value'] ?: NULL; if ($source == SpecFetcherInterface::SPEC_AS_FILE && empty($values['field_apidoc_spec'][0]['fids'][0])) { $form_state->setErrorByName('field_apidoc_spec', t('Provide an OpenAPI specification file.')); } elseif ($source == SpecFetcherInterface::SPEC_AS_URL && empty($values['field_apidoc_file_link'][0]['uri'])) { $form_state->setErrorByName('field_apidoc_file_link', t('Provide the URL to an OpenAPI specification file.')); } }