-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathRenderer.php
201 lines (174 loc) · 6.88 KB
/
Renderer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<?php
/*-------------------------------------------------------+
| SYSTOPIA - MORE GREETINGS EXTENSION |
| Copyright (C) 2017 SYSTOPIA |
| Author: B. Endres ([email protected]) |
| P. Batroff ([email protected]) |
| http://www.systopia.de/ |
+--------------------------------------------------------+
| This program is released as free software under the |
| Affero GPL license. You can redistribute it and/or |
| modify it under the terms of this license which you |
| can read by viewing the included agpl.txt or online |
| at www.gnu.org/licenses/agpl.html. Removal of this |
| copyright header is strictly prohibited without |
| written permission from the original author(s). |
+--------------------------------------------------------*/
use Civi\Api4\Contact;
/**
* update current greetings
*
*/
class CRM_Moregreetings_Renderer {
/** @var array list of contact ids that should be excluded from updating */
protected static $excluded_contact_ids = [];
/**
* Re-calculate the more-greetings for one contact
*/
public static function updateMoreGreetings($contact_id, $contact = NULL): void {
// check exclusion list
if (in_array($contact_id, self::$excluded_contact_ids)) {
return;
}
// load the templates
$templates = Civi::settings()->get('moregreetings_templates');
if (!is_array($templates)) {
return;
}
// load the contact
if ($contact == NULL) {
// remark: if you change these parameters, see if you also want to adjust
// CRM_Moregreetings_Job::run and CRM_Moregreetings_Renderer::updateMoreGreetingsForContacts
$contact = Contact::get(FALSE)
->setSelect(self::getUsedContactFields($templates))
->addWhere('id', '=', $contact_id)
->execute()
->single();
}
// TODO: assign more stuff?
// prepare smarty
$smarty = CRM_Core_Smarty::singleton();
CRM_Utils_Smarty::registerCustomFunctions($smarty);
$smarty->assign('contact', $contact);
// load the current greetings
$current_greetings = CRM_Moregreetings_Config::getCurrentData($contact_id);
// get the fields to render
$greetings_to_render = self::getGreetingsToRender($contact, $templates, $current_greetings);
// render the greetings
$greetings_update = array();
foreach ($greetings_to_render as $greeting_key => $template) {
$new_value = $smarty->fetch("string:$template");
$new_value = trim($new_value);
// check if the value is really different (avoid unecessary updates)
if ($new_value != $current_greetings[$greeting_key]) {
$greetings_update[$greeting_key] = $new_value;
}
}
// finally: run the update if there are changes
if (!empty($greetings_update)) {
$greetings_update['entity_id'] = $contact_id;
$greetings_update['entity_table'] = 'civicrm_contact';
civicrm_api3('CustomValue', 'create', $greetings_update);
} else {
// error_log("Nothing to do");
}
}
/**
* Re-calculate the more-greetings for a list of contacts ()
*
* @param int $from_id only consider contact with ID >= $from_id
* @param int $max_count process no more than $max_count contacts
*
* @return int last contact ID processed, 0 if none
*/
public static function updateMoreGreetingsForContacts($from_id, $max_count): int {
$templates = Civi::settings()->get('moregreetings_templates');
// remark: if you change these parameters, see if you also want to adjust
// CRM_Moregreetings_Job::run and CRM_Moregreetings_Renderer::updateMoreGreetings
$contacts = Contact::get(FALSE)
->setSelect(self::getUsedContactFields($templates))
->addSelect('id')
->addWhere('id', '>=', $from_id)
->addWhere('is_deleted', '=', false)
->addOrderBy('id')
->setLimit($max_count)
->execute();
$last_id = 0;
foreach ($contacts as $contact) {
$last_id = $contact['id'];
self::updateMoreGreetings($last_id, $contact);
}
return $last_id;
}
/**
* Get an array [custom_key] => [template]
* of the fields to be rendered for this contact,
* i.e. all the fields are there and not protected
*/
protected static function getGreetingsToRender($contact, $templates, $current_data) {
// first: load
$active_fields = CRM_Moregreetings_Config::getActiveFields();
// compile a list of protected field data (field_numbers)
$protected_fields = array();
foreach ($active_fields as $field_id => $field) {
if (preg_match("#^greeting_field_(?P<field_number>\\d+)_protected$#", $field['name'], $matches)) {
$field_number = $matches['field_number'];
if (!empty($current_data["custom_{$field['id']}"])) {
$protected_fields[] = $field_number;
}
}
}
// now compile the list of unprotected active greeting fields
$fields_to_render = array();
foreach ($active_fields as $field_id => $field) {
if (preg_match("#^greeting_field_(?P<field_number>\d+)$#", $field['name'], $matches)) {
$field_number = $matches['field_number'];
if (!in_array($field_number, $protected_fields)) {
// this field is not protected
$template = CRM_Utils_Array::value("greeting_smarty_{$field_number}", $templates, '');
$fields_to_render["custom_{$field['id']}"] = $template;
}
}
}
return $fields_to_render;
}
/**
* @phpstan-return list<string> Fields used in the templates
*/
public static function getUsedContactFields($templates): array {
$active_fields = CRM_Moregreetings_Config::getActiveFields();
$fields_used = array();
// now compile the list of unprotected active greeting fields
$fields_to_render = array();
foreach ($active_fields as $field_id => $field) {
if (preg_match("#^greeting_field_(?P<field_number>\d+)$#", $field['name'], $matches)) {
$field_number = $matches['field_number'];
$template = CRM_Utils_Array::value("greeting_smarty_{$field_number}", $templates, '');
if (preg_match_all('#\$contact\.(?P<field>\w+)#', $template, $tokens)) {
foreach ($tokens['field'] as $field_name) {
$fields_used[$field_name] = 1;
}
}
}
}
return array_keys($fields_used);
}
/**
* Add a list of contact IDs to the exclusion list
*
* @param array $excluded_contact_ids
* list of contact IDs to be excluded from rendering
*/
public static function addExcludedContactIDs($excluded_contact_ids) {
self::$excluded_contact_ids = array_merge(self::$excluded_contact_ids, $excluded_contact_ids);
}
/**
* Clear the list of contact_ids to be excluded from rendering
*
* @return array
* previously set list of contact IDs
*/
public static function clearExcludedContactIDs() {
self::$excluded_contact_ids = [];
}
}