1: <?php
2: /**
3: * Copyright 2013-2014 Horde LLC (http://www.horde.org/)
4: *
5: * See the enclosed file COPYING for license information (GPL). If you
6: * did not receive this file, see http://www.horde.org/licenses/gpl.
7: *
8: * @category Horde
9: * @copyright 2013-2014 Horde LLC
10: * @license http://www.horde.org/licenses/gpl GPL
11: * @package IMP
12: */
13:
14: /**
15: * Iterator filter for IMP_Ftree.
16: *
17: * @author Michael Slusarz <slusarz@horde.org>
18: * @category Horde
19: * @copyright 2013-2014 Horde LLC
20: * @license http://www.horde.org/licenses/gpl GPL
21: * @package IMP
22: */
23: class IMP_Ftree_IteratorFilter implements Iterator
24: {
25: /**
26: * Filter mask constants.
27: * - CHILDREN: Don't include child elements.
28: * - CONTAINERS: Don't include container elements.
29: * - EXPANDED: Don't include unexpanded mailboxes.
30: * - INVISIBLE: Don't include invisible elements.
31: * - NONIMAP: Don't include non-IMAP elements.
32: * - POLLED: Don't include non-polled elements.
33: * - REMOTE: Don't include remote accounts.
34: * - SPECIALMBOXES: Don't include special mailboxes.
35: * - UNSUB: Don't include unsubscribed elements.
36: * - VFOLDER: Don't include Virtual Folders.
37: */
38: const CHILDREN = 1;
39: const CONTAINERS = 2;
40: const EXPANDED = 4;
41: const INVISIBLE = 8;
42: const NONIMAP = 16;
43: const POLLED = 32;
44: const REMOTE = 64;
45: const SPECIALMBOXES = 128;
46: const UNSUB = 256;
47: const VFOLDER = 1024;
48:
49: /**
50: * Master iterator object.
51: *
52: * @var Iterator
53: */
54: public $iterator;
55:
56: /**
57: * A list of mailboxes to filter out.
58: *
59: * @var array
60: */
61: public $mboxes = array();
62:
63: /**
64: * Filtered iterator used for actual iteration.
65: *
66: * @var Iterator
67: */
68: private $_filter;
69:
70: /**
71: * Filter mask.
72: *
73: * @var integer
74: */
75: protected $_mask;
76:
77: /**
78: * Constructor.
79: *
80: * @param Iterator $i Master iterator object.
81: */
82: public function __construct($i = null)
83: {
84: $this->iterator = $i;
85:
86: $this->_filter = new EmptyIterator();
87: $this->_mask = (self::INVISIBLE | self::UNSUB);
88: }
89:
90: /**
91: * Add filter masks.
92: *
93: * @param mixed $mask Filter masks to add.
94: */
95: public function add($mask)
96: {
97: foreach ((is_array($mask) ? $mask : array($mask)) as $val) {
98: $this->_mask |= $val;
99: }
100: }
101:
102: /**
103: * Remove filter masks.
104: *
105: * @param mixed $mask Filter masks to remove.
106: */
107: public function remove($mask)
108: {
109: foreach ((is_array($mask) ? $mask : array($mask)) as $val) {
110: $this->_mask &= ~$val;
111: }
112: }
113:
114: /* Iterator methods. */
115:
116: /**
117: */
118: public function current()
119: {
120: return $this->_filter->current();
121: }
122:
123: /**
124: */
125: public function key()
126: {
127: return $this->_filter->key();
128: }
129:
130: /**
131: */
132: public function next()
133: {
134: $this->_filter->next();
135: }
136:
137: /**
138: */
139: public function rewind()
140: {
141: if (!isset($this->iterator)) {
142: throw new InvalidArgumentException('Missing iterator.');
143: }
144:
145: $i = $this->iterator;
146: if (!($i instanceof RecursiveIterator)) {
147: $i = $i->getIterator();
148: }
149:
150: /* Need to add RecursiveIteratorFilters first. */
151: $filters = array(
152: self::CHILDREN => 'IMP_Ftree_IteratorFilter_Children',
153: self::EXPANDED => 'IMP_Ftree_IteratorFilter_Expanded',
154: self::REMOTE => 'IMP_Ftree_IteratorFilter_Remote'
155: );
156:
157: foreach ($filters as $key => $val) {
158: if ($this->_mask & $key) {
159: $i = new $val($i);
160: }
161: }
162:
163: $i = new RecursiveIteratorIterator(
164: $i,
165: RecursiveIteratorIterator::SELF_FIRST
166: );
167:
168: /* Now we can add regular FilterIterators. */
169: $filters = array(
170: self::CONTAINERS => 'IMP_Ftree_IteratorFilter_Containers',
171: self::INVISIBLE => 'IMP_Ftree_IteratorFilter_Invisible',
172: self::NONIMAP => 'IMP_Ftree_IteratorFilter_Nonimap',
173: self::POLLED => 'IMP_Ftree_IteratorFilter_Polled',
174: self::SPECIALMBOXES => 'IMP_Ftree_IteratorFilter_Special',
175: self::UNSUB => 'IMP_Ftree_IteratorFilter_Subscribed',
176: self::VFOLDER => 'IMP_Ftree_IteratorFilter_Vfolder'
177: );
178:
179: foreach ($filters as $key => $val) {
180: if ($this->_mask & $key) {
181: $i = new $val($i);
182: }
183: }
184:
185: /* Mailbox filter is handled separately. */
186: if (!empty($this->mboxes)) {
187: $i = new IMP_Ftree_IteratorFilter_Mailboxes($i);
188: $i->mboxes = $this->mboxes;
189: }
190:
191: $i->rewind();
192:
193: $this->_filter = $i;
194: }
195:
196: /**
197: */
198: public function valid()
199: {
200: return $this->_filter->valid();
201: }
202:
203: }
204: