4
* Export all facilities from the system.
6
* It is called from facility actions, and this class has basically been constructed to avoid
7
* facility actions from growing to an unmanageable length.
11
* LICENSE: This source file is subject to LGPLv2.1 license
12
* that is available through the world-wide-web at the following URI:
13
* http://www.gnu.org/licenses/lgpl-2.1.html
15
* @author Nils Stolpe, CUNY SPS
16
* @author Shirley Chan, CUNY SPS
17
* @author Clayton Kramer, CUNY SPS
19
* Copyright of the Sahana Software Foundation, sahanafoundation.org
21
class agEventFacilityExporter
25
* The constructor sets up several variables, mostly arrays, that will be used
26
* elsewhere in the class. Calls are made to a number of agHelper classes to
27
* gather the datapoints that will be exported and handle the formatting.
29
* @todo Refactor so these parameters can be dynamically defined.
31
function __construct($eventId)
33
$this->primaryOnly = TRUE;
34
$this->contactType = 'work';
35
$this->addressStandard = 'us standard';
36
$this->exportHeaders = array('Facility Name', 'Facility Code', 'Facility Resource Type Abbr',
37
'Facility Resource Status', 'Facility Capacity', 'Facility Activation Sequence',
38
'Facility Allocation Status', 'Facility Group', 'Facility Group Type',
39
'Facility Group Allocation Status', 'Facility Group Activation Sequence',
40
'Work Email', 'Work Phone');
41
$this->facilityGeneralInfo = agFacilityHelper::facilityGeneralInfo('Scenario', $scenarioId);
42
$this->eventName = Doctrine_Core::getTable('agEvent')->find($eventId)->get('event_name');
43
$this->facilityAddress = agFacilityHelper::facilityAddress($this->addressStandard, $this->primaryOnly, $this->contactType);
44
$this->facilityGeo = agFacilityHelper::facilityGeo($this->primaryOnly, $this->contactType);
45
$this->facilityEmail = agFacilityHelper::facilityEmail($this->primaryOnly, $this->contactType);
46
$this->facilityPhone = agFacilityHelper::facilityPhone($this->primaryOnly, $this->contactType);
47
$this->facilityStaffResource = agFacilityHelper::facilityStaffResource();
48
$this->addressFormat = agDoctrineQuery::create()
49
->select('ae.address_element')
50
->from('agAddressElement ae')
51
->innerJoin('ae.agAddressFormat af')
52
->innerJoin('af.agAddressStandard astd')
53
->where('astd.address_standard=?', $this->addressStandard)
54
->andWhere('ae.address_element<>?', 'zip+4')
55
->orderBy('af.line_sequence, af.inline_sequence')
56
->execute(array(), 'single_value_array');
57
$this->staffResourceTypes = $this->queryStaffResourceTypes();
61
* This function calls the other functions needed to export facility data and
62
* returns the constructed XLS file.
64
* @return array() $exportResponse An associative array of two elements,
65
* fileName and filePath. fileName is the name
66
* of the XLS file that has been constructed
67
* and is held in temporary storage.
68
* filePath is the path to that file.
70
public function export()
72
$this->buildAddressHeaders();
73
$this->buildGeoHeaders();
74
$this->buildStaffTypeHeaders();
76
$lookUps = $this->buildLookUpArray();
77
$lookUpContent = $this->gatherLookupValues($lookUps);
79
$facilityExportRecords = $this->buildExportRecords();
81
$exportResponse = $this->buildXls($facilityExportRecords, $lookUpContent);
82
return $exportResponse;
85
public function getJsonExport()
88
$lookUps = $this->buildLookUpArray();
89
$lookUpContent = $this->gatherLookupValues($lookUps);
91
$facilityExportRecords = $this->buildExportRecords();
93
return json_encode($facilityExportRecords, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
98
* @return array() $facilityExportRecords A two-dimensional array. The first level
99
* is indexed, and each of it's elements
100
* contains all the data for a complete facility
101
* export record. Those datapoints are held in
102
* the second level associative array, the keys
103
* of which correspond to headers in the output XLS.
105
* @todo break this up into smaller functions.
107
private function buildExportRecords()
109
$facilityExportRecords = array();
110
foreach ($this->facilityGeneralInfo as $fac) {
112
$entry['Facility Name'] = $fac['f_facility_name'];
113
$entry['Facility Code'] = $fac['f_facility_code'];
114
$entry['Facility Resource Type Abbr'] = $fac['frt_facility_resource_type_abbr'];
115
$entry['Facility Resource Status'] = $fac['frs_facility_resource_status'];
116
$entry['Facility Capacity'] = $fac['fr_capacity'];
117
$entry['Facility Activation Sequence'] = $fac['sfr_activation_sequence'];
118
$entry['Facility Allocation Status'] = $fac['fras_facility_resource_allocation_status'];
119
$entry['Facility Group'] = $fac['sfg_scenario_facility_group'];
120
$entry['Facility Group Type'] = $fac['fgt_facility_group_type'];
121
$entry['Facility Group Allocation Status'] = $fac['fgas_facility_group_allocation_status'];
122
$entry['Facility Group Activation Sequence'] = $fac['sfg_activation_sequence'];
125
if (array_key_exists($fac['f_id'], $this->facilityEmail)) {
126
$priorityNumber = key($this->facilityEmail[$fac['f_id']][$this->contactType]);
127
$entry['Work Email'] = $this->facilityEmail[$fac['f_id']][$this->contactType][$priorityNumber];
129
$entry['Work Email'] = null;
132
// Facility phone numbers
133
if (array_key_exists($fac['f_id'], $this->facilityPhone)) {
134
$priorityNumber = key($this->facilityPhone[$fac['f_id']][$this->contactType]);
135
$entry['Work Phone'] = $this->facilityPhone[$fac['f_id']][$this->contactType][$priorityNumber];
137
$entry['Work Phone'] = null;
142
if (array_key_exists($fac['f_id'], $this->facilityAddress)) {
143
$priorityNumber = key($this->facilityAddress[$fac['f_id']][$this->contactType]);
144
$addressId = $this->facilityAddress[$fac['f_id']][$this->contactType][$priorityNumber]['address_id'];
146
foreach ($this->addressFormat as $key => $addr) {
149
$exp_index = 'Street 1';
152
$exp_index = 'Street 2';
155
$exp_index = 'Postal Code';
158
$exp_index = ucwords($addr);
162
if (array_key_exists($addr, $this->facilityAddress[$fac['f_id']][$this->contactType][$priorityNumber])) {
163
$entry[$exp_index] = $this->facilityAddress[$fac['f_id']][$this->contactType][$priorityNumber][$addr];
165
$entry[$exp_index] = null;
171
if (array_key_exists($fac['f_id'], $this->facilityGeo)) {
172
if (isset($addressId)) {
173
if (array_key_exists($addressId, $this->facilityGeo[$fac['f_id']])) {
174
$entry['Longitude'] = $this->facilityGeo[$fac['f_id']][$addressId]['longitude'];
175
$entry['Latitude'] = $this->facilityGeo[$fac['f_id']][$addressId]['latitude'];
177
$entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
180
$entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
183
$entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
186
// Use the staff resource types returned from the query above to get the actual
187
// staff type minimums and maximums.
188
foreach ($this->staffResourceTypes as $stfResType) {
189
if (strtolower($stfResType) == 'staff') {
190
$exp_index = 'generalist';
192
$exp_index = strtolower(str_replace(' ', '_', $stfResType));
195
if (array_key_exists($fac['sfr_id'], $this->facilityStaffResource)) {
196
if (array_key_exists($stfResType, $this->facilityStaffResource[$fac['sfr_id']])) {
197
$entry[$exp_index . '_min'] = $this->facilityStaffResource[$fac['sfr_id']][$stfResType]['minimum staff'];
198
$entry[$exp_index . '_max'] = $this->facilityStaffResource[$fac['sfr_id']][$stfResType]['maximum staff'];
200
$entry = $entry + array_combine(array($exp_index . '_min', $exp_index . '_max'), array_fill(count($entry), 2, NULL));
203
$entry = $entry + array_combine(array($exp_index . '_min', $exp_index . '_max'), array_fill(count($entry), 2, NULL));
207
// Append the array just built to the total list of records.
208
$facilityExportRecords[] = $entry;
210
return $facilityExportRecords;
214
* Each of the column in the XLS's active sheet is sized to display all contents.
216
* @param sfPhpExcel object $objPHPExcel The sfPhpExcel object that is being
217
* populated by buildXls.
219
private function sizeColumns($objPHPExcel)
221
$highestColumn = $objPHPExcel->getActiveSheet()->getHighestColumn();
222
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
223
for ($i = $highestColumnIndex; $i >= 0; $i--) {
224
$objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(true);
229
* $this->exportHeaders are used to create the headers for each sheet in the XLS. This functions is called whenever
230
* a new sheet is added (aside from the final definition sheet).
232
* @param sfPhpExcel object $objPHPExcel The sfPhpExcel object that is being
233
* populated by buildXls.
235
private function buildSheetHeaders($objPHPExcel)
237
foreach ($this->exportHeaders as $hKey => $heading) {
238
$objPHPExcel->getActiveSheet()->getCellByColumnAndRow($hKey, 1)->setValue($heading);
243
* Builds the headers for the address fields in the XLS file, then adds them to
244
* the exportHeaders array.
246
private function buildAddressHeaders()
248
$this->addressHeaders = array();
249
foreach ($this->addressFormat as $add) {
252
$this->addressHeaders[] = 'Street 1';
255
$this->addressHeaders[] = 'Street 2';
258
$this->addressHeaders[] = 'Postal Code';
261
$this->addressHeaders[] = ucwords($add);
264
$this->exportHeaders = array_merge($this->exportHeaders, $this->addressHeaders);
268
* Not much happens here, this function just appends Longitude and Latitude to the
269
* already defined exportHeaders. This is mainly a placeholder function in case it
270
* requires expansion or abstraction in the future.
272
private function buildGeoHeaders()
274
array_push($this->exportHeaders, "Longitude", "Latitude");
278
* Builds the headers for minimum and maximum staff type requirments.
280
private function buildStaffTypeHeaders()
282
$stfHeaders = array();
283
foreach ($this->staffResourceTypes as $stfResType) {
284
$stfResType = strtolower(str_replace(' ', '_', $stfResType));
285
$stfHeaders[] = $stfResType . '_min';
286
$stfHeaders[] = $stfResType . '_max';
288
$this->exportHeaders = array_merge($this->exportHeaders, $stfHeaders);
293
* @return array() $staffResourceTypes An array of all values from
294
* agStaffResourceType.staff_resource_type
296
private function queryStaffResourceTypes()
298
$staffResourceTypes = agDoctrineQuery::create()
299
->select('srt.staff_resource_type, srt.id')
300
->from('agStaffResourceType srt')
301
->execute(array(), 'single_value_array');
302
return $staffResourceTypes;
306
* In the future, this should be more of a function rather than just a multidimensional
307
* array. The values listed here (and in the future, constructed here) are use to
308
* construct doctrine queries in gatherLookupValues.
310
* @return array $lookUps A two dimensional associative array. Keys of the first level
311
* are headers for the lookup columns in the XLS that will be
312
* output once export() has completed. The second level keys
313
* are pretty self explanatory, determining the table and column
314
* to select from, and the column and value for a WHERE clause
317
* @todo make this into a function that does more than declare and return an array.
319
private function buildLookUpArray()
322
'Facility Resource Status' => array(
323
'selectTable' => 'agFacilityResourceStatus',
324
'selectColumn' => 'facility_resource_status',
325
'whereColumn' => null,
328
'Facility Resource Type Abbr' => array(
329
'selectTable' => 'agFacilityResourceType',
330
'selectColumn' => 'facility_resource_type_abbr',
331
'whereColumn' => null,
334
'Facility Allocation Status' => array(
335
'selectTable' => 'agFacilityResourceAllocationStatus',
336
'selectColumn' => 'facility_resource_allocation_status',
337
'whereColumn' => null,
340
'Facility Group Allocation Status' => array(
341
'selectTable' => 'agFacilityGroupAllocationStatus',
342
'selectColumn' => 'facility_group_allocation_status',
343
'whereColumn' => null,
347
'selectTable' => 'agAddressValue',
348
'selectColumn' => 'value',
349
'whereColumn' => 'address_element_id',
353
'selectTable' => 'agAddressValue',
354
'selectColumn' => 'value',
355
'whereColumn' => 'address_element_id',
358
'Facility Group Type' => array(
359
'selectTable' => 'agFacilityGroupType',
360
'selectColumn' => 'facility_group_type',
361
'whereColumn' => null,
364
'Event Facility Resource' => array(
365
'selectTable' => 'agEventFacilityResource',
366
'selectColumn' => 'facility_resource_id',
367
'whereColumn' => 'id',
375
* This function constructs a Doctrine Query based on the values of the parameter passed in.
377
* The query will return the values from a single column of a table, with the possiblity to
378
* add a where clause to the query.
380
* @param $lookups array() gatherLookupValues expects $lookups to be a two-dimensional array.
381
* Keys of the outer level are expected to be column headers for a
382
* lookup column, or some other kind of organized data list. However,
383
* submitting a non-associative array will not cause any errors.
385
* The expected structure of the array is something like this:
388
* 'Facility Resource Status' => array(
389
* 'selectTable' => 'agFacilityResourceStatus',
390
* 'selectColumn' => 'facility_resource_status',
391
* 'whereColumn' => null,
392
* 'whereValue' => null
394
* 'Facility Resource Status' => array(
395
* 'selectTable' => 'agFacilityResourceStatus',
396
* 'selectColumn' => 'facility_resource_status',
397
* 'whereColumn' => null,
398
* 'whereValue' => null
402
* Additional values of the $lookUps array can also be included.
403
* The keys of the inner array musy be set to selectTable, selectColumn,
404
* whereColumn, and whereValue.
406
private function gatherLookupValues($lookUps = null)
408
foreach ($lookUps as $key => $lookUp) {
409
$lookUpQuery = agDoctrineQuery::create()
410
->select($lookUp['selectColumn'])
411
->from($lookUp['selectTable']);
412
if (isset($lookUp['whereColumn']) && isset($lookUp['whereValue'])) {
413
$lookUpQuery->where($lookUp['whereColumn'] . " = " . $lookUp['whereValue']);
415
$returnedLookups[$key] = $lookUpQuery->execute(null, 'single_value_array');
417
return $returnedLookups;
b'\\ No newline at end of file'