xref: /plugin/davcal/vendor/sabre/dav/tests/Sabre/DAV/Sync/MockSyncCollection.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAV\Sync;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV;
6*a1a3b679SAndreas Boehler
7*a1a3b679SAndreas Boehler/**
8*a1a3b679SAndreas Boehler * This mocks a ISyncCollection, for unittesting.
9*a1a3b679SAndreas Boehler *
10*a1a3b679SAndreas Boehler * This object behaves the same as SimpleCollection. Call addChange to update
11*a1a3b679SAndreas Boehler * the 'changelog' that this class uses for the collection.
12*a1a3b679SAndreas Boehler *
13*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
14*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
15*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
16*a1a3b679SAndreas Boehler */
17*a1a3b679SAndreas Boehlerclass MockSyncCollection extends DAV\SimpleCollection implements ISyncCollection {
18*a1a3b679SAndreas Boehler
19*a1a3b679SAndreas Boehler    public $changeLog = [];
20*a1a3b679SAndreas Boehler
21*a1a3b679SAndreas Boehler    public $token = null;
22*a1a3b679SAndreas Boehler
23*a1a3b679SAndreas Boehler    /**
24*a1a3b679SAndreas Boehler     * This method returns the current sync-token for this collection.
25*a1a3b679SAndreas Boehler     * This can be any string.
26*a1a3b679SAndreas Boehler     *
27*a1a3b679SAndreas Boehler     * If null is returned from this function, the plugin assumes there's no
28*a1a3b679SAndreas Boehler     * sync information available.
29*a1a3b679SAndreas Boehler     *
30*a1a3b679SAndreas Boehler     * @return string|null
31*a1a3b679SAndreas Boehler     */
32*a1a3b679SAndreas Boehler    public function getSyncToken() {
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehler        // Will be 'null' in the first round, and will increment ever after.
35*a1a3b679SAndreas Boehler        return $this->token;
36*a1a3b679SAndreas Boehler
37*a1a3b679SAndreas Boehler    }
38*a1a3b679SAndreas Boehler
39*a1a3b679SAndreas Boehler    public function addChange(array $added, array $modified, array $deleted) {
40*a1a3b679SAndreas Boehler
41*a1a3b679SAndreas Boehler        $this->token++;
42*a1a3b679SAndreas Boehler        $this->changeLog[$this->token] = [
43*a1a3b679SAndreas Boehler            'added'     => $added,
44*a1a3b679SAndreas Boehler            'modified'  => $modified,
45*a1a3b679SAndreas Boehler            'deleted'   => $deleted,
46*a1a3b679SAndreas Boehler        ];
47*a1a3b679SAndreas Boehler
48*a1a3b679SAndreas Boehler    }
49*a1a3b679SAndreas Boehler
50*a1a3b679SAndreas Boehler    /**
51*a1a3b679SAndreas Boehler     * The getChanges method returns all the changes that have happened, since
52*a1a3b679SAndreas Boehler     * the specified syncToken and the current collection.
53*a1a3b679SAndreas Boehler     *
54*a1a3b679SAndreas Boehler     * This function should return an array, such as the following:
55*a1a3b679SAndreas Boehler     *
56*a1a3b679SAndreas Boehler     * array(
57*a1a3b679SAndreas Boehler     *   'syncToken' => 'The current synctoken',
58*a1a3b679SAndreas Boehler     *   'modified'   => array(
59*a1a3b679SAndreas Boehler     *      'new.txt',
60*a1a3b679SAndreas Boehler     *   ),
61*a1a3b679SAndreas Boehler     *   'deleted' => array(
62*a1a3b679SAndreas Boehler     *      'foo.php.bak',
63*a1a3b679SAndreas Boehler     *      'old.txt'
64*a1a3b679SAndreas Boehler     *   )
65*a1a3b679SAndreas Boehler     * );
66*a1a3b679SAndreas Boehler     *
67*a1a3b679SAndreas Boehler     * The syncToken property should reflect the *current* syncToken of the
68*a1a3b679SAndreas Boehler     * collection, as reported getSyncToken(). This is needed here too, to
69*a1a3b679SAndreas Boehler     * ensure the operation is atomic.
70*a1a3b679SAndreas Boehler     *
71*a1a3b679SAndreas Boehler     * If the syncToken is specified as null, this is an initial sync, and all
72*a1a3b679SAndreas Boehler     * members should be reported.
73*a1a3b679SAndreas Boehler     *
74*a1a3b679SAndreas Boehler     * The modified property is an array of nodenames that have changed since
75*a1a3b679SAndreas Boehler     * the last token.
76*a1a3b679SAndreas Boehler     *
77*a1a3b679SAndreas Boehler     * The deleted property is an array with nodenames, that have been deleted
78*a1a3b679SAndreas Boehler     * from collection.
79*a1a3b679SAndreas Boehler     *
80*a1a3b679SAndreas Boehler     * The second argument is basically the 'depth' of the report. If it's 1,
81*a1a3b679SAndreas Boehler     * you only have to report changes that happened only directly in immediate
82*a1a3b679SAndreas Boehler     * descendants. If it's 2, it should also include changes from the nodes
83*a1a3b679SAndreas Boehler     * below the child collections. (grandchildren)
84*a1a3b679SAndreas Boehler     *
85*a1a3b679SAndreas Boehler     * The third (optional) argument allows a client to specify how many
86*a1a3b679SAndreas Boehler     * results should be returned at most. If the limit is not specified, it
87*a1a3b679SAndreas Boehler     * should be treated as infinite.
88*a1a3b679SAndreas Boehler     *
89*a1a3b679SAndreas Boehler     * If the limit (infinite or not) is higher than you're willing to return,
90*a1a3b679SAndreas Boehler     * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception.
91*a1a3b679SAndreas Boehler     *
92*a1a3b679SAndreas Boehler     * If the syncToken is expired (due to data cleanup) or unknown, you must
93*a1a3b679SAndreas Boehler     * return null.
94*a1a3b679SAndreas Boehler     *
95*a1a3b679SAndreas Boehler     * The limit is 'suggestive'. You are free to ignore it.
96*a1a3b679SAndreas Boehler     *
97*a1a3b679SAndreas Boehler     * @param string $syncToken
98*a1a3b679SAndreas Boehler     * @param int $syncLevel
99*a1a3b679SAndreas Boehler     * @param int $limit
100*a1a3b679SAndreas Boehler     * @return array
101*a1a3b679SAndreas Boehler     */
102*a1a3b679SAndreas Boehler    public function getChanges($syncToken, $syncLevel, $limit = null) {
103*a1a3b679SAndreas Boehler
104*a1a3b679SAndreas Boehler        // This is an initial sync
105*a1a3b679SAndreas Boehler        if (is_null($syncToken)) {
106*a1a3b679SAndreas Boehler            return [
107*a1a3b679SAndreas Boehler               'added' => array_map(
108*a1a3b679SAndreas Boehler                    function($item) {
109*a1a3b679SAndreas Boehler                        return $item->getName();
110*a1a3b679SAndreas Boehler                    }, $this->getChildren()
111*a1a3b679SAndreas Boehler                ),
112*a1a3b679SAndreas Boehler                'modified' => [],
113*a1a3b679SAndreas Boehler                'deleted' => [],
114*a1a3b679SAndreas Boehler                'syncToken' => $this->getSyncToken(),
115*a1a3b679SAndreas Boehler            ];
116*a1a3b679SAndreas Boehler        }
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler        if (!is_int($syncToken) && !ctype_digit($syncToken)) {
119*a1a3b679SAndreas Boehler
120*a1a3b679SAndreas Boehler            return null;
121*a1a3b679SAndreas Boehler
122*a1a3b679SAndreas Boehler        }
123*a1a3b679SAndreas Boehler        if (is_null($this->token)) return null;
124*a1a3b679SAndreas Boehler
125*a1a3b679SAndreas Boehler        $added    = [];
126*a1a3b679SAndreas Boehler        $modified = [];
127*a1a3b679SAndreas Boehler        $deleted  = [];
128*a1a3b679SAndreas Boehler
129*a1a3b679SAndreas Boehler        foreach($this->changeLog as $token=>$change) {
130*a1a3b679SAndreas Boehler
131*a1a3b679SAndreas Boehler            if ($token > $syncToken) {
132*a1a3b679SAndreas Boehler
133*a1a3b679SAndreas Boehler                $added = array_merge($added, $change['added']);
134*a1a3b679SAndreas Boehler                $modified = array_merge($modified, $change['modified']);
135*a1a3b679SAndreas Boehler                $deleted = array_merge($deleted, $change['deleted']);
136*a1a3b679SAndreas Boehler
137*a1a3b679SAndreas Boehler                if ($limit) {
138*a1a3b679SAndreas Boehler                    // If there's a limit, we may need to cut things off.
139*a1a3b679SAndreas Boehler                    // This alghorithm is weird and stupid, but it works.
140*a1a3b679SAndreas Boehler                    $left = $limit - (count($modified) + count($deleted));
141*a1a3b679SAndreas Boehler                    if ($left>0) continue;
142*a1a3b679SAndreas Boehler                    if ($left===0) break;
143*a1a3b679SAndreas Boehler                    if ($left<0) {
144*a1a3b679SAndreas Boehler                        $modified = array_slice($modified, 0, $left);
145*a1a3b679SAndreas Boehler                    }
146*a1a3b679SAndreas Boehler                    $left = $limit - (count($modified) + count($deleted));
147*a1a3b679SAndreas Boehler                    if ($left===0) break;
148*a1a3b679SAndreas Boehler                    if ($left<0) {
149*a1a3b679SAndreas Boehler                        $deleted = array_slice($deleted, 0, $left);
150*a1a3b679SAndreas Boehler                    }
151*a1a3b679SAndreas Boehler                    break;
152*a1a3b679SAndreas Boehler
153*a1a3b679SAndreas Boehler                }
154*a1a3b679SAndreas Boehler
155*a1a3b679SAndreas Boehler            }
156*a1a3b679SAndreas Boehler
157*a1a3b679SAndreas Boehler        }
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler        return array(
160*a1a3b679SAndreas Boehler            'syncToken' => $this->token,
161*a1a3b679SAndreas Boehler            'added'     => $added,
162*a1a3b679SAndreas Boehler            'modified'  => $modified,
163*a1a3b679SAndreas Boehler            'deleted'   => $deleted,
164*a1a3b679SAndreas Boehler        );
165*a1a3b679SAndreas Boehler
166*a1a3b679SAndreas Boehler    }
167*a1a3b679SAndreas Boehler
168*a1a3b679SAndreas Boehler
169*a1a3b679SAndreas Boehler}
170