mirror of
https://codeberg.org/artfulrobot/contactcats.git
synced 2025-06-25 04:48:05 +02:00
133 lines
4.1 KiB
PHP
133 lines
4.1 KiB
PHP
<?php
|
|
namespace Civi\Api4\Action\ContactCategory;
|
|
|
|
use Civi;
|
|
use Civi\Api4\Activity;
|
|
use Civi\Api4\Generic\Result;
|
|
use Civi\Api4\Group;
|
|
use Civi\Api4\OptionValue;
|
|
use Civi\Api4\Setting;
|
|
use CRM_Core_DAO;
|
|
|
|
/**
|
|
* Sync the data
|
|
*
|
|
* @see \Civi\Api4\Generic\AbstractAction
|
|
*
|
|
*/
|
|
class Sync extends \Civi\Api4\Generic\AbstractAction {
|
|
|
|
public function _run(Result $result) {
|
|
$settings = Civi::settings()->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(<<<SQL
|
|
INSERT IGNORE INTO civicrm_contact_category
|
|
SELECT id, 0 as category, 0 next_category
|
|
FROM civicrm_contact
|
|
SQL);
|
|
|
|
foreach ($settings['groupIDs'] as $groupID) {
|
|
if ($groupID == 0) {
|
|
// The default 'group' isn't a ... group.
|
|
continue;
|
|
}
|
|
// Get contacts in group.
|
|
if (!$groups[$groupID]) {
|
|
Civi::log()->warning("Group $groupID no longer exists.");
|
|
continue;
|
|
}
|
|
$isSmart = !empty($groups[$groupID]['saved_search_id']);
|
|
if (!$isSmart) {
|
|
$sql = <<<SQL
|
|
UPDATE civicrm_contact_category cc
|
|
INNER JOIN civicrm_group_contact gc ON gc.contact_id = cc.id AND gc.status = 'Added' AND group_id = $groupID
|
|
SET next_category = $groupID
|
|
WHERE next_category = 0
|
|
SQL;
|
|
}
|
|
else {
|
|
// @todo refresh cache
|
|
$sql = <<<SQL
|
|
UPDATE civicrm_contact_category cc
|
|
INNER JOIN civicrm_group_contact_cache gcc ON gcc.contact_id = cc.id AND group_id = $groupID
|
|
SET next_category = $groupID
|
|
WHERE next_category = 0
|
|
SQL;
|
|
}
|
|
CRM_Core_DAO::executeQuery($sql);
|
|
}
|
|
$changes = CRM_Core_DAO::executeQuery(<<<SQL
|
|
SELECT id, category, next_category
|
|
FROM civicrm_contact_category
|
|
WHERE next_category <> 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);
|
|
}
|
|
|
|
}
|