function apigee_edge_user_presave in Apigee Edge 8
Implements hook_user_presave().
TODO Take (configurable?) actions if a user could not be saved in Drupal but it has been in Apigee Edge.
File
- ./
apigee_edge.module, line 1276 - Copyright 2018 Google Inc.
Code
function apigee_edge_user_presave(UserInterface $account) {
// If the developer-user synchronization is in progress, then saving
// developers while saving Drupal user should be avoided.
if (_apigee_edge_is_sync_in_progress()) {
return;
}
/** @var \Drupal\apigee_edge\UserDeveloperConverterInterface $user_developer */
$user_developer = \Drupal::service('apigee_edge.converter.user_developer');
/** @var \Drupal\apigee_edge\FieldAttributeConverterInterface $field_to_attribute */
$field_to_attribute = \Drupal::service('apigee_edge.converter.field_attribute');
/** @var \Drupal\Core\Logger\LoggerChannelInterface $logger */
$logger = \Drupal::service('logger.channel.apigee_edge');
try {
/** @var \Drupal\apigee_edge\Entity\Developer $developer */
$result = $user_developer
->convertUser($account);
// There were no changes.
if ($result
->getSuccessfullyAppliedChanges() === 0) {
return;
}
// Log problems occurred meanwhile the conversion process.
foreach ($result
->getProblems() as $conversionProblem) {
$context = [
'%mail' => $account
->getEmail(),
'link' => $account
->toLink()
->toString(),
];
if ($conversionProblem instanceof UserDeveloperConversionUserFieldDoesNotExistException) {
$message = "Skipping %mail developer's %attribute_name attribute update because %field_name field does not exist.";
$context['%field_name'] = $conversionProblem
->getFieldName();
$context['%attribute_name'] = $field_to_attribute
->getAttributeName($conversionProblem
->getFieldName());
$logger
->warning($message, $context);
}
elseif ($conversionProblem instanceof UserDeveloperConversionNoStorageFormatterFoundException) {
$message = "Skipping %mail developer's %attribute_name attribute update because there is no available storage formatter for %field_type field type.";
$context['%field_type'] = $conversionProblem
->getFieldDefinition()
->getType();
$context['%attribute_name'] = $field_to_attribute
->getAttributeName($conversionProblem
->getFieldDefinition()
->getName());
$logger
->warning($message, $context);
}
else {
$logger
->warning($conversionProblem
->getMessage());
}
}
$developer = $result
->getDeveloper();
$developer
->save();
} catch (\Exception $exception) {
$previous = $exception
->getPrevious();
$context = [
'@developer' => $account
->getEmail(),
'@message' => (string) $exception,
// UID 1 (created meanwhile the install process by config_installer) is
// not a new account.
// @see \Drupal\config_installer\Form\SiteConfigureForm::submitForm()
// Also, id() returns a string not an integer.
'@operation' => $account
->isNew() || $account
->id() == 1 ? 'create' : 'update',
];
if ($previous instanceof ClientErrorException && $previous
->getEdgeErrorCode()) {
if ($previous
->getEdgeErrorCode() === Developer::APIGEE_EDGE_ERROR_CODE_DEVELOPER_DOES_NOT_EXISTS) {
\Drupal::service('logger.channel.apigee_edge')
->info('Could not update @developer developer entity because it does not exist on Apigee Edge. Automatically trying to create a new developer entity.', $context);
try {
// Forcibly mark developer entity as new to send POST request to Edge
// instead of PUT. This should be a better way then clearing
// "originalEmail" property's value on the entity.
$developer
->enforceIsNew(TRUE);
$developer
->save();
} catch (\Exception $exception) {
$context = [
'@developer' => $account
->getEmail(),
'@message' => (string) $exception,
];
$context += Error::decodeException($exception);
$logger
->error('Could not create developer entity: @developer. @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
}
}
elseif ($previous
->getEdgeErrorCode() === Developer::APIGEE_EDGE_ERROR_CODE_DEVELOPER_ALREADY_EXISTS) {
$logger
->info($previous
->getMessage());
$developer = Developer::load($account
->getEmail());
if ($developer) {
$developer_id = $developer
->getDeveloperId();
// If a user could register on the portal with an email address
// that already belongs to a developer on Apigee Edge then override
// its stored developer data there with the new one.
if (isset($account->{APIGEE_EDGE_USER_REGISTRATION_SOURCE}) && $account->{APIGEE_EDGE_USER_REGISTRATION_SOURCE} === 'user_register_form') {
$developer = $user_developer
->convertUser($account);
$developer
->setDeveloperId($developer_id);
$developer
->enforceIsNew(FALSE);
try {
$developer
->save();
} catch (ApiException $exception) {
$logger
->error("Unable to update existing @developer developer's data after registered on the portal.", $context);
}
}
}
else {
$logger
->error("Unable to save @developer developer's developer id on user.", $context);
}
}
elseif ($previous
->getEdgeErrorCode() === Developer::APIGEE_HYBRID_ERROR_CODE_DEVELOPER_EMAIL_MISMATCH) {
// Apigee X and Hybrid runtime v1.5.0 and v1.5.1 a call to change the developer's
// email address will not work so need to prevent user email update on
// Drupal as well.
// @see https://github.com/apigee/apigee-client-php/issues/153
// @see https://github.com/apigee/apigee-edge-drupal/issues/587
throw new DeveloperUpdateFailedException($account
->getEmail(), "Developer @email profile cannot be updated. " . $previous
->getMessage());
}
}
else {
$context += Error::decodeException($exception);
$logger
->error('Could not @operation developer entity: @developer. @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
}
}
}