4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
13 namespace Civi\Api4\Service\Spec\Provider
;
15 use Civi\Api4\Query\Api4SelectQuery
;
16 use Civi\Api4\Service\Spec\FieldSpec
;
17 use Civi\Api4\Service\Spec\RequestSpec
;
19 class ContactGetSpecProvider
implements Generic\SpecProviderInterface
{
22 * @param \Civi\Api4\Service\Spec\RequestSpec $spec
24 public function modifySpec(RequestSpec
$spec) {
25 $field = new FieldSpec('groups', 'Contact', 'Array');
26 $field->setLabel(ts('In Groups'))
27 ->setTitle(ts('Groups'))
29 ->setDescription(ts('Groups (or sub-groups of groups) to which this contact belongs'))
31 ->setOperators(['IN', 'NOT IN'])
32 ->addSqlFilter([__CLASS__
, 'getContactGroupSql'])
33 ->setSuffixes(['id', 'name', 'label'])
34 ->setOptionsCallback([__CLASS__
, 'getGroupList']);
35 $spec->addFieldSpec($field);
39 * @param string $entity
40 * @param string $action
44 public function applies($entity, $action) {
45 return $entity === 'Contact' && $action === 'get';
50 * @param string $fieldAlias
51 * @param string $operator
53 * @param \Civi\Api4\Query\Api4SelectQuery $query
57 public static function getContactGroupSql(array $field, string $fieldAlias, string $operator, $value, Api4SelectQuery
$query, int $depth): string {
58 $tempTable = \CRM_Utils_SQL_TempTable
::build();
59 $tempTable->createWithColumns('contact_id INT');
60 $tableName = $tempTable->getName();
61 \CRM_Contact_BAO_GroupContactCache
::populateTemporaryTableWithContactsInGroups((array) $value, $tableName);
62 // SQL optimization - use INNER JOIN if the base table is Contact & this clause is not nested
63 if ($fieldAlias === '`a`.`id`' && $operator === "IN" && !$depth) {
64 $query->getQuery()->join($tableName, "INNER JOIN `$tableName` ON $fieldAlias = `$tableName`.contact_id");
67 // Else use IN or NOT IN (this filter only supports those 2 operators)
69 return "$fieldAlias $operator (SELECT contact_id FROM `$tableName`)";
74 * Callback function to build option lists groups pseudo-field.
76 * @param \Civi\Api4\Service\Spec\FieldSpec $spec
77 * @param array $values
78 * @param bool|array $returnFormat
79 * @param bool $checkPermissions
82 public static function getGroupList($spec, $values, $returnFormat, $checkPermissions) {
83 $groups = $checkPermissions ? \CRM_Core_PseudoConstant
::group() : \CRM_Core_PseudoConstant
::allGroup(NULL, FALSE);
84 $options = \CRM_Utils_Array
::makeNonAssociative($groups, 'id', 'label');
85 if ($options && is_array($returnFormat) && in_array('name', $returnFormat)) {
86 $groupIndex = array_flip(array_keys($groups));
87 $dao = \CRM_Core_DAO
::executeQuery('SELECT id, name FROM civicrm_group WHERE id IN (%1)', [
88 1 => [implode(',', array_keys($groups)), 'CommaSeparatedIntegers'],
90 while ($dao->fetch()) {
91 $options[$groupIndex[$dao->id
]]['name'] = $dao->name
;