~fabiocbalbuquerque/sahana-agasti/web-services

« back to all changes in this revision

Viewing changes to apps/frontend/lib/util/agEventFacilityExporter.class.php

  • Committer: Clayton Kramer
  • Date: 2011-07-26 15:25:28 UTC
  • mto: (1.26.1 push-trunk)
  • mto: This revision was merged to the branch mainline in revision 25.
  • Revision ID: clayton.kramer@mail.cuny.edu-20110726152528-ut61tu1u7fwn95xb
Merged Fabio's webservices package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/**
 
4
 * Export all facilities from the system.
 
5
 *
 
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.
 
8
 *
 
9
 * PHP Version 5.3
 
10
 *
 
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
 
14
 *
 
15
 * @author     Nils Stolpe, CUNY SPS
 
16
 * @author     Shirley Chan, CUNY SPS
 
17
 * @author     Clayton Kramer, CUNY SPS
 
18
 *
 
19
 * Copyright of the Sahana Software Foundation, sahanafoundation.org
 
20
 * */
 
21
class agEventFacilityExporter
 
22
{
 
23
 
 
24
    /**
 
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.
 
28
     *
 
29
     * @todo Refactor so these parameters can be dynamically defined.
 
30
     * */
 
31
    function __construct($eventId)
 
32
    {
 
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();
 
58
    }
 
59
 
 
60
    /**
 
61
     * This function calls the other functions needed to export facility data and
 
62
     * returns the constructed XLS file.
 
63
     *
 
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.
 
69
     */
 
70
    public function export()
 
71
    {
 
72
        $this->buildAddressHeaders();
 
73
        $this->buildGeoHeaders();
 
74
        $this->buildStaffTypeHeaders();
 
75
 
 
76
        $lookUps = $this->buildLookUpArray();
 
77
        $lookUpContent = $this->gatherLookupValues($lookUps);
 
78
 
 
79
        $facilityExportRecords = $this->buildExportRecords();
 
80
 
 
81
        $exportResponse = $this->buildXls($facilityExportRecords, $lookUpContent);
 
82
        return $exportResponse;
 
83
    }
 
84
 
 
85
    public function getJsonExport()
 
86
    {
 
87
 
 
88
        $lookUps = $this->buildLookUpArray();
 
89
        $lookUpContent = $this->gatherLookupValues($lookUps);
 
90
 
 
91
        $facilityExportRecords = $this->buildExportRecords();
 
92
 
 
93
        return json_encode($facilityExportRecords, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
 
94
    }
 
95
 
 
96
    /**
 
97
     *
 
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.
 
104
     *
 
105
     * @todo break this up into smaller functions.
 
106
     * */
 
107
    private function buildExportRecords()
 
108
    {
 
109
        $facilityExportRecords = array();
 
110
        foreach ($this->facilityGeneralInfo as $fac) {
 
111
            $entry = array();
 
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'];
 
123
 
 
124
            // Facility email
 
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];
 
128
            } else {
 
129
                $entry['Work Email'] = null;
 
130
            }
 
131
 
 
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];
 
136
            } else {
 
137
                $entry['Work Phone'] = null;
 
138
            }
 
139
 
 
140
            // Facility address
 
141
            $addressId = 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'];
 
145
 
 
146
                foreach ($this->addressFormat as $key => $addr) {
 
147
                    switch ($addr) {
 
148
                        case 'line 1':
 
149
                            $exp_index = 'Street 1';
 
150
                            break;
 
151
                        case 'line 2':
 
152
                            $exp_index = 'Street 2';
 
153
                            break;
 
154
                        case 'zip5':
 
155
                            $exp_index = 'Postal Code';
 
156
                            break;
 
157
                        default:
 
158
                            $exp_index = ucwords($addr);
 
159
                    }
 
160
 
 
161
 
 
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];
 
164
                    } else {
 
165
                        $entry[$exp_index] = null;
 
166
                    }
 
167
                }
 
168
            }
 
169
 
 
170
            // facility geo.
 
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'];
 
176
                    } else {
 
177
                        $entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
 
178
                    }
 
