summaryrefslogtreecommitdiff
path: root/lib/api/folder_list.php
blob: 5e5017d97428d245da66797c7b52540535438d72 (plain)
1
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
/*
 +--------------------------------------------------------------------------+
 | This file is part of the Kolab File API                                  |
 |                                                                          |
 | Copyright (C) 2012-2014, Kolab Systems AG                                |
 |                                                                          |
 | This program is free software: you can redistribute it and/or modify     |
 | it under the terms of the GNU Affero General Public License as published |
 | by the Free Software Foundation, either version 3 of the License, or     |
 | (at your option) any later version.                                      |
 |                                                                          |
 | This program is distributed in the hope that it will be useful,          |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of           |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             |
 | GNU Affero General Public License for more details.                      |
 |                                                                          |
 | You should have received a copy of the GNU Affero General Public License |
 | along with this program. If not, see <http://www.gnu.org/licenses/>      |
 +--------------------------------------------------------------------------+
 | Author: Aleksander Machniak <machniak@kolabsys.com>                      |
 +--------------------------------------------------------------------------+
*/

class file_api_folder_list extends file_api_common
{
    /**
     * Request handler
     */
    public function handle()
    {
        parent::handle();

        // get folders from main driver
        $backend = $this->api->get_backend();
        $folders = $backend->folder_list();

        // old result format
        if ($this->api->client_version() < 2) {
            return $folders;
        }

        $drivers  = $this->api->get_drivers(true);
        $has_more = false;
        $errors   = array();

        // get folders from external sources
        foreach ($drivers as $driver) {
            $title  = $driver->title();
            $prefix = $title . file_storage::SEPARATOR;

            // folder exists in main source, replace it with external one
            if (($idx = array_search($title, $folders)) !== false) {
                foreach ($folders as $idx => $folder) {
                    if ($folder == $title || strpos($folder, $prefix) === 0) {
                        unset($folders[$idx]);
                    }
                }
            }

            $folders[] = $title;
            $has_more  = true;

            if ($driver != $backend) {
                try {
                    foreach ($driver->folder_list() as $folder) {
                        $folders[] = $prefix . $folder;
                    }
                }
                catch (Exception $e) {
                    if ($e->getCode() == file_storage::ERROR_NOAUTH) {
                        // inform UI about to ask user for credentials
                        $errors[$title] = $this->parse_metadata($driver->driver_metadata());
                    }
                }
            }
        }

        // re-sort the list
        if ($has_more) {
            usort($folders, array($this, 'sort_folder_comparator'));
        }

        return array(
            'list'        => $folders,
            'auth_errors' => $errors,
        );
    }

    /**
     * Callback for uasort() that implements correct
     * locale-aware case-sensitive sorting
     */
    protected function sort_folder_comparator($str1, $str2)
    {
        $path1 = explode(file_storage::SEPARATOR, $str1);
        $path2 = explode(file_storage::SEPARATOR, $str2);

        foreach ($path1 as $idx => $folder1) {
            $folder2 = $path2[$idx];

            if ($folder1 === $folder2) {
                continue;
            }

            return strcoll($folder1, $folder2);
        }
    }
}