1: <?php
2: /**
3: * Function to sort a list of IMAP mailboxes.
4: *
5: * Copyright 2004-2012 Horde LLC (http://www.horde.org/)
6: *
7: * See the enclosed file COPYING for license information (LGPL). If you
8: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
9: *
10: * @author Michael Slusarz <slusarz@horde.org>
11: * @category Horde
12: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
13: * @package Imap_Client
14: */
15: class Horde_Imap_Client_Sort
16: {
17: /**
18: * The delimiter character to use.
19: *
20: * @var string
21: */
22: private static $_delimiter = '.';
23:
24: /**
25: * Should we sort with INBOX at the front of the list?
26: *
27: * @var boolean
28: */
29: private static $_sortinbox = true;
30:
31: /**
32: * Sort a list of mailboxes.
33: * $mbox will be sorted after running this function.
34: *
35: * @param array &$mbox The list of mailboxes to sort.
36: * @param array $options Additional options:
37: * - delimiter: (string) The delimiter to use.
38: * DEFAULT: '.'
39: * - inbox: (boolean) Always put INBOX at the head of the list?
40: * DEFAULT: Yes
41: * - index: (boolean) If sorting by value ('keysort' is false), maintain
42: * key index association?
43: * DEFAULT: No
44: * - keysort: (boolean) Sort by $mbox's keys?
45: * DEFAULT: Sort by $mbox values.
46: */
47: public static final function sortMailboxes(&$mbox, $options = array())
48: {
49: if (isset($options['delimiter'])) {
50: self::$_delimiter = $options['delimiter'];
51: }
52:
53: if (isset($options['inbox']) && empty($options['inbox'])) {
54: self::$_sortinbox = false;
55: }
56:
57: $cmp = array('Horde_Imap_Client_Sort', 'mboxCompare');
58: if (!empty($options['keysort'])) {
59: uksort($mbox, $cmp);
60: } elseif (!empty($options['index'])) {
61: uasort($mbox, $cmp);
62: } else {
63: usort($mbox, $cmp);
64: }
65: }
66:
67: /**
68: * Hierarchical folder sorting function (used with usort()).
69: *
70: * @param string $a Comparison item 1.
71: * @param string $b Comparison item 2.
72: *
73: * @return integer See usort().
74: */
75: public static final function mboxCompare($a, $b)
76: {
77: /* Always return INBOX as "smaller". */
78: if (self::$_sortinbox) {
79: if (strcasecmp($a, 'INBOX') == 0) {
80: return -1;
81: } elseif (strcasecmp($b, 'INBOX') == 0) {
82: return 1;
83: }
84: }
85:
86: $a_parts = explode(self::$_delimiter, $a);
87: $b_parts = explode(self::$_delimiter, $b);
88:
89: $a_count = count($a_parts);
90: $b_count = count($b_parts);
91:
92: for ($i = 0, $iMax = min($a_count, $b_count); $i < $iMax; ++$i) {
93: if ($a_parts[$i] != $b_parts[$i]) {
94: /* If only one of the folders is under INBOX, return it as
95: * "smaller". */
96: if (self::$_sortinbox && ($i == 0)) {
97: $a_base = (strcasecmp($a_parts[0], 'INBOX') == 0);
98: $b_base = (strcasecmp($b_parts[0], 'INBOX') == 0);
99: if ($a_base && !$b_base) {
100: return -1;
101: } elseif (!$a_base && $b_base) {
102: return 1;
103: }
104: }
105: $cmp = strnatcasecmp($a_parts[$i], $b_parts[$i]);
106: return ($cmp == 0) ? strcmp($a_parts[$i], $b_parts[$i]) : $cmp;
107: } elseif ($a_parts[$i] !== $b_parts[$i]) {
108: return strlen($a_parts[$i]) - strlen($b_parts[$i]);
109: }
110: }
111:
112: return ($a_count - $b_count);
113: }
114: }
115: