Passed
Push — master ( 34e8da...f497d2 )
by
unknown
06:10 queued 02:50
created
lib/interface/isearchprovider.php 1 patch
Indentation   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -9,63 +9,63 @@
 block discarded – undo
9 9
  */
10 10
 
11 11
 interface ISearchProvider {
12
-	public const SEARCH_GAL = "GAL";
13
-	public const SEARCH_MAILBOX = "MAILBOX";
14
-	public const SEARCH_DOCUMENTLIBRARY = "DOCUMENTLIBRARY";
12
+    public const SEARCH_GAL = "GAL";
13
+    public const SEARCH_MAILBOX = "MAILBOX";
14
+    public const SEARCH_DOCUMENTLIBRARY = "DOCUMENTLIBRARY";
15 15
 
16
-	/**
17
-	 * Constructor.
18
-	 *
19
-	 * @param mixed $searchtype
20
-	 *
21
-	 * @throws StatusException, FatalException
22
-	 */
16
+    /**
17
+     * Constructor.
18
+     *
19
+     * @param mixed $searchtype
20
+     *
21
+     * @throws StatusException, FatalException
22
+     */
23 23
 
24
-	/**
25
-	 * Indicates if a search type is supported by this SearchProvider
26
-	 * Currently only the type SEARCH_GAL (Global Address List) is implemented.
27
-	 *
28
-	 * @param string $searchtype
29
-	 *
30
-	 * @return bool
31
-	 */
32
-	public function SupportsType($searchtype);
24
+    /**
25
+     * Indicates if a search type is supported by this SearchProvider
26
+     * Currently only the type SEARCH_GAL (Global Address List) is implemented.
27
+     *
28
+     * @param string $searchtype
29
+     *
30
+     * @return bool
31
+     */
32
+    public function SupportsType($searchtype);
33 33
 
34
-	/**
35
-	 * Searches the GAL.
36
-	 *
37
-	 * @param string                       $searchquery   string to be searched for
38
-	 * @param string                       $searchrange   specified searchrange
39
-	 * @param SyncResolveRecipientsPicture $searchpicture limitations for picture
40
-	 *
41
-	 * @throws StatusException
42
-	 *
43
-	 * @return array search results
44
-	 */
45
-	public function GetGALSearchResults($searchquery, $searchrange, $searchpicture);
34
+    /**
35
+     * Searches the GAL.
36
+     *
37
+     * @param string                       $searchquery   string to be searched for
38
+     * @param string                       $searchrange   specified searchrange
39
+     * @param SyncResolveRecipientsPicture $searchpicture limitations for picture
40
+     *
41
+     * @throws StatusException
42
+     *
43
+     * @return array search results
44
+     */
45
+    public function GetGALSearchResults($searchquery, $searchrange, $searchpicture);
46 46
 
47
-	/**
48
-	 * Searches for the emails on the server.
49
-	 *
50
-	 * @param ContentParameter $cpo
51
-	 *
52
-	 * @return array
53
-	 */
54
-	public function GetMailboxSearchResults($cpo);
47
+    /**
48
+     * Searches for the emails on the server.
49
+     *
50
+     * @param ContentParameter $cpo
51
+     *
52
+     * @return array
53
+     */
54
+    public function GetMailboxSearchResults($cpo);
55 55
 
56
-	/**
57
-	 * Terminates a search for a given PID.
58
-	 *
59
-	 * @param int $pid
60
-	 *
61
-	 * @return bool
62
-	 */
63
-	public function TerminateSearch($pid);
56
+    /**
57
+     * Terminates a search for a given PID.
58
+     *
59
+     * @param int $pid
60
+     *
61
+     * @return bool
62
+     */
63
+    public function TerminateSearch($pid);
64 64
 
65
-	/**
66
-	 * Disconnects from the current search provider.
67
-	 *
68
-	 * @return bool
69
-	 */
70
-	public function Disconnect();
65
+    /**
66
+     * Disconnects from the current search provider.
67
+     *
68
+     * @return bool
69
+     */
70
+    public function Disconnect();
71 71
 }
Please login to merge, or discard this patch.
lib/interface/iipcprovider.php 1 patch
Indentation   +69 added lines, -69 removed lines patch added patch discarded remove patch
@@ -9,81 +9,81 @@
 block discarded – undo
9 9
  */
10 10
 
11 11
 interface IIpcProvider {
12
-	/**
13
-	 * Constructor.
14
-	 *
15
-	 * @param int    $type
16
-	 * @param int    $allocate
17
-	 * @param string $class
18
-	 * @param string $serverKey
19
-	 */
20
-	public function __construct($type, $allocate, $class, $serverKey);
12
+    /**
13
+     * Constructor.
14
+     *
15
+     * @param int    $type
16
+     * @param int    $allocate
17
+     * @param string $class
18
+     * @param string $serverKey
19
+     */
20
+    public function __construct($type, $allocate, $class, $serverKey);
21 21
 
22
-	/**
23
-	 * Reinitializes the IPC data. If the provider has no way of performing
24
-	 * this action, it should return 'false'.
25
-	 *
26
-	 * @return bool
27
-	 */
28
-	public function ReInitIPC();
22
+    /**
23
+     * Reinitializes the IPC data. If the provider has no way of performing
24
+     * this action, it should return 'false'.
25
+     *
26
+     * @return bool
27
+     */
28
+    public function ReInitIPC();
29 29
 
30
-	/**
31
-	 * Cleans up the IPC data block.
32
-	 *
33
-	 * @return bool
34
-	 */
35
-	public function Clean();
30
+    /**
31
+     * Cleans up the IPC data block.
32
+     *
33
+     * @return bool
34
+     */
35
+    public function Clean();
36 36
 
37
-	/**
38
-	 * Indicates if the IPC is active.
39
-	 *
40
-	 * @return bool
41
-	 */
42
-	public function IsActive();
37
+    /**
38
+     * Indicates if the IPC is active.
39
+     *
40
+     * @return bool
41
+     */
42
+    public function IsActive();
43 43
 
44
-	/**
45
-	 * Blocks the class mutex.
46
-	 * Method blocks until mutex is available!
47
-	 * ATTENTION: make sure that you *always* release a blocked mutex!
48
-	 *
49
-	 * @return bool
50
-	 */
51
-	public function BlockMutex();
44
+    /**
45
+     * Blocks the class mutex.
46
+     * Method blocks until mutex is available!
47
+     * ATTENTION: make sure that you *always* release a blocked mutex!
48
+     *
49
+     * @return bool
50
+     */
51
+    public function BlockMutex();
52 52
 
53
-	/**
54
-	 * Releases the class mutex.
55
-	 * After the release other processes are able to block the mutex themselves.
56
-	 *
57
-	 * @return bool
58
-	 */
59
-	public function ReleaseMutex();
53
+    /**
54
+     * Releases the class mutex.
55
+     * After the release other processes are able to block the mutex themselves.
56
+     *
57
+     * @return bool
58
+     */
59
+    public function ReleaseMutex();
60 60
 
61
-	/**
62
-	 * Indicates if the requested variable is available in IPC data.
63
-	 *
64
-	 * @param int $id int indicating the variable
65
-	 *
66
-	 * @return bool
67
-	 */
68
-	public function HasData($id = 2);
61
+    /**
62
+     * Indicates if the requested variable is available in IPC data.
63
+     *
64
+     * @param int $id int indicating the variable
65
+     *
66
+     * @return bool
67
+     */
68
+    public function HasData($id = 2);
69 69
 
70
-	/**
71
-	 * Returns the requested variable from IPC data.
72
-	 *
73
-	 * @param int $id int indicating the variable
74
-	 *
75
-	 * @return mixed
76
-	 */
77
-	public function GetData($id = 2);
70
+    /**
71
+     * Returns the requested variable from IPC data.
72
+     *
73
+     * @param int $id int indicating the variable
74
+     *
75
+     * @return mixed
76
+     */
77
+    public function GetData($id = 2);
78 78
 
79
-	/**
80
-	 * Writes the transmitted variable to IPC data.
81
-	 * Subclasses may never use an id < 2!
82
-	 *
83
-	 * @param mixed $data data which should be saved into IPC data
84
-	 * @param int   $id   int indicating the variable (bigger than 2!)
85
-	 *
86
-	 * @return bool
87
-	 */
88
-	public function SetData($data, $id = 2);
79
+    /**
80
+     * Writes the transmitted variable to IPC data.
81
+     * Subclasses may never use an id < 2!
82
+     *
83
+     * @param mixed $data data which should be saved into IPC data
84
+     * @param int   $id   int indicating the variable (bigger than 2!)
85
+     *
86
+     * @return bool
87
+     */
88
+    public function SetData($data, $id = 2);
89 89
 }
Please login to merge, or discard this patch.
lib/core/bodypartpreference.php 1 patch
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -8,26 +8,26 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class BodyPartPreference extends StateObject {
11
-	protected $unsetdata = [
12
-		'truncationsize' => false,
13
-		'allornone' => false,
14
-		'preview' => false,
15
-	];
11
+    protected $unsetdata = [
12
+        'truncationsize' => false,
13
+        'allornone' => false,
14
+        'preview' => false,
15
+    ];
16 16
 
17
-	/**
18
-	 * Expected magic getters and setters.
19
-	 *
20
-	 * GetTruncationSize() + SetTruncationSize()
21
-	 * GetAllOrNone() + SetAllOrNone()
22
-	 * GetPreview() + SetPreview()
23
-	 */
17
+    /**
18
+     * Expected magic getters and setters.
19
+     *
20
+     * GetTruncationSize() + SetTruncationSize()
21
+     * GetAllOrNone() + SetAllOrNone()
22
+     * GetPreview() + SetPreview()
23
+     */
24 24
 
25
-	/**
26
-	 * Indicates if this object has values.
27
-	 *
28
-	 * @return bool
29
-	 */
30
-	public function HasValues() {
31
-		return count($this->data) > 0;
32
-	}
25
+    /**
26
+     * Indicates if this object has values.
27
+     *
28
+     * @return bool
29
+     */
30
+    public function HasValues() {
31
+        return count($this->data) > 0;
32
+    }
33 33
 }
Please login to merge, or discard this patch.
lib/core/redisconnection.php 2 patches
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -8,8 +8,8 @@  discard block
 block discarded – undo
8 8
  */
9 9
 
10 10
 class RedisConnection {
11
-	private $redisObj;
12
-	private $luaCAS = <<<'EOF'
11
+    private $redisObj;
12
+    private $luaCAS = <<<'EOF'
13 13
     local old = redis.call('GET', KEYS[1]);
14 14
     if not old or old == ARGV[1] then
15 15
         redis.call('SET',KEYS[1], ARGV[2]);
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
     end
20 20
 EOF;
21 21
 
22
-	private $luaCASHash = <<<'EOF'
22
+    private $luaCASHash = <<<'EOF'
23 23
     local old = redis.call('HGET', KEYS[1], ARGV[1]);
24 24
     if not old or old == ARGV[2] then
25 25
         redis.call('HSET', KEYS[1], ARGV[1], ARGV[3]);
@@ -29,64 +29,64 @@  discard block
 block discarded – undo
29 29
     end
30 30
 EOF;
31 31
 
32
-	/**
33
-	 * Constructor.
34
-	 *
35
-	 * @param mixed $host
36
-	 * @param mixed $port
37
-	 * @param mixed $auth
38
-	 */
39
-	public function __construct($host = REDIS_HOST, $port = REDIS_PORT, $auth = REDIS_AUTH) {
40
-		$this->redisObj = new Redis();
41
-		// Opening a redis connection
42
-		$this->redisObj->connect($host, $port);
43
-		if ($auth) {
44
-			$this->redisObj->auth($auth);
45
-		}
46
-	}
32
+    /**
33
+     * Constructor.
34
+     *
35
+     * @param mixed $host
36
+     * @param mixed $port
37
+     * @param mixed $auth
38
+     */
39
+    public function __construct($host = REDIS_HOST, $port = REDIS_PORT, $auth = REDIS_AUTH) {
40
+        $this->redisObj = new Redis();
41
+        // Opening a redis connection
42
+        $this->redisObj->connect($host, $port);
43
+        if ($auth) {
44
+            $this->redisObj->auth($auth);
45
+        }
46
+    }
47 47
 
48
-	public function getKey($key) {
49
-		try {
50
-			return $this->redisObj->get($key);
51
-		}
52
-		catch (Exception $e) {
53
-			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->getKey(): %s", get_class($this), $e->getMessage()));
54
-		}
55
-	}
48
+    public function getKey($key) {
49
+        try {
50
+            return $this->redisObj->get($key);
51
+        }
52
+        catch (Exception $e) {
53
+            SLog::Write(LOGLEVEL_ERROR, sprintf("%s->getKey(): %s", get_class($this), $e->getMessage()));
54
+        }
55
+    }
56 56
 
57
-	public function setKey($key, $value, $ttl = -1) {
58
-		try {
59
-			if ($ttl > 0) {
60
-				return $this->redisObj->setEx($key, $ttl, $value);
61
-			}
57
+    public function setKey($key, $value, $ttl = -1) {
58
+        try {
59
+            if ($ttl > 0) {
60
+                return $this->redisObj->setEx($key, $ttl, $value);
61
+            }
62 62
 
63
-			return $this->redisObj->set($key, $value);
64
-		}
65
-		catch (Exception $e) {
66
-			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->setKey(): %s", get_class($this), $e->getMessage()));
67
-		}
68
-	}
63
+            return $this->redisObj->set($key, $value);
64
+        }
65
+        catch (Exception $e) {
66
+            SLog::Write(LOGLEVEL_ERROR, sprintf("%s->setKey(): %s", get_class($this), $e->getMessage()));
67
+        }
68
+    }
69 69
 
70
-	public function delKey($key) {
71
-		try {
72
-			return $this->redisObj->del($key);
73
-		}
74
-		catch (Exception $e) {
75
-			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->delKey(): %s", get_class($this), $e->getMessage()));
76
-		}
77
-	}
70
+    public function delKey($key) {
71
+        try {
72
+            return $this->redisObj->del($key);
73
+        }
74
+        catch (Exception $e) {
75
+            SLog::Write(LOGLEVEL_ERROR, sprintf("%s->delKey(): %s", get_class($this), $e->getMessage()));
76
+        }
77
+    }
78 78
 
79
-	public function get() {
80
-		return $this->redisObj;
81
-	}
79
+    public function get() {
80
+        return $this->redisObj;
81
+    }
82 82
 
83
-	public function CAS($key, $oldvalue, $newvalue) {
84
-		// custom Compare-and-swap implementation using LUA
85
-		return $this->redisObj->eval($this->luaCAS, [$key, $oldvalue, $newvalue], 1);
86
-	}
83
+    public function CAS($key, $oldvalue, $newvalue) {
84
+        // custom Compare-and-swap implementation using LUA
85
+        return $this->redisObj->eval($this->luaCAS, [$key, $oldvalue, $newvalue], 1);
86
+    }
87 87
 
88
-	public function CASHash($key, $subkey, $oldvalue, $newvalue) {
89
-		// custom Compare-and-swap implementation using LUA for a hash subkey
90
-		return $this->redisObj->eval($this->luaCASHash, [$key, $subkey, $oldvalue, $newvalue], 1);
91
-	}
88
+    public function CASHash($key, $subkey, $oldvalue, $newvalue) {
89
+        // custom Compare-and-swap implementation using LUA for a hash subkey
90
+        return $this->redisObj->eval($this->luaCASHash, [$key, $subkey, $oldvalue, $newvalue], 1);
91
+    }
92 92
 }
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -48,8 +48,7 @@  discard block
 block discarded – undo
48 48
 	public function getKey($key) {
49 49
 		try {
50 50
 			return $this->redisObj->get($key);
51
-		}
52
-		catch (Exception $e) {
51
+		} catch (Exception $e) {
53 52
 			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->getKey(): %s", get_class($this), $e->getMessage()));
54 53
 		}
55 54
 	}
@@ -61,8 +60,7 @@  discard block
 block discarded – undo
61 60
 			}
62 61
 
63 62
 			return $this->redisObj->set($key, $value);
64
-		}
65
-		catch (Exception $e) {
63
+		} catch (Exception $e) {
66 64
 			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->setKey(): %s", get_class($this), $e->getMessage()));
67 65
 		}
68 66
 	}
@@ -70,8 +68,7 @@  discard block
 block discarded – undo
70 68
 	public function delKey($key) {
71 69
 		try {
72 70
 			return $this->redisObj->del($key);
73
-		}
74
-		catch (Exception $e) {
71
+		} catch (Exception $e) {
75 72
 			SLog::Write(LOGLEVEL_ERROR, sprintf("%s->delKey(): %s", get_class($this), $e->getMessage()));
76 73
 		}
77 74
 	}
Please login to merge, or discard this patch.
lib/core/topcollector.php 3 patches
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -10,214 +10,214 @@
 block discarded – undo
10 10
  */
11 11
 
12 12
 class TopCollector extends InterProcessData {
13
-	public const ENABLEDAT = "grommunio-sync:topenabledat";
14
-	public const TOPDATA = "grommunio-sync:topdata";
15
-	public const ENABLED_CACHETIME = 5; // how often in seconds to check the ipc provider if it has data for the TopCollector
16
-
17
-	protected $preserved;
18
-	protected $latest;
19
-	private $disabled;
20
-	private $checkEnabledTime;
21
-	private $enabled;
22
-
23
-	/**
24
-	 * Constructor.
25
-	 */
26
-	public function __construct() {
27
-		// initialize super parameters
28
-		$this->allocate = 2097152; // 2 MB
29
-		$this->type = 20;
30
-		parent::__construct();
31
-
32
-		// initialize params
33
-		$this->initializeParams();
34
-
35
-		$this->preserved = [];
36
-		// static vars come from the parent class
37
-		$this->latest = ["pid" => self::$pid,
38
-			"ip" => Request::GetRemoteAddr(),
39
-			"user" => self::$user,
40
-			"start" => self::$start,
41
-			"devtype" => Request::GetDeviceType(),
42
-			"devid" => self::$devid,
43
-			"devagent" => Request::GetUserAgent(),
44
-			"command" => Request::GetCommandCode(),
45
-			"ended" => 0,
46
-			"push" => false,
47
-		];
48
-		$this->disabled = (bool) (defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true);
49
-		$this->checkEnabledTime = time() - self::ENABLED_CACHETIME - 1;
50
-		$this->AnnounceInformation("initializing");
51
-	}
52
-
53
-	/**
54
-	 * Destructor
55
-	 * indicates that the process is shutting down.
56
-	 */
57
-	public function __destruct() {
58
-		$this->AnnounceInformation("OK", false, true);
59
-	}
60
-
61
-	/**
62
-	 * Advices all other processes that they should start/stop
63
-	 * collecting data. The data saved is a timestamp. It has to be
64
-	 * reactivated every couple of seconds.
65
-	 *
66
-	 * @param bool $stop (opt) default false (do collect)
67
-	 *
68
-	 * @return bool indicating if it was set to collect before
69
-	 */
70
-	public function CollectData($stop = false) {
71
-		$wasEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
72
-
73
-		$time = time();
74
-		if ($stop === true) {
75
-			$time = 0;
76
-		}
77
-
78
-		if (!$this->setData($time, self::ENABLEDAT)) {
79
-			return false;
80
-		}
81
-
82
-		return $wasEnabled;
83
-	}
84
-
85
-	/**
86
-	 * Announces a string to the TopCollector.
87
-	 *
88
-	 * @param string $info
89
-	 * @param bool   $preserve    info should be displayed when process terminates
90
-	 * @param bool   $terminating indicates if the process is terminating
91
-	 * @param mixed  $addinfo
92
-	 *
93
-	 * @return bool
94
-	 */
95
-	public function AnnounceInformation($addinfo, $preserve = false, $terminating = false) {
96
-		if ($this->disabled) {
97
-			return true;
98
-		}
99
-
100
-		$this->latest["addinfo"] = $addinfo;
101
-		$this->latest["update"] = time();
102
-
103
-		if ($terminating) {
104
-			$this->latest["ended"] = time();
105
-			foreach ($this->preserved as $p) {
106
-				$this->latest["addinfo"] .= " : " . $p;
107
-			}
108
-		}
109
-
110
-		if ($preserve) {
111
-			$this->preserved[] = $addinfo;
112
-		}
113
-
114
-		if ($this->isEnabled()) {
115
-			// use the pid as subkey
116
-			$ok = $this->setDeviceUserData(self::TOPDATA, $this->latest, self::$devid, self::$user, self::$pid);
117
-			if (!$ok) {
118
-				SLog::Write(LOGLEVEL_WARN, "TopCollector::AnnounceInformation(): could not write to redis. grommunio-sync top will not display this data.");
119
-
120
-				return false;
121
-			}
122
-		}
123
-
124
-		return true;
125
-	}
126
-
127
-	/**
128
-	 * Returns all available top data.
129
-	 *
130
-	 * @return array
131
-	 */
132
-	public function ReadLatest() {
133
-		return $this->getAllDeviceUserData(self::TOPDATA);
134
-	}
135
-
136
-	/**
137
-	 * Cleans up data collected so far.
138
-	 *
139
-	 * @param bool $all (optional) if set all data independently from the age is removed
140
-	 *
141
-	 * @return bool status
142
-	 */
143
-	public function ClearLatest($all = false) {
144
-		// it's ok when doing this every 10 sec
145
-		if ($all == false && time() % 10 != 0) {
146
-			return true;
147
-		}
148
-
149
-		if ($all == true) {
150
-			$this->getRedis()->delKey(self::TOPDATA);
151
-		}
152
-		else {
153
-			foreach ($this->getRawDeviceUserData(self::TOPDATA) as $compKey => $rawline) {
154
-				$line = json_decode($rawline, true);
155
-				// remove everything which terminated for 20 secs or is not updated for more than 120 secs
156
-				if (($line["ended"] != 0 && time() - $line["ended"] > 20) ||
157
-					time() - $line["update"] > 120) {
158
-					$this->getRedis()->get()->hDel(self::TOPDATA, $compKey);
159
-				}
160
-			}
161
-		}
162
-
163
-		return true;
164
-	}
165
-
166
-	/**
167
-	 * Sets a different UserAgent for this connection.
168
-	 *
169
-	 * @param string $agent
170
-	 *
171
-	 * @return bool
172
-	 */
173
-	public function SetUserAgent($agent) {
174
-		$this->latest["devagent"] = $agent;
175
-
176
-		return true;
177
-	}
178
-
179
-	/**
180
-	 * Marks this process as push connection.
181
-	 *
182
-	 * @param string $agent
183
-	 *
184
-	 * @return bool
185
-	 */
186
-	public function SetAsPushConnection() {
187
-		$this->latest["push"] = true;
188
-
189
-		return true;
190
-	}
191
-
192
-	/**
193
-	 * Reinitializes the IPC data.
194
-	 *
195
-	 * @return bool
196
-	 */
197
-	public function ReInitIPC() {
198
-		return parent::ReInitIPC();
199
-		if (!status) {
200
-			$this->getRedis()->delKey(self::TOPDATA);
201
-		}
202
-
203
-		return $status;
204
-	}
205
-
206
-	/**
207
-	 * Indicates if top data should be saved or not
208
-	 * Returns true for 10 seconds after the latest CollectData()
209
-	 * SHOULD only be called with locked mutex!
210
-	 *
211
-	 * @return bool
212
-	 */
213
-	private function isEnabled() {
214
-		$time = time();
215
-		if ($this->checkEnabledTime + self::ENABLED_CACHETIME < $time) {
216
-			$isEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
217
-			$this->enabled = ($isEnabled !== false && ($isEnabled + 300) > $time);
218
-			$this->checkEnabledTime = $time;
219
-		}
220
-
221
-		return $this->enabled;
222
-	}
13
+    public const ENABLEDAT = "grommunio-sync:topenabledat";
14
+    public const TOPDATA = "grommunio-sync:topdata";
15
+    public const ENABLED_CACHETIME = 5; // how often in seconds to check the ipc provider if it has data for the TopCollector
16
+
17
+    protected $preserved;
18
+    protected $latest;
19
+    private $disabled;
20
+    private $checkEnabledTime;
21
+    private $enabled;
22
+
23
+    /**
24
+     * Constructor.
25
+     */
26
+    public function __construct() {
27
+        // initialize super parameters
28
+        $this->allocate = 2097152; // 2 MB
29
+        $this->type = 20;
30
+        parent::__construct();
31
+
32
+        // initialize params
33
+        $this->initializeParams();
34
+
35
+        $this->preserved = [];
36
+        // static vars come from the parent class
37
+        $this->latest = ["pid" => self::$pid,
38
+            "ip" => Request::GetRemoteAddr(),
39
+            "user" => self::$user,
40
+            "start" => self::$start,
41
+            "devtype" => Request::GetDeviceType(),
42
+            "devid" => self::$devid,
43
+            "devagent" => Request::GetUserAgent(),
44
+            "command" => Request::GetCommandCode(),
45
+            "ended" => 0,
46
+            "push" => false,
47
+        ];
48
+        $this->disabled = (bool) (defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true);
49
+        $this->checkEnabledTime = time() - self::ENABLED_CACHETIME - 1;
50
+        $this->AnnounceInformation("initializing");
51
+    }
52
+
53
+    /**
54
+     * Destructor
55
+     * indicates that the process is shutting down.
56
+     */
57
+    public function __destruct() {
58
+        $this->AnnounceInformation("OK", false, true);
59
+    }
60
+
61
+    /**
62
+     * Advices all other processes that they should start/stop
63
+     * collecting data. The data saved is a timestamp. It has to be
64
+     * reactivated every couple of seconds.
65
+     *
66
+     * @param bool $stop (opt) default false (do collect)
67
+     *
68
+     * @return bool indicating if it was set to collect before
69
+     */
70
+    public function CollectData($stop = false) {
71
+        $wasEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
72
+
73
+        $time = time();
74
+        if ($stop === true) {
75
+            $time = 0;
76
+        }
77
+
78
+        if (!$this->setData($time, self::ENABLEDAT)) {
79
+            return false;
80
+        }
81
+
82
+        return $wasEnabled;
83
+    }
84
+
85
+    /**
86
+     * Announces a string to the TopCollector.
87
+     *
88
+     * @param string $info
89
+     * @param bool   $preserve    info should be displayed when process terminates
90
+     * @param bool   $terminating indicates if the process is terminating
91
+     * @param mixed  $addinfo
92
+     *
93
+     * @return bool
94
+     */
95
+    public function AnnounceInformation($addinfo, $preserve = false, $terminating = false) {
96
+        if ($this->disabled) {
97
+            return true;
98
+        }
99
+
100
+        $this->latest["addinfo"] = $addinfo;
101
+        $this->latest["update"] = time();
102
+
103
+        if ($terminating) {
104
+            $this->latest["ended"] = time();
105
+            foreach ($this->preserved as $p) {
106
+                $this->latest["addinfo"] .= " : " . $p;
107
+            }
108
+        }
109
+
110
+        if ($preserve) {
111
+            $this->preserved[] = $addinfo;
112
+        }
113
+
114
+        if ($this->isEnabled()) {
115
+            // use the pid as subkey
116
+            $ok = $this->setDeviceUserData(self::TOPDATA, $this->latest, self::$devid, self::$user, self::$pid);
117
+            if (!$ok) {
118
+                SLog::Write(LOGLEVEL_WARN, "TopCollector::AnnounceInformation(): could not write to redis. grommunio-sync top will not display this data.");
119
+
120
+                return false;
121
+            }
122
+        }
123
+
124
+        return true;
125
+    }
126
+
127
+    /**
128
+     * Returns all available top data.
129
+     *
130
+     * @return array
131
+     */
132
+    public function ReadLatest() {
133
+        return $this->getAllDeviceUserData(self::TOPDATA);
134
+    }
135
+
136
+    /**
137
+     * Cleans up data collected so far.
138
+     *
139
+     * @param bool $all (optional) if set all data independently from the age is removed
140
+     *
141
+     * @return bool status
142
+     */
143
+    public function ClearLatest($all = false) {
144
+        // it's ok when doing this every 10 sec
145
+        if ($all == false && time() % 10 != 0) {
146
+            return true;
147
+        }
148
+
149
+        if ($all == true) {
150
+            $this->getRedis()->delKey(self::TOPDATA);
151
+        }
152
+        else {
153
+            foreach ($this->getRawDeviceUserData(self::TOPDATA) as $compKey => $rawline) {
154
+                $line = json_decode($rawline, true);
155
+                // remove everything which terminated for 20 secs or is not updated for more than 120 secs
156
+                if (($line["ended"] != 0 && time() - $line["ended"] > 20) ||
157
+                    time() - $line["update"] > 120) {
158
+                    $this->getRedis()->get()->hDel(self::TOPDATA, $compKey);
159
+                }
160
+            }
161
+        }
162
+
163
+        return true;
164
+    }
165
+
166
+    /**
167
+     * Sets a different UserAgent for this connection.
168
+     *
169
+     * @param string $agent
170
+     *
171
+     * @return bool
172
+     */
173
+    public function SetUserAgent($agent) {
174
+        $this->latest["devagent"] = $agent;
175
+
176
+        return true;
177
+    }
178
+
179
+    /**
180
+     * Marks this process as push connection.
181
+     *
182
+     * @param string $agent
183
+     *
184
+     * @return bool
185
+     */
186
+    public function SetAsPushConnection() {
187
+        $this->latest["push"] = true;
188
+
189
+        return true;
190
+    }
191
+
192
+    /**
193
+     * Reinitializes the IPC data.
194
+     *
195
+     * @return bool
196
+     */
197
+    public function ReInitIPC() {
198
+        return parent::ReInitIPC();
199
+        if (!status) {
200
+            $this->getRedis()->delKey(self::TOPDATA);
201
+        }
202
+
203
+        return $status;
204
+    }
205
+
206
+    /**
207
+     * Indicates if top data should be saved or not
208
+     * Returns true for 10 seconds after the latest CollectData()
209
+     * SHOULD only be called with locked mutex!
210
+     *
211
+     * @return bool
212
+     */
213
+    private function isEnabled() {
214
+        $time = time();
215
+        if ($this->checkEnabledTime + self::ENABLED_CACHETIME < $time) {
216
+            $isEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
217
+            $this->enabled = ($isEnabled !== false && ($isEnabled + 300) > $time);
218
+            $this->checkEnabledTime = $time;
219
+        }
220
+
221
+        return $this->enabled;
222
+    }
223 223
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
 			"ended" => 0,
46 46
 			"push" => false,
47 47
 		];
