mirror of
https://codeberg.org/artfulrobot/contactcats.git
synced 2025-06-24 21:38:06 +02:00
lots
This commit is contained in:
parent
3b393be4f4
commit
0b96026602
17 changed files with 458 additions and 38 deletions
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Generated from contactcats/xml/schema/CRM/Contactcats/ContactCategory.xml
|
||||
* DO NOT EDIT. Generated by CRM_Core_CodeGen
|
||||
* (GenCodeChecksum:c8054b52817309c4eb67221623e1c29e)
|
||||
* (GenCodeChecksum:01a6344ef3d86c080e4362dafa008d13)
|
||||
*/
|
||||
use CRM_Contactcats_ExtensionUtil as E;
|
||||
|
||||
|
@ -97,8 +97,10 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
|
|||
'entity' => 'ContactCategory',
|
||||
'bao' => 'CRM_Contactcats_DAO_ContactCategory',
|
||||
'localizable' => 0,
|
||||
'FKClassName' => 'CRM_Contact_DAO_Contact',
|
||||
'html' => [
|
||||
'type' => 'Number',
|
||||
'type' => 'EntityRef',
|
||||
'label' => E::ts("Contact"),
|
||||
],
|
||||
'readonly' => TRUE,
|
||||
'add' => NULL,
|
||||
|
@ -124,8 +126,8 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
|
|||
'type' => 'Select',
|
||||
],
|
||||
'pseudoconstant' => [
|
||||
'optionGroupName' => 'ContactCategories',
|
||||
'optionEditPath' => 'civicrm/admin/options/ContactCategories',
|
||||
'optionGroupName' => 'contact_categories',
|
||||
'optionEditPath' => 'civicrm/admin/options/contact_categories',
|
||||
],
|
||||
'add' => NULL,
|
||||
],
|
||||
|
@ -147,8 +149,8 @@ class CRM_Contactcats_DAO_ContactCategory extends CRM_Core_DAO {
|
|||
'bao' => 'CRM_Contactcats_DAO_ContactCategory',
|
||||
'localizable' => 0,
|
||||
'pseudoconstant' => [
|
||||
'optionGroupName' => 'ContactCategories',
|
||||
'optionEditPath' => 'civicrm/admin/options/ContactCategories',
|
||||
'optionGroupName' => 'contact_categories',
|
||||
'optionEditPath' => 'civicrm/admin/options/contact_categories',
|
||||
],
|
||||
'add' => NULL,
|
||||
],
|
||||
|
|
17
CRM/Contactcats/Page/Settings.php
Normal file
17
CRM/Contactcats/Page/Settings.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
use CRM_Contactcats_ExtensionUtil as E;
|
||||
|
||||
class CRM_Contactcats_Page_Settings extends CRM_Core_Page {
|
||||
|
||||
public function run() {
|
||||
// Example: Set the page-title dynamically; alternatively, declare a static title in xml/Menu/*.xml
|
||||
CRM_Utils_System::setTitle(E::ts('Contact Category Settings'));
|
||||
|
||||
// Example: Assign a variable for use in a template
|
||||
// $this->assign('currentTime', date('Y-m-d H:i:s'));
|
||||
|
||||
Civi::service('angularjs.loader')->addModules('crmContactcats');
|
||||
parent::run();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,9 +2,11 @@
|
|||
namespace Civi\Api4\Action\ContactCategory;
|
||||
|
||||
use Civi;
|
||||
use Civi\Api4\Generic\AbstractAction;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -12,56 +14,120 @@ use CRM_Core_DAO;
|
|||
*
|
||||
* @see \Civi\Api4\Generic\AbstractAction
|
||||
*
|
||||
* @package ContactCategory
|
||||
*/
|
||||
class Sync extends \Civi\Api4\Generic\AbstractAction {
|
||||
|
||||
public function _run(Result $result) {
|
||||
$map = [
|
||||
['groupID' => 5, 'name' => 'Nice', 'categoryID' => 2],
|
||||
];
|
||||
$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_contactcategory SET next_category = 1;");
|
||||
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_contactcategory
|
||||
SELECT id, 1 as category, 2 next_category
|
||||
INSERT IGNORE INTO civicrm_contact_category
|
||||
SELECT id, 0 as category, 0 next_category
|
||||
FROM civicrm_contact
|
||||
SQL);
|
||||
|
||||
foreach ($map as $row) {
|
||||
// Get contacts in group.
|
||||
$cat = (int) $row['categoryID'];
|
||||
$row['groupID'] = (int) $row['groupID'];
|
||||
|
||||
$group = Group::get(FALSE)->addWhere('id', '=', $row['groupID'])->execute()->first();
|
||||
if (!$group) {
|
||||
Civi::warning("Group $row[groupID] used for category $row[name] no longer exists.");
|
||||
foreach ($settings['groupIDs'] as $groupID) {
|
||||
if ($groupID == 0) {
|
||||
// The default 'group' isn't a ... group.
|
||||
continue;
|
||||
}
|
||||
$isSmart = !empty($group['saved_search_id']);
|
||||
|
||||
// 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_contactcategory cc
|
||||
INNER JOIN civicrm_group_contact gc ON gc.contact_id = cc.id AND gc.status = 'Added' AND group_id = $row[groupID]
|
||||
SET next_category = $cat
|
||||
WHERE next_category = 1
|
||||
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_contactcategory cc
|
||||
INNER JOIN civicrm_group_contact_cache gcc ON gcc.contact_id = cc.id AND group_id = $row[groupID]
|
||||
SET next_category = $cat
|
||||
WHERE next_category = 1
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class ContactCategory extends Generic\DAOEntity {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public function sync(): Sync {
|
||||
public static function sync(): Sync {
|
||||
return new Sync('ContactCategory', 'sync');
|
||||
}
|
||||
|
||||
|
|
23
ang/crmContactcats.ang.php
Normal file
23
ang/crmContactcats.ang.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
// Angular module crmContactcats.
|
||||
// @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_angularModules
|
||||
return [
|
||||
'js' => [
|
||||
'ang/crmContactcats.js',
|
||||
'ang/crmContactcats/*.js',
|
||||
'ang/crmContactcats/*/*.js',
|
||||
],
|
||||
'css' => [
|
||||
'ang/crmContactcats.css',
|
||||
],
|
||||
'partials' => [
|
||||
'ang/crmContactcats',
|
||||
],
|
||||
'requires' => [
|
||||
'crmUi',
|
||||
'crmUtil',
|
||||
'ngRoute',
|
||||
'api4',
|
||||
],
|
||||
'settings' => [],
|
||||
];
|
18
ang/crmContactcats.css
Normal file
18
ang/crmContactcats.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* Add any CSS rules for Angular module "crmContactcats" */
|
||||
crm-contact-category-settings ol {
|
||||
padding:0;
|
||||
}
|
||||
crm-contact-category-settings ol li {
|
||||
display: flex;
|
||||
padding:0.5em 0;
|
||||
gap: 1em;
|
||||
}
|
||||
crm-contact-category-settings .name-input-wrapper {
|
||||
flex: 0 1 29ch;
|
||||
}
|
||||
crm-contact-category-settings .hint {
|
||||
display:none;
|
||||
}
|
||||
crm-contact-category-settings .name-input-wrapper:focus-within .hint {
|
||||
display:block;
|
||||
}
|
134
ang/crmContactcats.js
Normal file
134
ang/crmContactcats.js
Normal file
|
@ -0,0 +1,134 @@
|
|||
(function(angular, $, _) {
|
||||
// Declare a list of dependencies.
|
||||
angular.module('crmContactcats', CRM.angRequires('crmContactcats'));
|
||||
angular.module('crmContactcats').component('crmContactCategorySettings', {
|
||||
templateUrl: '~/crmContactcats/crmContactCategorySettings.html',
|
||||
bindings: {
|
||||
// things listed here become properties on the controller using
|
||||
// values from attributes. @ means a fixed string is passed
|
||||
// e.g. <crm-reset-password token='foo' />
|
||||
// token: '@',
|
||||
// & is special. In the child, call ctrl.onMyAction with an
|
||||
// Object whose keys provide parameter names for the code in the parent.
|
||||
// onMyAction: '&',
|
||||
// '<' means one-way binding (parent»child) and I think is what you are
|
||||
// supposed to use for components.
|
||||
// v: '<'
|
||||
},
|
||||
controller: function($scope, $timeout, crmApi4, $document) {
|
||||
var ts = $scope.ts = CRM.ts(null),
|
||||
ctrl = this;
|
||||
|
||||
// this.$onInit gets run after the this controller is called, and after the bindings have been applied.
|
||||
this.$onInit = async function() {
|
||||
ctrl.saved = false;
|
||||
const various = await crmApi4({
|
||||
settings: ['Setting', 'get', { select: ["contact_categories"] }, 0],
|
||||
groups: ['Group', 'get', {
|
||||
where: [['is_active', '=', 1], ['is_hidden', '=', 0]],
|
||||
orderBy: { "name": "ASC" }
|
||||
}],
|
||||
cats: ['OptionValue', 'get', {
|
||||
select: ['value', "label"],
|
||||
where: [["option_group_id:name", "=", "contact_categories"]],
|
||||
}]
|
||||
});
|
||||
ctrl.catmap = [];
|
||||
if (!various.settings.value || !various.settings.value.groupIDs) {
|
||||
various.settings.value = {
|
||||
groupIDs: ["0"],
|
||||
updateAfter: 0,
|
||||
};
|
||||
};
|
||||
various.settings.value.groupIDs.forEach(groupID => {
|
||||
let cat = various.cats.find(c => c.value == groupID);
|
||||
ctrl.catmap.push({
|
||||
groupID,
|
||||
name: cat ? cat.label : '',
|
||||
});
|
||||
});
|
||||
console.log({ various, catmap: ctrl.catmap });
|
||||
ctrl.groups = various.groups;
|
||||
ctrl.nameKeydown = (keyEvt, idx) => {
|
||||
if (keyEvt.key === 'ArrowUp' || keyEvt.key === 'ArrowDown') {
|
||||
keyEvt.preventDefault();
|
||||
keyEvt.stopPropagation();
|
||||
if (keyEvt.key === 'ArrowUp' && idx > 0 && idx < ctrl.catmap.length - 1) {
|
||||
ctrl.catmap.splice(idx, 0, ...ctrl.catmap.splice(idx - 1, 1));
|
||||
console.log('up', { keyEvt });
|
||||
$timeout(() => keyEvt.target.focus(), 10);
|
||||
}
|
||||
else if (keyEvt.key === 'ArrowDown' && idx < ctrl.catmap.length - 2) {
|
||||
ctrl.catmap.splice(idx + 1, 0, ...ctrl.catmap.splice(idx, 1));
|
||||
console.log('down', ctrl.catmap.map(e => e.name));
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.$digest();
|
||||
ctrl.deleteRow = (idx) => {
|
||||
ctrl.catmap.splice(idx, 1);
|
||||
};
|
||||
ctrl.getGroupsFor = (idx) => {
|
||||
let groupsInUse = ctrl.catmap.map(c => c.groupID);
|
||||
groupsInUse.splice(idx, 1);
|
||||
return ctrl.groups.filter(g => !groupsInUse.includes(g.id.toString()));
|
||||
};
|
||||
|
||||
ctrl.save = async () => {
|
||||
console.log("save");
|
||||
// reconstruct everything.
|
||||
|
||||
const optValsRecords = [];
|
||||
let isInvalid = false;
|
||||
ctrl.catmap.forEach(r => {
|
||||
if (!(r.name) || !r.groupID) {
|
||||
return;
|
||||
}
|
||||
// Do we have an option value for this group ID?
|
||||
let c = various.cats.find(cat => cat.value == r.groupID);
|
||||
if (c) {
|
||||
if (c.label != r.name) {
|
||||
optValsRecords.push({
|
||||
id: c.id,
|
||||
label: r.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
optValsRecords.push({
|
||||
label: r.name,
|
||||
value: r.groupID,
|
||||
"option_group_id:name": "contact_categories"
|
||||
});
|
||||
}
|
||||
});
|
||||
console.log("optionValue updates", optValsRecords, ctrl.catmap);
|
||||
const updates = {
|
||||
saveSetting: ['Setting', 'set', {
|
||||
values: {
|
||||
contact_categories:
|
||||
{
|
||||
groupIDs: ctrl.catmap.map(i => i.groupID),
|
||||
updateAfter: 0
|
||||
}
|
||||
}
|
||||
}],
|
||||
};
|
||||
if (optValsRecords.length) {
|
||||
updates.saveOptions = ['OptionValue', 'save', { records: optValsRecords }];
|
||||
}
|
||||
await crmApi4(updates);
|
||||
console.log("saved", updates);
|
||||
ctrl.saved = true;
|
||||
$scope.$digest();
|
||||
};
|
||||
};
|
||||
// this.$onChange = function(changes) {
|
||||
// // changes is object keyed by name what '<' binding changed in
|
||||
// // the parent (e.g. 'v'), and value is another obj with keys
|
||||
// // something like previous, new, ...?...
|
||||
// };
|
||||
|
||||
}
|
||||
});
|
||||
})(angular, CRM.$, CRM._);
|
35
ang/crmContactcats/crmContactCategorySettings.html
Normal file
35
ang/crmContactcats/crmContactCategorySettings.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
<div ng-if="!$ctrl.catmap">
|
||||
Loading...
|
||||
</div>
|
||||
<form ng-if="$ctrl.catmap" crm-ui-id-scope>
|
||||
<button ng-click="$ctrl.catmap.unshift({groupID: '', name:''})"><i class="crm-i fa-plus"></i> Add category</button>
|
||||
<ol class="crm-catmap">
|
||||
<li ng-repeat="(idx, row) in $ctrl.catmap">
|
||||
<select ng-if="row.groupID === '' || row.groupID > 0"
|
||||
crm-ui-select="{placeholder:'Select group',allowClear:false}" ng-model="$ctrl.catmap[idx].groupID"
|
||||
style="width: 18rem">
|
||||
<option ng-repeat="(grpIdx, grp) in $ctrl.getGroupsFor(idx)" value="{{grp.id}}">{{grp.title}}</option>
|
||||
</select>
|
||||
<div ng-if="row.groupID !== '' && row.groupID == 0" style="width: 18rem;display: inline-block;">
|
||||
Default
|
||||
</div>
|
||||
<div class=name-input-wrapper>
|
||||
<label crm-ui-for="name{{idx}}">Label</label>
|
||||
<input crm-ui-id="name{{idx}}" type=text ng-model="$ctrl.catmap[idx].name"
|
||||
ng-keydown="$ctrl.nameKeydown($event, idx)" />
|
||||
<div class="hint description">
|
||||
{{ts('Use the Up/Down arrow keys to re-order')}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button ng-click="$ctrl.deleteRow(idx)"><i class="fa-trash crm-i"></i> Delete</button>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
<p>
|
||||
<button ng-click="$ctrl.save()"><i class="crm-i fa-save"></i> Save</button>
|
||||
</p>
|
||||
<div ng-if="$ctrl.saved" class="help">Categories saved. Contacts will be updated shortly (when the next Scheduled
|
||||
Job run
|
||||
happens).</div>
|
||||
</form>
|
|
@ -30,3 +30,20 @@ function contactcats_civicrm_install(): void {
|
|||
function contactcats_civicrm_enable(): void {
|
||||
_contactcats_civix_civicrm_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_civicrm_navigationMenu().
|
||||
*
|
||||
* @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_navigationMenu
|
||||
*/
|
||||
function contactcats_civicrm_navigationMenu(&$menu) {
|
||||
_contactcats_civix_insert_navigation_menu($menu, 'Contacts', [
|
||||
'label' => E::ts('Categories'),
|
||||
'name' => 'contact_categories',
|
||||
'url' => 'civicrm/admin/contactcategory',
|
||||
'permission' => 'edit all contacts',
|
||||
'operator' => 'OR',
|
||||
'separator' => 0,
|
||||
]);
|
||||
_contactcats_civix_navigationMenu($menu);
|
||||
}
|
||||
|
|
2
info.xml
2
info.xml
|
@ -37,6 +37,8 @@
|
|||
<mixin>smarty-v2@1.0.1</mixin>
|
||||
<mixin>entity-types-php@1.0.0</mixin>
|
||||
<mixin>mgd-php@1.0.0</mixin>
|
||||
<mixin>ang-php@1.0.0</mixin>
|
||||
<mixin>menu-xml@1.0.0</mixin>
|
||||
</mixins>
|
||||
<upgrader>CRM_Contactcats_Upgrader</upgrader>
|
||||
</extension>
|
||||
|
|
27
managed/activity-type-changed-cc.mgd.php
Normal file
27
managed/activity-type-changed-cc.mgd.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
use CRM_Contactcats_ExtensionUtil as E;
|
||||
|
||||
return [
|
||||
[
|
||||
'name' => 'OptionValue_Changed_Contact_Category',
|
||||
'entity' => 'OptionValue',
|
||||
'cleanup' => 'unused',
|
||||
'update' => 'unmodified',
|
||||
'params' => [
|
||||
'version' => 4,
|
||||
'values' => [
|
||||
'option_group_id.name' => 'activity_type',
|
||||
'label' => E::ts('Changed Contact Category'),
|
||||
'value' => '57',
|
||||
'name' => 'changed_contact_category',
|
||||
'weight' => 57,
|
||||
'icon' => 'fa-tags',
|
||||
],
|
||||
'match' => [
|
||||
'option_group_id',
|
||||
'name',
|
||||
'value',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
50
managed/options.mgd.php
Normal file
50
managed/options.mgd.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
use CRM_Contactcats_ExtensionUtil as E;
|
||||
|
||||
return [
|
||||
[
|
||||
'name' => 'OptionGroup_contact_categories',
|
||||
'entity' => 'OptionGroup',
|
||||
'cleanup' => 'unused',
|
||||
'update' => 'unmodified',
|
||||
'params' => [
|
||||
'version' => 4,
|
||||
'values' => [
|
||||
'name' => 'contact_categories',
|
||||
'title' => E::ts('Contact Categories'),
|
||||
'data_type' => 'Integer',
|
||||
'is_reserved' => FALSE,
|
||||
'is_active' => TRUE,
|
||||
'option_value_fields' => [
|
||||
'name',
|
||||
'label',
|
||||
'description',
|
||||
],
|
||||
],
|
||||
'match' => [
|
||||
'name',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'OptionGroup_contact_categories_OptionValue_Default',
|
||||
'entity' => 'OptionValue',
|
||||
'cleanup' => 'unused',
|
||||
'update' => 'unmodified',
|
||||
'params' => [
|
||||
'version' => 4,
|
||||
'values' => [
|
||||
'option_group_id.name' => 'contact_categories',
|
||||
'label' => E::ts('Default'),
|
||||
'is_active' => TRUE,
|
||||
'value' => '0',
|
||||
'name' => 'default',
|
||||
],
|
||||
'match' => [
|
||||
'option_group_id',
|
||||
'name',
|
||||
'value',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
15
settings/contactcategory.setting.php
Normal file
15
settings/contactcategory.setting.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
return [
|
||||
'contact_categories' => [
|
||||
'name' => 'contact_categories',
|
||||
'title' => ts('Contact Category settings'),
|
||||
'description' => ts('JSON encoded settings.'),
|
||||
'group_name' => 'domain',
|
||||
'type' => 'String',
|
||||
'serialize' => CRM_Core_DAO::SERIALIZE_JSON,
|
||||
'default' => FALSE,
|
||||
'add' => '5.70',
|
||||
'is_domain' => 1,
|
||||
'is_contact' => 0,
|
||||
],
|
||||
];
|
|
@ -37,6 +37,7 @@ CREATE TABLE `civicrm_contact_category` (
|
|||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID, corresponds to contact id',
|
||||
`category` int unsigned NOT NULL DEFAULT 0,
|
||||
`next_category` int unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT FK_civicrm_contact_category_id FOREIGN KEY (`id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE
|
||||
)
|
||||
ENGINE=InnoDB;
|
||||
|
|
3
templates/CRM/Contactcats/Page/Settings.tpl
Normal file
3
templates/CRM/Contactcats/Page/Settings.tpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
<crm-angular-js modules="crmContactcats">
|
||||
<crm-contact-category-settings ></crm-contact-category-settings>
|
||||
</crm-angular-js>
|
9
xml/Menu/contactcats.xml
Normal file
9
xml/Menu/contactcats.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<menu>
|
||||
<item>
|
||||
<path>civicrm/admin/contactcategory</path>
|
||||
<page_callback>CRM_Contactcats_Page_Settings</page_callback>
|
||||
<title>Settings</title>
|
||||
<access_arguments>access CiviCRM</access_arguments>
|
||||
</item>
|
||||
</menu>
|
|
@ -13,7 +13,8 @@
|
|||
<required>true</required>
|
||||
<comment>Unique ID, corresponds to contact id</comment>
|
||||
<html>
|
||||
<type>Number</type>
|
||||
<type>EntityRef</type>
|
||||
<label>Contact</label>
|
||||
</html>
|
||||
</field>
|
||||
<primaryKey>
|
||||
|
@ -21,7 +22,7 @@
|
|||
<autoincrement>true</autoincrement>
|
||||
</primaryKey>
|
||||
<foreignKey>
|
||||
<name>contact_id</name>
|
||||
<name>id</name>
|
||||
<table>civicrm_contact</table>
|
||||
<key>id</key>
|
||||
<onDelete>CASCADE</onDelete>
|
||||
|
@ -33,7 +34,7 @@
|
|||
<required>true</required>
|
||||
<default>0</default>
|
||||
<pseudoconstant>
|
||||
<optionGroupName>ContactCategories</optionGroupName>
|
||||
<optionGroupName>contact_categories</optionGroupName>
|
||||
</pseudoconstant>
|
||||
<html>
|
||||
<type>Select</type>
|
||||
|
@ -46,7 +47,7 @@
|
|||
<required>true</required>
|
||||
<default>0</default>
|
||||
<pseudoconstant>
|
||||
<optionGroupName>ContactCategories</optionGroupName>
|
||||
<optionGroupName>contact_categories</optionGroupName>
|
||||
</pseudoconstant>
|
||||
</field>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue