SMBNotifyHandler.php 4.1 KB

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