Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take into consideration the date definition settings #190

Merged
merged 2 commits into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/CiviEntityStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\field\FieldStorageConfigInterface;

/**
Expand Down Expand Up @@ -164,6 +166,7 @@ protected function doLoadMultiple(array $ids = NULL) {

// get all the fields
$fields = $this->getCiviCrmApi()->getFields($this->entityType->get('civicrm_entity'));
$field_names = [];
foreach ($fields as $field) {
$field_names[] = $field['name'];
}
Expand Down Expand Up @@ -362,13 +365,15 @@ protected function initFieldValues(ContentEntityInterface $entity, array $values
// Handle if the value provided is a timestamp.
// @note: This only occurred during test migrations.
elseif (is_numeric($item[$main_property_name])) {
$item_values[$delta][$main_property_name] = (new \DateTime())->setTimestamp($item[$main_property_name])->format(DATETIME_DATETIME_STORAGE_FORMAT);
$item_values[$delta][$main_property_name] = (new \DateTime())->setTimestamp($item[$main_property_name])->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
}
else {
$datetime_format = $definition->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE ? DateTimeItemInterface::DATE_STORAGE_FORMAT : DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
// CiviCRM gives us the datetime in the users timezone (or no
// timezone at all) but Drupal expects it in UTC. So, we need to
// convert from the users timezone into UTC.
$item_values[$delta][$main_property_name] = (new \DateTime($item[$main_property_name], new \DateTimeZone(drupal_get_user_timezone())))->setTimezone(new \DateTimeZone('UTC'))->format(DATETIME_DATETIME_STORAGE_FORMAT);
$datetime_value = (new \DateTime($item[$main_property_name], new \DateTimeZone(drupal_get_user_timezone())))->setTimezone(new \DateTimeZone('UTC'))->format($datetime_format);
$item_values[$delta][$main_property_name] = $datetime_value;
}
}
$items->setValue($item_values);
Expand Down
4 changes: 2 additions & 2 deletions tests/src/Kernel/CivicrmBaseFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public function testBaseFields() {
$this->assertTrue(isset($base_fields['id']));
$this->assertEquals('integer', $base_fields['id']->getType());
$this->assertEquals('civicrm_contact', $base_fields['id']->getTargetEntityTypeId());
$this->assertTrue(isset($base_fields['title']));
$this->assertEquals('string', $base_fields['title']->getType());
$this->assertTrue(isset($base_fields['display_name']));
$this->assertEquals('string', $base_fields['display_name']->getType());
$this->assertTrue(isset($base_fields['phone_number']));
$this->assertEquals('string', $base_fields['phone_number']->getType());
$this->assertTrue(isset($base_fields['birth_date']));
Expand Down
122 changes: 112 additions & 10 deletions tests/src/Kernel/CivicrmEntityTestBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ protected function setUp() {
*/
protected function mockCiviCrmApi() {
$civicrm_api_mock = $this->prophesize(CiviCrmApiInterface::class);
$civicrm_api_mock->get('event', Argument::type('array'))->willReturn($this->sampleEventsData());
$civicrm_api_mock->get('event', [
'id' => 1,
'return' => array_keys($this->sampleEventsGetFields()),
])->willReturn($this->sampleEventsData());
$civicrm_api_mock->get('contact', [
'id' => 10,
'return' => array_keys($this->sampleContactGetFields()),
])->willReturn($this->sampleContactData());

$civicrm_api_mock->getFields('event')->willReturn($this->sampleEventsGetFields());
$civicrm_api_mock->getFields('event', 'create')->willReturn($this->sampleEventsGetFields());
$civicrm_api_mock->getFields('contact')->willReturn($this->sampleContactGetFields());
Expand Down Expand Up @@ -76,6 +84,7 @@ protected function mockCiviCrmApi() {

$civicrm_api_mock->save('event', Argument::type('array'))->willReturn(TRUE);
$civicrm_api_mock->delete('event', Argument::type('array'))->willReturn(TRUE);

$this->container->set('civicrm_entity.api', $civicrm_api_mock->reveal());
}

Expand Down Expand Up @@ -1436,17 +1445,26 @@ protected function sampleContactGetFields() {
'0' => 'contact_id',
],
],
'title' => [
'name' => 'title',
'display_name' => [
'name' => 'display_name',
'type' => 2,
'title' => 'Group Title',
'description' => 'Name of Group.',
'maxlength' => 64,
'title' => 'Display Name',
'description' => 'Formatted name representing preferred format for display/print/other output.',
'maxlength' => 128,
'size' => 30,
'table_name' => 'civicrm_group',
'entity' => 'Group',
'bao' => 'CRM_Contact_BAO_Group',
'api.required' => 1,
'where' => 'civicrm_contact.display_name',
'export' => TRUE,
'table_name' => 'civicrm_contact',
'entity' => 'Contact',
'bao' => 'CRM_Contact_BAO_Contact',
'localizable' => 0,
'html' =>
[
'type' => 'Text',
'maxlength' => 128,
'size' => 30,
],
'is_core_field' => TRUE,
],
'phone_number' => [
'name' => 'phone_number',
Expand Down Expand Up @@ -1592,6 +1610,90 @@ protected function minimalGenericGetFields() {
];
}

/**
* Provides sample contacts data.
*
* @return array
* The events data.
*/
protected function sampleContactData() {
return [
0 => [
'contact_id' => '10',
'contact_type' => 'Individual',
'contact_sub_type' => '',
'sort_name' => 'Neal, Emma',
'display_name' => 'Emma Neal',
'do_not_email' => '0',
'do_not_phone' => '0',
'do_not_mail' => '0',
'do_not_sms' => '0',
'do_not_trade' => '0',
'is_opt_out' => '0',
'legal_identifier' => '',
'external_identifier' => '',
'nick_name' => '',
'legal_name' => '',
'image_URL' => '',
'preferred_communication_method' =>
[
0 => '5',
],
'preferred_language' => '',
'preferred_mail_format' => 'Both',
'first_name' => 'Emma',
'middle_name' => '',
'last_name' => 'Neal',
'prefix_id' => '',
'suffix_id' => '',
'formal_title' => '',
'communication_style_id' => '',
'job_title' => '',
'gender_id' => '2',
'birth_date' => '1982-06-28',
'is_deceased' => '0',
'deceased_date' => '',
'household_name' => '',
'organization_name' => '',
'sic_code' => '',
'contact_is_deleted' => '0',
'current_employer' => '',
'address_id' => '36',
'street_address' => '2262 Frances Ct',
'supplemental_address_1' => '',
'supplemental_address_2' => '',
'supplemental_address_3' => '',
'city' => 'Memphis',
'postal_code_suffix' => '',
'postal_code' => '68042',
'geo_code_1' => '41.095604',
'geo_code_2' => '-96.43168',
'state_province_id' => '1026',
'country_id' => '1228',
'phone_id' => '62',
'phone_type_id' => '1',
'phone' => '(555) 555-555',
'email_id' => '62',
'email' => '[email protected]',
'on_hold' => '0',
'im_id' => '',
'provider_id' => '',
'im' => '',
'worldregion_id' => '2',
'world_region' => 'America South, Central, North and Caribbean',
'languages' => '',
'individual_prefix' => '',
'individual_suffix' => '',
'communication_style' => '',
'gender' => 'Male',
'state_province_name' => 'Nebraska',
'state_province' => 'NE',
'country' => 'United States',
'id' => '10',
],
];
}

/**
* Provides sample events data.
*
Expand Down
102 changes: 99 additions & 3 deletions tests/src/Kernel/CivicrmStorageGetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace Drupal\Tests\civicrm_entity\Kernel;

use Drupal\civicrm_entity\CiviCrmApiInterface;
use Drupal\civicrm_entity\Entity\CivicrmEntity;
use Drupal\Core\TypedData\Type\DateTimeInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;

/**
* Tests the storage.
Expand All @@ -15,15 +18,23 @@ class CivicrmStorageGetTest extends CivicrmEntityTestBase {
* Tests getting a single entity.
*/
public function testGet() {
$result = $this->container->get('civicrm_entity.api')
->get('event', ['id' => 1]);
$result = $this->container->get('civicrm_entity.api')->get('event', [
'id' => 1,
'return' => array_keys($this->sampleEventsGetFields()),
]);
$this->assertEquals('Fall Fundraiser Dinner', $result[0]['title']);

$result = $this->container->get('civicrm_entity.api')->get('contact', [
'id' => 10,
'return' => array_keys($this->sampleContactGetFields()),
]);
$this->assertEquals('Emma Neal', $result[0]['display_name']);
}

/**
* Tests loading an entity through storage.
*/
public function testLoad() {
public function testLoadEvent() {
$storage = $this->container->get('entity_type.manager')
->getStorage('civicrm_event');
$entity = $storage->load(1);
Expand All @@ -35,4 +46,89 @@ public function testLoad() {
$this->assertTrue($entity->get('is_public')->value);
}

/**
* Tests loading a contact.
*/
public function testLoadContact() {
$storage = $this->container->get('entity_type.manager')->getStorage('civicrm_contact');
$entity = $storage->load(10);
$this->assertInstanceOf(CivicrmEntity::class, $entity);
$this->assertEquals($entity->id(), 10);
$this->assertEquals($entity->get('display_name')->value, 'Emma Neal');
$this->assertEquals('1982/06/27', $entity->get('birth_date')->date->format('Y/m/d'));
}

/**
* Tests datetime fields and timezone conversions.
*
* CiviCRM stores times in the user's timezone. However Drupal assumes all
* times are in UTC. When loading a date time, CiviEntityStorage converts
* the time into UTC so that Drupal handles the timezone correctly.
*
* @dataProvider datetimeTimezoneDataProvider
*
* @param array $original_datetimes
* @param array $expected_utc_datetime
* @param $timezone
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function testDatetimeTimezone(array $original_datetimes, array $expected_utc_datetime, $timezone) {
date_default_timezone_set($timezone);
$civicrm_api_mock = $this->prophesize(CiviCrmApiInterface::class);
$civicrm_api_mock->get('event', [
'id' => 1,
'return' => array_keys($this->sampleEventsGetFields()),
])->willReturn([$original_datetimes]);

$storage = $this->container->get('entity_type.manager')
->getStorage('civicrm_event');
$entity = $storage->load(1);
foreach ($expected_utc_datetime as $field_name => $field_data) {
$this->assertEquals(
$field_data,
$entity->get($field_name)->date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);
}
}

public function datetimeTimezoneDataProvider() {
yield [
[
'start_date' => '2018-05-02 17:00:00',
'end_date' => '2018-05-04 17:00:00',
],
// America/Chicago is UTC-5
[
'start_date' => '2018-05-02T22:00:00',
'end_date' => '2018-05-04T22:00:00',
],
'America/Chicago',
];
yield [
[
'start_date' => '2018-05-02 17:00:00',
'end_date' => '2018-05-04 17:00:00',
],
[
'start_date' => '2018-05-02T17:00:00',
'end_date' => '2018-05-04T17:00:00',
],
'UTC',
];
yield [
[
'start_date' => '2018-05-02 17:00:00',
'end_date' => '2018-05-04 17:00:00',
],
// Europe/Berlin if UTC-2
[
'start_date' => '2018-05-02T15:00:00',
'end_date' => '2018-05-04T15:00:00',
],
'Europe/Berlin',
];
}

}