1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: abstract class Horde_Data_Base
16: {
17: 18: 19: 20: 21:
22: protected $_browser;
23:
24: 25: 26: 27: 28:
29: protected $_cleanupCallback;
30:
31: 32: 33: 34: 35:
36: protected $_contentType = 'text/plain';
37:
38: 39: 40: 41: 42:
43: protected $_extension = '';
44:
45: 46: 47: 48: 49:
50: protected $_vars;
51:
52: 53: 54: 55: 56:
57: protected $_warnings = array();
58:
59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
71: public function __construct(array $params = array())
72: {
73: if (isset($params['browser'])) {
74: $this->_browser = $params['browser'];
75: }
76:
77: if (isset($params['cleanup']) && is_callable($params['cleanup'])) {
78: $this->_cleanupCallback = $params['cleanup'];
79: }
80:
81: $this->_vars = isset($params['vars'])
82: ? $params['vars']
83: : Horde_Variables::getDefaultVariables();
84: }
85:
86: 87: 88:
89: public function importData($text)
90: {
91: }
92:
93: 94: 95:
96: abstract public function exportData($data, $method = 'REQUEST');
97:
98: 99: 100:
101: public function importFile($filename, $header = false)
102: {
103: $data = file_get_contents($filename);
104: return $this->importData($data, $header);
105: }
106:
107: 108: 109:
110: abstract public function exportFile($filename, $data);
111:
112: 113: 114: 115: 116: 117: 118:
119: public function getNewline()
120: {
121: if (!isset($this->_browser)) {
122: throw new LogicException('Missing browser parameter.');
123: }
124:
125: switch ($this->_browser->getPlatform()) {
126: case 'win':
127: return "\r\n";
128:
129: case 'mac':
130: return "\r";
131:
132: case 'unix':
133: default:
134: return "\n";
135: }
136: }
137:
138: 139: 140: 141: 142: 143: 144:
145: public function getFilename($basename)
146: {
147: return $basename . '.' . $this->_extension;
148: }
149:
150: 151: 152: 153: 154:
155: public function getContentType()
156: {
157: return $this->_contentType;
158: }
159:
160: 161: 162: 163: 164: 165:
166: public function warnings()
167: {
168: return $this->_warnings;
169: }
170:
171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188:
189: protected function _mapDate($date, $type, $params, $key)
190: {
191: switch ($type) {
192: case 'date':
193: case 'monthday':
194: case 'monthdayyear':
195: $dates = explode($params['delimiter'][$key], $date);
196: if (count($dates) != 3) {
197: return $date;
198: }
199: $index = array_flip(explode('/', $params['format'][$key]));
200: return $dates[$index['year']] . '-' . $dates[$index['month']] . '-' . $dates[$index['mday']];
201:
202: case 'time':
203: $dates = explode($params['delimiter'][$key], $date);
204: if (count($dates) < 2 || count($dates) > 3) {
205: return $date;
206: }
207: if ($params['format'][$key] == 'ampm') {
208: if (strpos(strtolower($dates[count($dates)-1]), 'pm') !== false) {
209: if ($dates[0] !== '12') {
210: $dates[0] += 12;
211: }
212: } elseif ($dates[0] == '12') {
213: $dates[0] = '0';
214: }
215: $dates[count($dates) - 1] = sprintf('%02d', $dates[count($dates)-1]);
216: }
217: return $dates[0] . ':' . $dates[1] . (count($dates) == 3 ? (':' . $dates[2]) : ':00');
218:
219: case 'datetime':
220: switch ($params['order'][$key]) {
221: case -1:
222: return (string)(int)$date == $date
223: ? date('Y-m-d H:i:s', $date)
224: : $date;
225: case 0:
226: list($day, $time) = explode(' ', $date, 2);
227: break;
228: case 1:
229: list($time, $day) = explode(' ', $date, 2);
230: break;
231: }
232: $date = $this->_mapDate($day, 'date',
233: array('delimiter' => $params['day_delimiter'],
234: 'format' => $params['day_format']),
235: $key);
236: $time = $this->_mapDate($time, 'time',
237: array('delimiter' => $params['time_delimiter'],
238: 'format' => $params['time_format']),
239: $key);
240: return $date . ' ' . $time;
241:
242: }
243: }
244:
245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256:
257: public function nextStep($action, $param = array())
258: {
259:
260: if (is_null($action)) {
261: return Horde_Data::IMPORT_FILE;
262: }
263:
264:
265: $session = $GLOBALS['injector']->getInstance('Horde_Session');
266:
267: switch ($action) {
268: case Horde_Data::IMPORT_FILE:
269: if (!isset($this->_browser)) {
270: throw new LogicException('Missing browser parameter.');
271: }
272:
273: try {
274: $this->_browser->wasFileUploaded('import_file', $param['file_types'][$this->_vars->import_format]);
275: } catch (Horde_Exception $e) {
276: throw new Horde_Data_Exception($e);
277: }
278: if ($_FILES['import_file']['size'] <= 0) {
279: throw new Horde_Data_Exception(Horde_Data_Translation::t("The file contained no data."));
280: }
281: $session->set('horde', 'import_data/format', $this->_vars->import_format);
282: break;
283:
284: case Horde_Data::IMPORT_MAPPED:
285: if (!$this->_vars->dataKeys || !$this->_vars->appKeys) {
286: throw new Horde_Data_Exception(Horde_Data_Translation::t("You didn\'t map any fields from the imported file to the corresponding fields."));
287: }
288: $dataKeys = explode("\t", $this->_vars->dataKeys);
289: $appKeys = explode("\t", $this->_vars->appKeys);
290: $map = array();
291: $dates = array();
292:
293: $import_data = $session->get('horde', 'import_data/data', Horde_Session::TYPE_ARRAY);
294:
295: foreach ($appKeys as $key => $app) {
296: $map[$dataKeys[$key]] = $app;
297: if (isset($param['time_fields']) &&
298: isset($param['time_fields'][$app])) {
299: $dates[$dataKeys[$key]]['type'] = $param['time_fields'][$app];
300: $dates[$dataKeys[$key]]['values'] = array();
301: $i = 0;
302:
303: while ($i < count($import_data) &&
304: count($dates[$dataKeys[$key]]['values']) < 10) {
305: if (!empty($import_data[$i][$dataKeys[$key]])) {
306: $dates[$dataKeys[$key]]['values'][] = $import_data[$i][$dataKeys[$key]];
307: }
308: ++$i;
309: }
310: }
311: }
312:
313: $session->set('horde', 'import_data/map', $map);
314: if (count($dates) > 0) {
315: foreach ($dates as $key => $data) {
316: if (count($data['values'])) {
317: $session->set('horde', 'import_data/dates', $dates);
318: return Horde_Data::IMPORT_DATETIME;
319: }
320: }
321: }
322: return $this->nextStep(Horde_Data::IMPORT_DATA, $param);
323:
324: case Horde_Data::IMPORT_DATETIME:
325: case Horde_Data::IMPORT_DATA:
326: if ($action == Horde_Data::IMPORT_DATETIME) {
327: $params = array(
328: 'delimiter' => $this->_vars->delimiter,
329: 'format' => $this->_vars->format,
330: 'order' => $this->_vars->order,
331: 'day_delimiter' => $this->_vars->day_delimiter,
332: 'day_format' => $this->_vars->day_format,
333: 'time_delimiter' => $this->_vars->time_delimiter,
334: 'time_format' => $this->_vars->time_format
335: );
336: }
337:
338: if (!$session->exists('horde', 'import_data/data')) {
339: throw new Horde_Data_Exception(Horde_Data_Translation::t("The uploaded data was lost since the previous step."));
340: }
341:
342:
343: $data = array();
344: $data_map = $session->get('horde', 'import_data/map', Horde_Session::TYPE_ARRAY);
345:
346: foreach ($session->get('horde', 'import_data/data') as $row) {
347: $data_row = array();
348: foreach ($row as $key => $val) {
349: if (isset($data_map[$key])) {
350: $mapped_key = $data_map[$key];
351: if ($action == Horde_Data::IMPORT_DATETIME &&
352: !empty($val) &&
353: isset($param['time_fields']) &&
354: isset($param['time_fields'][$mapped_key])) {
355: $val = $this->_mapDate($val, $param['time_fields'][$mapped_key], $params, $key);
356: }
357: $data_row[$mapped_key] = $val;
358: }
359: }
360: $data[] = $data_row;
361: }
362:
363: return $data;
364: }
365: }
366:
367: 368: 369: 370: 371: 372: 373:
374: public function cleanup()
375: {
376:
377: $session = $GLOBALS['injector']->getInstance('Horde_Session');
378:
379: if ($filename = $session->get('horde', 'import_data/file_name')) {
380: @unlink($filename);
381: }
382: $session->remove('horde', 'import_data');
383:
384: if ($this->_cleanupCallback) {
385: return call_user_func($this->_cleanupCallback);
386: }
387: }
388:
389: }
390: