Passed
Push — master ( 5cdc85...37718d )
by Morris
38:53 queued 21:57
created

SMBNotifyHandler::mapChange()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 18
nc 6
nop 1
dl 0
loc 24
rs 9.0444
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Robin Appelman <[email protected]>
4
 *
5
 * @author Robin Appelman <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Files_External\Lib\Notify;
25
26
use OC\Files\Notify\Change;
27
use OC\Files\Notify\RenameChange;
28
use OCP\Files\Notify\IChange;
29
use OCP\Files\Notify\INotifyHandler;
30
31
class SMBNotifyHandler implements INotifyHandler {
32
	/**
33
	 * @var \Icewind\SMB\INotifyHandler
34
	 */
35
	private $shareNotifyHandler;
36
37
	/**
38
	 * @var string
39
	 */
40
	private $root;
41
42
	private $oldRenamePath = null;
43
44
	/**
45
	 * SMBNotifyHandler constructor.
46
	 *
47
	 * @param \Icewind\SMB\INotifyHandler $shareNotifyHandler
48
	 * @param string $root
49
	 */
50
	public function __construct(\Icewind\SMB\INotifyHandler $shareNotifyHandler, $root) {
51
		$this->shareNotifyHandler = $shareNotifyHandler;
52
		$this->root = $root;
53
	}
54
55
	private function relativePath($fullPath) {
56
		if ($fullPath === $this->root) {
57
			return '';
58
		} else if (substr($fullPath, 0, strlen($this->root)) === $this->root) {
59
			return substr($fullPath, strlen($this->root));
60
		} else {
61
			return null;
62
		}
63
	}
64
65
	public function listen(callable $callback) {
66
		$oldRenamePath = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $oldRenamePath is dead and can be removed.
Loading history...
67
		$this->shareNotifyHandler->listen(function (\Icewind\SMB\Change $shareChange) use ($callback) {
68
			$change = $this->mapChange($shareChange);
69
			if (!is_null($change)) {
70
				return $callback($change);
71
			} else {
72
				return true;
73
			}
74
		});
75
	}
76
77
	/**
78
	 * Get all changes detected since the start of the notify process or the last call to getChanges
79
	 *
80
	 * @return IChange[]
81
	 */
82
	public function getChanges() {
83
		$shareChanges = $this->shareNotifyHandler->getChanges();
84
		$changes = [];
85
		foreach ($shareChanges as $shareChange) {
86
			$change = $this->mapChange($shareChange);
87
			if ($change) {
88
				$changes[] = $change;
89
			}
90
		}
91
		return $changes;
92
	}
93
94
	/**
95
	 * Stop listening for changes
96
	 *
97
	 * Note that any pending changes will be discarded
98
	 */
99
	public function stop() {
100
		$this->shareNotifyHandler->stop();
101
	}
102
103
	/**
104
	 * @param \Icewind\SMB\Change $change
105
	 * @return IChange|null
106
	 */
107
	private function mapChange(\Icewind\SMB\Change $change) {
108
		$path = $this->relativePath($change->getPath());
109
		if (is_null($path)) {
110
			return null;
111
		}
112
		if ($change->getCode() === \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_OLD) {
113
			$this->oldRenamePath = $path;
114
			return null;
115
		}
116
		$type = $this->mapNotifyType($change->getCode());
117
		if (is_null($type)) {
118
			return null;
119
		}
120
		if ($type === IChange::RENAMED) {
121
			if (!is_null($this->oldRenamePath)) {
122
				$result = new RenameChange($type, $this->oldRenamePath, $path);
123
				$this->oldRenamePath = null;
124
			} else {
125
				$result = null;
126
			}
127
		} else {
128
			$result = new Change($type, $path);
129
		}
130
		return $result;
131
	}
132
133
	private function mapNotifyType($smbType) {
134
		switch ($smbType) {
135
			case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED:
136
				return IChange::ADDED;
137
			case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED:
138
				return IChange::REMOVED;
139
			case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED:
140
			case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED_STREAM:
141
			case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED_STREAM:
142
			case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED_STREAM:
143
				return IChange::MODIFIED;
144
			case \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_NEW:
145
				return IChange::RENAMED;
146
			default:
147
				return null;
148
		}
149
	}
150
}
151