diff --git a/composer.json b/composer.json index 2b12b780063d0a53bc88e70cd37915a3f27893e3..cf4474ec671bfaf92567f7987dc3cab0c6b46134 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "consolidation/output-formatters": "^3.2.0 || ^4.1", "lusitanian/oauth": "^0.8.11", "firebase/php-jwt": "^5.0 || ^6.0", - "drupal/address": "^1.8", + "drupal/address": "^1.8 || ^2.0", "drupal/key": "^1.14", "drupal/dynamic_entity_reference": "^1.9 || ^2.0 || ^3 || ^4", "drupal/typed_data": "^1.0-beta2", diff --git a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php index 55c24340596011c52fb09e3e582442f658a2bcb6..15face96f47e3fdbb90cded3c3b7ff133a150d14 100644 --- a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php +++ b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php @@ -194,7 +194,7 @@ class SalesforceExampleSubscriber implements EventSubscriberInterface { // Attach the new file id to the user entity. /* var \Drupal\file\FileInterface */ - if ($file = file_save_data($file_data, $destination, FileSystemInterface::EXISTS_REPLACE)) { + if ($file = \Drupal::service('file.repository')->writeData($file_data, $destination, FileSystemInterface::EXISTS_REPLACE)) { $account->user_picture->target_id = $file->id(); } else { diff --git a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php index 9fdf35341db1372bda7b677d4fcc227391b4e177..731df2768f7e6811c4d66c40b20ad768568dc8d3 100644 --- a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php +++ b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php @@ -51,9 +51,9 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase { * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, ClientInterface $httpClient, SalesforceAuthTokenStorageInterface $storage, ConfigFactoryInterface $configFactory, KeyRepositoryInterface $keyRepository, TimeInterface $time) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $httpClient, $storage, $configFactory); $this->keyRepository = $keyRepository; $this->time = $time; + parent::__construct($configuration, $plugin_id, $plugin_definition, $httpClient, $storage, $configFactory); } /** @@ -195,8 +195,9 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase { * JWT Assertion. */ protected function generateAssertion() { - $key = $this->keyRepository->getKey($this->getCredentials()->getKeyId()) - ->getKeyValue(); + $key = $this->keyRepository->getKey($this->getCredentials()->getKeyId()) ? + $this->keyRepository->getKey($this->getCredentials()->getKeyId()) + ->getKeyValue() : ''; $token = $this->generateAssertionClaim(); return JWT::encode($token, $key, 'RS256'); } diff --git a/modules/salesforce_logger/src/EventSubscriber/SalesforceLoggerSubscriber.php b/modules/salesforce_logger/src/EventSubscriber/SalesforceLoggerSubscriber.php index f60cca3a20cb6236378076f14bc7b21b6c8084a2..5457a26e027759d43cf8e24dbdd1d0d36570e029 100644 --- a/modules/salesforce_logger/src/EventSubscriber/SalesforceLoggerSubscriber.php +++ b/modules/salesforce_logger/src/EventSubscriber/SalesforceLoggerSubscriber.php @@ -31,7 +31,7 @@ class SalesforceLoggerSubscriber implements EventSubscriberInterface { * * @var \Drupal\Core\Config\ConfigFactoryInterface */ - protected $configFactory; + protected $config; /** * Create a new Salesforce Logger Subscriber. diff --git a/modules/salesforce_mapping/config/schema/salesforce_mapping.schema.yml b/modules/salesforce_mapping/config/schema/salesforce_mapping.schema.yml index bab9a2febc1f4a8e61831e5e7e3d4b08500dccc4..16b49031bc61c0581cabe93ce1094f6716f412d0 100644 --- a/modules/salesforce_mapping/config/schema/salesforce_mapping.schema.yml +++ b/modules/salesforce_mapping/config/schema/salesforce_mapping.schema.yml @@ -87,30 +87,30 @@ salesforce_mapping.salesforce_mapping.*: type: sequence label: 'Field Mappings' sequence: - - type: mapping - label: 'Field Mapping' - mapping: - drupal_field_type: - type: string - label: 'Fieldmap Type' - drupal_field_value: - type: string - label: 'Fieldmap Value' - direction: - type: string - label: 'Direction' - salesforce_field: - type: string - label: 'Salesforce Field Name' - id: - type: integer - label: 'Field Id' - drupal_constant: - type: string - label: 'Drupal Constant' - description: - type: text - label: 'Description' + type: mapping + label: 'Field Mapping' + mapping: + drupal_field_type: + type: string + label: 'Fieldmap Type' + drupal_field_value: + type: string + label: 'Fieldmap Value' + direction: + type: string + label: 'Direction' + salesforce_field: + type: string + label: 'Salesforce Field Name' + id: + type: integer + label: 'Field Id' + drupal_constant: + type: string + label: 'Drupal Constant' + description: + type: text + label: 'Description' # Schema / Config API requires that we add these: status: diff --git a/modules/salesforce_mapping/src/Plugin/Validation/Constraint/UniqueFieldsConstraintValidator.php b/modules/salesforce_mapping/src/Plugin/Validation/Constraint/UniqueFieldsConstraintValidator.php index b900cac3337237145ac5a0bc7b061ef6da16456d..39652cbcb39a52a65d066a0b852cf7e500a14936 100644 --- a/modules/salesforce_mapping/src/Plugin/Validation/Constraint/UniqueFieldsConstraintValidator.php +++ b/modules/salesforce_mapping/src/Plugin/Validation/Constraint/UniqueFieldsConstraintValidator.php @@ -2,6 +2,7 @@ namespace Drupal\salesforce_mapping\Plugin\Validation\Constraint; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Validator\Constraint; @@ -10,7 +11,7 @@ use Symfony\Component\Validator\ConstraintValidator; /** * Validates that a set of fields are unique for the given entity type. */ -class UniqueFieldsConstraintValidator extends ConstraintValidator { +class UniqueFieldsConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface { /** * The entity type manager. diff --git a/modules/salesforce_mapping_ui/src/MappedObjectList.php b/modules/salesforce_mapping_ui/src/MappedObjectList.php index edf34b46d361ab194ab824ba6c0a42693ae6e104..459df034744741b220526afc3842baa293fb9932 100644 --- a/modules/salesforce_mapping_ui/src/MappedObjectList.php +++ b/modules/salesforce_mapping_ui/src/MappedObjectList.php @@ -45,7 +45,8 @@ class MappedObjectList extends EntityListBuilder { return new static( $entity_type, $container->get('entity_type.manager')->getStorage($entity_type->id()), - $container->get('url_generator') + $container->get('url_generator'), + $container->get('date.formatter') ); } diff --git a/modules/salesforce_mapping_ui/src/Tests/SalesforceMappingCrudFormTest.php b/modules/salesforce_mapping_ui/src/Tests/SalesforceMappingCrudFormTest.php index 98c4244d30d5d30456ca8255ac50f729f7d21163..44f96515f976aa9b4f97faf44b1ce2426e559784 100644 --- a/modules/salesforce_mapping_ui/src/Tests/SalesforceMappingCrudFormTest.php +++ b/modules/salesforce_mapping_ui/src/Tests/SalesforceMappingCrudFormTest.php @@ -12,8 +12,6 @@ use Drupal\Tests\BrowserTestBase; */ class SalesforceMappingCrudFormTest extends BrowserTestBase { - use StringTranslationTrait; - /** * Default theme required for D9. * @@ -73,9 +71,9 @@ class SalesforceMappingCrudFormTest extends BrowserTestBase { 'drupal_bundle' => 'salesforce_mapping_test_content', 'salesforce_object_type' => 'Contact', ]; - $this->submitForm($post, $this->t('Save')); + $this->submitForm($post, 'Save'); $this->assertSession() - ->pageTextContainsOnce($this->t('The mapping has been successfully saved.')); + ->pageTextContainsOnce('The mapping has been successfully saved.'); $mapping = $mappingStorage->load($mapping_name); // Make sure mapping was saved correctly. @@ -92,7 +90,7 @@ class SalesforceMappingCrudFormTest extends BrowserTestBase { 'drupal_bundle' => 'salesforce_mapping_test_content', 'salesforce_object_type' => 'Contact', ]; - $this->submitForm($post, $this->t('Save')); + $this->submitForm($post, 'Save'); $this->assertSession()->fieldValueEquals('label', $post['label']); // Test simply adding a field plugin of every possible type. This is not @@ -108,7 +106,7 @@ class SalesforceMappingCrudFormTest extends BrowserTestBase { if (call_user_func([$definition['class'], 'isAllowed'], $mapping)) { // Add a new field: $post['buttons[field_type]'] = $definition['id']; - $this->submitForm($post, $this->t('Add a field mapping')); + $this->submitForm($post, 'Add a field mapping'); // Confirm that the new field shows up: $this->assertSession()->pageTextContains($definition['label']); @@ -141,9 +139,9 @@ class SalesforceMappingCrudFormTest extends BrowserTestBase { } // Confirm that form saves correctly. - $this->submitForm($post, $this->t('Save')); + $this->submitForm($post, 'Save'); $this->assertSession() - ->pageTextContainsOnce($this->t('The mapping has been successfully saved.')); + ->pageTextContainsOnce('The mapping has been successfully saved.'); // Confirm that the changes are stored properly by reloading and counting // the fields. diff --git a/src/Controller/SalesforceAuthListBuilder.php b/src/Controller/SalesforceAuthListBuilder.php index a4e02a44a526312b9a73e86901167b472ca8e0d1..6081c7cf50dd0d71b187436906678c60179b3646 100644 --- a/src/Controller/SalesforceAuthListBuilder.php +++ b/src/Controller/SalesforceAuthListBuilder.php @@ -17,16 +17,16 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder { public function buildRow(EntityInterface $entity) { /** @var \Drupal\salesforce\SalesforceAuthProviderInterface $plugin */ $plugin = $entity->getPlugin(); - $row['default'] = $entity->authManager() - ->getConfig() && $entity->authManager() - ->getConfig() - ->id() == $entity->id() - ? $this->t('Default') : ''; + $row['default'] = $entity->authManager()->getConfig()?->id == $entity->id() + ? $this->t('Default') + : ''; $row['label'] = $entity->label(); - $row['url'] = $plugin->getCredentials()->getLoginUrl(); - $row['key'] = substr($plugin->getCredentials()->getConsumerKey(), 0, 16) . '...'; - $row['type'] = $plugin->label(); - $row['status'] = $plugin->hasAccessToken() ? 'Authorized' : 'Missing'; + $row['url'] = $plugin?->getCredentials()?->getLoginUrl(); + $row['key'] = $plugin?->getCredentials()?->getConsumerKey() + ? substr($plugin?->getCredentials()?->getConsumerKey(), 0, 16) . '...' + : NULL; + $row['type'] = $plugin?->label(); + $row['status'] = $plugin?->hasAccessToken() ? 'Authorized' : 'Missing'; return $row + parent::buildRow($entity); } @@ -40,8 +40,8 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder { // Add a "revoke" action if we have a token. $operations['edit']['url'] = $entity->toUrl('edit-form'); if (!$entity instanceof SalesforceAuthConfig - || !$entity->getPlugin()->hasAccessToken() - || !$entity->hasLinkTemplate('revoke')) { + || !$entity->getPlugin()?->hasAccessToken() + || !$entity->hasLinkTemplate('revoke')) { return $operations; } // Add a "revoke" action if we have a token. diff --git a/src/Rest/RestClient.php b/src/Rest/RestClient.php index fd7b4d13c47fd72432d833b19348397b32a6e795..2d7be5e726428a2ff6efaca62c418e6749a60b0e 100644 --- a/src/Rest/RestClient.php +++ b/src/Rest/RestClient.php @@ -7,6 +7,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Logger\LoggerChannelTrait; use Drupal\Core\State\StateInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\salesforce\IdentityNotFoundException; @@ -25,6 +26,7 @@ use GuzzleHttp\Exception\RequestException; class RestClient implements RestClientInterface { use StringTranslationTrait; + use LoggerChannelTrait; /** * Response object. @@ -207,8 +209,14 @@ class RestClient implements RestClientInterface { } // If authToken is not set, try refreshing it before failing init. if (!$this->authToken) { - $this->authToken = $this->authManager->refreshToken(); - return isset($this->authToken); + try { + $this->authToken = $this->authManager->refreshToken(); + return isset($this->authToken); + } + catch (\Exception $e) { + $this->getLogger('salesforce')->error('@e', ['@e' => $e->getMessage()]); + return FALSE; + } } return TRUE; } diff --git a/src/Rest/RestResponseDescribe.php b/src/Rest/RestResponseDescribe.php index 2ee099561f034b3c5e1973ee4ae7a82615f72a4b..157c738eafed6525aea8b411e19e2f78e509a49e 100644 --- a/src/Rest/RestResponseDescribe.php +++ b/src/Rest/RestResponseDescribe.php @@ -122,6 +122,12 @@ class RestResponseDescribe extends RestResponse { protected array $urls; + protected bool $hasSubtypes; + + protected ?string $listviewable; + + protected ?string $lookupLayoutable; + // phpcs:enable /** diff --git a/src/SelectQuery.php b/src/SelectQuery.php index 95a5e5487c16bdb8d749e8c53a358ec9f3b3c600..5ac3a1368c72f26ff0d92dc4e62a9a86ee3f72ae 100644 --- a/src/SelectQuery.php +++ b/src/SelectQuery.php @@ -51,6 +51,13 @@ class SelectQuery implements SelectQueryInterface { */ public $offset; + /** + * The operator used to combine conditions, defaults to 'AND'. + * + * @var string + */ + public $conjunction; + /** * SelectQuery constructor. * @@ -59,11 +66,15 @@ class SelectQuery implements SelectQueryInterface { */ public function __construct($object_type = '') { $this->objectType = $object_type; + $this->conjunction = 'AND'; } /** * Add a condition to the query. * + * Conditions will be combined with the conjunction defined by + * $this->conjunction. Defaults to 'AND'. + * * @param string $field * Field name. * @param mixed $value @@ -100,6 +111,8 @@ class SelectQuery implements SelectQueryInterface { * Implements PHP's magic toString(). * * Function to convert the query to a string to pass to the SF API. + * Conditions will be combined with the conjunction defined by + * $this->conjunction. Defaults to 'AND'. * * @return string * SOQL query ready to be executed the SF API. @@ -116,7 +129,7 @@ class SelectQuery implements SelectQueryInterface { foreach ($this->conditions as $condition) { $where[] = implode('+', $condition); } - $query .= '+WHERE+' . implode('+AND+', $where); + $query .= '+WHERE+' . implode('+' . $this->conjunction . '+', $where); } if ($this->order) {