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