$spec->addFieldSpec($field);
}
- // Address, Email, Phone, IM
+ // Address, Email, Phone, IM primary/billing virtual fields
+ // This exposes the joins created by
+ // \Civi\Api4\Event\Subscriber\ContactSchemaMapSubscriber::onSchemaBuild()
$entities = [
'Address' => [
'primary' => [
foreach ($entities as $entity => $types) {
foreach ($types as $type => $info) {
$name = strtolower($entity) . '_' . $type;
- $field = new FieldSpec($name, 'Contact', 'String');
+ $field = new FieldSpec($name, 'Contact', 'Integer');
$field->setLabel($info['label'])
->setTitle($info['title'])
->setColumnName('id')
* @param array $field
* @return string
*/
- public static function calculateAge(array $field) {
+ public static function calculateAge(array $field): string {
return "TIMESTAMPDIFF(YEAR, {$field['sql_name']}, CURDATE())";
}
/**
* Generate SQL for address/email/phone/im id field
+ *
+ * This works because the join was declared in ContactSchemaMapSubscriber
+ * and that also magically allows implicit joins through this one, by virtue
+ * of the fact that `$query->getField` will create the join not just to the `id` field
+ * but to every field on the joined entity, allowing e.g. joins to `address_primary.country_id:label`.
+ *
+ * @see \Civi\Api4\Event\Subscriber\ContactSchemaMapSubscriber::onSchemaBuild()
* @param array $field
* @param \Civi\Api4\Query\Api4SelectQuery $query
* @return string
*/
- public static function getLocationFieldSql(array $field, Api4SelectQuery $query) {
+ public static function getLocationFieldSql(array $field, Api4SelectQuery $query): string {
$prefix = empty($field['explicit_join']) ? '' : $field['explicit_join'] . '.';
$idField = $query->getField($prefix . $field['name'] . '.id');
return $idField['sql_name'];