1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20: 21: 22:
23: class IMP_Mbox_Import
24: {
25: 26: 27: 28: 29:
30: protected $_import;
31:
32: 33: 34: 35: 36:
37: protected $_mbox;
38:
39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
49: public function import($mbox, $form_name)
50: {
51: $GLOBALS['browser']->wasFileUploaded($form_name, _("mailbox file"));
52: $this->_mbox = $mbox;
53:
54: $res = $this->_import($_FILES[$form_name]['tmp_name'], $_FILES[$form_name]['type']);
55: $mbox_name = basename(Horde_Util::dispelMagicQuotes($_FILES[$form_name]['name']));
56:
57: if ($res === false) {
58: throw new IMP_Exception(sprintf(_("There was an error importing %s."), $mbox_name));
59: }
60:
61: return sprintf(ngettext('Imported %d message from %s.', 'Imported %d messages from %s', $res), $res, $mbox_name);
62: }
63:
64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74:
75: protected function _import($fname, $type)
76: {
77: if (!is_readable($fname)) {
78: return false;
79: }
80:
81: $fd = null;
82:
83: switch ($type) {
84: case 'application/gzip':
85: case 'application/x-gzip':
86: case 'application/x-gzip-compressed':
87:
88:
89: if (in_array('compress.zlib', stream_get_wrappers())) {
90: $fd = 'compress.zlib://' . $fname;
91: }
92: break;
93:
94: case 'application/x-bzip2':
95: case 'application/x-bzip':
96: if (in_array('compress.bzip2', stream_get_wrappers())) {
97: $fd = 'compress.bzip2://' . $fname;
98: }
99: break;
100:
101: case 'application/zip':
102: case 'application/x-compressed':
103: case 'application/x-zip-compressed':
104: if (in_array('zip', stream_get_wrappers())) {
105: $fd = 'zip://' . $fname;
106: } else {
107: try {
108: $zip = Horde_Compress::factory('Zip');
109: if ($zip->canDecompress) {
110: $file_data = file_get_contents($fname);
111:
112: $zip_info = $zip->decompress($file_data, array(
113: 'action' => Horde_Compress_Zip::ZIP_LIST
114: ));
115:
116: if (!empty($zip_info)) {
117: $fd = fopen('php://temp', 'r+');
118:
119: foreach (array_keys($zip_info) as $key) {
120: fwrite($fd, $zip->decompress($file_data, array(
121: 'action' => Horde_Compress_Zip::ZIP_DATA,
122: 'info' => $zip_info,
123: 'key' => $key
124: )));
125: }
126:
127: rewind($fd);
128: }
129: }
130: } catch (Horde_Compress_Exception $e) {
131: if ($fd) {
132: fclose($fd);
133: $fd = null;
134: }
135: }
136: }
137: break;
138:
139: default:
140: $fd = $fname;
141: break;
142: }
143:
144: if (is_null($fd)) {
145: throw new IMP_Exception(_("The uploaded file cannot be opened."));
146: }
147:
148: $parsed = new Horde_Mail_Mbox_Parse(
149: $fd,
150: $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->config->import_limit
151: );
152:
153: $this->_import = array(
154: 'data' => array(),
155: 'msgs' => 0,
156: 'size' => 0
157: );
158:
159: if ($pcount = count($parsed)) {
160: foreach ($parsed as $key => $val) {
161: $this->_importHelper($val, ($key + 1) != $pcount);
162: }
163: } else {
164: $this->_importHelper($parsed[0]);
165: }
166:
167: return $this->_import['msgs']
168: ? $this->_import['msgs']
169: : false;
170: }
171:
172: 173: 174: 175: 176: 177:
178: protected function _importHelper($msg, $buffer = false)
179: {
180: $this->_import['data'][] = array_filter(array(
181: 'data' => $msg['data'],
182: 'internaldate' => $msg['date']
183: ));
184: $this->_import['size'] += $msg['size'];
185:
186:
187: if ($buffer && ($this->_import['size'] < 1048576)) {
188: return;
189: }
190:
191: try {
192: $this->_mbox->imp_imap->append($this->_mbox, $this->_import['data']);
193: $this->_import['msgs'] += count($this->_import['data']);
194: } catch (IMP_Imap_Exception $e) {
195: throw new IMP_Exception(sprintf(_("Error when importing messages; %u messages successfully imported before error."), $this->_import['msgs']));
196: }
197:
198: foreach ($this->_import['data'] as $val) {
199: fclose($val['data']);
200: }
201:
202: $this->_import['data'] = array();
203: $this->_import['size'] = 0;
204: }
205:
206: }
207: