Skip to content

Commit 1b64f46

Browse files
DTAMM-31: Add event types filters
1 parent ea7e56a commit 1b64f46

File tree

18 files changed

+417
-23
lines changed

18 files changed

+417
-23
lines changed

CRM/Certificate/BAO/CompuCertificateEventAttribute.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ public static function create($params) {
2323
return $instance;
2424
}
2525

26-
public static function assignCertificateEventAttribute($certificateId, $participantTypeId) {
26+
public static function assignCertificateEventAttribute($certificateId, $participantTypeId, array $eventTypeIds = []) {
2727
self::removeCertificateCurrentEventAttribute($certificateId);
2828

2929
if (empty($participantTypeId)) {
3030
return NULL;
3131
}
3232

33+
$eventTypeIds = self::sanitizeEventTypeIds($eventTypeIds);
34+
3335
$values = [
3436
'certificate_id' => $certificateId,
3537
'participant_type_id' => (int) $participantTypeId,
38+
'event_type_ids' => empty($eventTypeIds) ? NULL : implode(',', $eventTypeIds),
3639
];
3740

3841
$eventAttributeDAO = CRM_Certificate_BAO_CompuCertificateEventAttribute::create($values);
@@ -52,4 +55,18 @@ private static function removeCertificateCurrentEventAttribute($certificateId) {
5255
$statusBAO->delete(TRUE);
5356
}
5457

58+
/**
59+
* Clean up event type ids.
60+
*
61+
* @param array $eventTypeIds
62+
*
63+
* @return array
64+
*/
65+
private static function sanitizeEventTypeIds(array $eventTypeIds): array {
66+
$eventTypes = CRM_Core_OptionGroup::values('event_type', FALSE, FALSE, FALSE, 'AND v.is_active = 1');
67+
$eventTypeIds = array_map('intval', $eventTypeIds);
68+
69+
return array_values(array_intersect($eventTypeIds, array_keys($eventTypes)));
70+
}
71+
5572
}

CRM/Certificate/DAO/CompuCertificateEventAttribute.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Generated from uk.co.compucorp.certificate/xml/schema/CRM/Certificate/CompuCertificateEventAttribute.xml
88
* DO NOT EDIT. Generated by CRM_Core_CodeGen
9-
* (GenCodeChecksum:0aaaa92ec2247de74dd0e710fc5b6e53)
9+
* (GenCodeChecksum:0acab92dc3247df74dd0c712fc5d6e54)
1010
*/
1111
use CRM_Certificate_ExtensionUtil as E;
1212

@@ -52,6 +52,13 @@ class CRM_Certificate_DAO_CompuCertificateEventAttribute extends CRM_Core_DAO {
5252
*/
5353
public $participant_type_id;
5454

55+
/**
56+
* Comma separated event type ids.
57+
*
58+
* @var string
59+
*/
60+
public $event_type_ids;
61+
5562
/**
5663
* Class constructor.
5764
*/
@@ -131,6 +138,18 @@ public static function &fields() {
131138
'localizable' => 0,
132139
'add' => NULL,
133140
],
141+
'event_type_ids' => [
142+
'name' => 'event_type_ids',
143+
'type' => CRM_Utils_Type::T_STRING,
144+
'title' => E::ts('Event Type Ids'),
145+
'description' => E::ts('Comma separated event type ids.'),
146+
'where' => 'compucertificate_event_attribute.event_type_ids',
147+
'table_name' => 'compucertificate_event_attribute',
148+
'entity' => 'CompuCertificateEventAttribute',
149+
'bao' => 'CRM_Certificate_DAO_CompuCertificateEventAttribute',
150+
'localizable' => 0,
151+
'add' => NULL,
152+
],
134153
];
135154
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
136155
}

CRM/Certificate/Entity/AbstractEntity.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@ abstract public function getCertificateConfiguredStatuses($certificateId);
5656
*
5757
* @param int $certificateId
5858
* Id of the certificate instance to retrieve entity types for
59+
* @param bool $includeAttrs
60+
* Include attributes or not
5961
*
6062
* @return Array
6163
*/
62-
abstract public function getCertificateConfiguredTypes($certificateId);
64+
abstract public function getCertificateConfiguredTypes($certificateId, bool $includeAttrs = FALSE);
6365

6466
/**
6567
* Returns a configured certificate by ID

CRM/Certificate/Entity/Case.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function getCertificateConfiguredStatuses($certificateId) {
8181
/**
8282
* {@inheritDoc}
8383
*/
84-
public function getCertificateConfiguredTypes($certificateId) {
84+
public function getCertificateConfiguredTypes($certificateId, $includeAttrs = FALSE) {
8585
$entityTypeBAO = new CRM_Certificate_BAO_CompuCertificateEntityType();
8686
$entityTypeBAO->whereAdd("certificate_id = " . $certificateId);
8787

CRM/Certificate/Entity/Event.php

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,31 +82,53 @@ public function getCertificateConfiguredStatuses($certificateId) {
8282
/**
8383
* {@inheritDoc}
8484
*/
85-
public function getCertificateConfiguredTypes($certificateId) {
85+
public function getCertificateConfiguredTypes($certificateId, $includeAttrs = FALSE) {
86+
if ($includeAttrs) {
87+
return array_merge($this->getCertificateEvent((int) $certificateId), $this->getCertificateEventTypes((int) $certificateId));
88+
}
89+
90+
return $this->getCertificateEvent((int) $certificateId);
91+
}
92+
93+
private function getCertificateEvent(int $certificateId): array {
8694
$entityTypeBAO = new CRM_Certificate_BAO_CompuCertificateEntityType();
8795
$entityTypeBAO->whereAdd("certificate_id = " . $certificateId);
88-
8996
$entityType = new CRM_Event_DAO_Event();
9097
$entityTypeBAO->joinAdd(['entity_type_id', $entityType, 'id']);
9198
$entityTypeBAO->find();
9299
$entityTypes = $entityTypeBAO->fetchAll('id');
93-
94100
$entityTypes = array_map(function ($entityType) {
95-
return [
96-
"id" => $entityType["id"],
97-
"label" => $entityType["title"],
98-
];
101+
return ["id" => $entityType["id"], "label" => $entityType["title"]];
99102
}, $entityTypes);
100103

101104
return $entityTypes;
102105
}
103106

107+
private function getCertificateEventTypes(int $certificateId): array {
108+
$configuredEventTypes = [];
109+
$eventAttrBAO = new CRM_Certificate_BAO_CompuCertificateEventAttribute();
110+
$eventAttrBAO->selectAdd('event_type_ids');
111+
$eventAttrBAO->whereAdd("certificate_id = " . $certificateId);
112+
$eventAttrBAO->find();
113+
$eventTypes = $eventAttrBAO->fetchAll();
114+
$eventTypes = implode(',', array_column($eventTypes, 'event_type_ids'));
115+
if (!empty($eventTypes)) {
116+
$eventTypes = CRM_Core_OptionGroup::values('event_type', FALSE, FALSE, FALSE, 'AND v.is_active = 1 AND v.value IN (' . $eventTypes . ')');
117+
foreach ($eventTypes as $k => $eventType) {
118+
$configuredEventTypes[] = ['id' => $k, 'label' => $eventType];
119+
}
120+
}
121+
122+
return $configuredEventTypes;
123+
}
124+
104125
/**
105126
* {@inheritDoc}
106127
*/
107128
protected function addEntityExtraField($certificateBAO, &$certificate) {
108129
$eventAttribute = $this->getCertificateEventAttribute($certificateBAO->id);
109130
$certificate['participant_type_id'] = implode(', ', array_column($eventAttribute, 'participant_type_id'));
131+
$certificate['event_type_ids'] = implode(',', $this->getEventAttributeEventTypeIds($eventAttribute));
110132
}
111133

112134
private function getCertificateEventAttribute($certificateId) {
@@ -117,6 +139,57 @@ private function getCertificateEventAttribute($certificateId) {
117139
return $eventAttribute->fetchAll();
118140
}
119141

142+
/**
143+
* Retrieves event type ids from an event attribute configuration.
144+
*
145+
* @param array $eventAttribute
146+
*
147+
* @return array
148+
*/
149+
private function getEventAttributeEventTypeIds(array $eventAttribute): array {
150+
$eventTypeIds = [];
151+
152+
foreach ($eventAttribute as $attribute) {
153+
if (!empty($attribute['event_type_ids'])) {
154+
$eventTypeIds = array_merge($eventTypeIds, explode(',', $attribute['event_type_ids']));
155+
}
156+
}
157+
158+
return $this->sanitizeEventTypeIds($eventTypeIds);
159+
}
160+
161+
/**
162+
* Sanitizes event type ids and removes deleted values.
163+
*
164+
* @param array $eventTypeIds
165+
*
166+
* @return array
167+
*/
168+
private function sanitizeEventTypeIds(array $eventTypeIds): array {
169+
$eventTypes = CRM_Core_OptionGroup::values('event_type', FALSE, FALSE, FALSE, 'AND v.is_active = 1');
170+
$eventTypeIds = array_map('intval', $eventTypeIds);
171+
172+
return array_values(array_intersect($eventTypeIds, array_keys($eventTypes)));
173+
}
174+
175+
/**
176+
* Build event type condition for certificate retrieval.
177+
*
178+
* @param int $eventTypeId
179+
*
180+
* @return string
181+
*/
182+
private function getEventTypeCondition(int $eventTypeId) {
183+
$column = CRM_Certificate_BAO_CompuCertificateEventAttribute::getTableName() . '.event_type_ids';
184+
$eventTypeCondition = "$column IS NULL";
185+
186+
if (!empty($eventTypeId)) {
187+
$eventTypeCondition = sprintf('(%s OR FIND_IN_SET(%s, %s))', $eventTypeCondition, $eventTypeId, $column);
188+
}
189+
190+
return $eventTypeCondition;
191+
}
192+
120193
/**
121194
* {@inheritDoc}
122195
*/
@@ -127,6 +200,11 @@ protected function addEntityConditionals($certificateBAO, $entityId, $contactId)
127200
'is_active' => 1,
128201
]);
129202
$participantRoleIds = implode(',', (array) $participant['participant_role_id']);
203+
$event = civicrm_api3('Event', 'getsingle', [
204+
'id' => $participant['event_id'],
205+
'return' => ['event_type_id'],
206+
]);
207+
$eventTypeId = (int) ($event['event_type_id'] ?? 0);
130208

131209
$certificateBAO->joinAdd(['id', new CRM_Certificate_BAO_CompuCertificateEntityType(), 'certificate_id'], 'LEFT');
132210
$certificateBAO->joinAdd(['id', new CRM_Certificate_BAO_CompuCertificateStatus(), 'certificate_id'], 'LEFT');
@@ -135,6 +213,7 @@ protected function addEntityConditionals($certificateBAO, $entityId, $contactId)
135213
$certificateBAO->whereAdd('entity_type_id = ' . $participant['event_id'] . ' OR entity_type_id IS NULL');
136214
$certificateBAO->whereAdd('status_id = ' . $participant['participant_status_id'] . ' OR status_id IS NULL');
137215
$certificateBAO->whereAdd('participant_type_id IN (' . $participantRoleIds . ') OR participant_type_id IS NULL');
216+
$certificateBAO->whereAdd($this->getEventTypeCondition($eventTypeId));
138217
}
139218

140219
/**
@@ -152,6 +231,7 @@ public function formatConfiguredCertificatesForContact(array $configuredCertific
152231
foreach ($configuredCertificates as $configuredCertificate) {
153232
$eventAttribute = $this->getCertificateEventAttribute($configuredCertificate['certificate_id']);
154233
$participantTypeId = array_column($eventAttribute, 'participant_type_id');
234+
$eventTypeIds = $this->getEventAttributeEventTypeIds($eventAttribute);
155235

156236
$condition = [
157237
'contact_id' => $contactId,
@@ -170,6 +250,10 @@ public function formatConfiguredCertificatesForContact(array $configuredCertific
170250
$condition['participant_role_id'] = ['IN' => (array) $participantTypeId];
171251
}
172252

253+
if (!empty($eventTypeIds)) {
254+
$condition['api.Event.get']['event_type_id'] = ['IN' => $eventTypeIds];
255+
}
256+
173257
$result = [];
174258
try {
175259
$result = civicrm_api3('Participant', 'get', $condition);
@@ -182,10 +266,18 @@ public function formatConfiguredCertificatesForContact(array $configuredCertific
182266
continue;
183267
}
184268

185-
array_walk($result['values'], function ($participant) use (&$certificates, $configuredCertificate, $contactId) {
269+
array_walk($result['values'], function ($participant) use (&$certificates, $configuredCertificate, $contactId, $eventTypeIds) {
186270
if (empty($participant['api.Event.get']['values'])) {
187271
return;
188272
}
273+
if (!empty($eventTypeIds)) {
274+
$matchedEvent = reset($participant['api.Event.get']['values']);
275+
$matchedEventTypeId = (int) ($matchedEvent['event_type_id'] ?? 0);
276+
if (empty($matchedEventTypeId) || !in_array($matchedEventTypeId, $eventTypeIds)) {
277+
return;
278+
}
279+
}
280+
189281
$certificate = [
190282
'participant_id' => $participant['id'],
191283
'event_id' => $participant['event_id'],

CRM/Certificate/Entity/Membership.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function getCertificateConfiguredStatuses($certificateId) {
8282
/**
8383
* {@inheritDoc}
8484
*/
85-
public function getCertificateConfiguredTypes($certificateId) {
85+
public function getCertificateConfiguredTypes($certificateId, $includeAttrs = FALSE) {
8686
$entityTypeBAO = new CRM_Certificate_BAO_CompuCertificateEntityType();
8787
$entityTypeBAO->whereAdd("certificate_id = " . $certificateId);
8888

CRM/Certificate/Form/CertificateConfigure.php

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,21 @@ public function buildQuickForm() {
6161
1 => 'disabled',
6262
'class' => 'form-control',
6363
],
64-
TRUE
6564
);
6665

66+
$this->addEntityRef('event_type_ids', ts('Event Types'), [
67+
'entity' => 'OptionValue',
68+
'placeholder' => ts('- Select -'),
69+
'select' => ['multiple' => TRUE, 'minimumInputLength' => 0],
70+
'api' => [
71+
'params' => [
72+
'option_group_id' => 'event_type',
73+
'is_active' => 1,
74+
],
75+
],
76+
'class' => 'form-control',
77+
]);
78+
6779
$this->add(
6880
'text',
6981
'participant_type_id',
@@ -180,7 +192,7 @@ public function buildQuickForm() {
180192
],
181193
]);
182194

183-
$elementWithHelpTexts = ['relationship_types', 'min_valid_from_date', 'max_valid_through_date', 'download_type'];
195+
$elementWithHelpTexts = ['relationship_types', 'min_valid_from_date', 'max_valid_through_date', 'download_type', 'event_type_ids'];
184196

185197
$this->assign('help', $elementWithHelpTexts);
186198
$this->assign('previousFile', $this->getPreviousFileURL());
@@ -249,6 +261,7 @@ private function saveConfiguration($values) {
249261
$values['statuses'] = empty($values['statuses']) ? [] : explode(',', $values['statuses']);
250262
$values['linked_to'] = empty($values['linked_to']) ? [] : explode(',', $values['linked_to']);
251263
$values['relationship_types'] = empty($values['relationship_types']) ? [] : explode(',', $values['relationship_types']);
264+
$values['event_type_ids'] = empty($values['event_type_ids']) ? [] : explode(',', $values['event_type_ids']);
252265

253266
$result = $entity->store($values);
254267
}
@@ -306,6 +319,7 @@ public function certificateRule($values, $files) {
306319
// The participant_type field should only be validated for Event Certificate.
307320
if ($values['type'] == CRM_Certificate_Enum_CertificateType::EVENTS) {
308321
$this->validateParticipantTypeField($values, $errors);
322+
$this->validateEventCertificateFilters($values, $errors);
309323
}
310324

311325
return $errors ?: TRUE;
@@ -363,7 +377,7 @@ public function validateStatusesField(&$values, &$errors) {
363377
* @param array $errors
364378
*/
365379
public function validateLinkedToField(&$values, &$errors) {
366-
if (empty($values['linked_to'])) {
380+
if (empty($values['linked_to']) && ((int) $values['type']) !== CRM_Certificate_Enum_CertificateType::EVENTS) {
367381
$errors['linked_to'] = ts('The "linked to" field is required');
368382
}
369383
}
@@ -393,6 +407,29 @@ public function validateParticipantTypeField($values, &$errors) {
393407
}
394408
}
395409

410+
/**
411+
* Validates that either event type or event is selected for event certificates.
412+
*
413+
* @param array $values
414+
* @param array $errors
415+
*/
416+
public function validateEventCertificateFilters($values, &$errors) {
417+
$hasEventType = !empty($values['event_type_ids']);
418+
$hasEvent = !empty($values['linked_to']);
419+
420+
if ($hasEventType && $hasEvent) {
421+
CRM_Core_Session::setStatus(ts('Event and Event Type are both selected; the certificate will apply only when both match.'), ts('Notice'), 'info');
422+
}
423+
424+
if ($hasEventType || $hasEvent) {
425+
return;
426+
}
427+
428+
$message = ts('Select at least one Event Type or Specific Event.');
429+
$errors['event_type_ids'] = $message;
430+
$errors['linked_to'] = $message;
431+
}
432+
396433
/**
397434
* Validates date field.
398435
*

CRM/Certificate/Page/ConfigureCertificate.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private function getAllConfiguredCertificates() {
3636
$entity = CRM_Certificate_Entity_EntityFactory::create($certificateBAO->entity);
3737

3838
$options = CRM_Certificate_Enum_CertificateType::getOptions();
39-
$configuredTypes = $entity->getCertificateConfiguredTypes($certificateBAO->id);
39+
$configuredTypes = $entity->getCertificateConfiguredTypes($certificateBAO->id, TRUE);
4040
$configuredStatuses = $entity->getCertificateConfiguredStatuses($certificateBAO->id);
4141
$action = CRM_Core_Action::formLink($this->actionLinks(), NULL, ['id' => $certificateBAO->id]);
4242

0 commit comments

Comments
 (0)