1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
38: class IMP_Ftree
39: implements ArrayAccess, Countable, IteratorAggregate, Serializable
40: {
41:
42: const ELT_NOSELECT = 1;
43: const ELT_NAMESPACE_OTHER = 2;
44: const ELT_NAMESPACE_SHARED = 4;
45: const ELT_IS_OPEN = 8;
46: const ELT_IS_SUBSCRIBED = 16;
47: const ELT_NOINFERIORS = 32;
48: const ELT_IS_POLLED = 64;
49: const ELT_NOT_POLLED = 128;
50: const ELT_VFOLDER = 256;
51: const ELT_NONIMAP = 512;
52: const ELT_INVISIBLE = 1024;
53: const ELT_NEED_SORT = 2048;
54: const ELT_REMOTE = 4096;
55: const ELT_REMOTE_AUTH = 8192;
56: const ELT_REMOTE_MBOX = 16384;
57:
58: 59: 60: 61:
62: const BASE_ELT = "base\0";
63:
64: 65: 66: 67: 68:
69: protected $_accounts;
70:
71: 72: 73: 74: 75:
76: protected $_changed = false;
77:
78: 79: 80: 81: 82:
83: protected $_eltdiff;
84:
85: 86: 87: 88: 89:
90: protected $_elts;
91:
92: 93: 94: 95: 96:
97: protected $_parent;
98:
99: 100: 101: 102: 103:
104: protected $_temp = array();
105:
106: 107: 108:
109: public function __construct()
110: {
111: $this->init();
112: }
113:
114: 115:
116: public function __get($name)
117: {
118: global $prefs;
119:
120: switch ($name) {
121: case 'changed':
122: return ($this->_changed || $this->eltdiff->changed);
123:
124: case 'expanded':
125: if (!isset($this->_temp['expanded'])) {
126: $this->_temp['expanded'] = new IMP_Ftree_Prefs_Expanded();
127: }
128: return $this->_temp['expanded'];
129:
130: case 'eltdiff':
131: return $this->_eltdiff;
132:
133: case 'poll':
134: if (!isset($this->_temp['poll'])) {
135: $this->_temp['poll'] = new IMP_Ftree_Prefs_Poll($this);
136: }
137: return $this->_temp['poll'];
138:
139: case 'subscriptions':
140: return $prefs->getValue('subscribe');
141:
142: case 'unsubscribed_loaded':
143: return $this[self::BASE_ELT]->subscribed;
144: }
145: }
146:
147: 148: 149:
150: public function init()
151: {
152: global $injector, $session;
153:
154: $access_folders = $injector->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_FOLDERS);
155:
156:
157: $this->_accounts = $this->_elts = $this->_parent = array();
158: $this->_changed = true;
159:
160: $old_track = (isset($this->_eltdiff) && $this->_eltdiff->track);
161: $this->_eltdiff = new IMP_Ftree_Eltdiff();
162:
163: 164:
165: $this->_elts[self::BASE_ELT] = self::ELT_NEED_SORT | self::ELT_NONIMAP;
166: $this->_parent[self::BASE_ELT] = array();
167:
168: $mask = IMP_Ftree_Account::INIT;
169: if (!$access_folders || !$this->subscriptions || $session->get('imp', 'showunsub')) {
170: $mask |= IMP_Ftree_Account::UNSUB;
171: $this->setAttribute('subscribed', self::BASE_ELT, true);
172: }
173:
174:
175: $ob = $this->_accounts[self::BASE_ELT] = $access_folders
176: ? new IMP_Ftree_Account_Imap()
177: : new IMP_Ftree_Account_Inboxonly();
178: array_map(array($this, '_insertElt'), $ob->getList(null, $mask));
179:
180: if ($access_folders) {
181:
182: $this->insert(iterator_to_array(
183: $injector->getInstance('IMP_Remote')
184: ));
185:
186:
187: $this->insert(iterator_to_array(
188: IMP_Search_IteratorFilter::create(
189: IMP_Search_IteratorFilter::VFOLDER
190: )
191: ));
192: }
193:
194: if ($old_track) {
195: $this->eltdiff->track = true;
196: }
197: }
198:
199: 200: 201: 202: 203: 204: 205:
206: public function insert($id)
207: {
208: foreach ((is_array($id) ? $id : array($id)) as $val) {
209: if (($val instanceof IMP_Search_Vfolder) &&
210: !isset($this->_accounts[strval($val)])) {
211:
212: $account = $this->_accounts[strval($val)] = new IMP_Ftree_Account_Vfolder($val);
213: } elseif (($val instanceof IMP_Remote_Account) &&
214: !isset($this->_accounts[strval($val)])) {
215:
216: $account = $this->_accounts[strval($val)] = new IMP_Ftree_Account_Remote($val);
217: } else {
218: $account = $this->getAccount($val);
219: $val = $this->_normalize($val);
220: }
221:
222: array_map(array($this, '_insertElt'), $account->getList(array($val)));
223: }
224: }
225:
226: 227: 228: 229: 230: 231: 232:
233: public function expand($elts, $expandall = false)
234: {
235: foreach ((is_array($elts) ? $elts : array($elts)) as $val) {
236: if (($elt = $this[$val]) && $elt->children) {
237: if (!$elt->open) {
238: $elt->open = true;
239: }
240:
241:
242: if ($expandall) {
243: $this->expand($this->_parent[strval($elt)]);
244: }
245: }
246: }
247: }
248:
249: 250: 251:
252: public function expandAll()
253: {
254: $this->expand($this->_parent[self::BASE_ELT], true);
255: }
256:
257: 258: 259: 260: 261:
262: public function collapse($elts)
263: {
264: foreach ((is_array($elts) ? $elts : array($elts)) as $val) {
265: if ($elt = $this[$val]) {
266: $elt->open = false;
267: }
268: }
269: }
270:
271: 272: 273:
274: public function collapseAll()
275: {
276: $this->collapse(
277: array_diff_key(array_keys($this->_elts), array(self::BASE_ELT))
278: );
279: }
280:
281: 282: 283: 284: 285:
286: public function delete($id)
287: {
288: if (is_array($id)) {
289: 290:
291: $this->sortList($id);
292: $id = array_reverse($id);
293: } else {
294: $id = array($id);
295: }
296:
297: foreach (array_filter(array_map(array($this, 'offsetGet'), $id)) as $elt) {
298: $account = $this->getAccount($elt);
299: if (!($mask = $account->delete($elt))) {
300: continue;
301: }
302:
303: $this->_changed = true;
304:
305: if ($mask & IMP_Ftree_Account::DELETE_RECURSIVE) {
306: foreach (array_map('strval', iterator_to_array(new IMP_Ftree_Iterator($elt), false)) as $val) {
307: unset(
308: $this->_elts[$val],
309: $this->_parent[$val]
310: );
311: $this->eltdiff->delete($val);
312: }
313: unset($this->_parent[strval($elt)]);
314: }
315:
316: if (strval($account) == strval($elt)) {
317: unset($this->_accounts[strval($elt)]);
318: }
319:
320: if ($mask & IMP_Ftree_Account::DELETE_ELEMENT) {
321: 322:
323: if ($elt->children) {
324: $elt->container = true;
325: continue;
326: }
327:
328:
329: unset($this->expanded[$elt]);
330:
331:
332: $this->poll->removePollList($elt);
333: }
334:
335: $parent = strval($elt->parent);
336: $this->eltdiff->delete($elt);
337:
338:
339: unset(
340: $this->_elts[strval($elt)],
341: $this->_parent[$parent][array_search(strval($elt), $this->_parent[$parent], true)]
342: );
343:
344: if (empty($this->_parent[$parent])) {
345:
346: unset($this->_parent[$parent]);
347: if ($p_elt = $this[$parent]) {
348: if ($p_elt->container && !$p_elt->namespace) {
349: $this->delete($p_elt);
350: } else {
351: $p_elt->open = false;
352: $this->eltdiff->change($p_elt);
353: }
354: }
355: }
356:
357: if (!empty($this->_parent[$parent])) {
358: $this->_parent[$parent] = array_values($this->_parent[$parent]);
359: }
360: }
361: }
362:
363: 364: 365: 366: 367: 368:
369: public function rename($old, $new)
370: {
371: if (!($old_elt = $this[$old])) {
372: return;
373: }
374:
375: $new_list = $polled = array();
376: $old_list = array_merge(
377: array($old),
378: iterator_to_array(new IMP_Ftree_IteratorFilter(new IMP_Ftree_Iterator($old_elt)), false)
379: );
380:
381: foreach ($old_list as $val) {
382: $new_list[] = $new_name = substr_replace($val, $new, 0, strlen($old));
383: if ($val->polled) {
384: $polled[] = $new_name;
385: }
386: }
387:
388: $this->insert($new_list);
389: $this->poll->addPollList($polled);
390: $this->delete($old_list);
391: }
392:
393: 394: 395: 396: 397:
398: public function subscribe($id)
399: {
400: foreach ((is_array($id) ? $id : array($id)) as $val) {
401: $this->setAttribute('subscribed', $val, true);
402: $this->setAttribute('container', $val, false);
403: }
404: }
405:
406: 407: 408: 409: 410:
411: public function unsubscribe($id)
412: {
413: if (is_array($id)) {
414: 415:
416: $this->sortList($id);
417: $id = array_reverse($id);
418: } else {
419: $id = array($id);
420: }
421:
422: foreach ($id as $val) {
423:
424: if (($elt = $this[$val]) && !$elt->inbox) {
425: $this->_changed = true;
426:
427: 428:
429: if ($elt->children) {
430: $this->setAttribute('container', $elt, true);
431: }
432:
433: 434:
435: $this->setAttribute('subscribed', $elt, false);
436: }
437: }
438: }
439:
440: 441: 442:
443: public function loadUnsubscribed()
444: {
445: 446:
447: if ($this->unsubscribed_loaded) {
448: return;
449: }
450:
451: $this->_changed = true;
452:
453: 454:
455: $this->setAttribute('subscribed', self::BASE_ELT, true);
456:
457: 458: 459:
460: $old_track = $this->eltdiff->track;
461: $this->eltdiff->track = false;
462: foreach ($this->_accounts as $val) {
463: array_map(array($this, '_insertElt'), $val->getList(array(), $val::UNSUB));
464: }
465: $this->eltdiff->track = $old_track;
466: }
467:
468: 469: 470: 471: 472: 473: 474: 475: 476:
477: public function getAttribute($type, $name)
478: {
479: if (!($elt = $this[$name])) {
480: return null;
481: }
482: $s_elt = strval($elt);
483:
484: switch ($type) {
485: case 'children':
486: return isset($this->_parent[$s_elt]);
487:
488: case 'container':
489: $attr = self::ELT_NOSELECT;
490: break;
491:
492: case 'invisible':
493: $attr = self::ELT_INVISIBLE;
494: break;
495:
496: case 'namespace_other':
497: $attr = self::ELT_NAMESPACE_OTHER;
498: break;
499:
500: case 'namespace_shared':
501: $attr = self::ELT_NAMESPACE_SHARED;
502: break;
503:
504: case 'needsort':
505: $attr = self::ELT_NEED_SORT;
506: break;
507:
508: case 'nochildren':
509: $attr = self::ELT_NOINFERIORS;
510: break;
511:
512: case 'nonimap':
513: $attr = self::ELT_NONIMAP;
514: break;
515:
516: case 'open':
517: if (!$elt->children) {
518: return false;
519: }
520: $attr = self::ELT_IS_OPEN;
521: break;
522:
523: case 'polled':
524: if ($this->_elts[$s_elt] & self::ELT_IS_POLLED) {
525: return true;
526: } elseif ($this->_elts[$s_elt] & self::ELT_NOT_POLLED) {
527: return false;
528: }
529:
530: $polled = $this->poll[$elt];
531: $this->setAttribute('polled', $elt, $polled);
532: return $polled;
533:
534: case 'remote':
535: $attr = self::ELT_REMOTE;
536: break;
537:
538: case 'remote_auth':
539: $attr = self::ELT_REMOTE_AUTH;
540: break;
541:
542: case 'remote_mbox':
543: $attr = self::ELT_REMOTE_MBOX;
544: break;
545:
546: case 'subscribed':
547: if ($elt->inbox) {
548: return true;
549: }
550: $attr = self::ELT_IS_SUBSCRIBED;
551: break;
552:
553: case 'vfolder':
554: $attr = self::ELT_VFOLDER;
555: break;
556:
557: default:
558: return null;
559: }
560:
561: return (bool)($this->_elts[$s_elt] & $attr);
562: }
563:
564: 565: 566: 567: 568: 569: 570:
571: public function setAttribute($type, $elt, $bool)
572: {
573: if (!($elt = $this[$elt])) {
574: return;
575: }
576:
577: $attr = null;
578: $s_elt = strval($elt);
579:
580: switch ($type) {
581: case 'container':
582: $attr = self::ELT_NOSELECT;
583: $this->eltdiff->change($elt);
584: break;
585:
586: case 'invisible':
587: $attr = self::ELT_INVISIBLE;
588: $this->eltdiff->change($elt);
589: break;
590:
591: case 'needsort':
592: $attr = self::ELT_NEED_SORT;
593: break;
594:
595: case 'open':
596: $attr = self::ELT_IS_OPEN;
597: if ($bool) {
598: $this->expanded[$elt] = true;
599: } else {
600: unset($this->expanded[$elt]);
601: }
602: break;
603:
604: case 'polled':
605: if ($bool) {
606: $attr = self::ELT_IS_POLLED;
607: $remove = self::ELT_NOT_POLLED;
608: } else {
609: $attr = self::ELT_NOT_POLLED;
610: $remove = self::ELT_IS_POLLED;
611: }
612: $this->_elts[$s_elt] &= ~$remove;
613: break;
614:
615: case 'subscribed':
616: $attr = self::ELT_IS_SUBSCRIBED;
617: $this->eltdiff->change($elt);
618: break;
619:
620: default:
621: return;
622: }
623:
624: if ($bool) {
625: $this->_elts[$s_elt] |= $attr;
626: } else {
627: $this->_elts[$s_elt] &= ~$attr;
628: }
629:
630: $this->_changed = true;
631: }
632:
633: 634: 635: 636: 637: 638: 639:
640: public function getAccount($id)
641: {
642: foreach (array_diff(array_keys($this->_accounts), array(self::BASE_ELT)) as $val) {
643: if (strpos($id, $val) === 0) {
644: return $this->_accounts[$val];
645: }
646: }
647:
648: return $this->_accounts[self::BASE_ELT];
649: }
650:
651: 652: 653: 654: 655: 656: 657:
658: public function getChildren($id)
659: {
660: if (!($elt = $this[$id]) || !isset($this->_parent[strval($elt)])) {
661: return array();
662: }
663:
664: $this->_sortLevel($elt);
665: return array_map(
666: array($this, 'offsetGet'), $this->_parent[strval($elt)]
667: );
668: }
669:
670: 671: 672: 673: 674: 675: 676:
677: public function getParent($id)
678: {
679: $id = strval($id);
680:
681: if ($id == self::BASE_ELT) {
682: return null;
683: }
684:
685: foreach ($this->_parent as $key => $val) {
686: if (in_array($id, $val, true)) {
687: return $this[$key];
688: }
689: }
690:
691: return $this[self::BASE_ELT];
692: }
693:
694: 695: 696: 697: 698: 699:
700: public function sortList(&$mbox, $base = false)
701: {
702: if (count($mbox) < 2) {
703: return;
704: }
705:
706: if (!$base || (!$base->base_elt && !$base->remote_auth)) {
707: $list_ob = new Horde_Imap_Client_Mailbox_List($mbox);
708: $mbox = $list_ob->sort();
709: return;
710: }
711:
712: $prefix = $base->base_elt
713: ? ''
714: : (strval($this->getAccount($base)) . "\0");
715:
716: $basesort = $othersort = array();
717:
718: $sorted = array($prefix . 'INBOX');
719:
720: foreach ($mbox as $key => $val) {
721: $ob = $this[$val];
722: if ($ob->nonimap) {
723: $othersort[$key] = $ob->mbox_ob->label;
724: } elseif ($val !== ($prefix . 'INBOX')) {
725: $basesort[$key] = $ob->mbox_ob->label;
726: }
727: }
728:
729: natcasesort($basesort);
730: natcasesort($othersort);
731: foreach (array_merge(array_keys($basesort), array_keys($othersort)) as $key) {
732: $sorted[] = $mbox[$key];
733: }
734:
735: $mbox = $sorted;
736: }
737:
738:
739:
740:
741: 742: 743: 744: 745: 746: 747:
748: protected function _normalize($id)
749: {
750: $id = strval($id);
751:
752: return (strcasecmp($id, 'INBOX') === 0)
753: ? 'INBOX'
754: : $id;
755: }
756:
757: 758: 759: 760: 761: 762: 763: 764:
765: protected function _insertElt($elt)
766: {
767: $name = $this->_normalize($elt['v']);
768:
769: $change = false;
770: if (isset($this->_elts[$name])) {
771: if ($elt['a'] && self::ELT_NOSELECT) {
772: return;
773: }
774: $change = true;
775: }
776:
777: $p_elt = $this[isset($elt['p']) ? $elt['p'] : self::BASE_ELT];
778: $parent = strval($p_elt);
779:
780: $this->_changed = true;
781:
782: if (!isset($this->_parent[$parent])) {
783: $this->eltdiff->change($p_elt);
784: }
785: $this->_parent[$parent][] = $name;
786: $this->_elts[$name] = $elt['a'];
787:
788: if ($change) {
789: $this->eltdiff->change($name);
790: } else {
791: $this->eltdiff->add($name);
792: }
793:
794:
795: $this->setAttribute('polled', $name, $this->poll[$name]);
796:
797:
798: $this->setAttribute('open', $name, $this->expanded[$name]);
799:
800: if (empty($this->_temp['nohook'])) {
801: try {
802: $this->setAttribute(
803: 'invisible',
804: $name,
805: !$GLOBALS['injector']->getInstance('Horde_Core_Hooks')->callHook(
806: 'display_folder',
807: 'imp',
808: array($name)
809: )
810: );
811: } catch (Horde_Exception_HookNotSet $e) {
812: $this->_temp['nohook'] = true;
813: }
814: }
815:
816:
817: $this->setAttribute('needsort', $p_elt, true);
818: }
819:
820: 821: 822: 823: 824:
825: protected function _sortLevel($id)
826: {
827: if (($elt = $this[$id]) && $elt->needsort) {
828: if (count($this->_parent[strval($elt)]) > 1) {
829: $this->sortList($this->_parent[strval($elt)], $elt);
830: }
831: $this->setAttribute('needsort', $elt, false);
832: }
833: }
834:
835:
836:
837: 838:
839: public function offsetExists($offset)
840: {
841: 842:
843: $offset = strval($offset);
844: return (isset($this->_elts[$offset]) ||
845: isset($this->_elts[$this->_normalize($offset)]));
846: }
847:
848: 849: 850:
851: public function offsetGet($offset)
852: {
853: if ($offset instanceof IMP_Ftree_Element) {
854: return $offset;
855: }
856:
857: 858:
859: $offset = strval($offset);
860: if (isset($this->_elts[$offset])) {
861: return new IMP_Ftree_Element($offset, $this);
862: }
863:
864: $offset = $this->_normalize($offset);
865: return isset($this->_elts[$offset])
866: ? new IMP_Ftree_Element($offset, $this)
867: : null;
868: }
869:
870: 871:
872: public function offsetSet($offset, $value)
873: {
874: $this->insert($offset);
875: }
876:
877: 878:
879: public function offsetUnset($offset)
880: {
881: $this->delete($offset);
882: }
883:
884:
885:
886: 887: 888:
889: public function count()
890: {
891: $this->loadUnsubscribed();
892:
893: $iterator = new IMP_Ftree_IteratorFilter($this);
894: $iterator->add($iterator::NONIMAP);
895: $iterator->remove($iterator::UNSUB);
896:
897: return iterator_count($iterator);
898: }
899:
900:
901:
902: 903:
904: public function serialize()
905: {
906: return $GLOBALS['injector']->getInstance('Horde_Pack')->pack(array(
907: $this->_accounts,
908: $this->_eltdiff,
909: $this->_elts,
910: $this->_parent
911: ), array(
912: 'compress' => false,
913: 'phpob' => true
914: ));
915: }
916:
917: 918: 919:
920: public function unserialize($data)
921: {
922: list(
923: $this->_accounts,
924: $this->_eltdiff,
925: $this->_elts,
926: $this->_parent
927: ) = $GLOBALS['injector']->getInstance('Horde_Pack')->unpack($data);
928: }
929:
930: 931: 932: 933: 934: 935: 936: 937: 938: 939: 940: 941: 942: 943: 944: 945: 946: 947: 948: 949: 950: 951: 952: 953: 954: 955: 956: 957: 958:
959: public function createTree($name, array $opts = array())
960: {
961: global $injector, $registry;
962:
963: $opts = array_merge(array(
964: 'parent' => null,
965: 'render_params' => array(),
966: 'render_type' => 'Javascript'
967: ), $opts);
968:
969: $view = $registry->getView();
970:
971: if ($name instanceof Horde_Tree_Renderer_Base) {
972: $tree = $name;
973: $parent = $opts['parent'];
974: } else {
975: $tree = $injector->getInstance('Horde_Core_Factory_Tree')->create($name, $opts['render_type'], array_merge(array(
976: 'alternate' => true,
977: 'lines' => true,
978: 'lines_base' => true,
979: 'nosession' => true
980: ), $opts['render_params']));
981: $parent = null;
982: }
983:
984: $iterator = empty($opts['iterator'])
985: ? new IMP_Ftree_IteratorFilter($this)
986: : $opts['iterator'];
987:
988: foreach ($iterator as $val) {
989: $after = '';
990: $elt_parent = null;
991: $mbox_ob = $val->mbox_ob;
992: $params = array();
993:
994: switch ($opts['render_type']) {
995: case 'IMP_Tree_Flist':
996: if ($mbox_ob->vfolder_container) {
997: continue 2;
998: }
999:
1000: $is_open = true;
1001: $label = $params['orig_label'] = empty($opts['basename'])
1002: ? $mbox_ob->abbrev_label
1003: : $mbox_ob->basename;
1004: break;
1005:
1006: case 'IMP_Tree_Jquerymobile':
1007: $is_open = true;
1008: $label = $mbox_ob->display_html;
1009: $icon = $mbox_ob->icon;
1010: $params['icon'] = $icon->icon;
1011: $params['special'] = $mbox_ob->inbox || $mbox_ob->special;
1012: $params['class'] = 'imp-folder';
1013: $params['urlattributes'] = array(
1014: 'id' => 'imp-mailbox-' . $mbox_ob->form_to
1015: );
1016:
1017: 1018: 1019:
1020: $elt_parent = $this[self::BASE_ELT];
1021: break;
1022:
1023: case 'IMP_Tree_Simplehtml':
1024: $is_open = $val->open;
1025: if ($tree->shouldToggle($mbox_ob->form_to)) {
1026: if ($is_open) {
1027: $this->collapse($val);
1028: } else {
1029: $this->expand($val);
1030: }
1031: $is_open = !$is_open;
1032: }
1033: $label = htmlspecialchars(Horde_String::abbreviate($mbox_ob->abbrev_label, 30 - ($val->level * 2)));
1034: break;
1035:
1036: case 'Javascript':
1037: $is_open = $val->open;
1038: $label = empty($opts['basename'])
1039: ? htmlspecialchars($mbox_ob->abbrev_label)
1040: : htmlspecialchars($mbox_ob->basename);
1041: $icon = $mbox_ob->icon;
1042: $params['icon'] = $icon->icon;
1043: $params['iconopen'] = $icon->iconopen;
1044: break;
1045: }
1046:
1047: if (!empty($opts['poll_info']) && $val->polled) {
1048: $poll_info = $mbox_ob->poll_info;
1049:
1050: if ($poll_info->unseen) {
1051: switch ($opts['render_type']) {
1052: case 'IMP_Tree_Jquerymobile':
1053: $after = $poll_info->unseen;
1054: break;
1055:
1056: default:
1057: $label = '<strong>' . $label . '</strong> (' .
1058: $poll_info->unseen . ')';
1059: }
1060: }
1061: }
1062:
1063: if ($val->container) {
1064: $params['container'] = true;
1065: } else {
1066: switch ($view) {
1067: case $registry::VIEW_MINIMAL:
1068: $params['url'] = IMP_Minimal_Mailbox::url(array('mailbox' => $mbox_ob));
1069: break;
1070:
1071: case $registry::VIEW_SMARTMOBILE:
1072: $url = new Horde_Core_Smartmobile_Url();
1073: $url->add('mbox', $mbox_ob->form_to);
1074: $url->setAnchor('mailbox');
1075: $params['url'] = strval($url);
1076: break;
1077:
1078: default:
1079: $params['url'] = $mbox_ob->url('mailbox')->setRaw(true);
1080: break;
1081: }
1082:
1083: if (!$val->subscribed) {
1084: $params['class'] = 'mboxunsub';
1085: }
1086: }
1087:
1088: $checkbox = empty($opts['checkbox'])
1089: ? ''
1090: : '<input type="checkbox" class="checkbox" name="mbox_list[]" value="' . $mbox_ob->form_to . '"';
1091:
1092: if ($val->nonimap) {
1093: $checkbox .= ' disabled="disabled"';
1094: }
1095:
1096: if ($val->vfolder &&
1097: !empty($opts['editvfolder']) &&
1098: $val->container) {
1099: $after = ' [' .
1100: $registry->getServiceLink('prefs', 'imp')->add('group', 'searches')->link(array('title' => _("Edit Virtual Folder"))) . _("Edit") . '</a>'.
1101: ']';
1102: }
1103:
1104: if (is_null($elt_parent)) {
1105: $elt_parent = $val->parent;
1106: }
1107:
1108: $tree->addNode(array(
1109: 'id' => $mbox_ob->form_to,
1110: 'parent' => $elt_parent->base_elt ? $parent : $elt_parent->mbox_ob->form_to,
1111: 'label' => $label,
1112: 'expanded' => isset($opts['open']) ? $opts['open'] : $is_open,
1113: 'params' => $params,
1114: 'right' => $after,
1115: 'left' => empty($opts['checkbox']) ? null : $checkbox . ' />'
1116: ));
1117: }
1118:
1119: return $tree;
1120: }
1121:
1122:
1123:
1124: 1125: 1126: 1127: 1128: 1129:
1130: public function getIterator()
1131: {
1132: return new IMP_Ftree_Iterator($this[self::BASE_ELT]);
1133: }
1134:
1135: }
1136: