SK/FB work

This commit is contained in:
Rich Lott / Artful Robot 2025-02-25 17:42:47 +00:00
parent 16f2b6235d
commit a4c9251f5e
10 changed files with 163 additions and 233 deletions

View file

@ -24,6 +24,11 @@ class Processor {
->addOrderBy('execution_order')
->execute()->getArrayCopy();
// Check the last item is the 'default' one.
if ((end($this->categories)['search_type'] ?? '') !== 'default') {
throw new CRM_Core_Exception("ContactCategoryDefinition unconfigured; no default category.");
}
// Identify groups and searches used by definitions.
$groupIDs = $searchIDs = [];
foreach ($this->categories as $cat) {
@ -72,8 +77,10 @@ class Processor {
// TODO: check things like searches that group by contact_id
}
/**
* Main calling point.
*/
public function run() {
$this->refreshSmartGroups();
$summary = [];
\CRM_Core_Transaction::create()->run(function($tx) use (&$summary) {
@ -85,6 +92,12 @@ class Processor {
elseif ($cat['search_type'] === 'search') {
$this->assignCategoryFromSearch($cat);
}
elseif ($cat['search_type'] === 'default') {
$this->assignDefaultCategory($cat);
}
else {
throw new CRM_Core_DAO("Invalid search_type: $cat[search_type] for category $cat[id]");
}
// future...
}
$summary = $this->createChangeActivities();
@ -96,10 +109,10 @@ class Processor {
protected function createChangeActivities() {
Civi::log()->debug("Calculate changes", ['=' => 'timed', '=start' => "changes"]);
$changes = CRM_Core_DAO::executeQuery(<<<SQL
SELECT id, category, next_category
SELECT id, category_definition_id, next_category
FROM civicrm_contact_category
WHERE next_category <> category
ORDER BY category, next_category
WHERE next_category <> category_definition_id
ORDER BY category_definition_id, next_category
SQL);
$lastChange = [0, 0];
$batch = [];
@ -147,10 +160,11 @@ class Processor {
Civi::log()->debug('Apply changes', ['=change' => 'applyChanges', '=timed' => 1]);
CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category
SET category = next_category WHERE category <> next_category")->free();
SET category_definition_id = next_category
WHERE category_definition_id IS NULL OR category_definition_id <> next_category")->free();
Civi::log()->debug('', ['=pop' => 1]);
$summary = CRM_Core_DAO::executeQuery("SELECT next_category, count(*) from civicrm_contact_category group by next_category")->fetchAll();
$summary = CRM_Core_DAO::executeQuery("SELECT next_category, count(*) from civicrm_contact_category GROUP BY next_category")->fetchAll();
$summary['changes'] = $n;
$_ = memory_get_peak_usage(TRUE);
$summary['memory_use'] = @round($_ / pow(1024, ($i = floor(log($_, 1024)))), 2) . ' ' . ['b', 'kb', 'mb', 'gb', 'tb', 'pb'][$i];
@ -176,12 +190,14 @@ class Processor {
Civi::log()->debug('Resetting table', ['=' => 'start,timed']);
// clear out temp space.
CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = 0;")->free();
Civi::log()->debug('Resetting table stage 2');
// ensure we have all our contacts covered.
// TODO: is it quicker to do a WHERE NOT EXISTS?
// Q: is it quicker to do a WHERE NOT EXISTS? A: nope.
CRM_Core_DAO::executeQuery(<<<SQL
INSERT IGNORE INTO civicrm_contact_category
SELECT id, id contact_id, 0 as category, 0 next_category
INSERT INTO civicrm_contact_category
SELECT id, id contact_id, NULL as category_definition_id, 0 next_category
FROM civicrm_contact
WHERE NOT EXISTS (SELECT id FROM civicrm_contact_category WHERE id = civicrm_contact.id)
SQL)->free();
Civi::log()->debug('', ['=' => 'pop']);
}
@ -205,6 +221,7 @@ class Processor {
WHERE next_category = 0
SQL;
CRM_Core_DAO::executeQuery($sql)->free();
Civi::log()->debug('', ['=' => 'pop']);
}
/**
@ -212,6 +229,7 @@ class Processor {
*/
protected function assignCategoryFromSearch(array $cat) {
$search = $this->searchDetails[$cat['search_data']['saved_search_id']];
Civi::log()->debug("Doing $cat[id] $cat[label]", ['=' => 'timed', '=start' => "ss" . $cat['search_data']['saved_search_id']]);
$apiParams = $search['api_params'];
if ($search['api_entity'] === 'Contact' && in_array('id', $apiParams['select'] ?? [])) {
@ -225,7 +243,7 @@ class Processor {
// We don't need them ordered.
unset($apiParams['orderBy']);
$contactIDs = civicrm_api4($search['api_entity'], $search['get'], $apiParams)->column($contactIdKey);
$contactIDs = civicrm_api4($search['api_entity'], 'get', $apiParams)->column($contactIdKey);
// Unsure if this batching is needed
$batchSize = 10000;
while ($batch = array_splice($contactIDs, 0, $batchSize)) {
@ -241,6 +259,12 @@ class Processor {
SQL;
CRM_Core_DAO::executeQuery($sql)->free();
}
Civi::log()->debug('', ['=' => 'pop']);
}
protected function assignDefaultCategory(array $cat) {
$id = (int) $cat['id'];
CRM_Core_DAO::executeQuery("UPDATE civicrm_contact_category SET next_category = $id WHERE next_category = 0;")->free();
}
}