179
                } else {
 
180
                    $entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
 
181
                }
 
182
            } else {
 
183
                $entry = $entry + array_combine(array('Longitude', 'Latitude'), array_fill(count($entry), 2, NULL));
 
184
            }
 
185
 
 
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';
 
191
                } else {
 
192
                    $exp_index = strtolower(str_replace(' ', '_', $stfResType));
 
193
                }
 
194
 
 
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'];
 
199
                    } else {
 
200
                        $entry = $entry + array_combine(array($exp_index . '_min', $exp_index . '_max'), array_fill(count($entry), 2, NULL));
 
201
                    }
 
202
                } else {
 
203
                    $entry = $entry + array_combine(array($exp_index . '_min', $exp_index . '_max'), array_fill(count($entry), 2, NULL));
 
204
                }
 
205
            }
 
206
 
 
207
            // Append the array just built to the total list of records.
 
208
            $facilityExportRecords[] = $entry;
 
209
        }
 
210
        return $facilityExportRecords;
 
211
    }
 
212
 
 
213
    /**
 
214
     * Each of the column in the XLS's active sheet is sized to display all contents.
 
215
     *
 
216
     * @param sfPhpExcel object $objPHPExcel   The sfPhpExcel object that is being
 
217
     *                                         populated by buildXls.
 
218
     * */
 
219
    private function sizeColumns($objPHPExcel)
 
220
    {
 
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);
 
225
        }
 
226
    }
 
227
 
 
228
    /**
 
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).
 
231
     *
 
232
     * @param sfPhpExcel object $objPHPExcel   The sfPhpExcel object that is being
 
233
     *                                         populated by buildXls.
 
234
     * */
 
235
    private function buildSheetHeaders($objPHPExcel)
 
236
    {
 
237
        foreach ($this->exportHeaders as $hKey => $heading) {
 
238
            $objPHPExcel->getActiveSheet()->getCellByColumnAndRow($hKey, 1)->setValue($heading);
 
239
        }
 
240
    }
 
241
 
 
242
    /**
 
243
     * Builds the headers for the address fields in the XLS file, then adds them to
 
244
     * the exportHeaders array.
 
245
     * */
 
246
    private function buildAddressHeaders()
 
247
    {
 
248
        $this->addressHeaders = array();
 
249
        foreach ($this->addressFormat as $add) {
 
250
            switch ($add) {
 
251
                case 'line 1':
 
252
                    $this->addressHeaders[] = 'Street 1';
 
253
                    break;
 
254
                case 'line 2':
 
255
                    $this->addressHeaders[] = 'Street 2';
 
256
                    break;
 
257
                case 'zip5':
 
258
                    $this->addressHeaders[] = 'Postal Code';
 
259
                    break;
 
260
                default:
 
261
                    $this->addressHeaders[] = ucwords($add);
 
262
            }
 
263
        }
 
264
        $this->exportHeaders = array_merge($this->exportHeaders, $this->addressHeaders);
 
265
    }
 
266
 
 
267
    /**
 
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.
 
271
     * */
 
272
    private function buildGeoHeaders()
 
273
    {
 
274
        array_push($this->exportHeaders, "Longitude", "Latitude");
 
275
    }
 
276
 
 
277
    /**
 
278
     * Builds the headers for minimum and maximum staff type requirments.
 
279
     * */
 
280
    private function buildStaffTypeHeaders()
 
281
    {
 
282
        $stfHeaders = array();
 
283
        foreach ($this->staffResourceTypes as $stfResType) {
 
284
            $stfResType = strtolower(str_replace(' ', '_', $stfResType));
 
285
            $stfHeaders[] = $stfResType . '_min';
 
286
            $stfHeaders[] = $stfResType . '_max';
 
287
        }
 
288
        $this->exportHeaders = array_merge($this->exportHeaders, $stfHeaders);
 
289
    }
 
290
 
 
291
    /**
 
292
     *
 
293
     * @return array() $staffResourceTypes   An array of all values from
 
294
     *                                         agStaffResourceType.staff_resource_type
 
295
     * */
 
296
    private function queryStaffResourceTypes()
 
297
    {
 
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;
 
303
    }
 
304
 
 
305
    /**
 
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.
 
309
     *
 
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
 
315
     *                           (if there is one).
 
316
     *
 
317
     * @todo make this into a function that does more than declare and return an array.
 
318
     * */
 
319
    private function buildLookUpArray()
 
320
    {
 
321
        $lookUps = array(
 
322
          'Facility Resource Status' => array(
 
323
            'selectTable' => 'agFacilityResourceStatus',
 
324
            'selectColumn' => 'facility_resource_status',
 
325
            'whereColumn' => null,
 
326
            'whereValue' => null
 
327
          ),
 
328
          'Facility Resource Type Abbr' => array(
 
329
            'selectTable' => 'agFacilityResourceType',
 
330
            'selectColumn' => 'facility_resource_type_abbr',
 
331
            'whereColumn' => null,
 
332
            'whereValue' => null
 
333
          ),
 
334
          'Facility Allocation Status' => array(
 
335
            'selectTable' => 'agFacilityResourceAllocationStatus',
 
336
            'selectColumn' => 'facility_resource_allocation_status',
 
337
            'whereColumn' => null,
 
338
            'whereValue' => null
 
339
          ),
 
340
          'Facility Group Allocation Status' => array(
 
341
            'selectTable' => 'agFacilityGroupAllocationStatus',
 
342
            'selectColumn' => 'facility_group_allocation_status',
 
343
            'whereColumn' => null,
 
344
            'whereValue' => null
 
345
          ),
 
346
          'Borough' => array(
 
347
            'selectTable' => 'agAddressValue',
 
348
            'selectColumn' => 'value',
 
349
            'whereColumn' => 'address_element_id',
 
350
            'whereValue' => 8
 
351
          ),
 
352
          'State' => array(
 
353
            'selectTable' => 'agAddressValue',
 
354
            'selectColumn' => 'value',
 
355
            'whereColumn' => 'address_element_id',
 
356
            'whereValue' => 4
 
357
          ),
 
358
          'Facility Group Type' => array(
 
359
            'selectTable' => 'agFacilityGroupType',
 
360
            'selectColumn' => 'facility_group_type',
 
361
            'whereColumn' => null,
 
362
            'whereValue' => null
 
363
          ),
 
364
          'Event Facility Resource' => array(
 
365
            'selectTable' => 'agEventFacilityResource',
 
366
            'selectColumn' => 'facility_resource_id',
 
367
            'whereColumn' => 'id',
 
368
            'whereValue' => 2
 
369
          )
 
370
        );
 
371
        return $lookUps;
 
372
    }
 
373
 
 
374
    /**
 
375
     * This function constructs a Doctrine Query based on the values of the parameter passed in.
 
376
     *
 
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.
 
379
     *
 
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.
 
384
     *
 
385
     *                          The expected structure of the array is something like this:
 
386
     *
 
387
     *                          $lookUps = array(
 
388
     *                                       'Facility Resource Status' => array(
 
389
     *                                           'selectTable'  => 'agFacilityResourceStatus',
 
390
     *                                           'selectColumn' => 'facility_resource_status',
 
391
     *                                           'whereColumn'  => null,
 
392
     *                                           'whereValue' => null
 
393
     *                                       ),
 
394
     *                                       'Facility Resource Status' => array(
 
395
     *                                           'selectTable'  => 'agFacilityResourceStatus',
 
396
     *                                           'selectColumn' => 'facility_resource_status',
 
397
     *                                           'whereColumn'  => null,
 
398
     *                                           'whereValue' => null
 
399
     *                                       )
 
400
     *                          );
 
401
     *
 
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.
 
405
     * */
 
406
    private function gatherLookupValues($lookUps = null)
 
407
    {
 
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']);
 
414
            }
 
415
            $returnedLookups[$key] = $lookUpQuery->execute(null, 'single_value_array');
 
416
        }
 
417
        return $returnedLookups;
 
418
    }
 
419
 
 
420
}
 
 
b'\\ No newline at end of file'