diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index 33369bd..4356141 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -374,6 +374,11 @@ field_config_base:
label: 'Default value function'
settings:
type: field.[%parent.field_type].instance_settings
+ third_party_settings:
+ type: sequence
+ label: 'Third party settings'
+ sequence:
+ - type: field_config.third_party.[%key]
field_type:
type: string
label: 'Field type'
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index 210e259..9916615 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -326,6 +326,13 @@ public function calculateDependencies() {
}
}
}
+ if ($this instanceof ThirdPartySettingsInterface) {
+ // Configuration entities need to depend on the providers of any third
+ // parties that they store the configuration for.
+ foreach ($this->getThirdPartyProviders() as $provider) {
+ $this->addDependency('module', $provider);
+ }
+ }
return $this->dependencies;
}
diff --git a/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsException.php b/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsException.php
new file mode 100644
index 0000000..7320d81
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsException.php
@@ -0,0 +1,15 @@
+checkThirdPartyArray();
+ $this->{$this->thirdPartySettingKey}[$module][$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Gets the value of a third-party setting.
+ *
+ * @param string $module
+ * The module providing the third-party setting.
+ * @param string $key
+ * The setting name.
+ * @param mixed $default
+ * The default value
+ *
+ * @return mixed
+ * The value.
+ *
+ * @throws \Drupal\Core\Config\Entity\ThirdPartySettingsException
+ * If the third party providers property is not an array.
+ */
+ public function getThirdPartySetting($module, $key, $default = NULL) {
+ $this->checkThirdPartyArray();
+ if (isset($this->{$this->thirdPartySettingKey}[$module][$key])) {
+ return $this->{$this->thirdPartySettingKey}[$module][$key];
+ }
+ else {
+ return $default;
+ }
+ }
+
+ /**
+ * Unsets a third-party setting.
+ *
+ * @param string $module
+ * The module providing the third-party setting.
+ * @param string $key
+ * The setting name.
+ *
+ * @return mixed
+ * The value.
+ *
+ * @throws \Drupal\Core\Config\Entity\ThirdPartySettingsException
+ * If the third party providers property is not an array.
+ */
+ public function unsetThirdPartySetting($module, $key) {
+ $this->checkThirdPartyArray();
+ unset($this->{$this->thirdPartySettingKey}[$module][$key]);
+ // If the third party is no longer storing any information completely remove
+ // the setting.
+ if (empty($this->{$this->thirdPartySettingKey}[$module])) {
+ unset($this->{$this->thirdPartySettingKey}[$module]);
+ }
+ return $this;
+ }
+
+ /**
+ * Gets the list of third parties that store information.
+ *
+ * @return array
+ * The list of third parties.
+ *
+ * @throws \Drupal\Core\Config\Entity\ThirdPartySettingsException
+ * If the third party providers property is not an array.
+ */
+ public function getThirdPartyProviders() {
+ $this->checkThirdPartyArray();
+ return array_keys($this->{$this->thirdPartySettingKey});
+ }
+
+ /**
+ * Checks that the third party settings property is an array.
+ *
+ * @throws \Drupal\Core\Config\Entity\ThirdPartySettingsException
+ * If the third party providers property is not an array.
+ */
+ protected function checkThirdPartyArray() {
+ if (!is_array($this->{$this->thirdPartySettingKey})) {
+ throw new ThirdPartySettingsException('Third party settings storage should be an array.');
+ }
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
index 536a4cb..0836eaf 100644
--- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
+++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
@@ -80,11 +80,6 @@ protected function checkValue($key, $value) {
$error_key = $this->configName . ':' . $key;
$element = $this->schema->get($key);
if ($element instanceof Undefined) {
- // @todo Temporary workaround for https://www.drupal.org/node/2224761.
- $key_parts = explode('.', $key);
- if (array_pop($key_parts) == 'translation_sync' && strpos($this->configName, 'field.') === 0) {
- return array();
- }
return array($error_key => 'Missing schema.');
}
diff --git a/core/lib/Drupal/Core/Field/FieldConfigBase.php b/core/lib/Drupal/Core/Field/FieldConfigBase.php
index 1d12480..189b417 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigBase.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php
@@ -8,6 +8,7 @@
namespace Drupal\Core\Field;
use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Config\Entity\ThirdPartySettingsTrait;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
@@ -16,6 +17,7 @@
* Base class for configurable field definitions.
*/
abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigInterface {
+ use ThirdPartySettingsTrait;
/**
* The instance ID.
@@ -97,6 +99,15 @@
public $settings = array();
/**
+ * Third party field-type specific settings.
+ *
+ * An arrays of key/value pairs keyed by provider.
+ *
+ * @var array
+ */
+ protected $third_party_settings = array();
+
+ /**
* Flag indicating whether the field is required.
*
* TRUE if a value for this field is required when used with this bundle,
diff --git a/core/lib/Drupal/Core/Field/FieldConfigInterface.php b/core/lib/Drupal/Core/Field/FieldConfigInterface.php
index 1207356..93c71b5 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigInterface.php
@@ -8,6 +8,7 @@
namespace Drupal\Core\Field;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
/**
* Defines an interface for configurable field definitions.
@@ -19,7 +20,7 @@
* @see \Drupal\Core\Field\Entity\BaseFieldOverride
* @see \Drupal\field\Entity\FieldInstanceConfig
*/
-interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInterface {
+interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInterface, ThirdPartySettingsInterface {
/**
* Sets the field definition label.
diff --git a/core/modules/content_translation/config/schema/content_translation.schema.yml b/core/modules/content_translation/config/schema/content_translation.schema.yml
new file mode 100644
index 0000000..6e4167e
--- /dev/null
+++ b/core/modules/content_translation/config/schema/content_translation.schema.yml
@@ -0,0 +1,12 @@
+# Schema for the Content Translation module.
+
+field_config.third_party.content_translation:
+ type: mapping
+ label: 'Content translation field settings'
+ mapping:
+ translation_sync:
+ type: sequence
+ label: 'Field properties for which to synchronize translations'
+ sequence:
+ - type: string
+ label: 'Field column for which to synchronize translations'
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index 36ac92e..86d355d 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -6,6 +6,7 @@
*/
use Drupal\Component\Utility\String;
+use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
@@ -36,14 +37,16 @@ function content_translation_field_sync_widget(FieldDefinitionInterface $field)
$default[$group] = !empty($info['translatable']) ? $group : FALSE;
}
- $settings = array('dependent_selectors' => array('instance[settings][translation_sync]' => array('file')));
+ $settings = array('dependent_selectors' => array('instance[third_party_settings][content_translation][translation_sync]' => array('file')));
- $translation_sync = $field->getSetting('translation_sync');
+ if ($field instanceof ThirdPartySettingsInterface ) {
+ $default = $field->getThirdPartySetting('content_translation', 'translation_sync', $default);
+ }
$element = array(
'#type' => 'checkboxes',
'#title' => t('Translatable elements'),
'#options' => $options,
- '#default_value' => !empty($translation_sync) ? $translation_sync : $default,
+ '#default_value' => $default,
'#attached' => array(
'library' => array(
'content_translation/drupal.content_translation.admin',
@@ -313,9 +316,32 @@ function content_translation_form_language_content_settings_submit(array $form,
}
}
}
+ if (isset($bundle_settings['translatable'])) {
+ // Store whether a bundle has translation enabled or not.
+ content_translation_set_config($entity_type_id, $bundle, 'enabled', $bundle_settings['translatable']);
+
+ // Save translation_sync settings.
+ if (!empty($bundle_settings['columns'])) {
+ foreach ($bundle_settings['columns'] as $field_name => $column_settings) {
+ $field_config = $fields[$field_name]->getConfig($bundle);
+ if ($field_config->isTranslatable()) {
+ $field_config->setThirdPartySetting('content_translation', 'translation_sync', $column_settings);
+ }
+ // If the field does not have translatable enabled we need to reset
+ // the sync settings to their defaults.
+ else {
+ $field_config->unsetThirdPartySetting('content_translation', 'translation_sync');
+ }
+ $field_config->save();
+ }
+ }
+ }
}
}
- content_translation_save_settings($settings);
+ // Ensure entity and menu router information are correctly rebuilt.
+ \Drupal::entityManager()->clearCachedDefinitions();
+ \Drupal::service('router.builder')->setRebuildNeeded();
+
drupal_set_message(t('Settings successfully updated.'));
}
diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install
index 06a355b..4aa7e73 100644
--- a/core/modules/content_translation/content_translation.install
+++ b/core/modules/content_translation/content_translation.install
@@ -88,19 +88,6 @@ function content_translation_install() {
// hook_module_implements_alter() is run among the last ones.
module_set_weight('content_translation', 10);
\Drupal::service('language_negotiator')->saveConfiguration(LanguageInterface::TYPE_CONTENT, array(LanguageNegotiationUrl::METHOD_ID => 0));
-
- $config_names = \Drupal::configFactory()->listAll(\Drupal::entityManager()->getDefinition('field_storage_config')->getConfigPrefix() . '.');
- foreach ($config_names as $name) {
- \Drupal::config($name)
- ->set('settings.translation_sync', FALSE)
- ->save();
- }
- $config_names = \Drupal::configFactory()->listAll('field.instance.');
- foreach ($config_names as $name) {
- \Drupal::config($name)
- ->set('settings.translation_sync', FALSE)
- ->save();
- }
}
/**
@@ -118,21 +105,3 @@ function content_translation_enable() {
$message = t('Enable translation for content types, taxonomy vocabularies, accounts, or any other element you wish to translate.', $t_args);
drupal_set_message($message, 'warning');
}
-
-/**
- * Implements hook_uninstall().
- */
-function content_translation_uninstall() {
- $config_names = \Drupal::configFactory()->listAll(\Drupal::entityManager()->getDefinition('field_storage_config')->getConfigPrefix() . '.');
- foreach ($config_names as $name) {
- \Drupal::config($name)
- ->clear('settings.translation_sync')
- ->save();
- }
- $config_names = \Drupal::configFactory()->listAll('field.instance.');
- foreach ($config_names as $name) {
- \Drupal::config($name)
- ->clear('settings.translation_sync')
- ->save();
- }
-}
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index d218a8d..72d5bb9 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -642,8 +642,8 @@ function content_translation_form_field_ui_field_instance_edit_form_alter(array
module_load_include('inc', 'content_translation', 'content_translation.admin');
$element = content_translation_field_sync_widget($instance);
if ($element) {
- $form['instance']['settings']['translation_sync'] = $element;
- $form['instance']['settings']['translation_sync']['#weight'] = -10;
+ $form['instance']['third_party_settings']['content_translation']['translation_sync'] = $element;
+ $form['instance']['third_party_settings']['content_translation']['translation_sync']['#weight'] = -10;
}
}
}
@@ -652,16 +652,6 @@ function content_translation_form_field_ui_field_instance_edit_form_alter(array
* Implements hook_entity_presave().
*/
function content_translation_entity_presave(EntityInterface $entity) {
- // By default no column has to be synchronized.
- // @todo Replace with own storage in https://drupal.org/node/2224761
- if ($entity->getEntityTypeId() === 'field_storage_config') {
- $entity->settings += array('translation_sync' => FALSE);
- }
- // Synchronization can be enabled per instance.
- // @todo Replace with own storage in https://drupal.org/node/2224761
- if ($entity->getEntityTypeId() === 'field_instance_config') {
- $entity->settings += array('translation_sync' => FALSE);
- }
if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
// @todo Avoid using request attributes once translation metadata become
// regular fields.
@@ -791,45 +781,3 @@ function content_translation_preprocess_language_content_settings_table(&$variab
module_load_include('inc', 'content_translation', 'content_translation.admin');
_content_translation_preprocess_language_content_settings_table($variables);
}
-
-/**
- * Stores content translation settings.
- *
- * @param array $settings
- * An associative array of settings keyed by entity type and bundle. At bundle
- * level the following keys are available:
- * - translatable: The bundle translatability status, which is a bool.
- * - columns: An associative array of translation synchronization settings
- * keyed by field names.
- */
-function content_translation_save_settings($settings) {
- foreach ($settings as $entity_type => $entity_settings) {
- foreach ($entity_settings as $bundle => $bundle_settings) {
- // The 'translatable' value is set only if it is possible to enable.
- if (isset($bundle_settings['translatable'])) {
- // Store whether a bundle has translation enabled or not.
- content_translation_set_config($entity_type, $bundle, 'enabled', $bundle_settings['translatable']);
-
- // Save translation_sync settings.
- if (!empty($bundle_settings['columns'])) {
- foreach ($bundle_settings['columns'] as $field_name => $column_settings) {
- $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name);
- if ($instance->isTranslatable()) {
- $instance->settings['translation_sync'] = $column_settings;
- }
- // If the field does not have translatable enabled we need to reset
- // the sync settings to their defaults.
- else {
- unset($instance->settings['translation_sync']);
- }
- $instance->save();
- }
- }
- }
- }
- }
-
- // Ensure entity and menu router information are correctly rebuilt.
- \Drupal::entityManager()->clearCachedDefinitions();
- \Drupal::service('router.builder')->setRebuildNeeded();
-}
diff --git a/core/modules/content_translation/src/FieldTranslationSynchronizer.php b/core/modules/content_translation/src/FieldTranslationSynchronizer.php
index 196512b..6715577 100644
--- a/core/modules/content_translation/src/FieldTranslationSynchronizer.php
+++ b/core/modules/content_translation/src/FieldTranslationSynchronizer.php
@@ -7,6 +7,7 @@
namespace Drupal\content_translation;
+use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityManagerInterface;
@@ -54,6 +55,7 @@ public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode
return;
}
+ /** @var \Drupal\Core\Field\FieldItemListInterface $items */
foreach ($entity as $field_name => $items) {
$field_definition = $items->getFieldDefinition();
$field_type_definition = $field_type_manager->getDefinition($field_definition->getType());
@@ -61,7 +63,7 @@ public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode
// Sync if the field is translatable, not empty, and the synchronization
// setting is enabled.
- if ($field_definition->isTranslatable() && !$items->isEmpty() && $translation_sync = $field_definition->getSetting('translation_sync')) {
+ if ($field_definition instanceof ThirdPartySettingsInterface && $field_definition->isTranslatable() && !$items->isEmpty() && $translation_sync = $field_definition->getThirdPartySetting('content_translation', 'translation_sync')) {
// Retrieve all the untranslatable column groups and merge them into
// single list.
$groups = array_keys(array_diff($translation_sync, array_filter($translation_sync)));
diff --git a/core/modules/content_translation/src/FieldTranslationSynchronizerInterface.php b/core/modules/content_translation/src/FieldTranslationSynchronizerInterface.php
index 0c60b18..0a5f38a 100644
--- a/core/modules/content_translation/src/FieldTranslationSynchronizerInterface.php
+++ b/core/modules/content_translation/src/FieldTranslationSynchronizerInterface.php
@@ -20,7 +20,8 @@
* Field column synchronization takes care of propagating any change in the
* field items order and in the column values themselves to all the available
* translations. This functionality is provided by defining a
- * 'translation_sync' key in the field instance settings, holding an array of
+ * 'translation_sync' key for the 'content_translation' module's portion of
+ * the field definition's 'third_party_settings', holding an array of
* column names to be synchronized. The synchronized column values are shared
* across translations, while the rest varies per-language. This is useful for
* instance to translate the "alt" and "title" textual elements of an image
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php
index 98b9540..5783ed8 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php
@@ -62,11 +62,13 @@ protected function setupTestFields() {
'field_name' => $this->fieldName,
'bundle' => $this->entityTypeId,
'label' => 'Test translatable image field',
- 'settings' => array(
- 'translation_sync' => array(
- 'file' => FALSE,
- 'alt' => 'alt',
- 'title' => 'title',
+ 'third_party_settings' => array(
+ 'content_translation' => array(
+ 'translation_sync' => array(
+ 'file' => FALSE,
+ 'alt' => 'alt',
+ 'title' => 'title',
+ ),
),
),
))->save();
@@ -87,11 +89,11 @@ function testImageFieldSync() {
// Check that the alt and title fields are enabled for the image field.
$this->drupalLogin($this->editor);
$this->drupalGet('entity_test_mul/structure/' . $this->entityTypeId . '/fields/' . $this->entityTypeId . '.' . $this->entityTypeId . '.' . $this->fieldName);
- $this->assertFieldChecked('edit-instance-settings-translation-sync-alt');
- $this->assertFieldChecked('edit-instance-settings-translation-sync-title');
+ $this->assertFieldChecked('edit-instance-third-party-settings-content-translation-translation-sync-alt');
+ $this->assertFieldChecked('edit-instance-third-party-settings-content-translation-translation-sync-title');
$edit = array(
- 'instance[settings][translation_sync][alt]' => FALSE,
- 'instance[settings][translation_sync][title]' => FALSE,
+ 'instance[third_party_settings][content_translation][translation_sync][alt]' => FALSE,
+ 'instance[third_party_settings][content_translation][translation_sync][title]' => FALSE,
);
$this->drupalPostForm(NULL, $edit, t('Save settings'));
diff --git a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
index bc72248..dacd4f2 100644
--- a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php
@@ -186,7 +186,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
// Merge incoming values into the instance.
foreach ($form_state->getValue('instance') as $key => $value) {
- $this->instance->$key = $value;
+ $this->instance->set($key, $value);
}
$this->instance->save();
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php
index 8a58798..aef8d23 100644
--- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php
@@ -280,6 +280,18 @@ public function providerCalculateDependenciesWithPluginBags() {
}
/**
+ * @covers ::calculateDependencies
+ */
+ public function testCalculateDependenciesWithThirdPartySettings() {
+ $this->entity = $this->getMockForAbstractClass('\Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithThirdPartySettings', array(array(), $this->entityTypeId));
+ $this->entity->setThirdPartySetting('test_provider', 'test', 'test');
+ $this->entity->setThirdPartySetting('test_provider2', 'test', 'test');
+ $this->entity->setThirdPartySetting($this->provider, 'test', 'test');
+
+ $this->assertEquals(array('test_provider', 'test_provider2'), $this->entity->calculateDependencies()['module']);
+ }
+
+ /**
* @covers ::setOriginalId
* @covers ::getOriginalId
*/
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php b/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php
new file mode 100644
index 0000000..9d5db7c
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php
@@ -0,0 +1,24 @@
+getRandomGenerator()->string();
+
+ $trait_object = new TestThirdPartySettingsTrait($third_party_settings_key);
+
+ // Test getThirdPartySetting() with no settings.
+ $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key, $value));
+ $this->assertNull($trait_object->getThirdPartySetting($third_party, $key));
+
+ // Test setThirdPartySetting().
+ $trait_object->setThirdPartySetting($third_party, $key, $value);
+ $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key));
+ $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key, $this->randomGenerator->string()));
+
+ // Test getThirdPartyProviders().
+ $trait_object->setThirdPartySetting('test_provider2', $key, $value);
+ $this->assertEquals(array($third_party, 'test_provider2'), $trait_object->getThirdPartyProviders());
+
+ // Test unsetThirdPartyProviders().
+ $trait_object->unsetThirdPartySetting('test_provider2', $key);
+ $this->assertEquals(array($third_party), $trait_object->getThirdPartyProviders());
+ }
+
+ public function providerTestThirdPartySettings() {
+ return array(array(NULL), array('settings'));
+ }
+
+ /**
+ * @covers ::getThirdPartySetting
+ * @covers ::setThirdPartySetting
+ * @covers ::unsetThirdPartySetting
+ * @covers ::getThirdPartyProviders
+ */
+ public function testThirdPartySettingsException() {
+ $key = 'test';
+ $third_party = 'test_provider';
+ $value = $this->getRandomGenerator()->string();
+
+ $trait_object = new TestThirdPartySettingsTrait('exception');
+ $this->assertEquals('integer', gettype($trait_object->exception));
+
+ // Test getThirdPartySetting() with no settings.
+ try {
+ $trait_object->getThirdPartySetting($third_party, $key, $value);
+ $this->fail('getThirdPartySettings throws no exception when third party storage is not an array.');
+ }
+ catch (\Exception $e) { }
+
+ // Test setThirdPartySetting().
+ try {
+ $trait_object->setThirdPartySetting($third_party, $key, $value);
+ $this->fail('setThirdPartySettings throws no exception when third party storage is not an array.');
+ }
+ catch (\Exception $e) { }
+
+ // Test getThirdPartyProviders().
+ try {
+ $trait_object->getThirdPartyProviders();
+ $this->fail('getThirdPartyProviders throws no exception when third party storage is not an array.');
+ }
+ catch (\Exception $e) { }
+
+ // Test unsetThirdPartyProviders().
+ try {
+ $trait_object->unsetThirdPartySetting('test_provider', $key);
+ $this->fail('unsetThirdPartySetting throws no exception when third party storage is not an array.');
+ }
+ catch (\Exception $e) { }
+ }
+
+}
+
+class TestThirdPartySettingsTrait {
+ use ThirdPartySettingsTrait;
+
+ public function __construct($third_party_settings_key = NULL) {
+ if ($third_party_settings_key) {
+ $this->thirdPartySettingKey = $third_party_settings_key;
+ }
+ if ($third_party_settings_key != 'exception') {
+ $this->{$this->thirdPartySettingKey} = array();
+ }
+ else {
+ $this->{$this->thirdPartySettingKey} = 12;
+ }
+ }
+
+}