- Issue created by @kenorb
- πΊπΈUnited States markusa
Website is a separate CiviCRM Entity. There is no url provided by the API, so we don't have a property. All the fields returned by an entity type's 'getfields' call (action create), have Drupal base field definitions automatically generated.
A contact can have multiple Websites as well.
In Drupal 7, I had a field type, "CiviCRM Entity Reference FIeld" .. which acted as a "remote reference field" or a "reverse reference field" .. The Inline Entity Form widget could be used as the field widget. Basically a standard entity reference field, but draws its values not from a Drupal field table, but from the CiviCRM database via API. We've explored porting this, but work remains in an early stage. Funding welcome :)
A bespoke programmatic computed field would be another way to do this, in a small custom module.
- π¬π§United Kingdom kenorb
Ok, did it in custom module by extending the existing classes (relevant parts below):
namespace Drupal\custom_civicrm; class CustomCiviEntityStorage extends \Drupal\civicrm_entity\CiviEntityStorage { private function getCiviCrmApi() { if (!$this->civicrmApi) { $this->civicrmApi = \Drupal::service('civicrm_entity.api'); } return $this->civicrmApi; } // Copied from CiviEntityStorage. function doLoadMultiple(array $ids = NULL) { ... if (!empty($ids)) { $options = [ 'api.CustomValue.get' => [], 'api.Relationship.get' => [], 'api.website.get' => [], 'id' => ['IN' => $ids], 'options' => ['limit' => 0], 'return' => $field_names, //'api.Contribution.get' => [], //'api.GroupContact.get' => [], //'api.Note.get' => [], ]; ...
Then extended CivicrmEntity to support these custom fields on load:
namespace Drupal\custom_civicrm\Entity; class CustomCivicrmEntity extends \Drupal\civicrm_entity\Entity\CivicrmEntity { /** * {@inheritdoc} */ function get($field_name) { switch ($field_name) { case 'api.CustomValue.get': case 'api.Relationship.get': case 'api.website.get': return $this->values[$field_name]; default: return parent::get($field_name); } } }
Then registered these classes in hook_entity_type_alter:
function custom_civicrm_entity_type_alter(array &$entity_types) { if (isset($entity_types['civicrm_contact'])) { $entity_type_id = 'civicrm_contact'; $civicrm_entity_info = \Drupal\civicrm_entity\SupportedEntities::getInfo()[$entity_type_id]; $entity_types[$entity_type_id]->set('class', \Drupal\custom_civicrm\Entity\CustomCivicrmEntity::class); $entity_types[$entity_type_id]->set('handlers', [ // ... here - same as original, exempt this one: 'storage' => \Drupal\custom_civicrm\CustomCiviEntityStorage::class, // ... if (isset($entity_types['civicrm_event'])) { // Same can be used for civicrm_event. } }
Then in Twig template I could use:
{% set civicrm_entity = content.contact_type['#object'] %}
{% set website_url = civicrm_entity.get('api.website.get').values[0].url %}
{% set custom_value civicrm_entity.get('api.CustomValue.get').values %}
{% set relations = civicrm_entity.get('api.Relationship.get').values %}
- Status changed to Closed: works as designed
8 months ago 8:24pm 25 April 2024