You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

etagpropagator.php 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * @author Morris Jobke <hey@morrisjobke.de>
  4. * @author Robin Appelman <icewind@owncloud.com>
  5. * @author Vincent Petry <pvince81@owncloud.com>
  6. *
  7. * @copyright Copyright (c) 2015, ownCloud, Inc.
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  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, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OCA\Files_External;
  24. use OC\Files\Filesystem;
  25. /**
  26. * Updates the etag of parent folders whenever a new external storage mount
  27. * point has been created or deleted. Updates need to be triggered using
  28. * the updateHook() method.
  29. *
  30. * There are two modes of operation:
  31. * - for personal mount points, the etag is propagated directly
  32. * - for system mount points, a dirty flag is saved in the configuration and
  33. * the etag will be updated the next time propagateDirtyMountPoints() is called
  34. */
  35. class EtagPropagator {
  36. /**
  37. * @var \OCP\IUser
  38. */
  39. protected $user;
  40. /**
  41. * @var \OC\Files\Cache\ChangePropagator
  42. */
  43. protected $changePropagator;
  44. /**
  45. * @var \OCP\IConfig
  46. */
  47. protected $config;
  48. /**
  49. * @param \OCP\IUser $user current user, must match the propagator's
  50. * user
  51. * @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator
  52. * initialized with a view for $user
  53. * @param \OCP\IConfig $config
  54. */
  55. public function __construct($user, $changePropagator, $config) {
  56. $this->user = $user;
  57. $this->changePropagator = $changePropagator;
  58. $this->config = $config;
  59. }
  60. /**
  61. * Propagate the etag changes for all mountpoints marked as dirty and mark the mountpoints as clean
  62. *
  63. * @param int $time
  64. */
  65. public function propagateDirtyMountPoints($time = null) {
  66. if ($time === null) {
  67. $time = time();
  68. }
  69. $mountPoints = $this->getDirtyMountPoints();
  70. foreach ($mountPoints as $mountPoint) {
  71. $this->changePropagator->addChange($mountPoint);
  72. $this->config->setUserValue($this->user->getUID(), 'files_external', $mountPoint, $time);
  73. }
  74. if (count($mountPoints)) {
  75. $this->changePropagator->propagateChanges($time);
  76. }
  77. }
  78. /**
  79. * Get all mountpoints we need to update the etag for
  80. *
  81. * @return string[]
  82. */
  83. protected function getDirtyMountPoints() {
  84. $dirty = array();
  85. $mountPoints = $this->config->getAppKeys('files_external');
  86. foreach ($mountPoints as $mountPoint) {
  87. if (substr($mountPoint, 0, 1) === '/') {
  88. $updateTime = $this->config->getAppValue('files_external', $mountPoint);
  89. $userTime = $this->config->getUserValue($this->user->getUID(), 'files_external', $mountPoint);
  90. if ($updateTime > $userTime) {
  91. $dirty[] = $mountPoint;
  92. }
  93. }
  94. }
  95. return $dirty;
  96. }
  97. /**
  98. * @param string $mountPoint
  99. * @param int $time
  100. */
  101. protected function markDirty($mountPoint, $time = null) {
  102. if ($time === null) {
  103. $time = time();
  104. }
  105. $this->config->setAppValue('files_external', $mountPoint, $time);
  106. }
  107. /**
  108. * Update etags for mount points for known user
  109. * For global or group mount points, updating the etag for every user is not feasible
  110. * instead we mark the mount point as dirty and update the etag when the filesystem is loaded for the user
  111. * For personal mount points, the change is propagated directly
  112. *
  113. * @param array $params hook parameters
  114. * @param int $time update time to use when marking a mount point as dirty
  115. */
  116. public function updateHook($params, $time = null) {
  117. if ($time === null) {
  118. $time = time();
  119. }
  120. $users = $params[Filesystem::signal_param_users];
  121. $type = $params[Filesystem::signal_param_mount_type];
  122. $mountPoint = $params[Filesystem::signal_param_path];
  123. $mountPoint = Filesystem::normalizePath($mountPoint);
  124. if ($type === \OC_Mount_Config::MOUNT_TYPE_GROUP or $users === 'all') {
  125. $this->markDirty($mountPoint, $time);
  126. } else {
  127. $this->changePropagator->addChange($mountPoint);
  128. $this->changePropagator->propagateChanges($time);
  129. }
  130. }
  131. }