APIv4 - Add comments and fix data type for contact location joins
authorColeman Watts <coleman@civicrm.org>
Fri, 12 Aug 2022 21:27:09 +0000 (17:27 -0400)
committerColeman Watts <coleman@civicrm.org>
Fri, 12 Aug 2022 21:27:09 +0000 (17:27 -0400)
Civi/Api4/Event/Subscriber/ContactSchemaMapSubscriber.php
Civi/Api4/Service/Spec/Provider/ContactGetSpecProvider.php

index 6177ebe98a34d03a6cd4604a5ca3010dd1482718..d8aec88dc4320160f04d2574cbf0a004351aec15 100644 (file)
@@ -19,6 +19,10 @@ class ContactSchemaMapSubscriber implements EventSubscriberInterface {
   }
 
   /**
+   * This creates a joinable which gets exposed and rendered by:
+   *
+   * @see \Civi\Api4\Service\Spec\Provider\ContactGetSpecProvider
+   *
    * @param \Civi\Api4\Event\SchemaMapBuildEvent $event
    */
   public function onSchemaBuild(SchemaMapBuildEvent $event) {
index d3c9dab9219e45c63fe8391b1fc46ddb4a719e3b..d87cf7dc1336b9cedbfcb0bf37e8594c72f9df08 100644 (file)
@@ -50,7 +50,9 @@ class ContactGetSpecProvider implements Generic\SpecProviderInterface {
       $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' => [
@@ -96,7 +98,7 @@ class ContactGetSpecProvider implements Generic\SpecProviderInterface {
     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')
@@ -173,17 +175,24 @@ class ContactGetSpecProvider implements Generic\SpecProviderInterface {
    * @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'];