48
-		$this->disabled = (bool) (defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true);
48
+		$this->disabled = (bool)(defined('TOPCOLLECTOR_DISABLED') && constant('TOPCOLLECTOR_DISABLED') === true);
49 49
 		$this->checkEnabledTime = time() - self::ENABLED_CACHETIME - 1;
50 50
 		$this->AnnounceInformation("initializing");
51 51
 	}
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 		if ($terminating) {
104 104
 			$this->latest["ended"] = time();
105 105
 			foreach ($this->preserved as $p) {
106
-				$this->latest["addinfo"] .= " : " . $p;
106
+				$this->latest["addinfo"] .= " : ".$p;
107 107
 			}
108 108
 		}
109 109
 
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -148,8 +148,7 @@
 block discarded – undo
148 148
 
149 149
 		if ($all == true) {
150 150
 			$this->getRedis()->delKey(self::TOPDATA);
151
-		}
152
-		else {
151
+		} else {
153 152
 			foreach ($this->getRawDeviceUserData(self::TOPDATA) as $compKey => $rawline) {
154 153
 				$line = json_decode($rawline, true);
155 154
 				// remove everything which terminated for 20 secs or is not updated for more than 120 secs
Please login to merge, or discard this patch.
lib/core/bodypreference.php 1 patch
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -8,26 +8,26 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class BodyPreference extends StateObject {
11
-	protected $unsetdata = [
12
-		'truncationsize' => false,
13
-		'allornone' => false,
14
-		'preview' => false,
15
-	];
11
+    protected $unsetdata = [
12
+        'truncationsize' => false,
13
+        'allornone' => false,
14
+        'preview' => false,
15
+    ];
16 16
 
17
-	/**
18
-	 * expected magic getters and setters.
19
-	 *
20
-	 * GetTruncationSize() + SetTruncationSize()
21
-	 * GetAllOrNone() + SetAllOrNone()
22
-	 * GetPreview() + SetPreview()
23
-	 */
17
+    /**
18
+     * expected magic getters and setters.
19
+     *
20
+     * GetTruncationSize() + SetTruncationSize()
21
+     * GetAllOrNone() + SetAllOrNone()
22
+     * GetPreview() + SetPreview()
23
+     */
24 24
 
25
-	/**
26
-	 * Indicates if this object has values.
27
-	 *
28
-	 * @return bool
29
-	 */
30
-	public function HasValues() {
31
-		return count($this->data) > 0;
32
-	}
25
+    /**
26
+     * Indicates if this object has values.
27
+     *
28
+     * @return bool
29
+     */
30
+    public function HasValues() {
31
+        return count($this->data) > 0;
32
+    }
33 33
 }
Please login to merge, or discard this patch.
lib/core/hierarchycache.php 1 patch
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -8,184 +8,184 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class HierarchyCache extends StateObject {
11
-	protected $changed = false;
12
-	protected $data;
13
-	private $dataOld;
14
-
15
-	/**
16
-	 * Constructor of the HierarchyCache.
17
-	 *
18
-	 * @return
19
-	 */
20
-	public function __construct() {
21
-		$this->data = [];
22
-		$this->dataOld = $this->data;
23
-		$this->changed = true;
24
-	}
25
-
26
-	/**
27
-	 * Indicates if the cache was changed.
28
-	 *
29
-	 * @return bool
30
-	 */
31
-	public function IsStateChanged() {
32
-		return $this->changed;
33
-	}
34
-
35
-	/**
36
-	 * Copy current data to memory.
37
-	 *
38
-	 * @return bool
39
-	 */
40
-	public function CopyOldState() {
41
-		$this->dataOld = $this->data;
42
-		$this->changed = false;
43
-
44
-		return true;
45
-	}
46
-
47
-	/**
48
-	 * Returns the SyncFolder object for a folder id
49
-	 * If $oldstate is set, then the data from the previous state is returned.
50
-	 *
51
-	 * @param string $serverid
52
-	 * @param bool   $oldstate (optional) by default false
53
-	 * @param mixed  $oldState
54
-	 *
55
-	 * @return SyncObject/boolean       false if not found
56
-	 */
57
-	public function GetFolder($serverid, $oldState = false) {
58
-		if (!$oldState && array_key_exists($serverid, $this->data)) {
59
-			return $this->data[$serverid];
60
-		}
61
-		if ($oldState && array_key_exists($serverid, $this->dataOld)) {
62
-			return $this->dataOld[$serverid];
63
-		}
64
-
65
-		return false;
66
-	}
67
-
68
-	/**
69
-	 * Adds a folder to the HierarchyCache.
70
-	 *
71
-	 * @param SyncObject $folder
72
-	 *
73
-	 * @return bool
74
-	 */
75
-	public function AddFolder($folder) {
76
-		SLog::Write(LOGLEVEL_DEBUG, "HierarchyCache: AddFolder() serverid: {$folder->serverid} displayname: {$folder->displayname}");
77
-
78
-		// on update the $folder does most of the times not contain a type
79
-		// we copy the value in this case to the new $folder object
80
-		if (isset($this->data[$folder->serverid]) && (!isset($folder->type) || $folder->type == false) && isset($this->data[$folder->serverid]->type)) {
81
-			$folder->type = $this->data[$folder->serverid]->type;
82
-			SLog::Write(LOGLEVEL_DEBUG, sprintf("HierarchyCache: AddFolder() is an update: used type '%s' from old object", $folder->type));
83
-		}
84
-
85
-		// add/update
86
-		$this->data[$folder->serverid] = $folder;
87
-		$this->changed = true;
88
-
89
-		return true;
90
-	}
91
-
92
-	/**
93
-	 * Removes a folder to the HierarchyCache.
94
-	 *
95
-	 * @param string $serverid id of folder to be removed
96
-	 *
97
-	 * @return bool
98
-	 */
99
-	public function DelFolder($serverid) {
100
-		$ftype = $this->GetFolder($serverid);
101
-
102
-		SLog::Write(LOGLEVEL_DEBUG, sprintf("HierarchyCache: DelFolder() serverid: '%s' - type: '%s'", $serverid, $ftype->type));
103
-		unset($this->data[$serverid]);
104
-		$this->changed = true;
105
-
106
-		return true;
107
-	}
108
-
109
-	/**
110
-	 * Imports a folder array to the HierarchyCache.
111
-	 *
112
-	 * @param array $folders folders to the HierarchyCache
113
-	 *
114
-	 * @return bool
115
-	 */
116
-	public function ImportFolders($folders) {
117
-		if (!is_array($folders)) {
118
-			return false;
119
-		}
120
-
121
-		$this->data = [];
122
-
123
-		foreach ($folders as $folder) {
124
-			if (!isset($folder->type)) {
125
-				continue;
126
-			}
127
-			$this->AddFolder($folder);
128
-		}
129
-
130
-		return true;
131
-	}
132
-
133
-	/**
134
-	 * Exports all folders from the HierarchyCache.
135
-	 *
136
-	 * @param bool $oldstate (optional) by default false
137
-	 *
138
-	 * @return array
139
-	 */
140
-	public function ExportFolders($oldstate = false) {
141
-		if ($oldstate === false) {
142
-			return $this->data;
143
-		}
144
-
145
-		return $this->dataOld;
146
-	}
147
-
148
-	/**
149
-	 * Returns all folder objects which were deleted in this operation.
150
-	 *
151
-	 * @return array with SyncFolder objects
152
-	 */
153
-	public function GetDeletedFolders() {
154
-		// diffing the Olddata with data we know if folders were deleted
155
-		return array_diff_key($this->dataOld, $this->data);
156
-	}
157
-
158
-	/**
159
-	 * Returns some statistics about the HierarchyCache.
160
-	 *
161
-	 * @return string
162
-	 */
163
-	public function GetStat() {
164
-		return sprintf("HierarchyCache is %s - Cached objects: %d", ((isset($this->data)) ? "up" : "down"), ((isset($this->data)) ? count($this->data) : "0"));
165
-	}
166
-
167
-	/**
168
-	 * Removes internal data from the object, so this data can not be exposed.
169
-	 *
170
-	 * @return bool
171
-	 */
172
-	public function StripData() {
173
-		unset($this->changed, $this->dataOld);
174
-
175
-		foreach ($this->data as $id => $folder) {
176
-			$folder->StripData();
177
-		}
178
-
179
-		return true;
180
-	}
181
-
182
-	/**
183
-	 * Returns objects which should be persistent
184
-	 * called before serialization.
185
-	 *
186
-	 * @return array
187
-	 */
188
-	public function __sleep() {
189
-		return ["data"];
190
-	}
11
+    protected $changed = false;
12
+    protected $data;
13
+    private $dataOld;
14
+
15
+    /**
16
+     * Constructor of the HierarchyCache.
17
+     *
18
+     * @return
19
+     */
20
+    public function __construct() {
21
+        $this->data = [];
22
+        $this->dataOld = $this->data;
23
+        $this->changed = true;
24
+    }
25
+
26
+    /**
27
+     * Indicates if the cache was changed.
28
+     *
29
+     * @return bool
30
+     */
31
+    public function IsStateChanged() {
32
+        return $this->changed;
33
+    }
34
+
35
+    /**
36
+     * Copy current data to memory.
37
+     *
38
+     * @return bool
39
+     */
40
+    public function CopyOldState() {
41
+        $this->dataOld = $this->data;
42
+        $this->changed = false;
43
+
44
+        return true;
45
+    }
46
+
47
+    /**
48
+     * Returns the SyncFolder object for a folder id
49
+     * If $oldstate is set, then the data from the previous state is returned.
50
+     *
51
+     * @param string $serverid
52
+     * @param bool   $oldstate (optional) by default false
53
+     * @param mixed  $oldState
54
+     *
55
+     * @return SyncObject/boolean       false if not found
56
+     */
57
+    public function GetFolder($serverid, $oldState = false) {
58
+        if (!$oldState && array_key_exists($serverid, $this->data)) {
59
+            return $this->data[$serverid];
60
+        }
61
+        if ($oldState && array_key_exists($serverid, $this->dataOld)) {
62
+            return $this->dataOld[$serverid];
63
+        }
64
+
65
+        return false;
66
+    }
67
+
68
+    /**
69
+     * Adds a folder to the HierarchyCache.
70
+     *
71
+     * @param SyncObject $folder
72
+     *
73
+     * @return bool
74
+     */
75
+    public function AddFolder($folder) {
76
+        SLog::Write(LOGLEVEL_DEBUG, "HierarchyCache: AddFolder() serverid: {$folder->serverid} displayname: {$folder->displayname}");
77
+
78
+        // on update the $folder does most of the times not contain a type
79
+        // we copy the value in this case to the new $folder object
80
+        if (isset($this->data[$folder->serverid]) && (!isset($folder->type) || $folder->type == false) && isset($this->data[$folder->serverid]->type)) {
81
+            $folder->type = $this->data[$folder->serverid]->type;
82
+            SLog::Write(LOGLEVEL_DEBUG, sprintf("HierarchyCache: AddFolder() is an update: used type '%s' from old object", $folder->type));
83
+        }
84
+
85
+        // add/update
86
+        $this->data[$folder->serverid] = $folder;
87
+        $this->changed = true;
88
+
89
+        return true;
90
+    }
91
+
92
+    /**
93
+     * Removes a folder to the HierarchyCache.
94
+     *
95
+     * @param string $serverid id of folder to be removed
96
+     *
97
+     * @return bool
98
+     */
99
+    public function DelFolder($serverid) {
100
+        $ftype = $this->GetFolder($serverid);
101
+
102
+        SLog::Write(LOGLEVEL_DEBUG, sprintf("HierarchyCache: DelFolder() serverid: '%s' - type: '%s'", $serverid, $ftype->type));
103
+        unset($this->data[$serverid]);
104
+        $this->changed = true;
105
+
106
+        return true;
107
+    }
108
+
109
+    /**
110
+     * Imports a folder array to the HierarchyCache.
111
+     *
112
+     * @param array $folders folders to the HierarchyCache
113
+     *
114
+     * @return bool
115
+     */
116
+    public function ImportFolders($folders) {
117
+        if (!is_array($folders)) {
118
+            return false;
119
+        }
120
+
121
+        $this->data = [];
122
+
123
+        foreach ($folders as $folder) {
124
+            if (!isset($folder->type)) {
125
+                continue;
126
+            }
127
+            $this->AddFolder($folder);
128
+        }
129
+
130
+        return true;
131
+    }
132
+
133
+    /**
134
+     * Exports all folders from the HierarchyCache.
135
+     *
136
+     * @param bool $oldstate (optional) by default false
137
+     *
138
+     * @return array
139
+     */
140
+    public function ExportFolders($oldstate = false) {
141
+        if ($oldstate === false) {
142
+            return $this->data;
143
+        }
144
+
145
+        return $this->dataOld;
146
+    }
147
+
148
+    /**
149
+     * Returns all folder objects which were deleted in this operation.
150
+     *
151
+     * @return array with SyncFolder objects
152
+     */
153
+    public function GetDeletedFolders() {
154
+        // diffing the Olddata with data we know if folders were deleted
155
+        return array_diff_key($this->dataOld, $this->data);
156
+    }
157
+
158
+    /**
159
+     * Returns some statistics about the HierarchyCache.
160
+     *
161
+     * @return string
162
+     */
163
+    public function GetStat() {
164
+        return sprintf("HierarchyCache is %s - Cached objects: %d", ((isset($this->data)) ? "up" : "down"), ((isset($this->data)) ? count($this->data) : "0"));
165
+    }
166
+
167
+    /**
168
+     * Removes internal data from the object, so this data can not be exposed.
169
+     *
170
+     * @return bool
171
+     */
172
+    public function StripData() {
173
+        unset($this->changed, $this->dataOld);
174
+
175
+        foreach ($this->data as $id => $folder) {
176
+            $folder->StripData();
177
+        }
178
+
179
+        return true;
180
+    }
181
+
182
+    /**
183
+     * Returns objects which should be persistent
184
+     * called before serialization.
185
+     *
186
+     * @return array
187
+     */
188
+    public function __sleep() {
189
+        return ["data"];
190
+    }
191 191
 }
Please login to merge, or discard this patch.
lib/core/changesmemorywrapper.php 2 patches
Indentation   +402 added lines, -402 removed lines patch added patch discarded remove patch
@@ -8,412 +8,412 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IExportChanges {
11
-	public const CHANGE = 1;
12
-	public const DELETION = 2;
13
-	public const SOFTDELETION = 3;
14
-	public const SYNCHRONIZING = 4;
15
-
16
-	private $changes;
17
-	private $step;
18
-	private $destinationImporter;
19
-	private $exportImporter;
20
-	private $impersonating;
21
-	private $foldersWithoutPermissions;
22
-
23
-	/**
24
-	 * Constructor.
25
-	 *
26
-	 * @return
27
-	 */
28
-	public function __construct() {
29
-		$this->changes = [];
30
-		$this->step = 0;
31
-		$this->impersonating = null;
32
-		$this->foldersWithoutPermissions = [];
33
-		parent::__construct();
34
-	}
35
-
36
-	/**
37
-	 * Only used to load additional folder sync information for hierarchy changes.
38
-	 *
39
-	 * @param array $state current state of additional hierarchy folders
40
-	 * @param mixed $flags
41
-	 *
42
-	 * @return bool
43
-	 */
44
-	public function Config($state, $flags = 0) {
45
-		if ($this->impersonating == null) {
46
-			$this->impersonating = (Request::GetImpersonatedUser()) ? strtolower(Request::GetImpersonatedUser()) : false;
47
-		}
48
-
49
-		// we should never forward this changes to a backend
50
-		if (!isset($this->destinationImporter)) {
51
-			foreach ($state as $addKey => $addFolder) {
52
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : process folder '%s'", $addFolder->displayname));
53
-				if (isset($addFolder->NoBackendFolder) && $addFolder->NoBackendFolder == true) {
54
-					// check rights for readonly access only
55
-					$hasRights = GSync::GetBackend()->Setup($addFolder->Store, true, $addFolder->BackendId, true);
56
-					// delete the folder on the device
57
-					if (!$hasRights) {
58
-						// delete the folder only if it was an additional folder before, else ignore it
59
-						$synchedfolder = $this->GetFolder($addFolder->serverid);
60
-						if (isset($synchedfolder->NoBackendFolder) && $synchedfolder->NoBackendFolder == true) {
61
-							$this->ImportFolderDeletion($addFolder);
62
-						}
63
-
64
-						continue;
65
-					}
66
-				}
67
-				// make sure, if the folder is already in cache, to set the TypeReal flag (if available)
68
-				$cacheFolder = $this->GetFolder($addFolder->serverid);
69
-				if (isset($cacheFolder->TypeReal)) {
70
-					$addFolder->TypeReal = $cacheFolder->TypeReal;
71
-					SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(): Set REAL foldertype for folder '%s' from cache: '%s'", $addFolder->displayname, $addFolder->TypeReal));
72
-				}
73
-
74
-				// add folder to the device - if folder is already on the device, nothing will happen
75
-				$this->ImportFolderChange($addFolder);
76
-			}
77
-
78
-			// look for folders which are currently on the device if there are now not to be synched anymore
79
-			$alreadyDeleted = $this->GetDeletedFolders();
80
-			$folderIdsOnClient = [];
81
-			foreach ($this->ExportFolders(true) as $sid => $folder) {
82
-				// we are only looking at additional folders
83
-				if (isset($folder->NoBackendFolder)) {
84
-					// look if this folder is still in the list of additional folders and was not already deleted (e.g. missing permissions)
85
-					if (!array_key_exists($sid, $state) && !array_key_exists($sid, $alreadyDeleted)) {
86
-						SLog::Write(LOGLEVEL_INFO, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' is not to be synched anymore. Sending delete to mobile.", $folder->displayname));
87
-						$this->ImportFolderDeletion($folder);
88
-					}
89
-				}
90
-				else {
91
-					$folderIdsOnClient[] = $sid;
92
-				}
93
-			}
94
-
95
-			// check permissions on impersonated folders
96
-			if ($this->impersonating) {
97
-				SLog::Write(LOGLEVEL_DEBUG, "ChangesMemoryWrapper->Config(): check permissions of folders of impersonated account");
98
-				$hierarchy = GSync::GetBackend()->GetHierarchy();
99
-				foreach ($hierarchy as $folder) {
100
-					// Check for at least read permissions of the impersonater on folders
101
-					$hasRights = GSync::GetBackend()->Setup($this->impersonating, true, $folder->BackendId, true);
102
-
103
-					// the folder has no permissions
104
-					if (!$hasRights) {
105
-						$this->foldersWithoutPermissions[$folder->serverid] = $folder;
106
-						// if it's on the device, remove it
107
-						if (in_array($folder->serverid, $folderIdsOnClient)) {
108
-							SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' has no permissions anymore. Sending delete to mobile.", $folder->displayname));
109
-							// delete folder into memory so it's then sent to the client
110
-							$this->ImportFolderDeletion($folder);
111
-						}
112
-					}
113
-					// has permissions but is not on the device, add it
114
-					elseif (!in_array($folder->serverid, $folderIdsOnClient)) {
115
-						$folder->flags = SYNC_NEWMESSAGE;
116
-						$this->ImportFolderChange($folder);
117
-					}
118
-				}
119
-			}
120
-		}
121
-
122
-		return true;
123
-	}
124
-
125
-	/**
126
-	 * Implement interfaces which are never used.
127
-	 */
128
-	public function GetState() {
129
-		return false;
130
-	}
131
-
132
-	public function LoadConflicts($contentparameters, $state) {
133
-		return true;
134
-	}
135
-
136
-	public function ConfigContentParameters($contentparameters) {
137
-		return true;
138
-	}
139
-
140
-	public function ImportMessageReadFlag($id, $flags, $categories = []) {
141
-		return true;
142
-	}
143
-
144
-	public function ImportMessageMove($id, $newfolder) {
145
-		return true;
146
-	}
147
-
148
-	/*----------------------------------------------------------------------------------------------------------
11
+    public const CHANGE = 1;
12
+    public const DELETION = 2;
13
+    public const SOFTDELETION = 3;
14
+    public const SYNCHRONIZING = 4;
15
+
16
+    private $changes;
17
+    private $step;
18
+    private $destinationImporter;
19
+    private $exportImporter;
20
+    private $impersonating;
21
+    private $foldersWithoutPermissions;
22
+
23
+    /**
24
+     * Constructor.
25
+     *
26
+     * @return
27
+     */
28
+    public function __construct() {
29
+        $this->changes = [];
30
+        $this->step = 0;
31
+        $this->impersonating = null;
32
+        $this->foldersWithoutPermissions = [];
33
+        parent::__construct();
34
+    }
35
+
36
+    /**
37
+     * Only used to load additional folder sync information for hierarchy changes.
38
+     *
39
+     * @param array $state current state of additional hierarchy folders
40
+     * @param mixed $flags
41
+     *
42
+     * @return bool
43
+     */
44
+    public function Config($state, $flags = 0) {
45
+        if ($this->impersonating == null) {
46
+            $this->impersonating = (Request::GetImpersonatedUser()) ? strtolower(Request::GetImpersonatedUser()) : false;
47
+        }
48
+
49
+        // we should never forward this changes to a backend
50
+        if (!isset($this->destinationImporter)) {
51
+            foreach ($state as $addKey => $addFolder) {
52
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : process folder '%s'", $addFolder->displayname));
53
+                if (isset($addFolder->NoBackendFolder) && $addFolder->NoBackendFolder == true) {
54
+                    // check rights for readonly access only
55
+                    $hasRights = GSync::GetBackend()->Setup($addFolder->Store, true, $addFolder->BackendId, true);
56
+                    // delete the folder on the device
57
+                    if (!$hasRights) {
58
+                        // delete the folder only if it was an additional folder before, else ignore it
59
+                        $synchedfolder = $this->GetFolder($addFolder->serverid);
60
+                        if (isset($synchedfolder->NoBackendFolder) && $synchedfolder->NoBackendFolder == true) {
61
+                            $this->ImportFolderDeletion($addFolder);
62
+                        }
63
+
64
+                        continue;
65
+                    }
66
+                }
67
+                // make sure, if the folder is already in cache, to set the TypeReal flag (if available)
68
+                $cacheFolder = $this->GetFolder($addFolder->serverid);
69
+                if (isset($cacheFolder->TypeReal)) {
70
+                    $addFolder->TypeReal = $cacheFolder->TypeReal;
71
+                    SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(): Set REAL foldertype for folder '%s' from cache: '%s'", $addFolder->displayname, $addFolder->TypeReal));
72
+                }
73
+
74
+                // add folder to the device - if folder is already on the device, nothing will happen
75
+                $this->ImportFolderChange($addFolder);
76
+            }
77
+
78
+            // look for folders which are currently on the device if there are now not to be synched anymore
79
+            $alreadyDeleted = $this->GetDeletedFolders();
80
+            $folderIdsOnClient = [];
81
+            foreach ($this->ExportFolders(true) as $sid => $folder) {
82
+                // we are only looking at additional folders
83
+                if (isset($folder->NoBackendFolder)) {
84
+                    // look if this folder is still in the list of additional folders and was not already deleted (e.g. missing permissions)
85
+                    if (!array_key_exists($sid, $state) && !array_key_exists($sid, $alreadyDeleted)) {
86
+                        SLog::Write(LOGLEVEL_INFO, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' is not to be synched anymore. Sending delete to mobile.", $folder->displayname));
87
+                        $this->ImportFolderDeletion($folder);
88
+                    }
89
+                }
90
+                else {
91
+                    $folderIdsOnClient[] = $sid;
92
+                }
93
+            }
94
+
95
+            // check permissions on impersonated folders
96
+            if ($this->impersonating) {
97
+                SLog::Write(LOGLEVEL_DEBUG, "ChangesMemoryWrapper->Config(): check permissions of folders of impersonated account");
98
+                $hierarchy = GSync::GetBackend()->GetHierarchy();
99
+                foreach ($hierarchy as $folder) {
100
+                    // Check for at least read permissions of the impersonater on folders
101
+                    $hasRights = GSync::GetBackend()->Setup($this->impersonating, true, $folder->BackendId, true);
102
+
103
+                    // the folder has no permissions
104
+                    if (!$hasRights) {
105
+                        $this->foldersWithoutPermissions[$folder->serverid] = $folder;
106
+                        // if it's on the device, remove it
107
+                        if (in_array($folder->serverid, $folderIdsOnClient)) {
108
+                            SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' has no permissions anymore. Sending delete to mobile.", $folder->displayname));
109
+                            // delete folder into memory so it's then sent to the client
110
+                            $this->ImportFolderDeletion($folder);
111
+                        }
112
+                    }
113
+                    // has permissions but is not on the device, add it
114
+                    elseif (!in_array($folder->serverid, $folderIdsOnClient)) {
115
+                        $folder->flags = SYNC_NEWMESSAGE;
116
+                        $this->ImportFolderChange($folder);
117
+                    }
118
+                }
119
+            }
120
+        }
121
+
122
+        return true;
123
+    }
124
+
125
+    /**
126
+     * Implement interfaces which are never used.
127
+     */
128
+    public function GetState() {
129
+        return false;
130
+    }
131
+
132
+    public function LoadConflicts($contentparameters, $state) {
133
+        return true;
134
+    }
135
+
136
+    public function ConfigContentParameters($contentparameters) {
137
+        return true;
138
+    }
139
+
140
+    public function ImportMessageReadFlag($id, $flags, $categories = []) {
141
+        return true;
142
+    }
143
+
144
+    public function ImportMessageMove($id, $newfolder) {
145
+        return true;
146
+    }
147
+
148
+    /*----------------------------------------------------------------------------------------------------------
149 149
 	 * IImportChanges & destination importer
150 150
 	 */
151 151
 
152
-	/**
153
-	 * Sets an importer where incoming changes should be sent to.
154
-	 *
155
-	 * @param IImportChanges $importer message to be changed
156
-	 *
157
-	 * @return bool
158
-	 */
159
-	public function SetDestinationImporter(&$importer) {
160
-		$this->destinationImporter = $importer;
161
-
162
-		return true;
163
-	}
164
-
165
-	/**
166
-	 * Imports a message change, which is imported into memory.
167
-	 *
168
-	 * @param string     $id      id of message which is changed
169
-	 * @param SyncObject $message message to be changed
170
-	 *
171
-	 * @return bool
172
-	 */
173
-	public function ImportMessageChange($id, $message) {
174
-		$this->changes[] = [self::CHANGE, $id];
175
-
176
-		return true;
177
-	}
178
-
179
-	/**
180
-	 * Imports a message deletion, which is imported into memory.
181
-	 *
182
-	 * @param string $id           id of message which is deleted
183
-	 * @param bool   $asSoftDelete (opt) if true, the deletion is exported as "SoftDelete", else as "Remove" - default: false
184
-	 *
185
-	 * @return bool
186
-	 */
187
-	public function ImportMessageDeletion($id, $asSoftDelete = false) {
188
-		if ($asSoftDelete === true) {
189
-			$this->changes[] = [self::SOFTDELETION, $id];
190
-		}
191
-		else {
192
-			$this->changes[] = [self::DELETION, $id];
193
-		}
194
-
195
-		return true;
196
-	}
197
-
198
-	/**
199
-	 * Checks if a message id is flagged as changed.
200
-	 *
201
-	 * @param string $id message id
202
-	 *
203
-	 * @return bool
204
-	 */
205
-	public function IsChanged($id) {
206
-		return (array_search([self::CHANGE, $id], $this->changes) === false) ? false : true;
207
-	}
208
-
209
-	/**
210
-	 * Checks if a message id is flagged as deleted.
211
-	 *
212
-	 * @param string $id message id
213
-	 *
214
-	 * @return bool
215
-	 */
216
-	public function IsDeleted($id) {
217
-		return !((array_search([self::DELETION, $id], $this->changes) === false) && (array_search([self::SOFTDELETION, $id], $this->changes) === false));
218
-	}
219
-
220
-	/**
221
-	 * Imports a folder change.
222
-	 *
223
-	 * @param SyncFolder $folder folder to be changed
224
-	 *
225
-	 * @return boolean/SyncObject           status/object with the ath least the serverid of the folder set
226
-	 */
227
-	public function ImportFolderChange($folder) {
228
-		// if the destinationImporter is set, then this folder should be processed by another importer
229
-		// instead of being loaded in memory.
230
-		if (isset($this->destinationImporter)) {
231
-			// normally the $folder->type is not set, but we need this value to check if the change operation is permitted
232
-			// e.g. system folders can normally not be changed - set the type from cache and let the destinationImporter decide
233
-			if (!isset($folder->type) || !$folder->type) {
234
-				$cacheFolder = $this->GetFolder($folder->serverid);
235
-				$folder->type = $cacheFolder->type;
236
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set foldertype for folder '%s' from cache as it was not sent: '%s'", $folder->displayname, $folder->type));
237
-				if (isset($cacheFolder->TypeReal)) {
238
-					$folder->TypeReal = $cacheFolder->TypeReal;
239
-					SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set REAL foldertype for folder '%s' from cache: '%s'", $folder->displayname, $folder->TypeReal));
240
-				}
241
-			}
242
-
243
-			$retFolder = $this->destinationImporter->ImportFolderChange($folder);
244
-
245
-			// if the operation was successful, update the HierarchyCache
246
-			if ($retFolder) {
247
-				// if we get a folder back, we need to update some data in the cache
248
-				if (isset($retFolder->serverid) && $retFolder->serverid) {
249
-					// for folder creation, the serverid & backendid are not set and have to be updated
250
-					if (!isset($folder->serverid) || $folder->serverid == "") {
251
-						$folder->serverid = $retFolder->serverid;
252
-						if (isset($retFolder->BackendId) && $retFolder->BackendId) {
253
-							$folder->BackendId = $retFolder->BackendId;
254
-						}
255
-					}
256
-
257
-					// if the parentid changed (folder was moved) this needs to be updated as well
258
-					if ($retFolder->parentid != $folder->parentid) {
259
-						$folder->parentid = $retFolder->parentid;
260
-					}
261
-				}
262
-
263
-				$this->AddFolder($folder);
264
-			}
265
-
266
-			return $retFolder;
267
-		}
268
-		// load into memory
269
-
270
-		if (isset($folder->serverid)) {
271
-			// The grommunio HierarchyExporter exports all kinds of changes for folders (e.g. update no. of unread messages in a folder).
272
-			// These changes are not relevant for the mobiles, as something changes but the relevant displayname and parentid
273
-			// stay the same. These changes will be dropped and are not sent!
274
-			if ($folder->equals($this->GetFolder($folder->serverid), false, true)) {
275
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as modification is not relevant.", $folder->displayname));
276
-
277
-				return false;
278
-			}
279
-
280
-			// check if the parent ID is known on the device
281
-			if (!isset($folder->parentid) || ($folder->parentid != "0" && !$this->GetFolder($folder->parentid))) {
282
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as parent folder is not set or not known on mobile.", $folder->displayname));
283
-
284
-				return false;
285
-			}
286
-
287
-			// folder changes are only sent if the user has permissions on that folder, if not, change is ignored
288
-			if ($this->impersonating && array_key_exists($folder->serverid, $this->foldersWithoutPermissions)) {
289
-				SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as impersonating user has no permissions on folder.", $folder->displayname));
290
-
291
-				return false;
292
-			}
293
-
294
-			// load this change into memory
295
-			$this->changes[] = [self::CHANGE, $folder];
296
-
297
-			// HierarchyCache: already add/update the folder so changes are not sent twice (if exported twice)
298
-			$this->AddFolder($folder);
299
-
300
-			return true;
301
-		}
302
-
303
-		return false;
304
-	}
305
-
306
-	/**
307
-	 * Imports a folder deletion.
308
-	 *
309
-	 * @param SyncFolder $folder at least "serverid" needs to be set
310
-	 *
311
-	 * @return bool
312
-	 */
313
-	public function ImportFolderDeletion($folder) {
314
-		$id = $folder->serverid;
315
-
316
-		// if the forwarder is set, then this folder should be processed by another importer
317
-		// instead of being loaded in mem.
318
-		if (isset($this->destinationImporter)) {
319
-			$ret = $this->destinationImporter->ImportFolderDeletion($folder);
320
-
321
-			// if the operation was successful, update the HierarchyCache
322
-			if ($ret) {
323
-				$this->DelFolder($id);
324
-			}
325
-
326
-			return $ret;
327
-		}
328
-
329
-		// if this folder is not in the cache, the change does not need to be streamed to the mobile
330
-		if ($this->GetFolder($id)) {
331
-			// load this change into memory
332
-			$this->changes[] = [self::DELETION, $folder];
333
-
334
-			// HierarchyCache: delete the folder so changes are not sent twice (if exported twice)
335
-			$this->DelFolder($id);
336
-
337
-			return true;
338
-		}
339
-	}
340
-
341
-	/*----------------------------------------------------------------------------------------------------------
152
+    /**
153
+     * Sets an importer where incoming changes should be sent to.
154
+     *
155
+     * @param IImportChanges $importer message to be changed
156
+     *
157
+     * @return bool
158
+     */
159
+    public function SetDestinationImporter(&$importer) {
160
+        $this->destinationImporter = $importer;
161
+
162
+        return true;
163
+    }
164
+
165
+    /**
166
+     * Imports a message change, which is imported into memory.
167
+     *
168
+     * @param string     $id      id of message which is changed
169
+     * @param SyncObject $message message to be changed
170
+     *
171
+     * @return bool
172
+     */
173
+    public function ImportMessageChange($id, $message) {
174
+        $this->changes[] = [self::CHANGE, $id];
175
+
176
+        return true;
177
+    }
178
+
179
+    /**
180
+     * Imports a message deletion, which is imported into memory.
181
+     *
182
+     * @param string $id           id of message which is deleted
183
+     * @param bool   $asSoftDelete (opt) if true, the deletion is exported as "SoftDelete", else as "Remove" - default: false
184
+     *
185
+     * @return bool
186
+     */
187
+    public function ImportMessageDeletion($id, $asSoftDelete = false) {
188
+        if ($asSoftDelete === true) {
189
+            $this->changes[] = [self::SOFTDELETION, $id];
190
+        }
191
+        else {
192
+            $this->changes[] = [self::DELETION, $id];
193
+        }
194
+
195
+        return true;
196
+    }
197
+
198
+    /**
199
+     * Checks if a message id is flagged as changed.
200
+     *
201
+     * @param string $id message id
202
+     *
203
+     * @return bool
204
+     */
205
+    public function IsChanged($id) {
206
+        return (array_search([self::CHANGE, $id], $this->changes) === false) ? false : true;
207
+    }
208
+
209
+    /**
210
+     * Checks if a message id is flagged as deleted.
211
+     *
212
+     * @param string $id message id
213
+     *
214
+     * @return bool
215
+     */
216
+    public function IsDeleted($id) {
217
+        return !((array_search([self::DELETION, $id], $this->changes) === false) && (array_search([self::SOFTDELETION, $id], $this->changes) === false));
218
+    }
219
+
220
+    /**
221
+     * Imports a folder change.
222
+     *
223
+     * @param SyncFolder $folder folder to be changed
224
+     *
225
+     * @return boolean/SyncObject           status/object with the ath least the serverid of the folder set
226
+     */
227
+    public function ImportFolderChange($folder) {
228
+        // if the destinationImporter is set, then this folder should be processed by another importer
229
+        // instead of being loaded in memory.
230
+        if (isset($this->destinationImporter)) {
231
+            // normally the $folder->type is not set, but we need this value to check if the change operation is permitted
232
+            // e.g. system folders can normally not be changed - set the type from cache and let the destinationImporter decide
233
+            if (!isset($folder->type) || !$folder->type) {
234
+                $cacheFolder = $this->GetFolder($folder->serverid);
235
+                $folder->type = $cacheFolder->type;
236
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set foldertype for folder '%s' from cache as it was not sent: '%s'", $folder->displayname, $folder->type));
237
+                if (isset($cacheFolder->TypeReal)) {
238
+                    $folder->TypeReal = $cacheFolder->TypeReal;
239
+                    SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Set REAL foldertype for folder '%s' from cache: '%s'", $folder->displayname, $folder->TypeReal));
240
+                }
241
+            }
242
+
243
+            $retFolder = $this->destinationImporter->ImportFolderChange($folder);
244
+
245
+            // if the operation was successful, update the HierarchyCache
246
+            if ($retFolder) {
247
+                // if we get a folder back, we need to update some data in the cache
248
+                if (isset($retFolder->serverid) && $retFolder->serverid) {
249
+                    // for folder creation, the serverid & backendid are not set and have to be updated
250
+                    if (!isset($folder->serverid) || $folder->serverid == "") {
251
+                        $folder->serverid = $retFolder->serverid;
252
+                        if (isset($retFolder->BackendId) && $retFolder->BackendId) {
253
+                            $folder->BackendId = $retFolder->BackendId;
254
+                        }
255
+                    }
256
+
257
+                    // if the parentid changed (folder was moved) this needs to be updated as well
258
+                    if ($retFolder->parentid != $folder->parentid) {
259
+                        $folder->parentid = $retFolder->parentid;
260
+                    }
261
+                }
262
+
263
+                $this->AddFolder($folder);
264
+            }
265
+
266
+            return $retFolder;
267
+        }
268
+        // load into memory
269
+
270
+        if (isset($folder->serverid)) {
271
+            // The grommunio HierarchyExporter exports all kinds of changes for folders (e.g. update no. of unread messages in a folder).
272
+            // These changes are not relevant for the mobiles, as something changes but the relevant displayname and parentid
273
+            // stay the same. These changes will be dropped and are not sent!
274
+            if ($folder->equals($this->GetFolder($folder->serverid), false, true)) {
275
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as modification is not relevant.", $folder->displayname));
276
+
277
+                return false;
278
+            }
279
+
280
+            // check if the parent ID is known on the device
281
+            if (!isset($folder->parentid) || ($folder->parentid != "0" && !$this->GetFolder($folder->parentid))) {
282
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as parent folder is not set or not known on mobile.", $folder->displayname));
283
+
284
+                return false;
285
+            }
286
+
287
+            // folder changes are only sent if the user has permissions on that folder, if not, change is ignored
288
+            if ($this->impersonating && array_key_exists($folder->serverid, $this->foldersWithoutPermissions)) {
289
+                SLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as impersonating user has no permissions on folder.", $folder->displayname));
290
+
291
+                return false;
292
+            }
293
+
294
+            // load this change into memory
295
+            $this->changes[] = [self::CHANGE, $folder];
296
+
297
+            // HierarchyCache: already add/update the folder so changes are not sent twice (if exported twice)
298
+            $this->AddFolder($folder);
299
+
300
+            return true;
301
+        }
302
+
303
+        return false;
304
+    }
305
+
306
+    /**
307
+     * Imports a folder deletion.
308
+     *
309
+     * @param SyncFolder $folder at least "serverid" needs to be set
310
+     *
311
+     * @return bool
312
+     */
313
+    public function ImportFolderDeletion($folder) {
314
+        $id = $folder->serverid;
315
+
316
+        // if the forwarder is set, then this folder should be processed by another importer
317
+        // instead of being loaded in mem.
318
+        if (isset($this->destinationImporter)) {
319
+            $ret = $this->destinationImporter->ImportFolderDeletion($folder);
320
+
321
+            // if the operation was successful, update the HierarchyCache
322
+            if ($ret) {
323
+                $this->DelFolder($id);
324
+            }
325
+
326
+            return $ret;
327
+        }
328
+
329
+        // if this folder is not in the cache, the change does not need to be streamed to the mobile
330
+        if ($this->GetFolder($id)) {
331
+            // load this change into memory
332
+            $this->changes[] = [self::DELETION, $folder];
333
+
334
+            // HierarchyCache: delete the folder so changes are not sent twice (if exported twice)
335
+            $this->DelFolder($id);
336
+
337
+            return true;
338
+        }
339
+    }
340
+
341
+    /*----------------------------------------------------------------------------------------------------------
342 342
 	 * IExportChanges & destination importer
343 343
 	 */
344 344
 
345
-	/**
346
-	 * Initializes the Exporter where changes are synchronized to.
347
-	 *
348
-	 * @param IImportChanges $importer
349
-	 *
350
-	 * @return bool
351
-	 */
352
-	public function InitializeExporter(&$importer) {
353
-		$this->exportImporter = $importer;
354
-		$this->step = 0;
355
-
356
-		return true;
357
-	}
358
-
359
-	/**
360
-	 * Returns the amount of changes to be exported.
361
-	 *
362
-	 * @return int
363
-	 */
364
-	public function GetChangeCount() {
365
-		return count($this->changes);
366
-	}
367
-
368
-	/**
369
-	 * Synchronizes a change. Only HierarchyChanges will be Synchronized().
370
-	 *
371
-	 * @return array
372
-	 */
373
-	public function Synchronize() {
374
-		if ($this->step < count($this->changes) && isset($this->exportImporter)) {
375
-			$change = $this->changes[$this->step];
376
-
377
-			if ($change[0] == self::CHANGE) {
378
-				if (!$this->GetFolder($change[1]->serverid, true)) {
379
-					$change[1]->flags = SYNC_NEWMESSAGE;
380
-				}
381
-
382
-				$this->exportImporter->ImportFolderChange($change[1]);
383
-			}
384
-			// deletion
385
-			else {
386
-				$this->exportImporter->ImportFolderDeletion($change[1]);
387
-			}
388
-			++$this->step;
389
-
390
-			// return progress array
391
-			return ["steps" => count($this->changes), "progress" => $this->step];
392
-		}
393
-
394
-		return false;
395
-	}
396
-
397
-	/**
398
-	 * Initializes a few instance variables
399
-	 * called after unserialization.
400
-	 *
401
-	 * @return array
402
-	 */
403
-	public function __wakeup() {
404
-		$this->changes = [];
405
-		$this->step = 0;
406
-		$this->foldersWithoutPermissions = [];
407
-	}
408
-
409
-	/**
410
-	 * Removes internal data from the object, so this data can not be exposed.
411
-	 *
412
-	 * @return bool
413
-	 */
414
-	public function StripData() {
415
-		unset($this->changes, $this->step, $this->destinationImporter, $this->exportImporter);
416
-
417
-		return parent::StripData();
418
-	}
345
+    /**
346
+     * Initializes the Exporter where changes are synchronized to.
347
+     *
348
+     * @param IImportChanges $importer
349
+     *
350
+     * @return bool
351
+     */
352
+    public function InitializeExporter(&$importer) {
353
+        $this->exportImporter = $importer;
354
+        $this->step = 0;
355
+
356
+        return true;
357
+    }
358
+
359
+    /**
360
+     * Returns the amount of changes to be exported.
361
+     *
362
+     * @return int
363
+     */
364
+    public function GetChangeCount() {
365
+        return count($this->changes);
366
+    }
367
+
368
+    /**
369
+     * Synchronizes a change. Only HierarchyChanges will be Synchronized().
370
+     *
371
+     * @return array
372
+     */
373
+    public function Synchronize() {
374
+        if ($this->step < count($this->changes) && isset($this->exportImporter)) {
375
+            $change = $this->changes[$this->step];
376
+
377
+            if ($change[0] == self::CHANGE) {
378
+                if (!$this->GetFolder($change[1]->serverid, true)) {
379
+                    $change[1]->flags = SYNC_NEWMESSAGE;
380
+                }
381
+
382
+                $this->exportImporter->ImportFolderChange($change[1]);
383
+            }
384
+            // deletion
385
+            else {
386
+                $this->exportImporter->ImportFolderDeletion($change[1]);
387
+            }
388
+            ++$this->step;
389
+
390
+            // return progress array
391
+            return ["steps" => count($this->changes), "progress" => $this->step];
392
+        }
393
+
394
+        return false;
395
+    }
396
+
397
+    /**
398
+     * Initializes a few instance variables
399
+     * called after unserialization.
400
+     *
401
+     * @return array
402
+     */
403
+    public function __wakeup() {
404
+        $this->changes = [];
405
+        $this->step = 0;
406
+        $this->foldersWithoutPermissions = [];
407
+    }
408
+
409
+    /**
410
+     * Removes internal data from the object, so this data can not be exposed.
411
+     *
412
+     * @return bool
413
+     */
414
+    public function StripData() {
415
+        unset($this->changes, $this->step, $this->destinationImporter, $this->exportImporter);
416
+
417
+        return parent::StripData();
418
+    }
419 419
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -4 removed lines patch added patch discarded remove patch
@@ -86,8 +86,7 @@  discard block
 block discarded – undo
86 86
 						SLog::Write(LOGLEVEL_INFO, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' is not to be synched anymore. Sending delete to mobile.", $folder->displayname));
87 87
 						$this->ImportFolderDeletion($folder);
88 88
 					}
89
-				}
90
-				else {
89
+				} else {
91 90
 					$folderIdsOnClient[] = $sid;
92 91
 				}
93 92
 			}
@@ -187,8 +186,7 @@  discard block
 block discarded – undo
187 186
 	public function ImportMessageDeletion($id, $asSoftDelete = false) {
188 187
 		if ($asSoftDelete === true) {
189 188
 			$this->changes[] = [self::SOFTDELETION, $id];
190
-		}
191
-		else {
189
+		} else {
192 190
 			$this->changes[] = [self::DELETION, $id];
193 191
 		}
194 192
 
Please login to merge, or discard this patch.
lib/core/interprocessdata.php 3 patches
Indentation   +259 added lines, -259 removed lines patch added patch discarded remove patch
@@ -9,293 +9,293 @@
 block discarded – undo
9 9
  */
10 10
 
11 11
 abstract class InterProcessData {
12
-	public const CLEANUPTIME = 1;
12
+    public const CLEANUPTIME = 1;
13 13
 
14
-	protected static $devid;
15
-	protected static $pid;
16
-	protected static $user;
17
-	protected static $start;
18
-	protected $type;
19
-	protected $allocate;
14
+    protected static $devid;
15
+    protected static $pid;
16
+    protected static $user;
17
+    protected static $start;
18
+    protected $type;
19
+    protected $allocate;
20 20
 
21
-	/**
22
-	 * @var IIpcProvider
23
-	 */
24
-	private $ipcProvider;
21
+    /**
22
+     * @var IIpcProvider
23
+     */
24
+    private $ipcProvider;
25 25
 
26
-	/**
27
-	 * Constructor.
28
-	 */
29
-	public function __construct() {
30
-		if (!isset($this->type) || !isset($this->allocate)) {
31
-			throw new FatalNotImplementedException(sprintf("Class InterProcessData can not be initialized. Subclass %s did not initialize type and allocable memory.", get_class($this)));
32
-		}
26
+    /**
27
+     * Constructor.
28
+     */
29
+    public function __construct() {
30
+        if (!isset($this->type) || !isset($this->allocate)) {
31
+            throw new FatalNotImplementedException(sprintf("Class InterProcessData can not be initialized. Subclass %s did not initialize type and allocable memory.", get_class($this)));
32
+        }
33 33
 
34
-		try {
35
-			// ZP-987: use an own mutex + storage key for each device on non-shared-memory IPC
36
-			// this method is not suitable for the TopCollector atm
37
-			$type = Request::GetDeviceID();
38
-			$this->ipcProvider = GSync::GetRedis();
39
-		}
40
-		catch (Exception $e) {
41
-			// ipcProvider could not initialise
42
-			SLog::Write(LOGLEVEL_ERROR, sprintf("%s could not initialise IPC Redis provider: %s", get_class($this), $e->getMessage()));
43
-		}
44
-	}
34
+        try {
35
+            // ZP-987: use an own mutex + storage key for each device on non-shared-memory IPC
36
+            // this method is not suitable for the TopCollector atm
37
+            $type = Request::GetDeviceID();
38
+            $this->ipcProvider = GSync::GetRedis();
39
+        }
40
+        catch (Exception $e) {
41
+            // ipcProvider could not initialise
42
+            SLog::Write(LOGLEVEL_ERROR, sprintf("%s could not initialise IPC Redis provider: %s", get_class($this), $e->getMessage()));
43
+        }
44
+    }
45 45
 
46
-	/**
47
-	 * Initializes internal parameters.
48
-	 *
49
-	 * @return bool
50
-	 */
51
-	protected function initializeParams() {
52
-		if (!isset(self::$devid)) {
53
-			self::$devid = Request::GetDeviceID();
54
-			self::$pid = @getmypid();
55
-			self::$user = Request::GetAuthUserString(); // we want to see everything here
56
-			self::$start = time();
57
-			if (!self::$devid) {
58
-				self::$devid = "none";
59
-			}
60
-		}
46
+    /**
47
+     * Initializes internal parameters.
48
+     *
49
+     * @return bool
50
+     */
51
+    protected function initializeParams() {
52
+        if (!isset(self::$devid)) {
53
+            self::$devid = Request::GetDeviceID();
54
+            self::$pid = @getmypid();
55
+            self::$user = Request::GetAuthUserString(); // we want to see everything here
56
+            self::$start = time();
57
+            if (!self::$devid) {
58
+                self::$devid = "none";
59
+            }
60
+        }
61 61
 
62
-		return true;
63
-	}
62
+        return true;
63
+    }
64 64
 
65
-	/**
66
-	 * Returns the underlying redis connection object.
67
-	 *
68
-	 * @return RedisConnection
69
-	 */
70
-	protected function getRedis() {
71
-		return $this->ipcProvider;
72
-	}
65
+    /**
66
+     * Returns the underlying redis connection object.
67
+     *
68
+     * @return RedisConnection
69
+     */
70
+    protected function getRedis() {
71
+        return $this->ipcProvider;
72
+    }
73 73
 
74
-	/**
75
-	 * Reinitializes the IPC data by removing, detaching and re-allocating it.
76
-	 *
77
-	 * @return bool
78
-	 */
79
-	public function ReInitIPC() {
80
-		// TODO: do we need this?
81
-		return false;
82
-	}
74
+    /**
75
+     * Reinitializes the IPC data by removing, detaching and re-allocating it.
76
+     *
77
+     * @return bool
78
+     */
79
+    public function ReInitIPC() {
80
+        // TODO: do we need this?
81
+        return false;
82
+    }
83 83
 
84
-	/**
85
-	 * Cleans up the IPC data block.
86
-	 *
87
-	 * @return bool
88
-	 */
89
-	public function Clean() {
90
-		// TODO: do we need this?
91
-		return false;
92
-	}
84
+    /**
85
+     * Cleans up the IPC data block.
86
+     *
87
+     * @return bool
88
+     */
89
+    public function Clean() {
90
+        // TODO: do we need this?
91
+        return false;
92
+    }
93 93
 
94
-	/**
95
-	 * Indicates if the IPC is active.
96
-	 *
97
-	 * @return bool
98
-	 */
99
-	public function IsActive() {
100
-		return true;
101
-	}
94
+    /**
95
+     * Indicates if the IPC is active.
96
+     *
97
+     * @return bool
98
+     */
99
+    public function IsActive() {
100
+        return true;
101
+    }
102 102
 
103
-	/**
104
-	 * Blocks the class mutex.
105
-	 * Method blocks until mutex is available!
106
-	 * ATTENTION: make sure that you *always* release a blocked mutex!
107
-	 *
108
-	 * @return bool
109
-	 */
110
-	protected function blockMutex() {
111
-		return true;
112
-	}
103
+    /**
104
+     * Blocks the class mutex.
105
+     * Method blocks until mutex is available!
106
+     * ATTENTION: make sure that you *always* release a blocked mutex!
107
+     *
108
+     * @return bool
109
+     */
110
+    protected function blockMutex() {
111
+        return true;
112
+    }
113 113
 
114
-	/**
115
-	 * Releases the class mutex.
116
-	 * After the release other processes are able to block the mutex themselves.
117
-	 *
118
-	 * @return bool
119
-	 */
120
-	protected function releaseMutex() {
121
-		return true;
122
-	}
114
+    /**
115
+     * Releases the class mutex.
116
+     * After the release other processes are able to block the mutex themselves.
117
+     *
118
+     * @return bool
119
+     */
120
+    protected function releaseMutex() {
121
+        return true;
122
+    }
123 123
 
124
-	/**
125
-	 * Indicates if the requested variable is available in IPC data.
126
-	 *
127
-	 * @param int $id int indicating the variable
128
-	 *
129
-	 * @return bool
130
-	 */
131
-	protected function hasData($id = 2) {
132
-		return $this->ipcProvider ? $this->ipcProvider->get()->exists($id) : false;
133
-	}
124
+    /**
125
+     * Indicates if the requested variable is available in IPC data.
126
+     *
127
+     * @param int $id int indicating the variable
128
+     *
129
+     * @return bool
130
+     */
131
+    protected function hasData($id = 2) {
132
+        return $this->ipcProvider ? $this->ipcProvider->get()->exists($id) : false;
133
+    }
134 134
 
135
-	/**
136
-	 * Returns the requested variable from IPC data.
137
-	 *
138
-	 * @param int $id int indicating the variable
139
-	 *
140
-	 * @return mixed
141
-	 */
142
-	protected function getData($id = 2) {
143
-		return $this->ipcProvider ? json_decode($this->ipcProvider->getKey($id), true) : null;
144
-	}
135
+    /**
136
+     * Returns the requested variable from IPC data.
137
+     *
138
+     * @param int $id int indicating the variable
139
+     *
140
+     * @return mixed
141
+     */
142
+    protected function getData($id = 2) {
143
+        return $this->ipcProvider ? json_decode($this->ipcProvider->getKey($id), true) : null;
144
+    }
145 145
 
146
-	/**
147
-	 * Writes the transmitted variable to IPC data.
148
-	 * Subclasses may never use an id < 2!
149
-	 *
150
-	 * @param mixed $data data which should be saved into IPC data
151
-	 * @param int   $id   int indicating the variable (bigger than 2!)
152
-	 * @param mixed $ttl
153
-	 *
154
-	 * @return bool
155
-	 */
156
-	protected function setData($data, $id = 2, $ttl = -1) {
157
-		return $this->ipcProvider ? $this->ipcProvider->setKey($id, json_encode($data), $ttl) : false;
158
-	}
146
+    /**
147
+     * Writes the transmitted variable to IPC data.
148
+     * Subclasses may never use an id < 2!
149
+     *
150
+     * @param mixed $data data which should be saved into IPC data
151
+     * @param int   $id   int indicating the variable (bigger than 2!)
152
+     * @param mixed $ttl
153
+     *
154
+     * @return bool
155
+     */
156
+    protected function setData($data, $id = 2, $ttl = -1) {
157
+        return $this->ipcProvider ? $this->ipcProvider->setKey($id, json_encode($data), $ttl) : false;
158
+    }
159 159
 
160
-	protected function setDeviceUserData($key, $data, $devid, $user, $subkey = -1, $doCas = false, $rawdata = false) {
161
-		$compKey = $this->getComposedKey($devid, $user, $subkey);
160
+    protected function setDeviceUserData($key, $data, $devid, $user, $subkey = -1, $doCas = false, $rawdata = false) {
161
+        $compKey = $this->getComposedKey($devid, $user, $subkey);
162 162
 
163
-		// overwrite
164
-		if (!$doCas) {
165
-			$ok = ($this->ipcProvider->get()->hset($key, $compKey, json_encode($data)) !== false);
166
-		}
167
-		// merge data and do CAS on the $compKey
168
-		elseif ($doCas == "merge") {
169
-			$ok = false;
170
-			$okCount = 0;
171
-			// TODO: make this configurable (retrycount)?
172
-			while (!$ok && $okCount < 5) {
173
-				$newData = $data;
174
-				// step 1:  get current data
175
-				$_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
176
-				// step 2:  if data exists, merge it with the new data. Keys within
177
-				//          within the new data overwrite possible existing old data (update).
178
-				if ($_rawdata && $_rawdata !== null) {
179
-					$_old = json_decode($_rawdata, true);
180
-					$newData = array_merge($_old, $data);
181
-				}
182
-				// step 3:  replace old with new data
183
-				$ok = $this->ipcProvider->CASHash($key, $compKey, $_rawdata, json_encode($newData));
184
-				if (!$ok) {
185
-					++$okCount;
186
-					// retry in 0.1s
187
-					// TODO: make this configurable?
188
-					usleep(1000000);
189
-				}
190
-			}
191
-		}
192
-		// replace data and do CAS on the $compKey - fail hard if CAS fails
193
-		elseif ($doCas == "replace") {
194
-			if (!$rawdata) {
195
-				$ok = ($this->ipcProvider->get()->hset($key, $compKey, json_encode($data)) !== false);
196
-			}
197
-			else {
198
-				$ok = $this->ipcProvider->CASHash($key, $compKey, $rawdata, json_encode($data));
199
-			}
200
-		}
201
-		// delete keys of data and do CAS on the $compKey
202
-		elseif ($doCas == "deletekeys") {
203
-			$ok = false;
204
-			$okCount = 0;
205
-			// TODO: make this configurable (retrycount)?
206
-			while (!$ok && $okCount < 5) {
207
-				// step 1:  get current data
208
-				$_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
209
-				$newData = json_decode($_rawdata, true);
210
-				# no data to delete from, done
211
-				if (!is_array($newData) || count($newData) == 0) {
212
-					break;
213
-				}
214
-				// step 2:  if data exists, delete the keys of $data from it
215
-				foreach ($data as $delKey) {
216
-					unset($newData[$delKey]);
217
-				}
218
-				$rawNewData = json_encode($newData);
219
-				// step 3:  check if the data actually changed (not the correctest way to compare these, but still valid for our data)
220
-				if ($_rawdata == $rawNewData) {
221
-					break;
222
-				}
223
-				// step 4:  replace old with new data
224
-				$ok = $this->ipcProvider->CASHash($key, $compKey, $_rawdata, $rawNewData);
225
-				if (!$ok) {
226
-					++$okCount;
227
-					// TODO: make this configurable?
228
-					// retry in 0.1s
229
-					usleep(100000);
230
-					SLog::Write(LOG_DEBUG, "InterProcessData: setDeviceUserData CAS failed, retrying...");
231
-				}
232
-			}
233
-		}
163
+        // overwrite
164
+        if (!$doCas) {
165
+            $ok = ($this->ipcProvider->get()->hset($key, $compKey, json_encode($data)) !== false);
166
+        }
167
+        // merge data and do CAS on the $compKey
168
+        elseif ($doCas == "merge") {
169
+            $ok = false;
170
+            $okCount = 0;
171
+            // TODO: make this configurable (retrycount)?
172
+            while (!$ok && $okCount < 5) {
173
+                $newData = $data;
174
+                // step 1:  get current data
175
+                $_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
176
+                // step 2:  if data exists, merge it with the new data. Keys within
177
+                //          within the new data overwrite possible existing old data (update).
178
+                if ($_rawdata && $_rawdata !== null) {
179
+                    $_old = json_decode($_rawdata, true);
180
+                    $newData = array_merge($_old, $data);
181
+                }
182
+                // step 3:  replace old with new data
183
+                $ok = $this->ipcProvider->CASHash($key, $compKey, $_rawdata, json_encode($newData));
184
+                if (!$ok) {
185
+                    ++$okCount;
186
+                    // retry in 0.1s
187
+                    // TODO: make this configurable?
188
+                    usleep(1000000);
189
+                }
190
+            }
191
+        }
192
+        // replace data and do CAS on the $compKey - fail hard if CAS fails
193
+        elseif ($doCas == "replace") {
194
+            if (!$rawdata) {
195
+                $ok = ($this->ipcProvider->get()->hset($key, $compKey, json_encode($data)) !== false);
196
+            }
197
+            else {
198
+                $ok = $this->ipcProvider->CASHash($key, $compKey, $rawdata, json_encode($data));
199
+            }
200
+        }
201
+        // delete keys of data and do CAS on the $compKey
202
+        elseif ($doCas == "deletekeys") {
203
+            $ok = false;
204
+            $okCount = 0;
205
+            // TODO: make this configurable (retrycount)?
206
+            while (!$ok && $okCount < 5) {
207
+                // step 1:  get current data
208
+                $_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
209
+                $newData = json_decode($_rawdata, true);
210
+                # no data to delete from, done
211
+                if (!is_array($newData) || count($newData) == 0) {
212
+                    break;
213
+                }
214
+                // step 2:  if data exists, delete the keys of $data from it
215
+                foreach ($data as $delKey) {
216
+                    unset($newData[$delKey]);
217
+                }
218
+                $rawNewData = json_encode($newData);
219
+                // step 3:  check if the data actually changed (not the correctest way to compare these, but still valid for our data)
220
+                if ($_rawdata == $rawNewData) {
221
+                    break;
222
+                }
223
+                // step 4:  replace old with new data
224
+                $ok = $this->ipcProvider->CASHash($key, $compKey, $_rawdata, $rawNewData);
225
+                if (!$ok) {
226
+                    ++$okCount;
227
+                    // TODO: make this configurable?
228
+                    // retry in 0.1s
229
+                    usleep(100000);
230
+                    SLog::Write(LOG_DEBUG, "InterProcessData: setDeviceUserData CAS failed, retrying...");
231
+                }
232
+            }
233
+        }
234 234
 
235
-		return $ok;
236
-	}
235
+        return $ok;
236
+    }
237 237
 
238
-	protected function getDeviceUserData($key, $devid, $user, $subkey = -1, $returnRaw = false) {
239
-		$compKey = $this->getComposedKey($devid, $user, $subkey);
240
-		$_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
241
-		if ($returnRaw) {
242
-			if ($_rawdata) {
243
-				return [json_decode($_rawdata, true), $_rawdata];
244
-			}
238
+    protected function getDeviceUserData($key, $devid, $user, $subkey = -1, $returnRaw = false) {
239
+        $compKey = $this->getComposedKey($devid, $user, $subkey);
240
+        $_rawdata = $this->ipcProvider->get()->hget($key, $compKey);
241
+        if ($returnRaw) {
242
+            if ($_rawdata) {
243
+                return [json_decode($_rawdata, true), $_rawdata];
244
+            }
245 245
 
246
-			return [[], false];
247
-		}
246
+            return [[], false];
247
+        }
248 248
 
249
-		if ($_rawdata) {
250
-			return json_decode($_rawdata, true);
251
-		}
249
+        if ($_rawdata) {
250
+            return json_decode($_rawdata, true);
251
+        }
252 252
 
253
-		return [];
254
-	}
253
+        return [];
254
+    }
255 255
 
256
-	protected function delDeviceUserData($key, $devid, $user, $subkey = -1) {
257
-		$compKey = $this->getComposedKey($devid, $user, $subkey);
256
+    protected function delDeviceUserData($key, $devid, $user, $subkey = -1) {
257
+        $compKey = $this->getComposedKey($devid, $user, $subkey);
258 258
 
259
-		return $this->ipcProvider->get()->hdel($key, $compKey);
260
-	}
259
+        return $this->ipcProvider->get()->hdel($key, $compKey);
260
+    }
261 261
 
262
-	protected function getAllDeviceUserData($key) {
263
-		$_data = [];
264
-		$raw = $this->ipcProvider->get()->hGetAll($key);
265
-		foreach ($raw as $compKey => $status) {
266
-			$_linedata = json_decode($status, true);
267
-			list($devid, $user, $subkey) = explode("|-|", $compKey);
268
-			if (!isset($_data[$devid])) {
269
-				$_data[$devid] = [];
270
-			}
271
-			if (!$subkey) {
272
-				$_data[$devid][$user] = $_data;
273
-			}
274
-			else {
275
-				if (!isset($_data[$devid][$user])) {
276
-					$_data[$devid][$user] = [];
277
-				}
278
-				$_data[$devid][$user][$subkey] = $_linedata;
279
-			}
280
-		}
262
+    protected function getAllDeviceUserData($key) {
263
+        $_data = [];
264
+        $raw = $this->ipcProvider->get()->hGetAll($key);
265
+        foreach ($raw as $compKey => $status) {
266
+            $_linedata = json_decode($status, true);
267
+            list($devid, $user, $subkey) = explode("|-|", $compKey);
268
+            if (!isset($_data[$devid])) {
269
+                $_data[$devid] = [];
270
+            }
271
+            if (!$subkey) {
272
+                $_data[$devid][$user] = $_data;
273
+            }
274
+            else {
275
+                if (!isset($_data[$devid][$user])) {
276
+                    $_data[$devid][$user] = [];
277
+                }
278
+                $_data[$devid][$user][$subkey] = $_linedata;
279
+            }
280
+        }
281 281
 
282
-		return $_data;
283
-	}
282
+        return $_data;
283
+    }
284 284
 
285
-	protected function getRawDeviceUserData($key) {
286
-		return $this->ipcProvider->get()->hGetAll($key);
287
-	}
285
+    protected function getRawDeviceUserData($key) {
286
+        return $this->ipcProvider->get()->hGetAll($key);
287
+    }
288 288
 
289
-	protected function getComposedKey($key1, $key2, $key3 = -1) {
290
-		$_k = $key1;
291
-		if ($key2 > -1) {
292
-			$_k .= "|-|" . $key2;
293
-		}
289
+    protected function getComposedKey($key1, $key2, $key3 = -1) {
290
+        $_k = $key1;
291
+        if ($key2 > -1) {
292
+            $_k .= "|-|" . $key2;
293
+        }
294 294
 
295
-		if ($key3 > -1) {
296
-			$_k .= "|-|" . $key3;
297
-		}
295
+        if ($key3 > -1) {
296
+            $_k .= "|-|" . $key3;
297
+        }
298 298
 
299
-		return $_k;
300
-	}
299
+        return $_k;
300
+    }
301 301
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -289,11 +289,11 @@
 block discarded – undo
289 289
 	protected function getComposedKey($key1, $key2, $key3 = -1) {
290 290
 		$_k = $key1;
291 291
 		if ($key2 > -1) {
292
-			$_k .= "|-|" . $key2;
292
+			$_k .= "|-|".$key2;
293 293
 		}
294 294
 
295 295
 		if ($key3 > -1) {
296
-			$_k .= "|-|" . $key3;
296
+			$_k .= "|-|".$key3;
297 297
 		}
298 298
 
299 299
 		return $_k;
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -36,8 +36,7 @@  discard block
 block discarded – undo
36 36
 			// this method is not suitable for the TopCollector atm
37 37
 			$type = Request::GetDeviceID();
38 38
 			$this->ipcProvider = GSync::GetRedis();
39
-		}
40
-		catch (Exception $e) {
39
+		} catch (Exception $e) {
41 40
 			// ipcProvider could not initialise
42 41
 			SLog::Write(LOGLEVEL_ERROR, sprintf("%s could not initialise IPC Redis provider: %s", get_class($this), $e->getMessage()));
43 42
 		}
@@ -193,8 +192,7 @@  discard block
 block discarded – undo
193 192
 		elseif ($doCas == "replace") {
194 193
 			if (!$rawdata) {
195 194
 				$ok = ($this->ipcProvider->get()->hset($key, $compKey, json_encode($data)) !== false);
196
-			}
197
-			else {
195
+			} else {
198 196
 				$ok = $this->ipcProvider->CASHash($key, $compKey, $rawdata, json_encode($data));
199 197
 			}
200 198
 		}
@@ -270,8 +268,7 @@  discard block
 block discarded – undo
270 268
 			}
271 269
 			if (!$subkey) {
272 270
 				$_data[$devid][$user] = $_data;
273
-			}
274
-			else {
271
+			} else {
275 272
 				if (!isset($_data[$devid][$user])) {
276 273
 					$_data[$devid][$user] = [];
277 274
 				}
Please login to merge, or discard this patch.