Merge pull request #3587 from kurund/CRM-14567
[civicrm-core.git] / CRM / Case / Audit / AuditConfig.php
1 <?php
2
3 /**
4 * Class CRM_Case_Audit_AuditConfig
5 */
6 class CRM_Case_Audit_AuditConfig {
7 private $filename;
8 private $completionLabel;
9 private $completionValue;
10 private $sortByLabels;
11 private $regionFieldList;
12 private $includeRules;
13 private $sortRegion;
14 private $ifBlanks;
15
16 /**
17 * @param $filename
18 */
19 public function __construct($filename) {
20 $this->filename = $filename;
21
22 // set some defaults
23 $this->completionLabel = "Status";
24 $this->completionValue = "Completed";
25 $this->sortByLabels = array("Actual Date", "Due Date");
26 $this->ifBlanks = array();
27
28 $this->loadConfig();
29 }
30
31 /**
32 * @return string
33 */
34 public function getCompletionValue() {
35 return $this->completionValue;
36 }
37
38 /**
39 * @return string
40 */
41 public function getCompletionLabel() {
42 return $this->completionLabel;
43 }
44
45 /**
46 * @return array
47 */
48 public function getSortByLabels() {
49 return $this->sortByLabels;
50 }
51
52 /**
53 * @return array
54 */
55 public function getIfBlanks() {
56 return $this->ifBlanks;
57 }
58
59 public function loadConfig() {
60 $this->regionFieldList = array();
61 $this->includeRules = array();
62
63 $doc = new DOMDocument();
64 if ($doc->load(dirname(__FILE__) . '/' . $this->filename)) {
65 $regions = $doc->getElementsByTagName("region");
66 foreach ($regions as $region) {
67 $regionName = $region->getAttribute("name");
68 $this->regionFieldList[$regionName] = array();
69
70 // Inclusion/exclusion settings
71 $includeRule = $region->getAttribute("includeRule");
72 if (empty($includeRule)) {
73 $includeRule = 'include';
74 }
75 $this->includeRules[$regionName] = array('rule' => $includeRule);
76 if ($includeRule == 'exclude') {
77 $altRegion = $region->getAttribute("exclusionCorrespondingRegion");
78 $this->includeRules[$regionName]['altRegion'] = $altRegion;
79 }
80
81 // Time component display settings
82 $includeTime = $region->getAttribute("includeTime");
83 if (empty($includeTime)) {
84 $includeTime = 'false';
85 }
86 $this->includeRules[$regionName]['includeTime'] = $includeTime;
87
88 $fieldCount = 0;
89 $fields = $region->getElementsByTagName("field");
90 foreach ($fields as $field) {
91 /* Storing them this way, which is backwards to how you might normally
92 have arrays with a numeric key and a text value, ends up making things better
93 in the other functions, in particular the sorting and also inRegion should end
94 up being more efficient (searching for a key instead of a value). */
95
96 $this->regionFieldList[$regionName][$field->nodeValue] = $fieldCount;
97
98 // Field-level overrides of time component display settings
99 $includeTime = $field->getAttribute("includeTime");
100 if (!empty($includeTime)) {
101 $this->regionFieldList[$regionName][$field->nodeValue]['includeTime'] = $includeTime;
102 }
103
104 // ifBlank attribute
105 $ifBlank = $field->getAttribute("ifBlank");
106 if (!empty($ifBlank)) {
107 $this->ifBlanks[$regionName][$field->nodeValue] = $ifBlank;
108 }
109
110 $fieldCount++;
111 }
112 }
113
114 $completionStatus = $doc->getElementsByTagName("completionStatus");
115 if (!empty($completionStatus)) {
116 $label_elements = $completionStatus->item(0)->getElementsByTagName("label");
117 $this->completionLabel = $label_elements->item(0)->nodeValue;
118
119 $value_elements = $completionStatus->item(0)->getElementsByTagName("value");
120 $this->completionValue = $value_elements->item(0)->nodeValue;
121 }
122
123 $sortElement = $doc->getElementsByTagName("sortByLabels");
124 if (!empty($sortElement)) {
125 $this->sortByLabels = array();
126 $label_elements = $sortElement->item(0)->getElementsByTagName("label");
127 foreach ($label_elements as $ele) {
128 $this->sortByLabels[] = $ele->nodeValue;
129 }
130 }
131 }
132 }
133
134 /* inRegion
135 *
136 * Check if label $n is explicitly listed in region $r in the config.
137 */
138
139 /**
140 * @param $n
141 * @param $r
142 *
143 * @return bool
144 */
145 public function inRegion($n, $r) {
146 if (empty($this->regionFieldList[$r])) {
147 return FALSE;
148 }
149 else {
150 return array_key_exists($n, $this->regionFieldList[$r]);
151 }
152 }
153
154 /* includeInRegion
155 *
156 * Should field $n be included in region $r, taking into account exclusion rules.
157 */
158
159 /**
160 * @param $n
161 * @param $r
162 *
163 * @return bool
164 */
165 public function includeInRegion($n, $r) {
166 $add_it = FALSE;
167 $rules = $this->includeRules[$r];
168 if ($rules['rule'] == 'exclude') {
169 if (!$this->inRegion($n, $r) && !$this->inRegion($n, $rules['altRegion'])) {
170 $add_it = TRUE;
171 }
172 }
173 elseif ($this->inRegion($n, $r)) {
174 $add_it = TRUE;
175 }
176 return $add_it;
177 }
178
179 /* includeTime
180 *
181 * Should the time component of field $n in region $r be displayed?
182 */
183
184 /**
185 * @param $n
186 * @param $r
187 *
188 * @return bool
189 */
190 public function includeTime($n, $r) {
191 $retval = FALSE;
192 if (empty($this->regionFieldList[$r][$n]['includeTime'])) {
193 // No field-level override, so look at the region's settings
194 if (!empty($this->includeRules[$r]['includeTime'])) {
195 $retval = $this->includeRules[$r]['includeTime'];
196 }
197 }
198 else {
199 $retval = $this->regionFieldList[$r][$n]['includeTime'];
200 }
201
202 // There's a mix of strings and boolean, so convert any strings.
203 if ($retval == 'false') {
204 $retval = FALSE;
205 }
206 elseif ($retval == 'true') {
207 $retval = TRUE;
208 }
209
210 return $retval;
211 }
212
213 /* getRegions
214 *
215 * Return a list of all the regions in the config file.
216 */
217
218 /**
219 * @return array
220 */
221 public function getRegions() {
222 return array_keys($this->regionFieldList);
223 }
224
225 /* sort
226 *
227 * Sort a group of fields for a given region according to the order in the config.
228 * The array to be sorted should have elements that have a member with a key of 'label', and the value should be the field label.
229 */
230
231 /**
232 * @param $f
233 * @param $r
234 */
235 public function sort(&$f, $r) {
236 // For exclusion-type regions, there's nothing to do, because we won't have been given any ordering.
237 if ($this->includeRules[$r]['rule'] == 'exclude') {
238 return;
239 }
240
241 $this->sortRegion = $r;
242 uasort($f, array(&$this, "compareFields"));
243 }
244
245 /* compareFields
246 *
247 * This is intended to be called as a sort callback function, returning whether a field in a region comes before or after another one.
248 * See also PHP's usort().
249 */
250
251 /**
252 * @param $a
253 * @param $b
254 *
255 * @return int
256 */
257 public function compareFields($a, $b) {
258 if (empty($this->regionFieldList[$this->sortRegion][$a['label']])) {
259 $x = 0;
260 }
261 else {
262 $x = $this->regionFieldList[$this->sortRegion][$a['label']];
263 }
264
265 if (empty($this->regionFieldList[$this->sortRegion][$b['label']])) {
266 $y = 0;
267 }
268 else {
269 $y = $this->regionFieldList[$this->sortRegion][$b['label']];
270 }
271
272 return $x - $y;
273 }
274 }
275