Add ContactCategoryDefinition.Setup action

This commit is contained in:
Rich Lott / Artful Robot 2025-04-01 21:19:55 +01:00
parent bbaafc43e1
commit 0b625bcba0

View file

@ -0,0 +1,205 @@
<?php
namespace Civi\Api4\Action\ContactCategoryDefinition;
use CRM_Contactcats_ExtensionUtil as E;
use Civi\Api4\Generic\AbstractAction;
use Civi\Api4\Generic\Result;
use Civi\Api4\ContactCategoryDefinition;
use Civi\Api4\SavedSearch;
use CRM_Core_Exception;
/**
* This configures Contact Categories using a pre-set concrete scheme.
*/
class Setup extends AbstractAction {
/**
* The name of the scheme to load.
*
* @var string
*/
protected $scheme = 'ForumZFDFundraising1';
/**
*/
public function _run(Result $result) {
// TODO: could offer this as a hook.
// For now, it's hard-coded.
if ($this->scheme === 'ForumZFDFundraising1') {
$this->implementForumZFDFundraising1($result);
}
throw new CRM_Core_Exception("Unknown scheme " . $this->scheme);
}
/**
*/
public function implementForumZFDFundraising1(Result $result) {
$this->prepare();
$src = [
[
'_search_name' => 'ContactCategories_Locus_3_5',
'label' => '3.5',
'description' => E::ts('Multiple time major donors.'),
// 'search_type' => 'search',
// 'search_data' => ['saved_search_id']
'color' => '#009313',
'icon' => 'fa-face-grin-stars',
// 'execution_order' => '',
// 'presentation_order' => '',
],
[
'_search_name' => 'ContactCategories_Locus_3_4',
'label' => '3.4',
'description' => E::ts('Major donor: new'),
'color' => '#007e11',
'icon' => 'fa-leaf',
],
[
'_search_name' => 'ContactCategories_Locus_3_3',
'label' => '3.3',
'description' => E::ts('Major donor: one-time'),
'color' => '#00670e',
'icon' => 'fa-heart-pulse',
],
[
'_search_name' => 'ContactCategories_Locus_3_2',
'label' => '3.2',
'description' => E::ts('Major donor: two-time'),
'color' => '#00510b',
'icon' => 'fa-hand-holding-heart',
],
[
'_search_name' => 'ContactCategories_Locus_3_1',
'label' => '3.1',
'description' => E::ts('Major donor: critical'),
'color' => '#003c08',
'icon' => 'fa-heart-circle-exclamation',
],
[
'_search_name' => 'ContactCategories_Locus_3_0',
'label' => '3.0',
'description' => E::ts('Major donor: expired'),
'color' => '#4c7451',
'icon' => 'fa-heart-circle-xmark',
],
[
'_search_name' => 'ContactCategories_Locus_2_3',
'label' => '2.3',
'description' => E::ts('Regular donor: active'),
'color' => '#044657',
'icon' => 'fa-person-running',
],
[
'_search_name' => 'ContactCategories_Locus_2_2',
'label' => '2.2',
'description' => E::ts('Regular donor: new'),
'color' => '#024990',
'icon' => 'fa-person-circle-plus',
],
[
'_search_name' => 'ContactCategories_Locus_2_1',
'label' => '2.1',
'description' => E::ts('Regular donor: expired'),
'color' => '#004cc4',
'icon' => 'fa-person-circle-minus',
],
[
'_search_name' => 'ContactCategories_Locus_1_6',
'label' => '1.6',
'description' => E::ts('Occasional donor: multiple times'),
'color' => '#9e00b2',
'icon' => 'fa-money-bill-wave',
],
[
'_search_name' => 'ContactCategories_Locus_1_5',
'label' => '1.5',
'description' => E::ts('Occasional donor: two-time'),
'color' => '#8e009f',
'icon' => 'fa-money-bills',
],
[
'_search_name' => 'ContactCategories_Locus_1_4',
'label' => '1.4',
'description' => E::ts('Occasional donor: new'),
'color' => '#7d008c',
'icon' => 'fa-card-plus',
],
[
'_search_name' => 'ContactCategories_Locus_1_3',
'label' => '1.3',
'description' => E::ts('Occasional donor: one-time'), // FIXME:
'color' => '#6d0079',
'icon' => 'fa-money-bill-1',
],
[
'_search_name' => 'ContactCategories_Locus_1_2',
'label' => '1.2',
'description' => E::ts('Occasional donor: critical'),
'color' => '#5c0065',
'icon' => 'fa-triangle-exclamation',
],
[
'_search_name' => 'ContactCategories_Locus_1_1',
'label' => '1.1',
'description' => E::ts('Occasional donor: expired'),
'color' => '#fff',
'icon' => 'fa-road-circle-xmark',
],
[
'_search_name' => 'ContactCategories_Locus_0_2',
'label' => '0.2',
'description' => E::ts('Interested'),
'color' => '#613b05',
'icon' => '',
],
];
$searchNames = array_map(fn($r) => $r['_search_name'], $src);
$nameToIdMatch = SavedSearch::get()
->addWhere('name', 'IN', $searchNames)
->addSelect('name')
->execute()
->indexBy('name')->column('id');
if (count($nameToIdMatch) !== count($searchNames)) {
throw new CRM_Core_Exception("Missing saved search(es): " . implode(', ', array_diff($searchNames, array_keys($nameToIdMatch))));
}
$saveApi = ContactCategoryDefinition::save(FALSE)
->setDefaults([ 'search_type' => 'search' ]);
$order = 1;
foreach ($src as $rec) {
$src['search_data'] = ['saved_search_id' => $nameToIdMatch[$rec['_search_name']]];
$src['execution_order'] = $src['presentation_order'] = $order++;
unset($rec['_search_name']);
$saveApi->addRecord($rec);
}
$saveApi->addRecord([
'label' => '0.1',
'description' => E::ts('Uninterested'),
'color' => '#555',
'icon' => 'fa-ban',
'search_type' => 'default',
'presentation_order' => $order,
'execution_order' => $order,
]);
$r = $saveApi->execute();
$result->exchangeArray($r->getArrayCopy());
}
/**
*/
public function prepare() {
ContactCategoryDefinition::delete(FALSE)
->addWhere('id', '>', 0)
->execute();
$savedSearchNameToIDMap = SavedSearch::get()
->addSelect('id', 'name')
->execute()
->indexBy('name')->column('id');
return $savedSearchNameToIDMap;
}
}