1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16: class IMP_Flags implements ArrayAccess, Serializable
17: {
18: 19: 20: 21: 22:
23: public $changed = false;
24:
25: 26: 27: 28: 29:
30: protected $_flags = array();
31:
32: 33: 34: 35: 36:
37: protected $_userflags = array();
38:
39: 40: 41:
42: public function __construct()
43: {
44:
45: foreach (array('Imap', 'System') as $type) {
46: $di = new DirectoryIterator(IMP_BASE . '/lib/Flag/' . $type);
47: foreach ($di as $val) {
48: if ($val->isFile()) {
49: $cname = 'IMP_Flag_' . $type . '_' . $val->getBasename('.php');
50: if (class_exists($cname)) {
51: $ob = new $cname();
52: $this->_flags[$ob->id] = $ob;
53: }
54: }
55: }
56: }
57:
58: if ($f_list = $GLOBALS['prefs']->getValue('msgflags')) {
59: $f_list = @unserialize($f_list);
60: if (is_array($f_list)) {
61: foreach ($f_list as $val) {
62: $this->_userflags[$val->id] = $val;
63: }
64: }
65: }
66:
67: $this->changed = true;
68: }
69:
70: 71: 72:
73: protected function _save()
74: {
75: global $prefs;
76:
77: if (!$prefs->isLocked('msgflags')) {
78: $prefs->setValue('msgflags', serialize($this->_userflags));
79: }
80:
81: $this->changed = true;
82: }
83:
84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96:
97: public function getList(array $opts = array())
98: {
99: if (!$GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_FLAGS)) {
100: return array();
101: }
102:
103: $ret = array_merge($this->_flags, $this->_userflags);
104:
105: if (!empty($opts['imap'])) {
106: foreach ($ret as $key => $val) {
107: if (!($val instanceof IMP_Flag_Imap)) {
108: unset($ret[$key]);
109: }
110: }
111: }
112:
113: if (!isset($opts['mailbox']) ||
114: !strlen($opts['mailbox']) ||
115: IMP_Mailbox::get($opts['mailbox'])->search) {
116: return array_values($ret);
117: }
118:
119: 120:
121: $permflags = IMP_Mailbox::get($opts['mailbox'])->permflags;
122:
123:
124: foreach ($ret as $key => $val) {
125: if (($val instanceof IMP_Flag_Imap) &&
126: !$permflags->allowed($val->imapflag)) {
127: unset($ret[$key]);
128: }
129: }
130:
131:
132: if ($GLOBALS['prefs']->getValue('show_all_flags')) {
133:
134: $imapflags = array();
135: foreach ($ret as $val) {
136: if ($val instanceof IMP_Flag_Imap) {
137: $imapflags[] = $val->imapflag;
138: }
139: }
140:
141: foreach ($permflags as $val) {
142: if (!in_array($val, $imapflags)) {
143: $ret[] = new IMP_Flag_User(Horde_String::convertCharset($val, 'UTF7-IMAP', 'UTF-8'), $val);
144: }
145: }
146: }
147:
148: return array_values($ret);
149: }
150:
151: 152: 153: 154: 155: 156: 157:
158: public function addFlag($label)
159: {
160: if (strlen($label) == 0) {
161: return;
162: }
163:
164: $ob = new IMP_Flag_User($label);
165:
166: if (!isset($this->_userflags[$ob->id])) {
167: $this->_userflags[$ob->id] = $ob;
168: $this->_save();
169: }
170:
171: return $ob->imapflag;
172: }
173:
174: 175: 176: 177: 178: 179: 180: 181:
182: public function updateFlag($key, $type, $data)
183: {
184: if (isset($this->_userflags[$key])) {
185: $ob = clone $this->_userflags[$key];
186: } elseif (isset($this->_flags[$key])) {
187: $ob = clone $this->_flags[$key];
188: } else {
189: return;
190: }
191:
192: $ob->$type = $data;
193:
194: if (isset($this->_flags[$key]) && ($this->_flags[$key] == $ob)) {
195: unset($this->_userflags[$key]);
196: } else {
197: $this->_userflags[$key] = $ob;
198: }
199:
200: $this->_save();
201: }
202:
203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217:
218: public function parse(array $opts = array())
219: {
220: $opts = array_merge(array(
221: 'flags' => array(),
222: 'headers' => null,
223: 'personal' => null
224: ), $opts);
225:
226: $imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->imap;
227: $ret = array();
228:
229: foreach (array_merge($this->_flags, $this->_userflags) as $val) {
230: if ($val instanceof IMP_Flag_System_Match_Address) {
231: if (!is_null($opts['personal']) &&
232: $val->match($opts['personal'])) {
233: $ret[] = $val;
234: }
235: } elseif (($val instanceof IMP_Flag_Imap) ||
236: ($val instanceof IMP_Flag_System_Match_Flag)) {
237: if ($imap && $val->match($opts['flags'])) {
238: $ret[] = $val;
239: }
240: } elseif ($val instanceof IMP_Flag_System_Match_Header) {
241: if (!is_null($opts['headers']) &&
242: $val->match($opts['headers'])) {
243: $ret[] = $val;
244: }
245: }
246: }
247:
248: return $ret;
249: }
250:
251: 252: 253: 254: 255: 256: 257: 258: 259:
260: public function parseFormId($id)
261: {
262: return (strpos($id, '0\\') === 0)
263: ? array('flag' => substr($id, 2), 'set' => false)
264: : array('flag' => $id, 'set' => true);
265: }
266:
267: 268: 269: 270: 271: 272: 273: 274: 275: 276:
277: public function changed($flags, $add)
278: {
279: $ret = array(
280: 'add' => array(),
281: 'remove' => array()
282: );
283:
284: $obs = array();
285: foreach ($flags as $val) {
286: if ($tmp = $this[$val]) {
287: $obs[] = $tmp;
288: }
289: }
290:
291: if ($add) {
292: $ret['add'] = $obs;
293: } else {
294: $ret['remove'] = $obs;
295: }
296:
297: foreach (array_merge($this->_flags, $this->_userflags) as $val) {
298: $res = $val->changed($obs, $add);
299:
300: if ($res === false) {
301: $ret['remove'][] = $val;
302: } elseif ($res === true) {
303: $ret['add'][] = $val;
304: }
305: }
306:
307: return $ret;
308: }
309:
310:
311:
312: 313:
314: public function offsetExists($offset)
315: {
316: return isset($this->_flags[$offset]) ||
317: isset($this->_userflags[$offset]);
318: }
319:
320: 321:
322: public function offsetGet($offset)
323: {
324: if (isset($this->_flags[$offset])) {
325: return $this->_flags[$offset];
326: } elseif (isset($this->_userflags[$offset])) {
327: return $this->_userflags[$offset];
328: }
329:
330: return null;
331: }
332:
333: 334: 335:
336: public function offsetSet($offset, $value)
337: {
338: throw new InvalidArgumentException('Use addFlag()/updateFlag()');
339: }
340:
341: 342:
343: public function offsetUnset($offset)
344: {
345: if (isset($this->_userflags[$offset])) {
346: unset($this->_userflags[$offset]);
347: $this->_save();
348: }
349: }
350:
351:
352:
353: 354:
355: public function serialize()
356: {
357: return serialize(array(
358: $this->_flags,
359: $this->_userflags
360: ));
361: }
362:
363: 364:
365: public function unserialize($data)
366: {
367: $data = @unserialize($data);
368: if (!is_array($data)) {
369: throw new Exception('Cache invalidation.');
370: }
371:
372: $this->_flags = $data[0];
373: $this->_userflags = $data[1];
374: }
375:
376: }
377: