1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class Horde_Data_Tsv extends Horde_Data_Base
16: {
17: 18: 19: 20: 21:
22: protected $_extension = 'tsv';
23:
24: 25: 26: 27: 28:
29: protected $_contentType = 'text/tab-separated-values';
30:
31: 32: 33: 34: 35: 36: 37: 38: 39:
40: public function importData($contents, $header = false, $delimiter = "\t")
41: {
42: if ($GLOBALS['injector']->getInstance('Horde_Session')->get('horde', 'import_data/format') == 'pine') {
43: $contents = preg_replace('/\n +/', '', $contents);
44: }
45:
46: $contents = explode("\n", $contents);
47: $data = array();
48: if ($header) {
49: $head = explode($delimiter, array_shift($contents));
50: }
51:
52: foreach ($contents as $line) {
53: if (trim($line) == '') {
54: continue;
55: }
56: $line = explode($delimiter, $line);
57: if (!isset($head)) {
58: $data[] = $line;
59: } else {
60: $newline = array();
61: for ($i = 0; $i < count($head); $i++) {
62: $newline[$head[$i]] = empty($line[$i]) ? '' : $line[$i];
63: }
64: $data[] = $newline;
65: }
66: }
67:
68: return $data;
69: }
70:
71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
81: public function exportData($data, $header = false)
82: {
83: if (!is_array($data) || count($data) == 0) {
84: return '';
85: }
86: $export = '';
87: $head = array_keys(current($data));
88: if ($header) {
89: $export = implode("\t", $head) . "\n";
90: }
91: foreach ($data as $row) {
92: foreach ($head as $key) {
93: $cell = $row[$key];
94: if (!empty($cell) || $cell === 0) {
95: $export .= $cell;
96: }
97: $export .= "\t";
98: }
99: $export = substr($export, 0, -1) . "\n";
100: }
101:
102: return $export;
103: }
104:
105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115:
116: public function exportFile($filename, $data, $header = false)
117: {
118: if (!isset($this->_browser)) {
119: throw new LogicException('Missing browser parameter.');
120: }
121:
122: $export = $this->exportData($data, $header);
123: $this->_browser->downloadHeaders($filename, 'text/tab-separated-values', false, strlen($export));
124: echo $export;
125: }
126:
127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138:
139: public function nextStep($action, $param = array())
140: {
141: $session = $GLOBALS['injector']->getInstance('Horde_Session');
142:
143: switch ($action) {
144: case Horde_Data::IMPORT_FILE:
145: parent::nextStep($action, $param);
146:
147: $format = $session->get('horde', 'import_data/format');
148: if (in_array($format, array('mulberry', 'pine'))) {
149: $filedata = $this->importFile($_FILES['import_file']['tmp_name']);
150:
151: switch ($format) {
152: case 'mulberry':
153: $appKeys = array('alias', 'name', 'email', 'company', 'workAddress', 'workPhone', 'homePhone', 'fax', 'notes');
154: $dataKeys = array(0, 1, 2, 3, 4, 5, 6, 7, 9);
155: break;
156:
157: case 'pine':
158: $appKeys = array('alias', 'name', 'email', 'notes');
159: $dataKeys = array(0, 1, 2, 4);
160: break;
161: }
162:
163: foreach ($appKeys as $key => $app) {
164: $map[$dataKeys[$key]] = $app;
165: }
166:
167: $data = array();
168: foreach ($filedata as $row) {
169: $hash = array();
170:
171: switch ($format) {
172: case 'mulberry':
173: if (preg_match("/^Grp:/", $row[0]) || empty($row[1])) {
174: continue;
175: }
176: $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
177: foreach ($dataKeys as $key) {
178: if (array_key_exists($key, $row)) {
179: $hash[$key] = stripslashes(preg_replace('/\\\\r/', "\n", $row[$key]));
180: }
181: }
182: break;
183:
184: case 'pine':
185: if (count($row) < 3 || preg_match("/^#DELETED/", $row[0]) || preg_match("/[()]/", $row[2])) {
186: continue;
187: }
188: $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
189:
190: try {
191: $addr_arr = Horde_Mime_Address::parseAddressList($row[2]);
192: } catch (Horde_Mime_Exception $e) {
193: continue;
194: }
195: if (empty($addr_arr[0]->mailbox)) {
196: continue;
197: }
198: $row[2] = $addr_arr[0]->mailbox . '@' . $addr_arr[0]->host;
199: if (empty($row[1]) && !empty($addr_arr[0]->personal)) {
200: $row[1] = $addr_arr[0]->personal;
201: }
202: foreach ($dataKeys as $key) {
203: if (array_key_exists($key, $row)) {
204: $hash[$key] = $row[$key];
205: }
206: }
207: break;
208: }
209:
210: $data[] = $hash;
211: }
212:
213: $session->set('horde', 'import_data/data', $data);
214: $session->set('horde', 'import_data/map', $map);
215:
216: return $this->nextStep(Horde_Data::IMPORT_DATA, $param);
217: }
218:
219: 220:
221: try {
222: $this->_browser->wasFileUploaded('import_file', Horde_Data_Translation::t("TSV file"));
223: } catch (Horde_Browser_Exception $e) {
224: throw new Horde_Data_Exception($e);
225: }
226: $file_name = Horde_Util::getTempFile('import', false);
227: if (!move_uploaded_file($_FILES['import_file']['tmp_name'], $file_name)) {
228: throw new Horde_Data_Exception(Horde_Data_Translation::t("The uploaded file could not be saved."));
229: }
230: $session->set('horde', 'import_data/file_name', $file_name);
231:
232:
233: $first_lines = '';
234: if ($fp = @fopen($file_name, 'r')) {
235: $line_no = 1;
236: while (($line_no < 3) && ($line = fgets($fp))) {
237: $newline = Horde_String::length($line) > 100 ? "\n" : '';
238: $first_lines .= substr($line, 0, 100) . $newline;
239: ++$line_no;
240: }
241: }
242: $session->set('horde', 'import_data/first_lines', $first_lines);
243: return Horde_Data::IMPORT_TSV;
244:
245: case Horde_Data::IMPORT_TSV:
246: $session->set('horde', 'import_data/header', $this->_vars->header);
247: $session->set('horde', 'import_data/data', $this->importFile($session->get('horde', 'import_data/file_name'), $session->get('horde', 'import_data/header')));
248: $session->remove('horde', 'import_data/map');
249: return Horde_Data::IMPORT_MAPPED;
250: }
251:
252: return parent::nextStep($action, $param);
253: }
254:
255: }
256: