abstract class AppEditForm in Apigee Edge 8
Base entity form for developer- and team (company) app edit forms.
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\Core\Entity\EntityForm implements EntityFormInterface
- class \Drupal\apigee_edge\Entity\Form\FieldableEdgeEntityForm implements FieldableEdgeEntityFormInterface
- class \Drupal\apigee_edge\Entity\Form\AppForm
- class \Drupal\apigee_edge\Entity\Form\AppEditForm
- class \Drupal\apigee_edge\Entity\Form\AppForm
- class \Drupal\apigee_edge\Entity\Form\FieldableEdgeEntityForm implements FieldableEdgeEntityFormInterface
- class \Drupal\Core\Entity\EntityForm implements EntityFormInterface
Expanded class hierarchy of AppEditForm
1 file declares its use of AppEditForm
- TeamAppEditForm.php in modules/
apigee_edge_teams/ src/ Entity/ Form/ TeamAppEditForm.php
File
- src/
Entity/ Form/ AppEditForm.php, line 38
Namespace
Drupal\apigee_edge\Entity\FormView source
abstract class AppEditForm extends AppForm {
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $render;
/**
* AppEditForm constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Render\RendererInterface $render
* The renderer service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $render) {
parent::__construct($entity_type_manager);
$this->render = $render;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('renderer'));
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['#cache']['contexts'][] = 'user.permissions';
/** @var \Drupal\apigee_edge\Entity\AppInterface $app */
$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');
// Do not allow to change the (machine) name of the app.
$form['name'] = [
'#type' => 'value',
'#value' => $app
->getName(),
];
// Do not allow to change the owner of the app.
$form['owner']['#access'] = FALSE;
// If app's display name is empty then fallback to app name as default
// value just like Apigee Edge Management UI does.
if ($form['displayName']['widget'][0]['value']['#default_value'] === NULL) {
$form['displayName']['widget'][0]['value']['#default_value'] = $app
->getName();
}
// If app's callback URL field is visible on the form then set its value
// to the callback url property's value always, because it could happen that
// its value is empty if the saved value is not a valid URL.
// (Apigee Edge Management API does not validate the value of the
// callback URL, but Drupal does.)
if (isset($form['callbackUrl'])) {
$form['callbackUrl']['widget'][0]['value']['#default_value'] = $app
->getCallbackUrl();
}
// If "Let user select the product(s)" is enabled.
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,
];
// List of API product (ids/names) that the credential currently
// contains.
$credential_currently_assigned_product_ids = [];
foreach ($credential
->getApiProducts() as $product) {
$credential_currently_assigned_product_ids[] = $product
->getApiproduct();
}
// $available_products_by_user ensures that only those API products
// are visible in this list that the user can access.
// But we have to add this app credential's currently assigned API
// products to the list as well.
$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;
}
/**
* {@inheritdoc}
*/
protected function saveAppCredentials(AppInterface $app, FormStateInterface $form_state) : ?bool {
// We do not support creation of multiple app credentials on the add app
// form at this moment, but it could happen that a user edits an app
// that has multiple credentials (probably created outside of Drupal).
// This is the reason why we have to collect and summarize the result
// of the app credential changes.
$results = [];
$config = $this
->config('apigee_edge.common_app_settings');
// If a user can change associated API products on a credential.
if ($config
->get('user_select')) {
$app_credential_controller = $this
->appCredentialController($app
->getAppOwner(), $app
->getName());
// $app->getCredentials() always returns the already saved
// credentials on Apigee Edge.
// @see \Drupal\apigee_edge\Entity\DeveloperApp::getCredentials()
foreach ($form_state
->getValue('credential', []) as $credential_key => $credential_changes) {
foreach ($app
->getCredentials() as $credential) {
if ($credential_key === $credential
->getConsumerKey()) {
$original_api_product_ids = [];
// Cast it to array to be able handle the same way the single- and
// multi-select configuration.
$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;
// Remove API products from the credential.
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;
}
// Add new API products to the credential.
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;
}
// Do not add anything to the results if there were no change.
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);
}
/**
* Access check for editing API products.
*
* @return bool
* TRUE if current user can edit API products. FALSE otherwise.
*/
protected function canEditApiProducts() : bool {
return $this
->currentUser()
->hasPermission('bypass api product access control') || $this
->currentUser()
->hasPermission("edit_api_products {$this->entity->getEntityTypeId()}");
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AppEditForm:: |
protected | property | The renderer service. | |
AppEditForm:: |
protected | function | Access check for editing API products. | 1 |
AppEditForm:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
2 |
AppEditForm:: |
public | function |
Gets the actual form array to be built. Overrides AppForm:: |
1 |
AppEditForm:: |
protected | function |
Save app credentials on Apigee Edge. Overrides AppForm:: |
|
AppEditForm:: |
public | function |
AppEditForm constructor. Overrides AppForm:: |
2 |
AppForm:: |
protected | function |
Returns an array of supported actions for the current entity form. Overrides EntityForm:: |
1 |
AppForm:: |
abstract protected | function | Returns the list of API product that the user can see on the form. | |
AppForm:: |
abstract protected | function | Returns the app specific app credential controller. | 4 |
AppForm:: |
abstract protected | function | Returns the default lifetime of a created app credential. | |
AppForm:: |
abstract protected | function | Returns the developer/team (company) app entity definition. | |
AppForm:: |
abstract public static | function | Checks if the owner already has an app with the same name. | |
AppForm:: |
abstract protected | function | Returns the app owner (developer or team (company)) entity definition. | |
AppForm:: |
public | function |
Builds an updated entity object based upon the submitted form values. Overrides EntityForm:: |
|
AppForm:: |
public | function |
Determines which entity will be used by this form from a RouteMatch object. Overrides EntityForm:: |
|
AppForm:: |
protected | function | Returns the URL where the user should be redirected after form submission. | 4 |
AppForm:: |
public | function |
Form submission handler for the 'save' action. Overrides EntityForm:: |
|
AppForm:: |
protected | function | Saves the app entity on Apigee Edge. | |
AppForm:: |
protected | function | Returns the label of the Save button on the form. | 1 |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
EntityForm:: |
protected | property | The entity type manager. | 3 |
EntityForm:: |
protected | property | The module handler service. | |
EntityForm:: |
protected | property | The name of the current operation. | |
EntityForm:: |
private | property | The entity manager. | |
EntityForm:: |
protected | function | Returns the action form element for the current entity form. | |
EntityForm:: |
public | function | Form element #after_build callback: Updates the entity with submitted data. | |
EntityForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
10 |
EntityForm:: |
public | function |
Returns a string identifying the base form. Overrides BaseFormIdInterface:: |
5 |
EntityForm:: |
public | function |
Gets the form entity. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
10 |
EntityForm:: |
public | function |
Gets the operation identifying the form. Overrides EntityFormInterface:: |
|
EntityForm:: |
protected | function | Prepares the entity object before the form is built first. | 3 |
EntityForm:: |
protected | function | Invokes the specified prepare hook variant. | |
EntityForm:: |
public | function | Process callback: assigns weights and hides extra fields. | |
EntityForm:: |
public | function |
Sets the form entity. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
Sets the entity manager for this form. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
Sets the entity type manager for this form. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
Sets the module handler for this form. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
Sets the operation for this form. Overrides EntityFormInterface:: |
|
EntityForm:: |
public | function |
This is the default entity object builder function. It is called before any
other submit handler to build the new entity object to be used by the
following submit handlers. At this point of the form workflow the entity is
validated and the form state… Overrides FormInterface:: |
17 |
EntityForm:: |
public | function | ||
EntityForm:: |
public | function | ||
FieldableEdgeEntityForm:: |
protected | property |
The fieldable entity being used by this form. Overrides EntityForm:: |
|
FieldableEdgeEntityForm:: |
protected | function |
Copies top-level form values to entity properties Overrides EntityForm:: |
|
FieldableEdgeEntityForm:: |
protected | function | Flags violations for the current form. | |
FieldableEdgeEntityForm:: |
protected | function | Gets the names of all fields edited in the form. | |
FieldableEdgeEntityForm:: |
public | function |
Gets the form display. Overrides FieldableEdgeEntityFormInterface:: |
|
FieldableEdgeEntityForm:: |
protected | function |
Initialize the form state and the entity before the first form build. Overrides EntityForm:: |
|
FieldableEdgeEntityForm:: |
public | function |
Sets the form display. Overrides FieldableEdgeEntityFormInterface:: |
|
FieldableEdgeEntityForm:: |
public | function |
TODO Add missing return type-hint in 2.x. Overrides FormBase:: |
|
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |