View source
<?php
namespace Drupal\apigee_edge\Entity\Form;
use Apigee\Edge\Api\Management\Entity\AppCredentialInterface;
use Apigee\Edge\Exception\ApiException;
use Drupal\apigee_edge\Element\StatusPropertyElement;
use Drupal\apigee_edge\Entity\ApiProductInterface;
use Drupal\apigee_edge\Entity\AppInterface;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Utility\Error;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class AppEditForm extends AppForm {
protected $render;
public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $render) {
parent::__construct($entity_type_manager);
$this->render = $render;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('renderer'));
}
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['#cache']['contexts'][] = 'user.permissions';
$app = $this->entity;
$app_settings = $this
->config('apigee_edge.common_app_settings');
$is_multiple_selection = $app_settings
->get('multiple_products');
$api_product_def = $this->entityTypeManager
->getDefinition('api_product');
$form['name'] = [
'#type' => 'value',
'#value' => $app
->getName(),
];
$form['owner']['#access'] = FALSE;
if ($form['displayName']['widget'][0]['value']['#default_value'] === NULL) {
$form['displayName']['widget'][0]['value']['#default_value'] = $app
->getName();
}
if (isset($form['callbackUrl'])) {
$form['callbackUrl']['widget'][0]['value']['#default_value'] = $app
->getCallbackUrl();
}
if ($app_settings
->get('user_select')) {
$available_products_by_user = $this
->apiProductList($form, $form_state);
$form['credential'] = [
'#type' => 'container',
'#weight' => 100,
];
foreach ($app
->getCredentials() as $credential) {
$credential_status_element = [
'#type' => 'status_property',
'#value' => Xss::filter($credential
->getStatus()),
'#indicator_status' => $credential
->getStatus() === AppCredentialInterface::STATUS_APPROVED ? StatusPropertyElement::INDICATOR_STATUS_OK : StatusPropertyElement::INDICATOR_STATUS_ERROR,
];
$rendered_credential_status = $this->render
->render($credential_status_element);
$form['credential'][$credential
->getConsumerKey()] = [
'#type' => 'fieldset',
'#title' => $rendered_credential_status . $this
->t('Credential'),
'#collapsible' => FALSE,
];
$credential_currently_assigned_product_ids = [];
foreach ($credential
->getApiProducts() as $product) {
$credential_currently_assigned_product_ids[] = $product
->getApiproduct();
}
$credential_product_options = array_map(function (ApiProductInterface $product) {
return $product
->label();
}, $available_products_by_user + $this->entityTypeManager
->getStorage('api_product')
->loadMultiple($credential_currently_assigned_product_ids));
$form['credential'][$credential
->getConsumerKey()]['api_products'] = [
'#title' => $api_product_def
->getPluralLabel(),
'#required' => TRUE,
'#options' => $credential_product_options,
'#disabled' => !$this
->canEditApiProducts(),
];
if ($is_multiple_selection) {
$form['credential'][$credential
->getConsumerKey()]['api_products']['#default_value'] = $credential_currently_assigned_product_ids;
}
else {
if (count($credential_currently_assigned_product_ids) > 1) {
$this
->messenger()
->addWarning($this
->t('@apps now require selection of a single @api_product; multiple @api_product selection is no longer supported. Confirm your @api_product selection below.', [
'@apps' => $this
->appEntityDefinition()
->getPluralLabel(),
'@api_product' => $api_product_def
->getSingularLabel(),
]));
}
$form['credential'][$credential
->getConsumerKey()]['api_products']['#default_value'] = reset($credential_currently_assigned_product_ids) ?: NULL;
}
if ($app_settings
->get('display_as_select')) {
$form['credential'][$credential
->getConsumerKey()]['api_products']['#type'] = 'select';
$form['credential'][$credential
->getConsumerKey()]['api_products']['#multiple'] = $is_multiple_selection;
$form['credential'][$credential
->getConsumerKey()]['api_products']['#empty_value'] = '';
}
else {
if ($is_multiple_selection) {
$form['credential'][$credential
->getConsumerKey()]['api_products']['#type'] = 'checkboxes';
$form['credential'][$credential
->getConsumerKey()]['api_products']['#options'] = $credential_product_options;
}
else {
$form['credential'][$credential
->getConsumerKey()]['api_products']['#type'] = 'radios';
$form['credential'][$credential
->getConsumerKey()]['api_products']['#options'] = $credential_product_options;
}
}
}
}
return $form;
}
protected function saveAppCredentials(AppInterface $app, FormStateInterface $form_state) : ?bool {
$results = [];
$config = $this
->config('apigee_edge.common_app_settings');
if ($config
->get('user_select')) {
$app_credential_controller = $this
->appCredentialController($app
->getAppOwner(), $app
->getName());
foreach ($form_state
->getValue('credential', []) as $credential_key => $credential_changes) {
foreach ($app
->getCredentials() as $credential) {
if ($credential_key === $credential
->getConsumerKey()) {
$original_api_product_ids = [];
$new_api_product_ids = array_filter((array) $credential_changes['api_products']);
foreach ($credential
->getApiProducts() as $original_api_product) {
$original_api_product_ids[] = $original_api_product
->getApiproduct();
}
try {
$product_list_changed = FALSE;
if (array_diff($original_api_product_ids, $new_api_product_ids)) {
foreach (array_diff($original_api_product_ids, $new_api_product_ids) as $api_product_to_remove) {
$app_credential_controller
->deleteApiProduct($credential_key, $api_product_to_remove);
}
$product_list_changed = TRUE;
}
if (array_diff($new_api_product_ids, $original_api_product_ids)) {
$app_credential_controller
->addProducts($credential_key, array_values(array_diff($new_api_product_ids, $original_api_product_ids)));
$product_list_changed = TRUE;
}
if ($product_list_changed) {
$results[] = TRUE;
}
break;
} catch (ApiException $exception) {
$results[] = FALSE;
$context = [
'%app_name' => $app
->label(),
'%owner' => $app
->getAppOwner(),
'link' => $app
->toLink()
->toString(),
];
$context += Error::decodeException($exception);
$this
->logger('apigee_edge')
->error('Unable to update app credentials on app. App name: %app_name. Owner: %owner. @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
}
}
}
}
}
return empty($results) || !in_array(FALSE, $results);
}
protected function canEditApiProducts() : bool {
return $this
->currentUser()
->hasPermission('bypass api product access control') || $this
->currentUser()
->hasPermission("edit_api_products {$this->entity->getEntityTypeId()}");
}
}