SMBNotifyHandler.php 3.3 KB

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