Relationship Statistics
CRM maintains per-contact counts of relationships by type in the
relationship_statistics field on contacts. Statistics update when relationships
are created, updated, or deleted without saving a new contact revision.
Service
| Property | Value |
|---|---|
| Service ID | crm.relationship_statistics |
| Class | Drupal\crm\Service\RelationshipStatisticsService |
| Interface | Drupal\crm\Service\RelationshipStatisticsInterface |
Key methods
increment(ContactInterface $contact, string $type_key)— increase count for a typedecrement(ContactInterface $contact, string $type_key)— decrease count for a typerecalculateAll(int $batch_size = 100)— rebuild all contact statistics
Statistics are written directly to crm_contact__relationship_statistics (and
revision table when applicable), similar to comment statistics on nodes.
Hooks and maintenance
RelationshipHooks updates statistics on relationship insert, update, and delete.
If counts drift after bulk imports or manual database changes, recalculate:
ddev drush crm:recalculate-statistics
Optional batch size:
ddev drush crm:recalculate-statistics --batch-size=50
Alias: crm-rs.
Access
Stored counts cover every relationship type, with no access checks. Viewers
see counts only for relationship types they may view. A type is viewable when
the account has administer crm, view any crm relationship, or
view any {type} crm relationship. Each output path filters on read:
| Output | Behavior |
|---|---|
RelationshipStatisticsFormatter |
Skips types the viewer cannot view. Adds the user.permissions cache context. |
RelationshipStatisticsType Views filter |
When exposed, offers and applies only viewable types; hidden exposed defaults are dropped. Configured values and the admin form are unchanged. Adds the user.permissions cache context. |
| Serialization (REST and other serializers) | RelationshipStatisticsNormalizer drops items for types the viewer cannot view. Checks $context['account'] when set, else the current user. Adds the user.permissions cache context to the serialization cacheability. |
| JSON:API | Hides the whole field unless the viewer may view every relationship type. |
All four use getViewableBundles() on crm.relationship_access_query_alter
(RelationshipAccessQueryAlterInterface). It returns NULL when the account
may view every type, or else the list of viewable type IDs. The $account
argument is optional and defaults to the current user.
JSON:API does not use custom normalizers, so it cannot filter field items per
type. RelationshipStatisticsAccessHooks implements
hook_entity_field_access_alter() instead: on JSON:API routes it forbids view
access to relationship_statistics for restricted accounts. The result varies
by permissions and route name (route.name). It uses an alter hook because core keys
hook_entity_field_access() results by module, so a second CRM
implementation would overwrite UserMappedFieldAccessHooks.
RelationshipStatisticsNormalizer (crm.normalizer.relationship_statistics,
priority 20) is registered by CrmServiceProvider only when Serialization
is enabled.
Tests:
tests/src/Kernel/Normalizer/RelationshipStatisticsNormalizerTest.php— normalizer filtering and JSON:API field accesstests/src/Kernel/Plugin/Field/FieldFormatter/RelationshipStatisticsFormatterTest.phpandtests/src/Unit/Plugin/Field/FieldFormatter/RelationshipStatisticsFormatterTest.phptests/src/Kernel/Plugin/views/RelationshipStatisticsViewsTest.phpandtests/src/Unit/Plugin/views/filter/RelationshipStatisticsTypeTest.php
Views integration
- Filter:
RelationshipStatisticsType— filter contacts by relationship type counts - Field:
RelationshipStatisticsFormatter— display statistics on contact views
The formatter shows only relationship types the viewer may view. The filter limits exposed choices the same way (see Access).
See Views integration.
Field type
RelationshipStatisticsItem stores type key and count pairs on the contact entity.
The computed data is exposed to Views through ContactViewsData.
Related documentation
- Relationship entity — relationship types and limits
- Views integration
- Permissions