get('contact_categories'); $settings = Setting::get(FALSE) ->addSelect('contact_categories') ->execute()->first()['value'] ?? NULL; if (empty($settings['groupIDs'])) { throw new \API_Exception('Unconfigured'); } if ($settings['updateAfter'] > time()) { // not needed yet. return; } // Load category names $catNames = OptionValue::get(FALSE) ->addWhere('option_group_id:name', '=', 'contact_categories') ->addSelect('value', 'label') ->execute()->indexBy('value')->column('label'); $groups = Group::get(FALSE) ->addWhere('id', 'IN', $settings['groupIDs']) ->execute()->indexBy('id')->getArrayCopy(); $smartGroups = []; foreach ($groups as $groupID => $group) { if (!empty($group['saved_search_id'])) { $smartGroups[] = $groupID; } } if ($smartGroups) { \CRM_Contact_BAO_GroupContactCache::loadAll($smartGroups); } // clear out temp space. CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = 0;"); // ensure we have all our contacts covered. CRM_Core_DAO::executeQuery(<<warning("Group $groupID no longer exists."); continue; } $isSmart = !empty($groups[$groupID]['saved_search_id']); if (!$isSmart) { $sql = << category ORDER BY category, next_category SQL); $lastChange = [0, 0]; $batch = []; $n = 0; $writeBatch = function() use (&$lastChange, &$batch, $catNames) { if (empty($batch)) { return; } // Create activity Activity::create(FALSE) ->addValue('target_contact_id', $batch) ->addValue('activity_type_id:name', 'changed_contact_category') ->addValue('source_contact_id', \CRM_Core_BAO_Domain::getDomain()->contact_id) ->addValue('status_id:name', 'Completed') ->addValue('subject', $catNames[$lastChange[0] ?? 0] . ' → ' . $catNames[$lastChange[0] ?? 0]) ->execute(); }; while ($changes->fetch()) { $n++; if ($lastChange[0] !== $changes->category || $lastChange[1] !== $changes->next_category) { $writeBatch(); $lastChange = [$changes->category, $changes->next_category]; $batch = []; } $batch[] = $changes->id; } $writeBatch(); CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET category = next_category WHERE category <> next_category"); $summary = CRM_Core_DAO::executeQuery("SELECT next_category, count(*) from civicrm_contact_category group by next_category")->fetchAll(); $summary['changes'] = $n; $result->exchangeArray($summary); } }