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_Indices implements ArrayAccess, Countable, Iterator
24: {
25: 26: 27: 28: 29:
30: protected $_indices = array();
31:
32: 33: 34: 35: 36: 37: 38:
39: public function __construct()
40: {
41: if (func_num_args()) {
42: $args = func_get_args();
43: call_user_func_array(array($this, 'add'), $args);
44: }
45: }
46:
47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73:
74: public function add()
75: {
76: $data = func_get_arg(0);
77: $indices = array();
78:
79: switch (func_num_args()) {
80: case 1:
81: if (is_array($data)) {
82: foreach ($data as $key => $val) {
83: if (is_array($val)) {
84: $indices[$key] = array_keys(array_flip($val));
85: } elseif ($val instanceof Horde_Imap_Client_Ids) {
86: $this->add($key, $val);
87: } else {
88: $this->add($val);
89: }
90: }
91: } elseif (is_string($data)) {
92: $indices = $this->_fromSequenceString($data);
93: } elseif ($data instanceof IMP_Compose) {
94: $indices = $data->getMetadata('indices')->indices();
95: } elseif ($data instanceof IMP_Contents) {
96: $indices = array(
97: strval($data->getMailbox()) => array($data->getUid())
98: );
99: } elseif ($data instanceof IMP_Indices) {
100: $indices = $data->indices();
101: } elseif ($data instanceof IMP_Mailbox_List) {
102: if ($idx = $data[$data->getIndex()]) {
103: $indices = array(
104: strval($idx['m']) => array($idx['u'])
105: );
106: }
107: }
108: break;
109:
110: case 2:
111: $secondarg = func_get_arg(1);
112: if (is_array($secondarg)) {
113: $secondarg = array_keys(array_flip($secondarg));
114: } elseif ($secondarg instanceof Horde_Imap_Client_Ids) {
115: $secondarg = $secondarg->ids;
116: } else {
117: $secondarg = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->getIdsOb($secondarg)->ids;
118: }
119:
120: if (!empty($secondarg)) {
121: $indices = array(
122: strval(func_get_arg(0)) => $secondarg
123: );
124: }
125: break;
126: }
127:
128: if (!empty($indices)) {
129: if (empty($this->_indices)) {
130: $this->_indices = $indices;
131: } else {
132: 133: 134:
135: foreach (array_keys($indices) as $key) {
136: $this->_indices[$key] = isset($this->_indices[$key])
137: ? array_keys(array_flip(array_merge($this->_indices[$key], $indices[$key])))
138: : $indices[$key];
139: }
140: }
141: }
142: }
143:
144: 145: 146: 147: 148: 149: 150: 151: 152: 153:
154: public function getSingle($all = false)
155: {
156: $val = reset($this->_indices);
157: return array(
158: IMP_Mailbox::get(key($this->_indices)),
159: $all ? $val : (is_array($val) ? reset($val) : null)
160: );
161: }
162:
163: 164: 165: 166: 167: 168:
169: public function indices()
170: {
171: return $this->_indices;
172: }
173:
174: 175: 176: 177: 178: 179:
180: public function toArray()
181: {
182: $converted = array();
183: $imp_imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
184:
185: foreach ($this->_indices as $key => $val) {
186: $converted[IMP_Mailbox::formTo($key)] = strval($imp_imap->getIdsOb($val));
187: }
188:
189: return $converted;
190: }
191:
192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203:
204: protected function _fromSequenceString($str)
205: {
206: $str = trim($str);
207:
208: if (!strlen($str)) {
209: return array();
210: }
211:
212: if ($str[0] != '{') {
213: return $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->getIdsOb($str)->ids;
214: }
215:
216: $i = strpos($str, '}');
217: $count = intval(substr($str, 1, $i - 1));
218: $mbox = substr($str, $i + 1, $count);
219: $i += $count + 1;
220: $end = strpos($str, '{', $i);
221:
222: if ($end === false) {
223: $ids = array();
224: $uidstr = substr($str, $i);
225: } else {
226: $ids = $this->_fromSequenceString(substr($str, $end));
227: $uidstr = substr($str, $i, $end - $i);
228: }
229:
230: $ids[$mbox] = $this->_fromSequenceString($uidstr);
231:
232: return $ids;
233: }
234:
235: 236: 237: 238: 239: 240: 241: 242: 243:
244: protected function _toSequenceString($in)
245: {
246: $imap_ob = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
247: $str = '';
248:
249: foreach ($in as $mbox => $ids) {
250: $str .= '{' . strlen($mbox) . '}' . $mbox . $imap_ob->getIdsOb($ids)->tostring_sort;
251: }
252:
253: return $str;
254: }
255:
256:
257:
258: 259:
260: public function offsetExists($offset)
261: {
262: return isset($this->_indices[$offset]);
263: }
264:
265: 266:
267: public function offsetGet($offset)
268: {
269: return isset($this->_indices[$offset])
270: ? $this->_indices[$offset]
271: : null;
272: }
273:
274: 275:
276: public function offsetSet($offset, $value)
277: {
278: unset($this->_indices[$offset]);
279: $this->add($offset, $value);
280: }
281:
282: 283:
284: public function offsetUnset($offset)
285: {
286: unset($this->_indices[$offset]);
287: }
288:
289:
290:
291: 292: 293: 294: 295:
296: public function count()
297: {
298: $count = 0;
299:
300: foreach (array_keys($this->_indices) as $key) {
301: $count += count($this->_indices[$key]);
302: }
303:
304: return $count;
305: }
306:
307:
308:
309: 310: 311: 312: 313:
314: public function __toString()
315: {
316: return $this->_toSequenceString($this->_indices);
317: }
318:
319:
320:
321: public function current()
322: {
323: if (!$this->valid()) {
324: return null;
325: }
326:
327: $ret = new stdClass;
328: $ret->mbox = IMP_Mailbox::get($this->key());
329: $ret->uids = current($this->_indices);
330:
331: return $ret;
332: }
333:
334: public function key()
335: {
336: return key($this->_indices);
337: }
338:
339: public function next()
340: {
341: if ($this->valid()) {
342: next($this->_indices);
343: }
344: }
345:
346: public function rewind()
347: {
348: reset($this->_indices);
349: }
350:
351: public function valid()
352: {
353: return !is_null(key($this->_indices));
354: }
355:
356: }
357: