. */ namespace OC\Files\Cache; class Shared_Updater { // shares which can be removed from oc_share after the delete operation was successful static private $toRemove = array(); /** * Correct the parent folders' ETags for all users shared the file at $target * * @param string $target */ static public function correctFolders($target) { $uid = \OCP\User::getUser(); $uidOwner = \OC\Files\Filesystem::getOwner($target); $info = \OC\Files\Filesystem::getFileInfo($target); $checkedUser = array($uidOwner); // Correct Shared folders of other users shared with $users = \OCP\Share::getUsersItemShared('file', $info['fileid'], $uidOwner, true); if (!empty($users)) { while (!empty($users)) { $reshareUsers = array(); foreach ($users as $user) { if ( !in_array($user, $checkedUser) ) { $etag = \OC\Files\Filesystem::getETag(''); \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); // Look for reshares $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true)); $checkedUser[] = $user; } } $users = $reshareUsers; } } } /** * @brief remove all shares for a given file if the file was deleted * * @param string $path */ private static function removeShare($path) { $fileSource = self::$toRemove[$path]; if (!\OC\Files\Filesystem::file_exists($path)) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `file_source`=?'); try { \OC_DB::executeAudited($query, array($fileSource)); } catch (\Exception $e) { \OCP\Util::writeLog('files_sharing', "can't remove share: " . $e->getMessage(), \OCP\Util::WARN); } } unset(self::$toRemove[$path]); } /** * @param array $params */ static public function writeHook($params) { self::correctFolders($params['path']); } /** * @param array $params */ static public function renameHook($params) { self::correctFolders($params['newpath']); self::correctFolders(pathinfo($params['oldpath'], PATHINFO_DIRNAME)); } /** * @param array $params */ static public function deleteHook($params) { self::correctFolders($params['path']); $fileInfo = \OC\Files\Filesystem::getFileInfo($params['path']); // mark file as deleted so that we can clean up the share table if // the file was deleted successfully self::$toRemove[$params['path']] = $fileInfo['fileid']; } /** * @param array $params */ static public function postDeleteHook($params) { self::removeShare($params['path']); } /** * @param array $params */ static public function shareHook($params) { if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { if (isset($params['uidOwner'])) { $uidOwner = $params['uidOwner']; } else { $uidOwner = \OCP\User::getUser(); } $users = \OCP\Share::getUsersItemShared($params['itemType'], $params['fileSource'], $uidOwner, true, false); if (!empty($users)) { while (!empty($users)) { $reshareUsers = array(); foreach ($users as $user) { if ($user !== $uidOwner) { $etag = \OC\Files\Filesystem::getETag(''); \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); // Look for reshares $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $params['fileSource'], $user, true)); } } $users = $reshareUsers; } } } } /** * clean up oc_share table from files which are no longer exists * * This fixes issues from updates from files_sharing < 0.3.5.6 (ownCloud 4.5) * It will just be called during the update of the app */ static public function fixBrokenSharesOnAppUpdate() { // delete all shares where the original file no longer exists $findShares = \OC_DB::prepare('SELECT `*PREFIX*share`.`id` ' . 'FROM `*PREFIX*share` LEFT JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ' . 'WHERE `*PREFIX*filecache`.`fileid` IS NULL AND `*PREFIX*share`.`item_type` IN (\'file\', \'folder\')'); $sharesFound = $findShares->execute(array())->fetchAll(); // delete those shares from the oc_share table if (is_array($sharesFound) && !empty($sharesFound)) { $removeShares = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` = ? '); foreach ($sharesFound as $share) { $result = $removeShares->execute(array($share['id'])); } } } }