blob: deaf005e2c670c86193cdf33458968f63a556d56 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
<?php
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Files_External\Lib\Notify;
use OC\Files\Notify\Change;
use OC\Files\Notify\RenameChange;
use OCP\Files\Notify\IChange;
use OCP\Files\Notify\INotifyHandler;
class SMBNotifyHandler implements INotifyHandler {
/**
* @var string
*/
private $root;
private $oldRenamePath = null;
/**
* SMBNotifyHandler constructor.
*
* @param \Icewind\SMB\INotifyHandler $shareNotifyHandler
* @param string $root
*/
public function __construct(
private \Icewind\SMB\INotifyHandler $shareNotifyHandler,
$root,
) {
$this->root = str_replace('\\', '/', $root);
}
private function relativePath($fullPath) {
if ($fullPath === $this->root) {
return '';
} elseif (substr($fullPath, 0, strlen($this->root)) === $this->root) {
return substr($fullPath, strlen($this->root));
} else {
return null;
}
}
public function listen(callable $callback) {
$oldRenamePath = null;
$this->shareNotifyHandler->listen(function (\Icewind\SMB\Change $shareChange) use ($callback) {
$change = $this->mapChange($shareChange);
if (!is_null($change)) {
return $callback($change);
} else {
return true;
}
});
}
/**
* Get all changes detected since the start of the notify process or the last call to getChanges
*
* @return IChange[]
*/
public function getChanges() {
$shareChanges = $this->shareNotifyHandler->getChanges();
$changes = [];
foreach ($shareChanges as $shareChange) {
$change = $this->mapChange($shareChange);
if ($change) {
$changes[] = $change;
}
}
return $changes;
}
/**
* Stop listening for changes
*
* Note that any pending changes will be discarded
*/
public function stop() {
$this->shareNotifyHandler->stop();
}
/**
* @param \Icewind\SMB\Change $change
* @return IChange|null
*/
private function mapChange(\Icewind\SMB\Change $change) {
$path = $this->relativePath($change->getPath());
if (is_null($path)) {
return null;
}
if ($change->getCode() === \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_OLD) {
$this->oldRenamePath = $path;
return null;
}
$type = $this->mapNotifyType($change->getCode());
if (is_null($type)) {
return null;
}
if ($type === IChange::RENAMED) {
if (!is_null($this->oldRenamePath)) {
$result = new RenameChange($type, $this->oldRenamePath, $path);
$this->oldRenamePath = null;
} else {
$result = null;
}
} else {
$result = new Change($type, $path);
}
return $result;
}
private function mapNotifyType($smbType) {
switch ($smbType) {
case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED:
return IChange::ADDED;
case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED:
return IChange::REMOVED;
case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED:
case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED_STREAM:
case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED_STREAM:
case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED_STREAM:
return IChange::MODIFIED;
case \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_NEW:
return IChange::RENAMED;
default:
return null;
}
}
}
|