From 445957a0e2061b8f0b26ea6c859ca72abead3fa5 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 1 Mar 2016 16:59:42 -0500 Subject: [PATCH 001/286] 9.0.0 RC1 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 66f299ef4eba3..0476394327b43 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 0, 15); +$OC_Version = array(9, 0, 0, 16); // The human readable string -$OC_VersionString = '9.0.0 beta 2'; +$OC_VersionString = '9.0.0 RC1'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 8d07cb4d858e3ef86568a2075d257c9384c49428 Mon Sep 17 00:00:00 2001 From: RealRancor Date: Wed, 2 Mar 2016 12:51:04 +0100 Subject: [PATCH 002/286] Add Versions app header to config.sample.php --- config/config.sample.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/config.sample.php b/config/config.sample.php index 1a6c8b31280f8..4321e5bab83e7 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -413,6 +413,12 @@ 'trashbin_retention_obligation' => 'auto', +/** + * File versions + * + * These parameters control the Versions app. + */ + /** * If the versions app is enabled (default), this setting defines the policy * for when versions will be permanently deleted. From 98f79173ed01e8fa2a25fbb0ab3a01523a3c15e1 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 2 Mar 2016 20:37:13 +0100 Subject: [PATCH 003/286] Keep "encryptedVersion" when calling `\OC\Files\View::copy` When calling `\OC\Files\View::copy` we should also keep the version to ensure that the file will always have the correct version attached and can be successfully decrypted. To test this the following steps are necessary (from https://github.com/owncloud/core/issues/22781#issuecomment-191328982): 1. setup a new ownCloud 9.0 beta2 2. enable encryption 2. upload a docx (5.7MB large) 3. upload the same file again and overwrite the existing file 4. I can download the original file and the first version 5. I restore the first version 6. restored version can no longer be downloaded with the error described above The manual cache operation in `\OCA\Files_Versions\Storage` is unfortunately necessary since `\OCA\Files_Versions\Storage::copyFileContents` is not using `\OCP\Files\Storage::moveFromStorage` in the case when an object storage is used. Due to the workaround added in https://github.com/owncloud/core/commit/54cea05271b887f1c8062c034741df869bc0f055 the stream is directly copied and thus bypassing the FS. --- apps/files_versions/lib/storage.php | 22 ++++++----- .../files/storage/wrapper/encryption.php | 37 ++++++++++++++----- .../lib/files/storage/wrapper/encryption.php | 27 +++++++++++--- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php index b4111d88e3027..a213ea75238d1 100644 --- a/apps/files_versions/lib/storage.php +++ b/apps/files_versions/lib/storage.php @@ -191,12 +191,7 @@ public static function store($filename) { $mtime = $users_view->filemtime('files/' . $filename); $users_view->copy('files/' . $filename, 'files_versions/' . $filename . '.v' . $mtime); // call getFileInfo to enforce a file cache entry for the new version - $newFileInfo = $users_view->getFileInfo('files_versions/' . $filename . '.v' . $mtime); - - // Keep the "encrypted" value of the original file - $oldVersion = $files_view->getFileInfo($filename)->getEncryptedVersion(); - $cache = $newFileInfo->getStorage()->getCache(); - $cache->update($newFileInfo->getId(), ['encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion]); + $users_view->getFileInfo('files_versions/' . $filename . '.v' . $mtime); } } @@ -331,15 +326,22 @@ public static function rollback($file, $revision) { //first create a new version $version = 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename); - if ( !$users_view->file_exists($version)) { - + if (!$users_view->file_exists($version)) { $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename)); - $versionCreated = true; } + $fileToRestore = 'files_versions' . $filename . '.v' . $revision; + + // Restore encrypted version of the old file for the newly restored file + // This has to happen manually here since the file is manually copied below + $oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion(); + $newFileInfo = $files_view->getFileInfo($filename); + $cache = $newFileInfo->getStorage()->getCache(); + $cache->update($newFileInfo->getId(), ['encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion]); + // rollback - if (self::copyFileContents($users_view, 'files_versions' . $filename . '.v' . $revision, 'files' . $filename)) { + if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) { $files_view->touch($file, $revision); Storage::scheduleExpire($uid, $file); \OC_Hook::emit('\OCP\Versions', 'rollback', array( diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 7e9ada4174a7d..0b4816174bf0f 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -620,6 +620,32 @@ public function copyFromStorage(Storage $sourceStorage, $sourceInternalPath, $ta return $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, false); } + /** + * Update the encrypted cache version in the database + * + * @param Storage $sourceStorage + * @param string $sourceInternalPath + * @param string $targetInternalPath + * @param bool $isRename + */ + private function updateEncryptedVersion(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename) { + $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0; + $cacheInformation = [ + 'encrypted' => (bool)$isEncrypted, + ]; + if($isEncrypted === 1) { + $cacheInformation['encryptedVersion'] = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion']; + } + + // in case of a rename we need to manipulate the source cache because + // this information will be kept for the new target + if ($isRename) { + $sourceStorage->getCache()->put($sourceInternalPath, $cacheInformation); + } else { + $this->getCache()->put($targetInternalPath, $cacheInformation); + } + } + /** * copy file between two storages * @@ -647,6 +673,7 @@ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $info['size'] ); } + $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename); } return $result; } @@ -689,15 +716,7 @@ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, if ($preserveMtime) { $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath)); } - $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0; - - // in case of a rename we need to manipulate the source cache because - // this information will be kept for the new target - if ($isRename) { - $sourceStorage->getCache()->put($sourceInternalPath, ['encrypted' => $isEncrypted]); - } else { - $this->getCache()->put($targetInternalPath, ['encrypted' => $isEncrypted]); - } + $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename); } else { // delete partially written target file $this->unlink($targetInternalPath); diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index c18e518fe6dd2..b5ec15b12bf51 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -693,11 +693,19 @@ public function testCopyBetweenStorage($encryptionEnabled, $mountPointEncryption $temp = \OC::$server->getTempManager(); return fopen($temp->getTemporaryFile(), $mode); }); - + if($expectedEncrypted) { + $cache = $this->getMock('\OCP\Files\Cache\ICache'); + $cache->expects($this->once()) + ->method('get') + ->with($sourceInternalPath) + ->willReturn(['encryptedVersion' => 12345]); + $storage2->expects($this->once()) + ->method('getCache') + ->willReturn($cache); + } $this->encryptionManager->expects($this->any()) ->method('isEnabled') ->willReturn($encryptionEnabled); - // FIXME can not overwrite the return after definition // $this->mount->expects($this->at(0)) // ->method('getOption') @@ -706,9 +714,16 @@ public function testCopyBetweenStorage($encryptionEnabled, $mountPointEncryption global $mockedMountPointEncryptionEnabled; $mockedMountPointEncryptionEnabled = $mountPointEncryptionEnabled; + $expectedCachePut = [ + 'encrypted' => $expectedEncrypted, + ]; + if($expectedEncrypted === true) { + $expectedCachePut['encryptedVersion'] = 12345; + } + $this->cache->expects($this->once()) ->method('put') - ->with($sourceInternalPath, ['encrypted' => $expectedEncrypted]); + ->with($sourceInternalPath, $expectedCachePut); $this->invokePrivate($this->instance, 'copyBetweenStorage', [$storage2, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename]); @@ -765,10 +780,10 @@ public function testCopyBetweenStorageVersions($sourceInternalPath, $targetInte ->with($sourceStorage, $sourceInternalPath, $targetInternalPath) ->willReturn($copyResult); + $instance->expects($this->any())->method('getCache') + ->willReturn($cache); + if ($copyResult) { - $instance->expects($this->once())->method('getCache') - ->with('', $sourceStorage) - ->willReturn($cache); $cache->expects($this->once())->method('get') ->with($sourceInternalPath) ->willReturn(['encrypted' => $encrypted, 'size' => 42]); From 4186bcbdf2db98430d58cebec94cc86a0475259d Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 3 Mar 2016 13:46:41 +0100 Subject: [PATCH 004/286] Exclude the assets folder from integrity check We should not scan the assets folder as this can contain user specific content. Partially addresses https://github.com/owncloud/core/issues/22803 --- .../iterator/excludefoldersbypathfilteriterator.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php index fc261e4bc5abd..766897e751797 100644 --- a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php +++ b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php @@ -35,8 +35,9 @@ public function __construct(\RecursiveIterator $iterator, $root = '') { $excludedFolders = [ rtrim($root . '/data', '/'), rtrim($root .'/themes', '/'), - rtrim($root.'/config', '/'), - rtrim($root.'/apps', '/'), + rtrim($root . '/config', '/'), + rtrim($root . '/apps', '/'), + rtrim($root . '/assets', '/'), ]; $customDataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', ''); if($customDataDir !== '') { From dd556d77da93b30481d6fdeba0c0d30aa04b2025 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 2 Mar 2016 13:02:43 +0100 Subject: [PATCH 005/286] untangle different user manager instances, fixes #22770 --- apps/user_ldap/lib/proxy.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php index 74e2af45269f7..7002aaadaa550 100644 --- a/apps/user_ldap/lib/proxy.php +++ b/apps/user_ldap/lib/proxy.php @@ -61,7 +61,7 @@ private function addAccess($configPrefix) { static $userMap; static $groupMap; static $db; - static $userManager; + static $coreUserManager; if(is_null($fs)) { $ocConfig = \OC::$server->getConfig(); $fs = new FilesystemHelper(); @@ -70,10 +70,10 @@ private function addAccess($configPrefix) { $db = \OC::$server->getDatabaseConnection(); $userMap = new UserMapping($db); $groupMap = new GroupMapping($db); - $userManager = \OC::$server->getUserManager(); + $coreUserManager = \OC::$server->getUserManager(); } $userManager = - new user\Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, $userManager); + new user\Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, $coreUserManager); $connector = new Connection($this->ldap, $configPrefix); $access = new Access($connector, $this->ldap, $userManager); $access->setUserMapper($userMap); From e155f28f5ec4226c015e311e61fcc21710f091f7 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 3 Mar 2016 18:37:48 +0100 Subject: [PATCH 006/286] Revert "No longer evaluate appinfo/version" --- lib/private/app.php | 11 ++++++++--- lib/private/app/appmanager.php | 3 +++ lib/private/installer.php | 9 +++++++-- lib/public/app.php | 2 +- tests/data/testapp.zip | Bin 689 -> 895 bytes tests/data/testapp2.zip | Bin 2240 -> 2449 bytes 6 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/private/app.php b/lib/private/app.php index 3b8cbba3898af..7917c1c0c0140 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -567,7 +567,7 @@ public static function getAppWebPath($appId) { } /** - * get the last version of the app from appinfo/info.xml + * get the last version of the app, either from appinfo/version or from appinfo/info.xml * * @param string $appId * @return string @@ -587,9 +587,14 @@ public static function getAppVersion($appId) { * @return string */ public static function getAppVersionByPath($path) { + $versionFile = $path . '/appinfo/version'; $infoFile = $path . '/appinfo/info.xml'; - $appData = self::getAppInfo($infoFile, true); - return isset($appData['version']) ? $appData['version'] : ''; + if (is_file($versionFile)) { + return trim(file_get_contents($versionFile)); + } else { + $appData = self::getAppInfo($infoFile, true); + return isset($appData['version']) ? $appData['version'] : ''; + } } diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php index 69e5334774e5b..fba5bb19f610a 100644 --- a/lib/private/app/appmanager.php +++ b/lib/private/app/appmanager.php @@ -299,6 +299,9 @@ public function getAppsNeedingUpgrade($ocVersion) { /** * Returns the app information from "appinfo/info.xml". * + * If no version was present in "appinfo/info.xml", reads it + * from the external "appinfo/version" file instead. + * * @param string $appId app id * * @return array app iinfo diff --git a/lib/private/installer.php b/lib/private/installer.php index 36fda28cd27ae..64f84d58b5423 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -389,11 +389,16 @@ public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped } // check if the ocs version is the same as the version in info.xml/version - $version = trim($info['version']); + $versionFile= $extractDir.'/appinfo/version'; + if(is_file($versionFile)) { + $version = trim(file_get_contents($versionFile)); + }else{ + $version = trim($info['version']); + } if(isset($data['appdata']['version']) && $version<>trim($data['appdata']['version'])) { OC_Helper::rmdirr($extractDir); - throw new \Exception($l->t("App can't be installed because the version in info.xml is not the same as the version reported from the app store")); + throw new \Exception($l->t("App can't be installed because the version in info.xml/version is not the same as the version reported from the app store")); } return $info; diff --git a/lib/public/app.php b/lib/public/app.php index 032116eb43f2b..e25f025d12dfe 100644 --- a/lib/public/app.php +++ b/lib/public/app.php @@ -142,7 +142,7 @@ public static function checkAppEnabled( $app ) { } /** - * Get the last version of the app from appinfo/info.xml + * Get the last version of the app, either from appinfo/version or from appinfo/info.xml * @param string $app * @return string * @since 4.0.0 diff --git a/tests/data/testapp.zip b/tests/data/testapp.zip index c828572827f4ca1016cd5a859196586ee7f90287..e76c0d187248193e90ad487fbd172af065695aa3 100644 GIT binary patch delta 422 zcmdnU`k!sWJ~0LkAmpt*;=+IgBqjz5*JtLXe)L_&EgO3b=Ez9TexoAXIjO( z;jq)r84`}0g&&=Ds#v?`x5LIJ+0@w<({3rr>;7F_WU^T`pR<4YX~~jep&486I6GbN z4Vm&{W0BIG#=M{m=`OCv8`%FEbA2g)FFpAs<3kmDW)bX;1v(f46dESKW0DgK@MdKL R39ta6G9v>+1rReZ006-iT4n$M diff --git a/tests/data/testapp2.zip b/tests/data/testapp2.zip index 1953cc896f84dd3ddc6f1b837c08a9bdba15314e..f46832f7a757b2199f293ab05d16c368f55b3e8e 100644 GIT binary patch delta 455 zcmX>gI8k`A49nh$)?yo_9x*aYFbGVZ$RSxD8o|TxT(Lj+6cB%96k+h~+sJpwfX5~M zlW3@Y!-a*j3y&T-bl?EL%Syp%w^S@Lk3PT76_T{Ox_ld7+j$#PZO>;C=W@$!wlYgS z_|TKVcR*R})X}9ZVOu9XNITTNY1yGH(f%oW3$%VMjjOp_ziMfxEvtXU&U^U@<;xqR zPib?>H~r;wb$Z|0x`BPS_hRW+>v#ja**WTJ^}aVSFfeRo*!+OefpPLG7Lm#J%;Lhv zSBx1LKnhIr&Azh&6)-bwW?`0MWMO0yWuC0SBEiQ46a)i@AC3$RlQ*+FFqtt-{>tvb zRKhUXo{os;*lIx&8j{GZi}S)Y+%@_$CD$!Tn6Ol6Fd=dn4+AZ%w~kYGSE zv2ixju4U&DVPymPgc}IUm>C!#JOBiq Bj{N`t delta 371 zcmbOzd_ZvG2dRyhA2Dw3W>#UG%*pz1BGYaO5oQJk4u)-=ULMT;5kYMX3=C(1Sb|}) zH-}WcZ=WsSAp@S)^s25^>NzHK!v-rPH_+C>-_<%A9ZGF%$Z$tk$d*Pz}Q)q z0X!|sKYwL9H;eDjExDBn7Tir-w&8j$>;+;|XK8e)vs-8{dR@0qesTf3%;bM;e2ff} zdD)#9%_j%2doh*)Ns-A5m^mhIXE$Tq3*~W5UeCxm`39T7 Date: Thu, 3 Mar 2016 14:19:34 +0100 Subject: [PATCH 007/286] allow availability recheck for external storages --- .../files_external/lib/config/configadapter.php | 3 ++- .../files/storage/wrapper/availability.php | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php index 51c2debd72655..f097d55a31662 100644 --- a/apps/files_external/lib/config/configadapter.php +++ b/apps/files_external/lib/config/configadapter.php @@ -23,6 +23,7 @@ namespace OCA\Files_External\Config; +use OC\Files\Storage\Wrapper\Availability; use OCA\Files_external\Migration\StorageMigrator; use OCP\Files\Storage; use OC\Files\Mount\MountPoint; @@ -132,7 +133,7 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) { try { $availability = $impl->getAvailability(); - if (!$availability['available']) { + if (!$availability['available'] && !Availability::shouldRecheck($availability)) { $impl = new FailedStorage(['exception' => null]); } } catch (\Exception $e) { diff --git a/lib/private/files/storage/wrapper/availability.php b/lib/private/files/storage/wrapper/availability.php index 55ddb0d5e8f5c..0ed31ba854a66 100644 --- a/lib/private/files/storage/wrapper/availability.php +++ b/lib/private/files/storage/wrapper/availability.php @@ -29,6 +29,16 @@ class Availability extends Wrapper { const RECHECK_TTL_SEC = 600; // 10 minutes + public static function shouldRecheck($availability) { + if (!$availability['available']) { + // trigger a recheck if TTL reached + if ((time() - $availability['last_checked']) > self::RECHECK_TTL_SEC) { + return true; + } + } + return false; + } + /** * @return bool */ @@ -47,11 +57,8 @@ private function updateAvailability() { */ private function isAvailable() { $availability = $this->getAvailability(); - if (!$availability['available']) { - // trigger a recheck if TTL reached - if ((time() - $availability['last_checked']) > self::RECHECK_TTL_SEC) { - return $this->updateAvailability(); - } + if (self::shouldRecheck($availability)) { + return $this->updateAvailability(); } return $availability['available']; } From 8e8f5cdddf02a77c2f036ee8e9be407279d4fa69 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 2 Mar 2016 12:17:14 +0100 Subject: [PATCH 008/286] Properly set exception in FailedStorage --- apps/files_external/lib/config/configadapter.php | 5 ++++- apps/files_external/lib/failedstorage.php | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php index f097d55a31662..d85e0f4563190 100644 --- a/apps/files_external/lib/config/configadapter.php +++ b/apps/files_external/lib/config/configadapter.php @@ -35,6 +35,7 @@ use OCA\Files_External\Service\UserGlobalStoragesService; use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Lib\FailedStorage; +use OCP\Files\StorageNotAvailableException; /** * Make the old files_external config work with the new public mount config api @@ -134,7 +135,9 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) { try { $availability = $impl->getAvailability(); if (!$availability['available'] && !Availability::shouldRecheck($availability)) { - $impl = new FailedStorage(['exception' => null]); + $impl = new FailedStorage([ + 'exception' => new StorageNotAvailableException('Storage with mount id ' . $storage->getId() . ' is not available') + ]); } } catch (\Exception $e) { // propagate exception into filesystem diff --git a/apps/files_external/lib/failedstorage.php b/apps/files_external/lib/failedstorage.php index 928d09e20f829..20cf43d74b29b 100644 --- a/apps/files_external/lib/failedstorage.php +++ b/apps/files_external/lib/failedstorage.php @@ -39,6 +39,9 @@ class FailedStorage extends Common { */ public function __construct($params) { $this->e = $params['exception']; + if (!$this->e) { + throw new \InvalidArgumentException('Missing "exception" argument in FailedStorage constructor'); + } } public function getId() { From 3673cfae3cb4c2a1bcfc831ff314ca6c03d39e02 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 3 Mar 2016 19:47:35 +0100 Subject: [PATCH 009/286] Rename and move permissions are set when a file is updatable * Fix unit tests --- apps/dav/lib/connector/sabre/node.php | 2 +- apps/dav/tests/unit/connector/sabre/node.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/connector/sabre/node.php b/apps/dav/lib/connector/sabre/node.php index 41dcb42191323..95a5f0a87499c 100644 --- a/apps/dav/lib/connector/sabre/node.php +++ b/apps/dav/lib/connector/sabre/node.php @@ -230,7 +230,7 @@ public function getDavPermissions() { if ($this->info->isDeletable()) { $p .= 'D'; } - if ($this->info->isDeletable()) { + if ($this->info->isUpdateable()) { $p .= 'NV'; // Renameable, Moveable } if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) { diff --git a/apps/dav/tests/unit/connector/sabre/node.php b/apps/dav/tests/unit/connector/sabre/node.php index dfbd95bfad814..8c92c2f063cbb 100644 --- a/apps/dav/tests/unit/connector/sabre/node.php +++ b/apps/dav/tests/unit/connector/sabre/node.php @@ -31,8 +31,8 @@ public function davPermissionsProvider() { array(\OCP\Constants::PERMISSION_ALL, 'file', true, false, 'SRDNVW'), array(\OCP\Constants::PERMISSION_ALL, 'file', true, true, 'SRMDNVW'), array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE, 'file', true, false, 'SDNVW'), - array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_UPDATE, 'file', false, false, 'RDNV'), - array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_DELETE, 'file', false, false, 'RW'), + array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_UPDATE, 'file', false, false, 'RD'), + array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_DELETE, 'file', false, false, 'RNVW'), array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE, 'file', false, false, 'RDNVW'), array(\OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE, 'dir', false, false, 'RDNV'), ); From e6c6ee8d2ace97b301ace4022feb298f380f416d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 4 Mar 2016 10:48:08 +0100 Subject: [PATCH 010/286] Fix download spinner to work with CSS styles A recent change replaced img elements with CSS icons for file actions. This fix adjusts the logic to work properly with CSS icons instead of images. --- apps/files/css/files.css | 13 +++++++++++++ apps/files/js/fileactions.js | 19 +++++++++---------- apps/files/tests/js/fileactionsSpec.js | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index b65af1fa0f376..bfa5340fe0992 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -793,6 +793,19 @@ html.ie8 #controls .button.new { background-size: 16px 16px; } +#filestable .filename .action .icon.hidden, +#filestable .selectedActions a .icon.hidden, +#controls .actions .button .icon.hidden { + display: none; +} + +#filestable .filename .action .icon.loading, +#filestable .selectedActions a .icon.loading, +#controls .actions .button .icon.loading { + width: 15px; + height: 15px; +} + .app-files .actions .button.new .icon { margin-bottom: 2px; } diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 05ff2f0cbfa43..69e32d500c4f6 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -659,19 +659,18 @@ * Replaces the download icon with a loading spinner and vice versa * - also adds the class disabled to the passed in element * - * @param downloadButtonElement download fileaction + * @param {jQuery} $downloadButtonElement download fileaction * @param {boolean} showIt whether to show the spinner(true) or to hide it(false) */ - OCA.Files.FileActions.updateFileActionSpinner = function(downloadButtonElement, showIt) { - var icon = downloadButtonElement.find('img'), - sourceImage = icon.attr('src'); - - if(showIt) { - downloadButtonElement.addClass('disabled'); - icon.attr('src', sourceImage.replace('actions/download.svg', 'loading-small.gif')); + OCA.Files.FileActions.updateFileActionSpinner = function($downloadButtonElement, showIt) { + var $icon = $downloadButtonElement.find('.icon'); + if (showIt) { + var $loadingIcon = $(''); + $icon.after($loadingIcon); + $icon.addClass('hidden'); } else { - downloadButtonElement.removeClass('disabled'); - icon.attr('src', sourceImage.replace('loading-small.gif', 'actions/download.svg')); + $downloadButtonElement.find('.loading').remove(); + $downloadButtonElement.find('.icon').removeClass('hidden'); } }; diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js index 470f2854f43e3..3f46a27d1f920 100644 --- a/apps/files/tests/js/fileactionsSpec.js +++ b/apps/files/tests/js/fileactionsSpec.js @@ -656,4 +656,24 @@ describe('OCA.Files.FileActions tests', function() { }); }); }); + describe('download spinner', function() { + var FileActions = OCA.Files.FileActions; + var $el; + + beforeEach(function() { + $el = $('Download'); + }); + + it('replaces download icon with spinner', function() { + FileActions.updateFileActionSpinner($el, true); + expect($el.find('.icon.loading').length).toEqual(1); + expect($el.find('.icon.icon-download').hasClass('hidden')).toEqual(true); + }); + it('replaces spinner back with download icon with spinner', function() { + FileActions.updateFileActionSpinner($el, true); + FileActions.updateFileActionSpinner($el, false); + expect($el.find('.icon.loading').length).toEqual(0); + expect($el.find('.icon.icon-download').hasClass('hidden')).toEqual(false); + }); + }); }); From 62399f78523b6aa5840f8b1c2330bacc619874d4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 4 Mar 2016 12:06:16 +0100 Subject: [PATCH 011/286] ucwords does not support delimiter on 5.4 --- lib/private/comments/comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/comments/comment.php b/lib/private/comments/comment.php index 31848ed38b6ad..60663d615784b 100644 --- a/lib/private/comments/comment.php +++ b/lib/private/comments/comment.php @@ -362,7 +362,7 @@ public function setObject($objectType, $objectId) { protected function fromArray($data) { foreach(array_keys($data) as $key) { // translate DB keys to internal setter names - $setter = 'set' . str_replace('_', '', ucwords($key,'_')); + $setter = 'set' . implode('', array_map('ucfirst', explode('_', $key))); $setter = str_replace('Timestamp', 'DateTime', $setter); if(method_exists($this, $setter)) { From 7ff2b9232be1523f9a4ddce17b1d22a952ef1bb9 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 4 Mar 2016 13:56:13 +0100 Subject: [PATCH 012/286] Add release channel selection back Allows to select the release channels again and also shows the last check date --- apps/updatenotification/appinfo/app.php | 8 +- .../appinfo/application.php | 12 ++- apps/updatenotification/appinfo/routes.php | 1 + .../controller/admincontroller.php | 58 ++++++++++- apps/updatenotification/js/admin.js | 14 ++- apps/updatenotification/templates/admin.php | 42 +++++++- .../tests/controller/AdminControllerTest.php | 98 ++++++++++++++++++- 7 files changed, 219 insertions(+), 14 deletions(-) diff --git a/apps/updatenotification/appinfo/app.php b/apps/updatenotification/appinfo/app.php index 9148b6e6ef76e..f257cba697439 100644 --- a/apps/updatenotification/appinfo/app.php +++ b/apps/updatenotification/appinfo/app.php @@ -31,9 +31,11 @@ $userObject = \OC::$server->getUserSession()->getUser(); if($userObject !== null) { - if(\OC::$server->getGroupManager()->isAdmin($userObject->getUID()) && $updateChecker->getUpdateState() !== []) { - \OCP\Util::addScript('updatenotification', 'notification'); - OC_Hook::connect('\OCP\Config', 'js', $updateChecker, 'getJavaScript'); + if(\OC::$server->getGroupManager()->isAdmin($userObject->getUID())) { + if($updateChecker->getUpdateState() !== []) { + \OCP\Util::addScript('updatenotification', 'notification'); + OC_Hook::connect('\OCP\Config', 'js', $updateChecker, 'getJavaScript'); + } \OC_App::registerAdmin('updatenotification', 'admin'); } } diff --git a/apps/updatenotification/appinfo/application.php b/apps/updatenotification/appinfo/application.php index ae3317c1b54be..24c0a11af696d 100644 --- a/apps/updatenotification/appinfo/application.php +++ b/apps/updatenotification/appinfo/application.php @@ -22,7 +22,9 @@ namespace OCA\UpdateNotification\AppInfo; use OC\AppFramework\Utility\TimeFactory; +use OC\Updater; use OCA\UpdateNotification\Controller\AdminController; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; @@ -32,13 +34,21 @@ public function __construct (array $urlParams = array()) { $container = $this->getContainer(); $container->registerService('AdminController', function(IAppContainer $c) { + $updater = new \OC\Updater( + \OC::$server->getHTTPHelper(), + \OC::$server->getConfig(), + \OC::$server->getIntegrityCodeChecker() + ); return new AdminController( $c->query('AppName'), $c->query('Request'), $c->getServer()->getJobList(), $c->getServer()->getSecureRandom(), $c->getServer()->getConfig(), - new TimeFactory() + new TimeFactory(), + $c->getServer()->getL10N($c->query('AppName')), + new UpdateChecker($updater), + $c->getServer()->getDateTimeFormatter() ); }); } diff --git a/apps/updatenotification/appinfo/routes.php b/apps/updatenotification/appinfo/routes.php index 2cf43c8976965..9021d381b1bd4 100644 --- a/apps/updatenotification/appinfo/routes.php +++ b/apps/updatenotification/appinfo/routes.php @@ -24,4 +24,5 @@ $application = new Application(); $application->registerRoutes($this, ['routes' => [ ['name' => 'Admin#createCredentials', 'url' => '/credentials', 'verb' => 'GET'], + ['name' => 'Admin#setChannel', 'url' => '/channel', 'verb' => 'POST'], ]]); diff --git a/apps/updatenotification/controller/admincontroller.php b/apps/updatenotification/controller/admincontroller.php index 505ea01edd9b0..cb0c6409d7e3e 100644 --- a/apps/updatenotification/controller/admincontroller.php +++ b/apps/updatenotification/controller/admincontroller.php @@ -21,12 +21,15 @@ namespace OCA\UpdateNotification\Controller; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\IConfig; +use OCP\IDateTimeFormatter; +use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; @@ -39,6 +42,12 @@ class AdminController extends Controller { private $config; /** @var ITimeFactory */ private $timeFactory; + /** @var UpdateChecker */ + private $updateChecker; + /** @var IL10N */ + private $l10n; + /** @var IDateTimeFormatter */ + private $dateTimeFormatter; /** * @param string $appName @@ -47,25 +56,70 @@ class AdminController extends Controller { * @param ISecureRandom $secureRandom * @param IConfig $config * @param ITimeFactory $timeFactory + * @param IL10N $l10n + * @param UpdateChecker $updateChecker + * @param IDateTimeFormatter $dateTimeFormatter */ public function __construct($appName, IRequest $request, IJobList $jobList, ISecureRandom $secureRandom, IConfig $config, - ITimeFactory $timeFactory) { + ITimeFactory $timeFactory, + IL10N $l10n, + UpdateChecker $updateChecker, + IDateTimeFormatter $dateTimeFormatter) { parent::__construct($appName, $request); $this->jobList = $jobList; $this->secureRandom = $secureRandom; $this->config = $config; $this->timeFactory = $timeFactory; + $this->l10n = $l10n; + $this->updateChecker = $updateChecker; + $this->dateTimeFormatter = $dateTimeFormatter; } /** * @return TemplateResponse */ public function displayPanel() { - return new TemplateResponse($this->appName, 'admin', [], ''); + $lastUpdateCheck = $this->dateTimeFormatter->formatDateTime( + $this->config->getAppValue('core', 'lastupdatedat') + ); + + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $params = [ + 'isNewVersionAvailable' => ($this->updateChecker->getUpdateState() === []) ? false : true, + 'lastChecked' => $lastUpdateCheck, + 'currentChannel' => $currentChannel, + 'channels' => $channels, + ]; + + return new TemplateResponse($this->appName, 'admin', $params, ''); + } + + /** + * @UseSession + * + * @param string $channel + * @return DataResponse + */ + public function setChannel($channel) { + \OCP\Util::setChannel($channel); + $this->config->setAppValue('core', 'lastupdatedat', 0); + return new DataResponse(['status' => 'success', 'data' => ['message' => $this->l10n->t('Updated channel')]]); } /** diff --git a/apps/updatenotification/js/admin.js b/apps/updatenotification/js/admin.js index df021fe2e974e..2fc8c9d99b178 100644 --- a/apps/updatenotification/js/admin.js +++ b/apps/updatenotification/js/admin.js @@ -15,7 +15,7 @@ */ var loginToken = ''; $(document).ready(function(){ - $('#oca_updatenotification').click(function() { + $('#oca_updatenotification_button').click(function() { // Load the new token $.ajax({ url: OC.generateUrl('/apps/updatenotification/credentials') @@ -39,4 +39,16 @@ $(document).ready(function(){ }); }); }); + $('#release-channel').change(function() { + var newChannel = $('#release-channel').find(":selected").val(); + $.post( + OC.generateUrl('/apps/updatenotification/channel'), + { + 'channel': newChannel + }, + function(data){ + OC.msg.finishedAction('#channel_save_msg', data); + } + ); + }); }); diff --git a/apps/updatenotification/templates/admin.php b/apps/updatenotification/templates/admin.php index 647c88dea1727..c1adc8d0d3e37 100644 --- a/apps/updatenotification/templates/admin.php +++ b/apps/updatenotification/templates/admin.php @@ -1,8 +1,42 @@ - -
+ +

t('Updater')); ?>

+ + + t('A new version is available: %s', [$newVersionString])); ?> + + + t('Your version is up to date.')); ?> + + +

- t('For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button.')) ?> + + + +

+

+ t('You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel.')); ?>

-
diff --git a/apps/updatenotification/tests/controller/AdminControllerTest.php b/apps/updatenotification/tests/controller/AdminControllerTest.php index 5a0f9d2146930..50adcd2028bcb 100644 --- a/apps/updatenotification/tests/controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/controller/AdminControllerTest.php @@ -22,11 +22,14 @@ namespace OCA\UpdateNotification\Tests\Controller; use OCA\UpdateNotification\Controller\AdminController; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\IConfig; +use OCP\IDateTimeFormatter; +use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; use Test\TestCase; @@ -44,6 +47,12 @@ class AdminControllerTest extends TestCase { private $adminController; /** @var ITimeFactory */ private $timeFactory; + /** @var IL10N */ + private $l10n; + /** @var UpdateChecker */ + private $updateChecker; + /** @var IDateTimeFormatter */ + private $dateTimeFormatter; public function setUp() { parent::setUp(); @@ -53,6 +62,10 @@ public function setUp() { $this->secureRandom = $this->getMock('\\OCP\\Security\\ISecureRandom'); $this->config = $this->getMock('\\OCP\\IConfig'); $this->timeFactory = $this->getMock('\\OCP\\AppFramework\\Utility\\ITimeFactory'); + $this->l10n = $this->getMock('\\OCP\\IL10N'); + $this->updateChecker = $this->getMockBuilder('\\OCA\\UpdateNotification\\UpdateChecker') + ->disableOriginalConstructor()->getMock(); + $this->dateTimeFormatter = $this->getMock('\\OCP\\IDateTimeFormatter'); $this->adminController = new AdminController( 'updatenotification', @@ -60,15 +73,94 @@ public function setUp() { $this->jobList, $this->secureRandom, $this->config, - $this->timeFactory + $this->timeFactory, + $this->l10n, + $this->updateChecker, + $this->dateTimeFormatter ); } - public function testDisplayPanel() { - $expected = new TemplateResponse('updatenotification', 'admin', [], ''); + public function testDisplayPanelWithUpdate() { + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->willReturn('12345'); + $this->dateTimeFormatter + ->expects($this->once()) + ->method('formatDateTime') + ->with('12345') + ->willReturn('LastCheckedReturnValue'); + $this->updateChecker + ->expects($this->once()) + ->method('getUpdateState') + ->willReturn(['foo' => 'bar']); + + $params = [ + 'isNewVersionAvailable' => true, + 'lastChecked' => 'LastCheckedReturnValue', + 'currentChannel' => \OCP\Util::getChannel(), + 'channels' => $channels, + ]; + + $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); + $this->assertEquals($expected, $this->adminController->displayPanel()); + } + + public function testDisplayPanelWithoutUpdate() { + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->willReturn('12345'); + $this->dateTimeFormatter + ->expects($this->once()) + ->method('formatDateTime') + ->with('12345') + ->willReturn('LastCheckedReturnValue'); + $this->updateChecker + ->expects($this->once()) + ->method('getUpdateState') + ->willReturn([]); + + $params = [ + 'isNewVersionAvailable' => false, + 'lastChecked' => 'LastCheckedReturnValue', + 'currentChannel' => \OCP\Util::getChannel(), + 'channels' => $channels, + ]; + + $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); $this->assertEquals($expected, $this->adminController->displayPanel()); } + public function testCreateCredentials() { $this->jobList ->expects($this->once()) From 96d45e90dcab48992d7ab122b8e25f1d31361ea5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 4 Mar 2016 15:27:31 +0100 Subject: [PATCH 013/286] Properly check path validity before deleting to trash This prevents deleting the whole "files" folder of the user whenever $ownerPath is empty. This can happen in concurrency situations. --- apps/files_trashbin/lib/trashbin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index bcd73639d3c5f..46447908b90d4 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -204,7 +204,7 @@ public static function move2trash($file_path) { $ownerView = new View('/' . $owner); // file has been deleted in between - if (!$ownerView->file_exists('/files/' . $ownerPath)) { + if (is_null($ownerPath) || $ownerPath === '' || !$ownerView->file_exists('/files/' . $ownerPath)) { return true; } From eb59aa8be4affac838ebaa70feef8f692810af67 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 4 Mar 2016 17:40:45 +0100 Subject: [PATCH 014/286] Automatically enabled federation app --- apps/federation/appinfo/info.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/federation/appinfo/info.xml b/apps/federation/appinfo/info.xml index be591b5b6934c..d373d5ae23f5f 100644 --- a/apps/federation/appinfo/info.xml +++ b/apps/federation/appinfo/info.xml @@ -11,6 +11,7 @@ + From c9c85b8d4ab532d19a3be0bcb1c8d6910c158581 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 4 Mar 2016 17:59:57 +0100 Subject: [PATCH 015/286] Adjust OCS test --- build/integration/features/provisioning-v1.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature index 04a706f387b92..8c32c04523cbb 100644 --- a/build/integration/features/provisioning-v1.feature +++ b/build/integration/features/provisioning-v1.feature @@ -285,6 +285,7 @@ Feature: provisioning | comments | | dav | | federatedfilesharing | + | federation | | files | | files_sharing | | files_trashbin | From 9737290e3915a5565618e8db6a5decd42c8a794e Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 4 Mar 2016 15:42:35 +0100 Subject: [PATCH 016/286] Run cleanup of expired DB file locks to background job * fixes #22819 The old way fired a DELETE statement on each destruction of the DBLockingProvider. Which could cause a lot of queries. It's enough to run this every 5 minutes in a background job, which in the end could result in file locks that exists 5 minutes longer - in the worst case and for not properly released locks. This makes the DB based locking a lot more performant and could result in a similar performance to the Redis based locking provider. --- apps/files/appinfo/info.xml | 2 +- apps/files/appinfo/install.php | 1 + apps/files/appinfo/update.php | 1 + .../lib/backgroundjob/cleanupfilelocks.php | 57 +++++++++++++++++++ lib/private/lock/dblockingprovider.php | 26 ++++----- 5 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 apps/files/lib/backgroundjob/cleanupfilelocks.php diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml index b31232b799abd..66943170bb0b2 100644 --- a/apps/files/appinfo/info.xml +++ b/apps/files/appinfo/info.xml @@ -6,7 +6,7 @@ AGPL Robin Appelman, Vincent Petry - 1.4.3 + 1.4.4 diff --git a/apps/files/appinfo/install.php b/apps/files/appinfo/install.php index 4d1e59d214cde..55514935cda1d 100644 --- a/apps/files/appinfo/install.php +++ b/apps/files/appinfo/install.php @@ -24,3 +24,4 @@ // Cron job for scanning user storages \OC::$server->getJobList()->add('OCA\Files\BackgroundJob\ScanFiles'); \OC::$server->getJobList()->add('OCA\Files\BackgroundJob\DeleteOrphanedItems'); +\OC::$server->getJobList()->add('OCA\Files\BackgroundJob\CleanupFileLocks'); diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php index e4f8f8f29d7ed..72aff4cd0d4ca 100644 --- a/apps/files/appinfo/update.php +++ b/apps/files/appinfo/update.php @@ -102,3 +102,4 @@ function owncloud_reset_encrypted_flag(\OCP\IDBConnection $conn) { // Add cron job for scanning user storages \OC::$server->getJobList()->add('OCA\Files\BackgroundJob\ScanFiles'); \OC::$server->getJobList()->add('OCA\Files\BackgroundJob\DeleteOrphanedItems'); +\OC::$server->getJobList()->add('OCA\Files\BackgroundJob\CleanupFileLocks'); diff --git a/apps/files/lib/backgroundjob/cleanupfilelocks.php b/apps/files/lib/backgroundjob/cleanupfilelocks.php new file mode 100644 index 0000000000000..b5cf8e945513c --- /dev/null +++ b/apps/files/lib/backgroundjob/cleanupfilelocks.php @@ -0,0 +1,57 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files\BackgroundJob; + +use OC\BackgroundJob\TimedJob; +use OC\Lock\DBLockingProvider; + +/** + * Clean up all file locks that are expired for the DB file locking provider + */ +class CleanupFileLocks extends TimedJob { + + /** + * Default interval in minutes + * + * @var int $defaultIntervalMin + **/ + protected $defaultIntervalMin = 5; + + /** + * sets the correct interval for this timed job + */ + public function __construct() { + $this->interval = $this->defaultIntervalMin * 60; + } + + /** + * Makes the background job do its work + * + * @param array $argument unused argument + */ + public function run($argument) { + $lockingProvider = \OC::$server->getLockingProvider(); + if($lockingProvider instanceof DBLockingProvider) { + $lockingProvider->cleanExpiredLocks(); + } + } +} diff --git a/lib/private/lock/dblockingprovider.php b/lib/private/lock/dblockingprovider.php index 647250cdb6f80..c10cd8636ad1b 100644 --- a/lib/private/lock/dblockingprovider.php +++ b/lib/private/lock/dblockingprovider.php @@ -235,10 +235,17 @@ public function changeLock($path, $targetType) { */ public function cleanExpiredLocks() { $expire = $this->timeFactory->getTime(); - $this->connection->executeUpdate( - 'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?', - [$expire] - ); + try { + $this->connection->executeUpdate( + 'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?', + [$expire] + ); + } catch (\Exception $e) { + // If the table is missing, the clean up was successful + if ($this->connection->tableExists('file_locks')) { + throw $e; + } + } } /** @@ -257,15 +264,4 @@ public function releaseAll() { } } } - - public function __destruct() { - try { - $this->cleanExpiredLocks(); - } catch (\Exception $e) { - // If the table is missing, the clean up was successful - if ($this->connection->tableExists('file_locks')) { - throw $e; - } - } - } } From fb62043cc16de90dc671faf5a3752300d62f4d94 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 4 Mar 2016 22:12:54 +0100 Subject: [PATCH 017/286] [stable9] Use CLOB for timezone TEXT defaults to a length of 255 which is going to fail in some cases as the timezone can be rather long. This changes it back to a CLOB as it has been before as well: owncloudarchive/calendar@8d8bb68. I'm not super convinced that CLOB is the best choice here but at least it seems to work. Fixes #22876 Backport of https://github.com/owncloud/core/pull/22878 to stable9 --- apps/dav/appinfo/database.xml | 4 ++-- apps/dav/appinfo/info.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/dav/appinfo/database.xml b/apps/dav/appinfo/database.xml index 4221e590fa58b..b0a7ad4f2a832 100644 --- a/apps/dav/appinfo/database.xml +++ b/apps/dav/appinfo/database.xml @@ -283,7 +283,7 @@ CREATE TABLE calendarobjects ( description TEXT, calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0', calendarcolor VARBINARY(10), - timezone TEXT, + timezone CLOB, components VARBINARY(20), transparent TINYINT(1) NOT NULL DEFAULT '0', UNIQUE(principaluri, uri) @@ -337,7 +337,7 @@ CREATE TABLE calendarobjects ( timezone - text + clob components diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 4f3a93dbf8b7d..a8789f480e4a1 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -5,7 +5,7 @@ ownCloud WebDAV endpoint AGPL owncloud.org - 0.1.4 + 0.1.5 From 0a5f34ab8005cd0bfc8302cefe72a9a24f86e451 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Fri, 4 Mar 2016 18:08:02 -0500 Subject: [PATCH 018/286] 9.0.0 RC2 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 0476394327b43..1eb8f4cc6c9a7 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 0, 16); +$OC_Version = array(9, 0, 0, 17); // The human readable string -$OC_VersionString = '9.0.0 RC1'; +$OC_VersionString = '9.0.0 RC2'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 71e3f7f8662db3bfb095a4ea966e6e3d3746a861 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 4 Mar 2016 15:13:56 +0100 Subject: [PATCH 019/286] Cache results of testRemoteUrl Otherwise setting up the storage will result in a HTTP request and thus slowing down ownCloud. Replaces https://github.com/owncloud/core/pull/22855 --- apps/files_sharing/lib/external/storage.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index 41f7bef589b34..87f5a3598fb44 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -54,6 +54,11 @@ class Storage extends DAV implements ISharedStorage { */ private $token; + /** + * @var \OCP\ICacheFactory + */ + private $memcacheFactory; + /** * @var \OCP\ICertificateManager */ @@ -67,8 +72,9 @@ class Storage extends DAV implements ISharedStorage { private $manager; public function __construct($options) { + $this->memcacheFactory = \OC::$server->getMemCacheFactory(); $discoveryManager = new DiscoveryManager( - \OC::$server->getMemCacheFactory(), + $this->memcacheFactory, \OC::$server->getHTTPClientService() ); @@ -241,10 +247,21 @@ protected function testRemote() { } } + /** + * @param string $url + * @return bool + */ private function testRemoteUrl($url) { + $cache = $this->memcacheFactory->create('files_sharing_remote_url'); + if($result = $cache->get($url)) { + return (bool)$result; + } + $result = file_get_contents($url); $data = json_decode($result); - return (is_object($data) and !empty($data->version)); + $returnValue = (is_object($data) and !empty($data->version)); + $cache->set($url, $returnValue); + return $returnValue; } /** From 17f5f19187bcaf2ec67a80fbedf5391e0ba348a0 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 5 Mar 2016 21:58:58 +0100 Subject: [PATCH 020/286] Show version to update to properly Properly shows the version that will be updated to. --- apps/updatenotification/controller/admincontroller.php | 5 +++-- .../tests/controller/AdminControllerTest.php | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/updatenotification/controller/admincontroller.php b/apps/updatenotification/controller/admincontroller.php index cb0c6409d7e3e..5dbcc68580934 100644 --- a/apps/updatenotification/controller/admincontroller.php +++ b/apps/updatenotification/controller/admincontroller.php @@ -99,12 +99,13 @@ public function displayPanel() { if(($key = array_search($currentChannel, $channels)) !== false) { unset($channels[$key]); } - + $updateState = $this->updateChecker->getUpdateState(); $params = [ - 'isNewVersionAvailable' => ($this->updateChecker->getUpdateState() === []) ? false : true, + 'isNewVersionAvailable' => ($updateState === []) ? false : true, 'lastChecked' => $lastUpdateCheck, 'currentChannel' => $currentChannel, 'channels' => $channels, + 'newVersionString' => ($updateState === []) ? '' : $updateState['updateVersion'], ]; return new TemplateResponse($this->appName, 'admin', $params, ''); diff --git a/apps/updatenotification/tests/controller/AdminControllerTest.php b/apps/updatenotification/tests/controller/AdminControllerTest.php index 50adcd2028bcb..d8fc2dd335cbf 100644 --- a/apps/updatenotification/tests/controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/controller/AdminControllerTest.php @@ -107,13 +107,14 @@ public function testDisplayPanelWithUpdate() { $this->updateChecker ->expects($this->once()) ->method('getUpdateState') - ->willReturn(['foo' => 'bar']); + ->willReturn(['updateVersion' => '8.1.2']); $params = [ 'isNewVersionAvailable' => true, 'lastChecked' => 'LastCheckedReturnValue', 'currentChannel' => \OCP\Util::getChannel(), 'channels' => $channels, + 'newVersionString' => '8.1.2', ]; $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); @@ -154,6 +155,7 @@ public function testDisplayPanelWithoutUpdate() { 'lastChecked' => 'LastCheckedReturnValue', 'currentChannel' => \OCP\Util::getChannel(), 'channels' => $channels, + 'newVersionString' => '', ]; $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); From ef6672998026952c40d97e7fc22c87a469c6c28a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 5 Mar 2016 23:04:49 +0100 Subject: [PATCH 021/286] Use custom header PHP in CGI mode eats the Authorization header => :bomb: --- apps/updatenotification/js/admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/updatenotification/js/admin.js b/apps/updatenotification/js/admin.js index 2fc8c9d99b178..3bc5dd21527e7 100644 --- a/apps/updatenotification/js/admin.js +++ b/apps/updatenotification/js/admin.js @@ -24,7 +24,7 @@ $(document).ready(function(){ $.ajax({ url: OC.webroot+'/updater/', headers: { - 'Authorization': loginToken + 'X-Updater-Auth': loginToken }, method: 'POST', success: function(data){ From 0945cb7a0ed07a3559139552ef3be82bb895aac5 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Sun, 6 Mar 2016 17:51:05 -0500 Subject: [PATCH 022/286] 9.0.0 RC3 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 1eb8f4cc6c9a7..a4d2a62135a0f 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 0, 17); +$OC_Version = array(9, 0, 0, 18); // The human readable string -$OC_VersionString = '9.0.0 RC2'; +$OC_VersionString = '9.0.0 RC3'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 9ec89b99b13d98845e3de7ffcffdefb6d83f8c22 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 7 Mar 2016 10:48:16 +0100 Subject: [PATCH 023/286] Correctly default to null and add type hint --- apps/dav/lib/carddav/carddavbackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index 687ef7f3a878d..bfb6ea82ad75a 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -78,7 +78,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { */ public function __construct(IDBConnection $db, Principal $principalBackend, - $dispatcher ) { + EventDispatcherInterface $dispatcher = null) { $this->db = $db; $this->principalBackend = $principalBackend; $this->dispatcher = $dispatcher; From c1876ea51c07f2e513003f6a2d752312470371fc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 7 Mar 2016 10:42:36 +0100 Subject: [PATCH 024/286] Fix uploading when free space is unlimited A federated share can report unlimited quota as -3, so the ajax/upload.php code needs to be adjusted to block uploads when the free space is unlimited. --- apps/files/ajax/upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index 36aaed5ad9ed0..d14414125f531 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -138,7 +138,7 @@ $totalSize = 0; $isReceivedShare = \OC::$server->getRequest()->getParam('isReceivedShare', false) === 'true'; // defer quota check for received shares -if (!$isReceivedShare) { +if (!$isReceivedShare && $storageStats['freeSpace'] >= 0) { foreach ($files['size'] as $size) { $totalSize += $size; } From 71b3033b3500d5a6c0b008e5ff71ac53229ffdda Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 7 Mar 2016 11:57:05 +0100 Subject: [PATCH 025/286] Make sure that the return value is an array --- lib/private/group/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php index 84e3ac7dbf39b..e82a1d4f2e61c 100644 --- a/lib/private/group/manager.php +++ b/lib/private/group/manager.php @@ -227,7 +227,7 @@ public function search($search, $limit = null, $offset = null) { */ public function getUserGroups($user) { if (is_null($user)) { - return false; + return []; } return $this->getUserIdGroups($user->getUID()); } From b1a1a461936357d1b2053db614508dad6d9a52fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 9 Feb 2016 15:03:15 +0100 Subject: [PATCH 026/286] For 9.0 we don't have the possibility to store calendar and addressbook properties on a per-user basis and therefore we simple don't allow this for now --- apps/dav/lib/caldav/calendar.php | 8 ++++++++ apps/dav/lib/carddav/addressbook.php | 14 +++++++++++--- apps/dav/tests/unit/caldav/calendartest.php | 16 ++++++++++++++++ apps/dav/tests/unit/carddav/addressbooktest.php | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 16acbbf53a393..dd8de85f9c5df 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -23,6 +23,7 @@ use OCA\DAV\DAV\Sharing\IShareable; use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\PropPatch; class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { @@ -122,4 +123,11 @@ function delete() { } parent::delete(); } + + function propPatch(PropPatch $propPatch) { + if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { + throw new Forbidden(); + } + parent::propPatch($propPatch); + } } diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index be57a2d90a14f..6ae938b8e29a2 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -23,6 +23,7 @@ use OCA\DAV\DAV\Sharing\IShareable; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; +use Sabre\DAV\PropPatch; class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { @@ -83,14 +84,14 @@ function getACL() { } // add the current user - if (isset($this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'])) { - $owner = $this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal']; + if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) { + $owner = $this->addressBookInfo['{http://owncloud.org/ns}owner-principal']; $acl[] = [ 'privilege' => '{DAV:}read', 'principal' => $owner, 'protected' => true, ]; - if ($this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only']) { + if ($this->addressBookInfo['{http://owncloud.org/ns}read-only']) { $acl[] = [ 'privilege' => '{DAV:}write', 'principal' => $owner, @@ -162,6 +163,13 @@ function delete() { parent::delete(); } + function propPatch(PropPatch $propPatch) { + if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) { + throw new Forbidden(); + } + parent::propPatch($propPatch); + } + public function getContactsGroups() { /** @var CardDavBackend $cardDavBackend */ $cardDavBackend = $this->carddavBackend; diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index 4a3c94e8aba40..4a4de51e60a40 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -23,6 +23,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; +use Sabre\DAV\PropPatch; use Test\TestCase; class CalendarTest extends TestCase { @@ -63,4 +64,19 @@ public function testDeleteFromGroup() { $c = new Calendar($backend, $calendarInfo); $c->delete(); } + + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testPropPatch() { + /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ + $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); + $calendarInfo = [ + '{http://owncloud.org/ns}owner-principal' => 'user1', + 'principaluri' => 'user2', + 'id' => 666 + ]; + $c = new Calendar($backend, $calendarInfo); + $c->propPatch(new PropPatch([])); + } } diff --git a/apps/dav/tests/unit/carddav/addressbooktest.php b/apps/dav/tests/unit/carddav/addressbooktest.php index d714fc71679e6..854c121a95df0 100644 --- a/apps/dav/tests/unit/carddav/addressbooktest.php +++ b/apps/dav/tests/unit/carddav/addressbooktest.php @@ -23,6 +23,7 @@ use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; +use Sabre\DAV\PropPatch; use Test\TestCase; class AddressBookTest extends TestCase { @@ -61,4 +62,19 @@ public function testDeleteFromGroup() { $c = new AddressBook($backend, $calendarInfo); $c->delete(); } + + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testPropPatch() { + /** @var \PHPUnit_Framework_MockObject_MockObject | CardDavBackend $backend */ + $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); + $calendarInfo = [ + '{http://owncloud.org/ns}owner-principal' => 'user1', + 'principaluri' => 'user2', + 'id' => 666 + ]; + $c = new AddressBook($backend, $calendarInfo); + $c->propPatch(new PropPatch([])); + } } From 27f3dcc68200be65b7f374ae42259c8f799e8a14 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Feb 2016 12:12:14 +0100 Subject: [PATCH 027/286] Allow to hide a shared calendar --- apps/dav/lib/caldav/calendar.php | 4 ++- apps/dav/tests/unit/caldav/calendartest.php | 29 ++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index dd8de85f9c5df..55f1acec3962c 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -125,7 +125,9 @@ function delete() { } function propPatch(PropPatch $propPatch) { - if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { + $mutations = $propPatch->getMutations(); + // If this is a shared calendar, the user can only change the enabled property, to hide it. + if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']) && (sizeof($mutations) !== 1 || !isset($mutations['{http://owncloud.org/ns}calendar-enabled']))) { throw new Forbidden(); } parent::propPatch($propPatch); diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index 4a4de51e60a40..c41070ea435fb 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -65,10 +65,26 @@ public function testDeleteFromGroup() { $c->delete(); } + public function dataPropPatch() { + return [ + [[], true], + [[ + '{http://owncloud.org/ns}calendar-enabled' => true, + ], false], + [[ + '{DAV:}displayname' => true, + ], true], + [[ + '{DAV:}displayname' => true, + '{http://owncloud.org/ns}calendar-enabled' => true, + ], true], + ]; + } + /** - * @expectedException \Sabre\DAV\Exception\Forbidden + * @dataProvider dataPropPatch */ - public function testPropPatch() { + public function testPropPatch($mutations, $throws) { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); $calendarInfo = [ @@ -77,6 +93,13 @@ public function testPropPatch() { 'id' => 666 ]; $c = new Calendar($backend, $calendarInfo); - $c->propPatch(new PropPatch([])); + + if ($throws) { + $this->setExpectedException('\Sabre\DAV\Exception\Forbidden'); + } + $c->propPatch(new PropPatch($mutations)); + if (!$throws) { + $this->assertTrue(true); + } } } From 5af8ebe3bd32e905f32c88ad2ed301e7d0d9a6a1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 29 Feb 2016 17:17:57 +0100 Subject: [PATCH 028/286] Allow to change properties of readonly calendars --- apps/dav/lib/dav/sharing/backend.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/dav/lib/dav/sharing/backend.php b/apps/dav/lib/dav/sharing/backend.php index 8e2a9307b7086..ffc4193e34b64 100644 --- a/apps/dav/lib/dav/sharing/backend.php +++ b/apps/dav/lib/dav/sharing/backend.php @@ -190,6 +190,14 @@ public function applyShareAcl($resourceId, $acl) { 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], 'protected' => true, ]; + } else if ($this->resourceType === 'calendar') { + // Allow changing the properties of read only calendars, + // so users can change the visibility. + $acl[] = [ + 'privilege' => '{DAV:}write-properties', + 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'protected' => true, + ]; } } return $acl; From 6413fffdcb77bf7dc7c0a540cd510b48df0744bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 7 Mar 2016 14:11:14 +0100 Subject: [PATCH 029/286] Handle calendar migration issue by writing the faulty event to the log and continue --- apps/dav/appinfo/application.php | 5 +++- apps/dav/lib/migration/migratecalendars.php | 28 +++++++++++++++---- .../unit/migration/migratecalendartest.php | 12 ++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 0c21b22a1fe5d..d91d16d199d33 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -108,9 +108,12 @@ public function __construct (array $urlParams=array()) { $container->registerService('MigrateCalendars', function($c) { /** @var IAppContainer $c */ $db = $c->getServer()->getDatabaseConnection(); + $logger = $c->getServer()->getLogger(); return new MigrateCalendars( new CalendarAdapter($db), - $c->query('CalDavBackend') + $c->query('CalDavBackend'), + $logger, + null ); }); diff --git a/apps/dav/lib/migration/migratecalendars.php b/apps/dav/lib/migration/migratecalendars.php index c0929aa36bed0..9bd6e6d3a3f5e 100644 --- a/apps/dav/lib/migration/migratecalendars.php +++ b/apps/dav/lib/migration/migratecalendars.php @@ -23,9 +23,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; +use OCP\ILogger; use Symfony\Component\Console\Output\OutputInterface; class MigrateCalendars { @@ -36,15 +34,25 @@ class MigrateCalendars { /** @var CalDavBackend */ private $backend; + /** @var ILogger */ + private $logger; + + /** @var OutputInterface */ + private $consoleOutput; + /** * @param CalendarAdapter $adapter * @param CalDavBackend $backend */ function __construct(CalendarAdapter $adapter, - CalDavBackend $backend + CalDavBackend $backend, + ILogger $logger, + OutputInterface $consoleOutput = null ) { $this->adapter = $adapter; $this->backend = $backend; + $this->logger = $logger; + $this->consoleOutput = $consoleOutput; } /** @@ -82,7 +90,17 @@ public function setup() { */ private function migrateCalendar($calendarId, $newCalendarId) { $this->adapter->foreachCalendarObject($calendarId, function($calObject) use ($newCalendarId) { - $this->backend->createCalendarObject($newCalendarId, $calObject['uri'], $calObject['calendardata']); + try { + $this->backend->createCalendarObject($newCalendarId, $calObject['uri'], $calObject['calendardata']); + } catch (\Exception $ex) { + $eventId = $calObject['id']; + $calendarId = $calObject['calendarId']; + $msg = "One event could not be migrated. (id: $eventId, calendarid: $calendarId)"; + $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); + if (!is_null($this->consoleOutput)) { + $this->consoleOutput->writeln($msg); + } + } }); } diff --git a/apps/dav/tests/unit/migration/migratecalendartest.php b/apps/dav/tests/unit/migration/migratecalendartest.php index 1058773ffff51..ad3f6af23224e 100644 --- a/apps/dav/tests/unit/migration/migratecalendartest.php +++ b/apps/dav/tests/unit/migration/migratecalendartest.php @@ -22,6 +22,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\Dav\Migration\CalendarAdapter; +use OCP\ILogger; use Test\TestCase; class MigrateCalendarTest extends TestCase { @@ -35,15 +36,17 @@ public function testMigration() { $cardDav->method('createCalendar')->willReturn(666); $cardDav->expects($this->once())->method('createCalendar')->with('principals/users/test01', 'test_contacts'); $cardDav->expects($this->once())->method('createCalendarObject')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'BEGIN:VCARD'); + /** @var ILogger $logger */ + $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - $m = new \OCA\Dav\Migration\MigrateCalendars($adapter, $cardDav); + $m = new \OCA\Dav\Migration\MigrateCalendars($adapter, $cardDav, $logger, null); $m->migrateForUser('test01'); } /** * @return \PHPUnit_Framework_MockObject_MockObject */ - private function mockAdapter($shares = []) { + private function mockAdapter($shares = [], $calData = 'BEGIN:VCARD') { $adapter = $this->getMockBuilder('\OCA\Dav\Migration\CalendarAdapter') ->disableOriginalConstructor() ->getMock(); @@ -62,15 +65,14 @@ private function mockAdapter($shares = []) { 'components' => 'VEVENT,VTODO,VJOURNAL' ]); }); - $adapter->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) { + $adapter->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) use ($calData) { $callBack([ 'userid' => $addressBookId, 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', - 'calendardata' => 'BEGIN:VCARD' + 'calendardata' => $calData ]); }); $adapter->method('getShares')->willReturn($shares); return $adapter; } - } From 79811b58063d7f47d11cf66a1f93d268e08f54ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 7 Mar 2016 14:34:28 +0100 Subject: [PATCH 030/286] Handle addressbook migration issue by writing the faulty event to the log and continue --- apps/dav/appinfo/application.php | 5 +++- .../dav/lib/migration/migrateaddressbooks.php | 29 +++++++++++++++---- .../unit/migration/migrateaddressbooktest.php | 5 +++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index d91d16d199d33..1dae3d4efbf1b 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -99,9 +99,12 @@ public function __construct (array $urlParams=array()) { $container->registerService('MigrateAddressbooks', function($c) { /** @var IAppContainer $c */ $db = $c->getServer()->getDatabaseConnection(); + $logger = $c->getServer()->getLogger(); return new MigrateAddressbooks( new AddressBookAdapter($db), - $c->query('CardDavBackend') + $c->query('CardDavBackend'), + $logger, + null ); }); diff --git a/apps/dav/lib/migration/migrateaddressbooks.php b/apps/dav/lib/migration/migrateaddressbooks.php index d26ca4c18106a..c0223b30e2c00 100644 --- a/apps/dav/lib/migration/migrateaddressbooks.php +++ b/apps/dav/lib/migration/migrateaddressbooks.php @@ -23,10 +23,8 @@ use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; +use OCP\ILogger; use Sabre\CardDAV\Plugin; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class MigrateAddressbooks { @@ -37,15 +35,26 @@ class MigrateAddressbooks { /** @var CardDavBackend */ private $backend; + /** @var ILogger */ + private $logger; + + /** @var OutputInterface */ + private $consoleOutput; + + /** * @param AddressBookAdapter $adapter * @param CardDavBackend $backend */ function __construct(AddressBookAdapter $adapter, - CardDavBackend $backend + CardDavBackend $backend, + ILogger $logger, + OutputInterface $consoleOutput = null ) { $this->adapter = $adapter; $this->backend = $backend; + $this->logger = $logger; + $this->consoleOutput = $consoleOutput; } /** @@ -80,7 +89,17 @@ public function setup() { */ private function migrateBook($addressBookId, $newAddressBookId) { $this->adapter->foreachCard($addressBookId, function($card) use ($newAddressBookId) { - $this->backend->createCard($newAddressBookId, $card['uri'], $card['carddata']); + try { + $this->backend->createCard($newAddressBookId, $card['uri'], $card['carddata']); + } catch (\Exception $ex) { + $eventId = $card['id']; + $addressBookId = $card['addressbookid']; + $msg = "One event could not be migrated. (id: $eventId, addressbookid: $addressBookId)"; + $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); + if (!is_null($this->consoleOutput)) { + $this->consoleOutput->writeln($msg); + } + } }); } diff --git a/apps/dav/tests/unit/migration/migrateaddressbooktest.php b/apps/dav/tests/unit/migration/migrateaddressbooktest.php index 1b27536ce3ba3..0679e687a04ac 100644 --- a/apps/dav/tests/unit/migration/migrateaddressbooktest.php +++ b/apps/dav/tests/unit/migration/migrateaddressbooktest.php @@ -22,6 +22,7 @@ use OCA\DAV\CardDAV\CardDavBackend; use OCA\Dav\Migration\AddressBookAdapter; +use OCP\ILogger; use Test\TestCase; class MigrateAddressbookTest extends TestCase { @@ -35,8 +36,10 @@ public function testMigration() { $cardDav->method('createAddressBook')->willReturn(666); $cardDav->expects($this->once())->method('createAddressBook')->with('principals/users/test01', 'test_contacts'); $cardDav->expects($this->once())->method('createCard')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', 'BEGIN:VCARD'); + /** @var ILogger $logger */ + $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - $m = new \OCA\Dav\Migration\MigrateAddressbooks($adapter, $cardDav); + $m = new \OCA\Dav\Migration\MigrateAddressbooks($adapter, $cardDav, $logger, null); $m->migrateForUser('test01'); } From b5a06ecd5c0c39b218e4d6b41f4dccc5d7be7bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 7 Mar 2016 14:36:47 +0100 Subject: [PATCH 031/286] Calendar and addressbook migration commands are always available --- apps/dav/appinfo/register_command.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 340fbb16e90c0..570848f0b234e 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -29,7 +29,6 @@ $dbConnection = \OC::$server->getDatabaseConnection(); $userManager = OC::$server->getUserManager(); $groupManager = OC::$server->getGroupManager(); -$config = \OC::$server->getConfig(); $app = new Application(); @@ -38,12 +37,5 @@ $application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend'))); $application->add(new SyncSystemAddressBook($app->getSyncService())); $application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService'))); - -// the occ tool is *for now* only available in debug mode for developers to test -if ($config->getSystemValue('debug', false)){ - $app = new \OCA\Dav\AppInfo\Application(); - $migration = $app->getContainer()->query('MigrateAddressbooks'); - $application->add(new MigrateAddressbooks($userManager, $migration)); - $migration = $app->getContainer()->query('MigrateCalendars'); - $application->add(new MigrateCalendars($userManager, $migration)); -} +$application->add(new MigrateAddressbooks($userManager, $app->getContainer()->query('MigrateAddressbooks'))); +$application->add(new MigrateCalendars($userManager, $app->getContainer()->query('MigrateCalendars'))); From fab42c7cd24d2c98506e63443076a45c52f6b220 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 7 Mar 2016 19:29:15 +0100 Subject: [PATCH 032/286] Remove double URL encoding ZipStreamer as bundled with 9.0 will properly encode the filename already. Fixes https://github.com/owncloud/core/issues/22836#issuecomment-193336245 --- lib/private/streamer.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/private/streamer.php b/lib/private/streamer.php index 5fffa7ac3688d..23c191b68dadf 100644 --- a/lib/private/streamer.php +++ b/lib/private/streamer.php @@ -51,10 +51,6 @@ public function __construct(){ public function sendHeaders($name){ $extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar'; $fullName = $name . $extension; - // ZipStreamer does not escape name in Content-Disposition atm - if ($this->streamerInstance instanceof ZipStreamer) { - $fullName = rawurlencode($fullName); - } $this->streamerInstance->sendHeaders($fullName); } From f9e1d4d56e4fa82151ff1681e7de0837970d6cc6 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 7 Mar 2016 11:37:49 +0100 Subject: [PATCH 033/286] Fix archive file name when downloading public share When download a public link share folder using the button on the top right, it doesn't provide a list of files. This fix makes sure to trigger the correct logic when no file list was given. --- apps/files_sharing/lib/controllers/sharecontroller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index 84143d85e47e2..ea024b6016a1b 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -479,7 +479,7 @@ public function downloadShare($token, $files = null, $path = '', $downloadStartS $this->emitAccessShareHook($share); // download selected files - if (!is_null($files)) { + if (!is_null($files) && $files !== '') { // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well // after dispatching the request which results in a "Cannot modify header information" notice. OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); From ebfc8b67d79b05bd93d38a9a7a06e98f0d304830 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 7 Mar 2016 11:55:55 +0100 Subject: [PATCH 034/286] Remove "files" arg from download URL in public link page When no files were specified for download, it means folder download. In this case, no need to pass an empty "files" argument. --- apps/files_sharing/js/public.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index da83044714edc..70d5d619c12de 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -158,9 +158,11 @@ OCA.Sharing.PublicApp = { filename = JSON.stringify(filename); } var params = { - path: path, - files: filename + path: path }; + if (filename) { + params.files = filename; + } return OC.generateUrl('/s/' + token + '/download') + '?' + OC.buildQueryString(params); }; From cfd9c7f6b9fe83084832dc6bdcaac7ed3450ce4e Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 2 Mar 2016 17:50:46 +0100 Subject: [PATCH 035/286] Fix tooltip for versions mtime It was missing a call to jquery.tooltip --- apps/files_versions/js/versionstabview.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js index f2b1c18bd37c8..0e17fff466a17 100644 --- a/apps/files_versions/js/versionstabview.js +++ b/apps/files_versions/js/versionstabview.js @@ -140,7 +140,9 @@ }, _onAddModel: function(model) { - this.$versionsContainer.append(this.itemTemplate(this._formatItem(model))); + var $el = $(this.itemTemplate(this._formatItem(model))); + this.$versionsContainer.append($el); + $el.find('.has-tooltip').tooltip(); }, template: function(data) { From c9476115b0504fc132169b4fa4ef55d6f97a40ab Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 2 Mar 2016 17:42:51 +0100 Subject: [PATCH 036/286] Return false on 401 in file list + trash file list This gives a chance to the global ajax error handler to do its work if the session expired. --- apps/files/js/filelist.js | 4 ++++ apps/files_trashbin/js/filelist.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 95fdac02c2d08..fcdf6caaa5975 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1436,6 +1436,10 @@ delete this._reloadCall; this.hideMask(); + if (status === 401) { + return false; + } + // Firewall Blocked request? if (status === 403) { // Go home diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index 5812aff82f7ab..feed28d8fc7d1 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -325,6 +325,10 @@ return false; } + if (result.status === 401) { + return false; + } + // Firewall Blocked request? if (result.status === 403) { // Go home From 795331212a6e3fee152cec36f43d769a75f0044b Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 2 Mar 2016 17:10:29 +0100 Subject: [PATCH 037/286] Remove browser autocomplete in new file menu --- apps/files/js/newfilemenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/newfilemenu.js b/apps/files/js/newfilemenu.js index be7dcc40b6ed9..3553d2d1aa06c 100644 --- a/apps/files/js/newfilemenu.js +++ b/apps/files/js/newfilemenu.js @@ -27,7 +27,7 @@ var TEMPLATE_FILENAME_FORM = '
' + '' + - '' + + '' + '
'; /** From 859303164e79f9b550cd2777289578caedc1f98d Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 4 Mar 2016 18:11:42 +0100 Subject: [PATCH 038/286] Update error text for link passwords * this removes the old tooltip first before showing the new one to update the text - otherwise the old text will be shown --- core/js/sharedialoglinkshareview.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js index 5b464ee93230a..1d158ccec16ae 100644 --- a/core/js/sharedialoglinkshareview.js +++ b/core/js/sharedialoglinkshareview.js @@ -193,6 +193,8 @@ password: password }, { error: function(model, msg) { + // destroy old tooltips + $input.tooltip('destroy'); $loading.removeClass('inlineblock').addClass('hidden'); $input.addClass('error'); $input.attr('title', msg); From 213dfa2b85aab5b30862ef0141157f8b8993d09c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 3 Mar 2016 01:15:36 +0100 Subject: [PATCH 039/286] don't hide server not available exception, fixes #20536 --- lib/base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/base.php b/lib/base.php index b462a49fc9b9d..9db4a482f232a 100644 --- a/lib/base.php +++ b/lib/base.php @@ -714,6 +714,9 @@ public static function registerCacheHooks() { try { $cache = new \OC\Cache\File(); $cache->gc(); + } catch (\OC\ServerNotAvailableException $e) { + // not a GC exception, pass it on + throw $e; } catch (\Exception $e) { // a GC exception should not prevent users from using OC, // so log the exception From d63f5561fb793c556a307088f5e6ec7f3127106a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 8 Mar 2016 11:23:20 +0100 Subject: [PATCH 040/286] Fix share mounting recursion --- apps/files_sharing/lib/sharedstorage.php | 2 ++ lib/private/files/config/usermountcache.php | 9 +++++++-- lib/private/util.php | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 600599d717580..6998f94698edc 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -85,6 +85,7 @@ private function init() { } private function isValid() { + $this->init(); return ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; } @@ -566,6 +567,7 @@ public function hasUpdated($path, $time) { } public function getCache($path = '', $storage = null) { + $this->init(); if (!$storage) { $storage = $this; } diff --git a/lib/private/files/config/usermountcache.php b/lib/private/files/config/usermountcache.php index 58e7e9d156d5b..78b1997278740 100644 --- a/lib/private/files/config/usermountcache.php +++ b/lib/private/files/config/usermountcache.php @@ -24,6 +24,7 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OC\Files\Filesystem; +use OCA\Files_Sharing\SharedMount; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; @@ -75,12 +76,16 @@ public function __construct(IDBConnection $connection, IUserManager $userManager public function registerMounts(IUser $user, array $mounts) { // filter out non-proper storages coming from unit tests $mounts = array_filter($mounts, function (IMountPoint $mount) { - return $mount->getStorage() && $mount->getStorage()->getCache(); + return $mount instanceof SharedMount || $mount->getStorage() && $mount->getStorage()->getCache(); }); /** @var ICachedMountInfo[] $newMounts */ $newMounts = array_map(function (IMountPoint $mount) use ($user) { $storage = $mount->getStorage(); - $rootId = (int)$storage->getCache()->getId(''); + if ($storage->instanceOfStorage('\OC\Files\Storage\Shared')) { + $rootId = (int)$storage->getShare()['file_source']; + } else { + $rootId = (int)$storage->getCache()->getId(''); + } $storageId = (int)$storage->getStorageCache()->getNumericId(); // filter out any storages which aren't scanned yet since we aren't interested in files from those storages (yet) if ($rootId === -1) { diff --git a/lib/private/util.php b/lib/private/util.php index 6884e55c24367..f6191b96aa2e5 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -165,7 +165,7 @@ public static function setupFS($user = '') { // install storage availability wrapper, before most other wrappers \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, $storage) { - if (!$storage->isLocal()) { + if (!$storage->instanceOfStorage('\OC\Files\Storage\Shared') && !$storage->isLocal()) { return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]); } return $storage; From 8d6a6667e5c8ac49660a2a12a6e05136a59ac3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 8 Mar 2016 10:58:26 +0100 Subject: [PATCH 041/286] Fix group sharing and sharing permissions - fixes #22932 --- apps/dav/lib/carddav/addressbook.php | 4 ---- apps/dav/lib/migration/migrateaddressbooks.php | 5 +++-- apps/dav/lib/migration/migratecalendars.php | 5 +++-- .../unit/migration/migrateaddressbooktest.php | 18 +++++++++++++----- .../unit/migration/migratecalendartest.php | 17 ++++++++++++----- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index be57a2d90a14f..a450ffc262d22 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -26,10 +26,6 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { - public function __construct(CardDavBackend $carddavBackend, array $addressBookInfo) { - parent::__construct($carddavBackend, $addressBookInfo); - } - /** * Updates the list of shares. * diff --git a/apps/dav/lib/migration/migrateaddressbooks.php b/apps/dav/lib/migration/migrateaddressbooks.php index c0223b30e2c00..7e1f47ea75e1f 100644 --- a/apps/dav/lib/migration/migrateaddressbooks.php +++ b/apps/dav/lib/migration/migrateaddressbooks.php @@ -115,11 +115,12 @@ private function migrateShares($addressBookId, $newAddressBookId) { $add = array_map(function($s) { $prefix = 'principal:principals/users/'; - if ($s['share_type'] === 1) { + if ((int)$s['share_type'] === 1) { $prefix = 'principal:principals/groups/'; } return [ - 'href' => $prefix . $s['share_with'] + 'href' => $prefix . $s['share_with'], + 'readOnly' => !((int)$s['permissions'] === 31) ]; }, $shares); diff --git a/apps/dav/lib/migration/migratecalendars.php b/apps/dav/lib/migration/migratecalendars.php index 9bd6e6d3a3f5e..3c1487761c215 100644 --- a/apps/dav/lib/migration/migratecalendars.php +++ b/apps/dav/lib/migration/migratecalendars.php @@ -116,11 +116,12 @@ private function migrateShares($calendarId, $newCalendarId) { $add = array_map(function($s) { $prefix = 'principal:principals/users/'; - if ($s['share_type'] === 1) { + if ((int)$s['share_type'] === 1) { $prefix = 'principal:principals/groups/'; } return [ - 'href' => $prefix . $s['share_with'] + 'href' => $prefix . $s['share_with'], + 'readOnly' => !((int)$s['permissions'] === 31) ]; }, $shares); diff --git a/apps/dav/tests/unit/migration/migrateaddressbooktest.php b/apps/dav/tests/unit/migration/migrateaddressbooktest.php index 0679e687a04ac..31cb16265c0af 100644 --- a/apps/dav/tests/unit/migration/migrateaddressbooktest.php +++ b/apps/dav/tests/unit/migration/migrateaddressbooktest.php @@ -29,13 +29,21 @@ class MigrateAddressbookTest extends TestCase { public function testMigration() { /** @var AddressBookAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter(); + $adapter = $this->mockAdapter([ + ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], + ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], + ]); /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ $cardDav = $this->getMockBuilder('\OCA\Dav\CardDAV\CardDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->method('createAddressBook')->willReturn(666); + $cardDav->expects($this->any())->method('createAddressBook')->willReturn(666); + $cardDav->expects($this->any())->method('getAddressBookById')->willReturn([]); $cardDav->expects($this->once())->method('createAddressBook')->with('principals/users/test01', 'test_contacts'); $cardDav->expects($this->once())->method('createCard')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', 'BEGIN:VCARD'); + $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ + ['href' => 'principal:principals/groups/users', 'readOnly' => false], + ['href' => 'principal:principals/users/adam', 'readOnly' => true] + ]); /** @var ILogger $logger */ $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); @@ -48,7 +56,7 @@ public function testMigration() { */ private function mockAdapter($shares = []) { $adapter = $this->getMockBuilder('\OCA\Dav\Migration\AddressBookAdapter')->disableOriginalConstructor()->getMock(); - $adapter->method('foreachBook')->willReturnCallback(function ($user, \Closure $callBack) { + $adapter->expects($this->any())->method('foreachBook')->willReturnCallback(function ($user, \Closure $callBack) { $callBack([ 'id' => 0, 'userid' => $user, @@ -59,14 +67,14 @@ private function mockAdapter($shares = []) { 'active' => 1 ]); }); - $adapter->method('foreachCard')->willReturnCallback(function ($addressBookId, \Closure $callBack) { + $adapter->expects($this->any())->method('foreachCard')->willReturnCallback(function ($addressBookId, \Closure $callBack) { $callBack([ 'userid' => $addressBookId, 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', 'carddata' => 'BEGIN:VCARD' ]); }); - $adapter->method('getShares')->willReturn($shares); + $adapter->expects($this->any())->method('getShares')->willReturn($shares); return $adapter; } diff --git a/apps/dav/tests/unit/migration/migratecalendartest.php b/apps/dav/tests/unit/migration/migratecalendartest.php index ad3f6af23224e..e62970aef34d6 100644 --- a/apps/dav/tests/unit/migration/migratecalendartest.php +++ b/apps/dav/tests/unit/migration/migratecalendartest.php @@ -29,13 +29,20 @@ class MigrateCalendarTest extends TestCase { public function testMigration() { /** @var CalendarAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter(); + $adapter = $this->mockAdapter([ + ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], + ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], + ]); /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ $cardDav = $this->getMockBuilder('\OCA\Dav\CalDAV\CalDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->method('createCalendar')->willReturn(666); + $cardDav->expects($this->any())->method('createCalendar')->willReturn(666); $cardDav->expects($this->once())->method('createCalendar')->with('principals/users/test01', 'test_contacts'); $cardDav->expects($this->once())->method('createCalendarObject')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'BEGIN:VCARD'); + $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ + ['href' => 'principal:principals/groups/users', 'readOnly' => false], + ['href' => 'principal:principals/users/adam', 'readOnly' => true] + ]); /** @var ILogger $logger */ $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); @@ -50,7 +57,7 @@ private function mockAdapter($shares = [], $calData = 'BEGIN:VCARD') { $adapter = $this->getMockBuilder('\OCA\Dav\Migration\CalendarAdapter') ->disableOriginalConstructor() ->getMock(); - $adapter->method('foreachCalendar')->willReturnCallback(function ($user, \Closure $callBack) { + $adapter->expects($this->any())->method('foreachCalendar')->willReturnCallback(function ($user, \Closure $callBack) { $callBack([ // calendarorder | calendarcolor | timezone | components 'id' => 0, @@ -65,14 +72,14 @@ private function mockAdapter($shares = [], $calData = 'BEGIN:VCARD') { 'components' => 'VEVENT,VTODO,VJOURNAL' ]); }); - $adapter->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) use ($calData) { + $adapter->expects($this->any())->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) use ($calData) { $callBack([ 'userid' => $addressBookId, 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'calendardata' => $calData ]); }); - $adapter->method('getShares')->willReturn($shares); + $adapter->expects($this->any())->method('getShares')->willReturn($shares); return $adapter; } } From 81f694d83e8246d9b6482b773c8bdca675c51828 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 8 Mar 2016 08:48:12 -0500 Subject: [PATCH 042/286] 9.0.0 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index a4d2a62135a0f..3a8bd5adaea83 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 0, 18); +$OC_Version = array(9, 0, 0, 19); // The human readable string -$OC_VersionString = '9.0.0 RC3'; +$OC_VersionString = '9.0.0'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 1975ffa9e712fb5c568b1e3319a5438d403e021d Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 8 Mar 2016 18:04:24 +0100 Subject: [PATCH 043/286] Fix compatibility with PHP 5.4 Fixes https://github.com/owncloud/core/issues/22960 --- apps/files_external/lib/google.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 3e8b60d33df74..5e5716cf43801 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -265,7 +265,8 @@ public function opendir($path) { foreach ($children->getItems() as $child) { $name = $child->getTitle(); // Check if this is a Google Doc i.e. no extension in name - if (empty($child->getFileExtension()) + $extension = $child->getFileExtension(); + if (empty($extension) && $child->getMimeType() !== self::FOLDER ) { $name .= '.'.$this->getGoogleDocExtension($child->getMimeType()); From ddf56b84d4d3c36e5a65e202ac4d371957b1bb86 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 8 Mar 2016 23:24:44 +0100 Subject: [PATCH 044/286] Use "hasKey" instead of checking the value If the check is negative it would depending on the used cache store the value as an empty string. When reading the value this check would thus return "false" even if a value exists. --- apps/files_sharing/lib/external/storage.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index 87f5a3598fb44..80ab006f1ca3c 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -253,8 +253,8 @@ protected function testRemote() { */ private function testRemoteUrl($url) { $cache = $this->memcacheFactory->create('files_sharing_remote_url'); - if($result = $cache->get($url)) { - return (bool)$result; + if($cache->hasKey($url)) { + return (bool)$cache->get($url); } $result = file_get_contents($url); From 9120448302e627846ad2e4a83e36ebdc83b040e2 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 9 Mar 2016 11:19:57 +0100 Subject: [PATCH 045/286] Select queries in the default share provider should query for file/folder There can be leftover calendar and contacts shares in the oc_share table. We need to filter those out properly. --- lib/private/share20/defaultshareprovider.php | 61 ++++++++++++++++---- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/lib/private/share20/defaultshareprovider.php b/lib/private/share20/defaultshareprovider.php index dc5b47b0ab090..43dc6090a35ce 100644 --- a/lib/private/share20/defaultshareprovider.php +++ b/lib/private/share20/defaultshareprovider.php @@ -274,6 +274,10 @@ public function getChildren(\OCP\Share\IShare $parent) { ], IQueryBuilder::PARAM_INT_ARRAY) ) ) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) ->orderBy('id'); $cursor = $qb->execute(); @@ -332,6 +336,10 @@ public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) { ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))) ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))) ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) ->execute(); $data = $stmt->fetch(); @@ -405,6 +413,10 @@ public function move(\OCP\Share\IShare $share, $recipient) { ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))) ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))) ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) ->setMaxResults(1) ->execute(); @@ -455,7 +467,11 @@ public function move(\OCP\Share\IShare $share, $recipient) { public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { $qb = $this->dbConn->getQueryBuilder(); $qb->select('*') - ->from('share'); + ->from('share') + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType))); @@ -523,7 +539,11 @@ public function getShareById($id, $recipientId = null) { \OCP\Share::SHARE_TYPE_LINK, ], IQueryBuilder::PARAM_INT_ARRAY) ) - ); + ) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); $cursor = $qb->execute(); $data = $cursor->fetch(); @@ -564,7 +584,12 @@ public function getSharesByPath(Node $path) { $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)), $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)) ) - )->execute(); + ) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) + ->execute(); $shares = []; while($data = $cursor->fetch()) { @@ -597,8 +622,12 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { } $qb->setFirstResult($offset); - $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER))); - $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))); + $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); // Filter by node if provided if ($node !== null) { @@ -645,11 +674,15 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { $groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups); - $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))); - $qb->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter( - $groups, - IQueryBuilder::PARAM_STR_ARRAY - ))); + $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))) + ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter( + $groups, + IQueryBuilder::PARAM_STR_ARRAY + ))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); $cursor = $qb->execute(); while($data = $cursor->fetch()) { @@ -691,6 +724,10 @@ public function getShareByToken($token) { ->from('share') ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))) ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) ->execute(); $data = $cursor->fetch(); @@ -802,6 +839,10 @@ private function resolveGroupShare(\OCP\Share\IShare $share, $userId) { ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))) ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) ->setMaxResults(1) ->execute(); From 313b881d2b38f4a0ed43afc68dafacd65524b0b7 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 23 Feb 2016 16:19:23 +0100 Subject: [PATCH 046/286] Do not check all chunks of a chunked upload if we do not need to Fixes #22601 Before we did a full test on all chunks to verify if a chunked upload was completed. This is unneeded since if we are missing one chunk we can already fail. Also we look from back to front since it is much more likely that we find a missing chunk thus can error out early. --- lib/private/filechunking.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/private/filechunking.php b/lib/private/filechunking.php index ece215e734494..32cbb7559f0ae 100644 --- a/lib/private/filechunking.php +++ b/lib/private/filechunking.php @@ -74,14 +74,16 @@ public function store($index, $data) { public function isComplete() { $prefix = $this->getPrefix(); - $parts = 0; $cache = $this->getCache(); - for($i=0; $i < $this->info['chunkcount']; $i++) { - if ($cache->hasKey($prefix.$i)) { - $parts ++; + $chunkcount = (int)$this->info['chunkcount']; + + for($i=($chunkcount-1); $i >= 0; $i--) { + if (!$cache->hasKey($prefix.$i)) { + return false; } } - return $parts == $this->info['chunkcount']; + + return true; } /** From 91c7d293ca0c41addd25d79fa060be6506d898b1 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Mon, 7 Mar 2016 20:55:49 +0100 Subject: [PATCH 047/286] Added tests * Unit tests for OC_Filechunking to verify the isComplete function * Intergration tests to show that shuffling chunks is all fine --- .../integration/features/bootstrap/WebDav.php | 11 +++ .../features/webdav-related.feature | 27 +++++++ tests/lib/filechunking.php | 70 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 tests/lib/filechunking.php diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index fa6761d9f7143..0430768022c67 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -262,5 +262,16 @@ public function userCreatedAFolder($user, $destination){ } } + /** + * @Given user :user uploads chunk file :num of :total with :data to :destination + */ + public function userUploadsChunkFileOfWithToWithChecksum($user, $num, $total, $data, $destination) + { + $num -= 1; + $data = \GuzzleHttp\Stream\Stream::factory($data); + $file = $destination . '-chunking-42-'.$total.'-'.$num; + $this->makeDavRequest($user, 'PUT', $file, ['OC-Chunked' => '1'], $data); + } + } diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature index 63f205d1e4c29..019df3436f8a9 100644 --- a/build/integration/features/webdav-related.feature +++ b/build/integration/features/webdav-related.feature @@ -141,3 +141,30 @@ Feature: webdav-related Given Logging in using web as "admin" When Sending a "PROPFIND" to "/remote.php/webdav/welcome.txt" with requesttoken Then the HTTP status code should be "207" + + Scenario: Upload chunked file asc + Given user "user0" exists + And user "user0" uploads chunk file "1" of "3" with "AAAAA" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "2" of "3" with "BBBBB" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "3" of "3" with "CCCCC" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" + + Scenario: Upload chunked file desc + Given user "user0" exists + And user "user0" uploads chunk file "3" of "3" with "CCCCC" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "2" of "3" with "BBBBB" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "1" of "3" with "AAAAA" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" + + Scenario: Upload chunked file random + Given user "user0" exists + And user "user0" uploads chunk file "2" of "3" with "BBBBB" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "3" of "3" with "CCCCC" to "/myChunkedFile.txt" + And user "user0" uploads chunk file "1" of "3" with "AAAAA" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" diff --git a/tests/lib/filechunking.php b/tests/lib/filechunking.php new file mode 100644 index 0000000000000..2f3f411275d83 --- /dev/null +++ b/tests/lib/filechunking.php @@ -0,0 +1,70 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace Test; + +class FileChunking extends \Test\TestCase { + + public function dataIsComplete() { + return [ + [1, [], false], + [1, [0], true], + [2, [], false], + [2, [0], false], + [2, [1], false], + [2, [0,1], true], + [10, [], false], + [10, [0,1,2,3,4,5,6,7,8], false], + [10, [1,2,3,4,5,6,7,8,9], false], + [10, [0,1,2,3,5,6,7,8,9], false], + [10, [0,1,2,3,4,5,6,7,8,9], true], + ]; + } + + /** + * @dataProvider dataIsComplete + * @param $total + * @param array $present + * @param $expected + */ + public function testIsComplete($total, array $present, $expected) { + $fileChunking = $this->getMockBuilder('\OC_FileChunking') + ->setMethods(['getCache']) + ->setConstructorArgs([[ + 'name' => 'file', + 'transferid' => '42', + 'chunkcount' => $total, + ]]) + ->getMock(); + + $cache = $this->getMock('\OCP\ICache'); + + $cache->expects($this->atLeastOnce()) + ->method('hasKey') + ->will($this->returnCallback(function ($key) use ($present) { + $data = explode('-', $key); + return in_array($data[3], $present); + })); + + $fileChunking->method('getCache')->willReturn($cache); + + $this->assertEquals($expected, $fileChunking->isComplete()); + } +} From 88b9db44a0e1be72060bb223a2f543c7db6f250e Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 9 Mar 2016 08:38:05 +0100 Subject: [PATCH 048/286] Remove disabled autocorrect for new file names * ref #22784 --- apps/files/js/newfilemenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/newfilemenu.js b/apps/files/js/newfilemenu.js index 3553d2d1aa06c..f6cf87a55bfb1 100644 --- a/apps/files/js/newfilemenu.js +++ b/apps/files/js/newfilemenu.js @@ -27,7 +27,7 @@ var TEMPLATE_FILENAME_FORM = '
' + '' + - '' + + '' + '
'; /** From 316f86f2a3b0cfb32c7ef01b848a1ef1d65a4499 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 9 Mar 2016 11:11:00 +0100 Subject: [PATCH 049/286] Add XMLReader as requirement The SabreDAV release in 9.0 requires XMLReader, while this is usually compiled in by default some distributions like Gentoo don't. Without this ownCloud gives a fatal 500 error instead of telling people to enable XMLReader. Fixes https://github.com/owncloud/core/issues/23003 --- lib/private/util.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/util.php b/lib/private/util.php index f6191b96aa2e5..6f53be8446a9b 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -726,7 +726,8 @@ public static function checkServer(\OCP\IConfig $config) { 'classes' => array( 'ZipArchive' => 'zip', 'DOMDocument' => 'dom', - 'XMLWriter' => 'XMLWriter' + 'XMLWriter' => 'XMLWriter', + 'XMLReader' => 'XMLReader', ), 'functions' => [ 'xml_parser_create' => 'libxml', From 11f76b29184621a8a09369ed3c468b7dee4f3160 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 7 Mar 2016 10:58:24 +0100 Subject: [PATCH 050/286] Fix call to disk_free_space when a file is provided In the case of shared files, we have to call free_space() on the file name. This has the side-effect that when uploading to a local storage without quota set, it will call disk_free_space with the file name, which fails. This fix uses the parent folder in case the given path is a file. --- lib/private/files/storage/local.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index aa2b462828324..f6f5a8cc130b7 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -252,7 +252,15 @@ public function hash($type, $path, $raw = false) { } public function free_space($path) { - $space = @disk_free_space($this->getSourcePath($path)); + $sourcePath = $this->getSourcePath($path); + // using !is_dir because $sourcePath might be a part file or + // non-existing file, so we'd still want to use the parent dir + // in such cases + if (!is_dir($sourcePath)) { + // disk_free_space doesn't work on files + $sourcePath = dirname($sourcePath); + } + $space = @disk_free_space($sourcePath); if ($space === false || is_null($space)) { return \OCP\Files\FileInfo::SPACE_UNKNOWN; } From 48cdf38d00f60a1ab2d4f01e0b008e2c92995bb9 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 9 Mar 2016 20:20:37 +0100 Subject: [PATCH 051/286] Add mimetype to OCS Share API output Fixes #23044 --- apps/files_sharing/api/share20ocs.php | 1 + .../tests/api/share20ocstest.php | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php index 4abd821f2ae51..a6baa353e8a15 100644 --- a/apps/files_sharing/api/share20ocs.php +++ b/apps/files_sharing/api/share20ocs.php @@ -110,6 +110,7 @@ protected function formatShare(\OCP\Share\IShare $share) { } else { $result['item_type'] = 'file'; } + $result['mimetype'] = $node->getMimeType(); $result['storage_id'] = $node->getStorage()->getId(); $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId(); $result['item_source'] = $node->getId(); diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php index 81db3b963335a..a2c70d7673c68 100644 --- a/apps/files_sharing/tests/api/share20ocstest.php +++ b/apps/files_sharing/tests/api/share20ocstest.php @@ -203,12 +203,14 @@ public function dataGetShare() { $file->method('getPath')->willReturn('file'); $file->method('getStorage')->willReturn($storage); $file->method('getParent')->willReturn($parentFolder); + $file->method('getMimeType')->willReturn('myMimeType'); $folder = $this->getMock('OCP\Files\Folder'); $folder->method('getId')->willReturn(2); $folder->method('getPath')->willReturn('folder'); $folder->method('getStorage')->willReturn($storage); $folder->method('getParent')->willReturn($parentFolder); + $folder->method('getMimeType')->willReturn('myFolderMimeType'); // File shared with user $share = $this->createShare( @@ -247,7 +249,8 @@ public function dataGetShare() { 'storage' => 101, 'mail_send' => 0, 'uid_file_owner' => 'ownerId', - 'displayname_file_owner' => 'ownerDisplay' + 'displayname_file_owner' => 'ownerDisplay', + 'mimetype' => 'myMimeType', ]; $data[] = [$share, $expected]; @@ -288,7 +291,8 @@ public function dataGetShare() { 'storage' => 101, 'mail_send' => 0, 'uid_file_owner' => 'ownerId', - 'displayname_file_owner' => 'ownerDisplay' + 'displayname_file_owner' => 'ownerDisplay', + 'mimetype' => 'myFolderMimeType', ]; $data[] = [$share, $expected]; @@ -333,7 +337,8 @@ public function dataGetShare() { 'mail_send' => 0, 'url' => 'url', 'uid_file_owner' => 'ownerId', - 'displayname_file_owner' => 'ownerDisplay' + 'displayname_file_owner' => 'ownerDisplay', + 'mimetype' => 'myFolderMimeType', ]; $data[] = [$share, $expected]; @@ -1514,6 +1519,9 @@ public function dataFormatShare() { $folder = $this->getMock('\OCP\Files\Folder'); $parent = $this->getMock('\OCP\Files\Folder'); + $file->method('getMimeType')->willReturn('myMimeType'); + $folder->method('getMimeType')->willReturn('myFolderMimeType'); + $file->method('getPath')->willReturn('file'); $folder->method('getPath')->willReturn('folder'); @@ -1578,6 +1586,7 @@ public function dataFormatShare() { 'share_with' => 'recipient', 'share_with_displayname' => 'recipient', 'mail_send' => 0, + 'mimetype' => 'myMimeType', ], $share, [], false ]; @@ -1606,6 +1615,7 @@ public function dataFormatShare() { 'share_with' => 'recipient', 'share_with_displayname' => 'recipientDN', 'mail_send' => 0, + 'mimetype' => 'myMimeType', ], $share, [ ['owner', $owner], ['initiator', $initiator], @@ -1649,6 +1659,7 @@ public function dataFormatShare() { 'share_with' => 'recipient', 'share_with_displayname' => 'recipient', 'mail_send' => 0, + 'mimetype' => 'myMimeType', ], $share, [], false ]; @@ -1687,6 +1698,7 @@ public function dataFormatShare() { 'share_with' => 'recipient', 'share_with_displayname' => 'recipient', 'mail_send' => 0, + 'mimetype' => 'myMimeType', ], $share, [], false ]; @@ -1727,7 +1739,8 @@ public function dataFormatShare() { 'share_with' => 'mypassword', 'share_with_displayname' => 'mypassword', 'mail_send' => 0, - 'url' => 'myLink' + 'url' => 'myLink', + 'mimetype' => 'myMimeType', ], $share, [], false ]; @@ -1766,6 +1779,7 @@ public function dataFormatShare() { 'share_with' => 'user@server.com', 'share_with_displayname' => 'user@server.com', 'mail_send' => 0, + 'mimetype' => 'myFolderMimeType', ], $share, [], false ]; From b315a5ee29b346b7f6bcc7b56d5f369fac8bdec9 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 9 Mar 2016 15:13:07 +0100 Subject: [PATCH 052/286] Add base rewrite rule only when RewriteBase is defined In case Apache is configured with an `Alias` such as with the ownCloud packages the rewrite rules will fail when no valid RewriteBase is configured. --- .htaccess | 1 - lib/private/setup.php | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.htaccess b/.htaccess index ec33fe31e15bf..085467e91cad6 100644 --- a/.htaccess +++ b/.htaccess @@ -65,7 +65,6 @@ RewriteCond %{REQUEST_FILENAME} !/updater/ RewriteCond %{REQUEST_FILENAME} !/ocs-provider/ RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.* - RewriteRule .* index.php [PT,E=PATH_INFO:$1] AddType image/svg+xml svg svgz diff --git a/lib/private/setup.php b/lib/private/setup.php index b9f8828227e63..8a10a9cfbecd0 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -422,8 +422,9 @@ public static function updateHtaccess() { // Add rewrite base $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; - $content.="\n"; - $content.="\n RewriteBase ".$webRoot; + $content .= "\n"; + $content .= "\n RewriteRule .* index.php [PT,E=PATH_INFO:$1]"; + $content .= "\n RewriteBase ".$webRoot; $content .= "\n "; $content .= "\n SetEnv front_controller_active true"; $content .= "\n "; From f3743685685cce57d385b92b363ece0520e4f823 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 9 Mar 2016 15:40:34 +0100 Subject: [PATCH 053/286] Do not set response status in CLI in case of error --- lib/base.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index b462a49fc9b9d..a315ad13a040e 100644 --- a/lib/base.php +++ b/lib/base.php @@ -509,7 +509,9 @@ public static function init() { require_once $vendorAutoLoad; } catch (\RuntimeException $e) { - OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + if (!self::$CLI) { + OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + } // we can't use the template error page here, because this needs the // DI container which isn't available yet print($e->getMessage()); From 09febaad4940af5a4c0b00434867b54c5384f4c4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 10 Mar 2016 10:24:08 +0100 Subject: [PATCH 054/286] Correctly escape join statements and use selectAlias --- apps/dav/lib/caldav/caldavbackend.php | 4 ++-- apps/files_external/service/dbconfigservice.php | 4 ++-- lib/private/repair/oldgroupmembershipshares.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index 521d1b1de5e82..0315baada3d77 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -815,9 +815,9 @@ function calendarQuery($calendarId, array $filters) { function getCalendarObjectByUID($principalUri, $uid) { $query = $this->db->getQueryBuilder(); - $query->select([$query->createFunction('c.`uri` AS `calendaruri`'), $query->createFunction('co.`uri` AS `objecturi`')]) + $query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi') ->from('calendarobjects', 'co') - ->leftJoin('co', 'calendars', 'c', 'co.`calendarid` = c.`id`') + ->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id')) ->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri))) ->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid))); diff --git a/apps/files_external/service/dbconfigservice.php b/apps/files_external/service/dbconfigservice.php index 5bbc3b23682dd..a37c541f045ea 100644 --- a/apps/files_external/service/dbconfigservice.php +++ b/apps/files_external/service/dbconfigservice.php @@ -92,7 +92,7 @@ public function getAdminMounts() { protected function getForQuery(IQueryBuilder $builder, $type, $value) { $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type']) ->from('external_mounts', 'm') - ->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id') + ->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id')) ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT))); if (is_null($value)) { @@ -148,7 +148,7 @@ public function getAdminMountsForMultiple($type, array $values) { $query = $builder->select(['m.mount_id', 'mount_point', 'storage_backend', 'auth_backend', 'priority', 'm.type']) ->from('external_mounts', 'm') - ->innerJoin('m', 'external_applicable', 'a', 'm.mount_id = a.mount_id') + ->innerJoin('m', 'external_applicable', 'a', $builder->expr()->eq('m.mount_id', 'a.mount_id')) ->where($builder->expr()->eq('a.type', $builder->createNamedParameter($type, IQueryBuilder::PARAM_INT))) ->andWhere($builder->expr()->in('a.value', $params)); $query->andWhere($builder->expr()->eq('m.type', $builder->expr()->literal(self::MOUNT_TYPE_ADMIN, IQueryBuilder::PARAM_INT))); diff --git a/lib/private/repair/oldgroupmembershipshares.php b/lib/private/repair/oldgroupmembershipshares.php index bae1bf61a7f81..627645b116d61 100644 --- a/lib/private/repair/oldgroupmembershipshares.php +++ b/lib/private/repair/oldgroupmembershipshares.php @@ -69,7 +69,7 @@ public function run() { $deletedEntries = 0; $query = $this->connection->getQueryBuilder(); - $query->select(['s1.id', $query->createFunction('s1.`share_with` AS `user`'), $query->createFunction('s2.`share_with` AS `group`')]) + $query->select('s1.id')->selectAlias('s1.share_with', 'user')->selectAlias('s2.share_with', 'group') ->from('share', 's1') ->where($query->expr()->isNotNull('s1.parent')) // \OC\Share\Constant::$shareTypeGroupUserUnique === 2 From dd7131512df3aca500e8e53488ca6e854058465d Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 10 Mar 2016 13:06:02 +0100 Subject: [PATCH 055/286] Fix MKCOL for IE11 as well Using https://github.com/owncloud/core/pull/22274 we have to patch the iedavclient.js as well. --- core/js/files/iedavclient.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/js/files/iedavclient.js b/core/js/files/iedavclient.js index e5b3968a19779..9e83f5b9a22bc 100644 --- a/core/js/files/iedavclient.js +++ b/core/js/files/iedavclient.js @@ -39,7 +39,12 @@ for(ii in headers) { xhr.setRequestHeader(ii, headers[ii]); } - xhr.send(body); + + if (body === undefined) { + xhr.send(); + } else { + xhr.send(body); + } return new Promise(function(fulfill, reject) { From 098ce188b73a1ce93fc36c1383a340cdad3079b2 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 10 Mar 2016 15:02:37 +0100 Subject: [PATCH 056/286] Fake LOCK statement for Windows 7, 8 and 10 network mounts * fixes #22596 --- apps/dav/lib/connector/sabre/serverfactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php index fb20ef436e4ae..6ccec0bc0e83a 100644 --- a/apps/dav/lib/connector/sabre/serverfactory.php +++ b/apps/dav/lib/connector/sabre/serverfactory.php @@ -110,6 +110,7 @@ public function createServer($baseUri, if($this->request->isUserAgent([ '/WebDAVFS/', '/Microsoft Office OneNote 2013/', + '/Microsoft-WebDAV-MiniRedir/', ])) { $server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin()); } From 38d137c34c742ebab09d8b65daeee489c5f7da12 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 10 Mar 2016 13:13:38 +0100 Subject: [PATCH 057/286] remove deprecated ldap_sort --- apps/user_ldap/lib/access.php | 8 -------- apps/user_ldap/lib/ildapwrapper.php | 8 -------- apps/user_ldap/lib/ldap.php | 15 +-------------- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 8409e6ce3d88c..135eca1e625e9 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -1025,14 +1025,6 @@ private function search($filter, $base, $attr = null, $limit = null, $offset = n return array(); } - // Do the server-side sorting - foreach(array_reverse($attr) as $sortAttr){ - foreach($sr as $searchResource) { - $this->ldap->sort($cr, $searchResource, $sortAttr); - } - } - - foreach($sr as $res) { $findings = array_merge($findings, $this->ldap->getEntries($cr , $res )); } diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php index 44ec08f59fd5b..d607a3fdb66a4 100644 --- a/apps/user_ldap/lib/ildapwrapper.php +++ b/apps/user_ldap/lib/ildapwrapper.php @@ -178,14 +178,6 @@ public function setOption($link, $option, $value); */ public function startTls($link); - /** - * Sort the result of a LDAP search - * @param resource $link LDAP link resource - * @param resource $result LDAP result resource - * @param string $sortFilter attribute to use a key in sort - */ - public function sort($link, $result, $sortFilter); - /** * Unbind from LDAP directory * @param resource $link LDAP link resource diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php index ad8c338b587ea..383d71ca6ebb1 100644 --- a/apps/user_ldap/lib/ldap.php +++ b/apps/user_ldap/lib/ldap.php @@ -200,16 +200,6 @@ public function setOption($link, $option, $value) { return $this->invokeLDAPMethod('set_option', $link, $option, $value); } - /** - * @param LDAP $link - * @param LDAP $result - * @param string $sortFilter - * @return mixed - */ - public function sort($link, $result, $sortFilter) { - return $this->invokeLDAPMethod('sort', $link, $result, $sortFilter); - } - /** * @param LDAP $link * @return mixed|true @@ -283,10 +273,7 @@ private function postFunctionCall() { $errorCode = ldap_errno($this->curArgs[0]); $errorMsg = ldap_error($this->curArgs[0]); if($errorCode !== 0) { - if($this->curFunc === 'ldap_sort' && $errorCode === -4) { - //You can safely ignore that decoding error. - //… says https://bugs.php.net/bug.php?id=18023 - } else if($this->curFunc === 'ldap_get_entries' + if($this->curFunc === 'ldap_get_entries' && $errorCode === -4) { } else if ($errorCode === 32) { //for now From 7126b64088fbde6beac868b97b2f7a7b790da1d2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 10 Mar 2016 13:42:09 +0100 Subject: [PATCH 058/286] Allow to migrate calendars of all users --- apps/dav/command/migratecalendars.php | 4 ++-- apps/dav/command/syncbirthdaycalendar.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/dav/command/migratecalendars.php b/apps/dav/command/migratecalendars.php index 5e7f6e9b6974d..d887309ac3ea2 100644 --- a/apps/dav/command/migratecalendars.php +++ b/apps/dav/command/migratecalendars.php @@ -61,8 +61,8 @@ protected function configure() { protected function execute(InputInterface $input, OutputInterface $output) { $this->service->setup(); - if ($input->hasArgument('user')) { - $user = $input->getArgument('user'); + $user = $input->getArgument('user'); + if (!is_null($user)) { if (!$this->userManager->userExists($user)) { throw new \InvalidArgumentException("User <$user> in unknown."); } diff --git a/apps/dav/command/syncbirthdaycalendar.php b/apps/dav/command/syncbirthdaycalendar.php index 66ab540b9ad4c..90a73a3eeb3dc 100644 --- a/apps/dav/command/syncbirthdaycalendar.php +++ b/apps/dav/command/syncbirthdaycalendar.php @@ -61,8 +61,8 @@ protected function configure() { * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { - if ($input->hasArgument('user')) { - $user = $input->getArgument('user'); + $user = $input->getArgument('user'); + if (!is_null($user)) { if (!$this->userManager->userExists($user)) { throw new \InvalidArgumentException("User <$user> in unknown."); } From 8465f9b6c60ed12b575c8c3267cf7c32bfb2c2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 9 Mar 2016 18:12:39 +0100 Subject: [PATCH 059/286] fixes #23020 --- apps/dav/lib/caldav/caldavbackend.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index 521d1b1de5e82..e9a9cb2378bbe 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -1294,7 +1294,7 @@ protected function getDenormalizedData($calendarData) { if (!$componentType) { throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } - if ($componentType === 'VEVENT') { + if ($componentType === 'VEVENT' && $component->DTSTART) { $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); // Finding the last occurence is a bit harder if (!isset($component->RRULE)) { From 36b543c4903e3ea8f344578b521aee6f091ff29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 9 Mar 2016 18:13:34 +0100 Subject: [PATCH 060/286] fixes #23004 --- apps/dav/lib/caldav/caldavbackend.php | 2 +- .../tests/unit/caldav/caldavbackendtest.php | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index e9a9cb2378bbe..fdfc8c399eda9 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -1333,7 +1333,7 @@ protected function getDenormalizedData($calendarData) { 'etag' => md5($calendarData), 'size' => strlen($calendarData), 'componentType' => $componentType, - 'firstOccurence' => $firstOccurence, + 'firstOccurence' => is_null($firstOccurence) ? null : max(0, $firstOccurence), 'lastOccurence' => $lastOccurence, 'uid' => $uid, ]; diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index aece738166ae9..87a700a473dc7 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -57,11 +57,11 @@ public function setUp() { ->disableOriginalConstructor() ->setMethods(['getPrincipalByPath', 'getGroupMembership']) ->getMock(); - $this->principal->method('getPrincipalByPath') + $this->principal->expects($this->any())->method('getPrincipalByPath') ->willReturn([ 'uri' => 'principals/best-friend' ]); - $this->principal->method('getGroupMembership') + $this->principal->expects($this->any())->method('getGroupMembership') ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); @@ -446,6 +446,21 @@ public function testScheduling() { $this->assertEquals(0, count($sos)); } + /** + * @dataProvider providesCalDataForGetDenormalizedData + */ + public function testGetDenormalizedData($expectedFirstOccurance, $calData) { + $actual = $this->invokePrivate($this->backend, 'getDenormalizedData', [$calData]); + $this->assertEquals($expectedFirstOccurance, $actual['firstOccurence']); + } + + public function providesCalDataForGetDenormalizedData() { + return [ + [0, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"], + [null, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"] + ]; + } + private function assertAcl($principal, $privilege, $acl) { foreach($acl as $a) { if ($a['principal'] === $principal && $a['privilege'] === $privilege) { From 67c475901765ec12226e4ced4cb826cd85abd50e Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 10 Mar 2016 13:19:08 +0100 Subject: [PATCH 061/286] Add intergration tests --- build/integration/features/sharing-v1.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build/integration/features/sharing-v1.feature b/build/integration/features/sharing-v1.feature index 00e760ce1676a..ba535e83aabe1 100644 --- a/build/integration/features/sharing-v1.feature +++ b/build/integration/features/sharing-v1.feature @@ -65,6 +65,7 @@ Feature: sharing | expiration | +3 days | | url | AN_URL | | token | A_TOKEN | + | mimetype | httpd/unix-directory | Scenario: Creating a new public share with password and adding an expiration date Given user "user0" exists @@ -108,6 +109,7 @@ Feature: sharing | file_parent | A_NUMBER | | displayname_owner | user0 | | url | AN_URL | + | mimetype | httpd/unix-directory | Scenario: Creating a new public share, updating its password and getting its info Given user "user0" exists @@ -137,6 +139,7 @@ Feature: sharing | file_parent | A_NUMBER | | displayname_owner | user0 | | url | AN_URL | + | mimetype | httpd/unix-directory | Scenario: Creating a new public share, updating its permissions and getting its info Given user "user0" exists @@ -166,6 +169,7 @@ Feature: sharing | file_parent | A_NUMBER | | displayname_owner | user0 | | url | AN_URL | + | mimetype | httpd/unix-directory | Scenario: Creating a new public share, updating publicUpload option and getting its info Given user "user0" exists @@ -195,6 +199,7 @@ Feature: sharing | file_parent | A_NUMBER | | displayname_owner | user0 | | url | AN_URL | + | mimetype | httpd/unix-directory | Scenario: getting all shares of a user using that user Given user "user0" exists @@ -272,6 +277,7 @@ Feature: sharing | file_parent | A_NUMBER | | share_with_displayname | user1 | | displayname_owner | user0 | + | mimetype | text/plain | Scenario: keep group permissions in sync Given As an "admin" @@ -302,6 +308,7 @@ Feature: sharing | storage_id | home::user0 | | file_parent | A_NUMBER | | displayname_owner | user0 | + | mimetype | text/plain | Scenario: Sharee can see the share Given user "user0" exists From 62a36ee884ed689da0590b30bb96332c9fe6f0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 10 Mar 2016 12:32:46 +0100 Subject: [PATCH 062/286] The birthday_calendar is read-only --- apps/dav/lib/caldav/calendar.php | 13 +++++++++---- apps/dav/tests/unit/caldav/calendartest.php | 7 ++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 55f1acec3962c..1e87f9b433398 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -22,11 +22,20 @@ namespace OCA\DAV\CalDAV; use OCA\DAV\DAV\Sharing\IShareable; +use Sabre\CalDAV\Backend\BackendInterface; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\PropPatch; class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { + public function __construct(BackendInterface $caldavBackend, $calendarInfo) { + parent::__construct($caldavBackend, $calendarInfo); + + if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) { + $this->calendarInfo['{http://sabredav.org/ns}read-only'] = true; + } + } + /** * Updates the list of shares. * @@ -100,10 +109,6 @@ function getOwner() { } function delete() { - if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) { - throw new Forbidden(); - } - if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { $principal = 'principal:' . parent::getOwner(); $shares = $this->getShares(); diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index c41070ea435fb..e7f4d57067c51 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -32,7 +32,7 @@ public function testDelete() { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); $backend->expects($this->once())->method('updateShares'); - $backend->method('getShares')->willReturn([ + $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:user2'] ]); $calendarInfo = [ @@ -52,7 +52,7 @@ public function testDeleteFromGroup() { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); $backend->expects($this->never())->method('updateShares'); - $backend->method('getShares')->willReturn([ + $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:group2'] ]); $calendarInfo = [ @@ -90,7 +90,8 @@ public function testPropPatch($mutations, $throws) { $calendarInfo = [ '{http://owncloud.org/ns}owner-principal' => 'user1', 'principaluri' => 'user2', - 'id' => 666 + 'id' => 666, + 'uri' => 'default' ]; $c = new Calendar($backend, $calendarInfo); From bd17cc793c48629ebc8a3ef0084d7acff6077460 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 10 Mar 2016 22:18:53 +0100 Subject: [PATCH 063/286] Improved rewrite rule As per https://github.com/owncloud/core/issues/23098 and https://github.com/owncloud/core/issues/23117 --- lib/private/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index 8a10a9cfbecd0..5988a0b2d1de5 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -423,7 +423,7 @@ public static function updateHtaccess() { // Add rewrite base $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; $content .= "\n"; - $content .= "\n RewriteRule .* index.php [PT,E=PATH_INFO:$1]"; + $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; $content .= "\n RewriteBase ".$webRoot; $content .= "\n "; $content .= "\n SetEnv front_controller_active true"; From e89f27e191c363ddd608a4b29e5cd9e683d48715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 10 Mar 2016 20:53:56 +0100 Subject: [PATCH 064/286] getOwner is not available on FileHome - fixes #23116 --- apps/dav/lib/connector/sabre/filesplugin.php | 20 +++---- apps/dav/lib/files/fileshome.php | 5 ++ .../unit/connector/sabre/filesplugin.php | 52 ++++++++++++++++++- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php index 4b05922adfda5..e973b4e86826e 100644 --- a/apps/dav/lib/connector/sabre/filesplugin.php +++ b/apps/dav/lib/connector/sabre/filesplugin.php @@ -235,6 +235,16 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) $propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) { return $node->getEtag(); }); + + $propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) { + $owner = $node->getOwner(); + return $owner->getUID(); + }); + $propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) { + $owner = $node->getOwner(); + $displayName = $owner->getDisplayName(); + return $displayName; + }); } if ($node instanceof \OCA\DAV\Connector\Sabre\File) { @@ -267,16 +277,6 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) return $node->getSize(); }); } - - $propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) { - $owner = $node->getOwner(); - return $owner->getUID(); - }); - $propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) { - $owner = $node->getOwner(); - $displayName = $owner->getDisplayName(); - return $displayName; - }); } /** diff --git a/apps/dav/lib/files/fileshome.php b/apps/dav/lib/files/fileshome.php index d56b95881c359..ef572d6618b1e 100644 --- a/apps/dav/lib/files/fileshome.php +++ b/apps/dav/lib/files/fileshome.php @@ -28,6 +28,11 @@ class FilesHome implements ICollection { + /** + * @var array + */ + private $principalInfo; + /** * FilesHome constructor. * diff --git a/apps/dav/tests/unit/connector/sabre/filesplugin.php b/apps/dav/tests/unit/connector/sabre/filesplugin.php index c363ece374a62..0a790ec6fc951 100644 --- a/apps/dav/tests/unit/connector/sabre/filesplugin.php +++ b/apps/dav/tests/unit/connector/sabre/filesplugin.php @@ -109,8 +109,6 @@ private function createTestNode($class) { return $node; } - /** - */ public function testGetPropertiesForFile() { $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); @@ -165,6 +163,56 @@ public function testGetPropertiesForFile() { $this->assertEquals(array(self::SIZE_PROPERTYNAME), $propFind->get404Properties()); } + public function testGetPropertiesForFileHome() { + $node = $this->createTestNode('\OCA\DAV\Files\FilesHome'); + + $propFind = new \Sabre\DAV\PropFind( + '/dummyPath', + array( + self::GETETAG_PROPERTYNAME, + self::FILEID_PROPERTYNAME, + self::INTERNAL_FILEID_PROPERTYNAME, + self::SIZE_PROPERTYNAME, + self::PERMISSIONS_PROPERTYNAME, + self::DOWNLOADURL_PROPERTYNAME, + self::OWNER_ID_PROPERTYNAME, + self::OWNER_DISPLAY_NAME_PROPERTYNAME + ), + 0 + ); + + $user = $this->getMockBuilder('\OC\User\User') + ->disableOriginalConstructor()->getMock(); + $user->expects($this->never())->method('getUID'); + $user->expects($this->never())->method('getDisplayName'); + $node->expects($this->never())->method('getDirectDownload'); + $node->expects($this->never())->method('getOwner'); + $node->expects($this->never())->method('getSize'); + + $this->plugin->handleGetProperties( + $propFind, + $node + ); + + $this->assertEquals(null, $propFind->get(self::GETETAG_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::FILEID_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::INTERNAL_FILEID_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::SIZE_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::PERMISSIONS_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::DOWNLOADURL_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::OWNER_ID_PROPERTYNAME)); + $this->assertEquals(null, $propFind->get(self::OWNER_DISPLAY_NAME_PROPERTYNAME)); + $this->assertEquals(['{DAV:}getetag', + '{http://owncloud.org/ns}id', + '{http://owncloud.org/ns}fileid', + '{http://owncloud.org/ns}size', + '{http://owncloud.org/ns}permissions', + '{http://owncloud.org/ns}downloadURL', + '{http://owncloud.org/ns}owner-id', + '{http://owncloud.org/ns}owner-display-name' + ], $propFind->get404Properties()); + } + public function testGetPropertiesStorageNotAvailable() { $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); From b0c7eba7d0cfbc6f3aae680944d9bb6fc064309f Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Thu, 10 Mar 2016 13:02:42 +0100 Subject: [PATCH 065/286] add title and color to birthday calendar --- apps/dav/lib/caldav/birthdayservice.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/dav/lib/caldav/birthdayservice.php b/apps/dav/lib/caldav/birthdayservice.php index 3b0a2a10e1cbd..09bed2430e4bf 100644 --- a/apps/dav/lib/caldav/birthdayservice.php +++ b/apps/dav/lib/caldav/birthdayservice.php @@ -91,6 +91,11 @@ public function onCardDeleted($addressBookId, $cardUri) { * @throws \Sabre\DAV\Exception\BadRequest */ public function ensureCalendarExists($principal, $id, $properties) { + $properties = array_merge([ + '{DAV:}displayname' => 'Contact birthdays', + '{http://apple.com/ns/ical/}calendar-color' => '#FFFFCA', + ], $properties); + $book = $this->calDavBackEnd->getCalendarByUri($principal, $id); if (!is_null($book)) { return $book; From 9bc99bb297578145d019ee51c0830044bbc84e7c Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 10 Mar 2016 22:32:29 +0100 Subject: [PATCH 066/286] Explicitly check for port The setup uses `\OCP\IRequest::getInsecureServerHost` which in some cases can also include a port. This makes the trusted domain check fail thus. I've decided to add this here that way because adjusting the setup would require parsing the host properly. This is not something that can be done very good in PHP. Check the following example for why `parse_url` is not our friend: https://3v4l.org/k501Z --- lib/private/security/trusteddomainhelper.php | 6 ++++++ tests/lib/security/trusteddomainhelper.php | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/private/security/trusteddomainhelper.php b/lib/private/security/trusteddomainhelper.php index 885ceee23c34b..409628677a764 100644 --- a/lib/private/security/trusteddomainhelper.php +++ b/lib/private/security/trusteddomainhelper.php @@ -78,6 +78,12 @@ public function isTrustedDomain($domainWithPort) { if (preg_match(Request::REGEX_LOCALHOST, $domain) === 1) { return true; } + + // Compare with port appended + if(in_array($domainWithPort, $trustedList, true)) { + return true; + } + return in_array($domain, $trustedList, true); } diff --git a/tests/lib/security/trusteddomainhelper.php b/tests/lib/security/trusteddomainhelper.php index 52a8f1be63014..3581211ce61e0 100644 --- a/tests/lib/security/trusteddomainhelper.php +++ b/tests/lib/security/trusteddomainhelper.php @@ -42,7 +42,12 @@ public function testIsTrustedDomain($trustedDomains, $testDomain, $result) { * @return array */ public function trustedDomainDataProvider() { - $trustedHostTestList = ['host.one.test', 'host.two.test', '[1fff:0:a88:85a3::ac1f]']; + $trustedHostTestList = [ + 'host.one.test', + 'host.two.test', + '[1fff:0:a88:85a3::ac1f]', + 'host.three.test:443', + ]; return [ // empty defaults to false with 8.1 [null, 'host.one.test:8080', false], @@ -56,6 +61,9 @@ public function trustedDomainDataProvider() { [$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]', true], [$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801', true], [$trustedHostTestList, '[1fff:0:a88:85a3::ac1f]:801:34', false], + [$trustedHostTestList, 'host.three.test:443', true], + [$trustedHostTestList, 'host.three.test:80', false], + [$trustedHostTestList, 'host.three.test', false], // trust localhost regardless of trust list [$trustedHostTestList, 'localhost', true], [$trustedHostTestList, 'localhost:8080', true], From f98471892162191ab8f1aaf34ee6e6f487bb962f Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 11 Mar 2016 17:39:35 +0100 Subject: [PATCH 067/286] Adjust wording a bit **Before:** > Your PHP version (5.4.16) is no longer supported by PHP. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP. **After:** > You are currently running PHP 5.4.0. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by the PHP Group as soon as your distribution supports it. Fixes https://github.com/owncloud/enterprise/issues/1170 --- core/js/setupchecks.js | 2 +- core/js/tests/specs/setupchecksSpec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index c29c4137c587a..41f6a6e07b685 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -117,7 +117,7 @@ } if(data.phpSupported && data.phpSupported.eol) { messages.push({ - msg: t('core', 'Your PHP version ({version}) is no longer supported by PHP. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP.', {version: data.phpSupported.version, phpLink: 'https://secure.php.net/supported-versions.php'}), + msg: t('core', 'You are currently running PHP {version}. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by the PHP Group as soon as your distribution supports it.', {version: data.phpSupported.version, phpLink: 'https://secure.php.net/supported-versions.php'}), type: OC.SetupChecks.MESSAGE_TYPE_INFO }); } diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index fa0974c90f990..05be46781d6cf 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -358,7 +358,7 @@ describe('OC.SetupChecks tests', function() { async.done(function( data, s, x ){ expect(data).toEqual([{ - msg: 'Your PHP version (5.4.0) is no longer supported by PHP. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP.', + msg: 'You are currently running PHP 5.4.0. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by the PHP Group as soon as your distribution supports it.', type: OC.SetupChecks.MESSAGE_TYPE_INFO }]); done(); From 69cf557d0bbebc71f18e8a0448467d624ae2ef09 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 14 Mar 2016 11:05:46 +0100 Subject: [PATCH 068/286] Shorter cache key for URL entries --- lib/private/route/cachingrouter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/route/cachingrouter.php b/lib/private/route/cachingrouter.php index 4c702bb8e04e9..d6270dcf2c727 100644 --- a/lib/private/route/cachingrouter.php +++ b/lib/private/route/cachingrouter.php @@ -49,7 +49,7 @@ public function __construct($cache, ILogger $logger) { */ public function generate($name, $parameters = array(), $absolute = false) { asort($parameters); - $key = $this->context->getHost() . '#' . $this->context->getBaseUrl() . $name . json_encode($parameters) . intval($absolute); + $key = $this->context->getHost() . '#' . $this->context->getBaseUrl() . $name . sha1(json_encode($parameters)) . intval($absolute); if ($this->cache->hasKey($key)) { return $this->cache->get($key); } else { From 5b593450c3b99044f654a639fd86553e6351b188 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 10 Mar 2016 14:55:31 +0100 Subject: [PATCH 069/286] Return the correct group casing in sharee api --- apps/files_sharing/api/sharees.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php index 28dfd4af95514..88cf783b2a12c 100644 --- a/apps/files_sharing/api/sharees.php +++ b/apps/files_sharing/api/sharees.php @@ -223,10 +223,10 @@ protected function getGroups($search) { foreach ($groups as $gid) { if (strtolower($gid) === $search) { $this->result['exact']['groups'][] = [ - 'label' => $search, + 'label' => $gid, 'value' => [ 'shareType' => Share::SHARE_TYPE_GROUP, - 'shareWith' => $search, + 'shareWith' => $gid, ], ]; } else { From 8e49a99896eb2f0cdb43958d49d63341a4c7f342 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Mar 2016 13:58:13 +0100 Subject: [PATCH 070/286] Add integration tests for sharee API --- .../features/bootstrap/Sharing.php | 51 ++++++ build/integration/features/sharees.feature | 148 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 build/integration/features/sharees.feature diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php index da2e9ca109451..884d69597fc15 100644 --- a/build/integration/features/bootstrap/Sharing.php +++ b/build/integration/features/bootstrap/Sharing.php @@ -442,5 +442,56 @@ public function shareIdsShouldMatch() throw new \Excetion('Expected the same link share to be returned'); } } + + /** + * @When /^getting sharees for$/ + * @param \Behat\Gherkin\Node\TableNode $body + */ + public function whenGettingShareesFor($body) { + $url = '/apps/files_sharing/api/v1/sharees'; + if ($body instanceof \Behat\Gherkin\Node\TableNode) { + $parameters = []; + foreach ($body->getRowsHash() as $key => $value) { + $parameters[] = $key . '=' . $value; + } + if (!empty($parameters)) { + $url .= '?' . implode('&', $parameters); + } + } + + $this->sendingTo('GET', $url); + } + + /** + * @Then /^"([^"]*)" sharees returned (are|is empty)$/ + * @param string $shareeType + * @param string $isEmpty + * @param \Behat\Gherkin\Node\TableNode|null $shareesList + */ + public function thenListOfSharees($shareeType, $isEmpty, $shareesList = null) { + if ($isEmpty !== 'is empty') { + $sharees = $shareesList->getRows(); + $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); + PHPUnit_Framework_Assert::assertEquals($sharees, $respondedArray); + } else { + $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); + PHPUnit_Framework_Assert::assertEmpty($respondedArray); + } + } + + public function getArrayOfShareesResponded(ResponseInterface $response, $shareeType) { + $elements = $response->xml()->data; + $elements = json_decode(json_encode($elements), 1); + if (strpos($shareeType, 'exact ') === 0) { + $elements = $elements['exact']; + $shareeType = substr($shareeType, 6); + } + + $sharees = []; + foreach ($elements[$shareeType] as $element) { + $sharees[] = [$element['label'], $element['value']['shareType'], $element['value']['shareWith']]; + } + return $sharees; + } } diff --git a/build/integration/features/sharees.feature b/build/integration/features/sharees.feature new file mode 100644 index 0000000000000..ea3a2c9bcea02 --- /dev/null +++ b/build/integration/features/sharees.feature @@ -0,0 +1,148 @@ +Feature: sharees + Background: + Given using api version "1" + + Scenario: Search without exact match + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | Sharee | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And "exact users" sharees returned is empty + And "users" sharees returned are + | Sharee1 | 0 | Sharee1 | + And "exact groups" sharees returned is empty + And "groups" sharees returned are + | ShareeGroup | 1 | ShareeGroup | + And "exact remotes" sharees returned is empty + And "remotes" sharees returned is empty + + Scenario: Search without exact match not-exact casing + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | sharee | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And "exact users" sharees returned is empty + And "users" sharees returned are + | Sharee1 | 0 | Sharee1 | + And "exact groups" sharees returned is empty + And "groups" sharees returned are + | ShareeGroup | 1 | ShareeGroup | + And "exact remotes" sharees returned is empty + And "remotes" sharees returned is empty + + Scenario: Search with exact match + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | Sharee1 | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned are + | Sharee1 | 0 | Sharee1 | + Then "users" sharees returned is empty + Then "exact groups" sharees returned is empty + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned is empty + Then "remotes" sharees returned is empty + + Scenario: Search with exact match not-exact casing + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | sharee1 | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned are + | Sharee1 | 0 | Sharee1 | + Then "users" sharees returned is empty + Then "exact groups" sharees returned is empty + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned is empty + Then "remotes" sharees returned is empty + + Scenario: Search with exact match not-exact casing group + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | shareegroup | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned is empty + Then "users" sharees returned is empty + Then "exact groups" sharees returned are + | ShareeGroup | 1 | ShareeGroup | + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned is empty + Then "remotes" sharees returned is empty + + Scenario: Search with "self" + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "Sharee1" + When getting sharees for + | search | Sharee1 | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned are + | Sharee1 | 0 | Sharee1 | + Then "users" sharees returned is empty + Then "exact groups" sharees returned is empty + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned is empty + Then "remotes" sharees returned is empty + + Scenario: Remote sharee for files + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | test@localhost | + | itemType | file | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned is empty + Then "users" sharees returned is empty + Then "exact groups" sharees returned is empty + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned are + | test@localhost | 6 | test@localhost | + Then "remotes" sharees returned is empty + + Scenario: Remote sharee for calendars not allowed + Given user "test" exists + And user "Sharee1" exists + And group "ShareeGroup" exists + And As an "test" + When getting sharees for + | search | test@localhost | + | itemType | calendar | + Then the OCS status code should be "100" + And the HTTP status code should be "200" + Then "exact users" sharees returned is empty + Then "users" sharees returned is empty + Then "exact groups" sharees returned is empty + Then "groups" sharees returned is empty + Then "exact remotes" sharees returned is empty + Then "remotes" sharees returned is empty From a9ed80869a02e6ef44b53bdf1f47cb6e179a6bfd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 11 Mar 2016 09:11:43 +0100 Subject: [PATCH 071/286] Correctly lower the search input as well --- apps/files_sharing/api/sharees.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php index 88cf783b2a12c..718be4dece991 100644 --- a/apps/files_sharing/api/sharees.php +++ b/apps/files_sharing/api/sharees.php @@ -147,8 +147,8 @@ protected function getUsers($search) { $foundUserById = false; foreach ($users as $uid => $userDisplayName) { - if (strtolower($uid) === $search || strtolower($userDisplayName) === $search) { - if (strtolower($uid) === $search) { + if (strtolower($uid) === strtolower($search) || strtolower($userDisplayName) === strtolower($search)) { + if (strtolower($uid) === strtolower($search)) { $foundUserById = true; } $this->result['exact']['users'][] = [ @@ -221,7 +221,7 @@ protected function getGroups($search) { } foreach ($groups as $gid) { - if (strtolower($gid) === $search) { + if (strtolower($gid) === strtolower($search)) { $this->result['exact']['groups'][] = [ 'label' => $gid, 'value' => [ @@ -282,8 +282,8 @@ protected function getRemote($search) { } foreach ($cloudIds as $cloudId) { list(, $serverUrl) = $this->splitUserRemote($cloudId); - if (strtolower($contact['FN']) === $search || strtolower($cloudId) === $search) { - if (strtolower($cloudId) === $search) { + if (strtolower($contact['FN']) === strtolower($search) || strtolower($cloudId) === strtolower($search)) { + if (strtolower($cloudId) === strtolower($search)) { $foundRemoteById = true; } $this->result['exact']['remotes'][] = [ From 9190885b4e0bdcec4c7f3fafd3f0eb2dd727c716 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 14 Mar 2016 12:34:11 +0100 Subject: [PATCH 072/286] Fix errors in memcached implementation --- lib/private/memcache/memcached.php | 21 +++++++++++++++++---- tests/lib/memcache/cache.php | 9 ++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php index c13be68b47fd1..a30f9da7ed745 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/memcache/memcached.php @@ -88,7 +88,9 @@ public function hasKey($key) { public function remove($key) { $result= self::$cache->delete($this->getNamespace() . $key); - $this->verifyReturnCode(); + if (self::$cache->getResultCode() !== \Memcached::RES_NOTFOUND) { + $this->verifyReturnCode(); + } return $result; } @@ -124,10 +126,13 @@ public function clear($prefix = '') { * @param mixed $value * @param int $ttl Time To Live in seconds. Defaults to 60*60*24 * @return bool + * @throws \Exception */ public function add($key, $value, $ttl = 0) { $result = self::$cache->add($this->getPrefix() . $key, $value, $ttl); - $this->verifyReturnCode(); + if (self::$cache->getResultCode() !== \Memcached::RES_NOTSTORED) { + $this->verifyReturnCode(); + } return $result; } @@ -141,7 +146,11 @@ public function add($key, $value, $ttl = 0) { public function inc($key, $step = 1) { $this->add($key, 0); $result = self::$cache->increment($this->getPrefix() . $key, $step); - $this->verifyReturnCode(); + + if (self::$cache->getResultCode() !== \Memcached::RES_SUCCESS) { + return false; + } + return $result; } @@ -154,7 +163,11 @@ public function inc($key, $step = 1) { */ public function dec($key, $step = 1) { $result = self::$cache->decrement($this->getPrefix() . $key, $step); - $this->verifyReturnCode(); + + if (self::$cache->getResultCode() !== \Memcached::RES_SUCCESS) { + return false; + } + return $result; } diff --git a/tests/lib/memcache/cache.php b/tests/lib/memcache/cache.php index 3ff72ee931c7b..725b0fbbf57ed 100644 --- a/tests/lib/memcache/cache.php +++ b/tests/lib/memcache/cache.php @@ -39,6 +39,11 @@ public function testDoesNotExistAfterRemove() { $this->assertFalse($this->instance->hasKey('foo')); } + public function testRemoveNonExisting() { + $this->instance->remove('foo'); + $this->assertFalse($this->instance->hasKey('foo')); + } + public function testArrayAccessSet() { $this->instance['foo'] = 'bar'; $this->assertEquals('bar', $this->instance->get('foo')); @@ -72,7 +77,9 @@ public function testInc() { $this->assertEquals(1, $this->instance->inc('foo')); $this->assertEquals(1, $this->instance->get('foo')); $this->assertEquals(2, $this->instance->inc('foo')); + $this->assertEquals(2, $this->instance->get('foo')); $this->assertEquals(12, $this->instance->inc('foo', 10)); + $this->assertEquals(12, $this->instance->get('foo')); $this->instance->set('foo', 'bar'); $this->assertFalse($this->instance->inc('foo')); @@ -80,7 +87,7 @@ public function testInc() { } public function testDec() { - $this->assertEquals(false, $this->instance->dec('foo')); + $this->assertFalse($this->instance->dec('foo')); $this->instance->set('foo', 20); $this->assertEquals(19, $this->instance->dec('foo')); $this->assertEquals(19, $this->instance->get('foo')); From 3a73f977067d328dc77b6f69519801169d9cf657 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 12 Mar 2016 22:45:07 +0100 Subject: [PATCH 073/286] Verify the getResponse returns a ResponseInterface Can also return `null` as per PHPDoc. Regression added by https://github.com/owncloud/core/commit/97f5c095f4018119e15d7c612a685da1dc91a340 Fixes https://github.com/owncloud/core/issues/23145 --- lib/private/files/storage/dav.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index 495419fa865c0..df0f4c7e91d24 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -34,6 +34,7 @@ use Exception; use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Message\ResponseInterface; use OC\Files\Filesystem; use OC\Files\Stream\Close; use Icewind\Streams\IteratorDirectory; @@ -351,7 +352,8 @@ public function fopen($path, $mode) { 'stream' => true ]); } catch (RequestException $e) { - if ($e->getResponse()->getStatusCode() === 404) { + if ($e->getResponse() instanceof ResponseInterface + && $e->getResponse()->getStatusCode() === 404) { return false; } else { throw $e; From effc52257263d16bd9d570f7a9c2bfdaaaf2a143 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 12 Mar 2016 22:29:47 +0100 Subject: [PATCH 074/286] Use proper URLs for search results Fixes https://github.com/owncloud/core/issues/23136 --- lib/private/search/result/file.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/private/search/result/file.php b/lib/private/search/result/file.php index d987d6c8e7394..f1347001eaffb 100644 --- a/lib/private/search/result/file.php +++ b/lib/private/search/result/file.php @@ -79,10 +79,12 @@ public function __construct(FileInfo $data) { $info = pathinfo($path); $this->id = $data->getId(); $this->name = $info['basename']; - $this->link = \OCP\Util::linkTo( - 'files', - 'index.php', - array('dir' => $info['dirname'], 'scrollto' => $info['basename']) + $this->link = \OC::$server->getURLGenerator()->linkToRoute( + 'files.view.index', + [ + 'dir' => $info['dirname'], + 'scrollto' => $info['basename'], + ] ); $this->permissions = $data->getPermissions(); $this->path = $path; From e1727477ac53e609b22b8708542be0dacd891968 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 7 Mar 2016 11:17:33 +0100 Subject: [PATCH 075/286] Add DAV authenticated also to other scopes Fixes https://github.com/owncloud/core/issues/22893 --- lib/private/api.php | 12 ++++++++++++ lib/private/user.php | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/private/api.php b/lib/private/api.php index 87f2aa9b11843..12a78f1424b33 100644 --- a/lib/private/api.php +++ b/lib/private/api.php @@ -364,6 +364,18 @@ private static function loginUser() { \OC_Util::setUpFS(\OC_User::getUser()); self::$isLoggedIn = true; + /** + * Add DAV authenticated. This should in an ideal world not be + * necessary but the iOS App reads cookies from anywhere instead + * only the DAV endpoint. + * This makes sure that the cookies will be valid for the whole scope + * @see https://github.com/owncloud/core/issues/22893 + */ + \OC::$server->getSession()->set( + \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED, + \OC::$server->getUserSession()->getUser()->getUID() + ); + return \OC_User::getUser(); } } diff --git a/lib/private/user.php b/lib/private/user.php index b91f60e3b9b62..26062f503d28e 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -281,7 +281,20 @@ public static function logout() { */ public static function tryBasicAuthLogin() { if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { - \OC_User::login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + $result = \OC_User::login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); + if($result === true) { + /** + * Add DAV authenticated. This should in an ideal world not be + * necessary but the iOS App reads cookies from anywhere instead + * only the DAV endpoint. + * This makes sure that the cookies will be valid for the whole scope + * @see https://github.com/owncloud/core/issues/22893 + */ + \OC::$server->getSession()->set( + \OCA\DAV\Connector\Sabre\Auth::DAV_AUTHENTICATED, + \OC::$server->getUserSession()->getUser()->getUID() + ); + } } } From e2c557ab82119bda6bafe68b924e8cea3ea7299c Mon Sep 17 00:00:00 2001 From: Phiber2000 Date: Mon, 14 Mar 2016 17:59:40 +0100 Subject: [PATCH 076/286] backport of #23222 (#23225) --- lib/private/log/owncloud.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 5a48f9e1c6df4..6399d7ee588f7 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -76,9 +76,12 @@ public static function write($app, $message, $level) { } catch (Exception $e) { $timezone = new DateTimeZone('UTC'); } - $time = DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", ""), $timezone); + $time = DateTime::createFromFormat("U.u", number_format(microtime(true), 4, ".", "")); if ($time === false) { $time = new DateTime(null, $timezone); + } else { + // apply timezone if $time is created from UNIX timestamp + $time->setTimezone($timezone); } $request = \OC::$server->getRequest(); $reqId = $request->getId(); @@ -90,8 +93,7 @@ public static function write($app, $message, $level) { $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time', 'method', 'url'); - } - else { + } else { $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time'); } $entry = json_encode($entry); From 3a5e90fa03f11017f01a88be607640e4f7a9f0fa Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Mon, 14 Mar 2016 15:19:55 +0100 Subject: [PATCH 077/286] Generate a valid URL for link notification fixes #23197 * Updated unit test --- core/ajax/share.php | 6 +++-- lib/private/share/mailnotifications.php | 13 +++++++++-- tests/lib/share/MailNotificationsTest.php | 27 +++++++++++++++++++---- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 8ece9945c232f..44144b791e291 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -70,7 +70,8 @@ \OC::$server->getL10N('lib'), \OC::$server->getMailer(), \OC::$server->getLogger(), - $defaults + $defaults, + \OC::$server->getURLGenerator() ); $result = $mailNotification->sendInternalShareMail($recipientList, $itemSource, $itemType); @@ -108,7 +109,8 @@ \OC::$server->getL10N('lib'), \OC::$server->getMailer(), \OC::$server->getLogger(), - $defaults + $defaults, + \OC::$server->getURLGenerator() ); $expiration = null; diff --git a/lib/private/share/mailnotifications.php b/lib/private/share/mailnotifications.php index a664d4ebf47ab..f71651e71fcfe 100644 --- a/lib/private/share/mailnotifications.php +++ b/lib/private/share/mailnotifications.php @@ -30,6 +30,7 @@ use DateTime; use OCP\IL10N; +use OCP\IURLGenerator; use OCP\IUser; use OCP\Mail\IMailer; use OCP\ILogger; @@ -57,6 +58,8 @@ class MailNotifications { private $defaults; /** @var ILogger */ private $logger; + /** @var IURLGenerator */ + private $urlGenerator; /** * @param IUser $user @@ -64,17 +67,20 @@ class MailNotifications { * @param IMailer $mailer * @param ILogger $logger * @param Defaults $defaults + * @param IURLGenerator $urlGenerator */ public function __construct(IUser $user, IL10N $l10n, IMailer $mailer, ILogger $logger, - Defaults $defaults) { + Defaults $defaults, + IURLGenerator $urlGenerator) { $this->l = $l10n; $this->user = $user; $this->mailer = $mailer; $this->logger = $logger; $this->defaults = $defaults; + $this->urlGenerator = $urlGenerator; $this->replyTo = $this->user->getEMailAddress(); $this->senderDisplayName = $this->user->getDisplayName(); @@ -131,7 +137,10 @@ public function sendInternalShareMail($recipientList, $itemSource, $itemType) { ); } - $link = Util::linkToAbsolute('files', 'index.php', $args); + $link = $this->urlGenerator->linkToRouteAbsolute( + 'files.view.index', + $args + ); list($htmlBody, $textBody) = $this->createMailBody($filename, $link, $expiration, 'internal'); diff --git a/tests/lib/share/MailNotificationsTest.php b/tests/lib/share/MailNotificationsTest.php index 66bec8653fb60..8c8ca78f39af5 100644 --- a/tests/lib/share/MailNotificationsTest.php +++ b/tests/lib/share/MailNotificationsTest.php @@ -25,6 +25,7 @@ use OCP\Mail\IMailer; use OCP\ILogger; use OCP\Defaults; +use OCP\IURLGenerator; /** * Class MailNotificationsTest @@ -40,6 +41,8 @@ class MailNotificationsTest extends \Test\TestCase { private $defaults; /** @var IUser | PHPUnit_Framework_MockObject_MockObject */ private $user; + /** @var IURLGenerator | PHPUnit_Framework_MockObject_MockObject */ + private $urlGenerator; public function setUp() { @@ -55,6 +58,7 @@ public function setUp() { ->disableOriginalConstructor()->getMock(); $this->user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor()->getMock(); + $this->urlGenerator = $this->getMock('\OCP\IURLGenerator'); $this->l10n->expects($this->any()) ->method('t') @@ -116,7 +120,8 @@ public function testSendLinkShareMailWithoutReplyTo() { $this->l10n, $this->mailer, $this->logger, - $this->defaults + $this->defaults, + $this->urlGenerator ); $this->assertSame([], $mailNotifications->sendLinkShareMail('lukas@owncloud.com', 'MyFile', 'https://owncloud.com/file/?foo=bar', 3600)); @@ -180,7 +185,8 @@ public function testSendLinkShareMailWithReplyTo($to, array $expectedTo) { $this->l10n, $this->mailer, $this->logger, - $this->defaults + $this->defaults, + $this->urlGenerator ); $this->assertSame([], $mailNotifications->sendLinkShareMail($to, 'MyFile', 'https://owncloud.com/file/?foo=bar', 3600)); } @@ -193,7 +199,8 @@ public function testSendLinkShareMailException() { $this->l10n, $this->mailer, $this->logger, - $this->defaults + $this->defaults, + $this->urlGenerator ); $this->assertSame(['lukas@owncloud.com'], $mailNotifications->sendLinkShareMail('lukas@owncloud.com', 'MyFile', 'https://owncloud.com/file/?foo=bar', 3600)); @@ -208,7 +215,9 @@ public function testSendInternalShareMail() { $this->l10n, $this->mailer, $this->logger, - $this->defaults]); + $this->defaults, + $this->urlGenerator + ]); $mailNotifications->method('getItemSharedWithUser') ->withAnyParameters() @@ -227,6 +236,16 @@ public function testSendInternalShareMail() { ->method('getDisplayName') ->willReturn('Recipient'); + $this->urlGenerator->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with( + $this->equalTo('files.view.index'), + $this->equalTo([ + 'dir' => '/', + 'scrollto' => 'welcome.txt' + ]) + ); + $recipientList = [$recipient]; $result = $mailNotifications->sendInternalShareMail($recipientList, '3', 'file'); $this->assertSame([], $result); From f29440dbbc28c865c5d809b142060114392ccc1b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 9 Mar 2016 16:44:57 +0100 Subject: [PATCH 078/286] dont break when there is an invalid share --- apps/files_external/lib/failedcache.php | 13 ++++++++++++- apps/files_sharing/lib/sharedstorage.php | 24 +++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/apps/files_external/lib/failedcache.php b/apps/files_external/lib/failedcache.php index 0f59495e5952d..2fddb3eca89ef 100644 --- a/apps/files_external/lib/failedcache.php +++ b/apps/files_external/lib/failedcache.php @@ -29,6 +29,17 @@ * Storage placeholder to represent a missing precondition, storage unavailable */ class FailedCache implements ICache { + private $visible; + + /** + * FailedCache constructor. + * + * @param bool $visible + */ + public function __construct($visible = true) { + $this->visible = $visible; + } + public function getNumericStorageId() { return -1; @@ -41,7 +52,7 @@ public function get($file) { 'size' => 0, 'mimetype' => 'httpd/unix-directory', 'mimepart' => 'httpd', - 'permissions' => Constants::PERMISSION_READ, + 'permissions' => $this->visible ? Constants::PERMISSION_READ : 0, 'mtime' => time() ]); } else { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 6998f94698edc..6257320ca4e9b 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -31,6 +31,7 @@ namespace OC\Files\Storage; use OC\Files\Filesystem; +use OCA\Files_External\Lib\FailedCache; use OCA\Files_Sharing\ISharedStorage; use OCP\Constants; use OCP\Files\Cache\ICacheEntry; @@ -67,10 +68,16 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { */ private $sourceStorage; + /** + * @var \OCP\ILogger + */ + private $logger; + public function __construct($arguments) { $this->share = $arguments['share']; $this->ownerView = $arguments['ownerView']; $this->user = $arguments['user']; + $this->logger = \OC::$server->getLogger(); } private function init() { @@ -78,15 +85,19 @@ private function init() { return; } $this->initialized = true; - Filesystem::initMountPoints($this->share['uid_owner']); - $sourcePath = $this->ownerView->getPath($this->share['file_source']); - list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); - $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); + try { + Filesystem::initMountPoints($this->share['uid_owner']); + $sourcePath = $this->ownerView->getPath($this->share['file_source']); + list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); + $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); + } catch (\Exception $e) { + $this->logger->logException($e); + } } private function isValid() { $this->init(); - return ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; + return $this->sourceRootInfo && ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; } /** @@ -568,6 +579,9 @@ public function hasUpdated($path, $time) { public function getCache($path = '', $storage = null) { $this->init(); + if (is_null($this->sourceStorage)) { + return new FailedCache(false); + } if (!$storage) { $storage = $this; } From 9d688e655d75cf25c9601067c4cff09749be4d8d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 10 Mar 2016 13:38:48 +0100 Subject: [PATCH 079/286] move failedstorage to core --- apps/files_external/lib/config/configadapter.php | 2 +- apps/files_sharing/lib/sharedstorage.php | 2 +- .../lib => lib/private/files/cache}/failedcache.php | 4 ++-- .../lib => lib/private/files/storage}/failedstorage.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename {apps/files_external/lib => lib/private/files/cache}/failedcache.php (96%) rename {apps/files_external/lib => lib/private/files/storage}/failedstorage.php (99%) diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php index d85e0f4563190..a19a111d3d9fe 100644 --- a/apps/files_external/lib/config/configadapter.php +++ b/apps/files_external/lib/config/configadapter.php @@ -34,7 +34,7 @@ use OCA\Files_external\Service\UserStoragesService; use OCA\Files_External\Service\UserGlobalStoragesService; use OCA\Files_External\Lib\StorageConfig; -use OCA\Files_External\Lib\FailedStorage; +use OC\Files\Storage\FailedStorage; use OCP\Files\StorageNotAvailableException; /** diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 6257320ca4e9b..8f4888d20e21d 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -31,7 +31,7 @@ namespace OC\Files\Storage; use OC\Files\Filesystem; -use OCA\Files_External\Lib\FailedCache; +use OC\Files\Cache\FailedCache; use OCA\Files_Sharing\ISharedStorage; use OCP\Constants; use OCP\Files\Cache\ICacheEntry; diff --git a/apps/files_external/lib/failedcache.php b/lib/private/files/cache/failedcache.php similarity index 96% rename from apps/files_external/lib/failedcache.php rename to lib/private/files/cache/failedcache.php index 2fddb3eca89ef..0386ba3ca324b 100644 --- a/apps/files_external/lib/failedcache.php +++ b/lib/private/files/cache/failedcache.php @@ -19,9 +19,8 @@ * */ -namespace OCA\Files_External\Lib; +namespace OC\Files\Cache; -use OC\Files\Cache\CacheEntry; use OCP\Constants; use OCP\Files\Cache\ICache; @@ -29,6 +28,7 @@ * Storage placeholder to represent a missing precondition, storage unavailable */ class FailedCache implements ICache { + /** @var bool whether to show the failed storage in the ui */ private $visible; /** diff --git a/apps/files_external/lib/failedstorage.php b/lib/private/files/storage/failedstorage.php similarity index 99% rename from apps/files_external/lib/failedstorage.php rename to lib/private/files/storage/failedstorage.php index 20cf43d74b29b..df7f76856d554 100644 --- a/apps/files_external/lib/failedstorage.php +++ b/lib/private/files/storage/failedstorage.php @@ -20,10 +20,10 @@ * */ -namespace OCA\Files_External\Lib; +namespace OC\Files\Storage; +use OC\Files\Cache\FailedCache; use \OCP\Lock\ILockingProvider; -use \OC\Files\Storage\Common; use \OCP\Files\StorageNotAvailableException; /** From 987146d5db56ac95bc388944bf484615139f7ea3 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 9 Mar 2016 10:36:45 +0100 Subject: [PATCH 080/286] Delay check till scanner is used Fixes https://github.com/owncloud/core/issues/22973 and https://github.com/owncloud/core/issues/22987 --- apps/files_sharing/lib/external/scanner.php | 5 ++++- apps/files_sharing/lib/external/storage.php | 5 +---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/lib/external/scanner.php b/apps/files_sharing/lib/external/scanner.php index bfb9e817f0944..1cc6cf8f5f947 100644 --- a/apps/files_sharing/lib/external/scanner.php +++ b/apps/files_sharing/lib/external/scanner.php @@ -36,6 +36,10 @@ class Scanner extends \OC\Files\Cache\Scanner { /** {@inheritDoc} */ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true) { + if(!$this->storage->remoteIsOwnCloud()) { + return parent::scan($path, $recursive, $recursive, $lock); + } + $this->scanAll(); } @@ -90,7 +94,6 @@ public function scanAll() { } if ($data['status'] === 'success') { $this->addResult($data['data'], ''); - } elseif ($data['status'] === 'unsupported') { } else { throw new \Exception( 'Error while scanning remote share: "' . diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index 80ab006f1ca3c..999e7e322923b 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -148,9 +148,6 @@ public function getScanner($path = '', $storage = null) { if (!$storage) { $storage = $this; } - if(!$this->remoteIsOwnCloud()) { - return parent::getScanner($path, $storage); - } if (!isset($this->scanner)) { $this->scanner = new Scanner($storage); } @@ -270,7 +267,7 @@ private function testRemoteUrl($url) { * * @return bool */ - private function remoteIsOwnCloud() { + public function remoteIsOwnCloud() { if(defined('PHPUNIT_RUN') || !$this->testRemoteUrl($this->getRemote() . '/status.php')) { return false; } From 0f372a2a8c26dde1328496eaf59d33044b7ffb08 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 15 Mar 2016 11:23:49 +0100 Subject: [PATCH 081/286] allow group shares, even if not all public keys are available --- apps/encryption/lib/crypto/encryption.php | 6 ++- .../tests/lib/crypto/encryptionTest.php | 38 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php index 10c8c4a290af2..907a6437f5b3f 100644 --- a/apps/encryption/lib/crypto/encryption.php +++ b/apps/encryption/lib/crypto/encryption.php @@ -390,7 +390,11 @@ public function update($path, $uid, array $accessList) { $publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey(); } else { foreach ($accessList['users'] as $user) { - $publicKeys[$user] = $this->keyManager->getPublicKey($user); + try { + $publicKeys[$user] = $this->keyManager->getPublicKey($user); + } catch (PublicKeyMissingException $e) { + $this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage()); + } } } diff --git a/apps/encryption/tests/lib/crypto/encryptionTest.php b/apps/encryption/tests/lib/crypto/encryptionTest.php index 0ce1a2cb76a3f..8a228c2c2159c 100644 --- a/apps/encryption/tests/lib/crypto/encryptionTest.php +++ b/apps/encryption/tests/lib/crypto/encryptionTest.php @@ -304,7 +304,6 @@ public function testUpdate($fileKey, $expected) { $this->assertSame($expected, $this->instance->update('path', 'user1', ['users' => ['user1']]) ); - } public function dataTestUpdate() { @@ -330,6 +329,43 @@ public function testUpdateNoUsers() { $this->instance->update('path', 'user1', []); } + /** + * Test case if the public key is missing. ownCloud should still encrypt + * the file for the remaining users + */ + public function testUpdateMissingPublicKey() { + $this->keyManagerMock->expects($this->once()) + ->method('getFileKey')->willReturn('fileKey'); + + $this->keyManagerMock->expects($this->any()) + ->method('getPublicKey')->willReturnCallback( + function($user) { + throw new PublicKeyMissingException($user); + } + ); + + $this->keyManagerMock->expects($this->any()) + ->method('addSystemKeys') + ->willReturnCallback(function($accessList, $publicKeys) { + return $publicKeys; + }); + + $this->cryptMock->expects($this->once())->method('multiKeyEncrypt') + ->willReturnCallback( + function($fileKey, $publicKeys) { + $this->assertEmpty($publicKeys); + $this->assertSame('fileKey', $fileKey); + } + ); + + $this->keyManagerMock->expects($this->never())->method('getVersion'); + $this->keyManagerMock->expects($this->never())->method('setVersion'); + + $this->assertTrue( + $this->instance->update('path', 'user1', ['users' => ['user1']]) + ); + } + /** * by default the encryption module should encrypt regular files, files in * files_versions and files in files_trashbin From dfc7e6b421f8defee167b15501f8158c2a1ba6c0 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 14 Mar 2016 19:40:57 +0100 Subject: [PATCH 082/286] Duplicate block for PHP 7 --- .htaccess | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.htaccess b/.htaccess index 085467e91cad6..cf76c56563c11 100644 --- a/.htaccess +++ b/.htaccess @@ -37,6 +37,18 @@ SetEnv htaccessWorking true + + php_value upload_max_filesize 513M + php_value post_max_size 513M + php_value memory_limit 512M + php_value mbstring.func_overload 0 + php_value always_populate_raw_post_data -1 + php_value default_charset 'UTF-8' + php_value output_buffering 0 + + SetEnv htaccessWorking true + + RewriteEngine on RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}] From d1978a69500cb39e6aa542e55666b0f8f32d704a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 14 Mar 2016 20:55:26 +0100 Subject: [PATCH 083/286] Replace all required values --- lib/private/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/files.php b/lib/private/files.php index b0d070637d7af..9b6a1a4465f6a 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -267,7 +267,7 @@ public static function setUploadLimit($size, $files = []) { $pattern = vsprintf($patternMap['pattern'], [$key]); $setting = vsprintf($patternMap['setting'], [$key, $size]); $hasReplaced = 0; - $newContent = preg_replace($pattern, $setting, $content, 1, $hasReplaced); + $newContent = preg_replace($pattern, $setting, $content, 2, $hasReplaced); if ($newContent !== null) { $content = $newContent; } From 9ef7340dc74109e0bd9e0db75ad612a9b48fe920 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 14 Mar 2016 20:55:48 +0100 Subject: [PATCH 084/286] Add support for custom values in integrity checker --- lib/private/integritycheck/checker.php | 43 ++++++++++++++- lib/private/server.php | 3 +- .../.htaccess | 24 +++++++++ .../.user.ini | 7 +++ tests/lib/integritycheck/checkertest.php | 53 +++++++++++++++++-- 5 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 tests/data/integritycheck/htaccessWithValidModifiedContent/.user.ini diff --git a/lib/private/integritycheck/checker.php b/lib/private/integritycheck/checker.php index 8ede6216b766e..d7867936887a3 100644 --- a/lib/private/integritycheck/checker.php +++ b/lib/private/integritycheck/checker.php @@ -31,6 +31,7 @@ use OCP\ICache; use OCP\ICacheFactory; use OCP\IConfig; +use OCP\ITempManager; use phpseclib\Crypt\RSA; use phpseclib\File\X509; @@ -58,6 +59,8 @@ class Checker { private $cache; /** @var IAppManager */ private $appManager; + /** @var ITempManager */ + private $tempManager; /** * @param EnvironmentHelper $environmentHelper @@ -66,19 +69,22 @@ class Checker { * @param IConfig $config * @param ICacheFactory $cacheFactory * @param IAppManager $appManager + * @param ITempManager $tempManager */ public function __construct(EnvironmentHelper $environmentHelper, FileAccessHelper $fileAccessHelper, AppLocator $appLocator, IConfig $config = null, ICacheFactory $cacheFactory, - IAppManager $appManager = null) { + IAppManager $appManager = null, + ITempManager $tempManager) { $this->environmentHelper = $environmentHelper; $this->fileAccessHelper = $fileAccessHelper; $this->appLocator = $appLocator; $this->config = $config; $this->cache = $cacheFactory->create(self::CACHE_KEY); $this->appManager = $appManager; + $this->tempManager = $tempManager; } /** @@ -147,6 +153,8 @@ private function getFolderIterator($folderToIterate, $root = '') { private function generateHashes(\RecursiveIteratorIterator $iterator, $path) { $hashes = []; + $copiedWebserverSettingFiles = false; + $tmpFolder = ''; $baseDirectoryLength = strlen($path); foreach($iterator as $filename => $data) { @@ -167,6 +175,36 @@ private function generateHashes(\RecursiveIteratorIterator $iterator, continue; } + // The .user.ini and the .htaccess file of ownCloud can contain some + // custom modifications such as for example the maximum upload size + // to ensure that this will not lead to false positives this will + // copy the file to a temporary folder and reset it to the default + // values. + if($filename === $this->environmentHelper->getServerRoot() . '/.htaccess' + || $filename === $this->environmentHelper->getServerRoot() . '/.user.ini') { + + if(!$copiedWebserverSettingFiles) { + $tmpFolder = rtrim($this->tempManager->getTemporaryFolder(), '/'); + copy($this->environmentHelper->getServerRoot() . '/.htaccess', $tmpFolder . '/.htaccess'); + copy($this->environmentHelper->getServerRoot() . '/.user.ini', $tmpFolder . '/.user.ini'); + \OC_Files::setUploadLimit( + \OCP\Util::computerFileSize('513MB'), + [ + '.htaccess' => $tmpFolder . '/.htaccess', + '.user.ini' => $tmpFolder . '/.user.ini', + ] + ); + } + } + + // The .user.ini file can contain custom modifications to the file size + // as well. + if($filename === $this->environmentHelper->getServerRoot() . '/.user.ini') { + $fileContent = file_get_contents($tmpFolder . '/.user.ini'); + $hashes[$relativeFileName] = hash('sha512', $fileContent); + continue; + } + // The .htaccess file in the root folder of ownCloud can contain // custom content after the installation due to the fact that dynamic // content is written into it at installation time as well. This @@ -175,7 +213,7 @@ private function generateHashes(\RecursiveIteratorIterator $iterator, // "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####" and have the // hash generated based on this. if($filename === $this->environmentHelper->getServerRoot() . '/.htaccess') { - $fileContent = file_get_contents($filename); + $fileContent = file_get_contents($tmpFolder . '/.htaccess'); $explodedArray = explode('#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####', $fileContent); if(count($explodedArray) === 2) { $hashes[$relativeFileName] = hash('sha512', $explodedArray[0]); @@ -185,6 +223,7 @@ private function generateHashes(\RecursiveIteratorIterator $iterator, $hashes[$relativeFileName] = hash_file('sha512', $filename); } + return $hashes; } diff --git a/lib/private/server.php b/lib/private/server.php index 81187cdd71548..d68a361955f07 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -462,7 +462,8 @@ public function __construct($webRoot, \OC\Config $config) { new AppLocator(), $config, $c->getMemCacheFactory(), - $appManager + $appManager, + $c->getTempManager() ); }); $this->registerService('Request', function ($c) { diff --git a/tests/data/integritycheck/htaccessWithValidModifiedContent/.htaccess b/tests/data/integritycheck/htaccessWithValidModifiedContent/.htaccess index 33d4437c9282d..596d6718a8891 100644 --- a/tests/data/integritycheck/htaccessWithValidModifiedContent/.htaccess +++ b/tests/data/integritycheck/htaccessWithValidModifiedContent/.htaccess @@ -1,4 +1,28 @@ # Start of valid file + + php_value upload_max_filesize 519M + php_value post_max_size 519M + php_value memory_limit 512M + php_value mbstring.func_overload 0 + php_value always_populate_raw_post_data -1 + php_value default_charset 'UTF-8' + php_value output_buffering 0 + + SetEnv htaccessWorking true + + + + php_value upload_max_filesize 519M + php_value post_max_size 519M + php_value memory_limit 512M + php_value mbstring.func_overload 0 + php_value always_populate_raw_post_data -1 + php_value default_charset 'UTF-8' + php_value output_buffering 0 + + SetEnv htaccessWorking true + + #### DO NOT CHANGE ANYTHING ABOVE THIS LINE #### # Content that should change the hash in the root folder \ No newline at end of file diff --git a/tests/data/integritycheck/htaccessWithValidModifiedContent/.user.ini b/tests/data/integritycheck/htaccessWithValidModifiedContent/.user.ini new file mode 100644 index 0000000000000..90959b1e649b5 --- /dev/null +++ b/tests/data/integritycheck/htaccessWithValidModifiedContent/.user.ini @@ -0,0 +1,7 @@ +upload_max_filesize=519M +post_max_size=519M +memory_limit=512M +mbstring.func_overload=0 +always_populate_raw_post_data=-1 +default_charset='UTF-8' +output_buffering=0 diff --git a/tests/lib/integritycheck/checkertest.php b/tests/lib/integritycheck/checkertest.php index fac60b0c123c4..0910c543a7ada 100644 --- a/tests/lib/integritycheck/checkertest.php +++ b/tests/lib/integritycheck/checkertest.php @@ -71,7 +71,8 @@ public function setUp() { $this->appLocator, $this->config, $this->cacheFactory, - $this->appManager + $this->appManager, + \OC::$server->getTempManager() ); } @@ -523,13 +524,14 @@ public function testWriteCoreSignatureWithInvalidModifiedHtaccess() { $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); } - public function testWriteCoreSignatureWithValidModifiedHtaccess() { + public function testWriteCoreSignatureWithValidModifiedHtaccessAndUserIni() { $expectedSignatureFileData = '{ "hashes": { - ".htaccess": "a232e6a616c40635d0220e47ebaade40348aadf141a67a331b8870b8fae056584e52fe8b56c49468ee17b58f92cbcd269dc30ae598d6206e97f7d8bb00a766c6", + ".htaccess": "ef34c5f35fffb6e8e3008c2118617b53243cfc5ac2513edba9ebd383169862bc16e4f889316ad65788d6b172fe14713af90908c19838c4ba13b4146e12c7ac62", + ".user.ini": "0a557e3cdca4c2e3675deed761d79d109011dcdebbd9c7f6429f1d3476938ec95729543d7384651d1d0c48e26c5024cc5f517445920915a704ea748bdb903c5f", "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1" }, - "signature": "LNHvrAFg7NJL9h8TanIFmiI3xnmNRz8pltVgRJpnQTqLJCkhZWV5+poHIii\/\/dI4NhBijsoN0AAJckf1KFzyeI2rOk3w+niaOEXX7khoJDgbxuz0kwN13Bxa1A6j0cMFqm9IIWet0JK9MKaL8K\/n3CzNYovXhRBdJsYTQVWvkaY5KMQgTP2roqgaLBABfI8+fuZVnKie1D737UJ3LhxesEtqr9mJEUSdYuN1QpaScdv7bMkX7xTcg02T5Ljs4F0KsKSME43Pzxm33qCQ\/Gyfsz\/iNKHYQztg9wPkSanbqvFnDtHhcIhKBsETCbNuBZqBk0AwYCupLIJTjC6SShHc4TtWiv834wtSmc1fYfzrsq7gJalJifFAaeGemzFwkePFlVqjdYc63KSqK8ut0jEcjKPAmJ+5NCUoxc8iASMJCesf31mzUPlw1L9LCBMA0aywDqkZYK4tJHZYMvXc4UkSs19OuAzUbXMoVHsJ03ftfC02gpg4hqZDSiBqYuyKMvt2xuutTA+xQcl3fQGUuNdSmBqUFm0D5cCvT10aZPNUXA2cnS+89u58QSxO1wEZJCYKOrDvX1oqOyJs\/c8GNip3LwheIF2KB8\/Zh83h8ZncDxuesAzq89IjV815K3P1G\/kSVPhvQapw1KMLu9rBDZ3FVvQw8K8fg5a7opBrK2ggGds=", + "signature": "d6pqYc0pj5hihZK4Pi\/rM9XguY1xK9LEch+jUcxZWwhzOPL4qVHx5LN4FAhEOnr5ZjuhK\/umVEUjieamF4z8tP\/4nnnu2LmRuPMmj6+1tBEwbsKoeg7NiYfYL5h+VSdBePpIZDmjk0tjEpsMtCPhUPAY5vOSSDJ3Xef4KQIpeL6RKIctDcVdO26QWPLFpCo9NK3j91KHuXTcjbAsATDo+oXQzi0CaomBqL6Ft1SU\/Bdes6usgeVWd6mGygZ6zUCLqB4hSi6335xIkkUO1c3NekWksiqTWqdmVIpsTEsIpapx+nE0UFBGc7ZF2rnamg5813g67M5V\/UwhBRcHobMFWfbp73QDUsHcuLCOhamgYh7hbVIlDP7LS2V3kIRLgMLBVwLnvb8LAbaGUsdYGtbfmrhcMK\/jkpGCv0pqUCc4I+1QuVexNEQrdqafwYRnQUsmdFSFaCASYVvgxPrY5jA+y1HwNX5HEc5mMzVORNPhZXUcxWBRUQxUESY5j473DInMQUhq7SLVNAaglxDR1a9M5tQO8engvIJ5eTImLITm0qdefmEvFrxQ0BrrGmPNFYUysrHeNGDhMkGX+JIONj+T4Ht3Z7dr7cfufYDHRaummsTGgRx6206zRSqavsBWL\/Cbzrfu1HhiRagncVcoL40EommJt8lobaKHs3GZ8k861Wo=", "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->environmentHelper @@ -614,6 +616,48 @@ public function testVerifyCoreSignatureWithValidSignatureData() { $this->assertSame([], $this->checker->verifyCoreSignature()); } + public function testVerifyCoreSignatureWithValidModifiedHtaccessAndUserIniSignatureData() { + $this->environmentHelper + ->expects($this->once()) + ->method('getChannel') + ->will($this->returnValue('stable')); + $this->config + ->expects($this->any()) + ->method('getSystemValue') + ->with('integrity.check.disabled', false) + ->will($this->returnValue(false)); + + $this->environmentHelper + ->expects($this->any()) + ->method('getServerRoot') + ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent')); + $signatureDataFile = '{ + "hashes": { + ".htaccess": "ef34c5f35fffb6e8e3008c2118617b53243cfc5ac2513edba9ebd383169862bc16e4f889316ad65788d6b172fe14713af90908c19838c4ba13b4146e12c7ac62", + ".user.ini": "0a557e3cdca4c2e3675deed761d79d109011dcdebbd9c7f6429f1d3476938ec95729543d7384651d1d0c48e26c5024cc5f517445920915a704ea748bdb903c5f", + "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1" + }, + "signature": "d6pqYc0pj5hihZK4Pi\/rM9XguY1xK9LEch+jUcxZWwhzOPL4qVHx5LN4FAhEOnr5ZjuhK\/umVEUjieamF4z8tP\/4nnnu2LmRuPMmj6+1tBEwbsKoeg7NiYfYL5h+VSdBePpIZDmjk0tjEpsMtCPhUPAY5vOSSDJ3Xef4KQIpeL6RKIctDcVdO26QWPLFpCo9NK3j91KHuXTcjbAsATDo+oXQzi0CaomBqL6Ft1SU\/Bdes6usgeVWd6mGygZ6zUCLqB4hSi6335xIkkUO1c3NekWksiqTWqdmVIpsTEsIpapx+nE0UFBGc7ZF2rnamg5813g67M5V\/UwhBRcHobMFWfbp73QDUsHcuLCOhamgYh7hbVIlDP7LS2V3kIRLgMLBVwLnvb8LAbaGUsdYGtbfmrhcMK\/jkpGCv0pqUCc4I+1QuVexNEQrdqafwYRnQUsmdFSFaCASYVvgxPrY5jA+y1HwNX5HEc5mMzVORNPhZXUcxWBRUQxUESY5j473DInMQUhq7SLVNAaglxDR1a9M5tQO8engvIJ5eTImLITm0qdefmEvFrxQ0BrrGmPNFYUysrHeNGDhMkGX+JIONj+T4Ht3Z7dr7cfufYDHRaummsTGgRx6206zRSqavsBWL\/Cbzrfu1HhiRagncVcoL40EommJt8lobaKHs3GZ8k861Wo=", + "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" +}'; + $this->fileAccessHelper + ->expects($this->at(0)) + ->method('file_get_contents') + ->with( + \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json' + ) + ->will($this->returnValue($signatureDataFile)); + $this->fileAccessHelper + ->expects($this->at(1)) + ->method('file_get_contents') + ->with( + \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt' + ) + ->will($this->returnValue(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt'))); + + $this->assertSame([], $this->checker->verifyCoreSignature()); + } + public function testVerifyCoreSignatureWithValidSignatureDataAndNotAlphabeticOrder() { $this->environmentHelper ->expects($this->once()) @@ -867,6 +911,7 @@ public function testRunInstanceVerification() { $this->config, $this->cacheFactory, $this->appManager, + \OC::$server->getTempManager() ]) ->setMethods([ 'verifyCoreSignature', From 6f7fc6c5dba46f762168690ae2e6a11d70d9dd77 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 15 Mar 2016 11:28:14 +0100 Subject: [PATCH 085/286] always_populate_raw_post_data has been removed with PHP 7.0 --- .htaccess | 1 - 1 file changed, 1 deletion(-) diff --git a/.htaccess b/.htaccess index cf76c56563c11..82f13aa26c753 100644 --- a/.htaccess +++ b/.htaccess @@ -42,7 +42,6 @@ php_value post_max_size 513M php_value memory_limit 512M php_value mbstring.func_overload 0 - php_value always_populate_raw_post_data -1 php_value default_charset 'UTF-8' php_value output_buffering 0 From cdadd4cd1b1051b1c993eb245a27d0250f75fa74 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 12 Mar 2016 23:11:31 +0100 Subject: [PATCH 086/286] Fallback for crappy ancient distributions Fixes https://github.com/owncloud/core/issues/23181 --- apps/encryption/lib/crypto/crypt.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/encryption/lib/crypto/crypt.php b/apps/encryption/lib/crypto/crypt.php index 645f1ff05470b..ca70c88488f4c 100644 --- a/apps/encryption/lib/crypto/crypt.php +++ b/apps/encryption/lib/crypto/crypt.php @@ -266,6 +266,13 @@ public function getCipher() { $cipher = self::DEFAULT_CIPHER; } + // Workaround for OpenSSL 0.9.8. Fallback to an old cipher that should work. + if(OPENSSL_VERSION_NUMBER < 0x1000101f) { + if($cipher === 'AES-256-CTR' || $cipher === 'AES-128-CTR') { + $cipher = self::LEGACY_CIPHER; + } + } + return $cipher; } From f9ad57ee523db315e49f08ae4d28b592d32cc8c9 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 10 Mar 2016 15:58:24 +0100 Subject: [PATCH 087/286] Ensure that stored version is at least 1 for cross-storage copy In case of a move operation from an unencrypted to an encrypted storage the old encrypted version would stay with "0" while the correct value would be "1". Thus we manually set the value to "1" for those cases. See also https://github.com/owncloud/core/issues/23078 --- .../files/storage/wrapper/encryption.php | 13 +++++- .../lib/files/storage/wrapper/encryption.php | 42 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 0b4816174bf0f..81eea9944f891 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -634,7 +634,18 @@ private function updateEncryptedVersion(Storage $sourceStorage, $sourceInternalP 'encrypted' => (bool)$isEncrypted, ]; if($isEncrypted === 1) { - $cacheInformation['encryptedVersion'] = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion']; + $encryptedVersion = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion']; + + // In case of a move operation from an unencrypted to an encrypted + // storage the old encrypted version would stay with "0" while the + // correct value would be "1". Thus we manually set the value to "1" + // for those cases. + // See also https://github.com/owncloud/core/issues/23078 + if($encryptedVersion === 0) { + $encryptedVersion = 1; + } + + $cacheInformation['encryptedVersion'] = $encryptedVersion; } // in case of a rename we need to manipulate the source cache because diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index b5ec15b12bf51..bde920e440e6c 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -672,6 +672,48 @@ public function dataCopyBetweenStorage() { ]; } + public function testCopyBetweenStorageMinimumEncryptedVersion() { + $storage2 = $this->getMockBuilder('OCP\Files\Storage') + ->disableOriginalConstructor() + ->getMock(); + + $sourceInternalPath = $targetInternalPath = 'file.txt'; + $preserveMtime = $isRename = false; + + $storage2->expects($this->any()) + ->method('fopen') + ->willReturnCallback(function($path, $mode) { + $temp = \OC::$server->getTempManager(); + return fopen($temp->getTemporaryFile(), $mode); + }); + $cache = $this->getMock('\OCP\Files\Cache\ICache'); + $cache->expects($this->once()) + ->method('get') + ->with($sourceInternalPath) + ->willReturn(['encryptedVersion' => 0]); + $storage2->expects($this->once()) + ->method('getCache') + ->willReturn($cache); + $this->encryptionManager->expects($this->any()) + ->method('isEnabled') + ->willReturn(true); + global $mockedMountPointEncryptionEnabled; + $mockedMountPointEncryptionEnabled = true; + + $expectedCachePut = [ + 'encrypted' => true, + ]; + $expectedCachePut['encryptedVersion'] = 1; + + $this->cache->expects($this->once()) + ->method('put') + ->with($sourceInternalPath, $expectedCachePut); + + $this->invokePrivate($this->instance, 'copyBetweenStorage', [$storage2, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename]); + + $this->assertFalse(false); + } + /** * @dataProvider dataCopyBetweenStorage * From 8c035ae6f68cdcb95f788b210602c68197a09de2 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 11 Mar 2016 14:49:04 +0100 Subject: [PATCH 088/286] Specify the target user when unsharing a federated share --- apps/files_sharing/api/server2server.php | 2 +- apps/files_sharing/tests/server2server.php | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/api/server2server.php b/apps/files_sharing/api/server2server.php index 6da95ed654908..a3d58880f7057 100644 --- a/apps/files_sharing/api/server2server.php +++ b/apps/files_sharing/api/server2server.php @@ -178,7 +178,7 @@ public function declineShare($params) { if ($share) { // userId must be set to the user who unshares - \OCP\Share::unshare($share['item_type'], $share['item_source'], $share['share_type'], null, $share['uid_owner']); + \OCP\Share::unshare($share['item_type'], $share['item_source'], $share['share_type'], $share['share_with'], $share['uid_owner']); list($file, $link) = $this->getFile($share['uid_owner'], $share['file_source']); diff --git a/apps/files_sharing/tests/server2server.php b/apps/files_sharing/tests/server2server.php index 298f1008f712a..7714f274c6d18 100644 --- a/apps/files_sharing/tests/server2server.php +++ b/apps/files_sharing/tests/server2server.php @@ -147,6 +147,38 @@ function testDeclineShare() { $this->assertEmpty($data); } + function testDeclineShareMultiple() { + $dummy = \OCP\DB::prepare(' + INSERT INTO `*PREFIX*share` + (`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + '); + $dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token1', 'foo@bar')); + $dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token2', 'bar@bar')); + + $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $verify->execute(); + $data = $result->fetchAll(); + $this->assertCount(2, $data); + + $_POST['token'] = 'token1'; + $this->s2s->declineShare(array('id' => $data[0]['id'])); + + $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $verify->execute(); + $data = $result->fetchAll(); + $this->assertCount(1, $data); + $this->assertEquals('bar@bar', $data[0]['share_with']); + + $_POST['token'] = 'token2'; + $this->s2s->declineShare(array('id' => $data[0]['id'])); + + $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); + $result = $verify->execute(); + $data = $result->fetchAll(); + $this->assertEmpty($data); + } + /** * @dataProvider dataTestDeleteUser */ From 95cd1671b36dc936e4afcce43d27d7546b3aa0f7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Mar 2016 13:15:54 +0100 Subject: [PATCH 089/286] handle connection errors as storage not available in smb --- apps/files_external/lib/smb.php | 54 ++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 67d1a23f5a76c..25acae95fa3b1 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -30,6 +30,7 @@ namespace OC\Files\Storage; +use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\ForbiddenException; use Icewind\SMB\Exception\NotFoundException; @@ -39,6 +40,7 @@ use Icewind\Streams\IteratorDirectory; use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; +use OCP\Files\StorageNotAvailableException; class SMB extends Common { /** @@ -104,26 +106,36 @@ protected function buildPath($path) { /** * @param string $path * @return \Icewind\SMB\IFileInfo + * @throws StorageNotAvailableException */ protected function getFileInfo($path) { - $path = $this->buildPath($path); - if (!isset($this->statCache[$path])) { - $this->statCache[$path] = $this->share->stat($path); + try { + $path = $this->buildPath($path); + if (!isset($this->statCache[$path])) { + $this->statCache[$path] = $this->share->stat($path); + } + return $this->statCache[$path]; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } - return $this->statCache[$path]; } /** * @param string $path * @return \Icewind\SMB\IFileInfo[] + * @throws StorageNotAvailableException */ protected function getFolderContents($path) { - $path = $this->buildPath($path); - $files = $this->share->dir($path); - foreach ($files as $file) { - $this->statCache[$path . '/' . $file->getName()] = $file; + try { + $path = $this->buildPath($path); + $files = $this->share->dir($path); + foreach ($files as $file) { + $this->statCache[$path . '/' . $file->getName()] = $file; + } + return $files; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } - return $files; } /** @@ -163,6 +175,8 @@ public function unlink($path) { return false; } catch (ForbiddenException $e) { return false; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } } @@ -245,6 +259,8 @@ public function fopen($path, $mode) { return false; } catch (ForbiddenException $e) { return false; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } } @@ -265,16 +281,22 @@ public function rmdir($path) { return false; } catch (ForbiddenException $e) { return false; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } } public function touch($path, $time = null) { - if (!$this->file_exists($path)) { - $fh = $this->share->write($this->buildPath($path)); - fclose($fh); - return true; + try { + if (!$this->file_exists($path)) { + $fh = $this->share->write($this->buildPath($path)); + fclose($fh); + return true; + } + return false; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } - return false; } public function opendir($path) { @@ -307,6 +329,8 @@ public function mkdir($path) { try { $this->share->mkdir($path); return true; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } catch (Exception $e) { return false; } @@ -320,6 +344,8 @@ public function file_exists($path) { return false; } catch (ForbiddenException $e) { return false; + } catch (ConnectException $e) { + throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e); } } From aa91d50d043df254403479aedfa0f7b4f7f76502 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Fri, 11 Mar 2016 17:22:29 +0000 Subject: [PATCH 090/286] Prevent certain DBs throwing exceptions on same-value updates A PreconditionNotMetException must only be thrown if explicit preconditions are specified for setValues(), not if the value is merely the same as was already in the DB. --- lib/private/db/connection.php | 2 +- tests/lib/db/connection.php | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index 584904e637008..7904fab072652 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -293,7 +293,7 @@ public function setValues($table, array $keys, array $values, array $updatePreco $updateQb->where($where); $affected = $updateQb->execute(); - if ($affected === 0) { + if ($affected === 0 && !empty($updatePreconditionValues)) { throw new PreconditionNotMetException(); } diff --git a/tests/lib/db/connection.php b/tests/lib/db/connection.php index b10b1a322a9cd..62d0a77ca1fe7 100644 --- a/tests/lib/db/connection.php +++ b/tests/lib/db/connection.php @@ -47,6 +47,11 @@ public function setUp() { $this->connection = \OC::$server->getDatabaseConnection(); } + public function tearDown() { + parent::tearDown(); + $this->connection->dropTable('table'); + } + /** * @param string $table */ @@ -86,6 +91,7 @@ public function testTableExists() { * @depends testTableExists */ public function testDropTable() { + $this->makeTestTable(); $this->assertTableExist('table'); $this->connection->dropTable('table'); $this->assertTableNotExist('table'); @@ -111,8 +117,6 @@ public function testSetValues() { ]); $this->assertEquals('foo', $this->getTextValueByIntergerField(1)); - - $this->connection->dropTable('table'); } public function testSetValuesOverWrite() { @@ -131,8 +135,6 @@ public function testSetValuesOverWrite() { ]); $this->assertEquals('bar', $this->getTextValueByIntergerField(1)); - - $this->connection->dropTable('table'); } public function testSetValuesOverWritePrecondition() { @@ -154,8 +156,6 @@ public function testSetValuesOverWritePrecondition() { ]); $this->assertEquals('bar', $this->getTextValueByIntergerField(1)); - - $this->connection->dropTable('table'); } /** @@ -179,4 +179,22 @@ public function testSetValuesOverWritePreconditionFailed() { 'booleanfield' => false ]); } + + public function testSetValuesSameNoError() { + $this->makeTestTable(); + $this->connection->setValues('table', [ + 'integerfield' => 1 + ], [ + 'textfield' => 'foo', + 'clobfield' => 'not_null' + ]); + + // this will result in 'no affected rows' on certain optimizing DBs + // ensure the PreConditionNotMetException isn't thrown + $this->connection->setValues('table', [ + 'integerfield' => 1 + ], [ + 'textfield' => 'foo' + ]); + } } From 7b818d9442a2f0d8f80ddf63bda8ae3b85ef9376 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 16 Mar 2016 15:39:07 +0100 Subject: [PATCH 091/286] Execute travis on stable9 as well Backport of #23100 to stable9 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4f79311c33c7c..0f6a027d06144 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ env: branches: only: - master -# - /^stable\d+(\.\d+)?$/ + - /^stable\d+(\.\d+)?$/ addons: apt: From dbcb0376397a3b45d48427d12eb3de10d3c21c29 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sat, 12 Mar 2016 22:13:05 +0100 Subject: [PATCH 092/286] Require at least libxml 2.7.0 Fixes https://github.com/owncloud/core/issues/23168 --- lib/private/util.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/private/util.php b/lib/private/util.php index 6f53be8446a9b..88d78ad83c635 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -828,6 +828,14 @@ public static function checkServer(\OCP\IConfig $config) { ); } + if(function_exists('xml_parser_create') && + version_compare('2.7.0', LIBXML_DOTTED_VERSION) === 1) { + $errors[] = array( + 'error' => $l->t('libxml2 2.7.0 is at least required. Currently %s is installed.', [LIBXML_DOTTED_VERSION]), + 'hint' => $l->t('To fix this issue update your libxml2 version and restart your web server.') + ); + } + if (!self::isAnnotationsWorking()) { $errors[] = array( 'error' => $l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.'), From e71ebf334da958f23b2a70cd92a8dd46f77bee12 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 16 Mar 2016 15:17:27 +0100 Subject: [PATCH 093/286] [stable9] Execute parallel-lint Backport of #22994 and #23303 --- .travis.yml | 9 +++++++++ composer.json | 6 ++++++ 2 files changed, 15 insertions(+) create mode 100644 composer.json diff --git a/.travis.yml b/.travis.yml index 0f6a027d06144..529fd1c097583 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ install: script: + - sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ .; fi" - sh -c "if [ '$TEST_DAV' != '1' ]; then echo \"Not testing DAV\"; fi" - sh -c "if [ '$TEST_DAV' = '1' ]; then echo \"Testing DAV\"; fi" @@ -42,5 +43,13 @@ matrix: env: DB=sqlite;TC=carddav - php: 5.4 env: DB=sqlite;TC=caldav + - php: 5.4 + env: DB=sqlite;TC=syntax + - php: 5.5 + env: DB=sqlite;TC=syntax + - php: 5.6 + env: DB=sqlite;TC=syntax + - php: 7.0 + env: DB=sqlite;TC=syntax fast_finish: true diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000..754925d58a77f --- /dev/null +++ b/composer.json @@ -0,0 +1,6 @@ +{ + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.2", + "jakub-onderka/php-console-highlighter": "^0.3.2" + } +} From 3a773f4ecaf2655c03f877bf22416184ba87b5b6 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 15 Mar 2016 13:01:47 +0100 Subject: [PATCH 094/286] Give swift 15 seconds after startup --- apps/files_external/tests/env/start-swift-ceph.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files_external/tests/env/start-swift-ceph.sh b/apps/files_external/tests/env/start-swift-ceph.sh index 357512ae4d624..e884087c2481b 100755 --- a/apps/files_external/tests/env/start-swift-ceph.sh +++ b/apps/files_external/tests/env/start-swift-ceph.sh @@ -63,14 +63,15 @@ echo "${docker_image} container: $container" # put container IDs into a file to drop them after the test run (keep in mind that multiple tests run in parallel on the same host) echo $container >> $thisFolder/dockerContainerCeph.$EXECUTOR_NUMBER.swift -echo -n "Waiting for ceph initialization" +echo "Waiting for ceph initialization" ready=$(timeout 600 cat "$notify_sock") if [[ $ready != 'READY=1' ]]; then echo "[ERROR] Waited 600 seconds, no response" >&2 docker logs $container exit 1 fi -sleep 1 +echo "Waiting another 15 seconds" +sleep 15 cat > $thisFolder/config.swift.php < Date: Wed, 16 Mar 2016 22:06:49 +0000 Subject: [PATCH 095/286] Display external storage GUI even if user mounting disabled --- apps/files_external/appinfo/application.php | 4 +--- apps/files_external/js/settings.js | 1 + apps/files_external/personal.php | 1 + apps/files_external/settings.php | 1 - apps/files_external/templates/settings.php | 6 +++++- apps/files_external/tests/js/settingsSpec.js | 6 ++++++ 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 0f08cc6004fd0..cdc58aed7e882 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -59,9 +59,7 @@ public function registerSettings() { $backendService = $container->query('OCA\\Files_External\\Service\\BackendService'); \OCP\App::registerAdmin('files_external', 'settings'); - if ($backendService->isUserMountingAllowed()) { - \OCP\App::registerPersonal('files_external', 'personal'); - } + \OCP\App::registerPersonal('files_external', 'personal'); } /** diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index ceacbf4afab9d..0b33458bec23a 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -813,6 +813,7 @@ MountConfigListView.prototype = _.extend({ this.$el.find('tbody').append($tr.clone()); $tr.data('storageConfig', storageConfig); + $tr.show(); $tr.find('td').last().attr('class', 'remove'); $tr.find('td.mountOptionsToggle').removeClass('hidden'); $tr.find('td').last().removeAttr('style'); diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index 4d8f480ecc03d..5c568f45b7db4 100644 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -38,4 +38,5 @@ $tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); $tmpl->assign('backends', $backendService->getAvailableBackends()); $tmpl->assign('authMechanisms', $backendService->getAuthMechanisms()); +$tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); return $tmpl->fetchPage(); diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index 5bc330ff1897c..0d83d26ff9793 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -44,5 +44,4 @@ $tmpl->assign('authMechanisms', $backendService->getAuthMechanisms()); $tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); $tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); -$tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); return $tmpl->fetchPage(); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index f7caf3d2caa49..697a145131c84 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -85,7 +85,11 @@ function writeParameterInput($parameter, $options, $classes = []) { - + + style="display: none;" + + > diff --git a/apps/files_external/tests/js/settingsSpec.js b/apps/files_external/tests/js/settingsSpec.js index 2a7afd6c2fa84..462407e954046 100644 --- a/apps/files_external/tests/js/settingsSpec.js +++ b/apps/files_external/tests/js/settingsSpec.js @@ -179,6 +179,12 @@ describe('OCA.External.Settings tests', function() { // TODO: check "remove" button visibility }); + it('shows row even if selection row is hidden', function() { + view.$el.find('tr#addMountPoint').hide(); + selectBackend('\\OC\\TestBackend'); + expect(view.$el.find('tr:first').is(':visible')).toBe(true); + expect(view.$el.find('tr#addMountPoint').is(':visible')).toBe(false); + }); // TODO: test with personal mounts (no applicable fields) // TODO: test suggested mount point logic }); From b8af6e703a68adcac163b1873e2602dcf9e8489a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 17 Mar 2016 08:58:03 +0100 Subject: [PATCH 096/286] Don't try to execute a dav syntax test --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 529fd1c097583..37af4ab02e32e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,12 +44,12 @@ matrix: - php: 5.4 env: DB=sqlite;TC=caldav - php: 5.4 - env: DB=sqlite;TC=syntax + env: DB=sqlite;TC=syntax;TEST_DAV=0 - php: 5.5 - env: DB=sqlite;TC=syntax + env: DB=sqlite;TC=syntax;TEST_DAV=0 - php: 5.6 - env: DB=sqlite;TC=syntax + env: DB=sqlite;TC=syntax;TEST_DAV=0 - php: 7.0 - env: DB=sqlite;TC=syntax + env: DB=sqlite;TC=syntax;TEST_DAV=0 fast_finish: true From 9dfcb55a2f40226bfefee4fc30781f41790dcee2 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 17 Mar 2016 11:35:31 +0100 Subject: [PATCH 097/286] Set proper public webdav permissions when public upload disabled Fixes #23325 It can happen that a user shares a folder with public upload. And some time later the admin disables public upload on the server. To make sure this is handled correctly we need to check the config value and reduce the permissions. Fix is kept small to be easy backportable. --- apps/dav/lib/connector/publicauth.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/dav/lib/connector/publicauth.php b/apps/dav/lib/connector/publicauth.php index 3d800e88004ef..f069a214fe8d9 100644 --- a/apps/dav/lib/connector/publicauth.php +++ b/apps/dav/lib/connector/publicauth.php @@ -61,6 +61,11 @@ protected function validateUserPass($username, $password) { return false; } + if ((int)$linkItem['share_type'] === \OCP\Share::SHARE_TYPE_LINK && + $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') !== 'yes') { + $this->share['permissions'] &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + } + // check if the share is password protected if (isset($linkItem['share_with'])) { if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) { From e7152f495c4c48c4f03cc4a8152530999b44c331 Mon Sep 17 00:00:00 2001 From: Carla Schroder Date: Wed, 16 Mar 2016 16:14:25 -0700 Subject: [PATCH 098/286] Some typo corrections in occ command output --- apps/files/command/transferownership.php | 2 +- core/command/integrity/checkapp.php | 2 +- core/command/integrity/checkcore.php | 2 +- core/command/security/removecertificate.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php index c248620d5c5a2..3674727b1672c 100644 --- a/apps/files/command/transferownership.php +++ b/apps/files/command/transferownership.php @@ -69,7 +69,7 @@ public function __construct(IUserManager $userManager, IManager $shareManager) { protected function configure() { $this ->setName('files:transfer-ownership') - ->setDescription('All files and folders are move to another user - shares are moved as well.') + ->setDescription('All files and folders are moved to another user - shares are moved as well.') ->addArgument( 'source-user', InputArgument::REQUIRED, diff --git a/core/command/integrity/checkapp.php b/core/command/integrity/checkapp.php index 87b8eb47687d4..643af5285b43e 100644 --- a/core/command/integrity/checkapp.php +++ b/core/command/integrity/checkapp.php @@ -51,7 +51,7 @@ protected function configure() { parent::configure(); $this ->setName('integrity:check-app') - ->setDescription('Check an app integrity using a signature.') + ->setDescription('Check integrity of an app using a signature.') ->addArgument('appid', null, InputArgument::REQUIRED, 'Application to check') ->addOption('path', null, InputOption::VALUE_OPTIONAL, 'Path to application. If none is given it will be guessed.'); } diff --git a/core/command/integrity/checkcore.php b/core/command/integrity/checkcore.php index ac29937e2ed6c..460a78e4da71e 100644 --- a/core/command/integrity/checkcore.php +++ b/core/command/integrity/checkcore.php @@ -49,7 +49,7 @@ protected function configure() { parent::configure(); $this ->setName('integrity:check-core') - ->setDescription('Check a core integrity using a signature.'); + ->setDescription('Check integrity of core code using a signature.'); } /** diff --git a/core/command/security/removecertificate.php b/core/command/security/removecertificate.php index 14b427511acbf..68e409aee1c5f 100644 --- a/core/command/security/removecertificate.php +++ b/core/command/security/removecertificate.php @@ -43,7 +43,7 @@ public function __construct(ICertificateManager $certificateManager) { protected function configure() { $this ->setName('security:certificates:remove') - ->setDescription('import trusted certificate') + ->setDescription('remove trusted certificate') ->addArgument( 'name', InputArgument::REQUIRED, From 8e0b78c746404c8e385908cad1be6dcff6e8ebd1 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 16 Mar 2016 17:57:54 +0100 Subject: [PATCH 099/286] Chunk upload for GDrive Instead of storing the WHOLE file in memory in a PHP variable, use the library's chunk upload support. --- apps/files_external/lib/google.php | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 5e5716cf43801..112f7e9c57fcf 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -490,18 +490,15 @@ public function writeBack($tmpFile) { $path = self::$tempFiles[$tmpFile]; $parentFolder = $this->getDriveFile(dirname($path)); if ($parentFolder) { - // TODO Research resumable upload $mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile); - $data = file_get_contents($tmpFile); $params = array( - 'data' => $data, 'mimeType' => $mimetype, - 'uploadType' => 'media' ); $result = false; if ($this->file_exists($path)) { $file = $this->getDriveFile($path); - $result = $this->service->files->update($file->getId(), $file, $params); + $this->client->setDefer(true); + $request = $this->service->files->update($file->getId(), $file, $params); } else { $file = new \Google_Service_Drive_DriveFile(); $file->setTitle(basename($path)); @@ -509,8 +506,44 @@ public function writeBack($tmpFile) { $parent = new \Google_Service_Drive_ParentReference(); $parent->setId($parentFolder->getId()); $file->setParents(array($parent)); - $result = $this->service->files->insert($file, $params); + $this->client->setDefer(true); + $request = $this->service->files->insert($file, $params); } + + $chunkSizeBytes = 10 * 1024 * 1024; + + // Create a media file upload to represent our upload process. + $media = new \Google_Http_MediaFileUpload( + $this->client, + $request, + 'text/plain', + null, + true, + $chunkSizeBytes + ); + $media->setFileSize(filesize($tmpFile)); + + // Upload the various chunks. $status will be false until the process is + // complete. + $status = false; + $handle = fopen($tmpFile, 'rb'); + while (!$status && !feof($handle)) { + $chunk = fread($handle, $chunkSizeBytes); + $status = $media->nextChunk($chunk); + } + + // The final value of $status will be the data from the API for the object + // that has been uploaded. + $result = false; + if ($status !== false) { + $result = $status; + } + + fclose($handle); + + // Reset to the client to execute requests immediately in the future. + $this->client->setDefer(false); + if ($result) { $this->setDriveFile($path, $result); } From 1e1c0885c63c3568e74966b1f8ea33fc3cd3ccb6 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 17 Mar 2016 12:36:47 +0100 Subject: [PATCH 100/286] Only use GDrive chunks when needed --- apps/files_external/lib/google.php | 72 ++++++++++++++++++------------ 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 112f7e9c57fcf..b79f42d1e009b 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -493,11 +493,23 @@ public function writeBack($tmpFile) { $mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile); $params = array( 'mimeType' => $mimetype, + 'uploadType' => 'media' ); $result = false; + + $chunkSizeBytes = 10 * 1024 * 1024; + + $useChunking = false; + $size = filesize($tmpFile); + if ($size > $chunkSizeBytes) { + $useChunking = true; + } else { + $params['data'] = file_get_contents($tmpFile); + } + if ($this->file_exists($path)) { $file = $this->getDriveFile($path); - $this->client->setDefer(true); + $this->client->setDefer($useChunking); $request = $this->service->files->update($file->getId(), $file, $params); } else { $file = new \Google_Service_Drive_DriveFile(); @@ -506,41 +518,43 @@ public function writeBack($tmpFile) { $parent = new \Google_Service_Drive_ParentReference(); $parent->setId($parentFolder->getId()); $file->setParents(array($parent)); - $this->client->setDefer(true); + $this->client->setDefer($useChunking); $request = $this->service->files->insert($file, $params); } - $chunkSizeBytes = 10 * 1024 * 1024; + if ($useChunking) { + // Create a media file upload to represent our upload process. + $media = new \Google_Http_MediaFileUpload( + $this->client, + $request, + 'text/plain', + null, + true, + $chunkSizeBytes + ); + $media->setFileSize($size); + + // Upload the various chunks. $status will be false until the process is + // complete. + $status = false; + $handle = fopen($tmpFile, 'rb'); + while (!$status && !feof($handle)) { + $chunk = fread($handle, $chunkSizeBytes); + $status = $media->nextChunk($chunk); + } - // Create a media file upload to represent our upload process. - $media = new \Google_Http_MediaFileUpload( - $this->client, - $request, - 'text/plain', - null, - true, - $chunkSizeBytes - ); - $media->setFileSize(filesize($tmpFile)); - - // Upload the various chunks. $status will be false until the process is - // complete. - $status = false; - $handle = fopen($tmpFile, 'rb'); - while (!$status && !feof($handle)) { - $chunk = fread($handle, $chunkSizeBytes); - $status = $media->nextChunk($chunk); - } + // The final value of $status will be the data from the API for the object + // that has been uploaded. + $result = false; + if ($status !== false) { + $result = $status; + } - // The final value of $status will be the data from the API for the object - // that has been uploaded. - $result = false; - if ($status !== false) { - $result = $status; + fclose($handle); + } else { + $result = $request; } - fclose($handle); - // Reset to the client to execute requests immediately in the future. $this->client->setDefer(false); From d65c3a77e2de66112c87fd7df16a0c061fb8b0ad Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Thu, 17 Mar 2016 17:34:22 +0100 Subject: [PATCH 101/286] Update avatar on username change if avatar is set * fixes #20455 --- settings/js/personal.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/settings/js/personal.js b/settings/js/personal.js index b0bfa8eb230f7..3b2316d061426 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -83,7 +83,10 @@ function changeDisplayName () { $('#oldDisplayName').val($('#displayName').val()); // update displayName on the top right expand button $('#expandDisplayName').text($('#displayName').val()); - updateAvatar(); + // update avatar if avatar is available + if(!$('#removeavatar').hasClass('hidden')) { + updateAvatar(); + } } else { $('#newdisplayname').val(data.data.displayName); From 1fdf790c8f4a4448d9d2e00a1c7f6a962e5ad249 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 17 Mar 2016 17:59:28 +0100 Subject: [PATCH 102/286] Write .htaccess update only if not already written The ownCloud update routine also runs the "updateHtaccess" code in case only an application gets updated. This leads to having entries multiple time in the .htaccess file leading to unpredictable behaviour. With 9.0 we added the "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####" entry to the .htaccess file, this change uses it to ensure that only to the .htaccess gets written if the file has not been modified already. Since the .htaccess modifications are optional this is not a big deal. Without this change updates of applications can break the rewrite rules (ending in endless redirects) as well as breaking the code integrity checker. --- lib/private/setup.php | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index 5988a0b2d1de5..6303d0d47f3a8 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -411,32 +411,32 @@ public static function updateHtaccess() { $htaccessContent = file_get_contents($setupHelper->pathToHtaccess()); $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n"; - if (strpos($htaccessContent, 'ErrorDocument 403') === false) { + if(strpos($htaccessContent, $content) === false) { //custom 403 error page $content.= "\nErrorDocument 403 ".\OC::$WEBROOT."/core/templates/403.php"; - } - if (strpos($htaccessContent, 'ErrorDocument 404') === false) { + //custom 404 error page $content.= "\nErrorDocument 404 ".\OC::$WEBROOT."/core/templates/404.php"; - } - // Add rewrite base - $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; - $content .= "\n"; - $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; - $content .= "\n RewriteBase ".$webRoot; - $content .= "\n "; - $content .= "\n SetEnv front_controller_active true"; - $content .= "\n "; - $content .= "\n DirectorySlash off"; - $content .= "\n "; - $content.="\n "; - $content.="\n"; - - if ($content !== '') { - //suppress errors in case we don't have permissions for it - @file_put_contents($setupHelper->pathToHtaccess(), $content . "\n", FILE_APPEND); + // Add rewrite base + $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; + $content .= "\n"; + $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; + $content .= "\n RewriteBase ".$webRoot; + $content .= "\n "; + $content .= "\n SetEnv front_controller_active true"; + $content .= "\n "; + $content .= "\n DirectorySlash off"; + $content .= "\n "; + $content.="\n "; + $content.="\n"; + + if ($content !== '') { + //suppress errors in case we don't have permissions for it + @file_put_contents($setupHelper->pathToHtaccess(), $content . "\n", FILE_APPEND); + } } + } public static function protectDataDirectory() { From d9b632c00177e0625ef06e31e19ea1157546ebb4 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 17 Mar 2016 17:32:38 +0100 Subject: [PATCH 103/286] Use raw PATH_INFO PATH_INFO will be empty at this point and thus the logic in base.php did not catch this. Changing this to "getRawPathInfo" will ensure that the path info is properly read. Fixes https://github.com/owncloud/core/issues/23199 --- .htaccess | 4 ++-- lib/base.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.htaccess b/.htaccess index 82f13aa26c753..3c5affd823373 100644 --- a/.htaccess +++ b/.htaccess @@ -62,8 +62,8 @@ # Rewrite rules for `front_controller_active` Options -MultiViews - RewriteRule ^core/js/oc.js$ index.php/core/js/oc.js [PT,E=PATH_INFO:$1] - RewriteRule ^core/preview.png$ index.php/core/preview.png [PT,E=PATH_INFO:$1] + RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1] + RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1] RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff|ico)$ RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$ RewriteCond %{REQUEST_FILENAME} !/remote.php diff --git a/lib/base.php b/lib/base.php index 70498f3156703..36e5cd89d79d8 100644 --- a/lib/base.php +++ b/lib/base.php @@ -830,7 +830,7 @@ public static function handleRequest() { } $request = \OC::$server->getRequest(); - $requestPath = $request->getPathInfo(); + $requestPath = $request->getRawPathInfo(); if (substr($requestPath, -3) !== '.js') { // we need these files during the upgrade self::checkMaintenanceMode(); self::checkUpgrade(); From c513317c4924053b418b3472489c3099150308e5 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 16 Mar 2016 14:38:14 +0100 Subject: [PATCH 104/286] Update 3rdparty submodule for sabre 3.0.8 update --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index fc0c1159f4e27..913c4f0028a3b 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit fc0c1159f4e275186b45f8454aaa89f90718b89e +Subproject commit 913c4f0028a3bbdf716394c194f3cde8b92f8239 From fb705fa305cf249a06afd14530d1eccf9336bb11 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 2 Mar 2016 18:25:31 +0100 Subject: [PATCH 105/286] Add webdav property for share info in PROPFIND response --- .../dav/lib/connector/sabre/serverfactory.php | 6 + apps/dav/lib/connector/sabre/sharesplugin.php | 197 +++++++++++++ .../dav/lib/connector/sabre/sharetypelist.php | 87 ++++++ .../unit/connector/sabre/sharesplugin.php | 263 ++++++++++++++++++ apps/files_sharing/js/share.js | 57 ++-- apps/files_sharing/js/sharedfilelist.js | 10 + apps/files_sharing/tests/js/shareSpec.js | 33 +-- 7 files changed, 608 insertions(+), 45 deletions(-) create mode 100644 apps/dav/lib/connector/sabre/sharesplugin.php create mode 100644 apps/dav/lib/connector/sabre/sharetypelist.php create mode 100644 apps/dav/tests/unit/connector/sabre/sharesplugin.php diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php index 6ccec0bc0e83a..080f889ae71cd 100644 --- a/apps/dav/lib/connector/sabre/serverfactory.php +++ b/apps/dav/lib/connector/sabre/serverfactory.php @@ -137,6 +137,12 @@ public function createServer($baseUri, if($this->userSession->isLoggedIn()) { $server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager)); + $server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin( + $objectTree, + $this->userSession, + $userFolder, + \OC::$server->getShareManager() + )); $server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession)); $server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin( $objectTree, diff --git a/apps/dav/lib/connector/sabre/sharesplugin.php b/apps/dav/lib/connector/sabre/sharesplugin.php new file mode 100644 index 0000000000000..df524c11a844b --- /dev/null +++ b/apps/dav/lib/connector/sabre/sharesplugin.php @@ -0,0 +1,197 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\Connector\Sabre; + +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2016 Vincent Petry + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +use \Sabre\DAV\PropFind; +use \Sabre\DAV\PropPatch; +use OCP\IUserSession; +use OCP\Share\IShare; +use OCA\DAV\Connector\Sabre\ShareTypeList; + +/** + * Sabre Plugin to provide share-related properties + */ +class SharesPlugin extends \Sabre\DAV\ServerPlugin { + + const NS_OWNCLOUD = 'http://owncloud.org/ns'; + const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types'; + + /** + * Reference to main server object + * + * @var \Sabre\DAV\Server + */ + private $server; + + /** + * @var \OCP\Share\IManager + */ + private $shareManager; + + /** + * @var \Sabre\DAV\Tree + */ + private $tree; + + /** + * @var string + */ + private $userId; + + /** + * @var \OCP\Files\Folder + */ + private $userFolder; + + /** + * @var IShare[] + */ + private $cachedShareTypes; + + /** + * @param \Sabre\DAV\Tree $tree tree + * @param IUserSession $userSession user session + * @param \OCP\Files\Folder $userFolder user home folder + * @param \OCP\Share\IManager $shareManager share manager + */ + public function __construct( + \Sabre\DAV\Tree $tree, + IUserSession $userSession, + \OCP\Files\Folder $userFolder, + \OCP\Share\IManager $shareManager + ) { + $this->tree = $tree; + $this->shareManager = $shareManager; + $this->userFolder = $userFolder; + $this->userId = $userSession->getUser()->getUID(); + $this->cachedShareTypes = []; + } + + /** + * This initializes the plugin. + * + * This function is called by \Sabre\DAV\Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param \Sabre\DAV\Server $server + */ + public function initialize(\Sabre\DAV\Server $server) { + $server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc'; + $server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList'; + $server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME; + + $this->server = $server; + $this->server->on('propFind', array($this, 'handleGetProperties')); + } + + /** + * Return a list of share types for outgoing shares + * + * @param \OCP\Files\Node $node file node + * + * @return int[] array of share types + */ + private function getShareTypes(\OCP\Files\Node $node) { + $shareTypes = []; + $requestedShareTypes = [ + \OCP\Share::SHARE_TYPE_USER, + \OCP\Share::SHARE_TYPE_GROUP, + \OCP\Share::SHARE_TYPE_LINK + ]; + foreach ($requestedShareTypes as $requestedShareType) { + // one of each type is enough to find out about the types + $shares = $this->shareManager->getSharesBy( + $this->userId, + $requestedShareType, + $node, + false, + 1 + ); + if (!empty($shares)) { + $shareTypes[] = $requestedShareType; + } + } + return $shareTypes; + } + + /** + * Adds shares to propfind response + * + * @param PropFind $propFind propfind object + * @param \Sabre\DAV\INode $sabreNode sabre node + */ + public function handleGetProperties( + PropFind $propFind, + \Sabre\DAV\INode $sabreNode + ) { + if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) { + return; + } + + // need prefetch ? + if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory + && $propFind->getDepth() !== 0 + && !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) + ) { + $folderNode = $this->userFolder->get($propFind->getPath()); + $children = $folderNode->getDirectoryListing(); + + $this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode); + foreach ($children as $childNode) { + $this->cachedShareTypes[$childNode->getId()] = $this->getShareTypes($childNode); + } + } + + $propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) { + if (isset($this->cachedShareTypes[$sabreNode->getId()])) { + $shareTypes = $this->cachedShareTypes[$sabreNode->getId()]; + } else { + $node = $this->userFolder->get($sabreNode->getPath()); + $shareTypes = $this->getShareTypes($node); + } + + return new ShareTypeList($shareTypes); + }); + } +} diff --git a/apps/dav/lib/connector/sabre/sharetypelist.php b/apps/dav/lib/connector/sabre/sharetypelist.php new file mode 100644 index 0000000000000..763586412ad7a --- /dev/null +++ b/apps/dav/lib/connector/sabre/sharetypelist.php @@ -0,0 +1,87 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\DAV\Connector\Sabre; + +use Sabre\Xml\Element; +use Sabre\Xml\Reader; +use Sabre\Xml\Writer; + +/** + * ShareTypeList property + * + * This property contains multiple "share-type" elements, each containing a share type. + */ +class ShareTypeList implements Element { + const NS_OWNCLOUD = 'http://owncloud.org/ns'; + + /** + * Share types + * + * @var int[] + */ + private $shareTypes; + + /** + * @param int[] $shareTypes + */ + public function __construct($shareTypes) { + $this->shareTypes = $shareTypes; + } + + /** + * Returns the share types + * + * @return int[] + */ + public function getShareTypes() { + return $this->shareTypes; + } + + /** + * The deserialize method is called during xml parsing. + * + * @param Reader $reader + * @return mixed + */ + static function xmlDeserialize(Reader $reader) { + $shareTypes = []; + + foreach ($reader->parseInnerTree() as $elem) { + if ($elem['name'] === '{' . self::NS_OWNCLOUD . '}share-type') { + $shareTypes[] = (int)$elem['value']; + } + } + return new self($shareTypes); + } + + /** + * The xmlSerialize metod is called during xml writing. + * + * @param Writer $writer + * @return void + */ + function xmlSerialize(Writer $writer) { + foreach ($this->shareTypes as $shareType) { + $writer->writeElement('{' . self::NS_OWNCLOUD . '}share-type', $shareType); + } + } +} diff --git a/apps/dav/tests/unit/connector/sabre/sharesplugin.php b/apps/dav/tests/unit/connector/sabre/sharesplugin.php new file mode 100644 index 0000000000000..b491e95bcb9de --- /dev/null +++ b/apps/dav/tests/unit/connector/sabre/sharesplugin.php @@ -0,0 +1,263 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\Tests\Unit\Connector\Sabre; + +/** + * Copyright (c) 2016 Vincent Petry + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +class SharesPlugin extends \Test\TestCase { + + const SHARETYPES_PROPERTYNAME = \OCA\DAV\Connector\Sabre\SharesPlugin::SHARETYPES_PROPERTYNAME; + + /** + * @var \Sabre\DAV\Server + */ + private $server; + + /** + * @var \Sabre\DAV\Tree + */ + private $tree; + + /** + * @var \OCP\Share\IManager + */ + private $shareManager; + + /** + * @var \OCP\Files\Folder + */ + private $userFolder; + + /** + * @var \OCA\DAV\Connector\Sabre\SharesPlugin + */ + private $plugin; + + public function setUp() { + parent::setUp(); + $this->server = new \Sabre\DAV\Server(); + $this->tree = $this->getMockBuilder('\Sabre\DAV\Tree') + ->disableOriginalConstructor() + ->getMock(); + $this->shareManager = $this->getMock('\OCP\Share\IManager'); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('user1')); + $userSession = $this->getMock('\OCP\IUserSession'); + $userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $this->userFolder = $this->getMock('\OCP\Files\Folder'); + + $this->plugin = new \OCA\DAV\Connector\Sabre\SharesPlugin( + $this->tree, + $userSession, + $this->userFolder, + $this->shareManager + ); + $this->plugin->initialize($this->server); + } + + /** + * @dataProvider sharesGetPropertiesDataProvider + */ + public function testGetProperties($shareTypes) { + $sabreNode = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Node') + ->disableOriginalConstructor() + ->getMock(); + $sabreNode->expects($this->any()) + ->method('getId') + ->will($this->returnValue(123)); + $sabreNode->expects($this->once()) + ->method('getPath') + ->will($this->returnValue('/subdir')); + + // node API nodes + $node = $this->getMock('\OCP\Files\Folder'); + + $this->userFolder->expects($this->once()) + ->method('get') + ->with('/subdir') + ->will($this->returnValue($node)); + + $this->shareManager->expects($this->any()) + ->method('getSharesBy') + ->with( + $this->equalTo('user1'), + $this->anything(), + $this->anything(), + $this->equalTo(false), + $this->equalTo(1) + ) + ->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes){ + if (in_array($requestedShareType, $shareTypes)) { + return ['dummyshare']; + } + return []; + })); + + $propFind = new \Sabre\DAV\PropFind( + '/dummyPath', + [self::SHARETYPES_PROPERTYNAME], + 0 + ); + + $this->plugin->handleGetProperties( + $propFind, + $sabreNode + ); + + $result = $propFind->getResultForMultiStatus(); + + $this->assertEmpty($result[404]); + unset($result[404]); + $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes()); + } + + /** + * @dataProvider sharesGetPropertiesDataProvider + */ + public function testPreloadThenGetProperties($shareTypes) { + $sabreNode1 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File') + ->disableOriginalConstructor() + ->getMock(); + $sabreNode1->expects($this->any()) + ->method('getId') + ->will($this->returnValue(111)); + $sabreNode1->expects($this->never()) + ->method('getPath'); + $sabreNode2 = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File') + ->disableOriginalConstructor() + ->getMock(); + $sabreNode2->expects($this->any()) + ->method('getId') + ->will($this->returnValue(222)); + $sabreNode2->expects($this->never()) + ->method('getPath'); + + $sabreNode = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->getMock(); + $sabreNode->expects($this->any()) + ->method('getId') + ->will($this->returnValue(123)); + // never, because we use getDirectoryListing from the Node API instead + $sabreNode->expects($this->never()) + ->method('getChildren'); + $sabreNode->expects($this->any()) + ->method('getPath') + ->will($this->returnValue('/subdir')); + + // node API nodes + $node = $this->getMock('\OCP\Files\Folder'); + $node->expects($this->any()) + ->method('getId') + ->will($this->returnValue(123)); + $node1 = $this->getMock('\OCP\Files\File'); + $node1->expects($this->any()) + ->method('getId') + ->will($this->returnValue(111)); + $node2 = $this->getMock('\OCP\Files\File'); + $node2->expects($this->any()) + ->method('getId') + ->will($this->returnValue(222)); + $node->expects($this->once()) + ->method('getDirectoryListing') + ->will($this->returnValue([$node1, $node2])); + + $this->userFolder->expects($this->once()) + ->method('get') + ->with('/subdir') + ->will($this->returnValue($node)); + + $this->shareManager->expects($this->any()) + ->method('getSharesBy') + ->with( + $this->equalTo('user1'), + $this->anything(), + $this->anything(), + $this->equalTo(false), + $this->equalTo(1) + ) + ->will($this->returnCallback(function($userId, $requestedShareType, $node, $flag, $limit) use ($shareTypes){ + if ($node->getId() === 111 && in_array($requestedShareType, $shareTypes)) { + return ['dummyshare']; + } + + return []; + })); + + // simulate sabre recursive PROPFIND traversal + $propFindRoot = new \Sabre\DAV\PropFind( + '/subdir', + [self::SHARETYPES_PROPERTYNAME], + 1 + ); + $propFind1 = new \Sabre\DAV\PropFind( + '/subdir/test.txt', + [self::SHARETYPES_PROPERTYNAME], + 0 + ); + $propFind2 = new \Sabre\DAV\PropFind( + '/subdir/test2.txt', + [self::SHARETYPES_PROPERTYNAME], + 0 + ); + + $this->plugin->handleGetProperties( + $propFindRoot, + $sabreNode + ); + $this->plugin->handleGetProperties( + $propFind1, + $sabreNode1 + ); + $this->plugin->handleGetProperties( + $propFind2, + $sabreNode2 + ); + + $result = $propFind1->getResultForMultiStatus(); + + $this->assertEmpty($result[404]); + unset($result[404]); + $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes()); + } + + function sharesGetPropertiesDataProvider() { + return [ + [[]], + [[\OCP\Share::SHARE_TYPE_USER]], + [[\OCP\Share::SHARE_TYPE_GROUP]], + [[\OCP\Share::SHARE_TYPE_LINK]], + [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP]], + [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]], + [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK]], + [[\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]], + ]; + } +} diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 2711b2392e9fa..5ec7824758f4b 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -60,6 +60,9 @@ if (fileData.recipientsDisplayName) { tr.attr('data-share-recipients', fileData.recipientsDisplayName); } + if (fileData.shareTypes) { + tr.attr('data-share-types', fileData.shareTypes.join(',')); + } return tr; }; @@ -77,6 +80,7 @@ fileList._getWebdavProperties = function() { var props = oldGetWebdavProperties.apply(this, arguments); props.push('{' + NS_OC + '}owner-display-name'); + props.push('{' + NS_OC + '}share-types'); return props; }; @@ -88,40 +92,45 @@ if (permissionsProp && permissionsProp.indexOf('S') >= 0) { data.shareOwner = props['{' + NS_OC + '}owner-display-name']; } + + var shareTypesProp = props['{' + NS_OC + '}share-types']; + if (shareTypesProp) { + data.shareTypes = _.chain(shareTypesProp).filter(function(xmlvalue) { + return (xmlvalue.namespaceURI === NS_OC && xmlvalue.nodeName.split(':')[1] === 'share-type'); + }).map(function(xmlvalue) { + return parseInt(xmlvalue.textContent || xmlvalue.text, 10); + }).value(); + } + return data; }); // use delegate to catch the case with multiple file lists fileList.$el.on('fileActionsReady', function(ev){ - var fileList = ev.fileList; var $files = ev.$files; - function updateIcons($files) { - if (!$files) { - // if none specified, update all - $files = fileList.$fileList.find('tr'); + _.each($files, function(file) { + var $tr = $(file); + var shareTypes = $tr.attr('data-share-types'); + if (shareTypes) { + var hasLink = false; + var hasShares = false; + _.each(shareTypes.split(',') || [], function(shareType) { + shareType = parseInt(shareType, 10); + if (shareType === OC.Share.SHARE_TYPE_LINK) { + hasLink = true; + } else if (shareType === OC.Share.SHARE_TYPE_USER) { + hasShares = true; + } else if (shareType === OC.Share.SHARE_TYPE_GROUP) { + hasShares = true; + } + }); + OCA.Sharing.Util._updateFileActionIcon($tr, hasShares, hasLink); } - _.each($files, function(file) { - var $tr = $(file); - var shareStatus = OC.Share.statuses[$tr.data('id')]; - OCA.Sharing.Util._updateFileActionIcon($tr, !!shareStatus, shareStatus && shareStatus.link); - }); - } - - if (!OCA.Sharing.sharesLoaded){ - OC.Share.loadIcons('file', fileList, function() { - // since we don't know which files are affected, just refresh them all - updateIcons(); - }); - // assume that we got all shares, so switching directories - // will not invalidate that list - OCA.Sharing.sharesLoaded = true; - } - else{ - updateIcons($files); - } + }); }); + fileList.$el.on('changeDirectory', function() { OCA.Sharing.sharesLoaded = false; }); diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index a799d4a94c2a0..da0f957ed99b8 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -286,6 +286,8 @@ // using a hash to make them unique, // this is only a list to be displayed data.recipients = {}; + // share types + data.shareTypes = {}; // counter is cheaper than calling _.keys().length data.recipientsCount = 0; data.mtime = file.share.stime; @@ -308,6 +310,8 @@ data.recipientsCount++; } + data.shareTypes[file.share.type] = true; + delete file.share; return memo; }, {}) @@ -324,6 +328,12 @@ data.recipientsCount ); delete data.recipientsCount; + if (self._sharedWithUser) { + // only for outgoing shres + delete data.shareTypes; + } else { + data.shareTypes = _.keys(data.shareTypes); + } }) // Finish the chain by getting the result .value(); diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js index 7607ada50baf6..c488bd94fab98 100644 --- a/apps/files_sharing/tests/js/shareSpec.js +++ b/apps/files_sharing/tests/js/shareSpec.js @@ -53,35 +53,21 @@ describe('OCA.Sharing.Util tests', function() { permissions: OC.PERMISSION_ALL, etag: 'abc', shareOwner: 'User One', - isShareMountPoint: false + isShareMountPoint: false, + shareTypes: [OC.Share.SHARE_TYPE_USER] }]; - - OCA.Sharing.sharesLoaded = true; - OC.Share.statuses = { - 1: {link: false, path: '/subdir'} - }; }); afterEach(function() { delete OCA.Sharing.sharesLoaded; delete OC.Share.droppedDown; fileList.destroy(); fileList = null; - OC.Share.statuses = {}; - OC.Share.currentShares = {}; }); describe('Sharing data in table row', function() { // TODO: test data-permissions, data-share-owner, etc }); describe('Share action icon', function() { - beforeEach(function() { - OC.Share.statuses = {1: {link: false, path: '/subdir'}}; - OCA.Sharing.sharesLoaded = true; - }); - afterEach(function() { - OC.Share.statuses = {}; - OCA.Sharing.sharesLoaded = false; - }); it('do not shows share text when not shared', function() { var $action, $tr; OC.Share.statuses = {}; @@ -93,7 +79,8 @@ describe('OCA.Sharing.Util tests', function() { mimetype: 'httpd/unix-directory', size: 12, permissions: OC.PERMISSION_ALL, - etag: 'abc' + etag: 'abc', + shareTypes: [] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); @@ -111,7 +98,8 @@ describe('OCA.Sharing.Util tests', function() { mimetype: 'text/plain', size: 12, permissions: OC.PERMISSION_ALL, - etag: 'abc' + etag: 'abc', + shareTypes: [OC.Share.SHARE_TYPE_USER] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); @@ -131,7 +119,8 @@ describe('OCA.Sharing.Util tests', function() { mimetype: 'text/plain', size: 12, permissions: OC.PERMISSION_ALL, - etag: 'abc' + etag: 'abc', + shareTypes: [OC.Share.SHARE_TYPE_LINK] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); @@ -151,7 +140,8 @@ describe('OCA.Sharing.Util tests', function() { size: 12, permissions: OC.PERMISSION_ALL, shareOwner: 'User One', - etag: 'abc' + etag: 'abc', + shareTypes: [OC.Share.SHARE_TYPE_USER] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); @@ -171,7 +161,8 @@ describe('OCA.Sharing.Util tests', function() { size: 12, permissions: OC.PERMISSION_ALL, recipientsDisplayName: 'User One, User Two', - etag: 'abc' + etag: 'abc', + shareTypes: [OC.Share.SHARE_TYPE_USER] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); From 3c77311397e49282cef6e77a4f0c52bd67522edc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 16 Mar 2016 11:03:26 +0100 Subject: [PATCH 106/286] Display share status info in favorite list Returns the shareTypes share status info to the favorites file list. --- apps/files/appinfo/application.php | 4 +- apps/files/controller/apicontroller.php | 54 +++++++++++++++++- apps/files/service/tagservice.php | 13 ++--- .../tests/controller/apicontrollertest.php | 56 ++++++++++++++++++- 4 files changed, 112 insertions(+), 15 deletions(-) diff --git a/apps/files/appinfo/application.php b/apps/files/appinfo/application.php index bc6dc9fb9edd9..593e0533c8006 100644 --- a/apps/files/appinfo/application.php +++ b/apps/files/appinfo/application.php @@ -40,8 +40,10 @@ public function __construct(array $urlParams=array()) { return new ApiController( $c->query('AppName'), $c->query('Request'), + $server->getUserSession(), $c->query('TagService'), - $server->getPreviewManager() + $server->getPreviewManager(), + $server->getShareManager() ); }); diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php index c96d92a046b0a..43abf2ff45899 100644 --- a/apps/files/controller/apicontroller.php +++ b/apps/files/controller/apicontroller.php @@ -34,6 +34,10 @@ use OCP\AppFramework\Http\DataDisplayResponse; use OCA\Files\Service\TagService; use OCP\IPreview; +use OCP\Share\IManager; +use OCP\Files\FileInfo; +use OCP\Files\Node; +use OCP\IUserSession; /** * Class ApiController @@ -43,8 +47,12 @@ class ApiController extends Controller { /** @var TagService */ private $tagService; + /** @var IManager **/ + private $shareManager; /** @var IPreview */ private $previewManager; + /** IUserSession */ + private $userSession; /** * @param string $appName @@ -54,11 +62,15 @@ class ApiController extends Controller { */ public function __construct($appName, IRequest $request, + IUserSession $userSession, TagService $tagService, - IPreview $previewManager){ + IPreview $previewManager, + IManager $shareManager) { parent::__construct($appName, $request); + $this->userSession = $userSession; $this->tagService = $tagService; $this->previewManager = $previewManager; + $this->shareManager = $shareManager; } /** @@ -132,8 +144,10 @@ public function updateFileTags($path, $tags = null) { */ public function getFilesByTag($tagName) { $files = array(); - $fileInfos = $this->tagService->getFilesByTag($tagName); - foreach ($fileInfos as &$fileInfo) { + $nodes = $this->tagService->getFilesByTag($tagName); + foreach ($nodes as &$node) { + $shareTypes = $this->getShareTypes($node); + $fileInfo = $node->getFileInfo(); $file = \OCA\Files\Helper::formatFileInfo($fileInfo); $parts = explode('/', dirname($fileInfo->getPath()), 4); if(isset($parts[3])) { @@ -142,9 +156,43 @@ public function getFilesByTag($tagName) { $file['path'] = '/'; } $file['tags'] = [$tagName]; + if (!empty($shareTypes)) { + $file['shareTypes'] = $shareTypes; + } $files[] = $file; } return new DataResponse(['files' => $files]); } + /** + * Return a list of share types for outgoing shares + * + * @param Node $node file node + * + * @return int[] array of share types + */ + private function getShareTypes(Node $node) { + $userId = $this->userSession->getUser()->getUID(); + $shareTypes = []; + $requestedShareTypes = [ + \OCP\Share::SHARE_TYPE_USER, + \OCP\Share::SHARE_TYPE_GROUP, + \OCP\Share::SHARE_TYPE_LINK + ]; + foreach ($requestedShareTypes as $requestedShareType) { + // one of each type is enough to find out about the types + $shares = $this->shareManager->getSharesBy( + $userId, + $requestedShareType, + $node, + false, + 1 + ); + if (!empty($shares)) { + $shareTypes[] = $requestedShareType; + } + } + return $shareTypes; + } + } diff --git a/apps/files/service/tagservice.php b/apps/files/service/tagservice.php index e1425c466159e..57cad43a53942 100644 --- a/apps/files/service/tagservice.php +++ b/apps/files/service/tagservice.php @@ -25,6 +25,7 @@ namespace OCA\Files\Service; use OC\Files\FileInfo; +use OCP\Files\Node; /** * Service class to manage tags on files. @@ -93,7 +94,7 @@ public function updateFileTags($path, $tags) { * Get all files for the given tag * * @param string $tagName tag name to filter by - * @return FileInfo[] list of matching files + * @return Node[] list of matching files * @throws \Exception if the tag does not exist */ public function getFilesByTag($tagName) { @@ -103,15 +104,11 @@ public function getFilesByTag($tagName) { return []; } - $fileInfos = []; + $allNodes = []; foreach ($fileIds as $fileId) { - $nodes = $this->homeFolder->getById((int) $fileId); - foreach ($nodes as $node) { - /** @var \OC\Files\Node\Node $node */ - $fileInfos[] = $node->getFileInfo(); - } + $allNodes = array_merge($allNodes, $this->homeFolder->getById((int) $fileId)); } - return $fileInfos; + return $allNodes; } } diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php index 6fb8340ead800..a9b248a36fede 100644 --- a/apps/files/tests/controller/apicontrollertest.php +++ b/apps/files/tests/controller/apicontrollertest.php @@ -51,14 +51,27 @@ class ApiControllerTest extends TestCase { private $preview; /** @var ApiController */ private $apiController; + /** @var \OCP\Share\IManager */ + private $shareManager; public function setUp() { $this->request = $this->getMockBuilder('\OCP\IRequest') ->disableOriginalConstructor() ->getMock(); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('user1')); + $userSession = $this->getMock('\OCP\IUserSession'); + $userSession->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($user)); $this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService') ->disableOriginalConstructor() ->getMock(); + $this->shareManager = $this->getMockBuilder('\OCP\Share\IManager') + ->disableOriginalConstructor() + ->getMock(); $this->preview = $this->getMockBuilder('\OCP\IPreview') ->disableOriginalConstructor() ->getMock(); @@ -66,8 +79,10 @@ public function setUp() { $this->apiController = new ApiController( $this->appName, $this->request, + $userSession, $this->tagService, - $this->preview + $this->preview, + $this->shareManager ); } @@ -101,10 +116,32 @@ public function testGetFilesByTagSingle() { ->disableOriginalConstructor() ->getMock() ); + $node = $this->getMockBuilder('\OC\Files\Node\File') + ->disableOriginalConstructor() + ->getMock(); + $node->expects($this->once()) + ->method('getFileInfo') + ->will($this->returnValue($fileInfo)); $this->tagService->expects($this->once()) ->method('getFilesByTag') ->with($this->equalTo([$tagName])) - ->will($this->returnValue([$fileInfo])); + ->will($this->returnValue([$node])); + + $this->shareManager->expects($this->any()) + ->method('getSharesBy') + ->with( + $this->equalTo('user1'), + $this->anything(), + $node, + $this->equalTo(false), + $this->equalTo(1) + ) + ->will($this->returnCallback(function($userId, $shareType) { + if ($shareType === \OCP\Share::SHARE_TYPE_USER || $shareType === \OCP\Share::SHARE_TYPE_LINK) { + return ['dummy_share']; + } + return []; + })); $expected = new DataResponse([ 'files' => [ @@ -124,6 +161,7 @@ public function testGetFilesByTagSingle() { 'MyTagName' ] ], + 'shareTypes' => [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK] ], ], ]); @@ -166,10 +204,22 @@ public function testGetFilesByTagMultiple() { ->disableOriginalConstructor() ->getMock() ); + $node1 = $this->getMockBuilder('\OC\Files\Node\File') + ->disableOriginalConstructor() + ->getMock(); + $node1->expects($this->once()) + ->method('getFileInfo') + ->will($this->returnValue($fileInfo1)); + $node2 = $this->getMockBuilder('\OC\Files\Node\File') + ->disableOriginalConstructor() + ->getMock(); + $node2->expects($this->once()) + ->method('getFileInfo') + ->will($this->returnValue($fileInfo2)); $this->tagService->expects($this->once()) ->method('getFilesByTag') ->with($this->equalTo([$tagName])) - ->will($this->returnValue([$fileInfo1, $fileInfo2])); + ->will($this->returnValue([$node1, $node2])); $expected = new DataResponse([ 'files' => [ From 26deb0a8979b65e47b3f107fc237758590f67de4 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 17 Mar 2016 15:50:33 +0100 Subject: [PATCH 107/286] Add intergration tests Intergration tests to ensure the share-types property is set correctly. * Unshared item * Shared with user * Shared with group * Shared by link * Shared with user & group & link --- .../integration/features/bootstrap/WebDav.php | 55 +++++++++++++- .../features/webdav-related.feature | 73 +++++++++++++++++++ 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index 0430768022c67..0a4624ccc2b1c 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -168,8 +168,8 @@ public function asGetsPropertiesOfFolderWith($user, $path, $propertiesTable) { */ public function theSingleResponseShouldContainAPropertyWithValue($key, $expectedValue) { $keys = $this->response; - if (!isset($keys[$key])) { - throw new \Exception("Cannot find property \"$key\" with \"$expectedalue\""); + if (!array_key_exists($key, $keys)) { + throw new \Exception("Cannot find property \"$key\" with \"$expectedValue\""); } $value = $keys[$key]; @@ -178,6 +178,57 @@ public function theSingleResponseShouldContainAPropertyWithValue($key, $expected } } + /** + * @Then the response should contain a share-types property with + */ + public function theResponseShouldContainAShareTypesPropertyWith($table) + { + $keys = $this->response; + if (!array_key_exists('{http://owncloud.org/ns}share-types', $keys)) { + throw new \Exception("Cannot find property \"{http://owncloud.org/ns}share-types\""); + } + + $foundTypes = []; + $data = $keys['{http://owncloud.org/ns}share-types']; + foreach ($data as $item) { + if ($item['name'] !== '{http://owncloud.org/ns}share-type') { + throw new \Exception('Invalid property found: "' . $item['name'] . '"'); + } + + $foundTypes[] = $item['value']; + } + + foreach ($table->getRows() as $row) { + $key = array_search($row[0], $foundTypes); + if ($key === false) { + throw new \Exception('Expected type ' . $row[0] . ' not found'); + } + + unset($foundTypes[$key]); + } + + if ($foundTypes !== []) { + throw new \Exception('Found more share types then specified: ' . $foundTypes); + } + } + + /** + * @Then the response should contain an empty property :property + * @param string $property + * @throws \Exception + */ + public function theResponseShouldContainAnEmptyProperty($property) { + $properties = $this->response; + if (!array_key_exists($property, $properties)) { + throw new \Exception("Cannot find property \"$property\""); + } + + if ($properties[$property] !== null) { + throw new \Exception("Property \"$property\" is not empty"); + } + } + + /*Returns the elements of a propfind, $folderDepth requires 1 to see elements without children*/ public function listFolder($user, $path, $folderDepth, $properties = null){ $fullUrl = substr($this->baseUrl, 0, -4); diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature index 019df3436f8a9..ee841f9eb5b4e 100644 --- a/build/integration/features/webdav-related.feature +++ b/build/integration/features/webdav-related.feature @@ -168,3 +168,76 @@ Feature: webdav-related When As an "user0" And Downloading file "/myChunkedFile.txt" Then Downloaded content should be "AAAAABBBBBCCCCC" + + Scenario: A file that is not shared does not have a share-types property + Given user "user0" exists + And user "user0" created a folder "/test" + When as "user0" gets properties of folder "/test" with + |{http://owncloud.org/ns}share-types| + Then the response should contain an empty property "{http://owncloud.org/ns}share-types" + + Scenario: A file that is shared to a user has a share-types property + Given user "user0" exists + And user "user1" exists + And user "user0" created a folder "/test" + And as "user0" creating a share with + | path | test | + | shareType | 0 | + | permissions | 31 | + | shareWith | user1 | + When as "user0" gets properties of folder "/test" with + |{http://owncloud.org/ns}share-types| + Then the response should contain a share-types property with + | 0 | + + Scenario: A file that is shared to a group has a share-types property + Given user "user0" exists + And group "group1" exists + And user "user0" created a folder "/test" + And as "user0" creating a share with + | path | test | + | shareType | 1 | + | permissions | 31 | + | shareWith | group1 | + When as "user0" gets properties of folder "/test" with + |{http://owncloud.org/ns}share-types| + Then the response should contain a share-types property with + | 1 | + + Scenario: A file that is shared by link has a share-types property + Given user "user0" exists + And user "user0" created a folder "/test" + And as "user0" creating a share with + | path | test | + | shareType | 3 | + | permissions | 31 | + When as "user0" gets properties of folder "/test" with + |{http://owncloud.org/ns}share-types| + Then the response should contain a share-types property with + | 3 | + + Scenario: A file that is shared by user,group and link has a share-types property + Given user "user0" exists + And user "user1" exists + And group "group2" exists + And user "user0" created a folder "/test" + And as "user0" creating a share with + | path | test | + | shareType | 0 | + | permissions | 31 | + | shareWith | user1 | + And as "user0" creating a share with + | path | test | + | shareType | 1 | + | permissions | 31 | + | shareWith | group2 | + And as "user0" creating a share with + | path | test | + | shareType | 3 | + | permissions | 31 | + When as "user0" gets properties of folder "/test" with + |{http://owncloud.org/ns}share-types| + Then the response should contain a share-types property with + | 0 | + | 1 | + | 3 | From df056e129918e3b9dd5f9f15f594163356a775db Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 17 Mar 2016 17:01:37 +0100 Subject: [PATCH 108/286] Remove duplicated copyright --- apps/dav/lib/connector/sabre/sharesplugin.php | 21 ------------------- .../unit/connector/sabre/sharesplugin.php | 6 ------ 2 files changed, 27 deletions(-) diff --git a/apps/dav/lib/connector/sabre/sharesplugin.php b/apps/dav/lib/connector/sabre/sharesplugin.php index df524c11a844b..f75c137871804 100644 --- a/apps/dav/lib/connector/sabre/sharesplugin.php +++ b/apps/dav/lib/connector/sabre/sharesplugin.php @@ -20,27 +20,6 @@ */ namespace OCA\DAV\Connector\Sabre; -/** - * ownCloud - * - * @author Vincent Petry - * @copyright 2016 Vincent Petry - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - use \Sabre\DAV\PropFind; use \Sabre\DAV\PropPatch; use OCP\IUserSession; diff --git a/apps/dav/tests/unit/connector/sabre/sharesplugin.php b/apps/dav/tests/unit/connector/sabre/sharesplugin.php index b491e95bcb9de..9a1c6eec50751 100644 --- a/apps/dav/tests/unit/connector/sabre/sharesplugin.php +++ b/apps/dav/tests/unit/connector/sabre/sharesplugin.php @@ -20,12 +20,6 @@ */ namespace OCA\DAV\Tests\Unit\Connector\Sabre; -/** - * Copyright (c) 2016 Vincent Petry - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ class SharesPlugin extends \Test\TestCase { const SHARETYPES_PROPERTYNAME = \OCA\DAV\Connector\Sabre\SharesPlugin::SHARETYPES_PROPERTYNAME; From a7dfc70e2e267e5628dc668491b538676d220742 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 2 Feb 2016 10:42:35 +0100 Subject: [PATCH 109/286] Allow creating tags where another one with same prefix exists When creating a new entry, compare the full tag name and not only the prefix. --- core/js/systemtags/systemtagsinputfield.js | 4 +++- .../tests/specs/systemtags/systemtagsinputfieldSpec.js | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/js/systemtags/systemtagsinputfield.js b/core/js/systemtags/systemtagsinputfield.js index 148d52b57dd52..45dc5b7b03e9b 100644 --- a/core/js/systemtags/systemtagsinputfield.js +++ b/core/js/systemtags/systemtagsinputfield.js @@ -320,7 +320,9 @@ */ _createSearchChoice: function(term) { term = term.trim(); - if (this.collection.filterByName(term).length) { + if (this.collection.filter(function(entry) { + return entry.get('name') === term; + }).length) { return; } if (!this._newTag) { diff --git a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js index aadf0de53f2ae..22bf0d2c82a50 100644 --- a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js +++ b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js @@ -85,6 +85,15 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() { expect(result.userVisible).toEqual(true); expect(result.userAssignable).toEqual(true); }); + it('creates dummy tag when user types non-matching name even with prefix of existing tag', function() { + var opts = select2Stub.getCall(0).args[0]; + var result = opts.createSearchChoice('ab'); + expect(result.id).toEqual(-1); + expect(result.name).toEqual('ab'); + expect(result.isNew).toEqual(true); + expect(result.userVisible).toEqual(true); + expect(result.userAssignable).toEqual(true); + }); it('creates the real tag and fires select event after user selects the dummy tag', function() { var selectHandler = sinon.stub(); view.on('select', selectHandler); From 064e13511fecba105be567c31872138cca6b5ace Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 16 Mar 2016 09:02:08 +0100 Subject: [PATCH 110/286] Make sure to append the web root as per doc --- apps/files_sharing/api/server2server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/api/server2server.php b/apps/files_sharing/api/server2server.php index a3d58880f7057..11b24d9148b9f 100644 --- a/apps/files_sharing/api/server2server.php +++ b/apps/files_sharing/api/server2server.php @@ -107,12 +107,12 @@ public function createShare($params) { $declineAction = $notification->createAction(); $declineAction->setLabel('decline') - ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId), 'DELETE'); + ->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE'); $notification->addAction($declineAction); $acceptAction = $notification->createAction(); $acceptAction->setLabel('accept') - ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId), 'POST'); + ->setLink($urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'ocs/v1.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST'); $notification->addAction($acceptAction); $notificationManager->notify($notification); From 8ef8be6be52e17b459f08231a27ff08d7ddc2ec3 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 18 Mar 2016 11:59:57 +0100 Subject: [PATCH 111/286] Keep share checkboxes together - removed leading spaces before markup which can affect rendering in some cases - added shareOption CSS class to group and keep share option checkbox + label - moved ".showCruds" arrow into the matching shareOption to keep the arrow together with the checkbox --- core/css/share.css | 5 ++ core/js/sharedialogshareelistview.js | 86 ++++++++++++++++------------ 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/core/css/share.css b/core/css/share.css index 55ee5996a7505..047bb5eba506c 100644 --- a/core/css/share.css +++ b/core/css/share.css @@ -63,6 +63,11 @@ white-space: normal; } +#shareWithList .shareOption { + white-space: nowrap; + display: inline-block; +} + #shareWithList .unshare img, #shareWithList .showCruds img { vertical-align:text-bottom; /* properly align icons */ } diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js index 49580cc888bce..e4edbf24c0868 100644 --- a/core/js/sharedialogshareelistview.js +++ b/core/js/sharedialogshareelistview.js @@ -16,42 +16,56 @@ var TEMPLATE = '
    ' + '{{#each sharees}}' + - '
  • ' + - ' {{unshareLabel}}' + - ' {{#if avatarEnabled}}' + - '
    ' + - ' {{/if}}' + - ' {{shareWithDisplayName}}' + - ' {{#if mailNotificationEnabled}} {{#unless isRemoteShare}}' + - ' ' + - ' ' + - ' {{/unless}} {{/if}}' + - ' {{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isRemoteShare}}' + - ' ' + - ' ' + - ' {{/unless}} {{/if}} {{/if}}' + - ' {{#if editPermissionPossible}}' + - ' ' + - ' ' + - ' {{/if}}' + - ' {{#unless isRemoteShare}}' + - ' {{crudsLabel}}' + - ' ' + - ' {{/unless}}' + - '
  • ' + + '
  • ' + + '{{unshareLabel}}' + + '{{#if avatarEnabled}}' + + '
    ' + + '{{/if}}' + + '{{shareWithDisplayName}}' + + '{{#if mailNotificationEnabled}} {{#unless isRemoteShare}}' + + '' + + '' + + '' + + '' + + '{{/unless}} {{/if}}' + + '{{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isRemoteShare}}' + + '' + + '' + + '' + + '' + + '{{/unless}} {{/if}} {{/if}}' + + '{{#if editPermissionPossible}}' + + '' + + '' + + '' + + '{{#unless isRemoteShare}}' + + '{{crudsLabel}}' + + '{{/unless}}' + + '' + + '{{/if}}' + + '{{#unless isRemoteShare}}' + + '' + + '{{/unless}}' + + '
  • ' + '{{/each}}' + '
' ; From d282affec2ec4a34fa5aefeae3798f3aedcbf6bd Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 16 Mar 2016 00:45:30 +0100 Subject: [PATCH 112/286] fix writing to cache when fallback server should be used immediately --- apps/user_ldap/lib/connection.php | 14 +++++- apps/user_ldap/tests/connection.php | 78 ++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index fc6df5fc60292..74a8b55066d00 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -177,6 +177,16 @@ public function getConnectionResource() { return $this->ldapConnectionRes; } + /** + * resets the connection resource + */ + public function resetConnectionResource() { + if(!is_null($this->ldapConnectionRes)) { + @$this->ldap->unbind($this->ldapConnectionRes); + $this->ldapConnectionRes = null; + } + } + /** * @param string|null $key * @return string @@ -528,7 +538,7 @@ private function establishConnection() { } $bindStatus = false; - $error = null; + $error = -1; try { if (!$this->configuration->ldapOverrideMainServer && !$this->getFromCache('overrideMainServer') @@ -556,7 +566,7 @@ private function establishConnection() { $this->doConnect($this->configuration->ldapBackupHost, $this->configuration->ldapBackupPort); $bindStatus = $this->bind(); - if($bindStatus && $error === -1) { + if($bindStatus && $error === -1 && !$this->getFromCache('overrideMainServer')) { //when bind to backup server succeeded and failed to main server, //skip contacting him until next cache refresh $this->writeToCache('overrideMainServer', true); diff --git a/apps/user_ldap/tests/connection.php b/apps/user_ldap/tests/connection.php index ecee25583ab74..a6ccf4b340b47 100644 --- a/apps/user_ldap/tests/connection.php +++ b/apps/user_ldap/tests/connection.php @@ -23,6 +23,7 @@ */ namespace OCA\user_ldap\tests; +use OCA\user_ldap\lib\Connection; /** * Class Test_Connection @@ -32,6 +33,26 @@ * @package OCA\user_ldap\tests */ class Test_Connection extends \Test\TestCase { + /** @var \OCA\user_ldap\lib\ILDAPWrapper */ + protected $ldap; + + /** @var Connection */ + protected $connection; + + public function setUp() { + parent::setUp(); + + $this->ldap = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); + // we use a mock here to replace the cache mechanism, due to missing DI in LDAP backend. + $this->connection = $this->getMockBuilder('OCA\user_ldap\lib\Connection') + ->setMethods(['getFromCache', 'writeToCache']) + ->setConstructorArgs([$this->ldap, '', null]) + ->getMock(); + + $this->ldap->expects($this->any()) + ->method('areLDAPFunctionsAvailable') + ->will($this->returnValue(true)); + } public function testOriginalAgentUnchangedOnClone() { //background: upon login a bind is done with the user credentials @@ -39,7 +60,7 @@ public function testOriginalAgentUnchangedOnClone() { //to the agent's credentials $lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper'); - $connection = new \OCA\user_ldap\lib\Connection($lw, '', null); + $connection = new Connection($lw, '', null); $agent = array( 'ldapAgentName' => 'agent', 'ldapAgentPassword' => '123456', @@ -60,4 +81,59 @@ public function testOriginalAgentUnchangedOnClone() { $this->assertSame($agentPawd, $agent['ldapAgentPassword']); } + public function testUseBackupServer() { + $mainHost = 'ldap://nixda.ldap'; + $backupHost = 'ldap://fallback.ldap'; + $config = [ + 'ldapConfigurationActive' => true, + 'ldapHost' => $mainHost, + 'ldapPort' => 389, + 'ldapBackupHost' => $backupHost, + 'ldapBackupPort' => 389, + 'ldapAgentName' => 'uid=agent', + 'ldapAgentPassword' => 'SuchASecret' + ]; + + $this->connection->setIgnoreValidation(true); + $this->connection->setConfiguration($config); + + $this->ldap->expects($this->any()) + ->method('isResource') + ->will($this->returnValue(true)); + + $this->ldap->expects($this->any()) + ->method('setOption') + ->will($this->returnValue(true)); + + $this->ldap->expects($this->exactly(3)) + ->method('connect') + ->will($this->returnValue('ldapResource')); + + // Not called often enough? Then, the fallback to the backup server is broken. + $this->connection->expects($this->exactly(4)) + ->method('getFromCache') + ->with('overrideMainServer') + ->will($this->onConsecutiveCalls(false, false, true, true)); + + $this->connection->expects($this->once()) + ->method('writeToCache') + ->with('overrideMainServer', true); + + $isThrown = false; + $this->ldap->expects($this->exactly(3)) + ->method('bind') + ->will($this->returnCallback(function () use (&$isThrown) { + if(!$isThrown) { + $isThrown = true; + throw new \OC\ServerNotAvailableException(); + } + return true; + })); + + $this->connection->init(); + $this->connection->resetConnectionResource(); + // with the second init() we test whether caching works + $this->connection->init(); + } + } From 1a239b2f0db658a71322a9256f5d62539830f1ed Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 18 Mar 2016 13:22:05 +0100 Subject: [PATCH 113/286] Do not create a new job when it failed to connect atm --- .../backgroundjob/getsharedsecret.php | 25 ++++++++++------- .../backgroundjob/requestsharedsecret.php | 23 +++++++++------- .../backgroundjob/getsharedsecrettest.php | 27 ++++++++++++++----- .../backgroundjob/requestsharedsecrettest.php | 26 +++++++++++++----- 4 files changed, 68 insertions(+), 33 deletions(-) diff --git a/apps/federation/backgroundjob/getsharedsecret.php b/apps/federation/backgroundjob/getsharedsecret.php index d3dd00c74a22d..66ab082c1a25b 100644 --- a/apps/federation/backgroundjob/getsharedsecret.php +++ b/apps/federation/backgroundjob/getsharedsecret.php @@ -25,12 +25,13 @@ use GuzzleHttp\Exception\ClientException; use OC\BackgroundJob\JobList; -use OC\BackgroundJob\QueuedJob; +use OC\BackgroundJob\Job; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; use OCP\AppFramework\Http; use OCP\BackgroundJob\IJobList; use OCP\Http\Client\IClient; +use OCP\Http\Client\IResponse; use OCP\ILogger; use OCP\IURLGenerator; @@ -41,7 +42,7 @@ * * @package OCA\Federation\Backgroundjob */ -class GetSharedSecret extends QueuedJob{ +class GetSharedSecret extends Job{ /** @var IClient */ private $httpClient; @@ -61,6 +62,9 @@ class GetSharedSecret extends QueuedJob{ /** @var ILogger */ private $logger; + /** @var bool */ + protected $retainJob = false; + private $endPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret?format=json'; /** @@ -79,7 +83,7 @@ public function __construct( IJobList $jobList = null, TrustedServers $trustedServers = null, ILogger $logger = null, - dbHandler $dbHandler = null + DbHandler $dbHandler = null ) { $this->logger = $logger ? $logger : \OC::$server->getLogger(); $this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient(); @@ -108,12 +112,15 @@ public function __construct( * @param ILogger $logger */ public function execute($jobList, ILogger $logger = null) { - $jobList->remove($this, $this->argument); $target = $this->argument['url']; // only execute if target is still in the list of trusted domains if ($this->trustedServers->isTrustedServer($target)) { $this->parentExecute($jobList, $logger); } + + if (!$this->retainJob) { + $jobList->remove($this, $this->argument); + } } /** @@ -132,6 +139,7 @@ protected function run($argument) { $source = rtrim($source, '/'); $token = $argument['token']; + $result = null; try { $result = $this->httpClient->get( $target . $this->endPoint, @@ -156,7 +164,7 @@ protected function run($argument) { $this->logger->logException($e, ['app' => 'federation']); } } catch (\Exception $e) { - $status = HTTP::STATUS_INTERNAL_SERVER_ERROR; + $status = Http::STATUS_INTERNAL_SERVER_ERROR; $this->logger->logException($e, ['app' => 'federation']); } @@ -165,16 +173,13 @@ protected function run($argument) { $status !== Http::STATUS_OK && $status !== Http::STATUS_FORBIDDEN ) { - $this->jobList->add( - 'OCA\Federation\BackgroundJob\GetSharedSecret', - $argument - ); + $this->retainJob = true; } else { // reset token if we received a valid response $this->dbHandler->addToken($target, ''); } - if ($status === Http::STATUS_OK) { + if ($status === Http::STATUS_OK && $result instanceof IResponse) { $body = $result->getBody(); $result = json_decode($body, true); if (isset($result['ocs']['data']['sharedSecret'])) { diff --git a/apps/federation/backgroundjob/requestsharedsecret.php b/apps/federation/backgroundjob/requestsharedsecret.php index 79b55fe4ee485..040e8e1d8e258 100644 --- a/apps/federation/backgroundjob/requestsharedsecret.php +++ b/apps/federation/backgroundjob/requestsharedsecret.php @@ -27,7 +27,7 @@ use GuzzleHttp\Exception\ClientException; use OC\BackgroundJob\JobList; -use OC\BackgroundJob\QueuedJob; +use OC\BackgroundJob\Job; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; use OCP\AppFramework\Http; @@ -43,7 +43,7 @@ * * @package OCA\Federation\Backgroundjob */ -class RequestSharedSecret extends QueuedJob { +class RequestSharedSecret extends Job { /** @var IClient */ private $httpClient; @@ -65,6 +65,9 @@ class RequestSharedSecret extends QueuedJob { /** @var ILogger */ private $logger; + /** @var bool */ + protected $retainJob = false; + /** * RequestSharedSecret constructor. * @@ -79,7 +82,7 @@ public function __construct( IURLGenerator $urlGenerator = null, IJobList $jobList = null, TrustedServers $trustedServers = null, - dbHandler $dbHandler = null + DbHandler $dbHandler = null ) { $this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient(); $this->jobList = $jobList ? $jobList : \OC::$server->getJobList(); @@ -109,15 +112,20 @@ public function __construct( * @param ILogger $logger */ public function execute($jobList, ILogger $logger = null) { - $jobList->remove($this, $this->argument); $target = $this->argument['url']; // only execute if target is still in the list of trusted domains if ($this->trustedServers->isTrustedServer($target)) { $this->parentExecute($jobList, $logger); } + + if (!$this->retainJob) { + $jobList->remove($this, $this->argument); + } } /** + * call execute() method of parent + * * @param JobList $jobList * @param ILogger $logger */ @@ -155,7 +163,7 @@ protected function run($argument) { $this->logger->logException($e, ['app' => 'federation']); } } catch (\Exception $e) { - $status = HTTP::STATUS_INTERNAL_SERVER_ERROR; + $status = Http::STATUS_INTERNAL_SERVER_ERROR; $this->logger->logException($e, ['app' => 'federation']); } @@ -164,10 +172,7 @@ protected function run($argument) { $status !== Http::STATUS_OK && $status !== Http::STATUS_FORBIDDEN ) { - $this->jobList->add( - 'OCA\Federation\BackgroundJob\RequestSharedSecret', - $argument - ); + $this->retainJob = true; } if ($status === Http::STATUS_FORBIDDEN) { diff --git a/apps/federation/tests/backgroundjob/getsharedsecrettest.php b/apps/federation/tests/backgroundjob/getsharedsecrettest.php index 08c8677415cf7..25f7502741df2 100644 --- a/apps/federation/tests/backgroundjob/getsharedsecrettest.php +++ b/apps/federation/tests/backgroundjob/getsharedsecrettest.php @@ -95,8 +95,9 @@ public function setUp() { * @dataProvider dataTestExecute * * @param bool $isTrustedServer + * @param bool $retainBackgroundJob */ - public function testExecute($isTrustedServer) { + public function testExecute($isTrustedServer, $retainBackgroundJob) { /** @var GetSharedSecret |\PHPUnit_Framework_MockObject_MockObject $getSharedSecret */ $getSharedSecret = $this->getMockBuilder('OCA\Federation\BackgroundJob\GetSharedSecret') ->setConstructorArgs( @@ -111,7 +112,6 @@ public function testExecute($isTrustedServer) { )->setMethods(['parentExecute'])->getMock(); $this->invokePrivate($getSharedSecret, 'argument', [['url' => 'url']]); - $this->jobList->expects($this->once())->method('remove'); $this->trustedServers->expects($this->once())->method('isTrustedServer') ->with('url')->willReturn($isTrustedServer); if ($isTrustedServer) { @@ -119,6 +119,12 @@ public function testExecute($isTrustedServer) { } else { $getSharedSecret->expects($this->never())->method('parentExecute'); } + $this->invokePrivate($getSharedSecret, 'retainJob', [$retainBackgroundJob]); + if ($retainBackgroundJob) { + $this->jobList->expects($this->never())->method('remove'); + } else { + $this->jobList->expects($this->once())->method('remove'); + } $getSharedSecret->execute($this->jobList); @@ -126,8 +132,9 @@ public function testExecute($isTrustedServer) { public function dataTestExecute() { return [ - [true], - [false] + [true, true], + [true, false], + [false, false], ]; } @@ -167,12 +174,9 @@ public function testRun($statusCode) { $statusCode !== Http::STATUS_OK && $statusCode !== Http::STATUS_FORBIDDEN ) { - $this->jobList->expects($this->once())->method('add') - ->with('OCA\Federation\BackgroundJob\GetSharedSecret', $argument); $this->dbHandler->expects($this->never())->method('addToken'); } else { $this->dbHandler->expects($this->once())->method('addToken')->with($target, ''); - $this->jobList->expects($this->never())->method('add'); } if ($statusCode === Http::STATUS_OK) { @@ -185,6 +189,15 @@ public function testRun($statusCode) { } $this->invokePrivate($this->getSharedSecret, 'run', [$argument]); + if ( + $statusCode !== Http::STATUS_OK + && $statusCode !== Http::STATUS_FORBIDDEN + ) { + $this->assertTrue($this->invokePrivate($this->getSharedSecret, 'retainJob')); + } else { + $this->assertFalse($this->invokePrivate($this->getSharedSecret, 'retainJob')); + } + } public function dataTestRun() { diff --git a/apps/federation/tests/backgroundjob/requestsharedsecrettest.php b/apps/federation/tests/backgroundjob/requestsharedsecrettest.php index 45f79e05249cd..5b4a1f87a5f61 100644 --- a/apps/federation/tests/backgroundjob/requestsharedsecrettest.php +++ b/apps/federation/tests/backgroundjob/requestsharedsecrettest.php @@ -75,8 +75,9 @@ public function setUp() { * @dataProvider dataTestExecute * * @param bool $isTrustedServer + * @param bool $retainBackgroundJob */ - public function testExecute($isTrustedServer) { + public function testExecute($isTrustedServer, $retainBackgroundJob) { /** @var RequestSharedSecret |\PHPUnit_Framework_MockObject_MockObject $requestSharedSecret */ $requestSharedSecret = $this->getMockBuilder('OCA\Federation\BackgroundJob\RequestSharedSecret') ->setConstructorArgs( @@ -90,7 +91,6 @@ public function testExecute($isTrustedServer) { )->setMethods(['parentExecute'])->getMock(); $this->invokePrivate($requestSharedSecret, 'argument', [['url' => 'url']]); - $this->jobList->expects($this->once())->method('remove'); $this->trustedServers->expects($this->once())->method('isTrustedServer') ->with('url')->willReturn($isTrustedServer); if ($isTrustedServer) { @@ -98,6 +98,12 @@ public function testExecute($isTrustedServer) { } else { $requestSharedSecret->expects($this->never())->method('parentExecute'); } + $this->invokePrivate($requestSharedSecret, 'retainJob', [$retainBackgroundJob]); + if ($retainBackgroundJob) { + $this->jobList->expects($this->never())->method('remove'); + } else { + $this->jobList->expects($this->once())->method('remove'); + } $requestSharedSecret->execute($this->jobList); @@ -105,8 +111,9 @@ public function testExecute($isTrustedServer) { public function dataTestExecute() { return [ - [true], - [false] + [true, true], + [true, false], + [false, false], ]; } @@ -146,17 +153,22 @@ public function testRun($statusCode) { $statusCode !== Http::STATUS_OK && $statusCode !== Http::STATUS_FORBIDDEN ) { - $this->jobList->expects($this->once())->method('add') - ->with('OCA\Federation\BackgroundJob\RequestSharedSecret', $argument); $this->dbHandler->expects($this->never())->method('addToken'); } if ($statusCode === Http::STATUS_FORBIDDEN) { - $this->jobList->expects($this->never())->method('add'); $this->dbHandler->expects($this->once())->method('addToken')->with($target, ''); } $this->invokePrivate($this->requestSharedSecret, 'run', [$argument]); + if ( + $statusCode !== Http::STATUS_OK + && $statusCode !== Http::STATUS_FORBIDDEN + ) { + $this->assertTrue($this->invokePrivate($this->requestSharedSecret, 'retainJob')); + } else { + $this->assertFalse($this->invokePrivate($this->requestSharedSecret, 'retainJob')); + } } public function dataTestRun() { From 627724bc6aa20bf9bf2b90297427c9126d8492ff Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 21 Mar 2016 15:10:24 +0100 Subject: [PATCH 114/286] apply retry wrapper to make sure that we always read/write a complete block --- apps/files_external/lib/ftp.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 125888ef72237..338e2c14fa4c7 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -30,6 +30,8 @@ namespace OC\Files\Storage; +use Icewind\Streams\RetryWrapper; + class FTP extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; @@ -105,7 +107,8 @@ public function fopen($path,$mode) { case 'ab': //these are supported by the wrapper $context = stream_context_create(array('ftp' => array('overwrite' => true))); - return fopen($this->constructUrl($path), $mode, false, $context); + $handle = fopen($this->constructUrl($path), $mode, false, $context); + return RetryWrapper::wrap($handle); case 'r+': case 'w+': case 'wb+': From 419adc8d50a4e2b116fa07e50f75810322031400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 10 Mar 2016 13:04:50 +0100 Subject: [PATCH 115/286] Birthday events are generated on upgrade --- apps/dav/appinfo/application.php | 15 +++++++++++++++ apps/dav/appinfo/info.xml | 2 +- apps/dav/appinfo/update.php | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 1dae3d4efbf1b..d06daf97f5452 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -210,4 +210,19 @@ public function migrateCalendars() { $this->getContainer()->getServer()->getLogger()->logException($ex); } } + + public function generateBirthdays() { + try { + /** @var BirthdayService $migration */ + $migration = $this->getContainer()->query('BirthdayService'); + $userManager = $this->getContainer()->getServer()->getUserManager(); + + $userManager->callForAllUsers(function($user) use($migration) { + /** @var IUser $user */ + $migration->syncUser($user->getUID()); + }); + } catch (\Exception $ex) { + $this->getContainer()->getServer()->getLogger()->logException($ex); + } + } } diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index a8789f480e4a1..4ed401e5c5bff 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -5,7 +5,7 @@ ownCloud WebDAV endpoint AGPL owncloud.org - 0.1.5 + 0.1.6 diff --git a/apps/dav/appinfo/update.php b/apps/dav/appinfo/update.php index aaa36052cd2f6..fbd41d25f49cf 100644 --- a/apps/dav/appinfo/update.php +++ b/apps/dav/appinfo/update.php @@ -23,3 +23,4 @@ $app = new Application(); $app->setupCron(); +$app->generateBirthdays(); From 3f4be066f9252565ed3aaacc485dc81ef2da957c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 10 Mar 2016 14:17:21 +0100 Subject: [PATCH 116/286] Generate birthdays on upgrade from 8.2 as well --- apps/dav/appinfo/install.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/dav/appinfo/install.php b/apps/dav/appinfo/install.php index a7a3220b90faf..dc5ae39226ec8 100644 --- a/apps/dav/appinfo/install.php +++ b/apps/dav/appinfo/install.php @@ -25,3 +25,4 @@ $app->setupCron(); $app->migrateAddressbooks(); $app->migrateCalendars(); +$app->generateBirthdays(); From f6b6813f5f49c4129c3f6f110fe8add3d5c774c1 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 16 Mar 2016 20:51:03 +0100 Subject: [PATCH 117/286] Avatar must be saved after login is done and external storages set up properly, fixes #21555 --- apps/user_ldap/lib/user/user.php | 17 ++++++++++++++++- apps/user_ldap/tests/user/user.php | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/lib/user/user.php b/apps/user_ldap/lib/user/user.php index 43ff6014c9f04..9bf505c5c2254 100644 --- a/apps/user_ldap/lib/user/user.php +++ b/apps/user_ldap/lib/user/user.php @@ -217,7 +217,11 @@ public function processAttributes($ldapEntry) { foreach ($attrs as $attr) { if(isset($ldapEntry[$attr])) { $this->avatarImage = $ldapEntry[$attr][0]; - $this->updateAvatar(); + // the call to the method that saves the avatar in the file + // system must be postponed after the login. It is to ensure + // external mounts are mounted properly (e.g. with login + // credentials from the session). + \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin'); break; } } @@ -461,6 +465,17 @@ public function updateQuota($valueFromLDAP = null) { } } + /** + * called by a post_login hook to save the avatar picture + * + * @param array $params + */ + public function updateAvatarPostLogin($params) { + if(isset($params['uid']) && $params['uid'] === $this->getUsername()) { + $this->updateAvatar(); + } + } + /** * @brief attempts to get an image from LDAP and sets it as ownCloud avatar * @return null diff --git a/apps/user_ldap/tests/user/user.php b/apps/user_ldap/tests/user/user.php index ca8d81a4b791c..ed04520aa74df 100644 --- a/apps/user_ldap/tests/user/user.php +++ b/apps/user_ldap/tests/user/user.php @@ -798,6 +798,7 @@ public function testProcessAttributes() { } $userMock->processAttributes($record); + \OC_Hook::emit('OC_User', 'post_login', array('uid' => $uid)); } public function emptyHomeFolderAttributeValueProvider() { From d59860aacda4906bfd4b9e4243e6d336206d088d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 21 Mar 2016 09:41:13 +0100 Subject: [PATCH 118/286] Add comment icons and "You commented" translations --- apps/comments/activity/extension.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/comments/activity/extension.php b/apps/comments/activity/extension.php index b65f1911d17ff..6bf7cae588277 100644 --- a/apps/comments/activity/extension.php +++ b/apps/comments/activity/extension.php @@ -105,7 +105,7 @@ public function getDefaultTypes($method) { public function getTypeIcon($type) { switch ($type) { case self::APP_NAME: - return false; + return 'icon-comment'; } return false; @@ -150,6 +150,9 @@ protected function translateShort($text, IL10N $l, array $params) { switch ($text) { case self::ADD_COMMENT_SUBJECT: + if ($this->authorIsCurrentUser($params[0])) { + return (string) $l->t('You commented'); + } return (string) $l->t('%1$s commented', $params); case self::ADD_COMMENT_MESSAGE: return $this->convertParameterToComment($params[0], 120); @@ -168,6 +171,9 @@ protected function translateLong($text, IL10N $l, array $params) { switch ($text) { case self::ADD_COMMENT_SUBJECT: + if ($this->authorIsCurrentUser($params[0])) { + return (string) $l->t('You commented on %2$s', $params); + } return (string) $l->t('%1$s commented on %2$s', $params); case self::ADD_COMMENT_MESSAGE: return $this->convertParameterToComment($params[0]); @@ -176,6 +182,21 @@ protected function translateLong($text, IL10N $l, array $params) { return false; } + /** + * Check if the author is the current user + * + * @param string $user Parameter e.g. `admin` + * @return bool + */ + protected function authorIsCurrentUser($user) { + try { + return strip_tags($user) === $this->activityManager->getCurrentUserId(); + } catch (\UnexpectedValueException $e) { + // FIXME this is awkward, but we have no access to the current user in emails + return false; + } + } + /** * The extension can define the type of parameters for translation * From 177ad3985422ca80b3a19bcfd15e11ec78a99e3a Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 21 Mar 2016 15:21:22 +0100 Subject: [PATCH 119/286] Log more information by default This modifies the logger to add the following logging information by default: - Request Method - Request URL - Current user --- lib/private/log/owncloud.php | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 6399d7ee588f7..ec4af29dc8433 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -88,14 +88,21 @@ public static function write($app, $message, $level) { $remoteAddr = $request->getRemoteAddress(); // remove username/passwords from URLs before writing the to the log file $time = $time->format($format); - $minLevel=min($config->getValue( "loglevel", \OCP\Util::WARN ), \OCP\Util::ERROR); - if($minLevel == \OCP\Util::DEBUG) { - $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; - $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; - $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time', 'method', 'url'); - } else { - $entry = compact('reqId', 'remoteAddr', 'app', 'message', 'level', 'time'); - } + $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; + $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; + $userObj = \OC::$server->getUserSession()->getUser(); + $user = !is_null($userObj) ? $userObj->getUID() : '--'; + $entry = compact( + 'reqId', + 'remoteAddr', + 'app', + 'message', + 'level', + 'time', + 'method', + 'url', + 'user' + ); $entry = json_encode($entry); $handle = @fopen(self::$logFile, 'a'); @chmod(self::$logFile, 0640); From 8af75c734acc72213d358b63089321ed03554a92 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 17 Mar 2016 13:54:26 +0100 Subject: [PATCH 120/286] update icewind/streams to 0.4.0 and icewind/smb to 1.0.7 in files_external --- apps/files_external/3rdparty/.gitignore | 1 + apps/files_external/3rdparty/composer.json | 4 +- apps/files_external/3rdparty/composer.lock | 29 ++-- .../3rdparty/composer/ClassLoader.php | 8 +- .../3rdparty/composer/autoload_classmap.php | 15 ++ .../3rdparty/composer/autoload_real.php | 15 -- .../3rdparty/composer/installed.json | 29 ++-- .../3rdparty/icewind/smb/README.md | 2 +- .../3rdparty/icewind/smb/composer.json | 2 +- .../3rdparty/icewind/smb/src/NativeStream.php | 7 +- .../3rdparty/icewind/streams/.travis.yml | 7 +- .../3rdparty/icewind/streams/LICENCE | 21 +++ .../3rdparty/icewind/streams/README.md | 1 + .../3rdparty/icewind/streams/composer.json | 3 +- .../icewind/streams/src/CallbackWrapper.php | 67 +++++---- .../icewind/streams/src/DirectoryFilter.php | 60 ++++++++ .../icewind/streams/src/DirectoryWrapper.php | 88 ++++++++++++ .../3rdparty/icewind/streams/src/File.php | 2 +- .../icewind/streams/src/IteratorDirectory.php | 4 +- .../icewind/streams/src/NullWrapper.php | 15 +- .../3rdparty/icewind/streams/src/Path.php | 104 ++++++++++++++ .../icewind/streams/src/RetryWrapper.php | 66 +++++++++ .../icewind/streams/src/SeekableWrapper.php | 92 +++++++++++++ .../3rdparty/icewind/streams/src/Url.php | 64 +++++++++ .../icewind/streams/src/UrlCallBack.php | 121 ++++++++++++++++ .../3rdparty/icewind/streams/src/Wrapper.php | 31 ++++- .../icewind/streams/tests/CallbackWrapper.php | 72 ---------- .../streams/tests/IteratorDirectory.php | 130 ------------------ .../icewind/streams/tests/NullWrapper.php | 59 -------- .../icewind/streams/tests/Wrapper.php | 105 -------------- .../icewind/streams/tests/bootstrap.php | 9 -- .../icewind/streams/tests/phpunit.xml | 6 - 32 files changed, 761 insertions(+), 478 deletions(-) create mode 100644 apps/files_external/3rdparty/icewind/streams/LICENCE create mode 100644 apps/files_external/3rdparty/icewind/streams/src/DirectoryFilter.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/DirectoryWrapper.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/Path.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/RetryWrapper.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/SeekableWrapper.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/Url.php create mode 100644 apps/files_external/3rdparty/icewind/streams/src/UrlCallBack.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php delete mode 100644 apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml diff --git a/apps/files_external/3rdparty/.gitignore b/apps/files_external/3rdparty/.gitignore index c8d4e6eed0ba4..b56af237c35bb 100644 --- a/apps/files_external/3rdparty/.gitignore +++ b/apps/files_external/3rdparty/.gitignore @@ -2,3 +2,4 @@ example.php icewind/smb/tests icewind/smb/install_libsmbclient.sh icewind/smb/.travis.yml +icewind/streams/tests diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index 4c130404addcd..64bf1aa02cdf1 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -8,8 +8,8 @@ "classmap-authoritative": true }, "require": { - "icewind/smb": "1.0.5", - "icewind/streams": "0.2" + "icewind/smb": "1.0.7", + "icewind/streams": "0.4" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 7bfb48a2c0df7..fea8b05e2b258 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,25 +4,25 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "669663944c7232473a1c51a6d160319d", - "content-hash": "7612ced4391f6287fb3e50534500d217", + "hash": "1eea7879a98792c704df2d7c86d37577", + "content-hash": "aeb32fd12aaab76f3c8873dd81f5775b", "packages": [ { "name": "icewind/smb", - "version": "v1.0.5", + "version": "v1.0.7", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "acb94a0a85290d653cd64c883175b855ada5022f" + "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/acb94a0a85290d653cd64c883175b855ada5022f", - "reference": "acb94a0a85290d653cd64c883175b855ada5022f", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/b9364a984e9667416406c6f21c1bc5ac7ad86aa1", + "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1", "shasum": "" }, "require": { - "icewind/streams": "0.2.*", + "icewind/streams": ">=0.2.0", "php": ">=5.3" }, "require-dev": { @@ -47,27 +47,28 @@ } ], "description": "php wrapper for smbclient and libsmbclient-php", - "time": "2016-01-20 13:12:36" + "time": "2016-03-17 12:48:14" }, { "name": "icewind/streams", - "version": "0.2", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/icewind1991/Streams.git", - "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a" + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/Streams/zipball/5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a", - "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a", + "url": "https://api.github.com/repos/icewind1991/Streams/zipball/9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3", "shasum": "" }, "require": { "php": ">=5.3" }, "require-dev": { - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "v1.0.0" }, "type": "library", "autoload": { @@ -87,7 +88,7 @@ } ], "description": "A set of generic stream wrappers", - "time": "2014-07-30 23:46:15" + "time": "2016-03-17 12:32:25" } ], "packages-dev": [], diff --git a/apps/files_external/3rdparty/composer/ClassLoader.php b/apps/files_external/3rdparty/composer/ClassLoader.php index 5e1469e8307d9..ff6ecfb822f89 100644 --- a/apps/files_external/3rdparty/composer/ClassLoader.php +++ b/apps/files_external/3rdparty/composer/ClassLoader.php @@ -13,9 +13,7 @@ namespace Composer\Autoload; /** - * ClassLoader implements a PSR-0 class loader - * - * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. * * $loader = new \Composer\Autoload\ClassLoader(); * @@ -39,6 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -147,7 +147,7 @@ public function add($prefix, $paths, $prepend = false) * appending or prepending to the ones previously set for this namespace. * * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-0 base directories + * @param array|string $paths The PSR-4 base directories * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 5b0f2511e128c..c77d5df190678 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -52,12 +52,27 @@ 'Icewind\\SMB\\TimeZoneProvider' => $vendorDir . '/icewind/smb/src/TimeZoneProvider.php', 'Icewind\\Streams\\CallbackWrapper' => $vendorDir . '/icewind/streams/src/CallbackWrapper.php', 'Icewind\\Streams\\Directory' => $vendorDir . '/icewind/streams/src/Directory.php', + 'Icewind\\Streams\\DirectoryFilter' => $vendorDir . '/icewind/streams/src/DirectoryFilter.php', + 'Icewind\\Streams\\DirectoryWrapper' => $vendorDir . '/icewind/streams/src/DirectoryWrapper.php', 'Icewind\\Streams\\File' => $vendorDir . '/icewind/streams/src/File.php', 'Icewind\\Streams\\IteratorDirectory' => $vendorDir . '/icewind/streams/src/IteratorDirectory.php', 'Icewind\\Streams\\NullWrapper' => $vendorDir . '/icewind/streams/src/NullWrapper.php', + 'Icewind\\Streams\\Path' => $vendorDir . '/icewind/streams/src/Path.php', + 'Icewind\\Streams\\RetryWrapper' => $vendorDir . '/icewind/streams/src/RetryWrapper.php', + 'Icewind\\Streams\\SeekableWrapper' => $vendorDir . '/icewind/streams/src/SeekableWrapper.php', 'Icewind\\Streams\\Tests\\CallbackWrapper' => $vendorDir . '/icewind/streams/tests/CallbackWrapper.php', + 'Icewind\\Streams\\Tests\\DirectoryFilter' => $vendorDir . '/icewind/streams/tests/DirectoryFilter.php', + 'Icewind\\Streams\\Tests\\DirectoryWrapper' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', + 'Icewind\\Streams\\Tests\\DirectoryWrapperDummy' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', + 'Icewind\\Streams\\Tests\\DirectoryWrapperNull' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', 'Icewind\\Streams\\Tests\\IteratorDirectory' => $vendorDir . '/icewind/streams/tests/IteratorDirectory.php', 'Icewind\\Streams\\Tests\\NullWrapper' => $vendorDir . '/icewind/streams/tests/NullWrapper.php', + 'Icewind\\Streams\\Tests\\PartialWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', + 'Icewind\\Streams\\Tests\\RetryWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', + 'Icewind\\Streams\\Tests\\SeekableWrapper' => $vendorDir . '/icewind/streams/tests/SeekableWrapper.php', + 'Icewind\\Streams\\Tests\\UrlCallBack' => $vendorDir . '/icewind/streams/tests/UrlCallBack.php', 'Icewind\\Streams\\Tests\\Wrapper' => $vendorDir . '/icewind/streams/tests/Wrapper.php', + 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', + 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', ); diff --git a/apps/files_external/3rdparty/composer/autoload_real.php b/apps/files_external/3rdparty/composer/autoload_real.php index 9e8b3b558e5df..6f27fffb9dac7 100644 --- a/apps/files_external/3rdparty/composer/autoload_real.php +++ b/apps/files_external/3rdparty/composer/autoload_real.php @@ -23,16 +23,6 @@ public static function getLoader() self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader')); - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - $classMap = require __DIR__ . '/autoload_classmap.php'; if ($classMap) { $loader->addClassMap($classMap); @@ -44,8 +34,3 @@ public static function getLoader() return $loader; } } - -function composerRequire98fe9b281934250b3a93f69a5ce843b3($file) -{ - require $file; -} diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 6e0b5d0d8f998..a09d496cc2cd7 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -1,26 +1,27 @@ [ { "name": "icewind/streams", - "version": "0.2", - "version_normalized": "0.2.0.0", + "version": "0.4.0", + "version_normalized": "0.4.0.0", "source": { "type": "git", "url": "https://github.com/icewind1991/Streams.git", - "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a" + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/Streams/zipball/5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a", - "reference": "5aae45f2ddd3d1a6e2a496dd5d1e7857bfeb605a", + "url": "https://api.github.com/repos/icewind1991/Streams/zipball/9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3", "shasum": "" }, "require": { "php": ">=5.3" }, "require-dev": { - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "v1.0.0" }, - "time": "2014-07-30 23:46:15", + "time": "2016-03-17 12:32:25", "type": "library", "installation-source": "dist", "autoload": { @@ -43,28 +44,28 @@ }, { "name": "icewind/smb", - "version": "v1.0.5", - "version_normalized": "1.0.5.0", + "version": "v1.0.7", + "version_normalized": "1.0.7.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "acb94a0a85290d653cd64c883175b855ada5022f" + "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/acb94a0a85290d653cd64c883175b855ada5022f", - "reference": "acb94a0a85290d653cd64c883175b855ada5022f", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/b9364a984e9667416406c6f21c1bc5ac7ad86aa1", + "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1", "shasum": "" }, "require": { - "icewind/streams": "0.2.*", + "icewind/streams": ">=0.2.0", "php": ">=5.3" }, "require-dev": { "phpunit/phpunit": "^4.8", "satooshi/php-coveralls": "v1.0.0" }, - "time": "2016-01-20 13:12:36", + "time": "2016-03-17 12:48:14", "type": "library", "installation-source": "source", "autoload": { diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md index a0864717b098a..32f3c650f87b3 100644 --- a/apps/files_external/3rdparty/icewind/smb/README.md +++ b/apps/files_external/3rdparty/icewind/smb/README.md @@ -75,7 +75,7 @@ $share = $server->getShare('test'); $content = $share->dir('test'); foreach ($content as $info) { - echo $name->getName() . "\n"; + echo $info->getName() . "\n"; echo "\tsize :" . $info->getSize() . "\n"; } ``` diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json index 2e1fd35f7a6e8..4ac8b27e725c4 100644 --- a/apps/files_external/3rdparty/icewind/smb/composer.json +++ b/apps/files_external/3rdparty/icewind/smb/composer.json @@ -10,7 +10,7 @@ ], "require" : { "php": ">=5.3", - "icewind/streams": "0.2.*" + "icewind/streams": ">=0.2.0" }, "require-dev": { "satooshi/php-coveralls" : "v1.0.0", diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php index 07bd2f1e7978f..8ffa88369248f 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php @@ -7,6 +7,7 @@ namespace Icewind\SMB; +use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\InvalidRequestException; use Icewind\Streams\File; @@ -89,7 +90,11 @@ public function stream_seek($offset, $whence = SEEK_SET) { } public function stream_stat() { - return $this->state->fstat($this->handle); + try { + return $this->state->fstat($this->handle); + } catch (Exception $e) { + return false; + } } public function stream_tell() { diff --git a/apps/files_external/3rdparty/icewind/streams/.travis.yml b/apps/files_external/3rdparty/icewind/streams/.travis.yml index dfa52767dda15..d2e1afaad675a 100644 --- a/apps/files_external/3rdparty/icewind/streams/.travis.yml +++ b/apps/files_external/3rdparty/icewind/streams/.travis.yml @@ -1,13 +1,14 @@ language: php php: - - 5.3 - 5.4 - 5.5 + - 5.6 + - 7.0 - hhvm matrix: - allow_failures: - - php: hhvm # due to facebook/hhvm#3321 + allow_failures: + - php: hhvm # due to facebook/hhvm#3321 env: global: diff --git a/apps/files_external/3rdparty/icewind/streams/LICENCE b/apps/files_external/3rdparty/icewind/streams/LICENCE new file mode 100644 index 0000000000000..a194b9117b84a --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/LICENCE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Robin Appelman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/apps/files_external/3rdparty/icewind/streams/README.md b/apps/files_external/3rdparty/icewind/streams/README.md index 54f6d19a56080..ca13db28e4417 100644 --- a/apps/files_external/3rdparty/icewind/streams/README.md +++ b/apps/files_external/3rdparty/icewind/streams/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.org/icewind1991/Streams.svg?branch=master)](https://travis-ci.org/icewind1991/Streams) [![Coverage Status](https://img.shields.io/coveralls/icewind1991/Streams.svg)](https://coveralls.io/r/icewind1991/Streams?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/icewind1991/Streams/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/Streams/?branch=master) Generic stream wrappers for php. diff --git a/apps/files_external/3rdparty/icewind/streams/composer.json b/apps/files_external/3rdparty/icewind/streams/composer.json index 86d3c834258d1..f2f3e0fc25506 100644 --- a/apps/files_external/3rdparty/icewind/streams/composer.json +++ b/apps/files_external/3rdparty/icewind/streams/composer.json @@ -12,7 +12,8 @@ "php": ">=5.3" }, "require-dev" : { - "satooshi/php-coveralls": "dev-master" + "satooshi/php-coveralls": "v1.0.0", + "phpunit/phpunit": "^4.8" }, "autoload" : { "psr-4": { diff --git a/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php index fd99aa6ebe8ce..c5847b95fdbaa 100644 --- a/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php +++ b/apps/files_external/3rdparty/icewind/streams/src/CallbackWrapper.php @@ -13,10 +13,11 @@ * The following options should be passed in the context when opening the stream * [ * 'callback' => [ - * 'source' => resource - * 'read' => function($count){} (optional) - * 'write' => function($data){} (optional) - * 'close' => function(){} (optional) + * 'source' => resource + * 'read' => function($count){} (optional) + * 'write' => function($data){} (optional) + * 'close' => function(){} (optional) + * 'readdir' => function(){} (optional) * ] * ] * @@ -38,6 +39,11 @@ class CallbackWrapper extends Wrapper { */ protected $closeCallback; + /** + * @var callable + */ + protected $readDirCallBack; + /** * Wraps a stream with the provided callbacks * @@ -45,48 +51,45 @@ class CallbackWrapper extends Wrapper { * @param callable $read (optional) * @param callable $write (optional) * @param callable $close (optional) + * @param callable $readDir (optional) * @return resource * * @throws \BadMethodCallException */ - public static function wrap($source, $read = null, $write = null, $close = null) { + public static function wrap($source, $read = null, $write = null, $close = null, $readDir = null) { $context = stream_context_create(array( 'callback' => array( 'source' => $source, 'read' => $read, 'write' => $write, - 'close' => $close + 'close' => $close, + 'readDir' => $readDir ) )); - stream_wrapper_register('callback', '\Icewind\Streams\CallbackWrapper'); - try { - $wrapped = fopen('callback://', 'r+', false, $context); - } catch (\BadMethodCallException $e) { - stream_wrapper_unregister('callback'); - throw $e; - } - stream_wrapper_unregister('callback'); - return $wrapped; + return Wrapper::wrapSource($source, $context, 'callback', '\Icewind\Streams\CallbackWrapper'); } - public function stream_open($path, $mode, $options, &$opened_path) { + protected function open() { $context = $this->loadContext('callback'); - if (isset($context['read']) and is_callable($context['read'])) { - $this->readCallback = $context['read']; - } - if (isset($context['write']) and is_callable($context['write'])) { - $this->writeCallback = $context['write']; - } - if (isset($context['close']) and is_callable($context['close'])) { - $this->closeCallback = $context['close']; - } + $this->readCallback = $context['read']; + $this->writeCallback = $context['write']; + $this->closeCallback = $context['close']; + $this->readDirCallBack = $context['readDir']; return true; } + public function dir_opendir($path, $options) { + return $this->open(); + } + + public function stream_open($path, $mode, $options, &$opened_path) { + return $this->open(); + } + public function stream_read($count) { $result = parent::stream_read($count); - if ($this->readCallback) { + if (is_callable($this->readCallback)) { call_user_func($this->readCallback, $count); } return $result; @@ -94,7 +97,7 @@ public function stream_read($count) { public function stream_write($data) { $result = parent::stream_write($data); - if ($this->writeCallback) { + if (is_callable($this->writeCallback)) { call_user_func($this->writeCallback, $data); } return $result; @@ -102,9 +105,17 @@ public function stream_write($data) { public function stream_close() { $result = parent::stream_close(); - if ($this->closeCallback) { + if (is_callable($this->closeCallback)) { call_user_func($this->closeCallback); } return $result; } + + public function dir_readdir() { + $result = parent::dir_readdir(); + if (is_callable($this->readDirCallBack)) { + call_user_func($this->readDirCallBack); + } + return $result; + } } diff --git a/apps/files_external/3rdparty/icewind/streams/src/DirectoryFilter.php b/apps/files_external/3rdparty/icewind/streams/src/DirectoryFilter.php new file mode 100644 index 0000000000000..4b8696990007a --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/DirectoryFilter.php @@ -0,0 +1,60 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper allows filtering of directories + * + * The filter callback will be called for each entry in the folder + * when the callback return false the entry will be filtered out + */ +class DirectoryFilter extends DirectoryWrapper { + /** + * @var callable + */ + private $filter; + + /** + * @param string $path + * @param array $options + * @return bool + */ + public function dir_opendir($path, $options) { + $context = $this->loadContext('filter'); + $this->filter = $context['filter']; + return true; + } + + /** + * @return string + */ + public function dir_readdir() { + $file = readdir($this->source); + $filter = $this->filter; + // keep reading untill we have an accepted entry or we're at the end of the folder + while ($file !== false && $filter($file) === false) { + $file = readdir($this->source); + } + return $file; + } + + /** + * @param resource $source + * @param callable $filter + * @return resource + */ + public static function wrap($source, callable $filter) { + $options = array( + 'filter' => array( + 'source' => $source, + 'filter' => $filter + ) + ); + return self::wrapWithOptions($options, '\Icewind\Streams\DirectoryFilter'); + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/DirectoryWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/DirectoryWrapper.php new file mode 100644 index 0000000000000..63e4805a807c1 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/DirectoryWrapper.php @@ -0,0 +1,88 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +class DirectoryWrapper implements Directory { + /** + * @var resource + */ + public $context; + + /** + * @var resource + */ + protected $source; + + /** + * Load the source from the stream context and return the context options + * + * @param string $name + * @return array + * @throws \Exception + */ + protected function loadContext($name) { + $context = stream_context_get_options($this->context); + if (isset($context[$name])) { + $context = $context[$name]; + } else { + throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set'); + } + if (isset($context['source']) and is_resource($context['source'])) { + $this->source = $context['source']; + } else { + throw new \BadMethodCallException('Invalid context, source not set'); + } + return $context; + } + + /** + * @param string $path + * @param array $options + * @return bool + */ + public function dir_opendir($path, $options) { + $this->loadContext('dir'); + return true; + } + + /** + * @return string + */ + public function dir_readdir() { + return readdir($this->source); + } + + /** + * @return bool + */ + public function dir_closedir() { + closedir($this->source); + return true; + } + + /** + * @return bool + */ + public function dir_rewinddir() { + rewinddir($this->source); + return true; + } + + /** + * @param array $options the options for the context to wrap the stream with + * @param string $class + * @return resource + */ + protected static function wrapWithOptions($options, $class) { + $context = stream_context_create($options); + stream_wrapper_register('dirwrapper', $class); + $wrapped = opendir('dirwrapper://', $context); + stream_wrapper_unregister('dirwrapper'); + return $wrapped; + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/File.php b/apps/files_external/3rdparty/icewind/streams/src/File.php index 6202ef4a4b445..252b7b8971fb1 100644 --- a/apps/files_external/3rdparty/icewind/streams/src/File.php +++ b/apps/files_external/3rdparty/icewind/streams/src/File.php @@ -21,7 +21,7 @@ interface File { public function stream_open($path, $mode, $options, &$opened_path); /** - * @param string $offset + * @param int $offset * @param int $whence * @return bool */ diff --git a/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php index c4eac5d4ed3e7..6dfa42a8b684e 100644 --- a/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php +++ b/apps/files_external/3rdparty/icewind/streams/src/IteratorDirectory.php @@ -45,9 +45,9 @@ protected function loadContext($name) { } else { throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set'); } - if (isset($context['iterator']) and $context['iterator'] instanceof \Iterator) { + if (isset($context['iterator'])) { $this->iterator = $context['iterator']; - } else if (isset($context['array']) and is_array($context['array'])) { + } else if (isset($context['array'])) { $this->iterator = new \ArrayIterator($context['array']); } else { throw new \BadMethodCallException('Invalid context, iterator or array not set'); diff --git a/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php index 8cbaaa756d372..b6c71d98fc4a0 100644 --- a/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php +++ b/apps/files_external/3rdparty/icewind/streams/src/NullWrapper.php @@ -24,19 +24,16 @@ public static function wrap($source) { 'null' => array( 'source' => $source) )); - stream_wrapper_register('null', '\Icewind\Streams\NullWrapper'); - try { - $wrapped = fopen('null://', 'r+', false, $context); - } catch (\BadMethodCallException $e) { - stream_wrapper_unregister('null'); - throw $e; - } - stream_wrapper_unregister('null'); - return $wrapped; + return Wrapper::wrapSource($source, $context, 'null', '\Icewind\Streams\NullWrapper'); } public function stream_open($path, $mode, $options, &$opened_path) { $this->loadContext('null'); return true; } + + public function dir_opendir($path, $options) { + $this->loadContext('null'); + return true; + } } diff --git a/apps/files_external/3rdparty/icewind/streams/src/Path.php b/apps/files_external/3rdparty/icewind/streams/src/Path.php new file mode 100644 index 0000000000000..46d2156b69ad5 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/Path.php @@ -0,0 +1,104 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * A string-like object that automatically registers a stream wrapper when used and removes the stream wrapper when no longer used + * + * Can optionally pass context options to the stream wrapper + */ +class Path { + + /** + * @var bool + */ + protected $registered = false; + + /** + * @var string + */ + protected $protocol; + + /** + * @var string + */ + protected $class; + + /** + * @var array + */ + protected $contextOptions; + + /** + * @param string $class + * @param array $contextOptions + */ + public function __construct($class, $contextOptions = array()) { + $this->class = $class; + $this->contextOptions = $contextOptions; + } + + public function getProtocol() { + if (!$this->protocol) { + $this->protocol = 'auto' . uniqid(); + } + return $this->protocol; + } + + public function wrapPath($path) { + return $this->getProtocol() . '://' . $path; + } + + protected function register() { + if (!$this->registered) { + $this->appendDefaultContent($this->getProtocol(), $this->contextOptions); + stream_wrapper_register($this->getProtocol(), $this->class); + $this->registered = true; + } + } + + protected function unregister() { + stream_wrapper_unregister($this->getProtocol()); + $this->unsetDefaultContent($this->getProtocol()); + $this->registered = false; + } + + /** + * Add values to the default stream context + * + * @param string $key + * @param array $values + */ + protected function appendDefaultContent($key, $values) { + $context = stream_context_get_default(); + $defaults = stream_context_get_options($context); + $defaults[$key] = $values; + stream_context_set_default($defaults); + } + + /** + * Remove values from the default stream context + * + * @param string $key + */ + protected function unsetDefaultContent($key) { + $context = stream_context_get_default(); + $defaults = stream_context_get_options($context); + unset($defaults[$key]); + stream_context_set_default($defaults); + } + + public function __toString() { + $this->register(); + return $this->protocol . '://'; + } + + public function __destruct() { + $this->unregister(); + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/RetryWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/RetryWrapper.php new file mode 100644 index 0000000000000..84b43f6bd0279 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/RetryWrapper.php @@ -0,0 +1,66 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper that retries reads/writes to remote streams that dont deliver/recieve all requested data at once + */ +class RetryWrapper extends Wrapper { + + /** + * Wraps a stream with the provided callbacks + * + * @param resource $source + * @return resource + */ + public static function wrap($source) { + $context = stream_context_create(array( + 'retry' => array( + 'source' => $source + ) + )); + return Wrapper::wrapSource($source, $context, 'retry', '\Icewind\Streams\RetryWrapper'); + } + + protected function open() { + $this->loadContext('retry'); + return true; + } + + public function dir_opendir($path, $options) { + return false; + } + + public function stream_open($path, $mode, $options, &$opened_path) { + return $this->open(); + } + + public function stream_read($count) { + $result = parent::stream_read($count); + + $bytesReceived = strlen($result); + while ($bytesReceived < $count && !$this->stream_eof()) { + $result .= parent::stream_read($count - $bytesReceived); + $bytesReceived = strlen($result); + } + + return $result; + } + + public function stream_write($data) { + $bytesToSend = strlen($data); + $result = parent::stream_write($data); + + while ($result < $bytesToSend && !$this->stream_eof()) { + $dataLeft = substr($data, $result); + $result += parent::stream_write($dataLeft); + } + + return $result; + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/SeekableWrapper.php b/apps/files_external/3rdparty/icewind/streams/src/SeekableWrapper.php new file mode 100644 index 0000000000000..d41fd73ec9c2e --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/SeekableWrapper.php @@ -0,0 +1,92 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper that provides callbacks for write, read and close + * + * The following options should be passed in the context when opening the stream + * [ + * 'callback' => [ + * 'source' => resource + * ] + * ] + * + * All callbacks are called after the operation is executed on the source stream + */ +class SeekableWrapper extends Wrapper { + /** + * @var resource + */ + protected $cache; + + /** + * Wraps a stream to make it seekable + * + * @param resource $source + * @return resource + * + * @throws \BadMethodCallException + */ + public static function wrap($source) { + $context = stream_context_create(array( + 'callback' => array( + 'source' => $source + ) + )); + return Wrapper::wrapSource($source, $context, 'callback', '\Icewind\Streams\SeekableWrapper'); + } + + public function dir_opendir($path, $options) { + return false; + } + + public function stream_open($path, $mode, $options, &$opened_path) { + $this->loadContext('callback'); + $this->cache = fopen('php://temp', 'w+'); + return true; + } + + protected function readTill($position) { + $current = ftell($this->source); + if ($position > $current) { + $data = parent::stream_read($position - $current); + $cachePosition = ftell($this->cache); + fseek($this->cache, $current); + fwrite($this->cache, $data); + fseek($this->cache, $cachePosition); + } + } + + public function stream_read($count) { + $current = ftell($this->cache); + $this->readTill($current + $count); + return fread($this->cache, $count); + } + + public function stream_seek($offset, $whence = SEEK_SET) { + if ($whence === SEEK_SET) { + $target = $offset; + } else if ($whence === SEEK_CUR) { + $current = ftell($this->cache); + $target = $current + $offset; + } else { + return false; + } + $this->readTill($target); + return fseek($this->cache, $target) === 0; + } + + public function stream_tell() { + return ftell($this->cache); + } + + public function stream_eof() { + return parent::stream_eof() and (ftell($this->source) === ftell($this->cache)); + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/Url.php b/apps/files_external/3rdparty/icewind/streams/src/Url.php new file mode 100644 index 0000000000000..d6822608a333f --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/Url.php @@ -0,0 +1,64 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Interface for stream wrappers that implement url functions such as unlink, stat + */ +interface Url { + /** + * @param string $path + * @param array $options + * @return bool + */ + public function dir_opendir($path, $options); + + /** + * @param string $path + * @param string $mode + * @param int $options + * @param string &$opened_path + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path); + + /** + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + public function mkdir($path, $mode, $options); + + /** + * @param string $source + * @param string $target + * @return bool + */ + public function rename($source, $target); + + /** + * @param string $path + * @param int $options + * @return bool + */ + public function rmdir($path, $options); + + /** + * @param string + * @return bool + */ + public function unlink($path); + + /** + * @param string $path + * @param int $flags + * @return array + */ + public function url_stat($path, $flags); +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/UrlCallBack.php b/apps/files_external/3rdparty/icewind/streams/src/UrlCallBack.php new file mode 100644 index 0000000000000..580bfc6ba2210 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams/src/UrlCallBack.php @@ -0,0 +1,121 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper that provides callbacks for url actions such as fopen, unlink, rename + * + * Usage: + * + * $path = UrlCallBack('/path/so/source', function(){ + * echo 'fopen'; + * }, function(){ + * echo 'opendir'; + * }, function(){ + * echo 'mkdir'; + * }, function(){ + * echo 'rename'; + * }, function(){ + * echo 'rmdir'; + * }, function(){ + * echo 'unlink'; + * }, function(){ + * echo 'stat'; + * }); + * + * mkdir($path); + * ... + * + * All callbacks are called after the operation is executed on the source stream + */ +class UrlCallback extends Wrapper implements Url { + + /** + * @param string $source + * @param callable $fopen + * @param callable $opendir + * @param callable $mkdir + * @param callable $rename + * @param callable $rmdir + * @param callable $unlink + * @param callable $stat + * @return \Icewind\Streams\Path + * + * @throws \BadMethodCallException + * @throws \Exception + */ + public static function wrap($source, $fopen = null, $opendir = null, $mkdir = null, $rename = null, $rmdir = null, + $unlink = null, $stat = null) { + $options = array( + 'source' => $source, + 'fopen' => $fopen, + 'opendir' => $opendir, + 'mkdir' => $mkdir, + 'rename' => $rename, + 'rmdir' => $rmdir, + 'unlink' => $unlink, + 'stat' => $stat + ); + return new Path('\Icewind\Streams\UrlCallBack', $options); + } + + protected function loadContext($url) { + list($protocol) = explode('://', $url); + $options = stream_context_get_options($this->context); + return $options[$protocol]; + } + + protected function callCallBack($context, $callback) { + if (is_callable($context[$callback])) { + call_user_func($context[$callback]); + } + } + + public function stream_open($path, $mode, $options, &$opened_path) { + $context = $this->loadContext($path); + $this->callCallBack($context, 'fopen'); + $this->setSourceStream(fopen($context['source'], $mode)); + return true; + } + + public function dir_opendir($path, $options) { + $context = $this->loadContext($path); + $this->callCallBack($context, 'opendir'); + $this->setSourceStream(opendir($context['source'])); + return true; + } + + public function mkdir($path, $mode, $options) { + $context = $this->loadContext($path); + $this->callCallBack($context, 'mkdir'); + return mkdir($context['source'], $mode, $options & STREAM_MKDIR_RECURSIVE); + } + + public function rmdir($path, $options) { + $context = $this->loadContext($path); + $this->callCallBack($context, 'rmdir'); + return rmdir($context['source']); + } + + public function rename($source, $target) { + $context = $this->loadContext($source); + $this->callCallBack($context, 'rename'); + list(, $target) = explode('://', $target); + return rename($context['source'], $target); + } + + public function unlink($path) { + $context = $this->loadContext($path); + $this->callCallBack($context, 'unlink'); + return unlink($context['source']); + } + + public function url_stat($path, $flags) { + throw new \Exception('stat is not supported due to php bug 50526'); + } +} diff --git a/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php index 2e3a6e6cd8812..53de2942ca901 100644 --- a/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php +++ b/apps/files_external/3rdparty/icewind/streams/src/Wrapper.php @@ -12,7 +12,7 @@ * * This wrapper itself doesn't implement any functionality but is just a base class for other wrappers to extend */ -abstract class Wrapper implements File { +abstract class Wrapper implements File, Directory { /** * @var resource */ @@ -25,6 +25,22 @@ abstract class Wrapper implements File { */ protected $source; + protected static function wrapSource($source, $context, $protocol, $class) { + try { + stream_wrapper_register($protocol, $class); + if (@rewinddir($source) === false) { + $wrapped = fopen($protocol . '://', 'r+', false, $context); + } else { + $wrapped = opendir($protocol . '://', $context); + } + } catch (\BadMethodCallException $e) { + stream_wrapper_unregister($protocol); + throw $e; + } + stream_wrapper_unregister($protocol); + return $wrapped; + } + /** * Load the source from the stream context and return the context options * @@ -107,4 +123,17 @@ public function stream_eof() { public function stream_close() { return fclose($this->source); } + + public function dir_readdir() { + return readdir($this->source); + } + + public function dir_closedir() { + closedir($this->source); + return true; + } + + public function dir_rewinddir() { + return rewind($this->source); + } } diff --git a/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php deleted file mode 100644 index 229b629dcd99a..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/CallbackWrapper.php +++ /dev/null @@ -1,72 +0,0 @@ - - * This file is licensed under the Licensed under the MIT license: - * http://opensource.org/licenses/MIT - */ - -namespace Icewind\Streams\Tests; - -class CallbackWrapper extends Wrapper { - - /** - * @param resource $source - * @param callable $read - * @param callable $write - * @param callable $close - * @return resource - */ - protected function wrapSource($source, $read = null, $write = null, $close = null) { - return \Icewind\Streams\CallbackWrapper::wrap($source, $read, $write, $close); - } - - /** - * @expectedException \BadMethodCallException - */ - public function testWrapInvalidSource() { - $this->wrapSource('foo'); - } - - public function testReadCallback() { - $called = false; - $callBack = function () use (&$called) { - $called = true; - }; - - $source = fopen('php://temp', 'r+'); - fwrite($source, 'foobar'); - rewind($source); - - $wrapped = $this->wrapSource($source, $callBack); - $this->assertEquals('foo', fread($wrapped, 3)); - $this->assertTrue($called); - } - - public function testWriteCallback() { - $lastData = ''; - $callBack = function ($data) use (&$lastData) { - $lastData = $data; - }; - - $source = fopen('php://temp', 'r+'); - - $wrapped = $this->wrapSource($source, null, $callBack); - fwrite($wrapped, 'foobar'); - $this->assertEquals('foobar', $lastData); - } - - public function testCloseCallback() { - $called = false; - $callBack = function () use (&$called) { - $called = true; - }; - - $source = fopen('php://temp', 'r+'); - fwrite($source, 'foobar'); - rewind($source); - - $wrapped = $this->wrapSource($source, null, null, $callBack); - fclose($wrapped); - $this->assertTrue($called); - } -} diff --git a/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php b/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php deleted file mode 100644 index 0d990468368de..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/IteratorDirectory.php +++ /dev/null @@ -1,130 +0,0 @@ - - * This file is licensed under the Licensed under the MIT license: - * http://opensource.org/licenses/MIT - */ - -namespace Icewind\Streams\Tests; - -class IteratorDirectory extends \PHPUnit_Framework_TestCase { - - /** - * @param \Iterator | array $source - * @return resource - */ - protected function wrapSource($source) { - return \Icewind\Streams\IteratorDirectory::wrap($source); - } - - /** - * @expectedException \BadMethodCallException - */ - public function testNoContext() { - $context = stream_context_create(array()); - stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory'); - try { - opendir('iterator://', $context); - stream_wrapper_unregister('iterator'); - } catch (\Exception $e) { - stream_wrapper_unregister('iterator'); - throw $e; - } - } - - /** - * @expectedException \BadMethodCallException - */ - public function testInvalidSource() { - $context = stream_context_create(array( - 'dir' => array( - 'array' => 2 - ) - )); - stream_wrapper_register('iterator', '\Icewind\Streams\IteratorDirectory'); - try { - opendir('iterator://', $context); - stream_wrapper_unregister('iterator'); - } catch (\Exception $e) { - stream_wrapper_unregister('iterator'); - throw $e; - } - } - - /** - * @expectedException \BadMethodCallException - */ - public function testWrapInvalidSource() { - $this->wrapSource(2); - } - - public function fileListProvider() { - $longList = array_fill(0, 500, 'foo'); - return array( - array( - array( - 'foo', - 'bar', - 'qwerty' - ) - ), - array( - array( - 'with spaces', - 'under_scores', - '日本語', - 'character %$_', - '.', - '0', - 'double "quotes"', - "single 'quotes'" - ) - ), - array( - array( - 'single item' - ) - ), - array( - $longList - ), - array( - array() - ) - ); - } - - protected function basicTest($fileList, $dh) { - $result = array(); - - while (($file = readdir($dh)) !== false) { - $result[] = $file; - } - - $this->assertEquals($fileList, $result); - - rewinddir($dh); - if (count($fileList)) { - $this->assertEquals($fileList[0], readdir($dh)); - } else { - $this->assertFalse(readdir($dh)); - } - } - - /** - * @dataProvider fileListProvider - */ - public function testBasicIterator($fileList) { - $iterator = new \ArrayIterator($fileList); - $dh = $this->wrapSource($iterator); - $this->basicTest($fileList, $dh); - } - - /** - * @dataProvider fileListProvider - */ - public function testBasicArray($fileList) { - $dh = $this->wrapSource($fileList); - $this->basicTest($fileList, $dh); - } -} diff --git a/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php deleted file mode 100644 index ba42b4dfea1ba..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/NullWrapper.php +++ /dev/null @@ -1,59 +0,0 @@ - - * This file is licensed under the Licensed under the MIT license: - * http://opensource.org/licenses/MIT - */ - -namespace Icewind\Streams\Tests; - -class NullWrapper extends Wrapper { - - /** - * @param resource $source - * @return resource - */ - protected function wrapSource($source) { - return \Icewind\Streams\NullWrapper::wrap($source); - } - - /** - * @expectedException \BadMethodCallException - */ - public function testNoContext() { - stream_wrapper_register('null', '\Icewind\Streams\NullWrapper'); - $context = stream_context_create(array()); - try { - fopen('null://', 'r+', false, $context); - stream_wrapper_unregister('null'); - } catch (\Exception $e) { - stream_wrapper_unregister('null'); - throw $e; - } - } - - /** - * @expectedException \BadMethodCallException - */ - public function testNoSource() { - stream_wrapper_register('null', '\Icewind\Streams\NullWrapper'); - $context = stream_context_create(array( - 'null' => array( - 'source' => 'bar' - ) - )); - try { - fopen('null://', 'r+', false, $context); - } catch (\Exception $e) { - stream_wrapper_unregister('null'); - throw $e; - } - } - - /** - * @expectedException \BadMethodCallException - */ - public function testWrapInvalidSource() { - $this->wrapSource('foo'); - } -} diff --git a/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php b/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php deleted file mode 100644 index 6bb644dd6116e..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/Wrapper.php +++ /dev/null @@ -1,105 +0,0 @@ - - * This file is licensed under the Licensed under the MIT license: - * http://opensource.org/licenses/MIT - */ - -namespace Icewind\Streams\Tests; - -abstract class Wrapper extends \PHPUnit_Framework_TestCase { - /** - * @param resource $source - * @return resource - */ - abstract protected function wrapSource($source); - - public function testRead() { - $source = fopen('php://temp', 'r+'); - fwrite($source, 'foobar'); - rewind($source); - - $wrapped = $this->wrapSource($source); - $this->assertEquals('foo', fread($wrapped, 3)); - $this->assertEquals('bar', fread($wrapped, 3)); - $this->assertEquals('', fread($wrapped, 3)); - } - - public function testWrite() { - $source = fopen('php://temp', 'r+'); - rewind($source); - - $wrapped = $this->wrapSource($source); - - $this->assertEquals(6, fwrite($wrapped, 'foobar')); - rewind($source); - $this->assertEquals('foobar', stream_get_contents($source)); - } - - public function testClose() { - $source = fopen('php://temp', 'r+'); - rewind($source); - - $wrapped = $this->wrapSource($source); - - fclose($wrapped); - $this->assertFalse(is_resource($source)); - } - - public function testSeekTell() { - $source = fopen('php://temp', 'r+'); - fwrite($source, 'foobar'); - rewind($source); - - $wrapped = $this->wrapSource($source); - - $this->assertEquals(0, ftell($wrapped)); - - fseek($wrapped, 2); - $this->assertEquals(2, ftell($source)); - $this->assertEquals(2, ftell($wrapped)); - - fseek($wrapped, 2, SEEK_CUR); - $this->assertEquals(4, ftell($source)); - $this->assertEquals(4, ftell($wrapped)); - - fseek($wrapped, -1, SEEK_END); - $this->assertEquals(5, ftell($source)); - $this->assertEquals(5, ftell($wrapped)); - } - - public function testStat() { - $source = fopen(__FILE__, 'r+'); - $wrapped = $this->wrapSource($source); - $this->assertEquals(stat(__FILE__), fstat($wrapped)); - } - - public function testTruncate() { - if (version_compare(phpversion(), '5.4.0', '<')) { - $this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers'); - } - $source = fopen('php://temp', 'r+'); - fwrite($source, 'foobar'); - rewind($source); - $wrapped = $this->wrapSource($source); - - ftruncate($wrapped, 2); - $this->assertEquals('fo', fread($wrapped, 10)); - } - - public function testLock() { - $source = tmpfile(); - $wrapped = $this->wrapSource($source); - if (!flock($wrapped, LOCK_EX)) { - $this->fail('Unable to acquire lock'); - } - } - - public function testStreamOptions() { - $source = fopen('php://temp', 'r+'); - $wrapped = $this->wrapSource($source); - stream_set_blocking($wrapped, 0); - stream_set_timeout($wrapped, 1, 0); - stream_set_write_buffer($wrapped, 0); - } -} diff --git a/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php b/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php deleted file mode 100644 index 2c17fd57febfa..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/bootstrap.php +++ /dev/null @@ -1,9 +0,0 @@ - - * This file is licensed under the Licensed under the MIT license: - * http://opensource.org/licenses/MIT - */ - -date_default_timezone_set('UTC'); -require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml b/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml deleted file mode 100644 index e3d96352c4368..0000000000000 --- a/apps/files_external/3rdparty/icewind/streams/tests/phpunit.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - ./ - - From 204288f4a540672fa25890cfe362963340eb24c2 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 17 Mar 2016 14:41:10 +0100 Subject: [PATCH 121/286] update icewind/smb to 1.0.8 --- apps/files_external/3rdparty/composer.json | 2 +- apps/files_external/3rdparty/composer.lock | 14 +++++++------- .../3rdparty/composer/autoload_classmap.php | 4 ---- .../3rdparty/composer/installed.json | 12 ++++++------ .../3rdparty/icewind/smb/src/NativeShare.php | 10 ++++++---- .../3rdparty/icewind/smb/src/NativeStream.php | 14 +++++++++++--- .../3rdparty/icewind/streams-dummy/composer.json | 7 +++++++ 7 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 apps/files_external/3rdparty/icewind/streams-dummy/composer.json diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index 64bf1aa02cdf1..b0267ba34388f 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -8,7 +8,7 @@ "classmap-authoritative": true }, "require": { - "icewind/smb": "1.0.7", + "icewind/smb": "1.0.8", "icewind/streams": "0.4" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index fea8b05e2b258..13931ad757d76 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,21 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "1eea7879a98792c704df2d7c86d37577", - "content-hash": "aeb32fd12aaab76f3c8873dd81f5775b", + "hash": "1671a5ec7bef407432d42775f898dc34", + "content-hash": "9d995f0d55bee8a3b344a3c685e7b4a4", "packages": [ { "name": "icewind/smb", - "version": "v1.0.7", + "version": "v1.0.8", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1" + "reference": "764f3fc793a904eb937d619ad097fb076ff199cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/b9364a984e9667416406c6f21c1bc5ac7ad86aa1", - "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/764f3fc793a904eb937d619ad097fb076ff199cd", + "reference": "764f3fc793a904eb937d619ad097fb076ff199cd", "shasum": "" }, "require": { @@ -47,7 +47,7 @@ } ], "description": "php wrapper for smbclient and libsmbclient-php", - "time": "2016-03-17 12:48:14" + "time": "2016-03-17 13:29:58" }, { "name": "icewind/streams", diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index c77d5df190678..942dbce7336ec 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -60,18 +60,14 @@ 'Icewind\\Streams\\Path' => $vendorDir . '/icewind/streams/src/Path.php', 'Icewind\\Streams\\RetryWrapper' => $vendorDir . '/icewind/streams/src/RetryWrapper.php', 'Icewind\\Streams\\SeekableWrapper' => $vendorDir . '/icewind/streams/src/SeekableWrapper.php', - 'Icewind\\Streams\\Tests\\CallbackWrapper' => $vendorDir . '/icewind/streams/tests/CallbackWrapper.php', 'Icewind\\Streams\\Tests\\DirectoryFilter' => $vendorDir . '/icewind/streams/tests/DirectoryFilter.php', 'Icewind\\Streams\\Tests\\DirectoryWrapper' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', 'Icewind\\Streams\\Tests\\DirectoryWrapperDummy' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', 'Icewind\\Streams\\Tests\\DirectoryWrapperNull' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\IteratorDirectory' => $vendorDir . '/icewind/streams/tests/IteratorDirectory.php', - 'Icewind\\Streams\\Tests\\NullWrapper' => $vendorDir . '/icewind/streams/tests/NullWrapper.php', 'Icewind\\Streams\\Tests\\PartialWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', 'Icewind\\Streams\\Tests\\RetryWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', 'Icewind\\Streams\\Tests\\SeekableWrapper' => $vendorDir . '/icewind/streams/tests/SeekableWrapper.php', 'Icewind\\Streams\\Tests\\UrlCallBack' => $vendorDir . '/icewind/streams/tests/UrlCallBack.php', - 'Icewind\\Streams\\Tests\\Wrapper' => $vendorDir . '/icewind/streams/tests/Wrapper.php', 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index a09d496cc2cd7..48f8c555c349d 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -44,17 +44,17 @@ }, { "name": "icewind/smb", - "version": "v1.0.7", - "version_normalized": "1.0.7.0", + "version": "v1.0.8", + "version_normalized": "1.0.8.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1" + "reference": "764f3fc793a904eb937d619ad097fb076ff199cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/b9364a984e9667416406c6f21c1bc5ac7ad86aa1", - "reference": "b9364a984e9667416406c6f21c1bc5ac7ad86aa1", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/764f3fc793a904eb937d619ad097fb076ff199cd", + "reference": "764f3fc793a904eb937d619ad097fb076ff199cd", "shasum": "" }, "require": { @@ -65,7 +65,7 @@ "phpunit/phpunit": "^4.8", "satooshi/php-coveralls": "v1.0.0" }, - "time": "2016-03-17 12:48:14", + "time": "2016-03-17 13:29:58", "type": "library", "installation-source": "source", "autoload": { diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php index 0b184fd585c1b..27d975514a37d 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php @@ -239,8 +239,9 @@ public function get($source, $target) { */ public function read($source) { $this->connect(); - $handle = $this->state->open($this->buildUrl($source), 'r'); - return NativeStream::wrap($this->state, $handle, 'r'); + $url = $this->buildUrl($source); + $handle = $this->state->open($url, 'r'); + return NativeStream::wrap($this->state, $handle, 'r', $url); } /** @@ -254,8 +255,9 @@ public function read($source) { */ public function write($source) { $this->connect(); - $handle = $this->state->create($this->buildUrl($source)); - return NativeStream::wrap($this->state, $handle, 'w'); + $url = $this->buildUrl($source); + $handle = $this->state->create($url); + return NativeStream::wrap($this->state, $handle, 'w', $url); } /** diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php index 8ffa88369248f..481395b025a92 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeStream.php @@ -32,20 +32,27 @@ class NativeStream implements File { */ private $eof = false; + /** + * @var string + */ + private $url; + /** * Wrap a stream from libsmbclient-php into a regular php stream * * @param \Icewind\SMB\NativeState $state * @param resource $smbStream * @param string $mode + * @param string $url * @return resource */ - public static function wrap($state, $smbStream, $mode) { + public static function wrap($state, $smbStream, $mode, $url) { stream_wrapper_register('nativesmb', '\Icewind\SMB\NativeStream'); $context = stream_context_create(array( 'nativesmb' => array( 'state' => $state, - 'handle' => $smbStream + 'handle' => $smbStream, + 'url' => $url ) )); $fh = fopen('nativesmb://', $mode, false, $context); @@ -69,6 +76,7 @@ public function stream_open($path, $mode, $options, &$opened_path) { $context = stream_context_get_options($this->context); $this->state = $context['nativesmb']['state']; $this->handle = $context['nativesmb']['handle']; + $this->url = $context['nativesmb']['url']; return true; } @@ -91,7 +99,7 @@ public function stream_seek($offset, $whence = SEEK_SET) { public function stream_stat() { try { - return $this->state->fstat($this->handle); + return $this->state->stat($this->url); } catch (Exception $e) { return false; } diff --git a/apps/files_external/3rdparty/icewind/streams-dummy/composer.json b/apps/files_external/3rdparty/icewind/streams-dummy/composer.json new file mode 100644 index 0000000000000..ad6a6a1b1c170 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/streams-dummy/composer.json @@ -0,0 +1,7 @@ +{ + "name": "icewind/streams-dummy", + "provide": { + "icewind/streams": "0.2" + } +} + From 3a955ca43c98fc5fed717a77c6ef451e4335471a Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Mon, 21 Mar 2016 18:08:51 +0100 Subject: [PATCH 122/286] Adjusted 3rdparty submodule commit --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index 913c4f0028a3b..afb726b309490 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit 913c4f0028a3bbdf716394c194f3cde8b92f8239 +Subproject commit afb726b309490ce9df1bd521217da9bbf606593b From 77afc18b82d3777e7ca00d8db7d783523b951ab4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Mar 2016 14:35:41 +0100 Subject: [PATCH 123/286] properly use smb permissions --- apps/files_external/lib/smb.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 67d1a23f5a76c..a130537dfd1ce 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -323,6 +323,28 @@ public function file_exists($path) { } } + public function isReadable($path) { + try { + $info = $this->getFileInfo($path); + return !$info->isHidden(); + } catch (NotFoundException $e) { + return false; + } catch (ForbiddenException $e) { + return false; + } + } + + public function isUpdatable($path) { + try { + $info = $this->getFileInfo($path); + return !$info->isHidden() && !$info->isReadOnly(); + } catch (NotFoundException $e) { + return false; + } catch (ForbiddenException $e) { + return false; + } + } + /** * check if smbclient is installed */ From 50e94db4d5affbe2c7b8ef711f01576d1663fa4d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 21 Mar 2016 16:31:59 +0100 Subject: [PATCH 124/286] Do not abort with an exception when a default app can not be enabled --- lib/private/installer.php | 19 +++++++++++++++++-- lib/private/updater.php | 7 ++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/private/installer.php b/lib/private/installer.php index 64f84d58b5423..b238d141a0fe1 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -531,8 +531,12 @@ public static function removeApp( $name, $options = array()) { * Installs shipped apps * * This function installs all apps found in the 'apps' directory that should be enabled by default; + * @param bool $softErrors When updating we ignore errors and simply log them, better to have a + * working ownCloud at the end instead of an aborted update. + * @return array Array of error messages (appid => Exception) */ - public static function installShippedApps() { + public static function installShippedApps($softErrors = false) { + $errors = []; foreach(OC::$APPSROOTS as $app_dir) { if($dir = opendir( $app_dir['path'] )) { while( false !== ( $filename = readdir( $dir ))) { @@ -543,7 +547,16 @@ public static function installShippedApps() { $enabled = isset($info['default_enable']); if (($enabled || in_array($filename, \OC::$server->getAppManager()->getAlwaysEnabledApps())) && \OC::$server->getConfig()->getAppValue($filename, 'enabled') !== 'no') { - OC_Installer::installShippedApp($filename); + if ($softErrors) { + try { + OC_Installer::installShippedApp($filename); + } catch (\Doctrine\DBAL\Exception\TableExistsException $e) { + $errors[$filename] = $e; + continue; + } + } else { + OC_Installer::installShippedApp($filename); + } \OC::$server->getConfig()->setAppValue($filename, 'enabled', 'yes'); } } @@ -553,6 +566,8 @@ public static function installShippedApps() { closedir( $dir ); } } + + return $errors; } /** diff --git a/lib/private/updater.php b/lib/private/updater.php index 4f74481562b9c..0d567b8dfb93d 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -333,7 +333,12 @@ private function doUpgrade($currentVersion, $installedVersion) { // install new shipped apps on upgrade OC_App::loadApps('authentication'); - OC_Installer::installShippedApps(); + $errors = OC_Installer::installShippedApps(true); + foreach ($errors as $appId => $exception) { + /** @var \Exception $exception */ + $this->log->logException($exception, ['app' => $appId]); + $this->emit('\OC\Updater', 'failure', [$appId . ': ' . $exception->getMessage()]); + } // post-upgrade repairs $repair = new Repair(Repair::getRepairSteps()); From ad852ca24ae06acf2d1274a8523af85f97984761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 16 Mar 2016 17:19:14 +0100 Subject: [PATCH 125/286] Create the contact birthday calendar right away as soon as the command is executed once - fixes #23203 --- apps/dav/lib/caldav/birthdayservice.php | 28 +++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/dav/lib/caldav/birthdayservice.php b/apps/dav/lib/caldav/birthdayservice.php index 09bed2430e4bf..9e27b3ac644b2 100644 --- a/apps/dav/lib/caldav/birthdayservice.php +++ b/apps/dav/lib/caldav/birthdayservice.php @@ -50,8 +50,7 @@ public function onCardChanged($addressBookId, $cardUri, $cardData) { $book = $this->cardDavBackEnd->getAddressBookById($addressBookId); $principalUri = $book['principaluri']; - $calendarUri = self::BIRTHDAY_CALENDAR_URI; - $calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []); + $calendar = $this->ensureCalendarExists($principalUri); $objectUri = $book['uri'] . '-' . $cardUri. '.ics'; $calendarData = $this->buildBirthdayFromContact($cardData); $existing = $this->calDavBackEnd->getCalendarObject($calendar['id'], $objectUri); @@ -77,32 +76,27 @@ public function onCardChanged($addressBookId, $cardUri, $cardData) { public function onCardDeleted($addressBookId, $cardUri) { $book = $this->cardDavBackEnd->getAddressBookById($addressBookId); $principalUri = $book['principaluri']; - $calendarUri = self::BIRTHDAY_CALENDAR_URI; - $calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []); + $calendar = $this->ensureCalendarExists($principalUri); $objectUri = $book['uri'] . '-' . $cardUri. '.ics'; $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri); } /** * @param string $principal - * @param string $id - * @param array $properties * @return array|null * @throws \Sabre\DAV\Exception\BadRequest */ - public function ensureCalendarExists($principal, $id, $properties) { - $properties = array_merge([ - '{DAV:}displayname' => 'Contact birthdays', - '{http://apple.com/ns/ical/}calendar-color' => '#FFFFCA', - ], $properties); - - $book = $this->calDavBackEnd->getCalendarByUri($principal, $id); + public function ensureCalendarExists($principal) { + $book = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); if (!is_null($book)) { return $book; } - $this->calDavBackEnd->createCalendar($principal, $id, $properties); + $this->calDavBackEnd->createCalendar($principal, self::BIRTHDAY_CALENDAR_URI, [ + '{DAV:}displayname' => 'Contact birthdays', + '{http://apple.com/ns/ical/}calendar-color' => '#FFFFCA', + ]); - return $this->calDavBackEnd->getCalendarByUri($principal, $id); + return $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); } /** @@ -161,7 +155,9 @@ public function buildBirthdayFromContact($cardData) { * @param string $user */ public function syncUser($user) { - $books = $this->cardDavBackEnd->getAddressBooksForUser('principals/users/'.$user); + $principal = 'principals/users/'.$user; + $this->ensureCalendarExists($principal); + $books = $this->cardDavBackEnd->getAddressBooksForUser($principal); foreach($books as $book) { $cards = $this->cardDavBackEnd->getCards($book['id']); foreach($cards as $card) { From 4d8c81a2d9ddfcab56d50691fa3cd36c9add8978 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 18 Mar 2016 16:23:33 +0100 Subject: [PATCH 126/286] Add `allow sharing with groups` checkbox to admin page --- settings/admin.php | 1 + settings/js/admin.js | 4 ++++ settings/templates/admin.php | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/settings/admin.php b/settings/admin.php index 2364fb3aae0bd..e0d3a907f4779 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -129,6 +129,7 @@ $template->assign('allowMailNotification', $appConfig->getValue('core', 'shareapi_allow_mail_notification', 'no')); $template->assign('allowShareDialogUserEnumeration', $appConfig->getValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes')); $template->assign('onlyShareWithGroupMembers', \OC\Share\Share::shareWithGroupMembersOnly()); +$template->assign('allowGroupSharing', $appConfig->getValue('core', 'shareapi_allow_group_sharing', 'yes')); $databaseOverload = (strpos(\OCP\Config::getSystemValue('dbtype'), 'sqlite') !== false); $template->assign('databaseOverload', $databaseOverload); $template->assign('cronErrors', $appConfig->getValue('core', 'cronErrors')); diff --git a/settings/js/admin.js b/settings/js/admin.js index 90b1de683709e..1bbb20efa00de 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -161,6 +161,10 @@ $(document).ready(function(){ }); }); + $('#allowGroupSharing').change(function() { + $('#allowGroupSharing').toggleClass('hidden', !this.checked); + }); + $('#shareapiExcludeGroups').change(function() { $("#selectExcludedGroups").toggleClass('hidden', !this.checked); }); diff --git a/settings/templates/admin.php b/settings/templates/admin.php index a51b9aa16e270..2f4461589da73 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -239,6 +239,11 @@ value="1" />

+

+ /> +
+

/> From e9fc791e9fc72395193f66fa428be84d97ce3cab Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 18 Mar 2016 16:34:23 +0100 Subject: [PATCH 127/286] Add config to sharemanager --- lib/private/share20/manager.php | 7 +++++++ lib/public/share/imanager.php | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index 6f370eea4242a..4733167cb142f 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -1111,6 +1111,13 @@ public function shareWithGroupMembersOnly() { return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes'; } + /** + * Check if users can share with groups + * @return bool + */ + public function allowGroupSharing() { + return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes'; + } /** * Copied from \OC_Util::isSharingDisabledForUser diff --git a/lib/public/share/imanager.php b/lib/public/share/imanager.php index f926104dde0ae..7f1424c8ea84d 100644 --- a/lib/public/share/imanager.php +++ b/lib/public/share/imanager.php @@ -220,6 +220,13 @@ public function shareApiLinkAllowPublicUpload(); */ public function shareWithGroupMembersOnly(); + /** + * Check if users can share with groups + * @return bool + * @since 9.0.1 + */ + public function allowGroupSharing(); + /** * Check if sharing is disabled for the given user * From aa75cfcf144eda64db1ff5df8a255c3c23b869fd Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 18 Mar 2016 16:36:27 +0100 Subject: [PATCH 128/286] Block group sharing in API and in share manager * Fix tests --- apps/files_sharing/api/share20ocs.php | 4 ++ .../tests/api/share20ocstest.php | 50 ++++++++++++++++++- lib/private/share20/manager.php | 5 ++ tests/lib/share20/managertest.php | 30 +++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php index a6baa353e8a15..73cb8bc23ec9f 100644 --- a/apps/files_sharing/api/share20ocs.php +++ b/apps/files_sharing/api/share20ocs.php @@ -292,6 +292,10 @@ public function createShare() { $share->setSharedWith($shareWith); $share->setPermissions($permissions); } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { + if (!$this->shareManager->allowGroupSharing()) { + return new \OC_OCS_Result(null, 404, 'group sharing is disabled by the administrator'); + } + // Valid group is required to share if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) { return new \OC_OCS_Result(null, 404, 'please specify a valid group'); diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php index a2c70d7673c68..a354b01299da0 100644 --- a/apps/files_sharing/tests/api/share20ocstest.php +++ b/apps/files_sharing/tests/api/share20ocstest.php @@ -759,9 +759,12 @@ public function testCreateShareGroup() { ->with('valid-path') ->willReturn($path); - $group = $this->getMock('\OCP\IGroup'); $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true); + $this->shareManager->expects($this->once()) + ->method('allowGroupSharing') + ->willReturn(true); + $share->method('setPath')->with($path); $share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL); $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP); @@ -775,6 +778,51 @@ public function testCreateShareGroup() { $this->assertEquals($expected->getData(), $result->getData()); } + public function testCreateShareGroupNotAllowed() { + $share = $this->getMock('\OCP\Share\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP], + ['shareWith', null, 'validGroup'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\Folder'); + $storage = $this->getMock('OCP\Files\Storage'); + $storage->method('instanceOfStorage') + ->with('OCA\Files_Sharing\External\Storage') + ->willReturn(false); + $path->method('getStorage')->willReturn($storage); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true); + + $this->shareManager->expects($this->once()) + ->method('allowGroupSharing') + ->willReturn(false); + + $share->method('setPath')->with($path); + + $expected = new \OC_OCS_Result(null, 404, 'group sharing is disabled by the administrator'); + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + public function testCreateShareLinkNoLinksAllowed() { $this->request ->method('getParam') diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index 4733167cb142f..5e40acefbef56 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -361,6 +361,11 @@ protected function userCreateChecks(\OCP\Share\IShare $share) { * @throws \Exception */ protected function groupCreateChecks(\OCP\Share\IShare $share) { + // Verify group shares are allowed + if (!$this->allowGroupSharing()) { + throw new \Exception('Group sharing is now allowed'); + } + // Verify if the user can share with this group if ($this->shareWithGroupMembersOnly()) { $sharedBy = $this->userManager->get($share->getSharedBy()); diff --git a/tests/lib/share20/managertest.php b/tests/lib/share20/managertest.php index 4f23dd0e6d0fd..2f45de86b9828 100644 --- a/tests/lib/share20/managertest.php +++ b/tests/lib/share20/managertest.php @@ -1147,6 +1147,22 @@ public function testUserCreateChecksIdenticalPathNotSharedWithUser() { $this->invokePrivate($this->manager, 'userCreateChecks', [$share]); } + /** + * @expectedException Exception + * @expectedExceptionMessage Group sharing is now allowed + */ + public function testGroupCreateChecksShareWithGroupMembersGroupSharingNotAllowed() { + $share = $this->manager->newShare(); + + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'no'], + ])); + + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); + } + /** * @expectedException Exception * @expectedExceptionMessage Only sharing within your own groups is allowed @@ -1167,6 +1183,7 @@ public function testGroupCreateChecksShareWithGroupMembersOnlyNotInGroup() { ->method('getAppValue') ->will($this->returnValueMap([ ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], ])); $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); @@ -1195,6 +1212,7 @@ public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup() { ->method('getAppValue') ->will($this->returnValueMap([ ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'], + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], ])); $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); @@ -1222,6 +1240,12 @@ public function testGroupCreateChecksPathAlreadySharedWithSameGroup() { ->with($path) ->willReturn([$share2]); + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); } @@ -1240,6 +1264,12 @@ public function testGroupCreateChecksPathAlreadySharedWithDifferentGroup() { ->with($path) ->willReturn([$share2]); + $this->config + ->method('getAppValue') + ->will($this->returnValueMap([ + ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'], + ])); + $this->invokePrivate($this->manager, 'groupCreateChecks', [$share]); } From c7f1b82b4b3330a2b3625ddffff22ae404f8bacf Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 18 Mar 2016 16:39:03 +0100 Subject: [PATCH 129/286] Respect disabled group sharing in sharee endpoint * Fix tests --- apps/files_sharing/api/sharees.php | 17 +++- apps/files_sharing/appinfo/routes.php | 3 +- apps/files_sharing/tests/api/shareestest.php | 84 ++++++++++++-------- 3 files changed, 69 insertions(+), 35 deletions(-) diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php index 718be4dece991..4e005c5e26cd9 100644 --- a/apps/files_sharing/api/sharees.php +++ b/apps/files_sharing/api/sharees.php @@ -62,6 +62,9 @@ class Sharees { /** @var ILogger */ protected $logger; + /** @var \OCP\Share\IManager */ + protected $shareManager; + /** @var bool */ protected $shareWithGroupOnly = false; @@ -97,6 +100,7 @@ class Sharees { * @param IURLGenerator $urlGenerator * @param IRequest $request * @param ILogger $logger + * @param \OCP\Share\IManager $shareManager */ public function __construct(IGroupManager $groupManager, IUserManager $userManager, @@ -105,7 +109,8 @@ public function __construct(IGroupManager $groupManager, IUserSession $userSession, IURLGenerator $urlGenerator, IRequest $request, - ILogger $logger) { + ILogger $logger, + \OCP\Share\IManager $shareManager) { $this->groupManager = $groupManager; $this->userManager = $userManager; $this->contactsManager = $contactsManager; @@ -114,6 +119,7 @@ public function __construct(IGroupManager $groupManager, $this->urlGenerator = $urlGenerator; $this->request = $request; $this->logger = $logger; + $this->shareManager = $shareManager; } /** @@ -411,9 +417,14 @@ public function search() { $shareTypes = [ Share::SHARE_TYPE_USER, - Share::SHARE_TYPE_GROUP, - Share::SHARE_TYPE_REMOTE, ]; + + if ($this->shareManager->allowGroupSharing()) { + $shareTypes[] = Share::SHARE_TYPE_GROUP; + } + + $shareTypes[] = Share::SHARE_TYPE_REMOTE; + if (isset($_GET['shareType']) && is_array($_GET['shareType'])) { $shareTypes = array_intersect($shareTypes, $_GET['shareType']); sort($shareTypes); diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index 961206079beeb..80632f0fedf24 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -126,7 +126,8 @@ function() { \OC::$server->getUserSession(), \OC::$server->getURLGenerator(), \OC::$server->getRequest(), - \OC::$server->getLogger()); + \OC::$server->getLogger(), + \OC::$server->getShareManager()); API::register('get', '/apps/files_sharing/api/v1/sharees', diff --git a/apps/files_sharing/tests/api/shareestest.php b/apps/files_sharing/tests/api/shareestest.php index 87d143d085378..cda41f55183ee 100644 --- a/apps/files_sharing/tests/api/shareestest.php +++ b/apps/files_sharing/tests/api/shareestest.php @@ -55,6 +55,9 @@ class ShareesTest extends TestCase { /** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */ protected $request; + /** @var \OCP\Share\IManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $shareManager; + protected function setUp() { parent::setUp(); @@ -78,6 +81,10 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); + $this->shareManager = $this->getMockBuilder('OCP\Share\IManager') + ->disableOriginalConstructor() + ->getMock(); + $this->sharees = new Sharees( $this->groupManager, $this->userManager, @@ -86,7 +93,8 @@ protected function setUp() { $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->request, - $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), + $this->shareManager ); } @@ -966,89 +974,95 @@ public function dataSearch() { $allTypes = [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE]; return [ - [[], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + [[], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], // Test itemType [[ 'search' => '', - ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'search' => 'foobar', - ], '', 'yes', true, 'foobar', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, 'foobar', null, $allTypes, 1, 200, false, true, true], [[ 'search' => 0, - ], '', 'yes', true, '0', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '0', null, $allTypes, 1, 200, false, true, true], // Test itemType [[ 'itemType' => '', - ], '', 'yes', true, '', '', $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', '', $allTypes, 1, 200, false, true, true], [[ 'itemType' => 'folder', - ], '', 'yes', true, '', 'folder', $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', 'folder', $allTypes, 1, 200, false, true, true], [[ 'itemType' => 0, - ], '', 'yes', true, '', '0', $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', '0', $allTypes, 1, 200, false, true, true], // Test shareType [[ - ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'shareType' => 0, - ], '', 'yes', true, '', null, [0], 1, 200, false, true], + ], '', 'yes', true, '', null, [0], 1, 200, false, true, true], [[ 'shareType' => '0', - ], '', 'yes', true, '', null, [0], 1, 200, false, true], + ], '', 'yes', true, '', null, [0], 1, 200, false, true, true], [[ 'shareType' => 1, - ], '', 'yes', true, '', null, [1], 1, 200, false, true], + ], '', 'yes', true, '', null, [1], 1, 200, false, true, true], [[ 'shareType' => 12, - ], '', 'yes', true, '', null, [], 1, 200, false, true], + ], '', 'yes', true, '', null, [], 1, 200, false, true, true], [[ 'shareType' => 'foobar', - ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'shareType' => [0, 1, 2], - ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true], + ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true, true], [[ 'shareType' => [0, 1], - ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true], + ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true, true], [[ 'shareType' => $allTypes, - ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'shareType' => $allTypes, - ], '', 'yes', false, '', null, [0, 1], 1, 200, false, true], + ], '', 'yes', false, '', null, [0, 1], 1, 200, false, true, true], + [[ + 'shareType' => $allTypes, + ], '', 'yes', true, '', null, [0, 6], 1, 200, false, true, false], + [[ + 'shareType' => $allTypes, + ], '', 'yes', false, '', null, [0], 1, 200, false, true, false], // Test pagination [[ 'page' => 1, - ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'page' => 10, - ], '', 'yes', true, '', null, $allTypes, 10, 200, false, true], + ], '', 'yes', true, '', null, $allTypes, 10, 200, false, true, true], // Test perPage [[ 'perPage' => 1, - ], '', 'yes', true, '', null, $allTypes, 1, 1, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 1, false, true, true], [[ 'perPage' => 10, - ], '', 'yes', true, '', null, $allTypes, 1, 10, false, true], + ], '', 'yes', true, '', null, $allTypes, 1, 10, false, true, true], // Test $shareWithGroupOnly setting - [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true], - [[], 'yes', 'yes', true, '', null, $allTypes, 1, 200, true, true], + [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], + [[], 'yes', 'yes', true, '', null, $allTypes, 1, 200, true, true, true], // Test $shareeEnumeration setting - [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true], - [[], 'no', 'no', true, '', null, $allTypes, 1, 200, false, false], + [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], + [[], 'no', 'no', true, '', null, $allTypes, 1, 200, false, false, true], // Test keep case for search [[ 'search' => 'foo@example.com/ownCloud', - ], '', 'yes', true, 'foo@example.com/ownCloud', null, $allTypes, 1, 200, false, true], + ], '', 'yes', true, 'foo@example.com/ownCloud', null, $allTypes, 1, 200, false, true, true], ]; } @@ -1066,8 +1080,9 @@ public function dataSearch() { * @param int $perPage * @param bool $shareWithGroupOnly * @param bool $shareeEnumeration + * @param bool $allowGroupSharing */ - public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEnabled, $search, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly, $shareeEnumeration) { + public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEnabled, $search, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly, $shareeEnumeration, $allowGroupSharing) { $oldGet = $_GET; $_GET = $getData; @@ -1082,6 +1097,10 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', $enumSetting], ]); + $this->shareManager->expects($this->once()) + ->method('allowGroupSharing') + ->willReturn($allowGroupSharing); + $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees') ->setConstructorArgs([ $this->groupManager, @@ -1091,7 +1110,8 @@ public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEn $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), + $this->shareManager ]) ->setMethods(array('searchSharees', 'isRemoteSharingAllowed')) ->getMock(); @@ -1175,7 +1195,8 @@ public function testSearchInvalid($getData, $message) { $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), + $this->shareManager ]) ->setMethods(array('searchSharees', 'isRemoteSharingAllowed')) ->getMock(); @@ -1327,7 +1348,8 @@ public function testSearchSharees($searchTerm, $itemType, array $shareTypes, $pa $this->session, $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(), - $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock() + $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), + $this->shareManager ]) ->setMethods(array('getShareesForShareIds', 'getUsers', 'getGroups', 'getRemote')) ->getMock(); From f8f292ab16f70eaf4a248883150369b0eb2de7aa Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Mon, 21 Mar 2016 19:47:10 +0100 Subject: [PATCH 130/286] Fix js strings if group sharing is disabled --- core/js/config.php | 3 ++- core/js/shareconfigmodel.js | 3 ++- core/js/sharedialogview.js | 20 ++++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/js/config.php b/core/js/config.php index 1f0c756596d97..7f2d0517460ec 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -162,7 +162,8 @@ 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), 'resharingAllowed' => \OCP\Share::isResharingAllowed(), 'remoteShareAllowed' => $outgoingServer2serverShareEnabled, - 'federatedCloudShareDoc' => \OC::$server->getURLGenerator()->linkToDocs('user-sharing-federated') + 'federatedCloudShareDoc' => \OC::$server->getURLGenerator()->linkToDocs('user-sharing-federated'), + 'allowGroupSharing' => \OC::$server->getShareManager()->allowGroupSharing() ) ) ), diff --git a/core/js/shareconfigmodel.js b/core/js/shareconfigmodel.js index 5494feaf7fa27..b1bbde7a69579 100644 --- a/core/js/shareconfigmodel.js +++ b/core/js/shareconfigmodel.js @@ -26,7 +26,8 @@ isDefaultExpireDateEnabled: oc_appconfig.core.defaultExpireDateEnabled === true, isRemoteShareAllowed: oc_appconfig.core.remoteShareAllowed, defaultExpireDate: oc_appconfig.core.defaultExpireDate, - isResharingAllowed: oc_appconfig.core.resharingAllowed + isResharingAllowed: oc_appconfig.core.resharingAllowed, + allowGroupSharing: oc_appconfig.core.allowGroupSharing }, /** diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 5e1e14541c5f0..e5ef5bb1d6f67 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -216,8 +216,12 @@ .autocomplete("option", "autoFocus", true); response(suggestions); } else { + var title = t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()}); + if (!view.configModel.get('allowGroupSharing')) { + title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()}); + } $('.shareWithField').addClass('error') - .attr('data-original-title', t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()})) + .attr('data-original-title', title) .tooltip('hide') .tooltip({ placement: 'bottom', @@ -386,10 +390,18 @@ }, _renderSharePlaceholderPart: function () { - var sharePlaceholder = t('core', 'Share with users or groups …'); - if (this.configModel.get('isRemoteShareAllowed')) { - sharePlaceholder = t('core', 'Share with users, groups or remote users …'); + var sharePlaceholder = t('core', 'Share with users…'); + + if (this.configModel.get('allowGroupSharing')) { + if (this.configModel.get('isRemoteShareAllowed')) { + sharePlaceholder = t('core', 'Share with users, groups or remote users…'); + } else { + sharePlaceholder = t('core', 'Share with users or groups…') + } + } else if (this.configModel.get('isRemoteShareAllowed')) { + sharePlaceholder = t('core', 'Share with users or remote users…'); } + return sharePlaceholder; }, From b3ead7568df0fe6215bcc4c5e084c381b78cf48c Mon Sep 17 00:00:00 2001 From: RealRancor Date: Sat, 19 Mar 2016 14:08:21 +0100 Subject: [PATCH 131/286] Exclude lost+found dir in integrity check --- .../iterator/excludefoldersbypathfilteriterator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php index 766897e751797..1082e97c296a7 100644 --- a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php +++ b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php @@ -34,10 +34,11 @@ public function __construct(\RecursiveIterator $iterator, $root = '') { $excludedFolders = [ rtrim($root . '/data', '/'), - rtrim($root .'/themes', '/'), + rtrim($root . '/themes', '/'), rtrim($root . '/config', '/'), rtrim($root . '/apps', '/'), rtrim($root . '/assets', '/'), + rtrim($root . '/lost+found', '/'), ]; $customDataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', ''); if($customDataDir !== '') { From 4fdb2254a47c1553c65e6f92a7be635d28ff5eae Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 22 Mar 2016 13:10:33 +0100 Subject: [PATCH 132/286] Backport translations to stable9 --- apps/comments/l10n/cs_CZ.js | 3 +- apps/comments/l10n/cs_CZ.json | 3 +- apps/comments/l10n/de.js | 3 +- apps/comments/l10n/de.json | 3 +- apps/comments/l10n/de_DE.js | 3 +- apps/comments/l10n/de_DE.json | 3 +- apps/comments/l10n/en_GB.js | 3 +- apps/comments/l10n/en_GB.json | 3 +- apps/comments/l10n/eo.js | 3 +- apps/comments/l10n/eo.json | 3 +- apps/comments/l10n/es.js | 3 +- apps/comments/l10n/es.json | 3 +- apps/comments/l10n/fi_FI.js | 3 +- apps/comments/l10n/fi_FI.json | 3 +- apps/comments/l10n/fr.js | 3 +- apps/comments/l10n/fr.json | 3 +- apps/comments/l10n/he.js | 3 +- apps/comments/l10n/he.json | 3 +- apps/comments/l10n/hu_HU.js | 7 +++- apps/comments/l10n/hu_HU.json | 7 +++- apps/comments/l10n/id.js | 3 +- apps/comments/l10n/id.json | 3 +- apps/comments/l10n/is.js | 7 +++- apps/comments/l10n/is.json | 7 +++- apps/comments/l10n/it.js | 3 +- apps/comments/l10n/it.json | 3 +- apps/comments/l10n/ja.js | 3 +- apps/comments/l10n/ja.json | 3 +- apps/comments/l10n/ko.js | 7 +++- apps/comments/l10n/ko.json | 7 +++- apps/comments/l10n/nb_NO.js | 3 +- apps/comments/l10n/nb_NO.json | 3 +- apps/comments/l10n/nl.js | 3 +- apps/comments/l10n/nl.json | 3 +- apps/comments/l10n/pl.js | 7 +++- apps/comments/l10n/pl.json | 7 +++- apps/comments/l10n/pt_BR.js | 3 +- apps/comments/l10n/pt_BR.json | 3 +- apps/comments/l10n/pt_PT.js | 3 +- apps/comments/l10n/pt_PT.json | 3 +- apps/comments/l10n/ru.js | 3 +- apps/comments/l10n/ru.json | 3 +- apps/comments/l10n/sl.js | 3 +- apps/comments/l10n/sl.json | 3 +- apps/comments/l10n/sq.js | 3 +- apps/comments/l10n/sq.json | 3 +- apps/comments/l10n/sr.js | 7 +++- apps/comments/l10n/sr.json | 7 +++- apps/comments/l10n/sv.js | 3 +- apps/comments/l10n/sv.json | 3 +- apps/comments/l10n/th_TH.js | 3 +- apps/comments/l10n/th_TH.json | 3 +- apps/comments/l10n/tr.js | 3 +- apps/comments/l10n/tr.json | 3 +- apps/comments/l10n/uk.js | 3 +- apps/comments/l10n/uk.json | 3 +- apps/comments/l10n/zh_CN.js | 3 +- apps/comments/l10n/zh_CN.json | 3 +- apps/encryption/l10n/de_DE.js | 3 +- apps/encryption/l10n/de_DE.json | 3 +- apps/encryption/l10n/ko.js | 4 +- apps/encryption/l10n/ko.json | 4 +- apps/encryption/l10n/pl.js | 11 +++++- apps/encryption/l10n/pl.json | 11 +++++- apps/federatedfilesharing/l10n/gl.js | 3 +- apps/federatedfilesharing/l10n/gl.json | 3 +- apps/federatedfilesharing/l10n/hu_HU.js | 3 +- apps/federatedfilesharing/l10n/hu_HU.json | 3 +- apps/federatedfilesharing/l10n/ko.js | 3 +- apps/federatedfilesharing/l10n/ko.json | 3 +- apps/federation/l10n/cs_CZ.js | 5 ++- apps/federation/l10n/cs_CZ.json | 5 ++- apps/federation/l10n/de.js | 4 +- apps/federation/l10n/de.json | 4 +- apps/federation/l10n/de_DE.js | 4 +- apps/federation/l10n/de_DE.json | 4 +- apps/federation/l10n/en_GB.js | 5 ++- apps/federation/l10n/en_GB.json | 5 ++- apps/federation/l10n/es.js | 5 ++- apps/federation/l10n/es.json | 5 ++- apps/federation/l10n/fi_FI.js | 5 ++- apps/federation/l10n/fi_FI.json | 5 ++- apps/federation/l10n/fr.js | 5 ++- apps/federation/l10n/fr.json | 5 ++- apps/federation/l10n/he.js | 5 ++- apps/federation/l10n/he.json | 5 ++- apps/federation/l10n/it.js | 5 ++- apps/federation/l10n/it.json | 5 ++- apps/federation/l10n/ja.js | 5 ++- apps/federation/l10n/ja.json | 5 ++- apps/federation/l10n/nb_NO.js | 5 ++- apps/federation/l10n/nb_NO.json | 5 ++- apps/federation/l10n/nl.js | 5 ++- apps/federation/l10n/nl.json | 5 ++- apps/federation/l10n/pt_BR.js | 5 ++- apps/federation/l10n/pt_BR.json | 5 ++- apps/federation/l10n/pt_PT.js | 5 ++- apps/federation/l10n/pt_PT.json | 5 ++- apps/federation/l10n/ru.js | 4 +- apps/federation/l10n/ru.json | 4 +- apps/federation/l10n/sl.js | 5 ++- apps/federation/l10n/sl.json | 5 ++- apps/federation/l10n/sq.js | 5 ++- apps/federation/l10n/sq.json | 5 ++- apps/federation/l10n/sv.js | 5 ++- apps/federation/l10n/sv.json | 5 ++- apps/federation/l10n/zh_CN.js | 5 ++- apps/federation/l10n/zh_CN.json | 5 ++- apps/files/l10n/ar.js | 7 +++- apps/files/l10n/ar.json | 7 +++- apps/files/l10n/ast.js | 9 ++++- apps/files/l10n/ast.json | 9 ++++- apps/files/l10n/az.js | 6 ++- apps/files/l10n/az.json | 6 ++- apps/files/l10n/bg_BG.js | 6 ++- apps/files/l10n/bg_BG.json | 6 ++- apps/files/l10n/bn_BD.js | 6 ++- apps/files/l10n/bn_BD.json | 6 ++- apps/files/l10n/bn_IN.js | 5 ++- apps/files/l10n/bn_IN.json | 5 ++- apps/files/l10n/ca.js | 6 ++- apps/files/l10n/ca.json | 6 ++- apps/files/l10n/cs_CZ.js | 9 ++++- apps/files/l10n/cs_CZ.json | 9 ++++- apps/files/l10n/cy_GB.js | 3 +- apps/files/l10n/cy_GB.json | 3 +- apps/files/l10n/da.js | 9 ++++- apps/files/l10n/da.json | 9 ++++- apps/files/l10n/de.js | 10 ++++- apps/files/l10n/de.json | 10 ++++- apps/files/l10n/de_AT.js | 5 ++- apps/files/l10n/de_AT.json | 5 ++- apps/files/l10n/de_DE.js | 10 ++++- apps/files/l10n/de_DE.json | 10 ++++- apps/files/l10n/el.js | 9 ++++- apps/files/l10n/el.json | 9 ++++- apps/files/l10n/en_GB.js | 9 ++++- apps/files/l10n/en_GB.json | 9 ++++- apps/files/l10n/eo.js | 9 ++++- apps/files/l10n/eo.json | 9 ++++- apps/files/l10n/es.js | 9 ++++- apps/files/l10n/es.json | 9 ++++- apps/files/l10n/es_AR.js | 5 ++- apps/files/l10n/es_AR.json | 5 ++- apps/files/l10n/es_CL.js | 5 ++- apps/files/l10n/es_CL.json | 5 ++- apps/files/l10n/es_MX.js | 5 ++- apps/files/l10n/es_MX.json | 5 ++- apps/files/l10n/et_EE.js | 6 ++- apps/files/l10n/et_EE.json | 6 ++- apps/files/l10n/eu.js | 6 ++- apps/files/l10n/eu.json | 6 ++- apps/files/l10n/fa.js | 9 ++++- apps/files/l10n/fa.json | 9 ++++- apps/files/l10n/fi_FI.js | 9 ++++- apps/files/l10n/fi_FI.json | 9 ++++- apps/files/l10n/fil.js | 3 +- apps/files/l10n/fil.json | 3 +- apps/files/l10n/fr.js | 9 ++++- apps/files/l10n/fr.json | 9 ++++- apps/files/l10n/gl.js | 6 ++- apps/files/l10n/gl.json | 6 ++- apps/files/l10n/he.js | 9 ++++- apps/files/l10n/he.json | 9 ++++- apps/files/l10n/hr.js | 6 ++- apps/files/l10n/hr.json | 6 ++- apps/files/l10n/hu_HU.js | 9 ++++- apps/files/l10n/hu_HU.json | 9 ++++- apps/files/l10n/hy.js | 11 +++++- apps/files/l10n/hy.json | 11 +++++- apps/files/l10n/ia.js | 6 ++- apps/files/l10n/ia.json | 6 ++- apps/files/l10n/id.js | 9 ++++- apps/files/l10n/id.json | 9 ++++- apps/files/l10n/is.js | 17 +++++++- apps/files/l10n/is.json | 17 +++++++- apps/files/l10n/it.js | 9 ++++- apps/files/l10n/it.json | 9 ++++- apps/files/l10n/ja.js | 9 ++++- apps/files/l10n/ja.json | 9 ++++- apps/files/l10n/ka_GE.js | 3 +- apps/files/l10n/ka_GE.json | 3 +- apps/files/l10n/km.js | 6 ++- apps/files/l10n/km.json | 6 ++- apps/files/l10n/kn.js | 3 +- apps/files/l10n/kn.json | 3 +- apps/files/l10n/ko.js | 9 ++++- apps/files/l10n/ko.json | 9 ++++- apps/files/l10n/lb.js | 3 +- apps/files/l10n/lb.json | 3 +- apps/files/l10n/lt_LT.js | 9 ++++- apps/files/l10n/lt_LT.json | 9 ++++- apps/files/l10n/lv.js | 6 ++- apps/files/l10n/lv.json | 6 ++- apps/files/l10n/mk.js | 8 +++- apps/files/l10n/mk.json | 8 +++- apps/files/l10n/ml_IN.js | 5 ++- apps/files/l10n/ml_IN.json | 5 ++- apps/files/l10n/mn.js | 6 ++- apps/files/l10n/mn.json | 6 ++- apps/files/l10n/ms_MY.js | 5 ++- apps/files/l10n/ms_MY.json | 5 ++- apps/files/l10n/nb_NO.js | 9 ++++- apps/files/l10n/nb_NO.json | 9 ++++- apps/files/l10n/nl.js | 9 ++++- apps/files/l10n/nl.json | 9 ++++- apps/files/l10n/nn_NO.js | 5 ++- apps/files/l10n/nn_NO.json | 5 ++- apps/files/l10n/oc.js | 9 ++++- apps/files/l10n/oc.json | 9 ++++- apps/files/l10n/pl.js | 10 ++++- apps/files/l10n/pl.json | 10 ++++- apps/files/l10n/pt_BR.js | 9 ++++- apps/files/l10n/pt_BR.json | 9 ++++- apps/files/l10n/pt_PT.js | 9 ++++- apps/files/l10n/pt_PT.json | 9 ++++- apps/files/l10n/ro.js | 6 ++- apps/files/l10n/ro.json | 6 ++- apps/files/l10n/ru.js | 9 ++++- apps/files/l10n/ru.json | 9 ++++- apps/files/l10n/si_LK.js | 3 +- apps/files/l10n/si_LK.json | 3 +- apps/files/l10n/sk_SK.js | 6 ++- apps/files/l10n/sk_SK.json | 6 ++- apps/files/l10n/sl.js | 9 ++++- apps/files/l10n/sl.json | 9 ++++- apps/files/l10n/sq.js | 9 ++++- apps/files/l10n/sq.json | 9 ++++- apps/files/l10n/sr.js | 9 ++++- apps/files/l10n/sr.json | 9 ++++- apps/files/l10n/sr@latin.js | 6 ++- apps/files/l10n/sr@latin.json | 6 ++- apps/files/l10n/sv.js | 9 ++++- apps/files/l10n/sv.json | 9 ++++- apps/files/l10n/ta_IN.js | 5 ++- apps/files/l10n/ta_IN.json | 5 ++- apps/files/l10n/ta_LK.js | 3 +- apps/files/l10n/ta_LK.json | 3 +- apps/files/l10n/th_TH.js | 9 ++++- apps/files/l10n/th_TH.json | 9 ++++- apps/files/l10n/tr.js | 9 ++++- apps/files/l10n/tr.json | 9 ++++- apps/files/l10n/ug.js | 3 +- apps/files/l10n/ug.json | 3 +- apps/files/l10n/uk.js | 6 ++- apps/files/l10n/uk.json | 6 ++- apps/files/l10n/zh_CN.js | 9 ++++- apps/files/l10n/zh_CN.json | 9 ++++- apps/files/l10n/zh_HK.js | 5 ++- apps/files/l10n/zh_HK.json | 5 ++- apps/files/l10n/zh_TW.js | 9 ++++- apps/files/l10n/zh_TW.json | 9 ++++- apps/files_external/l10n/ast.js | 4 +- apps/files_external/l10n/ast.json | 4 +- apps/files_external/l10n/az.js | 4 +- apps/files_external/l10n/az.json | 4 +- apps/files_external/l10n/bg_BG.js | 4 +- apps/files_external/l10n/bg_BG.json | 4 +- apps/files_external/l10n/ca.js | 4 +- apps/files_external/l10n/ca.json | 4 +- apps/files_external/l10n/cs_CZ.js | 4 +- apps/files_external/l10n/cs_CZ.json | 4 +- apps/files_external/l10n/da.js | 3 +- apps/files_external/l10n/da.json | 3 +- apps/files_external/l10n/de.js | 4 +- apps/files_external/l10n/de.json | 4 +- apps/files_external/l10n/de_DE.js | 12 +++++- apps/files_external/l10n/de_DE.json | 12 +++++- apps/files_external/l10n/el.js | 6 ++- apps/files_external/l10n/el.json | 6 ++- apps/files_external/l10n/en_GB.js | 4 +- apps/files_external/l10n/en_GB.json | 4 +- apps/files_external/l10n/es.js | 4 +- apps/files_external/l10n/es.json | 4 +- apps/files_external/l10n/et_EE.js | 3 +- apps/files_external/l10n/et_EE.json | 3 +- apps/files_external/l10n/eu.js | 4 +- apps/files_external/l10n/eu.json | 4 +- apps/files_external/l10n/fa.js | 3 +- apps/files_external/l10n/fa.json | 3 +- apps/files_external/l10n/fi_FI.js | 4 +- apps/files_external/l10n/fi_FI.json | 4 +- apps/files_external/l10n/fr.js | 4 +- apps/files_external/l10n/fr.json | 4 +- apps/files_external/l10n/gl.js | 4 +- apps/files_external/l10n/gl.json | 4 +- apps/files_external/l10n/he.js | 4 +- apps/files_external/l10n/he.json | 4 +- apps/files_external/l10n/hr.js | 5 ++- apps/files_external/l10n/hr.json | 5 ++- apps/files_external/l10n/hu_HU.js | 3 +- apps/files_external/l10n/hu_HU.json | 3 +- apps/files_external/l10n/hy.js | 3 +- apps/files_external/l10n/hy.json | 3 +- apps/files_external/l10n/id.js | 3 +- apps/files_external/l10n/id.json | 3 +- apps/files_external/l10n/is.js | 48 ++++++++++++++++++++++- apps/files_external/l10n/is.json | 48 ++++++++++++++++++++++- apps/files_external/l10n/it.js | 4 +- apps/files_external/l10n/it.json | 4 +- apps/files_external/l10n/ja.js | 4 +- apps/files_external/l10n/ja.json | 4 +- apps/files_external/l10n/ko.js | 16 +++++++- apps/files_external/l10n/ko.json | 16 +++++++- apps/files_external/l10n/nb_NO.js | 4 +- apps/files_external/l10n/nb_NO.json | 4 +- apps/files_external/l10n/nds.js | 3 +- apps/files_external/l10n/nds.json | 3 +- apps/files_external/l10n/nl.js | 4 +- apps/files_external/l10n/nl.json | 4 +- apps/files_external/l10n/oc.js | 3 +- apps/files_external/l10n/oc.json | 3 +- apps/files_external/l10n/pl.js | 6 ++- apps/files_external/l10n/pl.json | 6 ++- apps/files_external/l10n/pt_BR.js | 4 +- apps/files_external/l10n/pt_BR.json | 4 +- apps/files_external/l10n/pt_PT.js | 4 +- apps/files_external/l10n/pt_PT.json | 4 +- apps/files_external/l10n/ru.js | 4 +- apps/files_external/l10n/ru.json | 4 +- apps/files_external/l10n/sk_SK.js | 3 +- apps/files_external/l10n/sk_SK.json | 3 +- apps/files_external/l10n/sl.js | 13 +++++- apps/files_external/l10n/sl.json | 13 +++++- apps/files_external/l10n/sq.js | 4 +- apps/files_external/l10n/sq.json | 4 +- apps/files_external/l10n/sr.js | 9 ++++- apps/files_external/l10n/sr.json | 9 ++++- apps/files_external/l10n/sr@latin.js | 4 +- apps/files_external/l10n/sr@latin.json | 4 +- apps/files_external/l10n/sv.js | 3 +- apps/files_external/l10n/sv.json | 3 +- apps/files_external/l10n/th_TH.js | 4 +- apps/files_external/l10n/th_TH.json | 4 +- apps/files_external/l10n/tr.js | 3 +- apps/files_external/l10n/tr.json | 3 +- apps/files_external/l10n/uk.js | 4 +- apps/files_external/l10n/uk.json | 4 +- apps/files_external/l10n/zh_CN.js | 15 ++++++- apps/files_external/l10n/zh_CN.json | 15 ++++++- apps/files_external/l10n/zh_TW.js | 3 +- apps/files_external/l10n/zh_TW.json | 3 +- apps/files_sharing/l10n/az.js | 4 +- apps/files_sharing/l10n/az.json | 4 +- apps/files_sharing/l10n/bg_BG.js | 4 +- apps/files_sharing/l10n/bg_BG.json | 4 +- apps/files_sharing/l10n/cs_CZ.js | 15 ++++++- apps/files_sharing/l10n/cs_CZ.json | 15 ++++++- apps/files_sharing/l10n/da.js | 7 +++- apps/files_sharing/l10n/da.json | 7 +++- apps/files_sharing/l10n/de.js | 15 ++++++- apps/files_sharing/l10n/de.json | 15 ++++++- apps/files_sharing/l10n/de_DE.js | 16 +++++++- apps/files_sharing/l10n/de_DE.json | 16 +++++++- apps/files_sharing/l10n/el.js | 7 +++- apps/files_sharing/l10n/el.json | 7 +++- apps/files_sharing/l10n/en_GB.js | 15 ++++++- apps/files_sharing/l10n/en_GB.json | 15 ++++++- apps/files_sharing/l10n/eo.js | 12 +++++- apps/files_sharing/l10n/eo.json | 12 +++++- apps/files_sharing/l10n/es.js | 15 ++++++- apps/files_sharing/l10n/es.json | 15 ++++++- apps/files_sharing/l10n/eu.js | 4 +- apps/files_sharing/l10n/eu.json | 4 +- apps/files_sharing/l10n/fi_FI.js | 9 ++++- apps/files_sharing/l10n/fi_FI.json | 9 ++++- apps/files_sharing/l10n/fr.js | 15 ++++++- apps/files_sharing/l10n/fr.json | 15 ++++++- apps/files_sharing/l10n/gl.js | 4 +- apps/files_sharing/l10n/gl.json | 4 +- apps/files_sharing/l10n/he.js | 15 ++++++- apps/files_sharing/l10n/he.json | 15 ++++++- apps/files_sharing/l10n/hu_HU.js | 7 +++- apps/files_sharing/l10n/hu_HU.json | 7 +++- apps/files_sharing/l10n/hy.js | 3 +- apps/files_sharing/l10n/hy.json | 3 +- apps/files_sharing/l10n/id.js | 7 +++- apps/files_sharing/l10n/id.json | 7 +++- apps/files_sharing/l10n/is.js | 15 ++++++- apps/files_sharing/l10n/is.json | 15 ++++++- apps/files_sharing/l10n/it.js | 15 ++++++- apps/files_sharing/l10n/it.json | 15 ++++++- apps/files_sharing/l10n/ja.js | 15 ++++++- apps/files_sharing/l10n/ja.json | 15 ++++++- apps/files_sharing/l10n/ko.js | 19 ++++++++- apps/files_sharing/l10n/ko.json | 19 ++++++++- apps/files_sharing/l10n/lt_LT.js | 7 +++- apps/files_sharing/l10n/lt_LT.json | 7 +++- apps/files_sharing/l10n/lv.js | 4 +- apps/files_sharing/l10n/lv.json | 4 +- apps/files_sharing/l10n/mk.js | 5 ++- apps/files_sharing/l10n/mk.json | 5 ++- apps/files_sharing/l10n/nb_NO.js | 15 ++++++- apps/files_sharing/l10n/nb_NO.json | 15 ++++++- apps/files_sharing/l10n/nl.js | 15 ++++++- apps/files_sharing/l10n/nl.json | 15 ++++++- apps/files_sharing/l10n/oc.js | 7 +++- apps/files_sharing/l10n/oc.json | 7 +++- apps/files_sharing/l10n/pl.js | 3 +- apps/files_sharing/l10n/pl.json | 3 +- apps/files_sharing/l10n/pt_BR.js | 15 ++++++- apps/files_sharing/l10n/pt_BR.json | 15 ++++++- apps/files_sharing/l10n/pt_PT.js | 15 ++++++- apps/files_sharing/l10n/pt_PT.json | 15 ++++++- apps/files_sharing/l10n/ru.js | 15 ++++++- apps/files_sharing/l10n/ru.json | 15 ++++++- apps/files_sharing/l10n/sk_SK.js | 7 +++- apps/files_sharing/l10n/sk_SK.json | 7 +++- apps/files_sharing/l10n/sl.js | 4 +- apps/files_sharing/l10n/sl.json | 4 +- apps/files_sharing/l10n/sq.js | 15 ++++++- apps/files_sharing/l10n/sq.json | 15 ++++++- apps/files_sharing/l10n/sr.js | 6 ++- apps/files_sharing/l10n/sr.json | 6 ++- apps/files_sharing/l10n/sr@latin.js | 4 +- apps/files_sharing/l10n/sr@latin.json | 4 +- apps/files_sharing/l10n/sv.js | 4 +- apps/files_sharing/l10n/sv.json | 4 +- apps/files_sharing/l10n/th_TH.js | 7 +++- apps/files_sharing/l10n/th_TH.json | 7 +++- apps/files_sharing/l10n/tr.js | 15 ++++++- apps/files_sharing/l10n/tr.json | 15 ++++++- apps/files_sharing/l10n/uk.js | 4 +- apps/files_sharing/l10n/uk.json | 4 +- apps/files_sharing/l10n/zh_CN.js | 10 ++++- apps/files_sharing/l10n/zh_CN.json | 10 ++++- apps/files_sharing/l10n/zh_TW.js | 7 +++- apps/files_sharing/l10n/zh_TW.json | 7 +++- apps/files_trashbin/l10n/hy.js | 3 +- apps/files_trashbin/l10n/hy.json | 3 +- apps/files_trashbin/l10n/pl.js | 3 +- apps/files_trashbin/l10n/pl.json | 3 +- apps/systemtags/l10n/de.js | 3 +- apps/systemtags/l10n/de.json | 3 +- apps/systemtags/l10n/de_DE.js | 3 +- apps/systemtags/l10n/de_DE.json | 3 +- apps/systemtags/l10n/hu_HU.js | 6 ++- apps/systemtags/l10n/hu_HU.json | 6 ++- apps/systemtags/l10n/hy.js | 3 +- apps/systemtags/l10n/hy.json | 3 +- apps/systemtags/l10n/pl.js | 5 ++- apps/systemtags/l10n/pl.json | 5 ++- apps/systemtags/l10n/sr.js | 3 +- apps/systemtags/l10n/sr.json | 3 +- apps/updatenotification/l10n/az.js | 3 +- apps/updatenotification/l10n/az.json | 3 +- apps/updatenotification/l10n/bg_BG.js | 3 +- apps/updatenotification/l10n/bg_BG.json | 3 +- apps/updatenotification/l10n/bs.js | 3 +- apps/updatenotification/l10n/bs.json | 3 +- apps/updatenotification/l10n/cs_CZ.js | 5 ++- apps/updatenotification/l10n/cs_CZ.json | 5 ++- apps/updatenotification/l10n/da.js | 3 +- apps/updatenotification/l10n/da.json | 3 +- apps/updatenotification/l10n/de.js | 5 ++- apps/updatenotification/l10n/de.json | 5 ++- apps/updatenotification/l10n/de_DE.js | 4 +- apps/updatenotification/l10n/de_DE.json | 4 +- apps/updatenotification/l10n/el.js | 4 +- apps/updatenotification/l10n/el.json | 4 +- apps/updatenotification/l10n/en_GB.js | 5 ++- apps/updatenotification/l10n/en_GB.json | 5 ++- apps/updatenotification/l10n/es.js | 5 ++- apps/updatenotification/l10n/es.json | 5 ++- apps/updatenotification/l10n/es_AR.js | 3 +- apps/updatenotification/l10n/es_AR.json | 3 +- apps/updatenotification/l10n/et_EE.js | 4 +- apps/updatenotification/l10n/et_EE.json | 4 +- apps/updatenotification/l10n/eu.js | 3 +- apps/updatenotification/l10n/eu.json | 3 +- apps/updatenotification/l10n/fi_FI.js | 5 ++- apps/updatenotification/l10n/fi_FI.json | 5 ++- apps/updatenotification/l10n/fr.js | 4 +- apps/updatenotification/l10n/fr.json | 4 +- apps/updatenotification/l10n/gl.js | 3 +- apps/updatenotification/l10n/gl.json | 3 +- apps/updatenotification/l10n/he.js | 5 ++- apps/updatenotification/l10n/he.json | 5 ++- apps/updatenotification/l10n/hr.js | 3 +- apps/updatenotification/l10n/hr.json | 3 +- apps/updatenotification/l10n/hu_HU.js | 6 ++- apps/updatenotification/l10n/hu_HU.json | 6 ++- apps/updatenotification/l10n/id.js | 3 +- apps/updatenotification/l10n/id.json | 3 +- apps/updatenotification/l10n/is.js | 5 ++- apps/updatenotification/l10n/is.json | 5 ++- apps/updatenotification/l10n/it.js | 5 ++- apps/updatenotification/l10n/it.json | 5 ++- apps/updatenotification/l10n/ja.js | 5 ++- apps/updatenotification/l10n/ja.json | 5 ++- apps/updatenotification/l10n/ko.js | 4 +- apps/updatenotification/l10n/ko.json | 4 +- apps/updatenotification/l10n/nb_NO.js | 5 ++- apps/updatenotification/l10n/nb_NO.json | 5 ++- apps/updatenotification/l10n/nl.js | 5 ++- apps/updatenotification/l10n/nl.json | 5 ++- apps/updatenotification/l10n/pl.js | 6 ++- apps/updatenotification/l10n/pl.json | 6 ++- apps/updatenotification/l10n/pt_BR.js | 5 ++- apps/updatenotification/l10n/pt_BR.json | 5 ++- apps/updatenotification/l10n/pt_PT.js | 5 ++- apps/updatenotification/l10n/pt_PT.json | 5 ++- apps/updatenotification/l10n/ru.js | 5 ++- apps/updatenotification/l10n/ru.json | 5 ++- apps/updatenotification/l10n/sk_SK.js | 3 +- apps/updatenotification/l10n/sk_SK.json | 3 +- apps/updatenotification/l10n/sl.js | 5 ++- apps/updatenotification/l10n/sl.json | 5 ++- apps/updatenotification/l10n/sq.js | 5 ++- apps/updatenotification/l10n/sq.json | 5 ++- apps/updatenotification/l10n/sr.js | 6 ++- apps/updatenotification/l10n/sr.json | 6 ++- apps/updatenotification/l10n/sv.js | 5 ++- apps/updatenotification/l10n/sv.json | 5 ++- apps/updatenotification/l10n/tr.js | 3 +- apps/updatenotification/l10n/tr.json | 3 +- apps/updatenotification/l10n/uk.js | 3 +- apps/updatenotification/l10n/uk.json | 3 +- apps/updatenotification/l10n/zh_CN.js | 5 ++- apps/updatenotification/l10n/zh_CN.json | 5 ++- apps/user_ldap/l10n/ar.js | 3 +- apps/user_ldap/l10n/ar.json | 3 +- apps/user_ldap/l10n/ast.js | 4 +- apps/user_ldap/l10n/ast.json | 4 +- apps/user_ldap/l10n/bg_BG.js | 4 +- apps/user_ldap/l10n/bg_BG.json | 4 +- apps/user_ldap/l10n/bn_BD.js | 4 +- apps/user_ldap/l10n/bn_BD.json | 4 +- apps/user_ldap/l10n/ca.js | 4 +- apps/user_ldap/l10n/ca.json | 4 +- apps/user_ldap/l10n/cs_CZ.js | 4 +- apps/user_ldap/l10n/cs_CZ.json | 4 +- apps/user_ldap/l10n/da.js | 4 +- apps/user_ldap/l10n/da.json | 4 +- apps/user_ldap/l10n/de.js | 4 +- apps/user_ldap/l10n/de.json | 4 +- apps/user_ldap/l10n/de_DE.js | 4 +- apps/user_ldap/l10n/de_DE.json | 4 +- apps/user_ldap/l10n/el.js | 4 +- apps/user_ldap/l10n/el.json | 4 +- apps/user_ldap/l10n/en_GB.js | 4 +- apps/user_ldap/l10n/en_GB.json | 4 +- apps/user_ldap/l10n/eo.js | 3 +- apps/user_ldap/l10n/eo.json | 3 +- apps/user_ldap/l10n/es.js | 4 +- apps/user_ldap/l10n/es.json | 4 +- apps/user_ldap/l10n/es_AR.js | 3 +- apps/user_ldap/l10n/es_AR.json | 3 +- apps/user_ldap/l10n/es_MX.js | 3 +- apps/user_ldap/l10n/es_MX.json | 3 +- apps/user_ldap/l10n/et_EE.js | 4 +- apps/user_ldap/l10n/et_EE.json | 4 +- apps/user_ldap/l10n/eu.js | 4 +- apps/user_ldap/l10n/eu.json | 4 +- apps/user_ldap/l10n/fa.js | 3 +- apps/user_ldap/l10n/fa.json | 3 +- apps/user_ldap/l10n/fi_FI.js | 3 +- apps/user_ldap/l10n/fi_FI.json | 3 +- apps/user_ldap/l10n/fil.js | 3 +- apps/user_ldap/l10n/fil.json | 3 +- apps/user_ldap/l10n/fr.js | 4 +- apps/user_ldap/l10n/fr.json | 4 +- apps/user_ldap/l10n/gl.js | 4 +- apps/user_ldap/l10n/gl.json | 4 +- apps/user_ldap/l10n/he.js | 10 ++++- apps/user_ldap/l10n/he.json | 10 ++++- apps/user_ldap/l10n/hu_HU.js | 4 +- apps/user_ldap/l10n/hu_HU.json | 4 +- apps/user_ldap/l10n/hy.js | 4 +- apps/user_ldap/l10n/hy.json | 4 +- apps/user_ldap/l10n/id.js | 4 +- apps/user_ldap/l10n/id.json | 4 +- apps/user_ldap/l10n/is.js | 3 +- apps/user_ldap/l10n/is.json | 3 +- apps/user_ldap/l10n/it.js | 4 +- apps/user_ldap/l10n/it.json | 4 +- apps/user_ldap/l10n/ja.js | 4 +- apps/user_ldap/l10n/ja.json | 4 +- apps/user_ldap/l10n/ka_GE.js | 3 +- apps/user_ldap/l10n/ka_GE.json | 3 +- apps/user_ldap/l10n/ko.js | 6 ++- apps/user_ldap/l10n/ko.json | 6 ++- apps/user_ldap/l10n/lv.js | 3 +- apps/user_ldap/l10n/lv.json | 3 +- apps/user_ldap/l10n/nb_NO.js | 4 +- apps/user_ldap/l10n/nb_NO.json | 4 +- apps/user_ldap/l10n/nl.js | 4 +- apps/user_ldap/l10n/nl.json | 4 +- apps/user_ldap/l10n/oc.js | 4 +- apps/user_ldap/l10n/oc.json | 4 +- apps/user_ldap/l10n/pl.js | 6 ++- apps/user_ldap/l10n/pl.json | 6 ++- apps/user_ldap/l10n/pt_BR.js | 4 +- apps/user_ldap/l10n/pt_BR.json | 4 +- apps/user_ldap/l10n/pt_PT.js | 4 +- apps/user_ldap/l10n/pt_PT.json | 4 +- apps/user_ldap/l10n/ro.js | 3 +- apps/user_ldap/l10n/ro.json | 3 +- apps/user_ldap/l10n/ru.js | 4 +- apps/user_ldap/l10n/ru.json | 4 +- apps/user_ldap/l10n/sk_SK.js | 4 +- apps/user_ldap/l10n/sk_SK.json | 4 +- apps/user_ldap/l10n/sl.js | 6 ++- apps/user_ldap/l10n/sl.json | 6 ++- apps/user_ldap/l10n/sq.js | 4 +- apps/user_ldap/l10n/sq.json | 4 +- apps/user_ldap/l10n/sr.js | 4 +- apps/user_ldap/l10n/sr.json | 4 +- apps/user_ldap/l10n/sv.js | 4 +- apps/user_ldap/l10n/sv.json | 4 +- apps/user_ldap/l10n/th_TH.js | 4 +- apps/user_ldap/l10n/th_TH.json | 4 +- apps/user_ldap/l10n/tr.js | 4 +- apps/user_ldap/l10n/tr.json | 4 +- apps/user_ldap/l10n/uk.js | 4 +- apps/user_ldap/l10n/uk.json | 4 +- apps/user_ldap/l10n/vi.js | 3 +- apps/user_ldap/l10n/vi.json | 3 +- apps/user_ldap/l10n/zh_CN.js | 5 ++- apps/user_ldap/l10n/zh_CN.json | 5 ++- apps/user_ldap/l10n/zh_HK.js | 3 +- apps/user_ldap/l10n/zh_HK.json | 3 +- apps/user_ldap/l10n/zh_TW.js | 4 +- apps/user_ldap/l10n/zh_TW.json | 4 +- core/l10n/af_ZA.js | 3 +- core/l10n/af_ZA.json | 3 +- core/l10n/ar.js | 3 +- core/l10n/ar.json | 3 +- core/l10n/ast.js | 4 +- core/l10n/ast.json | 4 +- core/l10n/bg_BG.js | 5 ++- core/l10n/bg_BG.json | 5 ++- core/l10n/bs.js | 5 ++- core/l10n/bs.json | 5 ++- core/l10n/ca.js | 4 +- core/l10n/ca.json | 4 +- core/l10n/cs_CZ.js | 4 +- core/l10n/cs_CZ.json | 4 +- core/l10n/da.js | 6 ++- core/l10n/da.json | 6 ++- core/l10n/de.js | 7 +++- core/l10n/de.json | 7 +++- core/l10n/de_AT.js | 5 ++- core/l10n/de_AT.json | 5 ++- core/l10n/de_DE.js | 9 ++++- core/l10n/de_DE.json | 9 ++++- core/l10n/el.js | 4 +- core/l10n/el.json | 4 +- core/l10n/en_GB.js | 4 +- core/l10n/en_GB.json | 4 +- core/l10n/eo.js | 3 +- core/l10n/eo.json | 3 +- core/l10n/es.js | 4 +- core/l10n/es.json | 4 +- core/l10n/es_AR.js | 4 +- core/l10n/es_AR.json | 4 +- core/l10n/es_MX.js | 4 +- core/l10n/es_MX.json | 4 +- core/l10n/et_EE.js | 5 ++- core/l10n/et_EE.json | 5 ++- core/l10n/eu.js | 4 +- core/l10n/eu.json | 4 +- core/l10n/fa.js | 4 +- core/l10n/fa.json | 4 +- core/l10n/fi_FI.js | 5 ++- core/l10n/fi_FI.json | 5 ++- core/l10n/fil.js | 24 +++++++++++- core/l10n/fil.json | 24 +++++++++++- core/l10n/fr.js | 5 ++- core/l10n/fr.json | 5 ++- core/l10n/gl.js | 4 +- core/l10n/gl.json | 4 +- core/l10n/he.js | 4 +- core/l10n/he.json | 4 +- core/l10n/hr.js | 4 +- core/l10n/hr.json | 4 +- core/l10n/hu_HU.js | 5 ++- core/l10n/hu_HU.json | 5 ++- core/l10n/hy.js | 41 ++++++++++++++++++- core/l10n/hy.json | 41 ++++++++++++++++++- core/l10n/ia.js | 3 +- core/l10n/ia.json | 3 +- core/l10n/id.js | 5 ++- core/l10n/id.json | 5 ++- core/l10n/is.js | 6 ++- core/l10n/is.json | 6 ++- core/l10n/it.js | 4 +- core/l10n/it.json | 4 +- core/l10n/ja.js | 4 +- core/l10n/ja.json | 4 +- core/l10n/kn.js | 3 +- core/l10n/kn.json | 3 +- core/l10n/ko.js | 9 ++++- core/l10n/ko.json | 9 ++++- core/l10n/lb.js | 4 +- core/l10n/lb.json | 4 +- core/l10n/lt_LT.js | 4 +- core/l10n/lt_LT.json | 4 +- core/l10n/lv.js | 3 +- core/l10n/lv.json | 3 +- core/l10n/mk.js | 4 +- core/l10n/mk.json | 4 +- core/l10n/nb_NO.js | 5 ++- core/l10n/nb_NO.json | 5 ++- core/l10n/nds.js | 4 +- core/l10n/nds.json | 4 +- core/l10n/nl.js | 6 ++- core/l10n/nl.json | 6 ++- core/l10n/nn_NO.js | 3 +- core/l10n/nn_NO.json | 3 +- core/l10n/oc.js | 4 +- core/l10n/oc.json | 4 +- core/l10n/pl.js | 11 +++++- core/l10n/pl.json | 11 +++++- core/l10n/pt_BR.js | 4 +- core/l10n/pt_BR.json | 4 +- core/l10n/pt_PT.js | 4 +- core/l10n/pt_PT.json | 4 +- core/l10n/ro.js | 4 +- core/l10n/ro.json | 4 +- core/l10n/ru.js | 4 +- core/l10n/ru.json | 4 +- core/l10n/sk_SK.js | 4 +- core/l10n/sk_SK.json | 4 +- core/l10n/sl.js | 8 +++- core/l10n/sl.json | 8 +++- core/l10n/sq.js | 4 +- core/l10n/sq.json | 4 +- core/l10n/sr.js | 4 +- core/l10n/sr.json | 4 +- core/l10n/sr@latin.js | 6 ++- core/l10n/sr@latin.json | 6 ++- core/l10n/sv.js | 5 ++- core/l10n/sv.json | 5 ++- core/l10n/ta_LK.js | 3 +- core/l10n/ta_LK.json | 3 +- core/l10n/th_TH.js | 4 +- core/l10n/th_TH.json | 4 +- core/l10n/tr.js | 4 +- core/l10n/tr.json | 4 +- core/l10n/uk.js | 4 +- core/l10n/uk.json | 4 +- core/l10n/vi.js | 3 +- core/l10n/vi.json | 3 +- core/l10n/zh_CN.js | 5 ++- core/l10n/zh_CN.json | 5 ++- core/l10n/zh_TW.js | 4 +- core/l10n/zh_TW.json | 4 +- 748 files changed, 3596 insertions(+), 748 deletions(-) diff --git a/apps/comments/l10n/cs_CZ.js b/apps/comments/l10n/cs_CZ.js index 4a18c2911ee16..6da67ee77307b 100644 --- a/apps/comments/l10n/cs_CZ.js +++ b/apps/comments/l10n/cs_CZ.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Uložit", "Allowed characters {count} of {max}" : "Povolených znaků {count} z {max}", "{count} unread comments" : "{count} nepřečtených komentářů", - "Comment" : "Komentář" + "Comment" : "Komentář", + "Comments for files" : "Komentáře souborů" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/comments/l10n/cs_CZ.json b/apps/comments/l10n/cs_CZ.json index 438fe7208bc1a..e3d7c437d50b3 100644 --- a/apps/comments/l10n/cs_CZ.json +++ b/apps/comments/l10n/cs_CZ.json @@ -14,6 +14,7 @@ "Save" : "Uložit", "Allowed characters {count} of {max}" : "Povolených znaků {count} z {max}", "{count} unread comments" : "{count} nepřečtených komentářů", - "Comment" : "Komentář" + "Comment" : "Komentář", + "Comments for files" : "Komentáře souborů" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/comments/l10n/de.js b/apps/comments/l10n/de.js index 636d9b88f2e3f..f3e5bc81d2212 100644 --- a/apps/comments/l10n/de.js +++ b/apps/comments/l10n/de.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Speichern", "Allowed characters {count} of {max}" : "Erlaubte Zeichen {count} von {max}", "{count} unread comments" : "{count} ungelesene Kommentare", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentare für Dateien" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/de.json b/apps/comments/l10n/de.json index 67c5352ab4616..0d244a760a49e 100644 --- a/apps/comments/l10n/de.json +++ b/apps/comments/l10n/de.json @@ -14,6 +14,7 @@ "Save" : "Speichern", "Allowed characters {count} of {max}" : "Erlaubte Zeichen {count} von {max}", "{count} unread comments" : "{count} ungelesene Kommentare", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentare für Dateien" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/de_DE.js b/apps/comments/l10n/de_DE.js index 33d448c56ef57..5b27b170c8077 100644 --- a/apps/comments/l10n/de_DE.js +++ b/apps/comments/l10n/de_DE.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Speichern", "Allowed characters {count} of {max}" : "{count} von {max} Zeichen benutzt", "{count} unread comments" : "[count] ungelesene Kommentare", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentare für Dateien" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/de_DE.json b/apps/comments/l10n/de_DE.json index a99a1663f50ea..91c55ed1c6bf1 100644 --- a/apps/comments/l10n/de_DE.json +++ b/apps/comments/l10n/de_DE.json @@ -14,6 +14,7 @@ "Save" : "Speichern", "Allowed characters {count} of {max}" : "{count} von {max} Zeichen benutzt", "{count} unread comments" : "[count] ungelesene Kommentare", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentare für Dateien" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/en_GB.js b/apps/comments/l10n/en_GB.js index 04a366a4f6dd8..2b050e0f38271 100644 --- a/apps/comments/l10n/en_GB.js +++ b/apps/comments/l10n/en_GB.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Save", "Allowed characters {count} of {max}" : "Allowed characters {count} of {max}", "{count} unread comments" : "{count} unread comments", - "Comment" : "Comment" + "Comment" : "Comment", + "Comments for files" : "Comments for files" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/en_GB.json b/apps/comments/l10n/en_GB.json index c43c1f4a6298d..9766fa43ae647 100644 --- a/apps/comments/l10n/en_GB.json +++ b/apps/comments/l10n/en_GB.json @@ -14,6 +14,7 @@ "Save" : "Save", "Allowed characters {count} of {max}" : "Allowed characters {count} of {max}", "{count} unread comments" : "{count} unread comments", - "Comment" : "Comment" + "Comment" : "Comment", + "Comments for files" : "Comments for files" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/eo.js b/apps/comments/l10n/eo.js index 515156d663bc9..3f53f5fd447ba 100644 --- a/apps/comments/l10n/eo.js +++ b/apps/comments/l10n/eo.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Konservi", "Allowed characters {count} of {max}" : "Permesataj karakteroj: {count} el {max}", "{count} unread comments" : "{count} nelegitaj komentoj", - "Comment" : "Komento" + "Comment" : "Komento", + "Comments for files" : "Komentoj por dosieroj" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/eo.json b/apps/comments/l10n/eo.json index 33b8109abb98f..3da6c92b549a1 100644 --- a/apps/comments/l10n/eo.json +++ b/apps/comments/l10n/eo.json @@ -14,6 +14,7 @@ "Save" : "Konservi", "Allowed characters {count} of {max}" : "Permesataj karakteroj: {count} el {max}", "{count} unread comments" : "{count} nelegitaj komentoj", - "Comment" : "Komento" + "Comment" : "Komento", + "Comments for files" : "Komentoj por dosieroj" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/es.js b/apps/comments/l10n/es.js index 23716ca57570c..50418b271a55c 100644 --- a/apps/comments/l10n/es.js +++ b/apps/comments/l10n/es.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Guardar", "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}", "{count} unread comments" : "{count} comentarios no leídos", - "Comment" : "Comentario" + "Comment" : "Comentario", + "Comments for files" : "Comentarios en archivos" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/es.json b/apps/comments/l10n/es.json index cc3e178129957..a6c5d7696a6f8 100644 --- a/apps/comments/l10n/es.json +++ b/apps/comments/l10n/es.json @@ -14,6 +14,7 @@ "Save" : "Guardar", "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}", "{count} unread comments" : "{count} comentarios no leídos", - "Comment" : "Comentario" + "Comment" : "Comentario", + "Comments for files" : "Comentarios en archivos" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/fi_FI.js b/apps/comments/l10n/fi_FI.js index e94f9ab21918a..ecb102fc082df 100644 --- a/apps/comments/l10n/fi_FI.js +++ b/apps/comments/l10n/fi_FI.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Tallenna", "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", "{count} unread comments" : "{count} lukematonta kommenttia", - "Comment" : "Kommentti" + "Comment" : "Kommentti", + "Comments for files" : "Kommentit tiedostoille" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/fi_FI.json b/apps/comments/l10n/fi_FI.json index 513a9ce75ddcd..975c1906fb033 100644 --- a/apps/comments/l10n/fi_FI.json +++ b/apps/comments/l10n/fi_FI.json @@ -14,6 +14,7 @@ "Save" : "Tallenna", "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", "{count} unread comments" : "{count} lukematonta kommenttia", - "Comment" : "Kommentti" + "Comment" : "Kommentti", + "Comments for files" : "Kommentit tiedostoille" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/fr.js b/apps/comments/l10n/fr.js index 514ba843f3e55..755ec083c7d61 100644 --- a/apps/comments/l10n/fr.js +++ b/apps/comments/l10n/fr.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Enregistrer", "Allowed characters {count} of {max}" : "{count} sur {max} caractères autorisés", "{count} unread comments" : "{count} commentaires non lus", - "Comment" : "Commenter" + "Comment" : "Commenter", + "Comments for files" : "Commentaires pour les fichiers" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/comments/l10n/fr.json b/apps/comments/l10n/fr.json index ace5e14a14ccb..1527fe4c2370f 100644 --- a/apps/comments/l10n/fr.json +++ b/apps/comments/l10n/fr.json @@ -14,6 +14,7 @@ "Save" : "Enregistrer", "Allowed characters {count} of {max}" : "{count} sur {max} caractères autorisés", "{count} unread comments" : "{count} commentaires non lus", - "Comment" : "Commenter" + "Comment" : "Commenter", + "Comments for files" : "Commentaires pour les fichiers" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/he.js b/apps/comments/l10n/he.js index 641d13861a79b..2a2bc3b5e37b7 100644 --- a/apps/comments/l10n/he.js +++ b/apps/comments/l10n/he.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "שמירה", "Allowed characters {count} of {max}" : "תווים מותרים {count} מתוך {max}", "{count} unread comments" : "{count} תגובות שלא נקראו", - "Comment" : "תגובה" + "Comment" : "תגובה", + "Comments for files" : "תגובות לקבצים" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/he.json b/apps/comments/l10n/he.json index dc10680e96a29..864edb512e55a 100644 --- a/apps/comments/l10n/he.json +++ b/apps/comments/l10n/he.json @@ -14,6 +14,7 @@ "Save" : "שמירה", "Allowed characters {count} of {max}" : "תווים מותרים {count} מתוך {max}", "{count} unread comments" : "{count} תגובות שלא נקראו", - "Comment" : "תגובה" + "Comment" : "תגובה", + "Comments for files" : "תגובות לקבצים" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/hu_HU.js b/apps/comments/l10n/hu_HU.js index c74b27f34cdeb..67937a36d6c9b 100644 --- a/apps/comments/l10n/hu_HU.js +++ b/apps/comments/l10n/hu_HU.js @@ -3,6 +3,11 @@ OC.L10N.register( { "Cancel" : "Mégsem", "Save" : "Mentés", - "Comment" : "Komment" + "Comment" : "Komment", + "Comments for files" : "Hozzászólások a fájlokhoz", + "Delete comment" : "Hozzászólás törlése", + "Edit comment" : "Hozzászólás szerkesztése", + "No other comments available" : "Nincs több hozzászólás.", + "Post" : "Küldés" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/hu_HU.json b/apps/comments/l10n/hu_HU.json index 7c8d88868953b..d66d025e7b0a6 100644 --- a/apps/comments/l10n/hu_HU.json +++ b/apps/comments/l10n/hu_HU.json @@ -1,6 +1,11 @@ { "translations": { "Cancel" : "Mégsem", "Save" : "Mentés", - "Comment" : "Komment" + "Comment" : "Komment", + "Comments for files" : "Hozzászólások a fájlokhoz", + "Delete comment" : "Hozzászólás törlése", + "Edit comment" : "Hozzászólás szerkesztése", + "No other comments available" : "Nincs több hozzászólás.", + "Post" : "Küldés" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/id.js b/apps/comments/l10n/id.js index 28965c9e91e3e..fcd98091f9945 100644 --- a/apps/comments/l10n/id.js +++ b/apps/comments/l10n/id.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Simpan", "Allowed characters {count} of {max}" : "Karakter yang diizinkan {count} dari {max}", "{count} unread comments" : "{count} komentar belum dibaca", - "Comment" : "Komentar" + "Comment" : "Komentar", + "Comments for files" : "Komentar untuk berkas" }, "nplurals=1; plural=0;"); diff --git a/apps/comments/l10n/id.json b/apps/comments/l10n/id.json index f66594eca1626..3cb03ae761ba6 100644 --- a/apps/comments/l10n/id.json +++ b/apps/comments/l10n/id.json @@ -14,6 +14,7 @@ "Save" : "Simpan", "Allowed characters {count} of {max}" : "Karakter yang diizinkan {count} dari {max}", "{count} unread comments" : "{count} komentar belum dibaca", - "Comment" : "Komentar" + "Comment" : "Komentar", + "Comments for files" : "Komentar untuk berkas" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/comments/l10n/is.js b/apps/comments/l10n/is.js index 0da04289f5e14..b111cabb26ac4 100644 --- a/apps/comments/l10n/is.js +++ b/apps/comments/l10n/is.js @@ -3,6 +3,11 @@ OC.L10N.register( { "Cancel" : "Hætta við", "Save" : "Vista", - "Comment" : "Athugasemd" + "Comment" : "Athugasemd", + "Comments for files" : "Athugasemdir við skrár", + "Delete comment" : "Eyða athugasemd", + "Edit comment" : "Breyta athugasemd", + "No other comments available" : "Engar aðrar athugasemdir eru tiltækar", + "Post" : "Senda" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/comments/l10n/is.json b/apps/comments/l10n/is.json index c931274010575..319b1c92c8b5c 100644 --- a/apps/comments/l10n/is.json +++ b/apps/comments/l10n/is.json @@ -1,6 +1,11 @@ { "translations": { "Cancel" : "Hætta við", "Save" : "Vista", - "Comment" : "Athugasemd" + "Comment" : "Athugasemd", + "Comments for files" : "Athugasemdir við skrár", + "Delete comment" : "Eyða athugasemd", + "Edit comment" : "Breyta athugasemd", + "No other comments available" : "Engar aðrar athugasemdir eru tiltækar", + "Post" : "Senda" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/comments/l10n/it.js b/apps/comments/l10n/it.js index fcf739c55723d..854b471c8d069 100644 --- a/apps/comments/l10n/it.js +++ b/apps/comments/l10n/it.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Salva", "Allowed characters {count} of {max}" : "Caratteri consentiti {count} di {max}", "{count} unread comments" : "{count} commenti non letti", - "Comment" : "Commento" + "Comment" : "Commento", + "Comments for files" : "Commenti sui file" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/it.json b/apps/comments/l10n/it.json index a3cf02c91ef29..45f12510ebd95 100644 --- a/apps/comments/l10n/it.json +++ b/apps/comments/l10n/it.json @@ -14,6 +14,7 @@ "Save" : "Salva", "Allowed characters {count} of {max}" : "Caratteri consentiti {count} di {max}", "{count} unread comments" : "{count} commenti non letti", - "Comment" : "Commento" + "Comment" : "Commento", + "Comments for files" : "Commenti sui file" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/ja.js b/apps/comments/l10n/ja.js index ff20dcedbc6c2..03e04f1c15f76 100644 --- a/apps/comments/l10n/ja.js +++ b/apps/comments/l10n/ja.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "保存", "Allowed characters {count} of {max}" : "入力文字数 {count} / {max}", "{count} unread comments" : "未読コメント数 {count}", - "Comment" : "コメント" + "Comment" : "コメント", + "Comments for files" : "ファイルについてのコメント" }, "nplurals=1; plural=0;"); diff --git a/apps/comments/l10n/ja.json b/apps/comments/l10n/ja.json index 603d2e3d49bf2..02afe04bf23a3 100644 --- a/apps/comments/l10n/ja.json +++ b/apps/comments/l10n/ja.json @@ -14,6 +14,7 @@ "Save" : "保存", "Allowed characters {count} of {max}" : "入力文字数 {count} / {max}", "{count} unread comments" : "未読コメント数 {count}", - "Comment" : "コメント" + "Comment" : "コメント", + "Comments for files" : "ファイルについてのコメント" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/comments/l10n/ko.js b/apps/comments/l10n/ko.js index 3644ac7489d6a..62ba084f80e3c 100644 --- a/apps/comments/l10n/ko.js +++ b/apps/comments/l10n/ko.js @@ -3,6 +3,11 @@ OC.L10N.register( { "Cancel" : "취소", "Save" : "저장", - "Comment" : "설명" + "Comment" : "설명", + "Comments for files" : "파일에 댓글 남기기", + "Delete comment" : "댓글 삭제", + "Edit comment" : "댓글 편집", + "No other comments available" : "더 이상 댓글 없음", + "Post" : "게시" }, "nplurals=1; plural=0;"); diff --git a/apps/comments/l10n/ko.json b/apps/comments/l10n/ko.json index d6a4b49e5b9a1..da40d1c272d4c 100644 --- a/apps/comments/l10n/ko.json +++ b/apps/comments/l10n/ko.json @@ -1,6 +1,11 @@ { "translations": { "Cancel" : "취소", "Save" : "저장", - "Comment" : "설명" + "Comment" : "설명", + "Comments for files" : "파일에 댓글 남기기", + "Delete comment" : "댓글 삭제", + "Edit comment" : "댓글 편집", + "No other comments available" : "더 이상 댓글 없음", + "Post" : "게시" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/comments/l10n/nb_NO.js b/apps/comments/l10n/nb_NO.js index 5d3732da82730..4443520d31be9 100644 --- a/apps/comments/l10n/nb_NO.js +++ b/apps/comments/l10n/nb_NO.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Lagre", "Allowed characters {count} of {max}" : "Antall tegn tillatt {count} av {max}", "{count} unread comments" : "{count} uleste kommentarer", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentarer for filer" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/nb_NO.json b/apps/comments/l10n/nb_NO.json index 80724fff6deac..0e98d6fc54357 100644 --- a/apps/comments/l10n/nb_NO.json +++ b/apps/comments/l10n/nb_NO.json @@ -14,6 +14,7 @@ "Save" : "Lagre", "Allowed characters {count} of {max}" : "Antall tegn tillatt {count} av {max}", "{count} unread comments" : "{count} uleste kommentarer", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentarer for filer" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/nl.js b/apps/comments/l10n/nl.js index 5772952a29116..e50f47bbf9230 100644 --- a/apps/comments/l10n/nl.js +++ b/apps/comments/l10n/nl.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Bewaren", "Allowed characters {count} of {max}" : "{count} van de {max} toegestane tekens", "{count} unread comments" : "{count} ongelezen reacties", - "Comment" : "Reactie" + "Comment" : "Reactie", + "Comments for files" : "Reacties voor bestanden" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/nl.json b/apps/comments/l10n/nl.json index a8c92241a7772..9c3228cbc6ae1 100644 --- a/apps/comments/l10n/nl.json +++ b/apps/comments/l10n/nl.json @@ -14,6 +14,7 @@ "Save" : "Bewaren", "Allowed characters {count} of {max}" : "{count} van de {max} toegestane tekens", "{count} unread comments" : "{count} ongelezen reacties", - "Comment" : "Reactie" + "Comment" : "Reactie", + "Comments for files" : "Reacties voor bestanden" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/pl.js b/apps/comments/l10n/pl.js index 543fed7a1aded..69d8cbdbe7e37 100644 --- a/apps/comments/l10n/pl.js +++ b/apps/comments/l10n/pl.js @@ -3,6 +3,11 @@ OC.L10N.register( { "Cancel" : "Anuluj", "Save" : "Zapisz", - "Comment" : "Komentarz" + "Comment" : "Komentarz", + "Comments for files" : "Komentarze dla plików", + "Delete comment" : "Skasuj komentarz", + "Edit comment" : "Edytuj komentarz", + "No other comments available" : "Nie ma więcej komentarzy", + "Post" : "Zapisz" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/comments/l10n/pl.json b/apps/comments/l10n/pl.json index 836f3bb1dcd9d..eed87388068be 100644 --- a/apps/comments/l10n/pl.json +++ b/apps/comments/l10n/pl.json @@ -1,6 +1,11 @@ { "translations": { "Cancel" : "Anuluj", "Save" : "Zapisz", - "Comment" : "Komentarz" + "Comment" : "Komentarz", + "Comments for files" : "Komentarze dla plików", + "Delete comment" : "Skasuj komentarz", + "Edit comment" : "Edytuj komentarz", + "No other comments available" : "Nie ma więcej komentarzy", + "Post" : "Zapisz" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/comments/l10n/pt_BR.js b/apps/comments/l10n/pt_BR.js index d7f61e4f161a7..9305fd50ad1bd 100644 --- a/apps/comments/l10n/pt_BR.js +++ b/apps/comments/l10n/pt_BR.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Salvar", "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}", "{count} unread comments" : "{count} comentários não lidos", - "Comment" : "Comentário" + "Comment" : "Comentário", + "Comments for files" : "Comentários por arquivos" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/comments/l10n/pt_BR.json b/apps/comments/l10n/pt_BR.json index 728a7e458ce73..be27d20cb3a5c 100644 --- a/apps/comments/l10n/pt_BR.json +++ b/apps/comments/l10n/pt_BR.json @@ -14,6 +14,7 @@ "Save" : "Salvar", "Allowed characters {count} of {max}" : "Caracteres permitidos {count} de {max}", "{count} unread comments" : "{count} comentários não lidos", - "Comment" : "Comentário" + "Comment" : "Comentário", + "Comments for files" : "Comentários por arquivos" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/pt_PT.js b/apps/comments/l10n/pt_PT.js index 821afec0c50a1..233f8058436cd 100644 --- a/apps/comments/l10n/pt_PT.js +++ b/apps/comments/l10n/pt_PT.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Guardar", "Allowed characters {count} of {max}" : "{count} de {max} caracteres restantes", "{count} unread comments" : "{count} comentários não lidos", - "Comment" : "Comentário" + "Comment" : "Comentário", + "Comments for files" : "Comentários para ficheiros" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/pt_PT.json b/apps/comments/l10n/pt_PT.json index d5a5edc8c7e35..1b4c067487ad1 100644 --- a/apps/comments/l10n/pt_PT.json +++ b/apps/comments/l10n/pt_PT.json @@ -14,6 +14,7 @@ "Save" : "Guardar", "Allowed characters {count} of {max}" : "{count} de {max} caracteres restantes", "{count} unread comments" : "{count} comentários não lidos", - "Comment" : "Comentário" + "Comment" : "Comentário", + "Comments for files" : "Comentários para ficheiros" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/ru.js b/apps/comments/l10n/ru.js index 0c7c966d707e1..934b248f5d4ed 100644 --- a/apps/comments/l10n/ru.js +++ b/apps/comments/l10n/ru.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Сохранить", "Allowed characters {count} of {max}" : "Допустимых символов {count} из {max}", "{count} unread comments" : "{count} непрочитанных комментариев", - "Comment" : "Коментарий" + "Comment" : "Коментарий", + "Comments for files" : "Комментарии к файлам" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/comments/l10n/ru.json b/apps/comments/l10n/ru.json index e6e352c191664..298c92935e3b1 100644 --- a/apps/comments/l10n/ru.json +++ b/apps/comments/l10n/ru.json @@ -14,6 +14,7 @@ "Save" : "Сохранить", "Allowed characters {count} of {max}" : "Допустимых символов {count} из {max}", "{count} unread comments" : "{count} непрочитанных комментариев", - "Comment" : "Коментарий" + "Comment" : "Коментарий", + "Comments for files" : "Комментарии к файлам" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/comments/l10n/sl.js b/apps/comments/l10n/sl.js index 331382f4f5b96..6b753db44b076 100644 --- a/apps/comments/l10n/sl.js +++ b/apps/comments/l10n/sl.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Shrani", "Allowed characters {count} of {max}" : "Dovoljeni znaki: {count} od {max}", "{count} unread comments" : "{count} neprebranih opomb", - "Comment" : "Opomba" + "Comment" : "Opomba", + "Comments for files" : "Opombe datotek" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/comments/l10n/sl.json b/apps/comments/l10n/sl.json index 54f77cfe571ec..3d9e00b2e81a7 100644 --- a/apps/comments/l10n/sl.json +++ b/apps/comments/l10n/sl.json @@ -14,6 +14,7 @@ "Save" : "Shrani", "Allowed characters {count} of {max}" : "Dovoljeni znaki: {count} od {max}", "{count} unread comments" : "{count} neprebranih opomb", - "Comment" : "Opomba" + "Comment" : "Opomba", + "Comments for files" : "Opombe datotek" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/comments/l10n/sq.js b/apps/comments/l10n/sq.js index cf18a031b0ed4..1f38a103d3f41 100644 --- a/apps/comments/l10n/sq.js +++ b/apps/comments/l10n/sq.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Ruaje", "Allowed characters {count} of {max}" : "Shenja të lejuara {count} nga {max}", "{count} unread comments" : "{count} komente të palexuar", - "Comment" : "Koment" + "Comment" : "Koment", + "Comments for files" : "Komente për kartela" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/sq.json b/apps/comments/l10n/sq.json index aa92903ab6088..4da2b3a0cf98e 100644 --- a/apps/comments/l10n/sq.json +++ b/apps/comments/l10n/sq.json @@ -14,6 +14,7 @@ "Save" : "Ruaje", "Allowed characters {count} of {max}" : "Shenja të lejuara {count} nga {max}", "{count} unread comments" : "{count} komente të palexuar", - "Comment" : "Koment" + "Comment" : "Koment", + "Comments for files" : "Komente për kartela" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/sr.js b/apps/comments/l10n/sr.js index caee7bc28ffa9..767b2d0778a17 100644 --- a/apps/comments/l10n/sr.js +++ b/apps/comments/l10n/sr.js @@ -3,6 +3,11 @@ OC.L10N.register( { "Cancel" : "Одустани", "Save" : "Сачувај", - "Comment" : "Коментар" + "Comment" : "Коментар", + "Comments for files" : "Коментари фајлова", + "Delete comment" : "Обриши коментар", + "Edit comment" : "Уреди коментар", + "No other comments available" : "Нема других коментара", + "Post" : "Објави" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/comments/l10n/sr.json b/apps/comments/l10n/sr.json index 7fa9bdcf27ad5..92e5ee90c0fe4 100644 --- a/apps/comments/l10n/sr.json +++ b/apps/comments/l10n/sr.json @@ -1,6 +1,11 @@ { "translations": { "Cancel" : "Одустани", "Save" : "Сачувај", - "Comment" : "Коментар" + "Comment" : "Коментар", + "Comments for files" : "Коментари фајлова", + "Delete comment" : "Обриши коментар", + "Edit comment" : "Уреди коментар", + "No other comments available" : "Нема других коментара", + "Post" : "Објави" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/comments/l10n/sv.js b/apps/comments/l10n/sv.js index db3cfe589aeae..9b975e17fddfa 100644 --- a/apps/comments/l10n/sv.js +++ b/apps/comments/l10n/sv.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Spara", "Allowed characters {count} of {max}" : "Tillåtet antal tecken {count} av {max}", "{count} unread comments" : "{count} olästa kommentarer", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentarer till filer" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/sv.json b/apps/comments/l10n/sv.json index 7547cfe69e263..7eea2b42b5604 100644 --- a/apps/comments/l10n/sv.json +++ b/apps/comments/l10n/sv.json @@ -14,6 +14,7 @@ "Save" : "Spara", "Allowed characters {count} of {max}" : "Tillåtet antal tecken {count} av {max}", "{count} unread comments" : "{count} olästa kommentarer", - "Comment" : "Kommentar" + "Comment" : "Kommentar", + "Comments for files" : "Kommentarer till filer" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/th_TH.js b/apps/comments/l10n/th_TH.js index ba0e9aa812cef..8a13b960bf702 100644 --- a/apps/comments/l10n/th_TH.js +++ b/apps/comments/l10n/th_TH.js @@ -12,6 +12,7 @@ OC.L10N.register( "Edit comment" : "แก้ไขความคิดเห็น", "[Deleted user]" : "[ผู้ใช้ถูกลบไปแล้ว]", "Save" : "บันทึก", - "Comment" : "แสดงความคิดเห็น" + "Comment" : "แสดงความคิดเห็น", + "Comments for files" : "แสดงความคิดเห็น สำหรับไฟล์" }, "nplurals=1; plural=0;"); diff --git a/apps/comments/l10n/th_TH.json b/apps/comments/l10n/th_TH.json index 02ce39195c750..e49a099c183d3 100644 --- a/apps/comments/l10n/th_TH.json +++ b/apps/comments/l10n/th_TH.json @@ -10,6 +10,7 @@ "Edit comment" : "แก้ไขความคิดเห็น", "[Deleted user]" : "[ผู้ใช้ถูกลบไปแล้ว]", "Save" : "บันทึก", - "Comment" : "แสดงความคิดเห็น" + "Comment" : "แสดงความคิดเห็น", + "Comments for files" : "แสดงความคิดเห็น สำหรับไฟล์" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/comments/l10n/tr.js b/apps/comments/l10n/tr.js index d098f212de65c..4a7c1876698c0 100644 --- a/apps/comments/l10n/tr.js +++ b/apps/comments/l10n/tr.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Kaydet", "Allowed characters {count} of {max}" : "İzin verilen karakterler {count} {max}", "{count} unread comments" : "{count} okunmamış yorumlar", - "Comment" : "Yorum" + "Comment" : "Yorum", + "Comments for files" : "Dosyalar için Yorumlar" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/comments/l10n/tr.json b/apps/comments/l10n/tr.json index 8b644c82ee1da..59e299052cac7 100644 --- a/apps/comments/l10n/tr.json +++ b/apps/comments/l10n/tr.json @@ -14,6 +14,7 @@ "Save" : "Kaydet", "Allowed characters {count} of {max}" : "İzin verilen karakterler {count} {max}", "{count} unread comments" : "{count} okunmamış yorumlar", - "Comment" : "Yorum" + "Comment" : "Yorum", + "Comments for files" : "Dosyalar için Yorumlar" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/comments/l10n/uk.js b/apps/comments/l10n/uk.js index a7e1cbad9588d..cf96584c4f2b7 100644 --- a/apps/comments/l10n/uk.js +++ b/apps/comments/l10n/uk.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "Зберегти", "Allowed characters {count} of {max}" : "Доступно символів {count} з {max}", "{count} unread comments" : "{count} непрочитаних коментарів", - "Comment" : "Коментар" + "Comment" : "Коментар", + "Comments for files" : "Коментарі до файлів" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/comments/l10n/uk.json b/apps/comments/l10n/uk.json index ff3f3b7dc645c..6c15d2474ad4d 100644 --- a/apps/comments/l10n/uk.json +++ b/apps/comments/l10n/uk.json @@ -14,6 +14,7 @@ "Save" : "Зберегти", "Allowed characters {count} of {max}" : "Доступно символів {count} з {max}", "{count} unread comments" : "{count} непрочитаних коментарів", - "Comment" : "Коментар" + "Comment" : "Коментар", + "Comments for files" : "Коментарі до файлів" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/comments/l10n/zh_CN.js b/apps/comments/l10n/zh_CN.js index edfd32a9926a8..31e0a43e0cd2a 100644 --- a/apps/comments/l10n/zh_CN.js +++ b/apps/comments/l10n/zh_CN.js @@ -16,6 +16,7 @@ OC.L10N.register( "Save" : "保存", "Allowed characters {count} of {max}" : "当前字数: {count},最大允许:{max}", "{count} unread comments" : "{count} 条未读评论", - "Comment" : "评论" + "Comment" : "评论", + "Comments for files" : "评论文件" }, "nplurals=1; plural=0;"); diff --git a/apps/comments/l10n/zh_CN.json b/apps/comments/l10n/zh_CN.json index 0eaefb409b14e..21288ed5e7bd7 100644 --- a/apps/comments/l10n/zh_CN.json +++ b/apps/comments/l10n/zh_CN.json @@ -14,6 +14,7 @@ "Save" : "保存", "Allowed characters {count} of {max}" : "当前字数: {count},最大允许:{max}", "{count} unread comments" : "{count} 条未读评论", - "Comment" : "评论" + "Comment" : "评论", + "Comments for files" : "评论文件" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/encryption/l10n/de_DE.js b/apps/encryption/l10n/de_DE.js index 3b87ed3beb1a3..71e3560725eb6 100644 --- a/apps/encryption/l10n/de_DE.js +++ b/apps/encryption/l10n/de_DE.js @@ -51,6 +51,7 @@ OC.L10N.register( "Enable password recovery:" : "Die Passwort-Wiederherstellung aktivieren:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Durch die Aktivierung dieser Option haben Sie die Möglichkeit, wieder auf Ihre verschlüsselten Dateien zugreifen zu können, wenn Sie Ihr Passwort verloren haben.", "Enabled" : "Aktiviert", - "Disabled" : "Deaktiviert" + "Disabled" : "Deaktiviert", + "one-time password for server-side-encryption" : "Einmalpasswort für Serverseitige Verschlüsselung" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/encryption/l10n/de_DE.json b/apps/encryption/l10n/de_DE.json index 6d247b09bc9da..86b6a89ac0e8c 100644 --- a/apps/encryption/l10n/de_DE.json +++ b/apps/encryption/l10n/de_DE.json @@ -49,6 +49,7 @@ "Enable password recovery:" : "Die Passwort-Wiederherstellung aktivieren:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Durch die Aktivierung dieser Option haben Sie die Möglichkeit, wieder auf Ihre verschlüsselten Dateien zugreifen zu können, wenn Sie Ihr Passwort verloren haben.", "Enabled" : "Aktiviert", - "Disabled" : "Deaktiviert" + "Disabled" : "Deaktiviert", + "one-time password for server-side-encryption" : "Einmalpasswort für Serverseitige Verschlüsselung" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/encryption/l10n/ko.js b/apps/encryption/l10n/ko.js index caaed72544054..901f30e2ca331 100644 --- a/apps/encryption/l10n/ko.js +++ b/apps/encryption/l10n/ko.js @@ -54,6 +54,8 @@ OC.L10N.register( "Enable password recovery:" : "암호 복구 사용:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "이 옵션을 사용하면 암호를 잊었을 때 암호화된 파일에 다시 접근할 수 있습니다", "Enabled" : "활성화", - "Disabled" : "비활성화" + "Disabled" : "비활성화", + "Bad Signature" : "잘못된 서명", + "Missing Signature" : "서명 없음" }, "nplurals=1; plural=0;"); diff --git a/apps/encryption/l10n/ko.json b/apps/encryption/l10n/ko.json index c8e4779b29c37..e95d62bba3fc3 100644 --- a/apps/encryption/l10n/ko.json +++ b/apps/encryption/l10n/ko.json @@ -52,6 +52,8 @@ "Enable password recovery:" : "암호 복구 사용:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "이 옵션을 사용하면 암호를 잊었을 때 암호화된 파일에 다시 접근할 수 있습니다", "Enabled" : "활성화", - "Disabled" : "비활성화" + "Disabled" : "비활성화", + "Bad Signature" : "잘못된 서명", + "Missing Signature" : "서명 없음" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/encryption/l10n/pl.js b/apps/encryption/l10n/pl.js index fda41f571474f..a47fcc2f701a0 100644 --- a/apps/encryption/l10n/pl.js +++ b/apps/encryption/l10n/pl.js @@ -34,6 +34,15 @@ OC.L10N.register( "Enable password recovery:" : "Włącz hasło odzyskiwania:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Włączenie tej opcji umożliwia otrzymać dostęp do zaszyfrowanych plików w przypadku utraty hasła", "Enabled" : "Włączone", - "Disabled" : "Wyłączone" + "Disabled" : "Wyłączone", + "Could not enable the recovery key, please try again or contact your administrator" : "Nie można włączyć klucza odzyskiwania. Proszę spróbować ponownie lub skontakuj sie z administratorem", + "Encryption App is enabled and ready" : "Aplikacja szyfrowania jest włączona i gotowa do pracy", + "Missing parameters" : "Brakujące dane", + "New recovery key password" : "Nowe hasło klucza odzyskiwania", + "Old recovery key password" : "Stare hasło klucza odzyskiwania", + "Recovery Key disabled" : "Klucz odzyskiwania wyłączony", + "Recovery Key enabled" : "Klucz odzyskiwania włączony", + "Repeat new recovery key password" : "Powtórz nowe hasło klucza odzyskiwania", + "Repeat recovery key password" : "Powtórz hasło klucza odzyskiwania" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/encryption/l10n/pl.json b/apps/encryption/l10n/pl.json index 7de8c5ad595e7..0758f300bcf70 100644 --- a/apps/encryption/l10n/pl.json +++ b/apps/encryption/l10n/pl.json @@ -32,6 +32,15 @@ "Enable password recovery:" : "Włącz hasło odzyskiwania:", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Włączenie tej opcji umożliwia otrzymać dostęp do zaszyfrowanych plików w przypadku utraty hasła", "Enabled" : "Włączone", - "Disabled" : "Wyłączone" + "Disabled" : "Wyłączone", + "Could not enable the recovery key, please try again or contact your administrator" : "Nie można włączyć klucza odzyskiwania. Proszę spróbować ponownie lub skontakuj sie z administratorem", + "Encryption App is enabled and ready" : "Aplikacja szyfrowania jest włączona i gotowa do pracy", + "Missing parameters" : "Brakujące dane", + "New recovery key password" : "Nowe hasło klucza odzyskiwania", + "Old recovery key password" : "Stare hasło klucza odzyskiwania", + "Recovery Key disabled" : "Klucz odzyskiwania wyłączony", + "Recovery Key enabled" : "Klucz odzyskiwania włączony", + "Repeat new recovery key password" : "Powtórz nowe hasło klucza odzyskiwania", + "Repeat recovery key password" : "Powtórz hasło klucza odzyskiwania" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/federatedfilesharing/l10n/gl.js b/apps/federatedfilesharing/l10n/gl.js index 86bf332fffcc4..a69c0a47c3108 100644 --- a/apps/federatedfilesharing/l10n/gl.js +++ b/apps/federatedfilesharing/l10n/gl.js @@ -3,6 +3,7 @@ OC.L10N.register( { "Invalid Federated Cloud ID" : "ID de nube federada incorrecto", "Sharing %s failed, because this item is already shared with %s" : "Fallou a compartición de %s, este elemento xa está compartido con %s", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Fallou a compartición de %s, non foi posíbel atopar %s,é probábel que o servidor non estea accesíbel." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Fallou a compartición de %s, non foi posíbel atopar %s,é probábel que o servidor non estea accesíbel.", + "Not allowed to create a federated share with the same user" : "Non está permitido crear unha compartición federada co mesmo usuario" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federatedfilesharing/l10n/gl.json b/apps/federatedfilesharing/l10n/gl.json index 6ca669901fc00..80ee9e50fa3d8 100644 --- a/apps/federatedfilesharing/l10n/gl.json +++ b/apps/federatedfilesharing/l10n/gl.json @@ -1,6 +1,7 @@ { "translations": { "Invalid Federated Cloud ID" : "ID de nube federada incorrecto", "Sharing %s failed, because this item is already shared with %s" : "Fallou a compartición de %s, este elemento xa está compartido con %s", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Fallou a compartición de %s, non foi posíbel atopar %s,é probábel que o servidor non estea accesíbel." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Fallou a compartición de %s, non foi posíbel atopar %s,é probábel que o servidor non estea accesíbel.", + "Not allowed to create a federated share with the same user" : "Non está permitido crear unha compartición federada co mesmo usuario" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federatedfilesharing/l10n/hu_HU.js b/apps/federatedfilesharing/l10n/hu_HU.js index 7d64fe0c3b75d..e5fa738384b79 100644 --- a/apps/federatedfilesharing/l10n/hu_HU.js +++ b/apps/federatedfilesharing/l10n/hu_HU.js @@ -3,6 +3,7 @@ OC.L10N.register( { "Invalid Federated Cloud ID" : "Érvénytelen Egyesített Felhő Azonosító", "Sharing %s failed, because this item is already shared with %s" : "%s megosztása nem sikerült, mert ez már meg van osztva %s-vel", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található, talán a szerver jelenleg nem elérhető." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található, talán a szerver jelenleg nem elérhető.", + "Not allowed to create a federated share with the same user" : "Azonos felhasználóval nem lehet létrehozni egyesített megosztást" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federatedfilesharing/l10n/hu_HU.json b/apps/federatedfilesharing/l10n/hu_HU.json index 3e24578c77f1d..58191354b9bdc 100644 --- a/apps/federatedfilesharing/l10n/hu_HU.json +++ b/apps/federatedfilesharing/l10n/hu_HU.json @@ -1,6 +1,7 @@ { "translations": { "Invalid Federated Cloud ID" : "Érvénytelen Egyesített Felhő Azonosító", "Sharing %s failed, because this item is already shared with %s" : "%s megosztása nem sikerült, mert ez már meg van osztva %s-vel", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található, talán a szerver jelenleg nem elérhető." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található, talán a szerver jelenleg nem elérhető.", + "Not allowed to create a federated share with the same user" : "Azonos felhasználóval nem lehet létrehozni egyesített megosztást" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federatedfilesharing/l10n/ko.js b/apps/federatedfilesharing/l10n/ko.js index 33bf8c550652a..0677d68dd73a8 100644 --- a/apps/federatedfilesharing/l10n/ko.js +++ b/apps/federatedfilesharing/l10n/ko.js @@ -3,6 +3,7 @@ OC.L10N.register( { "Invalid Federated Cloud ID" : "잘못된 연합 클라우드 ID", "Sharing %s failed, because this item is already shared with %s" : "%s을(를) 공유할 수 없습니다. 이미 %s 님과 공유되어 있습니다", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s을(를) 공유할 수 없습니다. %s을(를) 찾을 수 없습니다. 서버에 접근하지 못할 수도 있습니다." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s을(를) 공유할 수 없습니다. %s을(를) 찾을 수 없습니다. 서버에 접근하지 못할 수도 있습니다.", + "Not allowed to create a federated share with the same user" : "같은 사용자와 연합 공유를 만들 수 없음" }, "nplurals=1; plural=0;"); diff --git a/apps/federatedfilesharing/l10n/ko.json b/apps/federatedfilesharing/l10n/ko.json index e3f1bf5f674da..c100a2cba051f 100644 --- a/apps/federatedfilesharing/l10n/ko.json +++ b/apps/federatedfilesharing/l10n/ko.json @@ -1,6 +1,7 @@ { "translations": { "Invalid Federated Cloud ID" : "잘못된 연합 클라우드 ID", "Sharing %s failed, because this item is already shared with %s" : "%s을(를) 공유할 수 없습니다. 이미 %s 님과 공유되어 있습니다", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s을(를) 공유할 수 없습니다. %s을(를) 찾을 수 없습니다. 서버에 접근하지 못할 수도 있습니다." + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s을(를) 공유할 수 없습니다. %s을(를) 찾을 수 없습니다. 서버에 접근하지 못할 수도 있습니다.", + "Not allowed to create a federated share with the same user" : "같은 사용자와 연합 공유를 만들 수 없음" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/federation/l10n/cs_CZ.js b/apps/federation/l10n/cs_CZ.js index 487989cca3a62..6fa3bfeb1a758 100644 --- a/apps/federation/l10n/cs_CZ.js +++ b/apps/federation/l10n/cs_CZ.js @@ -5,6 +5,9 @@ OC.L10N.register( "Server is already in the list of trusted servers." : "Server je již přidán na seznam důvěryhodných serverů.", "No ownCloud server found" : "Nenalezen žádný ownCloud server", "Could not add server" : "Nepodařilo se přidat server", - "Federation" : "Sdružování" + "Federation" : "Sdružování", + "Add server automatically once a federated share was created successfully" : "Přidat server automaticky jakmile je úspěšně vytvořeno sdružené sdílení", + "ownCloud Server" : "ownCloud server", + "Trusted ownCloud Servers" : "Důvěryhodné ownCloud servery" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/federation/l10n/cs_CZ.json b/apps/federation/l10n/cs_CZ.json index e87c8f8e1f61e..0097bccc41c76 100644 --- a/apps/federation/l10n/cs_CZ.json +++ b/apps/federation/l10n/cs_CZ.json @@ -3,6 +3,9 @@ "Server is already in the list of trusted servers." : "Server je již přidán na seznam důvěryhodných serverů.", "No ownCloud server found" : "Nenalezen žádný ownCloud server", "Could not add server" : "Nepodařilo se přidat server", - "Federation" : "Sdružování" + "Federation" : "Sdružování", + "Add server automatically once a federated share was created successfully" : "Přidat server automaticky jakmile je úspěšně vytvořeno sdružené sdílení", + "ownCloud Server" : "ownCloud server", + "Trusted ownCloud Servers" : "Důvěryhodné ownCloud servery" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/federation/l10n/de.js b/apps/federation/l10n/de.js index e836ed04d2954..42fbfe320c630 100644 --- a/apps/federation/l10n/de.js +++ b/apps/federation/l10n/de.js @@ -6,6 +6,8 @@ OC.L10N.register( "No ownCloud server found" : "Es wurde kein ownCloud Server gefunden", "Could not add server" : "Konnte Server nicht hinzufügen", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es dir dich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es dir dich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet.", + "Add server automatically once a federated share was created successfully" : "Füge einen mit ownCloud Federation verbundenen Server automatisch hinzu, sobald die Verbindung einmal erfolgreich erstellt wurde", + "Trusted ownCloud Servers" : "vertrauenswürdige ownCloud Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/de.json b/apps/federation/l10n/de.json index 9585cdd87dbdd..9774c6490dcd3 100644 --- a/apps/federation/l10n/de.json +++ b/apps/federation/l10n/de.json @@ -4,6 +4,8 @@ "No ownCloud server found" : "Es wurde kein ownCloud Server gefunden", "Could not add server" : "Konnte Server nicht hinzufügen", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es dir dich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es dir dich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet.", + "Add server automatically once a federated share was created successfully" : "Füge einen mit ownCloud Federation verbundenen Server automatisch hinzu, sobald die Verbindung einmal erfolgreich erstellt wurde", + "Trusted ownCloud Servers" : "vertrauenswürdige ownCloud Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/de_DE.js b/apps/federation/l10n/de_DE.js index f590b47b8bf53..fa5d59a2c9b2b 100644 --- a/apps/federation/l10n/de_DE.js +++ b/apps/federation/l10n/de_DE.js @@ -6,6 +6,8 @@ OC.L10N.register( "No ownCloud server found" : "Es wurde kein ownCloud Server gefunden", "Could not add server" : "Konnte Server nicht hinzufügen", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es Ihnen sich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es Ihnen sich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet.", + "Add server automatically once a federated share was created successfully" : "Server automatisch hinzufügen sobale eine federated Freigabe erstellt wurde", + "Trusted ownCloud Servers" : "Vertrauenswürdige ownCloud Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/de_DE.json b/apps/federation/l10n/de_DE.json index e46dc186f1bb4..b44849c2a2f7e 100644 --- a/apps/federation/l10n/de_DE.json +++ b/apps/federation/l10n/de_DE.json @@ -4,6 +4,8 @@ "No ownCloud server found" : "Es wurde kein ownCloud Server gefunden", "Could not add server" : "Konnte Server nicht hinzufügen", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es Ihnen sich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation ermöglicht es Ihnen sich mit anderen vertrauenswürdigen Servern zu verbinden um das Benutzerverzeichnis auszutauschen. Dies wird, zum Beispiel, für die automatische Vervollständigung externer Benutzer verwendet.", + "Add server automatically once a federated share was created successfully" : "Server automatisch hinzufügen sobale eine federated Freigabe erstellt wurde", + "Trusted ownCloud Servers" : "Vertrauenswürdige ownCloud Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/en_GB.js b/apps/federation/l10n/en_GB.js index 348f84a796470..392d4fb4ef1b3 100644 --- a/apps/federation/l10n/en_GB.js +++ b/apps/federation/l10n/en_GB.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "No ownCloud server found", "Could not add server" : "Could not add server", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing.", + "Add server automatically once a federated share was created successfully" : "Add server automatically once a federated share was created successfully", + "ownCloud Server" : "ownCloud Server", + "Trusted ownCloud Servers" : "Trusted ownCloud Servers" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/en_GB.json b/apps/federation/l10n/en_GB.json index 435658922f95d..041f026a26a0b 100644 --- a/apps/federation/l10n/en_GB.json +++ b/apps/federation/l10n/en_GB.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "No ownCloud server found", "Could not add server" : "Could not add server", "Federation" : "Federation", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing.", + "Add server automatically once a federated share was created successfully" : "Add server automatically once a federated share was created successfully", + "ownCloud Server" : "ownCloud Server", + "Trusted ownCloud Servers" : "Trusted ownCloud Servers" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/es.js b/apps/federation/l10n/es.js index fb899bb0fc207..af85f8ce818ae 100644 --- a/apps/federation/l10n/es.js +++ b/apps/federation/l10n/es.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "No se ha encontrado el servidor ownCloud", "Could not add server" : "No se pudo agregar el servidor", "Federation" : "Federación", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Federación de ownCloud permite conectar con otros ownClouds en los que se confíe para intercambiar el directorio de usuario. Por ejemplo esto se usará para autocompletar usuarios externos para compartición federada." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Federación de ownCloud permite conectar con otros ownClouds en los que se confíe para intercambiar el directorio de usuario. Por ejemplo esto se usará para autocompletar usuarios externos para compartición federada.", + "Add server automatically once a federated share was created successfully" : "Añadir el servidor automáticamente una vez que un compartido federado se haya creado exitosamente", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores onwCloud en los que confío" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/es.json b/apps/federation/l10n/es.json index f4797b10ee418..7bf94ad13fab5 100644 --- a/apps/federation/l10n/es.json +++ b/apps/federation/l10n/es.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "No se ha encontrado el servidor ownCloud", "Could not add server" : "No se pudo agregar el servidor", "Federation" : "Federación", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Federación de ownCloud permite conectar con otros ownClouds en los que se confíe para intercambiar el directorio de usuario. Por ejemplo esto se usará para autocompletar usuarios externos para compartición federada." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Federación de ownCloud permite conectar con otros ownClouds en los que se confíe para intercambiar el directorio de usuario. Por ejemplo esto se usará para autocompletar usuarios externos para compartición federada.", + "Add server automatically once a federated share was created successfully" : "Añadir el servidor automáticamente una vez que un compartido federado se haya creado exitosamente", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores onwCloud en los que confío" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/fi_FI.js b/apps/federation/l10n/fi_FI.js index b9f813e993dc1..e0e8ad54df2ed 100644 --- a/apps/federation/l10n/fi_FI.js +++ b/apps/federation/l10n/fi_FI.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "ownCloud-palvelinta ei löydy", "Could not add server" : "Palvelimen lisääminen ei onnistunut", "Federation" : "Federaatio", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloudin federaatio mahdollistaa yhdistämisen muihin luotettuihin ownCloudeihin käyttäjähakemistojen vaihtamiseksi. Tätä käytetään muun muassa ulkoisten käyttäjien automaattiseen täydentämiseen federoidussa jakamisessa." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloudin federaatio mahdollistaa yhdistämisen muihin luotettuihin ownCloudeihin käyttäjähakemistojen vaihtamiseksi. Tätä käytetään muun muassa ulkoisten käyttäjien automaattiseen täydentämiseen federoidussa jakamisessa.", + "Add server automatically once a federated share was created successfully" : "Lisää palvelin automaattisesti, kun federoitu jako on luotu onnistuneesti", + "ownCloud Server" : "ownCloud-palvelin", + "Trusted ownCloud Servers" : "Luotetut ownCloud-palvelimet" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/fi_FI.json b/apps/federation/l10n/fi_FI.json index 0c8280ab0beb3..a1356c2d1288e 100644 --- a/apps/federation/l10n/fi_FI.json +++ b/apps/federation/l10n/fi_FI.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "ownCloud-palvelinta ei löydy", "Could not add server" : "Palvelimen lisääminen ei onnistunut", "Federation" : "Federaatio", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloudin federaatio mahdollistaa yhdistämisen muihin luotettuihin ownCloudeihin käyttäjähakemistojen vaihtamiseksi. Tätä käytetään muun muassa ulkoisten käyttäjien automaattiseen täydentämiseen federoidussa jakamisessa." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloudin federaatio mahdollistaa yhdistämisen muihin luotettuihin ownCloudeihin käyttäjähakemistojen vaihtamiseksi. Tätä käytetään muun muassa ulkoisten käyttäjien automaattiseen täydentämiseen federoidussa jakamisessa.", + "Add server automatically once a federated share was created successfully" : "Lisää palvelin automaattisesti, kun federoitu jako on luotu onnistuneesti", + "ownCloud Server" : "ownCloud-palvelin", + "Trusted ownCloud Servers" : "Luotetut ownCloud-palvelimet" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/fr.js b/apps/federation/l10n/fr.js index a6e4fbda16fd0..a017e77d6e32e 100644 --- a/apps/federation/l10n/fr.js +++ b/apps/federation/l10n/fr.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Aucun serveur ownCloud trouvé", "Could not add server" : "Impossible d'ajouter le serveur", "Federation" : "Fédération", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Fédération ownCloud vous permet de vous connecter avec d'autres ownCloud de confiance pour partager l'annuaire d'utilisateurs. Par exemple, cela peut être utilisé pour compléter automatiquement les noms des utilisateurs externes pour le partage fédéré." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Fédération ownCloud vous permet de vous connecter avec d'autres ownCloud de confiance pour partager l'annuaire d'utilisateurs. Par exemple, cela peut être utilisé pour compléter automatiquement les noms des utilisateurs externes pour le partage fédéré.", + "Add server automatically once a federated share was created successfully" : "Ajouter un serveur automatiquement une fois que le partage a été créer avec succès .", + "ownCloud Server" : "Serveur OwnCloud", + "Trusted ownCloud Servers" : "Serveur ownCloud de confiance " }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/federation/l10n/fr.json b/apps/federation/l10n/fr.json index c84cb78dbc1b0..2a382ee3b9d8a 100644 --- a/apps/federation/l10n/fr.json +++ b/apps/federation/l10n/fr.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Aucun serveur ownCloud trouvé", "Could not add server" : "Impossible d'ajouter le serveur", "Federation" : "Fédération", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Fédération ownCloud vous permet de vous connecter avec d'autres ownCloud de confiance pour partager l'annuaire d'utilisateurs. Par exemple, cela peut être utilisé pour compléter automatiquement les noms des utilisateurs externes pour le partage fédéré." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La Fédération ownCloud vous permet de vous connecter avec d'autres ownCloud de confiance pour partager l'annuaire d'utilisateurs. Par exemple, cela peut être utilisé pour compléter automatiquement les noms des utilisateurs externes pour le partage fédéré.", + "Add server automatically once a federated share was created successfully" : "Ajouter un serveur automatiquement une fois que le partage a été créer avec succès .", + "ownCloud Server" : "Serveur OwnCloud", + "Trusted ownCloud Servers" : "Serveur ownCloud de confiance " },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/he.js b/apps/federation/l10n/he.js index 1d7e25bbc345a..ba5a214e353b9 100644 --- a/apps/federation/l10n/he.js +++ b/apps/federation/l10n/he.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "לא אותר שרת ownCloud", "Could not add server" : "לא ניתן היה להוסיף שרת", "Federation" : "איגוד", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "איגוד ownCloud מאפשר לך להתחבר לשרתי ownCloud מהימנים אחרים למטרת החלפת תיקיות משתמש. לדוגמא ניתן יהיה להשתמש בזה כדי להשלים באופן אוטומטי משתמשים חיצוניים לשיתוף מאוגד." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "איגוד ownCloud מאפשר לך להתחבר לשרתי ownCloud מהימנים אחרים למטרת החלפת תיקיות משתמש. לדוגמא ניתן יהיה להשתמש בזה כדי להשלים באופן אוטומטי משתמשים חיצוניים לשיתוף מאוגד.", + "Add server automatically once a federated share was created successfully" : "הוספת שרת באופן אוטומטי לאחר יצירת שרת מאוגד", + "ownCloud Server" : "שרת ownCloud", + "Trusted ownCloud Servers" : "שרתי ownCloud אמינים" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/he.json b/apps/federation/l10n/he.json index 1cfce307743aa..b1c1f6072003c 100644 --- a/apps/federation/l10n/he.json +++ b/apps/federation/l10n/he.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "לא אותר שרת ownCloud", "Could not add server" : "לא ניתן היה להוסיף שרת", "Federation" : "איגוד", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "איגוד ownCloud מאפשר לך להתחבר לשרתי ownCloud מהימנים אחרים למטרת החלפת תיקיות משתמש. לדוגמא ניתן יהיה להשתמש בזה כדי להשלים באופן אוטומטי משתמשים חיצוניים לשיתוף מאוגד." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "איגוד ownCloud מאפשר לך להתחבר לשרתי ownCloud מהימנים אחרים למטרת החלפת תיקיות משתמש. לדוגמא ניתן יהיה להשתמש בזה כדי להשלים באופן אוטומטי משתמשים חיצוניים לשיתוף מאוגד.", + "Add server automatically once a federated share was created successfully" : "הוספת שרת באופן אוטומטי לאחר יצירת שרת מאוגד", + "ownCloud Server" : "שרת ownCloud", + "Trusted ownCloud Servers" : "שרתי ownCloud אמינים" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/it.js b/apps/federation/l10n/it.js index 2f5a8be4798ee..866225b957908 100644 --- a/apps/federation/l10n/it.js +++ b/apps/federation/l10n/it.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Nessun server ownCloud trovato", "Could not add server" : "Impossibile aggiungere il server", "Federation" : "Federazione", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La federazione di ownCloud ti consente di collegarti con altri ownCloud di fiducia per scambiare la cartella degli utenti. Ad esempio, sarà utilizzata per il completamento automatico degli utenti esterni per la condivisione federata." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La federazione di ownCloud ti consente di collegarti con altri ownCloud di fiducia per scambiare la cartella degli utenti. Ad esempio, sarà utilizzata per il completamento automatico degli utenti esterni per la condivisione federata.", + "Add server automatically once a federated share was created successfully" : "Aggiungi automaticamente il server dopo che una condivisione federata è stata creata con successo", + "ownCloud Server" : "Server ownCloud", + "Trusted ownCloud Servers" : "Server ownCloud di fiducia" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/it.json b/apps/federation/l10n/it.json index 69b8eb1819617..3f73d37a86de2 100644 --- a/apps/federation/l10n/it.json +++ b/apps/federation/l10n/it.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Nessun server ownCloud trovato", "Could not add server" : "Impossibile aggiungere il server", "Federation" : "Federazione", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La federazione di ownCloud ti consente di collegarti con altri ownCloud di fiducia per scambiare la cartella degli utenti. Ad esempio, sarà utilizzata per il completamento automatico degli utenti esterni per la condivisione federata." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La federazione di ownCloud ti consente di collegarti con altri ownCloud di fiducia per scambiare la cartella degli utenti. Ad esempio, sarà utilizzata per il completamento automatico degli utenti esterni per la condivisione federata.", + "Add server automatically once a federated share was created successfully" : "Aggiungi automaticamente il server dopo che una condivisione federata è stata creata con successo", + "ownCloud Server" : "Server ownCloud", + "Trusted ownCloud Servers" : "Server ownCloud di fiducia" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/ja.js b/apps/federation/l10n/ja.js index c97647f975575..63ae08fdbf0dd 100644 --- a/apps/federation/l10n/ja.js +++ b/apps/federation/l10n/ja.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "ownCloudサーバーが見つかりません", "Could not add server" : "サーバーを追加できませんでした", "Federation" : "連携", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud 連携機能では信頼済のownCloudのユーザーディレクトリを相互に接続することができます。例えば、連携で共有したときには、連携先の外部ユーザー名の自動補完を使えるようになります。" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud 連携機能では信頼済のownCloudのユーザーディレクトリを相互に接続することができます。例えば、連携で共有したときには、連携先の外部ユーザー名の自動補完を使えるようになります。", + "Add server automatically once a federated share was created successfully" : "追加するサーバは自動的に統合され、共有が追加されました", + "ownCloud Server" : "ownCloudサーバ", + "Trusted ownCloud Servers" : "ownCloudサーバを信頼する" }, "nplurals=1; plural=0;"); diff --git a/apps/federation/l10n/ja.json b/apps/federation/l10n/ja.json index d074b189c7e00..36984a1cd1ee8 100644 --- a/apps/federation/l10n/ja.json +++ b/apps/federation/l10n/ja.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "ownCloudサーバーが見つかりません", "Could not add server" : "サーバーを追加できませんでした", "Federation" : "連携", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud 連携機能では信頼済のownCloudのユーザーディレクトリを相互に接続することができます。例えば、連携で共有したときには、連携先の外部ユーザー名の自動補完を使えるようになります。" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud 連携機能では信頼済のownCloudのユーザーディレクトリを相互に接続することができます。例えば、連携で共有したときには、連携先の外部ユーザー名の自動補完を使えるようになります。", + "Add server automatically once a federated share was created successfully" : "追加するサーバは自動的に統合され、共有が追加されました", + "ownCloud Server" : "ownCloudサーバ", + "Trusted ownCloud Servers" : "ownCloudサーバを信頼する" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/federation/l10n/nb_NO.js b/apps/federation/l10n/nb_NO.js index 2366f2e92986a..dd5b7900cf567 100644 --- a/apps/federation/l10n/nb_NO.js +++ b/apps/federation/l10n/nb_NO.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Ingen ownCloud-server funnet", "Could not add server" : "Kunne ikke legge til server", "Federation" : "Sammenknytting", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-sammenknytting lar deg koble til andre klarerte ownCloud'er og utveksle brukerkatalogen. Dette vil for eksempel brukes til å fylle ut eksterne brukere for sammenknyttet deling automatisk." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-sammenknytting lar deg koble til andre klarerte ownCloud'er og utveksle brukerkatalogen. Dette vil for eksempel brukes til å fylle ut eksterne brukere for sammenknyttet deling automatisk.", + "Add server automatically once a federated share was created successfully" : "Legg til server automatisk når en sammenknyttet deling er blitt opprettet", + "ownCloud Server" : "ownCloud-server", + "Trusted ownCloud Servers" : "Klarerte ownCloud-servere" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/nb_NO.json b/apps/federation/l10n/nb_NO.json index 54f0526041e7b..768a3a7ab20c5 100644 --- a/apps/federation/l10n/nb_NO.json +++ b/apps/federation/l10n/nb_NO.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Ingen ownCloud-server funnet", "Could not add server" : "Kunne ikke legge til server", "Federation" : "Sammenknytting", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-sammenknytting lar deg koble til andre klarerte ownCloud'er og utveksle brukerkatalogen. Dette vil for eksempel brukes til å fylle ut eksterne brukere for sammenknyttet deling automatisk." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-sammenknytting lar deg koble til andre klarerte ownCloud'er og utveksle brukerkatalogen. Dette vil for eksempel brukes til å fylle ut eksterne brukere for sammenknyttet deling automatisk.", + "Add server automatically once a federated share was created successfully" : "Legg til server automatisk når en sammenknyttet deling er blitt opprettet", + "ownCloud Server" : "ownCloud-server", + "Trusted ownCloud Servers" : "Klarerte ownCloud-servere" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/nl.js b/apps/federation/l10n/nl.js index b30d581efc68b..e593739bb62a7 100644 --- a/apps/federation/l10n/nl.js +++ b/apps/federation/l10n/nl.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Geen ownCloud server gevonden", "Could not add server" : "Kon server niet toevoegen", "Federation" : "Federatie", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federatie stelt u in staat om een verbinding op te zetten met andere vertrouwde ownClouds en uw gebruikers lijst uit te wisselen. Dit stelt u bijvoorbeeld in staat om automatish suggesties te rkijgen voor gebruikeners tijdens het delen via federatie." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federatie stelt u in staat om een verbinding op te zetten met andere vertrouwde ownClouds en uw gebruikers lijst uit te wisselen. Dit stelt u bijvoorbeeld in staat om automatish suggesties te rkijgen voor gebruikeners tijdens het delen via federatie.", + "Add server automatically once a federated share was created successfully" : "Voeg server automatisch toe zodra een gefedereerde share succesvol gecreëerd is", + "ownCloud Server" : "ownCloud Server", + "Trusted ownCloud Servers" : "Vertrouwde ownCloud Servers" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/nl.json b/apps/federation/l10n/nl.json index e674fccec7f7f..5e67ab0d85188 100644 --- a/apps/federation/l10n/nl.json +++ b/apps/federation/l10n/nl.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Geen ownCloud server gevonden", "Could not add server" : "Kon server niet toevoegen", "Federation" : "Federatie", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federatie stelt u in staat om een verbinding op te zetten met andere vertrouwde ownClouds en uw gebruikers lijst uit te wisselen. Dit stelt u bijvoorbeeld in staat om automatish suggesties te rkijgen voor gebruikeners tijdens het delen via federatie." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud Federatie stelt u in staat om een verbinding op te zetten met andere vertrouwde ownClouds en uw gebruikers lijst uit te wisselen. Dit stelt u bijvoorbeeld in staat om automatish suggesties te rkijgen voor gebruikeners tijdens het delen via federatie.", + "Add server automatically once a federated share was created successfully" : "Voeg server automatisch toe zodra een gefedereerde share succesvol gecreëerd is", + "ownCloud Server" : "ownCloud Server", + "Trusted ownCloud Servers" : "Vertrouwde ownCloud Servers" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/pt_BR.js b/apps/federation/l10n/pt_BR.js index ae8f9acbe2ef2..b9ac2c4d8a115 100644 --- a/apps/federation/l10n/pt_BR.js +++ b/apps/federation/l10n/pt_BR.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Nenhum servidor ownCloud encontrado", "Could not add server" : "Não foi possível adicionar servidor", "Federation" : "Associação", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A associação ownCloud permite que você conecte com outros ownCloud confiáveis para haja trocas de diretórios do usuário. Por exemplo, este será utilizado para usuários externos de complementação para compartilhamento associado." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A associação ownCloud permite que você conecte com outros ownCloud confiáveis para haja trocas de diretórios do usuário. Por exemplo, este será utilizado para usuários externos de complementação para compartilhamento associado.", + "Add server automatically once a federated share was created successfully" : "Adicionar servidor automaticamente uma vez que um compartilhamento associado foi criado com êxito", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores OwnCloud Confiáveis" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/federation/l10n/pt_BR.json b/apps/federation/l10n/pt_BR.json index f37a3a4e28b9a..b7b1d34c643b2 100644 --- a/apps/federation/l10n/pt_BR.json +++ b/apps/federation/l10n/pt_BR.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Nenhum servidor ownCloud encontrado", "Could not add server" : "Não foi possível adicionar servidor", "Federation" : "Associação", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A associação ownCloud permite que você conecte com outros ownCloud confiáveis para haja trocas de diretórios do usuário. Por exemplo, este será utilizado para usuários externos de complementação para compartilhamento associado." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A associação ownCloud permite que você conecte com outros ownCloud confiáveis para haja trocas de diretórios do usuário. Por exemplo, este será utilizado para usuários externos de complementação para compartilhamento associado.", + "Add server automatically once a federated share was created successfully" : "Adicionar servidor automaticamente uma vez que um compartilhamento associado foi criado com êxito", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores OwnCloud Confiáveis" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/pt_PT.js b/apps/federation/l10n/pt_PT.js index 3e900bf1a2698..0372e68601631 100644 --- a/apps/federation/l10n/pt_PT.js +++ b/apps/federation/l10n/pt_PT.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Nenhum servidor ownCloud encontrado", "Could not add server" : "Não foi possível adicionar servidor", "Federation" : "Federação", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.", + "Add server automatically once a federated share was created successfully" : "Adicionar o servidor automaticamente assim que uma partilha federada tenha sido criada com sucesso", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores ownCloud de confiança" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/pt_PT.json b/apps/federation/l10n/pt_PT.json index 2758c6260e6be..296257e92c7d8 100644 --- a/apps/federation/l10n/pt_PT.json +++ b/apps/federation/l10n/pt_PT.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Nenhum servidor ownCloud encontrado", "Could not add server" : "Não foi possível adicionar servidor", "Federation" : "Federação", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.", + "Add server automatically once a federated share was created successfully" : "Adicionar o servidor automaticamente assim que uma partilha federada tenha sido criada com sucesso", + "ownCloud Server" : "Servidor ownCloud", + "Trusted ownCloud Servers" : "Servidores ownCloud de confiança" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/ru.js b/apps/federation/l10n/ru.js index d41e1f4391cf2..7772365d323dd 100644 --- a/apps/federation/l10n/ru.js +++ b/apps/federation/l10n/ru.js @@ -6,6 +6,8 @@ OC.L10N.register( "No ownCloud server found" : "Сервер ownCloud не найден", "Could not add server" : "Не удалось добавить сервер", "Federation" : "Объединение", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Объединение серверов ownCloud позволит Вам подключиться к другим доверенным серверам ownCloud для обмена директориями пользователей. Это будет использовано, например, для автоматического завершения внешних пользователей при объединенном общем доступе." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Объединение серверов ownCloud позволит Вам подключиться к другим доверенным серверам ownCloud для обмена директориями пользователей. Это будет использовано, например, для автоматического завершения внешних пользователей при объединенном общем доступе.", + "ownCloud Server" : "Сервер ownCloud", + "Trusted ownCloud Servers" : "Доверенные серверы ownCloud" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/federation/l10n/ru.json b/apps/federation/l10n/ru.json index 417d4be155910..821a553286a69 100644 --- a/apps/federation/l10n/ru.json +++ b/apps/federation/l10n/ru.json @@ -4,6 +4,8 @@ "No ownCloud server found" : "Сервер ownCloud не найден", "Could not add server" : "Не удалось добавить сервер", "Federation" : "Объединение", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Объединение серверов ownCloud позволит Вам подключиться к другим доверенным серверам ownCloud для обмена директориями пользователей. Это будет использовано, например, для автоматического завершения внешних пользователей при объединенном общем доступе." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Объединение серверов ownCloud позволит Вам подключиться к другим доверенным серверам ownCloud для обмена директориями пользователей. Это будет использовано, например, для автоматического завершения внешних пользователей при объединенном общем доступе.", + "ownCloud Server" : "Сервер ownCloud", + "Trusted ownCloud Servers" : "Доверенные серверы ownCloud" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/federation/l10n/sl.js b/apps/federation/l10n/sl.js index ab9bd3ec798c4..0098ab4e928ca 100644 --- a/apps/federation/l10n/sl.js +++ b/apps/federation/l10n/sl.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Ni mogoče najti nobenega strežnika ownCloud.", "Could not add server" : "Ni mogoče dodati strežnika.", "Federation" : "Prenos dovoljenj", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Prenos dovoljenj ownCloud omogoča povezovanje z drugimi potrjenimi strežniki ownCloud in souporabo uporabniških map. Možnost je uporabljena za samodejno dokončanje izpisa zunanjih uporabnikov za souporabo s prenosom dovoljenj." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Prenos dovoljenj ownCloud omogoča povezovanje z drugimi potrjenimi strežniki ownCloud in souporabo uporabniških map. Možnost je uporabljena za samodejno dokončanje izpisa zunanjih uporabnikov za souporabo s prenosom dovoljenj.", + "Add server automatically once a federated share was created successfully" : "Strežnik dodaj samodejno, ko je povezava zveznega oblaka uspešno ustvarjena", + "ownCloud Server" : "Strežnik ownCloud", + "Trusted ownCloud Servers" : "Zaupanja vredni strežniki ownCloud" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/federation/l10n/sl.json b/apps/federation/l10n/sl.json index 9a08a5c817a6b..fb101cf5a92b1 100644 --- a/apps/federation/l10n/sl.json +++ b/apps/federation/l10n/sl.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Ni mogoče najti nobenega strežnika ownCloud.", "Could not add server" : "Ni mogoče dodati strežnika.", "Federation" : "Prenos dovoljenj", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Prenos dovoljenj ownCloud omogoča povezovanje z drugimi potrjenimi strežniki ownCloud in souporabo uporabniških map. Možnost je uporabljena za samodejno dokončanje izpisa zunanjih uporabnikov za souporabo s prenosom dovoljenj." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Prenos dovoljenj ownCloud omogoča povezovanje z drugimi potrjenimi strežniki ownCloud in souporabo uporabniških map. Možnost je uporabljena za samodejno dokončanje izpisa zunanjih uporabnikov za souporabo s prenosom dovoljenj.", + "Add server automatically once a federated share was created successfully" : "Strežnik dodaj samodejno, ko je povezava zveznega oblaka uspešno ustvarjena", + "ownCloud Server" : "Strežnik ownCloud", + "Trusted ownCloud Servers" : "Zaupanja vredni strežniki ownCloud" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/federation/l10n/sq.js b/apps/federation/l10n/sq.js index a7265017d53bd..563102b14a4bd 100644 --- a/apps/federation/l10n/sq.js +++ b/apps/federation/l10n/sq.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "S’u gjet shërbyes ownCloud", "Could not add server" : "Shërbyesi s’u shtua dot", "Federation" : "Federim", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federimi ownCloud ju lejon të lidheni me ownCloud-e të tjerë për të shkëmbyer drejtorinë e përdoruesve. Për shembull, kjo do të përdoret për për vetëplotësim përdoruesish të jashtëm për ndarje të federuar." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federimi ownCloud ju lejon të lidheni me ownCloud-e të tjerë për të shkëmbyer drejtorinë e përdoruesve. Për shembull, kjo do të përdoret për për vetëplotësim përdoruesish të jashtëm për ndarje të federuar.", + "Add server automatically once a federated share was created successfully" : "Shtoje vetvetiu shërbyesin pasi të jetë krijuar me sukses një ndarje e federuar", + "ownCloud Server" : "Shërbyes ownCloud", + "Trusted ownCloud Servers" : "Shërbyes ownCloud të Besuar" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/sq.json b/apps/federation/l10n/sq.json index 39c86e7a7c437..090d9665b6f37 100644 --- a/apps/federation/l10n/sq.json +++ b/apps/federation/l10n/sq.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "S’u gjet shërbyes ownCloud", "Could not add server" : "Shërbyesi s’u shtua dot", "Federation" : "Federim", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federimi ownCloud ju lejon të lidheni me ownCloud-e të tjerë për të shkëmbyer drejtorinë e përdoruesve. Për shembull, kjo do të përdoret për për vetëplotësim përdoruesish të jashtëm për ndarje të federuar." + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federimi ownCloud ju lejon të lidheni me ownCloud-e të tjerë për të shkëmbyer drejtorinë e përdoruesve. Për shembull, kjo do të përdoret për për vetëplotësim përdoruesish të jashtëm për ndarje të federuar.", + "Add server automatically once a federated share was created successfully" : "Shtoje vetvetiu shërbyesin pasi të jetë krijuar me sukses një ndarje e federuar", + "ownCloud Server" : "Shërbyes ownCloud", + "Trusted ownCloud Servers" : "Shërbyes ownCloud të Besuar" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/sv.js b/apps/federation/l10n/sv.js index ed014c6997647..1fbe554e4c38d 100644 --- a/apps/federation/l10n/sv.js +++ b/apps/federation/l10n/sv.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "Ingen ownCloud-server kunde hittas", "Could not add server" : "Kunde inte lägga till server", "Federation" : "Förbund", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "\"OwnCloud Federation\" låter dig ansluta till andra pålitliga ownClouds för att dela användarkatalogen. T.ex. används detta för automagiskt fylla i externa användares namn när man delar över förbunda ownCloud-servrar" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "\"OwnCloud Federation\" låter dig ansluta till andra pålitliga ownClouds för att dela användarkatalogen. T.ex. används detta för automagiskt fylla i externa användares namn när man delar över förbunda ownCloud-servrar", + "Add server automatically once a federated share was created successfully" : "Lägg till servern automatiskt så fort en lyckad federerad delning skapats", + "ownCloud Server" : "ownCloud-server", + "Trusted ownCloud Servers" : "Pålitliga ownCloud-servrar" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federation/l10n/sv.json b/apps/federation/l10n/sv.json index 0a087f81ed580..5b78d76ecd122 100644 --- a/apps/federation/l10n/sv.json +++ b/apps/federation/l10n/sv.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "Ingen ownCloud-server kunde hittas", "Could not add server" : "Kunde inte lägga till server", "Federation" : "Förbund", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "\"OwnCloud Federation\" låter dig ansluta till andra pålitliga ownClouds för att dela användarkatalogen. T.ex. används detta för automagiskt fylla i externa användares namn när man delar över förbunda ownCloud-servrar" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "\"OwnCloud Federation\" låter dig ansluta till andra pålitliga ownClouds för att dela användarkatalogen. T.ex. används detta för automagiskt fylla i externa användares namn när man delar över förbunda ownCloud-servrar", + "Add server automatically once a federated share was created successfully" : "Lägg till servern automatiskt så fort en lyckad federerad delning skapats", + "ownCloud Server" : "ownCloud-server", + "Trusted ownCloud Servers" : "Pålitliga ownCloud-servrar" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/federation/l10n/zh_CN.js b/apps/federation/l10n/zh_CN.js index 7b50e5900e7f3..7dc93d81c732d 100644 --- a/apps/federation/l10n/zh_CN.js +++ b/apps/federation/l10n/zh_CN.js @@ -6,6 +6,9 @@ OC.L10N.register( "No ownCloud server found" : "没有找到对应服务器", "Could not add server" : "无法添加服务器", "Federation" : "联合", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "联合云系统使您可以方便快速的和其他用户共享文件。" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "联合云系统使您可以方便快速的和其他用户共享文件。", + "Add server automatically once a federated share was created successfully" : "一旦联合共享创建成功自动添加服务器", + "ownCloud Server" : "ownCloud 服务器", + "Trusted ownCloud Servers" : "可信 ownCloud 服务器" }, "nplurals=1; plural=0;"); diff --git a/apps/federation/l10n/zh_CN.json b/apps/federation/l10n/zh_CN.json index 6ca1d5dda4d10..cb63b28eefd3f 100644 --- a/apps/federation/l10n/zh_CN.json +++ b/apps/federation/l10n/zh_CN.json @@ -4,6 +4,9 @@ "No ownCloud server found" : "没有找到对应服务器", "Could not add server" : "无法添加服务器", "Federation" : "联合", - "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "联合云系统使您可以方便快速的和其他用户共享文件。" + "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "联合云系统使您可以方便快速的和其他用户共享文件。", + "Add server automatically once a federated share was created successfully" : "一旦联合共享创建成功自动添加服务器", + "ownCloud Server" : "ownCloud 服务器", + "Trusted ownCloud Servers" : "可信 ownCloud 服务器" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/ar.js b/apps/files/l10n/ar.js index a2329a0b57d4c..c144ee32bae7f 100644 --- a/apps/files/l10n/ar.js +++ b/apps/files/l10n/ar.js @@ -93,6 +93,11 @@ OC.L10N.register( "No favorites" : "لا يوجد مفضلات ", "Files and folders you mark as favorite will show up here" : "الملفات والمجلدات التي حددتها كامفضلة سوف تظهر هنا ", "Text file" : "ملف نصي", - "New text file.txt" : "ملف نصي جديد fille.txt" + "New text file.txt" : "ملف نصي جديد fille.txt", + "Path" : "المسار", + "You changed %1$s" : "لقد غيرت %1$s", + "You created %1$s" : "لقد أنشأت %1$s", + "You deleted %1$s" : "حذفت %1$s", + "You restored %1$s" : "لقد قمت باستعادة %1$s" }, "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); diff --git a/apps/files/l10n/ar.json b/apps/files/l10n/ar.json index fbc3f2e21d59f..02c5b97a0713d 100644 --- a/apps/files/l10n/ar.json +++ b/apps/files/l10n/ar.json @@ -91,6 +91,11 @@ "No favorites" : "لا يوجد مفضلات ", "Files and folders you mark as favorite will show up here" : "الملفات والمجلدات التي حددتها كامفضلة سوف تظهر هنا ", "Text file" : "ملف نصي", - "New text file.txt" : "ملف نصي جديد fille.txt" + "New text file.txt" : "ملف نصي جديد fille.txt", + "Path" : "المسار", + "You changed %1$s" : "لقد غيرت %1$s", + "You created %1$s" : "لقد أنشأت %1$s", + "You deleted %1$s" : "حذفت %1$s", + "You restored %1$s" : "لقد قمت باستعادة %1$s" },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" } \ No newline at end of file diff --git a/apps/files/l10n/ast.js b/apps/files/l10n/ast.js index 2262d23345e36..a2c865a7f9184 100644 --- a/apps/files/l10n/ast.js +++ b/apps/files/l10n/ast.js @@ -103,6 +103,13 @@ OC.L10N.register( "No favorites" : "Nengún favoritu", "Files and folders you mark as favorite will show up here" : "Los ficheros y carpetes que marque como favoritos apaecerán equí", "Text file" : "Ficheru de testu", - "New text file.txt" : "Nuevu testu ficheru.txt" + "New text file.txt" : "Nuevu testu ficheru.txt", + "Changed by %2$s" : "Modificáu por %2$s", + "Deleted by %2$s" : "Desaniciáu por %2$s", + "Restored by %2$s" : "Recuperáu por %2$s", + "You changed %1$s" : "Modificasti %1$s", + "You created %1$s" : "Creasti %1$s", + "You deleted %1$s" : "Desaniciasti %1$s", + "You restored %1$s" : "Recuperóse %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ast.json b/apps/files/l10n/ast.json index 53a2c6f8d863d..ebb702a330ef1 100644 --- a/apps/files/l10n/ast.json +++ b/apps/files/l10n/ast.json @@ -101,6 +101,13 @@ "No favorites" : "Nengún favoritu", "Files and folders you mark as favorite will show up here" : "Los ficheros y carpetes que marque como favoritos apaecerán equí", "Text file" : "Ficheru de testu", - "New text file.txt" : "Nuevu testu ficheru.txt" + "New text file.txt" : "Nuevu testu ficheru.txt", + "Changed by %2$s" : "Modificáu por %2$s", + "Deleted by %2$s" : "Desaniciáu por %2$s", + "Restored by %2$s" : "Recuperáu por %2$s", + "You changed %1$s" : "Modificasti %1$s", + "You created %1$s" : "Creasti %1$s", + "You deleted %1$s" : "Desaniciasti %1$s", + "You restored %1$s" : "Recuperóse %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/az.js b/apps/files/l10n/az.js index 57db9be81be49..0b2f69ca3c29f 100644 --- a/apps/files/l10n/az.js +++ b/apps/files/l10n/az.js @@ -100,6 +100,10 @@ OC.L10N.register( "No favorites" : "Seçilmiş yoxdur", "Files and folders you mark as favorite will show up here" : "İstəkli qeyd etdiyiniz fayllar və qovluqlar burda göstəriləcək", "Text file" : "Tekst faylı", - "New text file.txt" : "Yeni mətn file.txt" + "New text file.txt" : "Yeni mətn file.txt", + "You changed %1$s" : "Siz dəyişdiniz %1$s", + "You created %1$s" : "Siz yaratdınız %1$s", + "You deleted %1$s" : "Siz silindiniz %1$s", + "You restored %1$s" : "Siz qayıtdınız %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/az.json b/apps/files/l10n/az.json index e1539015a8342..39013d5ec79db 100644 --- a/apps/files/l10n/az.json +++ b/apps/files/l10n/az.json @@ -98,6 +98,10 @@ "No favorites" : "Seçilmiş yoxdur", "Files and folders you mark as favorite will show up here" : "İstəkli qeyd etdiyiniz fayllar və qovluqlar burda göstəriləcək", "Text file" : "Tekst faylı", - "New text file.txt" : "Yeni mətn file.txt" + "New text file.txt" : "Yeni mətn file.txt", + "You changed %1$s" : "Siz dəyişdiniz %1$s", + "You created %1$s" : "Siz yaratdınız %1$s", + "You deleted %1$s" : "Siz silindiniz %1$s", + "You restored %1$s" : "Siz qayıtdınız %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/bg_BG.js b/apps/files/l10n/bg_BG.js index dcc4508e2e2ea..0815b6b5a3728 100644 --- a/apps/files/l10n/bg_BG.js +++ b/apps/files/l10n/bg_BG.js @@ -91,6 +91,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файловете, които се опитваш да качиш са по-големи от позволеното на този сървър.", "No favorites" : "Няма любими", "Files and folders you mark as favorite will show up here" : "Файловете и папките които отбелязваш като любими ще се показват тук", - "Text file" : "Текстов файл" + "Text file" : "Текстов файл", + "You changed %1$s" : "Вие променихте %1$s.", + "You created %1$s" : "Вие създадохте %1$s.", + "You deleted %1$s" : "Вие изтрихте %1$s.", + "You restored %1$s" : "Вие възстановихте %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/bg_BG.json b/apps/files/l10n/bg_BG.json index 88370db84f78a..8a87b02ea52a8 100644 --- a/apps/files/l10n/bg_BG.json +++ b/apps/files/l10n/bg_BG.json @@ -89,6 +89,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файловете, които се опитваш да качиш са по-големи от позволеното на този сървър.", "No favorites" : "Няма любими", "Files and folders you mark as favorite will show up here" : "Файловете и папките които отбелязваш като любими ще се показват тук", - "Text file" : "Текстов файл" + "Text file" : "Текстов файл", + "You changed %1$s" : "Вие променихте %1$s.", + "You created %1$s" : "Вие създадохте %1$s.", + "You deleted %1$s" : "Вие изтрихте %1$s.", + "You restored %1$s" : "Вие възстановихте %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/bn_BD.js b/apps/files/l10n/bn_BD.js index e9020ade843ce..9e626a01b142d 100644 --- a/apps/files/l10n/bn_BD.js +++ b/apps/files/l10n/bn_BD.js @@ -60,6 +60,10 @@ OC.L10N.register( "Cancel upload" : "আপলোড বাতিল কর", "Upload too large" : "আপলোডের আকারটি অনেক বড়", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "আপনি এই সার্ভারে আপলোড করার জন্য অনুমোদিত ফাইলের সর্বোচ্চ আকারের চেয়ে বৃহদাকার ফাইল আপলোড করার চেষ্টা করছেন ", - "Text file" : "টেক্সট ফাইল" + "Text file" : "টেক্সট ফাইল", + "Upload cancelled." : "আপলোড বাতিল করা হয়েছে।", + "You changed %1$s" : "আপনি পরিবরতন করেছেন %1$s", + "You created %1$s" : "আপনি তৈরি করেছেন %1$s", + "You deleted %1$s" : "আপনি ডিলিট করেছেন %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/bn_BD.json b/apps/files/l10n/bn_BD.json index 1cd6534931419..c9e083dd90e69 100644 --- a/apps/files/l10n/bn_BD.json +++ b/apps/files/l10n/bn_BD.json @@ -58,6 +58,10 @@ "Cancel upload" : "আপলোড বাতিল কর", "Upload too large" : "আপলোডের আকারটি অনেক বড়", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "আপনি এই সার্ভারে আপলোড করার জন্য অনুমোদিত ফাইলের সর্বোচ্চ আকারের চেয়ে বৃহদাকার ফাইল আপলোড করার চেষ্টা করছেন ", - "Text file" : "টেক্সট ফাইল" + "Text file" : "টেক্সট ফাইল", + "Upload cancelled." : "আপলোড বাতিল করা হয়েছে।", + "You changed %1$s" : "আপনি পরিবরতন করেছেন %1$s", + "You created %1$s" : "আপনি তৈরি করেছেন %1$s", + "You deleted %1$s" : "আপনি ডিলিট করেছেন %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/bn_IN.js b/apps/files/l10n/bn_IN.js index e69597d35ca40..ff985a54ff03d 100644 --- a/apps/files/l10n/bn_IN.js +++ b/apps/files/l10n/bn_IN.js @@ -31,6 +31,9 @@ OC.L10N.register( "You deleted %1$s" : "আপনি %1$s কে মুছেছেন", "%2$s deleted %1$s" : "%2$s মুছেছে %1$s কে", "Save" : "সেভ", - "Settings" : "সেটিংস" + "Settings" : "সেটিংস", + "You changed %1$s" : "আপনি %1$s পরিবর্তন করেছেন ", + "You created %1$s" : "আপনি %1$s তৈরি করেছেন ", + "You deleted %1$s" : "আপনি %1$s কে মুছেছেন" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/bn_IN.json b/apps/files/l10n/bn_IN.json index 20c8c2e795e55..1c5c32a76372d 100644 --- a/apps/files/l10n/bn_IN.json +++ b/apps/files/l10n/bn_IN.json @@ -29,6 +29,9 @@ "You deleted %1$s" : "আপনি %1$s কে মুছেছেন", "%2$s deleted %1$s" : "%2$s মুছেছে %1$s কে", "Save" : "সেভ", - "Settings" : "সেটিংস" + "Settings" : "সেটিংস", + "You changed %1$s" : "আপনি %1$s পরিবর্তন করেছেন ", + "You created %1$s" : "আপনি %1$s তৈরি করেছেন ", + "You deleted %1$s" : "আপনি %1$s কে মুছেছেন" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ca.js b/apps/files/l10n/ca.js index 70626bb1ffa15..1a8fe363accee 100644 --- a/apps/files/l10n/ca.js +++ b/apps/files/l10n/ca.js @@ -94,6 +94,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Els fitxers que esteu intentant pujar excedeixen la mida màxima de pujada del servidor", "No favorites" : "No hi ha favorits", "Files and folders you mark as favorite will show up here" : "Aquí apareixeran els arxius i carpetes que vostè marqui com favorits", - "Text file" : "Fitxer de text" + "Text file" : "Fitxer de text", + "You changed %1$s" : "Has canviat %1$s", + "You created %1$s" : "Has creat %1$s", + "You deleted %1$s" : "Has esborrat %1$s", + "You restored %1$s" : "Has restaurat %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ca.json b/apps/files/l10n/ca.json index 3a9dae4e75e40..271829cd0db4a 100644 --- a/apps/files/l10n/ca.json +++ b/apps/files/l10n/ca.json @@ -92,6 +92,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Els fitxers que esteu intentant pujar excedeixen la mida màxima de pujada del servidor", "No favorites" : "No hi ha favorits", "Files and folders you mark as favorite will show up here" : "Aquí apareixeran els arxius i carpetes que vostè marqui com favorits", - "Text file" : "Fitxer de text" + "Text file" : "Fitxer de text", + "You changed %1$s" : "Has canviat %1$s", + "You created %1$s" : "Has creat %1$s", + "You deleted %1$s" : "Has esborrat %1$s", + "You restored %1$s" : "Has restaurat %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/cs_CZ.js b/apps/files/l10n/cs_CZ.js index 1b89c48b12996..ac1de4c898658 100644 --- a/apps/files/l10n/cs_CZ.js +++ b/apps/files/l10n/cs_CZ.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Žádné oblíbené", "Files and folders you mark as favorite will show up here" : "Soubory a adresáře označené jako oblíbené budou zobrazeny zde", "Text file" : "Textový soubor", - "New text file.txt" : "Nový textový soubor.txt" + "New text file.txt" : "Nový textový soubor.txt", + "Changed by %2$s" : "Změněno uživatelem %2$s", + "Deleted by %2$s" : "Smazáno uživatelem %2$s", + "Restored by %2$s" : "Obnoveno uživatelem %2$s", + "You changed %1$s" : "Změnili jste %1$s", + "You created %1$s" : "Vytvořili jste %1$s", + "You deleted %1$s" : "Smazali jste %1$s", + "You restored %1$s" : "Obnovili jste %1$s" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files/l10n/cs_CZ.json b/apps/files/l10n/cs_CZ.json index b307053d4491f..3e40aedeecfaa 100644 --- a/apps/files/l10n/cs_CZ.json +++ b/apps/files/l10n/cs_CZ.json @@ -115,6 +115,13 @@ "No favorites" : "Žádné oblíbené", "Files and folders you mark as favorite will show up here" : "Soubory a adresáře označené jako oblíbené budou zobrazeny zde", "Text file" : "Textový soubor", - "New text file.txt" : "Nový textový soubor.txt" + "New text file.txt" : "Nový textový soubor.txt", + "Changed by %2$s" : "Změněno uživatelem %2$s", + "Deleted by %2$s" : "Smazáno uživatelem %2$s", + "Restored by %2$s" : "Obnoveno uživatelem %2$s", + "You changed %1$s" : "Změnili jste %1$s", + "You created %1$s" : "Vytvořili jste %1$s", + "You deleted %1$s" : "Smazali jste %1$s", + "You restored %1$s" : "Obnovili jste %1$s" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files/l10n/cy_GB.js b/apps/files/l10n/cy_GB.js index e3879890b8629..b6b6da0fd5854 100644 --- a/apps/files/l10n/cy_GB.js +++ b/apps/files/l10n/cy_GB.js @@ -40,6 +40,7 @@ OC.L10N.register( "Cancel upload" : "Diddymu llwytho i fyny", "Upload too large" : "Maint llwytho i fyny'n rhy fawr", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Mae'r ffeiliau rydych yn ceisio llwytho i fyny'n fwy na maint mwyaf llwytho ffeiliau i fyny ar y gweinydd hwn.", - "Text file" : "Ffeil destun" + "Text file" : "Ffeil destun", + "Upload cancelled." : "Diddymwyd llwytho i fyny." }, "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"); diff --git a/apps/files/l10n/cy_GB.json b/apps/files/l10n/cy_GB.json index 7d217d631aed4..a699d2af145e7 100644 --- a/apps/files/l10n/cy_GB.json +++ b/apps/files/l10n/cy_GB.json @@ -38,6 +38,7 @@ "Cancel upload" : "Diddymu llwytho i fyny", "Upload too large" : "Maint llwytho i fyny'n rhy fawr", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Mae'r ffeiliau rydych yn ceisio llwytho i fyny'n fwy na maint mwyaf llwytho ffeiliau i fyny ar y gweinydd hwn.", - "Text file" : "Ffeil destun" + "Text file" : "Ffeil destun", + "Upload cancelled." : "Diddymwyd llwytho i fyny." },"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;" } \ No newline at end of file diff --git a/apps/files/l10n/da.js b/apps/files/l10n/da.js index 6b406fed53449..8191386245fbb 100644 --- a/apps/files/l10n/da.js +++ b/apps/files/l10n/da.js @@ -103,6 +103,13 @@ OC.L10N.register( "No favorites" : "Ingen foretrukne", "Files and folders you mark as favorite will show up here" : "Filer og mapper som du har markeret som foretrukne, vil blive vist her", "Text file" : "Tekstfil", - "New text file.txt" : "Ny tekst file.txt" + "New text file.txt" : "Ny tekst file.txt", + "Changed by %2$s" : "Ændret af %2$s", + "Deleted by %2$s" : "Slettet af %2$s", + "Restored by %2$s" : "Gendannet af %2$s", + "You changed %1$s" : "Du ændrede %1$s", + "You created %1$s" : "Du oprettede %1$s ", + "You deleted %1$s" : "Du slettede %1$s", + "You restored %1$s" : "Du gendannede %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/da.json b/apps/files/l10n/da.json index e186674656c1d..08b30e0a99de9 100644 --- a/apps/files/l10n/da.json +++ b/apps/files/l10n/da.json @@ -101,6 +101,13 @@ "No favorites" : "Ingen foretrukne", "Files and folders you mark as favorite will show up here" : "Filer og mapper som du har markeret som foretrukne, vil blive vist her", "Text file" : "Tekstfil", - "New text file.txt" : "Ny tekst file.txt" + "New text file.txt" : "Ny tekst file.txt", + "Changed by %2$s" : "Ændret af %2$s", + "Deleted by %2$s" : "Slettet af %2$s", + "Restored by %2$s" : "Gendannet af %2$s", + "You changed %1$s" : "Du ændrede %1$s", + "You created %1$s" : "Du oprettede %1$s ", + "You deleted %1$s" : "Du slettede %1$s", + "You restored %1$s" : "Du gendannede %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/de.js b/apps/files/l10n/de.js index d0ee9192669d0..b56e08c9ac7d7 100644 --- a/apps/files/l10n/de.js +++ b/apps/files/l10n/de.js @@ -117,6 +117,14 @@ OC.L10N.register( "No favorites" : "Keine Favoriten", "Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die Du als Favoriten markierst, werden hier erscheinen", "Text file" : "Textdatei", - "New text file.txt" : "Neue Textdatei.txt" + "New text file.txt" : "Neue Textdatei.txt", + "Changed by %2$s" : "Geändert von %2$s", + "Deleted by %2$s" : "Gelöscht von %2$s", + "Restored by %2$s" : "Wiederhergestellt von %2$s", + "Unable to set upload directory." : "Das Upload-Verzeichnis konnte nicht gesetzt werden.", + "You changed %1$s" : "Du hast %1$s geändert", + "You created %1$s" : "Du hast %1$s erstellt", + "You deleted %1$s" : "Du hast %1$s gelöscht", + "You restored %1$s" : "Du hast %1$s wiederhergestellt" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/de.json b/apps/files/l10n/de.json index 51120ebec0b58..d69bea8402e93 100644 --- a/apps/files/l10n/de.json +++ b/apps/files/l10n/de.json @@ -115,6 +115,14 @@ "No favorites" : "Keine Favoriten", "Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die Du als Favoriten markierst, werden hier erscheinen", "Text file" : "Textdatei", - "New text file.txt" : "Neue Textdatei.txt" + "New text file.txt" : "Neue Textdatei.txt", + "Changed by %2$s" : "Geändert von %2$s", + "Deleted by %2$s" : "Gelöscht von %2$s", + "Restored by %2$s" : "Wiederhergestellt von %2$s", + "Unable to set upload directory." : "Das Upload-Verzeichnis konnte nicht gesetzt werden.", + "You changed %1$s" : "Du hast %1$s geändert", + "You created %1$s" : "Du hast %1$s erstellt", + "You deleted %1$s" : "Du hast %1$s gelöscht", + "You restored %1$s" : "Du hast %1$s wiederhergestellt" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/de_AT.js b/apps/files/l10n/de_AT.js index 783ff4aaa6b2f..f978e691f0dbf 100644 --- a/apps/files/l10n/de_AT.js +++ b/apps/files/l10n/de_AT.js @@ -20,6 +20,9 @@ OC.L10N.register( "%2$s deleted %1$s" : "%2$s löschte %1$s", "Save" : "Speichern", "Settings" : "Einstellungen", - "Cancel upload" : "Hochladen abbrechen" + "Cancel upload" : "Hochladen abbrechen", + "You changed %1$s" : "Du hast %1$s geändert", + "You created %1$s" : "Du hast %1$s erstellt", + "You deleted %1$s" : "Du hast %1$s gelöscht" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/de_AT.json b/apps/files/l10n/de_AT.json index 2d54751bdf6fa..5c2e9c9347545 100644 --- a/apps/files/l10n/de_AT.json +++ b/apps/files/l10n/de_AT.json @@ -18,6 +18,9 @@ "%2$s deleted %1$s" : "%2$s löschte %1$s", "Save" : "Speichern", "Settings" : "Einstellungen", - "Cancel upload" : "Hochladen abbrechen" + "Cancel upload" : "Hochladen abbrechen", + "You changed %1$s" : "Du hast %1$s geändert", + "You created %1$s" : "Du hast %1$s erstellt", + "You deleted %1$s" : "Du hast %1$s gelöscht" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/de_DE.js b/apps/files/l10n/de_DE.js index d8472cbc459c0..83eaed5dfdf86 100644 --- a/apps/files/l10n/de_DE.js +++ b/apps/files/l10n/de_DE.js @@ -117,6 +117,14 @@ OC.L10N.register( "No favorites" : "Keine Favoriten", "Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die Sie als Favoriten kennzeichnen, werden hier erscheinen", "Text file" : "Textdatei", - "New text file.txt" : "Neue Textdatei file.txt" + "New text file.txt" : "Neue Textdatei file.txt", + "Changed by %2$s" : "Geändert von %2$s", + "Deleted by %2$s" : "Gelöscht durch %2$s", + "Restored by %2$s" : "Wiederhergestellt durch %2$s", + "Unable to set upload directory." : "Das Upload-Verzeichnis konnte nicht gesetzt werden.", + "You changed %1$s" : "Sie haben %1$s geändert", + "You created %1$s" : "Sie haben %1$s erstellt", + "You deleted %1$s" : "Sie haben %1$s gelöscht", + "You restored %1$s" : "Sie haben %1$s wiederhergestellt" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/de_DE.json b/apps/files/l10n/de_DE.json index 0ec7dea0e86fe..9d606209294fa 100644 --- a/apps/files/l10n/de_DE.json +++ b/apps/files/l10n/de_DE.json @@ -115,6 +115,14 @@ "No favorites" : "Keine Favoriten", "Files and folders you mark as favorite will show up here" : "Dateien und Ordner, die Sie als Favoriten kennzeichnen, werden hier erscheinen", "Text file" : "Textdatei", - "New text file.txt" : "Neue Textdatei file.txt" + "New text file.txt" : "Neue Textdatei file.txt", + "Changed by %2$s" : "Geändert von %2$s", + "Deleted by %2$s" : "Gelöscht durch %2$s", + "Restored by %2$s" : "Wiederhergestellt durch %2$s", + "Unable to set upload directory." : "Das Upload-Verzeichnis konnte nicht gesetzt werden.", + "You changed %1$s" : "Sie haben %1$s geändert", + "You created %1$s" : "Sie haben %1$s erstellt", + "You deleted %1$s" : "Sie haben %1$s gelöscht", + "You restored %1$s" : "Sie haben %1$s wiederhergestellt" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/el.js b/apps/files/l10n/el.js index 20b57e415b056..35cc554ed1260 100644 --- a/apps/files/l10n/el.js +++ b/apps/files/l10n/el.js @@ -112,6 +112,13 @@ OC.L10N.register( "No favorites" : "Δεν υπάρχουν αγαπημένα", "Files and folders you mark as favorite will show up here" : "Τα αρχεία και οι φάκελοι που σημειώνονται ως αγαπημένα θα εμφανιστούν εδώ ", "Text file" : "Αρχείο κειμένου", - "New text file.txt" : "Νέο αρχείο κειμένου.txt" + "New text file.txt" : "Νέο αρχείο κειμένου.txt", + "Changed by %2$s" : "Άλλαξε από το χρήστη %2$s", + "Deleted by %2$s" : "Διαγράφηκε από το χρήστη %2$s", + "Restored by %2$s" : "Επαναφορά από το χρήστη %2$s", + "You changed %1$s" : "Αλλάξατε το %1$s", + "You created %1$s" : "Δημιουργήσατε το %1$s", + "You deleted %1$s" : "Διαγράψατε το %1$s", + "You restored %1$s" : "Επαναφέρατε το %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/el.json b/apps/files/l10n/el.json index 849b0ee8a09d4..a941f24f2b1b4 100644 --- a/apps/files/l10n/el.json +++ b/apps/files/l10n/el.json @@ -110,6 +110,13 @@ "No favorites" : "Δεν υπάρχουν αγαπημένα", "Files and folders you mark as favorite will show up here" : "Τα αρχεία και οι φάκελοι που σημειώνονται ως αγαπημένα θα εμφανιστούν εδώ ", "Text file" : "Αρχείο κειμένου", - "New text file.txt" : "Νέο αρχείο κειμένου.txt" + "New text file.txt" : "Νέο αρχείο κειμένου.txt", + "Changed by %2$s" : "Άλλαξε από το χρήστη %2$s", + "Deleted by %2$s" : "Διαγράφηκε από το χρήστη %2$s", + "Restored by %2$s" : "Επαναφορά από το χρήστη %2$s", + "You changed %1$s" : "Αλλάξατε το %1$s", + "You created %1$s" : "Δημιουργήσατε το %1$s", + "You deleted %1$s" : "Διαγράψατε το %1$s", + "You restored %1$s" : "Επαναφέρατε το %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/en_GB.js b/apps/files/l10n/en_GB.js index f15fa7e49ad26..339358aca9c5c 100644 --- a/apps/files/l10n/en_GB.js +++ b/apps/files/l10n/en_GB.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "No favourites", "Files and folders you mark as favorite will show up here" : "Files and folders you mark as favourite will show up here", "Text file" : "Text file", - "New text file.txt" : "New text file.txt" + "New text file.txt" : "New text file.txt", + "Changed by %2$s" : "Changed by %2$s", + "Deleted by %2$s" : "Deleted by %2$s", + "Restored by %2$s" : "Restored by %2$s", + "You changed %1$s" : "You changed %1$s", + "You created %1$s" : "You created %1$s", + "You deleted %1$s" : "You deleted %1$s", + "You restored %1$s" : "You restored %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/en_GB.json b/apps/files/l10n/en_GB.json index 5606b0c2c7fb1..d87a880c6d469 100644 --- a/apps/files/l10n/en_GB.json +++ b/apps/files/l10n/en_GB.json @@ -115,6 +115,13 @@ "No favorites" : "No favourites", "Files and folders you mark as favorite will show up here" : "Files and folders you mark as favourite will show up here", "Text file" : "Text file", - "New text file.txt" : "New text file.txt" + "New text file.txt" : "New text file.txt", + "Changed by %2$s" : "Changed by %2$s", + "Deleted by %2$s" : "Deleted by %2$s", + "Restored by %2$s" : "Restored by %2$s", + "You changed %1$s" : "You changed %1$s", + "You created %1$s" : "You created %1$s", + "You deleted %1$s" : "You deleted %1$s", + "You restored %1$s" : "You restored %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/eo.js b/apps/files/l10n/eo.js index 5125d42feda60..0b17b81dcebc6 100644 --- a/apps/files/l10n/eo.js +++ b/apps/files/l10n/eo.js @@ -113,6 +113,13 @@ OC.L10N.register( "No favorites" : "Neniu pliŝato", "Files and folders you mark as favorite will show up here" : "Dosieroj kaj dosierujoj, kiujn vi markas, kiel pliŝatoj, aperos ĉi tie", "Text file" : "Tekstodosiero", - "New text file.txt" : "Nova tekstodosiero.txt" + "New text file.txt" : "Nova tekstodosiero.txt", + "Changed by %2$s" : "Ŝanĝita de %2$s", + "Deleted by %2$s" : "Forigita de %2$s", + "Restored by %2$s" : "Restaŭrita de %2$s", + "You changed %1$s" : "Vi ŝanĝis %1$s", + "You created %1$s" : "Vi kreis %1$s", + "You deleted %1$s" : "Vi forigis %1$s", + "You restored %1$s" : "Vi restaŭris %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/eo.json b/apps/files/l10n/eo.json index 7328acdef4212..a81a4b3ee9751 100644 --- a/apps/files/l10n/eo.json +++ b/apps/files/l10n/eo.json @@ -111,6 +111,13 @@ "No favorites" : "Neniu pliŝato", "Files and folders you mark as favorite will show up here" : "Dosieroj kaj dosierujoj, kiujn vi markas, kiel pliŝatoj, aperos ĉi tie", "Text file" : "Tekstodosiero", - "New text file.txt" : "Nova tekstodosiero.txt" + "New text file.txt" : "Nova tekstodosiero.txt", + "Changed by %2$s" : "Ŝanĝita de %2$s", + "Deleted by %2$s" : "Forigita de %2$s", + "Restored by %2$s" : "Restaŭrita de %2$s", + "You changed %1$s" : "Vi ŝanĝis %1$s", + "You created %1$s" : "Vi kreis %1$s", + "You deleted %1$s" : "Vi forigis %1$s", + "You restored %1$s" : "Vi restaŭris %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js index f88135163c23a..20fc54221bfd3 100644 --- a/apps/files/l10n/es.js +++ b/apps/files/l10n/es.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "No hay favoritos", "Files and folders you mark as favorite will show up here" : "Aquí aparecerán los archivos y carpetas que usted marque como favoritos", "Text file" : "Archivo de texto", - "New text file.txt" : "Nuevo archivo de texto.txt" + "New text file.txt" : "Nuevo archivo de texto.txt", + "Changed by %2$s" : "Cambiado por %2$s", + "Deleted by %2$s" : "Eliminado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Ha modificado %1$s", + "You created %1$s" : "Ha creado %1$s", + "You deleted %1$s" : "Ha eliminado %1$s", + "You restored %1$s" : "Usted restauró %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json index fe135f765cee2..3fb148bca71b5 100644 --- a/apps/files/l10n/es.json +++ b/apps/files/l10n/es.json @@ -115,6 +115,13 @@ "No favorites" : "No hay favoritos", "Files and folders you mark as favorite will show up here" : "Aquí aparecerán los archivos y carpetas que usted marque como favoritos", "Text file" : "Archivo de texto", - "New text file.txt" : "Nuevo archivo de texto.txt" + "New text file.txt" : "Nuevo archivo de texto.txt", + "Changed by %2$s" : "Cambiado por %2$s", + "Deleted by %2$s" : "Eliminado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Ha modificado %1$s", + "You created %1$s" : "Ha creado %1$s", + "You deleted %1$s" : "Ha eliminado %1$s", + "You restored %1$s" : "Usted restauró %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/es_AR.js b/apps/files/l10n/es_AR.js index bd4504592f157..77a321e721613 100644 --- a/apps/files/l10n/es_AR.js +++ b/apps/files/l10n/es_AR.js @@ -74,6 +74,9 @@ OC.L10N.register( "Cancel upload" : "Cancelar subida", "Upload too large" : "El tamaño del archivo que querés subir es demasiado grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Los archivos que intentás subir sobrepasan el tamaño máximo ", - "Text file" : "Archivo de texto" + "Text file" : "Archivo de texto", + "You changed %1$s" : "Modificaste %1$s", + "You created %1$s" : "Has creado %1$s", + "You deleted %1$s" : "Eliminaste %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/es_AR.json b/apps/files/l10n/es_AR.json index 81898bf489d83..dad05e342c8e4 100644 --- a/apps/files/l10n/es_AR.json +++ b/apps/files/l10n/es_AR.json @@ -72,6 +72,9 @@ "Cancel upload" : "Cancelar subida", "Upload too large" : "El tamaño del archivo que querés subir es demasiado grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Los archivos que intentás subir sobrepasan el tamaño máximo ", - "Text file" : "Archivo de texto" + "Text file" : "Archivo de texto", + "You changed %1$s" : "Modificaste %1$s", + "You created %1$s" : "Has creado %1$s", + "You deleted %1$s" : "Eliminaste %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/es_CL.js b/apps/files/l10n/es_CL.js index 7b67ca39ac5c3..ed0129ad89cd0 100644 --- a/apps/files/l10n/es_CL.js +++ b/apps/files/l10n/es_CL.js @@ -18,6 +18,9 @@ OC.L10N.register( "You deleted %1$s" : "Ha borrado %1$s", "%2$s deleted %1$s" : "%2$s borró %1$s", "Settings" : "Configuración", - "Cancel upload" : "cancelar subida" + "Cancel upload" : "cancelar subida", + "You changed %1$s" : "Cambió %1$s", + "You created %1$s" : "Ha creado %1$s", + "You deleted %1$s" : "Ha borrado %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/es_CL.json b/apps/files/l10n/es_CL.json index 7c42b2a40979c..dbe8db2983a2e 100644 --- a/apps/files/l10n/es_CL.json +++ b/apps/files/l10n/es_CL.json @@ -16,6 +16,9 @@ "You deleted %1$s" : "Ha borrado %1$s", "%2$s deleted %1$s" : "%2$s borró %1$s", "Settings" : "Configuración", - "Cancel upload" : "cancelar subida" + "Cancel upload" : "cancelar subida", + "You changed %1$s" : "Cambió %1$s", + "You created %1$s" : "Ha creado %1$s", + "You deleted %1$s" : "Ha borrado %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/es_MX.js b/apps/files/l10n/es_MX.js index 780c206c6226e..aefcc8313ecbd 100644 --- a/apps/files/l10n/es_MX.js +++ b/apps/files/l10n/es_MX.js @@ -60,6 +60,9 @@ OC.L10N.register( "Cancel upload" : "Cancelar subida", "Upload too large" : "Subida demasido grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.", - "Text file" : "Archivo de texto" + "Text file" : "Archivo de texto", + "You changed %1$s" : "Has cambiado %1$s", + "You created %1$s" : "Has creado %1$s", + "You deleted %1$s" : "Has eliminado %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/es_MX.json b/apps/files/l10n/es_MX.json index 17d5cb74e8741..813d6d13f2925 100644 --- a/apps/files/l10n/es_MX.json +++ b/apps/files/l10n/es_MX.json @@ -58,6 +58,9 @@ "Cancel upload" : "Cancelar subida", "Upload too large" : "Subida demasido grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.", - "Text file" : "Archivo de texto" + "Text file" : "Archivo de texto", + "You changed %1$s" : "Has cambiado %1$s", + "You created %1$s" : "Has creado %1$s", + "You deleted %1$s" : "Has eliminado %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/et_EE.js b/apps/files/l10n/et_EE.js index 5c59cf614b7ea..1d3d3ea60bb73 100644 --- a/apps/files/l10n/et_EE.js +++ b/apps/files/l10n/et_EE.js @@ -103,6 +103,10 @@ OC.L10N.register( "No favorites" : "Lemmikuid pole", "Files and folders you mark as favorite will show up here" : "Siin kuvatakse faile ja kaustasid, mille oled märkinud lemmikuteks", "Text file" : "Tekstifail", - "New text file.txt" : "Uus tekstifail.txt" + "New text file.txt" : "Uus tekstifail.txt", + "You changed %1$s" : "Sa muutsid %1$s", + "You created %1$s" : "Sa tekitasid %1$s", + "You deleted %1$s" : "Sa kustutasid %1$s", + "You restored %1$s" : "Sa taastasid %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/et_EE.json b/apps/files/l10n/et_EE.json index f438d07cdc83f..7678c63a18cc5 100644 --- a/apps/files/l10n/et_EE.json +++ b/apps/files/l10n/et_EE.json @@ -101,6 +101,10 @@ "No favorites" : "Lemmikuid pole", "Files and folders you mark as favorite will show up here" : "Siin kuvatakse faile ja kaustasid, mille oled märkinud lemmikuteks", "Text file" : "Tekstifail", - "New text file.txt" : "Uus tekstifail.txt" + "New text file.txt" : "Uus tekstifail.txt", + "You changed %1$s" : "Sa muutsid %1$s", + "You created %1$s" : "Sa tekitasid %1$s", + "You deleted %1$s" : "Sa kustutasid %1$s", + "You restored %1$s" : "Sa taastasid %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/eu.js b/apps/files/l10n/eu.js index 16d681ebeab48..fca2117c8f398 100644 --- a/apps/files/l10n/eu.js +++ b/apps/files/l10n/eu.js @@ -88,6 +88,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Igotzen saiatzen ari zaren fitxategiak zerbitzari honek igotzeko onartzen duena baino handiagoak dira.", "No favorites" : "Gogokorik ez", "Files and folders you mark as favorite will show up here" : "Gogokotzat markatutako fitxategi eta karpeta hemen agertuko dira", - "Text file" : "Testu fitxategia" + "Text file" : "Testu fitxategia", + "You changed %1$s" : "%1$s aldatu duzu", + "You created %1$s" : "Zuk sortua %1$s", + "You deleted %1$s" : "%1$s ezabatu duzu", + "You restored %1$s" : "Zuk %1$s berrezarri duzu" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/eu.json b/apps/files/l10n/eu.json index f23d06bb5db41..bed1fa049d7b1 100644 --- a/apps/files/l10n/eu.json +++ b/apps/files/l10n/eu.json @@ -86,6 +86,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Igotzen saiatzen ari zaren fitxategiak zerbitzari honek igotzeko onartzen duena baino handiagoak dira.", "No favorites" : "Gogokorik ez", "Files and folders you mark as favorite will show up here" : "Gogokotzat markatutako fitxategi eta karpeta hemen agertuko dira", - "Text file" : "Testu fitxategia" + "Text file" : "Testu fitxategia", + "You changed %1$s" : "%1$s aldatu duzu", + "You created %1$s" : "Zuk sortua %1$s", + "You deleted %1$s" : "%1$s ezabatu duzu", + "You restored %1$s" : "Zuk %1$s berrezarri duzu" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/fa.js b/apps/files/l10n/fa.js index 0d6086e090030..fd3b81657afd7 100644 --- a/apps/files/l10n/fa.js +++ b/apps/files/l10n/fa.js @@ -100,6 +100,13 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "فایلها بیش از حد تعیین شده در این سرور هستند\nمترجم:با تغییر فایل php,ini میتوان این محدودیت را برطرف کرد", "No favorites" : "هیچ برگزیده", "Files and folders you mark as favorite will show up here" : "فایل‌ها و پوشه‌های انتخاب شده به عنوان برگزیده توسط شما، در اینجا نمایش داده می‌شود", - "Text file" : "فایل متنی" + "Text file" : "فایل متنی", + "Changed by %2$s" : "تغییریافته توسط %2$s", + "Deleted by %2$s" : "حذف شده توسط %2$s", + "Restored by %2$s" : "بازگردانی شده توسط %2$s", + "You changed %1$s" : "شما %1$s را تغییر دادید", + "You created %1$s" : "شما %1$s را ایجاد کردید", + "You deleted %1$s" : "شما %1$s را حذف کردید", + "You restored %1$s" : "شما %1$s را بازگردانی کردید" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/fa.json b/apps/files/l10n/fa.json index 109dfbdb58564..1dab7441052ce 100644 --- a/apps/files/l10n/fa.json +++ b/apps/files/l10n/fa.json @@ -98,6 +98,13 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "فایلها بیش از حد تعیین شده در این سرور هستند\nمترجم:با تغییر فایل php,ini میتوان این محدودیت را برطرف کرد", "No favorites" : "هیچ برگزیده", "Files and folders you mark as favorite will show up here" : "فایل‌ها و پوشه‌های انتخاب شده به عنوان برگزیده توسط شما، در اینجا نمایش داده می‌شود", - "Text file" : "فایل متنی" + "Text file" : "فایل متنی", + "Changed by %2$s" : "تغییریافته توسط %2$s", + "Deleted by %2$s" : "حذف شده توسط %2$s", + "Restored by %2$s" : "بازگردانی شده توسط %2$s", + "You changed %1$s" : "شما %1$s را تغییر دادید", + "You created %1$s" : "شما %1$s را ایجاد کردید", + "You deleted %1$s" : "شما %1$s را حذف کردید", + "You restored %1$s" : "شما %1$s را بازگردانی کردید" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/fi_FI.js b/apps/files/l10n/fi_FI.js index ba63b92765542..cfe7fdbab0a3b 100644 --- a/apps/files/l10n/fi_FI.js +++ b/apps/files/l10n/fi_FI.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Ei suosikkeja", "Files and folders you mark as favorite will show up here" : "Suosikeiksi merkitsemäsi tiedostot ja kansiot näkyvät täällä", "Text file" : "Tekstitiedosto", - "New text file.txt" : "Uusi tekstitiedosto.txt" + "New text file.txt" : "Uusi tekstitiedosto.txt", + "Changed by %2$s" : "Muuttanut %2$s", + "Deleted by %2$s" : "Poistanut %2$s", + "Restored by %2$s" : "Palauttanut %2$s", + "You changed %1$s" : "Muutit kohdetta %1$s", + "You created %1$s" : "Loit kohteen %1$s", + "You deleted %1$s" : "Poistit kohteen %1$s", + "You restored %1$s" : "Palautit kohteen %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/fi_FI.json b/apps/files/l10n/fi_FI.json index bfcc08aaa774f..becae24aaff0d 100644 --- a/apps/files/l10n/fi_FI.json +++ b/apps/files/l10n/fi_FI.json @@ -115,6 +115,13 @@ "No favorites" : "Ei suosikkeja", "Files and folders you mark as favorite will show up here" : "Suosikeiksi merkitsemäsi tiedostot ja kansiot näkyvät täällä", "Text file" : "Tekstitiedosto", - "New text file.txt" : "Uusi tekstitiedosto.txt" + "New text file.txt" : "Uusi tekstitiedosto.txt", + "Changed by %2$s" : "Muuttanut %2$s", + "Deleted by %2$s" : "Poistanut %2$s", + "Restored by %2$s" : "Palauttanut %2$s", + "You changed %1$s" : "Muutit kohdetta %1$s", + "You created %1$s" : "Loit kohteen %1$s", + "You deleted %1$s" : "Poistit kohteen %1$s", + "You restored %1$s" : "Palautit kohteen %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/fil.js b/apps/files/l10n/fil.js index c50be1aa4793a..15c5b4bf119bc 100644 --- a/apps/files/l10n/fil.js +++ b/apps/files/l10n/fil.js @@ -4,6 +4,7 @@ OC.L10N.register( "_%n folder_::_%n folders_" : ["",""], "_%n file_::_%n files_" : ["",""], "_Uploading %n file_::_Uploading %n files_" : ["",""], - "_matches '{filter}'_::_match '{filter}'_" : ["",""] + "_matches '{filter}'_::_match '{filter}'_" : ["",""], + "New folder" : "Bagong folder" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/fil.json b/apps/files/l10n/fil.json index 210ac153bab17..7f241192053dc 100644 --- a/apps/files/l10n/fil.json +++ b/apps/files/l10n/fil.json @@ -2,6 +2,7 @@ "_%n folder_::_%n folders_" : ["",""], "_%n file_::_%n files_" : ["",""], "_Uploading %n file_::_Uploading %n files_" : ["",""], - "_matches '{filter}'_::_match '{filter}'_" : ["",""] + "_matches '{filter}'_::_match '{filter}'_" : ["",""], + "New folder" : "Bagong folder" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js index bc88d62fb20ed..176f30a7e9bd8 100644 --- a/apps/files/l10n/fr.js +++ b/apps/files/l10n/fr.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Aucun favori", "Files and folders you mark as favorite will show up here" : "Les fichiers et dossiers ajoutés à vos favoris apparaîtront ici", "Text file" : "Fichier texte", - "New text file.txt" : "Nouveau fichier texte.txt" + "New text file.txt" : "Nouveau fichier texte.txt", + "Changed by %2$s" : "Modifié par %2$s", + "Deleted by %2$s" : "Supprimé par %2$s", + "Restored by %2$s" : "Restauré par %2$s", + "You changed %1$s" : "Vous avez modifié %1$s", + "You created %1$s" : "Vous avez créé %1$s", + "You deleted %1$s" : "Vous avez supprimé %1$s", + "You restored %1$s" : "Vous avez restauré %1$s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/fr.json b/apps/files/l10n/fr.json index b3d28f92a4756..25475c454d1d3 100644 --- a/apps/files/l10n/fr.json +++ b/apps/files/l10n/fr.json @@ -115,6 +115,13 @@ "No favorites" : "Aucun favori", "Files and folders you mark as favorite will show up here" : "Les fichiers et dossiers ajoutés à vos favoris apparaîtront ici", "Text file" : "Fichier texte", - "New text file.txt" : "Nouveau fichier texte.txt" + "New text file.txt" : "Nouveau fichier texte.txt", + "Changed by %2$s" : "Modifié par %2$s", + "Deleted by %2$s" : "Supprimé par %2$s", + "Restored by %2$s" : "Restauré par %2$s", + "You changed %1$s" : "Vous avez modifié %1$s", + "You created %1$s" : "Vous avez créé %1$s", + "You deleted %1$s" : "Vous avez supprimé %1$s", + "You restored %1$s" : "Vous avez restauré %1$s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files/l10n/gl.js b/apps/files/l10n/gl.js index e463ef16b3d6f..70ad31c3651b8 100644 --- a/apps/files/l10n/gl.js +++ b/apps/files/l10n/gl.js @@ -98,6 +98,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Os ficheiros que tenta enviar exceden do tamaño máximo permitido neste servidor", "No favorites" : "Non hai favoritos", "Files and folders you mark as favorite will show up here" : "Os ficheiros e cartafoles que marque como favoritos amosaranse aquí", - "Text file" : "Ficheiro de texto" + "Text file" : "Ficheiro de texto", + "You changed %1$s" : "Cambiou %1$s", + "You created %1$s" : "Creou %1$s", + "You deleted %1$s" : "Eliminou %1$s", + "You restored %1$s" : "Vostede restaurou %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/gl.json b/apps/files/l10n/gl.json index 418767c516792..7b6d1fd81c55f 100644 --- a/apps/files/l10n/gl.json +++ b/apps/files/l10n/gl.json @@ -96,6 +96,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Os ficheiros que tenta enviar exceden do tamaño máximo permitido neste servidor", "No favorites" : "Non hai favoritos", "Files and folders you mark as favorite will show up here" : "Os ficheiros e cartafoles que marque como favoritos amosaranse aquí", - "Text file" : "Ficheiro de texto" + "Text file" : "Ficheiro de texto", + "You changed %1$s" : "Cambiou %1$s", + "You created %1$s" : "Creou %1$s", + "You deleted %1$s" : "Eliminou %1$s", + "You restored %1$s" : "Vostede restaurou %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/he.js b/apps/files/l10n/he.js index 74f54deb76e3c..49053e270fe8c 100644 --- a/apps/files/l10n/he.js +++ b/apps/files/l10n/he.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "אין מועדפים", "Files and folders you mark as favorite will show up here" : "קבצים ותיקיות שסומנו על ידך כמועדפים יוצגו כאן", "Text file" : "קובץ טקסט", - "New text file.txt" : "קובץ טקסט חדש.txt" + "New text file.txt" : "קובץ טקסט חדש.txt", + "Changed by %2$s" : "שונו על ידי %2$s", + "Deleted by %2$s" : "נמחקו על ידי %2$s", + "Restored by %2$s" : "שוחזרו על ידי %2$s", + "You changed %1$s" : "שינית %1$s", + "You created %1$s" : "יצרת %1$s", + "You deleted %1$s" : "מחקת %1$s", + "You restored %1$s" : "שחזרת %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/he.json b/apps/files/l10n/he.json index 8f45d4c851ba7..a0db94b6acccd 100644 --- a/apps/files/l10n/he.json +++ b/apps/files/l10n/he.json @@ -115,6 +115,13 @@ "No favorites" : "אין מועדפים", "Files and folders you mark as favorite will show up here" : "קבצים ותיקיות שסומנו על ידך כמועדפים יוצגו כאן", "Text file" : "קובץ טקסט", - "New text file.txt" : "קובץ טקסט חדש.txt" + "New text file.txt" : "קובץ טקסט חדש.txt", + "Changed by %2$s" : "שונו על ידי %2$s", + "Deleted by %2$s" : "נמחקו על ידי %2$s", + "Restored by %2$s" : "שוחזרו על ידי %2$s", + "You changed %1$s" : "שינית %1$s", + "You created %1$s" : "יצרת %1$s", + "You deleted %1$s" : "מחקת %1$s", + "You restored %1$s" : "שחזרת %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/hr.js b/apps/files/l10n/hr.js index 746ee8ded914e..8d7340e0d8fb7 100644 --- a/apps/files/l10n/hr.js +++ b/apps/files/l10n/hr.js @@ -88,6 +88,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Datoteke koje pokušavate učitati premašuju maksimalnu veličinu za unos datoteka na ovom poslužitelju.", "No favorites" : "Nema favorita", "Files and folders you mark as favorite will show up here" : "Fajlovi i folderi koje oznacite kao favorite ce se prikazati ovdje", - "Text file" : "Tekstualna datoteka" + "Text file" : "Tekstualna datoteka", + "You changed %1$s" : "Promijenili ste %1$s", + "You created %1$s" : "Vi ste kreirali %1$s", + "You deleted %1$s" : "Izbrisali ste %1$s", + "You restored %1$s" : "Vraćeno %1$s" }, "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); diff --git a/apps/files/l10n/hr.json b/apps/files/l10n/hr.json index 35bc43df7e009..e1fcf6fb91499 100644 --- a/apps/files/l10n/hr.json +++ b/apps/files/l10n/hr.json @@ -86,6 +86,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Datoteke koje pokušavate učitati premašuju maksimalnu veličinu za unos datoteka na ovom poslužitelju.", "No favorites" : "Nema favorita", "Files and folders you mark as favorite will show up here" : "Fajlovi i folderi koje oznacite kao favorite ce se prikazati ovdje", - "Text file" : "Tekstualna datoteka" + "Text file" : "Tekstualna datoteka", + "You changed %1$s" : "Promijenili ste %1$s", + "You created %1$s" : "Vi ste kreirali %1$s", + "You deleted %1$s" : "Izbrisali ste %1$s", + "You restored %1$s" : "Vraćeno %1$s" },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files/l10n/hu_HU.js b/apps/files/l10n/hu_HU.js index 399c70932b77c..99ca5b09c7c43 100644 --- a/apps/files/l10n/hu_HU.js +++ b/apps/files/l10n/hu_HU.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Nincsenek kedvencek", "Files and folders you mark as favorite will show up here" : "A kedvencnek jelölt fájlokat és mappákat itt találod meg", "Text file" : "Szövegfájl", - "New text file.txt" : "Új szöveges fájl.txt" + "New text file.txt" : "Új szöveges fájl.txt", + "Changed by %2$s" : "Megváltoztatta: %2$s", + "Deleted by %2$s" : "Törölte: %2$s", + "Restored by %2$s" : "Visszaállította: %2$s", + "You changed %1$s" : "Megváltoztattam: %1$s", + "You created %1$s" : "Létrehoztam: %1$s", + "You deleted %1$s" : "Töröltem: %1$s", + "You restored %1$s" : "Visszatöltötted %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/hu_HU.json b/apps/files/l10n/hu_HU.json index fdad833249930..75be9db71ded6 100644 --- a/apps/files/l10n/hu_HU.json +++ b/apps/files/l10n/hu_HU.json @@ -114,6 +114,13 @@ "No favorites" : "Nincsenek kedvencek", "Files and folders you mark as favorite will show up here" : "A kedvencnek jelölt fájlokat és mappákat itt találod meg", "Text file" : "Szövegfájl", - "New text file.txt" : "Új szöveges fájl.txt" + "New text file.txt" : "Új szöveges fájl.txt", + "Changed by %2$s" : "Megváltoztatta: %2$s", + "Deleted by %2$s" : "Törölte: %2$s", + "Restored by %2$s" : "Visszaállította: %2$s", + "You changed %1$s" : "Megváltoztattam: %1$s", + "You created %1$s" : "Létrehoztam: %1$s", + "You deleted %1$s" : "Töröltem: %1$s", + "You restored %1$s" : "Visszatöltötted %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/hy.js b/apps/files/l10n/hy.js index ecf99c1077f77..5a69a35f9c58d 100644 --- a/apps/files/l10n/hy.js +++ b/apps/files/l10n/hy.js @@ -21,6 +21,15 @@ OC.L10N.register( "Save" : "Պահպանել", "Select all" : "Նշել բոլորը", "Text file" : "Տեքստ ֆայլ", - "New text file.txt" : "Նոր տեքստ ֆայլ.txt" + "New text file.txt" : "Նոր տեքստ ֆայլ.txt", + "Changed by %2$s" : "Փոխվել է %2$sի կողմից", + "Deleted by %2$s" : "Ջնջվել է %2$sի կողմից", + "No files in here" : "Ֆայլեր չկան այստեղ", + "Restored by %2$s" : "Վերականգնվել է %2$sի կողմից", + "Upload" : "Բեռնել", + "You changed %1$s" : "Դու փոխեցիր %1$s", + "You created %1$s" : "Դու ստեղծեցիր %1$s", + "You deleted %1$s" : "Դու ջնջեցիր %1$s", + "You restored %1$s" : "Դու վերականգնեցիր %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/hy.json b/apps/files/l10n/hy.json index 8b23697b4a22c..59b97c2cf535a 100644 --- a/apps/files/l10n/hy.json +++ b/apps/files/l10n/hy.json @@ -19,6 +19,15 @@ "Save" : "Պահպանել", "Select all" : "Նշել բոլորը", "Text file" : "Տեքստ ֆայլ", - "New text file.txt" : "Նոր տեքստ ֆայլ.txt" + "New text file.txt" : "Նոր տեքստ ֆայլ.txt", + "Changed by %2$s" : "Փոխվել է %2$sի կողմից", + "Deleted by %2$s" : "Ջնջվել է %2$sի կողմից", + "No files in here" : "Ֆայլեր չկան այստեղ", + "Restored by %2$s" : "Վերականգնվել է %2$sի կողմից", + "Upload" : "Բեռնել", + "You changed %1$s" : "Դու փոխեցիր %1$s", + "You created %1$s" : "Դու ստեղծեցիր %1$s", + "You deleted %1$s" : "Դու ջնջեցիր %1$s", + "You restored %1$s" : "Դու վերականգնեցիր %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ia.js b/apps/files/l10n/ia.js index 8310334287f47..0db4700eb2a9d 100644 --- a/apps/files/l10n/ia.js +++ b/apps/files/l10n/ia.js @@ -37,6 +37,10 @@ OC.L10N.register( "Save" : "Salveguardar", "Settings" : "Configurationes", "Upload too large" : "Incargamento troppo longe", - "Text file" : "File de texto" + "Text file" : "File de texto", + "You changed %1$s" : "Tu modificava %1$s", + "You created %1$s" : "Tu creava %1$s", + "You deleted %1$s" : "Tu deleva %1$s", + "You restored %1$s" : "Tu restabiliva %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ia.json b/apps/files/l10n/ia.json index eee4980e34aed..89c450e996e42 100644 --- a/apps/files/l10n/ia.json +++ b/apps/files/l10n/ia.json @@ -35,6 +35,10 @@ "Save" : "Salveguardar", "Settings" : "Configurationes", "Upload too large" : "Incargamento troppo longe", - "Text file" : "File de texto" + "Text file" : "File de texto", + "You changed %1$s" : "Tu modificava %1$s", + "You created %1$s" : "Tu creava %1$s", + "You deleted %1$s" : "Tu deleva %1$s", + "You restored %1$s" : "Tu restabiliva %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/id.js b/apps/files/l10n/id.js index c67a74e43da5d..30d910dcc227c 100644 --- a/apps/files/l10n/id.js +++ b/apps/files/l10n/id.js @@ -103,6 +103,13 @@ OC.L10N.register( "No favorites" : "Tidak ada favorit", "Files and folders you mark as favorite will show up here" : "Berkas dan folder yang Anda tandai sebagai favorit akan ditampilkan disini.", "Text file" : "Berkas teks", - "New text file.txt" : "Teks baru file.txt" + "New text file.txt" : "Teks baru file.txt", + "Changed by %2$s" : "Diubah oleh %2$s", + "Deleted by %2$s" : "Dihapus oleh %2$s", + "Restored by %2$s" : "Dipulihkan oleh %2$s", + "You changed %1$s" : "Anda mengubah %1$s", + "You created %1$s" : "Anda membuat %1$s", + "You deleted %1$s" : "Anda menghapus %1$s", + "You restored %1$s" : "Anda memulihkan %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/id.json b/apps/files/l10n/id.json index 68f01e0393a58..88cb98f7ad083 100644 --- a/apps/files/l10n/id.json +++ b/apps/files/l10n/id.json @@ -101,6 +101,13 @@ "No favorites" : "Tidak ada favorit", "Files and folders you mark as favorite will show up here" : "Berkas dan folder yang Anda tandai sebagai favorit akan ditampilkan disini.", "Text file" : "Berkas teks", - "New text file.txt" : "Teks baru file.txt" + "New text file.txt" : "Teks baru file.txt", + "Changed by %2$s" : "Diubah oleh %2$s", + "Deleted by %2$s" : "Dihapus oleh %2$s", + "Restored by %2$s" : "Dipulihkan oleh %2$s", + "You changed %1$s" : "Anda mengubah %1$s", + "You created %1$s" : "Anda membuat %1$s", + "You deleted %1$s" : "Anda menghapus %1$s", + "You restored %1$s" : "Anda memulihkan %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/is.js b/apps/files/l10n/is.js index 15c0ee0f6fe86..a66a514d175b9 100644 --- a/apps/files/l10n/is.js +++ b/apps/files/l10n/is.js @@ -71,6 +71,21 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Skrárnar sem þú ert að senda inn eru stærri en hámarks innsendingarstærð á þessum netþjóni.", "No favorites" : "Engin eftirlæti", "Text file" : "Textaskrá", - "New text file.txt" : "Ný textaskrá.txt" + "New text file.txt" : "Ný textaskrá.txt", + "An error occurred while trying to update the tags" : "Villa kom upp við að reyna að uppfæra merkin", + "Changed by %2$s" : "Breytt af %2$s", + "Deleted by %2$s" : "Eytt af %2$s", + "Files and folders you mark as favorite will show up here" : "Skrár og möppur sem þú merkir sem uppáhald birtast hér", + "Not enough free space, you are uploading {size1} but only {size2} is left" : "Ekki nægilegt laust pláss, þú ert að senda inn {size1} en einungis {size2} eru eftir", + "Not enough storage available" : "Ekki er nægilegt geymslupláss tiltækt", + "Restored by %2$s" : "Endurheimt af %2$s", + "Storage invalid" : "Ógild geymsla", + "Storage not available" : "Geymsla ekki tiltæk", + "Unable to upload {filename} as it is a directory or has 0 bytes" : "Tókst ekki að hlaða inn {filename} þar sem þetta er mappa eða er 0 bæti", + "Upload failed. Could not find uploaded file" : "Innsending mistókst. Fann ekki innsendu skrána", + "You changed %1$s" : "Þú breyttir %1$s", + "You created %1$s" : "Þú bjóst til %1$s", + "You deleted %1$s" : "Þú eyddir %1$s", + "You restored %1$s" : "Þú endurheimtir %1$s" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/files/l10n/is.json b/apps/files/l10n/is.json index 240b5b2b7b41b..0b0dd8d6b70a0 100644 --- a/apps/files/l10n/is.json +++ b/apps/files/l10n/is.json @@ -69,6 +69,21 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Skrárnar sem þú ert að senda inn eru stærri en hámarks innsendingarstærð á þessum netþjóni.", "No favorites" : "Engin eftirlæti", "Text file" : "Textaskrá", - "New text file.txt" : "Ný textaskrá.txt" + "New text file.txt" : "Ný textaskrá.txt", + "An error occurred while trying to update the tags" : "Villa kom upp við að reyna að uppfæra merkin", + "Changed by %2$s" : "Breytt af %2$s", + "Deleted by %2$s" : "Eytt af %2$s", + "Files and folders you mark as favorite will show up here" : "Skrár og möppur sem þú merkir sem uppáhald birtast hér", + "Not enough free space, you are uploading {size1} but only {size2} is left" : "Ekki nægilegt laust pláss, þú ert að senda inn {size1} en einungis {size2} eru eftir", + "Not enough storage available" : "Ekki er nægilegt geymslupláss tiltækt", + "Restored by %2$s" : "Endurheimt af %2$s", + "Storage invalid" : "Ógild geymsla", + "Storage not available" : "Geymsla ekki tiltæk", + "Unable to upload {filename} as it is a directory or has 0 bytes" : "Tókst ekki að hlaða inn {filename} þar sem þetta er mappa eða er 0 bæti", + "Upload failed. Could not find uploaded file" : "Innsending mistókst. Fann ekki innsendu skrána", + "You changed %1$s" : "Þú breyttir %1$s", + "You created %1$s" : "Þú bjóst til %1$s", + "You deleted %1$s" : "Þú eyddir %1$s", + "You restored %1$s" : "Þú endurheimtir %1$s" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/files/l10n/it.js b/apps/files/l10n/it.js index e6072997b2d54..13e11a00443f9 100644 --- a/apps/files/l10n/it.js +++ b/apps/files/l10n/it.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Nessun preferito", "Files and folders you mark as favorite will show up here" : "I file e le cartelle che marchi come preferiti saranno mostrati qui", "Text file" : "File di testo", - "New text file.txt" : "Nuovo file di testo.txt" + "New text file.txt" : "Nuovo file di testo.txt", + "Changed by %2$s" : "Modificata da %2$s", + "Deleted by %2$s" : "Eliminata da %2$s", + "Restored by %2$s" : "Ripristinata da %2$s", + "You changed %1$s" : "Hai modificato %1$s", + "You created %1$s" : "Hai creato %1$s", + "You deleted %1$s" : "Hai eliminato %1$s", + "You restored %1$s" : "Hai ripristinato %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/it.json b/apps/files/l10n/it.json index f81affd9038c1..b249a7939a8b1 100644 --- a/apps/files/l10n/it.json +++ b/apps/files/l10n/it.json @@ -115,6 +115,13 @@ "No favorites" : "Nessun preferito", "Files and folders you mark as favorite will show up here" : "I file e le cartelle che marchi come preferiti saranno mostrati qui", "Text file" : "File di testo", - "New text file.txt" : "Nuovo file di testo.txt" + "New text file.txt" : "Nuovo file di testo.txt", + "Changed by %2$s" : "Modificata da %2$s", + "Deleted by %2$s" : "Eliminata da %2$s", + "Restored by %2$s" : "Ripristinata da %2$s", + "You changed %1$s" : "Hai modificato %1$s", + "You created %1$s" : "Hai creato %1$s", + "You deleted %1$s" : "Hai eliminato %1$s", + "You restored %1$s" : "Hai ripristinato %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ja.js b/apps/files/l10n/ja.js index 4280375b46ee2..b5e44eb232891 100644 --- a/apps/files/l10n/ja.js +++ b/apps/files/l10n/ja.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "お気に入りなし", "Files and folders you mark as favorite will show up here" : "お気に入りに登録されたファイルやフォルダーは、ここに表示されます。", "Text file" : "テキストファイル", - "New text file.txt" : "新規のテキストファイル作成" + "New text file.txt" : "新規のテキストファイル作成", + "Changed by %2$s" : "%2$s により更新", + "Deleted by %2$s" : "%2$s により削除", + "Restored by %2$s" : "%2$s により復元", + "You changed %1$s" : "あなたは %1$s を変更しました", + "You created %1$s" : "あなたは %1$s を作成しました", + "You deleted %1$s" : "あなたは %1$s を削除しました", + "You restored %1$s" : "%1$s を復元しました" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ja.json b/apps/files/l10n/ja.json index 674a315595492..7f092b8fd815c 100644 --- a/apps/files/l10n/ja.json +++ b/apps/files/l10n/ja.json @@ -115,6 +115,13 @@ "No favorites" : "お気に入りなし", "Files and folders you mark as favorite will show up here" : "お気に入りに登録されたファイルやフォルダーは、ここに表示されます。", "Text file" : "テキストファイル", - "New text file.txt" : "新規のテキストファイル作成" + "New text file.txt" : "新規のテキストファイル作成", + "Changed by %2$s" : "%2$s により更新", + "Deleted by %2$s" : "%2$s により削除", + "Restored by %2$s" : "%2$s により復元", + "You changed %1$s" : "あなたは %1$s を変更しました", + "You created %1$s" : "あなたは %1$s を作成しました", + "You deleted %1$s" : "あなたは %1$s を削除しました", + "You restored %1$s" : "%1$s を復元しました" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/ka_GE.js b/apps/files/l10n/ka_GE.js index c54da5a206d10..bd1baa73ba386 100644 --- a/apps/files/l10n/ka_GE.js +++ b/apps/files/l10n/ka_GE.js @@ -45,6 +45,7 @@ OC.L10N.register( "Cancel upload" : "ატვირთვის გაუქმება", "Upload too large" : "ასატვირთი ფაილი ძალიან დიდია", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ფაილის ზომა რომლის ატვირთვასაც თქვენ აპირებთ, აჭარბებს სერვერზე დაშვებულ მაქსიმუმს.", - "Text file" : "ტექსტური ფაილი" + "Text file" : "ტექსტური ფაილი", + "Upload cancelled." : "ატვირთვა შეჩერებულ იქნა." }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ka_GE.json b/apps/files/l10n/ka_GE.json index cdc9cd03126d2..b377cdfaeca41 100644 --- a/apps/files/l10n/ka_GE.json +++ b/apps/files/l10n/ka_GE.json @@ -43,6 +43,7 @@ "Cancel upload" : "ატვირთვის გაუქმება", "Upload too large" : "ასატვირთი ფაილი ძალიან დიდია", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ფაილის ზომა რომლის ატვირთვასაც თქვენ აპირებთ, აჭარბებს სერვერზე დაშვებულ მაქსიმუმს.", - "Text file" : "ტექსტური ფაილი" + "Text file" : "ტექსტური ფაილი", + "Upload cancelled." : "ატვირთვა შეჩერებულ იქნა." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/km.js b/apps/files/l10n/km.js index 55080926fc36b..1089f0bde7440 100644 --- a/apps/files/l10n/km.js +++ b/apps/files/l10n/km.js @@ -33,6 +33,10 @@ OC.L10N.register( "WebDAV" : "WebDAV", "Cancel upload" : "បោះបង់​ការ​ផ្ទុកឡើង", "Upload too large" : "ផ្ទុក​ឡើង​ធំ​ពេក", - "Text file" : "ឯកសារ​អក្សរ" + "Text file" : "ឯកសារ​អក្សរ", + "Upload cancelled." : "បាន​បោះបង់​ការ​ផ្ទុក​ឡើង។", + "You changed %1$s" : "អ្នក​បាន​ផ្លាស់​ប្ដូរ %1$s", + "You created %1$s" : "អ្នក​បាន​បង្កើត %1$s", + "You deleted %1$s" : "អ្នក​បាន​លុប %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/km.json b/apps/files/l10n/km.json index c1e9159ee88ac..2c46f4287f084 100644 --- a/apps/files/l10n/km.json +++ b/apps/files/l10n/km.json @@ -31,6 +31,10 @@ "WebDAV" : "WebDAV", "Cancel upload" : "បោះបង់​ការ​ផ្ទុកឡើង", "Upload too large" : "ផ្ទុក​ឡើង​ធំ​ពេក", - "Text file" : "ឯកសារ​អក្សរ" + "Text file" : "ឯកសារ​អក្សរ", + "Upload cancelled." : "បាន​បោះបង់​ការ​ផ្ទុក​ឡើង។", + "You changed %1$s" : "អ្នក​បាន​ផ្លាស់​ប្ដូរ %1$s", + "You created %1$s" : "អ្នក​បាន​បង្កើត %1$s", + "You deleted %1$s" : "អ្នក​បាន​លុប %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/kn.js b/apps/files/l10n/kn.js index 1e97d7ffa7967..66f5a07e0aa21 100644 --- a/apps/files/l10n/kn.js +++ b/apps/files/l10n/kn.js @@ -57,6 +57,7 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ನೀವು ವರ್ಗಾಯಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವ ಕಡತಗಳ ಗಾತ್ರ, ಈ ಗಣಕ ಕೋಶದ ಗರಿಷ್ಠ ಕಡತ ಮೀತಿಯಾನ್ನು ಮೀರುವಂತಿಲ್ಲ.", "No favorites" : "ಯಾವ ಅಚ್ಚುಮೆಚ್ಚಿನವುಗಳು ಇಲ್ಲ", "Files and folders you mark as favorite will show up here" : "ನೀವು ಗುರುತು ಮಾಡಿರುವ ನೆಚ್ಚಿನ ಕಡತ ಮತ್ತು ಕಡತಕೋಶಗಳನ್ನು ಇಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತಿದೆ", - "Text file" : "ಸರಳಾಕ್ಷರದ ಕಡತ" + "Text file" : "ಸರಳಾಕ್ಷರದ ಕಡತ", + "Upload cancelled." : "ವರ್ಗಾವಣೆಯನ್ನು ರದ್ದು ಮಾಡಲಾಯಿತು." }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/kn.json b/apps/files/l10n/kn.json index 9ebd3cb619b12..376562dc3b32f 100644 --- a/apps/files/l10n/kn.json +++ b/apps/files/l10n/kn.json @@ -55,6 +55,7 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ನೀವು ವರ್ಗಾಯಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತಿರುವ ಕಡತಗಳ ಗಾತ್ರ, ಈ ಗಣಕ ಕೋಶದ ಗರಿಷ್ಠ ಕಡತ ಮೀತಿಯಾನ್ನು ಮೀರುವಂತಿಲ್ಲ.", "No favorites" : "ಯಾವ ಅಚ್ಚುಮೆಚ್ಚಿನವುಗಳು ಇಲ್ಲ", "Files and folders you mark as favorite will show up here" : "ನೀವು ಗುರುತು ಮಾಡಿರುವ ನೆಚ್ಚಿನ ಕಡತ ಮತ್ತು ಕಡತಕೋಶಗಳನ್ನು ಇಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತಿದೆ", - "Text file" : "ಸರಳಾಕ್ಷರದ ಕಡತ" + "Text file" : "ಸರಳಾಕ್ಷರದ ಕಡತ", + "Upload cancelled." : "ವರ್ಗಾವಣೆಯನ್ನು ರದ್ದು ಮಾಡಲಾಯಿತು." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/ko.js b/apps/files/l10n/ko.js index 3bac96b5eb870..68895e0355956 100644 --- a/apps/files/l10n/ko.js +++ b/apps/files/l10n/ko.js @@ -103,6 +103,13 @@ OC.L10N.register( "No favorites" : "책갈피 없음", "Files and folders you mark as favorite will show up here" : "책갈피에 추가한 파일과 폴더가 여기에 나타납니다", "Text file" : "텍스트 파일", - "New text file.txt" : "새 텍스트 파일.txt" + "New text file.txt" : "새 텍스트 파일.txt", + "Changed by %2$s" : "%2$s 님이 변경함", + "Deleted by %2$s" : "%2$s 님이 삭제함", + "Restored by %2$s" : "%2$s 님이 복원함", + "You changed %1$s" : "내가 %1$s을(를) 변경함", + "You created %1$s" : "내가 %1$s을(를) 생성함", + "You deleted %1$s" : "내가 %1$s을(를) 삭제함", + "You restored %1$s" : "내가 %1$s을(를) 복원함" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ko.json b/apps/files/l10n/ko.json index e42745fc8b451..4f3738f248e37 100644 --- a/apps/files/l10n/ko.json +++ b/apps/files/l10n/ko.json @@ -101,6 +101,13 @@ "No favorites" : "책갈피 없음", "Files and folders you mark as favorite will show up here" : "책갈피에 추가한 파일과 폴더가 여기에 나타납니다", "Text file" : "텍스트 파일", - "New text file.txt" : "새 텍스트 파일.txt" + "New text file.txt" : "새 텍스트 파일.txt", + "Changed by %2$s" : "%2$s 님이 변경함", + "Deleted by %2$s" : "%2$s 님이 삭제함", + "Restored by %2$s" : "%2$s 님이 복원함", + "You changed %1$s" : "내가 %1$s을(를) 변경함", + "You created %1$s" : "내가 %1$s을(를) 생성함", + "You deleted %1$s" : "내가 %1$s을(를) 삭제함", + "You restored %1$s" : "내가 %1$s을(를) 복원함" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/lb.js b/apps/files/l10n/lb.js index c6ee76819ec39..564e9098a5428 100644 --- a/apps/files/l10n/lb.js +++ b/apps/files/l10n/lb.js @@ -37,6 +37,7 @@ OC.L10N.register( "Select all" : "All auswielen", "Upload too large" : "Upload ze grouss", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Déi Dateien déi Dir probéiert erop ze lueden sinn méi grouss wei déi Maximal Gréisst déi op dësem Server erlaabt ass.", - "Text file" : "Text Fichier" + "Text file" : "Text Fichier", + "Upload cancelled." : "Upload ofgebrach." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/lb.json b/apps/files/l10n/lb.json index 5928959971995..2404c21868422 100644 --- a/apps/files/l10n/lb.json +++ b/apps/files/l10n/lb.json @@ -35,6 +35,7 @@ "Select all" : "All auswielen", "Upload too large" : "Upload ze grouss", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Déi Dateien déi Dir probéiert erop ze lueden sinn méi grouss wei déi Maximal Gréisst déi op dësem Server erlaabt ass.", - "Text file" : "Text Fichier" + "Text file" : "Text Fichier", + "Upload cancelled." : "Upload ofgebrach." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/lt_LT.js b/apps/files/l10n/lt_LT.js index 6e33b1ac7ccd5..9a3bd9472231d 100644 --- a/apps/files/l10n/lt_LT.js +++ b/apps/files/l10n/lt_LT.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Nėra mėgstamiausių", "Files and folders you mark as favorite will show up here" : "Failai ir aplankai, kuriuos pažymite mėgstamais, atsiras čia", "Text file" : "Teksto failas", - "New text file.txt" : "Naujas tekstas file.txt" + "New text file.txt" : "Naujas tekstas file.txt", + "Changed by %2$s" : "Pakeitė %2$s", + "Deleted by %2$s" : "Ištrynė %2$s", + "Restored by %2$s" : "Atkūrė %2$s", + "You changed %1$s" : "Jūs pakeitėte %1$s", + "You created %1$s" : "Jūs sukūrėte %1$s", + "You deleted %1$s" : "Jūs ištrynėte %1$s", + "You restored %1$s" : "Jūs atkūrėte %1$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files/l10n/lt_LT.json b/apps/files/l10n/lt_LT.json index 0d32d1dbb2aca..a368c5725c408 100644 --- a/apps/files/l10n/lt_LT.json +++ b/apps/files/l10n/lt_LT.json @@ -114,6 +114,13 @@ "No favorites" : "Nėra mėgstamiausių", "Files and folders you mark as favorite will show up here" : "Failai ir aplankai, kuriuos pažymite mėgstamais, atsiras čia", "Text file" : "Teksto failas", - "New text file.txt" : "Naujas tekstas file.txt" + "New text file.txt" : "Naujas tekstas file.txt", + "Changed by %2$s" : "Pakeitė %2$s", + "Deleted by %2$s" : "Ištrynė %2$s", + "Restored by %2$s" : "Atkūrė %2$s", + "You changed %1$s" : "Jūs pakeitėte %1$s", + "You created %1$s" : "Jūs sukūrėte %1$s", + "You deleted %1$s" : "Jūs ištrynėte %1$s", + "You restored %1$s" : "Jūs atkūrėte %1$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/lv.js b/apps/files/l10n/lv.js index f5533fd899587..2e511bc884615 100644 --- a/apps/files/l10n/lv.js +++ b/apps/files/l10n/lv.js @@ -90,6 +90,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Augšupielādējamās datnes pārsniedz servera pieļaujamo datņu augšupielādes apjomu", "No favorites" : "Nav favorītu", "Files and folders you mark as favorite will show up here" : "Faili un mapes, ko atzīmēsit kā favorītus, tiks rādīti šeit", - "Text file" : "Teksta datne" + "Text file" : "Teksta datne", + "You changed %1$s" : "Tu izmainīji %1$s", + "You created %1$s" : "Tu izveidoji %1$s", + "You deleted %1$s" : "Tu izdzēsi %1$s", + "You restored %1$s" : "Tu atjaunoji %1$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/apps/files/l10n/lv.json b/apps/files/l10n/lv.json index 18189049ed864..05ee037488419 100644 --- a/apps/files/l10n/lv.json +++ b/apps/files/l10n/lv.json @@ -88,6 +88,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Augšupielādējamās datnes pārsniedz servera pieļaujamo datņu augšupielādes apjomu", "No favorites" : "Nav favorītu", "Files and folders you mark as favorite will show up here" : "Faili un mapes, ko atzīmēsit kā favorītus, tiks rādīti šeit", - "Text file" : "Teksta datne" + "Text file" : "Teksta datne", + "You changed %1$s" : "Tu izmainīji %1$s", + "You created %1$s" : "Tu izveidoji %1$s", + "You deleted %1$s" : "Tu izdzēsi %1$s", + "You restored %1$s" : "Tu atjaunoji %1$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/mk.js b/apps/files/l10n/mk.js index ec8387af0f6c5..1b8b1fd51bff6 100644 --- a/apps/files/l10n/mk.js +++ b/apps/files/l10n/mk.js @@ -75,6 +75,12 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Датотеките кои се обидувате да ги подигнете ја надминуваат максималната големина за подигнување датотеки на овој сервер.", "Files and folders you mark as favorite will show up here" : "Датотеките и папките кои ќе ги означите како чести, ќе се појават тука", "Text file" : "Текстуална датотека", - "New text file.txt" : "Нова текстуална датотека file.txt" + "New text file.txt" : "Нова текстуална датотека file.txt", + "Changed by %2$s" : "Променето од %2$s", + "Deleted by %2$s" : "Избришано од %2$s", + "Restored by %2$s" : "Повратено од %2$s", + "You changed %1$s" : "Вие изменивте %1$s", + "You created %1$s" : "Вие креиравте %1$s", + "You deleted %1$s" : "Вие избришавте %1$s" }, "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); diff --git a/apps/files/l10n/mk.json b/apps/files/l10n/mk.json index e587f4883efe8..aeeef59f6715e 100644 --- a/apps/files/l10n/mk.json +++ b/apps/files/l10n/mk.json @@ -73,6 +73,12 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Датотеките кои се обидувате да ги подигнете ја надминуваат максималната големина за подигнување датотеки на овој сервер.", "Files and folders you mark as favorite will show up here" : "Датотеките и папките кои ќе ги означите како чести, ќе се појават тука", "Text file" : "Текстуална датотека", - "New text file.txt" : "Нова текстуална датотека file.txt" + "New text file.txt" : "Нова текстуална датотека file.txt", + "Changed by %2$s" : "Променето од %2$s", + "Deleted by %2$s" : "Избришано од %2$s", + "Restored by %2$s" : "Повратено од %2$s", + "You changed %1$s" : "Вие изменивте %1$s", + "You created %1$s" : "Вие креиравте %1$s", + "You deleted %1$s" : "Вие избришавте %1$s" },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" } \ No newline at end of file diff --git a/apps/files/l10n/ml_IN.js b/apps/files/l10n/ml_IN.js index adce75dad9ae8..f166aa52c29c0 100644 --- a/apps/files/l10n/ml_IN.js +++ b/apps/files/l10n/ml_IN.js @@ -7,6 +7,9 @@ OC.L10N.register( "You changed %1$s" : "നിങ്ങൾ %1$s പരിഷ്കരിച്ചു", "%2$s changed %1$s" : "%2$s %1$s പരിഷ്കരിച്ചു", "You deleted %1$s" : "നിങ്ങൾ %1$s മായ്ച്ചു", - "%2$s deleted %1$s" : "%2$s %1$s മായ്ച്ചു" + "%2$s deleted %1$s" : "%2$s %1$s മായ്ച്ചു", + "You changed %1$s" : "നിങ്ങൾ %1$s പരിഷ്കരിച്ചു", + "You created %1$s" : "നിങ്ങൾ %1$s സൃഷ്ടിച്ചു", + "You deleted %1$s" : "നിങ്ങൾ %1$s മായ്ച്ചു" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ml_IN.json b/apps/files/l10n/ml_IN.json index 4df39836aaaaf..0138842a20e5c 100644 --- a/apps/files/l10n/ml_IN.json +++ b/apps/files/l10n/ml_IN.json @@ -5,6 +5,9 @@ "You changed %1$s" : "നിങ്ങൾ %1$s പരിഷ്കരിച്ചു", "%2$s changed %1$s" : "%2$s %1$s പരിഷ്കരിച്ചു", "You deleted %1$s" : "നിങ്ങൾ %1$s മായ്ച്ചു", - "%2$s deleted %1$s" : "%2$s %1$s മായ്ച്ചു" + "%2$s deleted %1$s" : "%2$s %1$s മായ്ച്ചു", + "You changed %1$s" : "നിങ്ങൾ %1$s പരിഷ്കരിച്ചു", + "You created %1$s" : "നിങ്ങൾ %1$s സൃഷ്ടിച്ചു", + "You deleted %1$s" : "നിങ്ങൾ %1$s മായ്ച്ചു" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/mn.js b/apps/files/l10n/mn.js index 994f002b48c71..684cf73ddc47e 100644 --- a/apps/files/l10n/mn.js +++ b/apps/files/l10n/mn.js @@ -17,6 +17,10 @@ OC.L10N.register( "You restored %1$s" : "Та %1$s-ийг сэргээлээ", "%2$s restored %1$s" : "%2$s %1$s-ийг сэргээлээ", "Save" : "Хадгалах", - "Settings" : "Тохиргоо" + "Settings" : "Тохиргоо", + "You changed %1$s" : "Та %1$s-ийг өөрчиллөө", + "You created %1$s" : "Та %1$s үүсгэлээ", + "You deleted %1$s" : "Та %1$s-ийг устгалаа", + "You restored %1$s" : "Та %1$s-ийг сэргээлээ" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/mn.json b/apps/files/l10n/mn.json index f1b58c7e13f3c..870ac0e094925 100644 --- a/apps/files/l10n/mn.json +++ b/apps/files/l10n/mn.json @@ -15,6 +15,10 @@ "You restored %1$s" : "Та %1$s-ийг сэргээлээ", "%2$s restored %1$s" : "%2$s %1$s-ийг сэргээлээ", "Save" : "Хадгалах", - "Settings" : "Тохиргоо" + "Settings" : "Тохиргоо", + "You changed %1$s" : "Та %1$s-ийг өөрчиллөө", + "You created %1$s" : "Та %1$s үүсгэлээ", + "You deleted %1$s" : "Та %1$s-ийг устгалаа", + "You restored %1$s" : "Та %1$s-ийг сэргээлээ" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ms_MY.js b/apps/files/l10n/ms_MY.js index dcd0c8e15e8ce..9a8a9d94ad172 100644 --- a/apps/files/l10n/ms_MY.js +++ b/apps/files/l10n/ms_MY.js @@ -33,6 +33,9 @@ OC.L10N.register( "Cancel upload" : "Batal muat naik", "Upload too large" : "Muatnaik terlalu besar", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fail yang cuba dimuat naik melebihi saiz maksimum fail upload server", - "Text file" : "Fail teks" + "Text file" : "Fail teks", + "Upload cancelled." : "Muatnaik dibatalkan.", + "You changed %1$s" : "Anda menukar %1$s", + "You created %1$s" : "Anda telah membina %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ms_MY.json b/apps/files/l10n/ms_MY.json index 6f7b93d6ef123..ae50f27fb9d47 100644 --- a/apps/files/l10n/ms_MY.json +++ b/apps/files/l10n/ms_MY.json @@ -31,6 +31,9 @@ "Cancel upload" : "Batal muat naik", "Upload too large" : "Muatnaik terlalu besar", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fail yang cuba dimuat naik melebihi saiz maksimum fail upload server", - "Text file" : "Fail teks" + "Text file" : "Fail teks", + "Upload cancelled." : "Muatnaik dibatalkan.", + "You changed %1$s" : "Anda menukar %1$s", + "You created %1$s" : "Anda telah membina %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/nb_NO.js b/apps/files/l10n/nb_NO.js index 4b4a9e192737a..761f69880b4c4 100644 --- a/apps/files/l10n/nb_NO.js +++ b/apps/files/l10n/nb_NO.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Ingen favoritter", "Files and folders you mark as favorite will show up here" : "Filer og mapper som du gjør til favoritter vises her", "Text file" : "Tekstfil", - "New text file.txt" : "Ny tekstfil.txt" + "New text file.txt" : "Ny tekstfil.txt", + "Changed by %2$s" : "Endret av %2$s", + "Deleted by %2$s" : "Slettet av %2$s", + "Restored by %2$s" : "Gjenopprettet av %2$s", + "You changed %1$s" : "Du endret %1$s", + "You created %1$s" : "Du opprettet %1$s", + "You deleted %1$s" : "Du slettet %1$s", + "You restored %1$s" : "Du gjenopprettet %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/nb_NO.json b/apps/files/l10n/nb_NO.json index f3b0021dbbf28..10b412609df08 100644 --- a/apps/files/l10n/nb_NO.json +++ b/apps/files/l10n/nb_NO.json @@ -115,6 +115,13 @@ "No favorites" : "Ingen favoritter", "Files and folders you mark as favorite will show up here" : "Filer og mapper som du gjør til favoritter vises her", "Text file" : "Tekstfil", - "New text file.txt" : "Ny tekstfil.txt" + "New text file.txt" : "Ny tekstfil.txt", + "Changed by %2$s" : "Endret av %2$s", + "Deleted by %2$s" : "Slettet av %2$s", + "Restored by %2$s" : "Gjenopprettet av %2$s", + "You changed %1$s" : "Du endret %1$s", + "You created %1$s" : "Du opprettet %1$s", + "You deleted %1$s" : "Du slettet %1$s", + "You restored %1$s" : "Du gjenopprettet %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/nl.js b/apps/files/l10n/nl.js index 79c4940072347..c43d5fa245788 100644 --- a/apps/files/l10n/nl.js +++ b/apps/files/l10n/nl.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Geen favorieten", "Files and folders you mark as favorite will show up here" : "Bestanden en mappen die u favoriet vindt worden hier getoont", "Text file" : "Tekstbestand", - "New text file.txt" : "Nieuw tekstbestand.txt" + "New text file.txt" : "Nieuw tekstbestand.txt", + "Changed by %2$s" : "Gewijzigd door %2$s", + "Deleted by %2$s" : "Verwijderd door %2$s", + "Restored by %2$s" : "Hersteld door %2$s", + "You changed %1$s" : "Gewijzigd: %1$s", + "You created %1$s" : "Gecreëerd: %1$s", + "You deleted %1$s" : "Verwijderd: %1$s", + "You restored %1$s" : "Hersteld: %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/nl.json b/apps/files/l10n/nl.json index 9cf0326d21680..12d05e75fe09b 100644 --- a/apps/files/l10n/nl.json +++ b/apps/files/l10n/nl.json @@ -114,6 +114,13 @@ "No favorites" : "Geen favorieten", "Files and folders you mark as favorite will show up here" : "Bestanden en mappen die u favoriet vindt worden hier getoont", "Text file" : "Tekstbestand", - "New text file.txt" : "Nieuw tekstbestand.txt" + "New text file.txt" : "Nieuw tekstbestand.txt", + "Changed by %2$s" : "Gewijzigd door %2$s", + "Deleted by %2$s" : "Verwijderd door %2$s", + "Restored by %2$s" : "Hersteld door %2$s", + "You changed %1$s" : "Gewijzigd: %1$s", + "You created %1$s" : "Gecreëerd: %1$s", + "You deleted %1$s" : "Verwijderd: %1$s", + "You restored %1$s" : "Hersteld: %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/nn_NO.js b/apps/files/l10n/nn_NO.js index 1e138d91b850c..97648a1440e12 100644 --- a/apps/files/l10n/nn_NO.js +++ b/apps/files/l10n/nn_NO.js @@ -65,6 +65,9 @@ OC.L10N.register( "Cancel upload" : "Avbryt opplasting", "Upload too large" : "For stor opplasting", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Filene du prøver å lasta opp er større enn maksgrensa til denne tenaren.", - "Text file" : "Tekst fil" + "Text file" : "Tekst fil", + "You changed %1$s" : "Du endra %1$s", + "You created %1$s" : "Du oppretta %1$s", + "You deleted %1$s" : "Du sletta %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/nn_NO.json b/apps/files/l10n/nn_NO.json index 5645a61b6bc6e..8d65e4f102da0 100644 --- a/apps/files/l10n/nn_NO.json +++ b/apps/files/l10n/nn_NO.json @@ -63,6 +63,9 @@ "Cancel upload" : "Avbryt opplasting", "Upload too large" : "For stor opplasting", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Filene du prøver å lasta opp er større enn maksgrensa til denne tenaren.", - "Text file" : "Tekst fil" + "Text file" : "Tekst fil", + "You changed %1$s" : "Du endra %1$s", + "You created %1$s" : "Du oppretta %1$s", + "You deleted %1$s" : "Du sletta %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/oc.js b/apps/files/l10n/oc.js index 6fde5981b126d..f6f1a3b7ceb11 100644 --- a/apps/files/l10n/oc.js +++ b/apps/files/l10n/oc.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Pas cap de favorit", "Files and folders you mark as favorite will show up here" : "Los fichièrs e dorsièrs aponduts a vòstres favorits apareisseràn aicí", "Text file" : "Fichièr tèxte", - "New text file.txt" : "Novèl fichièr tèxte .txt" + "New text file.txt" : "Novèl fichièr tèxte .txt", + "Changed by %2$s" : "Modificat per %2$s", + "Deleted by %2$s" : "Suprimit per %2$s", + "Restored by %2$s" : "Restablit per %2$s", + "You changed %1$s" : "Avètz modificat %1$s", + "You created %1$s" : "Avètz creat %1$s", + "You deleted %1$s" : "Avètz suprimit %1$s", + "You restored %1$s" : "Avètz restablit %1$s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/oc.json b/apps/files/l10n/oc.json index 37b2fc5f45292..8e85c37fe5344 100644 --- a/apps/files/l10n/oc.json +++ b/apps/files/l10n/oc.json @@ -114,6 +114,13 @@ "No favorites" : "Pas cap de favorit", "Files and folders you mark as favorite will show up here" : "Los fichièrs e dorsièrs aponduts a vòstres favorits apareisseràn aicí", "Text file" : "Fichièr tèxte", - "New text file.txt" : "Novèl fichièr tèxte .txt" + "New text file.txt" : "Novèl fichièr tèxte .txt", + "Changed by %2$s" : "Modificat per %2$s", + "Deleted by %2$s" : "Suprimit per %2$s", + "Restored by %2$s" : "Restablit per %2$s", + "You changed %1$s" : "Avètz modificat %1$s", + "You created %1$s" : "Avètz creat %1$s", + "You deleted %1$s" : "Avètz suprimit %1$s", + "You restored %1$s" : "Avètz restablit %1$s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files/l10n/pl.js b/apps/files/l10n/pl.js index e28b7bc25810a..c0fa90c7bfabd 100644 --- a/apps/files/l10n/pl.js +++ b/apps/files/l10n/pl.js @@ -87,6 +87,14 @@ OC.L10N.register( "Select all" : "Wybierz wszystko", "Upload too large" : "Ładowany plik jest za duży", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Pliki, które próbujesz przesłać, przekraczają maksymalną dopuszczalną wielkość.", - "Text file" : "Plik tekstowy" + "Text file" : "Plik tekstowy", + "Changed by %2$s" : "Zmienione przez %2$s", + "New text file.txt" : "Nowy plik tekstowy.txt", + "No files in here" : "Brak plików", + "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem.", + "You changed %1$s" : "Zmieniłeś %1$s", + "You created %1$s" : "Utworzyłeś %1$s", + "You deleted %1$s" : "Usunąłeś %1$s", + "You restored %1$s" : "Przywróciłeś %1$s" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files/l10n/pl.json b/apps/files/l10n/pl.json index 314caeb807ada..eb63aec73a778 100644 --- a/apps/files/l10n/pl.json +++ b/apps/files/l10n/pl.json @@ -85,6 +85,14 @@ "Select all" : "Wybierz wszystko", "Upload too large" : "Ładowany plik jest za duży", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Pliki, które próbujesz przesłać, przekraczają maksymalną dopuszczalną wielkość.", - "Text file" : "Plik tekstowy" + "Text file" : "Plik tekstowy", + "Changed by %2$s" : "Zmienione przez %2$s", + "New text file.txt" : "Nowy plik tekstowy.txt", + "No files in here" : "Brak plików", + "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem.", + "You changed %1$s" : "Zmieniłeś %1$s", + "You created %1$s" : "Utworzyłeś %1$s", + "You deleted %1$s" : "Usunąłeś %1$s", + "You restored %1$s" : "Przywróciłeś %1$s" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/pt_BR.js b/apps/files/l10n/pt_BR.js index 4af02942fb18b..6fc71f11a1ce3 100644 --- a/apps/files/l10n/pt_BR.js +++ b/apps/files/l10n/pt_BR.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Sem favoritos", "Files and folders you mark as favorite will show up here" : "Arquivos e pastas que você marcou como favoritos são mostrados aqui", "Text file" : "Arquivo texto", - "New text file.txt" : "Novo texto file.txt" + "New text file.txt" : "Novo texto file.txt", + "Changed by %2$s" : "Modificado por %2$s", + "Deleted by %2$s" : "Deletado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Você modificou %1$s", + "You created %1$s" : "Você criou %1$s", + "You deleted %1$s" : "Você excluiu %1$s ", + "You restored %1$s" : "Você restaurou %1$s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/pt_BR.json b/apps/files/l10n/pt_BR.json index 71ca647a90d0c..49393299c1f77 100644 --- a/apps/files/l10n/pt_BR.json +++ b/apps/files/l10n/pt_BR.json @@ -115,6 +115,13 @@ "No favorites" : "Sem favoritos", "Files and folders you mark as favorite will show up here" : "Arquivos e pastas que você marcou como favoritos são mostrados aqui", "Text file" : "Arquivo texto", - "New text file.txt" : "Novo texto file.txt" + "New text file.txt" : "Novo texto file.txt", + "Changed by %2$s" : "Modificado por %2$s", + "Deleted by %2$s" : "Deletado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Você modificou %1$s", + "You created %1$s" : "Você criou %1$s", + "You deleted %1$s" : "Você excluiu %1$s ", + "You restored %1$s" : "Você restaurou %1$s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files/l10n/pt_PT.js b/apps/files/l10n/pt_PT.js index 98ecabe7e47f2..bfb82dd856620 100644 --- a/apps/files/l10n/pt_PT.js +++ b/apps/files/l10n/pt_PT.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Sem favoritos", "Files and folders you mark as favorite will show up here" : "Os ficheiros e pastas que marcou como favoritos serão mostrados aqui", "Text file" : "Ficheiro de Texto", - "New text file.txt" : "Novo texto ficheiro.txt" + "New text file.txt" : "Novo texto ficheiro.txt", + "Changed by %2$s" : "Alterado por %2$s", + "Deleted by %2$s" : "Eliminado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Alterou %1$s", + "You created %1$s" : "Criou %1$s", + "You deleted %1$s" : "Apagou %1$s", + "You restored %1$s" : "Restaurou %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/pt_PT.json b/apps/files/l10n/pt_PT.json index 8277852b5be62..cb157c7a9df76 100644 --- a/apps/files/l10n/pt_PT.json +++ b/apps/files/l10n/pt_PT.json @@ -115,6 +115,13 @@ "No favorites" : "Sem favoritos", "Files and folders you mark as favorite will show up here" : "Os ficheiros e pastas que marcou como favoritos serão mostrados aqui", "Text file" : "Ficheiro de Texto", - "New text file.txt" : "Novo texto ficheiro.txt" + "New text file.txt" : "Novo texto ficheiro.txt", + "Changed by %2$s" : "Alterado por %2$s", + "Deleted by %2$s" : "Eliminado por %2$s", + "Restored by %2$s" : "Restaurado por %2$s", + "You changed %1$s" : "Alterou %1$s", + "You created %1$s" : "Criou %1$s", + "You deleted %1$s" : "Apagou %1$s", + "You restored %1$s" : "Restaurou %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ro.js b/apps/files/l10n/ro.js index bd869ce56d665..534e90cf98e8f 100644 --- a/apps/files/l10n/ro.js +++ b/apps/files/l10n/ro.js @@ -81,6 +81,10 @@ OC.L10N.register( "Select all" : "Selectează tot", "Upload too large" : "Fișierul încărcat este prea mare", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fișierele pe care încerci să le încarci depășesc limita de încărcare maximă admisă pe acest server.", - "Text file" : "Fișier text" + "Text file" : "Fișier text", + "You changed %1$s" : "Ai schimbat %1$s", + "You created %1$s" : "Ai creat %1$s", + "You deleted %1$s" : "Ai şters %1$s", + "You restored %1$s" : "Ai restaurat %1$s" }, "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); diff --git a/apps/files/l10n/ro.json b/apps/files/l10n/ro.json index b842342a09afc..794eabc0e1ee0 100644 --- a/apps/files/l10n/ro.json +++ b/apps/files/l10n/ro.json @@ -79,6 +79,10 @@ "Select all" : "Selectează tot", "Upload too large" : "Fișierul încărcat este prea mare", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fișierele pe care încerci să le încarci depășesc limita de încărcare maximă admisă pe acest server.", - "Text file" : "Fișier text" + "Text file" : "Fișier text", + "You changed %1$s" : "Ai schimbat %1$s", + "You created %1$s" : "Ai creat %1$s", + "You deleted %1$s" : "Ai şters %1$s", + "You restored %1$s" : "Ai restaurat %1$s" },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" } \ No newline at end of file diff --git a/apps/files/l10n/ru.js b/apps/files/l10n/ru.js index 510e8d8f08bd8..20e980b0d948f 100644 --- a/apps/files/l10n/ru.js +++ b/apps/files/l10n/ru.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Нет избранного", "Files and folders you mark as favorite will show up here" : "Здесь появятся файлы и каталоги, отмеченные как избранные", "Text file" : "Текстовый файл", - "New text file.txt" : "Новый текстовый документ.txt" + "New text file.txt" : "Новый текстовый документ.txt", + "Changed by %2$s" : "Изменено %2$s", + "Deleted by %2$s" : "Удалено %2$s", + "Restored by %2$s" : "Восстановлено %2$s", + "You changed %1$s" : "Вы изменили %1$s", + "You created %1$s" : "Вы создали %1$s", + "You deleted %1$s" : "Вы удалили %1$s", + "You restored %1$s" : "Вы восстановили %1$s" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/files/l10n/ru.json b/apps/files/l10n/ru.json index f62125fa61446..1a15d9f4f0ea8 100644 --- a/apps/files/l10n/ru.json +++ b/apps/files/l10n/ru.json @@ -114,6 +114,13 @@ "No favorites" : "Нет избранного", "Files and folders you mark as favorite will show up here" : "Здесь появятся файлы и каталоги, отмеченные как избранные", "Text file" : "Текстовый файл", - "New text file.txt" : "Новый текстовый документ.txt" + "New text file.txt" : "Новый текстовый документ.txt", + "Changed by %2$s" : "Изменено %2$s", + "Deleted by %2$s" : "Удалено %2$s", + "Restored by %2$s" : "Восстановлено %2$s", + "You changed %1$s" : "Вы изменили %1$s", + "You created %1$s" : "Вы создали %1$s", + "You deleted %1$s" : "Вы удалили %1$s", + "You restored %1$s" : "Вы восстановили %1$s" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/files/l10n/si_LK.js b/apps/files/l10n/si_LK.js index 4c26c421076c6..37a3197a20ca6 100644 --- a/apps/files/l10n/si_LK.js +++ b/apps/files/l10n/si_LK.js @@ -36,6 +36,7 @@ OC.L10N.register( "Cancel upload" : "උඩුගත කිරීම අත් හරින්න", "Upload too large" : "උඩුගත කිරීම විශාල වැඩිය", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ඔබ උඩුගත කිරීමට තැත් කරන ගොනු මෙම සේවාදායකයා උඩුගත කිරීමට ඉඩදී ඇති උපරිම ගොනු විශාලත්වයට වඩා වැඩිය", - "Text file" : "පෙළ ගොනුව" + "Text file" : "පෙළ ගොනුව", + "Upload cancelled." : "උඩුගත කිරීම අත් හරින්න ලදී" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/si_LK.json b/apps/files/l10n/si_LK.json index 2db6c10b75c50..f2269f59363f1 100644 --- a/apps/files/l10n/si_LK.json +++ b/apps/files/l10n/si_LK.json @@ -34,6 +34,7 @@ "Cancel upload" : "උඩුගත කිරීම අත් හරින්න", "Upload too large" : "උඩුගත කිරීම විශාල වැඩිය", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "ඔබ උඩුගත කිරීමට තැත් කරන ගොනු මෙම සේවාදායකයා උඩුගත කිරීමට ඉඩදී ඇති උපරිම ගොනු විශාලත්වයට වඩා වැඩිය", - "Text file" : "පෙළ ගොනුව" + "Text file" : "පෙළ ගොනුව", + "Upload cancelled." : "උඩුගත කිරීම අත් හරින්න ලදී" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/sk_SK.js b/apps/files/l10n/sk_SK.js index 52711dd9c7b5b..5f92db6eee92c 100644 --- a/apps/files/l10n/sk_SK.js +++ b/apps/files/l10n/sk_SK.js @@ -100,6 +100,10 @@ OC.L10N.register( "No favorites" : "Žiadne obľúbené", "Files and folders you mark as favorite will show up here" : "Súbory a priečinky označené ako obľúbené budú zobrazené tu", "Text file" : "Textový súbor", - "New text file.txt" : "Nový text file.txt" + "New text file.txt" : "Nový text file.txt", + "You changed %1$s" : "Zmenili ste %1$s", + "You created %1$s" : "Vytvorili ste %1$s", + "You deleted %1$s" : "Bol zmazaný %1$s", + "You restored %1$s" : "Bol obnovený %1$s" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files/l10n/sk_SK.json b/apps/files/l10n/sk_SK.json index ca371eb189c85..0b48ba03206da 100644 --- a/apps/files/l10n/sk_SK.json +++ b/apps/files/l10n/sk_SK.json @@ -98,6 +98,10 @@ "No favorites" : "Žiadne obľúbené", "Files and folders you mark as favorite will show up here" : "Súbory a priečinky označené ako obľúbené budú zobrazené tu", "Text file" : "Textový súbor", - "New text file.txt" : "Nový text file.txt" + "New text file.txt" : "Nový text file.txt", + "You changed %1$s" : "Zmenili ste %1$s", + "You created %1$s" : "Vytvorili ste %1$s", + "You deleted %1$s" : "Bol zmazaný %1$s", + "You restored %1$s" : "Bol obnovený %1$s" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files/l10n/sl.js b/apps/files/l10n/sl.js index 9e4a72eb848d6..f36eaf206df40 100644 --- a/apps/files/l10n/sl.js +++ b/apps/files/l10n/sl.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Ni priljubljenih", "Files and folders you mark as favorite will show up here" : "Datoteke ali mape, ki so označene kot priljubljene, bodo izpisane tukaj.", "Text file" : "Besedilna datoteka", - "New text file.txt" : "Nova datoteka.txt" + "New text file.txt" : "Nova datoteka.txt", + "Changed by %2$s" : "Zadnja sprememba: %2$s", + "Deleted by %2$s" : "Izbrisano: %2$s", + "Restored by %2$s" : "Obnovljeno: %2$s", + "You changed %1$s" : "Spremenili ste %1$s", + "You created %1$s" : "Ustvarili ste %1$s", + "You deleted %1$s" : "Izbrisali ste %1$s", + "You restored %1$s" : "Obnovljen je predmet %1$s" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/files/l10n/sl.json b/apps/files/l10n/sl.json index 2b4478db18510..ebae56b87056b 100644 --- a/apps/files/l10n/sl.json +++ b/apps/files/l10n/sl.json @@ -115,6 +115,13 @@ "No favorites" : "Ni priljubljenih", "Files and folders you mark as favorite will show up here" : "Datoteke ali mape, ki so označene kot priljubljene, bodo izpisane tukaj.", "Text file" : "Besedilna datoteka", - "New text file.txt" : "Nova datoteka.txt" + "New text file.txt" : "Nova datoteka.txt", + "Changed by %2$s" : "Zadnja sprememba: %2$s", + "Deleted by %2$s" : "Izbrisano: %2$s", + "Restored by %2$s" : "Obnovljeno: %2$s", + "You changed %1$s" : "Spremenili ste %1$s", + "You created %1$s" : "Ustvarili ste %1$s", + "You deleted %1$s" : "Izbrisali ste %1$s", + "You restored %1$s" : "Obnovljen je predmet %1$s" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/files/l10n/sq.js b/apps/files/l10n/sq.js index 0f5d5abdd4206..df0780318b1f4 100644 --- a/apps/files/l10n/sq.js +++ b/apps/files/l10n/sq.js @@ -117,6 +117,13 @@ OC.L10N.register( "No favorites" : "Pa të parapëlqyera", "Files and folders you mark as favorite will show up here" : "Këtu do të duken kartelat dhe dosjet që i shënoni si të parapëlqyera", "Text file" : "Kartelë tekst", - "New text file.txt" : "Kartelë e re file.txt" + "New text file.txt" : "Kartelë e re file.txt", + "Changed by %2$s" : "Ndryshuar nga %2$s", + "Deleted by %2$s" : "Fshirë nga %2$s", + "Restored by %2$s" : "Rikthyer nga %2$s", + "You changed %1$s" : "Ndryshuat %1$s", + "You created %1$s" : "Krijuat %1$s", + "You deleted %1$s" : "Fshitë %1$s", + "You restored %1$s" : "Rikthyet %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/sq.json b/apps/files/l10n/sq.json index 56025d4780707..d9e42b5e151d5 100644 --- a/apps/files/l10n/sq.json +++ b/apps/files/l10n/sq.json @@ -115,6 +115,13 @@ "No favorites" : "Pa të parapëlqyera", "Files and folders you mark as favorite will show up here" : "Këtu do të duken kartelat dhe dosjet që i shënoni si të parapëlqyera", "Text file" : "Kartelë tekst", - "New text file.txt" : "Kartelë e re file.txt" + "New text file.txt" : "Kartelë e re file.txt", + "Changed by %2$s" : "Ndryshuar nga %2$s", + "Deleted by %2$s" : "Fshirë nga %2$s", + "Restored by %2$s" : "Rikthyer nga %2$s", + "You changed %1$s" : "Ndryshuat %1$s", + "You created %1$s" : "Krijuat %1$s", + "You deleted %1$s" : "Fshitë %1$s", + "You restored %1$s" : "Rikthyet %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/sr.js b/apps/files/l10n/sr.js index fbfa08ecf86a7..d5e43d975ee76 100644 --- a/apps/files/l10n/sr.js +++ b/apps/files/l10n/sr.js @@ -103,6 +103,13 @@ OC.L10N.register( "No favorites" : "Нема омиљених", "Files and folders you mark as favorite will show up here" : "Фајлови и фасцикле које обележите као омиљене појавиће се овде", "Text file" : "текстуални фајл", - "New text file.txt" : "Нов текстуални фајл.txt" + "New text file.txt" : "Нов текстуални фајл.txt", + "Changed by %2$s" : "Изменио %2$s", + "Deleted by %2$s" : "Обрисао %2$s", + "Restored by %2$s" : "Повратио %2$s", + "You changed %1$s" : "Изменили сте %1$s", + "You created %1$s" : "Направили сте %1$s", + "You deleted %1$s" : "Обрисали сте %1$s", + "You restored %1$s" : "Вратили сте %1$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files/l10n/sr.json b/apps/files/l10n/sr.json index d231c5416c819..351fdd7bab16c 100644 --- a/apps/files/l10n/sr.json +++ b/apps/files/l10n/sr.json @@ -101,6 +101,13 @@ "No favorites" : "Нема омиљених", "Files and folders you mark as favorite will show up here" : "Фајлови и фасцикле које обележите као омиљене појавиће се овде", "Text file" : "текстуални фајл", - "New text file.txt" : "Нов текстуални фајл.txt" + "New text file.txt" : "Нов текстуални фајл.txt", + "Changed by %2$s" : "Изменио %2$s", + "Deleted by %2$s" : "Обрисао %2$s", + "Restored by %2$s" : "Повратио %2$s", + "You changed %1$s" : "Изменили сте %1$s", + "You created %1$s" : "Направили сте %1$s", + "You deleted %1$s" : "Обрисали сте %1$s", + "You restored %1$s" : "Вратили сте %1$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/sr@latin.js b/apps/files/l10n/sr@latin.js index 7c62a464494fa..8e21f16fdfd44 100644 --- a/apps/files/l10n/sr@latin.js +++ b/apps/files/l10n/sr@latin.js @@ -91,6 +91,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fajlovi koje želite da otpremite prevazilaze ograničenje otpremanja na ovom serveru.", "No favorites" : "Nema omiljenih", "Files and folders you mark as favorite will show up here" : "Fajlovi i fascikle koje obeležite kao omiljene pojaviće se ovde", - "Text file" : "tekstualni fajl" + "Text file" : "tekstualni fajl", + "You changed %1$s" : "Izmenili ste %1$s", + "You created %1$s" : "Napravili ste %1$s", + "You deleted %1$s" : "Obrisali ste %1$s", + "You restored %1$s" : "Vratili ste %1$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files/l10n/sr@latin.json b/apps/files/l10n/sr@latin.json index 506ae677ca4bc..5389761e8e172 100644 --- a/apps/files/l10n/sr@latin.json +++ b/apps/files/l10n/sr@latin.json @@ -89,6 +89,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fajlovi koje želite da otpremite prevazilaze ograničenje otpremanja na ovom serveru.", "No favorites" : "Nema omiljenih", "Files and folders you mark as favorite will show up here" : "Fajlovi i fascikle koje obeležite kao omiljene pojaviće se ovde", - "Text file" : "tekstualni fajl" + "Text file" : "tekstualni fajl", + "You changed %1$s" : "Izmenili ste %1$s", + "You created %1$s" : "Napravili ste %1$s", + "You deleted %1$s" : "Obrisali ste %1$s", + "You restored %1$s" : "Vratili ste %1$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/sv.js b/apps/files/l10n/sv.js index 2a11c614c3fbf..78bd1add25065 100644 --- a/apps/files/l10n/sv.js +++ b/apps/files/l10n/sv.js @@ -114,6 +114,13 @@ OC.L10N.register( "No favorites" : "Inga favoriter", "Files and folders you mark as favorite will show up here" : "Filer och mappar du markerat som favoriter kommer visas här", "Text file" : "Textfil", - "New text file.txt" : "nytextfil.txt" + "New text file.txt" : "nytextfil.txt", + "Changed by %2$s" : "Ändrad av %2$s", + "Deleted by %2$s" : "Bortagen av %2$s", + "Restored by %2$s" : "Återställd av %2$s", + "You changed %1$s" : "Du ändrade %1$s", + "You created %1$s" : "Du skapade %1$s", + "You deleted %1$s" : "Du raderade %1$s", + "You restored %1$s" : "Du återkapade %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/sv.json b/apps/files/l10n/sv.json index d948763241d66..b8e996affdf9a 100644 --- a/apps/files/l10n/sv.json +++ b/apps/files/l10n/sv.json @@ -112,6 +112,13 @@ "No favorites" : "Inga favoriter", "Files and folders you mark as favorite will show up here" : "Filer och mappar du markerat som favoriter kommer visas här", "Text file" : "Textfil", - "New text file.txt" : "nytextfil.txt" + "New text file.txt" : "nytextfil.txt", + "Changed by %2$s" : "Ändrad av %2$s", + "Deleted by %2$s" : "Bortagen av %2$s", + "Restored by %2$s" : "Återställd av %2$s", + "You changed %1$s" : "Du ändrade %1$s", + "You created %1$s" : "Du skapade %1$s", + "You deleted %1$s" : "Du raderade %1$s", + "You restored %1$s" : "Du återkapade %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ta_IN.js b/apps/files/l10n/ta_IN.js index b2371916f128d..79a5c6a47349c 100644 --- a/apps/files/l10n/ta_IN.js +++ b/apps/files/l10n/ta_IN.js @@ -14,6 +14,9 @@ OC.L10N.register( "%2$s changed %1$s" : "%2$s %1$s 'ல் மாற்றம் செய்துள்ளார். ", "You deleted %1$s" : "நீங்கள் %1$s 'ஐ நீக்கி உள்ளீர்கள்.", "%2$s deleted %1$s" : "%2$s , %1$s 'ஐ நீக்கியுள்ளார்.", - "Settings" : "அமைப்புகள்" + "Settings" : "அமைப்புகள்", + "You changed %1$s" : "நீங்கள் %1$s 'ல் மாற்றம் செய்து உள்ளீர்கள். ", + "You created %1$s" : "நீங்கள் %1$s 'ஐ உருவாக்கி உள்ளீர்கள். ", + "You deleted %1$s" : "நீங்கள் %1$s 'ஐ நீக்கி உள்ளீர்கள்." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ta_IN.json b/apps/files/l10n/ta_IN.json index e5fe6f3fc88bb..15a70d1848add 100644 --- a/apps/files/l10n/ta_IN.json +++ b/apps/files/l10n/ta_IN.json @@ -12,6 +12,9 @@ "%2$s changed %1$s" : "%2$s %1$s 'ல் மாற்றம் செய்துள்ளார். ", "You deleted %1$s" : "நீங்கள் %1$s 'ஐ நீக்கி உள்ளீர்கள்.", "%2$s deleted %1$s" : "%2$s , %1$s 'ஐ நீக்கியுள்ளார்.", - "Settings" : "அமைப்புகள்" + "Settings" : "அமைப்புகள்", + "You changed %1$s" : "நீங்கள் %1$s 'ல் மாற்றம் செய்து உள்ளீர்கள். ", + "You created %1$s" : "நீங்கள் %1$s 'ஐ உருவாக்கி உள்ளீர்கள். ", + "You deleted %1$s" : "நீங்கள் %1$s 'ஐ நீக்கி உள்ளீர்கள்." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ta_LK.js b/apps/files/l10n/ta_LK.js index 8b731d1f64b46..753194b046db5 100644 --- a/apps/files/l10n/ta_LK.js +++ b/apps/files/l10n/ta_LK.js @@ -37,6 +37,7 @@ OC.L10N.register( "Cancel upload" : "பதிவேற்றலை இரத்து செய்க", "Upload too large" : "பதிவேற்றல் மிகப்பெரியது", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "நீங்கள் பதிவேற்ற முயற்சிக்கும் கோப்புகளானது இந்த சேவையகத்தில் கோப்பு பதிவேற்றக்கூடிய ஆகக்கூடிய அளவிலும் கூடியது.", - "Text file" : "கோப்பு உரை" + "Text file" : "கோப்பு உரை", + "Upload cancelled." : "பதிவேற்றல் இரத்து செய்யப்பட்டுள்ளது" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/ta_LK.json b/apps/files/l10n/ta_LK.json index 67cc6f18d882c..029c15c3275bb 100644 --- a/apps/files/l10n/ta_LK.json +++ b/apps/files/l10n/ta_LK.json @@ -35,6 +35,7 @@ "Cancel upload" : "பதிவேற்றலை இரத்து செய்க", "Upload too large" : "பதிவேற்றல் மிகப்பெரியது", "The files you are trying to upload exceed the maximum size for file uploads on this server." : "நீங்கள் பதிவேற்ற முயற்சிக்கும் கோப்புகளானது இந்த சேவையகத்தில் கோப்பு பதிவேற்றக்கூடிய ஆகக்கூடிய அளவிலும் கூடியது.", - "Text file" : "கோப்பு உரை" + "Text file" : "கோப்பு உரை", + "Upload cancelled." : "பதிவேற்றல் இரத்து செய்யப்பட்டுள்ளது" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files/l10n/th_TH.js b/apps/files/l10n/th_TH.js index d4bd37cb1e7b3..36856128ad9c5 100644 --- a/apps/files/l10n/th_TH.js +++ b/apps/files/l10n/th_TH.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "ไม่มีรายการโปรด", "Files and folders you mark as favorite will show up here" : "ไฟล์และโฟลเดอร์ที่คุณทำเครื่องหมายเป็นรายการโปรดจะปรากฏขึ้นที่นี่", "Text file" : "ไฟล์ข้อความ", - "New text file.txt" : "ไฟล์ข้อความใหม่ .txt" + "New text file.txt" : "ไฟล์ข้อความใหม่ .txt", + "Changed by %2$s" : "เปลี่ยนแปลงโดย %2$s", + "Deleted by %2$s" : "ลบโดย %2$s", + "Restored by %2$s" : "กู้คืนโดย %2$s", + "You changed %1$s" : "คุณทำการเปลี่ยนแปลง %1$s", + "You created %1$s" : "คุณสร้าง %1$s", + "You deleted %1$s" : "คุณลบ %1$s ออก", + "You restored %1$s" : "คุณกู้คืน %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/th_TH.json b/apps/files/l10n/th_TH.json index 03d6c6adb76d1..e7cd7ed21a871 100644 --- a/apps/files/l10n/th_TH.json +++ b/apps/files/l10n/th_TH.json @@ -114,6 +114,13 @@ "No favorites" : "ไม่มีรายการโปรด", "Files and folders you mark as favorite will show up here" : "ไฟล์และโฟลเดอร์ที่คุณทำเครื่องหมายเป็นรายการโปรดจะปรากฏขึ้นที่นี่", "Text file" : "ไฟล์ข้อความ", - "New text file.txt" : "ไฟล์ข้อความใหม่ .txt" + "New text file.txt" : "ไฟล์ข้อความใหม่ .txt", + "Changed by %2$s" : "เปลี่ยนแปลงโดย %2$s", + "Deleted by %2$s" : "ลบโดย %2$s", + "Restored by %2$s" : "กู้คืนโดย %2$s", + "You changed %1$s" : "คุณทำการเปลี่ยนแปลง %1$s", + "You created %1$s" : "คุณสร้าง %1$s", + "You deleted %1$s" : "คุณลบ %1$s ออก", + "You restored %1$s" : "คุณกู้คืน %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/tr.js b/apps/files/l10n/tr.js index 7e0b3f17327c5..7de15d49b9737 100644 --- a/apps/files/l10n/tr.js +++ b/apps/files/l10n/tr.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "Sık kullanılan öge yok.", "Files and folders you mark as favorite will show up here" : "Sık kullanılan olarak işaretlediğiniz dosya ve klasörler burada gösterilecek", "Text file" : "Metin dosyası", - "New text file.txt" : "Yeni metin dosyası.txt" + "New text file.txt" : "Yeni metin dosyası.txt", + "Changed by %2$s" : "%2$s tarafından değiştirildi", + "Deleted by %2$s" : "%2$s tarafından silindi", + "Restored by %2$s" : "%2$s tarafından geri yüklendi", + "You changed %1$s" : "%1$s dosyasını değiştirdiniz", + "You created %1$s" : "%1$s dosyasını oluşturdunuz", + "You deleted %1$s" : "%1$s dosyasını sildiniz", + "You restored %1$s" : "%1$s ögesini geri aldınız" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/tr.json b/apps/files/l10n/tr.json index 87f3b063df131..e74bc7b7d65c8 100644 --- a/apps/files/l10n/tr.json +++ b/apps/files/l10n/tr.json @@ -114,6 +114,13 @@ "No favorites" : "Sık kullanılan öge yok.", "Files and folders you mark as favorite will show up here" : "Sık kullanılan olarak işaretlediğiniz dosya ve klasörler burada gösterilecek", "Text file" : "Metin dosyası", - "New text file.txt" : "Yeni metin dosyası.txt" + "New text file.txt" : "Yeni metin dosyası.txt", + "Changed by %2$s" : "%2$s tarafından değiştirildi", + "Deleted by %2$s" : "%2$s tarafından silindi", + "Restored by %2$s" : "%2$s tarafından geri yüklendi", + "You changed %1$s" : "%1$s dosyasını değiştirdiniz", + "You created %1$s" : "%1$s dosyasını oluşturdunuz", + "You deleted %1$s" : "%1$s dosyasını sildiniz", + "You restored %1$s" : "%1$s ögesini geri aldınız" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files/l10n/ug.js b/apps/files/l10n/ug.js index b587b590632ce..41d35d590a4b0 100644 --- a/apps/files/l10n/ug.js +++ b/apps/files/l10n/ug.js @@ -32,6 +32,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "Cancel upload" : "يۈكلەشتىن ۋاز كەچ", "Upload too large" : "يۈكلەندىغىنى بەك چوڭ", - "Text file" : "تېكىست ھۆججەت" + "Text file" : "تېكىست ھۆججەت", + "Upload cancelled." : "يۈكلەشتىن ۋاز كەچتى." }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ug.json b/apps/files/l10n/ug.json index dd2e9c98ee579..446cea02f3289 100644 --- a/apps/files/l10n/ug.json +++ b/apps/files/l10n/ug.json @@ -30,6 +30,7 @@ "WebDAV" : "WebDAV", "Cancel upload" : "يۈكلەشتىن ۋاز كەچ", "Upload too large" : "يۈكلەندىغىنى بەك چوڭ", - "Text file" : "تېكىست ھۆججەت" + "Text file" : "تېكىست ھۆججەت", + "Upload cancelled." : "يۈكلەشتىن ۋاز كەچتى." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/uk.js b/apps/files/l10n/uk.js index f41baa183f5f0..547965ee7481a 100644 --- a/apps/files/l10n/uk.js +++ b/apps/files/l10n/uk.js @@ -94,6 +94,10 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файли,що ви намагаєтесь вивантажити перевищують максимальний дозволений розмір файлів на цьому сервері.", "No favorites" : "Немає улюблених", "Files and folders you mark as favorite will show up here" : "Файли і теки, які ви позначили як улюблені, з’являться тут", - "Text file" : "Текстовий файл" + "Text file" : "Текстовий файл", + "You changed %1$s" : "Вами змінено %1$s", + "You created %1$s" : "Вами створено %1$s", + "You deleted %1$s" : "Вами видалено %1$s", + "You restored %1$s" : "Вами відновлено %1$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files/l10n/uk.json b/apps/files/l10n/uk.json index 86acf1b8b604f..fde010cac97a0 100644 --- a/apps/files/l10n/uk.json +++ b/apps/files/l10n/uk.json @@ -92,6 +92,10 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файли,що ви намагаєтесь вивантажити перевищують максимальний дозволений розмір файлів на цьому сервері.", "No favorites" : "Немає улюблених", "Files and folders you mark as favorite will show up here" : "Файли і теки, які ви позначили як улюблені, з’являться тут", - "Text file" : "Текстовий файл" + "Text file" : "Текстовий файл", + "You changed %1$s" : "Вами змінено %1$s", + "You created %1$s" : "Вами створено %1$s", + "You deleted %1$s" : "Вами видалено %1$s", + "You restored %1$s" : "Вами відновлено %1$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files/l10n/zh_CN.js b/apps/files/l10n/zh_CN.js index c9a07a0199c06..c5a10b02e4a2d 100644 --- a/apps/files/l10n/zh_CN.js +++ b/apps/files/l10n/zh_CN.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "无收藏", "Files and folders you mark as favorite will show up here" : "收藏的文件和文件夹会在这里显示", "Text file" : "文本文件", - "New text file.txt" : "创建文本文件 .txt" + "New text file.txt" : "创建文本文件 .txt", + "Changed by %2$s" : "被 %2$s 更改", + "Deleted by %2$s" : "被 %2$s 删除", + "Restored by %2$s" : "被 %2$s 恢复", + "You changed %1$s" : "您修改了%1$s", + "You created %1$s" : "您创建了%1$s", + "You deleted %1$s" : "您删除了 %1$s", + "You restored %1$s" : "你恢复了 %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/zh_CN.json b/apps/files/l10n/zh_CN.json index 1ae61d0119b99..d7a6916af1af4 100644 --- a/apps/files/l10n/zh_CN.json +++ b/apps/files/l10n/zh_CN.json @@ -114,6 +114,13 @@ "No favorites" : "无收藏", "Files and folders you mark as favorite will show up here" : "收藏的文件和文件夹会在这里显示", "Text file" : "文本文件", - "New text file.txt" : "创建文本文件 .txt" + "New text file.txt" : "创建文本文件 .txt", + "Changed by %2$s" : "被 %2$s 更改", + "Deleted by %2$s" : "被 %2$s 删除", + "Restored by %2$s" : "被 %2$s 恢复", + "You changed %1$s" : "您修改了%1$s", + "You created %1$s" : "您创建了%1$s", + "You deleted %1$s" : "您删除了 %1$s", + "You restored %1$s" : "你恢复了 %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/zh_HK.js b/apps/files/l10n/zh_HK.js index 8ecae84be9957..370902b65b929 100644 --- a/apps/files/l10n/zh_HK.js +++ b/apps/files/l10n/zh_HK.js @@ -29,6 +29,9 @@ OC.L10N.register( "Save" : "儲存", "Settings" : "設定", "WebDAV" : "WebDAV", - "Cancel upload" : "取消上戴" + "Cancel upload" : "取消上戴", + "You changed %1$s" : "你改變了%1$s", + "You created %1$s" : "你新增了%1$s", + "You deleted %1$s" : "你刪除了%1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/zh_HK.json b/apps/files/l10n/zh_HK.json index 798dbe13abe30..837e5700f3595 100644 --- a/apps/files/l10n/zh_HK.json +++ b/apps/files/l10n/zh_HK.json @@ -27,6 +27,9 @@ "Save" : "儲存", "Settings" : "設定", "WebDAV" : "WebDAV", - "Cancel upload" : "取消上戴" + "Cancel upload" : "取消上戴", + "You changed %1$s" : "你改變了%1$s", + "You created %1$s" : "你新增了%1$s", + "You deleted %1$s" : "你刪除了%1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files/l10n/zh_TW.js b/apps/files/l10n/zh_TW.js index 0f013be694f7c..736fae312c02d 100644 --- a/apps/files/l10n/zh_TW.js +++ b/apps/files/l10n/zh_TW.js @@ -116,6 +116,13 @@ OC.L10N.register( "No favorites" : "沒有最愛", "Files and folders you mark as favorite will show up here" : "您標記為最愛的檔案與資料夾將會顯示在這裡", "Text file" : "文字檔", - "New text file.txt" : "新文字檔.txt" + "New text file.txt" : "新文字檔.txt", + "Changed by %2$s" : "由 %2$s 改動", + "Deleted by %2$s" : "由 %2$s 刪除", + "Restored by %2$s" : "由 %2$s 還原", + "You changed %1$s" : "您變更了 %1$s", + "You created %1$s" : "您建立了 %1$s", + "You deleted %1$s" : "您刪除了 %1$s", + "You restored %1$s" : "您還原了 %1$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/zh_TW.json b/apps/files/l10n/zh_TW.json index 1258145c71fbc..b65fc088b1cd6 100644 --- a/apps/files/l10n/zh_TW.json +++ b/apps/files/l10n/zh_TW.json @@ -114,6 +114,13 @@ "No favorites" : "沒有最愛", "Files and folders you mark as favorite will show up here" : "您標記為最愛的檔案與資料夾將會顯示在這裡", "Text file" : "文字檔", - "New text file.txt" : "新文字檔.txt" + "New text file.txt" : "新文字檔.txt", + "Changed by %2$s" : "由 %2$s 改動", + "Deleted by %2$s" : "由 %2$s 刪除", + "Restored by %2$s" : "由 %2$s 還原", + "You changed %1$s" : "您變更了 %1$s", + "You created %1$s" : "您建立了 %1$s", + "You deleted %1$s" : "您刪除了 %1$s", + "You restored %1$s" : "您還原了 %1$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/ast.js b/apps/files_external/l10n/ast.js index dde6d0c1e5274..1cfdccdf92d1b 100644 --- a/apps/files_external/l10n/ast.js +++ b/apps/files_external/l10n/ast.js @@ -56,6 +56,8 @@ OC.L10N.register( "Available for" : "Disponible pa", "Add storage" : "Amestar almacenamientu", "Delete" : "Desaniciar", - "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamientu esternu" + "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamientu esternu", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: El soporte de FTP en PHP nun ta activáu o instaláu. Nun pue montase %s. Pídi-y al alministrador de sistema que lu instale.", + "SMB / CIFS using OC login" : "SMB / CIFS usando accesu OC" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/ast.json b/apps/files_external/l10n/ast.json index f31a288618c1c..35b18ed159fec 100644 --- a/apps/files_external/l10n/ast.json +++ b/apps/files_external/l10n/ast.json @@ -54,6 +54,8 @@ "Available for" : "Disponible pa", "Add storage" : "Amestar almacenamientu", "Delete" : "Desaniciar", - "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamientu esternu" + "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamientu esternu", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: El soporte de FTP en PHP nun ta activáu o instaláu. Nun pue montase %s. Pídi-y al alministrador de sistema que lu instale.", + "SMB / CIFS using OC login" : "SMB / CIFS usando accesu OC" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/az.js b/apps/files_external/l10n/az.js index ebb84a1b6f30e..7822e82c4a826 100644 --- a/apps/files_external/l10n/az.js +++ b/apps/files_external/l10n/az.js @@ -61,6 +61,8 @@ OC.L10N.register( "Add storage" : "Deponu əlavə et", "Advanced settings" : "İrəliləmiş quraşdırmalar", "Delete" : "Sil", - "Allow users to mount the following external storage" : "Göstərilən kənar deponun bərkidilməsi üçün istifadəçilərə izin ver" + "Allow users to mount the following external storage" : "Göstərilən kənar deponun bərkidilməsi üçün istifadəçilərə izin ver", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Qeyd: PHP-də FTP dəstəyi aktiv deyil və ya yüklənməyib. %s -in birləşdirilməsi mümkün deyil. Xahiş edilir onun yüklənilməsi barəsində inzibatşınıza məlumat verəsiniz.", + "SMB / CIFS using OC login" : "OC login istifadə edir SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/az.json b/apps/files_external/l10n/az.json index a8ec16bf97dbc..e32fb46ed8f0d 100644 --- a/apps/files_external/l10n/az.json +++ b/apps/files_external/l10n/az.json @@ -59,6 +59,8 @@ "Add storage" : "Deponu əlavə et", "Advanced settings" : "İrəliləmiş quraşdırmalar", "Delete" : "Sil", - "Allow users to mount the following external storage" : "Göstərilən kənar deponun bərkidilməsi üçün istifadəçilərə izin ver" + "Allow users to mount the following external storage" : "Göstərilən kənar deponun bərkidilməsi üçün istifadəçilərə izin ver", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Qeyd: PHP-də FTP dəstəyi aktiv deyil və ya yüklənməyib. %s -in birləşdirilməsi mümkün deyil. Xahiş edilir onun yüklənilməsi barəsində inzibatşınıza məlumat verəsiniz.", + "SMB / CIFS using OC login" : "OC login istifadə edir SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/bg_BG.js b/apps/files_external/l10n/bg_BG.js index 8e8ce312138ee..5013d402de0cf 100644 --- a/apps/files_external/l10n/bg_BG.js +++ b/apps/files_external/l10n/bg_BG.js @@ -63,6 +63,8 @@ OC.L10N.register( "Add storage" : "Добави дисково пространство", "Advanced settings" : "Разширени настройки", "Delete" : "Изтрий", - "Allow users to mount the following external storage" : "Разреши на потребителите да прикачват следното външно дисково пространство" + "Allow users to mount the following external storage" : "Разреши на потребителите да прикачват следното външно дисково пространство", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: PHP подръжката на FTP не е включена или инсталирана. Прикачването на %s не е възможно. Моля, поискай системния администратор да я инсталира.", + "SMB / CIFS using OC login" : "SMB / CIFS използвайки OC профил" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/bg_BG.json b/apps/files_external/l10n/bg_BG.json index cc76db1ebedc1..d3b70b34b172a 100644 --- a/apps/files_external/l10n/bg_BG.json +++ b/apps/files_external/l10n/bg_BG.json @@ -61,6 +61,8 @@ "Add storage" : "Добави дисково пространство", "Advanced settings" : "Разширени настройки", "Delete" : "Изтрий", - "Allow users to mount the following external storage" : "Разреши на потребителите да прикачват следното външно дисково пространство" + "Allow users to mount the following external storage" : "Разреши на потребителите да прикачват следното външно дисково пространство", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: PHP подръжката на FTP не е включена или инсталирана. Прикачването на %s не е възможно. Моля, поискай системния администратор да я инсталира.", + "SMB / CIFS using OC login" : "SMB / CIFS използвайки OC профил" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/ca.js b/apps/files_external/l10n/ca.js index 794409671e575..4dd845ce0817b 100644 --- a/apps/files_external/l10n/ca.js +++ b/apps/files_external/l10n/ca.js @@ -69,6 +69,8 @@ OC.L10N.register( "Add storage" : "Afegeix emmagatzemament", "Advanced settings" : "Configuració avançada", "Delete" : "Esborra", - "Allow users to mount the following external storage" : "Permet als usuaris muntar els dispositius externs següents" + "Allow users to mount the following external storage" : "Permet als usuaris muntar els dispositius externs següents", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: El suport FTP per PHP no està activat o no està instal·lat. No es pot muntar %s. Demaneu a l'administrador del sistema que l'instal·li.", + "SMB / CIFS using OC login" : "SMB / CIFS usant acreditació OC" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/ca.json b/apps/files_external/l10n/ca.json index 633cf9ba54a3b..be994ea1dec6a 100644 --- a/apps/files_external/l10n/ca.json +++ b/apps/files_external/l10n/ca.json @@ -67,6 +67,8 @@ "Add storage" : "Afegeix emmagatzemament", "Advanced settings" : "Configuració avançada", "Delete" : "Esborra", - "Allow users to mount the following external storage" : "Permet als usuaris muntar els dispositius externs següents" + "Allow users to mount the following external storage" : "Permet als usuaris muntar els dispositius externs següents", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: El suport FTP per PHP no està activat o no està instal·lat. No es pot muntar %s. Demaneu a l'administrador del sistema que l'instal·li.", + "SMB / CIFS using OC login" : "SMB / CIFS usant acreditació OC" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/cs_CZ.js b/apps/files_external/l10n/cs_CZ.js index 25c5f0c318d12..cc0e4918e32e2 100644 --- a/apps/files_external/l10n/cs_CZ.js +++ b/apps/files_external/l10n/cs_CZ.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Pokročilá nastavení", "Delete" : "Smazat", "Allow users to mount external storage" : "Povolit uživatelům připojení externího úložiště", - "Allow users to mount the following external storage" : "Povolit uživatelů připojit následující externí úložiště" + "Allow users to mount the following external storage" : "Povolit uživatelů připojit následující externí úložiště", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Některá z nastavených vzdálených úložišť nejsou připojena. Pro více informací prosím klikněte na červenou šipku(y)" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files_external/l10n/cs_CZ.json b/apps/files_external/l10n/cs_CZ.json index 192c60299fc28..916ac7dd527b6 100644 --- a/apps/files_external/l10n/cs_CZ.json +++ b/apps/files_external/l10n/cs_CZ.json @@ -118,6 +118,8 @@ "Advanced settings" : "Pokročilá nastavení", "Delete" : "Smazat", "Allow users to mount external storage" : "Povolit uživatelům připojení externího úložiště", - "Allow users to mount the following external storage" : "Povolit uživatelů připojit následující externí úložiště" + "Allow users to mount the following external storage" : "Povolit uživatelů připojit následující externí úložiště", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Některá z nastavených vzdálených úložišť nejsou připojena. Pro více informací prosím klikněte na červenou šipku(y)" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files_external/l10n/da.js b/apps/files_external/l10n/da.js index 59e32a55fe692..a4ebefe39ca55 100644 --- a/apps/files_external/l10n/da.js +++ b/apps/files_external/l10n/da.js @@ -100,6 +100,7 @@ OC.L10N.register( "Add storage" : "Tilføj lager", "Advanced settings" : "Avancerede indstillinger", "Delete" : "Slet", - "Allow users to mount the following external storage" : "Tillad brugere at montere følgende som eksternt lager" + "Allow users to mount the following external storage" : "Tillad brugere at montere følgende som eksternt lager", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/da.json b/apps/files_external/l10n/da.json index ae50904a225c7..57a1da69fab7e 100644 --- a/apps/files_external/l10n/da.json +++ b/apps/files_external/l10n/da.json @@ -98,6 +98,7 @@ "Add storage" : "Tilføj lager", "Advanced settings" : "Avancerede indstillinger", "Delete" : "Slet", - "Allow users to mount the following external storage" : "Tillad brugere at montere følgende som eksternt lager" + "Allow users to mount the following external storage" : "Tillad brugere at montere følgende som eksternt lager", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/de.js b/apps/files_external/l10n/de.js index a082b8c63aa5e..620b58080c104 100644 --- a/apps/files_external/l10n/de.js +++ b/apps/files_external/l10n/de.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", "Allow users to mount external storage" : "Benutzern erlauben, externen Speicher einzubinden", - "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:" + "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Einige der konfigurierten externen Bereitstellungspunkte sind nicht angeschlossen. Bitte klicke auf die roten Zeile(n) für weitere Informationen" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/de.json b/apps/files_external/l10n/de.json index 6157cb12fc3ab..48ac13e3e6078 100644 --- a/apps/files_external/l10n/de.json +++ b/apps/files_external/l10n/de.json @@ -118,6 +118,8 @@ "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", "Allow users to mount external storage" : "Benutzern erlauben, externen Speicher einzubinden", - "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:" + "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Einige der konfigurierten externen Bereitstellungspunkte sind nicht angeschlossen. Bitte klicke auf die roten Zeile(n) für weitere Informationen" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/de_DE.js b/apps/files_external/l10n/de_DE.js index 135e9a44eb8e5..fff524cb4eb3a 100644 --- a/apps/files_external/l10n/de_DE.js +++ b/apps/files_external/l10n/de_DE.js @@ -101,6 +101,16 @@ OC.L10N.register( "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", "Allow users to mount external storage" : "Erlauben Sie den Benutzern externen Speicher hinzuzufügen", - "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:" + "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:", + "Admin defined" : "Administrator definiert", + "Credentials required" : "Zugangsdaten benötigt", + "Credentials saved" : "Zugangsdaten gespeichert", + "Credentials saving failed" : "Speichern der Zugangsdaten fehlgeschlagen", + "Error configuring OAuth2" : "Fehler beim Konfigurieren von OAuth2", + "Log-in credentials, save in session" : "Anmelde-Zugangsdaten, speichere in Sitzung", + "Please enter the credentials for the {mount} mount" : "Bitte geben Sie die Zugangsdaten für den {mount} Speicher an", + "RSA public key" : "RSA öffentlicher Schlüssel", + "SMB / CIFS" : "SMB / CIFS", + "Unsatisfied authentication mechanism parameters" : "Unbefriedigende Autentifizierungs-Mechanismus Parameter" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/de_DE.json b/apps/files_external/l10n/de_DE.json index 956d202ff7239..4a7dcffd085e7 100644 --- a/apps/files_external/l10n/de_DE.json +++ b/apps/files_external/l10n/de_DE.json @@ -99,6 +99,16 @@ "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", "Allow users to mount external storage" : "Erlauben Sie den Benutzern externen Speicher hinzuzufügen", - "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:" + "Allow users to mount the following external storage" : "Benutzern erlauben, den oder die folgenden externen Speicher einzubinden:", + "Admin defined" : "Administrator definiert", + "Credentials required" : "Zugangsdaten benötigt", + "Credentials saved" : "Zugangsdaten gespeichert", + "Credentials saving failed" : "Speichern der Zugangsdaten fehlgeschlagen", + "Error configuring OAuth2" : "Fehler beim Konfigurieren von OAuth2", + "Log-in credentials, save in session" : "Anmelde-Zugangsdaten, speichere in Sitzung", + "Please enter the credentials for the {mount} mount" : "Bitte geben Sie die Zugangsdaten für den {mount} Speicher an", + "RSA public key" : "RSA öffentlicher Schlüssel", + "SMB / CIFS" : "SMB / CIFS", + "Unsatisfied authentication mechanism parameters" : "Unbefriedigende Autentifizierungs-Mechanismus Parameter" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/el.js b/apps/files_external/l10n/el.js index 8e60734244d15..8286c19573537 100644 --- a/apps/files_external/l10n/el.js +++ b/apps/files_external/l10n/el.js @@ -103,6 +103,10 @@ OC.L10N.register( "Advanced settings" : "Ρυθμίσεις για προχωρημένους", "Delete" : "Διαγραφή", "Allow users to mount external storage" : "Να επιτρέπεται στους χρήστες η σύνδεση εξωτερικού χώρου", - "Allow users to mount the following external storage" : "Χορήγηση άδειας στους χρήστες να συνδέσουν τα παρακάτω εξωτερικά μέσα αποθήκευσης" + "Allow users to mount the following external storage" : "Χορήγηση άδειας στους χρήστες να συνδέσουν τα παρακάτω εξωτερικά μέσα αποθήκευσης", + "Credentials saved" : "Τα διαπιστευτήρια αποθηκεύτηκαν", + "Credentials saving failed" : "Αποτυχία αποθήκευσης διαπιστευτηρίων", + "External mount error" : "Σφάλμα εξωτερικής προσάρτησης", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/el.json b/apps/files_external/l10n/el.json index 1e312eba6bf1e..e66296cb0fcfe 100644 --- a/apps/files_external/l10n/el.json +++ b/apps/files_external/l10n/el.json @@ -101,6 +101,10 @@ "Advanced settings" : "Ρυθμίσεις για προχωρημένους", "Delete" : "Διαγραφή", "Allow users to mount external storage" : "Να επιτρέπεται στους χρήστες η σύνδεση εξωτερικού χώρου", - "Allow users to mount the following external storage" : "Χορήγηση άδειας στους χρήστες να συνδέσουν τα παρακάτω εξωτερικά μέσα αποθήκευσης" + "Allow users to mount the following external storage" : "Χορήγηση άδειας στους χρήστες να συνδέσουν τα παρακάτω εξωτερικά μέσα αποθήκευσης", + "Credentials saved" : "Τα διαπιστευτήρια αποθηκεύτηκαν", + "Credentials saving failed" : "Αποτυχία αποθήκευσης διαπιστευτηρίων", + "External mount error" : "Σφάλμα εξωτερικής προσάρτησης", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/en_GB.js b/apps/files_external/l10n/en_GB.js index 7a8d221b26a5a..a140de780a883 100644 --- a/apps/files_external/l10n/en_GB.js +++ b/apps/files_external/l10n/en_GB.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Advanced settings", "Delete" : "Delete", "Allow users to mount external storage" : "Allow users to mount external storage", - "Allow users to mount the following external storage" : "Allow users to mount the following external storage" + "Allow users to mount the following external storage" : "Allow users to mount the following external storage", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/en_GB.json b/apps/files_external/l10n/en_GB.json index 107f769d624a9..f029f45e1a5e0 100644 --- a/apps/files_external/l10n/en_GB.json +++ b/apps/files_external/l10n/en_GB.json @@ -118,6 +118,8 @@ "Advanced settings" : "Advanced settings", "Delete" : "Delete", "Allow users to mount external storage" : "Allow users to mount external storage", - "Allow users to mount the following external storage" : "Allow users to mount the following external storage" + "Allow users to mount the following external storage" : "Allow users to mount the following external storage", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/es.js b/apps/files_external/l10n/es.js index 648c91e3164ea..221b41e7a0295 100644 --- a/apps/files_external/l10n/es.js +++ b/apps/files_external/l10n/es.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Configuración avanzada", "Delete" : "Eliminar", "Allow users to mount external storage" : "Permitir a los usuarios montar un almacenamiento externo", - "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamiento externo" + "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamiento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Algunos de los puntos de montaje externos configurados no están conectados. Por favor, haga clic en la fila roja (s) para obtener más información" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/es.json b/apps/files_external/l10n/es.json index c9a07f20d1318..f995cff1f74bb 100644 --- a/apps/files_external/l10n/es.json +++ b/apps/files_external/l10n/es.json @@ -118,6 +118,8 @@ "Advanced settings" : "Configuración avanzada", "Delete" : "Eliminar", "Allow users to mount external storage" : "Permitir a los usuarios montar un almacenamiento externo", - "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamiento externo" + "Allow users to mount the following external storage" : "Permitir a los usuarios montar el siguiente almacenamiento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Algunos de los puntos de montaje externos configurados no están conectados. Por favor, haga clic en la fila roja (s) para obtener más información" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/et_EE.js b/apps/files_external/l10n/et_EE.js index 5e03f32571d1d..e98605ca32da1 100644 --- a/apps/files_external/l10n/et_EE.js +++ b/apps/files_external/l10n/et_EE.js @@ -98,6 +98,7 @@ OC.L10N.register( "Add storage" : "Lisa andmehoidla", "Advanced settings" : "Lisavalikud", "Delete" : "Kustuta", - "Allow users to mount the following external storage" : "Võimalda kasutajatel ühendada järgmist välist andmehoidlat" + "Allow users to mount the following external storage" : "Võimalda kasutajatel ühendada järgmist välist andmehoidlat", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/et_EE.json b/apps/files_external/l10n/et_EE.json index 8d4334225e703..4028bd6cc07c8 100644 --- a/apps/files_external/l10n/et_EE.json +++ b/apps/files_external/l10n/et_EE.json @@ -96,6 +96,7 @@ "Add storage" : "Lisa andmehoidla", "Advanced settings" : "Lisavalikud", "Delete" : "Kustuta", - "Allow users to mount the following external storage" : "Võimalda kasutajatel ühendada järgmist välist andmehoidlat" + "Allow users to mount the following external storage" : "Võimalda kasutajatel ühendada järgmist välist andmehoidlat", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/eu.js b/apps/files_external/l10n/eu.js index 8790c1c117307..827b760839b89 100644 --- a/apps/files_external/l10n/eu.js +++ b/apps/files_external/l10n/eu.js @@ -55,6 +55,8 @@ OC.L10N.register( "Available for" : "Hauentzat eskuragarri", "Add storage" : "Gehitu biltegiratzea", "Delete" : "Ezabatu", - "Allow users to mount the following external storage" : "Baimendu erabiltzaileak hurrengo kanpo biltegiratzeak muntatzen" + "Allow users to mount the following external storage" : "Baimendu erabiltzaileak hurrengo kanpo biltegiratzeak muntatzen", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Oharra: :PHPko FTP euskarria ez dago instalatuta edo gaitua. Ezinezko da %s muntatzea. Mesedez eskatu sistema administratzaleari instala dezan. ", + "SMB / CIFS using OC login" : "SMB / CIFS saioa hasteko OC erabiliz" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/eu.json b/apps/files_external/l10n/eu.json index b083c3e210a1b..426c6937b42bb 100644 --- a/apps/files_external/l10n/eu.json +++ b/apps/files_external/l10n/eu.json @@ -53,6 +53,8 @@ "Available for" : "Hauentzat eskuragarri", "Add storage" : "Gehitu biltegiratzea", "Delete" : "Ezabatu", - "Allow users to mount the following external storage" : "Baimendu erabiltzaileak hurrengo kanpo biltegiratzeak muntatzen" + "Allow users to mount the following external storage" : "Baimendu erabiltzaileak hurrengo kanpo biltegiratzeak muntatzen", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Oharra: :PHPko FTP euskarria ez dago instalatuta edo gaitua. Ezinezko da %s muntatzea. Mesedez eskatu sistema administratzaleari instala dezan. ", + "SMB / CIFS using OC login" : "SMB / CIFS saioa hasteko OC erabiliz" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/fa.js b/apps/files_external/l10n/fa.js index edc3f1c0fb30a..3c8d9f6392c1b 100644 --- a/apps/files_external/l10n/fa.js +++ b/apps/files_external/l10n/fa.js @@ -60,6 +60,7 @@ OC.L10N.register( "Available for" : "در دسترس برای", "Add storage" : "اضافه کردن حافظه", "Advanced settings" : "تنظیمات پیشرفته", - "Delete" : "حذف" + "Delete" : "حذف", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/fa.json b/apps/files_external/l10n/fa.json index c3dfcafbbfe22..1812d9d11a8fc 100644 --- a/apps/files_external/l10n/fa.json +++ b/apps/files_external/l10n/fa.json @@ -58,6 +58,7 @@ "Available for" : "در دسترس برای", "Add storage" : "اضافه کردن حافظه", "Advanced settings" : "تنظیمات پیشرفته", - "Delete" : "حذف" + "Delete" : "حذف", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/fi_FI.js b/apps/files_external/l10n/fi_FI.js index b64d44bf12b32..12aa5b2301069 100644 --- a/apps/files_external/l10n/fi_FI.js +++ b/apps/files_external/l10n/fi_FI.js @@ -97,6 +97,8 @@ OC.L10N.register( "Advanced settings" : "Lisäasetukset", "Delete" : "Poista", "Allow users to mount external storage" : "Salli käyttäjien liittää erillisiä tallennustiloja", - "Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet" + "Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Jotkin määritetyt erilliset liitospisteet eivät ole yhdistettynä. Napsauta punaisia rivejä saadaksesi lisätietoja" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/fi_FI.json b/apps/files_external/l10n/fi_FI.json index 543ccafca3a3f..91c03d8adc1fc 100644 --- a/apps/files_external/l10n/fi_FI.json +++ b/apps/files_external/l10n/fi_FI.json @@ -95,6 +95,8 @@ "Advanced settings" : "Lisäasetukset", "Delete" : "Poista", "Allow users to mount external storage" : "Salli käyttäjien liittää erillisiä tallennustiloja", - "Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet" + "Allow users to mount the following external storage" : "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Jotkin määritetyt erilliset liitospisteet eivät ole yhdistettynä. Napsauta punaisia rivejä saadaksesi lisätietoja" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/fr.js b/apps/files_external/l10n/fr.js index faef02726cec7..3fe170e6fc9d2 100644 --- a/apps/files_external/l10n/fr.js +++ b/apps/files_external/l10n/fr.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Paramètres avancés", "Delete" : "Supprimer", "Allow users to mount external storage" : "Autoriser les utilisateurs à monter des espaces de stockage externes", - "Allow users to mount the following external storage" : "Autoriser les utilisateurs à monter les stockages externes suivants" + "Allow users to mount the following external storage" : "Autoriser les utilisateurs à monter les stockages externes suivants", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Certains points de montage externes configurés ne sont pas connectés. Veuillez cliquer sur la(les) ligne(s) rouge(s) pour plus d'informations" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_external/l10n/fr.json b/apps/files_external/l10n/fr.json index 4bcb65e9cafa7..8662e89dc334b 100644 --- a/apps/files_external/l10n/fr.json +++ b/apps/files_external/l10n/fr.json @@ -118,6 +118,8 @@ "Advanced settings" : "Paramètres avancés", "Delete" : "Supprimer", "Allow users to mount external storage" : "Autoriser les utilisateurs à monter des espaces de stockage externes", - "Allow users to mount the following external storage" : "Autoriser les utilisateurs à monter les stockages externes suivants" + "Allow users to mount the following external storage" : "Autoriser les utilisateurs à monter les stockages externes suivants", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Certains points de montage externes configurés ne sont pas connectés. Veuillez cliquer sur la(les) ligne(s) rouge(s) pour plus d'informations" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/gl.js b/apps/files_external/l10n/gl.js index 7c37f9a569481..b150258e38dcb 100644 --- a/apps/files_external/l10n/gl.js +++ b/apps/files_external/l10n/gl.js @@ -70,6 +70,8 @@ OC.L10N.register( "Add storage" : "Engadir almacenamento", "Advanced settings" : "Axustes avanzados", "Delete" : "Eliminar", - "Allow users to mount the following external storage" : "Permitirlle aos usuarios montar o seguinte almacenamento externo" + "Allow users to mount the following external storage" : "Permitirlle aos usuarios montar o seguinte almacenamento externo", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: A compatibilidade de FTP en PHP non está activada, ou non está instalado. Non é posíbel a montaxe de %s. Consulte co administrador do sistema como instalalo.", + "SMB / CIFS using OC login" : "SMB / CIFS usando acceso OC" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/gl.json b/apps/files_external/l10n/gl.json index 10daf8b6d20cf..3937413da1dce 100644 --- a/apps/files_external/l10n/gl.json +++ b/apps/files_external/l10n/gl.json @@ -68,6 +68,8 @@ "Add storage" : "Engadir almacenamento", "Advanced settings" : "Axustes avanzados", "Delete" : "Eliminar", - "Allow users to mount the following external storage" : "Permitirlle aos usuarios montar o seguinte almacenamento externo" + "Allow users to mount the following external storage" : "Permitirlle aos usuarios montar o seguinte almacenamento externo", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Nota: A compatibilidade de FTP en PHP non está activada, ou non está instalado. Non é posíbel a montaxe de %s. Consulte co administrador do sistema como instalalo.", + "SMB / CIFS using OC login" : "SMB / CIFS usando acceso OC" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/he.js b/apps/files_external/l10n/he.js index eb716d6b2cd33..d3044b0102bad 100644 --- a/apps/files_external/l10n/he.js +++ b/apps/files_external/l10n/he.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "הגדרות מתקדמות", "Delete" : "מחיקה", "Allow users to mount external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני", - "Allow users to mount the following external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני הבא" + "Allow users to mount the following external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני הבא", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "חלק מנקודות העיגון החיצוניות שהוגדרו אינן מחוברות. יש ללחוץ על השורה/ות האדומה/ות למידע נוסף" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/he.json b/apps/files_external/l10n/he.json index ffe7b62b5de24..aaeeb8067b525 100644 --- a/apps/files_external/l10n/he.json +++ b/apps/files_external/l10n/he.json @@ -118,6 +118,8 @@ "Advanced settings" : "הגדרות מתקדמות", "Delete" : "מחיקה", "Allow users to mount external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני", - "Allow users to mount the following external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני הבא" + "Allow users to mount the following external storage" : "מאפשר למשתמשים לחבר אחסון חיצוני הבא", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "חלק מנקודות העיגון החיצוניות שהוגדרו אינן מחוברות. יש ללחוץ על השורה/ות האדומה/ות למידע נוסף" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/hr.js b/apps/files_external/l10n/hr.js index 021c29253bc1f..7309f59c3809a 100644 --- a/apps/files_external/l10n/hr.js +++ b/apps/files_external/l10n/hr.js @@ -53,6 +53,9 @@ OC.L10N.register( "Available for" : "Dostupno za", "Add storage" : "Dodajte spremište", "Delete" : "Izbrišite", - "Allow users to mount the following external storage" : "Dopustite korisnicima postavljanje sljedećeg vanjskog spremišta" + "Allow users to mount the following external storage" : "Dopustite korisnicima postavljanje sljedećeg vanjskog spremišta", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: Podrška FTP u PHP nije omogućena ili nije instalirana. Postavljanje%s nije moguće. Molimo zamolite svotg administratora sustava da je instalira.", + "Note: The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: Podrška cURL u PHP nije omogućena ili nije instalirana. Postavljanje%s nije moguće. Molimo zamolite svog administratora sustava da je instalira.", + "SMB / CIFS using OC login" : "SMB / CIFS uz prijavu putem programa OC" }, "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); diff --git a/apps/files_external/l10n/hr.json b/apps/files_external/l10n/hr.json index 35da2cb9109d5..65715218ab166 100644 --- a/apps/files_external/l10n/hr.json +++ b/apps/files_external/l10n/hr.json @@ -51,6 +51,9 @@ "Available for" : "Dostupno za", "Add storage" : "Dodajte spremište", "Delete" : "Izbrišite", - "Allow users to mount the following external storage" : "Dopustite korisnicima postavljanje sljedećeg vanjskog spremišta" + "Allow users to mount the following external storage" : "Dopustite korisnicima postavljanje sljedećeg vanjskog spremišta", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: Podrška FTP u PHP nije omogućena ili nije instalirana. Postavljanje%s nije moguće. Molimo zamolite svotg administratora sustava da je instalira.", + "Note: The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Note: Podrška cURL u PHP nije omogućena ili nije instalirana. Postavljanje%s nije moguće. Molimo zamolite svog administratora sustava da je instalira.", + "SMB / CIFS using OC login" : "SMB / CIFS uz prijavu putem programa OC" },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files_external/l10n/hu_HU.js b/apps/files_external/l10n/hu_HU.js index f5c2ae3305181..65e6446336736 100644 --- a/apps/files_external/l10n/hu_HU.js +++ b/apps/files_external/l10n/hu_HU.js @@ -81,6 +81,7 @@ OC.L10N.register( "Advanced settings" : "Haladó beállítások", "Delete" : "Törlés", "Allow users to mount external storage" : "Külső tárolók engedélyezése a felhasználók részére", - "Allow users to mount the following external storage" : "A felhasználók számára engedélyezett külső tárolók:" + "Allow users to mount the following external storage" : "A felhasználók számára engedélyezett külső tárolók:", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/hu_HU.json b/apps/files_external/l10n/hu_HU.json index 846c6ee775ddc..34870e38a5690 100644 --- a/apps/files_external/l10n/hu_HU.json +++ b/apps/files_external/l10n/hu_HU.json @@ -79,6 +79,7 @@ "Advanced settings" : "Haladó beállítások", "Delete" : "Törlés", "Allow users to mount external storage" : "Külső tárolók engedélyezése a felhasználók részére", - "Allow users to mount the following external storage" : "A felhasználók számára engedélyezett külső tárolók:" + "Allow users to mount the following external storage" : "A felhasználók számára engedélyezett külső tárolók:", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/hy.js b/apps/files_external/l10n/hy.js index 1a5ef39ab4298..5128cb79b12a1 100644 --- a/apps/files_external/l10n/hy.js +++ b/apps/files_external/l10n/hy.js @@ -11,6 +11,7 @@ OC.L10N.register( "Share" : "Կիսվել", "Name" : "Անուն", "Folder name" : "Պանակի անուն", - "Delete" : "Ջնջել" + "Delete" : "Ջնջել", + "Saved" : "Պահված" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/hy.json b/apps/files_external/l10n/hy.json index 20dd743844d78..a7607b4e7170c 100644 --- a/apps/files_external/l10n/hy.json +++ b/apps/files_external/l10n/hy.json @@ -9,6 +9,7 @@ "Share" : "Կիսվել", "Name" : "Անուն", "Folder name" : "Պանակի անուն", - "Delete" : "Ջնջել" + "Delete" : "Ջնջել", + "Saved" : "Պահված" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/id.js b/apps/files_external/l10n/id.js index c17a0d5d0b2fb..4d707c425f14f 100644 --- a/apps/files_external/l10n/id.js +++ b/apps/files_external/l10n/id.js @@ -100,6 +100,7 @@ OC.L10N.register( "Add storage" : "Tambahkan penyimpanan", "Advanced settings" : "Pengaturan Lanjutan", "Delete" : "Hapus", - "Allow users to mount the following external storage" : "Izinkan pengguna untuk mengaitkan penyimpanan eksternal berikut" + "Allow users to mount the following external storage" : "Izinkan pengguna untuk mengaitkan penyimpanan eksternal berikut", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/id.json b/apps/files_external/l10n/id.json index f7a3054ab8db7..1dddb36316d41 100644 --- a/apps/files_external/l10n/id.json +++ b/apps/files_external/l10n/id.json @@ -98,6 +98,7 @@ "Add storage" : "Tambahkan penyimpanan", "Advanced settings" : "Pengaturan Lanjutan", "Delete" : "Hapus", - "Allow users to mount the following external storage" : "Izinkan pengguna untuk mengaitkan penyimpanan eksternal berikut" + "Allow users to mount the following external storage" : "Izinkan pengguna untuk mengaitkan penyimpanan eksternal berikut", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/is.js b/apps/files_external/l10n/is.js index e57c94ed957da..1326b9e67cfa4 100644 --- a/apps/files_external/l10n/is.js +++ b/apps/files_external/l10n/is.js @@ -22,6 +22,52 @@ OC.L10N.register( "External Storage" : "Ytri gagnageymsla", "Folder name" : "Nafn möppu", "Configuration" : "Uppsetning", - "Delete" : "Eyða" + "Delete" : "Eyða", + "Access key" : "Aðgangslykill", + "Advanced settings" : "Ítarlegri valkostir", + "Amazon S3" : "Amazon S3", + "API key" : "API-lykill", + "Authentication" : "Auðkenning", + "Available for" : "Tiltækt fyrir", + "Bucket" : "Bucket", + "Builtin" : "Innbyggt", + "Check for changes" : "Fylgjast með breytingum", + "Domain" : "Lén", + "Dropbox" : "Dropbox", + "Empty response from the server" : "Tómt svar frá þjóni móttekið", + "Enable previews" : "Virkja forskoðanir", + "Enable sharing" : "Virkja deilingu", + "Enable SSL" : "Virkja SSL", + "Error configuring OAuth1" : "Villa við uppsetningu OAuth1", + "Error configuring OAuth2" : "Villa við uppsetningu OAuth2", + "Error generating key pair" : "Villa við að útbúa nýtt lyklapar", + "External mount error" : "Villa við tengingu í fjartengdu skráakerfi", + "external-storage" : "ytri-gagnageymsla", + "External storage" : "Ytri gagnageymsla", + "FTP" : "FTP", + "Generate keys" : "Útbúa lykla", + "Google Drive" : "Google Drive", + "Hostname" : "Vélarheiti", + "Insufficient data: %s" : "Ónóg gögn: %s", + "Invalid mount point" : "Ógildur tengipunktur", + "Never" : "Aldrei", + "OpenStack" : "OpenStack", + "OpenStack Object Storage" : "OpenStack Object Storage", + "Public key" : "Dreifilykill", + "Rackspace" : "Rackspace", + "Region" : "Svæði", + "Remote subfolder" : "Fjartengd undirmappa", + "Root" : "Rót (root)", + "RSA public key" : "RSA-dreifilykill", + "Scope" : "Umfang", + "Secret key" : "Leynilykill", + "Service name" : "Heiti á þjónustu", + "SFTP" : "SFTP", + "SMB / CIFS" : "SMB / CIFS", + "Step 1 failed. Exception: %s" : "Skref 1 mistókst. Undantekning: %s", + "Step 2 failed. Exception: %s" : "Skref 2 mistókst. Undantekning: %s", + "System" : "Kerfi", + "Username and password" : "Notandanafn og lykilorð", + "Username as share" : "Notandanafn sem sameign" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/files_external/l10n/is.json b/apps/files_external/l10n/is.json index 3de37fd149fa1..e0ce0b8f8721f 100644 --- a/apps/files_external/l10n/is.json +++ b/apps/files_external/l10n/is.json @@ -20,6 +20,52 @@ "External Storage" : "Ytri gagnageymsla", "Folder name" : "Nafn möppu", "Configuration" : "Uppsetning", - "Delete" : "Eyða" + "Delete" : "Eyða", + "Access key" : "Aðgangslykill", + "Advanced settings" : "Ítarlegri valkostir", + "Amazon S3" : "Amazon S3", + "API key" : "API-lykill", + "Authentication" : "Auðkenning", + "Available for" : "Tiltækt fyrir", + "Bucket" : "Bucket", + "Builtin" : "Innbyggt", + "Check for changes" : "Fylgjast með breytingum", + "Domain" : "Lén", + "Dropbox" : "Dropbox", + "Empty response from the server" : "Tómt svar frá þjóni móttekið", + "Enable previews" : "Virkja forskoðanir", + "Enable sharing" : "Virkja deilingu", + "Enable SSL" : "Virkja SSL", + "Error configuring OAuth1" : "Villa við uppsetningu OAuth1", + "Error configuring OAuth2" : "Villa við uppsetningu OAuth2", + "Error generating key pair" : "Villa við að útbúa nýtt lyklapar", + "External mount error" : "Villa við tengingu í fjartengdu skráakerfi", + "external-storage" : "ytri-gagnageymsla", + "External storage" : "Ytri gagnageymsla", + "FTP" : "FTP", + "Generate keys" : "Útbúa lykla", + "Google Drive" : "Google Drive", + "Hostname" : "Vélarheiti", + "Insufficient data: %s" : "Ónóg gögn: %s", + "Invalid mount point" : "Ógildur tengipunktur", + "Never" : "Aldrei", + "OpenStack" : "OpenStack", + "OpenStack Object Storage" : "OpenStack Object Storage", + "Public key" : "Dreifilykill", + "Rackspace" : "Rackspace", + "Region" : "Svæði", + "Remote subfolder" : "Fjartengd undirmappa", + "Root" : "Rót (root)", + "RSA public key" : "RSA-dreifilykill", + "Scope" : "Umfang", + "Secret key" : "Leynilykill", + "Service name" : "Heiti á þjónustu", + "SFTP" : "SFTP", + "SMB / CIFS" : "SMB / CIFS", + "Step 1 failed. Exception: %s" : "Skref 1 mistókst. Undantekning: %s", + "Step 2 failed. Exception: %s" : "Skref 2 mistókst. Undantekning: %s", + "System" : "Kerfi", + "Username and password" : "Notandanafn og lykilorð", + "Username as share" : "Notandanafn sem sameign" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/files_external/l10n/it.js b/apps/files_external/l10n/it.js index 7d92442b8f1ef..802e68ab0fb4c 100644 --- a/apps/files_external/l10n/it.js +++ b/apps/files_external/l10n/it.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Impostazioni avanzate", "Delete" : "Elimina", "Allow users to mount external storage" : "Consenti agli utenti di montare archiviazioni esterne", - "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna" + "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alcuni dei punti di mount esterni configurati non sono connessi. Fai clic sulle righe rosse per ulteriori informazioni" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/it.json b/apps/files_external/l10n/it.json index c447b626d0e97..1549759867afa 100644 --- a/apps/files_external/l10n/it.json +++ b/apps/files_external/l10n/it.json @@ -118,6 +118,8 @@ "Advanced settings" : "Impostazioni avanzate", "Delete" : "Elimina", "Allow users to mount external storage" : "Consenti agli utenti di montare archiviazioni esterne", - "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna" + "Allow users to mount the following external storage" : "Consenti agli utenti di montare la seguente archiviazione esterna", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alcuni dei punti di mount esterni configurati non sono connessi. Fai clic sulle righe rosse per ulteriori informazioni" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/ja.js b/apps/files_external/l10n/ja.js index 07b6c963b4a91..99cbacbdc976a 100644 --- a/apps/files_external/l10n/ja.js +++ b/apps/files_external/l10n/ja.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "詳細設定", "Delete" : "削除", "Allow users to mount external storage" : "ユーザーに外部ストレージの接続を許可する", - "Allow users to mount the following external storage" : "ユーザーに以下の外部ストレージのマウントを許可する" + "Allow users to mount the following external storage" : "ユーザーに以下の外部ストレージのマウントを許可する", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "いくつかの設定済み外部マウントポイントに接続できませんでした。詳細情報は赤い行をクリックしてください" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/ja.json b/apps/files_external/l10n/ja.json index 21767757b599a..4c1fee239676c 100644 --- a/apps/files_external/l10n/ja.json +++ b/apps/files_external/l10n/ja.json @@ -118,6 +118,8 @@ "Advanced settings" : "詳細設定", "Delete" : "削除", "Allow users to mount external storage" : "ユーザーに外部ストレージの接続を許可する", - "Allow users to mount the following external storage" : "ユーザーに以下の外部ストレージのマウントを許可する" + "Allow users to mount the following external storage" : "ユーザーに以下の外部ストレージのマウントを許可する", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "いくつかの設定済み外部マウントポイントに接続できませんでした。詳細情報は赤い行をクリックしてください" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/ko.js b/apps/files_external/l10n/ko.js index 08961646a9700..914f492f1f2e6 100644 --- a/apps/files_external/l10n/ko.js +++ b/apps/files_external/l10n/ko.js @@ -102,6 +102,20 @@ OC.L10N.register( "Advanced settings" : "고급 설정", "Delete" : "삭제", "Allow users to mount external storage" : "사용자가 외부 저장소를 마운트하도록 허용", - "Allow users to mount the following external storage" : "사용자가 다음 외부 저장소를 마운트할 수 있도록 허용" + "Allow users to mount the following external storage" : "사용자가 다음 외부 저장소를 마운트할 수 있도록 허용", + "Admin defined" : "관리자 지정", + "Couldn't access. Please logout and login to activate this mount point" : "접근할 수 없습니다. 이 마운트 지점을 활성화하려면 로그아웃 후 로그인하십시오", + "Couldn't get the list of Windows network drive mount points: empty response from the server" : "Windows 네트워크 드라이브 마운트 지점 목록을 가져올 수 없음: 서버에서 빈 응답이 돌아옴", + "Credentials required" : "인증 정보 필요함", + "Credentials saved" : "인증 정보 저장됨", + "Credentials saving failed" : "인증 정보를 저장할 수 없음", + "Empty response from the server" : "서버에서 빈 응답이 돌아옴", + "Enable sharing" : "공유 사용", + "External mount error" : "외부 마운트 오류", + "external-storage" : "external-storage", + "Log-in credentials, save in session" : "로그인 인증 정보, 세션에 저장됨", + "Please enter the credentials for the {mount} mount" : "{mount} 마운트 인증 정보를 입력하십시오", + "SMB / CIFS" : "SMB/CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "일부 외부 마운트 지점을 연결할 수 없습니다. 빨간색으로 표시된 줄을 눌러서 더 많은 정보를 확인하십시오" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/ko.json b/apps/files_external/l10n/ko.json index 5c23716eb0fef..7f5373e1176a8 100644 --- a/apps/files_external/l10n/ko.json +++ b/apps/files_external/l10n/ko.json @@ -100,6 +100,20 @@ "Advanced settings" : "고급 설정", "Delete" : "삭제", "Allow users to mount external storage" : "사용자가 외부 저장소를 마운트하도록 허용", - "Allow users to mount the following external storage" : "사용자가 다음 외부 저장소를 마운트할 수 있도록 허용" + "Allow users to mount the following external storage" : "사용자가 다음 외부 저장소를 마운트할 수 있도록 허용", + "Admin defined" : "관리자 지정", + "Couldn't access. Please logout and login to activate this mount point" : "접근할 수 없습니다. 이 마운트 지점을 활성화하려면 로그아웃 후 로그인하십시오", + "Couldn't get the list of Windows network drive mount points: empty response from the server" : "Windows 네트워크 드라이브 마운트 지점 목록을 가져올 수 없음: 서버에서 빈 응답이 돌아옴", + "Credentials required" : "인증 정보 필요함", + "Credentials saved" : "인증 정보 저장됨", + "Credentials saving failed" : "인증 정보를 저장할 수 없음", + "Empty response from the server" : "서버에서 빈 응답이 돌아옴", + "Enable sharing" : "공유 사용", + "External mount error" : "외부 마운트 오류", + "external-storage" : "external-storage", + "Log-in credentials, save in session" : "로그인 인증 정보, 세션에 저장됨", + "Please enter the credentials for the {mount} mount" : "{mount} 마운트 인증 정보를 입력하십시오", + "SMB / CIFS" : "SMB/CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "일부 외부 마운트 지점을 연결할 수 없습니다. 빨간색으로 표시된 줄을 눌러서 더 많은 정보를 확인하십시오" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/nb_NO.js b/apps/files_external/l10n/nb_NO.js index f2bc60b147e53..60c525ee115bf 100644 --- a/apps/files_external/l10n/nb_NO.js +++ b/apps/files_external/l10n/nb_NO.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Avanserte innstillinger", "Delete" : "Slett", "Allow users to mount external storage" : "Tillat at brukere kobler opp eksterne lagre", - "Allow users to mount the following external storage" : "Tillat brukere å koble opp følgende eksterne lagring" + "Allow users to mount the following external storage" : "Tillat brukere å koble opp følgende eksterne lagring", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Noen av de konfigurerte eksterne oppkoblingspunktene er ikke tilkoblet. Klikk på de røde raden(e) for mer informasjon." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/nb_NO.json b/apps/files_external/l10n/nb_NO.json index 6de204d29dd80..55ac29f56edad 100644 --- a/apps/files_external/l10n/nb_NO.json +++ b/apps/files_external/l10n/nb_NO.json @@ -118,6 +118,8 @@ "Advanced settings" : "Avanserte innstillinger", "Delete" : "Slett", "Allow users to mount external storage" : "Tillat at brukere kobler opp eksterne lagre", - "Allow users to mount the following external storage" : "Tillat brukere å koble opp følgende eksterne lagring" + "Allow users to mount the following external storage" : "Tillat brukere å koble opp følgende eksterne lagring", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Noen av de konfigurerte eksterne oppkoblingspunktene er ikke tilkoblet. Klikk på de røde raden(e) for mer informasjon." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/nds.js b/apps/files_external/l10n/nds.js index eb23a6d966602..4c3277675f5d5 100644 --- a/apps/files_external/l10n/nds.js +++ b/apps/files_external/l10n/nds.js @@ -94,6 +94,7 @@ OC.L10N.register( "Add storage" : "Speicher hinzufügen", "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", - "Allow users to mount the following external storage" : "Erlaube Benutzern folgenden externen Speicher einzuhängen" + "Allow users to mount the following external storage" : "Erlaube Benutzern folgenden externen Speicher einzuhängen", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/nds.json b/apps/files_external/l10n/nds.json index 3de4a89b020c8..4d2b4aa57ab2c 100644 --- a/apps/files_external/l10n/nds.json +++ b/apps/files_external/l10n/nds.json @@ -92,6 +92,7 @@ "Add storage" : "Speicher hinzufügen", "Advanced settings" : "Erweiterte Einstellungen", "Delete" : "Löschen", - "Allow users to mount the following external storage" : "Erlaube Benutzern folgenden externen Speicher einzuhängen" + "Allow users to mount the following external storage" : "Erlaube Benutzern folgenden externen Speicher einzuhängen", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/nl.js b/apps/files_external/l10n/nl.js index 6e073cf682e5e..e294b009d4540 100644 --- a/apps/files_external/l10n/nl.js +++ b/apps/files_external/l10n/nl.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Geavanceerde instellingen", "Delete" : "Verwijder", "Allow users to mount external storage" : "Sta gebruikers toe om een externe opslag aan te koppelen", - "Allow users to mount the following external storage" : "Sta gebruikers toe de volgende externe opslag aan te koppelen" + "Allow users to mount the following external storage" : "Sta gebruikers toe de volgende externe opslag aan te koppelen", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Sommige van de geconfigureerde koppelpunten zijn niet verbonden. Klik op de rode rij(en) voor meer informatie" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/nl.json b/apps/files_external/l10n/nl.json index 72f822d7f6d16..fdbd807150199 100644 --- a/apps/files_external/l10n/nl.json +++ b/apps/files_external/l10n/nl.json @@ -118,6 +118,8 @@ "Advanced settings" : "Geavanceerde instellingen", "Delete" : "Verwijder", "Allow users to mount external storage" : "Sta gebruikers toe om een externe opslag aan te koppelen", - "Allow users to mount the following external storage" : "Sta gebruikers toe de volgende externe opslag aan te koppelen" + "Allow users to mount the following external storage" : "Sta gebruikers toe de volgende externe opslag aan te koppelen", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Sommige van de geconfigureerde koppelpunten zijn niet verbonden. Klik op de rode rij(en) voor meer informatie" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/oc.js b/apps/files_external/l10n/oc.js index 736e5f77a8a71..a3489cb93e24a 100644 --- a/apps/files_external/l10n/oc.js +++ b/apps/files_external/l10n/oc.js @@ -102,6 +102,7 @@ OC.L10N.register( "Advanced settings" : "Paramètres avançats", "Delete" : "Suprimir", "Allow users to mount external storage" : "Autorizar los utilizaires a montar l'espaci d'emmagazinatge extèrne", - "Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents" + "Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_external/l10n/oc.json b/apps/files_external/l10n/oc.json index 597a5d96301d3..79f2a8c7b2589 100644 --- a/apps/files_external/l10n/oc.json +++ b/apps/files_external/l10n/oc.json @@ -100,6 +100,7 @@ "Advanced settings" : "Paramètres avançats", "Delete" : "Suprimir", "Allow users to mount external storage" : "Autorizar los utilizaires a montar l'espaci d'emmagazinatge extèrne", - "Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents" + "Allow users to mount the following external storage" : "Autorizar los utilizaires a montar los emmagazinatges extèrnes seguents", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/pl.js b/apps/files_external/l10n/pl.js index f79309ff592c5..f9cc3c3877080 100644 --- a/apps/files_external/l10n/pl.js +++ b/apps/files_external/l10n/pl.js @@ -70,6 +70,10 @@ OC.L10N.register( "Add storage" : "Dodaj zasoby dyskowe", "Advanced settings" : "Ustawienia zaawansowane", "Delete" : "Usuń", - "Allow users to mount the following external storage" : "Pozwól użytkownikom montować następujące zewnętrzne zasoby dyskowe" + "Allow users to mount the following external storage" : "Pozwól użytkownikom montować następujące zewnętrzne zasoby dyskowe", + "Access key" : "Klucz dostępu", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Uwaga: Wsparcie dla FTP w PHP nie zostało włączone lub zainstalowane. Zamontowanie %s nie jest możliwe. Proszę poproś Twojego administratora o zainstalowanie go.", + "RSA public key" : "Klucz publiczny RSA", + "SMB / CIFS using OC login" : "SMB / CIFS przy użyciu loginu OC" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_external/l10n/pl.json b/apps/files_external/l10n/pl.json index 05ad6219e48bf..5342948fae244 100644 --- a/apps/files_external/l10n/pl.json +++ b/apps/files_external/l10n/pl.json @@ -68,6 +68,10 @@ "Add storage" : "Dodaj zasoby dyskowe", "Advanced settings" : "Ustawienia zaawansowane", "Delete" : "Usuń", - "Allow users to mount the following external storage" : "Pozwól użytkownikom montować następujące zewnętrzne zasoby dyskowe" + "Allow users to mount the following external storage" : "Pozwól użytkownikom montować następujące zewnętrzne zasoby dyskowe", + "Access key" : "Klucz dostępu", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Uwaga: Wsparcie dla FTP w PHP nie zostało włączone lub zainstalowane. Zamontowanie %s nie jest możliwe. Proszę poproś Twojego administratora o zainstalowanie go.", + "RSA public key" : "Klucz publiczny RSA", + "SMB / CIFS using OC login" : "SMB / CIFS przy użyciu loginu OC" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js index 692334ce6c454..3a5fa93410639 100644 --- a/apps/files_external/l10n/pt_BR.js +++ b/apps/files_external/l10n/pt_BR.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Configurações avançadas", "Delete" : "Excluir", "Allow users to mount external storage" : "Permitir que usuários montem armazenamento externo", - "Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo" + "Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor clique na linha vermelha(s) para mais informações" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json index 0b961f79a8f50..90dc0598c7d09 100644 --- a/apps/files_external/l10n/pt_BR.json +++ b/apps/files_external/l10n/pt_BR.json @@ -118,6 +118,8 @@ "Advanced settings" : "Configurações avançadas", "Delete" : "Excluir", "Allow users to mount external storage" : "Permitir que usuários montem armazenamento externo", - "Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo" + "Allow users to mount the following external storage" : "Permitir que usuários montem o seguinte armazenamento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor clique na linha vermelha(s) para mais informações" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/pt_PT.js b/apps/files_external/l10n/pt_PT.js index d37818dd4c190..699b0ca54f400 100644 --- a/apps/files_external/l10n/pt_PT.js +++ b/apps/files_external/l10n/pt_PT.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Definições avançadas", "Delete" : "Apagar", "Allow users to mount external storage" : "Permitir que os utilizadores montem armazenamento externo", - "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo" + "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor, clique na fila vermelha para mais informação" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/pt_PT.json b/apps/files_external/l10n/pt_PT.json index 7b1ff7f5ef3af..7dd84e6b3ffa5 100644 --- a/apps/files_external/l10n/pt_PT.json +++ b/apps/files_external/l10n/pt_PT.json @@ -118,6 +118,8 @@ "Advanced settings" : "Definições avançadas", "Delete" : "Apagar", "Allow users to mount external storage" : "Permitir que os utilizadores montem armazenamento externo", - "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo" + "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor, clique na fila vermelha para mais informação" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/ru.js b/apps/files_external/l10n/ru.js index 7475a6b5446e4..0236701182fdc 100644 --- a/apps/files_external/l10n/ru.js +++ b/apps/files_external/l10n/ru.js @@ -120,6 +120,8 @@ OC.L10N.register( "Advanced settings" : "Расширенные настройки", "Delete" : "Удалить", "Allow users to mount external storage" : "Разрешить пользователями монтировать внешние накопители", - "Allow users to mount the following external storage" : "Разрешить пользователям монтировать следующие сервисы хранения данных" + "Allow users to mount the following external storage" : "Разрешить пользователям монтировать следующие сервисы хранения данных", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Некоторые из настроенных внешних точек монтирования не подключены. Для получения дополнительной информации, пожалуйста нажмите на красную строку (ы)" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/files_external/l10n/ru.json b/apps/files_external/l10n/ru.json index 657a16910b86c..a571378b8d603 100644 --- a/apps/files_external/l10n/ru.json +++ b/apps/files_external/l10n/ru.json @@ -118,6 +118,8 @@ "Advanced settings" : "Расширенные настройки", "Delete" : "Удалить", "Allow users to mount external storage" : "Разрешить пользователями монтировать внешние накопители", - "Allow users to mount the following external storage" : "Разрешить пользователям монтировать следующие сервисы хранения данных" + "Allow users to mount the following external storage" : "Разрешить пользователям монтировать следующие сервисы хранения данных", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Некоторые из настроенных внешних точек монтирования не подключены. Для получения дополнительной информации, пожалуйста нажмите на красную строку (ы)" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/files_external/l10n/sk_SK.js b/apps/files_external/l10n/sk_SK.js index 8c1f74051b045..0d476fe9d3770 100644 --- a/apps/files_external/l10n/sk_SK.js +++ b/apps/files_external/l10n/sk_SK.js @@ -99,6 +99,7 @@ OC.L10N.register( "Add storage" : "Pridať úložisko", "Advanced settings" : "Rozšírené nastavenia", "Delete" : "Zmazať", - "Allow users to mount the following external storage" : "Povoliť používateľom pripojiť tieto externé úložiská" + "Allow users to mount the following external storage" : "Povoliť používateľom pripojiť tieto externé úložiská", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files_external/l10n/sk_SK.json b/apps/files_external/l10n/sk_SK.json index d2bf8c3792689..5a61368693a01 100644 --- a/apps/files_external/l10n/sk_SK.json +++ b/apps/files_external/l10n/sk_SK.json @@ -97,6 +97,7 @@ "Add storage" : "Pridať úložisko", "Advanced settings" : "Rozšírené nastavenia", "Delete" : "Zmazať", - "Allow users to mount the following external storage" : "Povoliť používateľom pripojiť tieto externé úložiská" + "Allow users to mount the following external storage" : "Povoliť používateľom pripojiť tieto externé úložiská", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files_external/l10n/sl.js b/apps/files_external/l10n/sl.js index 09ed491559a82..78f4caec88bc8 100644 --- a/apps/files_external/l10n/sl.js +++ b/apps/files_external/l10n/sl.js @@ -92,6 +92,17 @@ OC.L10N.register( "Advanced settings" : "Napredne nastavitve", "Delete" : "Izbriši", "Allow users to mount external storage" : "Dovoli uporabnikom priklapljanje zunanje shrambe", - "Allow users to mount the following external storage" : "Dovoli uporabnikom priklapljanje navedenih zunanjih shramb." + "Allow users to mount the following external storage" : "Dovoli uporabnikom priklapljanje navedenih zunanjih shramb.", + "Admin defined" : "Skrbnik je določen", + "Credentials required" : "Zahtevana so poverila", + "Credentials saved" : "Poverila so shranjena", + "Credentials saving failed" : "Shranjevanje poveril je spodletelo", + "Enable sharing" : "Omogoči souporabo", + "external-storage" : "zunanja-shramba", + "Identity endpoint URL" : "Naslov URL končne točke istovetnosti", + "Please enter the credentials for the {mount} mount" : "Vpišite poverila za priklopno točko {mount}", + "SMB / CIFS" : "SMB / CIFS", + "Unsatisfied authentication mechanism parameters" : "Nezadovoljivi parametri mehanizma overitve", + "Unsatisfied backend parameters" : "Nezadovoljivi parametri ozadnjega programa" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/files_external/l10n/sl.json b/apps/files_external/l10n/sl.json index 4aefcc681dd69..0b475c2036fea 100644 --- a/apps/files_external/l10n/sl.json +++ b/apps/files_external/l10n/sl.json @@ -90,6 +90,17 @@ "Advanced settings" : "Napredne nastavitve", "Delete" : "Izbriši", "Allow users to mount external storage" : "Dovoli uporabnikom priklapljanje zunanje shrambe", - "Allow users to mount the following external storage" : "Dovoli uporabnikom priklapljanje navedenih zunanjih shramb." + "Allow users to mount the following external storage" : "Dovoli uporabnikom priklapljanje navedenih zunanjih shramb.", + "Admin defined" : "Skrbnik je določen", + "Credentials required" : "Zahtevana so poverila", + "Credentials saved" : "Poverila so shranjena", + "Credentials saving failed" : "Shranjevanje poveril je spodletelo", + "Enable sharing" : "Omogoči souporabo", + "external-storage" : "zunanja-shramba", + "Identity endpoint URL" : "Naslov URL končne točke istovetnosti", + "Please enter the credentials for the {mount} mount" : "Vpišite poverila za priklopno točko {mount}", + "SMB / CIFS" : "SMB / CIFS", + "Unsatisfied authentication mechanism parameters" : "Nezadovoljivi parametri mehanizma overitve", + "Unsatisfied backend parameters" : "Nezadovoljivi parametri ozadnjega programa" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/files_external/l10n/sq.js b/apps/files_external/l10n/sq.js index ce1ceaa3ba13a..4f5c81d3c8a82 100644 --- a/apps/files_external/l10n/sq.js +++ b/apps/files_external/l10n/sq.js @@ -118,6 +118,8 @@ OC.L10N.register( "Advanced settings" : "Rregullime të mëtejshme", "Delete" : "Fshije", "Allow users to mount external storage" : "Lejoju përdoruesve të montojnë depozita të jashtme", - "Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese" + "Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Disa nga pikat e jashtme të formësuara të montimit s’janë të lidhura. Ju lutemi, klikoni në shigjetën(at) e kuqe për më tepër të dhëna" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/sq.json b/apps/files_external/l10n/sq.json index f6eae29a17fb8..d703eef1b769a 100644 --- a/apps/files_external/l10n/sq.json +++ b/apps/files_external/l10n/sq.json @@ -116,6 +116,8 @@ "Advanced settings" : "Rregullime të mëtejshme", "Delete" : "Fshije", "Allow users to mount external storage" : "Lejoju përdoruesve të montojnë depozita të jashtme", - "Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese" + "Allow users to mount the following external storage" : "Lejoju përdoruesve të montojnë depozitën e jashtme vijuese", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Disa nga pikat e jashtme të formësuara të montimit s’janë të lidhura. Ju lutemi, klikoni në shigjetën(at) e kuqe për më tepër të dhëna" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/sr.js b/apps/files_external/l10n/sr.js index ca9d0fcc61284..a433a987025e4 100644 --- a/apps/files_external/l10n/sr.js +++ b/apps/files_external/l10n/sr.js @@ -69,6 +69,13 @@ OC.L10N.register( "Add storage" : "Додај складиште", "Advanced settings" : "Напредне поставке", "Delete" : "Обриши", - "Allow users to mount the following external storage" : "Дозволи корисницима да монтирају следећа спољашња складишта" + "Allow users to mount the following external storage" : "Дозволи корисницима да монтирају следећа спољашња складишта", + "Authentication" : "Аутентификација", + "Domain" : "Домен", + "Enable sharing" : "Укључи дељење", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Напомена: ФТП подршка за ПХП није омогућена или инсталирана. Монтирање %s није могуће. Затражите од вашег администратора система да је инсталира.", + "Root" : "Корен", + "Service name" : "Назив услуге", + "SMB / CIFS" : "ЦМБ/ЦИФС" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_external/l10n/sr.json b/apps/files_external/l10n/sr.json index 5d694fd97d712..2cfb8be09caa3 100644 --- a/apps/files_external/l10n/sr.json +++ b/apps/files_external/l10n/sr.json @@ -67,6 +67,13 @@ "Add storage" : "Додај складиште", "Advanced settings" : "Напредне поставке", "Delete" : "Обриши", - "Allow users to mount the following external storage" : "Дозволи корисницима да монтирају следећа спољашња складишта" + "Allow users to mount the following external storage" : "Дозволи корисницима да монтирају следећа спољашња складишта", + "Authentication" : "Аутентификација", + "Domain" : "Домен", + "Enable sharing" : "Укључи дељење", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Напомена: ФТП подршка за ПХП није омогућена или инсталирана. Монтирање %s није могуће. Затражите од вашег администратора система да је инсталира.", + "Root" : "Корен", + "Service name" : "Назив услуге", + "SMB / CIFS" : "ЦМБ/ЦИФС" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_external/l10n/sr@latin.js b/apps/files_external/l10n/sr@latin.js index 68954a6b6ae72..c3cb72f95a447 100644 --- a/apps/files_external/l10n/sr@latin.js +++ b/apps/files_external/l10n/sr@latin.js @@ -51,6 +51,8 @@ OC.L10N.register( "Available for" : "Dostupno za", "Add storage" : "Dodaj skladište", "Delete" : "Obriši", - "Allow users to mount the following external storage" : "Omogući korisnicima da namontiraju sledeće spoljašnje skladište" + "Allow users to mount the following external storage" : "Omogući korisnicima da namontiraju sledeće spoljašnje skladište", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Obratite pažnju: FTP podrška u PHP-u nije uključena ili instalirana. Montiranje %s nije moguće. Molimo Vas da tražite od Vašeg sistem administratora da je instalira.", + "SMB / CIFS using OC login" : "SMB / CIFS koji koristi OC prijavljivanje" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_external/l10n/sr@latin.json b/apps/files_external/l10n/sr@latin.json index ffe95d4a52e30..5d27d22b4afe6 100644 --- a/apps/files_external/l10n/sr@latin.json +++ b/apps/files_external/l10n/sr@latin.json @@ -49,6 +49,8 @@ "Available for" : "Dostupno za", "Add storage" : "Dodaj skladište", "Delete" : "Obriši", - "Allow users to mount the following external storage" : "Omogući korisnicima da namontiraju sledeće spoljašnje skladište" + "Allow users to mount the following external storage" : "Omogući korisnicima da namontiraju sledeće spoljašnje skladište", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Obratite pažnju: FTP podrška u PHP-u nije uključena ili instalirana. Montiranje %s nije moguće. Molimo Vas da tražite od Vašeg sistem administratora da je instalira.", + "SMB / CIFS using OC login" : "SMB / CIFS koji koristi OC prijavljivanje" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_external/l10n/sv.js b/apps/files_external/l10n/sv.js index 51567940df1a0..da78247a546b3 100644 --- a/apps/files_external/l10n/sv.js +++ b/apps/files_external/l10n/sv.js @@ -97,6 +97,7 @@ OC.L10N.register( "Advanced settings" : "Avancerade inställningar", "Delete" : "Radera", "Allow users to mount external storage" : "Tillåt användare att montera extern lagring", - "Allow users to mount the following external storage" : "Tillåt användare att montera följande extern lagring" + "Allow users to mount the following external storage" : "Tillåt användare att montera följande extern lagring", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/sv.json b/apps/files_external/l10n/sv.json index 0a264bba4c1ea..dc7ca84467a7d 100644 --- a/apps/files_external/l10n/sv.json +++ b/apps/files_external/l10n/sv.json @@ -95,6 +95,7 @@ "Advanced settings" : "Avancerade inställningar", "Delete" : "Radera", "Allow users to mount external storage" : "Tillåt användare att montera extern lagring", - "Allow users to mount the following external storage" : "Tillåt användare att montera följande extern lagring" + "Allow users to mount the following external storage" : "Tillåt användare att montera följande extern lagring", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/th_TH.js b/apps/files_external/l10n/th_TH.js index 7668864cc607e..7f99058426cc9 100644 --- a/apps/files_external/l10n/th_TH.js +++ b/apps/files_external/l10n/th_TH.js @@ -115,6 +115,8 @@ OC.L10N.register( "Advanced settings" : "ตั้งค่าขั้นสูง", "Delete" : "ลบ", "Allow users to mount external storage" : "อนุญาตให้ผู้ใช้ติดตั้งการจัดเก็บข้อมูลภายนอก", - "Allow users to mount the following external storage" : "อนุญาตให้ผู้ใช้ติดตั้งจัดเก็บข้อมูลภายนอกต่อไปนี้" + "Allow users to mount the following external storage" : "อนุญาตให้ผู้ใช้ติดตั้งจัดเก็บข้อมูลภายนอกต่อไปนี้", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "การกำหนดค่าบางส่วนของจุดเชื่อมต่อภายนอกไม่ถูกเชื่อมต่อ กรุณาคลิกที่ตรงสีแดงสำหรับข้อมูลเพิ่มเติม" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/th_TH.json b/apps/files_external/l10n/th_TH.json index 7eccb2d371876..1705169ba6268 100644 --- a/apps/files_external/l10n/th_TH.json +++ b/apps/files_external/l10n/th_TH.json @@ -113,6 +113,8 @@ "Advanced settings" : "ตั้งค่าขั้นสูง", "Delete" : "ลบ", "Allow users to mount external storage" : "อนุญาตให้ผู้ใช้ติดตั้งการจัดเก็บข้อมูลภายนอก", - "Allow users to mount the following external storage" : "อนุญาตให้ผู้ใช้ติดตั้งจัดเก็บข้อมูลภายนอกต่อไปนี้" + "Allow users to mount the following external storage" : "อนุญาตให้ผู้ใช้ติดตั้งจัดเก็บข้อมูลภายนอกต่อไปนี้", + "SMB / CIFS" : "SMB / CIFS", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "การกำหนดค่าบางส่วนของจุดเชื่อมต่อภายนอกไม่ถูกเชื่อมต่อ กรุณาคลิกที่ตรงสีแดงสำหรับข้อมูลเพิ่มเติม" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/tr.js b/apps/files_external/l10n/tr.js index dfbbef593aee1..aa1d70c63d419 100644 --- a/apps/files_external/l10n/tr.js +++ b/apps/files_external/l10n/tr.js @@ -112,6 +112,7 @@ OC.L10N.register( "Advanced settings" : "Gelişmiş ayarlar", "Delete" : "Sil", "Allow users to mount external storage" : "Kullanıcılara harici depolama bağlamalarına izin ver", - "Allow users to mount the following external storage" : "Kullanıcıların aşağıdaki harici depolamayı bağlamalarına izin ver" + "Allow users to mount the following external storage" : "Kullanıcıların aşağıdaki harici depolamayı bağlamalarına izin ver", + "SMB / CIFS" : "SMB / CIFS" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_external/l10n/tr.json b/apps/files_external/l10n/tr.json index 2b1296e3c6f77..249ae1e6a0bd0 100644 --- a/apps/files_external/l10n/tr.json +++ b/apps/files_external/l10n/tr.json @@ -110,6 +110,7 @@ "Advanced settings" : "Gelişmiş ayarlar", "Delete" : "Sil", "Allow users to mount external storage" : "Kullanıcılara harici depolama bağlamalarına izin ver", - "Allow users to mount the following external storage" : "Kullanıcıların aşağıdaki harici depolamayı bağlamalarına izin ver" + "Allow users to mount the following external storage" : "Kullanıcıların aşağıdaki harici depolamayı bağlamalarına izin ver", + "SMB / CIFS" : "SMB / CIFS" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_external/l10n/uk.js b/apps/files_external/l10n/uk.js index 9341782dc86e9..d4a3a44594027 100644 --- a/apps/files_external/l10n/uk.js +++ b/apps/files_external/l10n/uk.js @@ -65,6 +65,8 @@ OC.L10N.register( "Add storage" : "Додати сховище", "Advanced settings" : "Розширені налаштування", "Delete" : "Видалити", - "Allow users to mount the following external storage" : "Дозволити користувачам монтувати наступні зовнішні сховища" + "Allow users to mount the following external storage" : "Дозволити користувачам монтувати наступні зовнішні сховища", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Примітка: Підтримку FTP в PHP не ввімкнено чи не встановлена. Під'єднатися до %s неможливо. Зверніться до системного адміністратора.", + "SMB / CIFS using OC login" : "SMB / CIFS з використанням логіна OC" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_external/l10n/uk.json b/apps/files_external/l10n/uk.json index a76795cba5e29..f19ca74468a6c 100644 --- a/apps/files_external/l10n/uk.json +++ b/apps/files_external/l10n/uk.json @@ -63,6 +63,8 @@ "Add storage" : "Додати сховище", "Advanced settings" : "Розширені налаштування", "Delete" : "Видалити", - "Allow users to mount the following external storage" : "Дозволити користувачам монтувати наступні зовнішні сховища" + "Allow users to mount the following external storage" : "Дозволити користувачам монтувати наступні зовнішні сховища", + "Note: The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Примітка: Підтримку FTP в PHP не ввімкнено чи не встановлена. Під'єднатися до %s неможливо. Зверніться до системного адміністратора.", + "SMB / CIFS using OC login" : "SMB / CIFS з використанням логіна OC" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_external/l10n/zh_CN.js b/apps/files_external/l10n/zh_CN.js index 0f00952e855f3..4dee71587fdee 100644 --- a/apps/files_external/l10n/zh_CN.js +++ b/apps/files_external/l10n/zh_CN.js @@ -55,6 +55,19 @@ OC.L10N.register( "Add storage" : "增加存储", "Advanced settings" : "高级选项", "Delete" : "删除", - "Allow users to mount the following external storage" : "允许用户挂载以下外部存储" + "Allow users to mount the following external storage" : "允许用户挂载以下外部存储", + "Allow users to mount external storage" : "允许用户挂载外部存储", + "Builtin" : "内置", + "Enable previews" : "启用预览", + "Enable sharing" : "启用分享", + "External mount error" : "外部挂载错误", + "Hostname" : "主机名", + "Invalid mount point" : "无效的挂载点", + "No external storage configured" : "未配置外部存储", + "Public key" : "公钥", + "RSA public key" : "RSA 公钥", + "SMB / CIFS" : "SMB / CIFS", + "Username and password" : "用户名和密码", + "You can add external storages in the personal settings" : "您可以在个人设置中添加外部存储" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/zh_CN.json b/apps/files_external/l10n/zh_CN.json index bbdc3beaf0160..bf9c18ba51858 100644 --- a/apps/files_external/l10n/zh_CN.json +++ b/apps/files_external/l10n/zh_CN.json @@ -53,6 +53,19 @@ "Add storage" : "增加存储", "Advanced settings" : "高级选项", "Delete" : "删除", - "Allow users to mount the following external storage" : "允许用户挂载以下外部存储" + "Allow users to mount the following external storage" : "允许用户挂载以下外部存储", + "Allow users to mount external storage" : "允许用户挂载外部存储", + "Builtin" : "内置", + "Enable previews" : "启用预览", + "Enable sharing" : "启用分享", + "External mount error" : "外部挂载错误", + "Hostname" : "主机名", + "Invalid mount point" : "无效的挂载点", + "No external storage configured" : "未配置外部存储", + "Public key" : "公钥", + "RSA public key" : "RSA 公钥", + "SMB / CIFS" : "SMB / CIFS", + "Username and password" : "用户名和密码", + "You can add external storages in the personal settings" : "您可以在个人设置中添加外部存储" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_external/l10n/zh_TW.js b/apps/files_external/l10n/zh_TW.js index b61b2e61b8b7e..44d4a23366ef1 100644 --- a/apps/files_external/l10n/zh_TW.js +++ b/apps/files_external/l10n/zh_TW.js @@ -102,6 +102,7 @@ OC.L10N.register( "Advanced settings" : "進階設定", "Delete" : "刪除", "Allow users to mount external storage" : "允許使用者能自行掛載外部儲存", - "Allow users to mount the following external storage" : "允許使用者自行掛載以下的外部儲存" + "Allow users to mount the following external storage" : "允許使用者自行掛載以下的外部儲存", + "SMB / CIFS" : "伺服器訊息區塊-SMB/網路文件共享系統 (CIFS)" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/zh_TW.json b/apps/files_external/l10n/zh_TW.json index 72d17f93161cc..ea94facc9237e 100644 --- a/apps/files_external/l10n/zh_TW.json +++ b/apps/files_external/l10n/zh_TW.json @@ -100,6 +100,7 @@ "Advanced settings" : "進階設定", "Delete" : "刪除", "Allow users to mount external storage" : "允許使用者能自行掛載外部儲存", - "Allow users to mount the following external storage" : "允許使用者自行掛載以下的外部儲存" + "Allow users to mount the following external storage" : "允許使用者自行掛載以下的外部儲存", + "SMB / CIFS" : "伺服器訊息區塊-SMB/網路文件共享系統 (CIFS)" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/az.js b/apps/files_sharing/l10n/az.js index 5cec471aa24c7..bdc8948bf8e20 100644 --- a/apps/files_sharing/l10n/az.js +++ b/apps/files_sharing/l10n/az.js @@ -59,6 +59,8 @@ OC.L10N.register( "Federated Cloud Sharing" : "Federal Cloud Paylaşım", "Open documentation" : "Sənədləri aç", "Allow users on this server to send shares to other servers" : "Bu serverdən digər serverlərə istifadəçilər tərəfindən paylaşımın göndərilməsinə izin vermək", - "Allow users on this server to receive shares from other servers" : "Digər serverlərdən bu serverə istifadəçilər tərəfindən paylaşımın ötürülməsinə izin vermək" + "Allow users on this server to receive shares from other servers" : "Digər serverlərdən bu serverə istifadəçilər tərəfindən paylaşımın ötürülməsinə izin vermək", + "Public shared file %1$s was downloaded" : "Ümumi paylaşılmış fayl %1$s endirilmişdir", + "Public shared folder %1$s was downloaded" : "Ümumi paylaşılmış qovluq %1$s endirilmişdir" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/az.json b/apps/files_sharing/l10n/az.json index bd74add7ca8a5..d078efadbb8ce 100644 --- a/apps/files_sharing/l10n/az.json +++ b/apps/files_sharing/l10n/az.json @@ -57,6 +57,8 @@ "Federated Cloud Sharing" : "Federal Cloud Paylaşım", "Open documentation" : "Sənədləri aç", "Allow users on this server to send shares to other servers" : "Bu serverdən digər serverlərə istifadəçilər tərəfindən paylaşımın göndərilməsinə izin vermək", - "Allow users on this server to receive shares from other servers" : "Digər serverlərdən bu serverə istifadəçilər tərəfindən paylaşımın ötürülməsinə izin vermək" + "Allow users on this server to receive shares from other servers" : "Digər serverlərdən bu serverə istifadəçilər tərəfindən paylaşımın ötürülməsinə izin vermək", + "Public shared file %1$s was downloaded" : "Ümumi paylaşılmış fayl %1$s endirilmişdir", + "Public shared folder %1$s was downloaded" : "Ümumi paylaşılmış qovluq %1$s endirilmişdir" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/bg_BG.js b/apps/files_sharing/l10n/bg_BG.js index 540f7d0f14aba..d8cc03e3ab7ba 100644 --- a/apps/files_sharing/l10n/bg_BG.js +++ b/apps/files_sharing/l10n/bg_BG.js @@ -53,6 +53,8 @@ OC.L10N.register( "Download %s" : "Изтегли %s", "Direct link" : "Директна връзка", "Allow users on this server to send shares to other servers" : "Позволи на потребители от този сървър да споделят папки с други сървъри", - "Allow users on this server to receive shares from other servers" : "Позволи на потребители на този сървър да получават споделени папки от други сървъри" + "Allow users on this server to receive shares from other servers" : "Позволи на потребители на този сървър да получават споделени папки от други сървъри", + "Public shared file %1$s was downloaded" : "Публично споделения файл %1$s бе изтеглен", + "Public shared folder %1$s was downloaded" : "Публично споделената папка %1$s бе изтеглена" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/bg_BG.json b/apps/files_sharing/l10n/bg_BG.json index 18dddd90cbcb5..0635f08c1ce4e 100644 --- a/apps/files_sharing/l10n/bg_BG.json +++ b/apps/files_sharing/l10n/bg_BG.json @@ -51,6 +51,8 @@ "Download %s" : "Изтегли %s", "Direct link" : "Директна връзка", "Allow users on this server to send shares to other servers" : "Позволи на потребители от този сървър да споделят папки с други сървъри", - "Allow users on this server to receive shares from other servers" : "Позволи на потребители на този сървър да получават споделени папки от други сървъри" + "Allow users on this server to receive shares from other servers" : "Позволи на потребители на този сървър да получават споделени папки от други сървъри", + "Public shared file %1$s was downloaded" : "Публично споделения файл %1$s бе изтеглен", + "Public shared folder %1$s was downloaded" : "Публично споделената папка %1$s бе изтеглена" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/cs_CZ.js b/apps/files_sharing/l10n/cs_CZ.js index 3394608fd6f34..4fd4561b13f95 100644 --- a/apps/files_sharing/l10n/cs_CZ.js +++ b/apps/files_sharing/l10n/cs_CZ.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Sdílet:", "Add to your website" : "Přidat na svou webovou stránku", "Share with me via ownCloud" : "Sdíleno se mnou přes ownCloud", - "HTML Code:" : "HTML kód:" + "HTML Code:" : "HTML kód:", + "Public link of %2$s expired" : "Veřejný odkaz %2$s vypršel", + "Public shared file %1$s was downloaded" : "Byl stažen veřejně sdílený soubor %1$s ", + "Public shared folder %1$s was downloaded" : "Byl stažen veřejně sdílený adresář %1$s ", + "Removed share for %2$s" : "Odstranil(a) sdílení pro %2$s", + "Removed share of group %2$s" : "Odstranil(a) sdílení skupině %2$s", + "Shared by %2$s" : "%2$s sdílel(a)", + "Shared via link by %2$s" : "%2$s sdílel(a) jako odkaz", + "Shared with group %3$s by %2$s" : "%2$s sdílí se skupinou %3$s", + "The public link of %2$s for %1$s expired" : "Veřejný odkaz na %2$s pro %1$s vypršel", + "You removed the public link for %1$s" : "Odstranil(a) jsi veřejný odkaz na %1$s", + "You removed the share of %2$s for %1$s" : "Odstranil(a) jsi sdílení %2$s pro %1$s", + "You removed the share of group %2$s for %1$s" : "Odstranil(a) jsi sdílení skupině %2$s pro %1$s", + "Your public link for %1$s expired" : "Veřejný odkaz pro %1$s vypršel" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files_sharing/l10n/cs_CZ.json b/apps/files_sharing/l10n/cs_CZ.json index d193eb69373a7..9767ec01f630b 100644 --- a/apps/files_sharing/l10n/cs_CZ.json +++ b/apps/files_sharing/l10n/cs_CZ.json @@ -99,6 +99,19 @@ "Share it:" : "Sdílet:", "Add to your website" : "Přidat na svou webovou stránku", "Share with me via ownCloud" : "Sdíleno se mnou přes ownCloud", - "HTML Code:" : "HTML kód:" + "HTML Code:" : "HTML kód:", + "Public link of %2$s expired" : "Veřejný odkaz %2$s vypršel", + "Public shared file %1$s was downloaded" : "Byl stažen veřejně sdílený soubor %1$s ", + "Public shared folder %1$s was downloaded" : "Byl stažen veřejně sdílený adresář %1$s ", + "Removed share for %2$s" : "Odstranil(a) sdílení pro %2$s", + "Removed share of group %2$s" : "Odstranil(a) sdílení skupině %2$s", + "Shared by %2$s" : "%2$s sdílel(a)", + "Shared via link by %2$s" : "%2$s sdílel(a) jako odkaz", + "Shared with group %3$s by %2$s" : "%2$s sdílí se skupinou %3$s", + "The public link of %2$s for %1$s expired" : "Veřejný odkaz na %2$s pro %1$s vypršel", + "You removed the public link for %1$s" : "Odstranil(a) jsi veřejný odkaz na %1$s", + "You removed the share of %2$s for %1$s" : "Odstranil(a) jsi sdílení %2$s pro %1$s", + "You removed the share of group %2$s for %1$s" : "Odstranil(a) jsi sdílení skupině %2$s pro %1$s", + "Your public link for %1$s expired" : "Veřejný odkaz pro %1$s vypršel" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/da.js b/apps/files_sharing/l10n/da.js index d3ba2463591d3..3b6bba58f18bd 100644 --- a/apps/files_sharing/l10n/da.js +++ b/apps/files_sharing/l10n/da.js @@ -81,6 +81,11 @@ OC.L10N.register( "Share it:" : "Del:", "Add to your website" : "Tilføj til dit websted", "Share with me via ownCloud" : "Del med mig gennem ownCloud", - "HTML Code:" : "HTMLkode:" + "HTML Code:" : "HTMLkode:", + "Public shared file %1$s was downloaded" : "Den offentligt delte fil %1$s blev downloadet", + "Public shared folder %1$s was downloaded" : "Den offentligt delte mappe %1$s blev downloadet", + "Shared by %2$s" : "Delt af %2$s", + "Shared via link by %2$s" : "Delt via link af %2$s", + "Shared with group %3$s by %2$s" : "Delt med gruppen %3$s af %2$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/da.json b/apps/files_sharing/l10n/da.json index d447dee544e35..daf55f1fd059f 100644 --- a/apps/files_sharing/l10n/da.json +++ b/apps/files_sharing/l10n/da.json @@ -79,6 +79,11 @@ "Share it:" : "Del:", "Add to your website" : "Tilføj til dit websted", "Share with me via ownCloud" : "Del med mig gennem ownCloud", - "HTML Code:" : "HTMLkode:" + "HTML Code:" : "HTMLkode:", + "Public shared file %1$s was downloaded" : "Den offentligt delte fil %1$s blev downloadet", + "Public shared folder %1$s was downloaded" : "Den offentligt delte mappe %1$s blev downloadet", + "Shared by %2$s" : "Delt af %2$s", + "Shared via link by %2$s" : "Delt via link af %2$s", + "Shared with group %3$s by %2$s" : "Delt med gruppen %3$s af %2$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/de.js b/apps/files_sharing/l10n/de.js index 176702670f516..77d1644b93369 100644 --- a/apps/files_sharing/l10n/de.js +++ b/apps/files_sharing/l10n/de.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Zum Teilen:", "Add to your website" : "Zu deiner Webseite hinzufügen", "Share with me via ownCloud" : "Teile mit mir über ownCloud", - "HTML Code:" : "HTML-Code:" + "HTML Code:" : "HTML-Code:", + "Public link of %2$s expired" : "Öffentlicher Link von %2$s ist abgelaufen", + "Public shared file %1$s was downloaded" : "Die öffentliche geteilte Datei %1$s wurde heruntergeladen", + "Public shared folder %1$s was downloaded" : "Der öffentliche geteilte Ordner %1$s wurde heruntergeladen", + "Removed share for %2$s" : "Freigabe für %2$s entfernt", + "Removed share of group %2$s" : "Freigabe für Gruppe %2$s entfernt", + "Shared by %2$s" : "Geteilt von %2$s", + "Shared via link by %2$s" : "Geteilt mittels Link von %2$s", + "Shared with group %3$s by %2$s" : "Freigabe für Gruppe %3$s von %2$s entfernt", + "The public link of %2$s for %1$s expired" : "Der öffentliche Link von %2$s für %1$s ist abgelaufen", + "You removed the public link for %1$s" : "Du hast den öffentlichen Link für %1$s entfernt", + "You removed the share of %2$s for %1$s" : "Du hast die Freigabe von %2$s für %1$s entfernt", + "You removed the share of group %2$s for %1$s" : "Du hast die Freigabe der Gruppe %2$s für %1$s entfernt", + "Your public link for %1$s expired" : "Dein öffentlicher Link für %1$s ist abgelaufen" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/de.json b/apps/files_sharing/l10n/de.json index 8b7649b760e7c..92ae5a6ea305d 100644 --- a/apps/files_sharing/l10n/de.json +++ b/apps/files_sharing/l10n/de.json @@ -99,6 +99,19 @@ "Share it:" : "Zum Teilen:", "Add to your website" : "Zu deiner Webseite hinzufügen", "Share with me via ownCloud" : "Teile mit mir über ownCloud", - "HTML Code:" : "HTML-Code:" + "HTML Code:" : "HTML-Code:", + "Public link of %2$s expired" : "Öffentlicher Link von %2$s ist abgelaufen", + "Public shared file %1$s was downloaded" : "Die öffentliche geteilte Datei %1$s wurde heruntergeladen", + "Public shared folder %1$s was downloaded" : "Der öffentliche geteilte Ordner %1$s wurde heruntergeladen", + "Removed share for %2$s" : "Freigabe für %2$s entfernt", + "Removed share of group %2$s" : "Freigabe für Gruppe %2$s entfernt", + "Shared by %2$s" : "Geteilt von %2$s", + "Shared via link by %2$s" : "Geteilt mittels Link von %2$s", + "Shared with group %3$s by %2$s" : "Freigabe für Gruppe %3$s von %2$s entfernt", + "The public link of %2$s for %1$s expired" : "Der öffentliche Link von %2$s für %1$s ist abgelaufen", + "You removed the public link for %1$s" : "Du hast den öffentlichen Link für %1$s entfernt", + "You removed the share of %2$s for %1$s" : "Du hast die Freigabe von %2$s für %1$s entfernt", + "You removed the share of group %2$s for %1$s" : "Du hast die Freigabe der Gruppe %2$s für %1$s entfernt", + "Your public link for %1$s expired" : "Dein öffentlicher Link für %1$s ist abgelaufen" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/de_DE.js b/apps/files_sharing/l10n/de_DE.js index 70db30c685590..e54cec7e50149 100644 --- a/apps/files_sharing/l10n/de_DE.js +++ b/apps/files_sharing/l10n/de_DE.js @@ -82,6 +82,20 @@ OC.L10N.register( "Share it:" : "Zum Teilen:", "Add to your website" : "Zu Ihrer Website hinzufügen", "Share with me via ownCloud" : "Teilen Sie mit mir über ownCloud", - "HTML Code:" : "HTML-Code:" + "HTML Code:" : "HTML-Code:", + "Not allowed to create a federated share with the same user server" : "Das Erstellen einer Federated Cloud Freigabe mit dem gleichen Benutzer ist nicht erlaubt", + "Public link of %2$s expired" : "Öffentlicher Link von %2$s ist abgelaufen", + "Public shared file %1$s was downloaded" : "Die öffentliche geteilte Datei %1$s wurde heruntergeladen", + "Public shared folder %1$s was downloaded" : "Der öffentliche geteilte Ordner %1$s wurde heruntergeladen", + "Removed share for %2$s" : "Freigabe für %2$s entfernt", + "Removed share of group %2$s" : "Freigabe für Gruppe %2$s entfernt", + "Shared by %2$s" : "Geteilt von %2$s", + "Shared via link by %2$s" : "Geteilt durch einen Link von %2$s", + "Shared with group %3$s by %2$s" : "Geteilt mit der Gruppe %3$s von %2$s", + "The public link of %2$s for %1$s expired" : "Die Freigabe als Link von %2$s für %1$s ist abgelaufen", + "You removed the public link for %1$s" : "Sie haben die Freigabe als Link für %1$s entfernt", + "You removed the share of %2$s for %1$s" : "Sie haben die Freigabe von %2$s für %1$s entfernt", + "You removed the share of group %2$s for %1$s" : "Sie haben die Freigabe der Gruppe %2$s für %1$s entfernt", + "Your public link for %1$s expired" : "Ihre Freigabe als Link für %1$s ist abgelaufen" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/de_DE.json b/apps/files_sharing/l10n/de_DE.json index 6a3f9b353dbcb..c07d4a0fabcd7 100644 --- a/apps/files_sharing/l10n/de_DE.json +++ b/apps/files_sharing/l10n/de_DE.json @@ -80,6 +80,20 @@ "Share it:" : "Zum Teilen:", "Add to your website" : "Zu Ihrer Website hinzufügen", "Share with me via ownCloud" : "Teilen Sie mit mir über ownCloud", - "HTML Code:" : "HTML-Code:" + "HTML Code:" : "HTML-Code:", + "Not allowed to create a federated share with the same user server" : "Das Erstellen einer Federated Cloud Freigabe mit dem gleichen Benutzer ist nicht erlaubt", + "Public link of %2$s expired" : "Öffentlicher Link von %2$s ist abgelaufen", + "Public shared file %1$s was downloaded" : "Die öffentliche geteilte Datei %1$s wurde heruntergeladen", + "Public shared folder %1$s was downloaded" : "Der öffentliche geteilte Ordner %1$s wurde heruntergeladen", + "Removed share for %2$s" : "Freigabe für %2$s entfernt", + "Removed share of group %2$s" : "Freigabe für Gruppe %2$s entfernt", + "Shared by %2$s" : "Geteilt von %2$s", + "Shared via link by %2$s" : "Geteilt durch einen Link von %2$s", + "Shared with group %3$s by %2$s" : "Geteilt mit der Gruppe %3$s von %2$s", + "The public link of %2$s for %1$s expired" : "Die Freigabe als Link von %2$s für %1$s ist abgelaufen", + "You removed the public link for %1$s" : "Sie haben die Freigabe als Link für %1$s entfernt", + "You removed the share of %2$s for %1$s" : "Sie haben die Freigabe von %2$s für %1$s entfernt", + "You removed the share of group %2$s for %1$s" : "Sie haben die Freigabe der Gruppe %2$s für %1$s entfernt", + "Your public link for %1$s expired" : "Ihre Freigabe als Link für %1$s ist abgelaufen" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/el.js b/apps/files_sharing/l10n/el.js index fe3a62c4357d1..de76a45511e20 100644 --- a/apps/files_sharing/l10n/el.js +++ b/apps/files_sharing/l10n/el.js @@ -81,6 +81,11 @@ OC.L10N.register( "Share it:" : "Μοιραστείτε το:", "Add to your website" : "Προσθήκη στην ιστοσελίδα σας", "Share with me via ownCloud" : "Διαμοιρασμός με εμένα μέσω του ", - "HTML Code:" : "Κώδικας HTML:" + "HTML Code:" : "Κώδικας HTML:", + "Public shared file %1$s was downloaded" : "Το κοινόχρηστο διαμοιρασμένο αρχείο %1$s ελήφθη", + "Public shared folder %1$s was downloaded" : "Ο κοινόχρηστος διαμοιρασμένος φάκελος %1$s ελήφθη", + "Shared by %2$s" : "Διαμοιράστηκε από %2$s", + "Shared via link by %2$s" : "Διαμοιράστηκε μέσω συνδέσμου από %2$s", + "Shared with group %3$s by %2$s" : "Διαμοιράστηκε με την ομάδα %3$s από %2$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/el.json b/apps/files_sharing/l10n/el.json index 3283aa0a0294c..19d9adb1675cc 100644 --- a/apps/files_sharing/l10n/el.json +++ b/apps/files_sharing/l10n/el.json @@ -79,6 +79,11 @@ "Share it:" : "Μοιραστείτε το:", "Add to your website" : "Προσθήκη στην ιστοσελίδα σας", "Share with me via ownCloud" : "Διαμοιρασμός με εμένα μέσω του ", - "HTML Code:" : "Κώδικας HTML:" + "HTML Code:" : "Κώδικας HTML:", + "Public shared file %1$s was downloaded" : "Το κοινόχρηστο διαμοιρασμένο αρχείο %1$s ελήφθη", + "Public shared folder %1$s was downloaded" : "Ο κοινόχρηστος διαμοιρασμένος φάκελος %1$s ελήφθη", + "Shared by %2$s" : "Διαμοιράστηκε από %2$s", + "Shared via link by %2$s" : "Διαμοιράστηκε μέσω συνδέσμου από %2$s", + "Shared with group %3$s by %2$s" : "Διαμοιράστηκε με την ομάδα %3$s από %2$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/en_GB.js b/apps/files_sharing/l10n/en_GB.js index 545934771bda7..9136597674f49 100644 --- a/apps/files_sharing/l10n/en_GB.js +++ b/apps/files_sharing/l10n/en_GB.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Share it:", "Add to your website" : "Add to your website", "Share with me via ownCloud" : "Share with me via ownCloud", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public link of %2$s expired" : "Public link of %2$s expired", + "Public shared file %1$s was downloaded" : "Public shared file %1$s was downloaded", + "Public shared folder %1$s was downloaded" : "Public shared folder %1$s was downloaded", + "Removed share for %2$s" : "Removed share for %2$s", + "Removed share of group %2$s" : "Removed share of group %2$s", + "Shared by %2$s" : "Shared by %2$s", + "Shared via link by %2$s" : "Shared via link by %2$s", + "Shared with group %3$s by %2$s" : "Shared with group %3$s by %2$s", + "The public link of %2$s for %1$s expired" : "The public link of %2$s for %1$s expired", + "You removed the public link for %1$s" : "You removed the public link for %1$s", + "You removed the share of %2$s for %1$s" : "You removed the share of %2$s for %1$s", + "You removed the share of group %2$s for %1$s" : "You removed the share of group %2$s for %1$s", + "Your public link for %1$s expired" : "Your public link for %1$s expired" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/en_GB.json b/apps/files_sharing/l10n/en_GB.json index a478bb9301ad8..e73f73dce24df 100644 --- a/apps/files_sharing/l10n/en_GB.json +++ b/apps/files_sharing/l10n/en_GB.json @@ -99,6 +99,19 @@ "Share it:" : "Share it:", "Add to your website" : "Add to your website", "Share with me via ownCloud" : "Share with me via ownCloud", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public link of %2$s expired" : "Public link of %2$s expired", + "Public shared file %1$s was downloaded" : "Public shared file %1$s was downloaded", + "Public shared folder %1$s was downloaded" : "Public shared folder %1$s was downloaded", + "Removed share for %2$s" : "Removed share for %2$s", + "Removed share of group %2$s" : "Removed share of group %2$s", + "Shared by %2$s" : "Shared by %2$s", + "Shared via link by %2$s" : "Shared via link by %2$s", + "Shared with group %3$s by %2$s" : "Shared with group %3$s by %2$s", + "The public link of %2$s for %1$s expired" : "The public link of %2$s for %1$s expired", + "You removed the public link for %1$s" : "You removed the public link for %1$s", + "You removed the share of %2$s for %1$s" : "You removed the share of %2$s for %1$s", + "You removed the share of group %2$s for %1$s" : "You removed the share of group %2$s for %1$s", + "Your public link for %1$s expired" : "Your public link for %1$s expired" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/eo.js b/apps/files_sharing/l10n/eo.js index bce9d7298b059..2b8bdee83c659 100644 --- a/apps/files_sharing/l10n/eo.js +++ b/apps/files_sharing/l10n/eo.js @@ -91,6 +91,16 @@ OC.L10N.register( "Share it:" : "Kunhavigi ĝin:", "Add to your website" : "Aldoni al via TTT-ejo", "Share with me via ownCloud" : "Kunhavigi kun mi per ownCloud", - "HTML Code:" : "HTML-kodo:" + "HTML Code:" : "HTML-kodo:", + "Public shared file %1$s was downloaded" : "La publika kunhavata dosiero %1$s elŝutiĝis", + "Public shared folder %1$s was downloaded" : "La publika kunhavata dosierujo %1$s elŝutiĝis", + "Removed share for %2$s" : "Foriĝis kunhavo kun %2$s", + "Removed share of group %2$s" : "Foriĝis kunhavo kun grupo %2$s", + "Shared by %2$s" : "Kunhavigata de %2$s", + "Shared via link by %2$s" : "Kunhavata ligile de %2$s", + "Shared with group %3$s by %2$s" : "Kunhavata kun grupo %3$s de %2$s", + "You removed the public link for %1$s" : "Vi forigis la publikan ligilon por %1$s", + "You removed the share of %2$s for %1$s" : "Vi malkunhavigis %1$s kun %2$s", + "You removed the share of group %2$s for %1$s" : "Vi malkunhavigis %1$s kun grupo %2$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/eo.json b/apps/files_sharing/l10n/eo.json index 63655bcea55b0..f5d4d6d5344d0 100644 --- a/apps/files_sharing/l10n/eo.json +++ b/apps/files_sharing/l10n/eo.json @@ -89,6 +89,16 @@ "Share it:" : "Kunhavigi ĝin:", "Add to your website" : "Aldoni al via TTT-ejo", "Share with me via ownCloud" : "Kunhavigi kun mi per ownCloud", - "HTML Code:" : "HTML-kodo:" + "HTML Code:" : "HTML-kodo:", + "Public shared file %1$s was downloaded" : "La publika kunhavata dosiero %1$s elŝutiĝis", + "Public shared folder %1$s was downloaded" : "La publika kunhavata dosierujo %1$s elŝutiĝis", + "Removed share for %2$s" : "Foriĝis kunhavo kun %2$s", + "Removed share of group %2$s" : "Foriĝis kunhavo kun grupo %2$s", + "Shared by %2$s" : "Kunhavigata de %2$s", + "Shared via link by %2$s" : "Kunhavata ligile de %2$s", + "Shared with group %3$s by %2$s" : "Kunhavata kun grupo %3$s de %2$s", + "You removed the public link for %1$s" : "Vi forigis la publikan ligilon por %1$s", + "You removed the share of %2$s for %1$s" : "Vi malkunhavigis %1$s kun %2$s", + "You removed the share of group %2$s for %1$s" : "Vi malkunhavigis %1$s kun grupo %2$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/es.js b/apps/files_sharing/l10n/es.js index 01f65761abb9e..cabd1ad20c1d1 100644 --- a/apps/files_sharing/l10n/es.js +++ b/apps/files_sharing/l10n/es.js @@ -93,6 +93,19 @@ OC.L10N.register( "Share it:" : "Compartir:", "Add to your website" : "Añadir a su sitio web", "Share with me via ownCloud" : "Compartirlo conmigo vía OwnCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "El enlace público %2$s ha expirado", + "Public shared file %1$s was downloaded" : "Se descargó el archivo público compartido %1$s", + "Public shared folder %1$s was downloaded" : "Se descargó la carpeta pública compartida %1$s", + "Removed share for %2$s" : "Borrado el compartido %2$s", + "Removed share of group %2$s" : "Borrado el compartido del grupo %2$s", + "Shared by %2$s" : "Compartido por %2$s", + "Shared via link by %2$s" : "Compartido vía enlace por %2$s", + "Shared with group %3$s by %2$s" : "Compartido con el grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "El enlace público de %2$s para %1$s ha expirado", + "You removed the public link for %1$s" : "Ha borrado el enlace público de %1$s", + "You removed the share of %2$s for %1$s" : "Ha cambiado el compartido %2$s por %1$s", + "You removed the share of group %2$s for %1$s" : "Ha cambiado el compartido del grupo %2$s por %1$s", + "Your public link for %1$s expired" : "Su enlace público %1$s ha expirado" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/es.json b/apps/files_sharing/l10n/es.json index bd5d497829b7e..f6a8d4d458ac2 100644 --- a/apps/files_sharing/l10n/es.json +++ b/apps/files_sharing/l10n/es.json @@ -91,6 +91,19 @@ "Share it:" : "Compartir:", "Add to your website" : "Añadir a su sitio web", "Share with me via ownCloud" : "Compartirlo conmigo vía OwnCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "El enlace público %2$s ha expirado", + "Public shared file %1$s was downloaded" : "Se descargó el archivo público compartido %1$s", + "Public shared folder %1$s was downloaded" : "Se descargó la carpeta pública compartida %1$s", + "Removed share for %2$s" : "Borrado el compartido %2$s", + "Removed share of group %2$s" : "Borrado el compartido del grupo %2$s", + "Shared by %2$s" : "Compartido por %2$s", + "Shared via link by %2$s" : "Compartido vía enlace por %2$s", + "Shared with group %3$s by %2$s" : "Compartido con el grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "El enlace público de %2$s para %1$s ha expirado", + "You removed the public link for %1$s" : "Ha borrado el enlace público de %1$s", + "You removed the share of %2$s for %1$s" : "Ha cambiado el compartido %2$s por %1$s", + "You removed the share of group %2$s for %1$s" : "Ha cambiado el compartido del grupo %2$s por %1$s", + "Your public link for %1$s expired" : "Su enlace público %1$s ha expirado" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/eu.js b/apps/files_sharing/l10n/eu.js index e7e5220d3f352..09d095f1aad81 100644 --- a/apps/files_sharing/l10n/eu.js +++ b/apps/files_sharing/l10n/eu.js @@ -52,6 +52,8 @@ OC.L10N.register( "Direct link" : "Lotura zuzena", "Federated Cloud Sharing" : "Federatutako Hodei Partekatzea", "Allow users on this server to send shares to other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzariekin partekatzera", - "Allow users on this server to receive shares from other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzarietatik partekatutakoak jasotzen" + "Allow users on this server to receive shares from other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzarietatik partekatutakoak jasotzen", + "Public shared file %1$s was downloaded" : "Publikoki partekatutako %1$s fitxategia deskargatu da", + "Public shared folder %1$s was downloaded" : "Publikoki partekatutako %1$s karpeta deskargatu da" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/eu.json b/apps/files_sharing/l10n/eu.json index 72e3b036323e0..1f8f2e42d3690 100644 --- a/apps/files_sharing/l10n/eu.json +++ b/apps/files_sharing/l10n/eu.json @@ -50,6 +50,8 @@ "Direct link" : "Lotura zuzena", "Federated Cloud Sharing" : "Federatutako Hodei Partekatzea", "Allow users on this server to send shares to other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzariekin partekatzera", - "Allow users on this server to receive shares from other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzarietatik partekatutakoak jasotzen" + "Allow users on this server to receive shares from other servers" : "Baimendu zerbitzari honetako erabiltzaileak beste zerbitzarietatik partekatutakoak jasotzen", + "Public shared file %1$s was downloaded" : "Publikoki partekatutako %1$s fitxategia deskargatu da", + "Public shared folder %1$s was downloaded" : "Publikoki partekatutako %1$s karpeta deskargatu da" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/fi_FI.js b/apps/files_sharing/l10n/fi_FI.js index 68b41feb46ce2..ed46c5a41cbf4 100644 --- a/apps/files_sharing/l10n/fi_FI.js +++ b/apps/files_sharing/l10n/fi_FI.js @@ -89,6 +89,13 @@ OC.L10N.register( "Share it:" : "Jaa se:", "Add to your website" : "Lisää verkkosivuillesi", "Share with me via ownCloud" : "Jaa kanssani ownCloudin kautta", - "HTML Code:" : "HTML-koodi:" + "HTML Code:" : "HTML-koodi:", + "Public link of %2$s expired" : "Kohteen %2$s julkinen linkki vanhentui", + "Public shared file %1$s was downloaded" : "Julkisesti jaettu tiedosto %1$s ladattiin", + "Public shared folder %1$s was downloaded" : "Julkisesti jaettu kansio %1$s ladattiin", + "Shared by %2$s" : "Jakanut %2$s", + "Shared via link by %2$s" : "Jaettu linkin kautta käyttäjän %2$s toimesta", + "Shared with group %3$s by %2$s" : "Jaettu ryhmän %3$s kanssa käyttäjän %2$s toimesta", + "Your public link for %1$s expired" : "Julkinen linkkisi kohteelle %1$s vanhentui" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/fi_FI.json b/apps/files_sharing/l10n/fi_FI.json index e1834ab3c0e24..0b0b5119ef536 100644 --- a/apps/files_sharing/l10n/fi_FI.json +++ b/apps/files_sharing/l10n/fi_FI.json @@ -87,6 +87,13 @@ "Share it:" : "Jaa se:", "Add to your website" : "Lisää verkkosivuillesi", "Share with me via ownCloud" : "Jaa kanssani ownCloudin kautta", - "HTML Code:" : "HTML-koodi:" + "HTML Code:" : "HTML-koodi:", + "Public link of %2$s expired" : "Kohteen %2$s julkinen linkki vanhentui", + "Public shared file %1$s was downloaded" : "Julkisesti jaettu tiedosto %1$s ladattiin", + "Public shared folder %1$s was downloaded" : "Julkisesti jaettu kansio %1$s ladattiin", + "Shared by %2$s" : "Jakanut %2$s", + "Shared via link by %2$s" : "Jaettu linkin kautta käyttäjän %2$s toimesta", + "Shared with group %3$s by %2$s" : "Jaettu ryhmän %3$s kanssa käyttäjän %2$s toimesta", + "Your public link for %1$s expired" : "Julkinen linkkisi kohteelle %1$s vanhentui" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/fr.js b/apps/files_sharing/l10n/fr.js index e99dffcdcac7f..bff1d1e9923c0 100644 --- a/apps/files_sharing/l10n/fr.js +++ b/apps/files_sharing/l10n/fr.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Partager :", "Add to your website" : "Ajouter à votre site web", "Share with me via ownCloud" : "Partagez avec moi via ownCloud", - "HTML Code:" : "Code HTML :" + "HTML Code:" : "Code HTML :", + "Public link of %2$s expired" : "Le lien public de %2$s a expiré", + "Public shared file %1$s was downloaded" : "Le fichier public %1$s a été téléchargé", + "Public shared folder %1$s was downloaded" : "Le dossier public %1$s a été téléchargé", + "Removed share for %2$s" : "Partage supprimé pour %2$s", + "Removed share of group %2$s" : "Partage supprimé du groupe %2$s", + "Shared by %2$s" : "Partagé par %2$s", + "Shared via link by %2$s" : "Partagé via lien par %2$s", + "Shared with group %3$s by %2$s" : "Partagé avec le groupe %3$s par %2$s", + "The public link of %2$s for %1$s expired" : "Le lien public de %2$s pour %1$s a expiré", + "You removed the public link for %1$s" : "Vous avez supprimé le lien public pour %1$s", + "You removed the share of %2$s for %1$s" : "Vous avez supprimé le partage de %2$s pour %1$s", + "You removed the share of group %2$s for %1$s" : "Vous avez supprimé le partage du groupe %2$s pour %1$s", + "Your public link for %1$s expired" : "Le lien public pour %1$s a expiré" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_sharing/l10n/fr.json b/apps/files_sharing/l10n/fr.json index c0c7b85bf9616..45182d0b4b34e 100644 --- a/apps/files_sharing/l10n/fr.json +++ b/apps/files_sharing/l10n/fr.json @@ -99,6 +99,19 @@ "Share it:" : "Partager :", "Add to your website" : "Ajouter à votre site web", "Share with me via ownCloud" : "Partagez avec moi via ownCloud", - "HTML Code:" : "Code HTML :" + "HTML Code:" : "Code HTML :", + "Public link of %2$s expired" : "Le lien public de %2$s a expiré", + "Public shared file %1$s was downloaded" : "Le fichier public %1$s a été téléchargé", + "Public shared folder %1$s was downloaded" : "Le dossier public %1$s a été téléchargé", + "Removed share for %2$s" : "Partage supprimé pour %2$s", + "Removed share of group %2$s" : "Partage supprimé du groupe %2$s", + "Shared by %2$s" : "Partagé par %2$s", + "Shared via link by %2$s" : "Partagé via lien par %2$s", + "Shared with group %3$s by %2$s" : "Partagé avec le groupe %3$s par %2$s", + "The public link of %2$s for %1$s expired" : "Le lien public de %2$s pour %1$s a expiré", + "You removed the public link for %1$s" : "Vous avez supprimé le lien public pour %1$s", + "You removed the share of %2$s for %1$s" : "Vous avez supprimé le partage de %2$s pour %1$s", + "You removed the share of group %2$s for %1$s" : "Vous avez supprimé le partage du groupe %2$s pour %1$s", + "Your public link for %1$s expired" : "Le lien public pour %1$s a expiré" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/gl.js b/apps/files_sharing/l10n/gl.js index 7d4028f0bade5..ee79caf9176a3 100644 --- a/apps/files_sharing/l10n/gl.js +++ b/apps/files_sharing/l10n/gl.js @@ -68,6 +68,8 @@ OC.L10N.register( "Your Federated Cloud ID:" : "ID da súa nube federada:", "Share it:" : "Compártao:", "Share with me via ownCloud" : "Comparte comigo a través do ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public shared file %1$s was downloaded" : "Foi descargado o ficheiro público %1$s", + "Public shared folder %1$s was downloaded" : "Foi descargado o cartafol público %1$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/gl.json b/apps/files_sharing/l10n/gl.json index a6aa34d14cb2a..5ad1ca31ad3c3 100644 --- a/apps/files_sharing/l10n/gl.json +++ b/apps/files_sharing/l10n/gl.json @@ -66,6 +66,8 @@ "Your Federated Cloud ID:" : "ID da súa nube federada:", "Share it:" : "Compártao:", "Share with me via ownCloud" : "Comparte comigo a través do ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public shared file %1$s was downloaded" : "Foi descargado o ficheiro público %1$s", + "Public shared folder %1$s was downloaded" : "Foi descargado o cartafol público %1$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/he.js b/apps/files_sharing/l10n/he.js index b0be1d34c978d..e18f489cd3e4d 100644 --- a/apps/files_sharing/l10n/he.js +++ b/apps/files_sharing/l10n/he.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "שיתוף שלו:", "Add to your website" : "הוספה לאתר האינטרנט שלך", "Share with me via ownCloud" : "שיתוף איתי באמצעות ownCloud", - "HTML Code:" : "קוד HTML:" + "HTML Code:" : "קוד HTML:", + "Public link of %2$s expired" : "קישור ציבורי של %2$s פג תוקף", + "Public shared file %1$s was downloaded" : "קובץ שיתוף ציבורי %1$s הורד", + "Public shared folder %1$s was downloaded" : "תיקיית שיתוף ציבורית %1$s הורדה", + "Removed share for %2$s" : "הסיר/ה שיתוף של %2$s", + "Removed share of group %2$s" : "הסיר/ה שיתוף של קבוצה %2$s", + "Shared by %2$s" : "שיתף/שיתפה על ידי %2$s", + "Shared via link by %2$s" : "שיתף/שיתפה על בסיס קישור על ידי %2$s", + "Shared with group %3$s by %2$s" : "שיתף/שיתפה עם קבוצה %3$s על ידי %2$s", + "The public link of %2$s for %1$s expired" : "הקישור הציבורי של %2$s עבור %1$s פג תוקף", + "You removed the public link for %1$s" : "הסרת את הקישור הציבורי של %1$s", + "You removed the share of %2$s for %1$s" : "הסרת את השיתוף של %2$s עבור %1$s", + "You removed the share of group %2$s for %1$s" : "הסרת את השיתוף לקבוצה %2$s עבור %1$s", + "Your public link for %1$s expired" : "הקישור הציבורי של %1$s פג תוקף" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/he.json b/apps/files_sharing/l10n/he.json index de1cfff07b568..dd0cfdb0f7d29 100644 --- a/apps/files_sharing/l10n/he.json +++ b/apps/files_sharing/l10n/he.json @@ -99,6 +99,19 @@ "Share it:" : "שיתוף שלו:", "Add to your website" : "הוספה לאתר האינטרנט שלך", "Share with me via ownCloud" : "שיתוף איתי באמצעות ownCloud", - "HTML Code:" : "קוד HTML:" + "HTML Code:" : "קוד HTML:", + "Public link of %2$s expired" : "קישור ציבורי של %2$s פג תוקף", + "Public shared file %1$s was downloaded" : "קובץ שיתוף ציבורי %1$s הורד", + "Public shared folder %1$s was downloaded" : "תיקיית שיתוף ציבורית %1$s הורדה", + "Removed share for %2$s" : "הסיר/ה שיתוף של %2$s", + "Removed share of group %2$s" : "הסיר/ה שיתוף של קבוצה %2$s", + "Shared by %2$s" : "שיתף/שיתפה על ידי %2$s", + "Shared via link by %2$s" : "שיתף/שיתפה על בסיס קישור על ידי %2$s", + "Shared with group %3$s by %2$s" : "שיתף/שיתפה עם קבוצה %3$s על ידי %2$s", + "The public link of %2$s for %1$s expired" : "הקישור הציבורי של %2$s עבור %1$s פג תוקף", + "You removed the public link for %1$s" : "הסרת את הקישור הציבורי של %1$s", + "You removed the share of %2$s for %1$s" : "הסרת את השיתוף של %2$s עבור %1$s", + "You removed the share of group %2$s for %1$s" : "הסרת את השיתוף לקבוצה %2$s עבור %1$s", + "Your public link for %1$s expired" : "הקישור הציבורי של %1$s פג תוקף" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/hu_HU.js b/apps/files_sharing/l10n/hu_HU.js index aee9a893a19be..24ca1d830ccc2 100644 --- a/apps/files_sharing/l10n/hu_HU.js +++ b/apps/files_sharing/l10n/hu_HU.js @@ -82,6 +82,11 @@ OC.L10N.register( "Share it:" : "Ossza meg:", "Add to your website" : "Add hozzá saját weboldaladhoz", "Share with me via ownCloud" : "Ossza meg velem ownCloud-on keresztül", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public shared file %1$s was downloaded" : "Nyilvánosan megosztott fálj %1$s le lett töltve", + "Public shared folder %1$s was downloaded" : "Nyilvánosan megosztott könyvtár %1$s le lett töltve", + "Shared by %2$s" : "Megosztó: %2$s", + "Shared via link by %2$s" : "Megosztva hivatkozással: %2$s", + "Shared with group %3$s by %2$s" : "Megosztva ezzel a csoporttal: %3$s, megosztó: %2$s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/hu_HU.json b/apps/files_sharing/l10n/hu_HU.json index a91d017d0fd83..97e01bb5a2794 100644 --- a/apps/files_sharing/l10n/hu_HU.json +++ b/apps/files_sharing/l10n/hu_HU.json @@ -80,6 +80,11 @@ "Share it:" : "Ossza meg:", "Add to your website" : "Add hozzá saját weboldaladhoz", "Share with me via ownCloud" : "Ossza meg velem ownCloud-on keresztül", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public shared file %1$s was downloaded" : "Nyilvánosan megosztott fálj %1$s le lett töltve", + "Public shared folder %1$s was downloaded" : "Nyilvánosan megosztott könyvtár %1$s le lett töltve", + "Shared by %2$s" : "Megosztó: %2$s", + "Shared via link by %2$s" : "Megosztva hivatkozással: %2$s", + "Shared with group %3$s by %2$s" : "Megosztva ezzel a csoporttal: %3$s, megosztó: %2$s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/hy.js b/apps/files_sharing/l10n/hy.js index 28de3fecd2ec1..cce3abb59a5d0 100644 --- a/apps/files_sharing/l10n/hy.js +++ b/apps/files_sharing/l10n/hy.js @@ -4,6 +4,7 @@ OC.L10N.register( "Cancel" : "Չեղարկել", "Password" : "Գաղտնաբառ", "Name" : "Անուն", - "Download" : "Բեռնել" + "Download" : "Բեռնել", + "Download %s" : "Ներբեռնել %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/hy.json b/apps/files_sharing/l10n/hy.json index ca2bc14a1202a..cb440f971943d 100644 --- a/apps/files_sharing/l10n/hy.json +++ b/apps/files_sharing/l10n/hy.json @@ -2,6 +2,7 @@ "Cancel" : "Չեղարկել", "Password" : "Գաղտնաբառ", "Name" : "Անուն", - "Download" : "Բեռնել" + "Download" : "Բեռնել", + "Download %s" : "Ներբեռնել %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/id.js b/apps/files_sharing/l10n/id.js index 837c0cfa843ed..261bc2d2df306 100644 --- a/apps/files_sharing/l10n/id.js +++ b/apps/files_sharing/l10n/id.js @@ -81,6 +81,11 @@ OC.L10N.register( "Share it:" : "Bagikan:", "Add to your website" : "Tambahkan pada situs web Anda", "Share with me via ownCloud" : "Dibagikan pada saya via ownCloud", - "HTML Code:" : "Kode HTML:" + "HTML Code:" : "Kode HTML:", + "Public shared file %1$s was downloaded" : "Berkas berbagi publik %1$s telah diunduh", + "Public shared folder %1$s was downloaded" : "Folder berbagi publik %1$s telah diunduh", + "Shared by %2$s" : "Dibagikan oleh %2$s", + "Shared via link by %2$s" : "Dibagikan via tautan oleh %2$s", + "Shared with group %3$s by %2$s" : "Dibagikan kepada grup %3$s oleh %2$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/id.json b/apps/files_sharing/l10n/id.json index 40789ec9355f1..d7f548195b2c3 100644 --- a/apps/files_sharing/l10n/id.json +++ b/apps/files_sharing/l10n/id.json @@ -79,6 +79,11 @@ "Share it:" : "Bagikan:", "Add to your website" : "Tambahkan pada situs web Anda", "Share with me via ownCloud" : "Dibagikan pada saya via ownCloud", - "HTML Code:" : "Kode HTML:" + "HTML Code:" : "Kode HTML:", + "Public shared file %1$s was downloaded" : "Berkas berbagi publik %1$s telah diunduh", + "Public shared folder %1$s was downloaded" : "Folder berbagi publik %1$s telah diunduh", + "Shared by %2$s" : "Dibagikan oleh %2$s", + "Shared via link by %2$s" : "Dibagikan via tautan oleh %2$s", + "Shared with group %3$s by %2$s" : "Dibagikan kepada grup %3$s oleh %2$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/is.js b/apps/files_sharing/l10n/is.js index fa95da0ffe2ea..603523110bfc9 100644 --- a/apps/files_sharing/l10n/is.js +++ b/apps/files_sharing/l10n/is.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Deila því:", "Add to your website" : "Bæta við vefsvæðið þitt", "Share with me via ownCloud" : "Deila með mér í gegnum ownCloud", - "HTML Code:" : "HTML-kóði:" + "HTML Code:" : "HTML-kóði:", + "Public link of %2$s expired" : "Almenningstengill %2$s er útrunninn", + "Public shared file %1$s was downloaded" : "Deild skrá í almenningsaðgangi %1$s var sótt", + "Public shared folder %1$s was downloaded" : "Deild mappa í almenningsaðgangi %1$s var sótt", + "Removed share for %2$s" : "Fjarlægði deilingu af %2$s", + "Removed share of group %2$s" : "Fjarlægði deilingu af hópnum %2$s", + "Shared by %2$s" : "Deilt af %2$s", + "Shared via link by %2$s" : "Deilt með tengli af %2$s", + "Shared with group %3$s by %2$s" : "Deilt með hópnum %3$s af %2$s", + "The public link of %2$s for %1$s expired" : "Almenningstengill %2$s fyrir %1$s er útrunninn", + "You removed the public link for %1$s" : "Þú fjarlægðir almenningstengilinn fyrir %1$s", + "You removed the share of %2$s for %1$s" : "Þú fjarlægðir deilingu af %2$s fyrir %1$s", + "You removed the share of group %2$s for %1$s" : "Þú fjarlægðir deilingu til hópsins %2$s fyrir %1$s", + "Your public link for %1$s expired" : "Almenningstengill þinn fyrir %1$s er útrunninn" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/files_sharing/l10n/is.json b/apps/files_sharing/l10n/is.json index 8ddb01882ab0f..9adefd67b8e18 100644 --- a/apps/files_sharing/l10n/is.json +++ b/apps/files_sharing/l10n/is.json @@ -99,6 +99,19 @@ "Share it:" : "Deila því:", "Add to your website" : "Bæta við vefsvæðið þitt", "Share with me via ownCloud" : "Deila með mér í gegnum ownCloud", - "HTML Code:" : "HTML-kóði:" + "HTML Code:" : "HTML-kóði:", + "Public link of %2$s expired" : "Almenningstengill %2$s er útrunninn", + "Public shared file %1$s was downloaded" : "Deild skrá í almenningsaðgangi %1$s var sótt", + "Public shared folder %1$s was downloaded" : "Deild mappa í almenningsaðgangi %1$s var sótt", + "Removed share for %2$s" : "Fjarlægði deilingu af %2$s", + "Removed share of group %2$s" : "Fjarlægði deilingu af hópnum %2$s", + "Shared by %2$s" : "Deilt af %2$s", + "Shared via link by %2$s" : "Deilt með tengli af %2$s", + "Shared with group %3$s by %2$s" : "Deilt með hópnum %3$s af %2$s", + "The public link of %2$s for %1$s expired" : "Almenningstengill %2$s fyrir %1$s er útrunninn", + "You removed the public link for %1$s" : "Þú fjarlægðir almenningstengilinn fyrir %1$s", + "You removed the share of %2$s for %1$s" : "Þú fjarlægðir deilingu af %2$s fyrir %1$s", + "You removed the share of group %2$s for %1$s" : "Þú fjarlægðir deilingu til hópsins %2$s fyrir %1$s", + "Your public link for %1$s expired" : "Almenningstengill þinn fyrir %1$s er útrunninn" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/it.js b/apps/files_sharing/l10n/it.js index 93adc33660409..9193c4eee0fed 100644 --- a/apps/files_sharing/l10n/it.js +++ b/apps/files_sharing/l10n/it.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Condividilo:", "Add to your website" : "Aggiungilo al tuo sito web", "Share with me via ownCloud" : "Condividi con me tramite ownCloud", - "HTML Code:" : "Codice HTML:" + "HTML Code:" : "Codice HTML:", + "Public link of %2$s expired" : "il collegamento pubblico di %2$s è scaduto", + "Public shared file %1$s was downloaded" : "Il file condiviso pubblicamente %1$s è stato scaricato", + "Public shared folder %1$s was downloaded" : "La cartella condivisa pubblicamente %1$s è stata scaricata", + "Removed share for %2$s" : "Condivisione rimossa per %2$s", + "Removed share of group %2$s" : "Condivisione rimossa del gruppo %2$s", + "Shared by %2$s" : "Condivisa da %2$s", + "Shared via link by %2$s" : "Condivisa tramite collegamento da %2$s", + "Shared with group %3$s by %2$s" : "Condivisa con il gruppo %3$s da %2$s", + "The public link of %2$s for %1$s expired" : "il collegamento pubblico di %2$s per %1$s è scaduto", + "You removed the public link for %1$s" : "Hai rimosso il collegamento pubblico per %1$s", + "You removed the share of %2$s for %1$s" : "Hai rimosso la condivisione di %2$s per %1$s", + "You removed the share of group %2$s for %1$s" : "Hai rimosso la condivisione del gruppo %2$s per %1$s", + "Your public link for %1$s expired" : "il tuo collegamento pubblico per %1$s è scaduto" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/it.json b/apps/files_sharing/l10n/it.json index d95f35be0a9c4..6650070b6f523 100644 --- a/apps/files_sharing/l10n/it.json +++ b/apps/files_sharing/l10n/it.json @@ -99,6 +99,19 @@ "Share it:" : "Condividilo:", "Add to your website" : "Aggiungilo al tuo sito web", "Share with me via ownCloud" : "Condividi con me tramite ownCloud", - "HTML Code:" : "Codice HTML:" + "HTML Code:" : "Codice HTML:", + "Public link of %2$s expired" : "il collegamento pubblico di %2$s è scaduto", + "Public shared file %1$s was downloaded" : "Il file condiviso pubblicamente %1$s è stato scaricato", + "Public shared folder %1$s was downloaded" : "La cartella condivisa pubblicamente %1$s è stata scaricata", + "Removed share for %2$s" : "Condivisione rimossa per %2$s", + "Removed share of group %2$s" : "Condivisione rimossa del gruppo %2$s", + "Shared by %2$s" : "Condivisa da %2$s", + "Shared via link by %2$s" : "Condivisa tramite collegamento da %2$s", + "Shared with group %3$s by %2$s" : "Condivisa con il gruppo %3$s da %2$s", + "The public link of %2$s for %1$s expired" : "il collegamento pubblico di %2$s per %1$s è scaduto", + "You removed the public link for %1$s" : "Hai rimosso il collegamento pubblico per %1$s", + "You removed the share of %2$s for %1$s" : "Hai rimosso la condivisione di %2$s per %1$s", + "You removed the share of group %2$s for %1$s" : "Hai rimosso la condivisione del gruppo %2$s per %1$s", + "Your public link for %1$s expired" : "il tuo collegamento pubblico per %1$s è scaduto" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/ja.js b/apps/files_sharing/l10n/ja.js index 3af2b548dfe59..f5c66798187ad 100644 --- a/apps/files_sharing/l10n/ja.js +++ b/apps/files_sharing/l10n/ja.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "以下で共有:", "Add to your website" : "ウェブサイトに追加", "Share with me via ownCloud" : "OwnCloud経由で共有", - "HTML Code:" : "HTMLコード:" + "HTML Code:" : "HTMLコード:", + "Public link of %2$s expired" : "公開リンク%2$sの期限が切れています", + "Public shared file %1$s was downloaded" : "公開共有ファイル %1$s がダウンロードされました", + "Public shared folder %1$s was downloaded" : "公開共有フォルダー %1$s がダウンロードされました", + "Removed share for %2$s" : " %2$sとの共有を削除しました", + "Removed share of group %2$s" : " %2$s グループとの共有を削除しました", + "Shared by %2$s" : "%2$s が共有", + "Shared via link by %2$s" : "リンク経由で %2$s が共有しました", + "Shared with group %3$s by %2$s" : "%3$s グループと %2$s で共有しました", + "The public link of %2$s for %1$s expired" : "%1$sへの公開リンク%2$sの期限が切れました", + "You removed the public link for %1$s" : "%1$s の公開URL共有を削除しました", + "You removed the share of %2$s for %1$s" : "%1$sとの%2$sの共有を削除しました", + "You removed the share of group %2$s for %1$s" : "%1$sとのグループ%2$sの共有を削除しました", + "Your public link for %1$s expired" : "公開URLリンク %1$s の期限が切れています" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/ja.json b/apps/files_sharing/l10n/ja.json index 5d36081daf3a9..1054834d5d2be 100644 --- a/apps/files_sharing/l10n/ja.json +++ b/apps/files_sharing/l10n/ja.json @@ -99,6 +99,19 @@ "Share it:" : "以下で共有:", "Add to your website" : "ウェブサイトに追加", "Share with me via ownCloud" : "OwnCloud経由で共有", - "HTML Code:" : "HTMLコード:" + "HTML Code:" : "HTMLコード:", + "Public link of %2$s expired" : "公開リンク%2$sの期限が切れています", + "Public shared file %1$s was downloaded" : "公開共有ファイル %1$s がダウンロードされました", + "Public shared folder %1$s was downloaded" : "公開共有フォルダー %1$s がダウンロードされました", + "Removed share for %2$s" : " %2$sとの共有を削除しました", + "Removed share of group %2$s" : " %2$s グループとの共有を削除しました", + "Shared by %2$s" : "%2$s が共有", + "Shared via link by %2$s" : "リンク経由で %2$s が共有しました", + "Shared with group %3$s by %2$s" : "%3$s グループと %2$s で共有しました", + "The public link of %2$s for %1$s expired" : "%1$sへの公開リンク%2$sの期限が切れました", + "You removed the public link for %1$s" : "%1$s の公開URL共有を削除しました", + "You removed the share of %2$s for %1$s" : "%1$sとの%2$sの共有を削除しました", + "You removed the share of group %2$s for %1$s" : "%1$sとのグループ%2$sの共有を削除しました", + "Your public link for %1$s expired" : "公開URLリンク %1$s の期限が切れています" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/ko.js b/apps/files_sharing/l10n/ko.js index 99cdb6bda8696..79db604c3db63 100644 --- a/apps/files_sharing/l10n/ko.js +++ b/apps/files_sharing/l10n/ko.js @@ -81,6 +81,23 @@ OC.L10N.register( "Share it:" : "공유하기:", "Add to your website" : "내 웹 사이트에 추가", "Share with me via ownCloud" : "ownCloud로 나와 공유하기", - "HTML Code:" : "HTML 코드:" + "HTML Code:" : "HTML 코드:", + "Federated sharing" : "연합 공유", + "Not allowed to create a federated share with the same user server" : "같은 사용자 서버 내에서 연합 공유를 만들 수 없음", + "Public link expired" : "공개 링크 만료됨", + "Public link of %2$s expired" : "%2$s 님의 공개 링크 만료됨", + "Public shared file %1$s was downloaded" : "공개 공유 파일 %1$s이(가) 다운로드됨", + "Public shared folder %1$s was downloaded" : "공개 공유 폴더 %1$s이(가) 다운로드됨", + "Removed public link" : "공개 링크 삭제함", + "Removed share for %2$s" : "%2$s 님의 공유를 삭제함", + "Removed share of group %2$s" : "%2$s 그룹의 공유를 삭제함", + "Shared by %2$s" : "%2$s 님이 공유함", + "Shared via link by %2$s" : "%2$s 님이 링크로 공유함", + "Shared with group %3$s by %2$s" : "%2$s 님이 %3$s 그룹과 공유함", + "The public link of %2$s for %1$s expired" : "%2$s 님의 %1$s 공개 링크가 만료됨", + "You removed the public link for %1$s" : "%1$s의 공개 링크를 삭제함", + "You removed the share of %2$s for %1$s" : "%1$s을(를) 위한 %2$s 그룹의 공유를 삭제함", + "You removed the share of group %2$s for %1$s" : "%1$s 님을 위한 %2$s 그룹 공유를 삭제함", + "Your public link for %1$s expired" : "%1$s의 공개 링크가 만료됨" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/ko.json b/apps/files_sharing/l10n/ko.json index ad944c69215db..bc7e8622a50a0 100644 --- a/apps/files_sharing/l10n/ko.json +++ b/apps/files_sharing/l10n/ko.json @@ -79,6 +79,23 @@ "Share it:" : "공유하기:", "Add to your website" : "내 웹 사이트에 추가", "Share with me via ownCloud" : "ownCloud로 나와 공유하기", - "HTML Code:" : "HTML 코드:" + "HTML Code:" : "HTML 코드:", + "Federated sharing" : "연합 공유", + "Not allowed to create a federated share with the same user server" : "같은 사용자 서버 내에서 연합 공유를 만들 수 없음", + "Public link expired" : "공개 링크 만료됨", + "Public link of %2$s expired" : "%2$s 님의 공개 링크 만료됨", + "Public shared file %1$s was downloaded" : "공개 공유 파일 %1$s이(가) 다운로드됨", + "Public shared folder %1$s was downloaded" : "공개 공유 폴더 %1$s이(가) 다운로드됨", + "Removed public link" : "공개 링크 삭제함", + "Removed share for %2$s" : "%2$s 님의 공유를 삭제함", + "Removed share of group %2$s" : "%2$s 그룹의 공유를 삭제함", + "Shared by %2$s" : "%2$s 님이 공유함", + "Shared via link by %2$s" : "%2$s 님이 링크로 공유함", + "Shared with group %3$s by %2$s" : "%2$s 님이 %3$s 그룹과 공유함", + "The public link of %2$s for %1$s expired" : "%2$s 님의 %1$s 공개 링크가 만료됨", + "You removed the public link for %1$s" : "%1$s의 공개 링크를 삭제함", + "You removed the share of %2$s for %1$s" : "%1$s을(를) 위한 %2$s 그룹의 공유를 삭제함", + "You removed the share of group %2$s for %1$s" : "%1$s 님을 위한 %2$s 그룹 공유를 삭제함", + "Your public link for %1$s expired" : "%1$s의 공개 링크가 만료됨" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/lt_LT.js b/apps/files_sharing/l10n/lt_LT.js index 8aa1be493b9e8..242a8ac199177 100644 --- a/apps/files_sharing/l10n/lt_LT.js +++ b/apps/files_sharing/l10n/lt_LT.js @@ -82,6 +82,11 @@ OC.L10N.register( "Share it:" : "Pasidalink:", "Add to your website" : "Pridėti tavo puslapį", "Share with me via ownCloud" : "Pasidalink su manimi per ownCloud", - "HTML Code:" : "HTML kodas:" + "HTML Code:" : "HTML kodas:", + "Public shared file %1$s was downloaded" : "Viešai dalinamas failas %1$s parsiųstas", + "Public shared folder %1$s was downloaded" : "Viešas dalijimosi aplankas %1$s parsiųstas", + "Shared by %2$s" : "Pasidalino %2$s", + "Shared via link by %2$s" : "%2$s pasidalino nuoroda", + "Shared with group %3$s by %2$s" : "%2$s pasidalino su grupe %3$s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/lt_LT.json b/apps/files_sharing/l10n/lt_LT.json index ef139068832bc..ca8a347b29d42 100644 --- a/apps/files_sharing/l10n/lt_LT.json +++ b/apps/files_sharing/l10n/lt_LT.json @@ -80,6 +80,11 @@ "Share it:" : "Pasidalink:", "Add to your website" : "Pridėti tavo puslapį", "Share with me via ownCloud" : "Pasidalink su manimi per ownCloud", - "HTML Code:" : "HTML kodas:" + "HTML Code:" : "HTML kodas:", + "Public shared file %1$s was downloaded" : "Viešai dalinamas failas %1$s parsiųstas", + "Public shared folder %1$s was downloaded" : "Viešas dalijimosi aplankas %1$s parsiųstas", + "Shared by %2$s" : "Pasidalino %2$s", + "Shared via link by %2$s" : "%2$s pasidalino nuoroda", + "Shared with group %3$s by %2$s" : "%2$s pasidalino su grupe %3$s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/lv.js b/apps/files_sharing/l10n/lv.js index a27ea0de207e3..b0490e5665ca5 100644 --- a/apps/files_sharing/l10n/lv.js +++ b/apps/files_sharing/l10n/lv.js @@ -58,6 +58,8 @@ OC.L10N.register( "Federated Cloud Sharing" : "Federatīva mākoņkoplietošana", "Open documentation" : "Atvērt dokumentāciju", "Allow users on this server to send shares to other servers" : "Atļaut šī servera lietotājiem sūtīt koplietotnes uz citiem serveriem", - "Allow users on this server to receive shares from other servers" : "Atļaut šī servera lietotājiem saņem koplietotnes no citiem serveriem" + "Allow users on this server to receive shares from other servers" : "Atļaut šī servera lietotājiem saņem koplietotnes no citiem serveriem", + "Public shared file %1$s was downloaded" : "Publiski koplietots fails %1$s tika lejupielādēts", + "Public shared folder %1$s was downloaded" : "Publiski koplietota mape %1$s tika lejupielādēta" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/lv.json b/apps/files_sharing/l10n/lv.json index 458683813047f..5aea435d07acf 100644 --- a/apps/files_sharing/l10n/lv.json +++ b/apps/files_sharing/l10n/lv.json @@ -56,6 +56,8 @@ "Federated Cloud Sharing" : "Federatīva mākoņkoplietošana", "Open documentation" : "Atvērt dokumentāciju", "Allow users on this server to send shares to other servers" : "Atļaut šī servera lietotājiem sūtīt koplietotnes uz citiem serveriem", - "Allow users on this server to receive shares from other servers" : "Atļaut šī servera lietotājiem saņem koplietotnes no citiem serveriem" + "Allow users on this server to receive shares from other servers" : "Atļaut šī servera lietotājiem saņem koplietotnes no citiem serveriem", + "Public shared file %1$s was downloaded" : "Publiski koplietots fails %1$s tika lejupielādēts", + "Public shared folder %1$s was downloaded" : "Publiski koplietota mape %1$s tika lejupielādēta" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/mk.js b/apps/files_sharing/l10n/mk.js index e628c96125b5f..df90a27dc702c 100644 --- a/apps/files_sharing/l10n/mk.js +++ b/apps/files_sharing/l10n/mk.js @@ -58,6 +58,9 @@ OC.L10N.register( "Share it:" : "Сподели го:", "Add to your website" : "Додади на твојот веб сајт", "Share with me via ownCloud" : "Сподели со мене преку ownCloud", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Shared by %2$s" : "Споделено од %2$s", + "Shared via link by %2$s" : "Споделено со врска/линк од %2$s", + "Shared with group %3$s by %2$s" : "Споделено со група %3$s од %2$s" }, "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); diff --git a/apps/files_sharing/l10n/mk.json b/apps/files_sharing/l10n/mk.json index 33358b782b759..f545f8dd6c666 100644 --- a/apps/files_sharing/l10n/mk.json +++ b/apps/files_sharing/l10n/mk.json @@ -56,6 +56,9 @@ "Share it:" : "Сподели го:", "Add to your website" : "Додади на твојот веб сајт", "Share with me via ownCloud" : "Сподели со мене преку ownCloud", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Shared by %2$s" : "Споделено од %2$s", + "Shared via link by %2$s" : "Споделено со врска/линк од %2$s", + "Shared with group %3$s by %2$s" : "Споделено со група %3$s од %2$s" },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/nb_NO.js b/apps/files_sharing/l10n/nb_NO.js index 7c1d4714bcb70..5dde5e320f2c9 100644 --- a/apps/files_sharing/l10n/nb_NO.js +++ b/apps/files_sharing/l10n/nb_NO.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Del den:", "Add to your website" : "Legg på websiden din", "Share with me via ownCloud" : "Del med meg via ownCloud", - "HTML Code:" : "HTML-kode:" + "HTML Code:" : "HTML-kode:", + "Public link of %2$s expired" : "Offentlig lenke til %2$s er utløpt", + "Public shared file %1$s was downloaded" : "Offentlig delt fil %1$s ble lastet ned", + "Public shared folder %1$s was downloaded" : "Offentlig delt mappe %1$s ble lastet ned", + "Removed share for %2$s" : "Fjernet deling for %2$s", + "Removed share of group %2$s" : "Fjernet deling av gruppe %2$s", + "Shared by %2$s" : "Delt av %2$s", + "Shared via link by %2$s" : "Delt via lenke av %2$s", + "Shared with group %3$s by %2$s" : "Delt med gruppe %3$s av %2$s", + "The public link of %2$s for %1$s expired" : "Den offentlige lenken til %2$s for %1$s er utløpt", + "You removed the public link for %1$s" : "Du fjernet den offentlige lenken for %1$s", + "You removed the share of %2$s for %1$s" : "Du fjernet deling av %2$s for %1$s", + "You removed the share of group %2$s for %1$s" : "Du fjernet deling av gruppe %2$s for %1$s", + "Your public link for %1$s expired" : "Din offentlige lenke for %1$s er utløpt" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/nb_NO.json b/apps/files_sharing/l10n/nb_NO.json index 0d99939ace943..95de8f6075e20 100644 --- a/apps/files_sharing/l10n/nb_NO.json +++ b/apps/files_sharing/l10n/nb_NO.json @@ -99,6 +99,19 @@ "Share it:" : "Del den:", "Add to your website" : "Legg på websiden din", "Share with me via ownCloud" : "Del med meg via ownCloud", - "HTML Code:" : "HTML-kode:" + "HTML Code:" : "HTML-kode:", + "Public link of %2$s expired" : "Offentlig lenke til %2$s er utløpt", + "Public shared file %1$s was downloaded" : "Offentlig delt fil %1$s ble lastet ned", + "Public shared folder %1$s was downloaded" : "Offentlig delt mappe %1$s ble lastet ned", + "Removed share for %2$s" : "Fjernet deling for %2$s", + "Removed share of group %2$s" : "Fjernet deling av gruppe %2$s", + "Shared by %2$s" : "Delt av %2$s", + "Shared via link by %2$s" : "Delt via lenke av %2$s", + "Shared with group %3$s by %2$s" : "Delt med gruppe %3$s av %2$s", + "The public link of %2$s for %1$s expired" : "Den offentlige lenken til %2$s for %1$s er utløpt", + "You removed the public link for %1$s" : "Du fjernet den offentlige lenken for %1$s", + "You removed the share of %2$s for %1$s" : "Du fjernet deling av %2$s for %1$s", + "You removed the share of group %2$s for %1$s" : "Du fjernet deling av gruppe %2$s for %1$s", + "Your public link for %1$s expired" : "Din offentlige lenke for %1$s er utløpt" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/nl.js b/apps/files_sharing/l10n/nl.js index 99979f08d399d..71bb28759ddd2 100644 --- a/apps/files_sharing/l10n/nl.js +++ b/apps/files_sharing/l10n/nl.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Deel het:", "Add to your website" : "Toevoegen aan uw website", "Share with me via ownCloud" : "Deel met mij via ownCloud", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public link of %2$s expired" : "Openbare link van %2$s is verlopen", + "Public shared file %1$s was downloaded" : "Openbaar gedeeld bestand %1$s werd gedownloaded", + "Public shared folder %1$s was downloaded" : "Openbaar gedeelde map %1$s werd gedownloaded", + "Removed share for %2$s" : "Share van %2$s verwijderd", + "Removed share of group %2$s" : "Share van de groep %2$s verwijderd", + "Shared by %2$s" : "Gedeeld door %2$s", + "Shared via link by %2$s" : "Gedeeld via link door %2$s", + "Shared with group %3$s by %2$s" : "Gedeeld met groep %3$s door %2$s", + "The public link of %2$s for %1$s expired" : "De openbare link van %2$s voor %1$s is verlopen", + "You removed the public link for %1$s" : "U heeft de openbare link voor %1$s verwijderd", + "You removed the share of %2$s for %1$s" : "U heeft de share van %1$s met %2$s verwijderd", + "You removed the share of group %2$s for %1$s" : "U heeft de share van %1$s met de groep %2$s verwijderd", + "Your public link for %1$s expired" : "Uw openbare link voor %1$s is verlopen" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/nl.json b/apps/files_sharing/l10n/nl.json index 1d66dd578fe36..dafd777391c97 100644 --- a/apps/files_sharing/l10n/nl.json +++ b/apps/files_sharing/l10n/nl.json @@ -99,6 +99,19 @@ "Share it:" : "Deel het:", "Add to your website" : "Toevoegen aan uw website", "Share with me via ownCloud" : "Deel met mij via ownCloud", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public link of %2$s expired" : "Openbare link van %2$s is verlopen", + "Public shared file %1$s was downloaded" : "Openbaar gedeeld bestand %1$s werd gedownloaded", + "Public shared folder %1$s was downloaded" : "Openbaar gedeelde map %1$s werd gedownloaded", + "Removed share for %2$s" : "Share van %2$s verwijderd", + "Removed share of group %2$s" : "Share van de groep %2$s verwijderd", + "Shared by %2$s" : "Gedeeld door %2$s", + "Shared via link by %2$s" : "Gedeeld via link door %2$s", + "Shared with group %3$s by %2$s" : "Gedeeld met groep %3$s door %2$s", + "The public link of %2$s for %1$s expired" : "De openbare link van %2$s voor %1$s is verlopen", + "You removed the public link for %1$s" : "U heeft de openbare link voor %1$s verwijderd", + "You removed the share of %2$s for %1$s" : "U heeft de share van %1$s met %2$s verwijderd", + "You removed the share of group %2$s for %1$s" : "U heeft de share van %1$s met de groep %2$s verwijderd", + "Your public link for %1$s expired" : "Uw openbare link voor %1$s is verlopen" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/oc.js b/apps/files_sharing/l10n/oc.js index 350d35b2de07c..ccf786b0299a5 100644 --- a/apps/files_sharing/l10n/oc.js +++ b/apps/files_sharing/l10n/oc.js @@ -81,6 +81,11 @@ OC.L10N.register( "Share it:" : "Partejar :", "Add to your website" : "Apondre a vòstre site web", "Share with me via ownCloud" : "Partejatz amb ieu via ownCloud", - "HTML Code:" : "Còde HTML :" + "HTML Code:" : "Còde HTML :", + "Public shared file %1$s was downloaded" : "Lo fichièr public %1$s es estat telecargat", + "Public shared folder %1$s was downloaded" : "Lo dorsièr public %1$s es estat telecargat", + "Shared by %2$s" : "Partejat per %2$s", + "Shared via link by %2$s" : "Partejat via ligam per %2$s", + "Shared with group %3$s by %2$s" : "Partejat amb lo grop %3$s per %2$s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_sharing/l10n/oc.json b/apps/files_sharing/l10n/oc.json index 90254deca48aa..b366f225a2b97 100644 --- a/apps/files_sharing/l10n/oc.json +++ b/apps/files_sharing/l10n/oc.json @@ -79,6 +79,11 @@ "Share it:" : "Partejar :", "Add to your website" : "Apondre a vòstre site web", "Share with me via ownCloud" : "Partejatz amb ieu via ownCloud", - "HTML Code:" : "Còde HTML :" + "HTML Code:" : "Còde HTML :", + "Public shared file %1$s was downloaded" : "Lo fichièr public %1$s es estat telecargat", + "Public shared folder %1$s was downloaded" : "Lo dorsièr public %1$s es estat telecargat", + "Shared by %2$s" : "Partejat per %2$s", + "Shared via link by %2$s" : "Partejat via ligam per %2$s", + "Shared with group %3$s by %2$s" : "Partejat amb lo grop %3$s per %2$s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/pl.js b/apps/files_sharing/l10n/pl.js index 5acdcf116fdf1..9ffad09039794 100644 --- a/apps/files_sharing/l10n/pl.js +++ b/apps/files_sharing/l10n/pl.js @@ -47,6 +47,7 @@ OC.L10N.register( "Download" : "Pobierz", "Download %s" : "Pobierz %s", "Direct link" : "Bezpośredni link", - "Open documentation" : "Otwórz dokumentację" + "Open documentation" : "Otwórz dokumentację", + "Add to your website" : "Dodaj do swojej strony" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/pl.json b/apps/files_sharing/l10n/pl.json index ded962ac9e110..3f59d73864dec 100644 --- a/apps/files_sharing/l10n/pl.json +++ b/apps/files_sharing/l10n/pl.json @@ -45,6 +45,7 @@ "Download" : "Pobierz", "Download %s" : "Pobierz %s", "Direct link" : "Bezpośredni link", - "Open documentation" : "Otwórz dokumentację" + "Open documentation" : "Otwórz dokumentację", + "Add to your website" : "Dodaj do swojej strony" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/pt_BR.js b/apps/files_sharing/l10n/pt_BR.js index b41f5492a0e96..472206f102ef3 100644 --- a/apps/files_sharing/l10n/pt_BR.js +++ b/apps/files_sharing/l10n/pt_BR.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Compartilhe:", "Add to your website" : "Adicione ao seu website", "Share with me via ownCloud" : "Compartilhe comigo via ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "O link público de %2$s expirou", + "Public shared file %1$s was downloaded" : "O arquivo %1$s compartilhado publicamente foi baixado", + "Public shared folder %1$s was downloaded" : "A pasta %1$s compartilhada publicamente foi baixada", + "Removed share for %2$s" : "Removido compartilhamento para %2$s", + "Removed share of group %2$s" : "Removido compartilhamento para o grupo %2$s", + "Shared by %2$s" : "Compartilhado por %2$s", + "Shared via link by %2$s" : "Compartilhado via link por %2$s", + "Shared with group %3$s by %2$s" : "Compartilhado com o grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "O link público de %2$s para %1$s expirou", + "You removed the public link for %1$s" : "Você removeu o link público de %1$s", + "You removed the share of %2$s for %1$s" : "Você removeu o compartilhamento de %2$s para %1$s", + "You removed the share of group %2$s for %1$s" : "Você removeu o compartilhamento de %2$s para %1$s", + "Your public link for %1$s expired" : "O seu link público para %1$s expirou" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_sharing/l10n/pt_BR.json b/apps/files_sharing/l10n/pt_BR.json index be38812857ef9..02980c177f30f 100644 --- a/apps/files_sharing/l10n/pt_BR.json +++ b/apps/files_sharing/l10n/pt_BR.json @@ -99,6 +99,19 @@ "Share it:" : "Compartilhe:", "Add to your website" : "Adicione ao seu website", "Share with me via ownCloud" : "Compartilhe comigo via ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "O link público de %2$s expirou", + "Public shared file %1$s was downloaded" : "O arquivo %1$s compartilhado publicamente foi baixado", + "Public shared folder %1$s was downloaded" : "A pasta %1$s compartilhada publicamente foi baixada", + "Removed share for %2$s" : "Removido compartilhamento para %2$s", + "Removed share of group %2$s" : "Removido compartilhamento para o grupo %2$s", + "Shared by %2$s" : "Compartilhado por %2$s", + "Shared via link by %2$s" : "Compartilhado via link por %2$s", + "Shared with group %3$s by %2$s" : "Compartilhado com o grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "O link público de %2$s para %1$s expirou", + "You removed the public link for %1$s" : "Você removeu o link público de %1$s", + "You removed the share of %2$s for %1$s" : "Você removeu o compartilhamento de %2$s para %1$s", + "You removed the share of group %2$s for %1$s" : "Você removeu o compartilhamento de %2$s para %1$s", + "Your public link for %1$s expired" : "O seu link público para %1$s expirou" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/pt_PT.js b/apps/files_sharing/l10n/pt_PT.js index e9cf412bc5375..e9655a4ed76a1 100644 --- a/apps/files_sharing/l10n/pt_PT.js +++ b/apps/files_sharing/l10n/pt_PT.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Partilhe:", "Add to your website" : "Adicione ao seu sítio da Web", "Share with me via ownCloud" : "Partilhe comigo via ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "Link público de %2$s expirou", + "Public shared file %1$s was downloaded" : "Foi transferido o ficheiro %1$s partilhado publicamente", + "Public shared folder %1$s was downloaded" : "A pasta partilhada publicamente %1$s foi transferida", + "Removed share for %2$s" : "Partilha removida para %2$s", + "Removed share of group %2$s" : "Partilha removida do grupo %2$s", + "Shared by %2$s" : "Partilhado por %2$s", + "Shared via link by %2$s" : "Partilhado via hiperligação por %2$s", + "Shared with group %3$s by %2$s" : "Partilhado com o grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "O link público de %2$s para %1$s expirou", + "You removed the public link for %1$s" : "Removeu o link público de %1$s", + "You removed the share of %2$s for %1$s" : "Removeu a partilha de %2$s para %1$s", + "You removed the share of group %2$s for %1$s" : "Removeu a partilha do grupo %2$s para %1$s", + "Your public link for %1$s expired" : "O seu link público de %1$s expirou" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/pt_PT.json b/apps/files_sharing/l10n/pt_PT.json index f311ef6bb3316..309499a7ca2d0 100644 --- a/apps/files_sharing/l10n/pt_PT.json +++ b/apps/files_sharing/l10n/pt_PT.json @@ -99,6 +99,19 @@ "Share it:" : "Partilhe:", "Add to your website" : "Adicione ao seu sítio da Web", "Share with me via ownCloud" : "Partilhe comigo via ownCloud", - "HTML Code:" : "Código HTML:" + "HTML Code:" : "Código HTML:", + "Public link of %2$s expired" : "Link público de %2$s expirou", + "Public shared file %1$s was downloaded" : "Foi transferido o ficheiro %1$s partilhado publicamente", + "Public shared folder %1$s was downloaded" : "A pasta partilhada publicamente %1$s foi transferida", + "Removed share for %2$s" : "Partilha removida para %2$s", + "Removed share of group %2$s" : "Partilha removida do grupo %2$s", + "Shared by %2$s" : "Partilhado por %2$s", + "Shared via link by %2$s" : "Partilhado via hiperligação por %2$s", + "Shared with group %3$s by %2$s" : "Partilhado com o grupo %3$s por %2$s", + "The public link of %2$s for %1$s expired" : "O link público de %2$s para %1$s expirou", + "You removed the public link for %1$s" : "Removeu o link público de %1$s", + "You removed the share of %2$s for %1$s" : "Removeu a partilha de %2$s para %1$s", + "You removed the share of group %2$s for %1$s" : "Removeu a partilha do grupo %2$s para %1$s", + "Your public link for %1$s expired" : "O seu link público de %1$s expirou" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/ru.js b/apps/files_sharing/l10n/ru.js index 8c9de804011fc..e75d7a7b06869 100644 --- a/apps/files_sharing/l10n/ru.js +++ b/apps/files_sharing/l10n/ru.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Поделись этим:", "Add to your website" : "Добавить к себе на сайт", "Share with me via ownCloud" : "Поделитесь мной через ownCloud", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Public link of %2$s expired" : "Срок действия публичной ссылки к %2$s закончился", + "Public shared file %1$s was downloaded" : "Общий файл %1$s, был скачан", + "Public shared folder %1$s was downloaded" : "Общий каталог %1$s был скачан", + "Removed share for %2$s" : "Удалён общий доступ к %2$s", + "Removed share of group %2$s" : "Удалён общий доступ к группе %2$s", + "Shared by %2$s" : "Поделился %2$s", + "Shared via link by %2$s" : "Поделился ссылкой %2$s", + "Shared with group %3$s by %2$s" : "Поделился %2$s с группой %3$s", + "The public link of %2$s for %1$s expired" : "Срок действия публичной ссылки к %2$s для %1$s закончился", + "You removed the public link for %1$s" : "Вы удалили публичную ссылку к %1$s", + "You removed the share of %2$s for %1$s" : "Вы удалили общий доступ к %2$s для %1$s", + "You removed the share of group %2$s for %1$s" : "Вы удалили общий доступ к группе %2$s для %1$s", + "Your public link for %1$s expired" : "Срок действия Вашей публичной ссылки к %1$s закончился" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/files_sharing/l10n/ru.json b/apps/files_sharing/l10n/ru.json index 5dc7af3719088..0a70c3e856b7d 100644 --- a/apps/files_sharing/l10n/ru.json +++ b/apps/files_sharing/l10n/ru.json @@ -99,6 +99,19 @@ "Share it:" : "Поделись этим:", "Add to your website" : "Добавить к себе на сайт", "Share with me via ownCloud" : "Поделитесь мной через ownCloud", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Public link of %2$s expired" : "Срок действия публичной ссылки к %2$s закончился", + "Public shared file %1$s was downloaded" : "Общий файл %1$s, был скачан", + "Public shared folder %1$s was downloaded" : "Общий каталог %1$s был скачан", + "Removed share for %2$s" : "Удалён общий доступ к %2$s", + "Removed share of group %2$s" : "Удалён общий доступ к группе %2$s", + "Shared by %2$s" : "Поделился %2$s", + "Shared via link by %2$s" : "Поделился ссылкой %2$s", + "Shared with group %3$s by %2$s" : "Поделился %2$s с группой %3$s", + "The public link of %2$s for %1$s expired" : "Срок действия публичной ссылки к %2$s для %1$s закончился", + "You removed the public link for %1$s" : "Вы удалили публичную ссылку к %1$s", + "You removed the share of %2$s for %1$s" : "Вы удалили общий доступ к %2$s для %1$s", + "You removed the share of group %2$s for %1$s" : "Вы удалили общий доступ к группе %2$s для %1$s", + "Your public link for %1$s expired" : "Срок действия Вашей публичной ссылки к %1$s закончился" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sk_SK.js b/apps/files_sharing/l10n/sk_SK.js index dfd287e067dc2..19d55daf238b1 100644 --- a/apps/files_sharing/l10n/sk_SK.js +++ b/apps/files_sharing/l10n/sk_SK.js @@ -81,6 +81,11 @@ OC.L10N.register( "Share it:" : "Zdieľať:", "Add to your website" : "Pridať na svoju webstránku", "Share with me via ownCloud" : "Zdieľané so mnou cez ownCloud", - "HTML Code:" : "HTML kód:" + "HTML Code:" : "HTML kód:", + "Public shared file %1$s was downloaded" : "Verejne zdieľaný súbor %1$s bol stiahnutý", + "Public shared folder %1$s was downloaded" : "Verejne zdieľaný priečinok %1$s bol stiahnutý", + "Shared by %2$s" : "Zdieľané s %2$s", + "Shared via link by %2$s" : "Zdieľané prostredníctvom odkazu s %2$s", + "Shared with group %3$s by %2$s" : "Zdieľané so skupinou %3$s prostredníctvom %2$s" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/files_sharing/l10n/sk_SK.json b/apps/files_sharing/l10n/sk_SK.json index 5d23d16c97611..6db7c1e22e03e 100644 --- a/apps/files_sharing/l10n/sk_SK.json +++ b/apps/files_sharing/l10n/sk_SK.json @@ -79,6 +79,11 @@ "Share it:" : "Zdieľať:", "Add to your website" : "Pridať na svoju webstránku", "Share with me via ownCloud" : "Zdieľané so mnou cez ownCloud", - "HTML Code:" : "HTML kód:" + "HTML Code:" : "HTML kód:", + "Public shared file %1$s was downloaded" : "Verejne zdieľaný súbor %1$s bol stiahnutý", + "Public shared folder %1$s was downloaded" : "Verejne zdieľaný priečinok %1$s bol stiahnutý", + "Shared by %2$s" : "Zdieľané s %2$s", + "Shared via link by %2$s" : "Zdieľané prostredníctvom odkazu s %2$s", + "Shared with group %3$s by %2$s" : "Zdieľané so skupinou %3$s prostredníctvom %2$s" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sl.js b/apps/files_sharing/l10n/sl.js index 33742cd4dcc50..e02559ef4304c 100644 --- a/apps/files_sharing/l10n/sl.js +++ b/apps/files_sharing/l10n/sl.js @@ -71,6 +71,8 @@ OC.L10N.register( "Federated Cloud" : "Oblak s podporo prenosa dovoljenj", "Your Federated Cloud ID:" : "Vaš ID za prenos dovoljenj:", "Add to your website" : "Dodaj na spletišče", - "HTML Code:" : "Koda HTML:" + "HTML Code:" : "Koda HTML:", + "Public shared file %1$s was downloaded" : "Datoteka v souporabi %1$s je bila prejeta", + "Public shared folder %1$s was downloaded" : "Mapa v souporabi %1$s je bila prejeta" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/files_sharing/l10n/sl.json b/apps/files_sharing/l10n/sl.json index 929a687e2183b..74f535bd6fb73 100644 --- a/apps/files_sharing/l10n/sl.json +++ b/apps/files_sharing/l10n/sl.json @@ -69,6 +69,8 @@ "Federated Cloud" : "Oblak s podporo prenosa dovoljenj", "Your Federated Cloud ID:" : "Vaš ID za prenos dovoljenj:", "Add to your website" : "Dodaj na spletišče", - "HTML Code:" : "Koda HTML:" + "HTML Code:" : "Koda HTML:", + "Public shared file %1$s was downloaded" : "Datoteka v souporabi %1$s je bila prejeta", + "Public shared folder %1$s was downloaded" : "Mapa v souporabi %1$s je bila prejeta" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sq.js b/apps/files_sharing/l10n/sq.js index 8ffc9dba38959..2a28f639662a1 100644 --- a/apps/files_sharing/l10n/sq.js +++ b/apps/files_sharing/l10n/sq.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Ndajeni:", "Add to your website" : "Shtojeni te sajti juaj", "Share with me via ownCloud" : "Ndani me mua përmes ownCloud-it", - "HTML Code:" : "Kod HTML:" + "HTML Code:" : "Kod HTML:", + "Public link of %2$s expired" : "Lidhja publike e %2$s skadoi", + "Public shared file %1$s was downloaded" : "U shkarkua kartela e ndarë publikisht %1$s", + "Public shared folder %1$s was downloaded" : "U shkarkua dosja e ndarë publikisht %1$s", + "Removed share for %2$s" : "Hoqi ndarjen për %2$s", + "Removed share of group %2$s" : "Hoqi ndarjen e grupit %2$s", + "Shared by %2$s" : "U nda nga %2$s", + "Shared via link by %2$s" : "U nda përmes një lidhje nga %2$s", + "Shared with group %3$s by %2$s" : "U nda me grupin %3$s nga %2$s", + "The public link of %2$s for %1$s expired" : "Lidhja publike e %2$s për %1$s skadoi", + "You removed the public link for %1$s" : "Hoqët lidhjen publike për %1$s", + "You removed the share of %2$s for %1$s" : "Hoqët ndarjen e %2$s për %1$s", + "You removed the share of group %2$s for %1$s" : "Hoqët ndarjen e grupit %2$s për %1$s", + "Your public link for %1$s expired" : "Lidhja juaj publike për %1$s skadoi" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/sq.json b/apps/files_sharing/l10n/sq.json index 70b2a3ff20db7..07785e834aeed 100644 --- a/apps/files_sharing/l10n/sq.json +++ b/apps/files_sharing/l10n/sq.json @@ -99,6 +99,19 @@ "Share it:" : "Ndajeni:", "Add to your website" : "Shtojeni te sajti juaj", "Share with me via ownCloud" : "Ndani me mua përmes ownCloud-it", - "HTML Code:" : "Kod HTML:" + "HTML Code:" : "Kod HTML:", + "Public link of %2$s expired" : "Lidhja publike e %2$s skadoi", + "Public shared file %1$s was downloaded" : "U shkarkua kartela e ndarë publikisht %1$s", + "Public shared folder %1$s was downloaded" : "U shkarkua dosja e ndarë publikisht %1$s", + "Removed share for %2$s" : "Hoqi ndarjen për %2$s", + "Removed share of group %2$s" : "Hoqi ndarjen e grupit %2$s", + "Shared by %2$s" : "U nda nga %2$s", + "Shared via link by %2$s" : "U nda përmes një lidhje nga %2$s", + "Shared with group %3$s by %2$s" : "U nda me grupin %3$s nga %2$s", + "The public link of %2$s for %1$s expired" : "Lidhja publike e %2$s për %1$s skadoi", + "You removed the public link for %1$s" : "Hoqët lidhjen publike për %1$s", + "You removed the share of %2$s for %1$s" : "Hoqët ndarjen e %2$s për %1$s", + "You removed the share of group %2$s for %1$s" : "Hoqët ndarjen e grupit %2$s për %1$s", + "Your public link for %1$s expired" : "Lidhja juaj publike për %1$s skadoi" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sr.js b/apps/files_sharing/l10n/sr.js index a9452e1489099..80e7cb482770d 100644 --- a/apps/files_sharing/l10n/sr.js +++ b/apps/files_sharing/l10n/sr.js @@ -61,6 +61,10 @@ OC.L10N.register( "Open documentation" : "Отвори документацију", "Allow users on this server to send shares to other servers" : "Дозвољава корисницима овог сервера да шаљу дељења на друге сервере", "Allow users on this server to receive shares from other servers" : "Дозвољава корисницима овог сервера да примају дељења са других сервера", - "Federated Cloud" : "Здружени облак" + "Federated Cloud" : "Здружени облак", + "Decline" : "Одбиј", + "Federated sharing" : "Здружено дељење", + "Public shared file %1$s was downloaded" : "Јавно дељени фајл %1$s је преузет", + "Public shared folder %1$s was downloaded" : "Јавно дељена фасцикла %1$s је преузета" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/sr.json b/apps/files_sharing/l10n/sr.json index 96d0e37bea5ab..ee8ec73cb6913 100644 --- a/apps/files_sharing/l10n/sr.json +++ b/apps/files_sharing/l10n/sr.json @@ -59,6 +59,10 @@ "Open documentation" : "Отвори документацију", "Allow users on this server to send shares to other servers" : "Дозвољава корисницима овог сервера да шаљу дељења на друге сервере", "Allow users on this server to receive shares from other servers" : "Дозвољава корисницима овог сервера да примају дељења са других сервера", - "Federated Cloud" : "Здружени облак" + "Federated Cloud" : "Здружени облак", + "Decline" : "Одбиј", + "Federated sharing" : "Здружено дељење", + "Public shared file %1$s was downloaded" : "Јавно дељени фајл %1$s је преузет", + "Public shared folder %1$s was downloaded" : "Јавно дељена фасцикла %1$s је преузета" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sr@latin.js b/apps/files_sharing/l10n/sr@latin.js index d9ea5a224164a..9456dc4fbcf7c 100644 --- a/apps/files_sharing/l10n/sr@latin.js +++ b/apps/files_sharing/l10n/sr@latin.js @@ -53,6 +53,8 @@ OC.L10N.register( "Download %s" : "Preuzmi %s", "Direct link" : "Direktna prečica", "Allow users on this server to send shares to other servers" : "Dozvoli korisnicima na ovom serveru da šalju deljene resurse na druge servere", - "Allow users on this server to receive shares from other servers" : "Dozvoli korisnicima na ovom serveru da primaju deljene resurse sa drugih servera" + "Allow users on this server to receive shares from other servers" : "Dozvoli korisnicima na ovom serveru da primaju deljene resurse sa drugih servera", + "Public shared file %1$s was downloaded" : "Javni deljeni fajl %1$s je preuzet", + "Public shared folder %1$s was downloaded" : "Javni deljeni direktorijum %1$s je preuzet" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/sr@latin.json b/apps/files_sharing/l10n/sr@latin.json index 8cba518384ec7..9ad96aceeb1e3 100644 --- a/apps/files_sharing/l10n/sr@latin.json +++ b/apps/files_sharing/l10n/sr@latin.json @@ -51,6 +51,8 @@ "Download %s" : "Preuzmi %s", "Direct link" : "Direktna prečica", "Allow users on this server to send shares to other servers" : "Dozvoli korisnicima na ovom serveru da šalju deljene resurse na druge servere", - "Allow users on this server to receive shares from other servers" : "Dozvoli korisnicima na ovom serveru da primaju deljene resurse sa drugih servera" + "Allow users on this server to receive shares from other servers" : "Dozvoli korisnicima na ovom serveru da primaju deljene resurse sa drugih servera", + "Public shared file %1$s was downloaded" : "Javni deljeni fajl %1$s je preuzet", + "Public shared folder %1$s was downloaded" : "Javni deljeni direktorijum %1$s je preuzet" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/sv.js b/apps/files_sharing/l10n/sv.js index d2357c0de333a..e5028d2436453 100644 --- a/apps/files_sharing/l10n/sv.js +++ b/apps/files_sharing/l10n/sv.js @@ -54,6 +54,8 @@ OC.L10N.register( "Download %s" : "Ladda ner %s", "Direct link" : "Direkt länk", "Allow users on this server to send shares to other servers" : "Tillåt användare på denna server att skicka utdelningar till andra servrar", - "Allow users on this server to receive shares from other servers" : "Tillåt användare på denna servern att ta emot utdelningar från andra servrar" + "Allow users on this server to receive shares from other servers" : "Tillåt användare på denna servern att ta emot utdelningar från andra servrar", + "Public shared file %1$s was downloaded" : "Publikt delad fil %1$s blev nerladdad", + "Public shared folder %1$s was downloaded" : "Publikt delad mapp %1$s blev nerladdad" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/sv.json b/apps/files_sharing/l10n/sv.json index 9331d95aafb99..859242ff6e7a1 100644 --- a/apps/files_sharing/l10n/sv.json +++ b/apps/files_sharing/l10n/sv.json @@ -52,6 +52,8 @@ "Download %s" : "Ladda ner %s", "Direct link" : "Direkt länk", "Allow users on this server to send shares to other servers" : "Tillåt användare på denna server att skicka utdelningar till andra servrar", - "Allow users on this server to receive shares from other servers" : "Tillåt användare på denna servern att ta emot utdelningar från andra servrar" + "Allow users on this server to receive shares from other servers" : "Tillåt användare på denna servern att ta emot utdelningar från andra servrar", + "Public shared file %1$s was downloaded" : "Publikt delad fil %1$s blev nerladdad", + "Public shared folder %1$s was downloaded" : "Publikt delad mapp %1$s blev nerladdad" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/th_TH.js b/apps/files_sharing/l10n/th_TH.js index 9303fd5cdd329..1e323f3dcf67c 100644 --- a/apps/files_sharing/l10n/th_TH.js +++ b/apps/files_sharing/l10n/th_TH.js @@ -83,6 +83,11 @@ OC.L10N.register( "Share it:" : "แชร์มัน:", "Add to your website" : "เพิ่มไปยังเว็บไซต์", "Share with me via ownCloud" : "แชร์ร่วมกับฉันผ่าน ownCloud", - "HTML Code:" : "โค้ด HTML:" + "HTML Code:" : "โค้ด HTML:", + "Public shared file %1$s was downloaded" : "ไฟล์สาธารณะ %1$s ที่แชร์ถูกดาวน์โหลด", + "Public shared folder %1$s was downloaded" : "โฟลเดอร์สาธารณะ %1$s ที่แชร์ถูกดาวน์โหลด", + "Shared by %2$s" : "แชร์โดย %2$s", + "Shared via link by %2$s" : "แชร์ผ่านลิงค์โดย %2$s", + "Shared with group %3$s by %2$s" : "แชร์กับกลุ่ม %3$s โดย %2$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/th_TH.json b/apps/files_sharing/l10n/th_TH.json index 9e4343bdee589..0a9cf3788c0f8 100644 --- a/apps/files_sharing/l10n/th_TH.json +++ b/apps/files_sharing/l10n/th_TH.json @@ -81,6 +81,11 @@ "Share it:" : "แชร์มัน:", "Add to your website" : "เพิ่มไปยังเว็บไซต์", "Share with me via ownCloud" : "แชร์ร่วมกับฉันผ่าน ownCloud", - "HTML Code:" : "โค้ด HTML:" + "HTML Code:" : "โค้ด HTML:", + "Public shared file %1$s was downloaded" : "ไฟล์สาธารณะ %1$s ที่แชร์ถูกดาวน์โหลด", + "Public shared folder %1$s was downloaded" : "โฟลเดอร์สาธารณะ %1$s ที่แชร์ถูกดาวน์โหลด", + "Shared by %2$s" : "แชร์โดย %2$s", + "Shared via link by %2$s" : "แชร์ผ่านลิงค์โดย %2$s", + "Shared with group %3$s by %2$s" : "แชร์กับกลุ่ม %3$s โดย %2$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/tr.js b/apps/files_sharing/l10n/tr.js index df267d35b1f6a..d39b94756ea52 100644 --- a/apps/files_sharing/l10n/tr.js +++ b/apps/files_sharing/l10n/tr.js @@ -101,6 +101,19 @@ OC.L10N.register( "Share it:" : "Paylaşın:", "Add to your website" : "Web sitenize ekleyin", "Share with me via ownCloud" : "Benimle ownCloud aracılığıyla paylaşıldı", - "HTML Code:" : "HTML Kodu:" + "HTML Code:" : "HTML Kodu:", + "Public link of %2$s expired" : "%2$s için paylaşım bağlantısı süresi doldu", + "Public shared file %1$s was downloaded" : "Herkese açık paylaşılan dosya %1$s indirildi", + "Public shared folder %1$s was downloaded" : "Herkese açık paylaşılan klasör %1$s indirildi", + "Removed share for %2$s" : "%2$s için paylaşım kaldırıldı", + "Removed share of group %2$s" : "%2$s, grup paylaşımını kaldırdı", + "Shared by %2$s" : "%2$s tarafından paylaşıldı", + "Shared via link by %2$s" : "%2$s tarafından bağlantı ile paylaşıldı", + "Shared with group %3$s by %2$s" : "%2$s tarafından %3$s grubu ile paylaşıldı", + "The public link of %2$s for %1$s expired" : "%1$s için %2$s paylaşım bağlantısının süresi doldu", + "You removed the public link for %1$s" : "%1$s için paylaşım bağlantısını kaldırdınız", + "You removed the share of %2$s for %1$s" : "%1$s için %2$s paylaşımını kaldırdınız", + "You removed the share of group %2$s for %1$s" : "%1$s için %2$s grup paylaşımını kaldırdınız", + "Your public link for %1$s expired" : "%1$s için paylaşım bağlantınızın süresi doldu" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files_sharing/l10n/tr.json b/apps/files_sharing/l10n/tr.json index 1b921920dd7d8..3b8860ed4ed37 100644 --- a/apps/files_sharing/l10n/tr.json +++ b/apps/files_sharing/l10n/tr.json @@ -99,6 +99,19 @@ "Share it:" : "Paylaşın:", "Add to your website" : "Web sitenize ekleyin", "Share with me via ownCloud" : "Benimle ownCloud aracılığıyla paylaşıldı", - "HTML Code:" : "HTML Kodu:" + "HTML Code:" : "HTML Kodu:", + "Public link of %2$s expired" : "%2$s için paylaşım bağlantısı süresi doldu", + "Public shared file %1$s was downloaded" : "Herkese açık paylaşılan dosya %1$s indirildi", + "Public shared folder %1$s was downloaded" : "Herkese açık paylaşılan klasör %1$s indirildi", + "Removed share for %2$s" : "%2$s için paylaşım kaldırıldı", + "Removed share of group %2$s" : "%2$s, grup paylaşımını kaldırdı", + "Shared by %2$s" : "%2$s tarafından paylaşıldı", + "Shared via link by %2$s" : "%2$s tarafından bağlantı ile paylaşıldı", + "Shared with group %3$s by %2$s" : "%2$s tarafından %3$s grubu ile paylaşıldı", + "The public link of %2$s for %1$s expired" : "%1$s için %2$s paylaşım bağlantısının süresi doldu", + "You removed the public link for %1$s" : "%1$s için paylaşım bağlantısını kaldırdınız", + "You removed the share of %2$s for %1$s" : "%1$s için %2$s paylaşımını kaldırdınız", + "You removed the share of group %2$s for %1$s" : "%1$s için %2$s grup paylaşımını kaldırdınız", + "Your public link for %1$s expired" : "%1$s için paylaşım bağlantınızın süresi doldu" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/uk.js b/apps/files_sharing/l10n/uk.js index b122664beca90..5d0bea9ff0a8e 100644 --- a/apps/files_sharing/l10n/uk.js +++ b/apps/files_sharing/l10n/uk.js @@ -61,6 +61,8 @@ OC.L10N.register( "Allow users on this server to send shares to other servers" : "Дозволити користувачам цього сервера публікувати на інших серверах", "Allow users on this server to receive shares from other servers" : "Дозволити користувачам на цьому сервері отримувати публікації з інших серверів", "Share it:" : "Поділитися цим:", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Public shared file %1$s was downloaded" : "Опублікований файл %1$s був завантажений", + "Public shared folder %1$s was downloaded" : "Опублікований каталог %1$s був завантажений" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_sharing/l10n/uk.json b/apps/files_sharing/l10n/uk.json index 363a02ed7edd9..f3baa83d611cf 100644 --- a/apps/files_sharing/l10n/uk.json +++ b/apps/files_sharing/l10n/uk.json @@ -59,6 +59,8 @@ "Allow users on this server to send shares to other servers" : "Дозволити користувачам цього сервера публікувати на інших серверах", "Allow users on this server to receive shares from other servers" : "Дозволити користувачам на цьому сервері отримувати публікації з інших серверів", "Share it:" : "Поділитися цим:", - "HTML Code:" : "HTML код:" + "HTML Code:" : "HTML код:", + "Public shared file %1$s was downloaded" : "Опублікований файл %1$s був завантажений", + "Public shared folder %1$s was downloaded" : "Опублікований каталог %1$s був завантажений" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/zh_CN.js b/apps/files_sharing/l10n/zh_CN.js index 4fc50f2ef18b2..cad122f3f68cb 100644 --- a/apps/files_sharing/l10n/zh_CN.js +++ b/apps/files_sharing/l10n/zh_CN.js @@ -60,6 +60,14 @@ OC.L10N.register( "Federated Cloud" : "联合云", "Your Federated Cloud ID:" : "你的联合云ID:", "Share with me via ownCloud" : "通过联合云与我共享", - "HTML Code:" : "HTML 代码:" + "HTML Code:" : "HTML 代码:", + "Add to your website" : "添加到您的网站", + "No shared links" : "无分享链接", + "Public link of %2$s expired" : "%2$s 的公开链接已过期", + "Public shared file %1$s was downloaded" : "公共共享文件 %1$s 已被下载", + "Public shared folder %1$s was downloaded" : "公共共享文件夹 %1$s 已被下载", + "Shared by %2$s" : "由 %2$s 共享", + "Shared via link by %2$s" : "%2$s 以链接方式共享", + "Shared with group %3$s by %2$s" : "由 %2$s 共享给组 %3$s" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/zh_CN.json b/apps/files_sharing/l10n/zh_CN.json index ac1852aa34789..06b9c1976845e 100644 --- a/apps/files_sharing/l10n/zh_CN.json +++ b/apps/files_sharing/l10n/zh_CN.json @@ -58,6 +58,14 @@ "Federated Cloud" : "联合云", "Your Federated Cloud ID:" : "你的联合云ID:", "Share with me via ownCloud" : "通过联合云与我共享", - "HTML Code:" : "HTML 代码:" + "HTML Code:" : "HTML 代码:", + "Add to your website" : "添加到您的网站", + "No shared links" : "无分享链接", + "Public link of %2$s expired" : "%2$s 的公开链接已过期", + "Public shared file %1$s was downloaded" : "公共共享文件 %1$s 已被下载", + "Public shared folder %1$s was downloaded" : "公共共享文件夹 %1$s 已被下载", + "Shared by %2$s" : "由 %2$s 共享", + "Shared via link by %2$s" : "%2$s 以链接方式共享", + "Shared with group %3$s by %2$s" : "由 %2$s 共享给组 %3$s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_sharing/l10n/zh_TW.js b/apps/files_sharing/l10n/zh_TW.js index a3de7a5ef4a70..90c0ddc01ec9e 100644 --- a/apps/files_sharing/l10n/zh_TW.js +++ b/apps/files_sharing/l10n/zh_TW.js @@ -82,6 +82,11 @@ OC.L10N.register( "Share it:" : "分享它:", "Add to your website" : "新增至您的網站", "Share with me via ownCloud" : "透過 ownCloud 與我分享", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public shared file %1$s was downloaded" : "共享檔案 %1$s 已被下載", + "Public shared folder %1$s was downloaded" : "共享資料夾 %1$s 已被下載", + "Shared by %2$s" : "由 %2$s 分享", + "Shared via link by %2$s" : "%2$s 透過連結分享", + "Shared with group %3$s by %2$s" : "透過 %2$s 與群組 %3$s 分享" }, "nplurals=1; plural=0;"); diff --git a/apps/files_sharing/l10n/zh_TW.json b/apps/files_sharing/l10n/zh_TW.json index 7a237c1c58afc..852bae4070824 100644 --- a/apps/files_sharing/l10n/zh_TW.json +++ b/apps/files_sharing/l10n/zh_TW.json @@ -80,6 +80,11 @@ "Share it:" : "分享它:", "Add to your website" : "新增至您的網站", "Share with me via ownCloud" : "透過 ownCloud 與我分享", - "HTML Code:" : "HTML Code:" + "HTML Code:" : "HTML Code:", + "Public shared file %1$s was downloaded" : "共享檔案 %1$s 已被下載", + "Public shared folder %1$s was downloaded" : "共享資料夾 %1$s 已被下載", + "Shared by %2$s" : "由 %2$s 分享", + "Shared via link by %2$s" : "%2$s 透過連結分享", + "Shared with group %3$s by %2$s" : "透過 %2$s 與群組 %3$s 分享" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/files_trashbin/l10n/hy.js b/apps/files_trashbin/l10n/hy.js index 39e49b47ae144..a0d51becf38d4 100644 --- a/apps/files_trashbin/l10n/hy.js +++ b/apps/files_trashbin/l10n/hy.js @@ -9,6 +9,7 @@ OC.L10N.register( "No deleted files" : "Ջնջված ֆայլեր չկան", "Select all" : "Նշել բոլորը", "Name" : "Անուն", - "Deleted" : "Ջնջված" + "Deleted" : "Ջնջված", + "Couldn't restore %s" : "Չկարողացա վերականգնել %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_trashbin/l10n/hy.json b/apps/files_trashbin/l10n/hy.json index 4bd34056b3fbb..f80b8cf81d52f 100644 --- a/apps/files_trashbin/l10n/hy.json +++ b/apps/files_trashbin/l10n/hy.json @@ -7,6 +7,7 @@ "No deleted files" : "Ջնջված ֆայլեր չկան", "Select all" : "Նշել բոլորը", "Name" : "Անուն", - "Deleted" : "Ջնջված" + "Deleted" : "Ջնջված", + "Couldn't restore %s" : "Չկարողացա վերականգնել %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/files_trashbin/l10n/pl.js b/apps/files_trashbin/l10n/pl.js index 0c11dab91d467..549634ee5b042 100644 --- a/apps/files_trashbin/l10n/pl.js +++ b/apps/files_trashbin/l10n/pl.js @@ -14,6 +14,7 @@ OC.L10N.register( "No entries found in this folder" : "Brak wpisów w tym folderze", "Select all" : "Wybierz wszystko", "Name" : "Nazwa", - "Deleted" : "Usunięte" + "Deleted" : "Usunięte", + "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem." }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/files_trashbin/l10n/pl.json b/apps/files_trashbin/l10n/pl.json index 8b56be020fbf4..c5adb1bf3139e 100644 --- a/apps/files_trashbin/l10n/pl.json +++ b/apps/files_trashbin/l10n/pl.json @@ -12,6 +12,7 @@ "No entries found in this folder" : "Brak wpisów w tym folderze", "Select all" : "Wybierz wszystko", "Name" : "Nazwa", - "Deleted" : "Usunięte" + "Deleted" : "Usunięte", + "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem." },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/de.js b/apps/systemtags/l10n/de.js index 83f9ccb2dc55e..b51775d7d230d 100644 --- a/apps/systemtags/l10n/de.js +++ b/apps/systemtags/l10n/de.js @@ -20,6 +20,7 @@ OC.L10N.register( "No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden", "Name" : "Name", "Size" : "Größe", - "Modified" : "Geändert" + "Modified" : "Geändert", + "System tags for a file have been modified" : "System-Tags für eine Datei sind geändert worden" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/systemtags/l10n/de.json b/apps/systemtags/l10n/de.json index 0534e1b3cef6e..5381b6eba4e20 100644 --- a/apps/systemtags/l10n/de.json +++ b/apps/systemtags/l10n/de.json @@ -18,6 +18,7 @@ "No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden", "Name" : "Name", "Size" : "Größe", - "Modified" : "Geändert" + "Modified" : "Geändert", + "System tags for a file have been modified" : "System-Tags für eine Datei sind geändert worden" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/de_DE.js b/apps/systemtags/l10n/de_DE.js index 9a76c2fd9ce09..bc47014979851 100644 --- a/apps/systemtags/l10n/de_DE.js +++ b/apps/systemtags/l10n/de_DE.js @@ -20,6 +20,7 @@ OC.L10N.register( "No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden", "Name" : "Name", "Size" : "Größe", - "Modified" : "Geändert" + "Modified" : "Geändert", + "System tags for a file have been modified" : "System-Tags für eine Datei sind geändert worden" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/systemtags/l10n/de_DE.json b/apps/systemtags/l10n/de_DE.json index 815479bdc7fd8..45206b01782c6 100644 --- a/apps/systemtags/l10n/de_DE.json +++ b/apps/systemtags/l10n/de_DE.json @@ -18,6 +18,7 @@ "No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden", "Name" : "Name", "Size" : "Größe", - "Modified" : "Geändert" + "Modified" : "Geändert", + "System tags for a file have been modified" : "System-Tags für eine Datei sind geändert worden" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/hu_HU.js b/apps/systemtags/l10n/hu_HU.js index ed90b2b07dca9..124eed4b5be1c 100644 --- a/apps/systemtags/l10n/hu_HU.js +++ b/apps/systemtags/l10n/hu_HU.js @@ -6,6 +6,10 @@ OC.L10N.register( "No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban", "Name" : "Név", "Size" : "Méret", - "Modified" : "Módosítva" + "Modified" : "Módosítva", + "No files found for the selected tags" : "Nem található fájl a kiválasztott címkéhez.", + "Please select tags to filter by" : "Kéjük, válasszon ki címkét a szűréshez:", + "Select tags to filter by" : "Kiválasztott címkék a szűrő által:", + "Tagged files" : "Címkézett fájlok" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/systemtags/l10n/hu_HU.json b/apps/systemtags/l10n/hu_HU.json index 8122c6f93cabe..7538ebb7cf1c2 100644 --- a/apps/systemtags/l10n/hu_HU.json +++ b/apps/systemtags/l10n/hu_HU.json @@ -4,6 +4,10 @@ "No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban", "Name" : "Név", "Size" : "Méret", - "Modified" : "Módosítva" + "Modified" : "Módosítva", + "No files found for the selected tags" : "Nem található fájl a kiválasztott címkéhez.", + "Please select tags to filter by" : "Kéjük, válasszon ki címkét a szűréshez:", + "Select tags to filter by" : "Kiválasztott címkék a szűrő által:", + "Tagged files" : "Címkézett fájlok" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/hy.js b/apps/systemtags/l10n/hy.js index 901854a96b64f..c461d4eea4edc 100644 --- a/apps/systemtags/l10n/hy.js +++ b/apps/systemtags/l10n/hy.js @@ -3,6 +3,7 @@ OC.L10N.register( { "Name" : "Անուն", "Size" : "Չափս", - "Modified" : "Փոփոխված" + "Modified" : "Փոփոխված", + "No files in here" : "Ֆայլեր չկան այստեղ" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/systemtags/l10n/hy.json b/apps/systemtags/l10n/hy.json index 9e937f42cf0ba..aaed0f7722d49 100644 --- a/apps/systemtags/l10n/hy.json +++ b/apps/systemtags/l10n/hy.json @@ -1,6 +1,7 @@ { "translations": { "Name" : "Անուն", "Size" : "Չափս", - "Modified" : "Փոփոխված" + "Modified" : "Փոփոխված", + "No files in here" : "Ֆայլեր չկան այստեղ" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/pl.js b/apps/systemtags/l10n/pl.js index 5e426a1e96e5f..b02248d5d5da5 100644 --- a/apps/systemtags/l10n/pl.js +++ b/apps/systemtags/l10n/pl.js @@ -5,6 +5,9 @@ OC.L10N.register( "No entries found in this folder" : "Brak wpisów w tym folderze", "Name" : "Nazwa", "Size" : "Rozmiar", - "Modified" : "Modyfikacja" + "Modified" : "Modyfikacja", + "No files found for the selected tags" : "Nie znaleziono plików dla wybranych etykiet", + "No files in here" : "Brak plików", + "Tagged files" : "Otagowane pliki" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/systemtags/l10n/pl.json b/apps/systemtags/l10n/pl.json index ca3158eaf4b20..9eee5358d9e10 100644 --- a/apps/systemtags/l10n/pl.json +++ b/apps/systemtags/l10n/pl.json @@ -3,6 +3,9 @@ "No entries found in this folder" : "Brak wpisów w tym folderze", "Name" : "Nazwa", "Size" : "Rozmiar", - "Modified" : "Modyfikacja" + "Modified" : "Modyfikacja", + "No files found for the selected tags" : "Nie znaleziono plików dla wybranych etykiet", + "No files in here" : "Brak plików", + "Tagged files" : "Otagowane pliki" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/systemtags/l10n/sr.js b/apps/systemtags/l10n/sr.js index fdd31cdf781af..10af36bfbc0dc 100644 --- a/apps/systemtags/l10n/sr.js +++ b/apps/systemtags/l10n/sr.js @@ -6,6 +6,7 @@ OC.L10N.register( "No entries found in this folder" : "Нема ничега у овој фасцикли", "Name" : "назив", "Size" : "величина", - "Modified" : "Измењен" + "Modified" : "Измењен", + "Tagged files" : "Означени фајлови" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/systemtags/l10n/sr.json b/apps/systemtags/l10n/sr.json index 2acc5aa42612a..ff7b063232acb 100644 --- a/apps/systemtags/l10n/sr.json +++ b/apps/systemtags/l10n/sr.json @@ -4,6 +4,7 @@ "No entries found in this folder" : "Нема ничега у овој фасцикли", "Name" : "назив", "Size" : "величина", - "Modified" : "Измењен" + "Modified" : "Измењен", + "Tagged files" : "Означени фајлови" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/az.js b/apps/updatenotification/l10n/az.js index 73782cba3e7b0..4e2a947c4045e 100644 --- a/apps/updatenotification/l10n/az.js +++ b/apps/updatenotification/l10n/az.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Yeniləyici" + "Updater" : "Yeniləyici", + "A new version is available: %s" : "Yeni versiya mövcuddur: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/az.json b/apps/updatenotification/l10n/az.json index 7be87969a4399..81ad8b461307e 100644 --- a/apps/updatenotification/l10n/az.json +++ b/apps/updatenotification/l10n/az.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Yeniləyici" + "Updater" : "Yeniləyici", + "A new version is available: %s" : "Yeni versiya mövcuddur: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/bg_BG.js b/apps/updatenotification/l10n/bg_BG.js index 443843734e1f5..585d75d9e57c5 100644 --- a/apps/updatenotification/l10n/bg_BG.js +++ b/apps/updatenotification/l10n/bg_BG.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Обновяване" + "Updater" : "Обновяване", + "A new version is available: %s" : "Има Нова Версия: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/bg_BG.json b/apps/updatenotification/l10n/bg_BG.json index 3dc540f8e6ffb..465f8e978ec7b 100644 --- a/apps/updatenotification/l10n/bg_BG.json +++ b/apps/updatenotification/l10n/bg_BG.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Обновяване" + "Updater" : "Обновяване", + "A new version is available: %s" : "Има Нова Версия: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/bs.js b/apps/updatenotification/l10n/bs.js index 34e6f1d1ac41a..63d9986a300d1 100644 --- a/apps/updatenotification/l10n/bs.js +++ b/apps/updatenotification/l10n/bs.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Unapređivač" + "Updater" : "Unapređivač", + "A new version is available: %s" : "Dostupna je nova verzija: %s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/updatenotification/l10n/bs.json b/apps/updatenotification/l10n/bs.json index da0308f62b9b8..6bf82bb07144e 100644 --- a/apps/updatenotification/l10n/bs.json +++ b/apps/updatenotification/l10n/bs.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Unapređivač" + "Updater" : "Unapređivač", + "A new version is available: %s" : "Dostupna je nova verzija: %s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/cs_CZ.js b/apps/updatenotification/l10n/cs_CZ.js index b7e261412ff76..db6661d16ab3a 100644 --- a/apps/updatenotification/l10n/cs_CZ.js +++ b/apps/updatenotification/l10n/cs_CZ.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "Je dostupná {version}. Přečtěte si více informací jak aktualizovat.", "Updater" : "Automatické aktualizace", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Z bezpečnostních důvodů používá zabudovaný program aktualizací ownCloud dodatečné přihlašovací údaje. Pro otevření stránky s aktualizacemi klikněte na následující tlačtko.", - "Open updater" : "Otevřít program aktualizací" + "Open updater" : "Otevřít program aktualizací", + "A new version is available: %s" : "Je dostupná nová verze: %s", + "Checked on %s" : "Zkontrolováno %s", + "Updated channel" : "Aktualizovat kanál" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/updatenotification/l10n/cs_CZ.json b/apps/updatenotification/l10n/cs_CZ.json index c022edc635d5a..c4062bddc90b3 100644 --- a/apps/updatenotification/l10n/cs_CZ.json +++ b/apps/updatenotification/l10n/cs_CZ.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "Je dostupná {version}. Přečtěte si více informací jak aktualizovat.", "Updater" : "Automatické aktualizace", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Z bezpečnostních důvodů používá zabudovaný program aktualizací ownCloud dodatečné přihlašovací údaje. Pro otevření stránky s aktualizacemi klikněte na následující tlačtko.", - "Open updater" : "Otevřít program aktualizací" + "Open updater" : "Otevřít program aktualizací", + "A new version is available: %s" : "Je dostupná nová verze: %s", + "Checked on %s" : "Zkontrolováno %s", + "Updated channel" : "Aktualizovat kanál" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/da.js b/apps/updatenotification/l10n/da.js index 5fb9ff0e75f29..98eb1a75c7b0d 100644 --- a/apps/updatenotification/l10n/da.js +++ b/apps/updatenotification/l10n/da.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} er tilgængelig. Få mere information om hvordan du opdaterer.", - "Updater" : "Updater" + "Updater" : "Updater", + "A new version is available: %s" : "Der er en ny version tligængelig: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/da.json b/apps/updatenotification/l10n/da.json index 93ec0654478f8..88f0db193bc4a 100644 --- a/apps/updatenotification/l10n/da.json +++ b/apps/updatenotification/l10n/da.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} er tilgængelig. Få mere information om hvordan du opdaterer.", - "Updater" : "Updater" + "Updater" : "Updater", + "A new version is available: %s" : "Der er en ny version tligængelig: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/de.js b/apps/updatenotification/l10n/de.js index e9299ed07e1d7..99dd7f20a82a8 100644 --- a/apps/updatenotification/l10n/de.js +++ b/apps/updatenotification/l10n/de.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} ist verfügbar. Weitere Informationen zur Aktualisierungen.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Aus Sicherheitsgründen nutzt der ownCloud Updater zusätzlichen Anmeldeinformationen. Um die Update-Seite aufzurufen, klicke bitte auf den folgenden Button.", - "Open updater" : "Updater aufrufen" + "Open updater" : "Updater aufrufen", + "A new version is available: %s" : "Eine neue Version ist verfügbar: %s", + "Checked on %s" : "Geprüft auf %s", + "Updated channel" : "Aktualisierter Kanal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/de.json b/apps/updatenotification/l10n/de.json index 10276b6608cca..e8c74c9869635 100644 --- a/apps/updatenotification/l10n/de.json +++ b/apps/updatenotification/l10n/de.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} ist verfügbar. Weitere Informationen zur Aktualisierungen.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Aus Sicherheitsgründen nutzt der ownCloud Updater zusätzlichen Anmeldeinformationen. Um die Update-Seite aufzurufen, klicke bitte auf den folgenden Button.", - "Open updater" : "Updater aufrufen" + "Open updater" : "Updater aufrufen", + "A new version is available: %s" : "Eine neue Version ist verfügbar: %s", + "Checked on %s" : "Geprüft auf %s", + "Updated channel" : "Aktualisierter Kanal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/de_DE.js b/apps/updatenotification/l10n/de_DE.js index d41bc16eeabc8..4c3d120d41840 100644 --- a/apps/updatenotification/l10n/de_DE.js +++ b/apps/updatenotification/l10n/de_DE.js @@ -4,6 +4,8 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} ist verfügbar. Weitere Informationen zur Aktualisierungen.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Aus Sicherheitsgründen nutzt der ownCloud Updater zusätzlichen Anmeldeinformationen. Um die Update-Seite aufzurufen, klicken Sie bitte auf den folgenden Button.", - "Open updater" : "Updater aufrufen" + "Open updater" : "Updater aufrufen", + "A new version is available: %s" : "Eine neue Version ist verfügbar: %s", + "Checked on %s" : "Überprüft auf %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/de_DE.json b/apps/updatenotification/l10n/de_DE.json index d406ef9b9ea6b..d0a767f936939 100644 --- a/apps/updatenotification/l10n/de_DE.json +++ b/apps/updatenotification/l10n/de_DE.json @@ -2,6 +2,8 @@ "{version} is available. Get more information on how to update." : "{version} ist verfügbar. Weitere Informationen zur Aktualisierungen.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Aus Sicherheitsgründen nutzt der ownCloud Updater zusätzlichen Anmeldeinformationen. Um die Update-Seite aufzurufen, klicken Sie bitte auf den folgenden Button.", - "Open updater" : "Updater aufrufen" + "Open updater" : "Updater aufrufen", + "A new version is available: %s" : "Eine neue Version ist verfügbar: %s", + "Checked on %s" : "Überprüft auf %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/el.js b/apps/updatenotification/l10n/el.js index ded65a8574eed..232c41b88e65f 100644 --- a/apps/updatenotification/l10n/el.js +++ b/apps/updatenotification/l10n/el.js @@ -2,6 +2,8 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "Η έκδοση {version} είναι διαθέσιμη. Δείτε περισσότερες πληροφορίες για το πως να κάνετε την ενημέρωση.", - "Updater" : "Εφαρμογή Ενημέρωσης" + "Updater" : "Εφαρμογή Ενημέρωσης", + "A new version is available: %s" : "Μία νέα έκδοση είναι διαθέσιμη: %s", + "Open updater" : "Άνοιγμα εφαρμογής ενημέρωσης" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/el.json b/apps/updatenotification/l10n/el.json index ed15493646bee..96b99f2cf4c34 100644 --- a/apps/updatenotification/l10n/el.json +++ b/apps/updatenotification/l10n/el.json @@ -1,5 +1,7 @@ { "translations": { "{version} is available. Get more information on how to update." : "Η έκδοση {version} είναι διαθέσιμη. Δείτε περισσότερες πληροφορίες για το πως να κάνετε την ενημέρωση.", - "Updater" : "Εφαρμογή Ενημέρωσης" + "Updater" : "Εφαρμογή Ενημέρωσης", + "A new version is available: %s" : "Μία νέα έκδοση είναι διαθέσιμη: %s", + "Open updater" : "Άνοιγμα εφαρμογής ενημέρωσης" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/en_GB.js b/apps/updatenotification/l10n/en_GB.js index a6f83cb048a10..2950c5be11a67 100644 --- a/apps/updatenotification/l10n/en_GB.js +++ b/apps/updatenotification/l10n/en_GB.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} is available. Get more information on how to update.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button.", - "Open updater" : "Open updater" + "Open updater" : "Open updater", + "A new version is available: %s" : "A new version is available: %s", + "Checked on %s" : "Checked on %s", + "Updated channel" : "Updated channel" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/en_GB.json b/apps/updatenotification/l10n/en_GB.json index 0ac5846f9e844..61bf5487b3372 100644 --- a/apps/updatenotification/l10n/en_GB.json +++ b/apps/updatenotification/l10n/en_GB.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} is available. Get more information on how to update.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button.", - "Open updater" : "Open updater" + "Open updater" : "Open updater", + "A new version is available: %s" : "A new version is available: %s", + "Checked on %s" : "Checked on %s", + "Updated channel" : "Updated channel" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/es.js b/apps/updatenotification/l10n/es.js index f8a88186f346d..24333ff2afde7 100644 --- a/apps/updatenotification/l10n/es.js +++ b/apps/updatenotification/l10n/es.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} está disponible. Obtenga más información sobre cómo actualizar.", "Updater" : "Actualizador", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razones de seguridad el actualizador incluido en ownCloud está utilizando credenciales adicionales. Para visitar la pagina del actualizador, por favor presione el siguiente botón.", - "Open updater" : "Abrir el actualizador" + "Open updater" : "Abrir el actualizador", + "A new version is available: %s" : "Hay una nueva versión disponible: %s", + "Checked on %s" : "Revisado el %s", + "Updated channel" : "Canal actualizado" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/es.json b/apps/updatenotification/l10n/es.json index 032ee8e85ea21..f57aaa7fa5b48 100644 --- a/apps/updatenotification/l10n/es.json +++ b/apps/updatenotification/l10n/es.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} está disponible. Obtenga más información sobre cómo actualizar.", "Updater" : "Actualizador", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razones de seguridad el actualizador incluido en ownCloud está utilizando credenciales adicionales. Para visitar la pagina del actualizador, por favor presione el siguiente botón.", - "Open updater" : "Abrir el actualizador" + "Open updater" : "Abrir el actualizador", + "A new version is available: %s" : "Hay una nueva versión disponible: %s", + "Checked on %s" : "Revisado el %s", + "Updated channel" : "Canal actualizado" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/es_AR.js b/apps/updatenotification/l10n/es_AR.js index 6546f696b2f1c..1adeb21635ade 100644 --- a/apps/updatenotification/l10n/es_AR.js +++ b/apps/updatenotification/l10n/es_AR.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Actualizador" + "Updater" : "Actualizador", + "A new version is available: %s" : "Una nueva versión esta disponible: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/es_AR.json b/apps/updatenotification/l10n/es_AR.json index 828c965caafc0..f3a64c95945f3 100644 --- a/apps/updatenotification/l10n/es_AR.json +++ b/apps/updatenotification/l10n/es_AR.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Actualizador" + "Updater" : "Actualizador", + "A new version is available: %s" : "Una nueva versión esta disponible: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/et_EE.js b/apps/updatenotification/l10n/et_EE.js index eaa6d0fc691fc..7c15b2d610aec 100644 --- a/apps/updatenotification/l10n/et_EE.js +++ b/apps/updatenotification/l10n/et_EE.js @@ -3,6 +3,8 @@ OC.L10N.register( { "{version} is available. Get more information on how to update." : "{version} on saadaval. Vaata lisainfot uuendamise kohta.", "Updater" : "Uuendaja", - "Open updater" : "Ava uuendaja" + "Open updater" : "Ava uuendaja", + "A new version is available: %s" : "Saadaval on uus versioon: %s", + "Updated channel" : "Uuendatud kanal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/et_EE.json b/apps/updatenotification/l10n/et_EE.json index f01d796b7e4dc..e50145f81bd1f 100644 --- a/apps/updatenotification/l10n/et_EE.json +++ b/apps/updatenotification/l10n/et_EE.json @@ -1,6 +1,8 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} on saadaval. Vaata lisainfot uuendamise kohta.", "Updater" : "Uuendaja", - "Open updater" : "Ava uuendaja" + "Open updater" : "Ava uuendaja", + "A new version is available: %s" : "Saadaval on uus versioon: %s", + "Updated channel" : "Uuendatud kanal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/eu.js b/apps/updatenotification/l10n/eu.js index 9677dc787dd99..6916a8579df74 100644 --- a/apps/updatenotification/l10n/eu.js +++ b/apps/updatenotification/l10n/eu.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Eguneratzailea" + "Updater" : "Eguneratzailea", + "A new version is available: %s" : "Bertsio berri bat eskuragarri dago: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/eu.json b/apps/updatenotification/l10n/eu.json index 663af5e409683..7d696825f5e84 100644 --- a/apps/updatenotification/l10n/eu.json +++ b/apps/updatenotification/l10n/eu.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Eguneratzailea" + "Updater" : "Eguneratzailea", + "A new version is available: %s" : "Bertsio berri bat eskuragarri dago: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/fi_FI.js b/apps/updatenotification/l10n/fi_FI.js index 165bc57936ad3..a75dc3d90ea01 100644 --- a/apps/updatenotification/l10n/fi_FI.js +++ b/apps/updatenotification/l10n/fi_FI.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} on saatavilla. Tarjolla on lisätietoja päivittämisestä.", "Updater" : "Päivitysohjelma", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Tietoturvasyistä ownCloudin sisäänrakennettu päivitysohjelma käyttää erillisiä tunnistamistietoja. Siirry päivitysohjelman sivulle napsauttamalla seuraavaa painiketta.", - "Open updater" : "Avaa päivitysohjelma" + "Open updater" : "Avaa päivitysohjelma", + "A new version is available: %s" : "Uusi versio on saatavilla: %s", + "Checked on %s" : "Tarkistettu %s", + "Updated channel" : "Päivitetty kanava" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/fi_FI.json b/apps/updatenotification/l10n/fi_FI.json index 5a96aadb04467..4c1948bd5d517 100644 --- a/apps/updatenotification/l10n/fi_FI.json +++ b/apps/updatenotification/l10n/fi_FI.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} on saatavilla. Tarjolla on lisätietoja päivittämisestä.", "Updater" : "Päivitysohjelma", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Tietoturvasyistä ownCloudin sisäänrakennettu päivitysohjelma käyttää erillisiä tunnistamistietoja. Siirry päivitysohjelman sivulle napsauttamalla seuraavaa painiketta.", - "Open updater" : "Avaa päivitysohjelma" + "Open updater" : "Avaa päivitysohjelma", + "A new version is available: %s" : "Uusi versio on saatavilla: %s", + "Checked on %s" : "Tarkistettu %s", + "Updated channel" : "Päivitetty kanava" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/fr.js b/apps/updatenotification/l10n/fr.js index b41a6de202eef..b0b2261de9900 100644 --- a/apps/updatenotification/l10n/fr.js +++ b/apps/updatenotification/l10n/fr.js @@ -4,6 +4,8 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "La version {version} est disponible. Cliquez ici pour plus d'informations sur comment mettre à jour.", "Updater" : "Mises à jour", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Pour des raisons de sécurité, le module de mises à jour intégré à ownCloud utilise des informations d'identification supplémentaires. Pour visiter la page du module de mises à jour, cliquez sur le bouton suivant.", - "Open updater" : "Ouvrir le système de mise à jour" + "Open updater" : "Ouvrir le système de mise à jour", + "A new version is available: %s" : "Une nouvelle version est disponible : %s", + "Checked on %s" : "Vérifié le %s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/updatenotification/l10n/fr.json b/apps/updatenotification/l10n/fr.json index 473d53d11ff4e..f663f5a7e34c3 100644 --- a/apps/updatenotification/l10n/fr.json +++ b/apps/updatenotification/l10n/fr.json @@ -2,6 +2,8 @@ "{version} is available. Get more information on how to update." : "La version {version} est disponible. Cliquez ici pour plus d'informations sur comment mettre à jour.", "Updater" : "Mises à jour", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Pour des raisons de sécurité, le module de mises à jour intégré à ownCloud utilise des informations d'identification supplémentaires. Pour visiter la page du module de mises à jour, cliquez sur le bouton suivant.", - "Open updater" : "Ouvrir le système de mise à jour" + "Open updater" : "Ouvrir le système de mise à jour", + "A new version is available: %s" : "Une nouvelle version est disponible : %s", + "Checked on %s" : "Vérifié le %s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/gl.js b/apps/updatenotification/l10n/gl.js index f87d3768aab22..62e21836e7015 100644 --- a/apps/updatenotification/l10n/gl.js +++ b/apps/updatenotification/l10n/gl.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} está dispoñíbel. Obteña máis información sobre como actualizar.", - "Updater" : "Actualizador" + "Updater" : "Actualizador", + "A new version is available: %s" : "Hai dispoñíbel unha versión: %s" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/gl.json b/apps/updatenotification/l10n/gl.json index dba6de2dc1720..a2d8ed88eaf52 100644 --- a/apps/updatenotification/l10n/gl.json +++ b/apps/updatenotification/l10n/gl.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} está dispoñíbel. Obteña máis información sobre como actualizar.", - "Updater" : "Actualizador" + "Updater" : "Actualizador", + "A new version is available: %s" : "Hai dispoñíbel unha versión: %s" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/he.js b/apps/updatenotification/l10n/he.js index 0468109610144..3375ac998481a 100644 --- a/apps/updatenotification/l10n/he.js +++ b/apps/updatenotification/l10n/he.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} זמינה. ניתן לקבל מידע נוסף על איך לעדכן.", "Updater" : "מעדכן", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "מסיבות הבטחה מעדכן ה- ownCloud המובנה משתמש באימות נוסף. לביקור בעמוד העדכון יש ללחוץ על הכפתור הבא.", - "Open updater" : "פתיחת מעדכן" + "Open updater" : "פתיחת מעדכן", + "A new version is available: %s" : "קיימת גרסה מעודכנת: %s", + "Checked on %s" : "נבדק לאחרונה ב- %s", + "Updated channel" : "ערוץ מעודכן" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/he.json b/apps/updatenotification/l10n/he.json index 8bdf252e4f3a9..fb31629c25ea9 100644 --- a/apps/updatenotification/l10n/he.json +++ b/apps/updatenotification/l10n/he.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} זמינה. ניתן לקבל מידע נוסף על איך לעדכן.", "Updater" : "מעדכן", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "מסיבות הבטחה מעדכן ה- ownCloud המובנה משתמש באימות נוסף. לביקור בעמוד העדכון יש ללחוץ על הכפתור הבא.", - "Open updater" : "פתיחת מעדכן" + "Open updater" : "פתיחת מעדכן", + "A new version is available: %s" : "קיימת גרסה מעודכנת: %s", + "Checked on %s" : "נבדק לאחרונה ב- %s", + "Updated channel" : "ערוץ מעודכן" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/hr.js b/apps/updatenotification/l10n/hr.js index 7a3d340816d43..e089797d824a3 100644 --- a/apps/updatenotification/l10n/hr.js +++ b/apps/updatenotification/l10n/hr.js @@ -1,6 +1,7 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Aplikcija za nadogradnju" + "Updater" : "Aplikcija za nadogradnju", + "A new version is available: %s" : "Nova verzija je dostupna: %s" }, "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); diff --git a/apps/updatenotification/l10n/hr.json b/apps/updatenotification/l10n/hr.json index 16dc7becd6a46..f45cdb0e89792 100644 --- a/apps/updatenotification/l10n/hr.json +++ b/apps/updatenotification/l10n/hr.json @@ -1,4 +1,5 @@ { "translations": { - "Updater" : "Aplikcija za nadogradnju" + "Updater" : "Aplikcija za nadogradnju", + "A new version is available: %s" : "Nova verzija je dostupna: %s" },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/hu_HU.js b/apps/updatenotification/l10n/hu_HU.js index 7d26aaf26dd8a..40f397868eee8 100644 --- a/apps/updatenotification/l10n/hu_HU.js +++ b/apps/updatenotification/l10n/hu_HU.js @@ -2,6 +2,10 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} rendelkezésre áll. További információ a frissítéshez.", - "Updater" : "Frissítéskezelő" + "Updater" : "Frissítéskezelő", + "A new version is available: %s" : "Új verzió érhető el: %s", + "Checked on %s" : "Ellenőrizve: %s", + "Open updater" : "Frissítő megnyitása", + "Updated channel" : "Frissített csatorna" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/hu_HU.json b/apps/updatenotification/l10n/hu_HU.json index d7a611238c9f7..acfb7fc0cd05f 100644 --- a/apps/updatenotification/l10n/hu_HU.json +++ b/apps/updatenotification/l10n/hu_HU.json @@ -1,5 +1,9 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} rendelkezésre áll. További információ a frissítéshez.", - "Updater" : "Frissítéskezelő" + "Updater" : "Frissítéskezelő", + "A new version is available: %s" : "Új verzió érhető el: %s", + "Checked on %s" : "Ellenőrizve: %s", + "Open updater" : "Frissítő megnyitása", + "Updated channel" : "Frissített csatorna" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/id.js b/apps/updatenotification/l10n/id.js index 7d90d3848f04e..0bf2afb333ba6 100644 --- a/apps/updatenotification/l10n/id.js +++ b/apps/updatenotification/l10n/id.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} tersedia. Dapatkan informasi lebih lanjut cara memperbaruinya.", - "Updater" : "Pengupdate" + "Updater" : "Pengupdate", + "A new version is available: %s" : "Versi baru tersedia: %s" }, "nplurals=1; plural=0;"); diff --git a/apps/updatenotification/l10n/id.json b/apps/updatenotification/l10n/id.json index 86dccdda80a65..ff819806a4fd2 100644 --- a/apps/updatenotification/l10n/id.json +++ b/apps/updatenotification/l10n/id.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} tersedia. Dapatkan informasi lebih lanjut cara memperbaruinya.", - "Updater" : "Pengupdate" + "Updater" : "Pengupdate", + "A new version is available: %s" : "Versi baru tersedia: %s" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/is.js b/apps/updatenotification/l10n/is.js index 6d2cf902382fb..d8b58dd29afe7 100644 --- a/apps/updatenotification/l10n/is.js +++ b/apps/updatenotification/l10n/is.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} er í boði. Fá frekari upplýsingar um hvernig á að uppfæra.", "Updater" : "Uppfærslustýring", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Af öryggisástæðum notar innbyggða uppfærslustýringin í ownCloud viðbótar-auðkennisupplýsingar. Til að skoða síðu uppfærslustýringarinnar skaltu smella á eftirfarandi hnapp.", - "Open updater" : "Opna uppfærslustýringu" + "Open updater" : "Opna uppfærslustýringu", + "A new version is available: %s" : "Ný útgáfa er tiltæk: %s", + "Checked on %s" : "Athugað þann %s", + "Updated channel" : "Uppfærði rás" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/updatenotification/l10n/is.json b/apps/updatenotification/l10n/is.json index dbf667e64affd..3fbb0475cfa7e 100644 --- a/apps/updatenotification/l10n/is.json +++ b/apps/updatenotification/l10n/is.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} er í boði. Fá frekari upplýsingar um hvernig á að uppfæra.", "Updater" : "Uppfærslustýring", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Af öryggisástæðum notar innbyggða uppfærslustýringin í ownCloud viðbótar-auðkennisupplýsingar. Til að skoða síðu uppfærslustýringarinnar skaltu smella á eftirfarandi hnapp.", - "Open updater" : "Opna uppfærslustýringu" + "Open updater" : "Opna uppfærslustýringu", + "A new version is available: %s" : "Ný útgáfa er tiltæk: %s", + "Checked on %s" : "Athugað þann %s", + "Updated channel" : "Uppfærði rás" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/it.js b/apps/updatenotification/l10n/it.js index 6c8ab0d33e485..4e2d773c0738f 100644 --- a/apps/updatenotification/l10n/it.js +++ b/apps/updatenotification/l10n/it.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} è disponibile. Ottieni ulteriori informazioni su come eseguire l'aggiornamento.", "Updater" : "Strumento di aggiornamento", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Per ragioni di sicurezza, lo strumento di aggiornamento integrato di ownCloud utilizza credenziali aggiuntive. Per visitare la pagine dello strumento di aggiornamento, fai clic sul pulsante seguente.", - "Open updater" : "Apri lo strumento di aggiornamento" + "Open updater" : "Apri lo strumento di aggiornamento", + "A new version is available: %s" : "Una nuova versione è disponibile: %s", + "Checked on %s" : "Controllato il %s", + "Updated channel" : "Canale di aggiornamento" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/it.json b/apps/updatenotification/l10n/it.json index 31b6d2b898936..a0e66a5a6aa9b 100644 --- a/apps/updatenotification/l10n/it.json +++ b/apps/updatenotification/l10n/it.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} è disponibile. Ottieni ulteriori informazioni su come eseguire l'aggiornamento.", "Updater" : "Strumento di aggiornamento", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Per ragioni di sicurezza, lo strumento di aggiornamento integrato di ownCloud utilizza credenziali aggiuntive. Per visitare la pagine dello strumento di aggiornamento, fai clic sul pulsante seguente.", - "Open updater" : "Apri lo strumento di aggiornamento" + "Open updater" : "Apri lo strumento di aggiornamento", + "A new version is available: %s" : "Una nuova versione è disponibile: %s", + "Checked on %s" : "Controllato il %s", + "Updated channel" : "Canale di aggiornamento" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/ja.js b/apps/updatenotification/l10n/ja.js index f3b271e9e49c4..926fc1e91bff5 100644 --- a/apps/updatenotification/l10n/ja.js +++ b/apps/updatenotification/l10n/ja.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} が利用可能です。アップデート方法について詳細情報を確認してください。", "Updater" : "アップデート", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "セキュリティ上の理由から、ownCloudに組み込まれているアップデーターは追加で認証情報を利用します。アップデーターページを開くには、以下のボタンをクリックしてください。", - "Open updater" : "アップデーターを開く" + "Open updater" : "アップデーターを開く", + "A new version is available: %s" : "新しいバージョンが利用可能: %s", + "Checked on %s" : "%s に確認", + "Updated channel" : "アップデートチャンネル" }, "nplurals=1; plural=0;"); diff --git a/apps/updatenotification/l10n/ja.json b/apps/updatenotification/l10n/ja.json index ffdb380427645..9130edcb15129 100644 --- a/apps/updatenotification/l10n/ja.json +++ b/apps/updatenotification/l10n/ja.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} が利用可能です。アップデート方法について詳細情報を確認してください。", "Updater" : "アップデート", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "セキュリティ上の理由から、ownCloudに組み込まれているアップデーターは追加で認証情報を利用します。アップデーターページを開くには、以下のボタンをクリックしてください。", - "Open updater" : "アップデーターを開く" + "Open updater" : "アップデーターを開く", + "A new version is available: %s" : "新しいバージョンが利用可能: %s", + "Checked on %s" : "%s に確認", + "Updated channel" : "アップデートチャンネル" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/ko.js b/apps/updatenotification/l10n/ko.js index 8e1d12173f360..b64b32003f3d9 100644 --- a/apps/updatenotification/l10n/ko.js +++ b/apps/updatenotification/l10n/ko.js @@ -2,6 +2,8 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version}을(를) 사용할 수 있습니다. 업데이트하는 방법에 대해서 알아보십시오.", - "Updater" : "업데이터" + "Updater" : "업데이터", + "A new version is available: %s" : "새 버전을 사용할 수 있습니다: %s", + "Open updater" : "업데이터 열기" }, "nplurals=1; plural=0;"); diff --git a/apps/updatenotification/l10n/ko.json b/apps/updatenotification/l10n/ko.json index 3c135df4f461c..aab5f6f786a27 100644 --- a/apps/updatenotification/l10n/ko.json +++ b/apps/updatenotification/l10n/ko.json @@ -1,5 +1,7 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version}을(를) 사용할 수 있습니다. 업데이트하는 방법에 대해서 알아보십시오.", - "Updater" : "업데이터" + "Updater" : "업데이터", + "A new version is available: %s" : "새 버전을 사용할 수 있습니다: %s", + "Open updater" : "업데이터 열기" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/nb_NO.js b/apps/updatenotification/l10n/nb_NO.js index 254a4fd6c2782..a4e78e4f2c26f 100644 --- a/apps/updatenotification/l10n/nb_NO.js +++ b/apps/updatenotification/l10n/nb_NO.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} er tilgjengelig. Få mer informasjon om å oppdatere.", "Updater" : "Oppdaterer", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Av sikkerhetsgrunner bruker den innebyggede ownCloud-oppdatereren flere påloggingsdetaljer. Klikk følgende knapp for å gå til oppdaterer-siden.", - "Open updater" : "Åpne oppdaterer" + "Open updater" : "Åpne oppdaterer", + "A new version is available: %s" : "En ny versjon er tilgjengelig: %s", + "Checked on %s" : "Sjekket %s", + "Updated channel" : "Oppdaterte kanal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/nb_NO.json b/apps/updatenotification/l10n/nb_NO.json index c6dded3fd86e6..c8a03933dd0d3 100644 --- a/apps/updatenotification/l10n/nb_NO.json +++ b/apps/updatenotification/l10n/nb_NO.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} er tilgjengelig. Få mer informasjon om å oppdatere.", "Updater" : "Oppdaterer", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Av sikkerhetsgrunner bruker den innebyggede ownCloud-oppdatereren flere påloggingsdetaljer. Klikk følgende knapp for å gå til oppdaterer-siden.", - "Open updater" : "Åpne oppdaterer" + "Open updater" : "Åpne oppdaterer", + "A new version is available: %s" : "En ny versjon er tilgjengelig: %s", + "Checked on %s" : "Sjekket %s", + "Updated channel" : "Oppdaterte kanal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/nl.js b/apps/updatenotification/l10n/nl.js index 17350598cfe47..027a72fb8b4b3 100644 --- a/apps/updatenotification/l10n/nl.js +++ b/apps/updatenotification/l10n/nl.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} is beschikbaar. Meer informatie over het bijwerken.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Om veiligheidsredenen gebruikt de ingebouwde ownCloud updater extra authenticatie. Klik op de knop om de updater pagina te bezoeken.", - "Open updater" : "Open updater" + "Open updater" : "Open updater", + "A new version is available: %s" : "Er is een nieuwe versie beschikbaar: %s", + "Checked on %s" : "Gecontroleerd op %s", + "Updated channel" : "Bijgewerkt kanaal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/nl.json b/apps/updatenotification/l10n/nl.json index 0ef455b949042..df988d375a743 100644 --- a/apps/updatenotification/l10n/nl.json +++ b/apps/updatenotification/l10n/nl.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} is beschikbaar. Meer informatie over het bijwerken.", "Updater" : "Updater", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Om veiligheidsredenen gebruikt de ingebouwde ownCloud updater extra authenticatie. Klik op de knop om de updater pagina te bezoeken.", - "Open updater" : "Open updater" + "Open updater" : "Open updater", + "A new version is available: %s" : "Er is een nieuwe versie beschikbaar: %s", + "Checked on %s" : "Gecontroleerd op %s", + "Updated channel" : "Bijgewerkt kanaal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/pl.js b/apps/updatenotification/l10n/pl.js index 5612249004413..a281f49bc4703 100644 --- a/apps/updatenotification/l10n/pl.js +++ b/apps/updatenotification/l10n/pl.js @@ -1,6 +1,10 @@ OC.L10N.register( "updatenotification", { - "Updater" : "Aktualizator" + "Updater" : "Aktualizator", + "A new version is available: %s" : "Dostępna jest nowa wersja: %s", + "Checked on %s" : "Sprawdzone na %s", + "Open updater" : "Otwórz aktualizator", + "Updated channel" : "Zaktualizowano kanał" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/updatenotification/l10n/pl.json b/apps/updatenotification/l10n/pl.json index 6826c9c5dec9e..968146b8581cf 100644 --- a/apps/updatenotification/l10n/pl.json +++ b/apps/updatenotification/l10n/pl.json @@ -1,4 +1,8 @@ { "translations": { - "Updater" : "Aktualizator" + "Updater" : "Aktualizator", + "A new version is available: %s" : "Dostępna jest nowa wersja: %s", + "Checked on %s" : "Sprawdzone na %s", + "Open updater" : "Otwórz aktualizator", + "Updated channel" : "Zaktualizowano kanał" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/pt_BR.js b/apps/updatenotification/l10n/pt_BR.js index b1207b6ad9f74..0ca9f0bdb0076 100644 --- a/apps/updatenotification/l10n/pt_BR.js +++ b/apps/updatenotification/l10n/pt_BR.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informações sobre como atualizar.", "Updater" : "Atualizador", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razões de segurança o atualizador interno do ownCloud está usando credenciais adicionais. Para visitar a página atualizador por favor clique no botão a seguir.", - "Open updater" : "Abrir o atualizador" + "Open updater" : "Abrir o atualizador", + "A new version is available: %s" : "Uma nova versão está disponível: %s", + "Checked on %s" : "Verificada em %s", + "Updated channel" : "Canal atualizado" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/updatenotification/l10n/pt_BR.json b/apps/updatenotification/l10n/pt_BR.json index 54551ca44c850..2496eae25ef3b 100644 --- a/apps/updatenotification/l10n/pt_BR.json +++ b/apps/updatenotification/l10n/pt_BR.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informações sobre como atualizar.", "Updater" : "Atualizador", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razões de segurança o atualizador interno do ownCloud está usando credenciais adicionais. Para visitar a página atualizador por favor clique no botão a seguir.", - "Open updater" : "Abrir o atualizador" + "Open updater" : "Abrir o atualizador", + "A new version is available: %s" : "Uma nova versão está disponível: %s", + "Checked on %s" : "Verificada em %s", + "Updated channel" : "Canal atualizado" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/pt_PT.js b/apps/updatenotification/l10n/pt_PT.js index 348803f9b95e5..65a739ff7d3f9 100644 --- a/apps/updatenotification/l10n/pt_PT.js +++ b/apps/updatenotification/l10n/pt_PT.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informação sobre como atualizar.", "Updater" : "actualizar", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razões de segurança o atualizador ownCloud está a usar credenciais adicionais. Para visitar a página do atualizador clique no seguinte botão.", - "Open updater" : "Abrir atualizador" + "Open updater" : "Abrir atualizador", + "A new version is available: %s" : "Está disponível uma nova versão: %s", + "Checked on %s" : "Verificado em %s", + "Updated channel" : "Actualizar canal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/pt_PT.json b/apps/updatenotification/l10n/pt_PT.json index bf7414d7128c2..769e4fe2c1813 100644 --- a/apps/updatenotification/l10n/pt_PT.json +++ b/apps/updatenotification/l10n/pt_PT.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} está disponível. Obtenha mais informação sobre como atualizar.", "Updater" : "actualizar", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Por razões de segurança o atualizador ownCloud está a usar credenciais adicionais. Para visitar a página do atualizador clique no seguinte botão.", - "Open updater" : "Abrir atualizador" + "Open updater" : "Abrir atualizador", + "A new version is available: %s" : "Está disponível uma nova versão: %s", + "Checked on %s" : "Verificado em %s", + "Updated channel" : "Actualizar canal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/ru.js b/apps/updatenotification/l10n/ru.js index c17da7848e4fd..923e02644c463 100644 --- a/apps/updatenotification/l10n/ru.js +++ b/apps/updatenotification/l10n/ru.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "Доступна версия {version}. Получить дополнительную информацию о порядке обновления.", "Updater" : "Обновление", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "По соображениям безопасности встроенное средство обновления ownCloud использует дополнительные учетные данные. Для перехода к странице обновления, пожалуйста, нажмите следующую кнопку.", - "Open updater" : "Открыть окно обновления" + "Open updater" : "Открыть окно обновления", + "A new version is available: %s" : "Доступна новая версия: %s", + "Checked on %s" : "Проверено %s", + "Updated channel" : "Обновленный канал" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/updatenotification/l10n/ru.json b/apps/updatenotification/l10n/ru.json index 1d857e584f0fc..5c69557a6a7a6 100644 --- a/apps/updatenotification/l10n/ru.json +++ b/apps/updatenotification/l10n/ru.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "Доступна версия {version}. Получить дополнительную информацию о порядке обновления.", "Updater" : "Обновление", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "По соображениям безопасности встроенное средство обновления ownCloud использует дополнительные учетные данные. Для перехода к странице обновления, пожалуйста, нажмите следующую кнопку.", - "Open updater" : "Открыть окно обновления" + "Open updater" : "Открыть окно обновления", + "A new version is available: %s" : "Доступна новая версия: %s", + "Checked on %s" : "Проверено %s", + "Updated channel" : "Обновленный канал" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/sk_SK.js b/apps/updatenotification/l10n/sk_SK.js index e684a120e579c..c7f27ee1cde84 100644 --- a/apps/updatenotification/l10n/sk_SK.js +++ b/apps/updatenotification/l10n/sk_SK.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} je dostupná. Získajte viac informácií o postupe aktualizácie.", - "Updater" : "Aktualizátor" + "Updater" : "Aktualizátor", + "A new version is available: %s" : "Je dostupná nová verzia: %s" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/updatenotification/l10n/sk_SK.json b/apps/updatenotification/l10n/sk_SK.json index 1edd18e5ed2f1..d6be61caf6e0c 100644 --- a/apps/updatenotification/l10n/sk_SK.json +++ b/apps/updatenotification/l10n/sk_SK.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} je dostupná. Získajte viac informácií o postupe aktualizácie.", - "Updater" : "Aktualizátor" + "Updater" : "Aktualizátor", + "A new version is available: %s" : "Je dostupná nová verzia: %s" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/sl.js b/apps/updatenotification/l10n/sl.js index f9cb689911f90..f93df09b272fb 100644 --- a/apps/updatenotification/l10n/sl.js +++ b/apps/updatenotification/l10n/sl.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "Na voljo je nova različica {version}. Na voljo je več podrobnosti o nadgradnji.", "Updater" : "Posodabljalnik", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Zaradi varnostnih razlogov uporablja vgrajeni posodabljalnik ownCloud dodatna poverita. Za dostop do strani posodabljalnika kliknite na gumb za nadaljevanje.", - "Open updater" : "Odpri posodabljalnik" + "Open updater" : "Odpri posodabljalnik", + "A new version is available: %s" : "Na voljo je nova različica: %s", + "Checked on %s" : "Zadnjič preverjeno %s", + "Updated channel" : "Posodobljen kanal" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/updatenotification/l10n/sl.json b/apps/updatenotification/l10n/sl.json index ae379cdb4050d..55b5c55f0d20e 100644 --- a/apps/updatenotification/l10n/sl.json +++ b/apps/updatenotification/l10n/sl.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "Na voljo je nova različica {version}. Na voljo je več podrobnosti o nadgradnji.", "Updater" : "Posodabljalnik", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Zaradi varnostnih razlogov uporablja vgrajeni posodabljalnik ownCloud dodatna poverita. Za dostop do strani posodabljalnika kliknite na gumb za nadaljevanje.", - "Open updater" : "Odpri posodabljalnik" + "Open updater" : "Odpri posodabljalnik", + "A new version is available: %s" : "Na voljo je nova različica: %s", + "Checked on %s" : "Zadnjič preverjeno %s", + "Updated channel" : "Posodobljen kanal" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/sq.js b/apps/updatenotification/l10n/sq.js index afebd62ee2aac..e68399a92c314 100644 --- a/apps/updatenotification/l10n/sq.js +++ b/apps/updatenotification/l10n/sq.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "Është gati {version}. Merrni më tepër informacion se si ta përditësoni.", "Updater" : "Përditësues", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Përditësuesi i brendshëm i ownCloud-it, për arsye sigurie po përdor kredenciale shtesë. Që të vizitoni faqen e përditësuesit, ju lutemi, klikoni butonin vijues.", - "Open updater" : "Hapni përditësuesin" + "Open updater" : "Hapni përditësuesin", + "A new version is available: %s" : "Ka gati një version të ri: %s", + "Checked on %s" : "Kontrolluar më %s", + "Updated channel" : "Kanali u përditësua" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/sq.json b/apps/updatenotification/l10n/sq.json index 2f943a69347fc..132623ed19ea7 100644 --- a/apps/updatenotification/l10n/sq.json +++ b/apps/updatenotification/l10n/sq.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "Është gati {version}. Merrni më tepër informacion se si ta përditësoni.", "Updater" : "Përditësues", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Përditësuesi i brendshëm i ownCloud-it, për arsye sigurie po përdor kredenciale shtesë. Që të vizitoni faqen e përditësuesit, ju lutemi, klikoni butonin vijues.", - "Open updater" : "Hapni përditësuesin" + "Open updater" : "Hapni përditësuesin", + "A new version is available: %s" : "Ka gati një version të ri: %s", + "Checked on %s" : "Kontrolluar më %s", + "Updated channel" : "Kanali u përditësua" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/sr.js b/apps/updatenotification/l10n/sr.js index 974698fbc2cee..a535bdf0ec185 100644 --- a/apps/updatenotification/l10n/sr.js +++ b/apps/updatenotification/l10n/sr.js @@ -2,6 +2,10 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "Верзија {version} је доступна. Сазнајте како да ажурирате.", - "Updater" : "Ажурирање" + "Updater" : "Ажурирање", + "A new version is available: %s" : "Доступна је нова верзија: %s", + "Checked on %s" : "Проверено %s", + "Open updater" : "Отвори ажурирање", + "Updated channel" : "Канал ажуриран" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/updatenotification/l10n/sr.json b/apps/updatenotification/l10n/sr.json index 41e5da4eb1a70..4e31fb27cdb68 100644 --- a/apps/updatenotification/l10n/sr.json +++ b/apps/updatenotification/l10n/sr.json @@ -1,5 +1,9 @@ { "translations": { "{version} is available. Get more information on how to update." : "Верзија {version} је доступна. Сазнајте како да ажурирате.", - "Updater" : "Ажурирање" + "Updater" : "Ажурирање", + "A new version is available: %s" : "Доступна је нова верзија: %s", + "Checked on %s" : "Проверено %s", + "Open updater" : "Отвори ажурирање", + "Updated channel" : "Канал ажуриран" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/sv.js b/apps/updatenotification/l10n/sv.js index 274c6f8eae526..0dcb83d787e64 100644 --- a/apps/updatenotification/l10n/sv.js +++ b/apps/updatenotification/l10n/sv.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "{version} är tillgänglig. Få mer information om hur du uppdaterar.", "Updater" : "Uppdaterare", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Utav säkerhetsskäl använder den inbyggda ownCloud-uppdateraren ytterligare inlogginingsiformation. För att öppna sidan för uppdatering vänligen tryck på följande knapp.", - "Open updater" : "Öppna uppdateraren" + "Open updater" : "Öppna uppdateraren", + "A new version is available: %s" : "En ny version är tillgänglig: %s", + "Checked on %s" : "Senast kontrollerad %s", + "Updated channel" : "Uppdaterad kanal" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/sv.json b/apps/updatenotification/l10n/sv.json index d36a8376d4372..f02a48f32c681 100644 --- a/apps/updatenotification/l10n/sv.json +++ b/apps/updatenotification/l10n/sv.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "{version} är tillgänglig. Få mer information om hur du uppdaterar.", "Updater" : "Uppdaterare", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "Utav säkerhetsskäl använder den inbyggda ownCloud-uppdateraren ytterligare inlogginingsiformation. För att öppna sidan för uppdatering vänligen tryck på följande knapp.", - "Open updater" : "Öppna uppdateraren" + "Open updater" : "Öppna uppdateraren", + "A new version is available: %s" : "En ny version är tillgänglig: %s", + "Checked on %s" : "Senast kontrollerad %s", + "Updated channel" : "Uppdaterad kanal" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/tr.js b/apps/updatenotification/l10n/tr.js index 3abe821a5eafa..907fe8cc0166d 100644 --- a/apps/updatenotification/l10n/tr.js +++ b/apps/updatenotification/l10n/tr.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "Sürüm {version} hazır. Nasıl güncelleyeceğinizle ilgili daha fazla bilgi alın.", - "Updater" : "Güncelleyici" + "Updater" : "Güncelleyici", + "A new version is available: %s" : "Yeni bir sürüm mevcut: %s" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/updatenotification/l10n/tr.json b/apps/updatenotification/l10n/tr.json index dba8d5533ddf4..d4f0c2f1955ad 100644 --- a/apps/updatenotification/l10n/tr.json +++ b/apps/updatenotification/l10n/tr.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "Sürüm {version} hazır. Nasıl güncelleyeceğinizle ilgili daha fazla bilgi alın.", - "Updater" : "Güncelleyici" + "Updater" : "Güncelleyici", + "A new version is available: %s" : "Yeni bir sürüm mevcut: %s" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/uk.js b/apps/updatenotification/l10n/uk.js index 0a594d6d47c0d..840cd62b10d66 100644 --- a/apps/updatenotification/l10n/uk.js +++ b/apps/updatenotification/l10n/uk.js @@ -2,6 +2,7 @@ OC.L10N.register( "updatenotification", { "{version} is available. Get more information on how to update." : "{version} доступна. Отримати більш детальну інформацію про те, як оновити.", - "Updater" : "Оновлення" + "Updater" : "Оновлення", + "A new version is available: %s" : "Доступна нова версія: %s" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/updatenotification/l10n/uk.json b/apps/updatenotification/l10n/uk.json index c5a3f6ce9ffaf..03aac67de93fa 100644 --- a/apps/updatenotification/l10n/uk.json +++ b/apps/updatenotification/l10n/uk.json @@ -1,5 +1,6 @@ { "translations": { "{version} is available. Get more information on how to update." : "{version} доступна. Отримати більш детальну інформацію про те, як оновити.", - "Updater" : "Оновлення" + "Updater" : "Оновлення", + "A new version is available: %s" : "Доступна нова версія: %s" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/updatenotification/l10n/zh_CN.js b/apps/updatenotification/l10n/zh_CN.js index 7a5dc8b9f71b9..b26d098a17bb3 100644 --- a/apps/updatenotification/l10n/zh_CN.js +++ b/apps/updatenotification/l10n/zh_CN.js @@ -4,6 +4,9 @@ OC.L10N.register( "{version} is available. Get more information on how to update." : "新版本 {version} 已可以使用。获取更多升级相关信息。", "Updater" : "更新管理器", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "出于安全考虑,内置ownCloud更新管理器需使用附加的凭证。要访问的页面更新,请点击下面的按钮。", - "Open updater" : "打开更新管理器" + "Open updater" : "打开更新管理器", + "A new version is available: %s" : "有可用的新版本: %s", + "Checked on %s" : "检查于 %s", + "Updated channel" : "更新通道" }, "nplurals=1; plural=0;"); diff --git a/apps/updatenotification/l10n/zh_CN.json b/apps/updatenotification/l10n/zh_CN.json index e7d091d28ceb0..f94f397ccd0ad 100644 --- a/apps/updatenotification/l10n/zh_CN.json +++ b/apps/updatenotification/l10n/zh_CN.json @@ -2,6 +2,9 @@ "{version} is available. Get more information on how to update." : "新版本 {version} 已可以使用。获取更多升级相关信息。", "Updater" : "更新管理器", "For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button." : "出于安全考虑,内置ownCloud更新管理器需使用附加的凭证。要访问的页面更新,请点击下面的按钮。", - "Open updater" : "打开更新管理器" + "Open updater" : "打开更新管理器", + "A new version is available: %s" : "有可用的新版本: %s", + "Checked on %s" : "检查于 %s", + "Updated channel" : "更新通道" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ar.js b/apps/user_ldap/l10n/ar.js index b940b69a1a79b..c424dca0f26bf 100644 --- a/apps/user_ldap/l10n/ar.js +++ b/apps/user_ldap/l10n/ar.js @@ -30,6 +30,7 @@ OC.L10N.register( "Back" : "رجوع", "Continue" : "المتابعة", "Advanced" : "تعديلات متقدمه", - "Email Field" : "خانة البريد الإلكتروني" + "Email Field" : "خانة البريد الإلكتروني", + "{nthServer}. Server" : "الخادم {nthServer}." }, "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); diff --git a/apps/user_ldap/l10n/ar.json b/apps/user_ldap/l10n/ar.json index 20ba16d1481ba..df14aa0633e7e 100644 --- a/apps/user_ldap/l10n/ar.json +++ b/apps/user_ldap/l10n/ar.json @@ -28,6 +28,7 @@ "Back" : "رجوع", "Continue" : "المتابعة", "Advanced" : "تعديلات متقدمه", - "Email Field" : "خانة البريد الإلكتروني" + "Email Field" : "خانة البريد الإلكتروني", + "{nthServer}. Server" : "الخادم {nthServer}." },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ast.js b/apps/user_ldap/l10n/ast.js index 5bdc52e47aed1..705c368b76569 100644 --- a/apps/user_ldap/l10n/ast.js +++ b/apps/user_ldap/l10n/ast.js @@ -102,6 +102,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Asignación del Nome d'usuariu LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los nomes d'usuariu usense p'atroxar (meta) datos. En cuenta d'identificar y reconocer usuarios, cada usuariu de LDAP tendrá'l so nome d'usuariu internu polo que rique un mapéu dende'l so nome d'usuariu al usuariu de LDAP. El nome d'usuariu creáu mapeáse al UUID del usuariu de LDAP. Amás cacheamos tamién la DN p'amenorgar la intecractividá de LDAP, pero ensin usala pa la identificación. Si la DN camuda, atoparanse los cambios. L'usu internu del nome d'usuariu ye perdayures. ", "Clear Username-LDAP User Mapping" : "Llimpiar l'asignación de los Nomes d'usuariu de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Llimpiar l'asignación de los Nomes de grupu de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Llimpiar l'asignación de los Nomes de grupu de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuariu veceru col que va facese l'asociación, p.ex. uid=axente,dc=exemplu,dc=com. P'accesu anónimu, dexa DN y contraseña baleros.", + "{nthServer}. Server" : "{nthServer}. Sirvidor" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/ast.json b/apps/user_ldap/l10n/ast.json index 934065b7a4b98..e2c4a6322e43b 100644 --- a/apps/user_ldap/l10n/ast.json +++ b/apps/user_ldap/l10n/ast.json @@ -100,6 +100,8 @@ "Username-LDAP User Mapping" : "Asignación del Nome d'usuariu LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los nomes d'usuariu usense p'atroxar (meta) datos. En cuenta d'identificar y reconocer usuarios, cada usuariu de LDAP tendrá'l so nome d'usuariu internu polo que rique un mapéu dende'l so nome d'usuariu al usuariu de LDAP. El nome d'usuariu creáu mapeáse al UUID del usuariu de LDAP. Amás cacheamos tamién la DN p'amenorgar la intecractividá de LDAP, pero ensin usala pa la identificación. Si la DN camuda, atoparanse los cambios. L'usu internu del nome d'usuariu ye perdayures. ", "Clear Username-LDAP User Mapping" : "Llimpiar l'asignación de los Nomes d'usuariu de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Llimpiar l'asignación de los Nomes de grupu de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Llimpiar l'asignación de los Nomes de grupu de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuariu veceru col que va facese l'asociación, p.ex. uid=axente,dc=exemplu,dc=com. P'accesu anónimu, dexa DN y contraseña baleros.", + "{nthServer}. Server" : "{nthServer}. Sirvidor" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/bg_BG.js b/apps/user_ldap/l10n/bg_BG.js index 3ba3f25bd16ce..c189abfe63dd8 100644 --- a/apps/user_ldap/l10n/bg_BG.js +++ b/apps/user_ldap/l10n/bg_BG.js @@ -103,6 +103,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "UUID Атрибут за Групите:", "Username-LDAP User Mapping" : "Username-LDAP User Mapping", "Clear Username-LDAP User Mapping" : "Изчисти Username-LDAP User Mapping", - "Clear Groupname-LDAP Group Mapping" : "Изчисти Groupname-LDAP Group Mapping" + "Clear Groupname-LDAP Group Mapping" : "Изчисти Groupname-LDAP Group Mapping", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN на потребителят, с който ще стане свързването, пр. uid=agent,dc=example,dc=com. За анонимен достъп, остави DN и Парола празни.", + "{nthServer}. Server" : "{nthServer}. Сървър" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/bg_BG.json b/apps/user_ldap/l10n/bg_BG.json index 1360e0cec1e1a..a46a5c5829c59 100644 --- a/apps/user_ldap/l10n/bg_BG.json +++ b/apps/user_ldap/l10n/bg_BG.json @@ -101,6 +101,8 @@ "UUID Attribute for Groups:" : "UUID Атрибут за Групите:", "Username-LDAP User Mapping" : "Username-LDAP User Mapping", "Clear Username-LDAP User Mapping" : "Изчисти Username-LDAP User Mapping", - "Clear Groupname-LDAP Group Mapping" : "Изчисти Groupname-LDAP Group Mapping" + "Clear Groupname-LDAP Group Mapping" : "Изчисти Groupname-LDAP Group Mapping", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN на потребителят, с който ще стане свързването, пр. uid=agent,dc=example,dc=com. За анонимен достъп, остави DN и Парола празни.", + "{nthServer}. Server" : "{nthServer}. Сървър" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/bn_BD.js b/apps/user_ldap/l10n/bn_BD.js index e7d34692f7485..a3a91987290b2 100644 --- a/apps/user_ldap/l10n/bn_BD.js +++ b/apps/user_ldap/l10n/bn_BD.js @@ -76,6 +76,8 @@ OC.L10N.register( "Quota Default" : "পূর্বনির্ধারিত কোটা", "in bytes" : "বাইটে", "Email Field" : "ইমেইল ক্ষেত্র", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।" + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. পরিচয় গোপন রেখে অধিগমনের জন্য DN এবং কূটশব্দটি ফাঁকা রাখুন।", + "{nthServer}. Server" : "{nthServer}. সার্ভার" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/bn_BD.json b/apps/user_ldap/l10n/bn_BD.json index e9b7cd0146ae6..39d583eb447e7 100644 --- a/apps/user_ldap/l10n/bn_BD.json +++ b/apps/user_ldap/l10n/bn_BD.json @@ -74,6 +74,8 @@ "Quota Default" : "পূর্বনির্ধারিত কোটা", "in bytes" : "বাইটে", "Email Field" : "ইমেইল ক্ষেত্র", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।" + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. পরিচয় গোপন রেখে অধিগমনের জন্য DN এবং কূটশব্দটি ফাঁকা রাখুন।", + "{nthServer}. Server" : "{nthServer}. সার্ভার" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ca.js b/apps/user_ldap/l10n/ca.js index ea01350ec2f3d..dafd31e0441f1 100644 --- a/apps/user_ldap/l10n/ca.js +++ b/apps/user_ldap/l10n/ca.js @@ -96,6 +96,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "Atribut UUID per Grups:", "Username-LDAP User Mapping" : "Mapatge d'usuari Nom d'usuari-LDAP", "Clear Username-LDAP User Mapping" : "Elimina el mapatge d'usuari Nom d'usuari-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Elimina el mapatge de grup Nom de grup-LDAP" + "Clear Groupname-LDAP Group Mapping" : "Elimina el mapatge de grup Nom de grup-LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "La DN de l'usuari client amb la que s'haurà de fer, per exemple uid=agent,dc=exemple,dc=com. Per un accés anònim, deixeu la DN i la contrasenya en blanc.", + "{nthServer}. Server" : "{nthServer}. Servidor" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/ca.json b/apps/user_ldap/l10n/ca.json index 62c842123e690..8327836486608 100644 --- a/apps/user_ldap/l10n/ca.json +++ b/apps/user_ldap/l10n/ca.json @@ -94,6 +94,8 @@ "UUID Attribute for Groups:" : "Atribut UUID per Grups:", "Username-LDAP User Mapping" : "Mapatge d'usuari Nom d'usuari-LDAP", "Clear Username-LDAP User Mapping" : "Elimina el mapatge d'usuari Nom d'usuari-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Elimina el mapatge de grup Nom de grup-LDAP" + "Clear Groupname-LDAP Group Mapping" : "Elimina el mapatge de grup Nom de grup-LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "La DN de l'usuari client amb la que s'haurà de fer, per exemple uid=agent,dc=exemple,dc=com. Per un accés anònim, deixeu la DN i la contrasenya en blanc.", + "{nthServer}. Server" : "{nthServer}. Servidor" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/cs_CZ.js b/apps/user_ldap/l10n/cs_CZ.js index 0ed1359482182..1b31691354b1e 100644 --- a/apps/user_ldap/l10n/cs_CZ.js +++ b/apps/user_ldap/l10n/cs_CZ.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Mapování uživatelských jmen z LDAPu", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Uživatelská jména jsou používána pro uchovávání a přiřazování (meta)dat. Pro správnou identifikaci a rozpoznání uživatelů bude mít každý LDAP uživatel interní uživatelské jméno. To vyžaduje mapování uživatelských jmen na uživatele LDAP. Vytvořené uživatelské jméno je mapováno na UUID uživatele v LDAP. DN informace je navíc udržována v paměti pro snížení interakce s LDAP, ale není používána pro identifikaci. Pokud se DN změní, bude to správně rozpoznáno. Interní uživatelské jméno se používá celé. Vyčištění mapování zanechá zbytky všude. Vyčištění navíc není specifické pro každou konfiguraci, bude mít vliv na všechny LDAP konfigurace! Nikdy nečistěte mapování v produkčním prostředí, ale pouze v testovací nebo experimentální fázi.", "Clear Username-LDAP User Mapping" : "Zrušit mapování uživatelských jmen LDAPu", - "Clear Groupname-LDAP Group Mapping" : "Zrušit mapování názvů skupin LDAPu" + "Clear Groupname-LDAP Group Mapping" : "Zrušit mapování názvů skupin LDAPu", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymní bind není povolen. Zadejte prosím User DN a Heslo.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/user_ldap/l10n/cs_CZ.json b/apps/user_ldap/l10n/cs_CZ.json index 912e7c49b0f3d..5598e25920983 100644 --- a/apps/user_ldap/l10n/cs_CZ.json +++ b/apps/user_ldap/l10n/cs_CZ.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Mapování uživatelských jmen z LDAPu", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Uživatelská jména jsou používána pro uchovávání a přiřazování (meta)dat. Pro správnou identifikaci a rozpoznání uživatelů bude mít každý LDAP uživatel interní uživatelské jméno. To vyžaduje mapování uživatelských jmen na uživatele LDAP. Vytvořené uživatelské jméno je mapováno na UUID uživatele v LDAP. DN informace je navíc udržována v paměti pro snížení interakce s LDAP, ale není používána pro identifikaci. Pokud se DN změní, bude to správně rozpoznáno. Interní uživatelské jméno se používá celé. Vyčištění mapování zanechá zbytky všude. Vyčištění navíc není specifické pro každou konfiguraci, bude mít vliv na všechny LDAP konfigurace! Nikdy nečistěte mapování v produkčním prostředí, ale pouze v testovací nebo experimentální fázi.", "Clear Username-LDAP User Mapping" : "Zrušit mapování uživatelských jmen LDAPu", - "Clear Groupname-LDAP Group Mapping" : "Zrušit mapování názvů skupin LDAPu" + "Clear Groupname-LDAP Group Mapping" : "Zrušit mapování názvů skupin LDAPu", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymní bind není povolen. Zadejte prosím User DN a Heslo.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/da.js b/apps/user_ldap/l10n/da.js index c01d3efa0187d..e98c22ebfb381 100644 --- a/apps/user_ldap/l10n/da.js +++ b/apps/user_ldap/l10n/da.js @@ -152,6 +152,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Kortlægning mellem brugernavn og LDAP-bruger", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Brugernavne bruges til at lagre og tildele (meta)data. For at kunne identificere og genkende brugere præcist, så vil hver LDAP-bruger have et internt brugernavn. Det oprettede brugernavn kortlægges til UUID'et for LDAP-brugeren. I tillæg mellemlagres DN'et for at mindske LDAP-interaktioner, men det benyttes ikke til identifikation. Hvis DN'et ændres, så vil ændringerne blive registreret. Det interne brugernavn anvendes overalt. Hvis kortlægningerne ryddes, så vil der være rester overalt. Rydning af kortlægningerne er ikke konfigurationssensitivt - det påvirker alle LDAP-konfigurationer! Ryd aldrig kortlægningerne i et produktionsmiljø, kun i et teststadie eller eksperimentelt stadie.", "Clear Username-LDAP User Mapping" : "Ryd kortlægning mellem brugernavn og LDAP-bruger", - "Clear Groupname-LDAP Group Mapping" : "Ryd kortlægning mellem gruppenavn og LDAP-gruppe" + "Clear Groupname-LDAP Group Mapping" : "Ryd kortlægning mellem gruppenavn og LDAP-gruppe", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonyme bindinger tillades ikke. Angiv venligst et User DN og adgangskode.", + "{nthServer}. Server" : "{nthServer}. server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/da.json b/apps/user_ldap/l10n/da.json index db61541ef73b1..5b1f3b76df55c 100644 --- a/apps/user_ldap/l10n/da.json +++ b/apps/user_ldap/l10n/da.json @@ -150,6 +150,8 @@ "Username-LDAP User Mapping" : "Kortlægning mellem brugernavn og LDAP-bruger", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Brugernavne bruges til at lagre og tildele (meta)data. For at kunne identificere og genkende brugere præcist, så vil hver LDAP-bruger have et internt brugernavn. Det oprettede brugernavn kortlægges til UUID'et for LDAP-brugeren. I tillæg mellemlagres DN'et for at mindske LDAP-interaktioner, men det benyttes ikke til identifikation. Hvis DN'et ændres, så vil ændringerne blive registreret. Det interne brugernavn anvendes overalt. Hvis kortlægningerne ryddes, så vil der være rester overalt. Rydning af kortlægningerne er ikke konfigurationssensitivt - det påvirker alle LDAP-konfigurationer! Ryd aldrig kortlægningerne i et produktionsmiljø, kun i et teststadie eller eksperimentelt stadie.", "Clear Username-LDAP User Mapping" : "Ryd kortlægning mellem brugernavn og LDAP-bruger", - "Clear Groupname-LDAP Group Mapping" : "Ryd kortlægning mellem gruppenavn og LDAP-gruppe" + "Clear Groupname-LDAP Group Mapping" : "Ryd kortlægning mellem gruppenavn og LDAP-gruppe", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonyme bindinger tillades ikke. Angiv venligst et User DN og adgangskode.", + "{nthServer}. Server" : "{nthServer}. server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/de.js b/apps/user_ldap/l10n/de.js index 431f99a87e72b..49558202c97bb 100644 --- a/apps/user_ldap/l10n/de.js +++ b/apps/user_ldap/l10n/de.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Die Benutzernamen werden genutzt, um (Meta)Daten zuzuordnen und zu speichern. Um Benutzer eindeutig und präzise zu identifizieren, hat jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung (mappen) von Benutzernamen zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzernamens zugeordnet. Zusätzlich wird der DN zwischengespeichert, um die Interaktion mit dem LDAP zu minimieren, was aber nicht der Identifikation dient. Ändert sich der DN, werden die Änderungen durch gefunden. Der interne Benutzername, wird in überall verwendet. Werden die Zuordnungen gelöscht, bleiben überall Reste zurück. Die Löschung der Zuordnungen kann nicht in der Konfiguration vorgenommen werden, beeinflusst aber die LDAP-Konfiguration! Löschen Sie niemals die Zuordnungen in einer produktiven Umgebung. Lösche die Zuordnungen nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung löschen", - "Clear Groupname-LDAP Group Mapping" : "LDAP-Gruppennamenzuordnung löschen" + "Clear Groupname-LDAP Group Mapping" : "LDAP-Gruppennamenzuordnung löschen", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymes binden ist nicht erlaubt. Bitte eine Nutzer-DN und ein Passwort angeben.", + "{nthServer}. Server" : "{nthServer}. - Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/de.json b/apps/user_ldap/l10n/de.json index 3e03d9b729413..0326d79c5d021 100644 --- a/apps/user_ldap/l10n/de.json +++ b/apps/user_ldap/l10n/de.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Die Benutzernamen werden genutzt, um (Meta)Daten zuzuordnen und zu speichern. Um Benutzer eindeutig und präzise zu identifizieren, hat jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung (mappen) von Benutzernamen zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzernamens zugeordnet. Zusätzlich wird der DN zwischengespeichert, um die Interaktion mit dem LDAP zu minimieren, was aber nicht der Identifikation dient. Ändert sich der DN, werden die Änderungen durch gefunden. Der interne Benutzername, wird in überall verwendet. Werden die Zuordnungen gelöscht, bleiben überall Reste zurück. Die Löschung der Zuordnungen kann nicht in der Konfiguration vorgenommen werden, beeinflusst aber die LDAP-Konfiguration! Löschen Sie niemals die Zuordnungen in einer produktiven Umgebung. Lösche die Zuordnungen nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung löschen", - "Clear Groupname-LDAP Group Mapping" : "LDAP-Gruppennamenzuordnung löschen" + "Clear Groupname-LDAP Group Mapping" : "LDAP-Gruppennamenzuordnung löschen", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymes binden ist nicht erlaubt. Bitte eine Nutzer-DN und ein Passwort angeben.", + "{nthServer}. Server" : "{nthServer}. - Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/de_DE.js b/apps/user_ldap/l10n/de_DE.js index b72b41ea29344..7e0275c063152 100644 --- a/apps/user_ldap/l10n/de_DE.js +++ b/apps/user_ldap/l10n/de_DE.js @@ -153,6 +153,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Benutzernamen dienen zum Speichern und Zuweisen von (Meta-)Daten. Um Benutzer eindeutig zu identifizieren und zu erkennen, besitzt jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung des jeweiligen Benutzernamens zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzers zugeordnet. Darüber hinaus wird der DN auch zwischengespeichert, um die Interaktion über LDAP zu reduzieren, was aber nicht zur Identifikation dient. Ändert sich der DN, werden die Änderungen gefunden. Der interne Benutzername wird durchgängig verwendet. Ein Löschen der Zuordnungen führt zum systemweiten Verbleib von Restdaten. Es bleibt nicht auf eine einzelne Konfiguration beschränkt, sondern wirkt sich auf alle LDAP-Konfigurationen aus! Löschen Sie die Zuordnungen nie innerhalb einer Produktivumgebung, sondern nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" : "Lösche LDAP-Benutzernamenzuordnung", - "Clear Groupname-LDAP Group Mapping" : "Lösche LDAP-Gruppennamenzuordnung" + "Clear Groupname-LDAP Group Mapping" : "Lösche LDAP-Gruppennamenzuordnung", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymous Bind ist nicht erlaubt. Bitte geben Sie eine User-DN und ein Passwort angeben.", + "{nthServer}. Server" : "{nthServer}. - Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/de_DE.json b/apps/user_ldap/l10n/de_DE.json index 58ccaa400c9e5..64f127e83e5f0 100644 --- a/apps/user_ldap/l10n/de_DE.json +++ b/apps/user_ldap/l10n/de_DE.json @@ -151,6 +151,8 @@ "Username-LDAP User Mapping" : "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Benutzernamen dienen zum Speichern und Zuweisen von (Meta-)Daten. Um Benutzer eindeutig zu identifizieren und zu erkennen, besitzt jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung des jeweiligen Benutzernamens zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzers zugeordnet. Darüber hinaus wird der DN auch zwischengespeichert, um die Interaktion über LDAP zu reduzieren, was aber nicht zur Identifikation dient. Ändert sich der DN, werden die Änderungen gefunden. Der interne Benutzername wird durchgängig verwendet. Ein Löschen der Zuordnungen führt zum systemweiten Verbleib von Restdaten. Es bleibt nicht auf eine einzelne Konfiguration beschränkt, sondern wirkt sich auf alle LDAP-Konfigurationen aus! Löschen Sie die Zuordnungen nie innerhalb einer Produktivumgebung, sondern nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" : "Lösche LDAP-Benutzernamenzuordnung", - "Clear Groupname-LDAP Group Mapping" : "Lösche LDAP-Gruppennamenzuordnung" + "Clear Groupname-LDAP Group Mapping" : "Lösche LDAP-Gruppennamenzuordnung", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymous Bind ist nicht erlaubt. Bitte geben Sie eine User-DN und ein Passwort angeben.", + "{nthServer}. Server" : "{nthServer}. - Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/el.js b/apps/user_ldap/l10n/el.js index 7ea629e673dcb..a5645f10f8ff4 100644 --- a/apps/user_ldap/l10n/el.js +++ b/apps/user_ldap/l10n/el.js @@ -153,6 +153,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Αντιστοίχιση Χρηστών Όνομα Χρήστη-LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Τα ονόματα χρηστών χρησιμοποιούνται για την αποθήκευση και τον προσδιορισμό των (μετα) δεδομένων. Προκειμένου να προσδιοριστούν με ακρίβεια και να αναγνωριστούν οι χρήστες, κάθε χρήστης LDAP θα έχει ένα εσωτερικό όνομα. Αυτό απαιτεί μια αντιστοίχιση του ονόματος χρήστη με το χρήστη LDAP. Το όνομα χρήστη που δημιουργήθηκαν αντιστοιχίζεται στην UUID του χρήστη LDAP. Επιπροσθέτως, το DN αποθηκεύεται προσωρινά (cache) ώστε να μειωθεί η αλληλεπίδραση LDAP, αλλά δεν χρησιμοποιείται για την ταυτοποίηση. Αν το DN αλλάξει, οι αλλαγές θα εντοπιστούν. Το εσωτερικό όνομα χρήστη χρησιμοποιείται παντού. Η εκκαθάριση των αντιστοιχίσεων θα αφήσει υπολείμματα παντού. Η εκκαθάριση των αντιστοιχίσεων δεν επηρεάζεται από τη διαμόρφωση, επηρεάζει όλες τις διαμορφώσεις LDAP! Μην διαγράψετε ποτέ τις αντιστοιχίσεις σε ένα λειτουργικό περιβάλλον παρά μόνο σε δοκιμές ή σε πειραματικό στάδιο.", "Clear Username-LDAP User Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Χρήστη LDAP-Χρήστη", - "Clear Groupname-LDAP Group Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Ομάδας-LDAP Ομάδας" + "Clear Groupname-LDAP Group Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Ομάδας-LDAP Ομάδας", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Η ανώνυμη δέσμευση δεν επιτρέπεται. Παρακαλούμε δώστε ένα DN χρήστη και Κωδικό Πρόσβασης.", + "{nthServer}. Server" : "{nthServer}. Διακομιστής" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/el.json b/apps/user_ldap/l10n/el.json index 338b0b8bad9d2..dd7baa9c8d53e 100644 --- a/apps/user_ldap/l10n/el.json +++ b/apps/user_ldap/l10n/el.json @@ -151,6 +151,8 @@ "Username-LDAP User Mapping" : "Αντιστοίχιση Χρηστών Όνομα Χρήστη-LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Τα ονόματα χρηστών χρησιμοποιούνται για την αποθήκευση και τον προσδιορισμό των (μετα) δεδομένων. Προκειμένου να προσδιοριστούν με ακρίβεια και να αναγνωριστούν οι χρήστες, κάθε χρήστης LDAP θα έχει ένα εσωτερικό όνομα. Αυτό απαιτεί μια αντιστοίχιση του ονόματος χρήστη με το χρήστη LDAP. Το όνομα χρήστη που δημιουργήθηκαν αντιστοιχίζεται στην UUID του χρήστη LDAP. Επιπροσθέτως, το DN αποθηκεύεται προσωρινά (cache) ώστε να μειωθεί η αλληλεπίδραση LDAP, αλλά δεν χρησιμοποιείται για την ταυτοποίηση. Αν το DN αλλάξει, οι αλλαγές θα εντοπιστούν. Το εσωτερικό όνομα χρήστη χρησιμοποιείται παντού. Η εκκαθάριση των αντιστοιχίσεων θα αφήσει υπολείμματα παντού. Η εκκαθάριση των αντιστοιχίσεων δεν επηρεάζεται από τη διαμόρφωση, επηρεάζει όλες τις διαμορφώσεις LDAP! Μην διαγράψετε ποτέ τις αντιστοιχίσεις σε ένα λειτουργικό περιβάλλον παρά μόνο σε δοκιμές ή σε πειραματικό στάδιο.", "Clear Username-LDAP User Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Χρήστη LDAP-Χρήστη", - "Clear Groupname-LDAP Group Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Ομάδας-LDAP Ομάδας" + "Clear Groupname-LDAP Group Mapping" : "Διαγραφή αντιστοίχησης Ονόματος Ομάδας-LDAP Ομάδας", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Η ανώνυμη δέσμευση δεν επιτρέπεται. Παρακαλούμε δώστε ένα DN χρήστη και Κωδικό Πρόσβασης.", + "{nthServer}. Server" : "{nthServer}. Διακομιστής" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/en_GB.js b/apps/user_ldap/l10n/en_GB.js index 702de9a8de629..ef5350a274a88 100644 --- a/apps/user_ldap/l10n/en_GB.js +++ b/apps/user_ldap/l10n/en_GB.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Username-LDAP User Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Usernames are used to store and assign (meta) data. In order to precisely identify and recognise users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.", "Clear Username-LDAP User Mapping" : "Clear Username-LDAP User Mapping", - "Clear Groupname-LDAP Group Mapping" : "Clear Groupname-LDAP Group Mapping" + "Clear Groupname-LDAP Group Mapping" : "Clear Groupname-LDAP Group Mapping", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymous bind is not allowed. Please provide a User DN and Password.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/en_GB.json b/apps/user_ldap/l10n/en_GB.json index 13ea62e76d876..2c1bd96c1d2b8 100644 --- a/apps/user_ldap/l10n/en_GB.json +++ b/apps/user_ldap/l10n/en_GB.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Username-LDAP User Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Usernames are used to store and assign (meta) data. In order to precisely identify and recognise users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.", "Clear Username-LDAP User Mapping" : "Clear Username-LDAP User Mapping", - "Clear Groupname-LDAP Group Mapping" : "Clear Groupname-LDAP Group Mapping" + "Clear Groupname-LDAP Group Mapping" : "Clear Groupname-LDAP Group Mapping", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymous bind is not allowed. Please provide a User DN and Password.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/eo.js b/apps/user_ldap/l10n/eo.js index 25c880dbdc5c7..525687e237a9f 100644 --- a/apps/user_ldap/l10n/eo.js +++ b/apps/user_ldap/l10n/eo.js @@ -58,6 +58,7 @@ OC.L10N.register( "Internal Username" : "Ena uzantonomo", "Internal Username Attribute:" : "Atribuo de ena uzantonomo:", "UUID Attribute for Users:" : "UUID-atribuo por uzantoj:", - "UUID Attribute for Groups:" : "UUID-atribuo por grupoj:" + "UUID Attribute for Groups:" : "UUID-atribuo por grupoj:", + "{nthServer}. Server" : "{nthServer}. Servilo" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/eo.json b/apps/user_ldap/l10n/eo.json index 37cdc4e251942..2a04ca06f6187 100644 --- a/apps/user_ldap/l10n/eo.json +++ b/apps/user_ldap/l10n/eo.json @@ -56,6 +56,7 @@ "Internal Username" : "Ena uzantonomo", "Internal Username Attribute:" : "Atribuo de ena uzantonomo:", "UUID Attribute for Users:" : "UUID-atribuo por uzantoj:", - "UUID Attribute for Groups:" : "UUID-atribuo por grupoj:" + "UUID Attribute for Groups:" : "UUID-atribuo por grupoj:", + "{nthServer}. Server" : "{nthServer}. Servilo" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/es.js b/apps/user_ldap/l10n/es.js index 8ba9fbefee5e4..dd897b9adf200 100644 --- a/apps/user_ldap/l10n/es.js +++ b/apps/user_ldap/l10n/es.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los usuarios son usados para almacenar y asignar (meta) datos. Con el fin de identificar de forma precisa y reconocer usuarios, cada usuario de LDAP tendrá un nombre de usuario interno. Esto requiere un mapeo entre el nombre de usuario y el usuario del LDAP. El nombre de usuario creado es mapeado respecto al UUID del usuario en el LDAP. De forma adicional, el DN es cacheado para reducir la interacción entre el LDAP, pero no es usado para identificar. Si el DN cambia, los cambios serán aplicados. El nombre de usuario interno es usado por encima de todo. Limpiar los mapeos dejará restos por todas partes, no es sensible a configuración, ¡afecta a todas las configuraciones del LDAP! Nunca limpies los mapeos en un entorno de producción, únicamente en una fase de desarrollo o experimental.", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Un vínculo anónimo no está permitido. Por favor, suministre un DN de usuario y contraseña. ", + "{nthServer}. Server" : "{nthServer}. servidor" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/es.json b/apps/user_ldap/l10n/es.json index 8cf67f71bb079..47428c595cb27 100644 --- a/apps/user_ldap/l10n/es.json +++ b/apps/user_ldap/l10n/es.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los usuarios son usados para almacenar y asignar (meta) datos. Con el fin de identificar de forma precisa y reconocer usuarios, cada usuario de LDAP tendrá un nombre de usuario interno. Esto requiere un mapeo entre el nombre de usuario y el usuario del LDAP. El nombre de usuario creado es mapeado respecto al UUID del usuario en el LDAP. De forma adicional, el DN es cacheado para reducir la interacción entre el LDAP, pero no es usado para identificar. Si el DN cambia, los cambios serán aplicados. El nombre de usuario interno es usado por encima de todo. Limpiar los mapeos dejará restos por todas partes, no es sensible a configuración, ¡afecta a todas las configuraciones del LDAP! Nunca limpies los mapeos en un entorno de producción, únicamente en una fase de desarrollo o experimental.", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Un vínculo anónimo no está permitido. Por favor, suministre un DN de usuario y contraseña. ", + "{nthServer}. Server" : "{nthServer}. servidor" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/es_AR.js b/apps/user_ldap/l10n/es_AR.js index e56510323ee31..ab48b560dda9f 100644 --- a/apps/user_ldap/l10n/es_AR.js +++ b/apps/user_ldap/l10n/es_AR.js @@ -90,6 +90,7 @@ OC.L10N.register( "UUID Attribute for Groups:" : "Atributo UUID para grupos:", "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, dejá DN y contraseña vacíos." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/es_AR.json b/apps/user_ldap/l10n/es_AR.json index f62e717dede73..75c94561530c0 100644 --- a/apps/user_ldap/l10n/es_AR.json +++ b/apps/user_ldap/l10n/es_AR.json @@ -88,6 +88,7 @@ "UUID Attribute for Groups:" : "Atributo UUID para grupos:", "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, dejá DN y contraseña vacíos." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/es_MX.js b/apps/user_ldap/l10n/es_MX.js index 0b7eb8085b9fd..f653f7da196f7 100644 --- a/apps/user_ldap/l10n/es_MX.js +++ b/apps/user_ldap/l10n/es_MX.js @@ -85,6 +85,7 @@ OC.L10N.register( "UUID Attribute for Groups:" : "Atributo UUID para Grupos:", "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, deje DN y contraseña vacíos." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/es_MX.json b/apps/user_ldap/l10n/es_MX.json index d458644b1379f..a308eafdbc240 100644 --- a/apps/user_ldap/l10n/es_MX.json +++ b/apps/user_ldap/l10n/es_MX.json @@ -83,6 +83,7 @@ "UUID Attribute for Groups:" : "Atributo UUID para Grupos:", "Username-LDAP User Mapping" : "Asignación del Nombre de usuario de un usuario LDAP", "Clear Username-LDAP User Mapping" : "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", - "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" + "Clear Groupname-LDAP Group Mapping" : "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, deje DN y contraseña vacíos." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/et_EE.js b/apps/user_ldap/l10n/et_EE.js index b583bbca3d9a9..33707cc563048 100644 --- a/apps/user_ldap/l10n/et_EE.js +++ b/apps/user_ldap/l10n/et_EE.js @@ -127,6 +127,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "UUID atribuut gruppidele:", "Username-LDAP User Mapping" : "LDAP-Kasutajatunnus Kasutaja Vastendus", "Clear Username-LDAP User Mapping" : "Puhasta LDAP-Kasutajatunnus Kasutaja Vastendus", - "Clear Groupname-LDAP Group Mapping" : "Puhasta LDAP-Grupinimi Grupp Vastendus" + "Clear Groupname-LDAP Group Mapping" : "Puhasta LDAP-Grupinimi Grupp Vastendus", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/et_EE.json b/apps/user_ldap/l10n/et_EE.json index d0ebc171777c4..6ba4e50d02c80 100644 --- a/apps/user_ldap/l10n/et_EE.json +++ b/apps/user_ldap/l10n/et_EE.json @@ -125,6 +125,8 @@ "UUID Attribute for Groups:" : "UUID atribuut gruppidele:", "Username-LDAP User Mapping" : "LDAP-Kasutajatunnus Kasutaja Vastendus", "Clear Username-LDAP User Mapping" : "Puhasta LDAP-Kasutajatunnus Kasutaja Vastendus", - "Clear Groupname-LDAP Group Mapping" : "Puhasta LDAP-Grupinimi Grupp Vastendus" + "Clear Groupname-LDAP Group Mapping" : "Puhasta LDAP-Grupinimi Grupp Vastendus", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/eu.js b/apps/user_ldap/l10n/eu.js index 410b626745c75..da73874ae0e4c 100644 --- a/apps/user_ldap/l10n/eu.js +++ b/apps/user_ldap/l10n/eu.js @@ -125,6 +125,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "Taldeentzako UUID atributuak:", "Username-LDAP User Mapping" : "LDAP-erabiltzaile-izena erabiltzailearen mapeatzea", "Clear Username-LDAP User Mapping" : "Garbitu LDAP-erabiltzaile-izenaren erabiltzaile mapaketa", - "Clear Groupname-LDAP Group Mapping" : "Garbitu LDAP-talde-izenaren talde mapaketa" + "Clear Groupname-LDAP Group Mapping" : "Garbitu LDAP-talde-izenaren talde mapaketa", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Lotura egingo den bezero erabiltzailearen DNa, adb. uid=agent,dc=example,dc=com. Sarrera anonimoak gaitzeko utzi DN eta Pasahitza hutsik.", + "{nthServer}. Server" : "{nthServer}. Zerbitzaria" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/eu.json b/apps/user_ldap/l10n/eu.json index f0599392c5037..66e7ee6e039d9 100644 --- a/apps/user_ldap/l10n/eu.json +++ b/apps/user_ldap/l10n/eu.json @@ -123,6 +123,8 @@ "UUID Attribute for Groups:" : "Taldeentzako UUID atributuak:", "Username-LDAP User Mapping" : "LDAP-erabiltzaile-izena erabiltzailearen mapeatzea", "Clear Username-LDAP User Mapping" : "Garbitu LDAP-erabiltzaile-izenaren erabiltzaile mapaketa", - "Clear Groupname-LDAP Group Mapping" : "Garbitu LDAP-talde-izenaren talde mapaketa" + "Clear Groupname-LDAP Group Mapping" : "Garbitu LDAP-talde-izenaren talde mapaketa", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Lotura egingo den bezero erabiltzailearen DNa, adb. uid=agent,dc=example,dc=com. Sarrera anonimoak gaitzeko utzi DN eta Pasahitza hutsik.", + "{nthServer}. Server" : "{nthServer}. Zerbitzaria" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/fa.js b/apps/user_ldap/l10n/fa.js index 082f297f98f30..7ee0c03d08aee 100644 --- a/apps/user_ldap/l10n/fa.js +++ b/apps/user_ldap/l10n/fa.js @@ -85,6 +85,7 @@ OC.L10N.register( "UUID Attribute for Users:" : "UUID ویژگی‌ برای کاربران:", "Username-LDAP User Mapping" : "نام کاربری - نگاشت کاربر LDAP ", "Clear Username-LDAP User Mapping" : "پاک کردن نام کاربری- LDAP نگاشت کاربر ", - "Clear Groupname-LDAP Group Mapping" : "پاک کردن نام گروه -LDAP گروه نقشه برداری" + "Clear Groupname-LDAP Group Mapping" : "پاک کردن نام گروه -LDAP گروه نقشه برداری", + "{nthServer}. Server" : "سرور {nthServer}." }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/fa.json b/apps/user_ldap/l10n/fa.json index 7a8b3e8212e66..54e027dbe4536 100644 --- a/apps/user_ldap/l10n/fa.json +++ b/apps/user_ldap/l10n/fa.json @@ -83,6 +83,7 @@ "UUID Attribute for Users:" : "UUID ویژگی‌ برای کاربران:", "Username-LDAP User Mapping" : "نام کاربری - نگاشت کاربر LDAP ", "Clear Username-LDAP User Mapping" : "پاک کردن نام کاربری- LDAP نگاشت کاربر ", - "Clear Groupname-LDAP Group Mapping" : "پاک کردن نام گروه -LDAP گروه نقشه برداری" + "Clear Groupname-LDAP Group Mapping" : "پاک کردن نام گروه -LDAP گروه نقشه برداری", + "{nthServer}. Server" : "سرور {nthServer}." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/fi_FI.js b/apps/user_ldap/l10n/fi_FI.js index e10a9f1755938..942573815c74d 100644 --- a/apps/user_ldap/l10n/fi_FI.js +++ b/apps/user_ldap/l10n/fi_FI.js @@ -76,6 +76,7 @@ OC.L10N.register( "Email Field" : "Sähköpostikenttä", "User Home Folder Naming Rule" : "Käyttäjän kotihakemiston nimeämissääntö", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Jätä tyhjäksi käyttäjänimi (oletusasetus). Muutoin anna LDAP/AD-atribuutti.", - "Internal Username" : "Sisäinen käyttäjänimi" + "Internal Username" : "Sisäinen käyttäjänimi", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Asiakasohjelman DN, jolla yhdistäminen tehdään, ts. uid=agent,dc=example,dc=com. Mahdollistaaksesi anonyymin yhteyden, jätä DN ja salasana tyhjäksi." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/fi_FI.json b/apps/user_ldap/l10n/fi_FI.json index 8abef4f8585c6..a463855cdca76 100644 --- a/apps/user_ldap/l10n/fi_FI.json +++ b/apps/user_ldap/l10n/fi_FI.json @@ -74,6 +74,7 @@ "Email Field" : "Sähköpostikenttä", "User Home Folder Naming Rule" : "Käyttäjän kotihakemiston nimeämissääntö", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Jätä tyhjäksi käyttäjänimi (oletusasetus). Muutoin anna LDAP/AD-atribuutti.", - "Internal Username" : "Sisäinen käyttäjänimi" + "Internal Username" : "Sisäinen käyttäjänimi", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Asiakasohjelman DN, jolla yhdistäminen tehdään, ts. uid=agent,dc=example,dc=com. Mahdollistaaksesi anonyymin yhteyden, jätä DN ja salasana tyhjäksi." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/fil.js b/apps/user_ldap/l10n/fil.js index 95c97db2f9c58..9fd9195021d03 100644 --- a/apps/user_ldap/l10n/fil.js +++ b/apps/user_ldap/l10n/fil.js @@ -2,6 +2,7 @@ OC.L10N.register( "user_ldap", { "_%s group found_::_%s groups found_" : ["",""], - "_%s user found_::_%s users found_" : ["",""] + "_%s user found_::_%s users found_" : ["",""], + "Password" : "Password" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/user_ldap/l10n/fil.json b/apps/user_ldap/l10n/fil.json index 8e0cd6f6783da..a1036ef8388e8 100644 --- a/apps/user_ldap/l10n/fil.json +++ b/apps/user_ldap/l10n/fil.json @@ -1,5 +1,6 @@ { "translations": { "_%s group found_::_%s groups found_" : ["",""], - "_%s user found_::_%s users found_" : ["",""] + "_%s user found_::_%s users found_" : ["",""], + "Password" : "Password" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/fr.js b/apps/user_ldap/l10n/fr.js index 9d934181190b4..6b82632a10488 100644 --- a/apps/user_ldap/l10n/fr.js +++ b/apps/user_ldap/l10n/fr.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Association Nom d'utilisateur-Utilisateur LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Les noms d'utilisateurs sont utilisés pour le stockage et l'assignation de (meta) données. Pour identifier et reconnaître précisément les utilisateurs, chaque utilisateur LDAP aura un nom interne spécifique. Cela requiert l'association d'un nom d'utilisateur ownCloud à un nom d'utilisateur LDAP. Le nom d'utilisateur créé est associé à l'attribut UUID de l'utilisateur LDAP. Par ailleurs, le DN est mémorisé en cache pour limiter les interactions LDAP mais il n'est pas utilisé pour l'identification. Si le DN est modifié, ces modifications seront retrouvées. Seul le nom interne à ownCloud est utilisé au sein du produit. Supprimer les associations créera des orphelins et l'action affectera toutes les configurations LDAP. NE JAMAIS SUPPRIMER LES ASSOCIATIONS EN ENVIRONNEMENT DE PRODUCTION, mais uniquement sur des environnements de tests et d'expérimentations.", "Clear Username-LDAP User Mapping" : "Supprimer l'association utilisateur interne-utilisateur LDAP", - "Clear Groupname-LDAP Group Mapping" : "Supprimer l'association nom de groupe-groupe LDAP" + "Clear Groupname-LDAP Group Mapping" : "Supprimer l'association nom de groupe-groupe LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Le lien anonyme n'est pas autorisé. Merci de fournir le DN d'un utilisateur et un mot de passe.", + "{nthServer}. Server" : "{nthServer}. Serveur" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/user_ldap/l10n/fr.json b/apps/user_ldap/l10n/fr.json index 64df1a3db67d3..3d44c0950b947 100644 --- a/apps/user_ldap/l10n/fr.json +++ b/apps/user_ldap/l10n/fr.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Association Nom d'utilisateur-Utilisateur LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Les noms d'utilisateurs sont utilisés pour le stockage et l'assignation de (meta) données. Pour identifier et reconnaître précisément les utilisateurs, chaque utilisateur LDAP aura un nom interne spécifique. Cela requiert l'association d'un nom d'utilisateur ownCloud à un nom d'utilisateur LDAP. Le nom d'utilisateur créé est associé à l'attribut UUID de l'utilisateur LDAP. Par ailleurs, le DN est mémorisé en cache pour limiter les interactions LDAP mais il n'est pas utilisé pour l'identification. Si le DN est modifié, ces modifications seront retrouvées. Seul le nom interne à ownCloud est utilisé au sein du produit. Supprimer les associations créera des orphelins et l'action affectera toutes les configurations LDAP. NE JAMAIS SUPPRIMER LES ASSOCIATIONS EN ENVIRONNEMENT DE PRODUCTION, mais uniquement sur des environnements de tests et d'expérimentations.", "Clear Username-LDAP User Mapping" : "Supprimer l'association utilisateur interne-utilisateur LDAP", - "Clear Groupname-LDAP Group Mapping" : "Supprimer l'association nom de groupe-groupe LDAP" + "Clear Groupname-LDAP Group Mapping" : "Supprimer l'association nom de groupe-groupe LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Le lien anonyme n'est pas autorisé. Merci de fournir le DN d'un utilisateur et un mot de passe.", + "{nthServer}. Server" : "{nthServer}. Serveur" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/gl.js b/apps/user_ldap/l10n/gl.js index ea7aa9674fea3..635512abb186f 100644 --- a/apps/user_ldap/l10n/gl.js +++ b/apps/user_ldap/l10n/gl.js @@ -152,6 +152,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Asignación do usuario ao «nome de usuario LDAP»", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Os nomes de usuario empréganse para almacenar e asignar (meta) datos. Coa fin de identificar con precisión e recoñecer aos usuarios, cada usuario LDAP terá un nome de usuario interno. Isto require unha asignación do nome de usuario a usuario LDAP. O nome de usuario creado asignase ao UUID do usuario LDAP. Ademais o DN almacenase na caché, para así reducir a interacción do LDAP, mais non se utiliza para a identificación. Se o DN cambia, os cambios poden ser atopados. O nome interno do usuario utilizase para todo. A limpeza das asignacións deixará rastros en todas partes. A limpeza das asignacións non é sensíbel á configuración, afecta a todas as configuracións de LDAP! Non limpar nunca as asignacións nun entorno de produción. Limpar as asignacións só en fases de proba ou experimentais.", "Clear Username-LDAP User Mapping" : "Limpar a asignación do usuario ao «nome de usuario LDAP»", - "Clear Groupname-LDAP Group Mapping" : "Limpar a asignación do grupo ao «nome de grupo LDAP»" + "Clear Groupname-LDAP Group Mapping" : "Limpar a asignación do grupo ao «nome de grupo LDAP»", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "O vínculo anónimo non está permitido. Forneza un DN de usuario e un contrasinal.", + "{nthServer}. Server" : "{nthServer}. Servidor" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/gl.json b/apps/user_ldap/l10n/gl.json index 53c96103238ef..5ef8851993ea9 100644 --- a/apps/user_ldap/l10n/gl.json +++ b/apps/user_ldap/l10n/gl.json @@ -150,6 +150,8 @@ "Username-LDAP User Mapping" : "Asignación do usuario ao «nome de usuario LDAP»", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Os nomes de usuario empréganse para almacenar e asignar (meta) datos. Coa fin de identificar con precisión e recoñecer aos usuarios, cada usuario LDAP terá un nome de usuario interno. Isto require unha asignación do nome de usuario a usuario LDAP. O nome de usuario creado asignase ao UUID do usuario LDAP. Ademais o DN almacenase na caché, para así reducir a interacción do LDAP, mais non se utiliza para a identificación. Se o DN cambia, os cambios poden ser atopados. O nome interno do usuario utilizase para todo. A limpeza das asignacións deixará rastros en todas partes. A limpeza das asignacións non é sensíbel á configuración, afecta a todas as configuracións de LDAP! Non limpar nunca as asignacións nun entorno de produción. Limpar as asignacións só en fases de proba ou experimentais.", "Clear Username-LDAP User Mapping" : "Limpar a asignación do usuario ao «nome de usuario LDAP»", - "Clear Groupname-LDAP Group Mapping" : "Limpar a asignación do grupo ao «nome de grupo LDAP»" + "Clear Groupname-LDAP Group Mapping" : "Limpar a asignación do grupo ao «nome de grupo LDAP»", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "O vínculo anónimo non está permitido. Forneza un DN de usuario e un contrasinal.", + "{nthServer}. Server" : "{nthServer}. Servidor" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/he.js b/apps/user_ldap/l10n/he.js index d54be2c546b35..111c9850d8a76 100644 --- a/apps/user_ldap/l10n/he.js +++ b/apps/user_ldap/l10n/he.js @@ -140,6 +140,14 @@ OC.L10N.register( "UUID Attribute for Groups:" : "מאפייני UUID לקבוצות:", "Username-LDAP User Mapping" : "מיפוי שם משתמש LDAP:", "Clear Username-LDAP User Mapping" : "ניקוי מיפוי שם משתמש LDAP:", - "Clear Groupname-LDAP Group Mapping" : "ניקוי מיפוי שם משתמש קבוצה LDAP:" + "Clear Groupname-LDAP Group Mapping" : "ניקוי מיפוי שם משתמש קבוצה LDAP:", + "Group-Member association" : "שיוך חברי-קבוצה", + "Nested Groups" : "קבוצות משנה", + "One Group Base DN per line" : "קבוצת DN בסיסית לשורה", + "One User Base DN per line" : "משתמש DN בסיסי אחד לשורה", + "Paging chunksize" : "Paging chunksize", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "קישור אננונימי אינו מותר. יש לספק שם משתמש DN וסיסמא.", + "{nthServer}. Server" : "{nthServer}. שרת", + "User Home Folder Naming Rule" : "כלל קביעת שם תיקיית בית למשתמש" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/he.json b/apps/user_ldap/l10n/he.json index eb69f01669871..0086621dfd943 100644 --- a/apps/user_ldap/l10n/he.json +++ b/apps/user_ldap/l10n/he.json @@ -138,6 +138,14 @@ "UUID Attribute for Groups:" : "מאפייני UUID לקבוצות:", "Username-LDAP User Mapping" : "מיפוי שם משתמש LDAP:", "Clear Username-LDAP User Mapping" : "ניקוי מיפוי שם משתמש LDAP:", - "Clear Groupname-LDAP Group Mapping" : "ניקוי מיפוי שם משתמש קבוצה LDAP:" + "Clear Groupname-LDAP Group Mapping" : "ניקוי מיפוי שם משתמש קבוצה LDAP:", + "Group-Member association" : "שיוך חברי-קבוצה", + "Nested Groups" : "קבוצות משנה", + "One Group Base DN per line" : "קבוצת DN בסיסית לשורה", + "One User Base DN per line" : "משתמש DN בסיסי אחד לשורה", + "Paging chunksize" : "Paging chunksize", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "קישור אננונימי אינו מותר. יש לספק שם משתמש DN וסיסמא.", + "{nthServer}. Server" : "{nthServer}. שרת", + "User Home Folder Naming Rule" : "כלל קביעת שם תיקיית בית למשתמש" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/hu_HU.js b/apps/user_ldap/l10n/hu_HU.js index 36fdcad380665..50085b900281c 100644 --- a/apps/user_ldap/l10n/hu_HU.js +++ b/apps/user_ldap/l10n/hu_HU.js @@ -98,6 +98,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "A csoportok UUID attribútuma:", "Username-LDAP User Mapping" : "Felhasználó - LDAP felhasználó hozzárendelés", "Clear Username-LDAP User Mapping" : "A felhasználó - LDAP felhasználó hozzárendelés törlése", - "Clear Groupname-LDAP Group Mapping" : "A csoport - LDAP csoport hozzárendelés törlése" + "Clear Groupname-LDAP Group Mapping" : "A csoport - LDAP csoport hozzárendelés törlése", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Annak a felhasználónak a DN-je, akinek a nevében bejelentkezve kapcsolódunk a kiszolgálóhoz, pl. uid=agent,dc=example,dc=com. Bejelentkezés nélküli eléréshez ne töltse ki a DN és Jelszó mezőket!", + "{nthServer}. Server" : "{nthServer}. Kiszolgáló" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/hu_HU.json b/apps/user_ldap/l10n/hu_HU.json index 14f16217ee34e..8575aa197dc0c 100644 --- a/apps/user_ldap/l10n/hu_HU.json +++ b/apps/user_ldap/l10n/hu_HU.json @@ -96,6 +96,8 @@ "UUID Attribute for Groups:" : "A csoportok UUID attribútuma:", "Username-LDAP User Mapping" : "Felhasználó - LDAP felhasználó hozzárendelés", "Clear Username-LDAP User Mapping" : "A felhasználó - LDAP felhasználó hozzárendelés törlése", - "Clear Groupname-LDAP Group Mapping" : "A csoport - LDAP csoport hozzárendelés törlése" + "Clear Groupname-LDAP Group Mapping" : "A csoport - LDAP csoport hozzárendelés törlése", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Annak a felhasználónak a DN-je, akinek a nevében bejelentkezve kapcsolódunk a kiszolgálóhoz, pl. uid=agent,dc=example,dc=com. Bejelentkezés nélküli eléréshez ne töltse ki a DN és Jelszó mezőket!", + "{nthServer}. Server" : "{nthServer}. Kiszolgáló" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/hy.js b/apps/user_ldap/l10n/hy.js index 469515bc42e88..d8f7ed1fc6005 100644 --- a/apps/user_ldap/l10n/hy.js +++ b/apps/user_ldap/l10n/hy.js @@ -2,6 +2,8 @@ OC.L10N.register( "user_ldap", { "Groups" : "Խմբեր", - "Password" : "Գաղտնաբառ" + "Password" : "Գաղտնաբառ", + "Continue" : "Շարունակել", + "Help" : "Օգնություն" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/hy.json b/apps/user_ldap/l10n/hy.json index 8b8bf5bd500bd..d5dbc0b95054f 100644 --- a/apps/user_ldap/l10n/hy.json +++ b/apps/user_ldap/l10n/hy.json @@ -1,5 +1,7 @@ { "translations": { "Groups" : "Խմբեր", - "Password" : "Գաղտնաբառ" + "Password" : "Գաղտնաբառ", + "Continue" : "Շարունակել", + "Help" : "Օգնություն" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/id.js b/apps/user_ldap/l10n/id.js index 282b1a8181d7f..e4c03dd0611a3 100644 --- a/apps/user_ldap/l10n/id.js +++ b/apps/user_ldap/l10n/id.js @@ -152,6 +152,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Pemetaan Pengguna LDAP-Nama pengguna", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nama pengguna digunakan untuk menyimpan dan menetapkan (meta) data. Dalam rangka untuk mengidentifikasi dan mengenali pengguna secara tepat, setiap pengguna LDAP akan memiliki nama pengguna internal. Hal ini memerlukan sebuah pemetaan dari nama pengguna ke pengguna LDAP. Nama pengguna yang dibuat akan dipetakan pada UUID pengguna LDAP. Selain itu, DN akan di cache untuk mengurangi interaksi LDAP, tetapi tidak digunakan untuk identifikasi. Jika DN berubah, perubahan akan ditemukan. Nama pengguna internal digunakan secara menyeluruh. Membersihkan pemetaan akan mempengaruhi semua konfigurasi LDAP! JANGAN PERNAH MENGHAPUS PEMETAAN PADA LINGKUNGAN PRODUKSI, hanya gunakan dalam tahap uji coba dan pengujian.", "Clear Username-LDAP User Mapping" : "Bersihkan Pemetaan Pengguna LDAP-Nama pengguna", - "Clear Groupname-LDAP Group Mapping" : "Bersihkan Pemetaan Grup LDAP-Nama grup" + "Clear Groupname-LDAP Group Mapping" : "Bersihkan Pemetaan Grup LDAP-Nama grup", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Bind anonim tidak diizinkan. Mohon berikan sebuah User DN dan Password.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/id.json b/apps/user_ldap/l10n/id.json index 556c5fd6970fa..69b3233667256 100644 --- a/apps/user_ldap/l10n/id.json +++ b/apps/user_ldap/l10n/id.json @@ -150,6 +150,8 @@ "Username-LDAP User Mapping" : "Pemetaan Pengguna LDAP-Nama pengguna", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nama pengguna digunakan untuk menyimpan dan menetapkan (meta) data. Dalam rangka untuk mengidentifikasi dan mengenali pengguna secara tepat, setiap pengguna LDAP akan memiliki nama pengguna internal. Hal ini memerlukan sebuah pemetaan dari nama pengguna ke pengguna LDAP. Nama pengguna yang dibuat akan dipetakan pada UUID pengguna LDAP. Selain itu, DN akan di cache untuk mengurangi interaksi LDAP, tetapi tidak digunakan untuk identifikasi. Jika DN berubah, perubahan akan ditemukan. Nama pengguna internal digunakan secara menyeluruh. Membersihkan pemetaan akan mempengaruhi semua konfigurasi LDAP! JANGAN PERNAH MENGHAPUS PEMETAAN PADA LINGKUNGAN PRODUKSI, hanya gunakan dalam tahap uji coba dan pengujian.", "Clear Username-LDAP User Mapping" : "Bersihkan Pemetaan Pengguna LDAP-Nama pengguna", - "Clear Groupname-LDAP Group Mapping" : "Bersihkan Pemetaan Grup LDAP-Nama grup" + "Clear Groupname-LDAP Group Mapping" : "Bersihkan Pemetaan Grup LDAP-Nama grup", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Bind anonim tidak diizinkan. Mohon berikan sebuah User DN dan Password.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/is.js b/apps/user_ldap/l10n/is.js index cec369b3f8724..c817ed9eb145d 100644 --- a/apps/user_ldap/l10n/is.js +++ b/apps/user_ldap/l10n/is.js @@ -9,6 +9,7 @@ OC.L10N.register( "Port" : "Gátt", "Password" : "Lykilorð", "Continue" : "Halda áfram", - "Advanced" : "Ítarlegt" + "Advanced" : "Ítarlegt", + "Server" : "Þjónn" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/user_ldap/l10n/is.json b/apps/user_ldap/l10n/is.json index 9d58f777e4225..8cf49500e9d96 100644 --- a/apps/user_ldap/l10n/is.json +++ b/apps/user_ldap/l10n/is.json @@ -7,6 +7,7 @@ "Port" : "Gátt", "Password" : "Lykilorð", "Continue" : "Halda áfram", - "Advanced" : "Ítarlegt" + "Advanced" : "Ítarlegt", + "Server" : "Þjónn" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/it.js b/apps/user_ldap/l10n/it.js index 7bc6de0d622a9..a69893c9ca272 100644 --- a/apps/user_ldap/l10n/it.js +++ b/apps/user_ldap/l10n/it.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Associazione Nome utente-Utente LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "I nomi utente sono utilizzati per archiviare e assegnare i (meta) dati. Per identificare con precisione e riconoscere gli utenti, ogni utente LDAP avrà un nome utente interno. Ciò richiede un'associazione tra il nome utente e l'utente LDAP. In aggiunta, il DN viene mantenuto in cache per ridurre l'interazione con LDAP, ma non è utilizzato per l'identificazione. Se il DN cambia, le modifiche saranno rilevate. Il nome utente interno è utilizzato dappertutto. La cancellazione delle associazioni lascerà tracce residue ovunque e interesserà tutta la configurazione LDAP. Non cancellare mai le associazioni in un ambiente di produzione, ma solo in una fase sperimentale o di test.", "Clear Username-LDAP User Mapping" : "Cancella associazione Nome utente-Utente LDAP", - "Clear Groupname-LDAP Group Mapping" : "Cancella associazione Nome gruppo-Gruppo LDAP" + "Clear Groupname-LDAP Group Mapping" : "Cancella associazione Nome gruppo-Gruppo LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "L'associazione anonima non è consentita. Fornisci un DN utente e la password.", + "{nthServer}. Server" : "{nthServer}. server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/it.json b/apps/user_ldap/l10n/it.json index 412508e64a7d4..9c65906ddf5f6 100644 --- a/apps/user_ldap/l10n/it.json +++ b/apps/user_ldap/l10n/it.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Associazione Nome utente-Utente LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "I nomi utente sono utilizzati per archiviare e assegnare i (meta) dati. Per identificare con precisione e riconoscere gli utenti, ogni utente LDAP avrà un nome utente interno. Ciò richiede un'associazione tra il nome utente e l'utente LDAP. In aggiunta, il DN viene mantenuto in cache per ridurre l'interazione con LDAP, ma non è utilizzato per l'identificazione. Se il DN cambia, le modifiche saranno rilevate. Il nome utente interno è utilizzato dappertutto. La cancellazione delle associazioni lascerà tracce residue ovunque e interesserà tutta la configurazione LDAP. Non cancellare mai le associazioni in un ambiente di produzione, ma solo in una fase sperimentale o di test.", "Clear Username-LDAP User Mapping" : "Cancella associazione Nome utente-Utente LDAP", - "Clear Groupname-LDAP Group Mapping" : "Cancella associazione Nome gruppo-Gruppo LDAP" + "Clear Groupname-LDAP Group Mapping" : "Cancella associazione Nome gruppo-Gruppo LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "L'associazione anonima non è consentita. Fornisci un DN utente e la password.", + "{nthServer}. Server" : "{nthServer}. server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ja.js b/apps/user_ldap/l10n/ja.js index 90d0ddb56b0b0..6e01a6e7da5b3 100644 --- a/apps/user_ldap/l10n/ja.js +++ b/apps/user_ldap/l10n/ja.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "ユーザー名とLDAPユーザのマッピング", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ユーザー名は(メタ)データの保存と割り当てに使用されます。ユーザーを正確に識別して認識するために、個々のLDAPユーザは内部ユーザ名を持っています。これは、ユーザー名からLDAPユーザーへのマッピングが必要であることを意味しています。この生成されたユーザ名は、LDAPユーザのUUIDにマッピングされます。加えて、DNがLDAPとのインタラクションを削減するためにキャッシュされますが、識別には利用されません。DNが変わった場合は、変更が検出されます。内部ユーザ名は全体に亘って利用されます。マッピングをクリアすると、いたるところに使われないままの物が残るでしょう。マッピングのクリアは設定に敏感ではありませんが、すべてのLDAPの設定に影響を与えます!本番の環境では決してマッピングをクリアしないでください。テストもしくは実験の段階でのみマッピングのクリアを行なってください。", "Clear Username-LDAP User Mapping" : "ユーザー名とLDAPユーザーのマッピングをクリアする", - "Clear Groupname-LDAP Group Mapping" : "グループ名とLDAPグループのマッピングをクリアする" + "Clear Groupname-LDAP Group Mapping" : "グループ名とLDAPグループのマッピングをクリアする", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "匿名接続が許可されていません。ユーザーDNとパスワードを入力してください。", + "{nthServer}. Server" : "{nthServer}. サーバー" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/ja.json b/apps/user_ldap/l10n/ja.json index 3ce515079ae5d..9e811722b144a 100644 --- a/apps/user_ldap/l10n/ja.json +++ b/apps/user_ldap/l10n/ja.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "ユーザー名とLDAPユーザのマッピング", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ユーザー名は(メタ)データの保存と割り当てに使用されます。ユーザーを正確に識別して認識するために、個々のLDAPユーザは内部ユーザ名を持っています。これは、ユーザー名からLDAPユーザーへのマッピングが必要であることを意味しています。この生成されたユーザ名は、LDAPユーザのUUIDにマッピングされます。加えて、DNがLDAPとのインタラクションを削減するためにキャッシュされますが、識別には利用されません。DNが変わった場合は、変更が検出されます。内部ユーザ名は全体に亘って利用されます。マッピングをクリアすると、いたるところに使われないままの物が残るでしょう。マッピングのクリアは設定に敏感ではありませんが、すべてのLDAPの設定に影響を与えます!本番の環境では決してマッピングをクリアしないでください。テストもしくは実験の段階でのみマッピングのクリアを行なってください。", "Clear Username-LDAP User Mapping" : "ユーザー名とLDAPユーザーのマッピングをクリアする", - "Clear Groupname-LDAP Group Mapping" : "グループ名とLDAPグループのマッピングをクリアする" + "Clear Groupname-LDAP Group Mapping" : "グループ名とLDAPグループのマッピングをクリアする", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "匿名接続が許可されていません。ユーザーDNとパスワードを入力してください。", + "{nthServer}. Server" : "{nthServer}. サーバー" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ka_GE.js b/apps/user_ldap/l10n/ka_GE.js index 0fdf25fea6fdd..5891250be0f0d 100644 --- a/apps/user_ldap/l10n/ka_GE.js +++ b/apps/user_ldap/l10n/ka_GE.js @@ -50,6 +50,7 @@ OC.L10N.register( "in bytes" : "ბაიტებში", "Email Field" : "იმეილის ველი", "User Home Folder Naming Rule" : "მომხმარებლის Home დირექტორიის სახელების დარქმევის წესი", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი." + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "მომხმარებლის DN რომელთანაც უნდა მოხდეს დაკავშირება მოხდება შემდეგნაირად მაგ: uid=agent,dc=example,dc=com. ხოლო ანონიმური დაშვებისთვის, დატოვეთ DN–ის და პაროლის ველები ცარიელი." }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/ka_GE.json b/apps/user_ldap/l10n/ka_GE.json index 7ddaaef5bda75..13f4449358ffb 100644 --- a/apps/user_ldap/l10n/ka_GE.json +++ b/apps/user_ldap/l10n/ka_GE.json @@ -48,6 +48,7 @@ "in bytes" : "ბაიტებში", "Email Field" : "იმეილის ველი", "User Home Folder Naming Rule" : "მომხმარებლის Home დირექტორიის სახელების დარქმევის წესი", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი." + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "მომხმარებლის DN რომელთანაც უნდა მოხდეს დაკავშირება მოხდება შემდეგნაირად მაგ: uid=agent,dc=example,dc=com. ხოლო ანონიმური დაშვებისთვის, დატოვეთ DN–ის და პაროლის ველები ცარიელი." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ko.js b/apps/user_ldap/l10n/ko.js index 0ed95377acb00..df9231ed020c4 100644 --- a/apps/user_ldap/l10n/ko.js +++ b/apps/user_ldap/l10n/ko.js @@ -153,6 +153,10 @@ OC.L10N.register( "Username-LDAP User Mapping" : "사용자 이름-LDAP 사용자 매핑", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "사용자 이름은 (메타)데이터를 저장하고 할당하는 데 사용됩니다. 사용자를 정확히 식별하기 위해서 모든 LDAP 사용자는 내부 사용자 이름을 갖고 있습니다. 이 정보에 접근하려면 사용자 이름과 LDAP 사용자 사이의 연결을 알아야 합니다. 생성된 사용자 이름은 LDAP 사용자의 UUID에 연결됩니다. LDAP에 연결하는 횟수를 줄이기 위하여 DN을 캐시에 저장하지만, 식별에는 사용하지 않습니다. DN이 변경되었을 때 변경 사항이 적용됩니다. 내부 사용자 이름은 항상 사용됩니다. 매핑을 비우면 과거 매핑의 흔적이 남습니다. 매핑을 비우는 것은 설정에 관계 없이 적용되므로 모든 LDAP 설정에 영향을 줍니다! 테스트 및 실험 단계에서만 매핑을 비우고, 상용 환경에서는 매핑을 비우지 마십시오.", "Clear Username-LDAP User Mapping" : "사용자 이름-LDAP 사용자 매핑 비우기", - "Clear Groupname-LDAP Group Mapping" : "그룹 이름-LDAP 그룹 매핑 비우기" + "Clear Groupname-LDAP Group Mapping" : "그룹 이름-LDAP 그룹 매핑 비우기", + "2nd User Display Name Field" : "보조 사용자 표시 이름 필드", + "Dynamic Group Member URL" : "동적 그룹 구성원 URL", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "익명 연결은 허용되지 않습니다. 사용자 DN과 암호를 입력하십시오.", + "{nthServer}. Server" : "{nthServer}. 서버" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/ko.json b/apps/user_ldap/l10n/ko.json index 3fccad0577c6d..69f01f284c6ed 100644 --- a/apps/user_ldap/l10n/ko.json +++ b/apps/user_ldap/l10n/ko.json @@ -151,6 +151,10 @@ "Username-LDAP User Mapping" : "사용자 이름-LDAP 사용자 매핑", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "사용자 이름은 (메타)데이터를 저장하고 할당하는 데 사용됩니다. 사용자를 정확히 식별하기 위해서 모든 LDAP 사용자는 내부 사용자 이름을 갖고 있습니다. 이 정보에 접근하려면 사용자 이름과 LDAP 사용자 사이의 연결을 알아야 합니다. 생성된 사용자 이름은 LDAP 사용자의 UUID에 연결됩니다. LDAP에 연결하는 횟수를 줄이기 위하여 DN을 캐시에 저장하지만, 식별에는 사용하지 않습니다. DN이 변경되었을 때 변경 사항이 적용됩니다. 내부 사용자 이름은 항상 사용됩니다. 매핑을 비우면 과거 매핑의 흔적이 남습니다. 매핑을 비우는 것은 설정에 관계 없이 적용되므로 모든 LDAP 설정에 영향을 줍니다! 테스트 및 실험 단계에서만 매핑을 비우고, 상용 환경에서는 매핑을 비우지 마십시오.", "Clear Username-LDAP User Mapping" : "사용자 이름-LDAP 사용자 매핑 비우기", - "Clear Groupname-LDAP Group Mapping" : "그룹 이름-LDAP 그룹 매핑 비우기" + "Clear Groupname-LDAP Group Mapping" : "그룹 이름-LDAP 그룹 매핑 비우기", + "2nd User Display Name Field" : "보조 사용자 표시 이름 필드", + "Dynamic Group Member URL" : "동적 그룹 구성원 URL", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "익명 연결은 허용되지 않습니다. 사용자 DN과 암호를 입력하십시오.", + "{nthServer}. Server" : "{nthServer}. 서버" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/lv.js b/apps/user_ldap/l10n/lv.js index b671b52872968..f7d67f11d006d 100644 --- a/apps/user_ldap/l10n/lv.js +++ b/apps/user_ldap/l10n/lv.js @@ -49,6 +49,7 @@ OC.L10N.register( "in bytes" : "baitos", "Email Field" : "E-pasta lauks", "User Home Folder Naming Rule" : "Lietotāja mājas mapes nosaukšanas kārtula", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu." + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klienta lietotāja DN, ar ko veiks sasaisti, piemēram, uid=agent,dc=example,dc=com. Lai piekļūtu anonīmi, atstājiet DN un paroli tukšu." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/apps/user_ldap/l10n/lv.json b/apps/user_ldap/l10n/lv.json index 44f2b7c048d5a..134c0b6225bda 100644 --- a/apps/user_ldap/l10n/lv.json +++ b/apps/user_ldap/l10n/lv.json @@ -47,6 +47,7 @@ "in bytes" : "baitos", "Email Field" : "E-pasta lauks", "User Home Folder Naming Rule" : "Lietotāja mājas mapes nosaukšanas kārtula", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu." + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klienta lietotāja DN, ar ko veiks sasaisti, piemēram, uid=agent,dc=example,dc=com. Lai piekļūtu anonīmi, atstājiet DN un paroli tukšu." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/nb_NO.js b/apps/user_ldap/l10n/nb_NO.js index 1c81b36de7025..42939c24cb68d 100644 --- a/apps/user_ldap/l10n/nb_NO.js +++ b/apps/user_ldap/l10n/nb_NO.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Tilknytning av brukernavn til LDAP-bruker", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Brukernavn brukes til å lagre og tilordne (meta)data. For at brukere skal identifiseres og gjenkjennes presist, vil hver LDAP-bruker ha et internt brukernavn. Dette krever en tilknytning fra brukernavn til LDAP-bruker. Brukernavn som opprettes blir knyttet til LDAP-brukerens UUID. I tillegg mellomlagres DN for å redusere LDAP-kommunikasjon, men det brukes ikke til identifisering. Hvis DN endres vil endringene bli oppdaget. Det interne brukernavnet brukes alle steder. Nullstilling av tilknytningene vil etterlate seg rester overalt. Nullstilling av tilknytningene skjer ikke pr. konfigurasjon, det påvirker alle LDAP-konfigurasjoner! Nullstill aldri tilknytningene i et produksjonsmiljø, kun ved testing eller eksperimentering.", "Clear Username-LDAP User Mapping" : "Nullstill tilknytning av brukernavn til LDAP-bruker", - "Clear Groupname-LDAP Group Mapping" : "Nullstill tilknytning av gruppenavn til LDAP-gruppe" + "Clear Groupname-LDAP Group Mapping" : "Nullstill tilknytning av gruppenavn til LDAP-gruppe", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonym binding er ikke tillatt. Oppgi en bruker-DN og passord.", + "{nthServer}. Server" : "{nthServer}. server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/nb_NO.json b/apps/user_ldap/l10n/nb_NO.json index 1d5ab6fa71f6b..22515c7193d65 100644 --- a/apps/user_ldap/l10n/nb_NO.json +++ b/apps/user_ldap/l10n/nb_NO.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Tilknytning av brukernavn til LDAP-bruker", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Brukernavn brukes til å lagre og tilordne (meta)data. For at brukere skal identifiseres og gjenkjennes presist, vil hver LDAP-bruker ha et internt brukernavn. Dette krever en tilknytning fra brukernavn til LDAP-bruker. Brukernavn som opprettes blir knyttet til LDAP-brukerens UUID. I tillegg mellomlagres DN for å redusere LDAP-kommunikasjon, men det brukes ikke til identifisering. Hvis DN endres vil endringene bli oppdaget. Det interne brukernavnet brukes alle steder. Nullstilling av tilknytningene vil etterlate seg rester overalt. Nullstilling av tilknytningene skjer ikke pr. konfigurasjon, det påvirker alle LDAP-konfigurasjoner! Nullstill aldri tilknytningene i et produksjonsmiljø, kun ved testing eller eksperimentering.", "Clear Username-LDAP User Mapping" : "Nullstill tilknytning av brukernavn til LDAP-bruker", - "Clear Groupname-LDAP Group Mapping" : "Nullstill tilknytning av gruppenavn til LDAP-gruppe" + "Clear Groupname-LDAP Group Mapping" : "Nullstill tilknytning av gruppenavn til LDAP-gruppe", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonym binding er ikke tillatt. Oppgi en bruker-DN og passord.", + "{nthServer}. Server" : "{nthServer}. server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/nl.js b/apps/user_ldap/l10n/nl.js index 6de5a70d3f530..aa0b855c363ac 100644 --- a/apps/user_ldap/l10n/nl.js +++ b/apps/user_ldap/l10n/nl.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Gebruikersnaam-LDAP gebruikers vertaling", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud maakt gebruik van gebruikersnamen om (meta) data op te slaan en toe te wijzen. Om gebruikers uniek te identificeren, krijgt elke LDAP-gebruiker ook een interne gebruikersnaam. Dit vereist een koppeling van de ownCloud gebruikersnaam aan een ​​LDAP-gebruiker. De gecreëerde gebruikersnaam is gekoppeld aan de UUID van de LDAP-gebruiker. Aanvullend wordt ook de 'DN' gecached om het aantal LDAP-interacties te verminderen, maar dit wordt niet gebruikt voor identificatie. Als de DN verandert, zullen de veranderingen worden gevonden. De interne naam wordt overal gebruikt. Het wissen van de koppeling zal overal resten achterlaten. Het wissen van koppelingen is niet configuratiegevoelig, maar het raakt wel alle LDAP instellingen! Zorg ervoor dat deze koppelingen nooit in een productieomgeving gewist worden. Maak ze alleen leeg in een test- of ontwikkelomgeving.", "Clear Username-LDAP User Mapping" : "Leegmaken Gebruikersnaam-LDAP gebruikers vertaling", - "Clear Groupname-LDAP Group Mapping" : "Leegmaken Groepsnaam-LDAP groep vertaling" + "Clear Groupname-LDAP Group Mapping" : "Leegmaken Groepsnaam-LDAP groep vertaling", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonieme bind is niet toegestaan. Geef een gebruikers DN en wachrwoord op.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/nl.json b/apps/user_ldap/l10n/nl.json index 82e9c6d72f1fd..4159918ddbba7 100644 --- a/apps/user_ldap/l10n/nl.json +++ b/apps/user_ldap/l10n/nl.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Gebruikersnaam-LDAP gebruikers vertaling", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud maakt gebruik van gebruikersnamen om (meta) data op te slaan en toe te wijzen. Om gebruikers uniek te identificeren, krijgt elke LDAP-gebruiker ook een interne gebruikersnaam. Dit vereist een koppeling van de ownCloud gebruikersnaam aan een ​​LDAP-gebruiker. De gecreëerde gebruikersnaam is gekoppeld aan de UUID van de LDAP-gebruiker. Aanvullend wordt ook de 'DN' gecached om het aantal LDAP-interacties te verminderen, maar dit wordt niet gebruikt voor identificatie. Als de DN verandert, zullen de veranderingen worden gevonden. De interne naam wordt overal gebruikt. Het wissen van de koppeling zal overal resten achterlaten. Het wissen van koppelingen is niet configuratiegevoelig, maar het raakt wel alle LDAP instellingen! Zorg ervoor dat deze koppelingen nooit in een productieomgeving gewist worden. Maak ze alleen leeg in een test- of ontwikkelomgeving.", "Clear Username-LDAP User Mapping" : "Leegmaken Gebruikersnaam-LDAP gebruikers vertaling", - "Clear Groupname-LDAP Group Mapping" : "Leegmaken Groepsnaam-LDAP groep vertaling" + "Clear Groupname-LDAP Group Mapping" : "Leegmaken Groepsnaam-LDAP groep vertaling", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonieme bind is niet toegestaan. Geef een gebruikers DN en wachrwoord op.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/oc.js b/apps/user_ldap/l10n/oc.js index 77cb592e4028c..016169b5defd0 100644 --- a/apps/user_ldap/l10n/oc.js +++ b/apps/user_ldap/l10n/oc.js @@ -153,6 +153,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Associacion Nom d'utilizaire-Utilizaire LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los noms d'utilizaires son utilizats per l'emmagazinatge e l'assignacion de (meta) donadas. Per identificar e reconéisser precisament los utilizaires, cada utilizaire LDAP aurà un nom intèrne especific. Aquò requerís l'associacion d'un nom d'utilizaire ownCloud a un nom d'utilizaire LDAP. Lo nom d'utilizaire creat es associat a l'atribut UUID de l'utilizaire LDAP. Amai, lo DN es memorizat en escondedor per limitar las interaccions LDAP mas es pas utilizat per l'identificacion. Se lo DN es modificat, aquelas modificacions seràn retrobadas. Sol lo nom intèrne a ownCloud es utilizat al dintre del produch. Suprimir las associacions crearà d'orfanèls e l'accion afectarà totas las configuracions LDAP. SUPRIMISSÈTZ PAS JAMAI LAS ASSOCIACIONS EN ENVIRONAMENT DE PRODUCCION, mas unicament sus d'environaments de tèsts e d'experimentacions.", "Clear Username-LDAP User Mapping" : "Suprimir l'associacion utilizaire intèrne-utilizaire LDAP", - "Clear Groupname-LDAP Group Mapping" : "Suprimir l'associacion nom de grop-grop LDAP" + "Clear Groupname-LDAP Group Mapping" : "Suprimir l'associacion nom de grop-grop LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Lo ligam anonim es pas autorizat. Mercé de provesir lo DN d'un utilizaire e un senhal.", + "{nthServer}. Server" : "{nthServer}. Servidor" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/user_ldap/l10n/oc.json b/apps/user_ldap/l10n/oc.json index aa8d2b4186191..0287dd808fda2 100644 --- a/apps/user_ldap/l10n/oc.json +++ b/apps/user_ldap/l10n/oc.json @@ -151,6 +151,8 @@ "Username-LDAP User Mapping" : "Associacion Nom d'utilizaire-Utilizaire LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Los noms d'utilizaires son utilizats per l'emmagazinatge e l'assignacion de (meta) donadas. Per identificar e reconéisser precisament los utilizaires, cada utilizaire LDAP aurà un nom intèrne especific. Aquò requerís l'associacion d'un nom d'utilizaire ownCloud a un nom d'utilizaire LDAP. Lo nom d'utilizaire creat es associat a l'atribut UUID de l'utilizaire LDAP. Amai, lo DN es memorizat en escondedor per limitar las interaccions LDAP mas es pas utilizat per l'identificacion. Se lo DN es modificat, aquelas modificacions seràn retrobadas. Sol lo nom intèrne a ownCloud es utilizat al dintre del produch. Suprimir las associacions crearà d'orfanèls e l'accion afectarà totas las configuracions LDAP. SUPRIMISSÈTZ PAS JAMAI LAS ASSOCIACIONS EN ENVIRONAMENT DE PRODUCCION, mas unicament sus d'environaments de tèsts e d'experimentacions.", "Clear Username-LDAP User Mapping" : "Suprimir l'associacion utilizaire intèrne-utilizaire LDAP", - "Clear Groupname-LDAP Group Mapping" : "Suprimir l'associacion nom de grop-grop LDAP" + "Clear Groupname-LDAP Group Mapping" : "Suprimir l'associacion nom de grop-grop LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Lo ligam anonim es pas autorizat. Mercé de provesir lo DN d'un utilizaire e un senhal.", + "{nthServer}. Server" : "{nthServer}. Servidor" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/pl.js b/apps/user_ldap/l10n/pl.js index e2e3a44d292ef..4479b329d54b5 100644 --- a/apps/user_ldap/l10n/pl.js +++ b/apps/user_ldap/l10n/pl.js @@ -120,6 +120,10 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Mapowanie użytkownika LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nazwy użytkowników służą do przechowywania i przypisywania (meta) danych. W celu dokładnego określenia i rozpoznawania użytkowników, każdy użytkownik LDAP ma przypisaną wewnętrzną nazwę użytkownika. Wymaga to mapowania nazwy użytkownika do użytkownika LDAP. Utworzona nazwa użytkownika jest odwzorowywana na UUID użytkownika LDAP. Dodatkowo DN są buforowane, także w celu zmniejszenia oddziaływania LDAP, ale nie są stosowane do identyfikacji. Po zmianie DN, będzie można znaleźć zmiany. Wewnętrzna nazwa jest używana wszędzie. Usuwanie mapowania będzie miało wpływ wszędzie. Usuwanie mapowania nie jest wrażliwe na konfiguracje, dotyczy to wszystkich konfiguracji LDAP! Nigdy nie usuwaj mapowania w środowisku produkcyjnym, jest to dopuszczalne tylko w fazie eksperymentalnej, testowej.", "Clear Username-LDAP User Mapping" : "Czyść Mapowanie użytkownika LDAP", - "Clear Groupname-LDAP Group Mapping" : "Czyść Mapowanie nazwy grupy LDAP" + "Clear Groupname-LDAP Group Mapping" : "Czyść Mapowanie nazwy grupy LDAP", + "Dynamic Group Member URL" : "URL Członka Grupy Dynamicznej", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN użytkownika klienta, z którym powiązanie wykonuje się, np. uid=agent,dc=example,dc=com. Dla dostępu anonimowego pozostawić DN i hasło puste", + "{nthServer}. Server" : "{nthServer}. Serwer", + "The Base DN appears to be wrong" : "Base DN wygląda na błedne" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/user_ldap/l10n/pl.json b/apps/user_ldap/l10n/pl.json index 1e518980dab8d..8484484fe3063 100644 --- a/apps/user_ldap/l10n/pl.json +++ b/apps/user_ldap/l10n/pl.json @@ -118,6 +118,10 @@ "Username-LDAP User Mapping" : "Mapowanie użytkownika LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nazwy użytkowników służą do przechowywania i przypisywania (meta) danych. W celu dokładnego określenia i rozpoznawania użytkowników, każdy użytkownik LDAP ma przypisaną wewnętrzną nazwę użytkownika. Wymaga to mapowania nazwy użytkownika do użytkownika LDAP. Utworzona nazwa użytkownika jest odwzorowywana na UUID użytkownika LDAP. Dodatkowo DN są buforowane, także w celu zmniejszenia oddziaływania LDAP, ale nie są stosowane do identyfikacji. Po zmianie DN, będzie można znaleźć zmiany. Wewnętrzna nazwa jest używana wszędzie. Usuwanie mapowania będzie miało wpływ wszędzie. Usuwanie mapowania nie jest wrażliwe na konfiguracje, dotyczy to wszystkich konfiguracji LDAP! Nigdy nie usuwaj mapowania w środowisku produkcyjnym, jest to dopuszczalne tylko w fazie eksperymentalnej, testowej.", "Clear Username-LDAP User Mapping" : "Czyść Mapowanie użytkownika LDAP", - "Clear Groupname-LDAP Group Mapping" : "Czyść Mapowanie nazwy grupy LDAP" + "Clear Groupname-LDAP Group Mapping" : "Czyść Mapowanie nazwy grupy LDAP", + "Dynamic Group Member URL" : "URL Członka Grupy Dynamicznej", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN użytkownika klienta, z którym powiązanie wykonuje się, np. uid=agent,dc=example,dc=com. Dla dostępu anonimowego pozostawić DN i hasło puste", + "{nthServer}. Server" : "{nthServer}. Serwer", + "The Base DN appears to be wrong" : "Base DN wygląda na błedne" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/pt_BR.js b/apps/user_ldap/l10n/pt_BR.js index f1b36b31cc709..9121583fabecc 100644 --- a/apps/user_ldap/l10n/pt_BR.js +++ b/apps/user_ldap/l10n/pt_BR.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Usuário-LDAP Mapeamento de Usuário", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nomes de usuários são usados para armazenar e atribuir dados (meta). A fim de identificar e reconhecer precisamente usuários, cada usuário LDAP terá um nome de usuário interno. Isso requer um mapeamento de nome de usuário para usuário LDAP. O nome de usuário criado é mapeado para o UUID do usuário LDAP. Além disso, o DN é armazenado em cache, assim como para reduzir a interação LDAP, mas não é usado para identificação. Se o DN muda, as mudanças serão encontrados. O nome de usuário interno é usado por toda parte. Limpando os mapeamentos terá sobras em todos os lugares. Limpando os mapeamentos não é a configuração sensível, que afeta todas as configurações LDAP! Nunca limpar os mapeamentos em um ambiente de produção, somente em um teste ou estágio experimental.", "Clear Username-LDAP User Mapping" : "Limpar Mapeamento de Usuário Nome de Usuário-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Limpar NomedoGrupo-LDAP Mapeamento do Grupo" + "Clear Groupname-LDAP Group Mapping" : "Limpar NomedoGrupo-LDAP Mapeamento do Grupo", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Vínculo anônimo não é permitido. Por favor, forneça um DN do usuário e senha.", + "{nthServer}. Server" : "Servidor {nthServer}." }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/user_ldap/l10n/pt_BR.json b/apps/user_ldap/l10n/pt_BR.json index 8da9273770469..e8a1c898641c7 100644 --- a/apps/user_ldap/l10n/pt_BR.json +++ b/apps/user_ldap/l10n/pt_BR.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Usuário-LDAP Mapeamento de Usuário", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Nomes de usuários são usados para armazenar e atribuir dados (meta). A fim de identificar e reconhecer precisamente usuários, cada usuário LDAP terá um nome de usuário interno. Isso requer um mapeamento de nome de usuário para usuário LDAP. O nome de usuário criado é mapeado para o UUID do usuário LDAP. Além disso, o DN é armazenado em cache, assim como para reduzir a interação LDAP, mas não é usado para identificação. Se o DN muda, as mudanças serão encontrados. O nome de usuário interno é usado por toda parte. Limpando os mapeamentos terá sobras em todos os lugares. Limpando os mapeamentos não é a configuração sensível, que afeta todas as configurações LDAP! Nunca limpar os mapeamentos em um ambiente de produção, somente em um teste ou estágio experimental.", "Clear Username-LDAP User Mapping" : "Limpar Mapeamento de Usuário Nome de Usuário-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Limpar NomedoGrupo-LDAP Mapeamento do Grupo" + "Clear Groupname-LDAP Group Mapping" : "Limpar NomedoGrupo-LDAP Mapeamento do Grupo", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Vínculo anônimo não é permitido. Por favor, forneça um DN do usuário e senha.", + "{nthServer}. Server" : "Servidor {nthServer}." },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/pt_PT.js b/apps/user_ldap/l10n/pt_PT.js index 788c092eb32e3..389f49b345883 100644 --- a/apps/user_ldap/l10n/pt_PT.js +++ b/apps/user_ldap/l10n/pt_PT.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Mapeamento do utilizador LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "O ownCloud usa nomes de utilizadores para guardar e atribuir (meta) dados. Para identificar com precisão os utilizadores, cada utilizador de LDAP tem um nome de utilizador interno. Isto requer um mapeamento entre o utilizador LDAP e o utilizador ownCloud. Adicionalmente, o DN é colocado em cache para reduzir a interação com LDAP, porém não é usado para identificação. Se o DN muda, essas alterações serão vistas pelo ownCloud. O nome interno do ownCloud é usado em todo o lado, no ownCloud. Limpar os mapeamentos deixará vestígios em todo o lado. A limpeza dos mapeamentos não é sensível à configuração, pois afeta todas as configurações de LDAP! Nunca limpe os mapeamentos num ambiente de produção, apenas o faça numa fase de testes ou experimental.", "Clear Username-LDAP User Mapping" : "Limpar mapeamento do utilizador-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Limpar o mapeamento do nome de grupo LDAP" + "Clear Groupname-LDAP Group Mapping" : "Limpar o mapeamento do nome de grupo LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Ligação anónima não permitida. Por favor forneça um ND de utilizador e password.", + "{nthServer}. Server" : "{nthServer}. Servidor" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/pt_PT.json b/apps/user_ldap/l10n/pt_PT.json index f75b1d1e5ea01..665e5de56aa83 100644 --- a/apps/user_ldap/l10n/pt_PT.json +++ b/apps/user_ldap/l10n/pt_PT.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Mapeamento do utilizador LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "O ownCloud usa nomes de utilizadores para guardar e atribuir (meta) dados. Para identificar com precisão os utilizadores, cada utilizador de LDAP tem um nome de utilizador interno. Isto requer um mapeamento entre o utilizador LDAP e o utilizador ownCloud. Adicionalmente, o DN é colocado em cache para reduzir a interação com LDAP, porém não é usado para identificação. Se o DN muda, essas alterações serão vistas pelo ownCloud. O nome interno do ownCloud é usado em todo o lado, no ownCloud. Limpar os mapeamentos deixará vestígios em todo o lado. A limpeza dos mapeamentos não é sensível à configuração, pois afeta todas as configurações de LDAP! Nunca limpe os mapeamentos num ambiente de produção, apenas o faça numa fase de testes ou experimental.", "Clear Username-LDAP User Mapping" : "Limpar mapeamento do utilizador-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Limpar o mapeamento do nome de grupo LDAP" + "Clear Groupname-LDAP Group Mapping" : "Limpar o mapeamento do nome de grupo LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Ligação anónima não permitida. Por favor forneça um ND de utilizador e password.", + "{nthServer}. Server" : "{nthServer}. Servidor" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ro.js b/apps/user_ldap/l10n/ro.js index cb3a126fe6f90..393f080af1d32 100644 --- a/apps/user_ldap/l10n/ro.js +++ b/apps/user_ldap/l10n/ro.js @@ -53,6 +53,7 @@ OC.L10N.register( "Special Attributes" : "Caracteristici speciale ", "in bytes" : "în octeți", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lăsați gol pentru numele de utilizator (implicit). În caz contrar, specificați un atribut LDAP / AD.", - "Internal Username" : "Nume utilizator intern" + "Internal Username" : "Nume utilizator intern", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN-ul clientului utilizator cu care se va efectua conectarea, d.e. uid=agent,dc=example,dc=com. Pentru acces anonim, lăsăți DN și Parolă libere." }, "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); diff --git a/apps/user_ldap/l10n/ro.json b/apps/user_ldap/l10n/ro.json index c84722f88bafc..2f2cf265b5369 100644 --- a/apps/user_ldap/l10n/ro.json +++ b/apps/user_ldap/l10n/ro.json @@ -51,6 +51,7 @@ "Special Attributes" : "Caracteristici speciale ", "in bytes" : "în octeți", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lăsați gol pentru numele de utilizator (implicit). În caz contrar, specificați un atribut LDAP / AD.", - "Internal Username" : "Nume utilizator intern" + "Internal Username" : "Nume utilizator intern", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN-ul clientului utilizator cu care se va efectua conectarea, d.e. uid=agent,dc=example,dc=com. Pentru acces anonim, lăsăți DN și Parolă libere." },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/ru.js b/apps/user_ldap/l10n/ru.js index f3928b80999b7..41a0fe4b6dde6 100644 --- a/apps/user_ldap/l10n/ru.js +++ b/apps/user_ldap/l10n/ru.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Соответствия Имя-Пользователь LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud использует имена пользователей для хранения и назначения метаданных. Для точной идентификации и распознавания пользователей, каждый пользователь LDAP будет иметь свое внутреннее имя пользователя. Это требует привязки имени пользователя ownCloud к пользователю LDAP. При создании имя пользователя назначается идентификатору UUID пользователя LDAP. Помимо этого кешируется доменное имя (DN) для уменьшения числа обращений к LDAP, однако оно не используется для идентификации. Если доменное имя было изменено, об этом станет известно ownCloud. Внутреннее имя ownCloud используется повсеместно в ownCloud. После сброса привязок в базе могут сохраниться остатки старой информации. Сброс привязок не привязан к конфигурации, он повлияет на все LDAP подключения! Ни в коем случае не рекомендуется сбрасывать привязки если система уже находится в эксплуатации, только на этапе тестирования.", "Clear Username-LDAP User Mapping" : "Очистить соответствия Имя-Пользователь LDAP", - "Clear Groupname-LDAP Group Mapping" : "Очистить соответствия Группа-Группа LDAP" + "Clear Groupname-LDAP Group Mapping" : "Очистить соответствия Группа-Группа LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонимная связь не разрешается. Пожалуйста укажите DN пользователя и пароль.", + "{nthServer}. Server" : "Сервер {nthServer}." }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/user_ldap/l10n/ru.json b/apps/user_ldap/l10n/ru.json index 5dbaca39353cf..7f1245b17a8fa 100644 --- a/apps/user_ldap/l10n/ru.json +++ b/apps/user_ldap/l10n/ru.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Соответствия Имя-Пользователь LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud использует имена пользователей для хранения и назначения метаданных. Для точной идентификации и распознавания пользователей, каждый пользователь LDAP будет иметь свое внутреннее имя пользователя. Это требует привязки имени пользователя ownCloud к пользователю LDAP. При создании имя пользователя назначается идентификатору UUID пользователя LDAP. Помимо этого кешируется доменное имя (DN) для уменьшения числа обращений к LDAP, однако оно не используется для идентификации. Если доменное имя было изменено, об этом станет известно ownCloud. Внутреннее имя ownCloud используется повсеместно в ownCloud. После сброса привязок в базе могут сохраниться остатки старой информации. Сброс привязок не привязан к конфигурации, он повлияет на все LDAP подключения! Ни в коем случае не рекомендуется сбрасывать привязки если система уже находится в эксплуатации, только на этапе тестирования.", "Clear Username-LDAP User Mapping" : "Очистить соответствия Имя-Пользователь LDAP", - "Clear Groupname-LDAP Group Mapping" : "Очистить соответствия Группа-Группа LDAP" + "Clear Groupname-LDAP Group Mapping" : "Очистить соответствия Группа-Группа LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонимная связь не разрешается. Пожалуйста укажите DN пользователя и пароль.", + "{nthServer}. Server" : "Сервер {nthServer}." },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/sk_SK.js b/apps/user_ldap/l10n/sk_SK.js index 6eca3c2735b42..a170615fa3bf2 100644 --- a/apps/user_ldap/l10n/sk_SK.js +++ b/apps/user_ldap/l10n/sk_SK.js @@ -152,6 +152,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Mapovanie názvov LDAP používateľských mien", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Používateľské mená sa používajú na uchovávanie a priraďovanie (meta)dát. Každý používateľ v LDAP bude mať interné používateľské meno, aby bolo možné správne identifikovať a rozpoznávať používateľov. To je vyžaduje vytvorenie mapovania používateľských mien na používateľov v LDAPe. Vytvorené používateľské meno sa namapuje na UUID používateľa v LDAPe. Naviac je sa vo vyrovnávacej pamäti udržiava DN, aby sa obmedzila nadmerná interakcia s LDAPom, ale to sa nepoužíva na identifikáciu. Ak sa DN zmení, zmena bude správne rozpoznaná. Interné používateľské meno sa používa všade. Vyčistenie mapovaní vymaže zvyšky všade. Vyčistenie mapovaní naviac nie je špecifické pre určitú konfiguráciu; bude mať vplyv na všetky konfigurácie LDAPu! Nikdy nečistite mapovanie v produkčnom prostredí, len v testovacej alebo experimentálnej fáze.", "Clear Username-LDAP User Mapping" : "Zrušiť mapovanie LDAP používateľských mien", - "Clear Groupname-LDAP Group Mapping" : "Zrušiť mapovanie názvov LDAP skupín" + "Clear Groupname-LDAP Group Mapping" : "Zrušiť mapovanie názvov LDAP skupín", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymný bind nie je povolený. Zadajte používateľské DN a heslo.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/apps/user_ldap/l10n/sk_SK.json b/apps/user_ldap/l10n/sk_SK.json index ca7275af8e63a..e4617b77d1273 100644 --- a/apps/user_ldap/l10n/sk_SK.json +++ b/apps/user_ldap/l10n/sk_SK.json @@ -150,6 +150,8 @@ "Username-LDAP User Mapping" : "Mapovanie názvov LDAP používateľských mien", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Používateľské mená sa používajú na uchovávanie a priraďovanie (meta)dát. Každý používateľ v LDAP bude mať interné používateľské meno, aby bolo možné správne identifikovať a rozpoznávať používateľov. To je vyžaduje vytvorenie mapovania používateľských mien na používateľov v LDAPe. Vytvorené používateľské meno sa namapuje na UUID používateľa v LDAPe. Naviac je sa vo vyrovnávacej pamäti udržiava DN, aby sa obmedzila nadmerná interakcia s LDAPom, ale to sa nepoužíva na identifikáciu. Ak sa DN zmení, zmena bude správne rozpoznaná. Interné používateľské meno sa používa všade. Vyčistenie mapovaní vymaže zvyšky všade. Vyčistenie mapovaní naviac nie je špecifické pre určitú konfiguráciu; bude mať vplyv na všetky konfigurácie LDAPu! Nikdy nečistite mapovanie v produkčnom prostredí, len v testovacej alebo experimentálnej fáze.", "Clear Username-LDAP User Mapping" : "Zrušiť mapovanie LDAP používateľských mien", - "Clear Groupname-LDAP Group Mapping" : "Zrušiť mapovanie názvov LDAP skupín" + "Clear Groupname-LDAP Group Mapping" : "Zrušiť mapovanie názvov LDAP skupín", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonymný bind nie je povolený. Zadajte používateľské DN a heslo.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/sl.js b/apps/user_ldap/l10n/sl.js index 0187bd4345b70..6112ded667973 100644 --- a/apps/user_ldap/l10n/sl.js +++ b/apps/user_ldap/l10n/sl.js @@ -117,6 +117,10 @@ OC.L10N.register( "UUID Attribute for Groups:" : "Atribut UUID za skupine:", "Username-LDAP User Mapping" : "Uporabniška preslikava uporabniškega imena na LDAP", "Clear Username-LDAP User Mapping" : "Izbriši preslikavo uporabniškega imena na LDAP", - "Clear Groupname-LDAP Group Mapping" : "Izbriši preslikavo skupine na LDAP" + "Clear Groupname-LDAP Group Mapping" : "Izbriši preslikavo skupine na LDAP", + "Detect Port" : "Zaznaj vrata", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Enolično ime uporabnikovega odjemalca, s katerim naj se opravi vezava, npr. uid=agent,dc=example,dc=com. Za brezimni dostop sta polji prikaznega imena in gesla prazni.", + "{nthServer}. Server" : "{nthServer}. strežnik", + "Test Loginname" : "Preizkusi prijavno ime" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/user_ldap/l10n/sl.json b/apps/user_ldap/l10n/sl.json index 11e6d443c49bb..0e01140eb8c60 100644 --- a/apps/user_ldap/l10n/sl.json +++ b/apps/user_ldap/l10n/sl.json @@ -115,6 +115,10 @@ "UUID Attribute for Groups:" : "Atribut UUID za skupine:", "Username-LDAP User Mapping" : "Uporabniška preslikava uporabniškega imena na LDAP", "Clear Username-LDAP User Mapping" : "Izbriši preslikavo uporabniškega imena na LDAP", - "Clear Groupname-LDAP Group Mapping" : "Izbriši preslikavo skupine na LDAP" + "Clear Groupname-LDAP Group Mapping" : "Izbriši preslikavo skupine na LDAP", + "Detect Port" : "Zaznaj vrata", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Enolično ime uporabnikovega odjemalca, s katerim naj se opravi vezava, npr. uid=agent,dc=example,dc=com. Za brezimni dostop sta polji prikaznega imena in gesla prazni.", + "{nthServer}. Server" : "{nthServer}. strežnik", + "Test Loginname" : "Preizkusi prijavno ime" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/sq.js b/apps/user_ldap/l10n/sq.js index 81da1fbf76bbc..c8a6509b8d12f 100644 --- a/apps/user_ldap/l10n/sq.js +++ b/apps/user_ldap/l10n/sq.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Përshoqërim Emër përdoruesi-Përdorues LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Emrat e përdoruesve përdoren për të depozituar dhe shpërndarë (tej) të dhëna. Që të mund të identifikohen dhe pranohen saktësisht përdoruesit, çdo përdorues LDAP do të ketë një emër të brendshëm përdoruesi. Kjo kërkon përshoqërim nga emër përdoruesi te përdorues LDAP. Emri i përdoruesit i krijuar i përshoqërohet UUID-së së përdoruesit LDAP. Tej kësaj, edhe DN-ja ruhet në fshehtinë, për të zvogëluar ndërveprim LDAP, por s’përdoret për identifikim. Nëse ndryshon DN-ja, ndryshimet do të gjenden. Emri i brendshëm i përdoruesi përdoret gjithandej. Heqja e përshoqërimeve do të lërë thërrime ngado. Heqja e përshoqërimeve nuk preket nga formësimi, prek krejt formësimet për LDAP-në! Mos i hiqni kurrë përshoqërimet në një mjedis prodhimi, vetëm në një faqë testimi ose eksperimetale.", "Clear Username-LDAP User Mapping" : "Pastro Përshoqërimin Emër përdoruesi-Përdorues LDAP", - "Clear Groupname-LDAP Group Mapping" : "Pastro Përshoqërimin Emër grupi-Grup LDAP" + "Clear Groupname-LDAP Group Mapping" : "Pastro Përshoqërimin Emër grupi-Grup LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "S’lejohet bind anonim. Ju lutemi, jepni një DN Përodruesi dhe Fjalëkalim.", + "{nthServer}. Server" : "{nthServer}. Shërbyes" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/sq.json b/apps/user_ldap/l10n/sq.json index f4f0224dd0a8a..7a07082e05466 100644 --- a/apps/user_ldap/l10n/sq.json +++ b/apps/user_ldap/l10n/sq.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Përshoqërim Emër përdoruesi-Përdorues LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Emrat e përdoruesve përdoren për të depozituar dhe shpërndarë (tej) të dhëna. Që të mund të identifikohen dhe pranohen saktësisht përdoruesit, çdo përdorues LDAP do të ketë një emër të brendshëm përdoruesi. Kjo kërkon përshoqërim nga emër përdoruesi te përdorues LDAP. Emri i përdoruesit i krijuar i përshoqërohet UUID-së së përdoruesit LDAP. Tej kësaj, edhe DN-ja ruhet në fshehtinë, për të zvogëluar ndërveprim LDAP, por s’përdoret për identifikim. Nëse ndryshon DN-ja, ndryshimet do të gjenden. Emri i brendshëm i përdoruesi përdoret gjithandej. Heqja e përshoqërimeve do të lërë thërrime ngado. Heqja e përshoqërimeve nuk preket nga formësimi, prek krejt formësimet për LDAP-në! Mos i hiqni kurrë përshoqërimet në një mjedis prodhimi, vetëm në një faqë testimi ose eksperimetale.", "Clear Username-LDAP User Mapping" : "Pastro Përshoqërimin Emër përdoruesi-Përdorues LDAP", - "Clear Groupname-LDAP Group Mapping" : "Pastro Përshoqërimin Emër grupi-Grup LDAP" + "Clear Groupname-LDAP Group Mapping" : "Pastro Përshoqërimin Emër grupi-Grup LDAP", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "S’lejohet bind anonim. Ju lutemi, jepni një DN Përodruesi dhe Fjalëkalim.", + "{nthServer}. Server" : "{nthServer}. Shërbyes" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/sr.js b/apps/user_ldap/l10n/sr.js index eb3ee924b7a39..8fd8db430a948 100644 --- a/apps/user_ldap/l10n/sr.js +++ b/apps/user_ldap/l10n/sr.js @@ -153,6 +153,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Username-LDAP мапирање корисника", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Корисничка имена се користи за чување и додељивање (мета) података. Да би се прецизно идентификовали и препознавали кориснике, сваки LDAP корисник ће имати локално корисничко име. Ово захтева мапирање од корисничког имена до LDAP корисника. Креирано корисничко име се мапира у UUID LDAP корисника. Поред тога, DN се кешира да смањи LDAP интеракцију, али се не користи за идентификацију. Ако се DN мења, промене се могу наћи. Локално корисничко име се користи свуда. Чишћење мапирања оставља свуда остатке. Чишћење мапирања није осетљиво на конфигурацију, оно утиче на све LDAP конфигурације! Никада не користит чишћење мапирања у радном окружењу, већ само у тестирању или експерименталној фази.", "Clear Username-LDAP User Mapping" : "Очисти Username-LDAP мапирање корисника", - "Clear Groupname-LDAP Group Mapping" : "Очисти Groupname-LDAP мапирање група" + "Clear Groupname-LDAP Group Mapping" : "Очисти Groupname-LDAP мапирање група", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонимно везивање није дозвољено. Дајте кориснички ДН и лозинку.", + "{nthServer}. Server" : "{nthServer}. Сервер" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/user_ldap/l10n/sr.json b/apps/user_ldap/l10n/sr.json index 233df2f4e34e8..f4b8fa0722a2e 100644 --- a/apps/user_ldap/l10n/sr.json +++ b/apps/user_ldap/l10n/sr.json @@ -151,6 +151,8 @@ "Username-LDAP User Mapping" : "Username-LDAP мапирање корисника", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Корисничка имена се користи за чување и додељивање (мета) података. Да би се прецизно идентификовали и препознавали кориснике, сваки LDAP корисник ће имати локално корисничко име. Ово захтева мапирање од корисничког имена до LDAP корисника. Креирано корисничко име се мапира у UUID LDAP корисника. Поред тога, DN се кешира да смањи LDAP интеракцију, али се не користи за идентификацију. Ако се DN мења, промене се могу наћи. Локално корисничко име се користи свуда. Чишћење мапирања оставља свуда остатке. Чишћење мапирања није осетљиво на конфигурацију, оно утиче на све LDAP конфигурације! Никада не користит чишћење мапирања у радном окружењу, већ само у тестирању или експерименталној фази.", "Clear Username-LDAP User Mapping" : "Очисти Username-LDAP мапирање корисника", - "Clear Groupname-LDAP Group Mapping" : "Очисти Groupname-LDAP мапирање група" + "Clear Groupname-LDAP Group Mapping" : "Очисти Groupname-LDAP мапирање група", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Анонимно везивање није дозвољено. Дајте кориснички ДН и лозинку.", + "{nthServer}. Server" : "{nthServer}. Сервер" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/sv.js b/apps/user_ldap/l10n/sv.js index dd75c836333da..2ad23bdfb6532 100644 --- a/apps/user_ldap/l10n/sv.js +++ b/apps/user_ldap/l10n/sv.js @@ -101,6 +101,8 @@ OC.L10N.register( "UUID Attribute for Groups:" : "UUID-attribut för grupper:", "Username-LDAP User Mapping" : "Användarnamn-LDAP användarmappning", "Clear Username-LDAP User Mapping" : "Rensa användarnamn-LDAP användarmappning", - "Clear Groupname-LDAP Group Mapping" : "Rensa gruppnamn-LDAP gruppmappning" + "Clear Groupname-LDAP Group Mapping" : "Rensa gruppnamn-LDAP gruppmappning", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN för användaren som skall användas, t.ex. uid=agent, dc=example, dc=com. För anonym åtkomst, lämna DN och lösenord tomt.", + "{nthServer}. Server" : "{nthServer}. Server" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/sv.json b/apps/user_ldap/l10n/sv.json index d71e94b30502f..ae91cd67eefa7 100644 --- a/apps/user_ldap/l10n/sv.json +++ b/apps/user_ldap/l10n/sv.json @@ -99,6 +99,8 @@ "UUID Attribute for Groups:" : "UUID-attribut för grupper:", "Username-LDAP User Mapping" : "Användarnamn-LDAP användarmappning", "Clear Username-LDAP User Mapping" : "Rensa användarnamn-LDAP användarmappning", - "Clear Groupname-LDAP Group Mapping" : "Rensa gruppnamn-LDAP gruppmappning" + "Clear Groupname-LDAP Group Mapping" : "Rensa gruppnamn-LDAP gruppmappning", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN för användaren som skall användas, t.ex. uid=agent, dc=example, dc=com. För anonym åtkomst, lämna DN och lösenord tomt.", + "{nthServer}. Server" : "{nthServer}. Server" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/th_TH.js b/apps/user_ldap/l10n/th_TH.js index 8b155dcfe23a1..b2c18ad585b62 100644 --- a/apps/user_ldap/l10n/th_TH.js +++ b/apps/user_ldap/l10n/th_TH.js @@ -153,6 +153,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Username-LDAP ผู้ใช้ Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ชื่อผู้ใช้จะใช้ในการจัดเก็บและกำหนดข้อมูล (เมตา) เพื่อรู้จักกับผู้ใช้และสามารถระบุได้อย่างแม่นยำ แต่ละ LDAP จะมีชื่อผู้ใช้ภายใน จึงต้องทำ Mapping ให้กับผู้ใช้ LDAP ชื่อผู้ใช้ที่ถูกสร้างขึ้นจะถูกแมปเข้ากับ UUID ของผู้ใช้ LDAP นอกจากนี้ DN ก็จะถูกแคชเช่นกันเพื่อลดการทำงานร่วมกันของ LDAP แต่มันก็ไม่ได้ใช้เพื่อระบุตัวตน หากมีการเปลี่ยนแปลง DN การเปลี่ยนแปลงจะถูกพบในทันที ชื่อผู้ใช้ภายในจะถูกใช้กับทั้งหมด การล้างแมปไม่มีผลต่อการกำหนดค่า LDAP ทั้งหมด! \nและจะเกิดขึ้นเฉพาะในการทดสอบหรือขั้นตอนการทดลอง", "Clear Username-LDAP User Mapping" : "ล้าง Username-LDAP ผู้ใช้ Mapping", - "Clear Groupname-LDAP Group Mapping" : "ล้าง Groupname-LDAP กลุ่ม Mapping" + "Clear Groupname-LDAP Group Mapping" : "ล้าง Groupname-LDAP กลุ่ม Mapping", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "บุคคลนิรนามไม่ได้รับอนุญาต กรุณาระบุ DN ของผู้ใช้และรหัสผ่าน", + "{nthServer}. Server" : "เซิร์ฟเวอร์ {nthServer}" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/th_TH.json b/apps/user_ldap/l10n/th_TH.json index 9787ba10037fb..60d7c34a29050 100644 --- a/apps/user_ldap/l10n/th_TH.json +++ b/apps/user_ldap/l10n/th_TH.json @@ -151,6 +151,8 @@ "Username-LDAP User Mapping" : "Username-LDAP ผู้ใช้ Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ชื่อผู้ใช้จะใช้ในการจัดเก็บและกำหนดข้อมูล (เมตา) เพื่อรู้จักกับผู้ใช้และสามารถระบุได้อย่างแม่นยำ แต่ละ LDAP จะมีชื่อผู้ใช้ภายใน จึงต้องทำ Mapping ให้กับผู้ใช้ LDAP ชื่อผู้ใช้ที่ถูกสร้างขึ้นจะถูกแมปเข้ากับ UUID ของผู้ใช้ LDAP นอกจากนี้ DN ก็จะถูกแคชเช่นกันเพื่อลดการทำงานร่วมกันของ LDAP แต่มันก็ไม่ได้ใช้เพื่อระบุตัวตน หากมีการเปลี่ยนแปลง DN การเปลี่ยนแปลงจะถูกพบในทันที ชื่อผู้ใช้ภายในจะถูกใช้กับทั้งหมด การล้างแมปไม่มีผลต่อการกำหนดค่า LDAP ทั้งหมด! \nและจะเกิดขึ้นเฉพาะในการทดสอบหรือขั้นตอนการทดลอง", "Clear Username-LDAP User Mapping" : "ล้าง Username-LDAP ผู้ใช้ Mapping", - "Clear Groupname-LDAP Group Mapping" : "ล้าง Groupname-LDAP กลุ่ม Mapping" + "Clear Groupname-LDAP Group Mapping" : "ล้าง Groupname-LDAP กลุ่ม Mapping", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "บุคคลนิรนามไม่ได้รับอนุญาต กรุณาระบุ DN ของผู้ใช้และรหัสผ่าน", + "{nthServer}. Server" : "เซิร์ฟเวอร์ {nthServer}" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/tr.js b/apps/user_ldap/l10n/tr.js index 709a9c46ffd71..a49cbd26a0243 100644 --- a/apps/user_ldap/l10n/tr.js +++ b/apps/user_ldap/l10n/tr.js @@ -157,6 +157,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirme", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Kullanıcı adları, (üst) veri depolaması ve ataması için kullanılır. Kullanıcıları kesin olarak tanımlamak ve algılamak için, her LDAP kullanıcısı bir dahili kullanıcı adına sahip olacak. Bu kullanıcı adı ile LDAP kullanıcısı arasında bir eşleşme gerektirir. Oluşturulan kullanıcı adı LDAP kullanıcısının UUID'si ile eşleştirilir. Ek olarak LDAP etkileşimini azaltmak için DN de önbelleğe alınır ancak bu kimlik tanıma için kullanılmaz. Eğer DN değişirse, değişiklikler tespit edilir. Dahili kullanıcı her yerde kullanılır. Eşleştirmeleri temizlemek, her yerde kalıntılar bırakacaktır. Eşleştirmeleri temizlemek yapılandırmaya hassas bir şekilde bağlı değildir, tüm LDAP yapılandırmalarını etkiler! Üretim ortamında eşleştirmeleri asla temizlemeyin, sadece sınama veya deneysel aşamada kullanın.", "Clear Username-LDAP User Mapping" : "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirmesini Temizle", - "Clear Groupname-LDAP Group Mapping" : "Grup Adı-LDAP Grubu Eşleştirmesini Temizle" + "Clear Groupname-LDAP Group Mapping" : "Grup Adı-LDAP Grubu Eşleştirmesini Temizle", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonim atamaya izin verilmiyor. Lütfen bir Kullanıcı DN ve Parola sağlayın.", + "{nthServer}. Server" : "{nthServer}. Sunucu" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/user_ldap/l10n/tr.json b/apps/user_ldap/l10n/tr.json index 6c34f8a5c20d4..f790abaf21be1 100644 --- a/apps/user_ldap/l10n/tr.json +++ b/apps/user_ldap/l10n/tr.json @@ -155,6 +155,8 @@ "Username-LDAP User Mapping" : "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirme", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "Kullanıcı adları, (üst) veri depolaması ve ataması için kullanılır. Kullanıcıları kesin olarak tanımlamak ve algılamak için, her LDAP kullanıcısı bir dahili kullanıcı adına sahip olacak. Bu kullanıcı adı ile LDAP kullanıcısı arasında bir eşleşme gerektirir. Oluşturulan kullanıcı adı LDAP kullanıcısının UUID'si ile eşleştirilir. Ek olarak LDAP etkileşimini azaltmak için DN de önbelleğe alınır ancak bu kimlik tanıma için kullanılmaz. Eğer DN değişirse, değişiklikler tespit edilir. Dahili kullanıcı her yerde kullanılır. Eşleştirmeleri temizlemek, her yerde kalıntılar bırakacaktır. Eşleştirmeleri temizlemek yapılandırmaya hassas bir şekilde bağlı değildir, tüm LDAP yapılandırmalarını etkiler! Üretim ortamında eşleştirmeleri asla temizlemeyin, sadece sınama veya deneysel aşamada kullanın.", "Clear Username-LDAP User Mapping" : "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirmesini Temizle", - "Clear Groupname-LDAP Group Mapping" : "Grup Adı-LDAP Grubu Eşleştirmesini Temizle" + "Clear Groupname-LDAP Group Mapping" : "Grup Adı-LDAP Grubu Eşleştirmesini Temizle", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonim atamaya izin verilmiyor. Lütfen bir Kullanıcı DN ve Parola sağlayın.", + "{nthServer}. Server" : "{nthServer}. Sunucu" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/uk.js b/apps/user_ldap/l10n/uk.js index fe2b587fec58c..75d3bee19f549 100644 --- a/apps/user_ldap/l10n/uk.js +++ b/apps/user_ldap/l10n/uk.js @@ -114,6 +114,8 @@ OC.L10N.register( "Username-LDAP User Mapping" : "Картографія Імен користувачів-LDAP ", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud використовує імена користувачів для зберігання та призначення метаданих. Для точної ідентифікації та розпізнавання користувачів, кожен користувач LDAP буде мати своє внутрішнє ім'я користувача. Це вимагає прив'язки імені користувача ownCloud до користувача LDAP. При створенні ім'я користувача призначається ідентифікатором UUID користувача LDAP. Крім цього кешируєтся доменне ім'я (DN) для зменшення числа звернень до LDAP, однак воно не використовується для ідентифікації. Якщо доменне ім'я було змінено, про це стане відомо ownCloud. Внутрішнє ім'я ownCloud використовується повсюдно в ownCloud. Після скидання прив'язок в базі можуть зберегтися залишки старої інформації. Скидання прив'язок не прив'язане до конфігурації, воно вплине на всі LDAP підключення! Ні в якому разі не рекомендується скидати прив'язки якщо система вже знаходиться в експлуатації, тільки на етапі тестування.", "Clear Username-LDAP User Mapping" : "Очистити картографію Імен користувачів-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Очистити картографію Імен груп-LDAP" + "Clear Groupname-LDAP Group Mapping" : "Очистити картографію Імен груп-LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN клієнтського користувача для прив'язки, наприклад: uid=agent,dc=example,dc=com. Для анонімного доступу, залиште DN і Пароль порожніми.", + "{nthServer}. Server" : "{nthServer}. Сервер" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/user_ldap/l10n/uk.json b/apps/user_ldap/l10n/uk.json index b43de37ab3633..3aa7a28770ae6 100644 --- a/apps/user_ldap/l10n/uk.json +++ b/apps/user_ldap/l10n/uk.json @@ -112,6 +112,8 @@ "Username-LDAP User Mapping" : "Картографія Імен користувачів-LDAP ", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "ownCloud використовує імена користувачів для зберігання та призначення метаданих. Для точної ідентифікації та розпізнавання користувачів, кожен користувач LDAP буде мати своє внутрішнє ім'я користувача. Це вимагає прив'язки імені користувача ownCloud до користувача LDAP. При створенні ім'я користувача призначається ідентифікатором UUID користувача LDAP. Крім цього кешируєтся доменне ім'я (DN) для зменшення числа звернень до LDAP, однак воно не використовується для ідентифікації. Якщо доменне ім'я було змінено, про це стане відомо ownCloud. Внутрішнє ім'я ownCloud використовується повсюдно в ownCloud. Після скидання прив'язок в базі можуть зберегтися залишки старої інформації. Скидання прив'язок не прив'язане до конфігурації, воно вплине на всі LDAP підключення! Ні в якому разі не рекомендується скидати прив'язки якщо система вже знаходиться в експлуатації, тільки на етапі тестування.", "Clear Username-LDAP User Mapping" : "Очистити картографію Імен користувачів-LDAP", - "Clear Groupname-LDAP Group Mapping" : "Очистити картографію Імен груп-LDAP" + "Clear Groupname-LDAP Group Mapping" : "Очистити картографію Імен груп-LDAP", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "DN клієнтського користувача для прив'язки, наприклад: uid=agent,dc=example,dc=com. Для анонімного доступу, залиште DN і Пароль порожніми.", + "{nthServer}. Server" : "{nthServer}. Сервер" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/vi.js b/apps/user_ldap/l10n/vi.js index e20feb8abba8d..5b38415b26912 100644 --- a/apps/user_ldap/l10n/vi.js +++ b/apps/user_ldap/l10n/vi.js @@ -40,6 +40,7 @@ OC.L10N.register( "Group-Member association" : "Nhóm thành viên Cộng đồng", "Special Attributes" : "Special Attributes", "in bytes" : "Theo Byte", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD" + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Các DN của người sử dụng đã được thực hiện, ví dụ như uid =agent , dc = example, dc = com. Để truy cập nặc danh ,DN và mật khẩu trống." }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/vi.json b/apps/user_ldap/l10n/vi.json index ffbeff90189e8..39113c112b7fa 100644 --- a/apps/user_ldap/l10n/vi.json +++ b/apps/user_ldap/l10n/vi.json @@ -38,6 +38,7 @@ "Group-Member association" : "Nhóm thành viên Cộng đồng", "Special Attributes" : "Special Attributes", "in bytes" : "Theo Byte", - "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD" + "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Các DN của người sử dụng đã được thực hiện, ví dụ như uid =agent , dc = example, dc = com. Để truy cập nặc danh ,DN và mật khẩu trống." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/zh_CN.js b/apps/user_ldap/l10n/zh_CN.js index a6a8f7edff9c6..6d398dd83a8f2 100644 --- a/apps/user_ldap/l10n/zh_CN.js +++ b/apps/user_ldap/l10n/zh_CN.js @@ -153,6 +153,9 @@ OC.L10N.register( "Username-LDAP User Mapping" : "用户名-LDAP用户映射", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "用户名用于存储和分配数据 (元)。为了准确地识别和确认用户,每个用户都有一个内部用户名。这需要一个 ownCloud 用户名到 LDAP 用户的映射。创建的用户名被映射到 LDAP 用户的 UUID。此外,DN 也会被缓存,以减少 LDAP 连接,但它不用于识别。DN 的变化会被监视到。内部用户名会被用于所有地方。清除映射将导致一片混乱。清除映射不是常用的设置,它会影响到所有的 LDAP 配置!千万不要在正式环境中清除映射,只有在测试或试验时才这样做。", "Clear Username-LDAP User Mapping" : "清除用户-LDAP用户映射", - "Clear Groupname-LDAP Group Mapping" : "清除组用户-LDAP级映射" + "Clear Groupname-LDAP Group Mapping" : "清除组用户-LDAP级映射", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "禁止匿名绑定。请提供有效的用户DN和密码。", + "Select object classes" : "选择对象类型", + "{nthServer}. Server" : "{nthServer}. 服务器" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/zh_CN.json b/apps/user_ldap/l10n/zh_CN.json index 1ffac3742d6e4..274aa6c307f7c 100644 --- a/apps/user_ldap/l10n/zh_CN.json +++ b/apps/user_ldap/l10n/zh_CN.json @@ -151,6 +151,9 @@ "Username-LDAP User Mapping" : "用户名-LDAP用户映射", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have an internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." : "用户名用于存储和分配数据 (元)。为了准确地识别和确认用户,每个用户都有一个内部用户名。这需要一个 ownCloud 用户名到 LDAP 用户的映射。创建的用户名被映射到 LDAP 用户的 UUID。此外,DN 也会被缓存,以减少 LDAP 连接,但它不用于识别。DN 的变化会被监视到。内部用户名会被用于所有地方。清除映射将导致一片混乱。清除映射不是常用的设置,它会影响到所有的 LDAP 配置!千万不要在正式环境中清除映射,只有在测试或试验时才这样做。", "Clear Username-LDAP User Mapping" : "清除用户-LDAP用户映射", - "Clear Groupname-LDAP Group Mapping" : "清除组用户-LDAP级映射" + "Clear Groupname-LDAP Group Mapping" : "清除组用户-LDAP级映射", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "禁止匿名绑定。请提供有效的用户DN和密码。", + "Select object classes" : "选择对象类型", + "{nthServer}. Server" : "{nthServer}. 服务器" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/zh_HK.js b/apps/user_ldap/l10n/zh_HK.js index 918e84c1c13b7..4670923ac4c7f 100644 --- a/apps/user_ldap/l10n/zh_HK.js +++ b/apps/user_ldap/l10n/zh_HK.js @@ -19,6 +19,7 @@ OC.L10N.register( "Back" : "返回", "Continue" : "繼續", "LDAP" : "LDAP", - "Advanced" : "進階" + "Advanced" : "進階", + "{nthServer}. Server" : "{nthServer}. 伺服器" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/zh_HK.json b/apps/user_ldap/l10n/zh_HK.json index eec1e9ed3aa68..67884e712e7b5 100644 --- a/apps/user_ldap/l10n/zh_HK.json +++ b/apps/user_ldap/l10n/zh_HK.json @@ -17,6 +17,7 @@ "Back" : "返回", "Continue" : "繼續", "LDAP" : "LDAP", - "Advanced" : "進階" + "Advanced" : "進階", + "{nthServer}. Server" : "{nthServer}. 伺服器" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/apps/user_ldap/l10n/zh_TW.js b/apps/user_ldap/l10n/zh_TW.js index 77bd5ab1258b8..b6ea861a34683 100644 --- a/apps/user_ldap/l10n/zh_TW.js +++ b/apps/user_ldap/l10n/zh_TW.js @@ -130,6 +130,8 @@ OC.L10N.register( "Internal Username Attribute:" : "內部使用者名稱屬性:", "Override UUID detection" : "偵測覆寫UUID", "UUID Attribute for Users:" : "使用者的UUID值:", - "UUID Attribute for Groups:" : "群組的UUID值:" + "UUID Attribute for Groups:" : "群組的UUID值:", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "匿名是不允許的,請提供使用者DN和密碼", + "{nthServer}. Server" : "{nthServer}. 伺服器" }, "nplurals=1; plural=0;"); diff --git a/apps/user_ldap/l10n/zh_TW.json b/apps/user_ldap/l10n/zh_TW.json index abbd1d6507174..2cb5314af3a89 100644 --- a/apps/user_ldap/l10n/zh_TW.json +++ b/apps/user_ldap/l10n/zh_TW.json @@ -128,6 +128,8 @@ "Internal Username Attribute:" : "內部使用者名稱屬性:", "Override UUID detection" : "偵測覆寫UUID", "UUID Attribute for Users:" : "使用者的UUID值:", - "UUID Attribute for Groups:" : "群組的UUID值:" + "UUID Attribute for Groups:" : "群組的UUID值:", + "Anonymous bind is not allowed. Please provide a User DN and Password." : "匿名是不允許的,請提供使用者DN和密碼", + "{nthServer}. Server" : "{nthServer}. 伺服器" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/af_ZA.js b/core/l10n/af_ZA.js index 1d7b1bda36116..5f5b30c374ff5 100644 --- a/core/l10n/af_ZA.js +++ b/core/l10n/af_ZA.js @@ -108,6 +108,7 @@ OC.L10N.register( "Alternative Logins" : "Alternatiewe aantekeninge", "Use the following link to reset your password: {link}" : "Gebruik die volgende skakel om jou wagwoord te herstel: {link}", "New password" : "Nuwe wagwoord", - "Reset password" : "Herstel wagwoord" + "Reset password" : "Herstel wagwoord", + "Password can not be changed. Please contact your administrator." : "Wagwoord kan nie verander word nie. Kontak asseblief jou stelsel administrateur." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/af_ZA.json b/core/l10n/af_ZA.json index fc83949b361b5..713f6faa4f2cc 100644 --- a/core/l10n/af_ZA.json +++ b/core/l10n/af_ZA.json @@ -106,6 +106,7 @@ "Alternative Logins" : "Alternatiewe aantekeninge", "Use the following link to reset your password: {link}" : "Gebruik die volgende skakel om jou wagwoord te herstel: {link}", "New password" : "Nuwe wagwoord", - "Reset password" : "Herstel wagwoord" + "Reset password" : "Herstel wagwoord", + "Password can not be changed. Please contact your administrator." : "Wagwoord kan nie verander word nie. Kontak asseblief jou stelsel administrateur." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/ar.js b/core/l10n/ar.js index 798b4ba07cda6..abbc7d7dfe5aa 100644 --- a/core/l10n/ar.js +++ b/core/l10n/ar.js @@ -131,6 +131,7 @@ OC.L10N.register( "Alternative Logins" : "اسماء دخول بديلة", "Use the following link to reset your password: {link}" : "استخدم هذه الوصلة لاسترجاع كلمة السر: {link}", "New password" : "كلمات سر جديدة", - "Reset password" : "تعديل كلمة السر" + "Reset password" : "تعديل كلمة السر", + "Password can not be changed. Please contact your administrator." : "كلمة المرور لا يمكن تغييرها. فضلاً تحدث مع المسؤول" }, "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); diff --git a/core/l10n/ar.json b/core/l10n/ar.json index 885babf2e6453..483ccbcc18322 100644 --- a/core/l10n/ar.json +++ b/core/l10n/ar.json @@ -129,6 +129,7 @@ "Alternative Logins" : "اسماء دخول بديلة", "Use the following link to reset your password: {link}" : "استخدم هذه الوصلة لاسترجاع كلمة السر: {link}", "New password" : "كلمات سر جديدة", - "Reset password" : "تعديل كلمة السر" + "Reset password" : "تعديل كلمة السر", + "Password can not be changed. Please contact your administrator." : "كلمة المرور لا يمكن تغييرها. فضلاً تحدث مع المسؤول" },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" } \ No newline at end of file diff --git a/core/l10n/ast.js b/core/l10n/ast.js index 4a027b866d6a3..c4df832cace6d 100644 --- a/core/l10n/ast.js +++ b/core/l10n/ast.js @@ -185,6 +185,8 @@ OC.L10N.register( "Add \"%s\" as trusted domain" : "Amestáu \"%s\" como dominiu de confianza", "The theme %s has been disabled." : "Deshabilitóse'l tema %s.", "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Enantes de siguir, asegúrate de que se fizo una copia de seguridá de la base de datos, la carpeta de configuración y la carpeta de datos.", - "Start update" : "Aniciar anovamientu" + "Start update" : "Aniciar anovamientu", + "Error loading file picker template: {error}" : "Fallu cargando'l ficheru de plantía d'escoyeta: {error}", + "Password can not be changed. Please contact your administrator." : "Nun pue camudase la contraseña. Por favor, contauta col alministrador." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/ast.json b/core/l10n/ast.json index de80a882ac650..237961529c969 100644 --- a/core/l10n/ast.json +++ b/core/l10n/ast.json @@ -183,6 +183,8 @@ "Add \"%s\" as trusted domain" : "Amestáu \"%s\" como dominiu de confianza", "The theme %s has been disabled." : "Deshabilitóse'l tema %s.", "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Enantes de siguir, asegúrate de que se fizo una copia de seguridá de la base de datos, la carpeta de configuración y la carpeta de datos.", - "Start update" : "Aniciar anovamientu" + "Start update" : "Aniciar anovamientu", + "Error loading file picker template: {error}" : "Fallu cargando'l ficheru de plantía d'escoyeta: {error}", + "Password can not be changed. Please contact your administrator." : "Nun pue camudase la contraseña. Por favor, contauta col alministrador." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/bg_BG.js b/core/l10n/bg_BG.js index c87cc3bbe3b79..40c9577e9681f 100644 --- a/core/l10n/bg_BG.js +++ b/core/l10n/bg_BG.js @@ -221,6 +221,9 @@ OC.L10N.register( "Start update" : "Започване на обновяването", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "За да избегнеш таймаутове при по-големи инсталации, можеш да изпълниш следните команди в инсталанционната директория:", "This %s instance is currently in maintenance mode, which may take a while." : "В момента този %s се обновява, а това може да отнеме време.", - "This page will refresh itself when the %s instance is available again." : "Тази страница ще се опресни автоматично, когато %s е отново на линия." + "This page will refresh itself when the %s instance is available again." : "Тази страница ще се опресни автоматично, когато %s е отново на линия.", + "Error loading file picker template: {error}" : "Грешка при зареждането на шаблон за избор на файл: {error}", + "Password can not be changed. Please contact your administrator." : "Паролата не може да бъде промена. Моля, свържете се с администратора.", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Сървърът няма работеща интернет връзка. Това означава, че някои функции като прикачването на външни дискови устройства, уведомления за обновяване или инсталиране на външни приложения няма да работят. Достъпът на файлове отвън или изпращане на имейли за уведомление вероятно също няма да работят. Препоръчваме да включиш интернет връзката за този сървър ако искаш да използваш всички тези функции." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/bg_BG.json b/core/l10n/bg_BG.json index 14d7db6af4bcd..70e10f8e541fc 100644 --- a/core/l10n/bg_BG.json +++ b/core/l10n/bg_BG.json @@ -219,6 +219,9 @@ "Start update" : "Започване на обновяването", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "За да избегнеш таймаутове при по-големи инсталации, можеш да изпълниш следните команди в инсталанционната директория:", "This %s instance is currently in maintenance mode, which may take a while." : "В момента този %s се обновява, а това може да отнеме време.", - "This page will refresh itself when the %s instance is available again." : "Тази страница ще се опресни автоматично, когато %s е отново на линия." + "This page will refresh itself when the %s instance is available again." : "Тази страница ще се опресни автоматично, когато %s е отново на линия.", + "Error loading file picker template: {error}" : "Грешка при зареждането на шаблон за избор на файл: {error}", + "Password can not be changed. Please contact your administrator." : "Паролата не може да бъде промена. Моля, свържете се с администратора.", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Сървърът няма работеща интернет връзка. Това означава, че някои функции като прикачването на външни дискови устройства, уведомления за обновяване или инсталиране на външни приложения няма да работят. Достъпът на файлове отвън или изпращане на имейли за уведомление вероятно също няма да работят. Препоръчваме да включиш интернет връзката за този сървър ако искаш да използваш всички тези функции." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/bs.js b/core/l10n/bs.js index 32766081862f5..2227fcddb6af1 100644 --- a/core/l10n/bs.js +++ b/core/l10n/bs.js @@ -198,6 +198,9 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Prije nego nastavite, molim osigurajte se da su baza podataka, direktorij konfiguracije i direktorij podataka sigurnosno kopirani.", "Start update" : "Započnite ažuriranje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da biste izbjegli vremensko prekoračenje s većim instalacijama, možete pokrenuti slijedeću naredbu iz svoga instalacijskog direktorija:", - "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama aktualizirati nakon što instanca %s postane ponovo dostupna." + "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama aktualizirati nakon što instanca %s postane ponovo dostupna.", + "Error loading file picker template: {error}" : "Pogrešno učitavanje šablona za izabir datoteke: {error}", + "You can click here to return to %s." : "Možete kliknuti ovdje da bih se vratili na %s.", + "Password can not be changed. Please contact your administrator." : "Lozinku ne može biti promjenuta. Molimo kontaktirajte vašeg administratora." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/bs.json b/core/l10n/bs.json index 77a7fb6fa4460..2f0ee127e88d7 100644 --- a/core/l10n/bs.json +++ b/core/l10n/bs.json @@ -196,6 +196,9 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Prije nego nastavite, molim osigurajte se da su baza podataka, direktorij konfiguracije i direktorij podataka sigurnosno kopirani.", "Start update" : "Započnite ažuriranje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da biste izbjegli vremensko prekoračenje s većim instalacijama, možete pokrenuti slijedeću naredbu iz svoga instalacijskog direktorija:", - "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama aktualizirati nakon što instanca %s postane ponovo dostupna." + "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama aktualizirati nakon što instanca %s postane ponovo dostupna.", + "Error loading file picker template: {error}" : "Pogrešno učitavanje šablona za izabir datoteke: {error}", + "You can click here to return to %s." : "Možete kliknuti ovdje da bih se vratili na %s.", + "Password can not be changed. Please contact your administrator." : "Lozinku ne može biti promjenuta. Molimo kontaktirajte vašeg administratora." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/ca.js b/core/l10n/ca.js index b0ea7d596f5dc..c2a0dc62c5732 100644 --- a/core/l10n/ca.js +++ b/core/l10n/ca.js @@ -256,6 +256,8 @@ OC.L10N.register( "Start update" : "Inicia l'actualització", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per evitar que s'esgoti el temps d'espera en instalacions grans, pots en el seu lloc fer córrer la següent comanda en el directori d'instalació. ", "This %s instance is currently in maintenance mode, which may take a while." : "Aquesta instància %s està actualment en manteniment i podria trigar una estona.", - "This page will refresh itself when the %s instance is available again." : "Aquesta pàgina s'actualitzarà automàticament quan la instància %s estigui disponible de nou." + "This page will refresh itself when the %s instance is available again." : "Aquesta pàgina s'actualitzarà automàticament quan la instància %s estigui disponible de nou.", + "Repair error: " : "Error de reparació:", + "Password can not be changed. Please contact your administrator." : "La contrasenya no es pot canviar. Contacteu amb l'administrador." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/ca.json b/core/l10n/ca.json index 90aaba126f6cb..050723c1c883b 100644 --- a/core/l10n/ca.json +++ b/core/l10n/ca.json @@ -254,6 +254,8 @@ "Start update" : "Inicia l'actualització", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per evitar que s'esgoti el temps d'espera en instalacions grans, pots en el seu lloc fer córrer la següent comanda en el directori d'instalació. ", "This %s instance is currently in maintenance mode, which may take a while." : "Aquesta instància %s està actualment en manteniment i podria trigar una estona.", - "This page will refresh itself when the %s instance is available again." : "Aquesta pàgina s'actualitzarà automàticament quan la instància %s estigui disponible de nou." + "This page will refresh itself when the %s instance is available again." : "Aquesta pàgina s'actualitzarà automàticament quan la instància %s estigui disponible de nou.", + "Repair error: " : "Error de reparació:", + "Password can not be changed. Please contact your administrator." : "La contrasenya no es pot canviar. Contacteu amb l'administrador." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/cs_CZ.js b/core/l10n/cs_CZ.js index 885a1eefec4b2..a106b4c7489b7 100644 --- a/core/l10n/cs_CZ.js +++ b/core/l10n/cs_CZ.js @@ -296,6 +296,8 @@ OC.L10N.register( "Start update" : "Spustit aktualizaci", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Abyste zabránili vypršení časového limitu u větších instalací, můžete namísto toho spustit následující příkaz v hlavním adresáři:", "This %s instance is currently in maintenance mode, which may take a while." : "Tato instalace %s je právě ve stavu údržby a to může chvíli trvat.", - "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s." + "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s.", + "Error loading file picker template: {error}" : "Chyba při nahrávání šablony výběru souborů: {error}", + "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého správce systému." }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/core/l10n/cs_CZ.json b/core/l10n/cs_CZ.json index 187ebcc2802b7..9fbd2fd5e368b 100644 --- a/core/l10n/cs_CZ.json +++ b/core/l10n/cs_CZ.json @@ -294,6 +294,8 @@ "Start update" : "Spustit aktualizaci", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Abyste zabránili vypršení časového limitu u větších instalací, můžete namísto toho spustit následující příkaz v hlavním adresáři:", "This %s instance is currently in maintenance mode, which may take a while." : "Tato instalace %s je právě ve stavu údržby a to může chvíli trvat.", - "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s." + "This page will refresh itself when the %s instance is available again." : "Tato stránka se automaticky načte poté, co bude opět dostupná instance %s.", + "Error loading file picker template: {error}" : "Chyba při nahrávání šablony výběru souborů: {error}", + "Password can not be changed. Please contact your administrator." : "Heslo nelze změnit. Kontaktujte prosím svého správce systému." },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/core/l10n/da.js b/core/l10n/da.js index 03ecb6f175dcb..b997f030eaa24 100644 --- a/core/l10n/da.js +++ b/core/l10n/da.js @@ -270,6 +270,10 @@ OC.L10N.register( "Start update" : "Begynd opdatering", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "For at undgå tidsudløb ved større installationer, så kan du i stedet køre følgende kommando fra din installationsmappe:", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instans befinder sig i vedligeholdelsestilstand for øjeblikket, hvilket kan tage et stykke tid.", - "This page will refresh itself when the %s instance is available again." : "Denne side vil genopfriske sig selv, når %s-instancen er tilgængelig igen." + "This page will refresh itself when the %s instance is available again." : "Denne side vil genopfriske sig selv, når %s-instancen er tilgængelig igen.", + "Error loading file picker template: {error}" : "Fejl ved indlæsning af filvælger skabelon: {error}", + "Error removing share" : "Fejl ved fjernelse af deling", + "invisible" : "usynlig", + "Password can not be changed. Please contact your administrator." : "Adgangskoden kunne ikke ændres. Kontakt venligst din administrator." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/da.json b/core/l10n/da.json index 10be7aa4b540f..4f242d64b232c 100644 --- a/core/l10n/da.json +++ b/core/l10n/da.json @@ -268,6 +268,10 @@ "Start update" : "Begynd opdatering", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "For at undgå tidsudløb ved større installationer, så kan du i stedet køre følgende kommando fra din installationsmappe:", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instans befinder sig i vedligeholdelsestilstand for øjeblikket, hvilket kan tage et stykke tid.", - "This page will refresh itself when the %s instance is available again." : "Denne side vil genopfriske sig selv, når %s-instancen er tilgængelig igen." + "This page will refresh itself when the %s instance is available again." : "Denne side vil genopfriske sig selv, når %s-instancen er tilgængelig igen.", + "Error loading file picker template: {error}" : "Fejl ved indlæsning af filvælger skabelon: {error}", + "Error removing share" : "Fejl ved fjernelse af deling", + "invisible" : "usynlig", + "Password can not be changed. Please contact your administrator." : "Adgangskoden kunne ikke ændres. Kontakt venligst din administrator." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/de.js b/core/l10n/de.js index 52f88b367343e..f4185b587bfb8 100644 --- a/core/l10n/de.js +++ b/core/l10n/de.js @@ -299,6 +299,11 @@ OC.L10N.register( "Start update" : "Aktualisierung starten", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Zur Vermeidung von Zeitüberschreitungen bei größeren Installationen kannst Du stattdessen den folgenden Befehl in Deinem Installationsverzeichnis ausführen:", "This %s instance is currently in maintenance mode, which may take a while." : "Diese %s-Instanz befindet sich gerade im Wartungsmodus, was eine Weile dauern kann.", - "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist." + "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist.", + "Error loading file picker template: {error}" : "Fehler beim Laden der Dateiauswahlvorlage: {error}", + "Fri." : "Fr", + "Mon." : "Mo", + "Password can not be changed. Please contact your administrator." : "Passwort kann nicht geändert werden. Bitte kontaktiere Deinen Administrator.", + "Sat." : "Sa" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/de.json b/core/l10n/de.json index 5f8b163c678aa..df268aa597d21 100644 --- a/core/l10n/de.json +++ b/core/l10n/de.json @@ -297,6 +297,11 @@ "Start update" : "Aktualisierung starten", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Zur Vermeidung von Zeitüberschreitungen bei größeren Installationen kannst Du stattdessen den folgenden Befehl in Deinem Installationsverzeichnis ausführen:", "This %s instance is currently in maintenance mode, which may take a while." : "Diese %s-Instanz befindet sich gerade im Wartungsmodus, was eine Weile dauern kann.", - "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist." + "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist.", + "Error loading file picker template: {error}" : "Fehler beim Laden der Dateiauswahlvorlage: {error}", + "Fri." : "Fr", + "Mon." : "Mo", + "Password can not be changed. Please contact your administrator." : "Passwort kann nicht geändert werden. Bitte kontaktiere Deinen Administrator.", + "Sat." : "Sa" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/de_AT.js b/core/l10n/de_AT.js index d0a5e054fca67..d51b56c3b427f 100644 --- a/core/l10n/de_AT.js +++ b/core/l10n/de_AT.js @@ -58,6 +58,9 @@ OC.L10N.register( "Add" : "Hinzufügen", "Personal" : "Persönlich", "Help" : "Hilfe", - "Username" : "Benutzername" + "Username" : "Benutzername", + "Fri." : "Fr", + "Mon." : "Mo", + "Sat." : "Sa" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/de_AT.json b/core/l10n/de_AT.json index 6ab59d45c2d99..21b9917c0776e 100644 --- a/core/l10n/de_AT.json +++ b/core/l10n/de_AT.json @@ -56,6 +56,9 @@ "Add" : "Hinzufügen", "Personal" : "Persönlich", "Help" : "Hilfe", - "Username" : "Benutzername" + "Username" : "Benutzername", + "Fri." : "Fr", + "Mon." : "Mo", + "Sat." : "Sa" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/de_DE.js b/core/l10n/de_DE.js index 15a7b0a6035bf..927f805f4057e 100644 --- a/core/l10n/de_DE.js +++ b/core/l10n/de_DE.js @@ -282,6 +282,13 @@ OC.L10N.register( "Start update" : "Aktualisierung starten", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Zur Vermeidung von Zeitüberschreitungen bei größeren Installationen können Sie stattdessen den folgenden Befehl in Ihrem Installationsverzeichnis ausführen:", "This %s instance is currently in maintenance mode, which may take a while." : "Diese %s-Instanz befindet sich gerade im Wartungsmodus, was eine Weile dauern kann.", - "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist." + "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist.", + "Could not unshare" : "Freigabe konnte nicht aufgehoben werden", + "Error loading file picker template: {error}" : "Fehler beim Laden der Dateiauswahlvorlage: {error}", + "Error removing share" : "Fehler beim Entfernen der Freigabe", + "Fri." : "Fr", + "Mon." : "Mo", + "Password can not be changed. Please contact your administrator." : "Passwort kann nicht geändert werden. Bitte kontaktieren Sie Ihren Administrator.", + "Sat." : "Sa" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/de_DE.json b/core/l10n/de_DE.json index 6fc700754e952..868817c69e280 100644 --- a/core/l10n/de_DE.json +++ b/core/l10n/de_DE.json @@ -280,6 +280,13 @@ "Start update" : "Aktualisierung starten", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Zur Vermeidung von Zeitüberschreitungen bei größeren Installationen können Sie stattdessen den folgenden Befehl in Ihrem Installationsverzeichnis ausführen:", "This %s instance is currently in maintenance mode, which may take a while." : "Diese %s-Instanz befindet sich gerade im Wartungsmodus, was eine Weile dauern kann.", - "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist." + "This page will refresh itself when the %s instance is available again." : "Diese Seite aktualisiert sich automatisch, wenn die %s-Instanz wieder verfügbar ist.", + "Could not unshare" : "Freigabe konnte nicht aufgehoben werden", + "Error loading file picker template: {error}" : "Fehler beim Laden der Dateiauswahlvorlage: {error}", + "Error removing share" : "Fehler beim Entfernen der Freigabe", + "Fri." : "Fr", + "Mon." : "Mo", + "Password can not be changed. Please contact your administrator." : "Passwort kann nicht geändert werden. Bitte kontaktieren Sie Ihren Administrator.", + "Sat." : "Sa" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/el.js b/core/l10n/el.js index 12da9336d2005..42e28b12cbfbb 100644 --- a/core/l10n/el.js +++ b/core/l10n/el.js @@ -271,6 +271,8 @@ OC.L10N.register( "Start update" : "Έναρξη ενημέρωσης", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Για να αποφύγετε τη λήξη χρόνου με μεγαλύτερες εγκαταστάσεις, μπορείτε αντί αυτού να τρέξετε την ακόλουθη εντολή από τον κατάλογο αρχείων εφαρμογών:", "This %s instance is currently in maintenance mode, which may take a while." : "Αυτή %s η εγκατάσταση είναι σε κατάσταση συντήρησης, η οποία μπορεί να πάρει κάποιο χρόνο.", - "This page will refresh itself when the %s instance is available again." : "Αυτή η σελίδα θα ανανεωθεί από μόνη της όταν η %s εγκατάσταση είναι διαθέσιμη ξανά." + "This page will refresh itself when the %s instance is available again." : "Αυτή η σελίδα θα ανανεωθεί από μόνη της όταν η %s εγκατάσταση είναι διαθέσιμη ξανά.", + "Error loading file picker template: {error}" : "Σφάλμα κατά την φόρτωση προτύπου επιλογέα αρχείων: {σφάλμα}", + "Password can not be changed. Please contact your administrator." : "Ο κωδικός πρόσβασης δεν μπορεί να αλλάξει. Παρακαλώ επικοινωνήστε με το διαχειριστή σας." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/el.json b/core/l10n/el.json index 7a0ee88004f0d..2a80d3074f982 100644 --- a/core/l10n/el.json +++ b/core/l10n/el.json @@ -269,6 +269,8 @@ "Start update" : "Έναρξη ενημέρωσης", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Για να αποφύγετε τη λήξη χρόνου με μεγαλύτερες εγκαταστάσεις, μπορείτε αντί αυτού να τρέξετε την ακόλουθη εντολή από τον κατάλογο αρχείων εφαρμογών:", "This %s instance is currently in maintenance mode, which may take a while." : "Αυτή %s η εγκατάσταση είναι σε κατάσταση συντήρησης, η οποία μπορεί να πάρει κάποιο χρόνο.", - "This page will refresh itself when the %s instance is available again." : "Αυτή η σελίδα θα ανανεωθεί από μόνη της όταν η %s εγκατάσταση είναι διαθέσιμη ξανά." + "This page will refresh itself when the %s instance is available again." : "Αυτή η σελίδα θα ανανεωθεί από μόνη της όταν η %s εγκατάσταση είναι διαθέσιμη ξανά.", + "Error loading file picker template: {error}" : "Σφάλμα κατά την φόρτωση προτύπου επιλογέα αρχείων: {σφάλμα}", + "Password can not be changed. Please contact your administrator." : "Ο κωδικός πρόσβασης δεν μπορεί να αλλάξει. Παρακαλώ επικοινωνήστε με το διαχειριστή σας." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/en_GB.js b/core/l10n/en_GB.js index ec991bf41872c..9c053fabfd171 100644 --- a/core/l10n/en_GB.js +++ b/core/l10n/en_GB.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Start update", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:", "This %s instance is currently in maintenance mode, which may take a while." : "This %s instance is currently in maintenance mode, which may take a while.", - "This page will refresh itself when the %s instance is available again." : "This page will refresh itself when the %s instance is available again." + "This page will refresh itself when the %s instance is available again." : "This page will refresh itself when the %s instance is available again.", + "Error loading file picker template: {error}" : "Error loading file picker template: {error}", + "Password can not be changed. Please contact your administrator." : "Password can not be changed. Please contact your administrator." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/en_GB.json b/core/l10n/en_GB.json index 44c88fae998ea..d1967ef5e2f9b 100644 --- a/core/l10n/en_GB.json +++ b/core/l10n/en_GB.json @@ -297,6 +297,8 @@ "Start update" : "Start update", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:", "This %s instance is currently in maintenance mode, which may take a while." : "This %s instance is currently in maintenance mode, which may take a while.", - "This page will refresh itself when the %s instance is available again." : "This page will refresh itself when the %s instance is available again." + "This page will refresh itself when the %s instance is available again." : "This page will refresh itself when the %s instance is available again.", + "Error loading file picker template: {error}" : "Error loading file picker template: {error}", + "Password can not be changed. Please contact your administrator." : "Password can not be changed. Please contact your administrator." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/eo.js b/core/l10n/eo.js index 7aba923dfca13..332045d6c49a5 100644 --- a/core/l10n/eo.js +++ b/core/l10n/eo.js @@ -212,6 +212,7 @@ OC.L10N.register( "%s will be updated to version %s" : "%s ĝisdatiĝos al eldono %s", "These apps will be updated:" : "Ĉi tiuj aplikaĵoj ĝisdatiĝos:", "These incompatible apps will be disabled:" : "Ĉi tiuj malkongruaj aplikaĵoj malkapabliĝos:", - "Start update" : "Ekĝisdatigi" + "Start update" : "Ekĝisdatigi", + "Error loading message template: {error}" : "Eraris ŝargo de mesaĝa ŝablono: {eraro}" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/eo.json b/core/l10n/eo.json index 410529d45acf8..e158df2124d6f 100644 --- a/core/l10n/eo.json +++ b/core/l10n/eo.json @@ -210,6 +210,7 @@ "%s will be updated to version %s" : "%s ĝisdatiĝos al eldono %s", "These apps will be updated:" : "Ĉi tiuj aplikaĵoj ĝisdatiĝos:", "These incompatible apps will be disabled:" : "Ĉi tiuj malkongruaj aplikaĵoj malkapabliĝos:", - "Start update" : "Ekĝisdatigi" + "Start update" : "Ekĝisdatigi", + "Error loading message template: {error}" : "Eraris ŝargo de mesaĝa ŝablono: {eraro}" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/es.js b/core/l10n/es.js index 145879a957ac7..bb1c32c90ab58 100644 --- a/core/l10n/es.js +++ b/core/l10n/es.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Iniciar actualización", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tiempos de espera en grandes instalaciones, en su lugar puede ejecutar el siguiente comando desde el directorio de instalación:", "This %s instance is currently in maintenance mode, which may take a while." : "Está instancia %s está en modo mantenimiento, por lo que puede llevar un tiempo.", - "This page will refresh itself when the %s instance is available again." : "La página se refrescará cuando la instalación %s vuelva a estar disponible." + "This page will refresh itself when the %s instance is available again." : "La página se refrescará cuando la instalación %s vuelva a estar disponible.", + "Repair error: " : "Error que reparar:", + "Password can not be changed. Please contact your administrator." : "La contraseña no se puede cambiar. Por favor, contacte a su administrador." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/es.json b/core/l10n/es.json index 299d6303cecea..463110fa0a649 100644 --- a/core/l10n/es.json +++ b/core/l10n/es.json @@ -297,6 +297,8 @@ "Start update" : "Iniciar actualización", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tiempos de espera en grandes instalaciones, en su lugar puede ejecutar el siguiente comando desde el directorio de instalación:", "This %s instance is currently in maintenance mode, which may take a while." : "Está instancia %s está en modo mantenimiento, por lo que puede llevar un tiempo.", - "This page will refresh itself when the %s instance is available again." : "La página se refrescará cuando la instalación %s vuelva a estar disponible." + "This page will refresh itself when the %s instance is available again." : "La página se refrescará cuando la instalación %s vuelva a estar disponible.", + "Repair error: " : "Error que reparar:", + "Password can not be changed. Please contact your administrator." : "La contraseña no se puede cambiar. Por favor, contacte a su administrador." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/es_AR.js b/core/l10n/es_AR.js index d556884a09591..6dd084d19415f 100644 --- a/core/l10n/es_AR.js +++ b/core/l10n/es_AR.js @@ -152,6 +152,8 @@ OC.L10N.register( "This ownCloud instance is currently in single user mode." : "Esta instancia de ownCloud está en modo de usuario único.", "This means only administrators can use the instance." : "Esto significa que solo administradores pueden usar esta instancia.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte su administrador de sistema si este mensaje persiste o aparece inesperadamente.", - "Thank you for your patience." : "Gracias por su paciencia." + "Thank you for your patience." : "Gracias por su paciencia.", + "Error loading file picker template: {error}" : "Error cargando la plantilla del selector de archivo: {error}", + "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Tu directorio de datos y tus archivos probablemente son accesibles a través de internet, ya que el archivo .htaccess no está funcionando." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/es_AR.json b/core/l10n/es_AR.json index cd8ee56e11b88..d515d2d33945e 100644 --- a/core/l10n/es_AR.json +++ b/core/l10n/es_AR.json @@ -150,6 +150,8 @@ "This ownCloud instance is currently in single user mode." : "Esta instancia de ownCloud está en modo de usuario único.", "This means only administrators can use the instance." : "Esto significa que solo administradores pueden usar esta instancia.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte su administrador de sistema si este mensaje persiste o aparece inesperadamente.", - "Thank you for your patience." : "Gracias por su paciencia." + "Thank you for your patience." : "Gracias por su paciencia.", + "Error loading file picker template: {error}" : "Error cargando la plantilla del selector de archivo: {error}", + "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Tu directorio de datos y tus archivos probablemente son accesibles a través de internet, ya que el archivo .htaccess no está funcionando." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/es_MX.js b/core/l10n/es_MX.js index 9c68992ffaebe..944c660bda469 100644 --- a/core/l10n/es_MX.js +++ b/core/l10n/es_MX.js @@ -146,6 +146,8 @@ OC.L10N.register( "This ownCloud instance is currently in single user mode." : "Esta instalación de ownCloud se encuentra en modo de usuario único.", "This means only administrators can use the instance." : "Esto quiere decir que solo un administrador puede usarla.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte con su administrador de sistemas si este mensaje persiste o aparece de forma inesperada.", - "Thank you for your patience." : "Gracias por su paciencia." + "Thank you for your patience." : "Gracias por su paciencia.", + "Error loading file picker template: {error}" : "Error cargando plantilla del seleccionador de archivos: {error}", + "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Su directorio de datos y sus archivos probablemente sean accesibles a través de internet ya que el archivo .htaccess no funciona." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/es_MX.json b/core/l10n/es_MX.json index 9c7f89d95d3b1..133f3f720ca89 100644 --- a/core/l10n/es_MX.json +++ b/core/l10n/es_MX.json @@ -144,6 +144,8 @@ "This ownCloud instance is currently in single user mode." : "Esta instalación de ownCloud se encuentra en modo de usuario único.", "This means only administrators can use the instance." : "Esto quiere decir que solo un administrador puede usarla.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte con su administrador de sistemas si este mensaje persiste o aparece de forma inesperada.", - "Thank you for your patience." : "Gracias por su paciencia." + "Thank you for your patience." : "Gracias por su paciencia.", + "Error loading file picker template: {error}" : "Error cargando plantilla del seleccionador de archivos: {error}", + "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Su directorio de datos y sus archivos probablemente sean accesibles a través de internet ya que el archivo .htaccess no funciona." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/et_EE.js b/core/l10n/et_EE.js index 21595418ea5f4..687402f637639 100644 --- a/core/l10n/et_EE.js +++ b/core/l10n/et_EE.js @@ -253,6 +253,9 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Enne jätkamist veendu, et andmebaas, seadete ning andmete kataloog on varundatud.", "Start update" : "Käivita uuendus", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Suurtel saitidel aegumise vältimiseks võid sa paigalduskaustas käivitada järgmise käsu:", - "This page will refresh itself when the %s instance is available again." : "Se leht laetakse uuesti, kui %s instantsi on uuesti saadaval." + "This page will refresh itself when the %s instance is available again." : "Se leht laetakse uuesti, kui %s instantsi on uuesti saadaval.", + "Error loading file picker template: {error}" : "Viga failivalija malli laadimisel: {error}", + "Password can not be changed. Please contact your administrator." : "Parooli ei saa muuta. Palun kontakteeru oma süsteemihalduriga.", + "Share with users, groups or remote users …" : "Jaga kasutajate, gruppide või eemal olevate kasutajatega ..." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/et_EE.json b/core/l10n/et_EE.json index 021cd28fb136f..e84690422b779 100644 --- a/core/l10n/et_EE.json +++ b/core/l10n/et_EE.json @@ -251,6 +251,9 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Enne jätkamist veendu, et andmebaas, seadete ning andmete kataloog on varundatud.", "Start update" : "Käivita uuendus", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Suurtel saitidel aegumise vältimiseks võid sa paigalduskaustas käivitada järgmise käsu:", - "This page will refresh itself when the %s instance is available again." : "Se leht laetakse uuesti, kui %s instantsi on uuesti saadaval." + "This page will refresh itself when the %s instance is available again." : "Se leht laetakse uuesti, kui %s instantsi on uuesti saadaval.", + "Error loading file picker template: {error}" : "Viga failivalija malli laadimisel: {error}", + "Password can not be changed. Please contact your administrator." : "Parooli ei saa muuta. Palun kontakteeru oma süsteemihalduriga.", + "Share with users, groups or remote users …" : "Jaga kasutajate, gruppide või eemal olevate kasutajatega ..." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/eu.js b/core/l10n/eu.js index c352fc6d091b7..b7e7c734afd9b 100644 --- a/core/l10n/eu.js +++ b/core/l10n/eu.js @@ -214,6 +214,8 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Ekin aurretik egiazta ezazu datu basearen, ezarpenen karpetaren eta datuen karpetaren babeskopia duzula.", "Start update" : "Hasi eguneraketa", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Instalazio handien itxarote-denbora saihesteko, ondoko komandoa exekuta dezakezu instalazio direktoriotik:", - "This page will refresh itself when the %s instance is available again." : "Orri honek bere burua eguneratuko du %s instantzia berriz prest dagoenean." + "This page will refresh itself when the %s instance is available again." : "Orri honek bere burua eguneratuko du %s instantzia berriz prest dagoenean.", + "Error loading file picker template: {error}" : "Errorea fitxategi hautatzaile txantiloiak kargatzerakoan: {error}", + "Password can not be changed. Please contact your administrator." : "Ezin da pasahitza aldatu. Mesedez jarri harremetan zure administradorearekin." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/eu.json b/core/l10n/eu.json index 8bdb8e754e813..4d4ebd62e2306 100644 --- a/core/l10n/eu.json +++ b/core/l10n/eu.json @@ -212,6 +212,8 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Ekin aurretik egiazta ezazu datu basearen, ezarpenen karpetaren eta datuen karpetaren babeskopia duzula.", "Start update" : "Hasi eguneraketa", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Instalazio handien itxarote-denbora saihesteko, ondoko komandoa exekuta dezakezu instalazio direktoriotik:", - "This page will refresh itself when the %s instance is available again." : "Orri honek bere burua eguneratuko du %s instantzia berriz prest dagoenean." + "This page will refresh itself when the %s instance is available again." : "Orri honek bere burua eguneratuko du %s instantzia berriz prest dagoenean.", + "Error loading file picker template: {error}" : "Errorea fitxategi hautatzaile txantiloiak kargatzerakoan: {error}", + "Password can not be changed. Please contact your administrator." : "Ezin da pasahitza aldatu. Mesedez jarri harremetan zure administradorearekin." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/fa.js b/core/l10n/fa.js index ce0f7aa40e131..1cf325c87594c 100644 --- a/core/l10n/fa.js +++ b/core/l10n/fa.js @@ -221,6 +221,8 @@ OC.L10N.register( "%s will be updated to version %s" : "%s به نسخه‌ی %s بروزرسانی خواهد شد", "These apps will be updated:" : "این برنامه‌ها بروزرسانی شده‌اند:", "The theme %s has been disabled." : "قالب %s غیر فعال شد.", - "Start update" : "اغاز به روز رسانی" + "Start update" : "اغاز به روز رسانی", + "Error loading file picker template: {error}" : "خطا در بارگذاری قالب انتخاب فایل : {error}", + "Password can not be changed. Please contact your administrator." : "رمز عبور نمی تواند تغییر بکند . لطفا با مدیر سیستم تماس بگیرید ." }, "nplurals=1; plural=0;"); diff --git a/core/l10n/fa.json b/core/l10n/fa.json index 8ef4c8b559437..f4d6b5b2f8c5b 100644 --- a/core/l10n/fa.json +++ b/core/l10n/fa.json @@ -219,6 +219,8 @@ "%s will be updated to version %s" : "%s به نسخه‌ی %s بروزرسانی خواهد شد", "These apps will be updated:" : "این برنامه‌ها بروزرسانی شده‌اند:", "The theme %s has been disabled." : "قالب %s غیر فعال شد.", - "Start update" : "اغاز به روز رسانی" + "Start update" : "اغاز به روز رسانی", + "Error loading file picker template: {error}" : "خطا در بارگذاری قالب انتخاب فایل : {error}", + "Password can not be changed. Please contact your administrator." : "رمز عبور نمی تواند تغییر بکند . لطفا با مدیر سیستم تماس بگیرید ." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/fi_FI.js b/core/l10n/fi_FI.js index c6550a1733cec..a3108adf8348f 100644 --- a/core/l10n/fi_FI.js +++ b/core/l10n/fi_FI.js @@ -299,6 +299,9 @@ OC.L10N.register( "Start update" : "Käynnistä päivitys", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Välttääksesi aikakatkaisuja suurikokoisten asennusten kanssa, voit suorittaa vaihtoehtoisesti seuraavan komennon asennushakemistossa:", "This %s instance is currently in maintenance mode, which may take a while." : "Tämä %s-instanssi on parhaillaan huoltotilassa, huollossa saattaa kestää hetki.", - "This page will refresh itself when the %s instance is available again." : "Tämä sivu päivittää itsensä, kun %s on jälleen käytettävissä." + "This page will refresh itself when the %s instance is available again." : "Tämä sivu päivittää itsensä, kun %s on jälleen käytettävissä.", + "Error loading file picker template: {error}" : "Virhe ladatessa tiedostopohjia: {error}", + "Password can not be changed. Please contact your administrator." : "Salasanan vaihtaminen ei onnistunut. Ota yhteys ylläpitäjään.", + "Sun." : "Su" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/fi_FI.json b/core/l10n/fi_FI.json index 58f2edb84024d..daa8fd5788a32 100644 --- a/core/l10n/fi_FI.json +++ b/core/l10n/fi_FI.json @@ -297,6 +297,9 @@ "Start update" : "Käynnistä päivitys", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Välttääksesi aikakatkaisuja suurikokoisten asennusten kanssa, voit suorittaa vaihtoehtoisesti seuraavan komennon asennushakemistossa:", "This %s instance is currently in maintenance mode, which may take a while." : "Tämä %s-instanssi on parhaillaan huoltotilassa, huollossa saattaa kestää hetki.", - "This page will refresh itself when the %s instance is available again." : "Tämä sivu päivittää itsensä, kun %s on jälleen käytettävissä." + "This page will refresh itself when the %s instance is available again." : "Tämä sivu päivittää itsensä, kun %s on jälleen käytettävissä.", + "Error loading file picker template: {error}" : "Virhe ladatessa tiedostopohjia: {error}", + "Password can not be changed. Please contact your administrator." : "Salasanan vaihtaminen ei onnistunut. Ota yhteys ylläpitäjään.", + "Sun." : "Su" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/fil.js b/core/l10n/fil.js index 572404948edb5..f0da933fff1d3 100644 --- a/core/l10n/fil.js +++ b/core/l10n/fil.js @@ -3,6 +3,28 @@ OC.L10N.register( { "_{count} file conflict_::_{count} file conflicts_" : ["",""], "_download %n file_::_download %n files_" : ["",""], - "_{count} search result in other places_::_{count} search results in other places_" : ["",""] + "_{count} search result in other places_::_{count} search results in other places_" : ["",""], + "April" : "Abril", + "August" : "Agosto", + "December" : "Disyembre", + "Error" : "Error", + "February" : "Pebrero", + "Friday" : "Biyernes", + "January" : "Enero", + "July" : "Hulyo", + "June" : "Hunyo", + "March" : "Marso", + "May" : "Mayo", + "Monday" : "Lunes", + "November" : "Nobyembre", + "October" : "Oktubre", + "Password" : "Password", + "Saturday" : "Sabado", + "September" : "Setyembre", + "Sunday" : "Linggo", + "Thursday" : "Huwebes", + "Tuesday" : "Martes", + "Username" : "Username", + "Wednesday" : "Miyerkules" }, "nplurals=2; plural=(n > 1);"); diff --git a/core/l10n/fil.json b/core/l10n/fil.json index b43ffe08ed377..5b85bdda649aa 100644 --- a/core/l10n/fil.json +++ b/core/l10n/fil.json @@ -1,6 +1,28 @@ { "translations": { "_{count} file conflict_::_{count} file conflicts_" : ["",""], "_download %n file_::_download %n files_" : ["",""], - "_{count} search result in other places_::_{count} search results in other places_" : ["",""] + "_{count} search result in other places_::_{count} search results in other places_" : ["",""], + "April" : "Abril", + "August" : "Agosto", + "December" : "Disyembre", + "Error" : "Error", + "February" : "Pebrero", + "Friday" : "Biyernes", + "January" : "Enero", + "July" : "Hulyo", + "June" : "Hunyo", + "March" : "Marso", + "May" : "Mayo", + "Monday" : "Lunes", + "November" : "Nobyembre", + "October" : "Oktubre", + "Password" : "Password", + "Saturday" : "Sabado", + "September" : "Setyembre", + "Sunday" : "Linggo", + "Thursday" : "Huwebes", + "Tuesday" : "Martes", + "Username" : "Username", + "Wednesday" : "Miyerkules" },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/core/l10n/fr.js b/core/l10n/fr.js index 15ff13d1b1dc5..ce1c1fcd0007d 100644 --- a/core/l10n/fr.js +++ b/core/l10n/fr.js @@ -297,6 +297,9 @@ OC.L10N.register( "Start update" : "Démarrer la mise à jour", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Afin d'éviter les timeouts avec les installations de volume conséquent, vous pouvez exécuter la commande suivante depuis le répertoire d'installation :", "This %s instance is currently in maintenance mode, which may take a while." : "Cette instance de %s est en cours de maintenance, cela peut prendre du temps.", - "This page will refresh itself when the %s instance is available again." : "Cette page se rafraîchira d'elle-même lorsque l'instance %s sera à nouveau disponible." + "This page will refresh itself when the %s instance is available again." : "Cette page se rafraîchira d'elle-même lorsque l'instance %s sera à nouveau disponible.", + "Collaborative tags" : "Étiquettes collaboratives ", + "Error loading file picker template: {error}" : "Erreur lors du chargement du modèle du sélecteur de fichiers : {error}", + "Password can not be changed. Please contact your administrator." : "Le mot de passe ne peut être modifié. Veuillez contacter votre administrateur." }, "nplurals=2; plural=(n > 1);"); diff --git a/core/l10n/fr.json b/core/l10n/fr.json index 55d603f9b9f62..de143d662cbf5 100644 --- a/core/l10n/fr.json +++ b/core/l10n/fr.json @@ -295,6 +295,9 @@ "Start update" : "Démarrer la mise à jour", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Afin d'éviter les timeouts avec les installations de volume conséquent, vous pouvez exécuter la commande suivante depuis le répertoire d'installation :", "This %s instance is currently in maintenance mode, which may take a while." : "Cette instance de %s est en cours de maintenance, cela peut prendre du temps.", - "This page will refresh itself when the %s instance is available again." : "Cette page se rafraîchira d'elle-même lorsque l'instance %s sera à nouveau disponible." + "This page will refresh itself when the %s instance is available again." : "Cette page se rafraîchira d'elle-même lorsque l'instance %s sera à nouveau disponible.", + "Collaborative tags" : "Étiquettes collaboratives ", + "Error loading file picker template: {error}" : "Erreur lors du chargement du modèle du sélecteur de fichiers : {error}", + "Password can not be changed. Please contact your administrator." : "Le mot de passe ne peut être modifié. Veuillez contacter votre administrateur." },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/core/l10n/gl.js b/core/l10n/gl.js index 01a055a328eaa..087eb7c43cfbe 100644 --- a/core/l10n/gl.js +++ b/core/l10n/gl.js @@ -252,6 +252,8 @@ OC.L10N.register( "Start update" : "Iniciar a actualización", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera nas instalacións grandes, no seu lugar pode executar a seguinte orde desde o directorio de instalación:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instancia de %s atopase en modo de mantemento, isto pode levar un anaco.", - "This page will refresh itself when the %s instance is available again." : "Esta páxina actualizarase automaticamente cando a instancia de %s estea dispoñíbel de novo." + "This page will refresh itself when the %s instance is available again." : "Esta páxina actualizarase automaticamente cando a instancia de %s estea dispoñíbel de novo.", + "Error loading file picker template: {error}" : "Produciuse un erro ao cargar o modelo do selector: {error}", + "Password can not be changed. Please contact your administrator." : "Non é posíbel cambiar o contrasinal. Póñase en contacto co administrador." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/gl.json b/core/l10n/gl.json index ef41d007edc6b..6a42a2bcadc9c 100644 --- a/core/l10n/gl.json +++ b/core/l10n/gl.json @@ -250,6 +250,8 @@ "Start update" : "Iniciar a actualización", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera nas instalacións grandes, no seu lugar pode executar a seguinte orde desde o directorio de instalación:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instancia de %s atopase en modo de mantemento, isto pode levar un anaco.", - "This page will refresh itself when the %s instance is available again." : "Esta páxina actualizarase automaticamente cando a instancia de %s estea dispoñíbel de novo." + "This page will refresh itself when the %s instance is available again." : "Esta páxina actualizarase automaticamente cando a instancia de %s estea dispoñíbel de novo.", + "Error loading file picker template: {error}" : "Produciuse un erro ao cargar o modelo do selector: {error}", + "Password can not be changed. Please contact your administrator." : "Non é posíbel cambiar o contrasinal. Póñase en contacto co administrador." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/he.js b/core/l10n/he.js index 9a4dca6db4b06..8a2ef4ba3db58 100644 --- a/core/l10n/he.js +++ b/core/l10n/he.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "התחלת עדכון", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "למניעת פסקי זמן בהתקנות גדולות, ניתן במקום להריץ את הפקודה הבאה בתיקיית ההתקנה שלך:", "This %s instance is currently in maintenance mode, which may take a while." : "הפעלה %s זו כרגע במצב אחזקה, שתמשך זמן מה.", - "This page will refresh itself when the %s instance is available again." : "עמוד זה ירענן את עצמו כשהפעלת %s תהיה זמינה שוב." + "This page will refresh itself when the %s instance is available again." : "עמוד זה ירענן את עצמו כשהפעלת %s תהיה זמינה שוב.", + "Error loading file picker template: {error}" : "שגיאה בטעינת תבנית בחירת הקבצים: {error}", + "Password can not be changed. Please contact your administrator." : "לא ניתן לשנות את הסיסמא. יש לפנות למנהל שלך." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/he.json b/core/l10n/he.json index 0cc3a80da2061..dbde292af5543 100644 --- a/core/l10n/he.json +++ b/core/l10n/he.json @@ -297,6 +297,8 @@ "Start update" : "התחלת עדכון", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "למניעת פסקי זמן בהתקנות גדולות, ניתן במקום להריץ את הפקודה הבאה בתיקיית ההתקנה שלך:", "This %s instance is currently in maintenance mode, which may take a while." : "הפעלה %s זו כרגע במצב אחזקה, שתמשך זמן מה.", - "This page will refresh itself when the %s instance is available again." : "עמוד זה ירענן את עצמו כשהפעלת %s תהיה זמינה שוב." + "This page will refresh itself when the %s instance is available again." : "עמוד זה ירענן את עצמו כשהפעלת %s תהיה זמינה שוב.", + "Error loading file picker template: {error}" : "שגיאה בטעינת תבנית בחירת הקבצים: {error}", + "Password can not be changed. Please contact your administrator." : "לא ניתן לשנות את הסיסמא. יש לפנות למנהל שלך." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/hr.js b/core/l10n/hr.js index 52662c400d661..0b210fd928131 100644 --- a/core/l10n/hr.js +++ b/core/l10n/hr.js @@ -213,6 +213,8 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Prije nego li nastavite, molimo osigurajte da su baza podataka, mapa konfiguracije i mapaza podatke sigurnosno kopirani.", "Start update" : "Započnite ažuriranje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da biste izbjegli vremensko prekoračenje s većim instalacijama, možete pokrenutisljedeću naredbu iz svoga instalacijskog direktorija:", - "This page will refresh itself when the %s instance is available again." : "Stranica će se sama osvježiti kada %s bude ponovo dostupno." + "This page will refresh itself when the %s instance is available again." : "Stranica će se sama osvježiti kada %s bude ponovo dostupno.", + "Error loading file picker template: {error}" : "Pogrešno učitavanje predloška za pronalazača datoteke: {error}", + "Password can not be changed. Please contact your administrator." : "Lozinku nije moguće promijeniti. Molimo kontaktirajte svog administratora." }, "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); diff --git a/core/l10n/hr.json b/core/l10n/hr.json index 8ca7bfa748f14..be85dc7ace9c0 100644 --- a/core/l10n/hr.json +++ b/core/l10n/hr.json @@ -211,6 +211,8 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Prije nego li nastavite, molimo osigurajte da su baza podataka, mapa konfiguracije i mapaza podatke sigurnosno kopirani.", "Start update" : "Započnite ažuriranje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da biste izbjegli vremensko prekoračenje s većim instalacijama, možete pokrenutisljedeću naredbu iz svoga instalacijskog direktorija:", - "This page will refresh itself when the %s instance is available again." : "Stranica će se sama osvježiti kada %s bude ponovo dostupno." + "This page will refresh itself when the %s instance is available again." : "Stranica će se sama osvježiti kada %s bude ponovo dostupno.", + "Error loading file picker template: {error}" : "Pogrešno učitavanje predloška za pronalazača datoteke: {error}", + "Password can not be changed. Please contact your administrator." : "Lozinku nije moguće promijeniti. Molimo kontaktirajte svog administratora." },"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;" } \ No newline at end of file diff --git a/core/l10n/hu_HU.js b/core/l10n/hu_HU.js index 305fd8140520d..21c5a026d2f15 100644 --- a/core/l10n/hu_HU.js +++ b/core/l10n/hu_HU.js @@ -286,6 +286,9 @@ OC.L10N.register( "Start update" : "A frissítés megkezdése", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, ha inkább a következő parancsot adja ki a telepítési alkönyvtárban:", "This %s instance is currently in maintenance mode, which may take a while." : "Ez a %s folyamat éppen karbantartó üzemmódban van, ami eltarthat egy darabig.", - "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető." + "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető.", + "Error loading file picker template: {error}" : "Nem sikerült betölteni a fájlkiválasztó sablont: {error}", + "not assignable" : "nem hozzárendelhető", + "Password can not be changed. Please contact your administrator." : "A jelszót nem lehet visszaállítani. Kérjük, lépjen kapcsolatba a redszergazdával." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/hu_HU.json b/core/l10n/hu_HU.json index 9c6818ca34976..5701af2625102 100644 --- a/core/l10n/hu_HU.json +++ b/core/l10n/hu_HU.json @@ -284,6 +284,9 @@ "Start update" : "A frissítés megkezdése", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, ha inkább a következő parancsot adja ki a telepítési alkönyvtárban:", "This %s instance is currently in maintenance mode, which may take a while." : "Ez a %s folyamat éppen karbantartó üzemmódban van, ami eltarthat egy darabig.", - "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető." + "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető.", + "Error loading file picker template: {error}" : "Nem sikerült betölteni a fájlkiválasztó sablont: {error}", + "not assignable" : "nem hozzárendelhető", + "Password can not be changed. Please contact your administrator." : "A jelszót nem lehet visszaállítani. Kérjük, lépjen kapcsolatba a redszergazdával." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/hy.js b/core/l10n/hy.js index 1899f4d7eebc9..2dec1ba1afbec 100644 --- a/core/l10n/hy.js +++ b/core/l10n/hy.js @@ -60,6 +60,45 @@ OC.L10N.register( "Add" : "Ավելացնել", "Personal" : "Անձնական", "Username" : "Օգտանուն", - "New password" : "Նոր գաղտնաբառ" + "New password" : "Նոր գաղտնաբառ", + "Allow editing" : "Թույլատրել խմբագրումը", + "can edit" : "կարող է խմբագրել", + "can share" : "կարող է տարածել", + "change" : "փոխել", + "Choose" : "Ընտրել", + "Code: %s" : "Կոդ. %s", + "Continue" : "Շարունակել", + "create" : "ստեղծել", + "Data folder" : "Տվյալների պանակ", + "Email link to person" : "Ուղարկել հղումը ոմնին", + "Error while sharing" : "Սխալ տարածելիս", + "File not found" : "Ֆայլը չգտնվեց", + "File: %s" : "Ֆայլ. %s", + "Fr" : "Ուրբ", + "Help" : "Օգնություն", + "invisible" : "անտեսանելի", + "Line: %s" : "Տող. %s", + "Log in" : "Մուտք գործել", + "Log out" : "Դուրս գալ", + "Message: %s" : "Նամակ. %s", + "Mo" : "Երկ", + "new" : "նոր", + "New Files" : "Նոր ֆայլեր", + "New Password" : "Նոր գաղտնաբառ", + "Ok" : "Լավ", + "remote" : "հեռակա", + "Sa" : "Շաբ", + "Search" : "Փնտրել", + "Security warning" : "Անվտանգության զգուշացում", + "Shared" : "Տարածած", + "So-so password" : "Միջինոտ գաղտնաբառ", + "Strong password" : "Ուժեղ գաղտնաբառ", + "Su" : "Կիր", + "sunny" : "արևոտ", + "Th" : "Հնգ", + "Trace" : "Հետք", + "Tu" : "Երք", + "Type: %s" : "Տիպ. %s", + "We" : "Չոր" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/hy.json b/core/l10n/hy.json index 23d99811203fd..d78a0f2e0d7ae 100644 --- a/core/l10n/hy.json +++ b/core/l10n/hy.json @@ -58,6 +58,45 @@ "Add" : "Ավելացնել", "Personal" : "Անձնական", "Username" : "Օգտանուն", - "New password" : "Նոր գաղտնաբառ" + "New password" : "Նոր գաղտնաբառ", + "Allow editing" : "Թույլատրել խմբագրումը", + "can edit" : "կարող է խմբագրել", + "can share" : "կարող է տարածել", + "change" : "փոխել", + "Choose" : "Ընտրել", + "Code: %s" : "Կոդ. %s", + "Continue" : "Շարունակել", + "create" : "ստեղծել", + "Data folder" : "Տվյալների պանակ", + "Email link to person" : "Ուղարկել հղումը ոմնին", + "Error while sharing" : "Սխալ տարածելիս", + "File not found" : "Ֆայլը չգտնվեց", + "File: %s" : "Ֆայլ. %s", + "Fr" : "Ուրբ", + "Help" : "Օգնություն", + "invisible" : "անտեսանելի", + "Line: %s" : "Տող. %s", + "Log in" : "Մուտք գործել", + "Log out" : "Դուրս գալ", + "Message: %s" : "Նամակ. %s", + "Mo" : "Երկ", + "new" : "նոր", + "New Files" : "Նոր ֆայլեր", + "New Password" : "Նոր գաղտնաբառ", + "Ok" : "Լավ", + "remote" : "հեռակա", + "Sa" : "Շաբ", + "Search" : "Փնտրել", + "Security warning" : "Անվտանգության զգուշացում", + "Shared" : "Տարածած", + "So-so password" : "Միջինոտ գաղտնաբառ", + "Strong password" : "Ուժեղ գաղտնաբառ", + "Su" : "Կիր", + "sunny" : "արևոտ", + "Th" : "Հնգ", + "Trace" : "Հետք", + "Tu" : "Երք", + "Type: %s" : "Տիպ. %s", + "We" : "Չոր" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/ia.js b/core/l10n/ia.js index e6ee2d05141ea..06e05e94497ad 100644 --- a/core/l10n/ia.js +++ b/core/l10n/ia.js @@ -155,6 +155,7 @@ OC.L10N.register( "New Password" : "Nove contrasigno", "Reset password" : "Reinitialisar contrasigno", "Thank you for your patience." : "Gratias pro tu patientia.", - "Start update" : "Initia actualisation" + "Start update" : "Initia actualisation", + "Password can not be changed. Please contact your administrator." : "Contrasigno non pote esser modificate. Pro favor continge tu administrator." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/ia.json b/core/l10n/ia.json index 2afceccdf509e..53b891976c14a 100644 --- a/core/l10n/ia.json +++ b/core/l10n/ia.json @@ -153,6 +153,7 @@ "New Password" : "Nove contrasigno", "Reset password" : "Reinitialisar contrasigno", "Thank you for your patience." : "Gratias pro tu patientia.", - "Start update" : "Initia actualisation" + "Start update" : "Initia actualisation", + "Password can not be changed. Please contact your administrator." : "Contrasigno non pote esser modificate. Pro favor continge tu administrator." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/id.js b/core/l10n/id.js index fb37b3a06ca28..e193bbb45466c 100644 --- a/core/l10n/id.js +++ b/core/l10n/id.js @@ -270,6 +270,9 @@ OC.L10N.register( "Start update" : "Jalankan pembaruan", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Untuk menghindari waktu habis dengan instalasi yang lebih besar, Anda bisa menjalankan perintah berikut dari direktori instalasi Anda:", "This %s instance is currently in maintenance mode, which may take a while." : "Instansi %s ini sedang dalam modus pemeliharaan, mungkin memerlukan beberapa saat.", - "This page will refresh itself when the %s instance is available again." : "Halaman ini akan disegarkan dengan sendiri saat instansi %s tersebut tersedia kembali." + "This page will refresh itself when the %s instance is available again." : "Halaman ini akan disegarkan dengan sendiri saat instansi %s tersebut tersedia kembali.", + "Error loading file picker template: {error}" : "Kesalahan saat memuat templat berkas pemilih: {error}", + "Password can not be changed. Please contact your administrator." : "Sandi tidak dapat diubah. Silakan hubungi administrator Anda", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Server ini tidak tersambung ke internet. Ini berarti beberapa fitur seperti me-mount penyimpanan eksternal, notifikasi pembaruan atau instalasi aplikasi pihak ketiga tidak akan bekerja. Mengakses berkas secara remote dan mengirim notifikasi email juga tidak bekerja. Kami menyarankan untuk mengaktifkan koneksi internet untuk server ini jika Anda ingin memiliki fitur ini." }, "nplurals=1; plural=0;"); diff --git a/core/l10n/id.json b/core/l10n/id.json index bd2108f87c2e5..73fd94954cead 100644 --- a/core/l10n/id.json +++ b/core/l10n/id.json @@ -268,6 +268,9 @@ "Start update" : "Jalankan pembaruan", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Untuk menghindari waktu habis dengan instalasi yang lebih besar, Anda bisa menjalankan perintah berikut dari direktori instalasi Anda:", "This %s instance is currently in maintenance mode, which may take a while." : "Instansi %s ini sedang dalam modus pemeliharaan, mungkin memerlukan beberapa saat.", - "This page will refresh itself when the %s instance is available again." : "Halaman ini akan disegarkan dengan sendiri saat instansi %s tersebut tersedia kembali." + "This page will refresh itself when the %s instance is available again." : "Halaman ini akan disegarkan dengan sendiri saat instansi %s tersebut tersedia kembali.", + "Error loading file picker template: {error}" : "Kesalahan saat memuat templat berkas pemilih: {error}", + "Password can not be changed. Please contact your administrator." : "Sandi tidak dapat diubah. Silakan hubungi administrator Anda", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Server ini tidak tersambung ke internet. Ini berarti beberapa fitur seperti me-mount penyimpanan eksternal, notifikasi pembaruan atau instalasi aplikasi pihak ketiga tidak akan bekerja. Mengakses berkas secara remote dan mengirim notifikasi email juga tidak bekerja. Kami menyarankan untuk mengaktifkan koneksi internet untuk server ini jika Anda ingin memiliki fitur ini." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/is.js b/core/l10n/is.js index 40388ee163eac..d6f419b14bc5b 100644 --- a/core/l10n/is.js +++ b/core/l10n/is.js @@ -295,6 +295,10 @@ OC.L10N.register( "Start update" : "Hefja uppfærslu", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Til að forðast að falla á tímamörkum með stærri uppsetningar, getur þú í staðinn keyrt eftirfarandi skipun úr uppsetningarmöppunni:", "This %s instance is currently in maintenance mode, which may take a while." : "Þessi %s er nú í viðhaldsham, sem getur tekið smá stund.", - "This page will refresh itself when the %s instance is available again." : "Þessi síða mun uppfæra sig þegar %s er í boði á ný." + "This page will refresh itself when the %s instance is available again." : "Þessi síða mun uppfæra sig þegar %s er í boði á ný.", + "Collaborative tags" : "Samstarfsmerkingar", + "Dismiss" : "Hafna", + "Error loading file picker template: {error}" : "Villa við að hlaða inn sniðmáti fyrir skráaveljara: {error}", + "Password can not be changed. Please contact your administrator." : "Ekki er hægt að breyta lykilorði. Hafðu samband við kerfisstjóra." }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/core/l10n/is.json b/core/l10n/is.json index cef73059881d8..23f2c3dcf75ef 100644 --- a/core/l10n/is.json +++ b/core/l10n/is.json @@ -293,6 +293,10 @@ "Start update" : "Hefja uppfærslu", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Til að forðast að falla á tímamörkum með stærri uppsetningar, getur þú í staðinn keyrt eftirfarandi skipun úr uppsetningarmöppunni:", "This %s instance is currently in maintenance mode, which may take a while." : "Þessi %s er nú í viðhaldsham, sem getur tekið smá stund.", - "This page will refresh itself when the %s instance is available again." : "Þessi síða mun uppfæra sig þegar %s er í boði á ný." + "This page will refresh itself when the %s instance is available again." : "Þessi síða mun uppfæra sig þegar %s er í boði á ný.", + "Collaborative tags" : "Samstarfsmerkingar", + "Dismiss" : "Hafna", + "Error loading file picker template: {error}" : "Villa við að hlaða inn sniðmáti fyrir skráaveljara: {error}", + "Password can not be changed. Please contact your administrator." : "Ekki er hægt að breyta lykilorði. Hafðu samband við kerfisstjóra." },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" } \ No newline at end of file diff --git a/core/l10n/it.js b/core/l10n/it.js index c5abb47800288..4af9cb8e532bf 100644 --- a/core/l10n/it.js +++ b/core/l10n/it.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Avvia l'aggiornamento", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per evitare timeout con installazioni di grandi dimensioni, puoi eseguire il comando che segue dalla cartella di installazione:", "This %s instance is currently in maintenance mode, which may take a while." : "Questa istanza di %s è attualmente in manutenzione, potrebbe richiedere del tempo.", - "This page will refresh itself when the %s instance is available again." : "Questa pagina si aggiornerà quando l'istanza di %s sarà nuovamente disponibile." + "This page will refresh itself when the %s instance is available again." : "Questa pagina si aggiornerà quando l'istanza di %s sarà nuovamente disponibile.", + "Error loading file picker template: {error}" : "Errore durante il caricamento del modello del selettore file: {error}", + "Password can not be changed. Please contact your administrator." : "La password non può essere cambiata. Contatta il tuo amministratore." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/it.json b/core/l10n/it.json index a8a463449c90e..52f980873b318 100644 --- a/core/l10n/it.json +++ b/core/l10n/it.json @@ -297,6 +297,8 @@ "Start update" : "Avvia l'aggiornamento", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per evitare timeout con installazioni di grandi dimensioni, puoi eseguire il comando che segue dalla cartella di installazione:", "This %s instance is currently in maintenance mode, which may take a while." : "Questa istanza di %s è attualmente in manutenzione, potrebbe richiedere del tempo.", - "This page will refresh itself when the %s instance is available again." : "Questa pagina si aggiornerà quando l'istanza di %s sarà nuovamente disponibile." + "This page will refresh itself when the %s instance is available again." : "Questa pagina si aggiornerà quando l'istanza di %s sarà nuovamente disponibile.", + "Error loading file picker template: {error}" : "Errore durante il caricamento del modello del selettore file: {error}", + "Password can not be changed. Please contact your administrator." : "La password non può essere cambiata. Contatta il tuo amministratore." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/ja.js b/core/l10n/ja.js index fb20050bb7e7a..974fc6bbdd03b 100644 --- a/core/l10n/ja.js +++ b/core/l10n/ja.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "アップデートを開始", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "大規模なサイトの場合、ブラウザーがタイムアウトする可能性があるため、インストールディレクトリで以下のコマンドを実行することもできます。", "This %s instance is currently in maintenance mode, which may take a while." : "このサーバー %s は現在メンテナンスモードです。しばらくお待ちください。", - "This page will refresh itself when the %s instance is available again." : "この画面は、サーバー %s の再起動後に自動的に更新されます。" + "This page will refresh itself when the %s instance is available again." : "この画面は、サーバー %s の再起動後に自動的に更新されます。", + "Error loading file picker template: {error}" : "ファイル選択テンプレートの読み込みエラー: {error}", + "Password can not be changed. Please contact your administrator." : "パスワードは変更できません。管理者に問い合わせてください。" }, "nplurals=1; plural=0;"); diff --git a/core/l10n/ja.json b/core/l10n/ja.json index 72e81c3d1959e..8f3e9a5fec690 100644 --- a/core/l10n/ja.json +++ b/core/l10n/ja.json @@ -297,6 +297,8 @@ "Start update" : "アップデートを開始", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "大規模なサイトの場合、ブラウザーがタイムアウトする可能性があるため、インストールディレクトリで以下のコマンドを実行することもできます。", "This %s instance is currently in maintenance mode, which may take a while." : "このサーバー %s は現在メンテナンスモードです。しばらくお待ちください。", - "This page will refresh itself when the %s instance is available again." : "この画面は、サーバー %s の再起動後に自動的に更新されます。" + "This page will refresh itself when the %s instance is available again." : "この画面は、サーバー %s の再起動後に自動的に更新されます。", + "Error loading file picker template: {error}" : "ファイル選択テンプレートの読み込みエラー: {error}", + "Password can not be changed. Please contact your administrator." : "パスワードは変更できません。管理者に問い合わせてください。" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/kn.js b/core/l10n/kn.js index 3f45d4ab4c89d..27347c7366836 100644 --- a/core/l10n/kn.js +++ b/core/l10n/kn.js @@ -158,6 +158,7 @@ OC.L10N.register( "This ownCloud instance is currently in single user mode." : "ಪ್ರಸ್ತುತ ಕ್ರಮದಲ್ಲಿ, ಈ OwnCloud ನ್ನು ಕೇವಲ ಒಬ್ಬನೇ ಬಳಕೆದಾರ ಮಾತ್ರ ಬಳಸಬಹುದಾಗಿದೆ.", "This means only administrators can use the instance." : "ಇದರ ಅರ್ಥ, ಸದ್ಯದ ನಿದರ್ಶನದಲ್ಲಿ ನಿರ್ವಾಹಕರು ಮಾತ್ರ ಬಳಸಬಹುದಾಗಿದೆ.", "Thank you for your patience." : "ನಿಮ್ಮ ತಾಳ್ಮೆಗೆ ಧನ್ಯವಾದಗಳು.", - "Start update" : "ನವೀಕರಿಣವನ್ನು ಆರಂಭಿಸಿ" + "Start update" : "ನವೀಕರಿಣವನ್ನು ಆರಂಭಿಸಿ", + "Password can not be changed. Please contact your administrator." : "ಗುಪ್ತಪದ ಬದಲಾವಣೆ ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ." }, "nplurals=1; plural=0;"); diff --git a/core/l10n/kn.json b/core/l10n/kn.json index 316e48955ac80..836e008b69af5 100644 --- a/core/l10n/kn.json +++ b/core/l10n/kn.json @@ -156,6 +156,7 @@ "This ownCloud instance is currently in single user mode." : "ಪ್ರಸ್ತುತ ಕ್ರಮದಲ್ಲಿ, ಈ OwnCloud ನ್ನು ಕೇವಲ ಒಬ್ಬನೇ ಬಳಕೆದಾರ ಮಾತ್ರ ಬಳಸಬಹುದಾಗಿದೆ.", "This means only administrators can use the instance." : "ಇದರ ಅರ್ಥ, ಸದ್ಯದ ನಿದರ್ಶನದಲ್ಲಿ ನಿರ್ವಾಹಕರು ಮಾತ್ರ ಬಳಸಬಹುದಾಗಿದೆ.", "Thank you for your patience." : "ನಿಮ್ಮ ತಾಳ್ಮೆಗೆ ಧನ್ಯವಾದಗಳು.", - "Start update" : "ನವೀಕರಿಣವನ್ನು ಆರಂಭಿಸಿ" + "Start update" : "ನವೀಕರಿಣವನ್ನು ಆರಂಭಿಸಿ", + "Password can not be changed. Please contact your administrator." : "ಗುಪ್ತಪದ ಬದಲಾವಣೆ ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/ko.js b/core/l10n/ko.js index ff71d0fbefec7..db6543f18f761 100644 --- a/core/l10n/ko.js +++ b/core/l10n/ko.js @@ -270,6 +270,13 @@ OC.L10N.register( "Start update" : "업데이트 시작", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "큰 파일을 설치하는 경우 시간이 초과될 수 있으므로, 설치 디렉터리에서 다음 명령을 실행하셔도 됩니다:", "This %s instance is currently in maintenance mode, which may take a while." : "이 %s 인스턴스는 현재 점검 모드입니다. 시간이 걸릴 수도 있습니다.", - "This page will refresh itself when the %s instance is available again." : "%s 인스턴스를 다시 사용할 수 있으면 자동으로 새로 고칩니다." + "This page will refresh itself when the %s instance is available again." : "%s 인스턴스를 다시 사용할 수 있으면 자동으로 새로 고칩니다.", + "Collaborative tags" : "협동 태그", + "Could not unshare" : "공유 해제할 수 없음", + "Error loading file picker template: {error}" : "파일 선택 템플릿을 불러오는 중 오류 발생: {error}", + "Error removing share" : "공유 삭제 중 오류 발생", + "invisible" : "보이지 않음", + "not assignable" : "할당할 수 없음", + "Password can not be changed. Please contact your administrator." : "암호를 변경할 수 없습니다. 관리자에게 문의하십시오." }, "nplurals=1; plural=0;"); diff --git a/core/l10n/ko.json b/core/l10n/ko.json index f1f2dd6796ba4..f63540a6c36fe 100644 --- a/core/l10n/ko.json +++ b/core/l10n/ko.json @@ -268,6 +268,13 @@ "Start update" : "업데이트 시작", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "큰 파일을 설치하는 경우 시간이 초과될 수 있으므로, 설치 디렉터리에서 다음 명령을 실행하셔도 됩니다:", "This %s instance is currently in maintenance mode, which may take a while." : "이 %s 인스턴스는 현재 점검 모드입니다. 시간이 걸릴 수도 있습니다.", - "This page will refresh itself when the %s instance is available again." : "%s 인스턴스를 다시 사용할 수 있으면 자동으로 새로 고칩니다." + "This page will refresh itself when the %s instance is available again." : "%s 인스턴스를 다시 사용할 수 있으면 자동으로 새로 고칩니다.", + "Collaborative tags" : "협동 태그", + "Could not unshare" : "공유 해제할 수 없음", + "Error loading file picker template: {error}" : "파일 선택 템플릿을 불러오는 중 오류 발생: {error}", + "Error removing share" : "공유 삭제 중 오류 발생", + "invisible" : "보이지 않음", + "not assignable" : "할당할 수 없음", + "Password can not be changed. Please contact your administrator." : "암호를 변경할 수 없습니다. 관리자에게 문의하십시오." },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/lb.js b/core/l10n/lb.js index 956d75da53ba5..ad737efcdc73f 100644 --- a/core/l10n/lb.js +++ b/core/l10n/lb.js @@ -120,6 +120,8 @@ OC.L10N.register( "Use the following link to reset your password: {link}" : "Benotz folgende Link fir däi Passwuert zréckzesetzen: {link}", "New password" : "Neit Passwuert", "Reset password" : "Passwuert zréck setzen", - "Thank you for your patience." : "Merci fir deng Gedold." + "Thank you for your patience." : "Merci fir deng Gedold.", + "Fri." : "Fr.", + "Sat." : "Sa." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/lb.json b/core/l10n/lb.json index 39d913782fb79..d6e94c4925bee 100644 --- a/core/l10n/lb.json +++ b/core/l10n/lb.json @@ -118,6 +118,8 @@ "Use the following link to reset your password: {link}" : "Benotz folgende Link fir däi Passwuert zréckzesetzen: {link}", "New password" : "Neit Passwuert", "Reset password" : "Passwuert zréck setzen", - "Thank you for your patience." : "Merci fir deng Gedold." + "Thank you for your patience." : "Merci fir deng Gedold.", + "Fri." : "Fr.", + "Sat." : "Sa." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/lt_LT.js b/core/l10n/lt_LT.js index 756fff5139d20..69493ad73c03a 100644 --- a/core/l10n/lt_LT.js +++ b/core/l10n/lt_LT.js @@ -194,6 +194,8 @@ OC.L10N.register( "This ownCloud instance is currently in single user mode." : "Ši ownCloud sistema yra vieno naudotojo veiksenoje.", "This means only administrators can use the instance." : "Tai reiškia, kad tik administratorius gali naudotis sistema.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Susisiekite su savo sistemos administratoriumi jei šis pranešimas nedingsta arba jei jis pasirodė netikėtai.", - "Thank you for your patience." : "Dėkojame už jūsų kantrumą." + "Thank you for your patience." : "Dėkojame už jūsų kantrumą.", + "Error loading file picker template: {error}" : "Klaida įkeliant failo parinkimo ruošinį: {error}", + "Password can not be changed. Please contact your administrator." : "Slaptažodis negali būti pakeistas, susisiekite su administratoriumi." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/lt_LT.json b/core/l10n/lt_LT.json index 541761aa35f1b..754297ce64ab1 100644 --- a/core/l10n/lt_LT.json +++ b/core/l10n/lt_LT.json @@ -192,6 +192,8 @@ "This ownCloud instance is currently in single user mode." : "Ši ownCloud sistema yra vieno naudotojo veiksenoje.", "This means only administrators can use the instance." : "Tai reiškia, kad tik administratorius gali naudotis sistema.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Susisiekite su savo sistemos administratoriumi jei šis pranešimas nedingsta arba jei jis pasirodė netikėtai.", - "Thank you for your patience." : "Dėkojame už jūsų kantrumą." + "Thank you for your patience." : "Dėkojame už jūsų kantrumą.", + "Error loading file picker template: {error}" : "Klaida įkeliant failo parinkimo ruošinį: {error}", + "Password can not be changed. Please contact your administrator." : "Slaptažodis negali būti pakeistas, susisiekite su administratoriumi." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/lv.js b/core/l10n/lv.js index fb79f8faf4c86..9389f8be74337 100644 --- a/core/l10n/lv.js +++ b/core/l10n/lv.js @@ -119,6 +119,7 @@ OC.L10N.register( "Alternative Logins" : "Alternatīvās pieteikšanās", "Use the following link to reset your password: {link}" : "Izmantojiet šo saiti, lai mainītu paroli: {link}", "New password" : "Jauna parole", - "Reset password" : "Mainīt paroli" + "Reset password" : "Mainīt paroli", + "Password can not be changed. Please contact your administrator." : "Paroli, nevar nomainīt. Lūdzu kontaktēties ar savu administratoru." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/core/l10n/lv.json b/core/l10n/lv.json index 6ffb0e194e7dc..476aabb231fba 100644 --- a/core/l10n/lv.json +++ b/core/l10n/lv.json @@ -117,6 +117,7 @@ "Alternative Logins" : "Alternatīvās pieteikšanās", "Use the following link to reset your password: {link}" : "Izmantojiet šo saiti, lai mainītu paroli: {link}", "New password" : "Jauna parole", - "Reset password" : "Mainīt paroli" + "Reset password" : "Mainīt paroli", + "Password can not be changed. Please contact your administrator." : "Paroli, nevar nomainīt. Lūdzu kontaktēties ar savu administratoru." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/mk.js b/core/l10n/mk.js index 5f66c0cfa8d6a..f9a49b6bb9595 100644 --- a/core/l10n/mk.js +++ b/core/l10n/mk.js @@ -216,6 +216,8 @@ OC.L10N.register( "Contact your system administrator if this message persists or appeared unexpectedly." : "Контактирајте го вашиот систем администратор до колку оваа порака продолжи да се појавува или пак се појавува ненадејно.", "Thank you for your patience." : "Благодариме на вашето трпение.", "These apps will be updated:" : "Следните апликации чќе бидат надградени:", - "Start update" : "Започни ја надградбата" + "Start update" : "Започни ја надградбата", + "Error loading file picker template: {error}" : "Грешка при вчитување на образецот за одбирач на датотеки: {error}", + "Password can not be changed. Please contact your administrator." : "Лозинката не може да се промени. Ве молам контактирајте го вашиот администратор." }, "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); diff --git a/core/l10n/mk.json b/core/l10n/mk.json index 2dceeb1fe5f8e..aa88cd51196cf 100644 --- a/core/l10n/mk.json +++ b/core/l10n/mk.json @@ -214,6 +214,8 @@ "Contact your system administrator if this message persists or appeared unexpectedly." : "Контактирајте го вашиот систем администратор до колку оваа порака продолжи да се појавува или пак се појавува ненадејно.", "Thank you for your patience." : "Благодариме на вашето трпение.", "These apps will be updated:" : "Следните апликации чќе бидат надградени:", - "Start update" : "Започни ја надградбата" + "Start update" : "Започни ја надградбата", + "Error loading file picker template: {error}" : "Грешка при вчитување на образецот за одбирач на датотеки: {error}", + "Password can not be changed. Please contact your administrator." : "Лозинката не може да се промени. Ве молам контактирајте го вашиот администратор." },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" } \ No newline at end of file diff --git a/core/l10n/nb_NO.js b/core/l10n/nb_NO.js index ccae2ebea70d1..f22dc3097a726 100644 --- a/core/l10n/nb_NO.js +++ b/core/l10n/nb_NO.js @@ -299,6 +299,9 @@ OC.L10N.register( "Start update" : "Start oppdatering", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "For å unngå tidsavbrudd ved store installasjoner, kan du i stedet kjøre følgende kommando fra installasjonsmappen:", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instansen er for øyeblikket i vedlikeholdsmodus, noe som kan vare en stund.", - "This page will refresh itself when the %s instance is available again." : "Denne siden vil bli lastet på nytt når %s-instansen er tilgjengelig igjen." + "This page will refresh itself when the %s instance is available again." : "Denne siden vil bli lastet på nytt når %s-instansen er tilgjengelig igjen.", + "Error loading file picker template: {error}" : "Feil ved lasting av filvelger-mal: {error}", + "Fri." : "Fr.", + "Password can not be changed. Please contact your administrator." : "Passordet kan ikke endres. Kontakt administratoren din." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/nb_NO.json b/core/l10n/nb_NO.json index f77e354a3deaa..bc3c3a5128216 100644 --- a/core/l10n/nb_NO.json +++ b/core/l10n/nb_NO.json @@ -297,6 +297,9 @@ "Start update" : "Start oppdatering", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "For å unngå tidsavbrudd ved store installasjoner, kan du i stedet kjøre følgende kommando fra installasjonsmappen:", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instansen er for øyeblikket i vedlikeholdsmodus, noe som kan vare en stund.", - "This page will refresh itself when the %s instance is available again." : "Denne siden vil bli lastet på nytt når %s-instansen er tilgjengelig igjen." + "This page will refresh itself when the %s instance is available again." : "Denne siden vil bli lastet på nytt når %s-instansen er tilgjengelig igjen.", + "Error loading file picker template: {error}" : "Feil ved lasting av filvelger-mal: {error}", + "Fri." : "Fr.", + "Password can not be changed. Please contact your administrator." : "Passordet kan ikke endres. Kontakt administratoren din." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/nds.js b/core/l10n/nds.js index 71bdf00fdcf5c..1e47e348032e7 100644 --- a/core/l10n/nds.js +++ b/core/l10n/nds.js @@ -110,6 +110,8 @@ OC.L10N.register( "Share" : "Teilen", "Delete" : "Löschen", "Personal" : "Persönlich", - "Username" : "Benutzername" + "Username" : "Benutzername", + "Error loading file picker template: {error}" : "Fehler beim Laden der Vorlage zum Auswählen von Dateien: {error}", + "Password can not be changed. Please contact your administrator." : "Das Passwort kann nicht geändert werden. Bitte wende Dich an Deinen Administrator." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/nds.json b/core/l10n/nds.json index 753a6bea64d52..dd245a1576674 100644 --- a/core/l10n/nds.json +++ b/core/l10n/nds.json @@ -108,6 +108,8 @@ "Share" : "Teilen", "Delete" : "Löschen", "Personal" : "Persönlich", - "Username" : "Benutzername" + "Username" : "Benutzername", + "Error loading file picker template: {error}" : "Fehler beim Laden der Vorlage zum Auswählen von Dateien: {error}", + "Password can not be changed. Please contact your administrator." : "Das Passwort kann nicht geändert werden. Bitte wende Dich an Deinen Administrator." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/nl.js b/core/l10n/nl.js index c96c087d5fd28..ef716a07c763d 100644 --- a/core/l10n/nl.js +++ b/core/l10n/nl.js @@ -298,6 +298,10 @@ OC.L10N.register( "Start update" : "Begin de update", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Om time-outs tijdens grotere installaties te voorkomen, kunt u in plaats hiervan de volgende opdracht geven vanaf uw installatiedirectory:", "This %s instance is currently in maintenance mode, which may take a while." : "Deze %s staat momenteel in de onderhoudsstand, dat kan enige tijd duren.", - "This page will refresh itself when the %s instance is available again." : "Deze pagina wordt ververst als de %s-installatie weer beschikbaar is." + "This page will refresh itself when the %s instance is available again." : "Deze pagina wordt ververst als de %s-installatie weer beschikbaar is.", + "Collaborative tags" : "Meewerkende labels", + "Error loading file picker template: {error}" : "Fout bij laden bestandenselecteur sjabloon: {error}", + "Password can not be changed. Please contact your administrator." : "Het wachtwoord kan niet worden gewijzigd. Neem contact op met uw beheerder.", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Deze server heeft geen actieve internetverbinding. Dat betekent dat sommige functies, zoals aankoppelen van externe opslag, notificaties over updates of installatie van apps van 3e partijen niet werken. Ook het benaderen van bestanden vanaf een remote locatie en het versturen van notificatie emails kan mislukken. We adviseren om de internetverbinding voor deze server in te schakelen als u alle functies wilt gebruiken." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/nl.json b/core/l10n/nl.json index 056b0697602b7..78e8f4460c2f5 100644 --- a/core/l10n/nl.json +++ b/core/l10n/nl.json @@ -296,6 +296,10 @@ "Start update" : "Begin de update", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Om time-outs tijdens grotere installaties te voorkomen, kunt u in plaats hiervan de volgende opdracht geven vanaf uw installatiedirectory:", "This %s instance is currently in maintenance mode, which may take a while." : "Deze %s staat momenteel in de onderhoudsstand, dat kan enige tijd duren.", - "This page will refresh itself when the %s instance is available again." : "Deze pagina wordt ververst als de %s-installatie weer beschikbaar is." + "This page will refresh itself when the %s instance is available again." : "Deze pagina wordt ververst als de %s-installatie weer beschikbaar is.", + "Collaborative tags" : "Meewerkende labels", + "Error loading file picker template: {error}" : "Fout bij laden bestandenselecteur sjabloon: {error}", + "Password can not be changed. Please contact your administrator." : "Het wachtwoord kan niet worden gewijzigd. Neem contact op met uw beheerder.", + "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Deze server heeft geen actieve internetverbinding. Dat betekent dat sommige functies, zoals aankoppelen van externe opslag, notificaties over updates of installatie van apps van 3e partijen niet werken. Ook het benaderen van bestanden vanaf een remote locatie en het versturen van notificatie emails kan mislukken. We adviseren om de internetverbinding voor deze server in te schakelen als u alle functies wilt gebruiken." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/nn_NO.js b/core/l10n/nn_NO.js index 82b4e5518fe2e..a84c514e52b90 100644 --- a/core/l10n/nn_NO.js +++ b/core/l10n/nn_NO.js @@ -126,6 +126,7 @@ OC.L10N.register( "Alternative Logins" : "Alternative innloggingar", "Use the following link to reset your password: {link}" : "Klikk følgjande lenkje til å nullstilla passordet ditt: {link}", "New password" : "Nytt passord", - "Reset password" : "Nullstill passord" + "Reset password" : "Nullstill passord", + "Error loading file picker template: {error}" : "Klarte ikkje å lasta filplukkarmal: {error}" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/nn_NO.json b/core/l10n/nn_NO.json index 9e74f280d4293..67cc12bcbf4b2 100644 --- a/core/l10n/nn_NO.json +++ b/core/l10n/nn_NO.json @@ -124,6 +124,7 @@ "Alternative Logins" : "Alternative innloggingar", "Use the following link to reset your password: {link}" : "Klikk følgjande lenkje til å nullstilla passordet ditt: {link}", "New password" : "Nytt passord", - "Reset password" : "Nullstill passord" + "Reset password" : "Nullstill passord", + "Error loading file picker template: {error}" : "Klarte ikkje å lasta filplukkarmal: {error}" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/oc.js b/core/l10n/oc.js index 90cfb7229b2c5..b3419fe4a43e3 100644 --- a/core/l10n/oc.js +++ b/core/l10n/oc.js @@ -270,6 +270,8 @@ OC.L10N.register( "Start update" : "Aviar la mesa a jorn", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per fin d'evitar los timeouts amb las installacions de volum consequent, podètz executar la comanda seguenta dempuèi lo repertòri d'installacion :", "This %s instance is currently in maintenance mode, which may take a while." : "Aquesta instància de %s es en cors de mantenença, aquò pòt prene de temps.", - "This page will refresh itself when the %s instance is available again." : "Aquesta pagina se refrescarà d'ela-meteissa quand l'instància %s serà disponibla tornamai." + "This page will refresh itself when the %s instance is available again." : "Aquesta pagina se refrescarà d'ela-meteissa quand l'instància %s serà disponibla tornamai.", + "Repair error: " : "Error de reparacion :", + "Password can not be changed. Please contact your administrator." : "Lo senhal pòt pas èsser modificat. Contactatz vòstre administrator." }, "nplurals=2; plural=(n > 1);"); diff --git a/core/l10n/oc.json b/core/l10n/oc.json index 4e61d91656742..10aa31c0fe28e 100644 --- a/core/l10n/oc.json +++ b/core/l10n/oc.json @@ -268,6 +268,8 @@ "Start update" : "Aviar la mesa a jorn", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per fin d'evitar los timeouts amb las installacions de volum consequent, podètz executar la comanda seguenta dempuèi lo repertòri d'installacion :", "This %s instance is currently in maintenance mode, which may take a while." : "Aquesta instància de %s es en cors de mantenença, aquò pòt prene de temps.", - "This page will refresh itself when the %s instance is available again." : "Aquesta pagina se refrescarà d'ela-meteissa quand l'instància %s serà disponibla tornamai." + "This page will refresh itself when the %s instance is available again." : "Aquesta pagina se refrescarà d'ela-meteissa quand l'instància %s serà disponibla tornamai.", + "Repair error: " : "Error de reparacion :", + "Password can not be changed. Please contact your administrator." : "Lo senhal pòt pas èsser modificat. Contactatz vòstre administrator." },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/core/l10n/pl.js b/core/l10n/pl.js index 9aeebb939354f..2b11aaf48a776 100644 --- a/core/l10n/pl.js +++ b/core/l10n/pl.js @@ -216,6 +216,15 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Proszę się upewnić, że baza danych, folder konfiguracji oraz folder danych zostały zarchiwizowane przed przejściem dalej.", "Start update" : "Rozpocznij aktualizację", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby uniknąć timeout-ów przy większych instalacjach, możesz zamiast tego uruchomić następującą komendę w katalogu Twojej instalacji:", - "This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna." + "This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna.", + "Error loading file picker template: {error}" : "Błąd podczas ładowania pliku wybranego szablonu: {error}", + "Following apps have been disabled: %s" : "Poniższe aplikacje zostały wyłączone: %s", + "Fr" : "Pt", + "Password can not be changed. Please contact your administrator." : "Hasło nie może zostać zmienione. Skontaktuj się z administratorem.", + "Sa" : "So", + "Su" : "Nd", + "Th" : "Czw", + "Tu" : "Wt", + "We" : "Śr" }, "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/pl.json b/core/l10n/pl.json index 848ef7ec1b555..3121ae8fd09d9 100644 --- a/core/l10n/pl.json +++ b/core/l10n/pl.json @@ -214,6 +214,15 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Proszę się upewnić, że baza danych, folder konfiguracji oraz folder danych zostały zarchiwizowane przed przejściem dalej.", "Start update" : "Rozpocznij aktualizację", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby uniknąć timeout-ów przy większych instalacjach, możesz zamiast tego uruchomić następującą komendę w katalogu Twojej instalacji:", - "This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna." + "This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna.", + "Error loading file picker template: {error}" : "Błąd podczas ładowania pliku wybranego szablonu: {error}", + "Following apps have been disabled: %s" : "Poniższe aplikacje zostały wyłączone: %s", + "Fr" : "Pt", + "Password can not be changed. Please contact your administrator." : "Hasło nie może zostać zmienione. Skontaktuj się z administratorem.", + "Sa" : "So", + "Su" : "Nd", + "Th" : "Czw", + "Tu" : "Wt", + "We" : "Śr" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/pt_BR.js b/core/l10n/pt_BR.js index fc00b309591fd..fada554eb4e95 100644 --- a/core/l10n/pt_BR.js +++ b/core/l10n/pt_BR.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Iniciar atualização", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera com instalações maiores, você pode em vez disso executar o seguinte comando a partir do diretório de instalação:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instância %s está em modo de manutenção, o que pode demorar um pouco.", - "This page will refresh itself when the %s instance is available again." : "Esta página será atualizada automaticamente quando esta instância %s estiver disponível novamente." + "This page will refresh itself when the %s instance is available again." : "Esta página será atualizada automaticamente quando esta instância %s estiver disponível novamente.", + "Error loading file picker template: {error}" : "Erro no seletor de carregamento modelo de arquivos: {error}", + "Password can not be changed. Please contact your administrator." : "A senha não pode ser alterada. Por favor, contate o administrador." }, "nplurals=2; plural=(n > 1);"); diff --git a/core/l10n/pt_BR.json b/core/l10n/pt_BR.json index 659da4f76cfaa..68248a4503dc5 100644 --- a/core/l10n/pt_BR.json +++ b/core/l10n/pt_BR.json @@ -297,6 +297,8 @@ "Start update" : "Iniciar atualização", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera com instalações maiores, você pode em vez disso executar o seguinte comando a partir do diretório de instalação:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instância %s está em modo de manutenção, o que pode demorar um pouco.", - "This page will refresh itself when the %s instance is available again." : "Esta página será atualizada automaticamente quando esta instância %s estiver disponível novamente." + "This page will refresh itself when the %s instance is available again." : "Esta página será atualizada automaticamente quando esta instância %s estiver disponível novamente.", + "Error loading file picker template: {error}" : "Erro no seletor de carregamento modelo de arquivos: {error}", + "Password can not be changed. Please contact your administrator." : "A senha não pode ser alterada. Por favor, contate o administrador." },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/core/l10n/pt_PT.js b/core/l10n/pt_PT.js index e40a01e6afc26..01bc0c7451f44 100644 --- a/core/l10n/pt_PT.js +++ b/core/l10n/pt_PT.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Iniciar atualização", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera com instalações maiores, você pode em vez disso, executar o seguinte comando a partir do diretório de instalação:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instância %s está actualmente em modo de manutenção, o que poderá demorar algum tempo.", - "This page will refresh itself when the %s instance is available again." : "Esta página irá ser recarregada novamente quando a instância %s ficar novamente disponível." + "This page will refresh itself when the %s instance is available again." : "Esta página irá ser recarregada novamente quando a instância %s ficar novamente disponível.", + "Error loading file picker template: {error}" : "Ocorreu um erro ao carregar o modelo do selecionador de ficheiro: {error}", + "Password can not be changed. Please contact your administrator." : "A palavra-passe não pode ser alterada. Por favor, contacte o seu administrador." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/pt_PT.json b/core/l10n/pt_PT.json index a5f3b8aef77df..4e0468bc7b5be 100644 --- a/core/l10n/pt_PT.json +++ b/core/l10n/pt_PT.json @@ -297,6 +297,8 @@ "Start update" : "Iniciar atualização", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Para evitar tempos de espera com instalações maiores, você pode em vez disso, executar o seguinte comando a partir do diretório de instalação:", "This %s instance is currently in maintenance mode, which may take a while." : "Esta instância %s está actualmente em modo de manutenção, o que poderá demorar algum tempo.", - "This page will refresh itself when the %s instance is available again." : "Esta página irá ser recarregada novamente quando a instância %s ficar novamente disponível." + "This page will refresh itself when the %s instance is available again." : "Esta página irá ser recarregada novamente quando a instância %s ficar novamente disponível.", + "Error loading file picker template: {error}" : "Ocorreu um erro ao carregar o modelo do selecionador de ficheiro: {error}", + "Password can not be changed. Please contact your administrator." : "A palavra-passe não pode ser alterada. Por favor, contacte o seu administrador." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/ro.js b/core/l10n/ro.js index 5089ce061be88..1998f2f0276e4 100644 --- a/core/l10n/ro.js +++ b/core/l10n/ro.js @@ -148,6 +148,8 @@ OC.L10N.register( "New Password" : "Noua parolă", "Reset password" : "Resetează parola", "Thank you for your patience." : "Îți mulțumim pentru răbrade.", - "Start update" : "Începe actualizarea" + "Start update" : "Începe actualizarea", + "Error loading file picker template: {error}" : "Eroare la încărcarea șablonului selectorului de fișiere: {error}", + "Password can not be changed. Please contact your administrator." : "Parola nu poate fi modificata. Vă rugăm să contactați administratorul dvs." }, "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); diff --git a/core/l10n/ro.json b/core/l10n/ro.json index cdc76824c7e2f..dadb4da255082 100644 --- a/core/l10n/ro.json +++ b/core/l10n/ro.json @@ -146,6 +146,8 @@ "New Password" : "Noua parolă", "Reset password" : "Resetează parola", "Thank you for your patience." : "Îți mulțumim pentru răbrade.", - "Start update" : "Începe actualizarea" + "Start update" : "Începe actualizarea", + "Error loading file picker template: {error}" : "Eroare la încărcarea șablonului selectorului de fișiere: {error}", + "Password can not be changed. Please contact your administrator." : "Parola nu poate fi modificata. Vă rugăm să contactați administratorul dvs." },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" } \ No newline at end of file diff --git a/core/l10n/ru.js b/core/l10n/ru.js index 3e96f1275b6a2..fd8c7a7373fe8 100644 --- a/core/l10n/ru.js +++ b/core/l10n/ru.js @@ -297,6 +297,8 @@ OC.L10N.register( "Start update" : "Запустить обновление", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Чтобы избежать тайм-аутов в крупных установках, вместо этого можно выполнить следующую команду в каталоге установки:", "This %s instance is currently in maintenance mode, which may take a while." : "Этот сервер %s находится в режиме технического обслуживания, которое может занять некоторое время.", - "This page will refresh itself when the %s instance is available again." : "Эта страница автоматически обновится, когда сервер %s снова станет доступен." + "This page will refresh itself when the %s instance is available again." : "Эта страница автоматически обновится, когда сервер %s снова станет доступен.", + "Error loading file picker template: {error}" : "Ошибка при загрузке шаблона выбора файлов: {error}", + "Password can not be changed. Please contact your administrator." : "Пароль не может быть изменён. Пожалуйста, свяжитесь с вашим администратором." }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/core/l10n/ru.json b/core/l10n/ru.json index b3534d4fc6e1f..c46cf14047034 100644 --- a/core/l10n/ru.json +++ b/core/l10n/ru.json @@ -295,6 +295,8 @@ "Start update" : "Запустить обновление", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Чтобы избежать тайм-аутов в крупных установках, вместо этого можно выполнить следующую команду в каталоге установки:", "This %s instance is currently in maintenance mode, which may take a while." : "Этот сервер %s находится в режиме технического обслуживания, которое может занять некоторое время.", - "This page will refresh itself when the %s instance is available again." : "Эта страница автоматически обновится, когда сервер %s снова станет доступен." + "This page will refresh itself when the %s instance is available again." : "Эта страница автоматически обновится, когда сервер %s снова станет доступен.", + "Error loading file picker template: {error}" : "Ошибка при загрузке шаблона выбора файлов: {error}", + "Password can not be changed. Please contact your administrator." : "Пароль не может быть изменён. Пожалуйста, свяжитесь с вашим администратором." },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" } \ No newline at end of file diff --git a/core/l10n/sk_SK.js b/core/l10n/sk_SK.js index 9ed67536a036c..306e9697bb5a8 100644 --- a/core/l10n/sk_SK.js +++ b/core/l10n/sk_SK.js @@ -268,6 +268,8 @@ OC.L10N.register( "Start update" : "Spustiť aktualizáciu", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby nedošlo k vypršaniu časového limitu vo väčších inštaláciách, môžete namiesto toho použiť nasledujúci príkaz z inštalačného priečinka:", "This %s instance is currently in maintenance mode, which may take a while." : "Táto %s inštancia je v súčasnej dobe v režime údržby. Počkajte prosím.", - "This page will refresh itself when the %s instance is available again." : "Táto stránka sa obnoví sama hneď ako bude %s inštancia znovu dostupná." + "This page will refresh itself when the %s instance is available again." : "Táto stránka sa obnoví sama hneď ako bude %s inštancia znovu dostupná.", + "Error loading file picker template: {error}" : "Chyba pri nahrávaní šablóny výberu súborov: {error}", + "Password can not be changed. Please contact your administrator." : "Heslo nemožno zmeniť. Kontaktujte prosím vášho administrátora." }, "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"); diff --git a/core/l10n/sk_SK.json b/core/l10n/sk_SK.json index a27a85ef2f976..03fcf4fd7e489 100644 --- a/core/l10n/sk_SK.json +++ b/core/l10n/sk_SK.json @@ -266,6 +266,8 @@ "Start update" : "Spustiť aktualizáciu", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby nedošlo k vypršaniu časového limitu vo väčších inštaláciách, môžete namiesto toho použiť nasledujúci príkaz z inštalačného priečinka:", "This %s instance is currently in maintenance mode, which may take a while." : "Táto %s inštancia je v súčasnej dobe v režime údržby. Počkajte prosím.", - "This page will refresh itself when the %s instance is available again." : "Táto stránka sa obnoví sama hneď ako bude %s inštancia znovu dostupná." + "This page will refresh itself when the %s instance is available again." : "Táto stránka sa obnoví sama hneď ako bude %s inštancia znovu dostupná.", + "Error loading file picker template: {error}" : "Chyba pri nahrávaní šablóny výberu súborov: {error}", + "Password can not be changed. Please contact your administrator." : "Heslo nemožno zmeniť. Kontaktujte prosím vášho administrátora." },"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;" } \ No newline at end of file diff --git a/core/l10n/sl.js b/core/l10n/sl.js index a86d7cdbe6f7b..e2cded6f63218 100644 --- a/core/l10n/sl.js +++ b/core/l10n/sl.js @@ -264,6 +264,12 @@ OC.L10N.register( "Start update" : "Začni posodobitev", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Za razreševanje časovnih zahtev večjih namestitev lahko uporabite ukaz iz namestitvene mape:", "This %s instance is currently in maintenance mode, which may take a while." : "Ta %s strežnik je trenutno v načinu vzdrževanja, kar lahko traja dlje časa.", - "This page will refresh itself when the %s instance is available again." : "Stran bo osvežena ko bo %s spet na voljo." + "This page will refresh itself when the %s instance is available again." : "Stran bo osvežena ko bo %s spet na voljo.", + "Could not unshare" : "Ni mogoče prekiniti souporabe", + "Error loading file picker template: {error}" : "Napaka nalaganja predloge izbirnika datotek: {error}", + "Error removing share" : "Napaka odstranjevanja souporabe", + "invisible" : "nevidno", + "not assignable" : "ni dodeljivo", + "Password can not be changed. Please contact your administrator." : "Gesla ni mogoče spremeniti. Stopite v stik s skrbnikom." }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/core/l10n/sl.json b/core/l10n/sl.json index cccdbee4f8baf..9a28564300bdc 100644 --- a/core/l10n/sl.json +++ b/core/l10n/sl.json @@ -262,6 +262,12 @@ "Start update" : "Začni posodobitev", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Za razreševanje časovnih zahtev večjih namestitev lahko uporabite ukaz iz namestitvene mape:", "This %s instance is currently in maintenance mode, which may take a while." : "Ta %s strežnik je trenutno v načinu vzdrževanja, kar lahko traja dlje časa.", - "This page will refresh itself when the %s instance is available again." : "Stran bo osvežena ko bo %s spet na voljo." + "This page will refresh itself when the %s instance is available again." : "Stran bo osvežena ko bo %s spet na voljo.", + "Could not unshare" : "Ni mogoče prekiniti souporabe", + "Error loading file picker template: {error}" : "Napaka nalaganja predloge izbirnika datotek: {error}", + "Error removing share" : "Napaka odstranjevanja souporabe", + "invisible" : "nevidno", + "not assignable" : "ni dodeljivo", + "Password can not be changed. Please contact your administrator." : "Gesla ni mogoče spremeniti. Stopite v stik s skrbnikom." },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" } \ No newline at end of file diff --git a/core/l10n/sq.js b/core/l10n/sq.js index 01359e4d6ddd4..a604cece8dd42 100644 --- a/core/l10n/sq.js +++ b/core/l10n/sq.js @@ -299,6 +299,8 @@ OC.L10N.register( "Start update" : "Fillo përditësimin", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Për të shmangur çaste bllokimi pune me instalime të mëdha, mundeni të ekzekutoni urdhrin vijues që nga drejtoria juaj e instalimit:", "This %s instance is currently in maintenance mode, which may take a while." : "Kjo instancë %s hëpërhë gjendet nën mënyrën mirëmbajtje, çka mund të zgjasë ca.", - "This page will refresh itself when the %s instance is available again." : "Kjo faqe do të rifreskohet vetiu, sapo instanca %s të jetë sërish gati." + "This page will refresh itself when the %s instance is available again." : "Kjo faqe do të rifreskohet vetiu, sapo instanca %s të jetë sërish gati.", + "Error loading file picker template: {error}" : "Gabim në ngarkimin e gjedhes së marrësit të kartelave: {error}", + "Password can not be changed. Please contact your administrator." : "Fjalëkalimi nuk mund të ndryshohet. Ju lutemi, lidhuni me përgjegjësin tuaj." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/sq.json b/core/l10n/sq.json index aa5d502a95b62..a611d90aa6d35 100644 --- a/core/l10n/sq.json +++ b/core/l10n/sq.json @@ -297,6 +297,8 @@ "Start update" : "Fillo përditësimin", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Për të shmangur çaste bllokimi pune me instalime të mëdha, mundeni të ekzekutoni urdhrin vijues që nga drejtoria juaj e instalimit:", "This %s instance is currently in maintenance mode, which may take a while." : "Kjo instancë %s hëpërhë gjendet nën mënyrën mirëmbajtje, çka mund të zgjasë ca.", - "This page will refresh itself when the %s instance is available again." : "Kjo faqe do të rifreskohet vetiu, sapo instanca %s të jetë sërish gati." + "This page will refresh itself when the %s instance is available again." : "Kjo faqe do të rifreskohet vetiu, sapo instanca %s të jetë sërish gati.", + "Error loading file picker template: {error}" : "Gabim në ngarkimin e gjedhes së marrësit të kartelave: {error}", + "Password can not be changed. Please contact your administrator." : "Fjalëkalimi nuk mund të ndryshohet. Ju lutemi, lidhuni me përgjegjësin tuaj." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/sr.js b/core/l10n/sr.js index 8cbe1c0c26576..d2a08aa0d6823 100644 --- a/core/l10n/sr.js +++ b/core/l10n/sr.js @@ -248,6 +248,8 @@ OC.L10N.register( "Start update" : "Почни надоградњу", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Да избегнете прекорачење времена одзива на већим инсталацијама, можете покренути следећу команду у инсталационом директоријуму:", "This %s instance is currently in maintenance mode, which may take a while." : "Овај %s је тренутно у режиму одржавања а то може потрајати.", - "This page will refresh itself when the %s instance is available again." : "Ова страница ће се сама освежити када %s постане поново доступан." + "This page will refresh itself when the %s instance is available again." : "Ова страница ће се сама освежити када %s постане поново доступан.", + "Error loading file picker template: {error}" : "Грешка при учитавању шаблона бирача фајлова: {error}", + "Password can not be changed. Please contact your administrator." : "Лозинка се не може променити. Контактирајте администратора." }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/sr.json b/core/l10n/sr.json index 7021e20be580c..c593cac0f64ec 100644 --- a/core/l10n/sr.json +++ b/core/l10n/sr.json @@ -246,6 +246,8 @@ "Start update" : "Почни надоградњу", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Да избегнете прекорачење времена одзива на већим инсталацијама, можете покренути следећу команду у инсталационом директоријуму:", "This %s instance is currently in maintenance mode, which may take a while." : "Овај %s је тренутно у режиму одржавања а то може потрајати.", - "This page will refresh itself when the %s instance is available again." : "Ова страница ће се сама освежити када %s постане поново доступан." + "This page will refresh itself when the %s instance is available again." : "Ова страница ће се сама освежити када %s постане поново доступан.", + "Error loading file picker template: {error}" : "Грешка при учитавању шаблона бирача фајлова: {error}", + "Password can not be changed. Please contact your administrator." : "Лозинка се не може променити. Контактирајте администратора." },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/sr@latin.js b/core/l10n/sr@latin.js index 2755dde9ad146..d3930cc8ba467 100644 --- a/core/l10n/sr@latin.js +++ b/core/l10n/sr@latin.js @@ -206,6 +206,10 @@ OC.L10N.register( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Molimo Vas da proverite da li su baza podataka, fascikla sa podešavanjima i fascikla sa podacima bekapovani pre nego što nastavite.", "Start update" : "Započni osvežavanje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da bi izbegli preduga čekanja na većim instalacijama, možete pokrenuti sledeću komandu iz instalacionog direktorijuma:", - "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama osvežiti kada %s instanca ponovo postane dostupna." + "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama osvežiti kada %s instanca ponovo postane dostupna.", + "Error loading file picker template: {error}" : "Greška u učitavanju obrasca za izbor fajla: {error}", + "You can click here to return to %s." : "Možete ovde kliknuti da biste se vratili na %s.", + "Password can not be changed. Please contact your administrator." : "Nije moguće promeniti lozinku. Molimo Vas, kontaktirajte Vašeg administratora.", + "Shared with you by {owner}" : "Sa vama podelio {owner}" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/sr@latin.json b/core/l10n/sr@latin.json index 62bb03d0b27f6..df109d788bf28 100644 --- a/core/l10n/sr@latin.json +++ b/core/l10n/sr@latin.json @@ -204,6 +204,10 @@ "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Molimo Vas da proverite da li su baza podataka, fascikla sa podešavanjima i fascikla sa podacima bekapovani pre nego što nastavite.", "Start update" : "Započni osvežavanje", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Da bi izbegli preduga čekanja na većim instalacijama, možete pokrenuti sledeću komandu iz instalacionog direktorijuma:", - "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama osvežiti kada %s instanca ponovo postane dostupna." + "This page will refresh itself when the %s instance is available again." : "Ova stranica će se sama osvežiti kada %s instanca ponovo postane dostupna.", + "Error loading file picker template: {error}" : "Greška u učitavanju obrasca za izbor fajla: {error}", + "You can click here to return to %s." : "Možete ovde kliknuti da biste se vratili na %s.", + "Password can not be changed. Please contact your administrator." : "Nije moguće promeniti lozinku. Molimo Vas, kontaktirajte Vašeg administratora.", + "Shared with you by {owner}" : "Sa vama podelio {owner}" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/sv.js b/core/l10n/sv.js index a960966527e32..0d85fff86330a 100644 --- a/core/l10n/sv.js +++ b/core/l10n/sv.js @@ -244,6 +244,9 @@ OC.L10N.register( "Start update" : "Starta uppdateringen", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "För att undvika timeout vid större installationer kan du istället köra följande kommando från din installationskatalog:", "This %s instance is currently in maintenance mode, which may take a while." : "Denna %s instans befinner sig för närvarande i underhållsläge, vilket kan ta ett tag.", - "This page will refresh itself when the %s instance is available again." : "Denna sida uppdaterar sig själv när %s instansen är tillgänglig igen." + "This page will refresh itself when the %s instance is available again." : "Denna sida uppdaterar sig själv när %s instansen är tillgänglig igen.", + "Error loading file picker template: {error}" : "Fel uppstod för filväljarmall: {error}", + "Following apps have been disabled: %s" : "Följande appar har inaktiverats: %s", + "Password can not be changed. Please contact your administrator." : "Lösenordet kan inte ändras. Vänligen kontakta din administratör." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/sv.json b/core/l10n/sv.json index 019c9c9436965..f23f0a219efb9 100644 --- a/core/l10n/sv.json +++ b/core/l10n/sv.json @@ -242,6 +242,9 @@ "Start update" : "Starta uppdateringen", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "För att undvika timeout vid större installationer kan du istället köra följande kommando från din installationskatalog:", "This %s instance is currently in maintenance mode, which may take a while." : "Denna %s instans befinner sig för närvarande i underhållsläge, vilket kan ta ett tag.", - "This page will refresh itself when the %s instance is available again." : "Denna sida uppdaterar sig själv när %s instansen är tillgänglig igen." + "This page will refresh itself when the %s instance is available again." : "Denna sida uppdaterar sig själv när %s instansen är tillgänglig igen.", + "Error loading file picker template: {error}" : "Fel uppstod för filväljarmall: {error}", + "Following apps have been disabled: %s" : "Följande appar har inaktiverats: %s", + "Password can not be changed. Please contact your administrator." : "Lösenordet kan inte ändras. Vänligen kontakta din administratör." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/ta_LK.js b/core/l10n/ta_LK.js index c5f022d08134b..7c7282cb63b97 100644 --- a/core/l10n/ta_LK.js +++ b/core/l10n/ta_LK.js @@ -91,6 +91,7 @@ OC.L10N.register( "Log in" : "புகுபதிகை", "Use the following link to reset your password: {link}" : "உங்கள் கடவுச்சொல்லை மீளமைக்க பின்வரும் இணைப்பை பயன்படுத்தவும் : {இணைப்பு}", "New password" : "புதிய கடவுச்சொல்", - "Reset password" : "மீளமைத்த கடவுச்சொல்" + "Reset password" : "மீளமைத்த கடவுச்சொல்", + "Shared with you and the group {group} by {owner}" : "உங்களுடனும் குழுவுக்கிடையிலும் {குழு} பகிரப்பட்டுள்ளது {உரிமையாளர்}" }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/ta_LK.json b/core/l10n/ta_LK.json index 4d978c78712ea..edbb93ca7fc6f 100644 --- a/core/l10n/ta_LK.json +++ b/core/l10n/ta_LK.json @@ -89,6 +89,7 @@ "Log in" : "புகுபதிகை", "Use the following link to reset your password: {link}" : "உங்கள் கடவுச்சொல்லை மீளமைக்க பின்வரும் இணைப்பை பயன்படுத்தவும் : {இணைப்பு}", "New password" : "புதிய கடவுச்சொல்", - "Reset password" : "மீளமைத்த கடவுச்சொல்" + "Reset password" : "மீளமைத்த கடவுச்சொல்", + "Shared with you and the group {group} by {owner}" : "உங்களுடனும் குழுவுக்கிடையிலும் {குழு} பகிரப்பட்டுள்ளது {உரிமையாளர்}" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/core/l10n/th_TH.js b/core/l10n/th_TH.js index fb9005d526d04..698693c4fb37b 100644 --- a/core/l10n/th_TH.js +++ b/core/l10n/th_TH.js @@ -292,6 +292,8 @@ OC.L10N.register( "Start update" : "เริ่มต้นอัพเดท", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "เพื่อหลีกเลี่ยงการหมดเวลากับการติดตั้งขนาดใหญ่ คุณสามารถเรียกใช้คำสั่งต่อไปนี้จากไดเรกทอรีการติดตั้งของคุณ:", "This %s instance is currently in maintenance mode, which may take a while." : "%s กำลังอยู่ในโหมดการบำรุงรักษาซึ่งอาจใช้เวลาสักครู่", - "This page will refresh itself when the %s instance is available again." : "หน้านี้จะรีเฟรชตัวเองเมื่อ %s สามารถใช้ได้อีกครั้ง" + "This page will refresh itself when the %s instance is available again." : "หน้านี้จะรีเฟรชตัวเองเมื่อ %s สามารถใช้ได้อีกครั้ง", + "Error loading file picker template: {error}" : "เกิดข้อผิดพลาดขณะกำลังโหลดไฟล์แม่แบบ: {error}", + "Password can not be changed. Please contact your administrator." : "หากคุณไม่สามารถเปลี่ยนแปลงรหัสผ่าน กรุณาติดต่อผู้ดูแลระบบ" }, "nplurals=1; plural=0;"); diff --git a/core/l10n/th_TH.json b/core/l10n/th_TH.json index 38dcbee715a01..b6897bb0e49b9 100644 --- a/core/l10n/th_TH.json +++ b/core/l10n/th_TH.json @@ -290,6 +290,8 @@ "Start update" : "เริ่มต้นอัพเดท", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "เพื่อหลีกเลี่ยงการหมดเวลากับการติดตั้งขนาดใหญ่ คุณสามารถเรียกใช้คำสั่งต่อไปนี้จากไดเรกทอรีการติดตั้งของคุณ:", "This %s instance is currently in maintenance mode, which may take a while." : "%s กำลังอยู่ในโหมดการบำรุงรักษาซึ่งอาจใช้เวลาสักครู่", - "This page will refresh itself when the %s instance is available again." : "หน้านี้จะรีเฟรชตัวเองเมื่อ %s สามารถใช้ได้อีกครั้ง" + "This page will refresh itself when the %s instance is available again." : "หน้านี้จะรีเฟรชตัวเองเมื่อ %s สามารถใช้ได้อีกครั้ง", + "Error loading file picker template: {error}" : "เกิดข้อผิดพลาดขณะกำลังโหลดไฟล์แม่แบบ: {error}", + "Password can not be changed. Please contact your administrator." : "หากคุณไม่สามารถเปลี่ยนแปลงรหัสผ่าน กรุณาติดต่อผู้ดูแลระบบ" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/tr.js b/core/l10n/tr.js index 1e0600e799674..f02fb89bbe4ab 100644 --- a/core/l10n/tr.js +++ b/core/l10n/tr.js @@ -294,6 +294,8 @@ OC.L10N.register( "Start update" : "Güncellemeyi başlat", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Daha büyük kurulumlarda zaman aşımlarının önüne geçmek için, kurulum dizininizden aşağıdaki komutu da çalıştırabilirsiniz:", "This %s instance is currently in maintenance mode, which may take a while." : "Bu %s örneği şu anda bakım kipinde, bu biraz zaman alabilir.", - "This page will refresh itself when the %s instance is available again." : "Bu sayfa, %s örneği tekrar kullanılabilir olduğunda kendini yenileyecektir." + "This page will refresh itself when the %s instance is available again." : "Bu sayfa, %s örneği tekrar kullanılabilir olduğunda kendini yenileyecektir.", + "Error loading file picker template: {error}" : "Dosya seçici şablonu yüklenirken hata: {error}", + "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile iletişime geçin." }, "nplurals=2; plural=(n > 1);"); diff --git a/core/l10n/tr.json b/core/l10n/tr.json index 36e12f3176b20..07ce833c947ac 100644 --- a/core/l10n/tr.json +++ b/core/l10n/tr.json @@ -292,6 +292,8 @@ "Start update" : "Güncellemeyi başlat", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Daha büyük kurulumlarda zaman aşımlarının önüne geçmek için, kurulum dizininizden aşağıdaki komutu da çalıştırabilirsiniz:", "This %s instance is currently in maintenance mode, which may take a while." : "Bu %s örneği şu anda bakım kipinde, bu biraz zaman alabilir.", - "This page will refresh itself when the %s instance is available again." : "Bu sayfa, %s örneği tekrar kullanılabilir olduğunda kendini yenileyecektir." + "This page will refresh itself when the %s instance is available again." : "Bu sayfa, %s örneği tekrar kullanılabilir olduğunda kendini yenileyecektir.", + "Error loading file picker template: {error}" : "Dosya seçici şablonu yüklenirken hata: {error}", + "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile iletişime geçin." },"pluralForm" :"nplurals=2; plural=(n > 1);" } \ No newline at end of file diff --git a/core/l10n/uk.js b/core/l10n/uk.js index 60594fbf8891a..6b2d2d3e314e8 100644 --- a/core/l10n/uk.js +++ b/core/l10n/uk.js @@ -269,6 +269,8 @@ OC.L10N.register( "Start update" : "Почати оновлення", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Щоб уникнути затримок у великих встановленнях, ви можете виконати наступну команду в каталозі встановлення:", "This %s instance is currently in maintenance mode, which may take a while." : "Цей %s знаходиться в режимі технічного обслуговування, яке може зайняти деякий час.", - "This page will refresh itself when the %s instance is available again." : "Ця сторінка автоматично перезавантажиться коли екземпляр %s стане знову доступний." + "This page will refresh itself when the %s instance is available again." : "Ця сторінка автоматично перезавантажиться коли екземпляр %s стане знову доступний.", + "Error loading file picker template: {error}" : "Помилка при завантаженні шаблону вибору: {error}", + "Password can not be changed. Please contact your administrator." : "Пароль не може бути змінено. Будь ласка, зверніться до вашого адміністратора" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/core/l10n/uk.json b/core/l10n/uk.json index 2f9f5d5e26988..a366f34c716b2 100644 --- a/core/l10n/uk.json +++ b/core/l10n/uk.json @@ -267,6 +267,8 @@ "Start update" : "Почати оновлення", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Щоб уникнути затримок у великих встановленнях, ви можете виконати наступну команду в каталозі встановлення:", "This %s instance is currently in maintenance mode, which may take a while." : "Цей %s знаходиться в режимі технічного обслуговування, яке може зайняти деякий час.", - "This page will refresh itself when the %s instance is available again." : "Ця сторінка автоматично перезавантажиться коли екземпляр %s стане знову доступний." + "This page will refresh itself when the %s instance is available again." : "Ця сторінка автоматично перезавантажиться коли екземпляр %s стане знову доступний.", + "Error loading file picker template: {error}" : "Помилка при завантаженні шаблону вибору: {error}", + "Password can not be changed. Please contact your administrator." : "Пароль не може бути змінено. Будь ласка, зверніться до вашого адміністратора" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" } \ No newline at end of file diff --git a/core/l10n/vi.js b/core/l10n/vi.js index ca5937b0f4fd0..ff3b364d1b336 100644 --- a/core/l10n/vi.js +++ b/core/l10n/vi.js @@ -144,6 +144,7 @@ OC.L10N.register( "This ownCloud instance is currently in single user mode." : "OwnCloud trong trường hợp này đang ở chế độ người dùng duy nhất.", "This means only administrators can use the instance." : "Điều này có nghĩa chỉ có người quản trị có thể sử dụng trong trường hợp này.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Liên hệ với người quản trị nếu lỗi này vẫn tồn tại hoặc xuất hiện bất ngờ.", - "Thank you for your patience." : "Cảm ơn sự kiên nhẫn của bạn." + "Thank you for your patience." : "Cảm ơn sự kiên nhẫn của bạn.", + "Error loading file picker template: {error}" : "Lỗi khi tải mẫu tập tin picker: {error}" }, "nplurals=1; plural=0;"); diff --git a/core/l10n/vi.json b/core/l10n/vi.json index b3837cb72f873..11de349e68642 100644 --- a/core/l10n/vi.json +++ b/core/l10n/vi.json @@ -142,6 +142,7 @@ "This ownCloud instance is currently in single user mode." : "OwnCloud trong trường hợp này đang ở chế độ người dùng duy nhất.", "This means only administrators can use the instance." : "Điều này có nghĩa chỉ có người quản trị có thể sử dụng trong trường hợp này.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Liên hệ với người quản trị nếu lỗi này vẫn tồn tại hoặc xuất hiện bất ngờ.", - "Thank you for your patience." : "Cảm ơn sự kiên nhẫn của bạn." + "Thank you for your patience." : "Cảm ơn sự kiên nhẫn của bạn.", + "Error loading file picker template: {error}" : "Lỗi khi tải mẫu tập tin picker: {error}" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/zh_CN.js b/core/l10n/zh_CN.js index 15dd1090e2fa5..9cb6a6a1ff1b0 100644 --- a/core/l10n/zh_CN.js +++ b/core/l10n/zh_CN.js @@ -290,6 +290,9 @@ OC.L10N.register( "Start update" : "开始更新", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "为进行避免较大的安装时超时,你可以在你的安装目录下运行下面的命令:", "This %s instance is currently in maintenance mode, which may take a while." : "该 %s 实例当前处于维护模式,这将进行一些时间。", - "This page will refresh itself when the %s instance is available again." : "当实例 %s 再次可用时这个页面将刷新。" + "This page will refresh itself when the %s instance is available again." : "当实例 %s 再次可用时这个页面将刷新。", + "Collaborative tags" : "协作标签", + "Error loading file picker template: {error}" : "加载文件分拣模板出错: {error}", + "Password can not be changed. Please contact your administrator." : "无法修改密码,请联系管理员。" }, "nplurals=1; plural=0;"); diff --git a/core/l10n/zh_CN.json b/core/l10n/zh_CN.json index cc75e35fd9edf..6edf7df625fa1 100644 --- a/core/l10n/zh_CN.json +++ b/core/l10n/zh_CN.json @@ -288,6 +288,9 @@ "Start update" : "开始更新", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "为进行避免较大的安装时超时,你可以在你的安装目录下运行下面的命令:", "This %s instance is currently in maintenance mode, which may take a while." : "该 %s 实例当前处于维护模式,这将进行一些时间。", - "This page will refresh itself when the %s instance is available again." : "当实例 %s 再次可用时这个页面将刷新。" + "This page will refresh itself when the %s instance is available again." : "当实例 %s 再次可用时这个页面将刷新。", + "Collaborative tags" : "协作标签", + "Error loading file picker template: {error}" : "加载文件分拣模板出错: {error}", + "Password can not be changed. Please contact your administrator." : "无法修改密码,请联系管理员。" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file diff --git a/core/l10n/zh_TW.js b/core/l10n/zh_TW.js index 4de7b3e8cfa52..7a155016d3e34 100644 --- a/core/l10n/zh_TW.js +++ b/core/l10n/zh_TW.js @@ -285,6 +285,8 @@ OC.L10N.register( "Start update" : "開始升級", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "在大型安裝上,為了避免升級請求逾時,你也可以在安裝目錄執行下列指令:", "This %s instance is currently in maintenance mode, which may take a while." : "這個 %s 安裝目前處於維護模式,需要一段時間恢復。", - "This page will refresh itself when the %s instance is available again." : "%s 安裝恢復可用之後,本頁會自動重新整理" + "This page will refresh itself when the %s instance is available again." : "%s 安裝恢復可用之後,本頁會自動重新整理", + "Error loading file picker template: {error}" : "載入檔案選擇器樣板出錯: {error}", + "Password can not be changed. Please contact your administrator." : "無法變更密碼,請聯絡您的系統管理員" }, "nplurals=1; plural=0;"); diff --git a/core/l10n/zh_TW.json b/core/l10n/zh_TW.json index 682c06e4b6ed3..3c091d4dafd29 100644 --- a/core/l10n/zh_TW.json +++ b/core/l10n/zh_TW.json @@ -283,6 +283,8 @@ "Start update" : "開始升級", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "在大型安裝上,為了避免升級請求逾時,你也可以在安裝目錄執行下列指令:", "This %s instance is currently in maintenance mode, which may take a while." : "這個 %s 安裝目前處於維護模式,需要一段時間恢復。", - "This page will refresh itself when the %s instance is available again." : "%s 安裝恢復可用之後,本頁會自動重新整理" + "This page will refresh itself when the %s instance is available again." : "%s 安裝恢復可用之後,本頁會自動重新整理", + "Error loading file picker template: {error}" : "載入檔案選擇器樣板出錯: {error}", + "Password can not be changed. Please contact your administrator." : "無法變更密碼,請聯絡您的系統管理員" },"pluralForm" :"nplurals=1; plural=0;" } \ No newline at end of file From 0d9edd80f1f826e9a55bc24b8273a1db3d427ad6 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 22 Mar 2016 08:42:25 +0100 Subject: [PATCH 133/286] Fix "AutoloadNotAllowedException" when files_sharing is disabled --- lib/private/activitymanager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php index 68bb8c1340101..9258b7298ccc4 100644 --- a/lib/private/activitymanager.php +++ b/lib/private/activitymanager.php @@ -256,11 +256,11 @@ public function getNotificationTypes($languageCode) { foreach ($this->getExtensions() as $c) { $result = $c->getNotificationTypes($languageCode); if (is_array($result)) { - if (class_exists('\OCA\Files\Activity') && $c instanceof \OCA\Files\Activity) { + if (class_exists('\OCA\Files\Activity', false) && $c instanceof \OCA\Files\Activity) { $filesNotificationTypes = $result; continue; } - if (class_exists('\OCA\Files_Sharing\Activity') && $c instanceof \OCA\Files_Sharing\Activity) { + if (class_exists('\OCA\Files_Sharing\Activity', false) && $c instanceof \OCA\Files_Sharing\Activity) { $sharingNotificationTypes = $result; continue; } From 90a2be58f887f7e00ead30be09fedb067691bc14 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 18 Mar 2016 23:31:11 +0100 Subject: [PATCH 134/286] adjust PrincipalUri as returned from Sabre to effective username backport of #23404 --- apps/dav/lib/connector/sabre/auth.php | 8 +++++++- apps/dav/tests/unit/connector/sabre/auth.php | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/dav/lib/connector/sabre/auth.php b/apps/dav/lib/connector/sabre/auth.php index 4bb07c5f0ed88..8c09c9fdc1c18 100644 --- a/apps/dav/lib/connector/sabre/auth.php +++ b/apps/dav/lib/connector/sabre/auth.php @@ -169,6 +169,12 @@ private function auth(RequestInterface $request, ResponseInterface $response) { throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls'); } - return parent::check($request, $response); + $data = parent::check($request, $response); + if($data[0] === true) { + $startPos = strrpos($data[1], '/') + 1; + $user = $this->userSession->getUser()->getUID(); + $data[1] = substr_replace($data[1], $user, $startPos); + } + return $data; } } diff --git a/apps/dav/tests/unit/connector/sabre/auth.php b/apps/dav/tests/unit/connector/sabre/auth.php index 57ed44f01c0f0..edb4073bdcb89 100644 --- a/apps/dav/tests/unit/connector/sabre/auth.php +++ b/apps/dav/tests/unit/connector/sabre/auth.php @@ -407,15 +407,15 @@ public function testAuthenticateValidCredentials() { $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor() ->getMock(); - $user->expects($this->exactly(2)) + $user->expects($this->exactly(3)) ->method('getUID') ->will($this->returnValue('MyTestUser')); $this->userSession - ->expects($this->exactly(2)) + ->expects($this->exactly(3)) ->method('getUser') ->will($this->returnValue($user)); $response = $this->auth->check($server->httpRequest, $server->httpResponse); - $this->assertEquals([true, 'principals/users/username'], $response); + $this->assertEquals([true, 'principals/users/MyTestUser'], $response); } public function testAuthenticateInvalidCredentials() { From 7fb32f83589701ed1e4cfefdf2874bdb65b34dd3 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 26 Feb 2016 14:58:41 +0100 Subject: [PATCH 135/286] When the Share API is disabled do not return shares Fixes #22668 Block everything in the OCS Share API --- apps/files_sharing/api/share20ocs.php | 21 ++++++ .../tests/api/share20ocstest.php | 71 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php index a6baa353e8a15..e370810c9c968 100644 --- a/apps/files_sharing/api/share20ocs.php +++ b/apps/files_sharing/api/share20ocs.php @@ -156,10 +156,15 @@ protected function formatShare(\OCP\Share\IShare $share) { * @return \OC_OCS_Result */ public function getShare($id) { + if (!$this->shareManager->shareApiEnabled()) { + return new \OC_OCS_Result(null, 404, 'Share API is disabled'); + } + // Try both our default, and our federated provider.. $share = null; // First check if it is an internal share. + try { $share = $this->shareManager->getShareById('ocinternal:'.$id); } catch (ShareNotFound $e) { @@ -198,6 +203,10 @@ public function getShare($id) { * @return \OC_OCS_Result */ public function deleteShare($id) { + if (!$this->shareManager->shareApiEnabled()) { + return new \OC_OCS_Result(null, 404, 'Share API is disabled'); + } + // Try both our default and our federated provider $share = null; @@ -236,6 +245,10 @@ public function deleteShare($id) { public function createShare() { $share = $this->shareManager->newShare(); + if (!$this->shareManager->shareApiEnabled()) { + return new \OC_OCS_Result(null, 404, 'Share API is disabled'); + } + // Verify path $path = $this->request->getParam('path', null); if ($path === null) { @@ -449,6 +462,10 @@ private function getSharesInDir($folder) { * @return \OC_OCS_Result */ public function getShares() { + if (!$this->shareManager->shareApiEnabled()) { + return new \OC_OCS_Result(); + } + $sharedWithMe = $this->request->getParam('shared_with_me', null); $reshares = $this->request->getParam('reshares', null); $subfiles = $this->request->getParam('subfiles'); @@ -506,6 +523,10 @@ public function getShares() { * @return \OC_OCS_Result */ public function updateShare($id) { + if (!$this->shareManager->shareApiEnabled()) { + return new \OC_OCS_Result(null, 404, 'Share API is disabled'); + } + // Try both our default and our federated provider $share = null; diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php index a2c70d7673c68..f641f683e7934 100644 --- a/apps/files_sharing/tests/api/share20ocstest.php +++ b/apps/files_sharing/tests/api/share20ocstest.php @@ -65,6 +65,10 @@ protected function setUp() { $this->shareManager = $this->getMockBuilder('OCP\Share\IManager') ->disableOriginalConstructor() ->getMock(); + $this->shareManager + ->expects($this->any()) + ->method('shareApiEnabled') + ->willReturn(true); $this->groupManager = $this->getMock('OCP\IGroupManager'); $this->userManager = $this->getMock('OCP\IUserManager'); $this->request = $this->getMock('OCP\IRequest'); @@ -1827,7 +1831,74 @@ public function testFormatShare(array $expects, \OCP\Share\IShare $share, array } catch (NotFoundException $e) { $this->assertTrue($exception); } + } + + /** + * @return Share20OCS + */ + public function getOcsDisabledAPI() { + $shareManager = $this->getMockBuilder('OCP\Share\IManager') + ->disableOriginalConstructor() + ->getMock(); + $shareManager + ->expects($this->any()) + ->method('shareApiEnabled') + ->willReturn(false); + + return new Share20OCS( + $shareManager, + $this->groupManager, + $this->userManager, + $this->request, + $this->rootFolder, + $this->urlGenerator, + $this->currentUser + ); + } + + public function testGetShareApiDisabled() { + $ocs = $this->getOcsDisabledAPI(); + + $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled'); + $result = $ocs->getShare('my:id'); + + $this->assertEquals($expected, $result); + } + + public function testDeleteShareApiDisabled() { + $ocs = $this->getOcsDisabledAPI(); + + $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled'); + $result = $ocs->deleteShare('my:id'); + + $this->assertEquals($expected, $result); + } + + + public function testCreateShareApiDisabled() { + $ocs = $this->getOcsDisabledAPI(); + + $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled'); + $result = $ocs->createShare(); + + $this->assertEquals($expected, $result); + } + + public function testGetSharesApiDisabled() { + $ocs = $this->getOcsDisabledAPI(); + + $expected = new \OC_OCS_Result(); + $result = $ocs->getShares(); + + $this->assertEquals($expected, $result); + } + + public function testUpdateShareApiDisabled() { + $ocs = $this->getOcsDisabledAPI(); + $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled'); + $result = $ocs->updateShare('my:id'); + $this->assertEquals($expected, $result); } } From 53f95373baf47ab4f3706a4e67cea16fadfa6a92 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 22 Mar 2016 17:01:51 -0400 Subject: [PATCH 136/286] 9.0.1 beta --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 3a8bd5adaea83..15871590df9e4 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 0, 19); +$OC_Version = array(9, 0, 1, 0); // The human readable string -$OC_VersionString = '9.0.0'; +$OC_VersionString = '9.0.1 beta'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 43516ebef94ebcabd19e0e656cdf4f6c6d648c28 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 22 Mar 2016 17:34:20 +0100 Subject: [PATCH 137/286] Only use the user session if ownCloud is already installed When installing ownCloud with autotest and MySQL some log entries may be created which will invoke the logging class. IUserSession has a dependency on the database which will make the installation fail => :bomb: --- lib/private/log/owncloud.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index ec4af29dc8433..9c106299e4c57 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -90,7 +90,11 @@ public static function write($app, $message, $level) { $time = $time->format($format); $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; - $userObj = \OC::$server->getUserSession()->getUser(); + if(\OC::$server->getConfig()->getSystemValue('installed', false)) { + $userObj = \OC::$server->getUserSession()->getUser(); + } else { + $userObj = null; + } $user = !is_null($userObj) ? $userObj->getUID() : '--'; $entry = compact( 'reqId', From 70a5233f697d27a24e51c8be239dfcf36b1d9b9d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 18 Feb 2016 15:36:38 +0100 Subject: [PATCH 138/286] Query the cache when checking if a node exists --- lib/private/files/node/root.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/private/files/node/root.php b/lib/private/files/node/root.php index 0be7ee2c4991f..b5306eed8bbdc 100644 --- a/lib/private/files/node/root.php +++ b/lib/private/files/node/root.php @@ -176,8 +176,9 @@ public function get($path) { $path = $this->normalizePath($path); if ($this->isValidPath($path)) { $fullPath = $this->getFullPath($path); - if ($this->view->file_exists($fullPath)) { - return $this->createNode($fullPath); + $fileInfo = $this->view->getFileInfo($fullPath); + if ($fileInfo) { + return $this->createNode($fullPath, $fileInfo); } else { throw new NotFoundException($path); } From f77ce8829c32a6258c1d18d833066636bff52179 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 18 Feb 2016 15:41:10 +0100 Subject: [PATCH 139/286] pass the fileinfo to the node if available --- lib/private/files/node/folder.php | 4 ++-- tests/lib/files/node/folder.php | 8 ++++---- tests/lib/files/node/root.php | 15 ++++----------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php index e8c49cd2c0b6a..c376bfb18813b 100644 --- a/lib/private/files/node/folder.php +++ b/lib/private/files/node/folder.php @@ -100,9 +100,9 @@ protected function createNode($path, $info = array()) { $isDir = $info['mimetype'] === 'httpd/unix-directory'; } if ($isDir) { - return new Folder($this->root, $this->view, $path); + return new Folder($this->root, $this->view, $path, $info); } else { - return new File($this->root, $this->view, $path); + return new File($this->root, $this->view, $path, $info); } } diff --git a/tests/lib/files/node/folder.php b/tests/lib/files/node/folder.php index 09bf32561e6de..06ca35f7f11ab 100644 --- a/tests/lib/files/node/folder.php +++ b/tests/lib/files/node/folder.php @@ -601,8 +601,8 @@ public function testGetById() { $cache = $this->getMock('\OC\Files\Cache\Cache', array(), array('')); $view->expects($this->once()) - ->method('file_exists') - ->will($this->returnValue(true)); + ->method('getFileInfo') + ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', [], null))); $storage->expects($this->once()) ->method('getCache') @@ -683,8 +683,8 @@ public function testGetByIdMultipleStorages() { $cache = $this->getMock('\OC\Files\Cache\Cache', array(), array('')); $view->expects($this->any()) - ->method('file_exists') - ->will($this->returnValue(true)); + ->method('getFileInfo') + ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', [], null))); $storage->expects($this->any()) ->method('getCache') diff --git a/tests/lib/files/node/root.php b/tests/lib/files/node/root.php index 4b1aea1da4e52..9c77959869d6c 100644 --- a/tests/lib/files/node/root.php +++ b/tests/lib/files/node/root.php @@ -12,6 +12,9 @@ use OCP\Files\NotPermittedException; use OC\Files\Mount\Manager; +/** + * @group DB + */ class Root extends \Test\TestCase { private $user; @@ -41,16 +44,6 @@ public function testGet() { ->with('/bar/foo') ->will($this->returnValue($this->getFileInfo(array('fileid' => 10, 'path' => 'bar/foo', 'name', 'mimetype' => 'text/plain')))); - $view->expects($this->once()) - ->method('is_dir') - ->with('/bar/foo') - ->will($this->returnValue(false)); - - $view->expects($this->once()) - ->method('file_exists') - ->with('/bar/foo') - ->will($this->returnValue(true)); - $root->mount($storage, ''); $node = $root->get('/bar/foo'); $this->assertEquals(10, $node->getId()); @@ -73,7 +66,7 @@ public function testGetNotFound() { $root = new \OC\Files\Node\Root($manager, $view, $this->user); $view->expects($this->once()) - ->method('file_exists') + ->method('getFileInfo') ->with('/bar/foo') ->will($this->returnValue(false)); From c864420d6c822bae1e019f71f414d7a738e8f9be Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 19 Feb 2016 14:27:55 +0100 Subject: [PATCH 140/286] improve reuse in getUserFolder --- lib/private/files/node/root.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/private/files/node/root.php b/lib/private/files/node/root.php index b5306eed8bbdc..69c98368dfd75 100644 --- a/lib/private/files/node/root.php +++ b/lib/private/files/node/root.php @@ -337,18 +337,18 @@ public function getUserFolder($userId) { $dir = '/' . $userId; $folder = null; - if (!$this->nodeExists($dir)) { - $folder = $this->newFolder($dir); - } else { + try { $folder = $this->get($dir); + } catch (NotFoundException $e) { + $folder = $this->newFolder($dir); } $dir = '/files'; - if (!$folder->nodeExists($dir)) { + try { + $folder = $folder->get($dir); + } catch (NotFoundException $e) { $folder = $folder->newFolder($dir); \OC_Util::copySkeleton($userId, $folder); - } else { - $folder = $folder->get($dir); } return $folder; From 24670b4218032a32b0cb83ce9d108eaa455c1ec6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 19 Feb 2016 14:29:01 +0100 Subject: [PATCH 141/286] set watch policy in test --- apps/files_trashbin/tests/trashbin.php | 33 +++++++++++++++++++------- apps/files_versions/tests/versions.php | 15 ++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/apps/files_trashbin/tests/trashbin.php b/apps/files_trashbin/tests/trashbin.php index 930f8c2bf3ebb..8d616b6e8e26d 100644 --- a/apps/files_trashbin/tests/trashbin.php +++ b/apps/files_trashbin/tests/trashbin.php @@ -86,11 +86,12 @@ public static function setUpBeforeClass() { } - public static function tearDownAfterClass() { // cleanup test user $user = \OC::$server->getUserManager()->get(self::TEST_TRASHBIN_USER1); - if ($user !== null) { $user->delete(); } + if ($user !== null) { + $user->delete(); + } \OC::$server->getConfig()->setSystemValue('trashbin_retention_obligation', self::$rememberRetentionObligation); @@ -109,6 +110,18 @@ protected function setUp() { parent::setUp(); \OC::$server->getAppManager()->enableApp('files_trashbin'); + $config = \OC::$server->getConfig(); + $mockConfig = $this->getMock('\OCP\IConfig'); + $mockConfig->expects($this->any()) + ->method('getSystemValue') + ->will($this->returnCallback(function ($key, $default) use ($config) { + if ($key === 'filesystem_check_changes') { + return \OC\Files\Cache\Watcher::CHECK_ONCE; + } else { + return $config->getSystemValue($key, $default); + } + })); + $this->overwriteService('AllConfig', $mockConfig); $this->trashRoot1 = '/' . self::TEST_TRASHBIN_USER1 . '/files_trashbin'; $this->trashRoot2 = '/' . self::TEST_TRASHBIN_USER2 . '/files_trashbin'; @@ -117,6 +130,7 @@ protected function setUp() { } protected function tearDown() { + $this->restoreService('AllConfig'); // disable trashbin to be able to properly clean up \OC::$server->getAppManager()->disableApp('files_trashbin'); @@ -138,8 +152,8 @@ protected function tearDown() { public function testExpireOldFiles() { $currentTime = time(); - $expireAt = $currentTime - 2*24*60*60; - $expiredDate = $currentTime - 3*24*60*60; + $expireAt = $currentTime - 2 * 24 * 60 * 60; + $expiredDate = $currentTime - 3 * 24 * 60 * 60; // create some files \OC\Files\Filesystem::file_put_contents('file1.txt', 'file1'); @@ -187,7 +201,7 @@ public function testExpireOldFilesShared() { $currentTime = time(); $folder = "trashTest-" . $currentTime . '/'; - $expiredDate = $currentTime - 3*24*60*60; + $expiredDate = $currentTime - 3 * 24 * 60 * 60; // create some files \OC\Files\Filesystem::mkdir($folder); @@ -250,6 +264,7 @@ public function testExpireOldFilesShared() { /** * verify that the array contains the expected results + * * @param OCP\Files\FileInfo[] $result * @param string[] $expected */ @@ -265,7 +280,7 @@ private function verifyArray($result, $expected) { } if (!$found) { // if we didn't found the expected file, something went wrong - $this->assertTrue(false, "can't find expected file '" . $expectedFile . "' in trash bin"); + $this->assertTrue(false, "can't find expected file '" . $expectedFile . "' in trash bin"); } } } @@ -281,7 +296,7 @@ private function manipulateDeleteTime($files, $trashRoot, $expireDate) { // modify every second file $counter = ($counter + 1) % 2; if ($counter === 1) { - $source = $trashRoot . '/files/' . $file['name'].'.d'.$file['mtime']; + $source = $trashRoot . '/files/' . $file['name'] . '.d' . $file['mtime']; $target = \OC\Files\Filesystem::normalizePath($trashRoot . '/files/' . $file['name'] . '.d' . $expireDate); $this->rootView->rename($source, $target); $file['mtime'] = $expireDate; @@ -445,7 +460,7 @@ public function testRestoreFileFromTrashedSubfolder() { $trashedFile = $filesInTrash[0]; $this->assertTrue( - OCA\Files_Trashbin\Trashbin::restore( + OCA\Files_Trashbin\Trashbin::restore( 'folder.d' . $trashedFile->getMtime() . '/file1.txt', 'file1.txt', $trashedFile->getMtime() @@ -639,7 +654,7 @@ public static function loginHelper($user, $create = false) { if ($create) { try { \OC::$server->getUserManager()->createUser($user, $user); - } catch(\Exception $e) { // catch username is already being used from previous aborted runs + } catch (\Exception $e) { // catch username is already being used from previous aborted runs } } diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php index e82e65bf3a5d0..f6658e092bd6d 100644 --- a/apps/files_versions/tests/versions.php +++ b/apps/files_versions/tests/versions.php @@ -74,6 +74,19 @@ public static function tearDownAfterClass() { protected function setUp() { parent::setUp(); + $config = \OC::$server->getConfig(); + $mockConfig = $this->getMock('\OCP\IConfig'); + $mockConfig->expects($this->any()) + ->method('getSystemValue') + ->will($this->returnCallback(function ($key, $default) use ($config) { + if ($key === 'filesystem_check_changes') { + return \OC\Files\Cache\Watcher::CHECK_ONCE; + } else { + return $config->getSystemValue($key, $default); + } + })); + $this->overwriteService('AllConfig', $mockConfig); + // clear hooks \OC_Hook::clear(); \OC::registerShareHooks(); @@ -87,6 +100,8 @@ protected function setUp() { } protected function tearDown() { + $this->restoreService('AllConfig'); + if ($this->rootView) { $this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/'); $this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/'); From 5a630c6a0e1542d3af9a1fbd92a3c9bf0792fb9e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Mar 2016 14:20:33 +0100 Subject: [PATCH 142/286] properly use fileinfo objects --- lib/private/files/node/folder.php | 28 +++++------ tests/lib/files/node/folder.php | 81 ++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 34 deletions(-) diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php index c376bfb18813b..f4d7dae20a3a7 100644 --- a/lib/private/files/node/folder.php +++ b/lib/private/files/node/folder.php @@ -90,14 +90,14 @@ public function getDirectoryListing() { /** * @param string $path - * @param array $info + * @param FileInfo $info * @return File|Folder */ - protected function createNode($path, $info = array()) { - if (!isset($info['mimetype'])) { + protected function createNode($path, FileInfo $info = null) { + if (is_null($info)) { $isDir = $this->view->is_dir($path); } else { - $isDir = $info['mimetype'] === 'httpd/unix-directory'; + $isDir = $info->getType() === FileInfo::TYPE_FOLDER; } if ($isDir) { return new Folder($this->root, $this->view, $path, $info); @@ -211,10 +211,9 @@ public function searchByTag($tag, $userId) { private function searchCommon($method, $args) { $files = array(); $rootLength = strlen($this->path); - /** - * @var \OC\Files\Storage\Storage $storage - */ - list($storage, $internalPath) = $this->view->resolvePath($this->path); + $mount = $this->root->getMount($this->path); + $storage = $mount->getStorage(); + $internalPath = $mount->getInternalPath($this->path); $internalPath = rtrim($internalPath, '/'); if ($internalPath !== '') { $internalPath = $internalPath . '/'; @@ -229,7 +228,7 @@ private function searchCommon($method, $args) { $result['internalPath'] = $result['path']; $result['path'] = substr($result['path'], $internalRootLength); $result['storage'] = $storage; - $files[] = $result; + $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount); } } @@ -245,17 +244,14 @@ private function searchCommon($method, $args) { $result['internalPath'] = $result['path']; $result['path'] = $relativeMountPoint . $result['path']; $result['storage'] = $storage; - $files[] = $result; + $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount); } } } - $result = array(); - foreach ($files as $file) { - $result[] = $this->createNode($this->normalizePath($this->path . '/' . $file['path']), $file); - } - - return $result; + return array_map(function(FileInfo $file) { + return $this->createNode($file->getPath(), $file); + }, $files); } /** diff --git a/tests/lib/files/node/folder.php b/tests/lib/files/node/folder.php index 06ca35f7f11ab..f6d488d659090 100644 --- a/tests/lib/files/node/folder.php +++ b/tests/lib/files/node/folder.php @@ -376,6 +376,14 @@ public function testSearch() { ->method('getCache') ->will($this->returnValue($cache)); + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $mount->expects($this->once()) + ->method('getStorage') + ->will($this->returnValue($storage)); + $mount->expects($this->once()) + ->method('getInternalPath') + ->will($this->returnValue('foo')); + $cache->expects($this->once()) ->method('search') ->with('%qw%') @@ -388,9 +396,10 @@ public function testSearch() { ->with('/bar/foo') ->will($this->returnValue(array())); - $view->expects($this->once()) - ->method('resolvePath') - ->will($this->returnValue(array($storage, 'foo'))); + $root->expects($this->once()) + ->method('getMount') + ->with('/bar/foo') + ->will($this->returnValue($mount)); $node = new \OC\Files\Node\Folder($root, $view, '/bar/foo'); $result = $node->search('qw'); @@ -404,13 +413,21 @@ public function testSearchInRoot() { * @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject $view */ $view = $this->getMock('\OC\Files\View'); - $root = $this->getMock('\OC\Files\Node\Root', array('getUser', 'getMountsIn'), array($manager, $view, $this->user)); + $root = $this->getMock('\OC\Files\Node\Root', array('getUser', 'getMountsIn', 'getMount'), array($manager, $view, $this->user)); $root->expects($this->any()) ->method('getUser') ->will($this->returnValue($this->user)); $storage = $this->getMock('\OC\Files\Storage\Storage'); $cache = $this->getMock('\OC\Files\Cache\Cache', array(), array('')); + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $mount->expects($this->once()) + ->method('getStorage') + ->will($this->returnValue($storage)); + $mount->expects($this->once()) + ->method('getInternalPath') + ->will($this->returnValue('files')); + $storage->expects($this->once()) ->method('getCache') ->will($this->returnValue($cache)); @@ -428,9 +445,10 @@ public function testSearchInRoot() { ->with('') ->will($this->returnValue(array())); - $view->expects($this->once()) - ->method('resolvePath') - ->will($this->returnValue(array($storage, 'files'))); + $root->expects($this->once()) + ->method('getMount') + ->with('') + ->will($this->returnValue($mount)); $result = $root->search('qw'); $this->assertEquals(1, count($result)); @@ -450,6 +468,14 @@ public function testSearchInStorageRoot() { $storage = $this->getMock('\OC\Files\Storage\Storage'); $cache = $this->getMock('\OC\Files\Cache\Cache', array(), array('')); + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $mount->expects($this->once()) + ->method('getStorage') + ->will($this->returnValue($storage)); + $mount->expects($this->once()) + ->method('getInternalPath') + ->will($this->returnValue('')); + $storage->expects($this->once()) ->method('getCache') ->will($this->returnValue($cache)); @@ -466,9 +492,10 @@ public function testSearchInStorageRoot() { ->with('/bar') ->will($this->returnValue(array())); - $view->expects($this->once()) - ->method('resolvePath') - ->will($this->returnValue(array($storage, ''))); + $root->expects($this->once()) + ->method('getMount') + ->with('/bar') + ->will($this->returnValue($mount)); $node = new \OC\Files\Node\Folder($root, $view, '/bar'); $result = $node->search('qw'); @@ -489,6 +516,14 @@ public function testSearchByTag() { $storage = $this->getMock('\OC\Files\Storage\Storage'); $cache = $this->getMock('\OC\Files\Cache\Cache', array(), array('')); + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $mount->expects($this->once()) + ->method('getStorage') + ->will($this->returnValue($storage)); + $mount->expects($this->once()) + ->method('getInternalPath') + ->will($this->returnValue('foo')); + $storage->expects($this->once()) ->method('getCache') ->will($this->returnValue($cache)); @@ -505,9 +540,10 @@ public function testSearchByTag() { ->with('/bar/foo') ->will($this->returnValue(array())); - $view->expects($this->once()) - ->method('resolvePath') - ->will($this->returnValue(array($storage, 'foo'))); + $root->expects($this->once()) + ->method('getMount') + ->with('/bar/foo') + ->will($this->returnValue($mount)); $node = new \OC\Files\Node\Folder($root, $view, '/bar/foo'); $result = $node->searchByTag('tag1', 'user1'); @@ -531,6 +567,14 @@ public function testSearchSubStorages() { $subStorage = $this->getMock('\OC\Files\Storage\Storage'); $subMount = $this->getMock('\OC\Files\Mount\MountPoint', array(), array(null, '')); + $mount = $this->getMock('\OCP\Files\Mount\IMountPoint'); + $mount->expects($this->once()) + ->method('getStorage') + ->will($this->returnValue($storage)); + $mount->expects($this->once()) + ->method('getInternalPath') + ->will($this->returnValue('foo')); + $subMount->expects($this->once()) ->method('getStorage') ->will($this->returnValue($subStorage)); @@ -566,9 +610,10 @@ public function testSearchSubStorages() { ->with('/bar/foo') ->will($this->returnValue(array($subMount))); - $view->expects($this->once()) - ->method('resolvePath') - ->will($this->returnValue(array($storage, 'foo'))); + $root->expects($this->once()) + ->method('getMount') + ->with('/bar/foo') + ->will($this->returnValue($mount)); $node = new \OC\Files\Node\Folder($root, $view, '/bar/foo'); @@ -602,7 +647,7 @@ public function testGetById() { $view->expects($this->once()) ->method('getFileInfo') - ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', [], null))); + ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', ['mimetype' => 'text/plain'], null))); $storage->expects($this->once()) ->method('getCache') @@ -684,7 +729,7 @@ public function testGetByIdMultipleStorages() { $view->expects($this->any()) ->method('getFileInfo') - ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', [], null))); + ->will($this->returnValue(new FileInfo('/bar/foo/qwerty', null, 'qwerty', ['mimetype' => 'plain'], null))); $storage->expects($this->any()) ->method('getCache') From 443d72ee87fa1b67863d5666f2fcd4eb3dc7b390 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 15 Mar 2016 17:22:16 +0100 Subject: [PATCH 143/286] Fix dropbox storage to not store the whole file in memory Since the library can only store the full response in memory on download, we use an alternate client lib and set the correct headers to be able to stream the content to a temp file. --- .../3rdparty/Dropbox/OAuth/Curl.php | 2 +- apps/files_external/lib/dropbox.php | 34 +++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/files_external/3rdparty/Dropbox/OAuth/Curl.php b/apps/files_external/3rdparty/Dropbox/OAuth/Curl.php index fd66e34bd2d8c..41134511b80ad 100644 --- a/apps/files_external/3rdparty/Dropbox/OAuth/Curl.php +++ b/apps/files_external/3rdparty/Dropbox/OAuth/Curl.php @@ -196,7 +196,7 @@ private function getOAuthBaseParams() { * @return array Array for request's headers section like * array('Authorization' => 'OAuth ...'); */ - private function getOAuthHeader($uri, $params, $method = 'GET', $oAuthParams = null) { + public function getOAuthHeader($uri, $params, $method = 'GET', $oAuthParams = null) { $oAuthParams = $oAuthParams ? $oAuthParams : $this->getOAuthBaseParams(); // create baseString to encode for the sent parameters diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 3c4022f24ce5c..f59b5a460e1de 100644 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -39,6 +39,7 @@ class Dropbox extends \OC\Files\Storage\Common { private $root; private $id; private $metaData = array(); + private $oauth; private static $tempFiles = array(); @@ -51,10 +52,10 @@ public function __construct($params) { ) { $this->root = isset($params['root']) ? $params['root'] : ''; $this->id = 'dropbox::'.$params['app_key'] . $params['token']. '/' . $this->root; - $oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); - $oauth->setToken($params['token'], $params['token_secret']); + $this->oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); + $this->oauth->setToken($params['token'], $params['token_secret']); // note: Dropbox_API connection is lazy - $this->dropbox = new \Dropbox_API($oauth, 'auto'); + $this->dropbox = new \Dropbox_API($this->oauth, 'auto'); } else { throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed'); } @@ -248,10 +249,31 @@ public function fopen($path, $mode) { switch ($mode) { case 'r': case 'rb': - $tmpFile = \OCP\Files::tmpFile(); try { - $data = $this->dropbox->getFile($path); - file_put_contents($tmpFile, $data); + // slashes need to stay + $encodedPath = str_replace('%2F', '/', rawurlencode(trim($path, '/'))); + $downloadUrl = 'https://api-content.dropbox.com/1/files/auto/' . $encodedPath; + $headers = $this->oauth->getOAuthHeader($downloadUrl, [], 'GET'); + + $client = \OC::$server->getHTTPClientService()->newClient(); + try { + $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); + $client->get($downloadUrl, [ + 'headers' => $headers, + 'save_to' => $tmpFile, + ]); + } catch (RequestException $e) { + if (!is_null($e->getResponse())) { + if ($e->getResponse()->getStatusCode() === 404) { + return false; + } else { + throw $e; + } + } else { + throw $e; + } + } + return fopen($tmpFile, 'r'); } catch (\Exception $exception) { \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); From 195cf4111e7d9ec4e3984d69f60818d7de8eb47d Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 23 Mar 2016 15:38:20 +0100 Subject: [PATCH 144/286] Dropbox stream download with RetryWrapper --- apps/files_external/lib/dropbox.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index f59b5a460e1de..8381ccbae59cf 100644 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -29,7 +29,9 @@ namespace OC\Files\Storage; +use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; +use Icewind\Streams\RetryWrapper; require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php'; @@ -257,10 +259,9 @@ public function fopen($path, $mode) { $client = \OC::$server->getHTTPClientService()->newClient(); try { - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); - $client->get($downloadUrl, [ + $response = $client->get($downloadUrl, [ 'headers' => $headers, - 'save_to' => $tmpFile, + 'stream' => true, ]); } catch (RequestException $e) { if (!is_null($e->getResponse())) { @@ -274,7 +275,8 @@ public function fopen($path, $mode) { } } - return fopen($tmpFile, 'r'); + $handle = $response->getBody(); + return RetryWrapper::wrap($handle); } catch (\Exception $exception) { \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); return false; From 2139130ec814bb2954d92a0cbeb86a80343eb789 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 23 Mar 2016 19:31:17 +0100 Subject: [PATCH 145/286] Check if request is sent from official ownCloud client There are authentication backends such as Shibboleth that do send no Basic Auth credentials for DAV requests. This means that the ownCloud DAV backend would consider these requests coming from an untrusted source and require higher levels of security checks. (e.g. a CSRF check) While an elegant solution would rely on authenticating via token (so that one can properly ensure that the request came indeed from a trusted client) this is a okay'ish workaround for this problem until we have something more reliable in the authentication code. --- apps/dav/lib/connector/sabre/auth.php | 82 ++++++-- apps/dav/tests/unit/connector/sabre/auth.php | 193 +++++++++++++++++-- lib/private/appframework/http/request.php | 3 + 3 files changed, 242 insertions(+), 36 deletions(-) diff --git a/apps/dav/lib/connector/sabre/auth.php b/apps/dav/lib/connector/sabre/auth.php index 8c09c9fdc1c18..b63efa3a1ba9f 100644 --- a/apps/dav/lib/connector/sabre/auth.php +++ b/apps/dav/lib/connector/sabre/auth.php @@ -30,6 +30,7 @@ namespace OCA\DAV\Connector\Sabre; use Exception; +use OC\AppFramework\Http\Request; use OCP\IRequest; use OCP\ISession; use OCP\IUserSession; @@ -48,6 +49,8 @@ class Auth extends AbstractBasic { private $userSession; /** @var IRequest */ private $request; + /** @var string */ + private $currentUser; /** * @param ISession $session @@ -130,7 +133,46 @@ function check(RequestInterface $request, ResponseInterface $response) { $msg = $e->getMessage(); throw new ServiceUnavailable("$class: $msg"); } - } + } + + /** + * Checks whether a CSRF check is required on the request + * + * @return bool + */ + private function requiresCSRFCheck() { + // GET requires no check at all + if($this->request->getMethod() === 'GET') { + return false; + } + + // Official ownCloud clients require no checks + if($this->request->isUserAgent([ + Request::USER_AGENT_OWNCLOUD_DESKTOP, + Request::USER_AGENT_OWNCLOUD_ANDROID, + Request::USER_AGENT_OWNCLOUD_IOS, + ])) { + return false; + } + + // If not logged-in no check is required + if(!$this->userSession->isLoggedIn()) { + return false; + } + + // POST always requires a check + if($this->request->getMethod() === 'POST') { + return true; + } + + // If logged-in AND DAV authenticated no check is required + if($this->userSession->isLoggedIn() && + $this->isDavAuthenticated($this->userSession->getUser()->getUID())) { + return false; + } + + return true; + } /** * @param RequestInterface $request @@ -139,27 +181,33 @@ function check(RequestInterface $request, ResponseInterface $response) { * @throws NotAuthenticated */ private function auth(RequestInterface $request, ResponseInterface $response) { - // If request is not GET and not authenticated via WebDAV a requesttoken is required - if($this->userSession->isLoggedIn() && - $this->request->getMethod() !== 'GET' && - !$this->isDavAuthenticated($this->userSession->getUser()->getUID())) { - if(!$this->request->passesCSRFCheck()) { + $forcedLogout = false; + if(!$this->request->passesCSRFCheck() && + $this->requiresCSRFCheck()) { + // In case of a fail with POST we need to recheck the credentials + if($this->request->getMethod() === 'POST') { + $forcedLogout = true; + } else { $response->setStatus(401); throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.'); } } - if (\OC_User::handleApacheAuth() || - //Fix for broken webdav clients - ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) || - //Well behaved clients that only send the cookie are allowed - ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null) - ) { - $user = $this->userSession->getUser()->getUID(); - \OC_Util::setupFS($user); - $this->currentUser = $user; - $this->session->close(); - return [true, $this->principalPrefix . $user]; + if($forcedLogout) { + $this->userSession->logout(); + } else { + if (\OC_User::handleApacheAuth() || + //Fix for broken webdav clients + ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) || + //Well behaved clients that only send the cookie are allowed + ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null) + ) { + $user = $this->userSession->getUser()->getUID(); + \OC_Util::setupFS($user); + $this->currentUser = $user; + $this->session->close(); + return [true, $this->principalPrefix . $user]; + } } if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) { diff --git a/apps/dav/tests/unit/connector/sabre/auth.php b/apps/dav/tests/unit/connector/sabre/auth.php index edb4073bdcb89..b81a5e003b514 100644 --- a/apps/dav/tests/unit/connector/sabre/auth.php +++ b/apps/dav/tests/unit/connector/sabre/auth.php @@ -198,10 +198,7 @@ public function testValidateUserPassWithInvalidPassword() { $this->assertFalse($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); } - /** - * @expectedException \Sabre\DAV\Exception\NotAuthenticated - * @expectedExceptionMessage CSRF check not passed. - */ + public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGet() { $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') ->disableOriginalConstructor() @@ -210,30 +207,42 @@ public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGet() { ->disableOriginalConstructor() ->getMock(); $this->userSession - ->expects($this->once()) + ->expects($this->any()) ->method('isLoggedIn') ->will($this->returnValue(true)); + $this->request + ->expects($this->any()) + ->method('getMethod') + ->willReturn('POST'); $this->session - ->expects($this->once()) + ->expects($this->any()) ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->will($this->returnValue(null)); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor() ->getMock(); - $user->expects($this->once()) + $user->expects($this->any()) ->method('getUID') ->will($this->returnValue('MyWrongDavUser')); $this->userSession - ->expects($this->once()) + ->expects($this->any()) ->method('getUser') ->will($this->returnValue($user)); + $this->request + ->expects($this->once()) + ->method('passesCSRFCheck') + ->willReturn(false); + $expectedResponse = [ + false, + "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is mis-configured", + ]; $response = $this->auth->check($request, $response); - $this->assertEquals([true, 'principals/users/MyWrongDavUser'], $response); + $this->assertSame($expectedResponse, $response); } - public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet() { + public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenAndCorrectlyDavAuthenticated() { $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') ->disableOriginalConstructor() ->getMock(); @@ -241,26 +250,169 @@ public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet() { ->disableOriginalConstructor() ->getMock(); $this->userSession - ->expects($this->exactly(2)) + ->expects($this->any()) ->method('isLoggedIn') - ->will($this->returnValue(true)); + ->willReturn(true); + $this->request + ->expects($this->any()) + ->method('getMethod') + ->willReturn('PROPFIND'); + $this->request + ->expects($this->any()) + ->method('isUserAgent') + ->with([ + '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', + '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/', + '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/', + ]) + ->willReturn(false); $this->session + ->expects($this->any()) + ->method('get') + ->with('AUTHENTICATED_TO_DAV_BACKEND') + ->will($this->returnValue('LoggedInUser')); + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('LoggedInUser')); + $this->userSession + ->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->request ->expects($this->once()) + ->method('passesCSRFCheck') + ->willReturn(false); + $this->auth->check($request, $response); + } + + /** + * @expectedException \Sabre\DAV\Exception\NotAuthenticated + * @expectedExceptionMessage CSRF check not passed. + */ + public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenAndIncorrectlyDavAuthenticated() { + $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') + ->disableOriginalConstructor() + ->getMock(); + $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->any()) + ->method('isLoggedIn') + ->willReturn(true); + $this->request + ->expects($this->any()) + ->method('getMethod') + ->willReturn('PROPFIND'); + $this->request + ->expects($this->any()) + ->method('isUserAgent') + ->with([ + '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', + '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/', + '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/', + ]) + ->willReturn(false); + $this->session + ->expects($this->any()) + ->method('get') + ->with('AUTHENTICATED_TO_DAV_BACKEND') + ->will($this->returnValue('AnotherUser')); + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('LoggedInUser')); + $this->userSession + ->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->request + ->expects($this->once()) + ->method('passesCSRFCheck') + ->willReturn(false); + $this->auth->check($request, $response); + } + + public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGetAndDesktopClient() { + $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') + ->disableOriginalConstructor() + ->getMock(); + $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->any()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + $this->request + ->expects($this->any()) + ->method('getMethod') + ->willReturn('POST'); + $this->request + ->expects($this->any()) + ->method('isUserAgent') + ->with([ + '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/', + '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/', + '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/', + ]) + ->willReturn(true); + $this->session + ->expects($this->any()) ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->will($this->returnValue(null)); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor() ->getMock(); - $user->expects($this->once()) + $user->expects($this->any()) ->method('getUID') ->will($this->returnValue('MyWrongDavUser')); $this->userSession - ->expects($this->once()) + ->expects($this->any()) ->method('getUser') ->will($this->returnValue($user)); $this->request ->expects($this->once()) + ->method('passesCSRFCheck') + ->willReturn(false); + + $this->auth->check($request, $response); + } + + public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet() { + $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') + ->disableOriginalConstructor() + ->getMock(); + $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->any()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + $this->session + ->expects($this->any()) + ->method('get') + ->with('AUTHENTICATED_TO_DAV_BACKEND') + ->will($this->returnValue(null)); + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('MyWrongDavUser')); + $this->userSession + ->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->request + ->expects($this->any()) ->method('getMethod') ->willReturn('GET'); @@ -268,7 +420,6 @@ public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet() { $this->assertEquals([true, 'principals/users/MyWrongDavUser'], $response); } - public function testAuthenticateAlreadyLoggedInWithCsrfTokenForGet() { $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface') ->disableOriginalConstructor() @@ -277,22 +428,22 @@ public function testAuthenticateAlreadyLoggedInWithCsrfTokenForGet() { ->disableOriginalConstructor() ->getMock(); $this->userSession - ->expects($this->exactly(2)) + ->expects($this->any()) ->method('isLoggedIn') ->will($this->returnValue(true)); $this->session - ->expects($this->exactly(2)) + ->expects($this->any()) ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->will($this->returnValue(null)); $user = $this->getMockBuilder('\OCP\IUser') ->disableOriginalConstructor() ->getMock(); - $user->expects($this->exactly(2)) + $user->expects($this->any()) ->method('getUID') ->will($this->returnValue('MyWrongDavUser')); $this->userSession - ->expects($this->exactly(2)) + ->expects($this->any()) ->method('getUser') ->will($this->returnValue($user)); $this->request @@ -368,6 +519,10 @@ public function testAuthenticateNoBasicAuthenticateHeadersProvidedWithAjaxButUse ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->will($this->returnValue('MyTestUser')); + $this->request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('GET'); $httpRequest ->expects($this->atLeastOnce()) ->method('getHeader') diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index caddb5a235d50..1b08b245f0879 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -52,6 +52,9 @@ class Request implements \ArrayAccess, \Countable, IRequest { // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; + const USER_AGENT_OWNCLOUD_IOS = '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/'; + const USER_AGENT_OWNCLOUD_ANDROID = '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/'; + const USER_AGENT_OWNCLOUD_DESKTOP = '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/'; const REGEX_LOCALHOST = '/^(127\.0\.0\.1|localhost)$/'; protected $inputStream; From a381cbc241582a84725b1c84303f088b59b3929e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 23 Mar 2016 15:34:25 +0100 Subject: [PATCH 146/286] Fix the translations of the User menu --- lib/private/l10n/factory.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php index 1440e9510c560..7e3f35e7535bc 100644 --- a/lib/private/l10n/factory.php +++ b/lib/private/l10n/factory.php @@ -89,20 +89,18 @@ public function get($app, $lang = null) { if ($lang !== null) { $lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang); } - $key = $lang; - if ($key === null || !$this->languageExists($app, $lang)) { - $key = 'null'; + if ($lang === null || !$this->languageExists($app, $lang)) { $lang = $this->findLanguage($app); } - if (!isset($this->instances[$key][$app])) { - $this->instances[$key][$app] = new L10N( + if (!isset($this->instances[$lang][$app])) { + $this->instances[$lang][$app] = new L10N( $this, $app, $lang, $this->getL10nFilesForApp($app, $lang) ); } - return $this->instances[$key][$app]; + return $this->instances[$lang][$app]; } /** From 0bb7644150a4b9666a066b5c9aaa06adde74cc4e Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 24 Mar 2016 09:19:43 +0100 Subject: [PATCH 147/286] getAppPath can return false Fixes https://github.com/owncloud/core/issues/23533 --- lib/private/route/router.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/private/route/router.php b/lib/private/route/router.php index 13f7a7a1cfb7b..e1690ed7b358b 100644 --- a/lib/private/route/router.php +++ b/lib/private/route/router.php @@ -95,9 +95,12 @@ public function getRoutingFiles() { if (!isset($this->routingFiles)) { $this->routingFiles = []; foreach (\OC_APP::getEnabledApps() as $app) { - $file = \OC_App::getAppPath($app) . '/appinfo/routes.php'; - if (file_exists($file)) { - $this->routingFiles[$app] = $file; + $appPath = \OC_App::getAppPath($app); + if($appPath !== false) { + $file = $appPath . '/appinfo/routes.php'; + if (file_exists($file)) { + $this->routingFiles[$app] = $file; + } } } } From 1f4738c37274f5f293df87ad9c81d06bbcc376bb Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Thu, 24 Mar 2016 12:16:57 +0100 Subject: [PATCH 148/286] Return remote shares in oc:share-types Webdav property Fixes web UI to properly display the share status icon when an outgoing remote share exists --- apps/dav/lib/connector/sabre/sharesplugin.php | 3 ++- apps/dav/tests/unit/connector/sabre/sharesplugin.php | 2 ++ apps/files/controller/apicontroller.php | 3 ++- apps/files_sharing/js/share.js | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/connector/sabre/sharesplugin.php b/apps/dav/lib/connector/sabre/sharesplugin.php index f75c137871804..c76068969e9ae 100644 --- a/apps/dav/lib/connector/sabre/sharesplugin.php +++ b/apps/dav/lib/connector/sabre/sharesplugin.php @@ -116,7 +116,8 @@ private function getShareTypes(\OCP\Files\Node $node) { $requestedShareTypes = [ \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, - \OCP\Share::SHARE_TYPE_LINK + \OCP\Share::SHARE_TYPE_LINK, + \OCP\Share::SHARE_TYPE_REMOTE ]; foreach ($requestedShareTypes as $requestedShareType) { // one of each type is enough to find out about the types diff --git a/apps/dav/tests/unit/connector/sabre/sharesplugin.php b/apps/dav/tests/unit/connector/sabre/sharesplugin.php index 9a1c6eec50751..42f1b53991664 100644 --- a/apps/dav/tests/unit/connector/sabre/sharesplugin.php +++ b/apps/dav/tests/unit/connector/sabre/sharesplugin.php @@ -248,10 +248,12 @@ function sharesGetPropertiesDataProvider() { [[\OCP\Share::SHARE_TYPE_USER]], [[\OCP\Share::SHARE_TYPE_GROUP]], [[\OCP\Share::SHARE_TYPE_LINK]], + [[\OCP\Share::SHARE_TYPE_REMOTE]], [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP]], [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]], [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_LINK]], [[\OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK]], + [[\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_REMOTE]], ]; } } diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php index 43abf2ff45899..ad28628438699 100644 --- a/apps/files/controller/apicontroller.php +++ b/apps/files/controller/apicontroller.php @@ -177,7 +177,8 @@ private function getShareTypes(Node $node) { $requestedShareTypes = [ \OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, - \OCP\Share::SHARE_TYPE_LINK + \OCP\Share::SHARE_TYPE_LINK, + \OCP\Share::SHARE_TYPE_REMOTE ]; foreach ($requestedShareTypes as $requestedShareType) { // one of each type is enough to find out about the types diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 5ec7824758f4b..a253763389c6e 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -123,6 +123,8 @@ hasShares = true; } else if (shareType === OC.Share.SHARE_TYPE_GROUP) { hasShares = true; + } else if (shareType === OC.Share.SHARE_TYPE_REMOTE) { + hasShares = true; } }); OCA.Sharing.Util._updateFileActionIcon($tr, hasShares, hasLink); From 7a6d4a32870c2a35916cce1d471b7d72ba0af887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 24 Mar 2016 14:29:55 +0100 Subject: [PATCH 149/286] In case of exception we return an html page in case the client is a browser --- apps/dav/lib/connector/sabre/objecttree.php | 6 +- .../dav/lib/connector/sabre/serverfactory.php | 5 + apps/dav/lib/files/browsererrorpageplugin.php | 110 ++++++++++++++++++ apps/dav/lib/server.php | 5 + apps/dav/templates/exception.php | 30 +++++ .../unit/dav/browsererrorpageplugintest.php | 57 +++++++++ lib/private/template.php | 5 +- 7 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 apps/dav/lib/files/browsererrorpageplugin.php create mode 100644 apps/dav/templates/exception.php create mode 100644 apps/dav/tests/unit/dav/browsererrorpageplugintest.php diff --git a/apps/dav/lib/connector/sabre/objecttree.php b/apps/dav/lib/connector/sabre/objecttree.php index 505a42d4746d2..f38dfe679c758 100644 --- a/apps/dav/lib/connector/sabre/objecttree.php +++ b/apps/dav/lib/connector/sabre/objecttree.php @@ -102,9 +102,11 @@ public function cacheNode(Node $node) { * Returns the INode object for the requested path * * @param string $path - * @throws \Sabre\DAV\Exception\ServiceUnavailable - * @throws \Sabre\DAV\Exception\NotFound * @return \Sabre\DAV\INode + * @throws InvalidPath + * @throws \Sabre\DAV\Exception\Locked + * @throws \Sabre\DAV\Exception\NotFound + * @throws \Sabre\DAV\Exception\ServiceUnavailable */ public function getNodeForPath($path) { if (!$this->fileView) { diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php index 080f889ae71cd..c0b45c36a00e1 100644 --- a/apps/dav/lib/connector/sabre/serverfactory.php +++ b/apps/dav/lib/connector/sabre/serverfactory.php @@ -26,6 +26,7 @@ namespace OCA\DAV\Connector\Sabre; +use OCA\DAV\Files\BrowserErrorPagePlugin; use OCP\Files\Mount\IMountManager; use OCP\IConfig; use OCP\IDBConnection; @@ -115,6 +116,10 @@ public function createServer($baseUri, $server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin()); } + if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) { + $server->addPlugin(new BrowserErrorPagePlugin()); + } + // wait with registering these until auth is handled and the filesystem is setup $server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) { // ensure the skeleton is copied diff --git a/apps/dav/lib/files/browsererrorpageplugin.php b/apps/dav/lib/files/browsererrorpageplugin.php new file mode 100644 index 0000000000000..129109558478e --- /dev/null +++ b/apps/dav/lib/files/browsererrorpageplugin.php @@ -0,0 +1,110 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\DAV\Files; + +use OC\AppFramework\Http\Request; +use OC_Template; +use OCP\IRequest; +use Sabre\DAV\Exception; +use Sabre\DAV\Server; +use Sabre\DAV\ServerPlugin; + +class BrowserErrorPagePlugin extends ServerPlugin { + + /** @var Server */ + private $server; + + /** + * This initializes the plugin. + * + * This function is called by Sabre\DAV\Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + * + * @param Server $server + * @return void + */ + function initialize(Server $server) { + $this->server = $server; + $server->on('exception', array($this, 'logException'), 1000); + } + + /** + * @param IRequest $request + * @return bool + */ + public static function isBrowserRequest(IRequest $request) { + if ($request->getMethod() !== 'GET') { + return false; + } + return $request->isUserAgent([Request::USER_AGENT_IE_8]); + } + + /** + * @param \Exception $ex + */ + public function logException(\Exception $ex) { + if ($ex instanceof Exception) { + $httpCode = $ex->getHTTPCode(); + $headers = $ex->getHTTPHeaders($this->server); + } else { + $httpCode = 500; + $headers = []; + } + $this->server->httpResponse->addHeaders($headers); + $this->server->httpResponse->setStatus($httpCode); + $body = $this->generateBody($ex); + $this->server->httpResponse->setBody($body); + $this->sendResponse(); + } + + /** + * @codeCoverageIgnore + * @param \Exception $ex + * @param int $httpCode + * @return bool|string + */ + public function generateBody(\Exception $exception) { + $request = \OC::$server->getRequest(); + $content = new OC_Template('dav', 'exception', 'guest'); + $content->assign('title', $this->server->httpResponse->getStatusText()); + $content->assign('message', $exception->getMessage()); + $content->assign('errorClass', get_class($exception)); + $content->assign('errorMsg', $exception->getMessage()); + $content->assign('errorCode', $exception->getCode()); + $content->assign('file', $exception->getFile()); + $content->assign('line', $exception->getLine()); + $content->assign('trace', $exception->getTraceAsString()); + $content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false)); + $content->assign('remoteAddr', $request->getRemoteAddress()); + $content->assign('requestID', $request->getId()); + return $content->fetchPage(); + } + + /* + * @codeCoverageIgnore + */ + public function sendResponse() { + $this->server->sapi->sendResponse($this->server->httpResponse); + } +} diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php index 05e81a1184c88..88096e222ecc8 100644 --- a/apps/dav/lib/server.php +++ b/apps/dav/lib/server.php @@ -29,6 +29,7 @@ use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; use OCA\DAV\Connector\Sabre\DavAclPlugin; use OCA\DAV\Connector\Sabre\FilesPlugin; +use OCA\DAV\Files\BrowserErrorPagePlugin; use OCA\DAV\Files\CustomPropertiesBackend; use OCP\IRequest; use OCP\SabrePluginEvent; @@ -112,6 +113,10 @@ public function __construct(IRequest $request, $baseUri) { $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin()); } + if (BrowserErrorPagePlugin::isBrowserRequest($request)) { + $this->server->addPlugin(new BrowserErrorPagePlugin()); + } + // wait with registering these until auth is handled and the filesystem is setup $this->server->on('beforeMethod', function () { // custom properties plugin must be the last one diff --git a/apps/dav/templates/exception.php b/apps/dav/templates/exception.php new file mode 100644 index 0000000000000..01c4eea4b5ada --- /dev/null +++ b/apps/dav/templates/exception.php @@ -0,0 +1,30 @@ + + +

+

+
+ +

t('Technical details')) ?>

+
    +
  • t('Remote Address: %s', $_['remoteAddr'])) ?>
  • +
  • t('Request ID: %s', $_['requestID'])) ?>
  • + +
  • t('Type: %s', $_['errorClass'])) ?>
  • +
  • t('Code: %s', $_['errorCode'])) ?>
  • +
  • t('Message: %s', $_['errorMsg'])) ?>
  • +
  • t('File: %s', $_['file'])) ?>
  • +
  • t('Line: %s', $_['line'])) ?>
  • + +
+ + +
+

t('Trace')) ?>

+
+ + diff --git a/apps/dav/tests/unit/dav/browsererrorpageplugintest.php b/apps/dav/tests/unit/dav/browsererrorpageplugintest.php new file mode 100644 index 0000000000000..aeae0e1b1527b --- /dev/null +++ b/apps/dav/tests/unit/dav/browsererrorpageplugintest.php @@ -0,0 +1,57 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\DAV\Tests\Unit\DAV; + +use OCA\DAV\Files\BrowserErrorPagePlugin; +use PHPUnit_Framework_MockObject_MockObject; +use Sabre\DAV\Exception\NotFound; + +class BrowserErrorPagePluginTest extends \Test\TestCase { + + /** + * @dataProvider providesExceptions + * @param $expectedCode + * @param $exception + */ + public function test($expectedCode, $exception) { + /** @var BrowserErrorPagePlugin | PHPUnit_Framework_MockObject_MockObject $plugin */ + $plugin = $this->getMockBuilder('OCA\DAV\Files\BrowserErrorPagePlugin')->setMethods(['sendResponse', 'generateBody'])->getMock(); + $plugin->expects($this->once())->method('generateBody')->willReturn(':boom:'); + $plugin->expects($this->once())->method('sendResponse'); + /** @var \Sabre\DAV\Server | PHPUnit_Framework_MockObject_MockObject $server */ + $server = $this->getMockBuilder('Sabre\DAV\Server')->disableOriginalConstructor()->getMock(); + $server->expects($this->once())->method('on'); + $httpResponse = $this->getMockBuilder('Sabre\HTTP\Response')->disableOriginalConstructor()->getMock(); + $httpResponse->expects($this->once())->method('addHeaders'); + $httpResponse->expects($this->once())->method('setStatus')->with($expectedCode); + $httpResponse->expects($this->once())->method('setBody')->with(':boom:'); + $server->httpResponse = $httpResponse; + $plugin->initialize($server); + $plugin->logException($exception); + } + + public function providesExceptions() { + return [ + [ 404, new NotFound()], + [ 500, new \RuntimeException()], + ]; + } +} diff --git a/lib/private/template.php b/lib/private/template.php index bc706e2934474..2653ae6086ad2 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -333,7 +333,7 @@ public static function printErrorPage( $error_msg, $hint = '' ) { * print error page using Exception details * @param Exception $exception */ - public static function printExceptionErrorPage($exception) { + public static function printExceptionErrorPage($exception, $fetchPage = false) { try { $request = \OC::$server->getRequest(); $content = new \OC_Template('', 'exception', 'error', false); @@ -346,6 +346,9 @@ public static function printExceptionErrorPage($exception) { $content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false)); $content->assign('remoteAddr', $request->getRemoteAddress()); $content->assign('requestID', $request->getId()); + if ($fetchPage) { + return $content->fetchPage(); + } $content->printPage(); } catch (\Exception $e) { $logger = \OC::$server->getLogger(); From 1f4e824d0b389ddfa9040583f58788682f5fdee2 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 24 Mar 2016 14:59:47 +0100 Subject: [PATCH 150/286] Add magical regex to catch browsers --- apps/dav/lib/files/browsererrorpageplugin.php | 8 +++++++- lib/private/appframework/http/request.php | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/dav/lib/files/browsererrorpageplugin.php b/apps/dav/lib/files/browsererrorpageplugin.php index 129109558478e..37a4166efef56 100644 --- a/apps/dav/lib/files/browsererrorpageplugin.php +++ b/apps/dav/lib/files/browsererrorpageplugin.php @@ -57,7 +57,13 @@ public static function isBrowserRequest(IRequest $request) { if ($request->getMethod() !== 'GET') { return false; } - return $request->isUserAgent([Request::USER_AGENT_IE_8]); + return $request->isUserAgent([ + Request::USER_AGENT_IE, + Request::USER_AGENT_MS_EDGE, + Request::USER_AGENT_CHROME, + Request::USER_AGENT_FIREFOX, + Request::USER_AGENT_SAFARI, + ]); } /** diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 1b08b245f0879..c415e606dca8a 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -49,6 +49,14 @@ class Request implements \ArrayAccess, \Countable, IRequest { const USER_AGENT_IE = '/(MSIE)|(Trident)/'; const USER_AGENT_IE_8 = '/MSIE 8.0/'; + // Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + const USER_AGENT_MS_EDGE = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/'; + // Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference + const USER_AGENT_FIREFOX = '/^Mozilla\/5\.0 \([^)]+\) Gecko\/[0-9.]+ Firefox\/[0-9.]+$/'; + // Chrome User Agent from https://developer.chrome.com/multidevice/user-agent + const USER_AGENT_CHROME = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (Mobile Safari|Safari)\/[0-9.]+$/'; + // Safari User Agent from http://www.useragentstring.com/pages/Safari/ + const USER_AGENT_SAFARI = '/^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Version\/[0-9.]+ Safari\/[0-9.A-Z]+$/'; // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#'; const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#'; From 4f78cb1e3dab7199a26cc3474089f116cff75c95 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 24 Mar 2016 15:17:13 +0100 Subject: [PATCH 151/286] handle completely unscanned storages in the background scanner --- lib/private/files/cache/scanner.php | 50 ++++++++++++++++++----------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 0a207de7b6484..5ca32548fe0ed 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -448,26 +448,38 @@ public static function isPartialFile($file) { * walk over any folders that are not fully scanned yet and scan them */ public function backgroundScan() { - $lastPath = null; - while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - try { - $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); - \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); - if ($this->cacheActive) { - $this->cache->correctFolderSize($path); - } - } catch (\OCP\Files\StorageInvalidException $e) { - // skip unavailable storages - } catch (\OCP\Files\StorageNotAvailableException $e) { - // skip unavailable storages - } catch (\OCP\Files\ForbiddenException $e) { - // skip forbidden storages - } catch (\OCP\Lock\LockedException $e) { - // skip unavailable storages + if (!$this->cache->inCache('')) { + $this->runBackgroundScanJob(function () { + $this->scan('', self::SCAN_RECURSIVE, self::REUSE_ETAG); + }, ''); + } else { + $lastPath = null; + while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { + $this->runBackgroundScanJob(function() use ($path) { + $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); + }, $path); + // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() + // to make this possible + $lastPath = $path; + } + } + } + + private function runBackgroundScanJob(callable $callback, $path) { + try { + $callback(); + \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); + if ($this->cacheActive) { + $this->cache->correctFolderSize($path); } - // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() - // to make this possible - $lastPath = $path; + } catch (\OCP\Files\StorageInvalidException $e) { + // skip unavailable storages + } catch (\OCP\Files\StorageNotAvailableException $e) { + // skip unavailable storages + } catch (\OCP\Files\ForbiddenException $e) { + // skip forbidden storages + } catch (\OCP\Lock\LockedException $e) { + // skip unavailable storages } } From b456035aa7b82a005c278395cbc25c9024761c18 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 11 Mar 2016 13:44:35 +0100 Subject: [PATCH 152/286] dont die when we cant save the resized avatar, log instead --- lib/private/avatar.php | 16 +++++++++++++--- lib/private/avatarmanager.php | 11 +++++++++-- lib/private/server.php | 3 ++- tests/lib/avatartest.php | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/private/avatar.php b/lib/private/avatar.php index 8ed920c9b18e2..4b9d3d824046e 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -31,10 +31,12 @@ use OCP\Files\Folder; use OCP\Files\File; use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; use OCP\IAvatar; use OCP\IImage; use OCP\IL10N; use OC_Image; +use OCP\ILogger; /** * This class gets and sets users avatars. @@ -47,6 +49,8 @@ class Avatar implements IAvatar { private $l; /** @var User */ private $user; + /** @var ILogger */ + private $logger; /** * constructor @@ -54,11 +58,13 @@ class Avatar implements IAvatar { * @param Folder $folder The folder where the avatars are * @param IL10N $l * @param User $user + * @param ILogger $logger */ - public function __construct (Folder $folder, IL10N $l, $user) { + public function __construct (Folder $folder, IL10N $l, $user, ILogger $logger) { $this->folder = $folder; $this->l = $l; $this->user = $user; + $this->logger = $logger; } /** @@ -164,8 +170,12 @@ public function getFile($size) { if ($size !== -1) { $avatar->resize($size); } - $file = $this->folder->newFile($path); - $file->putContent($avatar->data()); + try { + $file = $this->folder->newFile($path); + $file->putContent($avatar->data()); + } catch (NotPermittedException $e) { + $this->logger->error('Failed to save avatar for ' . $this->user->getUID()); + } } return $file; diff --git a/lib/private/avatarmanager.php b/lib/private/avatarmanager.php index 3b619cda574bc..62f4faf436cbf 100644 --- a/lib/private/avatarmanager.php +++ b/lib/private/avatarmanager.php @@ -28,6 +28,7 @@ use OCP\Files\Folder; use OCP\Files\NotFoundException; use OCP\IAvatarManager; +use OCP\ILogger; use OCP\IUserManager; use OCP\Files\IRootFolder; use OCP\IL10N; @@ -46,20 +47,26 @@ class AvatarManager implements IAvatarManager { /** @var IL10N */ private $l; + /** @var ILogger */ + private $logger; + /** * AvatarManager constructor. * * @param IUserManager $userManager * @param IRootFolder $rootFolder * @param IL10N $l + * @param ILogger $logger */ public function __construct( IUserManager $userManager, IRootFolder $rootFolder, - IL10N $l) { + IL10N $l, + ILogger $logger) { $this->userManager = $userManager; $this->rootFolder = $rootFolder; $this->l = $l; + $this->logger = $logger; } /** @@ -85,6 +92,6 @@ public function getAvatar($userId) { /** @var Folder $folder */ $folder = $this->rootFolder->get($dir); - return new Avatar($folder, $this->l, $user); + return new Avatar($folder, $this->l, $user, $this->logger); } } diff --git a/lib/private/server.php b/lib/private/server.php index d68a361955f07..509c1ea0e58ec 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -312,7 +312,8 @@ public function __construct($webRoot, \OC\Config $config) { return new AvatarManager( $c->getUserManager(), $c->getRootFolder(), - $c->getL10N('lib') + $c->getL10N('lib'), + $c->getLogger() ); }); $this->registerService('Logger', function (Server $c) { diff --git a/tests/lib/avatartest.php b/tests/lib/avatartest.php index e7d7831108513..b2b69ac1a6c3a 100644 --- a/tests/lib/avatartest.php +++ b/tests/lib/avatartest.php @@ -27,7 +27,7 @@ public function setUp() { $l = $this->getMock('\OCP\IL10N'); $l->method('t')->will($this->returnArgument(0)); $this->user = $this->getMockBuilder('\OC\User\User')->disableOriginalConstructor()->getMock(); - $this->avatar = new \OC\Avatar($this->folder, $l, $this->user); + $this->avatar = new \OC\Avatar($this->folder, $l, $this->user, $this->getMock('\OCP\ILogger')); } public function testGetNoAvatar() { From c066882309346468092e0b8202852a763354bd94 Mon Sep 17 00:00:00 2001 From: Daniel Hansson Date: Sat, 26 Mar 2016 15:10:04 +0100 Subject: [PATCH 153/286] [stable9] Fix for themes with .jpg backgrounds Without this all themes with .jpg or .jpeg are broken. --- .htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index 3c5affd823373..df074f7f80681 100644 --- a/.htaccess +++ b/.htaccess @@ -64,7 +64,7 @@ Options -MultiViews RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1] RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1] - RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff|ico)$ + RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$ RewriteCond %{REQUEST_FILENAME} !/remote.php RewriteCond %{REQUEST_FILENAME} !/public.php From 1733b6e8c87069ab903d8e09c1fd457c76e60f71 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 24 Mar 2016 09:32:11 +0100 Subject: [PATCH 154/286] We are only formatting an object when it's not null --- lib/private/activitymanager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php index 9258b7298ccc4..373105291dd7d 100644 --- a/lib/private/activitymanager.php +++ b/lib/private/activitymanager.php @@ -321,7 +321,8 @@ public function setFormattingObject($type, $id) { * @return bool */ public function isFormattingFilteredObject() { - return $this->formattingObjectType === $this->request->getParam('object_type') + return $this->formattingObjectType !== null && $this->formattingObjectId !== null + && $this->formattingObjectType === $this->request->getParam('object_type') && $this->formattingObjectId === $this->request->getParam('object_id'); } From b5922e467ab2570d25ccbfce0d20115fbf831be8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 24 Mar 2016 09:33:00 +0100 Subject: [PATCH 155/286] Allow the activity app to set the current user when sending emails --- lib/private/activitymanager.php | 20 +++++++++++++++++++- lib/public/activity/imanager.php | 10 ++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php index 373105291dd7d..e522dca9e3b4f 100644 --- a/lib/private/activitymanager.php +++ b/lib/private/activitymanager.php @@ -49,6 +49,9 @@ class ActivityManager implements IManager { /** @var int */ protected $formattingObjectId; + /** @var string */ + protected $currentUserId; + /** * constructor of the controller * @@ -475,6 +478,19 @@ public function getQueryForFilter($filter) { return array(' and ((' . implode(') or (', $conditions) . '))', $parameters); } + /** + * Set the user we need to use + * + * @param string|null $currentUserId + * @throws \UnexpectedValueException If the user is invalid + */ + public function setCurrentUserId($currentUserId) { + if (!is_string($currentUserId) && $currentUserId !== null) { + throw new \UnexpectedValueException('The given current user is invalid'); + } + $this->currentUserId = $currentUserId; + } + /** * Get the user we need to use * @@ -484,7 +500,9 @@ public function getQueryForFilter($filter) { * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique */ public function getCurrentUserId() { - if (!$this->session->isLoggedIn()) { + if ($this->currentUserId !== null) { + return $this->currentUserId; + } else if (!$this->session->isLoggedIn()) { return $this->getUserFromToken(); } else { return $this->session->getUser()->getUID(); diff --git a/lib/public/activity/imanager.php b/lib/public/activity/imanager.php index 0b97f8a07edaf..cbd08722410cc 100644 --- a/lib/public/activity/imanager.php +++ b/lib/public/activity/imanager.php @@ -204,6 +204,16 @@ public function filterNotificationTypes($types, $filter); */ public function getQueryForFilter($filter); + + /** + * Set the user we need to use + * + * @param string|null $currentUserId + * @throws \UnexpectedValueException If the user is invalid + * @since 9.0.1 + */ + public function setCurrentUserId($currentUserId); + /** * Get the user we need to use * From 52f4acf23d9e388fdc6348858c4572e291bbc56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 16 Mar 2016 15:54:47 +0100 Subject: [PATCH 156/286] Explicitly add the current principal to the acl in case of group sharing --- apps/dav/appinfo/application.php | 16 +++++-- apps/dav/appinfo/register_command.php | 2 +- apps/dav/appinfo/v1/caldav.php | 6 ++- apps/dav/appinfo/v1/carddav.php | 6 +-- apps/dav/command/createcalendar.php | 4 +- apps/dav/lib/caldav/caldavbackend.php | 37 ++++++++++------ apps/dav/lib/caldav/calendar.php | 4 +- apps/dav/lib/carddav/addressbook.php | 4 +- apps/dav/lib/carddav/carddavbackend.php | 31 ++++++++----- apps/dav/lib/dav/sharing/backend.php | 43 +++++++++++++++---- apps/dav/lib/dav/sharing/ishareable.php | 2 +- apps/dav/lib/rootcollection.php | 7 +-- .../tests/unit/caldav/caldavbackendtest.php | 10 ++++- .../tests/unit/carddav/carddavbackendtest.php | 32 ++++++++------ 14 files changed, 138 insertions(+), 66 deletions(-) diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index d06daf97f5452..6e86f422d4205 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -27,6 +27,7 @@ use OCA\DAV\CardDAV\ContactsManager; use OCA\DAV\CardDAV\SyncJob; use OCA\DAV\CardDAV\SyncService; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\HookManager; use OCA\Dav\Migration\AddressBookAdapter; use OCA\Dav\Migration\CalendarAdapter; @@ -83,7 +84,8 @@ public function __construct (array $urlParams=array()) { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new CardDavBackend($db, $principal, $dispatcher); + $groupPrincipal = new GroupPrincipalBackend($c->getServer()->getGroupManager()); + return new CardDavBackend($db, $principal, $groupPrincipal, $dispatcher); }); $container->registerService('CalDavBackend', function($c) { @@ -93,7 +95,8 @@ public function __construct (array $urlParams=array()) { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - return new CalDavBackend($db, $principal); + $groupPrincipal = new GroupPrincipalBackend($c->getServer()->getGroupManager()); + return new CalDavBackend($db, $principal, $groupPrincipal); }); $container->registerService('MigrateAddressbooks', function($c) { @@ -217,7 +220,7 @@ public function generateBirthdays() { $migration = $this->getContainer()->query('BirthdayService'); $userManager = $this->getContainer()->getServer()->getUserManager(); - $userManager->callForAllUsers(function($user) use($migration) { + $userManager->callForAllUsers(function ($user) use ($migration) { /** @var IUser $user */ $migration->syncUser($user->getUID()); }); @@ -225,4 +228,11 @@ public function generateBirthdays() { $this->getContainer()->getServer()->getLogger()->logException($ex); } } + + /** + * @return CardDavBackend + */ + public function getCardDavBackend() { + return $this->getContainer()->query('CardDavBackend'); + } } diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 570848f0b234e..45b43d6f2d5de 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -34,7 +34,7 @@ /** @var Symfony\Component\Console\Application $application */ $application->add(new CreateCalendar($userManager, $groupManager, $dbConnection)); -$application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend'))); +$application->add(new CreateAddressBook($userManager, $app->getCardDavBackend())); $application->add(new SyncSystemAddressBook($app->getSyncService())); $application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService'))); $application->add(new MigrateAddressbooks($userManager, $app->getContainer()->query('MigrateAddressbooks'))); diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index f2c886e0fdd0a..3e1a7ce625337 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -23,11 +23,12 @@ // Backends use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CalDAV\CalendarRoot; use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCA\DAV\Connector\Sabre\Principal; -use Sabre\CalDAV\CalendarRoot; +use OCA\DAV\DAV\GroupPrincipalBackend; $authBackend = new Auth( \OC::$server->getSession(), @@ -41,7 +42,8 @@ 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$calDavBackend = new CalDavBackend($db, $principalBackend); +$groupPrincipal = new GroupPrincipalBackend(\OC::$server->getGroupManager()); +$calDavBackend = new CalDavBackend($db, $principalBackend, $groupPrincipal); // Root nodes $principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend); diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index 44abcbaa19010..ac6ffea250604 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -42,14 +42,14 @@ 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$cardDavBackend = new CardDavBackend($db, $principalBackend); +$app = new \OCA\Dav\AppInfo\Application(); // Root nodes $principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend); $principalCollection->disableListing = true; // Disable listing -$addressBookRoot = new AddressBookRoot($principalBackend, $cardDavBackend); -$addressBookRoot->disableListing = true; // Disable listing +$addressBookRoot = new AddressBookRoot($principalBackend, $app->getCardDavBackend()); +$addressBookRoot->disableListing = false; // Disable listing $nodes = array( $principalCollection, diff --git a/apps/dav/command/createcalendar.php b/apps/dav/command/createcalendar.php index d7f82dd0e524f..a1a15513a001d 100644 --- a/apps/dav/command/createcalendar.php +++ b/apps/dav/command/createcalendar.php @@ -22,6 +22,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Connector\Sabre\Principal; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; @@ -73,9 +74,10 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->userManager, $this->groupManager ); + $groupPrincipal = new GroupPrincipalBackend($this->groupManager); $name = $input->getArgument('name'); - $caldav = new CalDavBackend($this->dbConnection, $principalBackend); + $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $groupPrincipal); $caldav->createCalendar("principals/users/$user", $name, []); } } diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index bb50100d9a2cd..a188d652eedd6 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -22,6 +22,7 @@ namespace OCA\DAV\CalDAV; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\DAV\Sharing\IShareable; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\Connector\Sabre\Principal; @@ -35,7 +36,9 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV; +use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\PropPatch; use Sabre\HTTP\URLUtil; use Sabre\VObject\DateTimeParser; use Sabre\VObject\Reader; @@ -104,12 +107,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * CalDavBackend constructor. * * @param IDBConnection $db - * @param Principal $principalBackend + * @param $userPrincipalBackend + * @param GroupPrincipalBackend $groupPrincipalBackend */ - public function __construct(IDBConnection $db, Principal $principalBackend) { + public function __construct(IDBConnection $db, $userPrincipalBackend, GroupPrincipalBackend $groupPrincipalBackend) { $this->db = $db; - $this->principalBackend = $principalBackend; - $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); + $this->principalBackend = $userPrincipalBackend; + $this->sharingBackend = new Backend($this->db, $userPrincipalBackend, $groupPrincipalBackend, 'calendar'); } /** @@ -340,6 +344,7 @@ public function getCalendarById($calendarId) { * @param string $calendarUri * @param array $properties * @return int + * @throws DAV\Exception */ function createCalendar($principalUri, $calendarUri, array $properties) { $values = [ @@ -391,10 +396,10 @@ function createCalendar($principalUri, $calendarUri, array $properties) { * * Read the PropPatch documentation for more info and examples. * - * @param \Sabre\DAV\PropPatch $propPatch - * @return void + * @param int $calendarId + * @param PropPatch $propPatch */ - function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) { + function updateCalendar($calendarId, PropPatch $propPatch) { $supportedProperties = array_keys($this->propertyMap); $supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp'; @@ -1034,6 +1039,7 @@ function getSubscriptionsForUser($principalUri) { * @param string $uri * @param array $properties * @return mixed + * @throws Forbidden */ function createSubscription($principalUri, $uri, array $properties) { @@ -1082,10 +1088,10 @@ function createSubscription($principalUri, $uri, array $properties) { * Read the PropPatch documentation for more info and examples. * * @param mixed $subscriptionId - * @param \Sabre\DAV\PropPatch $propPatch + * @param PropPatch $propPatch * @return void */ - function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) { + function updateSubscription($subscriptionId, PropPatch $propPatch) { $supportedProperties = array_keys($this->subscriptionPropertyMap); $supportedProperties[] = '{http://calendarserver.org/ns/}source'; @@ -1275,6 +1281,7 @@ protected function addChange($calendarId, $objectUri, $operation) { * * @param string $calendarData * @return array + * @throws BadRequest */ protected function getDenormalizedData($calendarData) { @@ -1292,7 +1299,7 @@ protected function getDenormalizedData($calendarData) { } } if (!$componentType) { - throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); + throw new BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } if ($componentType === 'VEVENT' && $component->DTSTART) { $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); @@ -1359,19 +1366,21 @@ public function updateShares($shareable, $add, $remove) { /** * @param int $resourceId + * @param string $currentPrincipal * @return array */ - public function getShares($resourceId) { - return $this->sharingBackend->getShares($resourceId); + public function getShares($resourceId, $currentPrincipal) { + return $this->sharingBackend->getShares($resourceId, $currentPrincipal); } /** * @param int $resourceId * @param array $acl + * @param string $currentPrincipal * @return array */ - public function applyShareAcl($resourceId, $acl) { - return $this->sharingBackend->applyShareAcl($resourceId, $acl); + public function applyShareAcl($resourceId, $acl, $currentPrincipal) { + return $this->sharingBackend->applyShareAcl($resourceId, $acl, $currentPrincipal); } private function convertPrincipal($principalUri, $toV2) { diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 1e87f9b433398..bc2646eb60d1c 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -75,7 +75,7 @@ function updateShares(array $add, array $remove) { function getShares() { /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; - return $calDavBackend->getShares($this->getResourceId()); + return $calDavBackend->getShares($this->getResourceId(), parent::getOwner()); } /** @@ -90,7 +90,7 @@ function getACL() { /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; - return $calDavBackend->applyShareAcl($this->getResourceId(), $acl); + return $calDavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); } function getChildACL() { diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index bb9d13b981e62..70456afbd0f37 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -66,7 +66,7 @@ function updateShares(array $add, array $remove) { function getShares() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->getShares($this->getResourceId()); + return $carddavBackend->getShares($this->getResourceId(), $this->getOwner()); } function getACL() { @@ -113,7 +113,7 @@ function getChildACL() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getResourceId(), $acl); + return $carddavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); } function getChild($name) { diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index bfb6ea82ad75a..89154c39d3785 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -25,6 +25,7 @@ namespace OCA\DAV\CardDAV; use OCA\DAV\Connector\Sabre\Principal; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\DAV\Sharing\Backend; use OCA\DAV\DAV\Sharing\IShareable; @@ -34,6 +35,7 @@ use Sabre\CardDAV\Backend\SyncSupport; use Sabre\CardDAV\Plugin; use Sabre\DAV\Exception\BadRequest; +use Sabre\DAV\PropPatch; use Sabre\HTTP\URLUtil; use Sabre\VObject\Component\VCard; use Sabre\VObject\Reader; @@ -73,16 +75,18 @@ class CardDavBackend implements BackendInterface, SyncSupport { * CardDavBackend constructor. * * @param IDBConnection $db - * @param Principal $principalBackend + * @param Principal $userPrincipalBackend + * @param GroupPrincipalBackend $groupPrincipalBackend * @param EventDispatcherInterface $dispatcher */ public function __construct(IDBConnection $db, - Principal $principalBackend, + Principal $userPrincipalBackend, + GroupPrincipalBackend $groupPrincipalBackend, EventDispatcherInterface $dispatcher = null) { $this->db = $db; - $this->principalBackend = $principalBackend; + $this->principalBackend = $userPrincipalBackend; $this->dispatcher = $dispatcher; - $this->sharingBackend = new Backend($this->db, $principalBackend, 'addressbook'); + $this->sharingBackend = new Backend($this->db, $userPrincipalBackend, $groupPrincipalBackend, 'addressbook'); } /** @@ -164,6 +168,7 @@ function getAddressBooksForUser($principalUri) { /** * @param int $addressBookId + * @return array|null */ public function getAddressBookById($addressBookId) { $query = $this->db->getQueryBuilder(); @@ -190,7 +195,8 @@ public function getAddressBookById($addressBookId) { } /** - * @param $addressBookUri + * @param string $principal + * @param string $addressBookUri * @return array|null */ public function getAddressBooksByUri($principal, $addressBookUri) { @@ -232,10 +238,10 @@ public function getAddressBooksByUri($principal, $addressBookUri) { * Read the PropPatch documentation for more info and examples. * * @param string $addressBookId - * @param \Sabre\DAV\PropPatch $propPatch + * @param PropPatch $propPatch * @return void */ - function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) { + function updateAddressBook($addressBookId, PropPatch $propPatch) { $supportedProperties = [ '{DAV:}displayname', '{' . Plugin::NS_CARDDAV . '}addressbook-description', @@ -870,10 +876,12 @@ public function getContact($addressBookId, $uri) { * * readOnly - boolean * * summary - Optional, a description for the share * + * @param $addressBookId + * @param string $currentPrincipal * @return array */ - public function getShares($addressBookId) { - return $this->sharingBackend->getShares($addressBookId); + public function getShares($addressBookId, $currentPrincipal) { + return $this->sharingBackend->getShares($addressBookId, $currentPrincipal); } /** @@ -971,10 +979,11 @@ protected function getCardId($addressBookId, $uri) { * For shared address books the sharee is set in the ACL of the address book * @param $addressBookId * @param $acl + * @param string $currentPrincipal * @return array */ - public function applyShareAcl($addressBookId, $acl) { - return $this->sharingBackend->applyShareAcl($addressBookId, $acl); + public function applyShareAcl($addressBookId, $acl, $currentPrincipal) { + return $this->sharingBackend->applyShareAcl($addressBookId, $acl, $currentPrincipal); } private function convertPrincipal($principalUri, $toV2) { diff --git a/apps/dav/lib/dav/sharing/backend.php b/apps/dav/lib/dav/sharing/backend.php index ffc4193e34b64..9ef1a07ebc60a 100644 --- a/apps/dav/lib/dav/sharing/backend.php +++ b/apps/dav/lib/dav/sharing/backend.php @@ -23,6 +23,7 @@ namespace OCA\DAV\DAV\Sharing; use OCA\DAV\Connector\Sabre\Principal; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\IDBConnection; class Backend { @@ -30,7 +31,9 @@ class Backend { /** @var IDBConnection */ private $db; /** @var Principal */ - private $principalBackend; + private $userPrincipalBackend; + /** @var GroupPrincipalBackend */ + private $groupPrincipalBackend; /** @var string */ private $resourceType; @@ -40,12 +43,14 @@ class Backend { /** * @param IDBConnection $db - * @param Principal $principalBackend + * @param Principal $userPrincipalBackend + * @param GroupPrincipalBackend $groupPrincipalBackend * @param string $resourceType */ - public function __construct(IDBConnection $db, Principal $principalBackend, $resourceType) { + public function __construct(IDBConnection $db, Principal $userPrincipalBackend, GroupPrincipalBackend $groupPrincipalBackend, $resourceType) { $this->db = $db; - $this->principalBackend = $principalBackend; + $this->userPrincipalBackend = $userPrincipalBackend; + $this->groupPrincipalBackend = $groupPrincipalBackend; $this->resourceType = $resourceType; } @@ -143,9 +148,10 @@ private function unshare($shareable, $element) { * * summary - Optional, a description for the share * * @param int $resourceId + * @param string $currentPrincipal * @return array */ - public function getShares($resourceId) { + public function getShares($resourceId, $currentPrincipal) { $query = $this->db->getQueryBuilder(); $result = $query->select(['principaluri', 'access']) ->from('dav_shares') @@ -155,13 +161,31 @@ public function getShares($resourceId) { $shares = []; while($row = $result->fetch()) { - $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); + $p = $this->userPrincipalBackend->getPrincipalByPath($row['principaluri']); + if (is_null($p)) { + $p = $this->groupPrincipalBackend->getPrincipalByPath($row['principaluri']); + if (is_null($p)) { + continue; + } + // also add the current user if it is member of the group + $groups = $this->userPrincipalBackend->getGroupMembership($currentPrincipal); + if (in_array($row['principaluri'], $groups)) { + $ownerPrincipal = $this->userPrincipalBackend->getPrincipalByPath($currentPrincipal); + $shares[]= [ + 'href' => "principal:$currentPrincipal", + 'commonName' => isset($ownerPrincipal['{DAV:}displayname']) ? $ownerPrincipal['{DAV:}displayname'] : '', + 'status' => 1, + 'readOnly' => ($row['access'] == self::ACCESS_READ), + '{http://owncloud.org/ns}principal' => $currentPrincipal + ]; + } + } $shares[]= [ 'href' => "principal:${row['principaluri']}", 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', 'status' => 1, 'readOnly' => ($row['access'] == self::ACCESS_READ), - '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $row['principaluri'] + '{http://owncloud.org/ns}principal' => $row['principaluri'] ]; } @@ -173,11 +197,12 @@ public function getShares($resourceId) { * * @param int $resourceId * @param array $acl + * @param string $currentPrincipal * @return array */ - public function applyShareAcl($resourceId, $acl) { + public function applyShareAcl($resourceId, $acl, $currentPrincipal) { - $shares = $this->getShares($resourceId); + $shares = $this->getShares($resourceId, $currentPrincipal); foreach ($shares as $share) { $acl[] = [ 'privilege' => '{DAV:}read', diff --git a/apps/dav/lib/dav/sharing/ishareable.php b/apps/dav/lib/dav/sharing/ishareable.php index f6b6bfa88624b..b0f3307335bab 100644 --- a/apps/dav/lib/dav/sharing/ishareable.php +++ b/apps/dav/lib/dav/sharing/ishareable.php @@ -71,4 +71,4 @@ public function getResourceId(); */ public function getOwner(); -} \ No newline at end of file +} diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index ea796c091753f..fd1a1558efd63 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -57,7 +57,7 @@ public function __construct() { $systemPrincipals->disableListing = $disableListing; $filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); $filesCollection->disableListing = $disableListing; - $caldavBackend = new CalDavBackend($db, $userPrincipalBackend); + $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $groupPrincipalBackend); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; @@ -80,12 +80,13 @@ public function __construct() { \OC::$server->getRootFolder(), \OC::$server->getLogger() ); + $groupPrincipal = new GroupPrincipalBackend(\OC::$server->getGroupManager()); - $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); + $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $groupPrincipal, $dispatcher); $usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, 'principals/users'); $usersAddressBookRoot->disableListing = $disableListing; - $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); + $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $groupPrincipal, $dispatcher); $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index 87a700a473dc7..db89661227652 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -25,6 +25,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; +use OCA\DAV\DAV\GroupPrincipalBackend; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Property\Href; @@ -46,6 +47,9 @@ class CalDavBackendTest extends TestCase { /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ private $principal; + /** @var GroupPrincipalBackend | \PHPUnit_Framework_MockObject_MockObject */ + private $groupPrincipal; + const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; @@ -64,9 +68,13 @@ public function setUp() { $this->principal->expects($this->any())->method('getGroupMembership') ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); + $this->groupPrincipal = $this->getMockBuilder('OCA\DAV\DAV\GroupPrincipalBackend') + ->disableOriginalConstructor() + ->setMethods(['getPrincipalByPath', 'getGroupMembership']) + ->getMock(); $db = \OC::$server->getDatabaseConnection(); - $this->backend = new CalDavBackend($db, $this->principal); + $this->backend = new CalDavBackend($db, $this->principal, $this->groupPrincipal); $this->tearDown(); } diff --git a/apps/dav/tests/unit/carddav/carddavbackendtest.php b/apps/dav/tests/unit/carddav/carddavbackendtest.php index 1ee09260c88ce..38b8a81b2bc2c 100644 --- a/apps/dav/tests/unit/carddav/carddavbackendtest.php +++ b/apps/dav/tests/unit/carddav/carddavbackendtest.php @@ -27,6 +27,7 @@ use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; +use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use Sabre\DAV\PropPatch; @@ -58,6 +59,9 @@ class CardDavBackendTest extends TestCase { /** @var string */ private $dbCardsPropertiesTable = 'cards_properties'; + /** @var GroupPrincipalBackend */ + private $groupPrincipal; + const UNIT_TEST_USER = 'principals/users/carddav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/carddav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/carddav-unit-test-group'; @@ -69,17 +73,21 @@ public function setUp() { ->disableOriginalConstructor() ->setMethods(['getPrincipalByPath', 'getGroupMembership']) ->getMock(); - $this->principal->method('getPrincipalByPath') + $this->principal->expects($this->any())->method('getPrincipalByPath') ->willReturn([ 'uri' => 'principals/best-friend' ]); - $this->principal->method('getGroupMembership') + $this->principal->expects($this->any())->method('getGroupMembership') ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); + $this->groupPrincipal = $this->getMockBuilder('OCA\DAV\DAV\GroupPrincipalBackend') + ->disableOriginalConstructor() + ->setMethods(['getPrincipalByPath', 'getGroupMembership']) + ->getMock(); $this->db = \OC::$server->getDatabaseConnection(); - $this->backend = new CardDavBackend($this->db, $this->principal, null); + $this->backend = new CardDavBackend($this->db, $this->principal, $this->groupPrincipal, null); // start every test with a empty cards_properties and cards table $query = $this->db->getQueryBuilder(); @@ -157,7 +165,7 @@ public function testCardOperations() { /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backend */ $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) ->setMethods(['updateProperties', 'purgeProperties'])->getMock(); // create a new address book @@ -203,7 +211,7 @@ public function testCardOperations() { public function testMultiCard() { $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -248,9 +256,8 @@ public function testMultiCard() { } public function testDeleteWithoutCard() { - $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) ->setMethods([ 'getCardId', 'addChange', @@ -289,9 +296,8 @@ public function testDeleteWithoutCard() { } public function testSyncSupport() { - $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -321,13 +327,13 @@ public function testSharing() { $exampleBook = new AddressBook($this->backend, $books[0]); $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getResourceId()); + $shares = $this->backend->getShares($exampleBook->getResourceId(), null); $this->assertEquals(1, count($shares)); // adding the same sharee again has no effect $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getResourceId()); + $shares = $this->backend->getShares($exampleBook->getResourceId(), null); $this->assertEquals(1, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -335,7 +341,7 @@ public function testSharing() { $this->backend->updateShares($exampleBook, [], ['principal:principals/best-friend']); - $shares = $this->backend->getShares($exampleBook->getResourceId()); + $shares = $this->backend->getShares($exampleBook->getResourceId(), null); $this->assertEquals(0, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -349,7 +355,7 @@ public function testUpdateProperties() { $cardId = 2; $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, null]) + ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) ->setMethods(['getCardId'])->getMock(); $backend->expects($this->any())->method('getCardId')->willReturn($cardId); From 3b4999c835ee35c5f68ef562a3175446a1a080a0 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 29 Mar 2016 19:11:52 +0200 Subject: [PATCH 157/286] correct form of upload-white icon to be same as upload icon --- core/img/actions/upload-white.png | Bin 152 -> 142 bytes core/img/actions/upload-white.svg | 4 +--- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/img/actions/upload-white.png b/core/img/actions/upload-white.png index a3b233e8aa68790c731bc989f6db0c1b7fdc1673..28693f855d3e8243fe54d533451921ce585d3770 100644 GIT binary patch delta 124 zcmbQi*vB|QvXq&Dfk8u;KNv{y1o(uw0_p!SU~#~D1(45N666=m(9oeYExaAb)$??5 z45?sDKENt5^TLlaXM8ehIyjp61sy*KDskAY(i7l!nXK&~VW7zopr01a{}A^-pY delta 134 zcmV;10D1q80hj@h8Gi-<001BJ|6u?C0AEQ&K~y-)WBmXBKLaIziGX|q6ypZ}|NqB@ z8~!6e11@#MXvS*@v6^ujLW*XrhLEZm!w_;bqZq=7BOSbDU| - - - + From fb77aa2e621d375820f22ea9c65fd585294282c9 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 29 Mar 2016 22:03:08 +0200 Subject: [PATCH 158/286] 9.0.1 RC1 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 15871590df9e4..39cddf766a6ab 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 1, 0); +$OC_Version = array(9, 0, 1, 1); // The human readable string -$OC_VersionString = '9.0.1 beta'; +$OC_VersionString = '9.0.1 RC1'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 8c9842fbd9c1a3e0f83640ce407ebe64f4d04b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 30 Mar 2016 10:01:17 +0200 Subject: [PATCH 159/286] Fix unit test --- apps/dav/lib/caldav/calendar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index bc2646eb60d1c..dbd75bad20b94 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -98,7 +98,7 @@ function getChildACL() { /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; - return $calDavBackend->applyShareAcl($this->getResourceId(), $acl); + return $calDavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); } function getOwner() { From 3cadc45ca5020d1ca6ca511e73e576be150e4c44 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 29 Mar 2016 18:52:17 +0200 Subject: [PATCH 160/286] only remove avatars from the folder we store them in --- lib/private/avatar.php | 2 +- tests/lib/avatartest.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/private/avatar.php b/lib/private/avatar.php index 4b9d3d824046e..3f8038360a40f 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -134,7 +134,7 @@ public function set ($data) { */ public function remove () { $regex = '/^avatar\.([0-9]+\.)?(jpg|png)$/'; - $avatars = $this->folder->search('avatar'); + $avatars = $this->folder->getDirectoryListing(); foreach ($avatars as $avatar) { if (preg_match($regex, $avatar->getName())) { diff --git a/tests/lib/avatartest.php b/tests/lib/avatartest.php index b2b69ac1a6c3a..b0ab4cb8b5cdf 100644 --- a/tests/lib/avatartest.php +++ b/tests/lib/avatartest.php @@ -148,8 +148,7 @@ public function testSetAvatar() { ->willReturn('avatarX'); $nonAvatarFile->expects($this->never())->method('delete'); - $this->folder->method('search') - ->with('avatar') + $this->folder->method('getDirectoryListing') ->willReturn([$avatarFileJPG, $avatarFilePNG, $resizedAvatarFile, $nonAvatarFile]); $newFile = $this->getMock('\OCP\Files\File'); From 2660cf80c3232bd09030b70f55ce8bfbd6700b92 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 30 Mar 2016 13:33:16 +0200 Subject: [PATCH 161/286] Non moveable mount points should always be UPDATE+DELETE shareable Fixes #23536 The new sharing code is much stricter in checking permissions. However for non moveable mounts the permissions UPDATE+DELETE are not reported on the mount point. This is just a quick fix. * Updated unit tests --- lib/private/share20/manager.php | 14 +++++++++++++- tests/lib/share20/managertest.php | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index 5e40acefbef56..9e04d57b28963 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -23,6 +23,7 @@ namespace OC\Share20; +use OC\Files\Mount\MoveableMount; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\IUserManager; @@ -215,8 +216,19 @@ protected function generalCreateChecks(\OCP\Share\IShare $share) { throw new \InvalidArgumentException('A share requires permissions'); } + /* + * Quick fix for #23536 + * Non moveable mount points do not have update and delete permissions + * while we 'most likely' do have that on the storage. + */ + $permissions = $share->getNode()->getPermissions(); + $mount = $share->getNode()->getMountPoint(); + if (!($mount instanceof MoveableMount)) { + $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE; + } + // Check that we do not share with more permissions than we have - if ($share->getPermissions() & ~$share->getNode()->getPermissions()) { + if ($share->getPermissions() & ~$permissions) { $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]); throw new GenericShareException($message_t, $message_t, 404); } diff --git a/tests/lib/share20/managertest.php b/tests/lib/share20/managertest.php index 2f45de86b9828..029c8cd85430d 100644 --- a/tests/lib/share20/managertest.php +++ b/tests/lib/share20/managertest.php @@ -640,10 +640,21 @@ public function dataGeneralChecks() { $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, null, null, null), 'A share requires permissions', true]; $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $limitedPermssions, null, $user0, $user0, null, null, null), 'A share requires permissions', true]; + $mount = $this->getMock('OC\Files\Mount\MoveableMount'); + $limitedPermssions->method('getMountPoint')->willReturn($mount); + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 31, null, null), 'Cannot increase permissions of path', true]; $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, 17, null, null), 'Cannot increase permissions of path', true]; $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_LINK, $limitedPermssions, null, $user0, $user0, 3, null, null), 'Cannot increase permissions of path', true]; + $nonMoveableMountPermssions = $this->getMock('\OCP\Files\File'); + $nonMoveableMountPermssions->method('isShareable')->willReturn(true); + $nonMoveableMountPermssions->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ); + $nonMoveableMountPermssions->method('getPath')->willReturn('path'); + + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_USER, $nonMoveableMountPermssions, $user2, $user0, $user0, 11, null, null), 'Cannot increase permissions of path', false]; + $data[] = [$this->createShare(null, \OCP\Share::SHARE_TYPE_GROUP, $nonMoveableMountPermssions, $group0, $user0, $user0, 11, null, null), 'Cannot increase permissions of path', false]; + $rootFolder = $this->getMock('\OCP\Files\Folder'); $rootFolder->method('isShareable')->willReturn(true); $rootFolder->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_ALL); From dd8d1c2b94d1790b96ab98c5c8e79c8f94b4cac3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 30 Mar 2016 14:54:56 +0200 Subject: [PATCH 162/286] xcache.var_size with 64M should evaluate to isAvailable --- lib/private/memcache/xcache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/memcache/xcache.php b/lib/private/memcache/xcache.php index eea55fefc4de2..e80901faadce5 100644 --- a/lib/private/memcache/xcache.php +++ b/lib/private/memcache/xcache.php @@ -125,7 +125,7 @@ static public function isAvailable() { // AND administration functions are password-protected. return false; } - $var_size = \OC::$server->getIniWrapper()->getNumeric('xcache.var_size'); + $var_size = \OC::$server->getIniWrapper()->getBytes('xcache.var_size'); if (!$var_size) { return false; } From 57596e14156c9b125cecd617fef21326b87e3438 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 30 Mar 2016 16:55:26 +0200 Subject: [PATCH 163/286] Use the shipped cacerts.pem instead of the global one The one we ship may cause problems since Equifax is not included anymore (SHA-1 certs) are deprecated. We should just be consistent here and also use the certificate file which is used by the other calls in the library. --- apps/files_external/lib/google.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index b79f42d1e009b..91e7dfee08df6 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -445,6 +445,7 @@ public function fopen($path, $mode) { $client->get($downloadUrl, [ 'headers' => $httpRequest->getRequestHeaders(), 'save_to' => $tmpFile, + 'verify' => __DIR__ . '/../3rdparty/google-api-php-client/src/Google/IO/cacerts.pem', ]); } catch (RequestException $e) { if(!is_null($e->getResponse())) { From f9816611959cc550952967bde4c4f2110d3507b9 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 30 Mar 2016 18:09:02 +0200 Subject: [PATCH 164/286] Fix displaying owner before share icon in file list Initial display of owner was missing --- apps/files_sharing/js/share.js | 5 +++-- apps/files_sharing/tests/js/shareSpec.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index a253763389c6e..5bfc8e1d4a241 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -111,8 +111,9 @@ _.each($files, function(file) { var $tr = $(file); - var shareTypes = $tr.attr('data-share-types'); - if (shareTypes) { + var shareTypes = $tr.attr('data-share-types') || ''; + var shareOwner = $tr.attr('data-share-owner'); + if (shareTypes || shareOwner) { var hasLink = false; var hasShares = false; _.each(shareTypes.split(',') || [], function(shareType) { diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js index c488bd94fab98..c34234bfe13f8 100644 --- a/apps/files_sharing/tests/js/shareSpec.js +++ b/apps/files_sharing/tests/js/shareSpec.js @@ -141,7 +141,7 @@ describe('OCA.Sharing.Util tests', function() { permissions: OC.PERMISSION_ALL, shareOwner: 'User One', etag: 'abc', - shareTypes: [OC.Share.SHARE_TYPE_USER] + shareTypes: [] }]); $tr = fileList.$el.find('tbody tr:first'); $action = $tr.find('.action-share'); From 99843c06f96d8381393bef2f42a0733beb1e2f51 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 23 Mar 2016 14:55:03 +0100 Subject: [PATCH 165/286] GDrive stream download with RetryWrapper --- apps/files_external/lib/google.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 91e7dfee08df6..62d264dfeefb9 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -35,6 +35,7 @@ use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; +use Icewind\Streams\RetryWrapper; set_include_path(get_include_path().PATH_SEPARATOR. \OC_App::getAppPath('files_external').'/3rdparty/google-api-php-client/src'); @@ -441,10 +442,9 @@ public function fopen($path, $mode) { // the library's service doesn't support streaming, so we use Guzzle instead $client = \OC::$server->getHTTPClientService()->newClient(); try { - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext); - $client->get($downloadUrl, [ + $response = $client->get($downloadUrl, [ 'headers' => $httpRequest->getRequestHeaders(), - 'save_to' => $tmpFile, + 'stream' => true, 'verify' => __DIR__ . '/../3rdparty/google-api-php-client/src/Google/IO/cacerts.pem', ]); } catch (RequestException $e) { @@ -459,7 +459,8 @@ public function fopen($path, $mode) { } } - return fopen($tmpFile, 'r'); + $handle = $response->getBody(); + return RetryWrapper::wrap($handle); } } return false; From 1f7b037a59af77b3aa88ddfdd9c05f29944796d5 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 30 Mar 2016 22:45:09 +0200 Subject: [PATCH 166/286] Use RetryWrapper for SFTP storage Equivalent to https://github.com/owncloud/core/pull/23442 Required for making encryption work with external storage reliable. --- apps/files_external/lib/sftp.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php index f6b2873cf49a4..c44ee9f908e0a 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/sftp.php @@ -32,6 +32,7 @@ namespace OC\Files\Storage; use Icewind\Streams\IteratorDirectory; +use Icewind\Streams\RetryWrapper; use phpseclib\Net\SFTP\Stream; /** @@ -374,7 +375,8 @@ public function fopen($path, $mode) { case 'c': case 'c+': $context = stream_context_create(array('sftp' => array('session' => $this->getConnection()))); - return fopen($this->constructUrl($path), $mode, false, $context); + $handle = fopen($this->constructUrl($path), $mode, false, $context); + return RetryWrapper::wrap($handle); } } catch (\Exception $e) { } From 7c7e079a3650616e2cd2ac9855b275ddbcf02a67 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 24 Mar 2016 11:40:14 +0100 Subject: [PATCH 167/286] Lock the mountpoint while removing --- lib/private/files/view.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 52be8a7e2263c..4421a016356ed 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -269,17 +269,21 @@ protected function removeMount($mount, $path) { // cut of /user/files to get the relative path to data/user/files $pathParts = explode('/', $path, 4); $relPath = '/' . $pathParts[3]; + $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true); \OC_Hook::emit( Filesystem::CLASSNAME, "umount", array(Filesystem::signal_param_path => $relPath) ); + $this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true); $result = $mount->removeMount(); + $this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true); if ($result) { \OC_Hook::emit( Filesystem::CLASSNAME, "post_umount", array(Filesystem::signal_param_path => $relPath) ); } + $this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true); return $result; } else { // do not allow deleting the storage's root / the mount point From e664e582fb0c4878186001b84448dfa1c7034789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 17 Mar 2016 10:31:33 +0100 Subject: [PATCH 168/286] Fix group shares on v1 caldav and carddav - fixes #23328 --- apps/dav/lib/caldav/caldavbackend.php | 3 ++- apps/dav/lib/carddav/carddavbackend.php | 2 +- apps/dav/lib/connector/sabre/principal.php | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index a188d652eedd6..3869d36886f84 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -142,6 +142,7 @@ public function __construct(IDBConnection $db, $userPrincipalBackend, GroupPrinc * @return array */ function getCalendarsForUser($principalUri) { + $principalUriOriginal = $principalUri; $principalUri = $this->convertPrincipal($principalUri, true); $fields = array_values($this->propertyMap); $fields[] = 'id'; @@ -188,7 +189,7 @@ function getCalendarsForUser($principalUri) { $stmt->closeCursor(); // query for shared calendars - $principals = $this->principalBackend->getGroupMembership($principalUri); + $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true); $principals[]= $principalUri; $fields = array_values($this->propertyMap); diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index 89154c39d3785..cabafd5c3ac52 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -130,7 +130,7 @@ function getAddressBooksForUser($principalUri) { $result->closeCursor(); // query for shared calendars - $principals = $this->principalBackend->getGroupMembership($principalUri); + $principals = $this->principalBackend->getGroupMembership($principalUri, true); $principals[]= $principalUri; $query = $this->db->getQueryBuilder(); diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php index 31de4e5bad13a..49fb4efdee2dd 100644 --- a/apps/dav/lib/connector/sabre/principal.php +++ b/apps/dav/lib/connector/sabre/principal.php @@ -135,7 +135,7 @@ public function getGroupMemberSet($principal) { * @return array * @throws Exception */ - public function getGroupMembership($principal) { + public function getGroupMembership($principal, $needGroups = false) { list($prefix, $name) = URLUtil::splitPath($principal); if ($prefix === $this->principalPrefix) { @@ -144,7 +144,7 @@ public function getGroupMembership($principal) { throw new Exception('Principal not found'); } - if ($this->hasGroups) { + if ($this->hasGroups || $needGroups) { $groups = $this->groupManager->getUserGroups($user); $groups = array_map(function($group) { /** @var IGroup $group */ From cb300d164ec14dd886dc41609cdb8c27cdf557e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 17 Mar 2016 11:51:38 +0100 Subject: [PATCH 169/286] Return proper current-user-principal on v1 endpoints - fixes #23306 --- apps/dav/lib/connector/legacydavacl.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/dav/lib/connector/legacydavacl.php b/apps/dav/lib/connector/legacydavacl.php index 07aefa1b86390..eb6ca1fd7d51e 100644 --- a/apps/dav/lib/connector/legacydavacl.php +++ b/apps/dav/lib/connector/legacydavacl.php @@ -23,7 +23,10 @@ namespace OCA\DAV\Connector; use OCA\DAV\Connector\Sabre\DavAclPlugin; +use Sabre\DAV\INode; +use Sabre\DAV\PropFind; use Sabre\HTTP\URLUtil; +use Sabre\DAVACL\Xml\Property\Principal; class LegacyDAVACL extends DavAclPlugin { @@ -67,4 +70,16 @@ private function convertPrincipal($principal, $toV2) { } return "principals/$name"; } + + function propFind(PropFind $propFind, INode $node) { + /* Overload current-user-principal */ + $propFind->handle('{DAV:}current-user-principal', function () { + if ($url = parent::getCurrentUserPrincipal()) { + return new Principal(Principal::HREF, $url . '/'); + } else { + return new Principal(Principal::UNAUTHENTICATED); + } + }); + parent::propFind($propFind, $node); + } } From f28817aed5f7570664f3432478e9f9509a4c749f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 17 Mar 2016 15:39:08 +0100 Subject: [PATCH 170/286] Fix acls for calendar objects and cards - fixes #23273 --- apps/dav/appinfo/v1/caldav.php | 3 +- apps/dav/lib/caldav/caldavbackend.php | 2 + apps/dav/lib/caldav/calendar.php | 40 ++++++++++-- apps/dav/lib/carddav/addressbook.php | 55 +++++++++------- apps/dav/lib/carddav/card.php | 45 ------------- apps/dav/lib/carddav/carddavbackend.php | 6 +- apps/dav/lib/connector/sabre/principal.php | 1 + apps/dav/tests/unit/caldav/calendartest.php | 60 +++++++++++++++++ .../tests/unit/carddav/addressbooktest.php | 65 ++++++++++++++++++- 9 files changed, 193 insertions(+), 84 deletions(-) delete mode 100644 apps/dav/lib/carddav/card.php diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 3e1a7ce625337..cae128831eedf 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -23,6 +23,7 @@ // Backends use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\Connector\LegacyDAVACL; use OCA\DAV\CalDAV\CalendarRoot; use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; @@ -67,7 +68,7 @@ $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'ownCloud')); $server->addPlugin(new \Sabre\CalDAV\Plugin()); -$acl = new \OCA\DAV\Connector\LegacyDAVACL(); +$acl = new LegacyDAVACL(); $server->addPlugin($acl); $server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin()); diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index 3869d36886f84..4fe479bf57d72 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -199,6 +199,7 @@ function getCalendarsForUser($principalUri) { $fields[] = 'a.components'; $fields[] = 'a.principaluri'; $fields[] = 'a.transparent'; + $fields[] = 's.access'; $query = $this->db->getQueryBuilder(); $result = $query->select($fields) ->from('dav_shares', 's') @@ -226,6 +227,7 @@ function getCalendarsForUser($principalUri) { '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ, ]; foreach($this->propertyMap as $xmlName=>$dbName) { diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index dbd75bad20b94..2bc9e4ed9ec32 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -86,7 +86,31 @@ public function getResourceId() { } function getACL() { - $acl = parent::getACL(); + $acl = [ + [ + 'privilege' => '{DAV:}read', + 'principal' => $this->getOwner(), + 'protected' => true, + ]]; + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $this->getOwner(), + 'protected' => true, + ]; + if ($this->getOwner() !== parent::getOwner()) { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => parent::getOwner(), + 'protected' => true, + ]; + if ($this->canWrite()) { + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => parent::getOwner(), + 'protected' => true, + ]; + } + } /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; @@ -94,11 +118,7 @@ function getACL() { } function getChildACL() { - $acl = parent::getChildACL(); - - /** @var CalDavBackend $calDavBackend */ - $calDavBackend = $this->caldavBackend; - return $calDavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); + return $this->getACL(); } function getOwner() { @@ -137,4 +157,12 @@ function propPatch(PropPatch $propPatch) { } parent::propPatch($propPatch); } + + private function canWrite() { + if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) { + return !$this->calendarInfo['{http://owncloud.org/ns}read-only']; + } + return true; + } + } diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index 70456afbd0f37..1a34436014b64 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -21,6 +21,7 @@ namespace OCA\DAV\CardDAV; use OCA\DAV\DAV\Sharing\IShareable; +use Sabre\CardDAV\Card; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropPatch; @@ -70,39 +71,31 @@ function getShares() { } function getACL() { - $acl = parent::getACL(); - if ($this->getOwner() === 'principals/system/system') { - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => '{DAV:}authenticated', - 'protected' => true, + $acl = [ + [ + 'privilege' => '{DAV:}read', + 'principal' => $this->getOwner(), + 'protected' => true, + ]]; + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $this->getOwner(), + 'protected' => true, ]; - } - - // add the current user - if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) { - $owner = $this->addressBookInfo['{http://owncloud.org/ns}owner-principal']; - $acl[] = [ + if ($this->getOwner() !== parent::getOwner()) { + $acl[] = [ 'privilege' => '{DAV:}read', - 'principal' => $owner, + 'principal' => parent::getOwner(), 'protected' => true, ]; - if ($this->addressBookInfo['{http://owncloud.org/ns}read-only']) { + if ($this->canWrite()) { $acl[] = [ 'privilege' => '{DAV:}write', - 'principal' => $owner, + 'principal' => parent::getOwner(), 'protected' => true, ]; } } - - /** @var CardDavBackend $carddavBackend */ - $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getResourceId(), $acl); - } - - function getChildACL() { - $acl = parent::getChildACL(); if ($this->getOwner() === 'principals/system/system') { $acl[] = [ 'privilege' => '{DAV:}read', @@ -116,12 +109,19 @@ function getChildACL() { return $carddavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); } + function getChildACL() { + return $this->getACL(); + } + function getChild($name) { - $obj = $this->carddavBackend->getCard($this->getResourceId(), $name); + + $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name); if (!$obj) { throw new NotFound('Card not found'); } + $obj['acl'] = $this->getChildACL(); return new Card($this->carddavBackend, $this->addressBookInfo, $obj); + } /** @@ -172,4 +172,11 @@ public function getContactsGroups() { return $cardDavBackend->collectCardProperties($this->getResourceId(), 'CATEGORIES'); } + + private function canWrite() { + if (isset($this->addressBookInfo['{http://owncloud.org/ns}read-only'])) { + return !$this->addressBookInfo['{http://owncloud.org/ns}read-only']; + } + return true; + } } diff --git a/apps/dav/lib/carddav/card.php b/apps/dav/lib/carddav/card.php deleted file mode 100644 index d848f2e28ecd5..0000000000000 --- a/apps/dav/lib/carddav/card.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\DAV\CardDAV; - -class Card extends \Sabre\CardDAV\Card { - - function getACL() { - $acl = parent::getACL(); - if ($this->getOwner() === 'principals/system/system') { - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ]; - } - - /** @var CardDavBackend $carddavBackend */ - $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getBookId(), $acl); - } - - private function getBookId() { - return $this->addressBookInfo['id']; - } - -} diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index cabafd5c3ac52..8757b83bf80b7 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -64,10 +64,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME', 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD'); - const ACCESS_OWNER = 1; - const ACCESS_READ_WRITE = 2; - const ACCESS_READ = 3; - /** @var EventDispatcherInterface */ private $dispatcher; @@ -157,7 +153,7 @@ function getAddressBooksForUser($principalUri) { '{http://calendarserver.org/ns/}getctag' => $row['synctoken'], '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], - '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => $row['access'] === self::ACCESS_READ, + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ, ]; } } diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php index 49fb4efdee2dd..18f28a916f1ec 100644 --- a/apps/dav/lib/connector/sabre/principal.php +++ b/apps/dav/lib/connector/sabre/principal.php @@ -132,6 +132,7 @@ public function getGroupMemberSet($principal) { * Returns the list of groups a principal is a member of * * @param string $principal + * @param bool $needGroups * @return array * @throws Exception */ diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index e7f4d57067c51..9e0c3c6c7e426 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -103,4 +103,64 @@ public function testPropPatch($mutations, $throws) { $this->assertTrue(true); } } + + /** + * @dataProvider providesReadOnlyInfo + */ + public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet) { + /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ + $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); + $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1); + $calendarInfo = [ + 'principaluri' => 'user2', + 'id' => 666, + 'uri' => 'default' + ]; + if (!is_null($readOnlyValue)) { + $calendarInfo['{http://owncloud.org/ns}read-only'] = $readOnlyValue; + } + if ($hasOwnerSet) { + $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1'; + } + $c = new Calendar($backend, $calendarInfo); + $acl = $c->getACL(); + $childAcl = $c->getChildACL(); + + $expectedAcl = [[ + 'privilege' => '{DAV:}read', + 'principal' => $hasOwnerSet ? 'user1' : 'user2', + 'protected' => true + ], [ + 'privilege' => '{DAV:}write', + 'principal' => $hasOwnerSet ? 'user1' : 'user2', + 'protected' => true + ]]; + if ($hasOwnerSet) { + $expectedAcl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => 'user2', + 'protected' => true + ]; + if ($expectsWrite) { + $expectedAcl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => 'user2', + 'protected' => true + ]; + } + } + $this->assertEquals($expectedAcl, $acl); + $this->assertEquals($expectedAcl, $childAcl); + } + + public function providesReadOnlyInfo() { + return [ + 'read-only property not set' => [true, null, true], + 'read-only property is false' => [true, false, true], + 'read-only property is true' => [false, true, true], + 'read-only property not set and no owner' => [true, null, false], + 'read-only property is false and no owner' => [true, false, false], + 'read-only property is true and no owner' => [false, true, false], + ]; + } } diff --git a/apps/dav/tests/unit/carddav/addressbooktest.php b/apps/dav/tests/unit/carddav/addressbooktest.php index 854c121a95df0..c5cf7e5f7bae9 100644 --- a/apps/dav/tests/unit/carddav/addressbooktest.php +++ b/apps/dav/tests/unit/carddav/addressbooktest.php @@ -32,7 +32,7 @@ public function testDelete() { /** @var \PHPUnit_Framework_MockObject_MockObject | CardDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); $backend->expects($this->once())->method('updateShares'); - $backend->method('getShares')->willReturn([ + $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:user2'] ]); $calendarInfo = [ @@ -51,7 +51,7 @@ public function testDeleteFromGroup() { /** @var \PHPUnit_Framework_MockObject_MockObject | CardDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); $backend->expects($this->never())->method('updateShares'); - $backend->method('getShares')->willReturn([ + $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:group2'] ]); $calendarInfo = [ @@ -77,4 +77,63 @@ public function testPropPatch() { $c = new AddressBook($backend, $calendarInfo); $c->propPatch(new PropPatch([])); } -} + + /** + * @dataProvider providesReadOnlyInfo + */ + public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet) { + /** @var \PHPUnit_Framework_MockObject_MockObject | CardDavBackend $backend */ + $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); + $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1); + $calendarInfo = [ + 'principaluri' => 'user2', + 'id' => 666, + 'uri' => 'default' + ]; + if (!is_null($readOnlyValue)) { + $calendarInfo['{http://owncloud.org/ns}read-only'] = $readOnlyValue; + } + if ($hasOwnerSet) { + $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1'; + } + $c = new AddressBook($backend, $calendarInfo); + $acl = $c->getACL(); + $childAcl = $c->getChildACL(); + + $expectedAcl = [[ + 'privilege' => '{DAV:}read', + 'principal' => $hasOwnerSet ? 'user1' : 'user2', + 'protected' => true + ], [ + 'privilege' => '{DAV:}write', + 'principal' => $hasOwnerSet ? 'user1' : 'user2', + 'protected' => true + ]]; + if ($hasOwnerSet) { + $expectedAcl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => 'user2', + 'protected' => true + ]; + if ($expectsWrite) { + $expectedAcl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => 'user2', + 'protected' => true + ]; + } + } + $this->assertEquals($expectedAcl, $acl); + $this->assertEquals($expectedAcl, $childAcl); + } + + public function providesReadOnlyInfo() { + return [ + 'read-only property not set' => [true, null, true], + 'read-only property is false' => [true, false, true], + 'read-only property is true' => [false, true, true], + 'read-only property not set and no owner' => [true, null, false], + 'read-only property is false and no owner' => [true, false, false], + 'read-only property is true and no owner' => [false, true, false], + ]; + }} From ef8b75960c5df67db3a771c6d145d20cfa02a1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 24 Mar 2016 17:11:07 +0100 Subject: [PATCH 171/286] Handle group shares of addressbooks on v1 as well ... now FINALLY .... --- apps/dav/lib/carddav/carddavbackend.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index 8757b83bf80b7..a50c5da54c4c3 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -103,6 +103,7 @@ public function __construct(IDBConnection $db, * @return array */ function getAddressBooksForUser($principalUri) { + $principalUriOriginal = $principalUri; $principalUri = $this->convertPrincipal($principalUri, true); $query = $this->db->getQueryBuilder(); $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) @@ -126,7 +127,7 @@ function getAddressBooksForUser($principalUri) { $result->closeCursor(); // query for shared calendars - $principals = $this->principalBackend->getGroupMembership($principalUri, true); + $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true); $principals[]= $principalUri; $query = $this->db->getQueryBuilder(); From b6fb3148c24cd97a4fe0a78c215fee466719201e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 31 Mar 2016 11:22:47 +0200 Subject: [PATCH 172/286] Revert "Explicitly add the current principal to the acl in case of group sharing" This reverts commit 52f4acf23d9e388fdc6348858c4572e291bbc56b. --- apps/dav/appinfo/application.php | 16 ++----- apps/dav/appinfo/register_command.php | 2 +- apps/dav/appinfo/v1/caldav.php | 4 +- apps/dav/appinfo/v1/carddav.php | 6 +-- apps/dav/command/createcalendar.php | 4 +- apps/dav/lib/caldav/caldavbackend.php | 37 ++++++---------- apps/dav/lib/caldav/calendar.php | 4 +- apps/dav/lib/carddav/addressbook.php | 4 +- apps/dav/lib/carddav/carddavbackend.php | 31 +++++-------- apps/dav/lib/dav/sharing/backend.php | 43 ++++--------------- apps/dav/lib/dav/sharing/ishareable.php | 2 +- apps/dav/lib/rootcollection.php | 7 ++- .../tests/unit/caldav/caldavbackendtest.php | 10 +---- .../tests/unit/carddav/carddavbackendtest.php | 32 ++++++-------- 14 files changed, 65 insertions(+), 137 deletions(-) diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 6e86f422d4205..d06daf97f5452 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -27,7 +27,6 @@ use OCA\DAV\CardDAV\ContactsManager; use OCA\DAV\CardDAV\SyncJob; use OCA\DAV\CardDAV\SyncService; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\HookManager; use OCA\Dav\Migration\AddressBookAdapter; use OCA\Dav\Migration\CalendarAdapter; @@ -84,8 +83,7 @@ public function __construct (array $urlParams=array()) { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - $groupPrincipal = new GroupPrincipalBackend($c->getServer()->getGroupManager()); - return new CardDavBackend($db, $principal, $groupPrincipal, $dispatcher); + return new CardDavBackend($db, $principal, $dispatcher); }); $container->registerService('CalDavBackend', function($c) { @@ -95,8 +93,7 @@ public function __construct (array $urlParams=array()) { $c->getServer()->getUserManager(), $c->getServer()->getGroupManager() ); - $groupPrincipal = new GroupPrincipalBackend($c->getServer()->getGroupManager()); - return new CalDavBackend($db, $principal, $groupPrincipal); + return new CalDavBackend($db, $principal); }); $container->registerService('MigrateAddressbooks', function($c) { @@ -220,7 +217,7 @@ public function generateBirthdays() { $migration = $this->getContainer()->query('BirthdayService'); $userManager = $this->getContainer()->getServer()->getUserManager(); - $userManager->callForAllUsers(function ($user) use ($migration) { + $userManager->callForAllUsers(function($user) use($migration) { /** @var IUser $user */ $migration->syncUser($user->getUID()); }); @@ -228,11 +225,4 @@ public function generateBirthdays() { $this->getContainer()->getServer()->getLogger()->logException($ex); } } - - /** - * @return CardDavBackend - */ - public function getCardDavBackend() { - return $this->getContainer()->query('CardDavBackend'); - } } diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 45b43d6f2d5de..570848f0b234e 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -34,7 +34,7 @@ /** @var Symfony\Component\Console\Application $application */ $application->add(new CreateCalendar($userManager, $groupManager, $dbConnection)); -$application->add(new CreateAddressBook($userManager, $app->getCardDavBackend())); +$application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend'))); $application->add(new SyncSystemAddressBook($app->getSyncService())); $application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService'))); $application->add(new MigrateAddressbooks($userManager, $app->getContainer()->query('MigrateAddressbooks'))); diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index cae128831eedf..02a0b38225e00 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -29,7 +29,6 @@ use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; $authBackend = new Auth( \OC::$server->getSession(), @@ -43,8 +42,7 @@ 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$groupPrincipal = new GroupPrincipalBackend(\OC::$server->getGroupManager()); -$calDavBackend = new CalDavBackend($db, $principalBackend, $groupPrincipal); +$calDavBackend = new CalDavBackend($db, $principalBackend); // Root nodes $principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend); diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index ac6ffea250604..44abcbaa19010 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -42,14 +42,14 @@ 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$app = new \OCA\Dav\AppInfo\Application(); +$cardDavBackend = new CardDavBackend($db, $principalBackend); // Root nodes $principalCollection = new \Sabre\CalDAV\Principal\Collection($principalBackend); $principalCollection->disableListing = true; // Disable listing -$addressBookRoot = new AddressBookRoot($principalBackend, $app->getCardDavBackend()); -$addressBookRoot->disableListing = false; // Disable listing +$addressBookRoot = new AddressBookRoot($principalBackend, $cardDavBackend); +$addressBookRoot->disableListing = true; // Disable listing $nodes = array( $principalCollection, diff --git a/apps/dav/command/createcalendar.php b/apps/dav/command/createcalendar.php index a1a15513a001d..d7f82dd0e524f 100644 --- a/apps/dav/command/createcalendar.php +++ b/apps/dav/command/createcalendar.php @@ -22,7 +22,6 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; @@ -74,10 +73,9 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->userManager, $this->groupManager ); - $groupPrincipal = new GroupPrincipalBackend($this->groupManager); $name = $input->getArgument('name'); - $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $groupPrincipal); + $caldav = new CalDavBackend($this->dbConnection, $principalBackend); $caldav->createCalendar("principals/users/$user", $name, []); } } diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php index 4fe479bf57d72..5f82db10b39d7 100644 --- a/apps/dav/lib/caldav/caldavbackend.php +++ b/apps/dav/lib/caldav/caldavbackend.php @@ -22,7 +22,6 @@ namespace OCA\DAV\CalDAV; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\DAV\Sharing\IShareable; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\Connector\Sabre\Principal; @@ -36,9 +35,7 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV; -use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\Exception\Forbidden; -use Sabre\DAV\PropPatch; use Sabre\HTTP\URLUtil; use Sabre\VObject\DateTimeParser; use Sabre\VObject\Reader; @@ -107,13 +104,12 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * CalDavBackend constructor. * * @param IDBConnection $db - * @param $userPrincipalBackend - * @param GroupPrincipalBackend $groupPrincipalBackend + * @param Principal $principalBackend */ - public function __construct(IDBConnection $db, $userPrincipalBackend, GroupPrincipalBackend $groupPrincipalBackend) { + public function __construct(IDBConnection $db, Principal $principalBackend) { $this->db = $db; - $this->principalBackend = $userPrincipalBackend; - $this->sharingBackend = new Backend($this->db, $userPrincipalBackend, $groupPrincipalBackend, 'calendar'); + $this->principalBackend = $principalBackend; + $this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); } /** @@ -347,7 +343,6 @@ public function getCalendarById($calendarId) { * @param string $calendarUri * @param array $properties * @return int - * @throws DAV\Exception */ function createCalendar($principalUri, $calendarUri, array $properties) { $values = [ @@ -399,10 +394,10 @@ function createCalendar($principalUri, $calendarUri, array $properties) { * * Read the PropPatch documentation for more info and examples. * - * @param int $calendarId - * @param PropPatch $propPatch + * @param \Sabre\DAV\PropPatch $propPatch + * @return void */ - function updateCalendar($calendarId, PropPatch $propPatch) { + function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) { $supportedProperties = array_keys($this->propertyMap); $supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp'; @@ -1042,7 +1037,6 @@ function getSubscriptionsForUser($principalUri) { * @param string $uri * @param array $properties * @return mixed - * @throws Forbidden */ function createSubscription($principalUri, $uri, array $properties) { @@ -1091,10 +1085,10 @@ function createSubscription($principalUri, $uri, array $properties) { * Read the PropPatch documentation for more info and examples. * * @param mixed $subscriptionId - * @param PropPatch $propPatch + * @param \Sabre\DAV\PropPatch $propPatch * @return void */ - function updateSubscription($subscriptionId, PropPatch $propPatch) { + function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) { $supportedProperties = array_keys($this->subscriptionPropertyMap); $supportedProperties[] = '{http://calendarserver.org/ns/}source'; @@ -1284,7 +1278,6 @@ protected function addChange($calendarId, $objectUri, $operation) { * * @param string $calendarData * @return array - * @throws BadRequest */ protected function getDenormalizedData($calendarData) { @@ -1302,7 +1295,7 @@ protected function getDenormalizedData($calendarData) { } } if (!$componentType) { - throw new BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); + throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } if ($componentType === 'VEVENT' && $component->DTSTART) { $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); @@ -1369,21 +1362,19 @@ public function updateShares($shareable, $add, $remove) { /** * @param int $resourceId - * @param string $currentPrincipal * @return array */ - public function getShares($resourceId, $currentPrincipal) { - return $this->sharingBackend->getShares($resourceId, $currentPrincipal); + public function getShares($resourceId) { + return $this->sharingBackend->getShares($resourceId); } /** * @param int $resourceId * @param array $acl - * @param string $currentPrincipal * @return array */ - public function applyShareAcl($resourceId, $acl, $currentPrincipal) { - return $this->sharingBackend->applyShareAcl($resourceId, $acl, $currentPrincipal); + public function applyShareAcl($resourceId, $acl) { + return $this->sharingBackend->applyShareAcl($resourceId, $acl); } private function convertPrincipal($principalUri, $toV2) { diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 2bc9e4ed9ec32..5072d96107e3a 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -75,7 +75,7 @@ function updateShares(array $add, array $remove) { function getShares() { /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; - return $calDavBackend->getShares($this->getResourceId(), parent::getOwner()); + return $calDavBackend->getShares($this->getResourceId()); } /** @@ -114,7 +114,7 @@ function getACL() { /** @var CalDavBackend $calDavBackend */ $calDavBackend = $this->caldavBackend; - return $calDavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); + return $calDavBackend->applyShareAcl($this->getResourceId(), $acl); } function getChildACL() { diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index 1a34436014b64..8b1b600ec3de4 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -67,7 +67,7 @@ function updateShares(array $add, array $remove) { function getShares() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->getShares($this->getResourceId(), $this->getOwner()); + return $carddavBackend->getShares($this->getResourceId()); } function getACL() { @@ -106,7 +106,7 @@ function getACL() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getResourceId(), $acl, parent::getOwner()); + return $carddavBackend->applyShareAcl($this->getResourceId(), $acl); } function getChildACL() { diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index a50c5da54c4c3..97f5706049af7 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -25,7 +25,6 @@ namespace OCA\DAV\CardDAV; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\DAV\DAV\Sharing\Backend; use OCA\DAV\DAV\Sharing\IShareable; @@ -35,7 +34,6 @@ use Sabre\CardDAV\Backend\SyncSupport; use Sabre\CardDAV\Plugin; use Sabre\DAV\Exception\BadRequest; -use Sabre\DAV\PropPatch; use Sabre\HTTP\URLUtil; use Sabre\VObject\Component\VCard; use Sabre\VObject\Reader; @@ -71,18 +69,16 @@ class CardDavBackend implements BackendInterface, SyncSupport { * CardDavBackend constructor. * * @param IDBConnection $db - * @param Principal $userPrincipalBackend - * @param GroupPrincipalBackend $groupPrincipalBackend + * @param Principal $principalBackend * @param EventDispatcherInterface $dispatcher */ public function __construct(IDBConnection $db, - Principal $userPrincipalBackend, - GroupPrincipalBackend $groupPrincipalBackend, + Principal $principalBackend, EventDispatcherInterface $dispatcher = null) { $this->db = $db; - $this->principalBackend = $userPrincipalBackend; + $this->principalBackend = $principalBackend; $this->dispatcher = $dispatcher; - $this->sharingBackend = new Backend($this->db, $userPrincipalBackend, $groupPrincipalBackend, 'addressbook'); + $this->sharingBackend = new Backend($this->db, $principalBackend, 'addressbook'); } /** @@ -165,7 +161,6 @@ function getAddressBooksForUser($principalUri) { /** * @param int $addressBookId - * @return array|null */ public function getAddressBookById($addressBookId) { $query = $this->db->getQueryBuilder(); @@ -192,8 +187,7 @@ public function getAddressBookById($addressBookId) { } /** - * @param string $principal - * @param string $addressBookUri + * @param $addressBookUri * @return array|null */ public function getAddressBooksByUri($principal, $addressBookUri) { @@ -235,10 +229,10 @@ public function getAddressBooksByUri($principal, $addressBookUri) { * Read the PropPatch documentation for more info and examples. * * @param string $addressBookId - * @param PropPatch $propPatch + * @param \Sabre\DAV\PropPatch $propPatch * @return void */ - function updateAddressBook($addressBookId, PropPatch $propPatch) { + function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) { $supportedProperties = [ '{DAV:}displayname', '{' . Plugin::NS_CARDDAV . '}addressbook-description', @@ -873,12 +867,10 @@ public function getContact($addressBookId, $uri) { * * readOnly - boolean * * summary - Optional, a description for the share * - * @param $addressBookId - * @param string $currentPrincipal * @return array */ - public function getShares($addressBookId, $currentPrincipal) { - return $this->sharingBackend->getShares($addressBookId, $currentPrincipal); + public function getShares($addressBookId) { + return $this->sharingBackend->getShares($addressBookId); } /** @@ -976,11 +968,10 @@ protected function getCardId($addressBookId, $uri) { * For shared address books the sharee is set in the ACL of the address book * @param $addressBookId * @param $acl - * @param string $currentPrincipal * @return array */ - public function applyShareAcl($addressBookId, $acl, $currentPrincipal) { - return $this->sharingBackend->applyShareAcl($addressBookId, $acl, $currentPrincipal); + public function applyShareAcl($addressBookId, $acl) { + return $this->sharingBackend->applyShareAcl($addressBookId, $acl); } private function convertPrincipal($principalUri, $toV2) { diff --git a/apps/dav/lib/dav/sharing/backend.php b/apps/dav/lib/dav/sharing/backend.php index 9ef1a07ebc60a..ffc4193e34b64 100644 --- a/apps/dav/lib/dav/sharing/backend.php +++ b/apps/dav/lib/dav/sharing/backend.php @@ -23,7 +23,6 @@ namespace OCA\DAV\DAV\Sharing; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\IDBConnection; class Backend { @@ -31,9 +30,7 @@ class Backend { /** @var IDBConnection */ private $db; /** @var Principal */ - private $userPrincipalBackend; - /** @var GroupPrincipalBackend */ - private $groupPrincipalBackend; + private $principalBackend; /** @var string */ private $resourceType; @@ -43,14 +40,12 @@ class Backend { /** * @param IDBConnection $db - * @param Principal $userPrincipalBackend - * @param GroupPrincipalBackend $groupPrincipalBackend + * @param Principal $principalBackend * @param string $resourceType */ - public function __construct(IDBConnection $db, Principal $userPrincipalBackend, GroupPrincipalBackend $groupPrincipalBackend, $resourceType) { + public function __construct(IDBConnection $db, Principal $principalBackend, $resourceType) { $this->db = $db; - $this->userPrincipalBackend = $userPrincipalBackend; - $this->groupPrincipalBackend = $groupPrincipalBackend; + $this->principalBackend = $principalBackend; $this->resourceType = $resourceType; } @@ -148,10 +143,9 @@ private function unshare($shareable, $element) { * * summary - Optional, a description for the share * * @param int $resourceId - * @param string $currentPrincipal * @return array */ - public function getShares($resourceId, $currentPrincipal) { + public function getShares($resourceId) { $query = $this->db->getQueryBuilder(); $result = $query->select(['principaluri', 'access']) ->from('dav_shares') @@ -161,31 +155,13 @@ public function getShares($resourceId, $currentPrincipal) { $shares = []; while($row = $result->fetch()) { - $p = $this->userPrincipalBackend->getPrincipalByPath($row['principaluri']); - if (is_null($p)) { - $p = $this->groupPrincipalBackend->getPrincipalByPath($row['principaluri']); - if (is_null($p)) { - continue; - } - // also add the current user if it is member of the group - $groups = $this->userPrincipalBackend->getGroupMembership($currentPrincipal); - if (in_array($row['principaluri'], $groups)) { - $ownerPrincipal = $this->userPrincipalBackend->getPrincipalByPath($currentPrincipal); - $shares[]= [ - 'href' => "principal:$currentPrincipal", - 'commonName' => isset($ownerPrincipal['{DAV:}displayname']) ? $ownerPrincipal['{DAV:}displayname'] : '', - 'status' => 1, - 'readOnly' => ($row['access'] == self::ACCESS_READ), - '{http://owncloud.org/ns}principal' => $currentPrincipal - ]; - } - } + $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); $shares[]= [ 'href' => "principal:${row['principaluri']}", 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', 'status' => 1, 'readOnly' => ($row['access'] == self::ACCESS_READ), - '{http://owncloud.org/ns}principal' => $row['principaluri'] + '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $row['principaluri'] ]; } @@ -197,12 +173,11 @@ public function getShares($resourceId, $currentPrincipal) { * * @param int $resourceId * @param array $acl - * @param string $currentPrincipal * @return array */ - public function applyShareAcl($resourceId, $acl, $currentPrincipal) { + public function applyShareAcl($resourceId, $acl) { - $shares = $this->getShares($resourceId, $currentPrincipal); + $shares = $this->getShares($resourceId); foreach ($shares as $share) { $acl[] = [ 'privilege' => '{DAV:}read', diff --git a/apps/dav/lib/dav/sharing/ishareable.php b/apps/dav/lib/dav/sharing/ishareable.php index b0f3307335bab..f6b6bfa88624b 100644 --- a/apps/dav/lib/dav/sharing/ishareable.php +++ b/apps/dav/lib/dav/sharing/ishareable.php @@ -71,4 +71,4 @@ public function getResourceId(); */ public function getOwner(); -} +} \ No newline at end of file diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index fd1a1558efd63..ea796c091753f 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -57,7 +57,7 @@ public function __construct() { $systemPrincipals->disableListing = $disableListing; $filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); $filesCollection->disableListing = $disableListing; - $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $groupPrincipalBackend); + $caldavBackend = new CalDavBackend($db, $userPrincipalBackend); $calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); $calendarRoot->disableListing = $disableListing; @@ -80,13 +80,12 @@ public function __construct() { \OC::$server->getRootFolder(), \OC::$server->getLogger() ); - $groupPrincipal = new GroupPrincipalBackend(\OC::$server->getGroupManager()); - $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $groupPrincipal, $dispatcher); + $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); $usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, 'principals/users'); $usersAddressBookRoot->disableListing = $disableListing; - $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $groupPrincipal, $dispatcher); + $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher); $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index db89661227652..87a700a473dc7 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -25,7 +25,6 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Property\Href; @@ -47,9 +46,6 @@ class CalDavBackendTest extends TestCase { /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ private $principal; - /** @var GroupPrincipalBackend | \PHPUnit_Framework_MockObject_MockObject */ - private $groupPrincipal; - const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; @@ -68,13 +64,9 @@ public function setUp() { $this->principal->expects($this->any())->method('getGroupMembership') ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); - $this->groupPrincipal = $this->getMockBuilder('OCA\DAV\DAV\GroupPrincipalBackend') - ->disableOriginalConstructor() - ->setMethods(['getPrincipalByPath', 'getGroupMembership']) - ->getMock(); $db = \OC::$server->getDatabaseConnection(); - $this->backend = new CalDavBackend($db, $this->principal, $this->groupPrincipal); + $this->backend = new CalDavBackend($db, $this->principal); $this->tearDown(); } diff --git a/apps/dav/tests/unit/carddav/carddavbackendtest.php b/apps/dav/tests/unit/carddav/carddavbackendtest.php index 38b8a81b2bc2c..1ee09260c88ce 100644 --- a/apps/dav/tests/unit/carddav/carddavbackendtest.php +++ b/apps/dav/tests/unit/carddav/carddavbackendtest.php @@ -27,7 +27,6 @@ use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; -use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use Sabre\DAV\PropPatch; @@ -59,9 +58,6 @@ class CardDavBackendTest extends TestCase { /** @var string */ private $dbCardsPropertiesTable = 'cards_properties'; - /** @var GroupPrincipalBackend */ - private $groupPrincipal; - const UNIT_TEST_USER = 'principals/users/carddav-unit-test'; const UNIT_TEST_USER1 = 'principals/users/carddav-unit-test1'; const UNIT_TEST_GROUP = 'principals/groups/carddav-unit-test-group'; @@ -73,21 +69,17 @@ public function setUp() { ->disableOriginalConstructor() ->setMethods(['getPrincipalByPath', 'getGroupMembership']) ->getMock(); - $this->principal->expects($this->any())->method('getPrincipalByPath') + $this->principal->method('getPrincipalByPath') ->willReturn([ 'uri' => 'principals/best-friend' ]); - $this->principal->expects($this->any())->method('getGroupMembership') + $this->principal->method('getGroupMembership') ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); - $this->groupPrincipal = $this->getMockBuilder('OCA\DAV\DAV\GroupPrincipalBackend') - ->disableOriginalConstructor() - ->setMethods(['getPrincipalByPath', 'getGroupMembership']) - ->getMock(); $this->db = \OC::$server->getDatabaseConnection(); - $this->backend = new CardDavBackend($this->db, $this->principal, $this->groupPrincipal, null); + $this->backend = new CardDavBackend($this->db, $this->principal, null); // start every test with a empty cards_properties and cards table $query = $this->db->getQueryBuilder(); @@ -165,7 +157,7 @@ public function testCardOperations() { /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backend */ $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) + ->setConstructorArgs([$this->db, $this->principal, null]) ->setMethods(['updateProperties', 'purgeProperties'])->getMock(); // create a new address book @@ -211,7 +203,7 @@ public function testCardOperations() { public function testMultiCard() { $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) + ->setConstructorArgs([$this->db, $this->principal, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -256,8 +248,9 @@ public function testMultiCard() { } public function testDeleteWithoutCard() { + $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) + ->setConstructorArgs([$this->db, $this->principal, null]) ->setMethods([ 'getCardId', 'addChange', @@ -296,8 +289,9 @@ public function testDeleteWithoutCard() { } public function testSyncSupport() { + $this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) + ->setConstructorArgs([$this->db, $this->principal, null]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -327,13 +321,13 @@ public function testSharing() { $exampleBook = new AddressBook($this->backend, $books[0]); $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getResourceId(), null); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(1, count($shares)); // adding the same sharee again has no effect $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getResourceId(), null); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(1, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -341,7 +335,7 @@ public function testSharing() { $this->backend->updateShares($exampleBook, [], ['principal:principals/best-friend']); - $shares = $this->backend->getShares($exampleBook->getResourceId(), null); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(0, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -355,7 +349,7 @@ public function testUpdateProperties() { $cardId = 2; $backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') - ->setConstructorArgs([$this->db, $this->principal, $this->groupPrincipal, null]) + ->setConstructorArgs([$this->db, $this->principal, null]) ->setMethods(['getCardId'])->getMock(); $backend->expects($this->any())->method('getCardId')->willReturn($cardId); From d16553d2d8f651e1c3ba8cc60df52558cb253983 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 31 Mar 2016 18:06:37 +0200 Subject: [PATCH 173/286] Make sure that the encrypted version is set The code path called when using external storage with WebDAV is using `\OC\Files\Storage\Wrapper\Encryption::getMetaData` which did not contain the actual encrypted version inside the cache entry version. This lead to the following: 1. User uploaded a file 2. File is created and `\OC\Files\Storage\Wrapper\Encryption::getMetaData` is called. It has an empty `encryptedVersion` but sets `encrypted` to either `true` or `false`. 3. The call when updating the file cache will use the old version. --- .../files/storage/wrapper/encryption.php | 9 +++++-- .../lib/files/storage/wrapper/encryption.php | 24 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 81eea9944f891..47daf6bab88b2 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -104,7 +104,7 @@ public function __construct( Update $update = null, Manager $mountManager = null ) { - + $this->mountPoint = $parameters['mountPoint']; $this->mount = $parameters['mount']; $this->encryptionManager = $encryptionManager; @@ -167,20 +167,25 @@ public function getMetaData($path) { return null; } $fullPath = $this->getFullPath($path); + $info = $this->getCache()->get($path); if (isset($this->unencryptedSize[$fullPath])) { $data['encrypted'] = true; $data['size'] = $this->unencryptedSize[$fullPath]; } else { - $info = $this->getCache()->get($path); if (isset($info['fileid']) && $info['encrypted']) { $data['size'] = $this->verifyUnencryptedSize($path, $info['size']); $data['encrypted'] = true; } } + if (isset($info['encryptedVersion']) && $info['encryptedVersion'] > 1) { + $data['encryptedVersion'] = $info['encryptedVersion']; + } + return $data; } + /** * see http://php.net/manual/en/function.file_get_contents.php * diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index bde920e440e6c..f4046b031e085 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -255,25 +255,39 @@ function($path) use ($encrypted) { $this->invokePrivate($this->instance, 'unencryptedSize', [[$path => $storedUnencryptedSize]]); } - + $fileEntry = $this->getMockBuilder('\OC\Files\Cache\Cache') + ->disableOriginalConstructor()->getMock(); $sourceStorage->expects($this->once())->method('getMetaData')->with($path) ->willReturn($metaData); + $sourceStorage->expects($this->any()) + ->method('getCache') + ->with($path) + ->willReturn($fileEntry); + $fileEntry->expects($this->any()) + ->method('get') + ->with($metaData['fileid']); $this->instance->expects($this->any())->method('getCache')->willReturn($cache); $this->instance->expects($this->any())->method('verifyUnencryptedSize') ->with($path, 0)->willReturn($expected['size']); $result = $this->instance->getMetaData($path); - $this->assertSame($expected['encrypted'], $result['encrypted']); + if(isset($expected['encrypted'])) { + $this->assertSame($expected['encrypted'], (bool)$result['encrypted']); + + if(isset($expected['encryptedVersion'])) { + $this->assertSame($expected['encryptedVersion'], $result['encryptedVersion']); + } + } $this->assertSame($expected['size'], $result['size']); } public function dataTestGetMetaData() { return [ - ['/test.txt', ['size' => 42, 'encrypted' => false], true, true, 12, ['size' => 12, 'encrypted' => true]], + ['/test.txt', ['size' => 42, 'encrypted' => 2, 'encryptedVersion' => 2, 'fileid' => 1], true, true, 12, ['size' => 12, 'encrypted' => true, 'encryptedVersion' => 2]], ['/test.txt', null, true, true, 12, null], - ['/test.txt', ['size' => 42, 'encrypted' => false], false, false, 12, ['size' => 42, 'encrypted' => false]], - ['/test.txt', ['size' => 42, 'encrypted' => false], true, false, 12, ['size' => 12, 'encrypted' => true]] + ['/test.txt', ['size' => 42, 'encrypted' => 0, 'fileid' => 1], false, false, 12, ['size' => 42, 'encrypted' => false]], + ['/test.txt', ['size' => 42, 'encrypted' => false, 'fileid' => 1], true, false, 12, ['size' => 12, 'encrypted' => true]] ]; } From 2cb45e71ea9602de9fb16662c1501495041b270d Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 30 Mar 2016 23:20:37 +0200 Subject: [PATCH 174/286] fix creation of versions of encrypted files on external storages in order to create a 1:1 copy of a file if a version gets created we need to store this information on copyBetweenStorage(). This allows us to by-pass the encryption wrapper if we read the source file. --- lib/base.php | 3 +- lib/private/encryption/encryptionwrapper.php | 124 ++++++++++++++++++ lib/private/encryption/manager.php | 19 +-- lib/private/encryption/util.php | 50 ------- .../files/storage/wrapper/encryption.php | 22 +++- lib/private/server.php | 4 +- .../lib/encryption/encryptionwrappertest.php | 101 ++++++++++++++ tests/lib/encryption/managertest.php | 6 +- tests/lib/encryption/utiltest.php | 45 ------- .../lib/files/storage/wrapper/encryption.php | 44 +++++-- tests/lib/files/stream/encryption.php | 7 +- tests/lib/traits/encryptiontrait.php | 16 +-- 12 files changed, 311 insertions(+), 130 deletions(-) create mode 100644 lib/private/encryption/encryptionwrapper.php create mode 100644 tests/lib/encryption/encryptionwrappertest.php diff --git a/lib/base.php b/lib/base.php index 36e5cd89d79d8..35c8592fe104c 100644 --- a/lib/base.php +++ b/lib/base.php @@ -729,7 +729,8 @@ public static function registerCacheHooks() { } private static function registerEncryptionWrapper() { - \OCP\Util::connectHook('OC_Filesystem', 'preSetup', 'OC\Encryption\Manager', 'setupStorage'); + $manager = self::$server->getEncryptionManager(); + \OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage'); } private static function registerEncryptionHooks() { diff --git a/lib/private/encryption/encryptionwrapper.php b/lib/private/encryption/encryptionwrapper.php new file mode 100644 index 0000000000000..11beb0cd6b147 --- /dev/null +++ b/lib/private/encryption/encryptionwrapper.php @@ -0,0 +1,124 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + + +namespace OC\Encryption; + + +use OC\Memcache\ArrayCache; +use OC\Files\Filesystem; +use OC\Files\Storage\Wrapper\Encryption; +use OCP\Files\Mount\IMountPoint; +use OC\Files\View; +use OCP\Files\Storage; +use OCP\ILogger; + +/** + * Class EncryptionWrapper + * + * applies the encryption storage wrapper + * + * @package OC\Encryption + */ +class EncryptionWrapper { + + /** @var ArrayCache */ + private $arrayCache; + + /** @var Manager */ + private $manager; + + /** @var ILogger */ + private $logger; + + /** + * EncryptionWrapper constructor. + * + * @param ArrayCache $arrayCache + * @param Manager $manager + * @param ILogger $logger + */ + public function __construct(ArrayCache $arrayCache, + Manager $manager, + ILogger $logger + ) { + $this->arrayCache = $arrayCache; + $this->manager = $manager; + $this->logger = $logger; + } + + /** + * Wraps the given storage when it is not a shared storage + * + * @param string $mountPoint + * @param Storage $storage + * @param IMountPoint $mount + * @return Encryption|Storage + */ + public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount) { + $parameters = [ + 'storage' => $storage, + 'mountPoint' => $mountPoint, + 'mount' => $mount + ]; + + if (!$storage->instanceOfStorage('OC\Files\Storage\Shared') + && !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') + && !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud')) { + + $user = \OC::$server->getUserSession()->getUser(); + $mountManager = Filesystem::getMountManager(); + $uid = $user ? $user->getUID() : null; + $fileHelper = \OC::$server->getEncryptionFilesHelper(); + $keyStorage = \OC::$server->getEncryptionKeyStorage(); + + $util = new Util( + new View(), + \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), + \OC::$server->getConfig() + ); + $update = new Update( + new View(), + $util, + Filesystem::getMountManager(), + $this->manager, + $fileHelper, + $uid + ); + return new Encryption( + $parameters, + $this->manager, + $util, + $this->logger, + $fileHelper, + $uid, + $keyStorage, + $update, + $mountManager, + $this->arrayCache + ); + } else { + return $storage; + } + } + +} diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index d1d17a9288738..d45bbf07ee966 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -27,6 +27,7 @@ use OC\Encryption\Keys\Storage; use OC\Files\Filesystem; use OC\Files\View; +use OC\Memcache\ArrayCache; use OC\ServiceUnavailableException; use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IManager; @@ -54,20 +55,25 @@ class Manager implements IManager { /** @var Util */ protected $util; + /** @var ArrayCache */ + protected $arrayCache; + /** * @param IConfig $config * @param ILogger $logger * @param IL10N $l10n * @param View $rootView * @param Util $util + * @param ArrayCache $arrayCache */ - public function __construct(IConfig $config, ILogger $logger, IL10N $l10n, View $rootView, Util $util) { + public function __construct(IConfig $config, ILogger $logger, IL10N $l10n, View $rootView, Util $util, ArrayCache $arrayCache) { $this->encryptionModules = array(); $this->config = $config; $this->logger = $logger; $this->l = $l10n; $this->rootView = $rootView; $this->util = $util; + $this->arrayCache = $arrayCache; } /** @@ -227,14 +233,9 @@ public function getDefaultEncryptionModuleId() { /** * Add storage wrapper */ - public static function setupStorage() { - $util = new Util( - new View(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager(), - \OC::$server->getConfig() - ); - Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2); + public function setupStorage() { + $encryptionWrapper = new EncryptionWrapper($this->arrayCache, $this, $this->logger); + Filesystem::addStorageWrapper('oc_encryption', array($encryptionWrapper, 'wrapStorage'), 2); } diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index 860c541934aec..9e0cfca830d6c 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -28,10 +28,8 @@ use OC\Encryption\Exceptions\EncryptionHeaderToLargeException; use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\Files\Filesystem; -use OC\Files\Storage\Wrapper\Encryption; use OC\Files\View; use OCP\Encryption\IEncryptionModule; -use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage; use OCP\IConfig; @@ -392,52 +390,4 @@ public function getKeyStorageRoot() { return $this->config->getAppValue('core', 'encryption_key_storage_root', ''); } - /** - * Wraps the given storage when it is not a shared storage - * - * @param string $mountPoint - * @param Storage $storage - * @param IMountPoint $mount - * @return Encryption|Storage - */ - public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount) { - $parameters = [ - 'storage' => $storage, - 'mountPoint' => $mountPoint, - 'mount' => $mount]; - - if (!$storage->instanceOfStorage('OC\Files\Storage\Shared') - && !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') - && !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud')) { - - $manager = \OC::$server->getEncryptionManager(); - $user = \OC::$server->getUserSession()->getUser(); - $logger = \OC::$server->getLogger(); - $mountManager = Filesystem::getMountManager(); - $uid = $user ? $user->getUID() : null; - $fileHelper = \OC::$server->getEncryptionFilesHelper(); - $keyStorage = \OC::$server->getEncryptionKeyStorage(); - $update = new Update( - new View(), - $this, - Filesystem::getMountManager(), - $manager, - $fileHelper, - $uid - ); - return new Encryption( - $parameters, - $manager, - $this, - $logger, - $fileHelper, - $uid, - $keyStorage, - $update, - $mountManager - ); - } else { - return $storage; - } - } } diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 81eea9944f891..2c8de38ddd25e 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -33,6 +33,7 @@ use OC\Files\Filesystem; use OC\Files\Mount\Manager; use OC\Files\Storage\LocalTempFileTrait; +use OC\Memcache\ArrayCache; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\Encryption\IFile; use OCP\Encryption\IManager; @@ -82,6 +83,9 @@ class Encryption extends Wrapper { /** @var array remember for which path we execute the repair step to avoid recursions */ private $fixUnencryptedSizeOf = array(); + /** @var ArrayCache */ + private $arrayCache; + /** * @param array $parameters * @param IManager $encryptionManager @@ -92,6 +96,7 @@ class Encryption extends Wrapper { * @param IStorage $keyStorage * @param Update $update * @param Manager $mountManager + * @param ArrayCache $arrayCache */ public function __construct( $parameters, @@ -102,7 +107,8 @@ public function __construct( $uid = null, IStorage $keyStorage = null, Update $update = null, - Manager $mountManager = null + Manager $mountManager = null, + ArrayCache $arrayCache = null ) { $this->mountPoint = $parameters['mountPoint']; @@ -116,6 +122,7 @@ public function __construct( $this->unencryptedSize = array(); $this->update = $update; $this->mountManager = $mountManager; + $this->arrayCache = $arrayCache; parent::__construct($parameters); } @@ -352,6 +359,14 @@ public function copy($path1, $path2) { */ public function fopen($path, $mode) { + // check if the file is stored in the array cache, this means that we + // copy a file over to the versions folder, in this case we don't want to + // decrypt it + if ($this->arrayCache->hasKey('encryption_copy_version_' . $path)) { + $this->arrayCache->remove('encryption_copy_version_' . $path); + return $this->storage->fopen($path, $mode); + } + $encryptionEnabled = $this->encryptionManager->isEnabled(); $shouldEncrypt = false; $encryptionModule = null; @@ -674,7 +689,12 @@ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, // key from the original file. Just create a 1:1 copy and done if ($this->isVersion($targetInternalPath) || $this->isVersion($sourceInternalPath)) { + // remember that we try to create a version so that we can detect it during + // fopen($sourceInternalPath) and by-pass the encryption in order to + // create a 1:1 copy of the file + $this->arrayCache->set('encryption_copy_version_' . $sourceInternalPath, true); $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); + $this->arrayCache->remove('encryption_copy_version_' . $sourceInternalPath); if ($result) { $info = $this->getCache('', $sourceStorage)->get($sourceInternalPath); // make sure that we update the unencrypted size for the version diff --git a/lib/private/server.php b/lib/private/server.php index 509c1ea0e58ec..938ec3bdc3b8a 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -59,6 +59,7 @@ use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; use OC\Mail\Mailer; +use OC\Memcache\ArrayCache; use OC\Notification\Manager; use OC\Security\CertificateManager; use OC\Security\CSP\ContentSecurityPolicyManager; @@ -117,7 +118,8 @@ public function __construct($webRoot, \OC\Config $config) { $c->getLogger(), $c->getL10N('core'), new View(), - $util + $util, + new ArrayCache() ); }); diff --git a/tests/lib/encryption/encryptionwrappertest.php b/tests/lib/encryption/encryptionwrappertest.php new file mode 100644 index 0000000000000..909187ae43b4c --- /dev/null +++ b/tests/lib/encryption/encryptionwrappertest.php @@ -0,0 +1,101 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + + +namespace Test\Encryption; + + +use OC\Encryption\EncryptionWrapper; +use Test\TestCase; + +class EncryptionWrapperTest extends TestCase { + + /** @var EncryptionWrapper */ + private $instance; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\ILogger */ + private $logger; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Encryption\Manager */ + private $manager; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Memcache\ArrayCache */ + private $arrayCache; + + public function setUp() { + parent::setUp(); + + $this->arrayCache = $this->getMock('OC\Memcache\ArrayCache'); + $this->manager = $this->getMockBuilder('OC\Encryption\Manager') + ->disableOriginalConstructor()->getMock(); + $this->logger = $this->getMock('OCP\ILogger'); + + $this->instance = new EncryptionWrapper($this->arrayCache, $this->manager, $this->logger); + } + + + /** + * @dataProvider provideWrapStorage + */ + public function testWrapStorage($expectedWrapped, $wrappedStorages) { + $storage = $this->getMockBuilder('OC\Files\Storage\Storage') + ->disableOriginalConstructor() + ->getMock(); + + foreach ($wrappedStorages as $wrapper) { + $storage->expects($this->any()) + ->method('instanceOfStorage') + ->willReturnMap([ + [$wrapper, true], + ]); + } + + $mount = $this->getMockBuilder('OCP\Files\Mount\IMountPoint') + ->disableOriginalConstructor() + ->getMock(); + + $returnedStorage = $this->instance->wrapStorage('mountPoint', $storage, $mount); + + $this->assertEquals( + $expectedWrapped, + $returnedStorage->instanceOfStorage('OC\Files\Storage\Wrapper\Encryption'), + 'Asserted that the storage is (not) wrapped with encryption' + ); + } + + public function provideWrapStorage() { + return [ + // Wrap when not wrapped or not wrapped with storage + [true, []], + [true, ['OCA\Files_Trashbin\Storage']], + + // Do not wrap shared storages + [false, ['OC\Files\Storage\Shared']], + [false, ['OCA\Files_Sharing\External\Storage']], + [false, ['OC\Files\Storage\OwnCloud']], + [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage']], + [false, ['OC\Files\Storage\Shared', 'OC\Files\Storage\OwnCloud']], + [false, ['OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], + [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], + ]; + } + +} diff --git a/tests/lib/encryption/managertest.php b/tests/lib/encryption/managertest.php index 6355c706b6100..3dcfc949a1826 100644 --- a/tests/lib/encryption/managertest.php +++ b/tests/lib/encryption/managertest.php @@ -24,6 +24,9 @@ class ManagerTest extends TestCase { /** @var \PHPUnit_Framework_MockObject_MockObject */ private $util; + + /** @var \PHPUnit_Framework_MockObject_MockObject | \OC\Memcache\ArrayCache */ + private $arrayCache; public function setUp() { parent::setUp(); @@ -32,7 +35,8 @@ public function setUp() { $this->l10n = $this->getMock('\OCP\Il10n'); $this->view = $this->getMock('\OC\Files\View'); $this->util = $this->getMockBuilder('\OC\Encryption\Util')->disableOriginalConstructor()->getMock(); - $this->manager = new Manager($this->config, $this->logger, $this->l10n, $this->view, $this->util); + $this->arrayCache = $this->getMock('OC\Memcache\ArrayCache'); + $this->manager = new Manager($this->config, $this->logger, $this->l10n, $this->view, $this->util, $this->arrayCache); } public function testManagerIsDisabled() { diff --git a/tests/lib/encryption/utiltest.php b/tests/lib/encryption/utiltest.php index 449326bb3514f..ec316a9f05a69 100644 --- a/tests/lib/encryption/utiltest.php +++ b/tests/lib/encryption/utiltest.php @@ -188,49 +188,4 @@ public function dataTestStripPartialFileExtension() { ); } - /** - * @dataProvider provideWrapStorage - */ - public function testWrapStorage($expectedWrapped, $wrappedStorages) { - $storage = $this->getMockBuilder('OC\Files\Storage\Storage') - ->disableOriginalConstructor() - ->getMock(); - - foreach ($wrappedStorages as $wrapper) { - $storage->expects($this->any()) - ->method('instanceOfStorage') - ->willReturnMap([ - [$wrapper, true], - ]); - } - - $mount = $this->getMockBuilder('OCP\Files\Mount\IMountPoint') - ->disableOriginalConstructor() - ->getMock(); - - $returnedStorage = $this->util->wrapStorage('mountPoint', $storage, $mount); - - $this->assertEquals( - $expectedWrapped, - $returnedStorage->instanceOfStorage('OC\Files\Storage\Wrapper\Encryption'), - 'Asserted that the storage is (not) wrapped with encryption' - ); - } - - public function provideWrapStorage() { - return [ - // Wrap when not wrapped or not wrapped with storage - [true, []], - [true, ['OCA\Files_Trashbin\Storage']], - - // Do not wrap shared storages - [false, ['OC\Files\Storage\Shared']], - [false, ['OCA\Files_Sharing\External\Storage']], - [false, ['OC\Files\Storage\OwnCloud']], - [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage']], - [false, ['OC\Files\Storage\Shared', 'OC\Files\Storage\OwnCloud']], - [false, ['OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], - [false, ['OC\Files\Storage\Shared', 'OCA\Files_Sharing\External\Storage', 'OC\Files\Storage\OwnCloud']], - ]; - } } diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index bde920e440e6c..9d68f3b14b2ef 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -87,6 +87,9 @@ class Encryption extends Storage { */ private $config; + /** @var \OC\Memcache\ArrayCache | \PHPUnit_Framework_MockObject_MockObject */ + private $arrayCache; + /** @var integer dummy unencrypted size */ private $dummySize = -1; @@ -104,6 +107,7 @@ protected function setUp() { ->method('getEncryptionModule') ->willReturn($mockModule); + $this->arrayCache = $this->getMock('OC\Memcache\ArrayCache'); $this->config = $this->getMockBuilder('\OCP\IConfig') ->disableOriginalConstructor() ->getMock(); @@ -111,9 +115,10 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); - $this->util = $this->getMock('\OC\Encryption\Util', + $this->util = $this->getMock( + '\OC\Encryption\Util', ['getUidAndFilename', 'isFile', 'isExcluded'], - [new View(), new \OC\User\Manager(), $this->groupManager, $this->config]); + [new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]); $this->util->expects($this->any()) ->method('getUidAndFilename') ->willReturnCallback(function ($path) { @@ -168,7 +173,7 @@ protected function setUp() { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['getMetaData', 'getCache', 'getEncryptionModule']) @@ -245,7 +250,7 @@ function($path) use ($encrypted) { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['getCache', 'verifyUnencryptedSize']) @@ -293,7 +298,7 @@ public function testFilesize() { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['getCache', 'verifyUnencryptedSize']) @@ -331,7 +336,7 @@ public function testVerifyUnencryptedSize($encryptedSize, $unencryptedSize, $fai 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['fixUnencryptedSize']) @@ -521,8 +526,15 @@ public function testGetHeader($path, $strippedPathExists, $strippedPath) { ->disableOriginalConstructor()->getMock(); $util = $this->getMockBuilder('\OC\Encryption\Util') - ->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config]) - ->getMock(); + ->setConstructorArgs( + [ + new View(), + new \OC\User\Manager(), + $this->groupManager, + $this->config, + $this->arrayCache + ] + )->getMock(); $instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption') ->setConstructorArgs( @@ -533,7 +545,7 @@ public function testGetHeader($path, $strippedPathExists, $strippedPath) { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['readFirstBlock', 'parseRawHeader']) @@ -582,7 +594,7 @@ public function testGetHeaderAddLegacyModule($header, $isEncrypted, $expected) { ->disableOriginalConstructor()->getMock(); $util = $this->getMockBuilder('\OC\Encryption\Util') - ->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config]) + ->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]) ->getMock(); $cache = $this->getMockBuilder('\OC\Files\Cache\Cache') @@ -600,7 +612,7 @@ public function testGetHeaderAddLegacyModule($header, $isEncrypted, $expected) { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ] ) ->setMethods(['readFirstBlock', 'parseRawHeader', 'getCache']) @@ -636,7 +648,7 @@ public function testParseRawHeader($rawHeader, $expected) { 'mountPoint' => '/', 'mount' => $this->mount ], - $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager + $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache ); @@ -763,6 +775,8 @@ public function testCopyBetweenStorage($encryptionEnabled, $mountPointEncryption $expectedCachePut['encryptedVersion'] = 12345; } + $this->arrayCache->expects($this->never())->method('set'); + $this->cache->expects($this->once()) ->method('put') ->with($sourceInternalPath, $expectedCachePut); @@ -812,7 +826,8 @@ public function testCopyBetweenStorageVersions($sourceInternalPath, $targetInte null, $this->keyStore, $this->update, - $this->mountManager + $this->mountManager, + $this->arrayCache ] ) ->setMethods(['updateUnencryptedSize', 'getCache']) @@ -825,6 +840,9 @@ public function testCopyBetweenStorageVersions($sourceInternalPath, $targetInte $instance->expects($this->any())->method('getCache') ->willReturn($cache); + $this->arrayCache->expects($this->once())->method('set') + ->with('encryption_copy_version_' . $sourceInternalPath, true); + if ($copyResult) { $cache->expects($this->once())->method('get') ->with($sourceInternalPath) diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php index f67dd09bc4dc3..afb31f2822d07 100644 --- a/tests/lib/files/stream/encryption.php +++ b/tests/lib/files/stream/encryption.php @@ -31,6 +31,7 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC $config = $this->getMockBuilder('\OCP\IConfig') ->disableOriginalConstructor() ->getMock(); + $arrayCache = $this->getMock('OC\Memcache\ArrayCache'); $groupManager = $this->getMockBuilder('\OC\Group\Manager') ->disableOriginalConstructor() ->getMock(); @@ -39,7 +40,11 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC ->setMethods(['getAccessList']) ->getMock(); $file->expects($this->any())->method('getAccessList')->willReturn([]); - $util = $this->getMock('\OC\Encryption\Util', ['getUidAndFilename'], [new View(), new \OC\User\Manager(), $groupManager, $config]); + $util = $this->getMock( + '\OC\Encryption\Util', + ['getUidAndFilename'], + [new View(), new \OC\User\Manager(), $groupManager, $config, $arrayCache] + ); $util->expects($this->any()) ->method('getUidAndFilename') ->willReturn(['user1', $internalPath]); diff --git a/tests/lib/traits/encryptiontrait.php b/tests/lib/traits/encryptiontrait.php index 92ba37348730b..2c1c585d6d46f 100644 --- a/tests/lib/traits/encryptiontrait.php +++ b/tests/lib/traits/encryptiontrait.php @@ -8,8 +8,8 @@ namespace Test\Traits; -use OC\Encryption\Util; -use OC\Files\View; +use OC\Encryption\EncryptionWrapper; +use OC\Memcache\ArrayCache; use OCA\Encryption\AppInfo\Application; use OCA\Encryption\KeyManager; use OCA\Encryption\Users\Setup; @@ -68,13 +68,13 @@ protected function setupForUser($name, $password) { } protected function postLogin() { - $util = new Util( - new View(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager(), - \OC::$server->getConfig() + $encryptionWrapper = new EncryptionWrapper( + new ArrayCache(), + \OC::$server->getEncryptionManager(), + \OC::$server->getLogger() ); - $this->registerStorageWrapper('oc_encryption', array($util, 'wrapStorage')); + + $this->registerStorageWrapper('oc_encryption', array($encryptionWrapper, 'wrapStorage')); } protected function setUpEncryptionTrait() { From 43579e784f85f244c24553b6cac01946ab4d96f2 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 30 Mar 2016 23:29:26 +0200 Subject: [PATCH 175/286] Properly handle return values of OC_App::getAppInfo() * fixes #23668 --- lib/private/app.php | 15 +++++++++++++++ lib/private/installer.php | 3 +++ lib/public/app.php | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/private/app.php b/lib/private/app.php index 7917c1c0c0140..5d0909de2a57a 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -207,6 +207,9 @@ private static function getAppTypes($app) { */ public static function setAppTypes($app) { $appData = self::getAppInfo($app); + if(!is_array($appData)) { + return; + } if (isset($appData['types'])) { $appTypes = implode(',', $appData['types']); @@ -788,6 +791,10 @@ public static function listAllApps($onlyLocal = false, if (array_search($app, $blacklist) === false) { $info = OC_App::getAppInfo($app); + if (!is_array($info)) { + \OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR); + continue; + } if (!isset($info['name'])) { \OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR); @@ -1086,6 +1093,14 @@ public static function installApp($app) { if ($app !== false) { // check if the app is compatible with this version of ownCloud $info = self::getAppInfo($app); + if(!is_array($info)) { + throw new \Exception( + $l->t('App "%s" cannot be installed because appinfo file cannot be read.', + [$info['name']] + ) + ); + } + $version = \OCP\Util::getVersion(); if (!self::isAppCompatible($version, $info)) { throw new \Exception( diff --git a/lib/private/installer.php b/lib/private/installer.php index b238d141a0fe1..fca9fce23efd4 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -342,6 +342,9 @@ public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped } $info = OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true); + if(!is_array($info)) { + throw new \Exception($l->t('App cannot be installed because appinfo file cannot be read.')); + } // We can't trust the parsed info.xml file as it may have been tampered // with by an attacker and thus we need to use the local data to check diff --git a/lib/public/app.php b/lib/public/app.php index e25f025d12dfe..41e4a7cbd61b5 100644 --- a/lib/public/app.php +++ b/lib/public/app.php @@ -112,7 +112,7 @@ public static function registerAdmin( $app, $page ) { * Read app metadata from the info.xml file * @param string $app id of the app or the path of the info.xml file * @param boolean $path (optional) - * @return array + * @return array|null * @since 4.0.0 */ public static function getAppInfo( $app, $path=false ) { From 78ee14dad5e1eb98109f47608fd9666fed0faaa5 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 1 Apr 2016 10:32:23 +0200 Subject: [PATCH 176/286] Also replace password in updatePrivateKeyPassword Fixes https://github.com/owncloud/core/issues/23717 --- lib/private/log.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/log.php b/lib/private/log.php index addefe6e53d4c..9a2a2da906eb2 100644 --- a/lib/private/log.php +++ b/lib/private/log.php @@ -284,7 +284,7 @@ public function logException(\Exception $exception, array $context = array()) { 'File' => $exception->getFile(), 'Line' => $exception->getLine(), ); - $exception['Trace'] = preg_replace('!(login|checkPassword)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']); + $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']); $msg = isset($context['message']) ? $context['message'] : 'Exception'; $msg .= ': ' . json_encode($exception); $this->error($msg, $context); From 752e6676e1c18eb269f4e2b19415c0f1f6c7c7cc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 22 Mar 2016 16:54:01 +0100 Subject: [PATCH 177/286] Detect user navigating away, don't interpret as ajax error Whenever a user navigates away, all ajax calls will fail with the same result like a cross-domain redirect (SSO). To distinguish these cases, we need to detect whether the error is a result of the user navigating away. For this, we introduce a new flag that will be set in "beforeunload". Additional handling was required for false positives in case "beforeunload" is used (ex: cancelled upload) and the user cancelled the navigation. --- core/js/js.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/core/js/js.js b/core/js/js.js index e90ceaf4e18ab..584bf1c1c838c 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -741,7 +741,9 @@ var OC={ */ _processAjaxError: function(xhr) { // purposefully aborted request ? - if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout')) { + // this._userIsNavigatingAway needed to distinguish ajax calls cancelled by navigating away + // from calls cancelled by failed cross-domain ajax due to SSO redirect + if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout' || this._userIsNavigatingAway)) { return; } @@ -1438,6 +1440,29 @@ function initCore() { $('html').addClass('edge'); } + $(window).on('unload', function() { + OC._unloadCalled = true; + }); + $(window).on('beforeunload', function() { + // super-trick thanks to http://stackoverflow.com/a/4651049 + // in case another handler displays a confirmation dialog (ex: navigating away + // during an upload), there are two possible outcomes: user clicked "ok" or + // "cancel" + + // first timeout handler is called after unload dialog is closed + setTimeout(function() { + OC._userIsNavigatingAway = true; + + // second timeout event is only called if user cancelled (Chrome), + // but in other browsers it might still be triggered, so need to + // set a higher delay... + setTimeout(function() { + if (!OC._unloadCalled) { + OC._userIsNavigatingAway = false; + } + }, 10000); + },1); + }); $(document).on('ajaxError.main', function( event, request, settings ) { if (settings && settings.allowAuthErrors) { return; From d8261d41cc7777c460a0a240b2b6291b7962b1b9 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 22 Mar 2016 16:55:43 +0100 Subject: [PATCH 178/286] Firefox returns 303 on cross-domain redirect Added 303 to catch SSO cross-domain redirect in Firefox. --- core/js/js.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/js.js b/core/js/js.js index 584bf1c1c838c..1a3b532ed4c5f 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -747,7 +747,7 @@ var OC={ return; } - if (_.contains([0, 302, 307, 401], xhr.status)) { + if (_.contains([0, 302, 303, 307, 401], xhr.status)) { OC.reload(); } }, From 51ff3e7443592461dba9ba3730e80ca775f2c04b Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 22 Mar 2016 18:28:54 +0100 Subject: [PATCH 179/286] Stronger fix for navigate away detection --- core/js/js.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index 1a3b532ed4c5f..f4e0fa464d8d5 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -740,15 +740,23 @@ var OC={ * if an error/auth error status was returned. */ _processAjaxError: function(xhr) { + var self = this; // purposefully aborted request ? // this._userIsNavigatingAway needed to distinguish ajax calls cancelled by navigating away // from calls cancelled by failed cross-domain ajax due to SSO redirect - if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout' || this._userIsNavigatingAway)) { + if (xhr.status === 0 && (xhr.statusText === 'abort' || xhr.statusText === 'timeout' || self._reloadCalled)) { return; } if (_.contains([0, 302, 303, 307, 401], xhr.status)) { - OC.reload(); + // sometimes "beforeunload" happens later, so need to defer the reload a bit + setTimeout(function() { + if (!self._userIsNavigatingAway && !self._reloadCalled) { + OC.reload(); + // only call reload once + self._reloadCalled = true; + } + }, 100); } }, From c58e96e6395dff5cf914d66df099922c0b1b6981 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 23 Mar 2016 10:53:40 +0100 Subject: [PATCH 180/286] Adjust core unit tests for unload/reload cases --- core/js/js.js | 4 +-- core/js/tests/specs/coreSpec.js | 45 ++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index f4e0fa464d8d5..b74775a935f8e 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1448,10 +1448,10 @@ function initCore() { $('html').addClass('edge'); } - $(window).on('unload', function() { + $(window).on('unload.main', function() { OC._unloadCalled = true; }); - $(window).on('beforeunload', function() { + $(window).on('beforeunload.main', function() { // super-trick thanks to http://stackoverflow.com/a/4651049 // in case another handler displays a confirmation dialog (ex: navigating away // during an upload), there are two possible outcomes: user clicked "ok" or diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 774c2fdc72fb3..f18ecbc1a448c 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -20,6 +20,15 @@ */ describe('Core base tests', function() { + afterEach(function() { + // many tests call window.initCore so need to unregister global events + // ideally in the future we'll need a window.unloadCore() function + $(document).off('ajaxError.main'); + $(document).off('unload.main'); + $(document).off('beforeunload.main'); + OC._userIsNavigatingAway = false; + OC._reloadCalled = false; + }); describe('Base values', function() { it('Sets webroots', function() { expect(OC.webroot).toBeDefined(); @@ -925,9 +934,10 @@ describe('Core base tests', function() { }); }); describe('global ajax errors', function() { - var reloadStub, ajaxErrorStub; + var reloadStub, ajaxErrorStub, clock; beforeEach(function() { + clock = sinon.useFakeTimers(); reloadStub = sinon.stub(OC, 'reload'); // unstub the error processing method ajaxErrorStub = OC._processAjaxError; @@ -936,15 +946,17 @@ describe('Core base tests', function() { }); afterEach(function() { reloadStub.restore(); - $(document).off('ajaxError'); + clock.restore(); }); - it('reloads current page in case of auth error', function () { + it('reloads current page in case of auth error', function() { var dataProvider = [ [200, false], [400, false], + [0, true], [401, true], [302, true], + [303, true], [307, true] ]; @@ -953,9 +965,13 @@ describe('Core base tests', function() { var expectedCall = dataProvider[i][1]; reloadStub.reset(); + OC._reloadCalled = false; $(document).trigger(new $.Event('ajaxError'), xhr); + // trigger timers + clock.tick(1000); + if (expectedCall) { expect(reloadStub.calledOnce).toEqual(true); } else { @@ -963,6 +979,27 @@ describe('Core base tests', function() { } } }); - }) + it('reload only called once in case of auth error', function() { + var xhr = { status: 401 }; + + $(document).trigger(new $.Event('ajaxError'), xhr); + $(document).trigger(new $.Event('ajaxError'), xhr); + + // trigger timers + clock.tick(1000); + + expect(reloadStub.calledOnce).toEqual(true); + }); + it('does not reload the page if the user was navigating away', function() { + var xhr = { status: 0 }; + OC._userIsNavigatingAway = true; + clock.tick(100); + + $(document).trigger(new $.Event('ajaxError'), xhr); + + clock.tick(1000); + expect(reloadStub.notCalled).toEqual(true); + }); + }); }); From 6774f602403b19b7870f44e55c6e5bf434442ff4 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Fri, 1 Apr 2016 23:00:23 +0200 Subject: [PATCH 181/286] 9.0.1 RC2 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 39cddf766a6ab..c1c70844af10d 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 1, 1); +$OC_Version = array(9, 0, 1, 2); // The human readable string -$OC_VersionString = '9.0.1 RC1'; +$OC_VersionString = '9.0.1 RC2'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From d857f7caf2bc6d2528ea1c31cec8a0729776651c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 1 Apr 2016 21:05:55 +0200 Subject: [PATCH 182/286] Unmount the share before deleting it, so we don't try to use it later on --- apps/files/command/transferownership.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php index 3674727b1672c..98dbc428220b6 100644 --- a/apps/files/command/transferownership.php +++ b/apps/files/command/transferownership.php @@ -203,9 +203,15 @@ protected function transfer(OutputInterface $output) { private function restoreShares(OutputInterface $output) { $output->writeln("Restoring shares ..."); $progress = new ProgressBar($output, count($this->shares)); + $mountManager = Filesystem::getMountManager($this->destinationUser); foreach($this->shares as $share) { if ($share->getSharedWith() === $this->destinationUser) { + // Unmount the shares before deleting, so we don't try to get the storage later on. + $shareMountPoint = $mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget()); + if ($shareMountPoint) { + $mountManager->removeMount($shareMountPoint->getMountPoint()); + } $this->shareManager->deleteShare($share); } else { if ($share->getShareOwner() === $this->sourceUser) { From dd5f38e35196de9971760e7845b7eec740f340fc Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Apr 2016 09:08:55 +0200 Subject: [PATCH 183/286] Inject the Mount Manager --- apps/files/appinfo/register_command.php | 3 ++- apps/files/command/transferownership.php | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/files/appinfo/register_command.php b/apps/files/appinfo/register_command.php index e77087a229aaa..dad78186c627e 100644 --- a/apps/files/appinfo/register_command.php +++ b/apps/files/appinfo/register_command.php @@ -24,8 +24,9 @@ $dbConnection = \OC::$server->getDatabaseConnection(); $userManager = OC::$server->getUserManager(); $shareManager = \OC::$server->getShareManager(); +$mountManager = \OC::$server->getMountManager(); /** @var Symfony\Component\Console\Application $application */ $application->add(new OCA\Files\Command\Scan($userManager)); $application->add(new OCA\Files\Command\DeleteOrphanedFiles($dbConnection)); -$application->add(new OCA\Files\Command\TransferOwnership($userManager, $shareManager)); +$application->add(new OCA\Files\Command\TransferOwnership($userManager, $shareManager, $mountManager)); diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php index 98dbc428220b6..6bf2fae6bdfc8 100644 --- a/apps/files/command/transferownership.php +++ b/apps/files/command/transferownership.php @@ -24,7 +24,7 @@ use OC\Files\Filesystem; use OC\Files\View; use OCP\Files\FileInfo; -use OCP\Files\Folder; +use OCP\Files\Mount\IMountManager; use OCP\IUserManager; use OCP\Share\IManager; use OCP\Share\IShare; @@ -42,6 +42,9 @@ class TransferOwnership extends Command { /** @var IManager */ private $shareManager; + /** @var IMountManager */ + private $mountManager; + /** @var FileInfo[] */ private $allFiles = []; @@ -60,9 +63,10 @@ class TransferOwnership extends Command { /** @var string */ private $finalTarget; - public function __construct(IUserManager $userManager, IManager $shareManager) { + public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager) { $this->userManager = $userManager; $this->shareManager = $shareManager; + $this->mountManager = $mountManager; parent::__construct(); } @@ -203,14 +207,13 @@ protected function transfer(OutputInterface $output) { private function restoreShares(OutputInterface $output) { $output->writeln("Restoring shares ..."); $progress = new ProgressBar($output, count($this->shares)); - $mountManager = Filesystem::getMountManager($this->destinationUser); foreach($this->shares as $share) { if ($share->getSharedWith() === $this->destinationUser) { // Unmount the shares before deleting, so we don't try to get the storage later on. - $shareMountPoint = $mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget()); + $shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget()); if ($shareMountPoint) { - $mountManager->removeMount($shareMountPoint->getMountPoint()); + $this->mountManager->removeMount($shareMountPoint->getMountPoint()); } $this->shareManager->deleteShare($share); } else { From 85a0dd36891d31a2af0e654a6c1b571c0f612c08 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 4 Apr 2016 13:29:04 +0200 Subject: [PATCH 184/286] [stable9] Read available l10n files also from theme folder * Read available l10n files also from theme folder The old behaviour was that only languages could be used for an app that are already present in the apps/$app/l10n folder. If there is a themed l10n that is not present in the apps default l10n folder the language could not be used and the texts are not translated. With this change this is possible and also the l10n files are loaded even if the default l10n doesn't contain the l10n file. * Inject server root - allows proper testing and separation of concerns --- lib/private/l10n/factory.php | 51 ++++++++++++++----- lib/private/server.php | 3 +- tests/data/themes/abc/apps/files/l10n/zz.json | 0 tests/lib/l10n/factorytest.php | 28 +++++++++- tests/lib/l10n/l10nlegacytest.php | 2 +- tests/lib/l10n/l10ntest.php | 2 +- 6 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 tests/data/themes/abc/apps/files/l10n/zz.json diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php index 1440e9510c560..fd093c3601b7e 100644 --- a/lib/private/l10n/factory.php +++ b/lib/private/l10n/factory.php @@ -64,17 +64,23 @@ class Factory implements IFactory { /** @var IUserSession */ protected $userSession; + /** @var string */ + protected $serverRoot; + /** * @param IConfig $config * @param IRequest $request * @param IUserSession $userSession + * @param string $serverRoot */ public function __construct(IConfig $config, IRequest $request, - IUserSession $userSession) { + IUserSession $userSession, + $serverRoot) { $this->config = $config; $this->request = $request; $this->userSession = $userSession; + $this->serverRoot = $serverRoot; } /** @@ -186,6 +192,23 @@ public function findAvailableLanguages($app = null) { } } + // merge with translations from theme + $theme = $this->config->getSystemValue('theme'); + if (!empty($theme)) { + $themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot)); + + if (is_dir($themeDir)) { + $files = scandir($themeDir); + if ($files !== false) { + foreach ($files as $file) { + if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') { + $available[] = substr($file, 0, -5); + } + } + } + } + } + $this->availableLanguages[$key] = $available; return $available; } @@ -263,22 +286,22 @@ public function getL10nFilesForApp($app, $lang) { $i18nDir = $this->findL10nDir($app); $transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json'; - if ((\OC_Helper::isSubDirectory($transFile, \OC::$SERVERROOT . '/core/l10n/') - || \OC_Helper::isSubDirectory($transFile, \OC::$SERVERROOT . '/lib/l10n/') - || \OC_Helper::isSubDirectory($transFile, \OC::$SERVERROOT . '/settings/l10n/') + if ((\OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/core/l10n/') + || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/') + || \OC_Helper::isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/') || \OC_Helper::isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/') ) && file_exists($transFile)) { // load the translations file $languageFiles[] = $transFile; + } - // merge with translations from theme - $theme = $this->config->getSystemValue('theme'); - if (!empty($theme)) { - $transFile = \OC::$SERVERROOT . '/themes/' . $theme . substr($transFile, strlen(\OC::$SERVERROOT)); - if (file_exists($transFile)) { - $languageFiles[] = $transFile; - } + // merge with translations from theme + $theme = $this->config->getSystemValue('theme'); + if (!empty($theme)) { + $transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot)); + if (file_exists($transFile)) { + $languageFiles[] = $transFile; } } @@ -293,14 +316,14 @@ public function getL10nFilesForApp($app, $lang) { */ protected function findL10nDir($app = null) { if (in_array($app, ['core', 'lib', 'settings'])) { - if (file_exists(\OC::$SERVERROOT . '/' . $app . '/l10n/')) { - return \OC::$SERVERROOT . '/' . $app . '/l10n/'; + if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) { + return $this->serverRoot . '/' . $app . '/l10n/'; } } else if ($app && \OC_App::getAppPath($app) !== false) { // Check if the app is in the app folder return \OC_App::getAppPath($app) . '/l10n/'; } - return \OC::$SERVERROOT . '/core/l10n/'; + return $this->serverRoot . '/core/l10n/'; } diff --git a/lib/private/server.php b/lib/private/server.php index 938ec3bdc3b8a..581a2b44cead8 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -263,7 +263,8 @@ public function __construct($webRoot, \OC\Config $config) { return new \OC\L10N\Factory( $c->getConfig(), $c->getRequest(), - $c->getUserSession() + $c->getUserSession(), + \OC::$SERVERROOT ); }); $this->registerService('URLGenerator', function (Server $c) { diff --git a/tests/data/themes/abc/apps/files/l10n/zz.json b/tests/data/themes/abc/apps/files/l10n/zz.json new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/lib/l10n/factorytest.php b/tests/lib/l10n/factorytest.php index 9f5954d0ee1e2..e4c0eab2e6a92 100644 --- a/tests/lib/l10n/factorytest.php +++ b/tests/lib/l10n/factorytest.php @@ -28,6 +28,9 @@ class FactoryTest extends TestCase { /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ protected $userSession; + /** @var string */ + protected $serverRoot; + public function setUp() { parent::setUp(); @@ -42,6 +45,8 @@ public function setUp() { ->getMock(); $this->userSession = $this->getMock('\OCP\IUserSession'); + + $this->serverRoot = \OC::$SERVERROOT; } /** @@ -54,12 +59,13 @@ protected function getFactory(array $methods = []) { ->setConstructorArgs([ $this->config, $this->request, - $this->userSession + $this->userSession, + $this->serverRoot, ]) ->setMethods($methods) ->getMock(); } else { - return new Factory($this->config, $this->request, $this->userSession); + return new Factory($this->config, $this->request, $this->userSession, $this->serverRoot); } } @@ -287,6 +293,24 @@ public function dataLanguageExists() { ]; } + public function testFindAvailableLanguagesWithThemes() { + $this->serverRoot .= '/tests/data'; + $app = 'files'; + + $factory = $this->getFactory(['findL10nDir']); + $factory->expects($this->once()) + ->method('findL10nDir') + ->with($app) + ->willReturn($this->serverRoot . '/apps/files/l10n/'); + $this->config + ->expects($this->once()) + ->method('getSystemValue') + ->with('theme') + ->willReturn('abc'); + + $this->assertEquals(['en', 'zz'], $factory->findAvailableLanguages($app), '', 0.0, 10, true); + } + /** * @dataProvider dataLanguageExists * diff --git a/tests/lib/l10n/l10nlegacytest.php b/tests/lib/l10n/l10nlegacytest.php index 025f761fe5c51..1df22ba36bd85 100644 --- a/tests/lib/l10n/l10nlegacytest.php +++ b/tests/lib/l10n/l10nlegacytest.php @@ -124,7 +124,7 @@ public function testFirstWeekDay($expected, $lang) { } public function testFactoryGetLanguageCode() { - $factory = new \OC\L10N\Factory($this->getMock('OCP\IConfig'), $this->getMock('OCP\IRequest'), $this->getMock('OCP\IUserSession')); + $factory = new \OC\L10N\Factory($this->getMock('OCP\IConfig'), $this->getMock('OCP\IRequest'), $this->getMock('OCP\IUserSession'), \OC::$SERVERROOT); $l = $factory->get('lib', 'de'); $this->assertEquals('de', $l->getLanguageCode()); } diff --git a/tests/lib/l10n/l10ntest.php b/tests/lib/l10n/l10ntest.php index 0d175954bc187..227e07056a854 100644 --- a/tests/lib/l10n/l10ntest.php +++ b/tests/lib/l10n/l10ntest.php @@ -31,7 +31,7 @@ protected function getFactory() { $request = $this->getMock('OCP\IRequest'); /** @var IUserSession $userSession */ $userSession = $this->getMock('OCP\IUserSession'); - return new Factory($config, $request, $userSession); + return new Factory($config, $request, $userSession, \OC::$SERVERROOT); } public function testGermanPluralTranslations() { From 7fdac35654c9a440d33ca0b4b0d8a469cd524dbf Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 16 Mar 2016 13:49:07 +0100 Subject: [PATCH 185/286] Fix PHP memory leak in file_get_contents() * ref https://bugs.php.net/bug.php?id=61961 * ref https://github.com/owncloud/core/issues/20261#issuecomment-180000256 * code is based on the proposal of @chriseqipe * fixes #20261 --- lib/private/filechunking.php | 4 +++- lib/private/files/storage/local.php | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/private/filechunking.php b/lib/private/filechunking.php index 32cbb7559f0ae..5cae0ab2cf05a 100644 --- a/lib/private/filechunking.php +++ b/lib/private/filechunking.php @@ -90,7 +90,7 @@ public function isComplete() { * Assembles the chunks into the file specified by the path. * Chunks are deleted afterwards. * - * @param string $f target path + * @param resource $f target path * * @return integer assembled file size * @@ -106,6 +106,8 @@ public function assemble($f) { // remove after reading to directly save space $cache->remove($prefix.$i); $count += fwrite($f, $chunk); + // let php release the memory to work around memory exhausted error with php 5.6 + $chunk = null; } return $count; diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index f6f5a8cc130b7..b6d0ec3fb3474 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -176,7 +176,12 @@ public function touch($path, $mtime = null) { } public function file_get_contents($path) { - return file_get_contents($this->getSourcePath($path)); + // file_get_contents() has a memory leak: https://bugs.php.net/bug.php?id=61961 + $filename = $this->getSourcePath($path); + $handle = fopen($filename,'rb'); + $content = fread($handle, filesize($filename)); + fclose($handle); + return $content; } public function file_put_contents($path, $data) { From a50619200c6a08929dbe802118a6afadb376b866 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 5 Apr 2016 12:45:46 +0200 Subject: [PATCH 186/286] Use static method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is ugly as hell. But if we directly access `\OCP\IUserSession::getUser` here PHP throws a segfault on some servers: ``` gdb /usr/sbin/apache2 --batch --quiet -ex "run -f /etc/apache2/apache2.conf -DNO_DETACH -DONE_PROCESS -DDEBUG $defines" -ex "quit" [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.6. Set the 'ServerName' directive globally to suppress this message warning: the debug information found in "/usr/lib/debug//usr/lib/php5/20121212/mysql.so" does not match "/usr/lib/php5/20121212/mysql.so" (CRC mismatch). warning: the debug information found in "/usr/lib/debug/usr/lib/php5/20121212/mysql.so" does not match "/usr/lib/php5/20121212/mysql.so" (CRC mismatch). warning: the debug information found in "/usr/lib/debug//usr/lib/php5/20121212/mysqli.so" does not match "/usr/lib/php5/20121212/mysqli.so" (CRC mismatch). warning: the debug information found in "/usr/lib/debug/usr/lib/php5/20121212/mysqli.so" does not match "/usr/lib/php5/20121212/mysqli.so" (CRC mismatch). warning: the debug information found in "/usr/lib/debug//usr/lib/php5/20121212/pdo_mysql.so" does not match "/usr/lib/php5/20121212/pdo_mysql.so" (CRC mismatch). warning: the debug information found in "/usr/lib/debug/usr/lib/php5/20121212/pdo_mysql.so" does not match "/usr/lib/php5/20121212/pdo_mysql.so" (CRC mismatch). [New Thread 0x7fffdd206700 (LWP 28386)] [Thread 0x7fffdd206700 (LWP 28386) exited] [New Thread 0x7fffdd206700 (LWP 28387)] [New Thread 0x7fffdc975700 (LWP 28388)] Program received signal SIGSEGV, Segmentation fault. zend_parse_parameters (num_args=2, type_spec=type_spec@entry=0x7ffff3f85227 "s|s") at /build/php5-pO28mL/php5-5.5.9+dfsg/Zend/zend_API.c:923 923 /build/php5-pO28mL/php5-5.5.9+dfsg/Zend/zend_API.c: No such file or directory. A debugging session is active. Inferior 1 [process 28382] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal] ``` I'm still struggling to get a minimal example of this (also considering that it doesn't happen on every system :party). Anyways, it's a functional workaround until I determined the root cause… (also given the fact that patches may never be backported to distributions :see_no_evil: --- lib/private/log/owncloud.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 9c106299e4c57..781b3b79b52ab 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -91,11 +91,10 @@ public static function write($app, $message, $level) { $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; $method = is_string($request->getMethod()) ? $request->getMethod() : '--'; if(\OC::$server->getConfig()->getSystemValue('installed', false)) { - $userObj = \OC::$server->getUserSession()->getUser(); + $user = (\OC_User::getUser()) ? \OC_User::getUser() : '--'; } else { - $userObj = null; + $user = '--'; } - $user = !is_null($userObj) ? $userObj->getUID() : '--'; $entry = compact( 'reqId', 'remoteAddr', From 19541dd1cecdaa8f234b8ce9fc63b706d4423f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 23 Mar 2016 11:37:00 +0100 Subject: [PATCH 187/286] fixes #23496 --- apps/dav/appinfo/app.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/dav/appinfo/app.php b/apps/dav/appinfo/app.php index 17596ffecbbbd..d85a3583bf147 100644 --- a/apps/dav/appinfo/app.php +++ b/apps/dav/appinfo/app.php @@ -46,6 +46,8 @@ function(GenericEvent $event) use ($app) { $cm = \OC::$server->getContactsManager(); $cm->register(function() use ($cm, $app) { - $userId = \OC::$server->getUserSession()->getUser()->getUID(); - $app->setupContactsProvider($cm, $userId); + $user = \OC::$server->getUserSession()->getUser(); + if (!is_null($user)) { + $app->setupContactsProvider($cm, $user->getUID()); + } }); From cff3122a37b8b75737fada19ac8c15b4705fe2fd Mon Sep 17 00:00:00 2001 From: Daniel Hansson Date: Tue, 5 Apr 2016 15:16:02 +0200 Subject: [PATCH 188/286] [stable9] Fix conditional check in MySQL setup Backport of #23760 Fix conditional check in MySQL setup. --- lib/private/setup/mysql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/setup/mysql.php b/lib/private/setup/mysql.php index de2466676c1dd..86b60d417af1b 100644 --- a/lib/private/setup/mysql.php +++ b/lib/private/setup/mysql.php @@ -43,7 +43,7 @@ public function setupDatabase($username) { $query='select count(*) from information_schema.tables where table_schema=? AND table_name = ?'; $result = $connection->executeQuery($query, [$this->dbName, $this->tablePrefix.'users']); $row = $result->fetch(); - if(!$result or $row[0]==0) { + if (!$row or $row['count(*)'] === '0') { \OC_DB::createDbFromStructure($this->dbDefinitionFile); } } From b05269826a64f9a45dd84c29b6d76884c9dff2f3 Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Thu, 24 Mar 2016 20:44:54 +0300 Subject: [PATCH 189/286] Add releasenotes class --- lib/private/releasenotes.php | 105 ++++++++++++++++++++++++++++++++ tests/lib/releasenotes.php | 114 +++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 lib/private/releasenotes.php create mode 100644 tests/lib/releasenotes.php diff --git a/lib/private/releasenotes.php b/lib/private/releasenotes.php new file mode 100644 index 0000000000000..581c20d47e211 --- /dev/null +++ b/lib/private/releasenotes.php @@ -0,0 +1,105 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC; + +use Doctrine\DBAL\Platforms\MySqlPlatform; +use OCP\IDBConnection; + +/** + * Class to store release notes + */ +class ReleaseNotes { + /** @var \OCP\IDBConnection $dbConnection */ + protected $dbConnection; + + /** + * @param OCP\IDBConnection $connection + */ + public function __construct(IDBConnection $dbConnection){ + $this->dbConnection = $dbConnection; + } + + /** + * @param string $fromVersion + * @param string $toVersion + * @return array + */ + public function getReleaseNotes($fromVersion, $toVersion){ + $releaseNotes = []; + + try { + $fromVersionMajorMinor = $this->getMajorMinor($fromVersion); + } catch (\InvalidArgumentException $e) { + $fromVersionMajorMinor = ''; + } + + try { + $toVersionMajorMinor = $this->getMajorMinor($toVersion); + } catch (\InvalidArgumentException $e) { + $toVersionMajorMinor = ''; + } + + if ( $fromVersionMajorMinor === '8.2' && $toVersionMajorMinor === '9.0' ) { + // MySQL only + if ($this->isMysql()) { + if ($this->countFilecacheEntries() > 200000) { + $message = \OC::$server->getL10N('core')->t( + "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", + [$this->dbConnection->getPrefix().'filecache'] + ); + $releaseNotes[] = $message; + } + } + } + return $releaseNotes; + } + + /** + * @return bool + */ + protected function isMysql(){ + return $this->dbConnection->getDatabasePlatform() instanceof MySqlPlatform; + } + + /** + * Count entries in filecache table + * @return int + */ + protected function countFilecacheEntries(){ + $result = $this->dbConnection->executeQuery("SELECT COUNT(*) FROM *PREFIX*filecache"); + $count = $result->fetchColumn(); + return $count ? $count : 0; + } + + /** + * Strip everything except first digits + * @param string $version + * @return string + */ + private function getMajorMinor($version){ + $versionArray = explode('.', $version); + if ( count($versionArray)<2 ) { + throw new \InvalidArgumentException('Version should have at least 2 parts separated by dot.'); + } + return implode('.', [ $versionArray[0], $versionArray[1] ]); + } +} diff --git a/tests/lib/releasenotes.php b/tests/lib/releasenotes.php new file mode 100644 index 0000000000000..8219c6194d3fa --- /dev/null +++ b/tests/lib/releasenotes.php @@ -0,0 +1,114 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +class Test_ReleaseNotes extends \Test\TestCase { + protected $prefix = 'ocx_'; + + protected function setUp() { + parent::setUp(); + } + + protected function tearDown() { + $this->expected = []; + parent::tearDown(); + } + + public function resultProvider82to90(){ + return [ + [ [], false, 20 ], + [ [], false, 1000000 ], + [ [], true, 20 ], + [ [ + \OC::$server->getL10N('core')->t( + "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", + ['ocx_filecache'] + ) + ], true, 1000000 ], + ]; + } + + /** + * @dataProvider resultProvider82to90 + */ + public function test82to90($expected, $isMysql, $fileCount){ + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); + $actual = $releaseNotesMock->getReleaseNotes('8.2.22', '9.0.1'); + $this->assertEquals($expected, $actual); + } + + + + public function resultProvider90to91(){ + return [ + [ [], false, 20 ], + [ [], false, 1000000 ], + [ [], true, 20 ], + [ [], true, 1000000 ], + ]; + } + + /** + * @dataProvider resultProvider90to91 + */ + public function test90to91($expected, $isMysql, $fileCount){ + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); + $actual = $releaseNotesMock->getReleaseNotes('9.0.1', '9.1.0'); + $this->assertEquals($expected, $actual); + } + + + private function getReleaseNotesMock($isMysql, $fileCount){ + $dbConnectionMock = $this->getMockBuilder('OCP\IDBConnection') + ->setMethods(array_merge($this->getMethods('OCP\IDBConnection'), ['getPrefix'])) + ->getMock() + ; + $dbConnectionMock->expects($this->any()) + ->method('getPrefix') + ->willReturn($this->prefix) + ; + $releaseNotesMock = $this->getMockBuilder('OC\ReleaseNotes') + ->setConstructorArgs([$dbConnectionMock]) + ->setMethods(['isMysql', 'countFilecacheEntries']) + ->getMock() + ; + + $releaseNotesMock->expects($this->any()) + ->method('isMysql') + ->willReturn($isMysql) + ; + $releaseNotesMock->expects($this->any()) + ->method('countFilecacheEntries') + ->willReturn($fileCount) + ; + return $releaseNotesMock; + } + + private function getMethods($class){ + $methods = []; + if (class_exists($class) || interface_exists($class)) { + $reflector = new ReflectionClass($class); + foreach ($reflector->getMethods( ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_ABSTRACT ) as $method) { + $methods[] = $method->getName(); + } + } + return $methods; + } +} From 118c39d4722b52b5024cc4efa588fe2bfe7577a7 Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Fri, 25 Mar 2016 13:22:22 +0300 Subject: [PATCH 190/286] Show cli notice for big installations --- lib/private/releasenotes.php | 29 +++++++++++++------- tests/lib/releasenotes.php | 53 +++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/lib/private/releasenotes.php b/lib/private/releasenotes.php index 581c20d47e211..32ab036f9c195 100644 --- a/lib/private/releasenotes.php +++ b/lib/private/releasenotes.php @@ -45,6 +45,7 @@ public function __construct(IDBConnection $dbConnection){ */ public function getReleaseNotes($fromVersion, $toVersion){ $releaseNotes = []; + $l10n = \OC::$server->getL10N('core'); try { $fromVersionMajorMinor = $this->getMajorMinor($fromVersion); @@ -59,20 +60,28 @@ public function getReleaseNotes($fromVersion, $toVersion){ } if ( $fromVersionMajorMinor === '8.2' && $toVersionMajorMinor === '9.0' ) { - // MySQL only - if ($this->isMysql()) { - if ($this->countFilecacheEntries() > 200000) { - $message = \OC::$server->getL10N('core')->t( - "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", - [$this->dbConnection->getPrefix().'filecache'] - ); - $releaseNotes[] = $message; - } + if (!$this->isCliMode() && $this->countFilecacheEntries() > 200000) { + $releaseNotes[] = $l10n->t( + "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers." + ); + } + if ($this->isMysql() && $this->countFilecacheEntries() > 200000) { + $releaseNotes[] = $l10n->t( + "Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", + [$this->dbConnection->getPrefix().'filecache'] + ); } } return $releaseNotes; } - + + /** + * @return bool + */ + protected function isCliMode(){ + return \OC::$CLI; + } + /** * @return bool */ diff --git a/tests/lib/releasenotes.php b/tests/lib/releasenotes.php index 8219c6194d3fa..ca2c3db66fb5e 100644 --- a/tests/lib/releasenotes.php +++ b/tests/lib/releasenotes.php @@ -32,24 +32,31 @@ protected function tearDown() { } public function resultProvider82to90(){ + $l10n = \OC::$server->getL10N('core'); + $alterTableMessage = $l10n->t( + "Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", + ['ocx_filecache'] + ); + $useCliMessage = $l10n->t( + "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers." + ); return [ - [ [], false, 20 ], - [ [], false, 1000000 ], - [ [], true, 20 ], - [ [ - \OC::$server->getL10N('core')->t( - "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", - ['ocx_filecache'] - ) - ], true, 1000000 ], + [ [], false, false, 20 ], + [ [], false, true, 20 ], + [ [], true, false, 20 ], + [ [], true, true, 20 ], + [ [ $useCliMessage ], false, false, 1000000 ], + [ [], false, true, 1000000 ], + [ [ $useCliMessage, $alterTableMessage ], true, false, 1000000 ], + [ [ $alterTableMessage ], true, true, 1000000 ], ]; } /** * @dataProvider resultProvider82to90 */ - public function test82to90($expected, $isMysql, $fileCount){ - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); + public function test82to90($expected, $isMysql, $isCliMode, $fileCount){ + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); $actual = $releaseNotesMock->getReleaseNotes('8.2.22', '9.0.1'); $this->assertEquals($expected, $actual); } @@ -58,24 +65,28 @@ public function test82to90($expected, $isMysql, $fileCount){ public function resultProvider90to91(){ return [ - [ [], false, 20 ], - [ [], false, 1000000 ], - [ [], true, 20 ], - [ [], true, 1000000 ], + [ [], false, false, 20 ], + [ [], false, true, 20 ], + [ [], true, false, 20 ], + [ [], true, true, 20 ], + [ [], false, false, 1000000 ], + [ [], false, true, 1000000 ], + [ [], true, false, 1000000 ], + [ [], true, true, 1000000 ], ]; } /** * @dataProvider resultProvider90to91 */ - public function test90to91($expected, $isMysql, $fileCount){ - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); + public function test90to91($expected, $isMysql, $isCliMode, $fileCount){ + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); $actual = $releaseNotesMock->getReleaseNotes('9.0.1', '9.1.0'); $this->assertEquals($expected, $actual); } - private function getReleaseNotesMock($isMysql, $fileCount){ + private function getReleaseNotesMock($isMysql, $isCliMode, $fileCount){ $dbConnectionMock = $this->getMockBuilder('OCP\IDBConnection') ->setMethods(array_merge($this->getMethods('OCP\IDBConnection'), ['getPrefix'])) ->getMock() @@ -86,7 +97,7 @@ private function getReleaseNotesMock($isMysql, $fileCount){ ; $releaseNotesMock = $this->getMockBuilder('OC\ReleaseNotes') ->setConstructorArgs([$dbConnectionMock]) - ->setMethods(['isMysql', 'countFilecacheEntries']) + ->setMethods(['isMysql', 'isCliMode', 'countFilecacheEntries']) ->getMock() ; @@ -94,6 +105,10 @@ private function getReleaseNotesMock($isMysql, $fileCount){ ->method('isMysql') ->willReturn($isMysql) ; + $releaseNotesMock->expects($this->any()) + ->method('isCliMode') + ->willReturn($isCliMode) + ; $releaseNotesMock->expects($this->any()) ->method('countFilecacheEntries') ->willReturn($fileCount) From cfd8cc3fd8382038a556ea729bb7c9beb09e4765 Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Fri, 25 Mar 2016 16:16:49 +0300 Subject: [PATCH 191/286] Show release notes --- core/templates/update.admin.php | 5 +++++ lib/base.php | 3 +++ lib/private/server.php | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/core/templates/update.admin.php b/core/templates/update.admin.php index 75815de84bcfa..543820e054fa8 100644 --- a/core/templates/update.admin.php +++ b/core/templates/update.admin.php @@ -34,6 +34,11 @@
t('Please make sure that the database, the config folder and the data folder have been backed up before proceeding.')) ?>
+ +
+ +
+
t('To avoid timeouts with larger installations, you can instead run the following command from your installation directory:')) ?> diff --git a/lib/base.php b/lib/base.php index 35c8592fe104c..a5b0dd429ae41 100644 --- a/lib/base.php +++ b/lib/base.php @@ -392,12 +392,15 @@ private static function printUpgradePage() { $tmpl->assign('isAppsOnlyUpgrade', false); } + $releaseNotes = \OC::$server->getReleaseNotes(); + // get third party apps $ocVersion = \OCP\Util::getVersion(); $tmpl->assign('appsToUpgrade', $appManager->getAppsNeedingUpgrade($ocVersion)); $tmpl->assign('incompatibleAppsList', $appManager->getIncompatibleApps($ocVersion)); $tmpl->assign('productName', 'ownCloud'); // for now $tmpl->assign('oldTheme', $oldTheme); + $tmpl->assign('releaseNotes', $releaseNotes->getReleaseNotes($installedVersion, $currentVersion)); $tmpl->printPage(); } diff --git a/lib/private/server.php b/lib/private/server.php index 581a2b44cead8..00ee4e5c565a0 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -623,6 +623,12 @@ public function __construct($webRoot, \OC\Config $config) { return $manager; }); + + $this->registerService('ReleaseNotes', function (Server $c) { + return new \OC\ReleaseNotes( + $c->getDatabaseConnection() + ); + }); } /** @@ -1276,4 +1282,11 @@ public function getShareManager() { return $this->query('ShareManager'); } + /** + * @return \OC\ReleaseNotes + */ + public function getReleaseNotes() { + return $this->query('ReleaseNotes'); + } + } From b87b27cbd94275895fd9da3f29edced27cd5aaad Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Tue, 29 Mar 2016 16:57:41 +0300 Subject: [PATCH 192/286] Show hint in CLI --- core/command/upgrade.php | 38 +++++++++- core/register_command.php | 6 +- lib/base.php | 2 +- lib/private/releasenotes.php | 30 +++++--- lib/private/server.php | 13 ---- tests/lib/releasenotes.php | 129 --------------------------------- tests/lib/releasenotestest.php | 119 ++++++++++++++++++++++++++++++ 7 files changed, 179 insertions(+), 158 deletions(-) delete mode 100644 tests/lib/releasenotes.php create mode 100644 tests/lib/releasenotestest.php diff --git a/core/command/upgrade.php b/core/command/upgrade.php index c45984d7a309a..c76c9be4ed834 100644 --- a/core/command/upgrade.php +++ b/core/command/upgrade.php @@ -30,6 +30,7 @@ namespace OC\Core\Command; use OC\Console\TimestampFormatter; +use OC\ReleaseNotes; use OC\Updater; use OCP\IConfig; use OCP\ILogger; @@ -37,8 +38,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Question\ConfirmationQuestion; -class Upgrade extends Command { +class Upgrade extends Base { const ERROR_SUCCESS = 0; const ERROR_NOT_INSTALLED = 1; @@ -53,17 +55,23 @@ class Upgrade extends Command { /** @var ILogger */ private $logger; + /** @var ReleaseNotes */ + private $releaseNotes; + /** * @param IConfig $config * @param ILogger $logger + * @param ReleaseNotes $releaseNotes */ - public function __construct(IConfig $config, ILogger $logger) { + public function __construct(IConfig $config, ILogger $logger, ReleaseNotes $releaseNotes) { parent::__construct(); $this->config = $config; $this->logger = $logger; + $this->releaseNotes = $releaseNotes; } protected function configure() { + parent::configure(); $this ->setName('upgrade') ->setDescription('run upgrade routines after installation of a new release. The release has to be installed before.') @@ -95,6 +103,19 @@ protected function configure() { */ protected function execute(InputInterface $input, OutputInterface $output) { + if ($input->isInteractive()) { + $installedVersion = $this->config->getSystemValue('version', '0.0.0'); + $currentVersion = \OCP\Util::getVersion(); + + $releaseNotesArray = $this->releaseNotes->getReleaseNotes($installedVersion, $currentVersion); + if (!empty($releaseNotesArray)) { + $this->writeArrayInOutputFormat($input, $output, $releaseNotesArray); + if (!$this->ask($input, $output)){ + return self::ERROR_SUCCESS; + } + } + } + $simulateStepEnabled = true; $updateStepEnabled = true; $skip3rdPartyAppsDisable = false; @@ -262,4 +283,17 @@ protected function postUpgradeCheck(InputInterface $input, OutputInterface $outp ); } } + + /** + * Ask for confirmation + * @param InputInterface $input + * @param OutputInterface $output + * @return bool + */ + public function ask(InputInterface $input, OutputInterface $output){ + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Continue with update (y/n)' . PHP_EOL, true); + return $helper->ask($input, $output, $question); + } + } diff --git a/core/register_command.php b/core/register_command.php index 17bd573133a2b..e06ff436f50dd 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -114,7 +114,11 @@ $application->add(new OC\Core\Command\Maintenance\Repair(new \OC\Repair(\OC\Repair::getRepairSteps()), \OC::$server->getConfig())); $application->add(new OC\Core\Command\Maintenance\SingleUser(\OC::$server->getConfig())); - $application->add(new OC\Core\Command\Upgrade(\OC::$server->getConfig(), \OC::$server->getLogger())); + $application->add(new OC\Core\Command\Upgrade( + \OC::$server->getConfig(), + \OC::$server->getLogger(), + new \OC\ReleaseNotes(\OC::$server->getDatabaseConnection()) + )); $application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager())); $application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager())); diff --git a/lib/base.php b/lib/base.php index a5b0dd429ae41..e77a07239c432 100644 --- a/lib/base.php +++ b/lib/base.php @@ -392,7 +392,7 @@ private static function printUpgradePage() { $tmpl->assign('isAppsOnlyUpgrade', false); } - $releaseNotes = \OC::$server->getReleaseNotes(); + $releaseNotes = new \OC\ReleaseNotes(\OC::$server->getDatabaseConnection()); // get third party apps $ocVersion = \OCP\Util::getVersion(); diff --git a/lib/private/releasenotes.php b/lib/private/releasenotes.php index 32ab036f9c195..a7caf8601ae73 100644 --- a/lib/private/releasenotes.php +++ b/lib/private/releasenotes.php @@ -32,18 +32,18 @@ class ReleaseNotes { protected $dbConnection; /** - * @param OCP\IDBConnection $connection + * @param \OCP\IDBConnection $dbConnection */ - public function __construct(IDBConnection $dbConnection){ + public function __construct(IDBConnection $dbConnection) { $this->dbConnection = $dbConnection; } /** * @param string $fromVersion * @param string $toVersion - * @return array + * @return string[] */ - public function getReleaseNotes($fromVersion, $toVersion){ + public function getReleaseNotes($fromVersion, $toVersion) { $releaseNotes = []; $l10n = \OC::$server->getL10N('core'); @@ -59,16 +59,16 @@ public function getReleaseNotes($fromVersion, $toVersion){ $toVersionMajorMinor = ''; } - if ( $fromVersionMajorMinor === '8.2' && $toVersionMajorMinor === '9.0' ) { + if ($fromVersionMajorMinor === '8.2' && $toVersionMajorMinor === '9.0') { if (!$this->isCliMode() && $this->countFilecacheEntries() > 200000) { $releaseNotes[] = $l10n->t( - "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers." + 'You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers.' ); } if ($this->isMysql() && $this->countFilecacheEntries() > 200000) { $releaseNotes[] = $l10n->t( - "Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", - [$this->dbConnection->getPrefix().'filecache'] + 'Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;', + [$this->dbConnection->getQueryBuilder()->getTableName('filecache')] ); } } @@ -78,7 +78,7 @@ public function getReleaseNotes($fromVersion, $toVersion){ /** * @return bool */ - protected function isCliMode(){ + protected function isCliMode() { return \OC::$CLI; } @@ -94,9 +94,15 @@ protected function isMysql(){ * @return int */ protected function countFilecacheEntries(){ - $result = $this->dbConnection->executeQuery("SELECT COUNT(*) FROM *PREFIX*filecache"); - $count = $result->fetchColumn(); - return $count ? $count : 0; + $query = $this->dbConnection->getQueryBuilder(); + $query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries') + ->from('filecache'); + + $result = $query->execute(); + $row = $result->fetch(); + $result->closeCursor(); + + return (int) $row['num_entries']; } /** diff --git a/lib/private/server.php b/lib/private/server.php index 00ee4e5c565a0..581a2b44cead8 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -623,12 +623,6 @@ public function __construct($webRoot, \OC\Config $config) { return $manager; }); - - $this->registerService('ReleaseNotes', function (Server $c) { - return new \OC\ReleaseNotes( - $c->getDatabaseConnection() - ); - }); } /** @@ -1282,11 +1276,4 @@ public function getShareManager() { return $this->query('ShareManager'); } - /** - * @return \OC\ReleaseNotes - */ - public function getReleaseNotes() { - return $this->query('ReleaseNotes'); - } - } diff --git a/tests/lib/releasenotes.php b/tests/lib/releasenotes.php deleted file mode 100644 index ca2c3db66fb5e..0000000000000 --- a/tests/lib/releasenotes.php +++ /dev/null @@ -1,129 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -class Test_ReleaseNotes extends \Test\TestCase { - protected $prefix = 'ocx_'; - - protected function setUp() { - parent::setUp(); - } - - protected function tearDown() { - $this->expected = []; - parent::tearDown(); - } - - public function resultProvider82to90(){ - $l10n = \OC::$server->getL10N('core'); - $alterTableMessage = $l10n->t( - "Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;", - ['ocx_filecache'] - ); - $useCliMessage = $l10n->t( - "You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers." - ); - return [ - [ [], false, false, 20 ], - [ [], false, true, 20 ], - [ [], true, false, 20 ], - [ [], true, true, 20 ], - [ [ $useCliMessage ], false, false, 1000000 ], - [ [], false, true, 1000000 ], - [ [ $useCliMessage, $alterTableMessage ], true, false, 1000000 ], - [ [ $alterTableMessage ], true, true, 1000000 ], - ]; - } - - /** - * @dataProvider resultProvider82to90 - */ - public function test82to90($expected, $isMysql, $isCliMode, $fileCount){ - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); - $actual = $releaseNotesMock->getReleaseNotes('8.2.22', '9.0.1'); - $this->assertEquals($expected, $actual); - } - - - - public function resultProvider90to91(){ - return [ - [ [], false, false, 20 ], - [ [], false, true, 20 ], - [ [], true, false, 20 ], - [ [], true, true, 20 ], - [ [], false, false, 1000000 ], - [ [], false, true, 1000000 ], - [ [], true, false, 1000000 ], - [ [], true, true, 1000000 ], - ]; - } - - /** - * @dataProvider resultProvider90to91 - */ - public function test90to91($expected, $isMysql, $isCliMode, $fileCount){ - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); - $actual = $releaseNotesMock->getReleaseNotes('9.0.1', '9.1.0'); - $this->assertEquals($expected, $actual); - } - - - private function getReleaseNotesMock($isMysql, $isCliMode, $fileCount){ - $dbConnectionMock = $this->getMockBuilder('OCP\IDBConnection') - ->setMethods(array_merge($this->getMethods('OCP\IDBConnection'), ['getPrefix'])) - ->getMock() - ; - $dbConnectionMock->expects($this->any()) - ->method('getPrefix') - ->willReturn($this->prefix) - ; - $releaseNotesMock = $this->getMockBuilder('OC\ReleaseNotes') - ->setConstructorArgs([$dbConnectionMock]) - ->setMethods(['isMysql', 'isCliMode', 'countFilecacheEntries']) - ->getMock() - ; - - $releaseNotesMock->expects($this->any()) - ->method('isMysql') - ->willReturn($isMysql) - ; - $releaseNotesMock->expects($this->any()) - ->method('isCliMode') - ->willReturn($isCliMode) - ; - $releaseNotesMock->expects($this->any()) - ->method('countFilecacheEntries') - ->willReturn($fileCount) - ; - return $releaseNotesMock; - } - - private function getMethods($class){ - $methods = []; - if (class_exists($class) || interface_exists($class)) { - $reflector = new ReflectionClass($class); - foreach ($reflector->getMethods( ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_ABSTRACT ) as $method) { - $methods[] = $method->getName(); - } - } - return $methods; - } -} diff --git a/tests/lib/releasenotestest.php b/tests/lib/releasenotestest.php new file mode 100644 index 0000000000000..aaa47bb248165 --- /dev/null +++ b/tests/lib/releasenotestest.php @@ -0,0 +1,119 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace Test; + +class ReleaseNotesTest extends \Test\TestCase { + + /** + * @param bool $isMysql + * @param bool $isCliMode + * @param int $fileCount + * @return \PHPUnit_Framework_MockObject_MockObject|\OC\ReleaseNotes + */ + protected function getReleaseNotesMock($isMysql, $isCliMode, $fileCount) { + $query = $this->getMockBuilder('OCP\DB\QueryBuilder\IQueryBuilder') + ->disableOriginalConstructor() + ->getMock(); + $query->expects($this->any()) + ->method('getTableName') + ->willReturnCallback(function($tableName) { + return 'ocx_' . $tableName; + }); + + $dbConnectionMock = $this->getMockBuilder('OCP\IDBConnection') + ->disableOriginalConstructor() + ->getMock(); + $dbConnectionMock->expects($this->any()) + ->method('getQueryBuilder') + ->willReturn($query); + $releaseNotesMock = $this->getMockBuilder('OC\ReleaseNotes') + ->setConstructorArgs([$dbConnectionMock]) + ->setMethods(['isMysql', 'isCliMode', 'countFilecacheEntries']) + ->getMock(); + + $releaseNotesMock->expects($this->any()) + ->method('isMysql') + ->willReturn($isMysql); + $releaseNotesMock->expects($this->any()) + ->method('isCliMode') + ->willReturn($isCliMode); + $releaseNotesMock->expects($this->any()) + ->method('countFilecacheEntries') + ->willReturn($fileCount); + return $releaseNotesMock; + } + + public function data82to90() { + $alterTableMessage = 'Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE ocx_filecache ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;'; + $useCliMessage = 'You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers.'; + return [ + [[], false, false, 20], + [[], false, true, 20], + [[], true, false, 20], + [[], true, true, 20], + [[$useCliMessage], false, false, 1000000], + [[], false, true, 1000000], + [[$useCliMessage, $alterTableMessage], true, false, 1000000], + [[$alterTableMessage], true, true, 1000000], + ]; + } + + /** + * @dataProvider data82to90 + * + * @param string[] $expected + * @param bool $isMysql + * @param bool $isCliMode + * @param int $fileCount + */ + public function test82to90($expected, $isMysql, $isCliMode, $fileCount) { + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); + $actual = $releaseNotesMock->getReleaseNotes('8.2.22', '9.0.1'); + $this->assertEquals($expected, $actual); + } + + public function data90to91() { + return [ + [false, false, 20], + [false, true, 20], + [true, false, 20], + [true, true, 20], + [false, false, 1000000], + [false, true, 1000000], + [true, false, 1000000], + [true, true, 1000000], + ]; + } + + /** + * @dataProvider data90to91 + * + * @param bool $isMysql + * @param bool $isCliMode + * @param int $fileCount + */ + public function test90to91($isMysql, $isCliMode, $fileCount) { + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); + $actual = $releaseNotesMock->getReleaseNotes('9.0.1', '9.1.0'); + $this->assertCount(0, $actual); + } +} From e5bec54e4e746364b621a4d26e400f7178c9c62f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 6 Apr 2016 15:41:25 +0200 Subject: [PATCH 193/286] Make the version a string --- core/command/upgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/command/upgrade.php b/core/command/upgrade.php index c76c9be4ed834..a60eee9e327d4 100644 --- a/core/command/upgrade.php +++ b/core/command/upgrade.php @@ -105,7 +105,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { if ($input->isInteractive()) { $installedVersion = $this->config->getSystemValue('version', '0.0.0'); - $currentVersion = \OCP\Util::getVersion(); + $currentVersion = implode('.', \OCP\Util::getVersion()); $releaseNotesArray = $this->releaseNotes->getReleaseNotes($installedVersion, $currentVersion); if (!empty($releaseNotesArray)) { From c43713515b7615cd34b695327e8b246d9de6d800 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 6 Apr 2016 15:51:25 +0200 Subject: [PATCH 194/286] Remove duplicated message --- lib/private/releasenotes.php | 21 ++++------------ tests/lib/releasenotestest.php | 44 +++++++++++----------------------- 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/lib/private/releasenotes.php b/lib/private/releasenotes.php index a7caf8601ae73..5da416c19f0f5 100644 --- a/lib/private/releasenotes.php +++ b/lib/private/releasenotes.php @@ -28,11 +28,11 @@ * Class to store release notes */ class ReleaseNotes { - /** @var \OCP\IDBConnection $dbConnection */ + /** @var IDBConnection $dbConnection */ protected $dbConnection; /** - * @param \OCP\IDBConnection $dbConnection + * @param IDBConnection $dbConnection */ public function __construct(IDBConnection $dbConnection) { $this->dbConnection = $dbConnection; @@ -60,11 +60,6 @@ public function getReleaseNotes($fromVersion, $toVersion) { } if ($fromVersionMajorMinor === '8.2' && $toVersionMajorMinor === '9.0') { - if (!$this->isCliMode() && $this->countFilecacheEntries() > 200000) { - $releaseNotes[] = $l10n->t( - 'You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers.' - ); - } if ($this->isMysql() && $this->countFilecacheEntries() > 200000) { $releaseNotes[] = $l10n->t( 'Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE %s ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;', @@ -74,14 +69,7 @@ public function getReleaseNotes($fromVersion, $toVersion) { } return $releaseNotes; } - - /** - * @return bool - */ - protected function isCliMode() { - return \OC::$CLI; - } - + /** * @return bool */ @@ -109,10 +97,11 @@ protected function countFilecacheEntries(){ * Strip everything except first digits * @param string $version * @return string + * @throws \InvalidArgumentException */ private function getMajorMinor($version){ $versionArray = explode('.', $version); - if ( count($versionArray)<2 ) { + if (count($versionArray) < 2) { throw new \InvalidArgumentException('Version should have at least 2 parts separated by dot.'); } return implode('.', [ $versionArray[0], $versionArray[1] ]); diff --git a/tests/lib/releasenotestest.php b/tests/lib/releasenotestest.php index aaa47bb248165..584f396038b08 100644 --- a/tests/lib/releasenotestest.php +++ b/tests/lib/releasenotestest.php @@ -25,11 +25,10 @@ class ReleaseNotesTest extends \Test\TestCase { /** * @param bool $isMysql - * @param bool $isCliMode * @param int $fileCount * @return \PHPUnit_Framework_MockObject_MockObject|\OC\ReleaseNotes */ - protected function getReleaseNotesMock($isMysql, $isCliMode, $fileCount) { + protected function getReleaseNotesMock($isMysql, $fileCount) { $query = $this->getMockBuilder('OCP\DB\QueryBuilder\IQueryBuilder') ->disableOriginalConstructor() ->getMock(); @@ -47,15 +46,12 @@ protected function getReleaseNotesMock($isMysql, $isCliMode, $fileCount) { ->willReturn($query); $releaseNotesMock = $this->getMockBuilder('OC\ReleaseNotes') ->setConstructorArgs([$dbConnectionMock]) - ->setMethods(['isMysql', 'isCliMode', 'countFilecacheEntries']) + ->setMethods(['isMysql', 'countFilecacheEntries']) ->getMock(); $releaseNotesMock->expects($this->any()) ->method('isMysql') ->willReturn($isMysql); - $releaseNotesMock->expects($this->any()) - ->method('isCliMode') - ->willReturn($isCliMode); $releaseNotesMock->expects($this->any()) ->method('countFilecacheEntries') ->willReturn($fileCount); @@ -63,17 +59,11 @@ protected function getReleaseNotesMock($isMysql, $isCliMode, $fileCount) { } public function data82to90() { - $alterTableMessage = 'Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE ocx_filecache ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;'; - $useCliMessage = 'You have an ownCloud installation with over 200.000 files so the upgrade might take a while. The recommendation is to use the command-line instead of the web interface for big ownCloud servers.'; return [ - [[], false, false, 20], - [[], false, true, 20], - [[], true, false, 20], - [[], true, true, 20], - [[$useCliMessage], false, false, 1000000], - [[], false, true, 1000000], - [[$useCliMessage, $alterTableMessage], true, false, 1000000], - [[$alterTableMessage], true, true, 1000000], + [[], false, 20], + [[], true, 20], + [[], false, 1000000], + [['Hint: You can speed up the upgrade by executing this SQL command manually: ALTER TABLE ocx_filecache ADD COLUMN checksum varchar(255) DEFAULT NULL AFTER permissions;'], true, 1000000], ]; } @@ -82,25 +72,20 @@ public function data82to90() { * * @param string[] $expected * @param bool $isMysql - * @param bool $isCliMode * @param int $fileCount */ - public function test82to90($expected, $isMysql, $isCliMode, $fileCount) { - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); + public function test82to90($expected, $isMysql, $fileCount) { + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); $actual = $releaseNotesMock->getReleaseNotes('8.2.22', '9.0.1'); $this->assertEquals($expected, $actual); } public function data90to91() { return [ - [false, false, 20], - [false, true, 20], - [true, false, 20], - [true, true, 20], - [false, false, 1000000], - [false, true, 1000000], - [true, false, 1000000], - [true, true, 1000000], + [false, 20], + [true, 20], + [false, 1000000], + [true, 1000000], ]; } @@ -108,11 +93,10 @@ public function data90to91() { * @dataProvider data90to91 * * @param bool $isMysql - * @param bool $isCliMode * @param int $fileCount */ - public function test90to91($isMysql, $isCliMode, $fileCount) { - $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $isCliMode, $fileCount); + public function test90to91($isMysql, $fileCount) { + $releaseNotesMock = $this->getReleaseNotesMock($isMysql, $fileCount); $actual = $releaseNotesMock->getReleaseNotes('9.0.1', '9.1.0'); $this->assertCount(0, $actual); } From 54fc92c37233d248de8da842352c43dffdfc5f8d Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Wed, 6 Apr 2016 17:30:21 -0400 Subject: [PATCH 195/286] 9.0.1 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index c1c70844af10d..136a9b2a10b05 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 1, 2); +$OC_Version = array(9, 0, 1, 3); // The human readable string -$OC_VersionString = '9.0.1 RC2'; +$OC_VersionString = '9.0.1'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 35d044c121fda51ca34d76e5faf73b21fbed8b7a Mon Sep 17 00:00:00 2001 From: Erik Pellikka Date: Wed, 23 Mar 2016 07:31:58 -0400 Subject: [PATCH 196/286] sidebar click modification --- apps/files/css/files.css | 20 +++++++++++++++++--- apps/files/js/filelist.js | 3 ++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index bfa5340fe0992..d20ab102ba57c 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -468,6 +468,7 @@ html.ie8 #fileList tr.selected td.filename>.selectCheckBox { position: relative; width: 100%; padding-left: 0; + padding-right:0; -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; } @@ -572,13 +573,26 @@ html.ie8 .column-mtime .selectedActions { opacity: 0; display:none; } -#fileList a.action.action-share, -#fileList a.action.action-menu { +#fileList a.action.action-share { padding: 17px 14px; } +#fileList a.action.action-menu { + padding-top: 17px; + padding-bottom: 17px; + padding-left:14px; + padding-right:0px; +} + +#fileList .filesize { + padding-top:0px; + padding-bottom:0px; + padding-left:60px; + padding-right:15px; +} + #fileList .popovermenu { - margin-right: 21px; + margin-right: -5px; } .ie8 #fileList .popovermenu { margin-top: -10px; diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index fcdf6caaa5975..47aff25678610 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -271,7 +271,8 @@ this.updateSearch(); - this.$fileList.on('click','td.filename>a.name', _.bind(this._onClickFile, this)); + this.$fileList.on('click','td.filename>a.name, td.filesize, td.date', _.bind(this._onClickFile, this)); + this.$fileList.on('change', 'td.filename>.selectCheckBox', _.bind(this._onClickFileCheckbox, this)); this.$el.on('urlChanged', _.bind(this._onUrlChanged, this)); this.$el.find('.select-all').click(_.bind(this._onClickSelectAll, this)); From 8b87837a4db052e8ccf6b89a5096f95c00889271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 5 Apr 2016 10:26:04 +0200 Subject: [PATCH 197/286] Prevent null to be passed into the closure of callForAllUsers --- lib/private/user/manager.php | 18 +++++++++++------- lib/public/iusermanager.php | 6 +++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index e2486a9ff1d11..7967f87702479 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -33,6 +33,7 @@ namespace OC\User; use OC\Hooks\PublicEmitter; +use OCP\IUserBackend; use OCP\IUserManager; use OCP\IConfig; @@ -170,24 +171,24 @@ public function userExists($uid) { /** * Check if the password is valid for the user * - * @param string $loginname + * @param string $loginName * @param string $password * @return mixed the User object on success, false otherwise */ - public function checkPassword($loginname, $password) { - $loginname = str_replace("\0", '', $loginname); + public function checkPassword($loginName, $password) { + $loginName = str_replace("\0", '', $loginName); $password = str_replace("\0", '', $password); foreach ($this->backends as $backend) { if ($backend->implementsActions(\OC_User_Backend::CHECK_PASSWORD)) { - $uid = $backend->checkPassword($loginname, $password); + $uid = $backend->checkPassword($loginName, $password); if ($uid !== false) { return $this->getUserObject($uid, $backend); } } } - \OC::$server->getLogger()->warning('Login failed: \''. $loginname .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']); + \OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']); return false; } @@ -304,7 +305,7 @@ public function countUsers() { if ($backend->implementsActions(\OC_User_Backend::COUNT_USERS)) { $backendUsers = $backend->countUsers(); if($backendUsers !== false) { - if($backend instanceof \OCP\IUserBackend) { + if($backend instanceof IUserBackend) { $name = $backend->getBackendName(); } else { $name = get_class($backend); @@ -325,7 +326,7 @@ public function countUsers() { * If the callback returns false no further users will be retrieved. * * @param \Closure $callback - * @return void + * @param string $search * @since 9.0.0 */ public function callForAllUsers(\Closure $callback, $search = '') { @@ -336,6 +337,9 @@ public function callForAllUsers(\Closure $callback, $search = '') { $users = $backend->getUsers($search, $limit, $offset); foreach ($users as $user) { $user = $this->get($user); + if (is_null($user)) { + continue; + } $return = $callback($user); if ($return === false) { break; diff --git a/lib/public/iusermanager.php b/lib/public/iusermanager.php index 057bd8e89fb75..6442938a99bc4 100644 --- a/lib/public/iusermanager.php +++ b/lib/public/iusermanager.php @@ -90,12 +90,12 @@ public function userExists($uid); /** * Check if the password is valid for the user * - * @param string $loginname + * @param string $loginName * @param string $password * @return mixed the User object on success, false otherwise * @since 8.0.0 */ - public function checkPassword($loginname, $password); + public function checkPassword($loginName, $password); /** * search by user id @@ -138,7 +138,7 @@ public function countUsers(); /** * @param \Closure $callback - * @return void + * @param string $search * @since 9.0.0 */ public function callForAllUsers (\Closure $callback, $search = ''); From d2c11a35b7d45bde9f661eb4155109a375642a1a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 8 Apr 2016 14:50:42 +0200 Subject: [PATCH 198/286] Correctly return an empty string for empty files --- lib/private/files/storage/local.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index b6d0ec3fb3474..b0918c82f987b 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -177,9 +177,15 @@ public function touch($path, $mtime = null) { public function file_get_contents($path) { // file_get_contents() has a memory leak: https://bugs.php.net/bug.php?id=61961 - $filename = $this->getSourcePath($path); - $handle = fopen($filename,'rb'); - $content = fread($handle, filesize($filename)); + $fileName = $this->getSourcePath($path); + + $fileSize = filesize($fileName); + if ($fileSize === 0) { + return ''; + } + + $handle = fopen($fileName,'rb'); + $content = fread($handle, $fileSize); fclose($handle); return $content; } From 1d4d45e91fd1d6e5c4fc5078838da8224d0fbcaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sun, 10 Apr 2016 12:43:15 +0200 Subject: [PATCH 199/286] Adding VCFExportPlugin --- apps/dav/lib/server.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php index 88096e222ecc8..4711a80800dd8 100644 --- a/apps/dav/lib/server.php +++ b/apps/dav/lib/server.php @@ -33,6 +33,7 @@ use OCA\DAV\Files\CustomPropertiesBackend; use OCP\IRequest; use OCP\SabrePluginEvent; +use Sabre\CardDAV\VCFExportPlugin; use Sabre\DAV\Auth\Plugin; class Server { @@ -90,6 +91,7 @@ public function __construct(IRequest $request, $baseUri) { // addressbook plugins $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); + $this->server->addPlugin(new VCFExportPlugin()); // system tags plugins $this->server->addPlugin(new \OCA\DAV\SystemTag\SystemTagPlugin( From 3587531331284e338913f1a19443f890d99a0e07 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 7 Apr 2016 15:05:21 +0200 Subject: [PATCH 200/286] Update sabre/dav to 3.0.9 onb stable9 --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index afb726b309490..1c47b6e6801fb 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit afb726b309490ce9df1bd521217da9bbf606593b +Subproject commit 1c47b6e6801fbff204ba97841be14e0d4178ef91 From 5408b16728ca42525ae59f15e589e72ab7123df9 Mon Sep 17 00:00:00 2001 From: Joshua Ruehlig Date: Mon, 11 Apr 2016 09:40:41 -0700 Subject: [PATCH 201/286] Backport #23752 to stable9 Fixes orientation of thumbnails and gallery view of JPG's with exif rotation. --- lib/private/preview/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/preview/image.php b/lib/private/preview/image.php index b377f0e855da6..3ea99d6963a7f 100644 --- a/lib/private/preview/image.php +++ b/lib/private/preview/image.php @@ -53,10 +53,10 @@ public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) { $fileName = $fileview->getLocalFile($path); } $image->loadFromFile($fileName); + $image->fixOrientation(); if ($useTempFile) { unlink($fileName); } - $image->fixOrientation(); if ($image->valid()) { $image->scaleDownToFit($maxX, $maxY); From aecfcf64c476151e290df28ded732bf72f7b7131 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 11 Apr 2016 09:52:25 +0200 Subject: [PATCH 202/286] Catch the AutoloadNotAllowedException also for legacy jobs * same as #18839 for legacy jobs * avoids spamming the log with useless entries --- lib/private/backgroundjob/legacy/regularjob.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/private/backgroundjob/legacy/regularjob.php b/lib/private/backgroundjob/legacy/regularjob.php index 8e8b6634c11a8..aedd6ef657ad4 100644 --- a/lib/private/backgroundjob/legacy/regularjob.php +++ b/lib/private/backgroundjob/legacy/regularjob.php @@ -22,10 +22,17 @@ namespace OC\BackgroundJob\Legacy; +use OCP\AutoloadNotAllowedException; + class RegularJob extends \OC\BackgroundJob\Job { public function run($argument) { - if (is_callable($argument)) { - call_user_func($argument); + try { + if (is_callable($argument)) { + call_user_func($argument); + } + } catch (AutoloadNotAllowedException $e) { + // job is from a disabled app, ignore + return null; } } } From 6e8adea2ab7f3b0fc89cc5ecaa88fd3afcb3cb32 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 12 Apr 2016 12:07:27 +0200 Subject: [PATCH 203/286] Exclude autoload_static.php (#23935) Composer 1.1 has since yesterday a new performance improvement that will be automatically used for PHP >= 5.6, however this file is incompatible with older PHP versions and thus we need to exclude it from the checks. Note that this performance improvement is only used on >= 5.6 so ownCloud will still run fine on older PHP versions as well. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 37af4ab02e32e..0643e20750a03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ install: script: - - sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ .; fi" + - sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ --exclude lib/composer/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .; fi" - sh -c "if [ '$TEST_DAV' != '1' ]; then echo \"Not testing DAV\"; fi" - sh -c "if [ '$TEST_DAV' = '1' ]; then echo \"Testing DAV\"; fi" From 57c08cfd772ed71e7a24ce6ebbbda34c6e84f69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 12 Apr 2016 16:26:25 +0200 Subject: [PATCH 204/286] Fix the exclude path --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0643e20750a03..eafa7ed839338 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ install: script: - - sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ --exclude lib/composer/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .; fi" + - sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/symfony/polyfill-php70/Resources/stubs/ --exclude 3rdparty/patchwork/utf8/src/Patchwork/Utf8/Bootup/ --exclude 3rdparty/paragonie/random_compat/lib/ --exclude vendor/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .; fi" - sh -c "if [ '$TEST_DAV' != '1' ]; then echo \"Not testing DAV\"; fi" - sh -c "if [ '$TEST_DAV' = '1' ]; then echo \"Testing DAV\"; fi" From 288b4e21d087ed5d85b0b41b9b19bbd3fd10215e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Tue, 19 Apr 2016 16:59:08 +0200 Subject: [PATCH 205/286] we need to initialize the mount points of the given user before we recover access to his files --- apps/encryption/hooks/userhooks.php | 11 +++++ apps/encryption/tests/hooks/UserHooksTest.php | 47 +++++++++++++++---- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/apps/encryption/hooks/userhooks.php b/apps/encryption/hooks/userhooks.php index 62acd1689094b..bde4d5869b49a 100644 --- a/apps/encryption/hooks/userhooks.php +++ b/apps/encryption/hooks/userhooks.php @@ -24,6 +24,7 @@ namespace OCA\Encryption\Hooks; +use OC\Files\Filesystem; use OCP\IUserManager; use OCP\Util as OCUtil; use OCA\Encryption\Hooks\Contracts\IHook; @@ -243,6 +244,7 @@ public function setPassphrase($params) { // used to decrypt it has changed } else { // admin changed the password for a different user, create new keys and re-encrypt file keys $user = $params['uid']; + $this->initMountPoints($user); $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null; // we generate new keys if... @@ -281,6 +283,15 @@ public function setPassphrase($params) { } } + /** + * init mount points for given user + * + * @param string $user + * @throws \OC\User\NoUserException + */ + protected function initMountPoints($user) { + Filesystem::initMountPoints($user); + } /** diff --git a/apps/encryption/tests/hooks/UserHooksTest.php b/apps/encryption/tests/hooks/UserHooksTest.php index 08d1981266c5a..d2a7d4f2d04c5 100644 --- a/apps/encryption/tests/hooks/UserHooksTest.php +++ b/apps/encryption/tests/hooks/UserHooksTest.php @@ -29,6 +29,12 @@ use OCA\Encryption\Hooks\UserHooks; use Test\TestCase; +/** + * Class UserHooksTest + * + * @group DB + * @package OCA\Encryption\Tests\Hooks + */ class UserHooksTest extends TestCase { /** * @var \PHPUnit_Framework_MockObject_MockObject @@ -190,6 +196,23 @@ public function testSetPassphrase() { ->willReturnOnConsecutiveCalls(true, false); + $this->instance = $this->getMockBuilder('OCA\Encryption\Hooks\UserHooks') + ->setConstructorArgs( + [ + $this->keyManagerMock, + $this->userManagerMock, + $this->loggerMock, + $this->userSetupMock, + $this->userSessionMock, + $this->utilMock, + $this->sessionMock, + $this->cryptMock, + $this->recoveryMock + ] + )->setMethods(['initMountPoints'])->getMock(); + + $this->instance->expects($this->exactly(3))->method('initMountPoints'); + // Test first if statement $this->assertNull($this->instance->setPassphrase($this->params)); @@ -236,16 +259,20 @@ public function testSetPasswordNoUser() { ->with('testUser') ->willReturn(false); - $userHooks = new UserHooks($this->keyManagerMock, - $this->userManagerMock, - $this->loggerMock, - $this->userSetupMock, - $userSessionMock, - $this->utilMock, - $this->sessionMock, - $this->cryptMock, - $this->recoveryMock - ); + $userHooks = $this->getMockBuilder('OCA\Encryption\Hooks\UserHooks') + ->setConstructorArgs( + [ + $this->keyManagerMock, + $this->userManagerMock, + $this->loggerMock, + $this->userSetupMock, + $userSessionMock, + $this->utilMock, + $this->sessionMock, + $this->cryptMock, + $this->recoveryMock + ] + )->setMethods(['initMountPoints'])->getMock(); $this->assertNull($userHooks->setPassphrase($this->params)); } From 21970c1b196b8d3195f63bccc8b16b5571f19952 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Apr 2016 10:36:15 +0200 Subject: [PATCH 206/286] Chunk the users correctly in the trashbin and versions background job --- .../lib/backgroundjob/expiretrash.php | 51 +++++-------------- .../tests/backgroundjob/expiretrash.php | 1 - .../lib/backgroundjob/expireversions.php | 28 +++++----- 3 files changed, 24 insertions(+), 56 deletions(-) diff --git a/apps/files_trashbin/lib/backgroundjob/expiretrash.php b/apps/files_trashbin/lib/backgroundjob/expiretrash.php index 4ee0658840bd8..8a4e2d41fec2e 100644 --- a/apps/files_trashbin/lib/backgroundjob/expiretrash.php +++ b/apps/files_trashbin/lib/backgroundjob/expiretrash.php @@ -23,6 +23,7 @@ namespace OCA\Files_Trashbin\BackgroundJob; use OCP\IConfig; +use OCP\IUser; use OCP\IUserManager; use OCA\Files_Trashbin\AppInfo\Application; use OCA\Files_Trashbin\Expiration; @@ -31,40 +32,28 @@ class ExpireTrash extends \OC\BackgroundJob\TimedJob { - const ITEMS_PER_SESSION = 1000; - /** * @var Expiration */ private $expiration; - - /** - * @var IConfig - */ - private $config; /** * @var IUserManager */ private $userManager; - - const USERS_PER_SESSION = 1000; /** - * @param IConfig|null $config * @param IUserManager|null $userManager * @param Expiration|null $expiration */ - public function __construct(IConfig $config = null, - IUserManager $userManager = null, + public function __construct(IUserManager $userManager = null, Expiration $expiration = null) { // Run once per 30 minutes $this->setInterval(60 * 30); - if (is_null($expiration) || is_null($userManager) || is_null($config)) { + if (is_null($expiration) || is_null($userManager)) { $this->fixDIForJobs(); } else { - $this->config = $config; $this->userManager = $userManager; $this->expiration = $expiration; } @@ -72,7 +61,6 @@ public function __construct(IConfig $config = null, protected function fixDIForJobs() { $application = new Application(); - $this->config = \OC::$server->getConfig(); $this->userManager = \OC::$server->getUserManager(); $this->expiration = $application->getContainer()->query('Expiration'); } @@ -86,26 +74,15 @@ protected function run($argument) { if (!$maxAge) { return; } - - $offset = $this->config->getAppValue('files_trashbin', 'cronjob_user_offset', 0); - $users = $this->userManager->search('', self::USERS_PER_SESSION, $offset); - if (!count($users)) { - // No users found, reset offset and retry - $offset = 0; - $users = $this->userManager->search('', self::USERS_PER_SESSION); - } - - $offset += self::USERS_PER_SESSION; - $this->config->setAppValue('files_trashbin', 'cronjob_user_offset', $offset); - - foreach ($users as $user) { + + $this->userManager->callForAllUsers(function(IUser $user) { $uid = $user->getUID(); if (!$this->setupFS($uid)) { - continue; + return; } $dirContent = Helper::getTrashFiles('/', $uid, 'mtime'); Trashbin::deleteExpiredFiles($dirContent, $uid); - } + }); \OC_Util::tearDownFS(); } @@ -115,20 +92,16 @@ protected function run($argument) { * @param string $user * @return boolean */ - private function setupFS($user){ - if (!$this->userManager->userExists($user)) { - return false; - } + protected function setupFS($user) { + \OC_Util::tearDownFS(); + \OC_Util::setupFS($user); - //Check if this user has a trashbin directory + // Check if this user has a trashbin directory $view = new \OC\Files\View('/' . $user); - if (!$view->is_dir('/files_trashbin/files')){ + if (!$view->is_dir('/files_trashbin/files')) { return false; } - \OC_Util::tearDownFS(); - \OC_Util::setupFS($user); - return true; } } diff --git a/apps/files_trashbin/tests/backgroundjob/expiretrash.php b/apps/files_trashbin/tests/backgroundjob/expiretrash.php index 79fc91884fc5f..c98a555c929bf 100644 --- a/apps/files_trashbin/tests/backgroundjob/expiretrash.php +++ b/apps/files_trashbin/tests/backgroundjob/expiretrash.php @@ -26,7 +26,6 @@ class ExpireTrash_Test extends \Test\TestCase { public function testConstructAndRun() { $backgroundJob = new ExpireTrash( - $this->getMock('OCP\IConfig'), $this->getMock('OCP\IUserManager'), $this->getMockBuilder('OCA\Files_Trashbin\Expiration')->disableOriginalConstructor()->getMock() ); diff --git a/apps/files_versions/lib/backgroundjob/expireversions.php b/apps/files_versions/lib/backgroundjob/expireversions.php index 5d8eef4e35119..8e14e65b9a7a0 100644 --- a/apps/files_versions/lib/backgroundjob/expireversions.php +++ b/apps/files_versions/lib/backgroundjob/expireversions.php @@ -21,6 +21,7 @@ namespace OCA\Files_Versions\BackgroundJob; +use OCP\IUser; use OCP\IUserManager; use OCA\Files_Versions\AppInfo\Application; use OCA\Files_Versions\Storage; @@ -64,20 +65,13 @@ protected function run($argument) { return; } - $users = $this->userManager->search(''); - $isFSready = false; - foreach ($users as $user) { + $this->userManager->callForAllUsers(function(IUser $user) { $uid = $user->getUID(); - if (!$isFSready) { - if (!$this->setupFS($uid)) { - continue; - } - $isFSready = true; + if (!$this->setupFS($uid)) { + return; } Storage::expireOlderThanMaxForUser($uid); - } - - \OC_Util::tearDownFS(); + }); } /** @@ -85,14 +79,16 @@ protected function run($argument) { * @param string $user * @return boolean */ - private function setupFS($user){ - if (!$this->userManager->userExists($user)) { - return false; - } - + protected function setupFS($user) { \OC_Util::tearDownFS(); \OC_Util::setupFS($user); + // Check if this user has a versions directory + $view = new \OC\Files\View('/' . $user); + if (!$view->is_dir('/files_versions')) { + return false; + } + return true; } } From 466b7dc05f191198ff57fd4f3c79758f1debd881 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 20 Apr 2016 08:21:21 +0200 Subject: [PATCH 207/286] Allow setting can edit permissions on federated shares in webUI Fixes #24032 Since we have a slightly different UI for the federated shares our normal logic fails us. This makes sure to add the correct permissions when it is a federated share. --- core/js/sharedialogshareelistview.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js index e4edbf24c0868..87badb6be0974 100644 --- a/core/js/sharedialogshareelistview.js +++ b/core/js/sharedialogshareelistview.js @@ -280,6 +280,17 @@ permissions |= $(checkbox).data('permissions'); }); + // The federated share UI is a bit different so handle it properly + if (shareType === OC.Share.SHARE_TYPE_REMOTE && + $element.attr('name') === 'edit' && + $element.is(':checked')) { + permissions |= OC.PERMISSION_UPDATE; + + if (this.model.deletePermissionPossible()) { + permissions |= OC.PERMISSION_CREATE; + } + } + this.model.updateShare(shareId, {permissions: permissions}); }, From ccddb18cab92883c38ba10e3e81e9e3e26203f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 20 Apr 2016 12:12:41 +0200 Subject: [PATCH 208/286] preserve information if it is a rename operation or not --- lib/private/files/storage/wrapper/encryption.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 8b9832d7e3618..430845471e2e4 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -627,9 +627,10 @@ public function moveFromStorage(Storage $sourceStorage, $sourceInternalPath, $ta * @param string $sourceInternalPath * @param string $targetInternalPath * @param bool $preserveMtime + * @param bool $isRename * @return bool */ - public function copyFromStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) { + public function copyFromStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false, $isRename = false) { // TODO clean this up once the underlying moveFromStorage in OC\Files\Storage\Wrapper\Common is fixed: // - call $this->storage->copyFromStorage() instead of $this->copyBetweenStorage @@ -637,7 +638,7 @@ public function copyFromStorage(Storage $sourceStorage, $sourceInternalPath, $ta // - copy the copyKeys() call from $this->copyBetweenStorage to this method // - remove $this->copyBetweenStorage - return $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, false); + return $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename); } /** @@ -732,7 +733,7 @@ private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, if (is_resource($dh)) { while ($result and ($file = readdir($dh)) !== false) { if (!Filesystem::isIgnoredDir($file)) { - $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file); + $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename); } } } From 2296552104a74d9f8841489d8d5e5dc691bb2a4d Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 19 Apr 2016 17:01:34 +0200 Subject: [PATCH 209/286] When the scanner detects a file is changed clear checksum Fixes #23782 and #23783 If the file scanner detects a changed file we clear the checksum while we update the cache. * Unit test added --- lib/private/files/cache/scanner.php | 2 ++ tests/lib/files/view.php | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 0a207de7b6484..d0b515573d6a4 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -195,6 +195,8 @@ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = $fileId = -1; } if (!empty($newData)) { + // Reset the checksum if the data has changed + $newData['checksum'] = ''; $data['fileid'] = $this->addToCache($file, $newData, $fileId); } if (isset($cacheData['size'])) { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 3e88a5306f891..86413c61aa116 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -2424,4 +2424,24 @@ public function testGetDirectoryContentMimeFilter($filter, $expected) { $this->assertEquals($expected, $files); } + + public function testFilePutContentsClearsChecksum() { + $storage = new Temporary(array()); + $scanner = $storage->getScanner(); + $storage->file_put_contents('foo.txt', 'bar'); + \OC\Files\Filesystem::mount($storage, array(), '/test/'); + $scanner->scan(''); + + $view = new \OC\Files\View('/test/foo.txt'); + $view->putFileInfo('.', ['checksum' => '42']); + + $this->assertEquals('bar', $view->file_get_contents('')); + $fh = tmpfile(); + fwrite($fh, 'fooo'); + rewind($fh); + $view->file_put_contents('', $fh); + $this->assertEquals('fooo', $view->file_get_contents('')); + $data = $view->getFileInfo('.'); + $this->assertEquals('', $data->getChecksum()); + } } From df544e8dbeddb11225a5d55a04038e42cfa5eecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 14 Apr 2016 17:32:25 +0200 Subject: [PATCH 210/286] Introduce isReadyForUser and verify in file transfer ownership - fixes #23786 --- apps/encryption/lib/crypto/encryption.php | 13 +++++++++++++ apps/encryption/lib/keymanager.php | 1 + apps/files/command/transferownership.php | 6 ++++++ lib/private/encryption/manager.php | 19 +++++++++++++++++++ lib/public/encryption/iencryptionmodule.php | 12 ++++++++++++ .../lib/files/storage/wrapper/encryption.php | 9 +++++---- tests/lib/files/stream/encryption.php | 2 +- 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php index 907a6437f5b3f..6eff66e72beab 100644 --- a/apps/encryption/lib/crypto/encryption.php +++ b/apps/encryption/lib/crypto/encryption.php @@ -547,4 +547,17 @@ protected function stripPartFileExtension($path) { return $path; } + /** + * Check if the module is ready to be used by that specific user. + * In case a module is not ready - because e.g. key pairs have not been generated + * upon login this method can return false before any operation starts and might + * cause issues during operations. + * + * @param string $user + * @return boolean + * @since 9.1.0 + */ + public function isReadyForUser($user) { + return $this->keyManager->userHasKeys($user); + } } diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index 12fa5f92bd5e9..0accfb7900ac5 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -493,6 +493,7 @@ public function getShareKey($path, $uid) { */ public function userHasKeys($userId) { $privateKey = $publicKey = true; + $exception = null; try { $this->getPrivateKey($userId); diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php index 6bf2fae6bdfc8..1f46efdde0d82 100644 --- a/apps/files/command/transferownership.php +++ b/apps/files/command/transferownership.php @@ -97,6 +97,12 @@ protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln("Unknown destination user $this->destinationUser"); return; } + + // target user has to be ready + if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) { + $output->writeln("The target user is not ready to accept files. The user has at least to be logged in once."); + return; + } $date = date('c'); $this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date"; diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index d45bbf07ee966..8714d1618074c 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -117,6 +117,25 @@ public function isReady() { } /** + * @param string $user + */ + public function isReadyForUser($user) { + if (!$this->isReady()) { + return false; + } + + foreach ($this->getEncryptionModules() as $module) { + /** @var IEncryptionModule $m */ + $m = call_user_func($module['callback']); + if (!$m->isReadyForUser($user)) { + return false; + } + } + + return true; + } + + /** * Registers an callback function which must return an encryption module instance * * @param string $id diff --git a/lib/public/encryption/iencryptionmodule.php b/lib/public/encryption/iencryptionmodule.php index df30dd57cee77..8d20a1ab57d1f 100644 --- a/lib/public/encryption/iencryptionmodule.php +++ b/lib/public/encryption/iencryptionmodule.php @@ -168,4 +168,16 @@ public function encryptAll(InputInterface $input, OutputInterface $output); */ public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = ''); + /** + * Check if the module is ready to be used by that specific user. + * In case a module is not ready - because e.g. key pairs have not been generated + * upon login this method can return false before any operation starts and might + * cause issues during operations. + * + * @param string $user + * @return boolean + * @since 9.1.0 + */ + public function isReadyForUser($user); + } diff --git a/tests/lib/files/storage/wrapper/encryption.php b/tests/lib/files/storage/wrapper/encryption.php index 651299a3eaba3..21f7d9f09b92d 100644 --- a/tests/lib/files/storage/wrapper/encryption.php +++ b/tests/lib/files/storage/wrapper/encryption.php @@ -5,6 +5,7 @@ use OC\Encryption\Util; use OC\Files\Storage\Temporary; use OC\Files\View; +use OC\User\Manager; use Test\Files\Storage\Storage; class Encryption extends Storage { @@ -118,7 +119,7 @@ protected function setUp() { $this->util = $this->getMock( '\OC\Encryption\Util', ['getUidAndFilename', 'isFile', 'isExcluded'], - [new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]); + [new View(), new Manager(), $this->groupManager, $this->config, $this->arrayCache]); $this->util->expects($this->any()) ->method('getUidAndFilename') ->willReturnCallback(function ($path) { @@ -200,7 +201,7 @@ protected function setUp() { protected function buildMockModule() { $this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') ->disableOriginalConstructor() - ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll']) + ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll', 'isReadyForUser']) ->getMock(); $this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); @@ -543,7 +544,7 @@ public function testGetHeader($path, $strippedPathExists, $strippedPath) { ->setConstructorArgs( [ new View(), - new \OC\User\Manager(), + new Manager(), $this->groupManager, $this->config, $this->arrayCache @@ -608,7 +609,7 @@ public function testGetHeaderAddLegacyModule($header, $isEncrypted, $expected) { ->disableOriginalConstructor()->getMock(); $util = $this->getMockBuilder('\OC\Encryption\Util') - ->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]) + ->setConstructorArgs([new View(), new Manager(), $this->groupManager, $this->config, $this->arrayCache]) ->getMock(); $cache = $this->getMockBuilder('\OC\Files\Cache\Cache') diff --git a/tests/lib/files/stream/encryption.php b/tests/lib/files/stream/encryption.php index afb31f2822d07..20a4100d2ff21 100644 --- a/tests/lib/files/stream/encryption.php +++ b/tests/lib/files/stream/encryption.php @@ -311,7 +311,7 @@ public function testWriteToNonSeekableStorage($testFile) { protected function buildMockModule() { $encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule') ->disableOriginalConstructor() - ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll']) + ->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll', 'isReadyForUser']) ->getMock(); $encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE'); From 2d373416d8e54a7de84879a365c372a85104c6df Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 20 Apr 2016 16:41:11 +0200 Subject: [PATCH 211/286] Add repair step for updater issues The updater as shipped with ownCloud =< 9.0.1 has several bugs leading to a not properly executed update. For example the third-party changes are not copied. This pull request: 1. Ships the third-party files changed since ownCloud 9.0.1 in the resources folder. On update the files are replaced. (https://github.com/owncloud/updater/issues/316) 2. Adds updater/* and _oc_upgrade/* as an exemption to the code integrity checker since the updater is updating in the wrong order. (https://github.com/owncloud/updater/issues/318) --- lib/private/integritycheck/checker.php | 13 + .../excludefoldersbypathfilteriterator.php | 5 + lib/private/repair.php | 2 + lib/private/repair/brokenupdaterrepair.php | 109 + resources/updater-fixes/composer.json | 44 + resources/updater-fixes/composer.lock | 3156 ++++++++++++++++ resources/updater-fixes/composer/LICENSE | 21 + .../composer/autoload_classmap.php | 1643 +++++++++ .../updater-fixes/composer/installed.json | 3247 +++++++++++++++++ .../icewind/streams/src/DirectoryFilter.php | 60 + .../icewind/streams/src/DirectoryWrapper.php | 88 + .../icewind/streams/src/RetryWrapper.php | 66 + .../icewind/streams/src/SeekableWrapper.php | 92 + .../updater-fixes/sabre/dav/CHANGELOG.md | 2138 +++++++++++ .../updater-fixes/sabre/dav/composer.json | 66 + .../sabre/dav/lib/CalDAV/Plugin.php | 992 +++++ .../sabre/dav/lib/CardDAV/Backend/PDO.php | 545 +++ .../sabre/dav/lib/DAV/CorePlugin.php | 927 +++++ .../sabre/dav/lib/DAV/Version.php | 19 + 19 files changed, 13233 insertions(+) create mode 100644 lib/private/repair/brokenupdaterrepair.php create mode 100644 resources/updater-fixes/composer.json create mode 100644 resources/updater-fixes/composer.lock create mode 100644 resources/updater-fixes/composer/LICENSE create mode 100644 resources/updater-fixes/composer/autoload_classmap.php create mode 100644 resources/updater-fixes/composer/installed.json create mode 100644 resources/updater-fixes/icewind/streams/src/DirectoryFilter.php create mode 100644 resources/updater-fixes/icewind/streams/src/DirectoryWrapper.php create mode 100644 resources/updater-fixes/icewind/streams/src/RetryWrapper.php create mode 100644 resources/updater-fixes/icewind/streams/src/SeekableWrapper.php create mode 100644 resources/updater-fixes/sabre/dav/CHANGELOG.md create mode 100644 resources/updater-fixes/sabre/dav/composer.json create mode 100644 resources/updater-fixes/sabre/dav/lib/CalDAV/Plugin.php create mode 100644 resources/updater-fixes/sabre/dav/lib/CardDAV/Backend/PDO.php create mode 100644 resources/updater-fixes/sabre/dav/lib/DAV/CorePlugin.php create mode 100644 resources/updater-fixes/sabre/dav/lib/DAV/Version.php diff --git a/lib/private/integritycheck/checker.php b/lib/private/integritycheck/checker.php index d7867936887a3..b991f66e22ebf 100644 --- a/lib/private/integritycheck/checker.php +++ b/lib/private/integritycheck/checker.php @@ -342,6 +342,19 @@ private function verify($signaturePath, $basePath, $certificateCN) { throw new InvalidSignatureException('Signature could not get verified.'); } + // Fixes for the updater as shipped with ownCloud 9.0.x: The updater is + // replaced after the code integrity check is performed. + // + // Due to this reason we exclude the whole updater/ folder from the code + // integrity check. + if($basePath === $this->environmentHelper->getServerRoot()) { + foreach($expectedHashes as $fileName => $hash) { + if(strpos($fileName, 'updater/') === 0) { + unset($expectedHashes[$fileName]); + } + } + } + // Compare the list of files which are not identical $currentInstanceHashes = $this->generateHashes($this->getFolderIterator($basePath), $basePath); $differencesA = array_diff($expectedHashes, $currentInstanceHashes); diff --git a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php index 1082e97c296a7..e4b9c0f1998e6 100644 --- a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php +++ b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php @@ -39,6 +39,11 @@ public function __construct(\RecursiveIterator $iterator, $root = '') { rtrim($root . '/apps', '/'), rtrim($root . '/assets', '/'), rtrim($root . '/lost+found', '/'), + // Ignore folders generated by updater since the updater is replaced + // after the integrity check is run. + // See https://github.com/owncloud/updater/issues/318#issuecomment-212497846 + rtrim($root . '/updater', '/'), + rtrim($root . '/_oc_upgrade', '/'), ]; $customDataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', ''); if($customDataDir !== '') { diff --git a/lib/private/repair.php b/lib/private/repair.php index d40c6464e1469..63b569b2ed3e2 100644 --- a/lib/private/repair.php +++ b/lib/private/repair.php @@ -31,6 +31,7 @@ use OC\Hooks\BasicEmitter; use OC\Hooks\Emitter; use OC\Repair\AssetCache; +use OC\Repair\BrokenUpdaterRepair; use OC\Repair\CleanTags; use OC\Repair\Collation; use OC\Repair\DropOldJobs; @@ -114,6 +115,7 @@ public static function getRepairSteps() { new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()), new UpdateOutdatedOcsIds(\OC::$server->getConfig()), new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), + new BrokenUpdaterRepair(), ]; } diff --git a/lib/private/repair/brokenupdaterrepair.php b/lib/private/repair/brokenupdaterrepair.php new file mode 100644 index 0000000000000..06dd322198f20 --- /dev/null +++ b/lib/private/repair/brokenupdaterrepair.php @@ -0,0 +1,109 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Repair; + +use OC\Hooks\BasicEmitter; + +/** + * Class BrokenUpdaterRepair fixes some issues caused by bugs in the ownCloud + * updater below version 9.0.2. + * + * FIXME: This file should be removed after the 9.0.2 release. The update server + * is instructed to deliver 9.0.2 for 9.0.0 and 9.0.1. + * + * @package OC\Repair + */ +class BrokenUpdaterRepair extends BasicEmitter implements \OC\RepairStep { + + public function getName() { + return 'Manually copies the third-party folder changes since 9.0.0 due ' . + 'to a bug in the updater.'; + } + + /** + * Manually copy the third-party files that have changed since 9.0.0 because + * the old updater does not copy over third-party changes. + * + * @return bool True if action performed, false otherwise + */ + private function manuallyCopyThirdPartyFiles() { + $resourceDir = __DIR__ . '/../../../resources/updater-fixes/'; + $thirdPartyDir = __DIR__ . '/../../../3rdparty/'; + + $filesToCopy = [ + // Composer updates + 'composer.json', + 'composer.lock', + 'composer/autoload_classmap.php', + 'composer/installed.json', + 'composer/LICENSE', + // Icewind stream library + 'icewind/streams/src/DirectoryFilter.php', + 'icewind/streams/src/DirectoryWrapper.php', + 'icewind/streams/src/RetryWrapper.php', + 'icewind/streams/src/SeekableWrapper.php', + // Sabre update + 'sabre/dav/CHANGELOG.md', + 'sabre/dav/composer.json', + 'sabre/dav/lib/CalDAV/Plugin.php', + 'sabre/dav/lib/CardDAV/Backend/PDO.php', + 'sabre/dav/lib/DAV/CorePlugin.php', + 'sabre/dav/lib/DAV/Version.php', + ]; + + // First check whether the files have been copied the first time already + // if so there is no need to run the move routine. + if(file_exists($thirdPartyDir . '/icewind/streams/src/RetryWrapper.php')) { + $this->emit('\OC\Repair', 'info', ['Third-party files seem already to have been copied. No repair necessary.']); + return false; + } + + foreach($filesToCopy as $file) { + $state = copy($resourceDir . '/' . $file, $thirdPartyDir . '/' . $file); + if($state === true) { + $this->emit('\OC\Repair', 'info', ['Successfully replaced '.$file.' with new version.']); + } else { + $this->emit('\OC\Repair', 'warning', ['Could not replace '.$file.' with new version.']); + } + } + return true; + } + + /** + * Rerun the integrity check after the update since the repair step has + * repaired some invalid copied files. + */ + private function recheckIntegrity() { + \OC::$server->getIntegrityCodeChecker()->runInstanceVerification(); + } + + public function run() { + if($this->manuallyCopyThirdPartyFiles()) { + $this->emit('\OC\Repair', 'info', ['Start integrity recheck.']); + $this->recheckIntegrity(); + $this->emit('\OC\Repair', 'info', ['Finished integrity recheck.']); + } else { + $this->emit('\OC\Repair', 'info', ['Rechecking code integrity not necessary.']); + } + } +} + diff --git a/resources/updater-fixes/composer.json b/resources/updater-fixes/composer.json new file mode 100644 index 0000000000000..fbc5e49fa4bfc --- /dev/null +++ b/resources/updater-fixes/composer.json @@ -0,0 +1,44 @@ +{ + "name": "owncloud/3rdparty", + "description": "All 3rdparty components", + "license": "MIT", + "config": { + "vendor-dir": ".", + "optimize-autoloader": true, + "classmap-authoritative": true + }, + "require": { + "doctrine/dbal": "2.5.2", + "mcnetic/zipstreamer": "^1.0", + "phpseclib/phpseclib": "2.0.0", + "rackspace/php-opencloud": "v1.9.2", + "james-heinrich/getid3": "dev-master", + "jeremeamia/superclosure": "2.1.0", + "ircmaxell/random-lib": "~1.1", + "bantu/ini-get-wrapper": "v1.0.1", + "natxet/CssMin": "dev-master", + "punic/punic": "1.6.3", + "pear/archive_tar": "1.4.1", + "patchwork/utf8": "1.2.6", + "symfony/console": "2.8.1", + "symfony/event-dispatcher": "2.8.1", + "symfony/routing": "2.8.1", + "symfony/process": "2.8.1", + "pimple/pimple": "3.0.2", + "ircmaxell/password-compat": "1.0.*", + "nikic/php-parser": "1.4.1", + "icewind/Streams": "0.4.0", + "swiftmailer/swiftmailer": "@stable", + "guzzlehttp/guzzle": "5.3.0", + "league/flysystem": "1.0.16", + "pear/pear-core-minimal": "v1.10.1", + "interfasys/lognormalizer": "^v1.0", + "deepdiver1975/TarStreamer": "v0.1.0", + "patchwork/jsqueeze": "^2.0", + "kriswallsmith/assetic": "1.3.2", + "sabre/dav": "3.0.9", + "symfony/polyfill-php70": "^1.0", + "symfony/polyfill-php55": "^1.0", + "symfony/polyfill-php56": "^1.0" + } +} diff --git a/resources/updater-fixes/composer.lock b/resources/updater-fixes/composer.lock new file mode 100644 index 0000000000000..6f9599798cd3d --- /dev/null +++ b/resources/updater-fixes/composer.lock @@ -0,0 +1,3156 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "e45bd9ffd35e8aa646134870a48bc4c0", + "content-hash": "c8078550a50c307c7e598d03fb0fe60b", + "packages": [ + { + "name": "bantu/ini-get-wrapper", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/bantuXorg/php-ini-get-wrapper.git", + "reference": "4770c7feab370c62e23db4f31c112b7c6d90aee2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bantuXorg/php-ini-get-wrapper/zipball/4770c7feab370c62e23db4f31c112b7c6d90aee2", + "reference": "4770c7feab370c62e23db4f31c112b7c6d90aee2", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "bantu\\IniGetWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Convenience wrapper around ini_get()", + "time": "2014-09-15 13:12:35" + }, + { + "name": "deepdiver1975/tarstreamer", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/owncloud/TarStreamer.git", + "reference": "859a0170de120c66b042e6c0dbc1a9979c74669b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/owncloud/TarStreamer/zipball/859a0170de120c66b042e6c0dbc1a9979c74669b", + "reference": "859a0170de120c66b042e6c0dbc1a9979c74669b", + "shasum": "" + }, + "require": { + "php": ">=5.3.8" + }, + "require-dev": { + "pear/archive_tar": "~1.4", + "pear/pear-core-minimal": "v1.10.0alpha2", + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "ownCloud\\TarStreamer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A library for dynamically streaming dynamic tar files without the need to have the complete file stored on the server.", + "homepage": "https://github.com/owncloud/TarStreamer", + "keywords": [ + "archive", + "php", + "stream", + "tar" + ], + "time": "2016-02-15 10:52:44" + }, + { + "name": "doctrine/annotations", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Annotations\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2015-08-31 12:32:49" + }, + { + "name": "doctrine/cache", + "version": "v1.5.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af", + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2015-12-03 10:50:37" + }, + { + "name": "doctrine/collections", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2015-04-14 22:21:58" + }, + { + "name": "doctrine/common", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2015-12-04 12:49:42" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.6-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2015-09-16 16:29:33" + }, + { + "name": "doctrine/inflector", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2015-11-06 14:35:42" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, + { + "name": "guzzle/common", + "version": "v3.8.1", + "target-dir": "Guzzle/Common", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/common.git", + "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/common/zipball/67f6c3fd04bae387d47c2a673fa623ed8f4189bb", + "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Common": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "collection", + "common", + "event", + "exception" + ], + "time": "2014-01-28 22:29:15" + }, + { + "name": "guzzle/http", + "version": "v3.8.1", + "target-dir": "Guzzle/Http", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/http.git", + "reference": "565fd64be16d91c840f497c5de76f86d54a822d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/http/zipball/565fd64be16d91c840f497c5de76f86d54a822d8", + "reference": "565fd64be16d91c840f497c5de76f86d54a822d8", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "ext-curl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Http": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "client", + "curl", + "http", + "http client" + ], + "time": "2014-01-23 18:23:29" + }, + { + "name": "guzzle/parser", + "version": "v3.8.1", + "target-dir": "Guzzle/Parser", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/parser.git", + "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/parser/zipball/3f52387052f2e4ef083145a0f73c3654aa14e086", + "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Parser": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "URI Template", + "cookie", + "http", + "message", + "url" + ], + "time": "2013-10-24 00:04:09" + }, + { + "name": "guzzle/stream", + "version": "v3.8.1", + "target-dir": "Guzzle/Stream", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/stream.git", + "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/stream/zipball/fa8af730ca714861c0001cfba64aaecc5f21bb96", + "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "guzzle/http": "To convert Guzzle request objects to PHP streams" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle\\Stream": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "component", + "stream" + ], + "time": "2014-01-28 22:14:17" + }, + { + "name": "guzzlehttp/guzzle", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-05-20 03:47:55" + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "time": "2015-05-20 03:37:09" + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "time": "2014-10-12 19:18:40" + }, + { + "name": "icewind/streams", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/icewind1991/Streams.git", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icewind1991/Streams/zipball/9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "v1.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Icewind\\Streams\\Tests\\": "tests/", + "Icewind\\Streams\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Appelman", + "email": "icewind@owncloud.com" + } + ], + "description": "A set of generic stream wrappers", + "time": "2016-03-17 12:32:25" + }, + { + "name": "interfasys/lognormalizer", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/interfasys/lognormalizer.git", + "reference": "d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/interfasys/lognormalizer/zipball/d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116", + "reference": "d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "codacy/coverage": "dev-master", + "codeclimate/php-test-reporter": "dev-master", + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "InterfaSys\\LogNormalizer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0" + ], + "authors": [ + { + "name": "Olivier Paroz", + "email": "dev-lognormalizer@interfasys.ch", + "homepage": "http://www.interfasys.ch", + "role": "Developer" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "role": "Developer" + } + ], + "description": "Parses variables and converts them to string so that they can be logged", + "homepage": "https://github.com/interfasys/lognormalizer", + "keywords": [ + "log", + "normalizer" + ], + "time": "2015-08-01 16:27:37" + }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20 16:49:30" + }, + { + "name": "ircmaxell/random-lib", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/RandomLib.git", + "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/RandomLib/zipball/13efa4368bb2ac88bb3b1459b487d907de4dbf7c", + "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c", + "shasum": "" + }, + "require": { + "ircmaxell/security-lib": "1.0.*@dev", + "php": ">=5.3.2" + }, + "require-dev": { + "mikey179/vfsstream": "1.1.*", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "RandomLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Library For Generating Secure Random Numbers", + "homepage": "https://github.com/ircmaxell/RandomLib", + "keywords": [ + "cryptography", + "random", + "random-numbers", + "random-strings" + ], + "time": "2015-01-15 16:31:45" + }, + { + "name": "ircmaxell/security-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/SecurityLib.git", + "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/SecurityLib/zipball/80934de3c482dcafb46b5756e59ebece082b6dc7", + "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "mikey179/vfsstream": "1.1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "SecurityLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Base Security Library", + "homepage": "https://github.com/ircmaxell/PHP-SecurityLib", + "time": "2013-04-30 18:00:34" + }, + { + "name": "james-heinrich/getid3", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/JamesHeinrich/getID3.git", + "reference": "afbdaa044a9a0a9dff2f800bd670e231b3ec99b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/995da7d5e8a7ac2b5ef076c64e9be66d380ede4f", + "reference": "afbdaa044a9a0a9dff2f800bd670e231b3ec99b2", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "getid3/getid3.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL" + ], + "description": "PHP script that extracts useful information from popular multimedia file formats", + "homepage": "http://www.getid3.org/", + "keywords": [ + "codecs", + "php", + "tags" + ], + "time": "2014-09-14 18:13:30" + }, + { + "name": "jeremeamia/SuperClosure", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/jeremeamia/super_closure.git", + "reference": "b712f39c671e5ead60c7ebfe662545456aade833" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/b712f39c671e5ead60c7ebfe662545456aade833", + "reference": "b712f39c671e5ead60c7ebfe662545456aade833", + "shasum": "" + }, + "require": { + "nikic/php-parser": "~1.0", + "php": ">=5.4" + }, + "require-dev": { + "codeclimate/php-test-reporter": "~0.1.2", + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "SuperClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia", + "role": "Developer" + } + ], + "description": "Serialize Closure objects, including their context and binding", + "homepage": "https://github.com/jeremeamia/super_closure", + "keywords": [ + "closure", + "function", + "lambda", + "parser", + "serializable", + "serialize", + "tokenizer" + ], + "time": "2015-03-11 20:06:43" + }, + { + "name": "kriswallsmith/assetic", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/kriswallsmith/assetic.git", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/9928f7c4ad98b234e3559d1049abd13387f86db5", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/process": "~2.1|~3.0" + }, + "conflict": { + "twig/twig": "<1.23" + }, + "require-dev": { + "cssmin/cssmin": "3.0.1", + "joliclic/javascript-packer": "1.1", + "kamicane/packager": "1.0", + "leafo/lessphp": "^0.3.7", + "leafo/scssphp": "~0.1", + "mrclay/minify": "~2.2", + "patchwork/jsqueeze": "~1.0|~2.0", + "phpunit/phpunit": "~4.8", + "psr/log": "~1.0", + "ptachoire/cssembed": "~1.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "twig/twig": "~1.8|~2.0" + }, + "suggest": { + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", + "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", + "twig/twig": "Assetic provides the integration with the Twig templating engine" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-0": { + "Assetic": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ], + "time": "2015-11-12 13:51:40" + }, + { + "name": "league/flysystem", + "version": "1.0.16", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/183e1a610664baf6dcd6fceda415baf43cbdc031", + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "ext-fileinfo": "*", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^2.2", + "phpspec/prophecy-phpunit": "~1.0", + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Allows you to use Dropbox storage", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2015-12-19 20:16:43" + }, + { + "name": "mcnetic/zipstreamer", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/McNetic/PHPZipStreamer.git", + "reference": "e57c198486242476587d04844084adbe8330581d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/McNetic/PHPZipStreamer/zipball/e57c198486242476587d04844084adbe8330581d", + "reference": "e57c198486242476587d04844084adbe8330581d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStreamer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0+" + ], + "authors": [ + { + "name": "Nicolai Ehemann", + "email": "en@enlightened.de", + "role": "Author/Maintainer" + }, + { + "name": "André Rothe", + "email": "arothe@zks.uni-leipzig.de", + "role": "Contributor" + }, + { + "name": "Lukas Reschke", + "email": "lukas@owncloud.com", + "role": "Contributor" + } + ], + "description": "Stream zip files without i/o overhead", + "homepage": "https://github.com/McNetic/PHPZipStreamer", + "keywords": [ + "stream", + "zip" + ], + "time": "2016-02-17 22:47:09" + }, + { + "name": "natxet/CssMin", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/natxet/CssMin.git", + "reference": "003920e783c568c2d8fdf03999eebefb8479092a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/natxet/CssMin/zipball/0b2170454eed9024c7e26b036fbccf2d7f6f2c53", + "reference": "003920e783c568c2d8fdf03999eebefb8479092a", + "shasum": "" + }, + "require": { + "php": ">=5.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joe Scylla", + "email": "joe.scylla@gmail.com", + "homepage": "https://profiles.google.com/joe.scylla" + } + ], + "description": "Minifying CSS", + "homepage": "http://code.google.com/p/cssmin/", + "keywords": [ + "css", + "minify" + ], + "time": "2014-09-10 14:34:00" + }, + { + "name": "nikic/php-parser", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "files": [ + "lib/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2015-09-19 14:15:08" + }, + { + "name": "paragonie/random_compat", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "d762ee5b099a29044603cd4649851e81aa66cb47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/d762ee5b099a29044603cd4649851e81aa66cb47", + "reference": "d762ee5b099a29044603cd4649851e81aa66cb47", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2015-12-10 14:48:13" + }, + { + "name": "patchwork/jsqueeze", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/tchwork/jsqueeze.git", + "reference": "074a7ac403d1fae262fd662c43c04b62d71c3e50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tchwork/jsqueeze/zipball/074a7ac403d1fae262fd662c43c04b62d71c3e50", + "reference": "074a7ac403d1fae262fd662c43c04b62d71c3e50", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Patchwork\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Efficient JavaScript minification in PHP", + "homepage": "https://github.com/tchwork/jsqueeze", + "keywords": [ + "compression", + "javascript", + "minification" + ], + "time": "2015-08-20 11:07:02" + }, + { + "name": "patchwork/utf8", + "version": "v1.2.6", + "source": { + "type": "git", + "url": "https://github.com/tchwork/utf8.git", + "reference": "f986d18f4e37ab70b792e977c7d85970cf84f164" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tchwork/utf8/zipball/f986d18f4e37ab70b792e977c7d85970cf84f164", + "reference": "f986d18f4e37ab70b792e977c7d85970cf84f164", + "shasum": "" + }, + "require": { + "lib-pcre": ">=7.3", + "php": ">=5.3.0" + }, + "suggest": { + "ext-iconv": "Use iconv for best performance", + "ext-intl": "Use Intl for best performance", + "ext-mbstring": "Use Mbstring for best performance", + "ext-wfio": "Use WFIO for UTF-8 filesystem access on Windows" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Patchwork\\": "src/Patchwork/" + }, + "classmap": [ + "src/Normalizer.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Portable and performant UTF-8, Unicode and Grapheme Clusters for PHP", + "homepage": "https://github.com/tchwork/utf8", + "keywords": [ + "grapheme", + "i18n", + "unicode", + "utf-8", + "utf8" + ], + "time": "2015-12-15 15:33:41" + }, + { + "name": "pear/archive_tar", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/pear/Archive_Tar.git", + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/fc2937c0e5a2a1c62a378d16394893172f970064", + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-bz2": "bz2 compression support.", + "ext-xz": "lzma2 compression support.", + "ext-zlib": "Gzip compression support." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Archive_Tar": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vincent Blavet", + "email": "vincent@phpconcept.net" + }, + { + "name": "Greg Beaver", + "email": "greg@chiaraquartet.net" + }, + { + "name": "Michiel Rook", + "email": "mrook@php.net" + } + ], + "description": "Tar file management class", + "homepage": "https://github.com/pear/Archive_Tar", + "keywords": [ + "archive", + "tar" + ], + "time": "2015-08-05 12:31:03" + }, + { + "name": "pear/console_getopt", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + }, + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "time": "2015-07-20 20:28:12" + }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.3", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency", + "time": "2015-10-17 11:41:19" + }, + { + "name": "pear/pear_exception", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pear/PEAR_Exception.git", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b", + "shasum": "" + }, + "require": { + "php": ">=4.4.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "class", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "PEAR": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "." + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Helgi Thormar", + "email": "dufuz@php.net" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net" + } + ], + "description": "The PEAR Exception base class.", + "homepage": "https://github.com/pear/PEAR_Exception", + "keywords": [ + "exception" + ], + "time": "2015-02-10 20:07:52" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "a74aa9efbe61430fcb60157c8e025a48ec8ff604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/a74aa9efbe61430fcb60157c8e025a48ec8ff604", + "reference": "a74aa9efbe61430fcb60157c8e025a48ec8ff604", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "~4.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0." + }, + "type": "library", + "autoload": { + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "phpseclib/" + ], + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "time": "2015-08-04 04:48:03" + }, + { + "name": "pimple/pimple", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2015-09-11 15:10:35" + }, + { + "name": "punic/punic", + "version": "1.6.3", + "source": { + "type": "git", + "url": "https://github.com/punic/punic.git", + "reference": "5805b35d6a574f754b49be1f539aaf3ae6484808" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/punic/punic/zipball/5805b35d6a574f754b49be1f539aaf3ae6484808", + "reference": "5805b35d6a574f754b49be1f539aaf3ae6484808", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "replace": { + "punic/calendar": "*", + "punic/common": "*" + }, + "require-dev": { + "apigen/apigen": "4.0.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Punic\\": "code/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michele Locati", + "email": "mlocati@gmail.com", + "role": "Developer" + }, + { + "name": "Remo Laubacher", + "email": "remo.laubacher@gmail.com", + "role": "Collaborator, motivator and perfectionist supporter" + } + ], + "description": "PHP-Unicode CLDR", + "homepage": "https://github.com/punic/punic", + "keywords": [ + "calendar", + "cldr", + "date", + "date-time", + "i18n", + "internationalization", + "l10n", + "localization", + "php", + "time", + "translate", + "translations", + "unicode" + ], + "time": "2015-06-16 13:04:27" + }, + { + "name": "rackspace/php-opencloud", + "version": "v1.9.2", + "source": { + "type": "git", + "url": "https://github.com/rackspace/php-opencloud.git", + "reference": "6551de7aebcebb369d025662f99ab27c9b4527ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rackspace/php-opencloud/zipball/6551de7aebcebb369d025662f99ab27c9b4527ac", + "reference": "6551de7aebcebb369d025662f99ab27c9b4527ac", + "shasum": "" + }, + "require": { + "guzzle/http": "3.8.*@dev", + "php": ">=5.3.3" + }, + "require-dev": { + "guzzle/guzzle": "dev-master", + "psr/log": "1.0.*", + "satooshi/php-coveralls": "0.6.*@dev" + }, + "type": "library", + "autoload": { + "psr-0": { + "OpenCloud": [ + "lib/", + "tests/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Glen Campbell", + "email": "glen.campbell@rackspace.com" + }, + { + "name": "Jamie Hannaford", + "email": "jamie.hannaford@rackspace.com", + "homepage": "https://github.com/jamiehannaford" + } + ], + "description": "PHP SDK for Rackspace/OpenStack APIs", + "keywords": [ + "Openstack", + "nova", + "opencloud", + "rackspace", + "swift" + ], + "time": "2014-02-06 20:53:21" + }, + { + "name": "react/promise", + "version": "v2.2.1", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "time": "2015-07-03 13:48:55" + }, + { + "name": "sabre/dav", + "version": "3.0.9", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-dav.git", + "reference": "b42593965211de1ce99f73bd3aede99c41258e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/b42593965211de1ce99f73bd3aede99c41258e08", + "reference": "b42593965211de1ce99f73bd3aede99c41258e08", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "lib-libxml": ">=2.7.0", + "php": ">=5.4.1", + "sabre/event": "~2.0", + "sabre/http": "~4.0", + "sabre/uri": "~1.0", + "sabre/vobject": "^3.3.4", + "sabre/xml": "~1.0" + }, + "require-dev": { + "evert/phpdoc-md": "~0.1.0", + "phpunit/phpunit": "~4.2", + "sabre/cs": "~0.0.2" + }, + "suggest": { + "ext-curl": "*", + "ext-pdo": "*" + }, + "bin": [ + "bin/sabredav", + "bin/naturalselection" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.0-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\DAV\\": "lib/DAV/", + "Sabre\\DAVACL\\": "lib/DAVACL/", + "Sabre\\CalDAV\\": "lib/CalDAV/", + "Sabre\\CardDAV\\": "lib/CardDAV/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "WebDAV Framework for PHP", + "homepage": "http://sabre.io/", + "keywords": [ + "CalDAV", + "CardDAV", + "WebDAV", + "framework", + "iCalendar" + ], + "time": "2016-04-07 00:32:57" + }, + { + "name": "sabre/event", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-event.git", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-event/zipball/337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "shasum": "" + }, + "require": { + "php": ">=5.4.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "events", + "hooks", + "plugin", + "promise", + "signal" + ], + "time": "2015-05-19 10:24:22" + }, + { + "name": "sabre/http", + "version": "4.2.1", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-http.git", + "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-http/zipball/2e93bc8321524c67be4ca5b8415daebd4c8bf85e", + "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.4", + "sabre/event": ">=1.0.0,<4.0.0", + "sabre/uri": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.3", + "sabre/cs": "~0.0.1" + }, + "suggest": { + "ext-curl": " to make http requests with the Client class" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\HTTP\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", + "homepage": "https://github.com/fruux/sabre-http", + "keywords": [ + "http" + ], + "time": "2016-01-06 23:00:08" + }, + { + "name": "sabre/uri", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-uri.git", + "reference": "6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-uri/zipball/6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42", + "reference": "6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42", + "shasum": "" + }, + "require": { + "php": ">=5.4.7" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.1" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\Uri\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "Functions for making sense out of URIs.", + "homepage": "http://sabre.io/uri/", + "keywords": [ + "rfc3986", + "uri", + "url" + ], + "time": "2015-04-29 03:47:26" + }, + { + "name": "sabre/vobject", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-vobject.git", + "reference": "061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4", + "reference": "061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "*" + }, + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "VObject", + "iCalendar", + "jCal", + "jCard", + "vCard" + ], + "time": "2016-01-11 18:13:23" + }, + { + "name": "sabre/xml", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-xml.git", + "reference": "420400f36655d79894fae8ce970516a71ea8f5f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/420400f36655d79894fae8ce970516a71ea8f5f5", + "reference": "420400f36655d79894fae8ce970516a71ea8f5f5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "lib-libxml": ">=2.6.20", + "php": ">=5.4.1", + "sabre/uri": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Xml\\": "lib/" + }, + "files": [ + "lib/Deserializer/functions.php", + "lib/Serializer/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Markus Staab", + "email": "markus.staab@redaxo.de", + "role": "Developer" + } + ], + "description": "sabre/xml is an XML library that you may not hate.", + "homepage": "https://sabre.io/xml/", + "keywords": [ + "XMLReader", + "XMLWriter", + "dom", + "xml" + ], + "time": "2015-12-29 20:51:22" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", + "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "mail", + "mailer" + ], + "time": "2014-12-05 14:17:14" + }, + { + "name": "symfony/console", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", + "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-12-22 10:25:57" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2015-10-30 20:15:42" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25", + "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2015-11-20 09:19:13" + }, + { + "name": "symfony/polyfill-php55", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "3adc962a6250c02adb508e85ecfa6fcfee9eec47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/3adc962a6250c02adb508e85ecfa6fcfee9eec47", + "reference": "3adc962a6250c02adb508e85ecfa6fcfee9eec47", + "shasum": "" + }, + "require": { + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2015-11-04 20:28:58" + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2015-12-18 15:10:25" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "7f7f3c9c2b9f17722e0cd64fdb4f957330c53146" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/7f7f3c9c2b9f17722e0cd64fdb4f957330c53146", + "reference": "7f7f3c9c2b9f17722e0cd64fdb4f957330c53146", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2015-11-04 20:28:58" + }, + { + "name": "symfony/polyfill-util", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "4271c55cbc0a77b2641f861b978123e46b3da969" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4271c55cbc0a77b2641f861b978123e46b3da969", + "reference": "4271c55cbc0a77b2641f861b978123e46b3da969", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "time": "2015-11-04 20:28:58" + }, + { + "name": "symfony/process", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "62c254438b5040bc2217156e1570cf2206e8540c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/62c254438b5040bc2217156e1570cf2206e8540c", + "reference": "62c254438b5040bc2217156e1570cf2206e8540c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2015-12-23 11:03:46" + }, + { + "name": "symfony/routing", + "version": "v2.8.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "b3261d88bad77de60e01f05706810413cc11367d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/b3261d88bad77de60e01f05706810413cc11367d", + "reference": "b3261d88bad77de60e01f05706810413cc11367d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~2.7|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.3|~3.0.0", + "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2015-12-23 07:56:26" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "james-heinrich/getid3": 20, + "natxet/cssmin": 20, + "swiftmailer/swiftmailer": 0 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/resources/updater-fixes/composer/LICENSE b/resources/updater-fixes/composer/LICENSE new file mode 100644 index 0000000000000..1a28124886db8 --- /dev/null +++ b/resources/updater-fixes/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2016 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/resources/updater-fixes/composer/autoload_classmap.php b/resources/updater-fixes/composer/autoload_classmap.php new file mode 100644 index 0000000000000..1fa193066cd55 --- /dev/null +++ b/resources/updater-fixes/composer/autoload_classmap.php @@ -0,0 +1,1643 @@ + $vendorDir . '/pear/archive_tar/Archive/Tar.php', + 'ArithmeticError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', + 'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php', + 'Assetic\\AssetManager' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/AssetManager.php', + 'Assetic\\AssetWriter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/AssetWriter.php', + 'Assetic\\Asset\\AssetCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/AssetCache.php', + 'Assetic\\Asset\\AssetCollection' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/AssetCollection.php', + 'Assetic\\Asset\\AssetCollectionInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/AssetCollectionInterface.php', + 'Assetic\\Asset\\AssetInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/AssetInterface.php', + 'Assetic\\Asset\\AssetReference' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/AssetReference.php', + 'Assetic\\Asset\\BaseAsset' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/BaseAsset.php', + 'Assetic\\Asset\\FileAsset' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/FileAsset.php', + 'Assetic\\Asset\\GlobAsset' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/GlobAsset.php', + 'Assetic\\Asset\\HttpAsset' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/HttpAsset.php', + 'Assetic\\Asset\\Iterator\\AssetCollectionFilterIterator' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionFilterIterator.php', + 'Assetic\\Asset\\Iterator\\AssetCollectionIterator' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/Iterator/AssetCollectionIterator.php', + 'Assetic\\Asset\\StringAsset' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Asset/StringAsset.php', + 'Assetic\\Cache\\ApcCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/ApcCache.php', + 'Assetic\\Cache\\ArrayCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/ArrayCache.php', + 'Assetic\\Cache\\CacheInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/CacheInterface.php', + 'Assetic\\Cache\\ConfigCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/ConfigCache.php', + 'Assetic\\Cache\\ExpiringCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/ExpiringCache.php', + 'Assetic\\Cache\\FilesystemCache' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Cache/FilesystemCache.php', + 'Assetic\\Exception\\Exception' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Exception/Exception.php', + 'Assetic\\Exception\\FilterException' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Exception/FilterException.php', + 'Assetic\\Extension\\Twig\\AsseticExtension' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticExtension.php', + 'Assetic\\Extension\\Twig\\AsseticFilterFunction' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterFunction.php', + 'Assetic\\Extension\\Twig\\AsseticFilterInvoker' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterInvoker.php', + 'Assetic\\Extension\\Twig\\AsseticFilterNode' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticFilterNode.php', + 'Assetic\\Extension\\Twig\\AsseticNode' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticNode.php', + 'Assetic\\Extension\\Twig\\AsseticTokenParser' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/AsseticTokenParser.php', + 'Assetic\\Extension\\Twig\\TwigFormulaLoader' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigFormulaLoader.php', + 'Assetic\\Extension\\Twig\\TwigResource' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/TwigResource.php', + 'Assetic\\Extension\\Twig\\ValueContainer' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Extension/Twig/ValueContainer.php', + 'Assetic\\Factory\\AssetFactory' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/AssetFactory.php', + 'Assetic\\Factory\\LazyAssetManager' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/LazyAssetManager.php', + 'Assetic\\Factory\\Loader\\BasePhpFormulaLoader' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Loader/BasePhpFormulaLoader.php', + 'Assetic\\Factory\\Loader\\CachedFormulaLoader' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Loader/CachedFormulaLoader.php', + 'Assetic\\Factory\\Loader\\FormulaLoaderInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Loader/FormulaLoaderInterface.php', + 'Assetic\\Factory\\Loader\\FunctionCallsFormulaLoader' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Loader/FunctionCallsFormulaLoader.php', + 'Assetic\\Factory\\Resource\\CoalescingDirectoryResource' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/CoalescingDirectoryResource.php', + 'Assetic\\Factory\\Resource\\DirectoryResource' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php', + 'Assetic\\Factory\\Resource\\DirectoryResourceFilterIterator' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php', + 'Assetic\\Factory\\Resource\\DirectoryResourceIterator' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/DirectoryResource.php', + 'Assetic\\Factory\\Resource\\FileResource' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/FileResource.php', + 'Assetic\\Factory\\Resource\\IteratorResourceInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/IteratorResourceInterface.php', + 'Assetic\\Factory\\Resource\\ResourceInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Resource/ResourceInterface.php', + 'Assetic\\Factory\\Worker\\CacheBustingWorker' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Worker/CacheBustingWorker.php', + 'Assetic\\Factory\\Worker\\EnsureFilterWorker' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Worker/EnsureFilterWorker.php', + 'Assetic\\Factory\\Worker\\WorkerInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Factory/Worker/WorkerInterface.php', + 'Assetic\\FilterManager' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/FilterManager.php', + 'Assetic\\Filter\\AutoprefixerFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/AutoprefixerFilter.php', + 'Assetic\\Filter\\BaseCssFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/BaseCssFilter.php', + 'Assetic\\Filter\\BaseNodeFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/BaseNodeFilter.php', + 'Assetic\\Filter\\BaseProcessFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/BaseProcessFilter.php', + 'Assetic\\Filter\\CallablesFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CallablesFilter.php', + 'Assetic\\Filter\\CleanCssFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CleanCssFilter.php', + 'Assetic\\Filter\\CoffeeScriptFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CoffeeScriptFilter.php', + 'Assetic\\Filter\\CompassFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CompassFilter.php', + 'Assetic\\Filter\\CssCacheBustingFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CssCacheBustingFilter.php', + 'Assetic\\Filter\\CssEmbedFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CssEmbedFilter.php', + 'Assetic\\Filter\\CssImportFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CssImportFilter.php', + 'Assetic\\Filter\\CssMinFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CssMinFilter.php', + 'Assetic\\Filter\\CssRewriteFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/CssRewriteFilter.php', + 'Assetic\\Filter\\DartFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/DartFilter.php', + 'Assetic\\Filter\\DependencyExtractorInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/DependencyExtractorInterface.php', + 'Assetic\\Filter\\EmberPrecompileFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/EmberPrecompileFilter.php', + 'Assetic\\Filter\\FilterCollection' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/FilterCollection.php', + 'Assetic\\Filter\\FilterInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/FilterInterface.php', + 'Assetic\\Filter\\GoogleClosure\\BaseCompilerFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/BaseCompilerFilter.php', + 'Assetic\\Filter\\GoogleClosure\\CompilerApiFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerApiFilter.php', + 'Assetic\\Filter\\GoogleClosure\\CompilerJarFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/GoogleClosure/CompilerJarFilter.php', + 'Assetic\\Filter\\GssFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/GssFilter.php', + 'Assetic\\Filter\\HandlebarsFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/HandlebarsFilter.php', + 'Assetic\\Filter\\HashableInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/HashableInterface.php', + 'Assetic\\Filter\\JSMinFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/JSMinFilter.php', + 'Assetic\\Filter\\JSMinPlusFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/JSMinPlusFilter.php', + 'Assetic\\Filter\\JSqueezeFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/JSqueezeFilter.php', + 'Assetic\\Filter\\JpegoptimFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/JpegoptimFilter.php', + 'Assetic\\Filter\\JpegtranFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/JpegtranFilter.php', + 'Assetic\\Filter\\LessFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/LessFilter.php', + 'Assetic\\Filter\\LessphpFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/LessphpFilter.php', + 'Assetic\\Filter\\MinifyCssCompressorFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/MinifyCssCompressorFilter.php', + 'Assetic\\Filter\\OptiPngFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/OptiPngFilter.php', + 'Assetic\\Filter\\PackagerFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/PackagerFilter.php', + 'Assetic\\Filter\\PackerFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/PackerFilter.php', + 'Assetic\\Filter\\PhpCssEmbedFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/PhpCssEmbedFilter.php', + 'Assetic\\Filter\\PngoutFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/PngoutFilter.php', + 'Assetic\\Filter\\ReactJsxFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/ReactJsxFilter.php', + 'Assetic\\Filter\\RooleFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/RooleFilter.php', + 'Assetic\\Filter\\Sass\\BaseSassFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Sass/BaseSassFilter.php', + 'Assetic\\Filter\\Sass\\SassFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Sass/SassFilter.php', + 'Assetic\\Filter\\Sass\\ScssFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Sass/ScssFilter.php', + 'Assetic\\Filter\\ScssphpFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/ScssphpFilter.php', + 'Assetic\\Filter\\SeparatorFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/SeparatorFilter.php', + 'Assetic\\Filter\\SprocketsFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/SprocketsFilter.php', + 'Assetic\\Filter\\StylusFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/StylusFilter.php', + 'Assetic\\Filter\\TypeScriptFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/TypeScriptFilter.php', + 'Assetic\\Filter\\UglifyCssFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/UglifyCssFilter.php', + 'Assetic\\Filter\\UglifyJs2Filter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/UglifyJs2Filter.php', + 'Assetic\\Filter\\UglifyJsFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/UglifyJsFilter.php', + 'Assetic\\Filter\\Yui\\BaseCompressorFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Yui/BaseCompressorFilter.php', + 'Assetic\\Filter\\Yui\\CssCompressorFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Yui/CssCompressorFilter.php', + 'Assetic\\Filter\\Yui\\JsCompressorFilter' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Filter/Yui/JsCompressorFilter.php', + 'Assetic\\Util\\CssUtils' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Util/CssUtils.php', + 'Assetic\\Util\\FilesystemUtils' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Util/FilesystemUtils.php', + 'Assetic\\Util\\LessUtils' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Util/LessUtils.php', + 'Assetic\\Util\\TraversableString' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Util/TraversableString.php', + 'Assetic\\Util\\VarUtils' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/Util/VarUtils.php', + 'Assetic\\ValueSupplierInterface' => $vendorDir . '/kriswallsmith/assetic/src/Assetic/ValueSupplierInterface.php', + 'Console_Getopt' => $vendorDir . '/pear/console_getopt/Console/Getopt.php', + 'CssAtCharsetParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtCharsetToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtFontFaceDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtFontFaceEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtFontFaceParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtFontFaceStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtImportParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtImportToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesRulesetDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtKeyframesStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtMediaEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtMediaParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtMediaStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtPageDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtPageEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtPageParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtPageStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtVariablesDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtVariablesEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtVariablesParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssAtVariablesStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssCommentParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssCommentToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssCompressColorValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssCompressExpressionValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssCompressUnitValuesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertFontWeightMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertHslColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertLevel3AtKeyframesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertLevel3PropertiesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertNamedColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssConvertRgbColorsMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssError' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssExpressionParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssImportImportsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssMin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssMinifier' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssNullToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssOtbsFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssParser' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRemoveCommentsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRemoveEmptyAtBlocksMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRemoveEmptyRulesetsMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRemoveLastDelarationSemiColonMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRulesetDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRulesetParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssSortRulesetPropertiesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssStringParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssUrlParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssVariablesMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssVariablesMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'CssWhitesmithsFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php', + 'Doctrine\\Common\\Annotations\\Annotation' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php', + 'Doctrine\\Common\\Annotations\\AnnotationException' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php', + 'Doctrine\\Common\\Annotations\\AnnotationReader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php', + 'Doctrine\\Common\\Annotations\\AnnotationRegistry' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php', + 'Doctrine\\Common\\Annotations\\Annotation\\Attribute' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php', + 'Doctrine\\Common\\Annotations\\Annotation\\Attributes' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php', + 'Doctrine\\Common\\Annotations\\Annotation\\Enum' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php', + 'Doctrine\\Common\\Annotations\\Annotation\\IgnoreAnnotation' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php', + 'Doctrine\\Common\\Annotations\\Annotation\\Required' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Required.php', + 'Doctrine\\Common\\Annotations\\Annotation\\Target' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php', + 'Doctrine\\Common\\Annotations\\CachedReader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php', + 'Doctrine\\Common\\Annotations\\DocLexer' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php', + 'Doctrine\\Common\\Annotations\\DocParser' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php', + 'Doctrine\\Common\\Annotations\\FileCacheReader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php', + 'Doctrine\\Common\\Annotations\\IndexedReader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php', + 'Doctrine\\Common\\Annotations\\PhpParser' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php', + 'Doctrine\\Common\\Annotations\\Reader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php', + 'Doctrine\\Common\\Annotations\\SimpleAnnotationReader' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php', + 'Doctrine\\Common\\Annotations\\TokenParser' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php', + 'Doctrine\\Common\\Cache\\ApcCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php', + 'Doctrine\\Common\\Cache\\ArrayCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php', + 'Doctrine\\Common\\Cache\\Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php', + 'Doctrine\\Common\\Cache\\CacheProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php', + 'Doctrine\\Common\\Cache\\ChainCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php', + 'Doctrine\\Common\\Cache\\ClearableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php', + 'Doctrine\\Common\\Cache\\CouchbaseCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php', + 'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php', + 'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php', + 'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php', + 'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php', + 'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php', + 'Doctrine\\Common\\Cache\\MongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php', + 'Doctrine\\Common\\Cache\\MultiGetCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php', + 'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php', + 'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php', + 'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php', + 'Doctrine\\Common\\Cache\\RiakCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php', + 'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php', + 'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php', + 'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php', + 'Doctrine\\Common\\Cache\\WinCacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php', + 'Doctrine\\Common\\Cache\\XcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php', + 'Doctrine\\Common\\Cache\\ZendDataCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php', + 'Doctrine\\Common\\ClassLoader' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/ClassLoader.php', + 'Doctrine\\Common\\Collections\\AbstractLazyCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php', + 'Doctrine\\Common\\Collections\\ArrayCollection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php', + 'Doctrine\\Common\\Collections\\Collection' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php', + 'Doctrine\\Common\\Collections\\Criteria' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php', + 'Doctrine\\Common\\Collections\\Expr\\ClosureExpressionVisitor' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php', + 'Doctrine\\Common\\Collections\\Expr\\Comparison' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php', + 'Doctrine\\Common\\Collections\\Expr\\CompositeExpression' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php', + 'Doctrine\\Common\\Collections\\Expr\\Expression' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php', + 'Doctrine\\Common\\Collections\\Expr\\ExpressionVisitor' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php', + 'Doctrine\\Common\\Collections\\Expr\\Value' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php', + 'Doctrine\\Common\\Collections\\ExpressionBuilder' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php', + 'Doctrine\\Common\\Collections\\Selectable' => $vendorDir . '/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php', + 'Doctrine\\Common\\CommonException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/CommonException.php', + 'Doctrine\\Common\\Comparable' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Comparable.php', + 'Doctrine\\Common\\EventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/EventArgs.php', + 'Doctrine\\Common\\EventManager' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/EventManager.php', + 'Doctrine\\Common\\EventSubscriber' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/EventSubscriber.php', + 'Doctrine\\Common\\Inflector\\Inflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php', + 'Doctrine\\Common\\Lexer' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Lexer.php', + 'Doctrine\\Common\\Lexer\\AbstractLexer' => $vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php', + 'Doctrine\\Common\\NotifyPropertyChanged' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php', + 'Doctrine\\Common\\Persistence\\AbstractManagerRegistry' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php', + 'Doctrine\\Common\\Persistence\\ConnectionRegistry' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php', + 'Doctrine\\Common\\Persistence\\Event\\LifecycleEventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php', + 'Doctrine\\Common\\Persistence\\Event\\LoadClassMetadataEventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php', + 'Doctrine\\Common\\Persistence\\Event\\ManagerEventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php', + 'Doctrine\\Common\\Persistence\\Event\\OnClearEventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php', + 'Doctrine\\Common\\Persistence\\Event\\PreUpdateEventArgs' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php', + 'Doctrine\\Common\\Persistence\\ManagerRegistry' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php', + 'Doctrine\\Common\\Persistence\\Mapping\\AbstractClassMetadataFactory' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php', + 'Doctrine\\Common\\Persistence\\Mapping\\ClassMetadata' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php', + 'Doctrine\\Common\\Persistence\\Mapping\\ClassMetadataFactory' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\AnnotationDriver' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\DefaultFileLocator' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\FileDriver' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\FileLocator' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriver' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriverChain' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\PHPDriver' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\StaticPHPDriver' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php', + 'Doctrine\\Common\\Persistence\\Mapping\\Driver\\SymfonyFileLocator' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php', + 'Doctrine\\Common\\Persistence\\Mapping\\MappingException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php', + 'Doctrine\\Common\\Persistence\\Mapping\\ReflectionService' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php', + 'Doctrine\\Common\\Persistence\\Mapping\\RuntimeReflectionService' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php', + 'Doctrine\\Common\\Persistence\\Mapping\\StaticReflectionService' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php', + 'Doctrine\\Common\\Persistence\\ObjectManager' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php', + 'Doctrine\\Common\\Persistence\\ObjectManagerAware' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php', + 'Doctrine\\Common\\Persistence\\ObjectManagerDecorator' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php', + 'Doctrine\\Common\\Persistence\\ObjectRepository' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php', + 'Doctrine\\Common\\Persistence\\PersistentObject' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php', + 'Doctrine\\Common\\Persistence\\Proxy' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php', + 'Doctrine\\Common\\PropertyChangedListener' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php', + 'Doctrine\\Common\\Proxy\\AbstractProxyFactory' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php', + 'Doctrine\\Common\\Proxy\\Autoloader' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Autoloader.php', + 'Doctrine\\Common\\Proxy\\Exception\\InvalidArgumentException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Exception/InvalidArgumentException.php', + 'Doctrine\\Common\\Proxy\\Exception\\OutOfBoundsException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Exception/OutOfBoundsException.php', + 'Doctrine\\Common\\Proxy\\Exception\\ProxyException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Exception/ProxyException.php', + 'Doctrine\\Common\\Proxy\\Exception\\UnexpectedValueException' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Exception/UnexpectedValueException.php', + 'Doctrine\\Common\\Proxy\\Proxy' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/Proxy.php', + 'Doctrine\\Common\\Proxy\\ProxyDefinition' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/ProxyDefinition.php', + 'Doctrine\\Common\\Proxy\\ProxyGenerator' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php', + 'Doctrine\\Common\\Reflection\\ClassFinderInterface' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/ClassFinderInterface.php', + 'Doctrine\\Common\\Reflection\\Psr0FindFile' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/Psr0FindFile.php', + 'Doctrine\\Common\\Reflection\\ReflectionProviderInterface' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/ReflectionProviderInterface.php', + 'Doctrine\\Common\\Reflection\\RuntimePublicReflectionProperty' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/RuntimePublicReflectionProperty.php', + 'Doctrine\\Common\\Reflection\\StaticReflectionClass' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php', + 'Doctrine\\Common\\Reflection\\StaticReflectionMethod' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionMethod.php', + 'Doctrine\\Common\\Reflection\\StaticReflectionParser' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php', + 'Doctrine\\Common\\Reflection\\StaticReflectionProperty' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php', + 'Doctrine\\Common\\Util\\ClassUtils' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php', + 'Doctrine\\Common\\Util\\Debug' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Util/Debug.php', + 'Doctrine\\Common\\Util\\Inflector' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Util/Inflector.php', + 'Doctrine\\Common\\Version' => $vendorDir . '/doctrine/common/lib/Doctrine/Common/Version.php', + 'Doctrine\\DBAL\\Cache\\ArrayStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php', + 'Doctrine\\DBAL\\Cache\\CacheException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php', + 'Doctrine\\DBAL\\Cache\\QueryCacheProfile' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php', + 'Doctrine\\DBAL\\Cache\\ResultCacheStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php', + 'Doctrine\\DBAL\\Configuration' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php', + 'Doctrine\\DBAL\\Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Connection.php', + 'Doctrine\\DBAL\\ConnectionException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php', + 'Doctrine\\DBAL\\Connections\\MasterSlaveConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php', + 'Doctrine\\DBAL\\DBALException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php', + 'Doctrine\\DBAL\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver.php', + 'Doctrine\\DBAL\\DriverManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php', + 'Doctrine\\DBAL\\Driver\\AbstractDB2Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractDB2Driver.php', + 'Doctrine\\DBAL\\Driver\\AbstractDriverException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractDriverException.php', + 'Doctrine\\DBAL\\Driver\\AbstractMySQLDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php', + 'Doctrine\\DBAL\\Driver\\AbstractOracleDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php', + 'Doctrine\\DBAL\\Driver\\AbstractPostgreSQLDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php', + 'Doctrine\\DBAL\\Driver\\AbstractSQLAnywhereDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php', + 'Doctrine\\DBAL\\Driver\\AbstractSQLServerDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php', + 'Doctrine\\DBAL\\Driver\\AbstractSQLiteDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php', + 'Doctrine\\DBAL\\Driver\\Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php', + 'Doctrine\\DBAL\\Driver\\DriverException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/DriverException.php', + 'Doctrine\\DBAL\\Driver\\DrizzlePDOMySql\\Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Connection.php', + 'Doctrine\\DBAL\\Driver\\DrizzlePDOMySql\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/DrizzlePDOMySql/Driver.php', + 'Doctrine\\DBAL\\Driver\\ExceptionConverterDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php', + 'Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php', + 'Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php', + 'Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Exception' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php', + 'Doctrine\\DBAL\\Driver\\IBMDB2\\DB2Statement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php', + 'Doctrine\\DBAL\\Driver\\Mysqli\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php', + 'Doctrine\\DBAL\\Driver\\Mysqli\\MysqliConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php', + 'Doctrine\\DBAL\\Driver\\Mysqli\\MysqliException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php', + 'Doctrine\\DBAL\\Driver\\Mysqli\\MysqliStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\OCI8Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\OCI8Exception' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php', + 'Doctrine\\DBAL\\Driver\\OCI8\\OCI8Statement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php', + 'Doctrine\\DBAL\\Driver\\PDOConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php', + 'Doctrine\\DBAL\\Driver\\PDOException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOException.php', + 'Doctrine\\DBAL\\Driver\\PDOIbm\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOMySql\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOOracle\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOPgSql\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOSqlite\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOSqlsrv\\Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php', + 'Doctrine\\DBAL\\Driver\\PDOSqlsrv\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php', + 'Doctrine\\DBAL\\Driver\\PDOStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php', + 'Doctrine\\DBAL\\Driver\\PingableConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/PingableConnection.php', + 'Doctrine\\DBAL\\Driver\\ResultStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php', + 'Doctrine\\DBAL\\Driver\\SQLAnywhere\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/Driver.php', + 'Doctrine\\DBAL\\Driver\\SQLAnywhere\\SQLAnywhereConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php', + 'Doctrine\\DBAL\\Driver\\SQLAnywhere\\SQLAnywhereException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php', + 'Doctrine\\DBAL\\Driver\\SQLAnywhere\\SQLAnywhereStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereStatement.php', + 'Doctrine\\DBAL\\Driver\\SQLSrv\\Driver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php', + 'Doctrine\\DBAL\\Driver\\SQLSrv\\LastInsertId' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/LastInsertId.php', + 'Doctrine\\DBAL\\Driver\\SQLSrv\\SQLSrvConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php', + 'Doctrine\\DBAL\\Driver\\SQLSrv\\SQLSrvException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php', + 'Doctrine\\DBAL\\Driver\\SQLSrv\\SQLSrvStatement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php', + 'Doctrine\\DBAL\\Driver\\ServerInfoAwareConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php', + 'Doctrine\\DBAL\\Driver\\Statement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php', + 'Doctrine\\DBAL\\Event\\ConnectionEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php', + 'Doctrine\\DBAL\\Event\\Listeners\\MysqlSessionInit' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php', + 'Doctrine\\DBAL\\Event\\Listeners\\OracleSessionInit' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php', + 'Doctrine\\DBAL\\Event\\Listeners\\SQLSessionInit' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php', + 'Doctrine\\DBAL\\Event\\SchemaAlterTableAddColumnEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaAlterTableChangeColumnEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaAlterTableEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaAlterTableRemoveColumnEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaAlterTableRenameColumnEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaColumnDefinitionEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaCreateTableColumnEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaCreateTableEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaDropTableEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php', + 'Doctrine\\DBAL\\Event\\SchemaIndexDefinitionEventArgs' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php', + 'Doctrine\\DBAL\\Events' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Events.php', + 'Doctrine\\DBAL\\Exception\\ConnectionException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/ConnectionException.php', + 'Doctrine\\DBAL\\Exception\\ConstraintViolationException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/ConstraintViolationException.php', + 'Doctrine\\DBAL\\Exception\\DatabaseObjectExistsException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/DatabaseObjectExistsException.php', + 'Doctrine\\DBAL\\Exception\\DatabaseObjectNotFoundException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/DatabaseObjectNotFoundException.php', + 'Doctrine\\DBAL\\Exception\\DriverException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/DriverException.php', + 'Doctrine\\DBAL\\Exception\\ForeignKeyConstraintViolationException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/ForeignKeyConstraintViolationException.php', + 'Doctrine\\DBAL\\Exception\\InvalidArgumentException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/InvalidArgumentException.php', + 'Doctrine\\DBAL\\Exception\\InvalidFieldNameException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/InvalidFieldNameException.php', + 'Doctrine\\DBAL\\Exception\\NonUniqueFieldNameException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/NonUniqueFieldNameException.php', + 'Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/NotNullConstraintViolationException.php', + 'Doctrine\\DBAL\\Exception\\ReadOnlyException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/ReadOnlyException.php', + 'Doctrine\\DBAL\\Exception\\ServerException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/ServerException.php', + 'Doctrine\\DBAL\\Exception\\SyntaxErrorException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/SyntaxErrorException.php', + 'Doctrine\\DBAL\\Exception\\TableExistsException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/TableExistsException.php', + 'Doctrine\\DBAL\\Exception\\TableNotFoundException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/TableNotFoundException.php', + 'Doctrine\\DBAL\\Exception\\UniqueConstraintViolationException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Exception/UniqueConstraintViolationException.php', + 'Doctrine\\DBAL\\Id\\TableGenerator' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGenerator.php', + 'Doctrine\\DBAL\\Id\\TableGeneratorSchemaVisitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGeneratorSchemaVisitor.php', + 'Doctrine\\DBAL\\LockMode' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php', + 'Doctrine\\DBAL\\Logging\\DebugStack' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php', + 'Doctrine\\DBAL\\Logging\\EchoSQLLogger' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php', + 'Doctrine\\DBAL\\Logging\\LoggerChain' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php', + 'Doctrine\\DBAL\\Logging\\SQLLogger' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php', + 'Doctrine\\DBAL\\Platforms\\AbstractPlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php', + 'Doctrine\\DBAL\\Platforms\\DB2Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php', + 'Doctrine\\DBAL\\Platforms\\DrizzlePlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\DB2Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\DrizzleKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DrizzleKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\MsSQLKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL57Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL57Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQLKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\OracleKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL91Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL91Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL92Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL92Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQLKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQLKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\ReservedKeywordsValidator' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/ReservedKeywordsValidator.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLAnywhere11Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere11Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLAnywhere12Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere12Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLAnywhere16Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere16Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLAnywhereKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhereKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServer2005Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServer2005Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServer2008Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServer2008Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServer2012Keywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServer2012Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServerKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServerKeywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLiteKeywords' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php', + 'Doctrine\\DBAL\\Platforms\\MySQL57Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php', + 'Doctrine\\DBAL\\Platforms\\MySqlPlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php', + 'Doctrine\\DBAL\\Platforms\\OraclePlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php', + 'Doctrine\\DBAL\\Platforms\\PostgreSQL91Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php', + 'Doctrine\\DBAL\\Platforms\\PostgreSQL92Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php', + 'Doctrine\\DBAL\\Platforms\\PostgreSqlPlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php', + 'Doctrine\\DBAL\\Platforms\\SQLAnywhere11Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLAnywhere12Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere12Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLAnywhere16Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php', + 'Doctrine\\DBAL\\Platforms\\SQLAzurePlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php', + 'Doctrine\\DBAL\\Platforms\\SQLServer2005Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLServer2008Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLServer2012Platform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php', + 'Doctrine\\DBAL\\Platforms\\SQLServerPlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php', + 'Doctrine\\DBAL\\Platforms\\SqlitePlatform' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php', + 'Doctrine\\DBAL\\Portability\\Connection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php', + 'Doctrine\\DBAL\\Portability\\Statement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php', + 'Doctrine\\DBAL\\Query\\Expression\\CompositeExpression' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php', + 'Doctrine\\DBAL\\Query\\Expression\\ExpressionBuilder' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php', + 'Doctrine\\DBAL\\Query\\QueryBuilder' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php', + 'Doctrine\\DBAL\\Query\\QueryException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php', + 'Doctrine\\DBAL\\SQLParserUtils' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php', + 'Doctrine\\DBAL\\SQLParserUtilsException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php', + 'Doctrine\\DBAL\\Schema\\AbstractAsset' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php', + 'Doctrine\\DBAL\\Schema\\AbstractSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\Column' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php', + 'Doctrine\\DBAL\\Schema\\ColumnDiff' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php', + 'Doctrine\\DBAL\\Schema\\Comparator' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php', + 'Doctrine\\DBAL\\Schema\\Constraint' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php', + 'Doctrine\\DBAL\\Schema\\DB2SchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/DB2SchemaManager.php', + 'Doctrine\\DBAL\\Schema\\DrizzleSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\ForeignKeyConstraint' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php', + 'Doctrine\\DBAL\\Schema\\Identifier' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Identifier.php', + 'Doctrine\\DBAL\\Schema\\Index' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php', + 'Doctrine\\DBAL\\Schema\\MySqlSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\OracleSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\PostgreSqlSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\SQLAnywhereSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\SQLServerSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\Schema' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php', + 'Doctrine\\DBAL\\Schema\\SchemaConfig' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php', + 'Doctrine\\DBAL\\Schema\\SchemaDiff' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php', + 'Doctrine\\DBAL\\Schema\\SchemaException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php', + 'Doctrine\\DBAL\\Schema\\Sequence' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php', + 'Doctrine\\DBAL\\Schema\\SqliteSchemaManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php', + 'Doctrine\\DBAL\\Schema\\Synchronizer\\AbstractSchemaSynchronizer' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/AbstractSchemaSynchronizer.php', + 'Doctrine\\DBAL\\Schema\\Synchronizer\\SchemaSynchronizer' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SchemaSynchronizer.php', + 'Doctrine\\DBAL\\Schema\\Synchronizer\\SingleDatabaseSynchronizer' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SingleDatabaseSynchronizer.php', + 'Doctrine\\DBAL\\Schema\\Table' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php', + 'Doctrine\\DBAL\\Schema\\TableDiff' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php', + 'Doctrine\\DBAL\\Schema\\View' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\AbstractVisitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/AbstractVisitor.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\CreateSchemaSqlCollector' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/CreateSchemaSqlCollector.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\DropSchemaSqlCollector' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\Graphviz' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\NamespaceVisitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/NamespaceVisitor.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\RemoveNamespacedAssets' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/RemoveNamespacedAssets.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\SchemaDiffVisitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/SchemaDiffVisitor.php', + 'Doctrine\\DBAL\\Schema\\Visitor\\Visitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Visitor.php', + 'Doctrine\\DBAL\\Sharding\\PoolingShardConnection' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardConnection.php', + 'Doctrine\\DBAL\\Sharding\\PoolingShardManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardManager.php', + 'Doctrine\\DBAL\\Sharding\\SQLAzure\\SQLAzureFederationsSynchronizer' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php', + 'Doctrine\\DBAL\\Sharding\\SQLAzure\\SQLAzureShardManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php', + 'Doctrine\\DBAL\\Sharding\\SQLAzure\\Schema\\MultiTenantVisitor' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/Schema/MultiTenantVisitor.php', + 'Doctrine\\DBAL\\Sharding\\ShardChoser\\MultiTenantShardChoser' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardChoser/MultiTenantShardChoser.php', + 'Doctrine\\DBAL\\Sharding\\ShardChoser\\ShardChoser' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardChoser/ShardChoser.php', + 'Doctrine\\DBAL\\Sharding\\ShardManager' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardManager.php', + 'Doctrine\\DBAL\\Sharding\\ShardingException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardingException.php', + 'Doctrine\\DBAL\\Statement' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Statement.php', + 'Doctrine\\DBAL\\Tools\\Console\\Command\\ImportCommand' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php', + 'Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php', + 'Doctrine\\DBAL\\Tools\\Console\\Command\\RunSqlCommand' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php', + 'Doctrine\\DBAL\\Tools\\Console\\ConsoleRunner' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php', + 'Doctrine\\DBAL\\Tools\\Console\\Helper\\ConnectionHelper' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php', + 'Doctrine\\DBAL\\Types\\ArrayType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php', + 'Doctrine\\DBAL\\Types\\BigIntType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php', + 'Doctrine\\DBAL\\Types\\BinaryType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php', + 'Doctrine\\DBAL\\Types\\BlobType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php', + 'Doctrine\\DBAL\\Types\\BooleanType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php', + 'Doctrine\\DBAL\\Types\\ConversionException' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php', + 'Doctrine\\DBAL\\Types\\DateTimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php', + 'Doctrine\\DBAL\\Types\\DateTimeTzType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php', + 'Doctrine\\DBAL\\Types\\DateType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php', + 'Doctrine\\DBAL\\Types\\DecimalType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php', + 'Doctrine\\DBAL\\Types\\FloatType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php', + 'Doctrine\\DBAL\\Types\\GuidType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php', + 'Doctrine\\DBAL\\Types\\IntegerType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php', + 'Doctrine\\DBAL\\Types\\JsonArrayType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php', + 'Doctrine\\DBAL\\Types\\ObjectType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php', + 'Doctrine\\DBAL\\Types\\SimpleArrayType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php', + 'Doctrine\\DBAL\\Types\\SmallIntType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php', + 'Doctrine\\DBAL\\Types\\StringType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php', + 'Doctrine\\DBAL\\Types\\TextType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php', + 'Doctrine\\DBAL\\Types\\TimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php', + 'Doctrine\\DBAL\\Types\\Type' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php', + 'Doctrine\\DBAL\\Types\\VarDateTimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php', + 'Doctrine\\DBAL\\Version' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Version.php', + 'Doctrine\\DBAL\\VersionAwarePlatformDriver' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php', + 'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php', + 'GuzzleHttp\\BatchResults' => $vendorDir . '/guzzlehttp/guzzle/src/BatchResults.php', + 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', + 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', + 'GuzzleHttp\\Collection' => $vendorDir . '/guzzlehttp/guzzle/src/Collection.php', + 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', + 'GuzzleHttp\\Cookie\\CookieJarInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php', + 'GuzzleHttp\\Cookie\\FileCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php', + 'GuzzleHttp\\Cookie\\SessionCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php', + 'GuzzleHttp\\Cookie\\SetCookie' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SetCookie.php', + 'GuzzleHttp\\Event\\AbstractEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractEvent.php', + 'GuzzleHttp\\Event\\AbstractRequestEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php', + 'GuzzleHttp\\Event\\AbstractRetryableEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php', + 'GuzzleHttp\\Event\\AbstractTransferEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php', + 'GuzzleHttp\\Event\\BeforeEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/BeforeEvent.php', + 'GuzzleHttp\\Event\\CompleteEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/CompleteEvent.php', + 'GuzzleHttp\\Event\\Emitter' => $vendorDir . '/guzzlehttp/guzzle/src/Event/Emitter.php', + 'GuzzleHttp\\Event\\EmitterInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EmitterInterface.php', + 'GuzzleHttp\\Event\\EndEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EndEvent.php', + 'GuzzleHttp\\Event\\ErrorEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ErrorEvent.php', + 'GuzzleHttp\\Event\\EventInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/EventInterface.php', + 'GuzzleHttp\\Event\\HasEmitterInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/HasEmitterInterface.php', + 'GuzzleHttp\\Event\\HasEmitterTrait' => $vendorDir . '/guzzlehttp/guzzle/src/Event/HasEmitterTrait.php', + 'GuzzleHttp\\Event\\ListenerAttacherTrait' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php', + 'GuzzleHttp\\Event\\ProgressEvent' => $vendorDir . '/guzzlehttp/guzzle/src/Event/ProgressEvent.php', + 'GuzzleHttp\\Event\\RequestEvents' => $vendorDir . '/guzzlehttp/guzzle/src/Event/RequestEvents.php', + 'GuzzleHttp\\Event\\SubscriberInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Event/SubscriberInterface.php', + 'GuzzleHttp\\Exception\\BadResponseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/BadResponseException.php', + 'GuzzleHttp\\Exception\\ClientException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ClientException.php', + 'GuzzleHttp\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ConnectException.php', + 'GuzzleHttp\\Exception\\CouldNotRewindStreamException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/CouldNotRewindStreamException.php', + 'GuzzleHttp\\Exception\\ParseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ParseException.php', + 'GuzzleHttp\\Exception\\RequestException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/RequestException.php', + 'GuzzleHttp\\Exception\\ServerException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ServerException.php', + 'GuzzleHttp\\Exception\\StateException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/StateException.php', + 'GuzzleHttp\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php', + 'GuzzleHttp\\Exception\\TransferException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TransferException.php', + 'GuzzleHttp\\Exception\\XmlParseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/XmlParseException.php', + 'GuzzleHttp\\HasDataTrait' => $vendorDir . '/guzzlehttp/guzzle/src/HasDataTrait.php', + 'GuzzleHttp\\Message\\AbstractMessage' => $vendorDir . '/guzzlehttp/guzzle/src/Message/AbstractMessage.php', + 'GuzzleHttp\\Message\\AppliesHeadersInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php', + 'GuzzleHttp\\Message\\FutureResponse' => $vendorDir . '/guzzlehttp/guzzle/src/Message/FutureResponse.php', + 'GuzzleHttp\\Message\\MessageFactory' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageFactory.php', + 'GuzzleHttp\\Message\\MessageFactoryInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php', + 'GuzzleHttp\\Message\\MessageInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageInterface.php', + 'GuzzleHttp\\Message\\MessageParser' => $vendorDir . '/guzzlehttp/guzzle/src/Message/MessageParser.php', + 'GuzzleHttp\\Message\\Request' => $vendorDir . '/guzzlehttp/guzzle/src/Message/Request.php', + 'GuzzleHttp\\Message\\RequestInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/RequestInterface.php', + 'GuzzleHttp\\Message\\Response' => $vendorDir . '/guzzlehttp/guzzle/src/Message/Response.php', + 'GuzzleHttp\\Message\\ResponseInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Message/ResponseInterface.php', + 'GuzzleHttp\\Mimetypes' => $vendorDir . '/guzzlehttp/guzzle/src/Mimetypes.php', + 'GuzzleHttp\\Pool' => $vendorDir . '/guzzlehttp/guzzle/src/Pool.php', + 'GuzzleHttp\\Post\\MultipartBody' => $vendorDir . '/guzzlehttp/guzzle/src/Post/MultipartBody.php', + 'GuzzleHttp\\Post\\PostBody' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostBody.php', + 'GuzzleHttp\\Post\\PostBodyInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostBodyInterface.php', + 'GuzzleHttp\\Post\\PostFile' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostFile.php', + 'GuzzleHttp\\Post\\PostFileInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Post/PostFileInterface.php', + 'GuzzleHttp\\Query' => $vendorDir . '/guzzlehttp/guzzle/src/Query.php', + 'GuzzleHttp\\QueryParser' => $vendorDir . '/guzzlehttp/guzzle/src/QueryParser.php', + 'GuzzleHttp\\RequestFsm' => $vendorDir . '/guzzlehttp/guzzle/src/RequestFsm.php', + 'GuzzleHttp\\RingBridge' => $vendorDir . '/guzzlehttp/guzzle/src/RingBridge.php', + 'GuzzleHttp\\Ring\\Client\\ClientUtils' => $vendorDir . '/guzzlehttp/ringphp/src/Client/ClientUtils.php', + 'GuzzleHttp\\Ring\\Client\\CurlFactory' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlFactory.php', + 'GuzzleHttp\\Ring\\Client\\CurlHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlHandler.php', + 'GuzzleHttp\\Ring\\Client\\CurlMultiHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php', + 'GuzzleHttp\\Ring\\Client\\Middleware' => $vendorDir . '/guzzlehttp/ringphp/src/Client/Middleware.php', + 'GuzzleHttp\\Ring\\Client\\MockHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/MockHandler.php', + 'GuzzleHttp\\Ring\\Client\\StreamHandler' => $vendorDir . '/guzzlehttp/ringphp/src/Client/StreamHandler.php', + 'GuzzleHttp\\Ring\\Core' => $vendorDir . '/guzzlehttp/ringphp/src/Core.php', + 'GuzzleHttp\\Ring\\Exception\\CancelledException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/CancelledException.php', + 'GuzzleHttp\\Ring\\Exception\\CancelledFutureAccessException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/CancelledFutureAccessException.php', + 'GuzzleHttp\\Ring\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/ConnectException.php', + 'GuzzleHttp\\Ring\\Exception\\RingException' => $vendorDir . '/guzzlehttp/ringphp/src/Exception/RingException.php', + 'GuzzleHttp\\Ring\\Future\\BaseFutureTrait' => $vendorDir . '/guzzlehttp/ringphp/src/Future/BaseFutureTrait.php', + 'GuzzleHttp\\Ring\\Future\\CompletedFutureArray' => $vendorDir . '/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php', + 'GuzzleHttp\\Ring\\Future\\CompletedFutureValue' => $vendorDir . '/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php', + 'GuzzleHttp\\Ring\\Future\\FutureArray' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureArray.php', + 'GuzzleHttp\\Ring\\Future\\FutureArrayInterface' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php', + 'GuzzleHttp\\Ring\\Future\\FutureInterface' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureInterface.php', + 'GuzzleHttp\\Ring\\Future\\FutureValue' => $vendorDir . '/guzzlehttp/ringphp/src/Future/FutureValue.php', + 'GuzzleHttp\\Ring\\Future\\MagicFutureTrait' => $vendorDir . '/guzzlehttp/ringphp/src/Future/MagicFutureTrait.php', + 'GuzzleHttp\\Stream\\AppendStream' => $vendorDir . '/guzzlehttp/streams/src/AppendStream.php', + 'GuzzleHttp\\Stream\\AsyncReadStream' => $vendorDir . '/guzzlehttp/streams/src/AsyncReadStream.php', + 'GuzzleHttp\\Stream\\BufferStream' => $vendorDir . '/guzzlehttp/streams/src/BufferStream.php', + 'GuzzleHttp\\Stream\\CachingStream' => $vendorDir . '/guzzlehttp/streams/src/CachingStream.php', + 'GuzzleHttp\\Stream\\DroppingStream' => $vendorDir . '/guzzlehttp/streams/src/DroppingStream.php', + 'GuzzleHttp\\Stream\\Exception\\CannotAttachException' => $vendorDir . '/guzzlehttp/streams/src/Exception/CannotAttachException.php', + 'GuzzleHttp\\Stream\\Exception\\SeekException' => $vendorDir . '/guzzlehttp/streams/src/Exception/SeekException.php', + 'GuzzleHttp\\Stream\\FnStream' => $vendorDir . '/guzzlehttp/streams/src/FnStream.php', + 'GuzzleHttp\\Stream\\GuzzleStreamWrapper' => $vendorDir . '/guzzlehttp/streams/src/GuzzleStreamWrapper.php', + 'GuzzleHttp\\Stream\\InflateStream' => $vendorDir . '/guzzlehttp/streams/src/InflateStream.php', + 'GuzzleHttp\\Stream\\LazyOpenStream' => $vendorDir . '/guzzlehttp/streams/src/LazyOpenStream.php', + 'GuzzleHttp\\Stream\\LimitStream' => $vendorDir . '/guzzlehttp/streams/src/LimitStream.php', + 'GuzzleHttp\\Stream\\MetadataStreamInterface' => $vendorDir . '/guzzlehttp/streams/src/MetadataStreamInterface.php', + 'GuzzleHttp\\Stream\\NoSeekStream' => $vendorDir . '/guzzlehttp/streams/src/NoSeekStream.php', + 'GuzzleHttp\\Stream\\NullStream' => $vendorDir . '/guzzlehttp/streams/src/NullStream.php', + 'GuzzleHttp\\Stream\\PumpStream' => $vendorDir . '/guzzlehttp/streams/src/PumpStream.php', + 'GuzzleHttp\\Stream\\Stream' => $vendorDir . '/guzzlehttp/streams/src/Stream.php', + 'GuzzleHttp\\Stream\\StreamDecoratorTrait' => $vendorDir . '/guzzlehttp/streams/src/StreamDecoratorTrait.php', + 'GuzzleHttp\\Stream\\StreamInterface' => $vendorDir . '/guzzlehttp/streams/src/StreamInterface.php', + 'GuzzleHttp\\Stream\\Utils' => $vendorDir . '/guzzlehttp/streams/src/Utils.php', + 'GuzzleHttp\\Subscriber\\Cookie' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Cookie.php', + 'GuzzleHttp\\Subscriber\\History' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/History.php', + 'GuzzleHttp\\Subscriber\\HttpError' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/HttpError.php', + 'GuzzleHttp\\Subscriber\\Mock' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Mock.php', + 'GuzzleHttp\\Subscriber\\Prepare' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Prepare.php', + 'GuzzleHttp\\Subscriber\\Redirect' => $vendorDir . '/guzzlehttp/guzzle/src/Subscriber/Redirect.php', + 'GuzzleHttp\\ToArrayInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ToArrayInterface.php', + 'GuzzleHttp\\Transaction' => $vendorDir . '/guzzlehttp/guzzle/src/Transaction.php', + 'GuzzleHttp\\UriTemplate' => $vendorDir . '/guzzlehttp/guzzle/src/UriTemplate.php', + 'GuzzleHttp\\Url' => $vendorDir . '/guzzlehttp/guzzle/src/Url.php', + 'GuzzleHttp\\Utils' => $vendorDir . '/guzzlehttp/guzzle/src/Utils.php', + 'Guzzle\\Common\\AbstractHasDispatcher' => $vendorDir . '/guzzle/common/Guzzle/Common/AbstractHasDispatcher.php', + 'Guzzle\\Common\\Collection' => $vendorDir . '/guzzle/common/Guzzle/Common/Collection.php', + 'Guzzle\\Common\\Event' => $vendorDir . '/guzzle/common/Guzzle/Common/Event.php', + 'Guzzle\\Common\\Exception\\BadMethodCallException' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/BadMethodCallException.php', + 'Guzzle\\Common\\Exception\\ExceptionCollection' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/ExceptionCollection.php', + 'Guzzle\\Common\\Exception\\GuzzleException' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/GuzzleException.php', + 'Guzzle\\Common\\Exception\\InvalidArgumentException' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/InvalidArgumentException.php', + 'Guzzle\\Common\\Exception\\RuntimeException' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/RuntimeException.php', + 'Guzzle\\Common\\Exception\\UnexpectedValueException' => $vendorDir . '/guzzle/common/Guzzle/Common/Exception/UnexpectedValueException.php', + 'Guzzle\\Common\\FromConfigInterface' => $vendorDir . '/guzzle/common/Guzzle/Common/FromConfigInterface.php', + 'Guzzle\\Common\\HasDispatcherInterface' => $vendorDir . '/guzzle/common/Guzzle/Common/HasDispatcherInterface.php', + 'Guzzle\\Common\\ToArrayInterface' => $vendorDir . '/guzzle/common/Guzzle/Common/ToArrayInterface.php', + 'Guzzle\\Common\\Version' => $vendorDir . '/guzzle/common/Guzzle/Common/Version.php', + 'Guzzle\\Http\\AbstractEntityBodyDecorator' => $vendorDir . '/guzzle/http/Guzzle/Http/AbstractEntityBodyDecorator.php', + 'Guzzle\\Http\\CachingEntityBody' => $vendorDir . '/guzzle/http/Guzzle/Http/CachingEntityBody.php', + 'Guzzle\\Http\\Client' => $vendorDir . '/guzzle/http/Guzzle/Http/Client.php', + 'Guzzle\\Http\\ClientInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/ClientInterface.php', + 'Guzzle\\Http\\Curl\\CurlHandle' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/CurlHandle.php', + 'Guzzle\\Http\\Curl\\CurlMulti' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/CurlMulti.php', + 'Guzzle\\Http\\Curl\\CurlMultiInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/CurlMultiInterface.php', + 'Guzzle\\Http\\Curl\\CurlMultiProxy' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/CurlMultiProxy.php', + 'Guzzle\\Http\\Curl\\CurlVersion' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/CurlVersion.php', + 'Guzzle\\Http\\Curl\\RequestMediator' => $vendorDir . '/guzzle/http/Guzzle/Http/Curl/RequestMediator.php', + 'Guzzle\\Http\\EntityBody' => $vendorDir . '/guzzle/http/Guzzle/Http/EntityBody.php', + 'Guzzle\\Http\\EntityBodyInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/EntityBodyInterface.php', + 'Guzzle\\Http\\Exception\\BadResponseException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/BadResponseException.php', + 'Guzzle\\Http\\Exception\\ClientErrorResponseException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/ClientErrorResponseException.php', + 'Guzzle\\Http\\Exception\\CouldNotRewindStreamException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/CouldNotRewindStreamException.php', + 'Guzzle\\Http\\Exception\\CurlException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/CurlException.php', + 'Guzzle\\Http\\Exception\\HttpException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/HttpException.php', + 'Guzzle\\Http\\Exception\\MultiTransferException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/MultiTransferException.php', + 'Guzzle\\Http\\Exception\\RequestException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/RequestException.php', + 'Guzzle\\Http\\Exception\\ServerErrorResponseException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/ServerErrorResponseException.php', + 'Guzzle\\Http\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzle/http/Guzzle/Http/Exception/TooManyRedirectsException.php', + 'Guzzle\\Http\\IoEmittingEntityBody' => $vendorDir . '/guzzle/http/Guzzle/Http/IoEmittingEntityBody.php', + 'Guzzle\\Http\\Message\\AbstractMessage' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/AbstractMessage.php', + 'Guzzle\\Http\\Message\\EntityEnclosingRequest' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/EntityEnclosingRequest.php', + 'Guzzle\\Http\\Message\\EntityEnclosingRequestInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/EntityEnclosingRequestInterface.php', + 'Guzzle\\Http\\Message\\Header' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header.php', + 'Guzzle\\Http\\Message\\Header\\CacheControl' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/CacheControl.php', + 'Guzzle\\Http\\Message\\Header\\HeaderCollection' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/HeaderCollection.php', + 'Guzzle\\Http\\Message\\Header\\HeaderFactory' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/HeaderFactory.php', + 'Guzzle\\Http\\Message\\Header\\HeaderFactoryInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/HeaderFactoryInterface.php', + 'Guzzle\\Http\\Message\\Header\\HeaderInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/HeaderInterface.php', + 'Guzzle\\Http\\Message\\Header\\Link' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Header/Link.php', + 'Guzzle\\Http\\Message\\MessageInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/MessageInterface.php', + 'Guzzle\\Http\\Message\\PostFile' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/PostFile.php', + 'Guzzle\\Http\\Message\\PostFileInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/PostFileInterface.php', + 'Guzzle\\Http\\Message\\Request' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Request.php', + 'Guzzle\\Http\\Message\\RequestFactory' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/RequestFactory.php', + 'Guzzle\\Http\\Message\\RequestFactoryInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/RequestFactoryInterface.php', + 'Guzzle\\Http\\Message\\RequestInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/RequestInterface.php', + 'Guzzle\\Http\\Message\\Response' => $vendorDir . '/guzzle/http/Guzzle/Http/Message/Response.php', + 'Guzzle\\Http\\Mimetypes' => $vendorDir . '/guzzle/http/Guzzle/Http/Mimetypes.php', + 'Guzzle\\Http\\QueryAggregator\\CommaAggregator' => $vendorDir . '/guzzle/http/Guzzle/Http/QueryAggregator/CommaAggregator.php', + 'Guzzle\\Http\\QueryAggregator\\DuplicateAggregator' => $vendorDir . '/guzzle/http/Guzzle/Http/QueryAggregator/DuplicateAggregator.php', + 'Guzzle\\Http\\QueryAggregator\\PhpAggregator' => $vendorDir . '/guzzle/http/Guzzle/Http/QueryAggregator/PhpAggregator.php', + 'Guzzle\\Http\\QueryAggregator\\QueryAggregatorInterface' => $vendorDir . '/guzzle/http/Guzzle/Http/QueryAggregator/QueryAggregatorInterface.php', + 'Guzzle\\Http\\QueryString' => $vendorDir . '/guzzle/http/Guzzle/Http/QueryString.php', + 'Guzzle\\Http\\ReadLimitEntityBody' => $vendorDir . '/guzzle/http/Guzzle/Http/ReadLimitEntityBody.php', + 'Guzzle\\Http\\RedirectPlugin' => $vendorDir . '/guzzle/http/Guzzle/Http/RedirectPlugin.php', + 'Guzzle\\Http\\StaticClient' => $vendorDir . '/guzzle/http/Guzzle/Http/StaticClient.php', + 'Guzzle\\Http\\Url' => $vendorDir . '/guzzle/http/Guzzle/Http/Url.php', + 'Guzzle\\Parser\\Cookie\\CookieParser' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Cookie/CookieParser.php', + 'Guzzle\\Parser\\Cookie\\CookieParserInterface' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Cookie/CookieParserInterface.php', + 'Guzzle\\Parser\\Message\\AbstractMessageParser' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Message/AbstractMessageParser.php', + 'Guzzle\\Parser\\Message\\MessageParser' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Message/MessageParser.php', + 'Guzzle\\Parser\\Message\\MessageParserInterface' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Message/MessageParserInterface.php', + 'Guzzle\\Parser\\Message\\PeclHttpMessageParser' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Message/PeclHttpMessageParser.php', + 'Guzzle\\Parser\\ParserRegistry' => $vendorDir . '/guzzle/parser/Guzzle/Parser/ParserRegistry.php', + 'Guzzle\\Parser\\UriTemplate\\PeclUriTemplate' => $vendorDir . '/guzzle/parser/Guzzle/Parser/UriTemplate/PeclUriTemplate.php', + 'Guzzle\\Parser\\UriTemplate\\UriTemplate' => $vendorDir . '/guzzle/parser/Guzzle/Parser/UriTemplate/UriTemplate.php', + 'Guzzle\\Parser\\UriTemplate\\UriTemplateInterface' => $vendorDir . '/guzzle/parser/Guzzle/Parser/UriTemplate/UriTemplateInterface.php', + 'Guzzle\\Parser\\Url\\UrlParser' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Url/UrlParser.php', + 'Guzzle\\Parser\\Url\\UrlParserInterface' => $vendorDir . '/guzzle/parser/Guzzle/Parser/Url/UrlParserInterface.php', + 'Guzzle\\Stream\\PhpStreamRequestFactory' => $vendorDir . '/guzzle/stream/Guzzle/Stream/PhpStreamRequestFactory.php', + 'Guzzle\\Stream\\Stream' => $vendorDir . '/guzzle/stream/Guzzle/Stream/Stream.php', + 'Guzzle\\Stream\\StreamInterface' => $vendorDir . '/guzzle/stream/Guzzle/Stream/StreamInterface.php', + 'Guzzle\\Stream\\StreamRequestFactoryInterface' => $vendorDir . '/guzzle/stream/Guzzle/Stream/StreamRequestFactoryInterface.php', + 'Icewind\\Streams\\CallbackWrapper' => $vendorDir . '/icewind/streams/src/CallbackWrapper.php', + 'Icewind\\Streams\\Directory' => $vendorDir . '/icewind/streams/src/Directory.php', + 'Icewind\\Streams\\DirectoryFilter' => $vendorDir . '/icewind/streams/src/DirectoryFilter.php', + 'Icewind\\Streams\\DirectoryWrapper' => $vendorDir . '/icewind/streams/src/DirectoryWrapper.php', + 'Icewind\\Streams\\File' => $vendorDir . '/icewind/streams/src/File.php', + 'Icewind\\Streams\\IteratorDirectory' => $vendorDir . '/icewind/streams/src/IteratorDirectory.php', + 'Icewind\\Streams\\NullWrapper' => $vendorDir . '/icewind/streams/src/NullWrapper.php', + 'Icewind\\Streams\\Path' => $vendorDir . '/icewind/streams/src/Path.php', + 'Icewind\\Streams\\RetryWrapper' => $vendorDir . '/icewind/streams/src/RetryWrapper.php', + 'Icewind\\Streams\\SeekableWrapper' => $vendorDir . '/icewind/streams/src/SeekableWrapper.php', + 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', + 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', + 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', + 'InterfaSys\\LogNormalizer\\Normalizer' => $vendorDir . '/interfasys/lognormalizer/src/Normalizer.php', + 'League\\Flysystem\\AdapterInterface' => $vendorDir . '/league/flysystem/src/AdapterInterface.php', + 'League\\Flysystem\\Adapter\\AbstractAdapter' => $vendorDir . '/league/flysystem/src/Adapter/AbstractAdapter.php', + 'League\\Flysystem\\Adapter\\AbstractFtpAdapter' => $vendorDir . '/league/flysystem/src/Adapter/AbstractFtpAdapter.php', + 'League\\Flysystem\\Adapter\\Ftp' => $vendorDir . '/league/flysystem/src/Adapter/Ftp.php', + 'League\\Flysystem\\Adapter\\Ftpd' => $vendorDir . '/league/flysystem/src/Adapter/Ftpd.php', + 'League\\Flysystem\\Adapter\\Local' => $vendorDir . '/league/flysystem/src/Adapter/Local.php', + 'League\\Flysystem\\Adapter\\NullAdapter' => $vendorDir . '/league/flysystem/src/Adapter/NullAdapter.php', + 'League\\Flysystem\\Adapter\\Polyfill\\NotSupportingVisibilityTrait' => $vendorDir . '/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php', + 'League\\Flysystem\\Adapter\\Polyfill\\StreamedCopyTrait' => $vendorDir . '/league/flysystem/src/Adapter/Polyfill/StreamedCopyTrait.php', + 'League\\Flysystem\\Adapter\\Polyfill\\StreamedReadingTrait' => $vendorDir . '/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php', + 'League\\Flysystem\\Adapter\\Polyfill\\StreamedTrait' => $vendorDir . '/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php', + 'League\\Flysystem\\Adapter\\Polyfill\\StreamedWritingTrait' => $vendorDir . '/league/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php', + 'League\\Flysystem\\Adapter\\SynologyFtp' => $vendorDir . '/league/flysystem/src/Adapter/SynologyFtp.php', + 'League\\Flysystem\\Config' => $vendorDir . '/league/flysystem/src/Config.php', + 'League\\Flysystem\\ConfigAwareTrait' => $vendorDir . '/league/flysystem/src/ConfigAwareTrait.php', + 'League\\Flysystem\\Directory' => $vendorDir . '/league/flysystem/src/Directory.php', + 'League\\Flysystem\\Exception' => $vendorDir . '/league/flysystem/src/Exception.php', + 'League\\Flysystem\\File' => $vendorDir . '/league/flysystem/src/File.php', + 'League\\Flysystem\\FileExistsException' => $vendorDir . '/league/flysystem/src/FileExistsException.php', + 'League\\Flysystem\\FileNotFoundException' => $vendorDir . '/league/flysystem/src/FileNotFoundException.php', + 'League\\Flysystem\\Filesystem' => $vendorDir . '/league/flysystem/src/Filesystem.php', + 'League\\Flysystem\\FilesystemInterface' => $vendorDir . '/league/flysystem/src/FilesystemInterface.php', + 'League\\Flysystem\\Handler' => $vendorDir . '/league/flysystem/src/Handler.php', + 'League\\Flysystem\\MountManager' => $vendorDir . '/league/flysystem/src/MountManager.php', + 'League\\Flysystem\\NotSupportedException' => $vendorDir . '/league/flysystem/src/NotSupportedException.php', + 'League\\Flysystem\\PluginInterface' => $vendorDir . '/league/flysystem/src/PluginInterface.php', + 'League\\Flysystem\\Plugin\\AbstractPlugin' => $vendorDir . '/league/flysystem/src/Plugin/AbstractPlugin.php', + 'League\\Flysystem\\Plugin\\EmptyDir' => $vendorDir . '/league/flysystem/src/Plugin/EmptyDir.php', + 'League\\Flysystem\\Plugin\\GetWithMetadata' => $vendorDir . '/league/flysystem/src/Plugin/GetWithMetadata.php', + 'League\\Flysystem\\Plugin\\ListFiles' => $vendorDir . '/league/flysystem/src/Plugin/ListFiles.php', + 'League\\Flysystem\\Plugin\\ListPaths' => $vendorDir . '/league/flysystem/src/Plugin/ListPaths.php', + 'League\\Flysystem\\Plugin\\ListWith' => $vendorDir . '/league/flysystem/src/Plugin/ListWith.php', + 'League\\Flysystem\\Plugin\\PluggableTrait' => $vendorDir . '/league/flysystem/src/Plugin/PluggableTrait.php', + 'League\\Flysystem\\Plugin\\PluginNotFoundException' => $vendorDir . '/league/flysystem/src/Plugin/PluginNotFoundException.php', + 'League\\Flysystem\\ReadInterface' => $vendorDir . '/league/flysystem/src/ReadInterface.php', + 'League\\Flysystem\\RootViolationException' => $vendorDir . '/league/flysystem/src/RootViolationException.php', + 'League\\Flysystem\\UnreadableFileException' => $vendorDir . '/league/flysystem/src/UnreadableFileException.php', + 'League\\Flysystem\\Util' => $vendorDir . '/league/flysystem/src/Util.php', + 'League\\Flysystem\\Util\\ContentListingFormatter' => $vendorDir . '/league/flysystem/src/Util/ContentListingFormatter.php', + 'League\\Flysystem\\Util\\MimeType' => $vendorDir . '/league/flysystem/src/Util/MimeType.php', + 'Normalizer' => $vendorDir . '/patchwork/utf8/src/Normalizer.php', + 'OS_Guess' => $vendorDir . '/pear/pear-core-minimal/src/OS/Guess.php', + 'OpenCloud\\Autoscale\\Resource\\AbstractResource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/AbstractResource.php', + 'OpenCloud\\Autoscale\\Resource\\Group' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/Group.php', + 'OpenCloud\\Autoscale\\Resource\\GroupConfiguration' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/GroupConfiguration.php', + 'OpenCloud\\Autoscale\\Resource\\LaunchConfiguration' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/LaunchConfiguration.php', + 'OpenCloud\\Autoscale\\Resource\\ScalingPolicy' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/ScalingPolicy.php', + 'OpenCloud\\Autoscale\\Resource\\Webhook' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Resource/Webhook.php', + 'OpenCloud\\Autoscale\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Autoscale/Service.php', + 'OpenCloud\\CloudMonitoring\\Exception\\AgentException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/AgentException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\AlarmException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/AlarmException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\CheckException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/CheckException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\CloudMonitoringException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/CloudMonitoringException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\EntityException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/EntityException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\MetricException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/MetricException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\NotificationHistoryException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/NotificationHistoryException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\NotificationPlanException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/NotificationPlanException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\ServiceException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/ServiceException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\TestException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/TestException.php', + 'OpenCloud\\CloudMonitoring\\Exception\\ZoneException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Exception/ZoneException.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AbstractResource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AbstractResource.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Agent' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Agent.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AgentConnection' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AgentConnection.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AgentHost' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AgentHost.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AgentHostInfo' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AgentHostInfo.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AgentTarget' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AgentTarget.php', + 'OpenCloud\\CloudMonitoring\\Resource\\AgentToken' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/AgentToken.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Alarm' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Alarm.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Changelog' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Changelog.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Check' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Check.php', + 'OpenCloud\\CloudMonitoring\\Resource\\CheckType' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/CheckType.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Entity' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Entity.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Metric' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Metric.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Notification' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Notification.php', + 'OpenCloud\\CloudMonitoring\\Resource\\NotificationHistory' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/NotificationHistory.php', + 'OpenCloud\\CloudMonitoring\\Resource\\NotificationPlan' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/NotificationPlan.php', + 'OpenCloud\\CloudMonitoring\\Resource\\NotificationType' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/NotificationType.php', + 'OpenCloud\\CloudMonitoring\\Resource\\ReadonlyResource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/ReadOnlyResource.php', + 'OpenCloud\\CloudMonitoring\\Resource\\View' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/View.php', + 'OpenCloud\\CloudMonitoring\\Resource\\Zone' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Resource/Zone.php', + 'OpenCloud\\CloudMonitoring\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/CloudMonitoring/Service.php', + 'OpenCloud\\Common\\Base' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Base.php', + 'OpenCloud\\Common\\Collection' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Collection.php', + 'OpenCloud\\Common\\Collection\\ArrayCollection' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Collection/ArrayCollection.php', + 'OpenCloud\\Common\\Collection\\PaginatedIterator' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Collection/PaginatedIterator.php', + 'OpenCloud\\Common\\Collection\\ResourceIterator' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Collection/ResourceIterator.php', + 'OpenCloud\\Common\\Constants\\Datetime' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/Datetime.php', + 'OpenCloud\\Common\\Constants\\Header' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/Header.php', + 'OpenCloud\\Common\\Constants\\Mime' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/Mime.php', + 'OpenCloud\\Common\\Constants\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/Service.php', + 'OpenCloud\\Common\\Constants\\Size' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/Size.php', + 'OpenCloud\\Common\\Constants\\State' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Constants/State.php', + 'OpenCloud\\Common\\Exceptions\\AsyncError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncError.php', + 'OpenCloud\\Common\\Exceptions\\AsyncHttpError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncHttpError.php', + 'OpenCloud\\Common\\Exceptions\\AsyncTimeoutError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncTimeoutError.php', + 'OpenCloud\\Common\\Exceptions\\AttributeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/AttributeError.php', + 'OpenCloud\\Common\\Exceptions\\AuthenticationError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/AuthenticationError.php', + 'OpenCloud\\Common\\Exceptions\\BaseException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/BaseException.php', + 'OpenCloud\\Common\\Exceptions\\CdnError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnError.php', + 'OpenCloud\\Common\\Exceptions\\CdnHttpError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnHttpError.php', + 'OpenCloud\\Common\\Exceptions\\CdnNotAvailableError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnNotAvailableError.php', + 'OpenCloud\\Common\\Exceptions\\CdnTtlError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnTtlError.php', + 'OpenCloud\\Common\\Exceptions\\CollectionException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CollectionException.php', + 'OpenCloud\\Common\\Exceptions\\ContainerCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerCreateError.php', + 'OpenCloud\\Common\\Exceptions\\ContainerDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\ContainerError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerError.php', + 'OpenCloud\\Common\\Exceptions\\ContainerNameError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNameError.php', + 'OpenCloud\\Common\\Exceptions\\ContainerNotEmptyError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotEmptyError.php', + 'OpenCloud\\Common\\Exceptions\\ContainerNotFoundError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotFoundError.php', + 'OpenCloud\\Common\\Exceptions\\CreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateError.php', + 'OpenCloud\\Common\\Exceptions\\CreateUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\CredentialError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/CredentialError.php', + 'OpenCloud\\Common\\Exceptions\\DatabaseCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseCreateError.php', + 'OpenCloud\\Common\\Exceptions\\DatabaseDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\DatabaseListError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseListError.php', + 'OpenCloud\\Common\\Exceptions\\DatabaseNameError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseNameError.php', + 'OpenCloud\\Common\\Exceptions\\DatabaseUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\DeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DeleteError.php', + 'OpenCloud\\Common\\Exceptions\\DocumentError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DocumentError.php', + 'OpenCloud\\Common\\Exceptions\\DomainError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/DomainError.php', + 'OpenCloud\\Common\\Exceptions\\EmptyResponseError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/EmptyResponseError.php', + 'OpenCloud\\Common\\Exceptions\\EndpointError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/EndpointError.php', + 'OpenCloud\\Common\\Exceptions\\FlavorError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/FlavorError.php', + 'OpenCloud\\Common\\Exceptions\\HttpError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpError.php', + 'OpenCloud\\Common\\Exceptions\\HttpForbiddenError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpForbiddenError.php', + 'OpenCloud\\Common\\Exceptions\\HttpOverLimitError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpOverLimitError.php', + 'OpenCloud\\Common\\Exceptions\\HttpRetryError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpRetryError.php', + 'OpenCloud\\Common\\Exceptions\\HttpTimeoutError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpTimeoutError.php', + 'OpenCloud\\Common\\Exceptions\\HttpUnauthorizedError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUnauthorizedError.php', + 'OpenCloud\\Common\\Exceptions\\HttpUrlError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUrlError.php', + 'OpenCloud\\Common\\Exceptions\\IOError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/IOError.php', + 'OpenCloud\\Common\\Exceptions\\IdRequiredError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/IdRequiredError.php', + 'OpenCloud\\Common\\Exceptions\\ImageError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ImageError.php', + 'OpenCloud\\Common\\Exceptions\\InstanceCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceCreateError.php', + 'OpenCloud\\Common\\Exceptions\\InstanceDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\InstanceError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceError.php', + 'OpenCloud\\Common\\Exceptions\\InstanceFlavorError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceFlavorError.php', + 'OpenCloud\\Common\\Exceptions\\InstanceNotFound' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceNotFound.php', + 'OpenCloud\\Common\\Exceptions\\InstanceUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\InvalidArgumentError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidArgumentError.php', + 'OpenCloud\\Common\\Exceptions\\InvalidIdTypeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIdTypeError.php', + 'OpenCloud\\Common\\Exceptions\\InvalidIpTypeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIpTypeError.php', + 'OpenCloud\\Common\\Exceptions\\InvalidParameterError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidParameterError.php', + 'OpenCloud\\Common\\Exceptions\\InvalidRequestError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidRequestError.php', + 'OpenCloud\\Common\\Exceptions\\JsonError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/JsonError.php', + 'OpenCloud\\Common\\Exceptions\\LoggingException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/LoggingException.php', + 'OpenCloud\\Common\\Exceptions\\MetadataCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataCreateError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataJsonError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataJsonError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataKeyError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataKeyError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataPrefixError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataPrefixError.php', + 'OpenCloud\\Common\\Exceptions\\MetadataUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\MisMatchedChecksumError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MisMatchedChecksumError.php', + 'OpenCloud\\Common\\Exceptions\\MissingValueError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/MissingValueError.php', + 'OpenCloud\\Common\\Exceptions\\NameError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NameError.php', + 'OpenCloud\\Common\\Exceptions\\NetworkCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkCreateError.php', + 'OpenCloud\\Common\\Exceptions\\NetworkDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\NetworkError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkError.php', + 'OpenCloud\\Common\\Exceptions\\NetworkUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\NetworkUrlError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUrlError.php', + 'OpenCloud\\Common\\Exceptions\\NoContentTypeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NoContentTypeError.php', + 'OpenCloud\\Common\\Exceptions\\NoNameError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/NoNameError.php', + 'OpenCloud\\Common\\Exceptions\\ObjFetchError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjFetchError.php', + 'OpenCloud\\Common\\Exceptions\\ObjectCopyError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectCopyError.php', + 'OpenCloud\\Common\\Exceptions\\ObjectError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectError.php', + 'OpenCloud\\Common\\Exceptions\\RebuildError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/RebuildError.php', + 'OpenCloud\\Common\\Exceptions\\RecordTypeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/RecordTypeError.php', + 'OpenCloud\\Common\\Exceptions\\ResourceBucketException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ResourceBucketException.php', + 'OpenCloud\\Common\\Exceptions\\RuntimeException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/RuntimeException.php', + 'OpenCloud\\Common\\Exceptions\\ServerActionError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerActionError.php', + 'OpenCloud\\Common\\Exceptions\\ServerCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerCreateError.php', + 'OpenCloud\\Common\\Exceptions\\ServerDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\ServerImageScheduleError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerImageScheduleError.php', + 'OpenCloud\\Common\\Exceptions\\ServerIpsError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerIpsError.php', + 'OpenCloud\\Common\\Exceptions\\ServerJsonError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerJsonError.php', + 'OpenCloud\\Common\\Exceptions\\ServerUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\ServerUrlError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUrlError.php', + 'OpenCloud\\Common\\Exceptions\\ServiceException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/ServiceException.php', + 'OpenCloud\\Common\\Exceptions\\SnapshotError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/SnapshotError.php', + 'OpenCloud\\Common\\Exceptions\\TempUrlMethodError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/TempUrlMethodError.php', + 'OpenCloud\\Common\\Exceptions\\UnknownError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownError.php', + 'OpenCloud\\Common\\Exceptions\\UnknownParameterError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownParameterError.php', + 'OpenCloud\\Common\\Exceptions\\UnrecognizedServiceError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnrecognizedServiceError.php', + 'OpenCloud\\Common\\Exceptions\\UnsupportedExtensionError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedExtensionError.php', + 'OpenCloud\\Common\\Exceptions\\UnsupportedFeatureExtension' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedFeatureExtension.php', + 'OpenCloud\\Common\\Exceptions\\UnsupportedVersionError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedVersionError.php', + 'OpenCloud\\Common\\Exceptions\\UpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UpdateError.php', + 'OpenCloud\\Common\\Exceptions\\UrlError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UrlError.php', + 'OpenCloud\\Common\\Exceptions\\UserCreateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UserCreateError.php', + 'OpenCloud\\Common\\Exceptions\\UserDeleteError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UserDeleteError.php', + 'OpenCloud\\Common\\Exceptions\\UserListError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UserListError.php', + 'OpenCloud\\Common\\Exceptions\\UserNameError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UserNameError.php', + 'OpenCloud\\Common\\Exceptions\\UserUpdateError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/UserUpdateError.php', + 'OpenCloud\\Common\\Exceptions\\VolumeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeError.php', + 'OpenCloud\\Common\\Exceptions\\VolumeTypeError' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeTypeError.php', + 'OpenCloud\\Common\\Http\\Client' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Http/Client.php', + 'OpenCloud\\Common\\Http\\Message\\Formatter' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Http/Message/Formatter.php', + 'OpenCloud\\Common\\Http\\Message\\RequestSubscriber' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Http/Message/RequestSubscriber.php', + 'OpenCloud\\Common\\Lang' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Lang.php', + 'OpenCloud\\Common\\Log\\AbstractLogger' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Log/AbstractLogger.php', + 'OpenCloud\\Common\\Log\\LogLevel' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Log/LogLevel.php', + 'OpenCloud\\Common\\Log\\Logger' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Log/Logger.php', + 'OpenCloud\\Common\\Log\\LoggerInterface' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Log/LoggerInterface.php', + 'OpenCloud\\Common\\Metadata' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Metadata.php', + 'OpenCloud\\Common\\PersistentObject' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/PersistentObject.php', + 'OpenCloud\\Common\\Service\\AbstractService' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/AbstractService.php', + 'OpenCloud\\Common\\Service\\Catalog' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/Catalog.php', + 'OpenCloud\\Common\\Service\\CatalogItem' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/CatalogItem.php', + 'OpenCloud\\Common\\Service\\CatalogService' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/CatalogService.php', + 'OpenCloud\\Common\\Service\\Endpoint' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/Endpoint.php', + 'OpenCloud\\Common\\Service\\NovaService' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/NovaService.php', + 'OpenCloud\\Common\\Service\\ServiceBuilder' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/ServiceBuilder.php', + 'OpenCloud\\Common\\Service\\ServiceInterface' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Common/Service/ServiceInterface.php', + 'OpenCloud\\Compute\\Constants\\ImageState' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Constants/ImageState.php', + 'OpenCloud\\Compute\\Constants\\Network' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Constants/Network.php', + 'OpenCloud\\Compute\\Constants\\ServerState' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Constants/ServerState.php', + 'OpenCloud\\Compute\\Exception\\KeyPairException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Exception/KeyPairException.php', + 'OpenCloud\\Compute\\Resource\\Flavor' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/Flavor.php', + 'OpenCloud\\Compute\\Resource\\Image' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/Image.php', + 'OpenCloud\\Compute\\Resource\\KeyPair' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/KeyPair.php', + 'OpenCloud\\Compute\\Resource\\Network' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/Network.php', + 'OpenCloud\\Compute\\Resource\\Server' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/Server.php', + 'OpenCloud\\Compute\\Resource\\ServerMetadata' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/ServerMetadata.php', + 'OpenCloud\\Compute\\Resource\\VolumeAttachment' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Resource/VolumeAttachment.php', + 'OpenCloud\\Compute\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Compute/Service.php', + 'OpenCloud\\DNS\\Collection\\DnsIterator' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Collection/DnsIterator.php', + 'OpenCloud\\DNS\\Resource\\AsyncResponse' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/AsyncResponse.php', + 'OpenCloud\\DNS\\Resource\\Domain' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/Domain.php', + 'OpenCloud\\DNS\\Resource\\Object' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/Object.php', + 'OpenCloud\\DNS\\Resource\\PtrRecord' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/PtrRecord.php', + 'OpenCloud\\DNS\\Resource\\Record' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/Record.php', + 'OpenCloud\\DNS\\Resource\\Subdomain' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Resource/Subdomain.php', + 'OpenCloud\\DNS\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/DNS/Service.php', + 'OpenCloud\\Database\\Resource\\Database' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Database/Resource/Database.php', + 'OpenCloud\\Database\\Resource\\Instance' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Database/Resource/Instance.php', + 'OpenCloud\\Database\\Resource\\User' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Database/Resource/User.php', + 'OpenCloud\\Database\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Database/Service.php', + 'OpenCloud\\Identity\\Constants\\User' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Constants/User.php', + 'OpenCloud\\Identity\\Resource\\Role' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Resource/Role.php', + 'OpenCloud\\Identity\\Resource\\Tenant' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Resource/Tenant.php', + 'OpenCloud\\Identity\\Resource\\Token' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Resource/Token.php', + 'OpenCloud\\Identity\\Resource\\User' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Resource/User.php', + 'OpenCloud\\Identity\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Identity/Service.php', + 'OpenCloud\\LoadBalancer\\Resource\\Access' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Access.php', + 'OpenCloud\\LoadBalancer\\Resource\\Algorithm' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Algorithm.php', + 'OpenCloud\\LoadBalancer\\Resource\\AllowedDomain' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/AllowedDomain.php', + 'OpenCloud\\LoadBalancer\\Resource\\BillableLoadBalancer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/BillableLoadBalancer.php', + 'OpenCloud\\LoadBalancer\\Resource\\ConnectionLogging' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/ConnectionLogging.php', + 'OpenCloud\\LoadBalancer\\Resource\\ConnectionThrottle' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/ConnectionThrottle.php', + 'OpenCloud\\LoadBalancer\\Resource\\ContentCaching' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/ContentCaching.php', + 'OpenCloud\\LoadBalancer\\Resource\\ErrorPage' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/ErrorPage.php', + 'OpenCloud\\LoadBalancer\\Resource\\HealthMonitor' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/HealthMonitor.php', + 'OpenCloud\\LoadBalancer\\Resource\\LoadBalancer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/LoadBalancer.php', + 'OpenCloud\\LoadBalancer\\Resource\\Metadata' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Metadata.php', + 'OpenCloud\\LoadBalancer\\Resource\\Node' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Node.php', + 'OpenCloud\\LoadBalancer\\Resource\\NodeEvent' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/NodeEvent.php', + 'OpenCloud\\LoadBalancer\\Resource\\Protocol' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Protocol.php', + 'OpenCloud\\LoadBalancer\\Resource\\Readonly' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Readonly.php', + 'OpenCloud\\LoadBalancer\\Resource\\SSLTermination' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/SSLTermination.php', + 'OpenCloud\\LoadBalancer\\Resource\\SessionPersistence' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/SessionPersistence.php', + 'OpenCloud\\LoadBalancer\\Resource\\Stats' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Stats.php', + 'OpenCloud\\LoadBalancer\\Resource\\SubResource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/SubResource.php', + 'OpenCloud\\LoadBalancer\\Resource\\Usage' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/Usage.php', + 'OpenCloud\\LoadBalancer\\Resource\\VirtualIp' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Resource/VirtualIp.php', + 'OpenCloud\\LoadBalancer\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/LoadBalancer/Service.php', + 'OpenCloud\\ObjectStore\\AbstractService' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/AbstractService.php', + 'OpenCloud\\ObjectStore\\CDNService' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/CDNService.php', + 'OpenCloud\\ObjectStore\\Constants\\Header' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Constants/Header.php', + 'OpenCloud\\ObjectStore\\Constants\\UrlType' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Constants/UrlType.php', + 'OpenCloud\\ObjectStore\\Exception\\BulkOperationException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Exception/BulkOperationException.php', + 'OpenCloud\\ObjectStore\\Exception\\ContainerException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Exception/ContainerException.php', + 'OpenCloud\\ObjectStore\\Exception\\ObjectNotFoundException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Exception/ObjectNotFoundException.php', + 'OpenCloud\\ObjectStore\\Exception\\StreamException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Exception/StreamException.php', + 'OpenCloud\\ObjectStore\\Exception\\UploadException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Exception/UploadException.php', + 'OpenCloud\\ObjectStore\\Resource\\AbstractContainer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/AbstractContainer.php', + 'OpenCloud\\ObjectStore\\Resource\\AbstractResource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/AbstractResource.php', + 'OpenCloud\\ObjectStore\\Resource\\Account' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/Account.php', + 'OpenCloud\\ObjectStore\\Resource\\CDNContainer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php', + 'OpenCloud\\ObjectStore\\Resource\\Container' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/Container.php', + 'OpenCloud\\ObjectStore\\Resource\\ContainerMetadata' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/ContainerMetadata.php', + 'OpenCloud\\ObjectStore\\Resource\\DataObject' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Resource/DataObject.php', + 'OpenCloud\\ObjectStore\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Service.php', + 'OpenCloud\\ObjectStore\\Upload\\AbstractTransfer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/AbstractTransfer.php', + 'OpenCloud\\ObjectStore\\Upload\\ConcurrentTransfer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/ConcurrentTransfer.php', + 'OpenCloud\\ObjectStore\\Upload\\ConsecutiveTransfer' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/ConsecutiveTransfer.php', + 'OpenCloud\\ObjectStore\\Upload\\ContainerMigration' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/ContainerMigration.php', + 'OpenCloud\\ObjectStore\\Upload\\DirectorySync' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/DirectorySync.php', + 'OpenCloud\\ObjectStore\\Upload\\TransferBuilder' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/TransferBuilder.php', + 'OpenCloud\\ObjectStore\\Upload\\TransferPart' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/TransferPart.php', + 'OpenCloud\\ObjectStore\\Upload\\TransferState' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/ObjectStore/Upload/TransferState.php', + 'OpenCloud\\OpenStack' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/OpenStack.php', + 'OpenCloud\\Orchestration\\Resource' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Orchestration/Resource.php', + 'OpenCloud\\Orchestration\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Orchestration/Service.php', + 'OpenCloud\\Orchestration\\Stack' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Orchestration/Stack.php', + 'OpenCloud\\Queues\\Exception\\DeleteMessageException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Exception/DeleteMessageException.php', + 'OpenCloud\\Queues\\Exception\\MessageException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Exception/MessageException.php', + 'OpenCloud\\Queues\\Exception\\QueueException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Exception/QueueException.php', + 'OpenCloud\\Queues\\Exception\\QueueMetadataException' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Exception/QueueMetadataException.php', + 'OpenCloud\\Queues\\Resource\\Claim' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Resource/Claim.php', + 'OpenCloud\\Queues\\Resource\\Message' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Resource/Message.php', + 'OpenCloud\\Queues\\Resource\\Queue' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Resource/Queue.php', + 'OpenCloud\\Queues\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Queues/Service.php', + 'OpenCloud\\Rackspace' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Rackspace.php', + 'OpenCloud\\Version' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Version.php', + 'OpenCloud\\Volume\\Resource\\Snapshot' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Volume/Resource/Snapshot.php', + 'OpenCloud\\Volume\\Resource\\Volume' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Volume/Resource/Volume.php', + 'OpenCloud\\Volume\\Resource\\VolumeType' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Volume/Resource/VolumeType.php', + 'OpenCloud\\Volume\\Service' => $vendorDir . '/rackspace/php-opencloud/lib/OpenCloud/Volume/Service.php', + 'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_Error' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', + 'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php', + 'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php', + 'Patchwork\\JSqueeze' => $vendorDir . '/patchwork/jsqueeze/src/JSqueeze.php', + 'Patchwork\\PHP\\Shim\\Iconv' => $vendorDir . '/patchwork/utf8/src/Patchwork/PHP/Shim/Iconv.php', + 'Patchwork\\PHP\\Shim\\Intl' => $vendorDir . '/patchwork/utf8/src/Patchwork/PHP/Shim/Intl.php', + 'Patchwork\\PHP\\Shim\\Mbstring' => $vendorDir . '/patchwork/utf8/src/Patchwork/PHP/Shim/Mbstring.php', + 'Patchwork\\PHP\\Shim\\Normalizer' => $vendorDir . '/patchwork/utf8/src/Patchwork/PHP/Shim/Normalizer.php', + 'Patchwork\\PHP\\Shim\\Xml' => $vendorDir . '/patchwork/utf8/src/Patchwork/PHP/Shim/Xml.php', + 'Patchwork\\TurkishUtf8' => $vendorDir . '/patchwork/utf8/src/Patchwork/TurkishUtf8.php', + 'Patchwork\\Utf8' => $vendorDir . '/patchwork/utf8/src/Patchwork/Utf8.php', + 'Patchwork\\Utf8\\BestFit' => $vendorDir . '/patchwork/utf8/src/Patchwork/Utf8/BestFit.php', + 'Patchwork\\Utf8\\Bootup' => $vendorDir . '/patchwork/utf8/src/Patchwork/Utf8/Bootup.php', + 'Patchwork\\Utf8\\WindowsStreamWrapper' => $vendorDir . '/patchwork/utf8/src/Patchwork/Utf8/WindowsStreamWrapper.php', + 'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php', + 'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php', + 'Punic\\Calendar' => $vendorDir . '/punic/punic/code/Calendar.php', + 'Punic\\Comparer' => $vendorDir . '/punic/punic/code/Comparer.php', + 'Punic\\Currency' => $vendorDir . '/punic/punic/code/Currency.php', + 'Punic\\Data' => $vendorDir . '/punic/punic/code/Data.php', + 'Punic\\Exception' => $vendorDir . '/punic/punic/code/Exception.php', + 'Punic\\Exception\\BadArgumentType' => $vendorDir . '/punic/punic/code/Exception/BadArgumentType.php', + 'Punic\\Exception\\BadDataFileContents' => $vendorDir . '/punic/punic/code/Exception/BadDataFileContents.php', + 'Punic\\Exception\\DataFileNotFound' => $vendorDir . '/punic/punic/code/Exception/DataFileNotFound.php', + 'Punic\\Exception\\DataFileNotReadable' => $vendorDir . '/punic/punic/code/Exception/DataFileNotReadable.php', + 'Punic\\Exception\\DataFolderNotFound' => $vendorDir . '/punic/punic/code/Exception/DataFolderNotFound.php', + 'Punic\\Exception\\InvalidDataFile' => $vendorDir . '/punic/punic/code/Exception/InvalidDataFile.php', + 'Punic\\Exception\\InvalidLocale' => $vendorDir . '/punic/punic/code/Exception/InvalidLocale.php', + 'Punic\\Exception\\NotImplemented' => $vendorDir . '/punic/punic/code/Exception/NotImplemented.php', + 'Punic\\Exception\\ValueNotInList' => $vendorDir . '/punic/punic/code/Exception/ValueNotInList.php', + 'Punic\\Language' => $vendorDir . '/punic/punic/code/Language.php', + 'Punic\\Misc' => $vendorDir . '/punic/punic/code/Misc.php', + 'Punic\\Number' => $vendorDir . '/punic/punic/code/Number.php', + 'Punic\\Phone' => $vendorDir . '/punic/punic/code/Phone.php', + 'Punic\\Plural' => $vendorDir . '/punic/punic/code/Plural.php', + 'Punic\\Territory' => $vendorDir . '/punic/punic/code/Territory.php', + 'Punic\\Unit' => $vendorDir . '/punic/punic/code/Unit.php', + 'RandomLib\\AbstractMixer' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/AbstractMixer.php', + 'RandomLib\\Factory' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Factory.php', + 'RandomLib\\Generator' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Generator.php', + 'RandomLib\\Mixer' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Mixer.php', + 'RandomLib\\Mixer\\Hash' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Mixer/Hash.php', + 'RandomLib\\Source' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source.php', + 'RandomLib\\Source\\CAPICOM' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/CAPICOM.php', + 'RandomLib\\Source\\MTRand' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/MTRand.php', + 'RandomLib\\Source\\MicroTime' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/MicroTime.php', + 'RandomLib\\Source\\OpenSSL' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/OpenSSL.php', + 'RandomLib\\Source\\Rand' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/Rand.php', + 'RandomLib\\Source\\Random' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/Random.php', + 'RandomLib\\Source\\URandom' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/URandom.php', + 'RandomLib\\Source\\UniqID' => $vendorDir . '/ircmaxell/random-lib/lib/RandomLib/Source/UniqID.php', + 'React\\Promise\\CancellablePromiseInterface' => $vendorDir . '/react/promise/src/CancellablePromiseInterface.php', + 'React\\Promise\\Deferred' => $vendorDir . '/react/promise/src/Deferred.php', + 'React\\Promise\\ExtendedPromiseInterface' => $vendorDir . '/react/promise/src/ExtendedPromiseInterface.php', + 'React\\Promise\\FulfilledPromise' => $vendorDir . '/react/promise/src/FulfilledPromise.php', + 'React\\Promise\\LazyPromise' => $vendorDir . '/react/promise/src/LazyPromise.php', + 'React\\Promise\\Promise' => $vendorDir . '/react/promise/src/Promise.php', + 'React\\Promise\\PromiseInterface' => $vendorDir . '/react/promise/src/PromiseInterface.php', + 'React\\Promise\\PromisorInterface' => $vendorDir . '/react/promise/src/PromisorInterface.php', + 'React\\Promise\\RejectedPromise' => $vendorDir . '/react/promise/src/RejectedPromise.php', + 'React\\Promise\\UnhandledRejectionException' => $vendorDir . '/react/promise/src/UnhandledRejectionException.php', + 'Sabre\\CalDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php', + 'Sabre\\CalDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php', + 'Sabre\\CalDAV\\Backend\\NotificationSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php', + 'Sabre\\CalDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/PDO.php', + 'Sabre\\CalDAV\\Backend\\SchedulingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php', + 'Sabre\\CalDAV\\Backend\\SharingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SharingSupport.php', + 'Sabre\\CalDAV\\Backend\\SubscriptionSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php', + 'Sabre\\CalDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SyncSupport.php', + 'Sabre\\CalDAV\\Calendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Calendar.php', + 'Sabre\\CalDAV\\CalendarHome' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarHome.php', + 'Sabre\\CalDAV\\CalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarObject.php', + 'Sabre\\CalDAV\\CalendarQueryValidator' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarQueryValidator.php', + 'Sabre\\CalDAV\\CalendarRoot' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarRoot.php', + 'Sabre\\CalDAV\\Exception\\InvalidComponentType' => $vendorDir . '/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php', + 'Sabre\\CalDAV\\ICSExportPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/ICSExportPlugin.php', + 'Sabre\\CalDAV\\ICalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendar.php', + 'Sabre\\CalDAV\\ICalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObject.php', + 'Sabre\\CalDAV\\ICalendarObjectContainer' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php', + 'Sabre\\CalDAV\\IShareableCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/IShareableCalendar.php', + 'Sabre\\CalDAV\\ISharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ISharedCalendar.php', + 'Sabre\\CalDAV\\Notifications\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Collection.php', + 'Sabre\\CalDAV\\Notifications\\ICollection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/ICollection.php', + 'Sabre\\CalDAV\\Notifications\\INode' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/INode.php', + 'Sabre\\CalDAV\\Notifications\\Node' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Node.php', + 'Sabre\\CalDAV\\Notifications\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Plugin.php', + 'Sabre\\CalDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Plugin.php', + 'Sabre\\CalDAV\\Principal\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/Collection.php', + 'Sabre\\CalDAV\\Principal\\IProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyRead.php', + 'Sabre\\CalDAV\\Principal\\IProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php', + 'Sabre\\CalDAV\\Principal\\ProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyRead.php', + 'Sabre\\CalDAV\\Principal\\ProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php', + 'Sabre\\CalDAV\\Principal\\User' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/User.php', + 'Sabre\\CalDAV\\Schedule\\IInbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IInbox.php', + 'Sabre\\CalDAV\\Schedule\\IMipPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php', + 'Sabre\\CalDAV\\Schedule\\IOutbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IOutbox.php', + 'Sabre\\CalDAV\\Schedule\\ISchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php', + 'Sabre\\CalDAV\\Schedule\\Inbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Inbox.php', + 'Sabre\\CalDAV\\Schedule\\Outbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Outbox.php', + 'Sabre\\CalDAV\\Schedule\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Plugin.php', + 'Sabre\\CalDAV\\Schedule\\SchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php', + 'Sabre\\CalDAV\\ShareableCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ShareableCalendar.php', + 'Sabre\\CalDAV\\SharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/SharedCalendar.php', + 'Sabre\\CalDAV\\SharingPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/SharingPlugin.php', + 'Sabre\\CalDAV\\Subscriptions\\ISubscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php', + 'Sabre\\CalDAV\\Subscriptions\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php', + 'Sabre\\CalDAV\\Subscriptions\\Subscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php', + 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php', + 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php', + 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php', + 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php', + 'Sabre\\CalDAV\\Xml\\Notification\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php', + 'Sabre\\CalDAV\\Xml\\Notification\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php', + 'Sabre\\CalDAV\\Xml\\Notification\\NotificationInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php', + 'Sabre\\CalDAV\\Xml\\Notification\\SystemStatus' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php', + 'Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php', + 'Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php', + 'Sabre\\CalDAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/Invite.php', + 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php', + 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php', + 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php', + 'Sabre\\CalDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php', + 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php', + 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php', + 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php', + 'Sabre\\CalDAV\\Xml\\Request\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php', + 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php', + 'Sabre\\CalDAV\\Xml\\Request\\Share' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/Share.php', + 'Sabre\\CardDAV\\AddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBook.php', + 'Sabre\\CardDAV\\AddressBookHome' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookHome.php', + 'Sabre\\CardDAV\\AddressBookRoot' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookRoot.php', + 'Sabre\\CardDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php', + 'Sabre\\CardDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/BackendInterface.php', + 'Sabre\\CardDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/PDO.php', + 'Sabre\\CardDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/SyncSupport.php', + 'Sabre\\CardDAV\\Card' => $vendorDir . '/sabre/dav/lib/CardDAV/Card.php', + 'Sabre\\CardDAV\\IAddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/IAddressBook.php', + 'Sabre\\CardDAV\\ICard' => $vendorDir . '/sabre/dav/lib/CardDAV/ICard.php', + 'Sabre\\CardDAV\\IDirectory' => $vendorDir . '/sabre/dav/lib/CardDAV/IDirectory.php', + 'Sabre\\CardDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CardDAV/Plugin.php', + 'Sabre\\CardDAV\\VCFExportPlugin' => $vendorDir . '/sabre/dav/lib/CardDAV/VCFExportPlugin.php', + 'Sabre\\CardDAV\\Xml\\Filter\\AddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php', + 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php', + 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php', + 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php', + 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php', + 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php', + 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php', + 'Sabre\\DAVACL\\AbstractPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php', + 'Sabre\\DAVACL\\Exception\\AceConflict' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/AceConflict.php', + 'Sabre\\DAVACL\\Exception\\NeedPrivileges' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php', + 'Sabre\\DAVACL\\Exception\\NoAbstract' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NoAbstract.php', + 'Sabre\\DAVACL\\Exception\\NotRecognizedPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php', + 'Sabre\\DAVACL\\Exception\\NotSupportedPrivilege' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php', + 'Sabre\\DAVACL\\FS\\Collection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/Collection.php', + 'Sabre\\DAVACL\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/File.php', + 'Sabre\\DAVACL\\FS\\HomeCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/HomeCollection.php', + 'Sabre\\DAVACL\\IACL' => $vendorDir . '/sabre/dav/lib/DAVACL/IACL.php', + 'Sabre\\DAVACL\\IPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipal.php', + 'Sabre\\DAVACL\\IPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipalCollection.php', + 'Sabre\\DAVACL\\Plugin' => $vendorDir . '/sabre/dav/lib/DAVACL/Plugin.php', + 'Sabre\\DAVACL\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Principal.php', + 'Sabre\\DAVACL\\PrincipalBackend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php', + 'Sabre\\DAVACL\\PrincipalBackend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php', + 'Sabre\\DAVACL\\PrincipalBackend\\CreatePrincipalSupport' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php', + 'Sabre\\DAVACL\\PrincipalBackend\\PDO' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php', + 'Sabre\\DAVACL\\PrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalCollection.php', + 'Sabre\\DAVACL\\Xml\\Property\\Acl' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Acl.php', + 'Sabre\\DAVACL\\Xml\\Property\\AclRestrictions' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php', + 'Sabre\\DAVACL\\Xml\\Property\\CurrentUserPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php', + 'Sabre\\DAVACL\\Xml\\Property\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Principal.php', + 'Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php', + 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php', + 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php', + 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php', + 'Sabre\\DAV\\Auth\\Backend\\AbstractBasic' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php', + 'Sabre\\DAV\\Auth\\Backend\\AbstractDigest' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php', + 'Sabre\\DAV\\Auth\\Backend\\Apache' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/Apache.php', + 'Sabre\\DAV\\Auth\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php', + 'Sabre\\DAV\\Auth\\Backend\\BasicCallBack' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php', + 'Sabre\\DAV\\Auth\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/File.php', + 'Sabre\\DAV\\Auth\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/PDO.php', + 'Sabre\\DAV\\Auth\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Plugin.php', + 'Sabre\\DAV\\Browser\\GuessContentType' => $vendorDir . '/sabre/dav/lib/DAV/Browser/GuessContentType.php', + 'Sabre\\DAV\\Browser\\HtmlOutput' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutput.php', + 'Sabre\\DAV\\Browser\\HtmlOutputHelper' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php', + 'Sabre\\DAV\\Browser\\MapGetToPropFind' => $vendorDir . '/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php', + 'Sabre\\DAV\\Browser\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Browser/Plugin.php', + 'Sabre\\DAV\\Browser\\PropFindAll' => $vendorDir . '/sabre/dav/lib/DAV/Browser/PropFindAll.php', + 'Sabre\\DAV\\Client' => $vendorDir . '/sabre/dav/lib/DAV/Client.php', + 'Sabre\\DAV\\Collection' => $vendorDir . '/sabre/dav/lib/DAV/Collection.php', + 'Sabre\\DAV\\CorePlugin' => $vendorDir . '/sabre/dav/lib/DAV/CorePlugin.php', + 'Sabre\\DAV\\Exception' => $vendorDir . '/sabre/dav/lib/DAV/Exception.php', + 'Sabre\\DAV\\Exception\\BadRequest' => $vendorDir . '/sabre/dav/lib/DAV/Exception/BadRequest.php', + 'Sabre\\DAV\\Exception\\Conflict' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Conflict.php', + 'Sabre\\DAV\\Exception\\ConflictingLock' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ConflictingLock.php', + 'Sabre\\DAV\\Exception\\Forbidden' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Forbidden.php', + 'Sabre\\DAV\\Exception\\InsufficientStorage' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InsufficientStorage.php', + 'Sabre\\DAV\\Exception\\InvalidResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidResourceType.php', + 'Sabre\\DAV\\Exception\\InvalidSyncToken' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php', + 'Sabre\\DAV\\Exception\\LengthRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LengthRequired.php', + 'Sabre\\DAV\\Exception\\LockTokenMatchesRequestUri' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php', + 'Sabre\\DAV\\Exception\\Locked' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Locked.php', + 'Sabre\\DAV\\Exception\\MethodNotAllowed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php', + 'Sabre\\DAV\\Exception\\NotAuthenticated' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotAuthenticated.php', + 'Sabre\\DAV\\Exception\\NotFound' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotFound.php', + 'Sabre\\DAV\\Exception\\NotImplemented' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotImplemented.php', + 'Sabre\\DAV\\Exception\\PaymentRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PaymentRequired.php', + 'Sabre\\DAV\\Exception\\PreconditionFailed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PreconditionFailed.php', + 'Sabre\\DAV\\Exception\\ReportNotSupported' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ReportNotSupported.php', + 'Sabre\\DAV\\Exception\\RequestedRangeNotSatisfiable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php', + 'Sabre\\DAV\\Exception\\ServiceUnavailable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php', + 'Sabre\\DAV\\Exception\\TooManyMatches' => $vendorDir . '/sabre/dav/lib/DAV/Exception/TooManyMatches.php', + 'Sabre\\DAV\\Exception\\UnsupportedMediaType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php', + 'Sabre\\DAV\\FSExt\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/Directory.php', + 'Sabre\\DAV\\FSExt\\File' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/File.php', + 'Sabre\\DAV\\FS\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FS/Directory.php', + 'Sabre\\DAV\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAV/FS/File.php', + 'Sabre\\DAV\\FS\\Node' => $vendorDir . '/sabre/dav/lib/DAV/FS/Node.php', + 'Sabre\\DAV\\File' => $vendorDir . '/sabre/dav/lib/DAV/File.php', + 'Sabre\\DAV\\ICollection' => $vendorDir . '/sabre/dav/lib/DAV/ICollection.php', + 'Sabre\\DAV\\IExtendedCollection' => $vendorDir . '/sabre/dav/lib/DAV/IExtendedCollection.php', + 'Sabre\\DAV\\IFile' => $vendorDir . '/sabre/dav/lib/DAV/IFile.php', + 'Sabre\\DAV\\IMoveTarget' => $vendorDir . '/sabre/dav/lib/DAV/IMoveTarget.php', + 'Sabre\\DAV\\IMultiGet' => $vendorDir . '/sabre/dav/lib/DAV/IMultiGet.php', + 'Sabre\\DAV\\INode' => $vendorDir . '/sabre/dav/lib/DAV/INode.php', + 'Sabre\\DAV\\IProperties' => $vendorDir . '/sabre/dav/lib/DAV/IProperties.php', + 'Sabre\\DAV\\IQuota' => $vendorDir . '/sabre/dav/lib/DAV/IQuota.php', + 'Sabre\\DAV\\Locks\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php', + 'Sabre\\DAV\\Locks\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php', + 'Sabre\\DAV\\Locks\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/File.php', + 'Sabre\\DAV\\Locks\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/PDO.php', + 'Sabre\\DAV\\Locks\\LockInfo' => $vendorDir . '/sabre/dav/lib/DAV/Locks/LockInfo.php', + 'Sabre\\DAV\\Locks\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Plugin.php', + 'Sabre\\DAV\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/MkCol.php', + 'Sabre\\DAV\\Mount\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Mount/Plugin.php', + 'Sabre\\DAV\\Node' => $vendorDir . '/sabre/dav/lib/DAV/Node.php', + 'Sabre\\DAV\\PartialUpdate\\IPatchSupport' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php', + 'Sabre\\DAV\\PartialUpdate\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/Plugin.php', + 'Sabre\\DAV\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/PropFind.php', + 'Sabre\\DAV\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/PropPatch.php', + 'Sabre\\DAV\\PropertyStorage\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php', + 'Sabre\\DAV\\PropertyStorage\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php', + 'Sabre\\DAV\\PropertyStorage\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Plugin.php', + 'Sabre\\DAV\\Server' => $vendorDir . '/sabre/dav/lib/DAV/Server.php', + 'Sabre\\DAV\\ServerPlugin' => $vendorDir . '/sabre/dav/lib/DAV/ServerPlugin.php', + 'Sabre\\DAV\\SimpleCollection' => $vendorDir . '/sabre/dav/lib/DAV/SimpleCollection.php', + 'Sabre\\DAV\\SimpleFile' => $vendorDir . '/sabre/dav/lib/DAV/SimpleFile.php', + 'Sabre\\DAV\\StringUtil' => $vendorDir . '/sabre/dav/lib/DAV/StringUtil.php', + 'Sabre\\DAV\\Sync\\ISyncCollection' => $vendorDir . '/sabre/dav/lib/DAV/Sync/ISyncCollection.php', + 'Sabre\\DAV\\Sync\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sync/Plugin.php', + 'Sabre\\DAV\\TemporaryFileFilterPlugin' => $vendorDir . '/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php', + 'Sabre\\DAV\\Tree' => $vendorDir . '/sabre/dav/lib/DAV/Tree.php', + 'Sabre\\DAV\\UUIDUtil' => $vendorDir . '/sabre/dav/lib/DAV/UUIDUtil.php', + 'Sabre\\DAV\\Version' => $vendorDir . '/sabre/dav/lib/DAV/Version.php', + 'Sabre\\DAV\\Xml\\Element\\Prop' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Prop.php', + 'Sabre\\DAV\\Xml\\Element\\Response' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Response.php', + 'Sabre\\DAV\\Xml\\Property\\Complex' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Complex.php', + 'Sabre\\DAV\\Xml\\Property\\GetLastModified' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php', + 'Sabre\\DAV\\Xml\\Property\\Href' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Href.php', + 'Sabre\\DAV\\Xml\\Property\\LockDiscovery' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php', + 'Sabre\\DAV\\Xml\\Property\\ResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ResourceType.php', + 'Sabre\\DAV\\Xml\\Property\\SupportedLock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php', + 'Sabre\\DAV\\Xml\\Property\\SupportedMethodSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php', + 'Sabre\\DAV\\Xml\\Property\\SupportedReportSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php', + 'Sabre\\DAV\\Xml\\Request\\Lock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/Lock.php', + 'Sabre\\DAV\\Xml\\Request\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/MkCol.php', + 'Sabre\\DAV\\Xml\\Request\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropFind.php', + 'Sabre\\DAV\\Xml\\Request\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropPatch.php', + 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php', + 'Sabre\\DAV\\Xml\\Response\\MultiStatus' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php', + 'Sabre\\DAV\\Xml\\Service' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Service.php', + 'Sabre\\Event\\EventEmitter' => $vendorDir . '/sabre/event/lib/EventEmitter.php', + 'Sabre\\Event\\EventEmitterInterface' => $vendorDir . '/sabre/event/lib/EventEmitterInterface.php', + 'Sabre\\Event\\EventEmitterTrait' => $vendorDir . '/sabre/event/lib/EventEmitterTrait.php', + 'Sabre\\Event\\Promise' => $vendorDir . '/sabre/event/lib/Promise.php', + 'Sabre\\Event\\PromiseAlreadyResolvedException' => $vendorDir . '/sabre/event/lib/PromiseAlreadyResolvedException.php', + 'Sabre\\Event\\Version' => $vendorDir . '/sabre/event/lib/Version.php', + 'Sabre\\HTTP\\Auth\\AWS' => $vendorDir . '/sabre/http/lib/Auth/AWS.php', + 'Sabre\\HTTP\\Auth\\AbstractAuth' => $vendorDir . '/sabre/http/lib/Auth/AbstractAuth.php', + 'Sabre\\HTTP\\Auth\\Basic' => $vendorDir . '/sabre/http/lib/Auth/Basic.php', + 'Sabre\\HTTP\\Auth\\Bearer' => $vendorDir . '/sabre/http/lib/Auth/Bearer.php', + 'Sabre\\HTTP\\Auth\\Digest' => $vendorDir . '/sabre/http/lib/Auth/Digest.php', + 'Sabre\\HTTP\\Client' => $vendorDir . '/sabre/http/lib/Client.php', + 'Sabre\\HTTP\\ClientException' => $vendorDir . '/sabre/http/lib/ClientException.php', + 'Sabre\\HTTP\\ClientHttpException' => $vendorDir . '/sabre/http/lib/ClientHttpException.php', + 'Sabre\\HTTP\\HttpException' => $vendorDir . '/sabre/http/lib/HttpException.php', + 'Sabre\\HTTP\\Message' => $vendorDir . '/sabre/http/lib/Message.php', + 'Sabre\\HTTP\\MessageDecoratorTrait' => $vendorDir . '/sabre/http/lib/MessageDecoratorTrait.php', + 'Sabre\\HTTP\\MessageInterface' => $vendorDir . '/sabre/http/lib/MessageInterface.php', + 'Sabre\\HTTP\\Request' => $vendorDir . '/sabre/http/lib/Request.php', + 'Sabre\\HTTP\\RequestDecorator' => $vendorDir . '/sabre/http/lib/RequestDecorator.php', + 'Sabre\\HTTP\\RequestInterface' => $vendorDir . '/sabre/http/lib/RequestInterface.php', + 'Sabre\\HTTP\\Response' => $vendorDir . '/sabre/http/lib/Response.php', + 'Sabre\\HTTP\\ResponseDecorator' => $vendorDir . '/sabre/http/lib/ResponseDecorator.php', + 'Sabre\\HTTP\\ResponseInterface' => $vendorDir . '/sabre/http/lib/ResponseInterface.php', + 'Sabre\\HTTP\\Sapi' => $vendorDir . '/sabre/http/lib/Sapi.php', + 'Sabre\\HTTP\\URLUtil' => $vendorDir . '/sabre/http/lib/URLUtil.php', + 'Sabre\\HTTP\\Util' => $vendorDir . '/sabre/http/lib/Util.php', + 'Sabre\\HTTP\\Version' => $vendorDir . '/sabre/http/lib/Version.php', + 'Sabre\\Uri\\Version' => $vendorDir . '/sabre/uri/lib/Version.php', + 'Sabre\\VObject\\Cli' => $vendorDir . '/sabre/vobject/lib/Cli.php', + 'Sabre\\VObject\\Component' => $vendorDir . '/sabre/vobject/lib/Component.php', + 'Sabre\\VObject\\Component\\Available' => $vendorDir . '/sabre/vobject/lib/Component/Available.php', + 'Sabre\\VObject\\Component\\VAlarm' => $vendorDir . '/sabre/vobject/lib/Component/VAlarm.php', + 'Sabre\\VObject\\Component\\VAvailability' => $vendorDir . '/sabre/vobject/lib/Component/VAvailability.php', + 'Sabre\\VObject\\Component\\VCalendar' => $vendorDir . '/sabre/vobject/lib/Component/VCalendar.php', + 'Sabre\\VObject\\Component\\VCard' => $vendorDir . '/sabre/vobject/lib/Component/VCard.php', + 'Sabre\\VObject\\Component\\VEvent' => $vendorDir . '/sabre/vobject/lib/Component/VEvent.php', + 'Sabre\\VObject\\Component\\VFreeBusy' => $vendorDir . '/sabre/vobject/lib/Component/VFreeBusy.php', + 'Sabre\\VObject\\Component\\VJournal' => $vendorDir . '/sabre/vobject/lib/Component/VJournal.php', + 'Sabre\\VObject\\Component\\VTimeZone' => $vendorDir . '/sabre/vobject/lib/Component/VTimeZone.php', + 'Sabre\\VObject\\Component\\VTodo' => $vendorDir . '/sabre/vobject/lib/Component/VTodo.php', + 'Sabre\\VObject\\DateTimeParser' => $vendorDir . '/sabre/vobject/lib/DateTimeParser.php', + 'Sabre\\VObject\\Document' => $vendorDir . '/sabre/vobject/lib/Document.php', + 'Sabre\\VObject\\ElementList' => $vendorDir . '/sabre/vobject/lib/ElementList.php', + 'Sabre\\VObject\\EofException' => $vendorDir . '/sabre/vobject/lib/EofException.php', + 'Sabre\\VObject\\FreeBusyGenerator' => $vendorDir . '/sabre/vobject/lib/FreeBusyGenerator.php', + 'Sabre\\VObject\\ITip\\Broker' => $vendorDir . '/sabre/vobject/lib/ITip/Broker.php', + 'Sabre\\VObject\\ITip\\ITipException' => $vendorDir . '/sabre/vobject/lib/ITip/ITipException.php', + 'Sabre\\VObject\\ITip\\Message' => $vendorDir . '/sabre/vobject/lib/ITip/Message.php', + 'Sabre\\VObject\\ITip\\SameOrganizerForAllComponentsException' => $vendorDir . '/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php', + 'Sabre\\VObject\\Node' => $vendorDir . '/sabre/vobject/lib/Node.php', + 'Sabre\\VObject\\Parameter' => $vendorDir . '/sabre/vobject/lib/Parameter.php', + 'Sabre\\VObject\\ParseException' => $vendorDir . '/sabre/vobject/lib/ParseException.php', + 'Sabre\\VObject\\Parser\\Json' => $vendorDir . '/sabre/vobject/lib/Parser/Json.php', + 'Sabre\\VObject\\Parser\\MimeDir' => $vendorDir . '/sabre/vobject/lib/Parser/MimeDir.php', + 'Sabre\\VObject\\Parser\\Parser' => $vendorDir . '/sabre/vobject/lib/Parser/Parser.php', + 'Sabre\\VObject\\Property' => $vendorDir . '/sabre/vobject/lib/Property.php', + 'Sabre\\VObject\\Property\\Binary' => $vendorDir . '/sabre/vobject/lib/Property/Binary.php', + 'Sabre\\VObject\\Property\\Boolean' => $vendorDir . '/sabre/vobject/lib/Property/Boolean.php', + 'Sabre\\VObject\\Property\\FlatText' => $vendorDir . '/sabre/vobject/lib/Property/FlatText.php', + 'Sabre\\VObject\\Property\\FloatValue' => $vendorDir . '/sabre/vobject/lib/Property/FloatValue.php', + 'Sabre\\VObject\\Property\\ICalendar\\CalAddress' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/CalAddress.php', + 'Sabre\\VObject\\Property\\ICalendar\\Date' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Date.php', + 'Sabre\\VObject\\Property\\ICalendar\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/DateTime.php', + 'Sabre\\VObject\\Property\\ICalendar\\Duration' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Duration.php', + 'Sabre\\VObject\\Property\\ICalendar\\Period' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Period.php', + 'Sabre\\VObject\\Property\\ICalendar\\Recur' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Recur.php', + 'Sabre\\VObject\\Property\\IntegerValue' => $vendorDir . '/sabre/vobject/lib/Property/IntegerValue.php', + 'Sabre\\VObject\\Property\\Text' => $vendorDir . '/sabre/vobject/lib/Property/Text.php', + 'Sabre\\VObject\\Property\\Time' => $vendorDir . '/sabre/vobject/lib/Property/Time.php', + 'Sabre\\VObject\\Property\\Unknown' => $vendorDir . '/sabre/vobject/lib/Property/Unknown.php', + 'Sabre\\VObject\\Property\\Uri' => $vendorDir . '/sabre/vobject/lib/Property/Uri.php', + 'Sabre\\VObject\\Property\\UtcOffset' => $vendorDir . '/sabre/vobject/lib/Property/UtcOffset.php', + 'Sabre\\VObject\\Property\\VCard\\Date' => $vendorDir . '/sabre/vobject/lib/Property/VCard/Date.php', + 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateAndOrTime.php', + 'Sabre\\VObject\\Property\\VCard\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateTime.php', + 'Sabre\\VObject\\Property\\VCard\\LanguageTag' => $vendorDir . '/sabre/vobject/lib/Property/VCard/LanguageTag.php', + 'Sabre\\VObject\\Property\\VCard\\TimeStamp' => $vendorDir . '/sabre/vobject/lib/Property/VCard/TimeStamp.php', + 'Sabre\\VObject\\Reader' => $vendorDir . '/sabre/vobject/lib/Reader.php', + 'Sabre\\VObject\\Recur\\EventIterator' => $vendorDir . '/sabre/vobject/lib/Recur/EventIterator.php', + 'Sabre\\VObject\\Recur\\NoInstancesException' => $vendorDir . '/sabre/vobject/lib/Recur/NoInstancesException.php', + 'Sabre\\VObject\\Recur\\RDateIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RDateIterator.php', + 'Sabre\\VObject\\Recur\\RRuleIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RRuleIterator.php', + 'Sabre\\VObject\\RecurrenceIterator' => $vendorDir . '/sabre/vobject/lib/RecurrenceIterator.php', + 'Sabre\\VObject\\Splitter\\ICalendar' => $vendorDir . '/sabre/vobject/lib/Splitter/ICalendar.php', + 'Sabre\\VObject\\Splitter\\SplitterInterface' => $vendorDir . '/sabre/vobject/lib/Splitter/SplitterInterface.php', + 'Sabre\\VObject\\Splitter\\VCard' => $vendorDir . '/sabre/vobject/lib/Splitter/VCard.php', + 'Sabre\\VObject\\StringUtil' => $vendorDir . '/sabre/vobject/lib/StringUtil.php', + 'Sabre\\VObject\\TimeZoneUtil' => $vendorDir . '/sabre/vobject/lib/TimeZoneUtil.php', + 'Sabre\\VObject\\UUIDUtil' => $vendorDir . '/sabre/vobject/lib/UUIDUtil.php', + 'Sabre\\VObject\\VCardConverter' => $vendorDir . '/sabre/vobject/lib/VCardConverter.php', + 'Sabre\\VObject\\Version' => $vendorDir . '/sabre/vobject/lib/Version.php', + 'Sabre\\Xml\\ContextStackTrait' => $vendorDir . '/sabre/xml/lib/ContextStackTrait.php', + 'Sabre\\Xml\\Element' => $vendorDir . '/sabre/xml/lib/Element.php', + 'Sabre\\Xml\\Element\\Base' => $vendorDir . '/sabre/xml/lib/Element/Base.php', + 'Sabre\\Xml\\Element\\Cdata' => $vendorDir . '/sabre/xml/lib/Element/Cdata.php', + 'Sabre\\Xml\\Element\\Elements' => $vendorDir . '/sabre/xml/lib/Element/Elements.php', + 'Sabre\\Xml\\Element\\KeyValue' => $vendorDir . '/sabre/xml/lib/Element/KeyValue.php', + 'Sabre\\Xml\\Element\\Uri' => $vendorDir . '/sabre/xml/lib/Element/Uri.php', + 'Sabre\\Xml\\Element\\XmlFragment' => $vendorDir . '/sabre/xml/lib/Element/XmlFragment.php', + 'Sabre\\Xml\\LibXMLException' => $vendorDir . '/sabre/xml/lib/LibXMLException.php', + 'Sabre\\Xml\\ParseException' => $vendorDir . '/sabre/xml/lib/ParseException.php', + 'Sabre\\Xml\\Reader' => $vendorDir . '/sabre/xml/lib/Reader.php', + 'Sabre\\Xml\\Service' => $vendorDir . '/sabre/xml/lib/Service.php', + 'Sabre\\Xml\\Version' => $vendorDir . '/sabre/xml/lib/Version.php', + 'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php', + 'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php', + 'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php', + 'SecurityLib\\AbstractFactory' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/AbstractFactory.php', + 'SecurityLib\\BaseConverter' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/BaseConverter.php', + 'SecurityLib\\BigMath' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/BigMath.php', + 'SecurityLib\\BigMath\\BCMath' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/BigMath/BCMath.php', + 'SecurityLib\\BigMath\\GMP' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/BigMath/GMP.php', + 'SecurityLib\\BigMath\\PHPMath' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/BigMath/PHPMath.php', + 'SecurityLib\\Enum' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/Enum.php', + 'SecurityLib\\Hash' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/Hash.php', + 'SecurityLib\\Strength' => $vendorDir . '/ircmaxell/security-lib/lib/SecurityLib/Strength.php', + 'SuperClosure\\Analyzer\\AstAnalyzer' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/AstAnalyzer.php', + 'SuperClosure\\Analyzer\\ClosureAnalyzer' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/ClosureAnalyzer.php', + 'SuperClosure\\Analyzer\\Token' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/Token.php', + 'SuperClosure\\Analyzer\\TokenAnalyzer' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/TokenAnalyzer.php', + 'SuperClosure\\Analyzer\\Visitor\\ClosureLocatorVisitor' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/Visitor/ClosureLocatorVisitor.php', + 'SuperClosure\\Analyzer\\Visitor\\MagicConstantVisitor' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/Visitor/MagicConstantVisitor.php', + 'SuperClosure\\Analyzer\\Visitor\\ThisDetectorVisitor' => $vendorDir . '/jeremeamia/SuperClosure/src/Analyzer/Visitor/ThisDetectorVisitor.php', + 'SuperClosure\\Exception\\ClosureAnalysisException' => $vendorDir . '/jeremeamia/SuperClosure/src/Exception/ClosureAnalysisException.php', + 'SuperClosure\\Exception\\ClosureUnserializationException' => $vendorDir . '/jeremeamia/SuperClosure/src/Exception/ClosureUnserializationException.php', + 'SuperClosure\\Exception\\SuperClosureException' => $vendorDir . '/jeremeamia/SuperClosure/src/Exception/SuperClosureException.php', + 'SuperClosure\\SerializableClosure' => $vendorDir . '/jeremeamia/SuperClosure/src/SerializableClosure.php', + 'SuperClosure\\Serializer' => $vendorDir . '/jeremeamia/SuperClosure/src/Serializer.php', + 'SuperClosure\\SerializerInterface' => $vendorDir . '/jeremeamia/SuperClosure/src/SerializerInterface.php', + 'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', + 'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', + 'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', + 'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', + 'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', + 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', + 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', + 'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', + 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', + 'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php', + 'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php', + 'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php', + 'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', + 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', + 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', + 'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Helper/DialogHelper.php', + 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', + 'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', + 'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', + 'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php', + 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', + 'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Helper/ProgressHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', + 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', + 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', + 'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', + 'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', + 'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Helper/TableHelper.php', + 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', + 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', + 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', + 'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', + 'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', + 'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php', + 'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php', + 'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', + 'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', + 'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', + 'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', + 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', + 'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', + 'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php', + 'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php', + 'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php', + 'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php', + 'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php', + 'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php', + 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', + 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', + 'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', + 'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Shell.php', + 'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', + 'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', + 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', + 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', + 'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', + 'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php', + 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', + 'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php', + 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/EventDispatcherInterface.php', + 'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php', + 'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php', + 'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php', + 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', + 'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', + 'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', + 'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', + 'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', + 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', + 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', + 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', + 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', + 'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', + 'Symfony\\Component\\Process\\ProcessBuilder' => $vendorDir . '/symfony/process/ProcessBuilder.php', + 'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', + 'Symfony\\Component\\Routing\\Annotation\\Route' => $vendorDir . '/symfony/routing/Annotation/Route.php', + 'Symfony\\Component\\Routing\\CompiledRoute' => $vendorDir . '/symfony/routing/CompiledRoute.php', + 'Symfony\\Component\\Routing\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/routing/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Routing\\Exception\\InvalidParameterException' => $vendorDir . '/symfony/routing/Exception/InvalidParameterException.php', + 'Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException' => $vendorDir . '/symfony/routing/Exception/MethodNotAllowedException.php', + 'Symfony\\Component\\Routing\\Exception\\MissingMandatoryParametersException' => $vendorDir . '/symfony/routing/Exception/MissingMandatoryParametersException.php', + 'Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException' => $vendorDir . '/symfony/routing/Exception/ResourceNotFoundException.php', + 'Symfony\\Component\\Routing\\Exception\\RouteNotFoundException' => $vendorDir . '/symfony/routing/Exception/RouteNotFoundException.php', + 'Symfony\\Component\\Routing\\Generator\\ConfigurableRequirementsInterface' => $vendorDir . '/symfony/routing/Generator/ConfigurableRequirementsInterface.php', + 'Symfony\\Component\\Routing\\Generator\\Dumper\\GeneratorDumper' => $vendorDir . '/symfony/routing/Generator/Dumper/GeneratorDumper.php', + 'Symfony\\Component\\Routing\\Generator\\Dumper\\GeneratorDumperInterface' => $vendorDir . '/symfony/routing/Generator/Dumper/GeneratorDumperInterface.php', + 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper' => $vendorDir . '/symfony/routing/Generator/Dumper/PhpGeneratorDumper.php', + 'Symfony\\Component\\Routing\\Generator\\UrlGenerator' => $vendorDir . '/symfony/routing/Generator/UrlGenerator.php', + 'Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface' => $vendorDir . '/symfony/routing/Generator/UrlGeneratorInterface.php', + 'Symfony\\Component\\Routing\\Loader\\AnnotationClassLoader' => $vendorDir . '/symfony/routing/Loader/AnnotationClassLoader.php', + 'Symfony\\Component\\Routing\\Loader\\AnnotationDirectoryLoader' => $vendorDir . '/symfony/routing/Loader/AnnotationDirectoryLoader.php', + 'Symfony\\Component\\Routing\\Loader\\AnnotationFileLoader' => $vendorDir . '/symfony/routing/Loader/AnnotationFileLoader.php', + 'Symfony\\Component\\Routing\\Loader\\ClosureLoader' => $vendorDir . '/symfony/routing/Loader/ClosureLoader.php', + 'Symfony\\Component\\Routing\\Loader\\DependencyInjection\\ServiceRouterLoader' => $vendorDir . '/symfony/routing/Loader/DependencyInjection/ServiceRouterLoader.php', + 'Symfony\\Component\\Routing\\Loader\\DirectoryLoader' => $vendorDir . '/symfony/routing/Loader/DirectoryLoader.php', + 'Symfony\\Component\\Routing\\Loader\\ObjectRouteLoader' => $vendorDir . '/symfony/routing/Loader/ObjectRouteLoader.php', + 'Symfony\\Component\\Routing\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/routing/Loader/PhpFileLoader.php', + 'Symfony\\Component\\Routing\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/routing/Loader/XmlFileLoader.php', + 'Symfony\\Component\\Routing\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/routing/Loader/YamlFileLoader.php', + 'Symfony\\Component\\Routing\\Matcher\\ApacheUrlMatcher' => $vendorDir . '/symfony/routing/Matcher/ApacheUrlMatcher.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\ApacheMatcherDumper' => $vendorDir . '/symfony/routing/Matcher/Dumper/ApacheMatcherDumper.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperCollection' => $vendorDir . '/symfony/routing/Matcher/Dumper/DumperCollection.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperPrefixCollection' => $vendorDir . '/symfony/routing/Matcher/Dumper/DumperPrefixCollection.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\DumperRoute' => $vendorDir . '/symfony/routing/Matcher/Dumper/DumperRoute.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\MatcherDumper' => $vendorDir . '/symfony/routing/Matcher/Dumper/MatcherDumper.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\MatcherDumperInterface' => $vendorDir . '/symfony/routing/Matcher/Dumper/MatcherDumperInterface.php', + 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper' => $vendorDir . '/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php', + 'Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcher' => $vendorDir . '/symfony/routing/Matcher/RedirectableUrlMatcher.php', + 'Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface' => $vendorDir . '/symfony/routing/Matcher/RedirectableUrlMatcherInterface.php', + 'Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface' => $vendorDir . '/symfony/routing/Matcher/RequestMatcherInterface.php', + 'Symfony\\Component\\Routing\\Matcher\\TraceableUrlMatcher' => $vendorDir . '/symfony/routing/Matcher/TraceableUrlMatcher.php', + 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher' => $vendorDir . '/symfony/routing/Matcher/UrlMatcher.php', + 'Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface' => $vendorDir . '/symfony/routing/Matcher/UrlMatcherInterface.php', + 'Symfony\\Component\\Routing\\RequestContext' => $vendorDir . '/symfony/routing/RequestContext.php', + 'Symfony\\Component\\Routing\\RequestContextAwareInterface' => $vendorDir . '/symfony/routing/RequestContextAwareInterface.php', + 'Symfony\\Component\\Routing\\Route' => $vendorDir . '/symfony/routing/Route.php', + 'Symfony\\Component\\Routing\\RouteCollection' => $vendorDir . '/symfony/routing/RouteCollection.php', + 'Symfony\\Component\\Routing\\RouteCollectionBuilder' => $vendorDir . '/symfony/routing/RouteCollectionBuilder.php', + 'Symfony\\Component\\Routing\\RouteCompiler' => $vendorDir . '/symfony/routing/RouteCompiler.php', + 'Symfony\\Component\\Routing\\RouteCompilerInterface' => $vendorDir . '/symfony/routing/RouteCompilerInterface.php', + 'Symfony\\Component\\Routing\\Router' => $vendorDir . '/symfony/routing/Router.php', + 'Symfony\\Component\\Routing\\RouterInterface' => $vendorDir . '/symfony/routing/RouterInterface.php', + 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', + 'Symfony\\Polyfill\\Php55\\Php55' => $vendorDir . '/symfony/polyfill-php55/Php55.php', + 'Symfony\\Polyfill\\Php55\\Php55ArrayColumn' => $vendorDir . '/symfony/polyfill-php55/Php55ArrayColumn.php', + 'Symfony\\Polyfill\\Php56\\Php56' => $vendorDir . '/symfony/polyfill-php56/Php56.php', + 'Symfony\\Polyfill\\Php70\\Php70' => $vendorDir . '/symfony/polyfill-php70/Php70.php', + 'Symfony\\Polyfill\\Util\\Binary' => $vendorDir . '/symfony/polyfill-util/Binary.php', + 'Symfony\\Polyfill\\Util\\BinaryNoFuncOverload' => $vendorDir . '/symfony/polyfill-util/BinaryNoFuncOverload.php', + 'Symfony\\Polyfill\\Util\\BinaryOnFuncOverload' => $vendorDir . '/symfony/polyfill-util/BinaryOnFuncOverload.php', + 'Symfony\\Polyfill\\Util\\TestListener' => $vendorDir . '/symfony/polyfill-util/TestListener.php', + 'System' => $vendorDir . '/pear/pear-core-minimal/src/System.php', + 'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php', + 'ZipStreamer\\COMPR' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\Count64' => $vendorDir . '/mcnetic/zipstreamer/src/lib/Count64.php', + 'ZipStreamer\\Count64Base' => $vendorDir . '/mcnetic/zipstreamer/src/lib/Count64.php', + 'ZipStreamer\\Count64_32' => $vendorDir . '/mcnetic/zipstreamer/src/lib/Count64.php', + 'ZipStreamer\\Count64_64' => $vendorDir . '/mcnetic/zipstreamer/src/lib/Count64.php', + 'ZipStreamer\\DOS' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\DeflatePeclStream' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\DeflateStoreStream' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\DeflateStream' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\ExtFileAttr' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\GPFLAGS' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\UNIX' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'ZipStreamer\\ZipStreamer' => $vendorDir . '/mcnetic/zipstreamer/src/ZipStreamer.php', + 'aCssAtBlockEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssAtBlockStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssDeclarationToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssFormatter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssMinifierFilter' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssMinifierPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssParserPlugin' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssRulesetEndToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssRulesetStartToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'aCssToken' => $vendorDir . '/natxet/CssMin/src/CssMin.php', + 'bantu\\IniGetWrapper\\IniGetWrapper' => $vendorDir . '/bantu/ini-get-wrapper/src/IniGetWrapper.php', + 'getID3' => $vendorDir . '/james-heinrich/getid3/getid3/getid3.php', + 'getid3_exception' => $vendorDir . '/james-heinrich/getid3/getid3/getid3.php', + 'getid3_handler' => $vendorDir . '/james-heinrich/getid3/getid3/getid3.php', + 'ownCloud\\TarStreamer\\TarStreamer' => $vendorDir . '/deepdiver1975/tarstreamer/src/TarStreamer.php', + 'phpseclib\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php', + 'phpseclib\\Crypt\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php', + 'phpseclib\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php', + 'phpseclib\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/DES.php', + 'phpseclib\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Hash.php', + 'phpseclib\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC2.php', + 'phpseclib\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RC4.php', + 'phpseclib\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/RSA.php', + 'phpseclib\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Random.php', + 'phpseclib\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php', + 'phpseclib\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php', + 'phpseclib\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php', + 'phpseclib\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ANSI.php', + 'phpseclib\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1.php', + 'phpseclib\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php', + 'phpseclib\\File\\X509' => $vendorDir . '/phpseclib/phpseclib/phpseclib/File/X509.php', + 'phpseclib\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Math/BigInteger.php', + 'phpseclib\\Net\\SCP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SCP.php', + 'phpseclib\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP.php', + 'phpseclib\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php', + 'phpseclib\\Net\\SSH1' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH1.php', + 'phpseclib\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Net/SSH2.php', + 'phpseclib\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', + 'phpseclib\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', +); diff --git a/resources/updater-fixes/composer/installed.json b/resources/updater-fixes/composer/installed.json new file mode 100644 index 0000000000000..1c1e7a0c6b8e3 --- /dev/null +++ b/resources/updater-fixes/composer/installed.json @@ -0,0 +1,3247 @@ +[ + { + "name": "guzzle/common", + "version": "v3.8.1", + "version_normalized": "3.8.1.0", + "target-dir": "Guzzle/Common", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/common.git", + "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/common/zipball/67f6c3fd04bae387d47c2a673fa623ed8f4189bb", + "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" + }, + "time": "2014-01-28 22:29:15", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Guzzle\\Common": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Common libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "collection", + "common", + "event", + "exception" + ] + }, + { + "name": "guzzle/stream", + "version": "v3.8.1", + "version_normalized": "3.8.1.0", + "target-dir": "Guzzle/Stream", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/stream.git", + "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/stream/zipball/fa8af730ca714861c0001cfba64aaecc5f21bb96", + "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "guzzle/http": "To convert Guzzle request objects to PHP streams" + }, + "time": "2014-01-28 22:14:17", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Guzzle\\Stream": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle stream wrapper component", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "component", + "stream" + ] + }, + { + "name": "guzzle/parser", + "version": "v3.8.1", + "version_normalized": "3.8.1.0", + "target-dir": "Guzzle/Parser", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/parser.git", + "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/parser/zipball/3f52387052f2e4ef083145a0f73c3654aa14e086", + "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "time": "2013-10-24 00:04:09", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Guzzle\\Parser": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interchangeable parsers used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "URI Template", + "cookie", + "http", + "message", + "url" + ] + }, + { + "name": "guzzle/http", + "version": "v3.8.1", + "version_normalized": "3.8.1.0", + "target-dir": "Guzzle/Http", + "source": { + "type": "git", + "url": "https://github.com/Guzzle3/http.git", + "reference": "565fd64be16d91c840f497c5de76f86d54a822d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Guzzle3/http/zipball/565fd64be16d91c840f497c5de76f86d54a822d8", + "reference": "565fd64be16d91c840f497c5de76f86d54a822d8", + "shasum": "" + }, + "require": { + "guzzle/common": "self.version", + "guzzle/parser": "self.version", + "guzzle/stream": "self.version", + "php": ">=5.3.2" + }, + "suggest": { + "ext-curl": "*" + }, + "time": "2014-01-23 18:23:29", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Guzzle\\Http": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "HTTP libraries used by Guzzle", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "client", + "curl", + "http", + "http client" + ] + }, + { + "name": "rackspace/php-opencloud", + "version": "v1.9.2", + "version_normalized": "1.9.2.0", + "source": { + "type": "git", + "url": "https://github.com/rackspace/php-opencloud.git", + "reference": "6551de7aebcebb369d025662f99ab27c9b4527ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rackspace/php-opencloud/zipball/6551de7aebcebb369d025662f99ab27c9b4527ac", + "reference": "6551de7aebcebb369d025662f99ab27c9b4527ac", + "shasum": "" + }, + "require": { + "guzzle/http": "3.8.*@dev", + "php": ">=5.3.3" + }, + "require-dev": { + "guzzle/guzzle": "dev-master", + "psr/log": "1.0.*", + "satooshi/php-coveralls": "0.6.*@dev" + }, + "time": "2014-02-06 20:53:21", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "OpenCloud": [ + "lib/", + "tests/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Glen Campbell", + "email": "glen.campbell@rackspace.com" + }, + { + "name": "Jamie Hannaford", + "email": "jamie.hannaford@rackspace.com", + "homepage": "https://github.com/jamiehannaford" + } + ], + "description": "PHP SDK for Rackspace/OpenStack APIs", + "keywords": [ + "Openstack", + "nova", + "opencloud", + "rackspace", + "swift" + ] + }, + { + "name": "ircmaxell/security-lib", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/SecurityLib.git", + "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/SecurityLib/zipball/80934de3c482dcafb46b5756e59ebece082b6dc7", + "reference": "80934de3c482dcafb46b5756e59ebece082b6dc7", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "mikey179/vfsstream": "1.1.*" + }, + "time": "2013-04-30 18:00:34", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "SecurityLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Base Security Library", + "homepage": "https://github.com/ircmaxell/PHP-SecurityLib" + }, + { + "name": "bantu/ini-get-wrapper", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/bantuXorg/php-ini-get-wrapper.git", + "reference": "4770c7feab370c62e23db4f31c112b7c6d90aee2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bantuXorg/php-ini-get-wrapper/zipball/4770c7feab370c62e23db4f31c112b7c6d90aee2", + "reference": "4770c7feab370c62e23db4f31c112b7c6d90aee2", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "time": "2014-09-15 13:12:35", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "bantu\\IniGetWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Convenience wrapper around ini_get()" + }, + { + "name": "james-heinrich/getid3", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/JamesHeinrich/getID3.git", + "reference": "afbdaa044a9a0a9dff2f800bd670e231b3ec99b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/995da7d5e8a7ac2b5ef076c64e9be66d380ede4f", + "reference": "afbdaa044a9a0a9dff2f800bd670e231b3ec99b2", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2014-09-14 18:13:30", + "type": "library", + "installation-source": "source", + "autoload": { + "classmap": [ + "getid3/getid3.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL" + ], + "description": "PHP script that extracts useful information from popular multimedia file formats", + "homepage": "http://www.getid3.org/", + "keywords": [ + "codecs", + "php", + "tags" + ] + }, + { + "name": "natxet/CssMin", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/natxet/CssMin.git", + "reference": "003920e783c568c2d8fdf03999eebefb8479092a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/natxet/CssMin/zipball/0b2170454eed9024c7e26b036fbccf2d7f6f2c53", + "reference": "003920e783c568c2d8fdf03999eebefb8479092a", + "shasum": "" + }, + "require": { + "php": ">=5.0" + }, + "time": "2014-09-10 14:34:00", + "type": "library", + "installation-source": "source", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joe Scylla", + "email": "joe.scylla@gmail.com", + "homepage": "https://profiles.google.com/joe.scylla" + } + ], + "description": "Minifying CSS", + "homepage": "http://code.google.com/p/cssmin/", + "keywords": [ + "css", + "minify" + ] + }, + { + "name": "ircmaxell/random-lib", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/RandomLib.git", + "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/RandomLib/zipball/13efa4368bb2ac88bb3b1459b487d907de4dbf7c", + "reference": "13efa4368bb2ac88bb3b1459b487d907de4dbf7c", + "shasum": "" + }, + "require": { + "ircmaxell/security-lib": "1.0.*@dev", + "php": ">=5.3.2" + }, + "require-dev": { + "mikey179/vfsstream": "1.1.*", + "phpunit/phpunit": "3.7.*" + }, + "time": "2015-01-15 16:31:45", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "RandomLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Library For Generating Secure Random Numbers", + "homepage": "https://github.com/ircmaxell/RandomLib", + "keywords": [ + "cryptography", + "random", + "random-numbers", + "random-strings" + ] + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.3.1", + "version_normalized": "5.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", + "reference": "c5f963e7f9d6f6438fda4f22d5cc2db296ec621a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1" + }, + "time": "2014-12-05 14:17:14", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "mail", + "mailer" + ] + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2014-10-12 19:18:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ] + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "time": "2015-05-20 03:37:09", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function." + }, + { + "name": "pear/console_getopt", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "reference": "82f05cd1aa3edf34e19aa7c8ca312ce13a6a577f", + "shasum": "" + }, + "time": "2015-07-20 20:28:12", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + }, + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt" + }, + { + "name": "pear/pear_exception", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/pear/PEAR_Exception.git", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/8c18719fdae000b690e3912be401c76e406dd13b", + "reference": "8c18719fdae000b690e3912be401c76e406dd13b", + "shasum": "" + }, + "require": { + "php": ">=4.4.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "time": "2015-02-10 20:07:52", + "type": "class", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "PEAR": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "." + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Helgi Thormar", + "email": "dufuz@php.net" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net" + } + ], + "description": "The PEAR Exception base class.", + "homepage": "https://github.com/pear/PEAR_Exception", + "keywords": [ + "exception" + ] + }, + { + "name": "doctrine/annotations", + "version": "v1.2.7", + "version_normalized": "1.2.7.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "time": "2015-08-31 12:32:49", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Annotations\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ] + }, + { + "name": "patchwork/jsqueeze", + "version": "v2.0.3", + "version_normalized": "2.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/tchwork/jsqueeze.git", + "reference": "074a7ac403d1fae262fd662c43c04b62d71c3e50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tchwork/jsqueeze/zipball/074a7ac403d1fae262fd662c43c04b62d71c3e50", + "reference": "074a7ac403d1fae262fd662c43c04b62d71c3e50", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2015-08-20 11:07:02", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Patchwork\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Efficient JavaScript minification in PHP", + "homepage": "https://github.com/tchwork/jsqueeze", + "keywords": [ + "compression", + "javascript", + "minification" + ] + }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "version_normalized": "1.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "time": "2014-11-20 16:49:30", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ] + }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.1", + "version_normalized": "1.10.1.0", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "reference": "cae0f1ce0cb5bddb611b0a652d322905a65a5896", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.3", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "time": "2015-10-17 11:41:19", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency" + }, + { + "name": "pimple/pimple", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2015-09-11 15:10:35", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ] + }, + { + "name": "pear/archive_tar", + "version": "1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/pear/Archive_Tar.git", + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/fc2937c0e5a2a1c62a378d16394893172f970064", + "reference": "fc2937c0e5a2a1c62a378d16394893172f970064", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-bz2": "bz2 compression support.", + "ext-xz": "lzma2 compression support.", + "ext-zlib": "Gzip compression support." + }, + "time": "2015-08-05 12:31:03", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Archive_Tar": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vincent Blavet", + "email": "vincent@phpconcept.net" + }, + { + "name": "Greg Beaver", + "email": "greg@chiaraquartet.net" + }, + { + "name": "Michiel Rook", + "email": "mrook@php.net" + } + ], + "description": "Tar file management class", + "homepage": "https://github.com/pear/Archive_Tar", + "keywords": [ + "archive", + "tar" + ] + }, + { + "name": "react/promise", + "version": "v2.2.1", + "version_normalized": "2.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "time": "2015-07-03 13:48:55", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP" + }, + { + "name": "guzzlehttp/guzzle", + "version": "5.3.0", + "version_normalized": "5.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" + }, + "time": "2015-05-20 03:47:55", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ] + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "a74aa9efbe61430fcb60157c8e025a48ec8ff604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/a74aa9efbe61430fcb60157c8e025a48ec8ff604", + "reference": "a74aa9efbe61430fcb60157c8e025a48ec8ff604", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "~4.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 5.0.0." + }, + "time": "2015-08-04 04:48:03", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "phpseclib/" + ], + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ] + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "time": "2014-09-09 13:34:57", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ] + }, + { + "name": "doctrine/collections", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2015-04-14 22:21:58", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ] + }, + { + "name": "doctrine/dbal", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.6-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "time": "2015-09-16 16:29:33", + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ] + }, + { + "name": "sabre/uri", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-uri.git", + "reference": "6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-uri/zipball/6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42", + "reference": "6bae7efdd9dfcfdb3edfc4362741e59ce4b64f42", + "shasum": "" + }, + "require": { + "php": ">=5.4.7" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.1" + }, + "time": "2015-04-29 03:47:26", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\Uri\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "Functions for making sense out of URIs.", + "homepage": "http://sabre.io/uri/", + "keywords": [ + "rfc3986", + "uri", + "url" + ] + }, + { + "name": "sabre/event", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-event.git", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-event/zipball/337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "shasum": "" + }, + "require": { + "php": ">=5.4.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.1" + }, + "time": "2015-05-19 10:24:22", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "events", + "hooks", + "plugin", + "promise", + "signal" + ] + }, + { + "name": "kriswallsmith/assetic", + "version": "v1.3.2", + "version_normalized": "1.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/kriswallsmith/assetic.git", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/9928f7c4ad98b234e3559d1049abd13387f86db5", + "reference": "9928f7c4ad98b234e3559d1049abd13387f86db5", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/process": "~2.1|~3.0" + }, + "conflict": { + "twig/twig": "<1.23" + }, + "require-dev": { + "cssmin/cssmin": "3.0.1", + "joliclic/javascript-packer": "1.1", + "kamicane/packager": "1.0", + "leafo/lessphp": "^0.3.7", + "leafo/scssphp": "~0.1", + "mrclay/minify": "~2.2", + "patchwork/jsqueeze": "~1.0|~2.0", + "phpunit/phpunit": "~4.8", + "psr/log": "~1.0", + "ptachoire/cssembed": "~1.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "twig/twig": "~1.8|~2.0" + }, + "suggest": { + "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", + "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", + "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", + "patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor", + "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", + "twig/twig": "Assetic provides the integration with the Twig templating engine" + }, + "time": "2015-11-12 13:51:40", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Assetic": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kris Wallsmith", + "email": "kris.wallsmith@gmail.com", + "homepage": "http://kriswallsmith.net/" + } + ], + "description": "Asset Management for PHP", + "homepage": "https://github.com/kriswallsmith/assetic", + "keywords": [ + "assets", + "compression", + "minification" + ] + }, + { + "name": "punic/punic", + "version": "1.6.3", + "version_normalized": "1.6.3.0", + "source": { + "type": "git", + "url": "https://github.com/punic/punic.git", + "reference": "5805b35d6a574f754b49be1f539aaf3ae6484808" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/punic/punic/zipball/5805b35d6a574f754b49be1f539aaf3ae6484808", + "reference": "5805b35d6a574f754b49be1f539aaf3ae6484808", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "replace": { + "punic/calendar": "*", + "punic/common": "*" + }, + "require-dev": { + "apigen/apigen": "4.0.*" + }, + "time": "2015-06-16 13:04:27", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Punic\\": "code/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michele Locati", + "email": "mlocati@gmail.com", + "role": "Developer" + }, + { + "name": "Remo Laubacher", + "email": "remo.laubacher@gmail.com", + "role": "Collaborator, motivator and perfectionist supporter" + } + ], + "description": "PHP-Unicode CLDR", + "homepage": "https://github.com/punic/punic", + "keywords": [ + "calendar", + "cldr", + "date", + "date-time", + "i18n", + "internationalization", + "l10n", + "localization", + "php", + "time", + "translate", + "translations", + "unicode" + ] + }, + { + "name": "jeremeamia/SuperClosure", + "version": "2.1.0", + "version_normalized": "2.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/jeremeamia/super_closure.git", + "reference": "b712f39c671e5ead60c7ebfe662545456aade833" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/b712f39c671e5ead60c7ebfe662545456aade833", + "reference": "b712f39c671e5ead60c7ebfe662545456aade833", + "shasum": "" + }, + "require": { + "nikic/php-parser": "~1.0", + "php": ">=5.4" + }, + "require-dev": { + "codeclimate/php-test-reporter": "~0.1.2", + "phpunit/phpunit": "~4.0" + }, + "time": "2015-03-11 20:06:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "SuperClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia", + "role": "Developer" + } + ], + "description": "Serialize Closure objects, including their context and binding", + "homepage": "https://github.com/jeremeamia/super_closure", + "keywords": [ + "closure", + "function", + "lambda", + "parser", + "serializable", + "serialize", + "tokenizer" + ] + }, + { + "name": "nikic/php-parser", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3" + }, + "time": "2015-09-19 14:15:08", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "lib/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ] + }, + { + "name": "doctrine/inflector", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "time": "2015-11-06 14:35:42", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ] + }, + { + "name": "paragonie/random_compat", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "d762ee5b099a29044603cd4649851e81aa66cb47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/d762ee5b099a29044603cd4649851e81aa66cb47", + "reference": "d762ee5b099a29044603cd4649851e81aa66cb47", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2015-12-10 14:48:13", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ] + }, + { + "name": "doctrine/cache", + "version": "v1.5.2", + "version_normalized": "1.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af", + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "time": "2015-12-03 10:50:37", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ] + }, + { + "name": "doctrine/common", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "time": "2015-12-04 12:49:42", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ] + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25", + "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2015-11-20 09:19:13", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/polyfill-php55", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "3adc962a6250c02adb508e85ecfa6fcfee9eec47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/3adc962a6250c02adb508e85ecfa6fcfee9eec47", + "reference": "3adc962a6250c02adb508e85ecfa6fcfee9eec47", + "shasum": "" + }, + "require": { + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" + }, + "time": "2015-11-04 20:28:58", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/polyfill-util", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "4271c55cbc0a77b2641f861b978123e46b3da969" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4271c55cbc0a77b2641f861b978123e46b3da969", + "reference": "4271c55cbc0a77b2641f861b978123e46b3da969", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-11-04 20:28:58", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ] + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", + "reference": "e2e77609a9e2328eb370fbb0e0d8b2000ebb488f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "time": "2015-12-18 15:10:25", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "7f7f3c9c2b9f17722e0cd64fdb4f957330c53146" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/7f7f3c9c2b9f17722e0cd64fdb4f957330c53146", + "reference": "7f7f3c9c2b9f17722e0cd64fdb4f957330c53146", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0", + "php": ">=5.3.3" + }, + "time": "2015-11-04 20:28:58", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "sabre/http", + "version": "4.2.1", + "version_normalized": "4.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-http.git", + "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-http/zipball/2e93bc8321524c67be4ca5b8415daebd4c8bf85e", + "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.4", + "sabre/event": ">=1.0.0,<4.0.0", + "sabre/uri": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.3", + "sabre/cs": "~0.0.1" + }, + "suggest": { + "ext-curl": " to make http requests with the Client class" + }, + "time": "2016-01-06 23:00:08", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Sabre\\HTTP\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", + "homepage": "https://github.com/fruux/sabre-http", + "keywords": [ + "http" + ] + }, + { + "name": "sabre/xml", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-xml.git", + "reference": "420400f36655d79894fae8ce970516a71ea8f5f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/420400f36655d79894fae8ce970516a71ea8f5f5", + "reference": "420400f36655d79894fae8ce970516a71ea8f5f5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "lib-libxml": ">=2.6.20", + "php": ">=5.4.1", + "sabre/uri": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.2" + }, + "time": "2015-12-29 20:51:22", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sabre\\Xml\\": "lib/" + }, + "files": [ + "lib/Deserializer/functions.php", + "lib/Serializer/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Markus Staab", + "email": "markus.staab@redaxo.de", + "role": "Developer" + } + ], + "description": "sabre/xml is an XML library that you may not hate.", + "homepage": "https://sabre.io/xml/", + "keywords": [ + "XMLReader", + "XMLWriter", + "dom", + "xml" + ] + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.1", + "version_normalized": "2.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2015-10-30 20:15:42", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com" + }, + { + "name": "sabre/vobject", + "version": "3.5.0", + "version_normalized": "3.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-vobject.git", + "reference": "061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4", + "reference": "061dd47ce40074bf63da8e3d6dbe7f18b5a4f3a4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "squizlabs/php_codesniffer": "*" + }, + "time": "2016-01-11 18:13:23", + "bin": [ + "bin/vobject", + "bin/generate_vcards" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sabre\\VObject\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + }, + { + "name": "Dominik Tobschall", + "email": "dominik@fruux.com", + "homepage": "http://tobschall.de/", + "role": "Developer" + } + ], + "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", + "homepage": "http://sabre.io/vobject/", + "keywords": [ + "VObject", + "iCalendar", + "jCal", + "jCard", + "vCard" + ] + }, + { + "name": "symfony/console", + "version": "v2.8.1", + "version_normalized": "2.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", + "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "time": "2015-12-22 10:25:57", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com" + }, + { + "name": "interfasys/lognormalizer", + "version": "v1.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/interfasys/lognormalizer.git", + "reference": "d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/interfasys/lognormalizer/zipball/d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116", + "reference": "d5e4c95e0b0ecc886b78aafda3773b3bcf2ec116", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "codacy/coverage": "dev-master", + "codeclimate/php-test-reporter": "dev-master", + "phpunit/phpunit": "4.*" + }, + "time": "2015-08-01 16:27:37", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "InterfaSys\\LogNormalizer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0" + ], + "authors": [ + { + "name": "Olivier Paroz", + "email": "dev-lognormalizer@interfasys.ch", + "homepage": "http://www.interfasys.ch", + "role": "Developer" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "role": "Developer" + } + ], + "description": "Parses variables and converts them to string so that they can be logged", + "homepage": "https://github.com/interfasys/lognormalizer", + "keywords": [ + "log", + "normalizer" + ] + }, + { + "name": "symfony/routing", + "version": "v2.8.1", + "version_normalized": "2.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "b3261d88bad77de60e01f05706810413cc11367d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/b3261d88bad77de60e01f05706810413cc11367d", + "reference": "b3261d88bad77de60e01f05706810413cc11367d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~2.7|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.3|~3.0.0", + "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/yaml": "For using the YAML loader" + }, + "time": "2015-12-23 07:56:26", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ] + }, + { + "name": "symfony/process", + "version": "v2.8.1", + "version_normalized": "2.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "62c254438b5040bc2217156e1570cf2206e8540c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/62c254438b5040bc2217156e1570cf2206e8540c", + "reference": "62c254438b5040bc2217156e1570cf2206e8540c", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "time": "2015-12-23 11:03:46", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com" + }, + { + "name": "league/flysystem", + "version": "1.0.16", + "version_normalized": "1.0.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/183e1a610664baf6dcd6fceda415baf43cbdc031", + "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "ext-fileinfo": "*", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^2.2", + "phpspec/prophecy-phpunit": "~1.0", + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Allows you to use Dropbox storage", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" + }, + "time": "2015-12-19 20:16:43", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ] + }, + { + "name": "deepdiver1975/tarstreamer", + "version": "v0.1.0", + "version_normalized": "0.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/owncloud/TarStreamer.git", + "reference": "859a0170de120c66b042e6c0dbc1a9979c74669b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/owncloud/TarStreamer/zipball/859a0170de120c66b042e6c0dbc1a9979c74669b", + "reference": "859a0170de120c66b042e6c0dbc1a9979c74669b", + "shasum": "" + }, + "require": { + "php": ">=5.3.8" + }, + "require-dev": { + "pear/archive_tar": "~1.4", + "pear/pear-core-minimal": "v1.10.0alpha2", + "phpunit/phpunit": "^4.8" + }, + "time": "2016-02-15 10:52:44", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ownCloud\\TarStreamer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A library for dynamically streaming dynamic tar files without the need to have the complete file stored on the server.", + "homepage": "https://github.com/owncloud/TarStreamer", + "keywords": [ + "archive", + "php", + "stream", + "tar" + ] + }, + { + "name": "patchwork/utf8", + "version": "v1.2.6", + "version_normalized": "1.2.6.0", + "source": { + "type": "git", + "url": "https://github.com/tchwork/utf8.git", + "reference": "f986d18f4e37ab70b792e977c7d85970cf84f164" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tchwork/utf8/zipball/f986d18f4e37ab70b792e977c7d85970cf84f164", + "reference": "f986d18f4e37ab70b792e977c7d85970cf84f164", + "shasum": "" + }, + "require": { + "lib-pcre": ">=7.3", + "php": ">=5.3.0" + }, + "suggest": { + "ext-iconv": "Use iconv for best performance", + "ext-intl": "Use Intl for best performance", + "ext-mbstring": "Use Mbstring for best performance", + "ext-wfio": "Use WFIO for UTF-8 filesystem access on Windows" + }, + "time": "2015-12-15 15:33:41", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Patchwork\\": "src/Patchwork/" + }, + "classmap": [ + "src/Normalizer.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "(Apache-2.0 or GPL-2.0)" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Portable and performant UTF-8, Unicode and Grapheme Clusters for PHP", + "homepage": "https://github.com/tchwork/utf8", + "keywords": [ + "grapheme", + "i18n", + "unicode", + "utf-8", + "utf8" + ] + }, + { + "name": "mcnetic/zipstreamer", + "version": "v1.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/McNetic/PHPZipStreamer.git", + "reference": "e57c198486242476587d04844084adbe8330581d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/McNetic/PHPZipStreamer/zipball/e57c198486242476587d04844084adbe8330581d", + "reference": "e57c198486242476587d04844084adbe8330581d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-02-17 22:47:09", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ZipStreamer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0+" + ], + "authors": [ + { + "name": "Nicolai Ehemann", + "email": "en@enlightened.de", + "role": "Author/Maintainer" + }, + { + "name": "André Rothe", + "email": "arothe@zks.uni-leipzig.de", + "role": "Contributor" + }, + { + "name": "Lukas Reschke", + "email": "lukas@owncloud.com", + "role": "Contributor" + } + ], + "description": "Stream zip files without i/o overhead", + "homepage": "https://github.com/McNetic/PHPZipStreamer", + "keywords": [ + "stream", + "zip" + ] + }, + { + "name": "icewind/streams", + "version": "0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/icewind1991/Streams.git", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icewind1991/Streams/zipball/9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "reference": "9ca40274645a967ecc3408b0ca2e6255ead1d1d3", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "v1.0.0" + }, + "time": "2016-03-17 12:32:25", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Icewind\\Streams\\Tests\\": "tests/", + "Icewind\\Streams\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Appelman", + "email": "icewind@owncloud.com" + } + ], + "description": "A set of generic stream wrappers" + }, + { + "name": "sabre/dav", + "version": "3.0.9", + "version_normalized": "3.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-dav.git", + "reference": "b42593965211de1ce99f73bd3aede99c41258e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/b42593965211de1ce99f73bd3aede99c41258e08", + "reference": "b42593965211de1ce99f73bd3aede99c41258e08", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-dom": "*", + "ext-iconv": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "lib-libxml": ">=2.7.0", + "php": ">=5.4.1", + "sabre/event": "~2.0", + "sabre/http": "~4.0", + "sabre/uri": "~1.0", + "sabre/vobject": "^3.3.4", + "sabre/xml": "~1.0" + }, + "require-dev": { + "evert/phpdoc-md": "~0.1.0", + "phpunit/phpunit": "~4.2", + "sabre/cs": "~0.0.2" + }, + "suggest": { + "ext-curl": "*", + "ext-pdo": "*" + }, + "time": "2016-04-07 00:32:57", + "bin": [ + "bin/sabredav", + "bin/naturalselection" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sabre\\DAV\\": "lib/DAV/", + "Sabre\\DAVACL\\": "lib/DAVACL/", + "Sabre\\CalDAV\\": "lib/CalDAV/", + "Sabre\\CardDAV\\": "lib/CardDAV/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "WebDAV Framework for PHP", + "homepage": "http://sabre.io/", + "keywords": [ + "CalDAV", + "CardDAV", + "WebDAV", + "framework", + "iCalendar" + ] + } +] diff --git a/resources/updater-fixes/icewind/streams/src/DirectoryFilter.php b/resources/updater-fixes/icewind/streams/src/DirectoryFilter.php new file mode 100644 index 0000000000000..4b8696990007a --- /dev/null +++ b/resources/updater-fixes/icewind/streams/src/DirectoryFilter.php @@ -0,0 +1,60 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper allows filtering of directories + * + * The filter callback will be called for each entry in the folder + * when the callback return false the entry will be filtered out + */ +class DirectoryFilter extends DirectoryWrapper { + /** + * @var callable + */ + private $filter; + + /** + * @param string $path + * @param array $options + * @return bool + */ + public function dir_opendir($path, $options) { + $context = $this->loadContext('filter'); + $this->filter = $context['filter']; + return true; + } + + /** + * @return string + */ + public function dir_readdir() { + $file = readdir($this->source); + $filter = $this->filter; + // keep reading untill we have an accepted entry or we're at the end of the folder + while ($file !== false && $filter($file) === false) { + $file = readdir($this->source); + } + return $file; + } + + /** + * @param resource $source + * @param callable $filter + * @return resource + */ + public static function wrap($source, callable $filter) { + $options = array( + 'filter' => array( + 'source' => $source, + 'filter' => $filter + ) + ); + return self::wrapWithOptions($options, '\Icewind\Streams\DirectoryFilter'); + } +} diff --git a/resources/updater-fixes/icewind/streams/src/DirectoryWrapper.php b/resources/updater-fixes/icewind/streams/src/DirectoryWrapper.php new file mode 100644 index 0000000000000..63e4805a807c1 --- /dev/null +++ b/resources/updater-fixes/icewind/streams/src/DirectoryWrapper.php @@ -0,0 +1,88 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +class DirectoryWrapper implements Directory { + /** + * @var resource + */ + public $context; + + /** + * @var resource + */ + protected $source; + + /** + * Load the source from the stream context and return the context options + * + * @param string $name + * @return array + * @throws \Exception + */ + protected function loadContext($name) { + $context = stream_context_get_options($this->context); + if (isset($context[$name])) { + $context = $context[$name]; + } else { + throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set'); + } + if (isset($context['source']) and is_resource($context['source'])) { + $this->source = $context['source']; + } else { + throw new \BadMethodCallException('Invalid context, source not set'); + } + return $context; + } + + /** + * @param string $path + * @param array $options + * @return bool + */ + public function dir_opendir($path, $options) { + $this->loadContext('dir'); + return true; + } + + /** + * @return string + */ + public function dir_readdir() { + return readdir($this->source); + } + + /** + * @return bool + */ + public function dir_closedir() { + closedir($this->source); + return true; + } + + /** + * @return bool + */ + public function dir_rewinddir() { + rewinddir($this->source); + return true; + } + + /** + * @param array $options the options for the context to wrap the stream with + * @param string $class + * @return resource + */ + protected static function wrapWithOptions($options, $class) { + $context = stream_context_create($options); + stream_wrapper_register('dirwrapper', $class); + $wrapped = opendir('dirwrapper://', $context); + stream_wrapper_unregister('dirwrapper'); + return $wrapped; + } +} diff --git a/resources/updater-fixes/icewind/streams/src/RetryWrapper.php b/resources/updater-fixes/icewind/streams/src/RetryWrapper.php new file mode 100644 index 0000000000000..84b43f6bd0279 --- /dev/null +++ b/resources/updater-fixes/icewind/streams/src/RetryWrapper.php @@ -0,0 +1,66 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper that retries reads/writes to remote streams that dont deliver/recieve all requested data at once + */ +class RetryWrapper extends Wrapper { + + /** + * Wraps a stream with the provided callbacks + * + * @param resource $source + * @return resource + */ + public static function wrap($source) { + $context = stream_context_create(array( + 'retry' => array( + 'source' => $source + ) + )); + return Wrapper::wrapSource($source, $context, 'retry', '\Icewind\Streams\RetryWrapper'); + } + + protected function open() { + $this->loadContext('retry'); + return true; + } + + public function dir_opendir($path, $options) { + return false; + } + + public function stream_open($path, $mode, $options, &$opened_path) { + return $this->open(); + } + + public function stream_read($count) { + $result = parent::stream_read($count); + + $bytesReceived = strlen($result); + while ($bytesReceived < $count && !$this->stream_eof()) { + $result .= parent::stream_read($count - $bytesReceived); + $bytesReceived = strlen($result); + } + + return $result; + } + + public function stream_write($data) { + $bytesToSend = strlen($data); + $result = parent::stream_write($data); + + while ($result < $bytesToSend && !$this->stream_eof()) { + $dataLeft = substr($data, $result); + $result += parent::stream_write($dataLeft); + } + + return $result; + } +} diff --git a/resources/updater-fixes/icewind/streams/src/SeekableWrapper.php b/resources/updater-fixes/icewind/streams/src/SeekableWrapper.php new file mode 100644 index 0000000000000..d41fd73ec9c2e --- /dev/null +++ b/resources/updater-fixes/icewind/streams/src/SeekableWrapper.php @@ -0,0 +1,92 @@ + + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\Streams; + +/** + * Wrapper that provides callbacks for write, read and close + * + * The following options should be passed in the context when opening the stream + * [ + * 'callback' => [ + * 'source' => resource + * ] + * ] + * + * All callbacks are called after the operation is executed on the source stream + */ +class SeekableWrapper extends Wrapper { + /** + * @var resource + */ + protected $cache; + + /** + * Wraps a stream to make it seekable + * + * @param resource $source + * @return resource + * + * @throws \BadMethodCallException + */ + public static function wrap($source) { + $context = stream_context_create(array( + 'callback' => array( + 'source' => $source + ) + )); + return Wrapper::wrapSource($source, $context, 'callback', '\Icewind\Streams\SeekableWrapper'); + } + + public function dir_opendir($path, $options) { + return false; + } + + public function stream_open($path, $mode, $options, &$opened_path) { + $this->loadContext('callback'); + $this->cache = fopen('php://temp', 'w+'); + return true; + } + + protected function readTill($position) { + $current = ftell($this->source); + if ($position > $current) { + $data = parent::stream_read($position - $current); + $cachePosition = ftell($this->cache); + fseek($this->cache, $current); + fwrite($this->cache, $data); + fseek($this->cache, $cachePosition); + } + } + + public function stream_read($count) { + $current = ftell($this->cache); + $this->readTill($current + $count); + return fread($this->cache, $count); + } + + public function stream_seek($offset, $whence = SEEK_SET) { + if ($whence === SEEK_SET) { + $target = $offset; + } else if ($whence === SEEK_CUR) { + $current = ftell($this->cache); + $target = $current + $offset; + } else { + return false; + } + $this->readTill($target); + return fseek($this->cache, $target) === 0; + } + + public function stream_tell() { + return ftell($this->cache); + } + + public function stream_eof() { + return parent::stream_eof() and (ftell($this->source) === ftell($this->cache)); + } +} diff --git a/resources/updater-fixes/sabre/dav/CHANGELOG.md b/resources/updater-fixes/sabre/dav/CHANGELOG.md new file mode 100644 index 0000000000000..1739f40cd7bc9 --- /dev/null +++ b/resources/updater-fixes/sabre/dav/CHANGELOG.md @@ -0,0 +1,2138 @@ +ChangeLog +========= + +3.0.9 (2016-04-06) +------------------ + +* Set minimum libxml version to 2.7.0 in `composer.json`. +* #727: Added another workaround to make CalDAV work for Windows 10 clients. +* #805: It wasn't possible to create calendars that hold events, journals and + todos using MySQL, because the `components` column was 1 byte too small. +* The zip release ships with [sabre/vobject 3.5.1][vobj], + [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. + + +3.0.8 (2016-03-12) +------------------ + +* #784: Sync logs for address books were not correctly cleaned up after + deleting them. +* #787: Cannot use non-seekable stream-wrappers with range requests. +* Faster XML parsing and generating due to sabre/xml update. +* The zip release ships with [sabre/vobject 3.5.0][vobj], + [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml]. + + +3.0.7 (2016-01-12) +------------------ + +* #752: PHP 7 support for 3.0 branch. (@DeepDiver1975) +* The zip release ships with [sabre/vobject 3.5.0][vobj], + [sabre/http 4.2.1][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. + + +3.0.6 (2016-01-04) +------------------ + +* #730: Switched all mysql tables to `utf8mb4` character set, allowing you to + use emoji in some tables where you couldn't before. +* #729: Not all calls to `Sabre\DAV\Tree::getChildren()` were properly cached. +* #734: Return `418 I'm a Teapot` when generating a multistatus response that + has resources with no returned properties. +* #740: Bugs in `migrate20.php` script. +* The zip release ships with [sabre/vobject 3.4.8][vobj], + [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.3.0][xml]. + + +3.0.5 (2015-09-15) +------------------ + +* #704: Fixed broken uri encoding in multistatus responses. This affected + at least CyberDuck, but probably also others. +* The zip release ships with [sabre/vobject 3.4.7][vobj], + [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.2.0][xml]. + + +3.0.4 (2015-09-06) +------------------ + +* #703: PropPatch in client is not correctly encoded. +* #709: Throw exception when running into empty + `supported-calendar-component-set`. +* #711: Don't trigger deserializers for empty elements in `{DAV:}prop`. This + fixes issues when using sabre/dav as a client. +* #705: A `MOVE` request that gets prevented from deleting the source resource + will still remove the target resource. Now all events are triggered before + any destructive operations. +* The zip release ships with [sabre/vobject 3.4.7][vobj], + [sabre/http 4.1.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.2.0][xml]. + + +3.0.3 (2015-08-06) +------------------ + +* #700: Digest Auth fails on `HEAD` requests. +* Fixed example files to no longer use now-deprecated realm argument. +* The zip release ships with [sabre/vobject 3.4.6][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. + + +3.0.2 (2015-07-21) +------------------ + +* #657: Migration script would break when coming a cross an iCalendar object + with no UID. +* #691: Workaround for broken Windows Phone client. +* Fixed a whole bunch of incorrect php docblocks. +* The zip release ships with [sabre/vobject 3.4.5][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. + + +3.0.1 (2015-07-02) +------------------ + +* #674: Postgres sql file fixes. (@davesouthey) +* #677: Resources with the name '0' would not get retrieved when using + `Depth: infinity` in a `PROPFIND` request. +* #680: Fix 'autoprefixing' of dead `{DAV:}href` properties. +* #675: NTLM support in DAV\Client. (@k42b3) +* The zip release ships with [sabre/vobject 3.4.5][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml]. + + +3.0.0 (2015-06-02) +------------------ + +* No changes since last beta. +* The zip release ships with [sabre/vobject 3.4.5][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. + + +3.0.0-beta3 (2015-05-29) +------------------------ + +* Fixed deserializing href properties with no value. +* Fixed deserializing `{DAV:}propstat` without a `{DAV:}prop`. +* #668: More information about vcf-export-plugin in browser plugin. +* #669: Add export button to browser plugin for address books. (@mgee) +* #670: multiget report hrefs were not decoded. +* The zip release ships with [sabre/vobject 3.4.4][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. + + +3.0.0-beta2 (2015-05-27) +------------------------ + +* A node's properties should not overwrite properties that were already set. +* Some uris were not correctly encoded in notifications. +* The zip release ships with [sabre/vobject 3.4.4][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. + + +3.0.0-beta1 (2015-05-25) +------------------------ + +* `migrate22.php` is now called `migrate30.php`. +* Using php-cs-fixer for automated coding standards enforcement and fixing. +* #660: principals could break html output. +* #662: Fixed several bugs in the `share` request parser. +* #665: Fix a bug in serialization of complex properties in the proppatch + request in the client. +* #666: expand-property report did not correctly prepend the base uri when + generating uris, this caused delegation to break. +* #659: Don't throw errors when when etag-related checks are done on + collections. +* Fully supporting the updated `Prefer` header syntax, as defined in + [rfc7240][rfc7240]. +* The zip release ships with [sabre/vobject 3.4.3][vobj], + [sabre/http 4.0.0][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 1.0.0][xml]. + + +3.0.0-alpha1 (2015-05-19) +------------------------- + +* It's now possible to get all property information from files using the + browser plugin. +* Browser plugin will now show a 'calendar export' button when the + ics-export plugin is enabled. +* Some nodes that by default showed the current time as their last + modification time, now no longer has a last modification time. +* CardDAV namespace was missing from default namespaceMap. +* #646: Properties can now control their own HTML output in the browser plugin. +* #646: Nicer HTML output for the `{DAV:}acl` property. +* Browser plugin no longer shows a few properties that take up a lot of space, + but are likely not really interesting for most users. +* #654: Added a collection, `Sabre\DAVACL\FS\HomeCollection` for automatically + creating a private home collection per-user. +* Changed all MySQL columns from `VARCHAR` to `VARBINARY` where possible. +* Improved older migration scripts a bit to allow easier testing. +* The zip release ships with [sabre/vobject 3.4.3][vobj], + [sabre/http 4.0.0-alpha3][http], [sabre/event 2.0.2][evnt], + [sabre/uri 1.0.1][uri] and [sabre/xml 0.4.3][xml]. + + +2.2.0-alpha4 (2015-04-13) +------------------------- + +* Complete rewrite of the XML system. We now use our own [sabre/xml][xml], + which has a much smarter XML Reader and Writer. +* BC Break: It's no longer possible to instantiate the Locks plugin without + a locks backend. I'm not sure why this ever made sense. +* Simplified the Locking system and fixed a bug related to if tokens checking + locks unrelated to the current request. +* `FSExt` Directory and File no longer do custom property storage. This + functionality is already covered pretty well by the `PropertyStorage` plugin, + so please switch. +* Renamed `Sabre\CardDAV\UserAddressBooks` to `Sabre\CardDAV\AddressBookHome` + to be more consistent with `CalendarHome` as well as the CardDAV + specification. +* `Sabre\DAV\IExtendedCollection` now receives a `Sabre\DAV\MkCol` object as + its second argument, and no longer receives seperate properties and + resourcetype arguments. +* `MKCOL` now integrates better with propertystorage plugins. +* The zip release ships with [sabre/vobject 3.4.2][vobj], + [sabre/http 4.0.0-alpha1][http], [sabre/event 2.0.1][evnt], + [sabre/uri 1.0.0][uri] and [sabre/xml 0.4.3][xml]. + + +2.2.0-alpha3 (2015-02-25) +------------------------- + +* Contains all the changes introduced between 2.1.2 and 2.1.3. +* The zip release ships with [sabre/vobject 3.4.2][vobj], + [sabre/http 4.0.0-alpha1][http], [sabre/event 2.0.1][evnt] and + [sabre/uri 1.0.0][uri]. + + +2.2.0-alpha2 (2015-01-09) +------------------------- + +* Renamed `Sabre\DAV\Auth\Backend\BackendInterface::requireAuth` to + `challenge`, which is a more correct and better sounding name. +* The zip release ships with [sabre/vobject 3.3.5][vobj], + [sabre/http 3.0.4][http], [sabre/event 2.0.1][evnt]. + + +2.2.0-alpha1 (2014-12-10) +------------------------- + +* The browser plugin now has a new page with information about your sabredav + server, and shows information about every plugin that's loaded in the + system. +* #191: The Authentication system can now support multiple authentication + backends. +* Removed: all `$tableName` arguments from every PDO backend. This was already + deprecated, but has now been fully removed. All of these have been replaced + with public properties. +* Deleted several classes that were already deprecated much earlier: + * `Sabre\CalDAV\CalendarRootNode` + * `Sabre\CalDAV\UserCalendars` + * `Sabre\DAV\Exception\FileNotFound` + * `Sabre\DAV\Locks\Backend\FS` + * `Sabre\DAV\PartialUpdate\IFile` + * `Sabre\DAV\URLUtil` +* Removed: `Sabre\DAV\Client::addTrustedCertificates` and + `Sabre\DAV\Client::setVerifyPeer`. +* Removed: `Sabre\DAV\Plugin::getPlugin()` can now no longer return plugins + based on its class name. +* Removed: `Sabre\DAVACL\Plugin::getPrincipalByEmail()`. +* #560: GuessContentType plugin will now set content-type to + `application/octet-stream` if a better content-type could not be determined. +* #568: Added a `componentType` argument to `ICSExportPlugin`, allowing you to + specifically fetch `VEVENT`, `VTODO` or `VJOURNAL`. +* #582: Authentication backend interface changed to be stateless. If you + implemented your own authentication backend, make sure you upgrade your class + to the latest API! +* #582: `Sabre\DAV\Auth\Plugin::getCurrentUser()` is now deprecated. Use + `Sabre\DAV\Auth\Plugin::getCurrentPrincipal()` instead. +* #193: Fix `Sabre\DAV\FSExt\Directory::getQuotaInfo()` on windows. + + +2.1.11 (2016-??-??) +------------------- + +* #805: It wasn't possible to create calendars that hold events, journals and + todos using MySQL, because the `components` column was 1 byte too small. + + +2.1.10 (2016-03-10) +------------------- + +* #784: Sync logs for address books were not correctly cleaned up after + deleting them. + + +2.1.9 (2016-01-25) +------------------ + +* #674: PHP7 support (@DeepDiver1975). +* The zip release ships with [sabre/vobject 3.5.0][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.8 (2016-01-04) +------------------ + +* #729: Fixed a caching problem in the Tree object. +* #740: Bugs in `migrate20.php` script. +* The zip release ships with [sabre/vobject 3.4.8][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.7 (2015-09-05) +------------------ + +* #705: A `MOVE` request that gets prevented from deleting the source resource + will still remove the target resource. Now all events are triggered before + any destructive operations. +* The zip release ships with [sabre/vobject 3.4.7][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.6 (2015-07-21) +------------------ + +* #657: Migration script would break when coming a cross an iCalendar object + with no UID. +* #691: Workaround for broken Windows Phone client. +* The zip release ships with [sabre/vobject 3.4.5][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.5 (2015-07-11) +------------------ + +* #677: Resources with the name '0' would not get retrieved when using + `Depth: infinity` in a `PROPFIND` request. +* The zip release ships with [sabre/vobject 3.4.5][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.4 (2015-05-25) +------------------ + +* #651: Double-encoded path in the browser plugin. Should fix a few broken + links in some setups. +* #650: Correctly cleaning up change info after deleting calendars (@ErrOrnAmE). +* #658: Updating `schedule-calendar-default-URL` does not work well, so we're + disabling it until there's a better fix. +* The zip release ships with [sabre/vobject 3.4.3][vobj], + [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt]. + + +2.1.3 (2015-02-25) +------------------ + +* #586: `SCHEDULE-STATUS` should not contain a reason-phrase. +* #539: Fixed a bug related to scheduling in shared calendars. +* #595: Support for calendar-timezone in iCalendar exports. +* #581: findByUri would send empty prefixes to the principal backend (@soydeedo) +* #611: Escaping a bit more HTML output in the browser plugin. (@LukasReschke) +* #610: Don't allow discovery of arbitrary files using `..` in the browser + plugin (@LukasReschke). +* Browser plugin now shows quota properties. +* #612: PropertyStorage didn't delete properties from nodes when a node's + parents get deleted. +* #581: Fixed problems related to finding attendee information during + scheduling. +* The zip release ships with [sabre/vobject 3.4.2][vobj], + [sabre/http 3.0.4][http], and [sabre/event 2.0.1][evnt]. + + +2.1.2 (2014-12-10) +------------------ + +* #566: Another issue related to the migration script, which would cause + scheduling to not work well for events that were already added before the + migration. +* #567: Doing freebusy requests on accounts that had 0 calendars would throw + a `E_NOTICE`. +* #572: `HEAD` requests trigger a PHP warning. +* #579: Browser plugin can throw exception for a few resourcetypes that didn't + have an icon defined. +* The zip release ships with [sabre/vobject 3.3.4][vobj], + [sabre/http 3.0.4][http], and [sabre/event 2.0.1][evnt]. + + +2.1.1 (2014-11-22) +------------------ + +* #561: IMip Plugin didn't strip mailto: from email addresses. +* #566: Migration process had 2 problems related to adding the `uid` field + to the `calendarobjects` table. +* The zip release ships with [sabre/vobject 3.3.4][vobj], + [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. + + +2.1.0 (2014-11-19) +------------------ + +* #541: CalDAV PDO backend didn't respect overridden PDO table names. +* #550: Scheduling invites are no longer delivered into shared calendars. +* #554: `calendar-multiget` `REPORT` did not work on inbox items. +* #555: The `calendar-timezone` property is now respected for floating times + and all-day events in the `calendar-query`, `calendar-multiget` and + `free-busy-query` REPORTs. +* #555: The `calendar-timezone` property is also respected for scheduling + free-busy requests. +* #547: CalDAV system too aggressively 'corrects' incoming iCalendar data, and + as a result doesn't return an etag for common cases. +* The zip release ships with [sabre/vobject 3.3.4][vobj], + [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. + + +2.1.0-alpha2 (2014-10-23) +------------------------- + +* Added: calendar-user-address-set to default principal search properties + list. This should fix iOS attendee autocomplete support. +* Changed: Moved all 'notifications' functionality from `Sabre\CalDAV\Plugin` + to a new plugin: `Sabre\CalDAV\Notifications\Plugin`. If you want to use + notifications-related functionality, just add this plugin. +* Changed: Accessing the caldav inbox, outbox or notification collection no + longer triggers getCalendarsForUser() on backends. +* #533: New invites are no longer delivered to taks-only calendars. +* #538: Added `calendarObjectChange` event. +* Scheduling speedups. +* #539: added `afterResponse` event. (@joserobleda) +* Deprecated: All the "tableName" constructor arguments for all the PDO + backends are now deprecated. They still work, but will be removed in the + next major sabredav version. Every argument that is now deprecated can now + be accessed as a public property on the respective backends. +* #529: Added getCalendarObjectByUID to PDO backend, speeding up scheduling + operations on large calendars. +* The zip release ships with [sabre/vobject 3.3.3][vobj], + [sabre/http 3.0.2][http], and [sabre/event 2.0.1][evnt]. + + +2.1.0-alpha1 (2014-09-23) +------------------------- + +* Added: Support for [rfc6638][rfc6638], also known as CalDAV Scheduling. +* Added: Automatically converting between vCard 3, 4 and jCard using the + `Accept:` header, in CardDAV reports, and automatically converting from + jCard to vCard upon `PUT`. It's important to note that your backends _may_ + now recieve both vCard 3.0 and 4.0. +* Added: #444. Collections can now opt-in to support high-speed `MOVE`. +* Changed: PropertyStorage backends now have a `move` method. +* Added: `beforeMove`, and `afterMove` events. +* Changed: A few database changes for the CalDAV PDO backend. Make sure you + run `bin/migrate21.php` to upgrade your database schema. +* Changed: CalDAV backends have a new method: `getCalendarObjectByUID`. This + method MUST be implemented by all backends, but the `AbstractBackend` has a + simple default implementation for this. +* Changed: `Sabre\CalDAV\UserCalendars` has been renamed to + `Sabre\CalDAV\CalendarHome`. +* Changed: `Sabre\CalDAV\CalendarRootNode` has been renamed to + `Sabre\CalDAV\CalendarRoot`. +* Changed: The IMipHandler has been completely removed. With CalDAV scheduling + support, it is no longer needed. It's functionality has been replaced by + `Sabre\CalDAV\Schedule\IMipPlugin`, which can now send emails for clients + other than iCal. +* Removed: `Sabre\DAV\ObjectTree` and `Sabre\DAV\Tree\FileSystem`. All this + functionality has been merged into `Sabre\DAV\Tree`. +* Changed: PrincipalBackend now has a findByUri method. +* Changed: `PrincipalBackend::searchPrincipals` has a new optional `test` + argument. +* Added: Support for the `{http://calendarserver.org/ns/}email-address-set` + property. +* #460: PropertyStorage must move properties during `MOVE` requests. +* Changed: Restructured the zip distribution to be a little bit more lean + and consistent. +* #524: Full support for the `test="anyof"` attribute in principal-search + `REPORT`. +* #472: Always returning lock tokens in the lockdiscovery property. +* Directory entries in the Browser plugin are sorted by type and name. + (@aklomp) +* #486: It's now possible to return additional properties when an 'allprop' + PROPFIND request is being done. (@aklomp) +* Changed: Now return HTTP errors when an addressbook-query REPORT is done + on a uri that's not a vcard. This should help with debugging this common + mistake. +* Changed: `PUT` requests with a `Content-Range` header now emit a 400 status + instead of 501, as per RFC7231. +* Added: Browser plugin can now display the contents of the + `{DAV:}supported-privilege-set` property. +* Added: Now reporting `CALDAV:max-resource-size`, but we're not actively + restricting it yet. +* Changed: CalDAV plugin is now responsible for reporting + `CALDAV:supported-collation-set` and `CALDAV:supported-calendar-data` + properties. +* Added: Now reporting `CARDDAV:max-resource-size`, but we're not actively + restricting it yet. +* Added: Support for `CARDDAV:supported-collation-set`. +* Changed: CardDAV plugin is now responsible for reporting + `CARDDAV:supported-address-data`. This functionality has been removed from + the CardDAV PDO backend. +* When a REPORT is not supported, we now emit HTTP error 415, instead of 403. +* #348: `HEAD` requests now work wherever `GET` also works. +* Changed: Lower priority for the iMip plugins `schedule` event listener. +* Added: #523 Custom CalDAV backends can now mark any calendar as read-only. +* The zip release ships with [sabre/vobject 3.3.3][vobj], + [sabre/http 3.0.0][http], and [sabre/event 2.0.0][evnt]. + + +2.0.9 (2015-09-04) +------------------ + +* #705: A `MOVE` request that gets prevented from deleting the source resource + will still remove the target resource. Now all events are triggered before + any destructive operations. +* The zip release ships with [sabre/vobject 3.4.6][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + + +2.0.8 (2015-07-11) +------------------ + +* #677: Resources with the name '0' would not get retrieved when using + `Depth: infinity` in a `PROPFIND` request. +* The zip release ships with [sabre/vobject 3.3.5][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.7 (2015-05-25) +------------------ + +* #650: Correctly cleaning up change info after deleting calendars (@ErrOrnAmE). +* The zip release ships with [sabre/vobject 3.3.4][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.6 (2014-12-10) +------------------ + +* Added `Sabre\CalDAV\CalendarRoot` as an alias for + `Sabre\CalDAV\CalendarRootNode`. The latter is going to be deprecated in 2.1, + so this makes it slightly easier to write code that works in both branches. +* #497: Making sure we're initializing the sync-token field with a value after + migration. +* The zip release ships with [sabre/vobject 3.3.4][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.5 (2014-10-14) +------------------ + +* #514: CalDAV PDO backend didn't work when overriding the 'calendar changes' + database table name. +* #515: 304 status code was not being sent when checking preconditions. +* The zip release ships with [sabre/vobject 3.3.3][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.4 (2014-08-27) +------------------ + +* #483: typo in calendars creation for PostgreSQL. +* #487: Locks are now automatically removed after a node has been deleted. +* #496: Improve CalDAV and CardDAV sync when there is no webdav-sync support. +* Added: Automatically mapping internal sync-tokens to getctag. +* The zip release ships with [sabre/vobject 3.3.1][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.3 (2014-07-14) +------------------ + +* #474: Fixed PropertyStorage `pathFilter()`. +* #476: CSP policy incorrect, causing stylesheets to not load in the browser + plugin. +* #475: Href properties in the browser plugin sometimes included a backslash. +* #478: `TooMuchMatches` exception never worked. This was fixed, and we also + took this opportunity to rename it to `TooManyMatches`. +* The zip release ships with [sabre/vobject 3.2.4][vobj], + [sabre/http 2.0.4][http], and [sabre/event 1.0.1][evnt]. + + +2.0.2 (2014-06-12) +------------------ + +* #470: Fixed compatibility with PHP < 5.4.14. +* #467: Fixed a problem in `examples/calendarserver.php`. +* #466: All the postgresql sample files have been updated. +* Fixed: An error would be thrown if a client did a propfind on a node the + user didn't have access to. +* Removed: Old and broken example code from the `examples/` directory. +* The zip release ships with [sabre/vobject 3.2.3][vobj], + [sabre/http 2.0.3][http], and [sabre/event 1.0.1][evnt]. + + +2.0.1 (2014-05-28) +------------------ + +* #459: PROPFIND requests on Files with no Depth header would return a fatal + error. +* #464: A PROPFIND allprops request should not return properties with status + 404. +* The zip release ships with [sabre/vobject 3.2.2][vobj], + [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. + + +2.0.0 (2014-05-22) +------------------ + +* The zip release ships with [sabre/vobject 3.2.2][vobj], + [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. +* Fixed: #456: Issue in sqlite migration script. +* Updated: MySQL database schema optimized by using more efficient column types. +* Cleaned up browser design. + + +2.0.0-beta1 (2014-05-15) +------------------------- + +* The zip release ships with [sabre/vobject 3.2.2][vobj], + [sabre/http 2.0.3][http], and [sabre/event 1.0.0][evnt]. +* BC Break: Property updating and fetching got refactored. Read the [migration + document][mi20] for more information. This allows for creation of a generic + property storage, and other property-related functionality that was not + possible before. +* BC Break: Removed `propertyUpdate`, `beforeGetProperties` and + `afterGetProperties` events. +* Fixed: #413: Memory optimizations for the CardDAV PDO backend. +* Updated: Brand new browser plugin with more debugging features and a design + that is slightly less painful. +* Added: Support for the `{DAV:}supported-method-set` property server-wide. +* Making it easier for implementors to override how the CardDAV addressbook + home is located. +* Fixed: Issue #422 Preconditions were not being set on PUT on non-existant + files. Not really a chance for data-loss, but incorrect nevertheless. +* Fixed: Issue #428: Etag check with `If:` fails if the target is a collection. +* Fixed: Issues #430, #431, #433: Locks plugin didn't not properly release + filesystem based locks. +* Fixed: #443. Support for creating new calendar subscriptions for OS X 10.9.2 + and up. +* Removed: `Sabre\DAV\Server::NODE_*` constants. +* Moved all precondition checking into a central place, instead of having to + think about it on a per-method basis. +* jCal transformation for calendar-query REPORT now works again. +* Switched to PSR-4 +* Fixed: #175. Returning ETag header upon a failed `If-Match` or + `If-None-Match` check. +* Removed: `lib/Sabre/autoload.php`. Use `vendor/autoload.php` instead. +* Removed: all the rfc documentation from the sabre/dav source. This made the + package needlessly larger. +* Updated: Issue #439. Lots of updates in PATCH support. The + Sabre_DAV_PartialUpdate_IFile interface is now deprecated and will be + removed in a future version. +* Added: `Sabre\DAV\Exception\LengthRequired`. + +1.9.0-alpha2 (2014-01-14) +------------------------- + +* The zip release ships with sabre/vobject 3.1.3, sabre/http 2.0.1, and + sabre/event 1.0.0. +* Added: Browser can now inspect any node, if ?sabreaction=browser is appended. +* Fixed: Issue #178. Support for multiple items in the Timeout header. +* Fixed: Issue #382. Stricter checking if calendar-query is allowed to run. +* Added: Depth: Infinity support for PROPFIND request. Thanks Thomas Müller and + Markus Goetz. + + +1.9.0-alpha1 (2013-11-07) +------------------------- + +* The zip release ships with sabre/vobject 3.1.3, sabre/http 2.0.0alpha5, and + sabre/event 1.0.0. +* BC Break: The CardDAV and CalDAV BackendInterface each have a new method: + getMultipleCards and getMultipleCalendarObjects. The Abstract and PDO backends + have default implementations, but if you implement that interface directly, + this method is now required. +* BC Break: XML property classes now receive an extra argument in their + unserialize method ($propertyMap). This allows for recursively parsing + properties, if needed. +* BC Break: Now using sabre/event for event emitting/subscription. For plugin + authors this means Server::subscribeEvent is now Server::on, and + Server::broadcastEvent is now Server::emit. +* BC Break: Almost all core functionality moved into a CorePlugin. +* BC Break: Most events triggered by the server got an overhaul. +* Changed: Sabre\HTTP now moved into a dedicated sabre/http package. +* Added: Support for WebDAV-sync (rfc6578). +* Added: Support for caldav-subscriptions, which is an easy way for caldav + clients to manage a list of subscriptions on the server. +* Added: Support for emitting and receiving jCal instead of iCalendar for + CalDAV. +* Added: BasicCallback authenticaton backend, for creating simple authentication + systems without having to define any classes. +* Added: A $transactionType property on the server class. This can be used for + logging and performance measuring purposes. +* Fixed: If event handlers modify the request body from a PUT request, an ETag + is no longer sent back. +* Added: Sabre\DAV\IMultiGet to optimize requests that retrieve information + about lists of resources. +* Added: MultiGet support to default CalDAV and CardDAV backends, speeding up + the multiget and sync reports quite a bit! +* Added: ICSExportPlugin can now generate jCal, filter on time-ranges and expand + recurrences. +* Fixed: Read-only access to calendars still allows the sharee to modify basic + calendar properties, such as the displayname and color. +* Changed: The default supportedPrivilegeSet has changed. Most privileges are no + longer marked as abstract. +* Changed: More elegant ACL management for CalendarObject and Card nodes. +* Added: Browser plugin now marks a carddav directory as type Directory, and a + shared calendar as 'Shared'. +* Added: When debugExceptions is turned on, all previous exceptions are also + traversed. +* Removed: Got rid of the Version classes for CalDAV, CardDAV, HTTP, and DAVACL. + Now that there's no separate packages anymore, this makes a bit more sense. +* Added: Generalized the multistatus response parser a bit more, for better + re-use. +* Added: Sabre\DAV\Client now has support for complex properties for PROPPATCH. + (Issue #299). +* Added: Sabre\DAV\Client has support for gzip and deflate encoding. +* Added: Sabre\DAV\Client now has support for sending objects as streams. +* Added: Deserializer for {DAV:}current-user-privilege-set. +* Added: Addressbooks or backends can now specify custom acl rules when creating + cards. +* Added: The ability for plugins to validate custom tokens in If: headers. +* Changed: Completely refactored the Lock plugin to deal with the new If: header + system. +* Added: Checking preconditions for MOVE, COPY, DELETE and PROPPATCH methods. +* Added: has() method on DAV\Property\SupportedReportSet. +* Added: If header now gets checked (with ETag) all the time. Before the dealing + with the If-header was a responsibility of the Locking plugin. +* Fixed: Outbox access for delegates. +* Added: Issue 333: It's now possible to override the calendar-home in the + CalDAV plugin. +* Added: A negotiateContentType to HTTP\Request. A convenience method. +* Fixed: Issue 349: Denying copying or moving a resource into it's own subtree. +* Fixed: SabreDAV catches every exception again. +* Added: Issue #358, adding a component=vevent parameter to the content-types + for calendar objects, if the caldav backend provides this info. + + +1.8.12-stable (2015-01-21) +-------------------------- + +* The zip release ships with sabre/vobject 2.1.7. +* #568: Support empty usernames and passwords in basic auth. + + +1.8.11 (2014-12-10) +------------------- + +* The zip release ships with sabre/vobject 2.1.6. +* Updated: MySQL database schema optimized by using more efficient column types. +* #516: The DAV client will now only redirect to HTTP and HTTPS urls. + + +1.8.10 (2014-05-15) +------------------- + +* The zip release ships with sabre/vobject 2.1.4. +* includes changes from version 1.7.12. + + +1.8.9 (2014-02-26) +------------------ + +* The zip release ships with sabre/vobject 2.1.3. +* includes changes from version 1.7.11. + + +1.8.8 (2014-02-09) +------------------ + +* includes changes from version 1.7.10. +* The zip release ships with sabre/vobject 2.1.3. + +1.8.7 (2013-10-02) +------------------ + +* the zip release ships with sabre/vobject 2.1.3. +* includes changes from version 1.7.9. + + +1.8.6 (2013-06-18) +------------------ + +* The zip release ships with sabre/vobject 2.1.0. +* Includes changes from version 1.7.8. + + +1.8.5 (2013-04-11) +------------------ + +* The zip release ships with sabre/vobject 2.0.7. +* Includes changes from version 1.7.7. + + +1.8.4 (2013-04-08) +------------------ + +* The zip release ships with sabre/vobject 2.0.7. +* Includes changes from version 1.7.6. + + +1.8.3 (2013-03-01) +------------------ + +* The zip release ships with sabre/vobject 2.0.6. +* Includes changes from version 1.7.5. +* Fixed: organizer email-address for shared calendars is now prefixed with + mailto:, as it should. + + +1.8.2 (2013-01-19) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* Includes changes from version 1.7.4. + + +1.8.1 (2012-12-01) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* Includes changes from version 1.7.3. +* Fixed: Typo in 1.7 migration script caused it to fail. + + +1.8.0 (2012-11-08) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* BC Break: Moved the entire codebase to PHP namespaces. +* BC Break: Every backend package (CalDAV, CardDAV, Auth, Locks, Principals) now + has consistent naming conventions. There's a BackendInterface, and an + AbstractBackend class. +* BC Break: Changed a bunch of constructor signatures in the CalDAV package, to + reduce dependencies on the ACL package. +* BC Break: Sabre_CalDAV_ISharedCalendar now also has a getShares method, so + sharees can figure out who is also on a shared calendar. +* Added: Sabre_DAVACL_IPrincipalCollection interface, to advertise support for + principal-property-search on any node. +* Added: Simple console script to fire up a fileserver in the current directory + using PHP 5.4's built-in webserver. +* Added: Sharee's can now also read out the list of invites for a shared + calendar. +* Added: The Proxy principal classes now both implement an interface, for + greater flexiblity. + + +1.7.13 (2014-07-28) +------------------- + +* The zip release ships with sabre/vobject 2.1.4. +* Changed: Removed phing and went with a custom build script for now. + + +1.7.12 (2014-05-15) +------------------- + +* The zip release ships with sabre/vobject 2.1.4. +* Updated: Issue #439. Lots of updates in PATCH support. The + Sabre_DAV_PartialUpdate_IFile interface is now deprecated and will be removed + in a future version. +* Fixed: Restoring old setting after changing libxml_disable_entity_loader. +* Fixed: Issue #422: Preconditions were not being set on PUT on non-existant + files. Not really a chance for data-loss, but incorrect nevertheless. +* Fixed: Issue #427: Now checking preconditions on DELETE requests. +* Fixed: Issue #428: Etag check with If: fails if the target is a collection. +* Fixed: Issue #393: PATCH request with missing end-range was handled + incorrectly. +* Added: Sabre_DAV_Exception_LengthRequired to omit 411 errors. + + +1.7.11 (2014-02-26) +------------------- + +* The zip release ships with sabre/vobject 2.1.3. +* Fixed: Issue #407: large downloads failed. +* Fixed: Issue #414: XXE security problem on older PHP versions. + + +1.7.10 (2014-02-09) +------------------- + +* Fixed: Issue #374: Don't urlescape colon (:) when it's not required. +* Fixed: Potential security vulnerability in the http client. + + +1.7.9 (2013-10-02) +------------------ + +* The zip release ships with sabre/vobject 2.1.3. +* Fixed: Issue #365. Incorrect output when principal urls have spaces in them. +* Added: Issue #367: Automatically adding a UID to vcards that don't have them. + + +1.7.8 (2013-06-17) +------------------ + +* The zip release ships with sabre/vobject 2.1.0. +* Changed: Sabre\DAV\Client::verifyPeer is now a protected property (instead of + private). +* Fixed: Text was incorrectly escaped in the Href and HrefList properties, + disallowing urls with ampersands (&) in them. +* Added: deserializer for Sabre\DAVACL\Property\CurrentUserPrivilegeSet. +* Fixed: Issue 335: Client only deserializes properties with status 200. +* Fixed: Issue 341: Escaping xml in 423 Locked error responses. +* Added: Issue 339: beforeGetPropertiesForPath event. + + +1.7.7 (2013-04-11) +------------------ + +* The zip release ships with sabre/vobject 2.0.7. +* Fixed: Assets in the browser plugins were not being served on windows + machines. + + +1.7.6 (2013-04-08) +------------------ + +* The zip release ships with sabre/vobject 2.0.7. +* Fixed: vcardurl in database schema can now hold 255 characters instead of 80 + (which is often way to small). +* Fixed: The browser plugin potentially allowed people to open any arbitrary + file on windows servers (CVE-2013-1939). + + +1.7.5 (2013-03-01) +------------------ + +* The zip release ships with sabre/vobject 2.0.6. +* Change: No longer advertising support for 4.0 vcards. iOS and OS X address + book don't handle this well, and just advertising 3.0 support seems like the + most logical course of action. +* Added: ->setVerifyPeers to Sabre_DAV_Client (greatly resisting against it, + don't use this..). + + +1.7.4 (2013-01-19) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* Changed: To be compatibile with MS Office 2011 for Mac, a workaround was + removed that was added to support old versions of Windows XP (pre-SP3). + Indeed! We needed a crazy workaround to work with one MS product in the past, + and we can't keep that workaround to be compatible with another MS product. +* Fixed: expand-properties REPORT had incorrect values for the href element. +* Fixed: Range requests now work for non-seekable streams. (Thanks Alfred + Klomp). +* Fixed: Changed serialization of {DAV:}getlastmodified and {DAV:}supportedlock + to improve compatiblity with MS Office 2011 for Mac. +* Changed: reverted the automatic translation of 'DAV:' xml namespaces to + 'urn:DAV' when parsing files. Issues were reported with libxml 2.6.32, on a + relatively recent debian release, so we'll wait till 2015 to take this one out + again. +* Added: Sabre_DAV_Exception_ServiceUnavailable, for emitting 503's. + + +1.7.3 (2012-12-01) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* Fixed: Removing double slashes from getPropertiesForPath. +* Change: Marked a few more properties in the CardDAV as protected, instead of + private. +* Fixed: SharingPlugin now plays nicer with other plugins with similar + functionality. +* Fixed: Issue 174. Sending back HTTP/1.0 for requests with this version. + + +1.7.2 (2012-11-08) +------------------ + +* The zip release ships with sabre/vobject 2.0.5. +* Added: ACL plugin advertises support for 'calendarserver-principal- + property-search'. +* Fixed: [#153] Allowing for relative http principals in iMip requests. +* Added: Support for cs:first-name and cs:last-name properties in sharing + invites. +* Fixed: Made a bunch of properties protected, where they were private before. +* Added: Some non-standard properties for sharing to improve compatibility. +* Fixed: some bugfixes in postgres sql script. +* Fixed: When requesting some properties using PROPFIND, they could show up as + both '200 Ok' and '403 Forbidden'. +* Fixed: calendar-proxy principals were not checked for deeper principal + membership than 1 level. +* Fixed: setGroupMemberSet argument now correctly receives relative principal + urls, instead of the absolute ones. +* Fixed: Server class will filter out any bonus properties if any extra were + returned. This means the implementor of the IProperty class can be a bit + lazier when implementing. Note: bug numbers after this line refer to Google + Code tickets. We're using github now. + + +1.7.1 (2012-10-07) +------------------ + +* Fixed: include path problem in the migration script. + + +1.7.0 (2012-10-06) +------------------ + +* BC Break: The calendarobjects database table has a bunch of new fields, and a + migration script is required to ensure everything will keep working. Read the + wiki for more details. +* BC Break: The ICalendar interface now has a new method: calendarQuery. +* BC Break: In this version a number of classes have been deleted, that have + been previously deprecated. Namely: - Sabre_DAV_Directory (now: + Sabre_DAV_Collection) - Sabre_DAV_SimpleDirectory (now: + Sabre_DAV_SimpleCollection) +* BC Break: Sabre_CalDAV_Schedule_IMip::sendMessage now has an extra argument. + If you extended this class, you should fix this method. It's only used for + informational purposes. +* BC Break: The DAV: namespace is no longer converted to urn:DAV. This was a + workaround for a bug in older PHP versions (pre-5.3). +* Removed: Sabre.includes.php was deprecated, and is now removed. +* Removed: Sabre_CalDAV_Server was deprecated, and is now removed. Please use + Sabre_DAV_Server and check the examples in the examples/ directory. +* Changed: The Sabre_VObject library now spawned into it's own project! The + VObject library is still included in the SabreDAV zip package. +* Added: Experimental interfaces to allow implementation of caldav-sharing. Note + that no implementation is provided yet, just the api hooks. +* Added: Free-busy reporting compliant with the caldav-scheduling standard. This + allows iCal and other clients to fetch other users' free-busy data. +* Added: Experimental NotificationSupport interface to add caldav notifications. +* Added: VCF Export plugin. If enabled, it can generate an export of an entire + addressbook. +* Added: Support for PATCH using a SabreDAV format, to live-patch files. +* Added: Support for Prefer: return-minimal and Brief: t headers for PROPFIND + and PROPPATCH requests. +* Changed: Responsibility for dealing with the calendar-query is now moved from + the CalDAV plugin to the CalDAV backends. This allows for heavy optimizations. +* Changed: The CalDAV PDO backend is now a lot faster for common calendar + queries. +* Changed: We are now using the composer autoloader. +* Changed: The CalDAV backend now all implement an interface. +* Changed: Instead of Sabre_DAV_Property, Sabre_DAV_PropertyInterface is now the + basis of every property class. +* Update: Caching results for principal lookups. This should cut down queries + and performance for a number of heavy requests. +* Update: ObjectTree caches lookups much more aggresively, which will help + especially speeding up a bunch of REPORT queries. +* Added: Support for the schedule-calendar-transp property. +* Fixed: Marking both the text/calendar and text/x-vcard as UTF-8 encoded. +* Fixed: Workaround for the SOGO connector, as it doesn't understand receiving + "text/x-vcard; charset=utf-8" for a contenttype. +* Added: Sabre_DAV_Client now throws more specific exceptions in cases where we + already has an exception class. +* Added: Sabre_DAV_PartialUpdate. This plugin allows you to use the PATCH method + to update parts of a file. +* Added: Tons of timezone name mappings for Microsoft Exchange. +* Added: Support for an 'exception' event in the server class. +* Fixed: Uploaded VCards without a UID are now rejected. (thanks Dominik!) +* Fixed: Rejecting calendar objects if they are not in the + supported-calendar-component list. (thanks Armin!) +* Fixed: Issue 219: serialize() now reorders correctly. +* Fixed: Sabre_DAV_XMLUtil no longer returns empty $dom->childNodes if there is + whitespace in $dom. +* Fixed: Returning 409 Conflict instead of 500 when an attempt is made to create + a file as a child of something that's not a collection. +* Fixed: Issue 237: xml-encoding values in SabreDAV error responses. +* Fixed: Returning 403, instead of 501 when an unknown REPORT is requested. +* Fixed: Postfixing slash on {DAV:}owner properties. +* Fixed: Several embarrassing spelling mistakes in docblocks. + + +1.6.10 (2013-06-17) +------------------- + +* Fixed: Text was incorrectly escaped in the Href and HrefList properties, + disallowing urls with ampersands (&) in them. +* Fixed: Issue 341: Escaping xml in 423 Locked error responses. + + +1.6.9 (2013-04-11) +------------------ + +* Fixed: Assets in the browser plugins were not being served on windows + machines. + + +1.6.8 (2013-04-08) +------------------ + +* Fixed: vcardurl in database schema can now hold 255 characters instead of 80 + (which is often way to small). +* Fixed: The browser plugin potentially allowed people to open any arbitrary + file on windows servers. (CVE-2013-1939). + + +1.6.7 (2013-03-01) +------------------ + +* Change: No longer advertising support for 4.0 vcards. iOS and OS X address + book don't handle this well, and just advertising 3.0 support seems like the + most logical course of action. +* Added: ->setVerifyPeers to Sabre_DAV_Client (greatly resisting against it, + don't use this..). + + +1.6.6 (2013-01-19) +------------------ + +* Fixed: Backported a fix for broken XML serialization in error responses. + (Thanks @DeepDiver1975!) + + +1.6.5 (2012-10-04) +------------------ + +* Fixed: Workaround for line-ending bug OS X 10.8 addressbook has. +* Added: Ability to allow users to set SSL certificates for the Client class. + (Thanks schiesbn!). +* Fixed: Directory indexes with lots of nodes should be a lot faster. +* Fixed: Issue 235: E_NOTICE thrown when doing a propfind request with + Sabre_DAV_Client, and no valid properties are returned. +* Fixed: Issue with filtering on alarms in tasks. + + +1.6.4 (2012-08-02) +------------------ + +* Fixed: Issue 220: Calendar-query filters may fail when filtering on alarms, if + an overridden event has it's alarm removed. +* Fixed: Compatibility for OS/X 10.8 iCal in the IMipHandler. +* Fixed: Issue 222: beforeWriteContent shouldn't be called for lock requests. +* Fixed: Problem with POST requests to the outbox if mailto: was not lower + cased. +* Fixed: Yearly recurrence rule expansion on leap-days no behaves correctly. +* Fixed: Correctly checking if recurring, all-day events with no dtstart fall in + a timerange if the start of the time-range exceeds the start of the instance + of an event, but not the end. +* Fixed: All-day recurring events wouldn't match if an occurence ended exactly + on the start of a time-range. +* Fixed: HTTP basic auth did not correctly deal with passwords containing colons + on some servers. +* Fixed: Issue 228: DTEND is now non-inclusive for all-day events in the + calendar-query REPORT and free-busy calculations. + + +1.6.3 (2012-06-12) +------------------ + +* Added: It's now possible to specify in Sabre_DAV_Client which type of + authentication is to be used. +* Fixed: Issue 206: Sabre_DAV_Client PUT requests are fixed. +* Fixed: Issue 205: Parsing an iCalendar 0-second date interval. +* Fixed: Issue 112: Stronger validation of iCalendar objects. Now making sure + every iCalendar object only contains 1 component, and disallowing vcards, + forcing every component to have a UID. +* Fixed: Basic validation for vcards in the CardDAV plugin. +* Fixed: Issue 213: Workaround for an Evolution bug, that prevented it from + updating events. +* Fixed: Issue 211: A time-limit query on a non-relative alarm trigger in a + recurring event could result in an endless loop. +* Fixed: All uri fields are now a maximum of 200 characters. The Bynari outlook + plugin used much longer strings so this should improve compatibility. +* Fixed: Added a workaround for a bug in KDE 4.8.2 contact syncing. See + https://bugs.kde.org/show_bug.cgi?id=300047 +* Fixed: Issue 217: Sabre_DAV_Tree_FileSystem was pretty broken. + + +1.6.2 (2012-04-16) +------------------ + +* Fixed: Sabre_VObject_Node::$parent should have been public. +* Fixed: Recurrence rules of events are now taken into consideration when doing + time-range queries on alarms. +* Fixed: Added a workaround for the fact that php's DateInterval cannot parse + weeks and days at the same time. +* Added: Sabre_DAV_Server::$exposeVersion, allowing you to hide SabreDAV's + version number from various outputs. +* Fixed: DTSTART values would be incorrect when expanding events. +* Fixed: DTSTART and DTEND would be incorrect for expansion of WEEKLY BYDAY + recurrences. +* Fixed: Issue 203: A problem with overridden events hitting the exact date and + time of a subsequent event in the recurrence set. +* Fixed: There was a problem with recurrence rules, for example the 5th tuesday + of the month, if this day did not exist. +* Added: New HTTP status codes from draft-nottingham-http-new-status-04. + + +1.6.1 (2012-03-05) +------------------ + +* Added: createFile and put() can now return an ETag. +* Added: Sending back an ETag on for operations on CardDAV backends. This should + help with OS X 10.6 Addressbook compatibility. +* Fixed: Fixed a bug where an infinite loop could occur in the recurrence + iterator if the recurrence was YEARLY, with a BYMONTH rule, and either BYDAY + or BYMONTHDAY match the first day of the month. +* Fixed: Events that are excluded using EXDATE are still counted in the COUNT= + parameter in the RRULE property. +* Added: Support for time-range filters on VALARM components. +* Fixed: Correctly filtering all-day events. +* Fixed: Sending back correct mimetypes from the browser plugin (thanks + Jürgen). +* Fixed: Issue 195: Sabre_CardDAV pear package had an incorrect dependency. +* Fixed: Calendardata would be destroyed when performing a MOVE request. + + +1.6.0 (2012-02-22) +------------------ + +* BC Break: Now requires PHP 5.3 +* BC Break: Any node that implemented Sabre_DAVACL_IACL must now also implement + the getSupportedPrivilegeSet method. See website for details. +* BC Break: Moved functions from Sabre_CalDAV_XMLUtil to + Sabre_VObject_DateTimeParser. +* BC Break: The Sabre_DAVACL_IPrincipalCollection now has two new methods: + 'searchPrincipals' and 'updatePrincipal'. +* BC Break: Sabre_DAV_ILockable is removed and all related per-node locking + functionality. +* BC Break: Sabre_DAV_Exception_FileNotFound is now deprecated in favor of + Sabre_DAV_Exception_NotFound. The former will be removed in a later version. +* BC Break: Removed Sabre_CalDAV_ICalendarUtil, use Sabre_VObject instead. +* BC Break: Sabre_CalDAV_Server is now deprecated, check out the documentation + on how to setup a caldav server with just Sabre_DAV_Server. +* BC Break: Default Principals PDO backend now needs a new field in the + 'principals' table. See the website for details. +* Added: Ability to create new calendars and addressbooks from within the + browser plugin. +* Added: Browser plugin: icons for various nodes. +* Added: Support for FREEBUSY reports! +* Added: Support for creating principals with admin-level privileges. +* Added: Possibility to let server send out invitation emails on behalf of + CalDAV client, using Sabre_CalDAV_Schedule_IMip. +* Changed: beforeCreateFile event now passes data argument by reference. +* Changed: The 'propertyMap' property from Sabre_VObject_Reader, must now be + specified in Sabre_VObject_Property::$classMap. +* Added: Ability for plugins to tell the ACL plugin which principal plugins are + searchable. +* Added: [DAVACL] Per-node overriding of supported privileges. This allows for + custom privileges where needed. +* Added: [DAVACL] Public 'principalSearch' method on the DAVACL plugin, which + allows for easy searching for principals, based on their properties. +* Added: Sabre_VObject_Component::getComponents() to return a list of only + components and not properties. +* Added: An includes.php file in every sub-package (CalDAV, CardDAV, DAV, + DAVACL, HTTP, VObject) as an alternative to the autoloader. This often works + much faster. +* Added: Support for the 'Me card', which allows Addressbook.app users specify + which vcard is their own. +* Added: Support for updating principal properties in the DAVACL principal + backends. +* Changed: Major refactoring in the calendar-query REPORT code. Should make + things more flexible and correct. +* Changed: The calendar-proxy-[read|write] principals will now only appear in + the tree, if they actually exist in the Principal backend. This should reduce + some problems people have been having with this. +* Changed: Sabre_VObject_Element_* classes are now renamed to + Sabre_VObject_Property. Old classes are retained for backwards compatibility, + but this will be removed in the future. +* Added: Sabre_VObject_FreeBusyGenerator to generate free-busy reports based on + lists of events. +* Added: Sabre_VObject_RecurrenceIterator to find all the dates and times for + recurring events. +* Fixed: Issue 97: Correctly handling RRULE for the calendar-query REPORT. +* Fixed: Issue 154: Encoding of VObject parameters with no value was incorrect. +* Added: Support for {DAV:}acl-restrictions property from RFC3744. +* Added: The contentlength for calendar objects can now be supplied by a CalDAV + backend, allowing for more optimizations. +* Fixed: Much faster implementation of Sabre_DAV_URLUtil::encodePath. +* Fixed: {DAV:}getcontentlength may now be not specified. +* Fixed: Issue 66: Using rawurldecode instead of urldecode to decode paths from + clients. This means that + will now be treated as a literal rather than a + space, and this should improve compatibility with the Windows built-in client. +* Added: Sabre_DAV_Exception_PaymentRequired exception, to emit HTTP 402 status + codes. +* Added: Some mysql unique constraints to example files. +* Fixed: Correctly formatting HTTP dates. +* Fixed: Issue 94: Sending back Last-Modified header for 304 responses. +* Added: Sabre_VObject_Component_VEvent, Sabre_VObject_Component_VJournal, + Sabre_VObject_Component_VTodo and Sabre_VObject_Component_VCalendar. +* Changed: Properties are now also automatically mapped to their appropriate + classes, if they are created using the add() or __set() methods. +* Changed: Cloning VObject objects now clones the entire tree, rather than just + the default shallow copy. +* Added: Support for recurrence expansion in the CALDAV:calendar-multiget and + CALDAV:calendar-query REPORTS. +* Changed: CalDAV PDO backend now sorts calendars based on the internal + 'calendarorder' field. +* Added: Issue 181: Carddav backends may no optionally not supply the carddata + in getCards, if etag and size are specified. This may speed up certain + requests. +* Added: More arguments to beforeWriteContent and beforeCreateFile (see + WritingPlugins wiki document). +* Added: Hook for iCalendar validation. This allows us to validate iCalendar + objects when they're uploaded. At the moment we're just validating syntax. +* Added: VObject now support Windows Timezone names correctly (thanks mrpace2). +* Added: If a timezonename could not be detected, we fall back on the default + PHP timezone. +* Added: Now a Composer package (thanks willdurand). +* Fixed: Support for \N as a newline character in the VObject reader. +* Added: afterWriteContent, afterCreateFile and afterUnbind events. +* Added: Postgresql example files. Not part of the unittests though, so use at + your own risk. +* Fixed: Issue 182: Removed backticks from sql queries, so it will work with + Postgres. + + +1.5.9 (2012-04-16) +------------------ + +* Fixed: Issue with parsing timezone identifiers that were surrounded by quotes. + (Fixes emClient compatibility). + + +1.5.8 (2012-02-22) +------------------ + +* Fixed: Issue 95: Another timezone parsing issue, this time in calendar-query. + + +1.5.7 (2012-02-19) +------------------ + +* Fixed: VObject properties are now always encoded before components. +* Fixed: Sabre_DAVACL had issues with multiple levels of privilege aggregration. +* Changed: Added 'GuessContentType' plugin to fileserver.php example. +* Fixed: The Browser plugin will now trigger the correct events when creating + files. +* Fixed: The ICSExportPlugin now considers ACL's. +* Added: Made it optional to supply carddata from an Addressbook backend when + requesting getCards. This can make some operations much faster, and could + result in much lower memory use. +* Fixed: Issue 187: Sabre_DAV_UUIDUtil was missing from includes file. +* Fixed: Issue 191: beforeUnlock was triggered twice. + + +1.5.6 (2012-01-07) +------------------ + +* Fixed: Issue 174: VObject could break UTF-8 characters. +* Fixed: pear package installation issues. + + +1.5.5 (2011-12-16) +------------------ + +* Fixed: CalDAV time-range filter workaround for recurring events. +* Fixed: Bug in Sabre_DAV_Locks_Backend_File that didn't allow multiple files to + be locked at the same time. + + +1.5.4 (2011-10-28) +------------------ + +* Fixed: GuessContentType plugin now supports mixed case file extensions. +* Fixed: DATE-TIME encoding was wrong in VObject. (we used 'DATETIME'). +* Changed: Sending back HTTP 204 after a PUT request on an existing resource + instead of HTTP 200. This should fix Evolution CardDAV client compatibility. +* Fixed: Issue 95: Parsing X-LIC-LOCATION if it's available. +* Added: All VObject elements now have a reference to their parent node. + + +1.5.3 (2011-09-28) +------------------ + +* Fixed: Sabre_DAV_Collection was missing from the includes file. +* Fixed: Issue 152. iOS 1.4.2 apparantly requires HTTP/1.1 200 OK to be in + uppercase. +* Fixed: Issue 153: Support for files with mixed newline styles in + Sabre_VObject. +* Fixed: Issue 159: Automatically converting any vcard and icalendardata to + UTF-8. +* Added: Sabre_DAV_SimpleFile class for easy static file creation. +* Added: Issue 158: Support for the CARDDAV:supported-address-data property. + + +1.5.2 (2011-09-21) +------------------ + +* Fixed: carddata and calendardata MySQL fields are now of type 'mediumblob'. + 'TEXT' was too small sometimes to hold all the data. +* Fixed: {DAV:}supported-report-set is now correctly reporting the reports for + IAddressBook. +* Added: Sabre_VObject_Property::add() to add duplicate parameters to + properties. +* Added: Issue 151: Sabre_CalDAV_ICalendar and Sabre_CalDAV_ICalendarObject + interfaces. +* Fixed: Issue 140: Not returning 201 Created if an event cancelled the creation + of a file. +* Fixed: Issue 150: Faster URLUtil::encodePath() implementation. +* Fixed: Issue 144: Browser plugin could interfere with + TemporaryFileFilterPlugin if it was loaded first. +* Added: It's not possible to specify more 'alternate uris' in principal + backends. + + +1.5.1 (2011-08-24) +------------------ + +* Fixed: Issue 137. Hiding action interface in HTML browser for non-collections. +* Fixed: addressbook-query is now correctly returned from the + {DAV:}supported-report-set property. +* Fixed: Issue 142: Bugs in groupwareserver.php example. +* Fixed: Issue 139: Rejecting PUT requests with Content-Range. + + +1.5.0 (2011-08-12) +------------------ + +* Added: CardDAV support. +* Added: An experimental WebDAV client. +* Added: MIME-Directory grouping support in the VObject library. This is very + useful for people attempting to parse vcards. +* BC Break: Adding parameters with the VObject libraries now overwrites the + previous parameter, rather than just add it. This makes more sense for 99% of + the cases. +* BC Break: lib/Sabre.autoload.php is now removed in favor of + lib/Sabre/autoload.php. +* Deprecated: Sabre_DAV_Directory is now deprecated and will be removed in a + future version. Use Sabre_DAV_Collection instead. +* Deprecated: Sabre_DAV_SimpleDirectory is now deprecated and will be removed in + a future version. Use Sabre_DAV_SimpleCollection instead. +* Fixed: Problem with overriding tablenames for the CalDAV backend. +* Added: Clark-notation parser to XML utility. +* Added: unset() support to VObject components. +* Fixed: Refactored CalDAV property fetching to be faster and simpler. +* Added: Central string-matcher for CalDAV and CardDAV plugins. +* Added: i;unicode-casemap support +* Fixed: VObject bug: wouldn't parse parameters if they weren't specified in + uppercase. +* Fixed: VObject bug: Parameters now behave more like Properties. +* Fixed: VObject bug: Parameters with no value are now correctly parsed. +* Changed: If calendars don't specify which components they allow, 'all' + components are assumed (e.g.: VEVENT, VTODO, VJOURNAL). +* Changed: Browser plugin now uses POST variable 'sabreAction' instead of + 'action' to reduce the chance of collisions. + + +1.4.4 (2011-07-07) +------------------ + +* Fixed: Issue 131: Custom CalDAV backends could break in certain cases. +* Added: The option to override the default tablename all PDO backends use. + (Issue 60). +* Fixed: Issue 124: 'File' authentication backend now takes realm into + consideration. +* Fixed: Sabre_DAV_Property_HrefList now properly deserializes. This allows + users to update the {DAV:}group-member-set property. +* Added: Helper functions for DateTime-values in Sabre_VObject package. +* Added: VObject library can now automatically map iCalendar properties to + custom classes. + + +1.4.3 (2011-04-25) +------------------ + +* Fixed: Issue 123: Added workaround for Windows 7 UNLOCK bug. +* Fixed: datatype of lastmodified field in mysql.calendars.sql. Please change + the DATETIME field to an INT to ensure this field will work correctly. +* Change: Sabre_DAV_Property_Principal is now renamed to + Sabre_DAVACL_Property_Principal. +* Added: API level support for ACL HTTP method. +* Fixed: Bug in serializing {DAV:}acl property. +* Added: deserializer for {DAV:}resourcetype property. +* Added: deserializer for {DAV:}acl property. +* Added: deserializer for {DAV:}principal property. + + +1.4.2-beta (2011-04-01) +----------------------- + +* Added: It's not possible to disable listing of nodes that are denied read + access by ACL. +* Fixed: Changed a few properties in CalDAV classes from private to protected. +* Fixed: Issue 119: Terrible things could happen when relying on guessBaseUri, + the server was running on the root of the domain and a user tried to access a + file ending in .php. This is a slight BC break. +* Fixed: Issue 118: Lock tokens in If headers without a uri should be treated as + the request uri, not 'all relevant uri's. +* Fixed: Issue 120: PDO backend was incorrectly fetching too much locks in cases + where there were similar named locked files in a directory. + + +1.4.1-beta (2011-02-26) +----------------------- + +* Fixed: Sabre_DAV_Locks_Backend_PDO returned too many locks. +* Fixed: Sabre_HTTP_Request::getHeader didn't return Content-Type when running + on apache, so a few workarounds were added. +* Change: Slightly changed CalDAV Backend API's, to allow for heavy + optimizations. This is non-bc breaking. + + +1.4.0-beta (2011-02-12) +----------------------- + +* Added: Partly RFC3744 ACL support. +* Added: Calendar-delegation (caldav-proxy) support. +* BC break: In order to fix Issue 99, a new argument had to be added to + Sabre_DAV_Locks_Backend_*::getLocks classes. Consult the classes for details. +* Deprecated: Sabre_DAV_Locks_Backend_FS is now deprecated and will be removed + in a later version. Use PDO or the new File class instead. +* Deprecated: The Sabre_CalDAV_ICalendarUtil class is now marked deprecated, and + will be removed in a future version. Please use Sabre_VObject instead. +* Removed: All principal-related functionality has been removed from the + Sabre_DAV_Auth_Plugin, and moved to the Sabre_DAVACL_Plugin. +* Added: VObject library, for easy vcard/icalendar parsing using a natural + interface. +* Added: Ability to automatically generate full .ics feeds off calendars. To + use: Add the Sabre_CalDAV_ICSExportPlugin, and add ?export to your calendar + url. +* Added: Plugins can now specify a pluginname, for easy access using + Sabre_DAV_Server::getPlugin(). +* Added: beforeGetProperties event. +* Added: updateProperties event. +* Added: Principal listings and calendar-access can now be done privately, + disallowing users from accessing or modifying other users' data. +* Added: You can now pass arrays to the Sabre_DAV_Server constructor. If it's an + array with node-objects, a Root collection will automatically be created, and + the nodes are used as top-level children. +* Added: The principal base uri is now customizable. It used to be hardcoded to + 'principals/[user]'. +* Added: getSupportedReportSet method in ServerPlugin class. This allows you to + easily specify which reports you're implementing. +* Added: A '..' link to the HTML browser. +* Fixed: Issue 99: Locks on child elements were ignored when their parent nodes + were deleted. +* Fixed: Issue 90: lockdiscovery property and LOCK response now include a + {DAV}lockroot element. +* Fixed: Issue 96: support for 'default' collation in CalDAV text-match filters. +* Fixed: Issue 102: Ensuring that copy and move with identical source and + destination uri's fails. +* Fixed: Issue 105: Supporting MKCALENDAR with no body. +* Fixed: Issue 109: Small fixes in Sabre_HTTP_Util. +* Fixed: Issue 111: Properly catching the ownername in a lock (if it's a string) +* Fixed: Sabre_DAV_ObjectTree::nodeExist always returned false for the root + node. +* Added: Global way to easily supply new resourcetypes for certain node classes. +* Fixed: Issue 59: Allowing the user to override the authentication realm in + Sabre_CalDAV_Server. +* Update: Issue 97: Looser time-range checking if there's a recurrence rule in + an event. This fixes 'missing recurring events'. + + +1.3.0 (2010-10-14) +------------------ + +* Added: childExists method to Sabre_DAV_ICollection. This is an api break, so + if you implement Sabre_DAV_ICollection directly, add the method. +* Changed: Almost all HTTP method implementations now take a uri argument, + including events. This allows for internal rerouting of certain calls. If you + have custom plugins, make sure they use this argument. If they don't, they + will likely still work, but it might get in the way of future changes. +* Changed: All getETag methods MUST now surround the etag with double-quotes. + This was a mistake made in all previous SabreDAV versions. If you don't do + this, any If-Match, If-None-Match and If: headers using Etags will work + incorrectly. (Issue 85). +* Added: Sabre_DAV_Auth_Backend_AbstractBasic class, which can be used to easily + implement basic authentication. +* Removed: Sabre_DAV_PermissionDenied class. Use Sabre_DAV_Forbidden instead. +* Removed: Sabre_DAV_IDirectory interface, use Sabre_DAV_ICollection instead. +* Added: Browser plugin now uses {DAV:}displayname if this property is + available. +* Added: Cache layer in the ObjectTree. +* Added: Tree classes now have a delete and getChildren method. +* Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if the + date is an exact match. +* Fixed: Support for multiple ETags in If-Match and If-None-Match headers. +* Fixed: Improved baseUrl handling. +* Fixed: Issue 67: Non-seekable stream support in ::put()/::get(). +* Fixed: Issue 65: Invalid dates are now ignored. +* Updated: Refactoring in Sabre_CalDAV to make everything a bit more ledgable. +* Fixed: Issue 88, Issue 89: Fixed compatibility for running SabreDAV on + Windows. +* Fixed: Issue 86: Fixed Content-Range top-boundary from 'file size' to 'file + size'-1. + + +1.2.5 (2010-08-18) +------------------ + +* Fixed: Issue 73: guessBaseUrl fails for some servers. +* Fixed: Issue 67: SabreDAV works better with non-seekable streams. +* Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if + the date is an exact match. + + +1.2.4 (2010-07-13) +------------------ + +* Fixed: Issue 62: Guessing baseUrl fails when url contains a query-string. +* Added: Apache configuration sample for CGI/FastCGI setups. +* Fixed: Issue 64: Only returning calendar-data when it was actually requested. + + +1.2.3 (2010-06-26) +------------------ + +* Fixed: Issue 57: Supporting quotes around etags in If-Match and If-None-Match + + +1.2.2 (2010-06-21) +------------------ + +* Updated: SabreDAV now attempts to guess the BaseURI if it's not set. +* Updated: Better compatibility with BitKinex +* Fixed: Issue 56: Incorrect behaviour for If-None-Match headers and GET + requests. +* Fixed: Issue with certain encoded paths in Browser Plugin. + + +1.2.1 (2010-06-07) +------------------ + +* Fixed: Issue 50, patch by Mattijs Hoitink. +* Fixed: Issue 51, Adding windows 7 lockfiles to TemporaryFileFilter. +* Fixed: Issue 38, Allowing custom filters to be added to TemporaryFileFilter. +* Fixed: Issue 53, ETags in the If: header were always failing. This behaviour + is now corrected. +* Added: Apache Authentication backend, in case authentication through .htaccess + is desired. +* Updated: Small improvements to example files. + + +1.2.0 (2010-05-24) +------------------ + +* Fixed: Browser plugin now displays international characters. +* Changed: More properties in CalDAV classes are now protected instead of + private. + + +1.2.0beta3 (2010-05-14) +----------------------- + +* Fixed: Custom properties were not properly sent back for allprops requests. +* Fixed: Issue 49, incorrect parsing of PROPPATCH, affecting Office 2007. +* Changed: Removed CalDAV items from includes.php, and added a few missing ones. + + +1.2.0beta2 (2010-05-04) +----------------------- + +* Fixed: Issue 46: Fatal error for some non-existent nodes. +* Updated: some example sql to include email address. +* Added: 208 and 508 statuscodes from RFC5842. +* Added: Apache2 configuration examples + + +1.2.0beta1 (2010-04-28) +----------------------- + +* Fixed: redundant namespace declaration in resourcetypes. +* Fixed: 2 locking bugs triggered by litmus when no Sabre_DAV_ILockable + interface is used. +* Changed: using http://sabredav.org/ns for all custom xml properties. +* Added: email address property to principals. +* Updated: CalendarObject validation. + + +1.2.0alpha4 (2010-04-24) +------------------------ + +* Added: Support for If-Range, If-Match, If-None-Match, If-Modified-Since, + If-Unmodified-Since. +* Changed: Brand new build system. Functionality is split up between Sabre, + Sabre_HTTP, Sabre_DAV and Sabre_CalDAV packages. In addition to that a new + non-pear package will be created with all this functionality combined. +* Changed: Autoloader moved to Sabre/autoload.php. +* Changed: The Allow: header is now more accurate, with appropriate HTTP methods + per uri. +* Changed: Now throwing back Sabre_DAV_Exception_MethodNotAllowed on a few + places where Sabre_DAV_Exception_NotImplemented was used. + + +1.2.0alpha3 (2010-04-20) +------------------------ + +* Update: Complete rewrite of property updating. Now easier to use and atomic. +* Fixed: Issue 16, automatically adding trailing / to baseUri. +* Added: text/plain is used for .txt files in GuessContentType plugin. +* Added: support for principal-property-search and principal-search-property-set + reports. +* Added: Issue 31: Hiding exception information by default. Can be turned on + with the Sabre_DAV_Server::$debugExceptions property. + + +1.2.0alpha2 (2010-04-08) +------------------------ + +* Added: Calendars are now private and can only be read by the owner. +* Fixed: double namespace declaration in multistatus responses. +* Added: MySQL database dumps. MySQL is now also supported next to SQLite. +* Added: expand-properties REPORT from RFC 3253. +* Added: Sabre_DAV_Property_IHref interface for properties exposing urls. +* Added: Issue 25: Throwing error on broken Finder behaviour. +* Changed: Authentication backend is now aware of current user. + + +1.2.0alpha1 (2010-03-31) +------------------------ + +* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded special + characters. +* Fixed: Issue 34: Incorrect Lock-Token response header for LOCK. Fixes Office + 2010 compatibility. +* Added: Issue 35: SabreDAV version to header to OPTIONS response to ease + debugging. +* Fixed: Issue 36: Incorrect variable name, throwing error in some requests. +* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter. +* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8. +* Fixed: Issue 39 & Issue 40: Basename fails on non-utf-8 locales. +* Added: More unittests. +* Added: SabreDAV version to all error responses. +* Added: URLUtil class for decoding urls. +* Changed: Now using pear.sabredav.org pear channel. +* Changed: Sabre_DAV_Server::getCopyAndMoveInfo is now a public method. + + +1.1.2-alpha (2010-03-18) +------------------------ + +* Added: RFC5397 - current-user-principal support. +* Fixed: Issue 27: encoding entities in property responses. +* Added: naturalselection script now allows the user to specify a 'minimum + number of bytes' for deletion. This should reduce load due to less crawling +* Added: Full support for the calendar-query report. +* Added: More unittests. +* Added: Support for complex property deserialization through the static + ::unserialize() method. +* Added: Support for modifying calendar-component-set +* Fixed: Issue 29: Added TIMEOUT_INFINITE constant + + +1.1.1-alpha (2010-03-11) +------------------------ + +* Added: RFC5689 - Extended MKCOL support. +* Fixed: Evolution support for CalDAV. +* Fixed: PDO-locks backend was pretty much completely broken. This is 100% + unittested now. +* Added: support for ctags. +* Fixed: Comma's between HTTP methods in 'Allow' method. +* Changed: default argument for Sabre_DAV_Locks_Backend_FS. This means a + datadirectory must always be specified from now on. +* Changed: Moved Sabre_DAV_Server::parseProps to + Sabre_DAV_XMLUtil::parseProperties. +* Changed: Sabre_DAV_IDirectory is now Sabre_DAV_ICollection. +* Changed: Sabre_DAV_Exception_PermissionDenied is now + Sabre_DAV_Exception_Forbidden. +* Changed: Sabre_CalDAV_ICalendarCollection is removed. +* Added: Sabre_DAV_IExtendedCollection. +* Added: Many more unittests. +* Added: support for calendar-timezone property. + + +1.1.0-alpha (2010-03-01) +------------------------ + +* Note: This version is forked from version 1.0.5, so release dates may be out + of order. +* Added: CalDAV - RFC 4791 +* Removed: Sabre_PHP_Exception. PHP has a built-in ErrorException for this. +* Added: PDO authentication backend. +* Added: Example sql for auth, caldav, locks for sqlite. +* Added: Sabre_DAV_Browser_GuessContentType plugin +* Changed: Authentication plugin refactored, making it possible to implement + non-digest authentication. +* Fixed: Better error display in browser plugin. +* Added: Support for {DAV:}supported-report-set +* Added: XML utility class with helper functions for the WebDAV protocol. +* Added: Tons of unittests +* Added: PrincipalCollection and Principal classes +* Added: Sabre_DAV_Server::getProperties for easy property retrieval +* Changed: {DAV:}resourceType defaults to 0 +* Changed: Any non-null resourceType now gets a / appended to the href value. + Before this was just for {DAV:}collection's, but this is now also the case for + for example {DAV:}principal. +* Changed: The Href property class can now optionally create non-relative uri's. +* Changed: Sabre_HTTP_Response now returns false if headers are already sent and + header-methods are called. +* Fixed: Issue 19: HEAD requests on Collections +* Fixed: Issue 21: Typo in Sabre_DAV_Property_Response +* Fixed: Issue 18: Doesn't work with Evolution Contacts + + +1.0.15 (2010-05-28) +------------------- + +* Added: Issue 31: Hiding exception information by default. Can be turned on + with the Sabre_DAV_Server::$debugExceptions property. +* Added: Moved autoload from lib/ to lib/Sabre/autoload.php. This is also the + case in the upcoming 1.2.0, so it will improve future compatibility. + + +1.0.14 (2010-04-15) +------------------- + +* Fixed: double namespace declaration in multistatus responses. + + +1.0.13 (2010-03-30) +------------------- + +* Fixed: Issue 40: Last references to basename/dirname + + +1.0.12 (2010-03-30) +------------------- + +* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter. +* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded special + characters. +* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8. +* Fixed: Issue 39: Basename fails on non-utf-8 locales. +* Added: More unittests. +* Added: SabreDAV version to all error responses. +* Added: URLUtil class for decoding urls. +* Updated: Now using pear.sabredav.org pear channel. + + +1.0.11 (2010-03-23) +------------------- + +* Non-public release. This release is identical to 1.0.10, but it is used to + test releasing packages to pear.sabredav.org. + + +1.0.10 (2010-03-22) +------------------- + +* Fixed: Issue 34: Invalid Lock-Token header response. +* Added: Issue 35: Addign SabreDAV version to HTTP OPTIONS responses. + + +1.0.9 (2010-03-19) +------------------ + +* Fixed: Issue 27: Entities not being encoded in PROPFIND responses. +* Fixed: Issue 29: Added missing TIMEOUT_INFINITE constant. + + +1.0.8 (2010-03-03) +------------------ + +* Fixed: Issue 21: typos causing errors +* Fixed: Issue 23: Comma's between methods in Allow header. +* Added: Sabre_DAV_ICollection interface, to aid in future compatibility. +* Added: Sabre_DAV_Exception_Forbidden exception. This will replace + Sabre_DAV_Exception_PermissionDenied in the future, and can already be used to + ensure future compatibility. + + +1.0.7 (2010-02-24) +------------------ + +* Fixed: Issue 19 regression for MS Office + + +1.0.6 (2010-02-23) +------------------ + +* Fixed: Issue 19: HEAD requests on Collections + + +1.0.5 (2010-01-22) +------------------ + +* Fixed: Fatal error when a malformed url was used for unlocking, in conjuction + with Sabre.autoload.php due to a incorrect filename. +* Fixed: Improved unittests and build system + + +1.0.4 (2010-01-11) +------------------ + +* Fixed: needed 2 different releases. One for googlecode and one for pearfarm. + This is to retain the old method to install SabreDAV until pearfarm becomes + the standard installation method. + + +1.0.3 (2010-01-11) +------------------ + +* Added: RFC4709 support (davmount) +* Added: 6 unittests +* Added: naturalselection. A tool to keep cache directories below a specified + theshold. +* Changed: Now using pearfarm.org channel server. + + +1.0.1 (2009-12-22) +------------------ + +* Fixed: Issue 15: typos in examples +* Fixed: Minor pear installation issues + + +1.0.0 (2009-11-02) +------------------ + +* Added: SimpleDirectory class. This class allows creating static directory + structures with ease. +* Changed: Custom complex properties and exceptions now get an instance of + Sabre_DAV_Server as their first argument in serialize() +* Changed: Href complex property now prepends server's baseUri +* Changed: delete before an overwriting copy/move is now handles by server class + instead of tree classes +* Changed: events must now explicitly return false to stop execution. Before, + execution would be stopped by anything loosely evaluating to false. +* Changed: the getPropertiesForPath method now takes a different set of + arguments, and returns a different response. This allows plugin developers to + return statuses for properties other than 200 and 404. The hrefs are now also + always calculated relative to the baseUri, and not the uri of the request. +* Changed: generatePropFindResponse is renamed to generateMultiStatus, and now + takes a list of properties similar to the response of getPropertiesForPath. + This was also needed to improve flexibility for plugin development. +* Changed: Auth plugins are no longer included. They were not yet stable + quality, so they will probably be reintroduced in a later version. +* Changed: PROPPATCH also used generateMultiStatus now. +* Removed: unknownProperties event. This is replaced by the afterGetProperties + event, which should provide more flexibility. +* Fixed: Only calling getSize() on IFile instances in httpHead() +* Added: beforeBind event. This is invoked upon file or directory creation +* Added: beforeWriteContent event, this is invoked by PUT and LOCK on an + existing resource. +* Added: beforeUnbind event. This is invoked right before deletion of any + resource. +* Added: afterGetProperties event. This event can be used to make modifications + to property responses. +* Added: beforeLock and beforeUnlock events. +* Added: afterBind event. +* Fixed: Copy and Move could fail in the root directory. This is now fixed. +* Added: Plugins can now be retrieved by their classname. This is useful for + inter-plugin communication. +* Added: The Auth backend can now return usernames and user-id's. +* Added: The Auth backend got a getUsers method +* Added: Sabre_DAV_FSExt_Directory now returns quota info + + +0.12.1-beta (2009-09-11) +------------------------ + +* Fixed: UNLOCK bug. Unlock didn't work at all + + +0.12-beta (2009-09-10) +---------------------- + +* Updated: Browser plugin now shows multiple {DAV:}resourcetype values if + available. +* Added: Experimental PDO backend for Locks Manager +* Fixed: Sending Content-Length: 0 for every empty response. This improves NGinx + compatibility. +* Fixed: Last modification time is reported in UTC timezone. This improves + Finder compatibility. + + +0.11-beta (2009-08-11) +---------------------- + +* Updated: Now in Beta +* Updated: Pear package no longer includes docs/ directory. These just contained + rfc's, which are publically available. This reduces the package from ~800k to + ~60k +* Added: generatePropfindResponse now takes a baseUri argument +* Added: ResourceType property can now contain multiple resourcetypes. +* Fixed: Issue 13. + + +0.10-alpha (2009-08-03) +----------------------- + +* Added: Plugin to automatically map GET requests to non-files to PROPFIND + (Sabre_DAV_Browser_MapGetToPropFind). This should allow easier debugging of + complicated WebDAV setups. +* Added: Sabre_DAV_Property_Href class. For future use. +* Added: Ability to choose to use auth-int, auth or both for HTTP Digest + authentication. (Issue 11) +* Changed: Made more methods in Sabre_DAV_Server public. +* Fixed: TemporaryFileFilter plugin now intercepts HTTP LOCK requests to + non-existent files. (Issue 12) +* Added: Central list of defined xml namespace prefixes. This can reduce + Bandwidth and legibility for xml bodies with user-defined namespaces. +* Added: now a PEAR-compatible package again, thanks to Michael Gauthier +* Changed: moved default copy and move logic from ObjectTree to Tree class + +0.9a-alpha (2009-07-21) +---------------------- + +* Fixed: Broken release + +0.9-alpha (2009-07-21) +---------------------- + +* Changed: Major refactoring, removed most of the logic from the Tree objects. + The Server class now directly works with the INode, IFile and IDirectory + objects. If you created your own Tree objects, this will most likely break in + this release. +* Changed: Moved all the Locking logic from the Tree and Server classes into a + separate plugin. +* Changed: TemporaryFileFilter is now a plugin. +* Added: Comes with an autoloader script. This can be used instead of the + includer script, and is preferred by some people. +* Added: AWS Authentication class. +* Added: simpleserversetup.py script. This will quickly get a fileserver up and + running. +* Added: When subscribing to events, it is now possible to supply a priority. + This is for example needed to ensure that the Authentication Plugin is used + before any other Plugin. +* Added: 22 new tests. +* Added: Users-manager plugin for .htdigest files. Experimental and subject to + change. +* Added: RFC 2324 HTTP 418 status code +* Fixed: Exclusive locks could in some cases be picked up as shared locks +* Fixed: Digest auth for non-apache servers had a bug (still not actually tested + this well). + + +0.8-alpha (2009-05-30) +---------------------- + +* Changed: Renamed all exceptions! This is a compatibility break. Every + Exception now follows Sabre_DAV_Exception_FileNotFound convention instead of + Sabre_DAV_FileNotFoundException. +* Added: Browser plugin now allows uploading and creating directories straight + from the browser. +* Added: 12 more unittests +* Fixed: Locking bug, which became prevalent on Windows Vista. +* Fixed: Netdrive support +* Fixed: TemporaryFileFilter filtered out too many files. Fixed some of the + regexes. +* Fixed: Added README and ChangeLog to package + + +0.7-alpha (2009-03-29) +---------------------- + +* Added: System to return complex properties from PROPFIND. +* Added: support for {DAV:}supportedlock. +* Added: support for {DAV:}lockdiscovery. +* Added: 6 new tests. +* Added: New plugin system. +* Added: Simple HTML directory plugin, for browser access. +* Added: Server class now sends back standard pre-condition error xml bodies. + This was new since RFC4918. +* Added: Sabre_DAV_Tree_Aggregrate, which can 'host' multiple Tree objects into + one. +* Added: simple basis for HTTP REPORT method. This method is not used yet, but + can be used by plugins to add reports. +* Changed: ->getSize is only called for files, no longer for collections. r303 +* Changed: Sabre_DAV_FilterTree is now Sabre_DAV_Tree_Filter +* Changed: Sabre_DAV_TemporaryFileFilter is now called + Sabre_DAV_Tree_TemporaryFileFilter. +* Changed: removed functions (get(/set)HTTPRequest(/Response)) from Server + class, and using a public property instead. +* Fixed: bug related to parsing proppatch and propfind requests. Didn't show up + in most clients, but it needed fixing regardless. (r255) +* Fixed: auth-int is now properly supported within HTTP Digest. +* Fixed: Using application/xml for a mimetype vs. text/xml as per RFC4918 sec + 8.2. +* Fixed: TemporaryFileFilter now lets through GET's if they actually exist on + the backend. (r274) +* FIxed: Some methods didn't get passed through in the FilterTree (r283). +* Fixed: LockManager is now slightly more complex, Tree classes slightly less. + (r287) + + +0.6-alpha (2009-02-16) +---------------------- + +* Added: Now uses streams for files, instead of strings. This means it won't + require to hold entire files in memory, which can be an issue if you're + dealing with big files. Note that this breaks compatibility for put() and + createFile methods. +* Added: HTTP Digest Authentication helper class. +* Added: Support for HTTP Range header +* Added: Support for ETags within If: headers +* Added: The API can now return ETags and override the default Content-Type +* Added: starting with basic framework for unittesting, using PHPUnit. +* Added: 49 unittests. +* Added: Abstraction for the HTTP request. +* Updated: Using Clark Notation for tags in properties. This means tags are + serialized as {namespace}tagName instead of namespace#tagName +* Fixed: HTTP_BasicAuth class now works as expected. +* Fixed: DAV_Server uses / for a default baseUrl. +* Fixed: Last modification date is no longer ignored in PROPFIND. +* Fixed: PROPFIND now sends back information about the requestUri even when + "Depth: 1" is specified. + + +0.5-alpha (2009-01-14) +---------------------- + +* Added: Added a very simple example for implementing a mapping to PHP file + streams. This should allow easy implementation of for example a WebDAV to FTP + proxy. +* Added: HTTP Basic Authentication helper class. +* Added: Sabre_HTTP_Response class. This centralizes HTTP operations and will be + a start towards the creating of a testing framework. +* Updated: Backwards compatibility break: all require_once() statements are + removed from all the files. It is now recommended to use autoloading of + classes, or just including lib/Sabre.includes.php. This fix was made to allow + easier integration into applications not using this standard inclusion model. +* Updated: Better in-file documentation. +* Updated: Sabre_DAV_Tree can now work with Sabre_DAV_LockManager. +* Updated: Fixes a shared-lock bug. +* Updated: Removed ?> from the bottom of each php file. +* Updated: Split up some operations from Sabre_DAV_Server to + Sabre_HTTP_Response. +* Fixed: examples are now actually included in the pear package. + + +0.4-alpha (2008-11-05) +---------------------- + +* Passes all litmus tests! +* Added: more examples +* Added: Custom property support +* Added: Shared lock support +* Added: Depth support to locks +* Added: Locking on unmapped urls (non-existent nodes) +* Fixed: Advertising as WebDAV class 3 support + + +0.3-alpha (2008-06-29) +---------------------- + +* Fully working in MS Windows clients. +* Added: temporary file filter: support for smultron files. +* Added: Phing build scripts +* Added: PEAR package +* Fixed: MOVE bug identified using finder. +* Fixed: Using gzuncompress instead of gzdecode in the temporary file filter. + This seems more common. + + +0.2-alpha (2008-05-27) +---------------------- + +* Somewhat working in Windows clients +* Added: Working PROPPATCH method (doesn't support custom properties yet) +* Added: Temporary filename handling system +* Added: Sabre_DAV_IQuota to return quota information +* Added: PROPFIND now reads the request body and only supplies the requested + properties + + +0.1-alpha (2008-04-04) +---------------------- + +* First release! +* Passes litmus: basic, http and copymove test. +* Fully working in Finder and DavFSv2 Project started: 2007-12-13 + + +[vobj]: http://sabre.io/vobject/ +[evnt]: http://sabre.io/event/ +[http]: http://sabre.io/http/ +[uri]: http://sabre.io/uri/ +[xml]: http://sabre.io/xml/ +[mi20]: http://sabre.io/dav/upgrade/1.8-to-2.0/ +[rfc6638]: http://tools.ietf.org/html/rfc6638 "CalDAV Scheduling" +[rfc7240]: http://tools.ietf.org/html/rfc7240 diff --git a/resources/updater-fixes/sabre/dav/composer.json b/resources/updater-fixes/sabre/dav/composer.json new file mode 100644 index 0000000000000..999460500c086 --- /dev/null +++ b/resources/updater-fixes/sabre/dav/composer.json @@ -0,0 +1,66 @@ +{ + "name": "sabre/dav", + "type": "library", + "description": "WebDAV Framework for PHP", + "keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"], + "homepage": "http://sabre.io/", + "license" : "BSD-3-Clause", + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage" : "http://evertpot.com/", + "role" : "Developer" + } + ], + "require": { + "php": ">=5.4.1", + "sabre/vobject": "^3.3.4", + "sabre/event" : "~2.0", + "sabre/xml" : "~1.0", + "sabre/http" : "~4.0", + "sabre/uri" : "~1.0", + "ext-dom": "*", + "ext-pcre": "*", + "ext-spl": "*", + "ext-simplexml": "*", + "ext-mbstring" : "*", + "ext-ctype" : "*", + "ext-date" : "*", + "ext-iconv" : "*", + "lib-libxml" : ">=2.7.0" + }, + "require-dev" : { + "phpunit/phpunit" : "~4.2", + "evert/phpdoc-md" : "~0.1.0", + "sabre/cs" : "~0.0.2" + }, + "suggest" : { + "ext-curl" : "*", + "ext-pdo" : "*" + }, + "autoload": { + "psr-4" : { + "Sabre\\DAV\\" : "lib/DAV/", + "Sabre\\DAVACL\\" : "lib/DAVACL/", + "Sabre\\CalDAV\\" : "lib/CalDAV/", + "Sabre\\CardDAV\\" : "lib/CardDAV/" + } + }, + "support" : { + "forum" : "https://groups.google.com/group/sabredav-discuss", + "source" : "https://github.com/fruux/sabre-dav" + }, + "bin" : [ + "bin/sabredav", + "bin/naturalselection" + ], + "config" : { + "bin-dir" : "./bin" + }, + "extra" : { + "branch-alias": { + "dev-master": "3.0.0-dev" + } + } +} diff --git a/resources/updater-fixes/sabre/dav/lib/CalDAV/Plugin.php b/resources/updater-fixes/sabre/dav/lib/CalDAV/Plugin.php new file mode 100644 index 0000000000000..50b00778d89c6 --- /dev/null +++ b/resources/updater-fixes/sabre/dav/lib/CalDAV/Plugin.php @@ -0,0 +1,992 @@ +server->tree->getNodeForPath($parent); + + if ($node instanceof DAV\IExtendedCollection) { + try { + $node->getChild($name); + } catch (DAV\Exception\NotFound $e) { + return ['MKCALENDAR']; + } + } + return []; + + } + + /** + * Returns the path to a principal's calendar home. + * + * The return url must not end with a slash. + * + * @param string $principalUrl + * @return string + */ + function getCalendarHomeForPrincipal($principalUrl) { + + // The default is a bit naive, but it can be overwritten. + list(, $nodeName) = Uri\split($principalUrl); + + return self::CALENDAR_ROOT . '/' . $nodeName; + + } + + /** + * Returns a list of features for the DAV: HTTP header. + * + * @return array + */ + function getFeatures() { + + return ['calendar-access', 'calendar-proxy']; + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using DAV\Server::getPlugin + * + * @return string + */ + function getPluginName() { + + return 'caldav'; + + } + + /** + * Returns a list of reports this plugin supports. + * + * This will be used in the {DAV:}supported-report-set property. + * Note that you still need to subscribe to the 'report' event to actually + * implement them + * + * @param string $uri + * @return array + */ + function getSupportedReportSet($uri) { + + $node = $this->server->tree->getNodeForPath($uri); + + $reports = []; + if ($node instanceof ICalendarObjectContainer || $node instanceof ICalendarObject) { + $reports[] = '{' . self::NS_CALDAV . '}calendar-multiget'; + $reports[] = '{' . self::NS_CALDAV . '}calendar-query'; + } + if ($node instanceof ICalendar) { + $reports[] = '{' . self::NS_CALDAV . '}free-busy-query'; + } + // iCal has a bug where it assumes that sync support is enabled, only + // if we say we support it on the calendar-home, even though this is + // not actually the case. + if ($node instanceof CalendarHome && $this->server->getPlugin('sync')) { + $reports[] = '{DAV:}sync-collection'; + } + return $reports; + + } + + /** + * Initializes the plugin + * + * @param DAV\Server $server + * @return void + */ + function initialize(DAV\Server $server) { + + $this->server = $server; + + $server->on('method:MKCALENDAR', [$this, 'httpMkCalendar']); + $server->on('report', [$this, 'report']); + $server->on('propFind', [$this, 'propFind']); + $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']); + $server->on('beforeCreateFile', [$this, 'beforeCreateFile']); + $server->on('beforeWriteContent', [$this, 'beforeWriteContent']); + $server->on('afterMethod:GET', [$this, 'httpAfterGET']); + + $server->xml->namespaceMap[self::NS_CALDAV] = 'cal'; + $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs'; + + $server->xml->elementMap['{' . self::NS_CALDAV . '}calendar-query'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport'; + $server->xml->elementMap['{' . self::NS_CALDAV . '}calendar-multiget'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport'; + $server->xml->elementMap['{' . self::NS_CALDAV . '}free-busy-query'] = 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport'; + $server->xml->elementMap['{' . self::NS_CALDAV . '}mkcalendar'] = 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar'; + $server->xml->elementMap['{' . self::NS_CALDAV . '}schedule-calendar-transp'] = 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp'; + $server->xml->elementMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet'; + + $server->resourceTypeMapping['\\Sabre\\CalDAV\\ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar'; + + $server->resourceTypeMapping['\\Sabre\\CalDAV\\Principal\\IProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read'; + $server->resourceTypeMapping['\\Sabre\\CalDAV\\Principal\\IProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write'; + + array_push($server->protectedProperties, + + '{' . self::NS_CALDAV . '}supported-calendar-component-set', + '{' . self::NS_CALDAV . '}supported-calendar-data', + '{' . self::NS_CALDAV . '}max-resource-size', + '{' . self::NS_CALDAV . '}min-date-time', + '{' . self::NS_CALDAV . '}max-date-time', + '{' . self::NS_CALDAV . '}max-instances', + '{' . self::NS_CALDAV . '}max-attendees-per-instance', + '{' . self::NS_CALDAV . '}calendar-home-set', + '{' . self::NS_CALDAV . '}supported-collation-set', + '{' . self::NS_CALDAV . '}calendar-data', + + // CalendarServer extensions + '{' . self::NS_CALENDARSERVER . '}getctag', + '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for', + '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for' + + ); + + if ($aclPlugin = $server->getPlugin('acl')) { + $aclPlugin->principalSearchPropertySet['{' . self::NS_CALDAV . '}calendar-user-address-set'] = 'Calendar address'; + } + } + + /** + * This functions handles REPORT requests specific to CalDAV + * + * @param string $reportName + * @param mixed $report + * @return bool + */ + function report($reportName, $report) { + + switch ($reportName) { + case '{' . self::NS_CALDAV . '}calendar-multiget' : + $this->server->transactionType = 'report-calendar-multiget'; + $this->calendarMultiGetReport($report); + return false; + case '{' . self::NS_CALDAV . '}calendar-query' : + $this->server->transactionType = 'report-calendar-query'; + $this->calendarQueryReport($report); + return false; + case '{' . self::NS_CALDAV . '}free-busy-query' : + $this->server->transactionType = 'report-free-busy-query'; + $this->freeBusyQueryReport($report); + return false; + + } + + + } + + /** + * This function handles the MKCALENDAR HTTP method, which creates + * a new calendar. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpMkCalendar(RequestInterface $request, ResponseInterface $response) { + + $body = $request->getBodyAsString(); + $path = $request->getPath(); + + $properties = []; + + if ($body) { + + try { + $mkcalendar = $this->server->xml->expect( + '{urn:ietf:params:xml:ns:caldav}mkcalendar', + $body + ); + } catch (\Sabre\Xml\ParseException $e) { + throw new BadRequest($e->getMessage(), null, $e); + } + $properties = $mkcalendar->getProperties(); + + } + + // iCal abuses MKCALENDAR since iCal 10.9.2 to create server-stored + // subscriptions. Before that it used MKCOL which was the correct way + // to do this. + // + // If the body had a {DAV:}resourcetype, it means we stumbled upon this + // request, and we simply use it instead of the pre-defined list. + if (isset($properties['{DAV:}resourcetype'])) { + $resourceType = $properties['{DAV:}resourcetype']->getValue(); + } else { + $resourceType = ['{DAV:}collection','{urn:ietf:params:xml:ns:caldav}calendar']; + } + + $this->server->createCollection($path, new MkCol($resourceType, $properties)); + + $this->server->httpResponse->setStatus(201); + $this->server->httpResponse->setHeader('Content-Length', 0); + + // This breaks the method chain. + return false; + } + + /** + * PropFind + * + * This method handler is invoked before any after properties for a + * resource are fetched. This allows us to add in any CalDAV specific + * properties. + * + * @param DAV\PropFind $propFind + * @param DAV\INode $node + * @return void + */ + function propFind(DAV\PropFind $propFind, DAV\INode $node) { + + $ns = '{' . self::NS_CALDAV . '}'; + + if ($node instanceof ICalendarObjectContainer) { + + $propFind->handle($ns . 'max-resource-size', $this->maxResourceSize); + $propFind->handle($ns . 'supported-calendar-data', function() { + return new Xml\Property\SupportedCalendarData(); + }); + $propFind->handle($ns . 'supported-collation-set', function() { + return new Xml\Property\SupportedCollationSet(); + }); + + } + + if ($node instanceof DAVACL\IPrincipal) { + + $principalUrl = $node->getPrincipalUrl(); + + $propFind->handle('{' . self::NS_CALDAV . '}calendar-home-set', function() use ($principalUrl) { + + $calendarHomePath = $this->getCalendarHomeForPrincipal($principalUrl) . '/'; + return new Href($calendarHomePath); + + }); + // The calendar-user-address-set property is basically mapped to + // the {DAV:}alternate-URI-set property. + $propFind->handle('{' . self::NS_CALDAV . '}calendar-user-address-set', function() use ($node) { + $addresses = $node->getAlternateUriSet(); + $addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl() . '/'; + return new Href($addresses, false); + }); + // For some reason somebody thought it was a good idea to add + // another one of these properties. We're supporting it too. + $propFind->handle('{' . self::NS_CALENDARSERVER . '}email-address-set', function() use ($node) { + $addresses = $node->getAlternateUriSet(); + $emails = []; + foreach ($addresses as $address) { + if (substr($address, 0, 7) === 'mailto:') { + $emails[] = substr($address, 7); + } + } + return new Xml\Property\EmailAddressSet($emails); + }); + + // These two properties are shortcuts for ical to easily find + // other principals this principal has access to. + $propRead = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for'; + $propWrite = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for'; + + if ($propFind->getStatus($propRead) === 404 || $propFind->getStatus($propWrite) === 404) { + + $aclPlugin = $this->server->getPlugin('acl'); + $membership = $aclPlugin->getPrincipalMembership($propFind->getPath()); + $readList = []; + $writeList = []; + + foreach ($membership as $group) { + + $groupNode = $this->server->tree->getNodeForPath($group); + + $listItem = Uri\split($group)[0] . '/'; + + // If the node is either ap proxy-read or proxy-write + // group, we grab the parent principal and add it to the + // list. + if ($groupNode instanceof Principal\IProxyRead) { + $readList[] = $listItem; + } + if ($groupNode instanceof Principal\IProxyWrite) { + $writeList[] = $listItem; + } + + } + + $propFind->set($propRead, new Href($readList)); + $propFind->set($propWrite, new Href($writeList)); + + } + + } // instanceof IPrincipal + + if ($node instanceof ICalendarObject) { + + // The calendar-data property is not supposed to be a 'real' + // property, but in large chunks of the spec it does act as such. + // Therefore we simply expose it as a property. + $propFind->handle('{' . self::NS_CALDAV . '}calendar-data', function() use ($node) { + $val = $node->get(); + if (is_resource($val)) + $val = stream_get_contents($val); + + // Taking out \r to not screw up the xml output + return str_replace("\r", "", $val); + + }); + + } + + } + + /** + * This function handles the calendar-multiget REPORT. + * + * This report is used by the client to fetch the content of a series + * of urls. Effectively avoiding a lot of redundant requests. + * + * @param CalendarMultiGetReport $report + * @return void + */ + function calendarMultiGetReport($report) { + + $needsJson = $report->contentType === 'application/calendar+json'; + + $timeZones = []; + $propertyList = []; + + $paths = array_map( + [$this->server, 'calculateUri'], + $report->hrefs + ); + + foreach ($this->server->getPropertiesForMultiplePaths($paths, $report->properties) as $uri => $objProps) { + + if (($needsJson || $report->expand) && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) { + $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']); + + if ($report->expand) { + // We're expanding, and for that we need to figure out the + // calendar's timezone. + list($calendarPath) = Uri\split($uri); + if (!isset($timeZones[$calendarPath])) { + // Checking the calendar-timezone property. + $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone'; + $tzResult = $this->server->getProperties($calendarPath, [$tzProp]); + if (isset($tzResult[$tzProp])) { + // This property contains a VCALENDAR with a single + // VTIMEZONE. + $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); + $timeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); + } else { + // Defaulting to UTC. + $timeZone = new DateTimeZone('UTC'); + } + $timeZones[$calendarPath] = $timeZone; + } + + $vObject->expand($report->expand['start'], $report->expand['end'], $timeZones[$calendarPath]); + } + if ($needsJson) { + $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize()); + } else { + $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize(); + } + } + + $propertyList[] = $objProps; + + } + + $prefer = $this->server->getHTTPPrefer(); + + $this->server->httpResponse->setStatus(207); + $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); + $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); + $this->server->httpResponse->setBody($this->server->generateMultiStatus($propertyList, $prefer['return'] === 'minimal')); + + } + + /** + * This function handles the calendar-query REPORT + * + * This report is used by clients to request calendar objects based on + * complex conditions. + * + * @param Xml\Request\CalendarQueryReport $report + * @return void + */ + function calendarQueryReport($report) { + + $path = $this->server->getRequestUri(); + + $needsJson = $report->contentType === 'application/calendar+json'; + + $node = $this->server->tree->getNodeForPath($this->server->getRequestUri()); + $depth = $this->server->getHTTPDepth(0); + + // The default result is an empty array + $result = []; + + $calendarTimeZone = null; + if ($report->expand) { + // We're expanding, and for that we need to figure out the + // calendar's timezone. + $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone'; + $tzResult = $this->server->getProperties($path, [$tzProp]); + if (isset($tzResult[$tzProp])) { + // This property contains a VCALENDAR with a single + // VTIMEZONE. + $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); + $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); + unset($vtimezoneObj); + } else { + // Defaulting to UTC. + $calendarTimeZone = new DateTimeZone('UTC'); + } + } + + // The calendarobject was requested directly. In this case we handle + // this locally. + if ($depth == 0 && $node instanceof ICalendarObject) { + + $requestedCalendarData = true; + $requestedProperties = $report->properties; + + if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) { + + // We always retrieve calendar-data, as we need it for filtering. + $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data'; + + // If calendar-data wasn't explicitly requested, we need to remove + // it after processing. + $requestedCalendarData = false; + } + + $properties = $this->server->getPropertiesForPath( + $path, + $requestedProperties, + 0 + ); + + // This array should have only 1 element, the first calendar + // object. + $properties = current($properties); + + // If there wasn't any calendar-data returned somehow, we ignore + // this. + if (isset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) { + + $validator = new CalendarQueryValidator(); + + $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']); + if ($validator->validate($vObject, $report->filters)) { + + // If the client didn't require the calendar-data property, + // we won't give it back. + if (!$requestedCalendarData) { + unset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']); + } else { + + + if ($report->expand) { + $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone); + } + if ($needsJson) { + $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize()); + } elseif ($report->expand) { + $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize(); + } + } + + $result = [$properties]; + + } + + } + + } + + if ($node instanceof ICalendarObjectContainer && $depth === 0) { + + if (strpos($this->server->httpRequest->getHeader('User-Agent'), 'MSFT-') === 0) { + // Microsoft clients incorrectly supplied depth as 0, when it actually + // should have set depth to 1. We're implementing a workaround here + // to deal with this. + // + // This targets at least the following clients: + // Windows 10 + // Windows Phone 8, 10 + $depth = 1; + } else { + throw new BadRequest('A calendar-query REPORT on a calendar with a Depth: 0 is undefined. Set Depth to 1'); + } + + } + + // If we're dealing with a calendar, the calendar itself is responsible + // for the calendar-query. + if ($node instanceof ICalendarObjectContainer && $depth == 1) { + + $nodePaths = $node->calendarQuery($report->filters); + + foreach ($nodePaths as $path) { + + list($properties) = + $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $report->properties); + + if (($needsJson || $report->expand)) { + $vObject = VObject\Reader::read($properties[200]['{' . self::NS_CALDAV . '}calendar-data']); + + if ($report->expand) { + $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone); + } + + if ($needsJson) { + $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize()); + } else { + $properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize(); + } + } + $result[] = $properties; + + } + + } + + $prefer = $this->server->getHTTPPrefer(); + + $this->server->httpResponse->setStatus(207); + $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); + $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); + $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return'] === 'minimal')); + + } + + /** + * This method is responsible for parsing the request and generating the + * response for the CALDAV:free-busy-query REPORT. + * + * @param Xml\Request\FreeBusyQueryReport $report + * @return void + */ + protected function freeBusyQueryReport(Xml\Request\FreeBusyQueryReport $report) { + + $uri = $this->server->getRequestUri(); + + $acl = $this->server->getPlugin('acl'); + if ($acl) { + $acl->checkPrivileges($uri, '{' . self::NS_CALDAV . '}read-free-busy'); + } + + $calendar = $this->server->tree->getNodeForPath($uri); + if (!$calendar instanceof ICalendar) { + throw new DAV\Exception\NotImplemented('The free-busy-query REPORT is only implemented on calendars'); + } + + $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone'; + + // Figuring out the default timezone for the calendar, for floating + // times. + $calendarProps = $this->server->getProperties($uri, [$tzProp]); + + if (isset($calendarProps[$tzProp])) { + $vtimezoneObj = VObject\Reader::read($calendarProps[$tzProp]); + $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); + } else { + $calendarTimeZone = new DateTimeZone('UTC'); + } + + // Doing a calendar-query first, to make sure we get the most + // performance. + $urls = $calendar->calendarQuery([ + 'name' => 'VCALENDAR', + 'comp-filters' => [ + [ + 'name' => 'VEVENT', + 'comp-filters' => [], + 'prop-filters' => [], + 'is-not-defined' => false, + 'time-range' => [ + 'start' => $report->start, + 'end' => $report->end, + ], + ], + ], + 'prop-filters' => [], + 'is-not-defined' => false, + 'time-range' => null, + ]); + + $objects = array_map(function($url) use ($calendar) { + $obj = $calendar->getChild($url)->get(); + return $obj; + }, $urls); + + $generator = new VObject\FreeBusyGenerator(); + $generator->setObjects($objects); + $generator->setTimeRange($report->start, $report->end); + $generator->setTimeZone($calendarTimeZone); + $result = $generator->getResult(); + $result = $result->serialize(); + + $this->server->httpResponse->setStatus(200); + $this->server->httpResponse->setHeader('Content-Type', 'text/calendar'); + $this->server->httpResponse->setHeader('Content-Length', strlen($result)); + $this->server->httpResponse->setBody($result); + + } + + /** + * This method is triggered before a file gets updated with new content. + * + * This plugin uses this method to ensure that CalDAV objects receive + * valid calendar data. + * + * @param string $path + * @param DAV\IFile $node + * @param resource $data + * @param bool $modified Should be set to true, if this event handler + * changed &$data. + * @return void + */ + function beforeWriteContent($path, DAV\IFile $node, &$data, &$modified) { + + if (!$node instanceof ICalendarObject) + return; + + // We're onyl interested in ICalendarObject nodes that are inside of a + // real calendar. This is to avoid triggering validation and scheduling + // for non-calendars (such as an inbox). + list($parent) = Uri\split($path); + $parentNode = $this->server->tree->getNodeForPath($parent); + + if (!$parentNode instanceof ICalendar) + return; + + $this->validateICalendar( + $data, + $path, + $modified, + $this->server->httpRequest, + $this->server->httpResponse, + false + ); + + } + + /** + * This method is triggered before a new file is created. + * + * This plugin uses this method to ensure that newly created calendar + * objects contain valid calendar data. + * + * @param string $path + * @param resource $data + * @param DAV\ICollection $parentNode + * @param bool $modified Should be set to true, if this event handler + * changed &$data. + * @return void + */ + function beforeCreateFile($path, &$data, DAV\ICollection $parentNode, &$modified) { + + if (!$parentNode instanceof ICalendar) + return; + + $this->validateICalendar( + $data, + $path, + $modified, + $this->server->httpRequest, + $this->server->httpResponse, + true + ); + + } + + /** + * Checks if the submitted iCalendar data is in fact, valid. + * + * An exception is thrown if it's not. + * + * @param resource|string $data + * @param string $path + * @param bool $modified Should be set to true, if this event handler + * changed &$data. + * @param RequestInterface $request The http request. + * @param ResponseInterface $response The http response. + * @param bool $isNew Is the item a new one, or an update. + * @return void + */ + protected function validateICalendar(&$data, $path, &$modified, RequestInterface $request, ResponseInterface $response, $isNew) { + + // If it's a stream, we convert it to a string first. + if (is_resource($data)) { + $data = stream_get_contents($data); + } + + $before = md5($data); + // Converting the data to unicode, if needed. + $data = DAV\StringUtil::ensureUTF8($data); + + if ($before !== md5($data)) $modified = true; + + try { + + // If the data starts with a [, we can reasonably assume we're dealing + // with a jCal object. + if (substr($data, 0, 1) === '[') { + $vobj = VObject\Reader::readJson($data); + + // Converting $data back to iCalendar, as that's what we + // technically support everywhere. + $data = $vobj->serialize(); + $modified = true; + } else { + $vobj = VObject\Reader::read($data); + } + + } catch (VObject\ParseException $e) { + + throw new DAV\Exception\UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage()); + + } + + if ($vobj->name !== 'VCALENDAR') { + throw new DAV\Exception\UnsupportedMediaType('This collection can only support iCalendar objects.'); + } + + $sCCS = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; + + // Get the Supported Components for the target calendar + list($parentPath) = Uri\split($path); + $calendarProperties = $this->server->getProperties($parentPath, [$sCCS]); + + if (isset($calendarProperties[$sCCS])) { + $supportedComponents = $calendarProperties[$sCCS]->getValue(); + } else { + $supportedComponents = ['VJOURNAL', 'VTODO', 'VEVENT']; + } + + $foundType = null; + $foundUID = null; + foreach ($vobj->getComponents() as $component) { + switch ($component->name) { + case 'VTIMEZONE' : + continue 2; + case 'VEVENT' : + case 'VTODO' : + case 'VJOURNAL' : + if (is_null($foundType)) { + $foundType = $component->name; + if (!in_array($foundType, $supportedComponents)) { + throw new Exception\InvalidComponentType('This calendar only supports ' . implode(', ', $supportedComponents) . '. We found a ' . $foundType); + } + if (!isset($component->UID)) { + throw new DAV\Exception\BadRequest('Every ' . $component->name . ' component must have an UID'); + } + $foundUID = (string)$component->UID; + } else { + if ($foundType !== $component->name) { + throw new DAV\Exception\BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType); + } + if ($foundUID !== (string)$component->UID) { + throw new DAV\Exception\BadRequest('Every ' . $component->name . ' in this object must have identical UIDs'); + } + } + break; + default : + throw new DAV\Exception\BadRequest('You are not allowed to create components of type: ' . $component->name . ' here'); + + } + } + if (!$foundType) + throw new DAV\Exception\BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL'); + + // We use an extra variable to allow event handles to tell us wether + // the object was modified or not. + // + // This helps us determine if we need to re-serialize the object. + $subModified = false; + + $this->server->emit( + 'calendarObjectChange', + [ + $request, + $response, + $vobj, + $parentPath, + &$subModified, + $isNew + ] + ); + + if ($subModified) { + // An event handler told us that it modified the object. + $data = $vobj->serialize(); + + // Using md5 to figure out if there was an *actual* change. + if (!$modified && $before !== md5($data)) { + $modified = true; + } + + } + + } + + + /** + * This method is used to generate HTML output for the + * DAV\Browser\Plugin. This allows us to generate an interface users + * can use to create new calendars. + * + * @param DAV\INode $node + * @param string $output + * @return bool + */ + function htmlActionsPanel(DAV\INode $node, &$output) { + + if (!$node instanceof CalendarHome) + return; + + $output .= '
+

Create new calendar

+ + +
+
+ +
+ '; + + return false; + + } + + /** + * This event is triggered after GET requests. + * + * This is used to transform data into jCal, if this was requested. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function httpAfterGet(RequestInterface $request, ResponseInterface $response) { + + if (strpos($response->getHeader('Content-Type'), 'text/calendar') === false) { + return; + } + + $result = HTTP\Util::negotiate( + $request->getHeader('Accept'), + ['text/calendar', 'application/calendar+json'] + ); + + if ($result !== 'application/calendar+json') { + // Do nothing + return; + } + + // Transforming. + $vobj = VObject\Reader::read($response->getBody()); + + $jsonBody = json_encode($vobj->jsonSerialize()); + $response->setBody($jsonBody); + + $response->setHeader('Content-Type', 'application/calendar+json'); + $response->setHeader('Content-Length', strlen($jsonBody)); + + } + + /** + * Returns a bunch of meta-data about the plugin. + * + * Providing this information is optional, and is mainly displayed by the + * Browser plugin. + * + * The description key in the returned array may contain html and will not + * be sanitized. + * + * @return array + */ + function getPluginInfo() { + + return [ + 'name' => $this->getPluginName(), + 'description' => 'Adds support for CalDAV (rfc4791)', + 'link' => 'http://sabre.io/dav/caldav/', + ]; + + } + +} diff --git a/resources/updater-fixes/sabre/dav/lib/CardDAV/Backend/PDO.php b/resources/updater-fixes/sabre/dav/lib/CardDAV/Backend/PDO.php new file mode 100644 index 0000000000000..040a5bbb3af80 --- /dev/null +++ b/resources/updater-fixes/sabre/dav/lib/CardDAV/Backend/PDO.php @@ -0,0 +1,545 @@ +pdo = $pdo; + + } + + /** + * Returns the list of addressbooks for a specific user. + * + * @param string $principalUri + * @return array + */ + function getAddressBooksForUser($principalUri) { + + $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, synctoken FROM ' . $this->addressBooksTableName . ' WHERE principaluri = ?'); + $stmt->execute([$principalUri]); + + $addressBooks = []; + + foreach ($stmt->fetchAll() as $row) { + + $addressBooks[] = [ + 'id' => $row['id'], + 'uri' => $row['uri'], + 'principaluri' => $row['principaluri'], + '{DAV:}displayname' => $row['displayname'], + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'], + '{http://calendarserver.org/ns/}getctag' => $row['synctoken'], + '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0', + ]; + + } + + return $addressBooks; + + } + + + /** + * Updates properties for an address book. + * + * The list of mutations is stored in a Sabre\DAV\PropPatch object. + * To do the actual updates, you must tell this object which properties + * you're going to process with the handle() method. + * + * Calling the handle method is like telling the PropPatch object "I + * promise I can handle updating this property". + * + * Read the PropPatch documenation for more info and examples. + * + * @param string $addressBookId + * @param \Sabre\DAV\PropPatch $propPatch + * @return void + */ + function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) { + + $supportedProperties = [ + '{DAV:}displayname', + '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description', + ]; + + $propPatch->handle($supportedProperties, function($mutations) use ($addressBookId) { + + $updates = []; + foreach ($mutations as $property => $newValue) { + + switch ($property) { + case '{DAV:}displayname' : + $updates['displayname'] = $newValue; + break; + case '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' : + $updates['description'] = $newValue; + break; + } + } + $query = 'UPDATE ' . $this->addressBooksTableName . ' SET '; + $first = true; + foreach ($updates as $key => $value) { + if ($first) { + $first = false; + } else { + $query .= ', '; + } + $query .= ' `' . $key . '` = :' . $key . ' '; + } + $query .= ' WHERE id = :addressbookid'; + + $stmt = $this->pdo->prepare($query); + $updates['addressbookid'] = $addressBookId; + + $stmt->execute($updates); + + $this->addChange($addressBookId, "", 2); + + return true; + + }); + + } + + /** + * Creates a new address book + * + * @param string $principalUri + * @param string $url Just the 'basename' of the url. + * @param array $properties + * @return void + */ + function createAddressBook($principalUri, $url, array $properties) { + + $values = [ + 'displayname' => null, + 'description' => null, + 'principaluri' => $principalUri, + 'uri' => $url, + ]; + + foreach ($properties as $property => $newValue) { + + switch ($property) { + case '{DAV:}displayname' : + $values['displayname'] = $newValue; + break; + case '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' : + $values['description'] = $newValue; + break; + default : + throw new DAV\Exception\BadRequest('Unknown property: ' . $property); + } + + } + + $query = 'INSERT INTO ' . $this->addressBooksTableName . ' (uri, displayname, description, principaluri, synctoken) VALUES (:uri, :displayname, :description, :principaluri, 1)'; + $stmt = $this->pdo->prepare($query); + $stmt->execute($values); + return $this->pdo->lastInsertId(); + + } + + /** + * Deletes an entire addressbook and all its contents + * + * @param int $addressBookId + * @return void + */ + function deleteAddressBook($addressBookId) { + + $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?'); + $stmt->execute([$addressBookId]); + + $stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBooksTableName . ' WHERE id = ?'); + $stmt->execute([$addressBookId]); + + $stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBookChangesTableName . ' WHERE addressbookid = ?'); + $stmt->execute([$addressBookId]); + + } + + /** + * Returns all cards for a specific addressbook id. + * + * This method should return the following properties for each card: + * * carddata - raw vcard data + * * uri - Some unique url + * * lastmodified - A unix timestamp + * + * It's recommended to also return the following properties: + * * etag - A unique etag. This must change every time the card changes. + * * size - The size of the card in bytes. + * + * If these last two properties are provided, less time will be spent + * calculating them. If they are specified, you can also ommit carddata. + * This may speed up certain requests, especially with large cards. + * + * @param mixed $addressbookId + * @return array + */ + function getCards($addressbookId) { + + $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, size FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?'); + $stmt->execute([$addressbookId]); + + $result = []; + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + $row['etag'] = '"' . $row['etag'] . '"'; + $result[] = $row; + } + return $result; + + } + + /** + * Returns a specfic card. + * + * The same set of properties must be returned as with getCards. The only + * exception is that 'carddata' is absolutely required. + * + * If the card does not exist, you must return false. + * + * @param mixed $addressBookId + * @param string $cardUri + * @return array + */ + function getCard($addressBookId, $cardUri) { + + $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified, etag, size FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ? LIMIT 1'); + $stmt->execute([$addressBookId, $cardUri]); + + $result = $stmt->fetch(\PDO::FETCH_ASSOC); + + if (!$result) return false; + + $result['etag'] = '"' . $result['etag'] . '"'; + return $result; + + } + + /** + * Returns a list of cards. + * + * This method should work identical to getCard, but instead return all the + * cards in the list as an array. + * + * If the backend supports this, it may allow for some speed-ups. + * + * @param mixed $addressBookId + * @param array $uris + * @return array + */ + function getMultipleCards($addressBookId, array $uris) { + + $query = 'SELECT id, uri, lastmodified, etag, size, carddata FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri IN ('; + // Inserting a whole bunch of question marks + $query .= implode(',', array_fill(0, count($uris), '?')); + $query .= ')'; + + $stmt = $this->pdo->prepare($query); + $stmt->execute(array_merge([$addressBookId], $uris)); + $result = []; + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + $row['etag'] = '"' . $row['etag'] . '"'; + $result[] = $row; + } + return $result; + + } + + /** + * Creates a new card. + * + * The addressbook id will be passed as the first argument. This is the + * same id as it is returned from the getAddressBooksForUser method. + * + * The cardUri is a base uri, and doesn't include the full path. The + * cardData argument is the vcard body, and is passed as a string. + * + * It is possible to return an ETag from this method. This ETag is for the + * newly created resource, and must be enclosed with double quotes (that + * is, the string itself must contain the double quotes). + * + * You should only return the ETag if you store the carddata as-is. If a + * subsequent GET request on the same card does not have the same body, + * byte-by-byte and you did return an ETag here, clients tend to get + * confused. + * + * If you don't return an ETag, you can just return null. + * + * @param mixed $addressBookId + * @param string $cardUri + * @param string $cardData + * @return string|null + */ + function createCard($addressBookId, $cardUri, $cardData) { + + $stmt = $this->pdo->prepare('INSERT INTO ' . $this->cardsTableName . ' (carddata, uri, lastmodified, addressbookid, size, etag) VALUES (?, ?, ?, ?, ?, ?)'); + + $etag = md5($cardData); + + $stmt->execute([ + $cardData, + $cardUri, + time(), + $addressBookId, + strlen($cardData), + $etag, + ]); + + $this->addChange($addressBookId, $cardUri, 1); + + return '"' . $etag . '"'; + + } + + /** + * Updates a card. + * + * The addressbook id will be passed as the first argument. This is the + * same id as it is returned from the getAddressBooksForUser method. + * + * The cardUri is a base uri, and doesn't include the full path. The + * cardData argument is the vcard body, and is passed as a string. + * + * It is possible to return an ETag from this method. This ETag should + * match that of the updated resource, and must be enclosed with double + * quotes (that is: the string itself must contain the actual quotes). + * + * You should only return the ETag if you store the carddata as-is. If a + * subsequent GET request on the same card does not have the same body, + * byte-by-byte and you did return an ETag here, clients tend to get + * confused. + * + * If you don't return an ETag, you can just return null. + * + * @param mixed $addressBookId + * @param string $cardUri + * @param string $cardData + * @return string|null + */ + function updateCard($addressBookId, $cardUri, $cardData) { + + $stmt = $this->pdo->prepare('UPDATE ' . $this->cardsTableName . ' SET carddata = ?, lastmodified = ?, size = ?, etag = ? WHERE uri = ? AND addressbookid =?'); + + $etag = md5($cardData); + $stmt->execute([ + $cardData, + time(), + strlen($cardData), + $etag, + $cardUri, + $addressBookId + ]); + + $this->addChange($addressBookId, $cardUri, 2); + + return '"' . $etag . '"'; + + } + + /** + * Deletes a card + * + * @param mixed $addressBookId + * @param string $cardUri + * @return bool + */ + function deleteCard($addressBookId, $cardUri) { + + $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ?'); + $stmt->execute([$addressBookId, $cardUri]); + + $this->addChange($addressBookId, $cardUri, 3); + + return $stmt->rowCount() === 1; + + } + + /** + * The getChanges method returns all the changes that have happened, since + * the specified syncToken in the specified address book. + * + * This function should return an array, such as the following: + * + * [ + * 'syncToken' => 'The current synctoken', + * 'added' => [ + * 'new.txt', + * ], + * 'modified' => [ + * 'updated.txt', + * ], + * 'deleted' => [ + * 'foo.php.bak', + * 'old.txt' + * ] + * ]; + * + * The returned syncToken property should reflect the *current* syncToken + * of the addressbook, as reported in the {http://sabredav.org/ns}sync-token + * property. This is needed here too, to ensure the operation is atomic. + * + * If the $syncToken argument is specified as null, this is an initial + * sync, and all members should be reported. + * + * The modified property is an array of nodenames that have changed since + * the last token. + * + * The deleted property is an array with nodenames, that have been deleted + * from collection. + * + * The $syncLevel argument is basically the 'depth' of the report. If it's + * 1, you only have to report changes that happened only directly in + * immediate descendants. If it's 2, it should also include changes from + * the nodes below the child collections. (grandchildren) + * + * The $limit argument allows a client to specify how many results should + * be returned at most. If the limit is not specified, it should be treated + * as infinite. + * + * If the limit (infinite or not) is higher than you're willing to return, + * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. + * + * If the syncToken is expired (due to data cleanup) or unknown, you must + * return null. + * + * The limit is 'suggestive'. You are free to ignore it. + * + * @param string $addressBookId + * @param string $syncToken + * @param int $syncLevel + * @param int $limit + * @return array + */ + function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null) { + + // Current synctoken + $stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->addressBooksTableName . ' WHERE id = ?'); + $stmt->execute([ $addressBookId ]); + $currentToken = $stmt->fetchColumn(0); + + if (is_null($currentToken)) return null; + + $result = [ + 'syncToken' => $currentToken, + 'added' => [], + 'modified' => [], + 'deleted' => [], + ]; + + if ($syncToken) { + + $query = "SELECT uri, operation FROM " . $this->addressBookChangesTableName . " WHERE synctoken >= ? AND synctoken < ? AND addressbookid = ? ORDER BY synctoken"; + if ($limit > 0) $query .= " LIMIT " . (int)$limit; + + // Fetching all changes + $stmt = $this->pdo->prepare($query); + $stmt->execute([$syncToken, $currentToken, $addressBookId]); + + $changes = []; + + // This loop ensures that any duplicates are overwritten, only the + // last change on a node is relevant. + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + + $changes[$row['uri']] = $row['operation']; + + } + + foreach ($changes as $uri => $operation) { + + switch ($operation) { + case 1: + $result['added'][] = $uri; + break; + case 2: + $result['modified'][] = $uri; + break; + case 3: + $result['deleted'][] = $uri; + break; + } + + } + } else { + // No synctoken supplied, this is the initial sync. + $query = "SELECT uri FROM " . $this->cardsTableName . " WHERE addressbookid = ?"; + $stmt = $this->pdo->prepare($query); + $stmt->execute([$addressBookId]); + + $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN); + } + return $result; + + } + + /** + * Adds a change record to the addressbookchanges table. + * + * @param mixed $addressBookId + * @param string $objectUri + * @param int $operation 1 = add, 2 = modify, 3 = delete + * @return void + */ + protected function addChange($addressBookId, $objectUri, $operation) { + + $stmt = $this->pdo->prepare('INSERT INTO ' . $this->addressBookChangesTableName . ' (uri, synctoken, addressbookid, operation) SELECT ?, synctoken, ?, ? FROM ' . $this->addressBooksTableName . ' WHERE id = ?'); + $stmt->execute([ + $objectUri, + $addressBookId, + $operation, + $addressBookId + ]); + $stmt = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET synctoken = synctoken + 1 WHERE id = ?'); + $stmt->execute([ + $addressBookId + ]); + + } +} diff --git a/resources/updater-fixes/sabre/dav/lib/DAV/CorePlugin.php b/resources/updater-fixes/sabre/dav/lib/DAV/CorePlugin.php new file mode 100644 index 0000000000000..4cb137068a13d --- /dev/null +++ b/resources/updater-fixes/sabre/dav/lib/DAV/CorePlugin.php @@ -0,0 +1,927 @@ +server = $server; + $server->on('method:GET', [$this, 'httpGet']); + $server->on('method:OPTIONS', [$this, 'httpOptions']); + $server->on('method:HEAD', [$this, 'httpHead']); + $server->on('method:DELETE', [$this, 'httpDelete']); + $server->on('method:PROPFIND', [$this, 'httpPropFind']); + $server->on('method:PROPPATCH', [$this, 'httpPropPatch']); + $server->on('method:PUT', [$this, 'httpPut']); + $server->on('method:MKCOL', [$this, 'httpMkcol']); + $server->on('method:MOVE', [$this, 'httpMove']); + $server->on('method:COPY', [$this, 'httpCopy']); + $server->on('method:REPORT', [$this, 'httpReport']); + + $server->on('propPatch', [$this, 'propPatchProtectedPropertyCheck'], 90); + $server->on('propPatch', [$this, 'propPatchNodeUpdate'], 200); + $server->on('propFind', [$this, 'propFind']); + $server->on('propFind', [$this, 'propFindNode'], 120); + $server->on('propFind', [$this, 'propFindLate'], 200); + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using DAV\Server::getPlugin + * + * @return string + */ + function getPluginName() { + + return 'core'; + + } + + /** + * This is the default implementation for the GET method. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpGet(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + $node = $this->server->tree->getNodeForPath($path, 0); + + if (!$node instanceof IFile) return; + + $body = $node->get(); + + // Converting string into stream, if needed. + if (is_string($body)) { + $stream = fopen('php://temp', 'r+'); + fwrite($stream, $body); + rewind($stream); + $body = $stream; + } + + /* + * TODO: getetag, getlastmodified, getsize should also be used using + * this method + */ + $httpHeaders = $this->server->getHTTPHeaders($path); + + /* ContentType needs to get a default, because many webservers will otherwise + * default to text/html, and we don't want this for security reasons. + */ + if (!isset($httpHeaders['Content-Type'])) { + $httpHeaders['Content-Type'] = 'application/octet-stream'; + } + + + if (isset($httpHeaders['Content-Length'])) { + + $nodeSize = $httpHeaders['Content-Length']; + + // Need to unset Content-Length, because we'll handle that during figuring out the range + unset($httpHeaders['Content-Length']); + + } else { + $nodeSize = null; + } + + $response->addHeaders($httpHeaders); + + $range = $this->server->getHTTPRange(); + $ifRange = $request->getHeader('If-Range'); + $ignoreRangeHeader = false; + + // If ifRange is set, and range is specified, we first need to check + // the precondition. + if ($nodeSize && $range && $ifRange) { + + // if IfRange is parsable as a date we'll treat it as a DateTime + // otherwise, we must treat it as an etag. + try { + $ifRangeDate = new \DateTime($ifRange); + + // It's a date. We must check if the entity is modified since + // the specified date. + if (!isset($httpHeaders['Last-Modified'])) $ignoreRangeHeader = true; + else { + $modified = new \DateTime($httpHeaders['Last-Modified']); + if ($modified > $ifRangeDate) $ignoreRangeHeader = true; + } + + } catch (\Exception $e) { + + // It's an entity. We can do a simple comparison. + if (!isset($httpHeaders['ETag'])) $ignoreRangeHeader = true; + elseif ($httpHeaders['ETag'] !== $ifRange) $ignoreRangeHeader = true; + } + } + + // We're only going to support HTTP ranges if the backend provided a filesize + if (!$ignoreRangeHeader && $nodeSize && $range) { + + // Determining the exact byte offsets + if (!is_null($range[0])) { + + $start = $range[0]; + $end = $range[1] ? $range[1] : $nodeSize - 1; + if ($start >= $nodeSize) + throw new Exception\RequestedRangeNotSatisfiable('The start offset (' . $range[0] . ') exceeded the size of the entity (' . $nodeSize . ')'); + + if ($end < $start) throw new Exception\RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')'); + if ($end >= $nodeSize) $end = $nodeSize - 1; + + } else { + + $start = $nodeSize - $range[1]; + $end = $nodeSize - 1; + + if ($start < 0) $start = 0; + + } + + // Streams may advertise themselves as seekable, but still not + // actually allow fseek. We'll manually go forward in the stream + // if fseek failed. + if (!stream_get_meta_data($body)['seekable'] || fseek($body, $start, SEEK_SET) === -1) { + $consumeBlock = 8192; + for ($consumed = 0; $start - $consumed > 0;){ + if (feof($body)) throw new Exception\RequestedRangeNotSatisfiable('The start offset (' . $start . ') exceeded the size of the entity (' . $consumed . ')'); + $consumed += strlen(fread($body, min($start - $consumed, $consumeBlock))); + } + } + + $response->setHeader('Content-Length', $end - $start + 1); + $response->setHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $nodeSize); + $response->setStatus(206); + $response->setBody($body); + + } else { + + if ($nodeSize) $response->setHeader('Content-Length', $nodeSize); + $response->setStatus(200); + $response->setBody($body); + + } + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * HTTP OPTIONS + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpOptions(RequestInterface $request, ResponseInterface $response) { + + $methods = $this->server->getAllowedMethods($request->getPath()); + + $response->setHeader('Allow', strtoupper(implode(', ', $methods))); + $features = ['1', '3', 'extended-mkcol']; + + foreach ($this->server->getPlugins() as $plugin) { + $features = array_merge($features, $plugin->getFeatures()); + } + + $response->setHeader('DAV', implode(', ', $features)); + $response->setHeader('MS-Author-Via', 'DAV'); + $response->setHeader('Accept-Ranges', 'bytes'); + $response->setHeader('Content-Length', '0'); + $response->setStatus(200); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * HTTP HEAD + * + * This method is normally used to take a peak at a url, and only get the + * HTTP response headers, without the body. This is used by clients to + * determine if a remote file was changed, so they can use a local cached + * version, instead of downloading it again + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpHead(RequestInterface $request, ResponseInterface $response) { + + // This is implemented by changing the HEAD request to a GET request, + // and dropping the response body. + $subRequest = clone $request; + $subRequest->setMethod('GET'); + + try { + $this->server->invokeMethod($subRequest, $response, false); + $response->setBody(''); + } catch (Exception\NotImplemented $e) { + // Some clients may do HEAD requests on collections, however, GET + // requests and HEAD requests _may_ not be defined on a collection, + // which would trigger a 501. + // This breaks some clients though, so we're transforming these + // 501s into 200s. + $response->setStatus(200); + $response->setBody(''); + $response->setHeader('Content-Type', 'text/plain'); + $response->setHeader('X-Sabre-Real-Status', $e->getHTTPCode()); + } + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * HTTP Delete + * + * The HTTP delete method, deletes a given uri + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function httpDelete(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + if (!$this->server->emit('beforeUnbind', [$path])) return false; + $this->server->tree->delete($path); + $this->server->emit('afterUnbind', [$path]); + + $response->setStatus(204); + $response->setHeader('Content-Length', '0'); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * WebDAV PROPFIND + * + * This WebDAV method requests information about an uri resource, or a list of resources + * If a client wants to receive the properties for a single resource it will add an HTTP Depth: header with a 0 value + * If the value is 1, it means that it also expects a list of sub-resources (e.g.: files in a directory) + * + * The request body contains an XML data structure that has a list of properties the client understands + * The response body is also an xml document, containing information about every uri resource and the requested properties + * + * It has to return a HTTP 207 Multi-status status code + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function httpPropFind(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + $requestBody = $request->getBodyAsString(); + if (strlen($requestBody)) { + try { + $propFindXml = $this->server->xml->expect('{DAV:}propfind', $requestBody); + } catch (ParseException $e) { + throw new BadRequest($e->getMessage(), null, $e); + } + } else { + $propFindXml = new Xml\Request\PropFind(); + $propFindXml->allProp = true; + $propFindXml->properties = []; + } + + $depth = $this->server->getHTTPDepth(1); + // The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled + if (!$this->server->enablePropfindDepthInfinity && $depth != 0) $depth = 1; + + $newProperties = $this->server->getPropertiesForPath($path, $propFindXml->properties, $depth); + + // This is a multi-status response + $response->setStatus(207); + $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); + $response->setHeader('Vary', 'Brief,Prefer'); + + // Normally this header is only needed for OPTIONS responses, however.. + // iCal seems to also depend on these being set for PROPFIND. Since + // this is not harmful, we'll add it. + $features = ['1', '3', 'extended-mkcol']; + foreach ($this->server->getPlugins() as $plugin) { + $features = array_merge($features, $plugin->getFeatures()); + } + $response->setHeader('DAV', implode(', ', $features)); + + $prefer = $this->server->getHTTPPrefer(); + $minimal = $prefer['return'] === 'minimal'; + + $data = $this->server->generateMultiStatus($newProperties, $minimal); + $response->setBody($data); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * WebDAV PROPPATCH + * + * This method is called to update properties on a Node. The request is an XML body with all the mutations. + * In this XML body it is specified which properties should be set/updated and/or deleted + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpPropPatch(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + try { + $propPatch = $this->server->xml->expect('{DAV:}propertyupdate', $request->getBody()); + } catch (ParseException $e) { + throw new BadRequest($e->getMessage(), null, $e); + } + $newProperties = $propPatch->properties; + + $result = $this->server->updateProperties($path, $newProperties); + + $prefer = $this->server->getHTTPPrefer(); + $response->setHeader('Vary', 'Brief,Prefer'); + + if ($prefer['return'] === 'minimal') { + + // If return-minimal is specified, we only have to check if the + // request was succesful, and don't need to return the + // multi-status. + $ok = true; + foreach ($result as $prop => $code) { + if ((int)$code > 299) { + $ok = false; + } + } + + if ($ok) { + + $response->setStatus(204); + return false; + + } + + } + + $response->setStatus(207); + $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); + + + // Reorganizing the result for generateMultiStatus + $multiStatus = []; + foreach ($result as $propertyName => $code) { + if (isset($multiStatus[$code])) { + $multiStatus[$code][$propertyName] = null; + } else { + $multiStatus[$code] = [$propertyName => null]; + } + } + $multiStatus['href'] = $path; + + $response->setBody( + $this->server->generateMultiStatus([$multiStatus]) + ); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * HTTP PUT method + * + * This HTTP method updates a file, or creates a new one. + * + * If a new resource was created, a 201 Created status code should be returned. If an existing resource is updated, it's a 204 No Content + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpPut(RequestInterface $request, ResponseInterface $response) { + + $body = $request->getBodyAsStream(); + $path = $request->getPath(); + + // Intercepting Content-Range + if ($request->getHeader('Content-Range')) { + /* + An origin server that allows PUT on a given target resource MUST send + a 400 (Bad Request) response to a PUT request that contains a + Content-Range header field. + + Reference: http://tools.ietf.org/html/rfc7231#section-4.3.4 + */ + throw new Exception\BadRequest('Content-Range on PUT requests are forbidden.'); + } + + // Intercepting the Finder problem + if (($expected = $request->getHeader('X-Expected-Entity-Length')) && $expected > 0) { + + /* + Many webservers will not cooperate well with Finder PUT requests, + because it uses 'Chunked' transfer encoding for the request body. + + The symptom of this problem is that Finder sends files to the + server, but they arrive as 0-length files in PHP. + + If we don't do anything, the user might think they are uploading + files successfully, but they end up empty on the server. Instead, + we throw back an error if we detect this. + + The reason Finder uses Chunked, is because it thinks the files + might change as it's being uploaded, and therefore the + Content-Length can vary. + + Instead it sends the X-Expected-Entity-Length header with the size + of the file at the very start of the request. If this header is set, + but we don't get a request body we will fail the request to + protect the end-user. + */ + + // Only reading first byte + $firstByte = fread($body, 1); + if (strlen($firstByte) !== 1) { + throw new Exception\Forbidden('This server is not compatible with OS/X finder. Consider using a different WebDAV client or webserver.'); + } + + // The body needs to stay intact, so we copy everything to a + // temporary stream. + + $newBody = fopen('php://temp', 'r+'); + fwrite($newBody, $firstByte); + stream_copy_to_stream($body, $newBody); + rewind($newBody); + + $body = $newBody; + + } + + if ($this->server->tree->nodeExists($path)) { + + $node = $this->server->tree->getNodeForPath($path); + + // If the node is a collection, we'll deny it + if (!($node instanceof IFile)) throw new Exception\Conflict('PUT is not allowed on non-files.'); + + if (!$this->server->updateFile($path, $body, $etag)) { + return false; + } + + $response->setHeader('Content-Length', '0'); + if ($etag) $response->setHeader('ETag', $etag); + $response->setStatus(204); + + } else { + + $etag = null; + // If we got here, the resource didn't exist yet. + if (!$this->server->createFile($path, $body, $etag)) { + // For one reason or another the file was not created. + return false; + } + + $response->setHeader('Content-Length', '0'); + if ($etag) $response->setHeader('ETag', $etag); + $response->setStatus(201); + + } + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + + /** + * WebDAV MKCOL + * + * The MKCOL method is used to create a new collection (directory) on the server + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpMkcol(RequestInterface $request, ResponseInterface $response) { + + $requestBody = $request->getBodyAsString(); + $path = $request->getPath(); + + if ($requestBody) { + + $contentType = $request->getHeader('Content-Type'); + if (strpos($contentType, 'application/xml') !== 0 && strpos($contentType, 'text/xml') !== 0) { + + // We must throw 415 for unsupported mkcol bodies + throw new Exception\UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type'); + + } + + try { + $mkcol = $this->server->xml->expect('{DAV:}mkcol', $requestBody); + } catch (\Sabre\Xml\ParseException $e) { + throw new Exception\BadRequest($e->getMessage(), null, $e); + } + + $properties = $mkcol->getProperties(); + + if (!isset($properties['{DAV:}resourcetype'])) + throw new Exception\BadRequest('The mkcol request must include a {DAV:}resourcetype property'); + + $resourceType = $properties['{DAV:}resourcetype']->getValue(); + unset($properties['{DAV:}resourcetype']); + + } else { + + $properties = []; + $resourceType = ['{DAV:}collection']; + + } + + $mkcol = new MkCol($resourceType, $properties); + + $result = $this->server->createCollection($path, $mkcol); + + if (is_array($result)) { + $response->setStatus(207); + $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); + + $response->setBody( + $this->server->generateMultiStatus([$result]) + ); + + } else { + $response->setHeader('Content-Length', '0'); + $response->setStatus(201); + } + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * WebDAV HTTP MOVE method + * + * This method moves one uri to a different uri. A lot of the actual request processing is done in getCopyMoveInfo + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpMove(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + $moveInfo = $this->server->getCopyAndMoveInfo($request); + + if ($moveInfo['destinationExists']) { + + if (!$this->server->emit('beforeUnbind', [$moveInfo['destination']])) return false; + + } + if (!$this->server->emit('beforeUnbind', [$path])) return false; + if (!$this->server->emit('beforeBind', [$moveInfo['destination']])) return false; + if (!$this->server->emit('beforeMove', [$path, $moveInfo['destination']])) return false; + + if ($moveInfo['destinationExists']) { + + $this->server->tree->delete($moveInfo['destination']); + $this->server->emit('afterUnbind', [$moveInfo['destination']]); + + } + + $this->server->tree->move($path, $moveInfo['destination']); + + // Its important afterMove is called before afterUnbind, because it + // allows systems to transfer data from one path to another. + // PropertyStorage uses this. If afterUnbind was first, it would clean + // up all the properties before it has a chance. + $this->server->emit('afterMove', [$path, $moveInfo['destination']]); + $this->server->emit('afterUnbind', [$path]); + $this->server->emit('afterBind', [$moveInfo['destination']]); + + // If a resource was overwritten we should send a 204, otherwise a 201 + $response->setHeader('Content-Length', '0'); + $response->setStatus($moveInfo['destinationExists'] ? 204 : 201); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * WebDAV HTTP COPY method + * + * This method copies one uri to a different uri, and works much like the MOVE request + * A lot of the actual request processing is done in getCopyMoveInfo + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpCopy(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + $copyInfo = $this->server->getCopyAndMoveInfo($request); + + if ($copyInfo['destinationExists']) { + if (!$this->server->emit('beforeUnbind', [$copyInfo['destination']])) return false; + $this->server->tree->delete($copyInfo['destination']); + + } + if (!$this->server->emit('beforeBind', [$copyInfo['destination']])) return false; + $this->server->tree->copy($path, $copyInfo['destination']); + $this->server->emit('afterBind', [$copyInfo['destination']]); + + // If a resource was overwritten we should send a 204, otherwise a 201 + $response->setHeader('Content-Length', '0'); + $response->setStatus($copyInfo['destinationExists'] ? 204 : 201); + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + + } + + /** + * HTTP REPORT method implementation + * + * Although the REPORT method is not part of the standard WebDAV spec (it's from rfc3253) + * It's used in a lot of extensions, so it made sense to implement it into the core. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function httpReport(RequestInterface $request, ResponseInterface $response) { + + $path = $request->getPath(); + + $result = $this->server->xml->parse( + $request->getBody(), + $request->getUrl(), + $rootElementName + ); + + if ($this->server->emit('report', [$rootElementName, $result, $path])) { + + // If emit returned true, it means the report was not supported + throw new Exception\ReportNotSupported(); + + } + + // Sending back false will interupt the event chain and tell the server + // we've handled this method. + return false; + + } + + /** + * This method is called during property updates. + * + * Here we check if a user attempted to update a protected property and + * ensure that the process fails if this is the case. + * + * @param string $path + * @param PropPatch $propPatch + * @return void + */ + function propPatchProtectedPropertyCheck($path, PropPatch $propPatch) { + + // Comparing the mutation list to the list of propetected properties. + $mutations = $propPatch->getMutations(); + + $protected = array_intersect( + $this->server->protectedProperties, + array_keys($mutations) + ); + + if ($protected) { + $propPatch->setResultCode($protected, 403); + } + + } + + /** + * This method is called during property updates. + * + * Here we check if a node implements IProperties and let the node handle + * updating of (some) properties. + * + * @param string $path + * @param PropPatch $propPatch + * @return void + */ + function propPatchNodeUpdate($path, PropPatch $propPatch) { + + // This should trigger a 404 if the node doesn't exist. + $node = $this->server->tree->getNodeForPath($path); + + if ($node instanceof IProperties) { + $node->propPatch($propPatch); + } + + } + + /** + * This method is called when properties are retrieved. + * + * Here we add all the default properties. + * + * @param PropFind $propFind + * @param INode $node + * @return void + */ + function propFind(PropFind $propFind, INode $node) { + + $propFind->handle('{DAV:}getlastmodified', function() use ($node) { + $lm = $node->getLastModified(); + if ($lm) { + return new Xml\Property\GetLastModified($lm); + } + }); + + if ($node instanceof IFile) { + $propFind->handle('{DAV:}getcontentlength', [$node, 'getSize']); + $propFind->handle('{DAV:}getetag', [$node, 'getETag']); + $propFind->handle('{DAV:}getcontenttype', [$node, 'getContentType']); + } + + if ($node instanceof IQuota) { + $quotaInfo = null; + $propFind->handle('{DAV:}quota-used-bytes', function() use (&$quotaInfo, $node) { + $quotaInfo = $node->getQuotaInfo(); + return $quotaInfo[0]; + }); + $propFind->handle('{DAV:}quota-available-bytes', function() use (&$quotaInfo, $node) { + if (!$quotaInfo) { + $quotaInfo = $node->getQuotaInfo(); + } + return $quotaInfo[1]; + }); + } + + $propFind->handle('{DAV:}supported-report-set', function() use ($propFind) { + $reports = []; + foreach ($this->server->getPlugins() as $plugin) { + $reports = array_merge($reports, $plugin->getSupportedReportSet($propFind->getPath())); + } + return new Xml\Property\SupportedReportSet($reports); + }); + $propFind->handle('{DAV:}resourcetype', function() use ($node) { + return new Xml\Property\ResourceType($this->server->getResourceTypeForNode($node)); + }); + $propFind->handle('{DAV:}supported-method-set', function() use ($propFind) { + return new Xml\Property\SupportedMethodSet( + $this->server->getAllowedMethods($propFind->getPath()) + ); + }); + + } + + /** + * Fetches properties for a node. + * + * This event is called a bit later, so plugins have a chance first to + * populate the result. + * + * @param PropFind $propFind + * @param INode $node + * @return void + */ + function propFindNode(PropFind $propFind, INode $node) { + + if ($node instanceof IProperties && $propertyNames = $propFind->get404Properties()) { + + $nodeProperties = $node->getProperties($propertyNames); + foreach ($propertyNames as $propertyName) { + if (array_key_exists($propertyName, $nodeProperties)) { + $propFind->set($propertyName, $nodeProperties[$propertyName], 200); + } + } + + } + + } + + /** + * This method is called when properties are retrieved. + * + * This specific handler is called very late in the process, because we + * want other systems to first have a chance to handle the properties. + * + * @param PropFind $propFind + * @param INode $node + * @return void + */ + function propFindLate(PropFind $propFind, INode $node) { + + $propFind->handle('{http://calendarserver.org/ns/}getctag', function() use ($propFind) { + + // If we already have a sync-token from the current propFind + // request, we can re-use that. + $val = $propFind->get('{http://sabredav.org/ns}sync-token'); + if ($val) return $val; + + $val = $propFind->get('{DAV:}sync-token'); + if ($val && is_scalar($val)) { + return $val; + } + if ($val && $val instanceof Xml\Property\Href) { + return substr($val->getHref(), strlen(Sync\Plugin::SYNCTOKEN_PREFIX)); + } + + // If we got here, the earlier two properties may simply not have + // been part of the earlier request. We're going to fetch them. + $result = $this->server->getProperties($propFind->getPath(), [ + '{http://sabredav.org/ns}sync-token', + '{DAV:}sync-token', + ]); + + if (isset($result['{http://sabredav.org/ns}sync-token'])) { + return $result['{http://sabredav.org/ns}sync-token']; + } + if (isset($result['{DAV:}sync-token'])) { + $val = $result['{DAV:}sync-token']; + if (is_scalar($val)) { + return $val; + } elseif ($val instanceof Xml\Property\Href) { + return substr($val->getHref(), strlen(Sync\Plugin::SYNCTOKEN_PREFIX)); + } + } + + }); + + } + + /** + * Returns a bunch of meta-data about the plugin. + * + * Providing this information is optional, and is mainly displayed by the + * Browser plugin. + * + * The description key in the returned array may contain html and will not + * be sanitized. + * + * @return array + */ + function getPluginInfo() { + + return [ + 'name' => $this->getPluginName(), + 'description' => 'The Core plugin provides a lot of the basic functionality required by WebDAV, such as a default implementation for all HTTP and WebDAV methods.', + 'link' => null, + ]; + + } +} diff --git a/resources/updater-fixes/sabre/dav/lib/DAV/Version.php b/resources/updater-fixes/sabre/dav/lib/DAV/Version.php new file mode 100644 index 0000000000000..c8b17233ffbee --- /dev/null +++ b/resources/updater-fixes/sabre/dav/lib/DAV/Version.php @@ -0,0 +1,19 @@ + Date: Wed, 20 Apr 2016 22:00:44 +0200 Subject: [PATCH 212/286] Write .htaccess also from CLI The new updater as shipped with ownCloud 9.0.x invokes `occ` via `shell_exec`. This means that the `\OC::$CLI` code is used when updating. This removes the manual `.htaccess` modifications, effectively leading to the fact that URLs without index.php in it stop working. This also affects share URLs which could be considered a rather serious regression. - User installs 9.0.0 via web - User shares /s/1234 - User updates to 9.0.1 via ownCloud updater - Link to /s/1234 is broken, /index.php/s/1234 works --- lib/private/setup.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index 6303d0d47f3a8..d2f3802ebad7e 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -400,12 +400,21 @@ private function pathToHtaccess() { * Append the correct ErrorDocument path for Apache hosts */ public static function updateHtaccess() { - // From CLI we don't know the defined web root. Thus we can't write any - // directives into the .htaccess file. + $config = \OC::$server->getConfig(); + + // For CLI read the value from overwrite.cli.url if(\OC::$CLI) { - return; + $webRoot = $config->getSystemValue('overwrite.cli.url', ''); + if($webRoot === '') { + return; + } + $webRoot = parse_url($webRoot, PHP_URL_PATH); + $webRoot = rtrim($webRoot, '/'); + } else { + $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; } - $setupHelper = new \OC\Setup(\OC::$server->getConfig(), \OC::$server->getIniWrapper(), + + $setupHelper = new \OC\Setup($config, \OC::$server->getIniWrapper(), \OC::$server->getL10N('lib'), new \OC_Defaults(), \OC::$server->getLogger(), \OC::$server->getSecureRandom()); @@ -413,13 +422,12 @@ public static function updateHtaccess() { $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n"; if(strpos($htaccessContent, $content) === false) { //custom 403 error page - $content.= "\nErrorDocument 403 ".\OC::$WEBROOT."/core/templates/403.php"; + $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php"; //custom 404 error page - $content.= "\nErrorDocument 404 ".\OC::$WEBROOT."/core/templates/404.php"; + $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php"; // Add rewrite base - $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; $content .= "\n"; $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; $content .= "\n RewriteBase ".$webRoot; From e33adcf0df870b1cd9fabe54371dadfca3fbeae4 Mon Sep 17 00:00:00 2001 From: Christoph Wurst Date: Wed, 13 Apr 2016 17:32:00 +0200 Subject: [PATCH 213/286] remember email when setting expiration date fixes #22947 --- core/js/sharedialoglinkshareview.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js index 1d158ccec16ae..26b0606d8119c 100644 --- a/core/js/sharedialoglinkshareview.js +++ b/core/js/sharedialoglinkshareview.js @@ -42,7 +42,7 @@ ' {{/if}}' + ' {{#if mailPublicNotificationEnabled}}' + '' + ' {{/if}}' + @@ -249,6 +249,7 @@ render: function() { var linkShareTemplate = this.template(); var resharingAllowed = this.model.sharePermissionPossible(); + var email = this.$el.find('.emailField').val(); if(!resharingAllowed || !this.showLink @@ -296,7 +297,8 @@ publicUploadLabel: t('core', 'Allow editing'), mailPublicNotificationEnabled: isLinkShare && this.configModel.isMailPublicNotificationEnabled(), mailPrivatePlaceholder: t('core', 'Email link to person'), - mailButtonText: t('core', 'Send') + mailButtonText: t('core', 'Send'), + email: email })); var $emailField = this.$el.find('.emailField'); From 440cf335ad63a57b643a94cc360e97d15c96436f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 20 Apr 2016 14:58:43 +0200 Subject: [PATCH 214/286] Add unit tests for shared size propagation with encryption --- .../tests/encryptedsizepropagation.php | 41 +++++++++++++++++++ apps/files_sharing/tests/sizepropagation.php | 41 ++++++++++++------- 2 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 apps/files_sharing/tests/encryptedsizepropagation.php diff --git a/apps/files_sharing/tests/encryptedsizepropagation.php b/apps/files_sharing/tests/encryptedsizepropagation.php new file mode 100644 index 0000000000000..e341606abe454 --- /dev/null +++ b/apps/files_sharing/tests/encryptedsizepropagation.php @@ -0,0 +1,41 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_sharing\Tests; + +use OC\Files\View; +use Test\Traits\EncryptionTrait; + +/** + * @group DB + */ +class EncryptedSizePropagation extends SizePropagation { + use EncryptionTrait; + + protected function setupUser($name, $password = '') { + $this->createUser($name, $password); + $tmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); + $this->setupForUser($name, $password); + $this->loginWithEncryption($name); + return new View('/' . $name . '/files'); + } +} diff --git a/apps/files_sharing/tests/sizepropagation.php b/apps/files_sharing/tests/sizepropagation.php index 7b7884f3f9635..06ab6fb3d3b42 100644 --- a/apps/files_sharing/tests/sizepropagation.php +++ b/apps/files_sharing/tests/sizepropagation.php @@ -24,6 +24,8 @@ namespace OCA\Files_sharing\Tests; use OC\Files\View; +use Test\Traits\MountProviderTrait; +use Test\Traits\UserTrait; /** * Class SizePropagation @@ -33,13 +35,21 @@ * @package OCA\Files_sharing\Tests */ class SizePropagation extends TestCase { + use UserTrait; + use MountProviderTrait; + + protected function setupUser($name, $password = '') { + $this->createUser($name, $password); + $tmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); + $this->loginAsUser($name); + return new View('/' . $name . '/files'); + } public function testSizePropagationWhenOwnerChangesFile() { - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); - $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); - $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->mkdir('/sharedfolder/subfolder'); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar'); @@ -48,31 +58,29 @@ public function testSizePropagationWhenOwnerChangesFile() { \OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31); $ownerRootInfo = $ownerView->getFileInfo('', false); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt')); $recipientRootInfo = $recipientView->getFileInfo('', false); // when file changed as owner - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar'); // size of recipient's root stays the same - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $newRecipientRootInfo = $recipientView->getFileInfo('', false); $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize()); // size of owner's root increases - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $newOwnerRootInfo = $ownerView->getFileInfo('', false); $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize()); } public function testSizePropagationWhenRecipientChangesFile() { - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); - $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); - $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->mkdir('/sharedfolder/subfolder'); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar'); @@ -81,9 +89,10 @@ public function testSizePropagationWhenRecipientChangesFile() { \OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31); $ownerRootInfo = $ownerView->getFileInfo('', false); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt')); $recipientRootInfo = $recipientView->getFileInfo('', false); + $recipientRootInfoWithMounts = $recipientView->getFileInfo('', true); // when file changed as recipient $recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar'); @@ -92,8 +101,12 @@ public function testSizePropagationWhenRecipientChangesFile() { $newRecipientRootInfo = $recipientView->getFileInfo('', false); $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize()); + // but the size including mountpoints increases + $newRecipientRootInfo = $recipientView->getFileInfo('', true); + $this->assertEquals($recipientRootInfoWithMounts->getSize() +3, $newRecipientRootInfo->getSize()); + // size of owner's root increases - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $newOwnerRootInfo = $ownerView->getFileInfo('', false); $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize()); } From 74ed0a8abaca4198e101c7c356677d47b93d35f0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 20 Apr 2016 15:22:22 +0200 Subject: [PATCH 215/286] dont do optimized size propagation for encrypted files --- lib/private/files/cache/scanner.php | 7 +++++++ lib/private/files/cache/updater.php | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index c16e8515b0191..8730707f1c2f8 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -205,6 +205,10 @@ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = $data['oldSize'] = 0; } + if (isset($cacheData['encrypted'])) { + $data['encrypted'] = $cacheData['encrypted']; + } + // post-emit only if it was a file. By that we avoid counting/treating folders as files if ($data['mimetype'] !== 'httpd/unix-directory') { $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId)); @@ -222,6 +226,9 @@ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = } } + if ($data && !isset($data['encrypted'])) { + $data['encrypted'] = false; + } return $data; } diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 80ba704883e5c..3f80f2b6167ad 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -118,7 +118,10 @@ public function update($path, $time = null) { } $data = $this->scanner->scan($path, Scanner::SCAN_SHALLOW, -1, false); - if (isset($data['oldSize']) && isset($data['size'])) { + if ( + isset($data['oldSize']) && isset($data['size']) && + !$data['encrypted'] // encryption is a pita and touches the cache itself + ) { $sizeDifference = $data['size'] - $data['oldSize']; } else { // scanner didn't provide size info, fallback to full size calculation From 4e50dd87d511597d1e7afbe231893fd3d79f2098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 21 Apr 2016 13:36:52 +0200 Subject: [PATCH 216/286] Birthday calendar should never have write acl - fixes #24154 --- apps/dav/lib/caldav/calendar.php | 20 +++++++------------ .../tests/unit/caldav/caldavbackendtest.php | 1 + apps/dav/tests/unit/caldav/calendartest.php | 13 ++++++++++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 5072d96107e3a..9ff73f43f1ea5 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -28,14 +28,6 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { - public function __construct(BackendInterface $caldavBackend, $calendarInfo) { - parent::__construct($caldavBackend, $calendarInfo); - - if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) { - $this->calendarInfo['{http://sabredav.org/ns}read-only'] = true; - } - } - /** * Updates the list of shares. * @@ -92,11 +84,13 @@ function getACL() { 'principal' => $this->getOwner(), 'protected' => true, ]]; - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->getOwner(), - 'protected' => true, - ]; + if ($this->getName() !== BirthdayService::BIRTHDAY_CALENDAR_URI) { + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $this->getOwner(), + 'protected' => true, + ]; + } if ($this->getOwner() !== parent::getOwner()) { $acl[] = [ 'privilege' => '{DAV:}read', diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index 87a700a473dc7..4a41c3e5674c9 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -25,6 +25,7 @@ use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\Connector\Sabre\Principal; +use OCP\IL10N; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\PropPatch; use Sabre\DAV\Xml\Property\Href; diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index 9e0c3c6c7e426..41363dbf97831 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -21,6 +21,7 @@ namespace OCA\DAV\Tests\Unit\CalDAV; +use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; use Sabre\DAV\PropPatch; @@ -107,14 +108,14 @@ public function testPropPatch($mutations, $throws) { /** * @dataProvider providesReadOnlyInfo */ - public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet) { + public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet, $uri = 'default') { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1); $calendarInfo = [ 'principaluri' => 'user2', 'id' => 666, - 'uri' => 'default' + 'uri' => $uri ]; if (!is_null($readOnlyValue)) { $calendarInfo['{http://owncloud.org/ns}read-only'] = $readOnlyValue; @@ -135,6 +136,13 @@ public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet) { 'principal' => $hasOwnerSet ? 'user1' : 'user2', 'protected' => true ]]; + if ($uri === BirthdayService::BIRTHDAY_CALENDAR_URI) { + $expectedAcl = [[ + 'privilege' => '{DAV:}read', + 'principal' => $hasOwnerSet ? 'user1' : 'user2', + 'protected' => true + ]]; + } if ($hasOwnerSet) { $expectedAcl[] = [ 'privilege' => '{DAV:}read', @@ -161,6 +169,7 @@ public function providesReadOnlyInfo() { 'read-only property not set and no owner' => [true, null, false], 'read-only property is false and no owner' => [true, false, false], 'read-only property is true and no owner' => [false, true, false], + 'birthday calendar' => [false, false, false, BirthdayService::BIRTHDAY_CALENDAR_URI] ]; } } From 830a080f0e4b67d6265ba09ab578060945f28916 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 21 Apr 2016 18:55:33 +0200 Subject: [PATCH 217/286] [stable9] Ignore certificate file if it starts with file:// --- lib/private/security/certificate.php | 7 +++++++ tests/lib/security/certificate.php | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/private/security/certificate.php b/lib/private/security/certificate.php index 54486ff51fe70..9aca278174e5b 100644 --- a/lib/private/security/certificate.php +++ b/lib/private/security/certificate.php @@ -50,6 +50,13 @@ class Certificate implements ICertificate { public function __construct($data, $name) { $this->name = $name; $gmt = new \DateTimeZone('GMT'); + + // If string starts with "file://" ignore the certificate + $query = 'file://'; + if(strtolower(substr($data, 0, strlen($query))) === $query) { + throw new \Exception('Certificate could not get parsed.'); + } + $info = openssl_x509_parse($data); if(!is_array($info)) { throw new \Exception('Certificate could not get parsed.'); diff --git a/tests/lib/security/certificate.php b/tests/lib/security/certificate.php index 81d159ebd528e..82e91c717330e 100644 --- a/tests/lib/security/certificate.php +++ b/tests/lib/security/certificate.php @@ -50,6 +50,14 @@ public function testBogusData() { $certificate->getIssueDate(); } + /** + * @expectedException \Exception + * @expectedExceptionMessage Certificate could not get parsed. + */ + function testCertificateStartingWithFileReference() { + new Certificate('file://'.__DIR__ . '/../../data/certificates/goodCertificate.crt', 'bar'); + } + public function testGetName() { $this->assertSame('GoodCertificate', $this->goodCertificate->getName()); $this->assertSame('BadCertificate', $this->invalidCertificate->getName()); From 9dc1c6c41f4f59ba23d2823973b9ea33178f3bf3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Apr 2016 10:33:44 +0200 Subject: [PATCH 218/286] Make sure that CLI cron doesn't run for ever, but makes use of the next spawn --- cron.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cron.php b/cron.php index 73f233e135006..6825c10fb011d 100644 --- a/cron.php +++ b/cron.php @@ -131,6 +131,10 @@ // Work $jobList = \OC::$server->getJobList(); + // We only ask for jobs for 14 minutes, because after 15 minutes the next + // system cron task should spawn. + $endTime = time() + 14 * 60; + $executedJobs = []; while ($job = $jobList->getNext()) { if (isset($executedJobs[$job->getId()])) { @@ -144,6 +148,10 @@ $jobList->setLastJob($job); $executedJobs[$job->getId()] = true; unset($job); + + if (time() > $endTime) { + break; + } } // unlock the file From 711641e4a9cf8a7b0699210331f9960e387bef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 21 Apr 2016 12:34:20 +0200 Subject: [PATCH 219/286] Personal calendar should be generated even if the birthday calendar already exists - fixes #24082 --- apps/dav/lib/hookmanager.php | 33 ++--- apps/dav/tests/unit/dav/HookManagerTest.php | 152 ++++++++++++++++++++ 2 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 apps/dav/tests/unit/dav/HookManagerTest.php diff --git a/apps/dav/lib/hookmanager.php b/apps/dav/lib/hookmanager.php index c3d68a3ee2a4c..0f5a22edc2557 100644 --- a/apps/dav/lib/hookmanager.php +++ b/apps/dav/lib/hookmanager.php @@ -20,6 +20,7 @@ */ namespace OCA\DAV; +use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\SyncService; @@ -100,24 +101,24 @@ public function changeUser($params) { public function postLogin($params) { $user = $this->userManager->get($params['uid']); - - $principal = 'principals/users/' . $user->getUID(); - $calendars = $this->calDav->getCalendarsForUser($principal); - if (empty($calendars)) { - try { - $this->calDav->createCalendar($principal, 'default', []); - } catch (\Exception $ex) { - \OC::$server->getLogger()->logException($ex); + if (!is_null($user)) { + $principal = 'principals/users/' . $user->getUID(); + $calendars = $this->calDav->getCalendarsForUser($principal); + if (empty($calendars) || (count($calendars) === 1 && $calendars[0]['uri'] === BirthdayService::BIRTHDAY_CALENDAR_URI)) { + try { + $this->calDav->createCalendar($principal, 'default', []); + } catch (\Exception $ex) { + \OC::$server->getLogger()->logException($ex); + } } - } - $books = $this->cardDav->getAddressBooksForUser($principal); - if (empty($books)) { - try { - $this->cardDav->createAddressBook($principal, 'default', []); - } catch (\Exception $ex) { - \OC::$server->getLogger()->logException($ex); + $books = $this->cardDav->getAddressBooksForUser($principal); + if (empty($books)) { + try { + $this->cardDav->createAddressBook($principal, 'default', []); + } catch (\Exception $ex) { + \OC::$server->getLogger()->logException($ex); + } } } - } } diff --git a/apps/dav/tests/unit/dav/HookManagerTest.php b/apps/dav/tests/unit/dav/HookManagerTest.php new file mode 100644 index 0000000000000..7893ed654521a --- /dev/null +++ b/apps/dav/tests/unit/dav/HookManagerTest.php @@ -0,0 +1,152 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\DAV\Tests\Unit\DAV; + +use OCA\DAV\CalDAV\BirthdayService; +use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CardDAV\CardDavBackend; +use OCA\DAV\CardDAV\SyncService; +use OCA\DAV\HookManager; +use OCP\IUserManager; +use Test\TestCase; + +class HookManagerTest extends TestCase { + public function test() { + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->once())->method('getUID')->willReturn('newUser'); + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $userManager */ + $userManager = $this->getMockBuilder('\OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); + $userManager->expects($this->once())->method('get')->willReturn($user); + + /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */ + $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') + ->disableOriginalConstructor() + ->getMock(); + + /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cal */ + $cal = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $cal->expects($this->once())->method('getCalendarsForUser')->willReturn([]); + $cal->expects($this->once())->method('createCalendar')->with( + 'principals/users/newUser', + 'default', []); + + /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $card */ + $card = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $card->expects($this->once())->method('getAddressBooksForUser')->willReturn([]); + $card->expects($this->once())->method('createAddressBook')->with( + 'principals/users/newUser', + 'default', []); + + $hm = new HookManager($userManager, $syncService, $cal, $card); + $hm->postLogin(['uid' => 'newUser']); + } + + public function testWithExisting() { + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->once())->method('getUID')->willReturn('newUser'); + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $userManager */ + $userManager = $this->getMockBuilder('\OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); + $userManager->expects($this->once())->method('get')->willReturn($user); + + /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */ + $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') + ->disableOriginalConstructor() + ->getMock(); + + /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cal */ + $cal = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $cal->expects($this->once())->method('getCalendarsForUser')->willReturn([ + ['uri' => 'my-events'] + ]); + $cal->expects($this->never())->method('createCalendar'); + + /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $card */ + $card = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $card->expects($this->once())->method('getAddressBooksForUser')->willReturn([ + ['uri' => 'my-contacts'] + ]); + $card->expects($this->never())->method('createAddressBook'); + + $hm = new HookManager($userManager, $syncService, $cal, $card); + $hm->postLogin(['uid' => 'newUser']); + } + + public function testWithBirthdayCalendar() { + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->once())->method('getUID')->willReturn('newUser'); + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $userManager */ + $userManager = $this->getMockBuilder('\OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); + $userManager->expects($this->once())->method('get')->willReturn($user); + + /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */ + $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') + ->disableOriginalConstructor() + ->getMock(); + + /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cal */ + $cal = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $cal->expects($this->once())->method('getCalendarsForUser')->willReturn([ + ['uri' => BirthdayService::BIRTHDAY_CALENDAR_URI] + ]); + $cal->expects($this->once())->method('createCalendar')->with( + 'principals/users/newUser', + 'default', []); + + /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $card */ + $card = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $card->expects($this->once())->method('getAddressBooksForUser')->willReturn([]); + $card->expects($this->once())->method('createAddressBook')->with( + 'principals/users/newUser', + 'default', []); + + $hm = new HookManager($userManager, $syncService, $cal, $card); + $hm->postLogin(['uid' => 'newUser']); + } +} From 27d12f7a993f335812cf29f19a12e2f86f553afc Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 22 Apr 2016 11:10:51 +0200 Subject: [PATCH 220/286] Throw NoUserException when attempting to init mount point for null user In some scenarios initMountPoints is called with an empty user, and also there is no user in the session. In such cases, it is unsafe to let the code move on with an empty user. --- lib/private/files/filesystem.php | 3 +++ tests/lib/files/filesystem.php | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index a9138b0d2d7e0..ec9b537a35884 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -372,6 +372,9 @@ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } + if ($user === null || $user === false || $user === '') { + throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session'); + } if (isset(self::$usersSetup[$user])) { return; } diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index db1f22f894ad9..8245af0ace1cb 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -319,6 +319,28 @@ public function testLocalMountWhenUserDoesNotExist() { \OC\Files\Filesystem::initMountPoints($userId); } + /** + * @expectedException \OC\User\NoUserException + */ + public function testNullUserThrows() { + \OC\Files\Filesystem::initMountPoints(null); + } + + public function testNullUserThrowsTwice() { + $thrown = 0; + try { + \OC\Files\Filesystem::initMountPoints(null); + } catch (NoUserException $e) { + $thrown++; + } + try { + \OC\Files\Filesystem::initMountPoints(null); + } catch (NoUserException $e) { + $thrown++; + } + $this->assertEquals(2, $thrown); + } + /** * Tests that the home storage is used for the user's mount point */ From 3e1dc647376c998f5e7752e8e7b39582144e1398 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 22 Apr 2016 10:49:55 +0200 Subject: [PATCH 221/286] Change the sort order of background jobs to be DESC instead of ASC In theory, if your instance ever creates more jobs then your system cron can handle, the default background jobs get never executed anymore. Because everytime when the joblist returns the next job it looks for the next ID, however there is always a new next ID, so it will never wrap back to execute the low IDs. But when we change the sort order to be DESC, we make sure that these low IDs are always executed, before the system jumps back up to execute the new IDs. --- lib/private/backgroundjob/joblist.php | 6 +++--- tests/lib/backgroundjob/joblist.php | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index b8230fca4de3e..2429b83044637 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -172,8 +172,8 @@ public function getNext() { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('jobs') - ->where($query->expr()->gt('id', $query->createNamedParameter($lastId, IQueryBuilder::PARAM_INT))) - ->orderBy('id', 'ASC') + ->where($query->expr()->lt('id', $query->createNamedParameter($lastId, IQueryBuilder::PARAM_INT))) + ->orderBy('id', 'DESC') ->setMaxResults(1); $result = $query->execute(); $row = $result->fetch(); @@ -187,7 +187,7 @@ public function getNext() { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('jobs') - ->orderBy('id', 'ASC') + ->orderBy('id', 'DESC') ->setMaxResults(1); $result = $query->execute(); $row = $result->fetch(); diff --git a/tests/lib/backgroundjob/joblist.php b/tests/lib/backgroundjob/joblist.php index c0796d8253aee..fcc3c44081858 100644 --- a/tests/lib/backgroundjob/joblist.php +++ b/tests/lib/backgroundjob/joblist.php @@ -9,6 +9,7 @@ namespace Test\BackgroundJob; use OCP\BackgroundJob\IJob; +use OCP\IDBConnection; use Test\TestCase; /** @@ -28,10 +29,17 @@ protected function setUp() { parent::setUp(); $connection = \OC::$server->getDatabaseConnection(); + $this->clearJobsList($connection); $this->config = $this->getMock('\OCP\IConfig'); $this->instance = new \OC\BackgroundJob\JobList($connection, $this->config); } + protected function clearJobsList(IDBConnection $connection) { + $query = $connection->getQueryBuilder(); + $query->delete('jobs'); + $query->execute(); + } + protected function getAllSorted() { $jobs = $this->instance->getAll(); @@ -149,11 +157,11 @@ public function testGetNext() { $this->config->expects($this->once()) ->method('getAppValue') ->with('backgroundjob', 'lastjob', 0) - ->will($this->returnValue($savedJob1->getId())); + ->will($this->returnValue($savedJob2->getId())); $nextJob = $this->instance->getNext(); - $this->assertEquals($savedJob2, $nextJob); + $this->assertEquals($savedJob1, $nextJob); $this->instance->remove($job, 1); $this->instance->remove($job, 2); @@ -166,16 +174,17 @@ public function testGetNextWrapAround() { $jobs = $this->getAllSorted(); + $savedJob1 = $jobs[count($jobs) - 2]; $savedJob2 = $jobs[count($jobs) - 1]; $this->config->expects($this->once()) ->method('getAppValue') ->with('backgroundjob', 'lastjob', 0) - ->will($this->returnValue($savedJob2->getId())); + ->will($this->returnValue($savedJob1->getId())); $nextJob = $this->instance->getNext(); - $this->assertEquals($jobs[0], $nextJob); + $this->assertEquals($savedJob2, $nextJob); $this->instance->remove($job, 1); $this->instance->remove($job, 2); From 8ebde1e74d582a98b691c796a2ec6ecbaa555e98 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 22 Apr 2016 21:43:41 +0200 Subject: [PATCH 222/286] on clone Connection, do not take over the existing LDAP resource For one, it solves potential conflicts when using the resource. For the other, one on the login check (the only place where a clone happens currently) we do not need to rebind after confirming the user's login was successful. --- apps/user_ldap/lib/access.php | 4 +--- apps/user_ldap/lib/connection.php | 10 ++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 135eca1e625e9..ad273845509ad 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -1295,9 +1295,7 @@ public function areCredentialsValid($name, $password) { if(!$testConnection->setConfiguration($credentials)) { return false; } - $result=$testConnection->bind(); - $this->ldap->unbind($this->connection->getConnectionResource()); - return $result; + return $testConnection->bind(); } /** diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 74a8b55066d00..24d6809129c1b 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -47,9 +47,6 @@ class Connection extends LDAPUtility { private $configPrefix; private $configID; private $configured = false; - - //whether connection should be kept on __destruct - private $dontDestruct = false; private $hasPagedResultSupport = true; /** @@ -91,8 +88,7 @@ public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = } public function __destruct() { - if(!$this->dontDestruct && - $this->ldap->isResource($this->ldapConnectionRes)) { + if($this->ldap->isResource($this->ldapConnectionRes)) { @$this->ldap->unbind($this->ldapConnectionRes); }; } @@ -101,11 +97,9 @@ public function __destruct() { * defines behaviour when the instance is cloned */ public function __clone() { - //a cloned instance inherits the connection resource. It may use it, - //but it may not disconnect it - $this->dontDestruct = true; $this->configuration = new Configuration($this->configPrefix, !is_null($this->configID)); + $this->ldapConnectionRes = null; } /** From 5b126cde486290b37ed47608a94ce60e79424117 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 18 Apr 2016 10:32:15 +0200 Subject: [PATCH 223/286] Fix LDAP race conditions * getFromCache is wrapped in isCached * inbetween the two calls the cache entry hits it's TTL * getFromCache returns null * this fix only checkes if the returned value is null and return only non-null values --- apps/user_ldap/group_ldap.php | 32 +++++++++++++++-------------- apps/user_ldap/lib/access.php | 10 +++++---- apps/user_ldap/lib/connection.php | 19 ----------------- apps/user_ldap/lib/user/user.php | 5 +++-- apps/user_ldap/tests/group_ldap.php | 4 ---- apps/user_ldap/user_ldap.php | 10 +++++---- 6 files changed, 32 insertions(+), 48 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index c50ab0a8e1fbb..eba39ca50f778 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -72,8 +72,9 @@ public function inGroup($uid, $gid) { return false; } $cacheKey = 'inGroup'.$uid.':'.$gid; - if($this->access->connection->isCached($cacheKey)) { - return $this->access->connection->getFromCache($cacheKey); + $inGroup = $this->access->connection->getFromCache($cacheKey); + if(!is_null($inGroup)) { + return (bool)$inGroup; } $userDN = $this->access->username2dn($uid); @@ -84,8 +85,8 @@ public function inGroup($uid, $gid) { } $cacheKeyMembers = 'inGroup-members:'.$gid; - if($this->access->connection->isCached($cacheKeyMembers)) { - $members = $this->access->connection->getFromCache($cacheKeyMembers); + $members = $this->access->connection->getFromCache($cacheKeyMembers); + if(!is_null($members)) { $this->cachedGroupMembers[$gid] = $members; $isInGroup = in_array($userDN, $members); $this->access->connection->writeToCache($cacheKey, $isInGroup); @@ -204,8 +205,9 @@ private function _groupMembers($dnGroup, &$seen = null) { } // used extensively in cron job, caching makes sense for nested groups $cacheKey = '_groupMembers'.$dnGroup; - if($this->access->connection->isCached($cacheKey)) { - return $this->access->connection->getFromCache($cacheKey); + $groupMembers = $this->access->connection->getFromCache($cacheKey); + if(!is_null($groupMembers)) { + return $groupMembers; } $seen[$dnGroup] = 1; $members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr, @@ -267,11 +269,9 @@ private function _getGroupDNsFromMemberOf($DN, &$seen = null) { */ public function primaryGroupID2Name($gid, $dn) { $cacheKey = 'primaryGroupIDtoName'; - if($this->access->connection->isCached($cacheKey)) { - $groupNames = $this->access->connection->getFromCache($cacheKey); - if(isset($groupNames[$gid])) { - return $groupNames[$gid]; - } + $groupNames = $this->access->connection->getFromCache($cacheKey); + if(!is_null($groupNames) && isset($groupNames[$gid])) { + return $groupNames[$gid]; } $domainObjectSid = $this->access->getSID($dn); @@ -440,8 +440,9 @@ public function getUserGroups($uid) { return array(); } $cacheKey = 'getUserGroups'.$uid; - if($this->access->connection->isCached($cacheKey)) { - return $this->access->connection->getFromCache($cacheKey); + $userGroups = $this->access->connection->getFromCache($cacheKey); + if(!is_null($userGroups)) { + return $userGroups; } $userDN = $this->access->username2dn($uid); if(!$userDN) { @@ -861,8 +862,9 @@ public function groupMatchesFilter($group) { * @return bool */ public function groupExists($gid) { - if($this->access->connection->isCached('groupExists'.$gid)) { - return $this->access->connection->getFromCache('groupExists'.$gid); + $groupExists = $this->access->connection->getFromCache('groupExists'.$gid); + if(!is_null($groupExists)) { + return (bool)$groupExists; } //getting dn, if false the group does not exist. If dn, it may be mapped diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 135eca1e625e9..569d2dbcbe97e 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -364,8 +364,9 @@ public function groupsMatchFilter($groupDNs) { $validGroupDNs = []; foreach($groupDNs as $dn) { $cacheKey = 'groupsMatchFilter-'.$dn; - if($this->connection->isCached($cacheKey)) { - if($this->connection->getFromCache($cacheKey)) { + $groupMatchFilter = $this->connection->getFromCache($cacheKey); + if(!is_null($groupMatchFilter)) { + if($groupMatchFilter) { $validGroupDNs[] = $dn; } continue; @@ -1505,8 +1506,9 @@ public function formatGuid2ForFilterUser($guid) { public function getSID($dn) { $domainDN = $this->getDomainDNFromDN($dn); $cacheKey = 'getSID-'.$domainDN; - if($this->connection->isCached($cacheKey)) { - return $this->connection->getFromCache($cacheKey); + $sid = $this->connection->getFromCache($cacheKey); + if(!is_null($sid)) { + return $sid; } $objectSid = $this->readAttribute($domainDN, 'objectsid'); diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 74a8b55066d00..91a02e3d92e3f 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -210,30 +210,11 @@ public function getFromCache($key) { if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) { return null; } - if(!$this->isCached($key)) { - return null; - - } $key = $this->getCacheKey($key); return json_decode(base64_decode($this->cache->get($key)), true); } - /** - * @param string $key - * @return bool - */ - public function isCached($key) { - if(!$this->configured) { - $this->readConfiguration(); - } - if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) { - return false; - } - $key = $this->getCacheKey($key); - return $this->cache->hasKey($key); - } - /** * @param string $key * @param mixed $value diff --git a/apps/user_ldap/lib/user/user.php b/apps/user_ldap/lib/user/user.php index 9bf505c5c2254..c7a1fcdefff68 100644 --- a/apps/user_ldap/lib/user/user.php +++ b/apps/user_ldap/lib/user/user.php @@ -297,8 +297,9 @@ public function getHomePath($valueFromLDAP = null) { public function getMemberOfGroups() { $cacheKey = 'getMemberOf'.$this->getUsername(); - if($this->connection->isCached($cacheKey)) { - return $this->connection->getFromCache($cacheKey); + $memberOfGroups = $this->connection->getFromCache($cacheKey); + if(!is_null($memberOfGroups)) { + return $memberOfGroups; } $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf'); $this->connection->writeToCache($cacheKey, $groupDNs); diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php index 667a1c3acb2b7..51bb1d84732a6 100644 --- a/apps/user_ldap/tests/group_ldap.php +++ b/apps/user_ldap/tests/group_ldap.php @@ -294,10 +294,6 @@ public function testInGroupHitsUidGidCache() { $uid = 'someUser'; $gid = 'someGroup'; $cacheKey = 'inGroup'.$uid.':'.$gid; - $access->connection->expects($this->once()) - ->method('isCached') - ->with($cacheKey) - ->will($this->returnValue(true)); $access->connection->expects($this->once()) ->method('getFromCache') diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 865b7e61892e1..a11e5ec592bcc 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -249,8 +249,9 @@ public function userExistsOnLDAP($user) { * @throws \Exception when connection could not be established */ public function userExists($uid) { - if($this->access->connection->isCached('userExists'.$uid)) { - return $this->access->connection->getFromCache('userExists'.$uid); + $userExists = $this->access->connection->getFromCache('userExists'.$uid); + if(!is_null($userExists)) { + return (bool)$userExists; } //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking. $user = $this->access->userManager->get($uid); @@ -320,8 +321,9 @@ public function getHome($uid) { } $cacheKey = 'getHome'.$uid; - if($this->access->connection->isCached($cacheKey)) { - return $this->access->connection->getFromCache($cacheKey); + $path = $this->access->connection->getFromCache($cacheKey); + if(!is_null($path)) { + return $path; } $user = $this->access->userManager->get($uid); From dd415b62f5c99c501358769e16ad67f1ce6ef154 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Apr 2016 13:22:54 +0200 Subject: [PATCH 224/286] Add missing use statement --- apps/files_versions/lib/storage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php index a213ea75238d1..3c23f2f730a0e 100644 --- a/apps/files_versions/lib/storage.php +++ b/apps/files_versions/lib/storage.php @@ -45,6 +45,7 @@ use OC\Files\View; use OCA\Files_Versions\AppInfo\Application; use OCA\Files_Versions\Command\Expire; +use OCP\Files\NotFoundException; use OCP\Lock\ILockingProvider; use OCP\User; From 1aa8765177d96a52452d01b8a020f920996cd6e9 Mon Sep 17 00:00:00 2001 From: Daniel Jagszent Date: Fri, 22 Apr 2016 15:59:13 +0200 Subject: [PATCH 225/286] [9.0] Call private cache methods only for `OC\Files\Cache\Cache` --- lib/private/files/cache/scanner.php | 2 +- lib/private/files/cache/updater.php | 16 ++++++++++++---- lib/private/files/cache/watcher.php | 4 +++- lib/private/files/cache/wrapper/cachejail.php | 12 ++++++++++-- lib/private/files/cache/wrapper/cachewrapper.php | 10 ++++++++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 8730707f1c2f8..0280138343197 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -478,7 +478,7 @@ private function runBackgroundScanJob(callable $callback, $path) { try { $callback(); \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); - if ($this->cacheActive) { + if ($this->cacheActive && $this->cache instanceof Cache) { $this->cache->correctFolderSize($path); } } catch (\OCP\Files\StorageInvalidException $e) { diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 3f80f2b6167ad..9e4214ad72ae3 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -126,7 +126,9 @@ public function update($path, $time = null) { } else { // scanner didn't provide size info, fallback to full size calculation $sizeDifference = 0; - $this->cache->correctFolderSize($path, $data); + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($path, $data); + } } $this->correctParentStorageMtime($path); $this->propagator->propagateChange($path, $time, $sizeDifference); @@ -148,7 +150,9 @@ public function remove($path) { } $this->cache->remove($path); - $this->cache->correctFolderSize($parent); + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($parent); + } $this->correctParentStorageMtime($path); $this->propagator->propagateChange($path, time()); } @@ -190,8 +194,12 @@ public function renameFromStorage(IStorage $sourceStorage, $source, $target) { $this->cache->update($fileId, ['mimetype' => $mimeType]); } - $sourceCache->correctFolderSize($source); - $this->cache->correctFolderSize($target); + if ($sourceCache instanceof Cache) { + $sourceCache->correctFolderSize($source); + } + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($target); + } if ($sourceUpdater instanceof Updater) { $sourceUpdater->correctParentStorageMtime($source); } diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php index a00e875a2d400..0cf6caf0c285c 100644 --- a/lib/private/files/cache/watcher.php +++ b/lib/private/files/cache/watcher.php @@ -106,7 +106,9 @@ public function update($path, $cachedData) { if ($cachedData['mimetype'] === 'httpd/unix-directory') { $this->cleanFolder($path); } - $this->cache->correctFolderSize($path); + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($path); + } } /** diff --git a/lib/private/files/cache/wrapper/cachejail.php b/lib/private/files/cache/wrapper/cachejail.php index 868e63cdf81b5..65275bcb79879 100644 --- a/lib/private/files/cache/wrapper/cachejail.php +++ b/lib/private/files/cache/wrapper/cachejail.php @@ -23,6 +23,7 @@ */ namespace OC\Files\Cache\Wrapper; +use OC\Files\Cache\Cache; /** * Jail to a subdirectory of the wrapped cache @@ -233,7 +234,9 @@ public function searchByTag($tag, $userId) { * @param array $data (optional) meta data of the folder */ public function correctFolderSize($path, $data = null) { - $this->cache->correctFolderSize($this->getSourcePath($path), $data); + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($this->getSourcePath($path), $data); + } } /** @@ -244,7 +247,12 @@ public function correctFolderSize($path, $data = null) { * @return int */ public function calculateFolderSize($path, $entry = null) { - return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry); + if ($this->cache instanceof Cache) { + return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry); + } else { + return 0; + } + } /** diff --git a/lib/private/files/cache/wrapper/cachewrapper.php b/lib/private/files/cache/wrapper/cachewrapper.php index 4080883419ea2..3f2d382145a9b 100644 --- a/lib/private/files/cache/wrapper/cachewrapper.php +++ b/lib/private/files/cache/wrapper/cachewrapper.php @@ -240,7 +240,9 @@ public function searchByTag($tag, $userId) { * @param array $data (optional) meta data of the folder */ public function correctFolderSize($path, $data = null) { - $this->cache->correctFolderSize($path, $data); + if ($this->cache instanceof Cache) { + $this->cache->correctFolderSize($path, $data); + } } /** @@ -251,7 +253,11 @@ public function correctFolderSize($path, $data = null) { * @return int */ public function calculateFolderSize($path, $entry = null) { - return $this->cache->calculateFolderSize($path, $entry); + if ($this->cache instanceof Cache) { + return $this->cache->calculateFolderSize($path, $entry); + } else { + return 0; + } } /** From 51f5edd7498333f1f6356fbfd90578db4875cf83 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 22 Apr 2016 16:07:08 +0200 Subject: [PATCH 226/286] add locks in the scanner to prevent multiple scanners running on the same files --- lib/private/files/cache/scanner.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 8730707f1c2f8..feefe29d27692 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -296,6 +296,7 @@ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $loc } if ($lock) { if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $this->storage->acquireLock('scanner::' . $path, ILockingProvider::LOCK_EXCLUSIVE, $this->lockingProvider); $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider); } } @@ -307,6 +308,7 @@ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $loc if ($lock) { if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider); + $this->storage->releaseLock('scanner::' . $path, ILockingProvider::LOCK_EXCLUSIVE, $this->lockingProvider); } } return $data; From d436326e19b8df1594f781e74e8c50151f003ea5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 25 Apr 2016 13:50:19 +0200 Subject: [PATCH 227/286] don't get the config for the same mount multiple times --- apps/files_external/service/dbconfigservice.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/files_external/service/dbconfigservice.php b/apps/files_external/service/dbconfigservice.php index a37c541f045ea..9f7061eb938d8 100644 --- a/apps/files_external/service/dbconfigservice.php +++ b/apps/files_external/service/dbconfigservice.php @@ -322,10 +322,19 @@ public function removeApplicable($mountId, $type, $value) { private function getMountsFromQuery(IQueryBuilder $query) { $result = $query->execute(); $mounts = $result->fetchAll(); + $uniqueMounts = []; + foreach ($mounts as $mount) { + $id = $mount['mount_id']; + if (!isset($uniqueMounts[$id])) { + $uniqueMounts[$id] = $mount; + } + } + $uniqueMounts = array_values($uniqueMounts); $mountIds = array_map(function ($mount) { return $mount['mount_id']; - }, $mounts); + }, $uniqueMounts); + $mountIds = array_values(array_unique($mountIds)); $applicable = $this->getApplicableForMounts($mountIds); $config = $this->getConfigForMounts($mountIds); @@ -338,7 +347,7 @@ private function getMountsFromQuery(IQueryBuilder $query) { $mount['config'] = $config; $mount['options'] = $options; return $mount; - }, $mounts, $applicable, $config, $options); + }, $uniqueMounts, $applicable, $config, $options); } /** From b375086c473f7117d6ee8b61cf0c6e24350b113a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 25 Apr 2016 14:28:01 +0200 Subject: [PATCH 228/286] add test --- .../tests/service/dbconfigservicetest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/files_external/tests/service/dbconfigservicetest.php b/apps/files_external/tests/service/dbconfigservicetest.php index c6d1add36b6db..b088a7078d1de 100644 --- a/apps/files_external/tests/service/dbconfigservicetest.php +++ b/apps/files_external/tests/service/dbconfigservicetest.php @@ -271,4 +271,15 @@ public function testSetAuthBackend() { $mount = $this->dbConfig->getMountById($id2); $this->assertEquals('bar', $mount['auth_backend']); } + + public function testGetMountsForDuplicateByGroup() { + $id1 = $this->addMount('/test', 'foo', 'bar', 100, DBConfigService::MOUNT_TYPE_ADMIN); + + $this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_GROUP, 'group1'); + $this->dbConfig->addApplicable($id1, DBConfigService::APPLICABLE_TYPE_GROUP, 'group2'); + + $mounts = $this->dbConfig->getAdminMountsForMultiple(DBConfigService::APPLICABLE_TYPE_GROUP, ['group1', 'group2']); + $this->assertCount(1, $mounts); + $this->assertEquals($id1, $mounts[0]['mount_id']); + } } From 1397d9a93c0b86f412688825871cbbe8b841f9b5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 25 Apr 2016 17:23:48 +0200 Subject: [PATCH 229/286] triger the propagator from the command line scanner --- lib/private/files/utils/scanner.php | 16 ++++++++++++++++ tests/lib/files/utils/scanner.php | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php index 0652658389976..b013cbecabc63 100644 --- a/lib/private/files/utils/scanner.php +++ b/lib/private/files/utils/scanner.php @@ -29,6 +29,7 @@ use OC\ForbiddenException; use OC\Hooks\PublicEmitter; use OC\Lock\DBLockingProvider; +use OCP\Files\Storage\IStorage; use OCP\Files\StorageNotAvailableException; use OCP\ILogger; @@ -153,6 +154,17 @@ public function scan($dir = '') { $scanner->setUseTransactions(false); $this->attachListener($mount); $isDbLocking = \OC::$server->getLockingProvider() instanceof DBLockingProvider; + + $scanner->listen('\OC\Files\Cache\Scanner', 'removeFromCache', function ($path) use ($storage) { + $this->triggerPropagator($storage, $path); + }); + $scanner->listen('\OC\Files\Cache\Scanner', 'updateCache', function ($path) use ($storage) { + $this->triggerPropagator($storage, $path); + }); + $scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', function ($path) use ($storage) { + $this->triggerPropagator($storage, $path); + }); + if (!$isDbLocking) { $this->db->beginTransaction(); } @@ -168,5 +180,9 @@ public function scan($dir = '') { } } } + + private function triggerPropagator(IStorage $storage, $internalPath) { + $storage->getPropagator()->propagateChange($internalPath, time()); + } } diff --git a/tests/lib/files/utils/scanner.php b/tests/lib/files/utils/scanner.php index 7779e2778cb0b..1220c57e96285 100644 --- a/tests/lib/files/utils/scanner.php +++ b/tests/lib/files/utils/scanner.php @@ -163,4 +163,28 @@ public function testInvalidPathScanning($invalidPath) { $scanner = new TestScanner('', \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); $scanner->scan($invalidPath); } + + public function testPropagateEtag() { + $storage = new Temporary(array()); + $mount = new MountPoint($storage, ''); + Filesystem::getMountManager()->addMount($mount); + $cache = $storage->getCache(); + + $storage->mkdir('folder'); + $storage->file_put_contents('folder/bar.txt', 'qwerty'); + $storage->touch('folder/bar.txt', time() - 200); + + $scanner = new TestScanner('', \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); + $scanner->addMount($mount); + + $scanner->scan(''); + $this->assertTrue($cache->inCache('folder/bar.txt')); + $oldRoot = $cache->get(''); + + $storage->file_put_contents('folder/bar.txt', 'qwerty'); + $scanner->scan(''); + $newRoot = $cache->get(''); + + $this->assertNotEquals($oldRoot->getEtag(), $newRoot->getEtag()); + } } From e542bfd1d7044e6eeec9d0cf4c815a1e85614458 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 25 Apr 2016 18:36:50 +0200 Subject: [PATCH 230/286] check whether index is set before using it --- lib/private/installer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/installer.php b/lib/private/installer.php index fca9fce23efd4..f1d4d551786c5 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -269,7 +269,8 @@ public static function downloadApp($data = array()) { //download the file if necessary if($data['source']=='http') { $pathInfo = pathinfo($data['href']); - $path = \OC::$server->getTempManager()->getTemporaryFile('.' . $pathInfo['extension']); + $extension = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : ''; + $path = \OC::$server->getTempManager()->getTemporaryFile($extension); if(!isset($data['href'])) { throw new \Exception($l->t("No href specified when installing app from http")); } From a70d6f6a62863711ed33707736bdf40b218b8f3b Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 22 Mar 2016 20:28:57 +0100 Subject: [PATCH 231/286] Disable pastezone for jquery.fileupload jquery.fileupload offers the [`pastezone`](https://github.com/blueimp/jQuery-File-Upload/wiki/Options#pastezone) functionality. This functionality is enabled by default and if somebody copy-pastes something into Chrome it will automatically trigger an upload of the content to any configured jquery.fileupload element embedded in the JS. This implementation triggers some problems: 1. The pastezone is defined globally by default (:see_no_evil:). So if there are multiple fileupload's on a page (such as in the personal settings) then stuff is going to be uploaded to all embedded uploads. 2. Our server code is not able to parse the data. For example for uploads in the files app we expect a file name which is not specified => Just an error is thrown. You can reproduce this by taking a file into your clipboard and in Chrome then pressing CTRL + V. 3. When copy-pasting some string from MS Office on the personal page a temporary avatar with said content is created. Considering that this is anyways was never working at all and causes bugs I've set the `pastezone` to `null`. This mens that upload via copy and paste will be disabled. Lesson learned: Third-party JS libraries can have some weird details. --- apps/files/js/file-upload.js | 1 + settings/js/certificates.js | 1 + settings/js/personal.js | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index bd80afd072cb2..fca69064cde2a 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -274,6 +274,7 @@ OC.Upload = { if ( $('#file_upload_start').exists() ) { var file_upload_param = { dropZone: $('#content'), // restrict dropZone to content div + pasteZone: null, autoUpload: false, sequentialUploads: true, //singleFileUploads is on by default, so the data.files array will always have length 1 diff --git a/settings/js/certificates.js b/settings/js/certificates.js index 9ce9f9aa8d8c9..f2a8e6b0afb3d 100644 --- a/settings/js/certificates.js +++ b/settings/js/certificates.js @@ -16,6 +16,7 @@ $(document).ready(function () { $('#sslCertificate tr > td').tipsy({gravity: 'n', live: true}); $('#rootcert_import').fileupload({ + pasteZone: null, submit: function (e, data) { data.formData = _.extend(data.formData || {}, { requesttoken: OC.requestToken diff --git a/settings/js/personal.js b/settings/js/personal.js index 3b2316d061426..bd13b7fd251a9 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -244,6 +244,7 @@ $(document).ready(function () { }); var uploadparms = { + pasteZone: null, done: function (e, data) { var response = data; if (typeof data.result === 'string') { From 590ed3eddaab33f7a05040c23b07a56c18c8dea6 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 26 Apr 2016 11:52:47 +0200 Subject: [PATCH 232/286] Also exclude __apps Workaround for https://github.com/owncloud/updater/issues/331 for 9.0.2 --- .../iterator/excludefoldersbypathfilteriterator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php index e4b9c0f1998e6..29deea6268d35 100644 --- a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php +++ b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php @@ -44,6 +44,7 @@ public function __construct(\RecursiveIterator $iterator, $root = '') { // See https://github.com/owncloud/updater/issues/318#issuecomment-212497846 rtrim($root . '/updater', '/'), rtrim($root . '/_oc_upgrade', '/'), + rtrim($root . '/__apps', '/'), ]; $customDataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', ''); if($customDataDir !== '') { From ffe561df62d34116b5b745083d793ae27449346f Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Tue, 26 Apr 2016 21:08:33 +0300 Subject: [PATCH 233/286] Remove pcntl warning for now --- console.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/console.php b/console.php index fc571b03f1efd..72f961515d7ae 100644 --- a/console.php +++ b/console.php @@ -79,10 +79,6 @@ exit(1); } - if (!function_exists('pcntl_signal') && !in_array('--no-warnings', $argv)) { - echo "The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see http://php.net/manual/en/book.pcntl.php" . PHP_EOL; - } - $application = new Application(\OC::$server->getConfig(), \OC::$server->getEventDispatcher(), \OC::$server->getRequest()); $application->loadCommands(new ArgvInput(), new ConsoleOutput()); $application->run(); From 7ee7d091f2bb1d0271507782bf193b232f9199c3 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 26 Apr 2016 13:18:18 +0200 Subject: [PATCH 234/286] Don't write empty RewriteBase ownCloud may be configured to live at the root folder without a trailing slash being specified. In this case manually set the rewrite base to `/` --- lib/private/setup.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/private/setup.php b/lib/private/setup.php index d2f3802ebad7e..196ae8a8bcee9 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -427,10 +427,18 @@ public static function updateHtaccess() { //custom 404 error page $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php"; + // ownCloud may be configured to live at the root folder without a + // trailing slash being specified. In this case manually set the + // rewrite base to `/` + $rewriteBase = $webRoot; + if($webRoot === '') { + $rewriteBase = '/'; + } + // Add rewrite base $content .= "\n"; $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; - $content .= "\n RewriteBase ".$webRoot; + $content .= "\n RewriteBase ".$rewriteBase; $content .= "\n "; $content .= "\n SetEnv front_controller_active true"; $content .= "\n "; From 06bfd58b2c05095945d3307bdf87211d1d48dbd3 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 25 Apr 2016 14:36:53 +0200 Subject: [PATCH 235/286] error out if a local storage isn't setup correctly --- lib/private/files/storage/local.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index b0918c82f987b..42b7ff0d15c2f 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -39,6 +39,9 @@ class Local extends \OC\Files\Storage\Common { protected $datadir; public function __construct($arguments) { + if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) { + throw new \InvalidArgumentException('No data directory set for local storage'); + } $this->datadir = $arguments['datadir']; if (substr($this->datadir, -1) !== '/') { $this->datadir .= '/'; From 884c8215f800e4753e71a03df26f26459f480964 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 26 Apr 2016 16:08:52 +0200 Subject: [PATCH 236/286] add tests --- tests/lib/files/storage/local.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/lib/files/storage/local.php b/tests/lib/files/storage/local.php index 2583863b554ab..4cc6c6a842c34 100644 --- a/tests/lib/files/storage/local.php +++ b/tests/lib/files/storage/local.php @@ -70,5 +70,19 @@ public function testEtagChange() { $etag2 = $this->instance->getETag('test.txt'); $this->assertNotEquals($etag1, $etag2); } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidArgumentsEmptyArray() { + new \OC\Files\Storage\Local([]); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidArgumentsNoArray() { + new \OC\Files\Storage\Local(null); + } } From 795f321a1985b682bff584f252dd6f2fd95dad65 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 26 Apr 2016 21:22:56 -0400 Subject: [PATCH 237/286] 9.0.2 RC1 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 136a9b2a10b05..2dcbc57b5edb6 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 1, 3); +$OC_Version = array(9, 0, 2, 0); // The human readable string -$OC_VersionString = '9.0.1'; +$OC_VersionString = '9.0.2 RC1'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 145810dc20aadf2fa965cc8d315b59ca0612d636 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Wed, 27 Apr 2016 15:46:24 +0200 Subject: [PATCH 238/286] Check for hash instead of file existence The previous logic did not necessarily trigger in every case. This logic is more error-resistant, the autoload_classmap.php file has a guaranteed different hash on 9.0.0, 9.0.1 and 9.0.2 Fixes https://github.com/owncloud/updater/issues/342 --- lib/private/repair/brokenupdaterrepair.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/private/repair/brokenupdaterrepair.php b/lib/private/repair/brokenupdaterrepair.php index 06dd322198f20..0e4431f6ba3b9 100644 --- a/lib/private/repair/brokenupdaterrepair.php +++ b/lib/private/repair/brokenupdaterrepair.php @@ -70,9 +70,10 @@ private function manuallyCopyThirdPartyFiles() { 'sabre/dav/lib/DAV/Version.php', ]; - // First check whether the files have been copied the first time already - // if so there is no need to run the move routine. - if(file_exists($thirdPartyDir . '/icewind/streams/src/RetryWrapper.php')) { + // Check the hash for the autoload_classmap.php file, if the hash does match + // the expected value then the third-party folder has already been copied + // properly. + if(hash_file('sha512', $thirdPartyDir . '/composer/autoload_classmap.php') === 'abe09be19b6d427283cbfa7c4156d2c342cd9368d7d0564828a00ae02c435b642e7092cef444f94635f370dbe507eb6b2aa05109b32d8fb5d8a65c3a5a1c658f') { $this->emit('\OC\Repair', 'info', ['Third-party files seem already to have been copied. No repair necessary.']); return false; } From a834531aef418688538adb809a796cf830c5385b Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Thu, 28 Apr 2016 12:23:17 +0200 Subject: [PATCH 239/286] Make ownCloud work again in php 7.0.6 See https://bugs.php.net/bug.php?id=72117 Basically a bugfix in php caused this issue. So isset is not called more often. We have to catch this. --- lib/private/appframework/http/request.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index c415e606dca8a..bdd40ef1573a6 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -264,6 +264,9 @@ public function __get($name) { * @return bool */ public function __isset($name) { + if (in_array($name, $this->allowedKeys, true)) { + return true; + } return isset($this->items['parameters'][$name]); } From fb82321090779bcfb1043f32f755765e702ddf02 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Mon, 2 May 2016 04:14:16 -0400 Subject: [PATCH 240/286] 9.0.2 RC2 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 2dcbc57b5edb6..849173f8796d7 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 2, 0); +$OC_Version = array(9, 0, 2, 1); // The human readable string -$OC_VersionString = '9.0.2 RC1'; +$OC_VersionString = '9.0.2 RC2'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 13ea66e791ccbcbb5e9910f4a6e5dba4d28476bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 28 Apr 2016 12:03:19 +0200 Subject: [PATCH 241/286] Don't loop over the backends, we already know where the user should be --- lib/private/user/manager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 7967f87702479..8758a4667f56f 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -335,11 +335,11 @@ public function callForAllUsers(\Closure $callback, $search = '') { $offset = 0; do { $users = $backend->getUsers($search, $limit, $offset); - foreach ($users as $user) { - $user = $this->get($user); - if (is_null($user)) { + foreach ($users as $uid) { + if (!$backend->userExists($uid)) { continue; } + $user = $this->getUserObject($uid, $backend); $return = $callback($user); if ($return === false) { break; From bbcef57d2a7f6e66b47eb2f531663ecc946de8a9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 28 Apr 2016 12:26:48 +0200 Subject: [PATCH 242/286] When we iterate over all users that might be too much memory --- lib/private/user/manager.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php index 8758a4667f56f..4371be134aa26 100644 --- a/lib/private/user/manager.php +++ b/lib/private/user/manager.php @@ -147,14 +147,19 @@ public function get($uid) { * * @param string $uid * @param \OCP\UserInterface $backend + * @param bool $cacheUser If false the newly created user object will not be cached * @return \OC\User\User */ - protected function getUserObject($uid, $backend) { + protected function getUserObject($uid, $backend, $cacheUser = true) { if (isset($this->cachedUsers[$uid])) { return $this->cachedUsers[$uid]; } - $this->cachedUsers[$uid] = new User($uid, $backend, $this, $this->config); - return $this->cachedUsers[$uid]; + + $user = new User($uid, $backend, $this, $this->config); + if ($cacheUser) { + $this->cachedUsers[$uid] = $user; + } + return $user; } /** @@ -339,7 +344,7 @@ public function callForAllUsers(\Closure $callback, $search = '') { if (!$backend->userExists($uid)) { continue; } - $user = $this->getUserObject($uid, $backend); + $user = $this->getUserObject($uid, $backend, false); $return = $callback($user); if ($return === false) { break; From e13d02de2d5d260720b63f3f9ffe87b5aa0dd6c4 Mon Sep 17 00:00:00 2001 From: C Montero-Luque Date: Tue, 3 May 2016 04:37:42 -0400 Subject: [PATCH 243/286] 9.0.2 --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 849173f8796d7..c90e84a79c769 100644 --- a/version.php +++ b/version.php @@ -26,10 +26,10 @@ // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(9, 0, 2, 1); +$OC_Version = array(9, 0, 2, 2); // The human readable string -$OC_VersionString = '9.0.2 RC2'; +$OC_VersionString = '9.0.2'; $OC_VersionCanBeUpgradedFrom = array(8, 2); From 1c7ec3a7f58f793d58b8f19556d2051e4d5243f4 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 3 May 2016 09:29:22 +0200 Subject: [PATCH 244/286] Use a CappedCache in the user database backend When running with a user database backend on large installations the cache can grow to significant sizes. This can be especially problematic when running big cron/repair jobs. --- lib/private/user/database.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/private/user/database.php b/lib/private/user/database.php index 22a05090b96ea..fd273055ae18c 100644 --- a/lib/private/user/database.php +++ b/lib/private/user/database.php @@ -48,11 +48,21 @@ * */ +use OC\Cache\CappedMemoryCache; + /** * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ class OC_User_Database extends OC_User_Backend implements \OCP\IUserBackend { - private $cache = array(); + /** @var CappedMemoryCache */ + private $cache; + + /** + * OC_User_Database constructor. + */ + public function __construct() { + $this->cache = new CappedMemoryCache(); + } /** * Create a new user From f9aef7ab9fa0979ae72dbed89bb96207c3ed4fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 11 Apr 2016 10:35:52 +0200 Subject: [PATCH 245/286] Fixes #23899 --- lib/private/user.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/private/user.php b/lib/private/user.php index 26062f503d28e..58405ed644474 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -203,6 +203,10 @@ public static function loginWithApache(\OCP\Authentication\IApacheBackend $backe self::setUserId($uid); self::setDisplayName($uid); self::getUserSession()->setLoginName($uid); + // setup the filesystem + OC_Util::setupFS($uid); + //trigger creation of user home and /files folder + \OC::$server->getUserFolder($uid); OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => '')); } From 6c797eed82e0b03b497103c9dd5bc747b1d951be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Tue, 3 May 2016 14:16:17 +0200 Subject: [PATCH 246/286] first call the post_login hooks, before we call getUserFolder. The login process needs to be completed before we can safely create the users home folder. For example we need to give encryption a chance to initialize the users encryption keys in order to copy the skeleton files correctly --- lib/private/user.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/private/user.php b/lib/private/user.php index 58405ed644474..604fd8674b176 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -205,10 +205,14 @@ public static function loginWithApache(\OCP\Authentication\IApacheBackend $backe self::getUserSession()->setLoginName($uid); // setup the filesystem OC_Util::setupFS($uid); + // first call the post_login hooks, the login-process needs to be + // completed before we can safely create the users folder. + // For example encryption needs to initialize the users keys first + // before we can create the user folder with the skeleton files + OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => '')); //trigger creation of user home and /files folder \OC::$server->getUserFolder($uid); - OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => '')); } return true; } From f7f9ef55b6b6129113f0de1e3589e1ed1f9850a7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 4 May 2016 08:28:13 +0200 Subject: [PATCH 247/286] Do not save the language as request lang for apps when we didn't find any --- lib/private/l10n/factory.php | 2 +- tests/lib/l10n/factorytest.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php index 8f157d9c0bb17..08b92657a1b1e 100644 --- a/lib/private/l10n/factory.php +++ b/lib/private/l10n/factory.php @@ -263,7 +263,7 @@ public function setLanguageFromRequest($app = null) { } } - if (!$this->requestLanguage) { + if ($app === null && !$this->requestLanguage) { $this->requestLanguage = 'en'; } return 'en'; // Last try: English diff --git a/tests/lib/l10n/factorytest.php b/tests/lib/l10n/factorytest.php index e4c0eab2e6a92..98bb5ec13c989 100644 --- a/tests/lib/l10n/factorytest.php +++ b/tests/lib/l10n/factorytest.php @@ -343,6 +343,15 @@ public function dataSetLanguageFromRequest() { [null, 'de', 'ru', ['de'], 'de', 'ru'], [null, 'de,en', 'ru', ['de'], 'de', 'ru'], [null, 'de-DE,en-US;q=0.8,en;q=0.6', 'ru', ['de'], 'de', 'ru'], + + // Request lang should not be set for apps: Language is available + ['files_pdfviewer', 'de', null, ['de'], 'de', ''], + ['files_pdfviewer', 'de,en', null, ['de'], 'de', ''], + ['files_pdfviewer', 'de-DE,en-US;q=0.8,en;q=0.6', null, ['de'], 'de', ''], + // Request lang should not be set for apps: Language is not available + ['files_pdfviewer', 'de', null, ['ru'], 'en', ''], + ['files_pdfviewer', 'de,en', null, ['ru', 'en'], 'en', ''], + ['files_pdfviewer', 'de-DE,en-US;q=0.8,en;q=0.6', null, ['ru', 'en'], 'en', ''], ]; } From 7fb631a13bfcc7679927b28994803089d8cbfed4 Mon Sep 17 00:00:00 2001 From: Petr Svoboda Date: Tue, 19 Apr 2016 00:49:21 +0200 Subject: [PATCH 248/286] solves problem with moving files via WebDAV When moving files via WebDAV I sometimes got PHP Fatal error: Nesting level too deep - recursive dependency? in /var/www/owncloud/lib/private/files/view.php on line 729 This small change has fixed the problem for me --- lib/private/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 4421a016356ed..02c12c80a2071 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -726,7 +726,7 @@ public function rename($path1, $path2) { $result = false; } // moving a file/folder within the same mount point - } elseif ($storage1 == $storage2) { + } elseif ($storage1 === $storage2) { if ($storage1) { $result = $storage1->rename($internalPath1, $internalPath2); } else { From fefb59e7d0ac0225b270bc0f5fddb6d96dcb5db7 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 10 May 2016 16:41:47 +0200 Subject: [PATCH 249/286] Do not automatically try to enable index.php-less URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current logic for mod_rewrite relies on the fact that people have properly configured ownCloud, basically it reads from the `overwrite.cli.ur l` entry and then derives the `RewriteBase` from it. This usually works. However, since the ownCloud packages seem to install themselves at `/owncloud` (because subfolders are cool or so…) _a lot_ of people have just created a new Virtual Host for it or have simply symlinked the path etc. This means that `overwrite.cli.url` is wrong, which fails hard if it is used as RewriteBase since Apache does not know where it should serve files from. In the end the ownCloud instance will not be accessible anymore and users will be frustrated. Also some shared hosters like 1&1 (because using shared hosters is so awesome… ;-)) have somewhat dubious Apache configurations or use versions of mod_rewrite from the mediveal age. (because updating is money or so…) Anyhow. This makes this explicitly an opt-in configuration flag. If `htaccess.RewriteBase` is set then it will configure index.php-less URLs, if admins set that after installation and don't want to wait until the next ownCloud version they can run `occ maintenance:update:htaccess`. For ownCloud 9.0 we also have to add a repair step to make sure that instances that already have a RewriteBase configured continue to use it by copying it into the config file. That way all existing URLs stay valid. That one is not in this PR since this is unneccessary in master. Effectively this reduces another risk of breakage when updating from ownCloud 8 to ownCloud 9. Fixes https://github.com/owncloud/core/issues/24525, https://github.com/owncloud/core/issues/24426 and probably some more. --- .htaccess | 17 ------- config/config.sample.php | 25 +++++++++++ core/Command/Maintenance/UpdateHtaccess.php | 44 ++++++++++++++++++ core/register_command.php | 1 + lib/private/setup.php | 50 ++++++++++++--------- 5 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 core/Command/Maintenance/UpdateHtaccess.php diff --git a/.htaccess b/.htaccess index df074f7f80681..5bf7b321f0cc1 100644 --- a/.htaccess +++ b/.htaccess @@ -59,23 +59,6 @@ RewriteRule ^(build|tests|config|lib|3rdparty|templates)/.* - [R=404,L] RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.* RewriteRule ^(\.|autotest|occ|issue|indie|db_|console).* - [R=404,L] - - # Rewrite rules for `front_controller_active` - Options -MultiViews - RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1] - RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1] - RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ - RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$ - RewriteCond %{REQUEST_FILENAME} !/remote.php - RewriteCond %{REQUEST_FILENAME} !/public.php - RewriteCond %{REQUEST_FILENAME} !/cron.php - RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php - RewriteCond %{REQUEST_FILENAME} !/status.php - RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php - RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php - RewriteCond %{REQUEST_FILENAME} !/updater/ - RewriteCond %{REQUEST_FILENAME} !/ocs-provider/ - RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.* AddType image/svg+xml svg svgz diff --git a/config/config.sample.php b/config/config.sample.php index 4321e5bab83e7..a0f04c0925134 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -361,6 +361,31 @@ */ 'overwrite.cli.url' => '', +/** + * To have clean URLs without `/index.php` this parameter needs to be configured. + * + * This parameter will be written as "RewriteBase" on update and installation of + * ownCloud to your `.htaccess` file. While this value is often simply the URL + * path of the ownCloud installation it cannot be set automatically properly in + * every scenario and needs thus some manual configuration. + * + * In a standard Apache setup this usually equals the folder that ownCloud is + * accessible at. So if ownCloud is accessible via "https://mycloud.org/owncloud" + * the correct value would most likely be "/owncloud". If ownCloud is running + * under "https://mycloud.org/" then it would be "/". + * + * Note that above rule is not valid in every case, there are some rare setup + * cases where this may not apply. However, to avoid any update problems this + * configuration value is explicitly opt-in. + * + * After setting this value run `occ maintenance:update:htaccess` and when following + * conditions are met ownCloud uses URLs without index.php in it: + * + * - `mod_rewrite` is installed + * - `mod_env` is installed + */ +'htaccess.RewriteBase' => '/', + /** * The URL of your proxy server, for example ``proxy.example.com:8081``. */ diff --git a/core/Command/Maintenance/UpdateHtaccess.php b/core/Command/Maintenance/UpdateHtaccess.php new file mode 100644 index 0000000000000..ad5bf5d8bdeb9 --- /dev/null +++ b/core/Command/Maintenance/UpdateHtaccess.php @@ -0,0 +1,44 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OC\Core\Command\Maintenance; + +use InvalidArgumentException; +use OC\Setup; +use OCP\IConfig; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class UpdateHtaccess extends Command { + + protected function configure() { + $this + ->setName('maintenance:update:htaccess') + ->setDescription('Updates the .htaccess file'); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + \OC\Setup::updateHtaccess(); + $output->writeln('.htaccess has been updated'); + return 0; + } +} diff --git a/core/register_command.php b/core/register_command.php index e06ff436f50dd..b074339f4c3c5 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -113,6 +113,7 @@ $application->add(new OC\Core\Command\Maintenance\Mode(\OC::$server->getConfig())); $application->add(new OC\Core\Command\Maintenance\Repair(new \OC\Repair(\OC\Repair::getRepairSteps()), \OC::$server->getConfig())); $application->add(new OC\Core\Command\Maintenance\SingleUser(\OC::$server->getConfig())); + $application->add(new OC\Core\Command\Maintenance\UpdateHtaccess()); $application->add(new OC\Core\Command\Upgrade( \OC::$server->getConfig(), diff --git a/lib/private/setup.php b/lib/private/setup.php index 196ae8a8bcee9..a38f594ff7f52 100644 --- a/lib/private/setup.php +++ b/lib/private/setup.php @@ -420,37 +420,47 @@ public static function updateHtaccess() { $htaccessContent = file_get_contents($setupHelper->pathToHtaccess()); $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n"; - if(strpos($htaccessContent, $content) === false) { - //custom 403 error page - $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php"; + $htaccessContent = explode($content, $htaccessContent, 2)[0]; - //custom 404 error page - $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php"; + //custom 403 error page + $content.= "\nErrorDocument 403 ".$webRoot."/core/templates/403.php"; - // ownCloud may be configured to live at the root folder without a - // trailing slash being specified. In this case manually set the - // rewrite base to `/` - $rewriteBase = $webRoot; - if($webRoot === '') { - $rewriteBase = '/'; - } + //custom 404 error page + $content.= "\nErrorDocument 404 ".$webRoot."/core/templates/404.php"; - // Add rewrite base + // Add rewrite rules if the RewriteBase is configured + $rewriteBase = $config->getSystemValue('htaccess.RewriteBase', ''); + if($rewriteBase !== '') { $content .= "\n"; + $content .= "\n Options -MultiViews"; + $content .= "\n RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]"; + $content .= "\n RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/remote.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/public.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/cron.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/status.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/updater/"; + $content .= "\n RewriteCond %{REQUEST_FILENAME} !/ocs-provider/"; + $content .= "\n RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.*"; $content .= "\n RewriteRule . index.php [PT,E=PATH_INFO:$1]"; - $content .= "\n RewriteBase ".$rewriteBase; + $content .= "\n RewriteBase " . $rewriteBase; $content .= "\n "; $content .= "\n SetEnv front_controller_active true"; $content .= "\n "; $content .= "\n DirectorySlash off"; $content .= "\n "; - $content.="\n "; - $content.="\n"; + $content .= "\n "; + $content .= "\n"; + } - if ($content !== '') { - //suppress errors in case we don't have permissions for it - @file_put_contents($setupHelper->pathToHtaccess(), $content . "\n", FILE_APPEND); - } + if ($content !== '') { + //suppress errors in case we don't have permissions for it + @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content . "\n"); } } From 4e10b81eb0ec1116c722b048d3f8ed61d58d5767 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 10 May 2016 16:53:50 +0200 Subject: [PATCH 250/286] Move file since stable9 uses old autoloader --- .../UpdateHtaccess.php => command/maintenance/updatehtaccess.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/{Command/Maintenance/UpdateHtaccess.php => command/maintenance/updatehtaccess.php} (100%) diff --git a/core/Command/Maintenance/UpdateHtaccess.php b/core/command/maintenance/updatehtaccess.php similarity index 100% rename from core/Command/Maintenance/UpdateHtaccess.php rename to core/command/maintenance/updatehtaccess.php From b78625e0ae34514d7c0ea4eae3f3fd4e64b1c9a8 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 10 May 2016 17:19:45 +0200 Subject: [PATCH 251/286] Add repair step for copying the RewriteBase --- lib/private/repair.php | 2 + .../repair/copyrewritebasetoconfig.php | 89 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 lib/private/repair/copyrewritebasetoconfig.php diff --git a/lib/private/repair.php b/lib/private/repair.php index 63b569b2ed3e2..d3d2eafe92e29 100644 --- a/lib/private/repair.php +++ b/lib/private/repair.php @@ -34,6 +34,7 @@ use OC\Repair\BrokenUpdaterRepair; use OC\Repair\CleanTags; use OC\Repair\Collation; +use OC\Repair\CopyRewriteBaseToConfig; use OC\Repair\DropOldJobs; use OC\Repair\OldGroupMembershipShares; use OC\Repair\RemoveGetETagEntries; @@ -144,6 +145,7 @@ public static function getBeforeUpgradeRepairSteps() { new Collation(\OC::$server->getConfig(), $connection), new SqliteAutoincrement($connection), new SearchLuceneTables(), + new CopyRewriteBaseToConfig(\OC::$server->getConfig()), ]; //There is no need to delete all previews on every single update diff --git a/lib/private/repair/copyrewritebasetoconfig.php b/lib/private/repair/copyrewritebasetoconfig.php new file mode 100644 index 0000000000000..e5e03f9d4374c --- /dev/null +++ b/lib/private/repair/copyrewritebasetoconfig.php @@ -0,0 +1,89 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Repair; + +use OC\Hooks\BasicEmitter; +use OC\RepairStep; +use OCP\IConfig; + +/** + * Class CopyRewriteBaseToConfig + * + * @package OC\Repair + */ +class CopyRewriteBaseToConfig extends BasicEmitter implements RepairStep { + /** @var IConfig */ + private $config; + + /** + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } + + /** + * {@inheritdoc} + */ + public function getName() { + return 'Copy the rewrite base to the config file'; + } + + /** + * {@inheritdoc} + */ + public function run() { + $ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); + + $versionsToApplyFrom = [ + '9.0.0.19', + '9.0.1.3', + '9.0.2.2', + ]; + + if(in_array($ocVersionFromBeforeUpdate, $versionsToApplyFrom, true)) { + // For CLI read the value from overwrite.cli.url + if(\OC::$CLI) { + $webRoot = $this->config->getSystemValue('overwrite.cli.url', ''); + if($webRoot === '') { + return; + } + $webRoot = parse_url($webRoot, PHP_URL_PATH); + $webRoot = rtrim($webRoot, '/'); + } else { + $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/'; + } + + // ownCloud may be configured to live at the root folder without a + // trailing slash being specified. In this case manually set the + // rewrite base to `/` + $rewriteBase = $webRoot; + if($webRoot === '') { + $rewriteBase = '/'; + } + + $this->config->setSystemValue('htaccess.RewriteBase', $rewriteBase); + \OC\Setup::updateHtaccess(); + } + + } +} From 5d736706865806c56c4c2cd2a7560ea779cd978a Mon Sep 17 00:00:00 2001 From: Pau Date: Mon, 4 Apr 2016 10:56:36 +0200 Subject: [PATCH 252/286] Fixed 'Help Translate' link --- settings/templates/personal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 9693f1afe18af..11dc0d7881b30 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -160,7 +160,7 @@ - t('Help translate'));?> From decb4789bbf3983713b7f4c9d7ee0e984a0b2ceb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 10 May 2016 10:05:26 +0200 Subject: [PATCH 253/286] Pass on the error message from the user manager to the UI --- settings/controller/userscontroller.php | 6 +++++- settings/js/users/users.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/settings/controller/userscontroller.php b/settings/controller/userscontroller.php index f5b7f2d2e5d85..5f74eaa82fb56 100644 --- a/settings/controller/userscontroller.php +++ b/settings/controller/userscontroller.php @@ -355,9 +355,13 @@ public function create($username, $password, array $groups=array(), $email='') { try { $user = $this->userManager->createUser($username, $password); } catch (\Exception $exception) { + $message = $exception->getMessage(); + if (!$message) { + $message = $this->l10n->t('Unable to create user.'); + } return new DataResponse( array( - 'message' => (string)$this->l10n->t('Unable to create user.') + 'message' => (string) $message, ), Http::STATUS_FORBIDDEN ); diff --git a/settings/js/users/users.js b/settings/js/users/users.js index 261d9a8eb5280..02d3a25be70ef 100644 --- a/settings/js/users/users.js +++ b/settings/js/users/users.js @@ -825,7 +825,7 @@ $(document).ready(function () { }).fail(function(result) { OC.Notification.showTemporary(t('settings', 'Error creating user: {message}', { message: result.responseJSON.message - })); + }, undefined, {escape: false})); }).success(function(){ $('#newuser').get(0).reset(); }); From 750aeda8b797b183f5d43b55d0d4c196b262ee37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 May 2016 11:22:08 +0200 Subject: [PATCH 254/286] Yo-ho-oh - Murder all band 'o pirates - backport of #24550 --- apps/files/l10n/en@pirate.js | 6 ------ apps/files/l10n/en@pirate.json | 4 ---- apps/files_external/l10n/en@pirate.js | 6 ------ apps/files_external/l10n/en@pirate.json | 4 ---- apps/files_sharing/l10n/en@pirate.js | 7 ------- apps/files_sharing/l10n/en@pirate.json | 5 ----- apps/user_ldap/l10n/en@pirate.js | 6 ------ apps/user_ldap/l10n/en@pirate.json | 4 ---- core/l10n/en@pirate.js | 6 ------ core/l10n/en@pirate.json | 4 ---- lib/l10n/en@pirate.js | 6 ------ lib/l10n/en@pirate.json | 4 ---- settings/l10n/en@pirate.js | 6 ------ settings/l10n/en@pirate.json | 4 ---- 14 files changed, 72 deletions(-) delete mode 100644 apps/files/l10n/en@pirate.js delete mode 100644 apps/files/l10n/en@pirate.json delete mode 100644 apps/files_external/l10n/en@pirate.js delete mode 100644 apps/files_external/l10n/en@pirate.json delete mode 100644 apps/files_sharing/l10n/en@pirate.js delete mode 100644 apps/files_sharing/l10n/en@pirate.json delete mode 100644 apps/user_ldap/l10n/en@pirate.js delete mode 100644 apps/user_ldap/l10n/en@pirate.json delete mode 100644 core/l10n/en@pirate.js delete mode 100644 core/l10n/en@pirate.json delete mode 100644 lib/l10n/en@pirate.js delete mode 100644 lib/l10n/en@pirate.json delete mode 100644 settings/l10n/en@pirate.js delete mode 100644 settings/l10n/en@pirate.json diff --git a/apps/files/l10n/en@pirate.js b/apps/files/l10n/en@pirate.js deleted file mode 100644 index 5c456a089fee7..0000000000000 --- a/apps/files/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "files", - { - "Download" : "Download" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/en@pirate.json b/apps/files/l10n/en@pirate.json deleted file mode 100644 index a8fb407329845..0000000000000 --- a/apps/files/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "Download" : "Download" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/apps/files_external/l10n/en@pirate.js b/apps/files_external/l10n/en@pirate.js deleted file mode 100644 index 7345429f75097..0000000000000 --- a/apps/files_external/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "files_external", - { - "Password" : "Secret Code" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/en@pirate.json b/apps/files_external/l10n/en@pirate.json deleted file mode 100644 index bde5153f30961..0000000000000 --- a/apps/files_external/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "Password" : "Secret Code" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/apps/files_sharing/l10n/en@pirate.js b/apps/files_sharing/l10n/en@pirate.js deleted file mode 100644 index 84e0fabadc68f..0000000000000 --- a/apps/files_sharing/l10n/en@pirate.js +++ /dev/null @@ -1,7 +0,0 @@ -OC.L10N.register( - "files_sharing", - { - "Password" : "Secret Code", - "Download" : "Download" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/en@pirate.json b/apps/files_sharing/l10n/en@pirate.json deleted file mode 100644 index ec5b5f4b2721b..0000000000000 --- a/apps/files_sharing/l10n/en@pirate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ "translations": { - "Password" : "Secret Code", - "Download" : "Download" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/apps/user_ldap/l10n/en@pirate.js b/apps/user_ldap/l10n/en@pirate.js deleted file mode 100644 index 0670deb5fbcc1..0000000000000 --- a/apps/user_ldap/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "user_ldap", - { - "Password" : "Passcode" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/en@pirate.json b/apps/user_ldap/l10n/en@pirate.json deleted file mode 100644 index 6f74658eb82f2..0000000000000 --- a/apps/user_ldap/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "Password" : "Passcode" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/core/l10n/en@pirate.js b/core/l10n/en@pirate.js deleted file mode 100644 index adc62c8c96292..0000000000000 --- a/core/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "core", - { - "Password" : "Passcode" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/en@pirate.json b/core/l10n/en@pirate.json deleted file mode 100644 index 6f74658eb82f2..0000000000000 --- a/core/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "Password" : "Passcode" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/lib/l10n/en@pirate.js b/lib/l10n/en@pirate.js deleted file mode 100644 index ade0ad04df423..0000000000000 --- a/lib/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "lib", - { - "web services under your control" : "web services under your control" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/lib/l10n/en@pirate.json b/lib/l10n/en@pirate.json deleted file mode 100644 index 8bbc4280faefc..0000000000000 --- a/lib/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "web services under your control" : "web services under your control" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file diff --git a/settings/l10n/en@pirate.js b/settings/l10n/en@pirate.js deleted file mode 100644 index f9293f8094c4b..0000000000000 --- a/settings/l10n/en@pirate.js +++ /dev/null @@ -1,6 +0,0 @@ -OC.L10N.register( - "settings", - { - "Password" : "Passcode" -}, -"nplurals=2; plural=(n != 1);"); diff --git a/settings/l10n/en@pirate.json b/settings/l10n/en@pirate.json deleted file mode 100644 index 6f74658eb82f2..0000000000000 --- a/settings/l10n/en@pirate.json +++ /dev/null @@ -1,4 +0,0 @@ -{ "translations": { - "Password" : "Passcode" -},"pluralForm" :"nplurals=2; plural=(n != 1);" -} \ No newline at end of file From 3505776b6e898c6f8e1d9b2bc8fa1380c6e04746 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 9 May 2016 11:25:58 +0200 Subject: [PATCH 255/286] Make update server URL configurable Currently testing the updates is a big problem and not really super easy possible. Since we now have a new updater server we should also make this configurable so that people can properly test updates. --- config/config.sample.php | 5 +++ lib/private/updater.php | 7 +--- tests/lib/updater.php | 90 ++++++++++++++-------------------------- 3 files changed, 38 insertions(+), 64 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 4321e5bab83e7..8cdcc551e4d6e 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -471,6 +471,11 @@ */ 'updatechecker' => true, +/** + * URL that ownCloud should use to look for updates + */ +'updater.server.url' => 'https://updates.owncloud.com/server/', + /** * Is ownCloud connected to the Internet or running in a closed network? */ diff --git a/lib/private/updater.php b/lib/private/updater.php index 0d567b8dfb93d..55d9a5bed2b9a 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -134,19 +134,16 @@ public function setSkip3rdPartyAppsDisable($flag) { /** * Check if a new version is available * - * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' * @return array|bool */ - public function check($updaterUrl = null) { + public function check() { // Look up the cache - it is invalidated all 30 minutes if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) { return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true); } - if (is_null($updaterUrl)) { - $updaterUrl = 'https://updates.owncloud.com/server/'; - } + $updaterUrl = $this->config->getSystemValue('updater.server.url', 'https://updates.owncloud.com/server/'); $this->config->setAppValue('core', 'lastupdatedat', time()); diff --git a/tests/lib/updater.php b/tests/lib/updater.php index 8ee77b9f81e34..4b6205a42c76f 100644 --- a/tests/lib/updater.php +++ b/tests/lib/updater.php @@ -221,20 +221,25 @@ public function testCheckWithoutUpdateUrl() { ->will($this->returnValue(0)); $this->config ->expects($this->at(1)) + ->method('getSystemValue') + ->with('updater.server.url', 'https://updates.owncloud.com/server/') + ->willReturn('https://updates.owncloud.com/server/'); + $this->config + ->expects($this->at(2)) ->method('setAppValue') ->with('core', 'lastupdatedat', $this->isType('integer')); $this->config - ->expects($this->at(3)) + ->expects($this->at(4)) ->method('getAppValue') ->with('core', 'installedat') ->will($this->returnValue('installedat')); $this->config - ->expects($this->at(4)) + ->expects($this->at(5)) ->method('getAppValue') ->with('core', 'lastupdatedat') ->will($this->returnValue('lastupdatedat')); $this->config - ->expects($this->at(5)) + ->expects($this->at(6)) ->method('setAppValue') ->with('core', 'lastupdateResult', json_encode($expectedResult)); @@ -262,20 +267,25 @@ public function testCheckWithInvalidXml() { ->will($this->returnValue(0)); $this->config ->expects($this->at(1)) + ->method('getSystemValue') + ->with('updater.server.url', 'https://updates.owncloud.com/server/') + ->willReturn('https://updates.owncloud.com/server/'); + $this->config + ->expects($this->at(2)) ->method('setAppValue') ->with('core', 'lastupdatedat', $this->isType('integer')); $this->config - ->expects($this->at(3)) + ->expects($this->at(4)) ->method('getAppValue') ->with('core', 'installedat') ->will($this->returnValue('installedat')); $this->config - ->expects($this->at(4)) + ->expects($this->at(5)) ->method('getAppValue') ->with('core', 'lastupdatedat') ->will($this->returnValue('lastupdatedat')); $this->config - ->expects($this->at(5)) + ->expects($this->at(6)) ->method('setAppValue') ->with('core', 'lastupdateResult', 'false'); @@ -289,54 +299,6 @@ public function testCheckWithInvalidXml() { $this->assertSame([], $this->updater->check()); } - public function testCheckWithUpdateUrl() { - $expectedResult = [ - 'version' => '8.0.4.2', - 'versionstring' => 'ownCloud 8.0.4', - 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', - 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', - ]; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - $this->config - ->expects($this->at(5)) - ->method('setAppValue') - ->with('core', 'lastupdateResult', json_encode($expectedResult)); - - $updateXml = ' - - 8.0.4.2 - ownCloud 8.0.4 - https://download.owncloud.org/community/owncloud-8.0.4.zip - http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html -'; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://myupdater.com/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame($expectedResult, $this->updater->check('https://myupdater.com/')); - } - public function testCheckWithEmptyValidXmlResponse() { $expectedResult = [ 'version' => '', @@ -352,15 +314,20 @@ public function testCheckWithEmptyValidXmlResponse() { ->will($this->returnValue(0)); $this->config ->expects($this->at(1)) + ->method('getSystemValue') + ->with('updater.server.url', 'https://updates.owncloud.com/server/') + ->willReturn('https://updates.owncloud.com/server/'); + $this->config + ->expects($this->at(2)) ->method('setAppValue') ->with('core', 'lastupdatedat', $this->isType('integer')); $this->config - ->expects($this->at(3)) + ->expects($this->at(4)) ->method('getAppValue') ->with('core', 'installedat') ->will($this->returnValue('installedat')); $this->config - ->expects($this->at(4)) + ->expects($this->at(5)) ->method('getAppValue') ->with('core', 'lastupdatedat') ->will($this->returnValue('lastupdatedat')); @@ -391,20 +358,25 @@ public function testCheckWithEmptyInvalidXmlResponse() { ->will($this->returnValue(0)); $this->config ->expects($this->at(1)) + ->method('getSystemValue') + ->with('updater.server.url', 'https://updates.owncloud.com/server/') + ->willReturn('https://updates.owncloud.com/server/'); + $this->config + ->expects($this->at(2)) ->method('setAppValue') ->with('core', 'lastupdatedat', $this->isType('integer')); $this->config - ->expects($this->at(3)) + ->expects($this->at(4)) ->method('getAppValue') ->with('core', 'installedat') ->will($this->returnValue('installedat')); $this->config - ->expects($this->at(4)) + ->expects($this->at(5)) ->method('getAppValue') ->with('core', 'lastupdatedat') ->will($this->returnValue('lastupdatedat')); $this->config - ->expects($this->at(5)) + ->expects($this->at(6)) ->method('setAppValue') ->with('core', 'lastupdateResult', json_encode($expectedResult)); From 8aebab98531be762e1254e072d69d5207fbf117f Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 11 May 2016 14:01:05 +0200 Subject: [PATCH 256/286] Fix test race condition E-tag propagation replies on the mtime of the file. Order of events: 1. add file 'foo.txt' with content 'bar' 2. Set mtime to now() - 1 3. Check if etag changed. Now this goes right often when 1 and 2 happen in the same second. However imagine 1. add file 'foo.txt' with content 'bar' (at t=0.999) 2. Set mtime to now() - 1 (at t=1.001) Now the mtime will be set to the same time. Thus not chaning the etag. --- apps/files_sharing/tests/etagpropagation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/tests/etagpropagation.php b/apps/files_sharing/tests/etagpropagation.php index 55972dd9221a8..67c5410dc80ac 100644 --- a/apps/files_sharing/tests/etagpropagation.php +++ b/apps/files_sharing/tests/etagpropagation.php @@ -126,7 +126,8 @@ public function testOwnerWritesToShare() { public function testOwnerWritesToSingleFileShare() { $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); Filesystem::file_put_contents('/foo.txt', 'longer_bar'); - Filesystem::touch('/foo.txt', time() - 1); + $t = (int)Filesystem::filemtime('/foo.txt') - 1; + Filesystem::touch('/foo.txt', $t); $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER3]); $this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2]); From 7de566b7c00f0987a276c15d9299f8bc81fdd8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 6 May 2016 17:05:34 +0200 Subject: [PATCH 257/286] Wait a while even after successful conect ... --- autotest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autotest.sh b/autotest.sh index ba6ec3838666b..1fa9df18d757e 100755 --- a/autotest.sh +++ b/autotest.sh @@ -239,7 +239,7 @@ function execute_tests { # Try to connect to the OCI host via sqlplus to ensure that the connection is already running for i in {1..48} do - if sqlplus "system/oracle@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=$DATABASEHOST)(Port=1521))(CONNECT_DATA=(SID=XE)))" < /dev/null | grep 'Connected to'; then + if sqlplus "autotest/owncloud@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=$DATABASEHOST)(Port=1521))(CONNECT_DATA=(SID=XE)))" < /dev/null | grep 'Connected to'; then break; fi sleep 5 From 60ec1fc85d91629aa119f200890f4a543cc7063d Mon Sep 17 00:00:00 2001 From: VicDeo Date: Thu, 12 May 2016 13:08:08 +0300 Subject: [PATCH 258/286] Put back pcntl warning (#24295) --- console.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/console.php b/console.php index 72f961515d7ae..fc571b03f1efd 100644 --- a/console.php +++ b/console.php @@ -79,6 +79,10 @@ exit(1); } + if (!function_exists('pcntl_signal') && !in_array('--no-warnings', $argv)) { + echo "The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see http://php.net/manual/en/book.pcntl.php" . PHP_EOL; + } + $application = new Application(\OC::$server->getConfig(), \OC::$server->getEventDispatcher(), \OC::$server->getRequest()); $application->loadCommands(new ArgvInput(), new ConsoleOutput()); $application->run(); From 283347a026782afe033db73563d43948c9638846 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Thu, 12 May 2016 12:08:54 +0200 Subject: [PATCH 259/286] Remove repair steps for broken updater repair (#24438) That's only required for an update to 9.0.2, the updater server has the required logic to ensure that clients get the right update delivered. --- lib/private/repair.php | 2 - lib/private/repair/brokenupdaterrepair.php | 110 --------------------- 2 files changed, 112 deletions(-) delete mode 100644 lib/private/repair/brokenupdaterrepair.php diff --git a/lib/private/repair.php b/lib/private/repair.php index 63b569b2ed3e2..d40c6464e1469 100644 --- a/lib/private/repair.php +++ b/lib/private/repair.php @@ -31,7 +31,6 @@ use OC\Hooks\BasicEmitter; use OC\Hooks\Emitter; use OC\Repair\AssetCache; -use OC\Repair\BrokenUpdaterRepair; use OC\Repair\CleanTags; use OC\Repair\Collation; use OC\Repair\DropOldJobs; @@ -115,7 +114,6 @@ public static function getRepairSteps() { new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()), new UpdateOutdatedOcsIds(\OC::$server->getConfig()), new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), - new BrokenUpdaterRepair(), ]; } diff --git a/lib/private/repair/brokenupdaterrepair.php b/lib/private/repair/brokenupdaterrepair.php deleted file mode 100644 index 0e4431f6ba3b9..0000000000000 --- a/lib/private/repair/brokenupdaterrepair.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OC\Repair; - -use OC\Hooks\BasicEmitter; - -/** - * Class BrokenUpdaterRepair fixes some issues caused by bugs in the ownCloud - * updater below version 9.0.2. - * - * FIXME: This file should be removed after the 9.0.2 release. The update server - * is instructed to deliver 9.0.2 for 9.0.0 and 9.0.1. - * - * @package OC\Repair - */ -class BrokenUpdaterRepair extends BasicEmitter implements \OC\RepairStep { - - public function getName() { - return 'Manually copies the third-party folder changes since 9.0.0 due ' . - 'to a bug in the updater.'; - } - - /** - * Manually copy the third-party files that have changed since 9.0.0 because - * the old updater does not copy over third-party changes. - * - * @return bool True if action performed, false otherwise - */ - private function manuallyCopyThirdPartyFiles() { - $resourceDir = __DIR__ . '/../../../resources/updater-fixes/'; - $thirdPartyDir = __DIR__ . '/../../../3rdparty/'; - - $filesToCopy = [ - // Composer updates - 'composer.json', - 'composer.lock', - 'composer/autoload_classmap.php', - 'composer/installed.json', - 'composer/LICENSE', - // Icewind stream library - 'icewind/streams/src/DirectoryFilter.php', - 'icewind/streams/src/DirectoryWrapper.php', - 'icewind/streams/src/RetryWrapper.php', - 'icewind/streams/src/SeekableWrapper.php', - // Sabre update - 'sabre/dav/CHANGELOG.md', - 'sabre/dav/composer.json', - 'sabre/dav/lib/CalDAV/Plugin.php', - 'sabre/dav/lib/CardDAV/Backend/PDO.php', - 'sabre/dav/lib/DAV/CorePlugin.php', - 'sabre/dav/lib/DAV/Version.php', - ]; - - // Check the hash for the autoload_classmap.php file, if the hash does match - // the expected value then the third-party folder has already been copied - // properly. - if(hash_file('sha512', $thirdPartyDir . '/composer/autoload_classmap.php') === 'abe09be19b6d427283cbfa7c4156d2c342cd9368d7d0564828a00ae02c435b642e7092cef444f94635f370dbe507eb6b2aa05109b32d8fb5d8a65c3a5a1c658f') { - $this->emit('\OC\Repair', 'info', ['Third-party files seem already to have been copied. No repair necessary.']); - return false; - } - - foreach($filesToCopy as $file) { - $state = copy($resourceDir . '/' . $file, $thirdPartyDir . '/' . $file); - if($state === true) { - $this->emit('\OC\Repair', 'info', ['Successfully replaced '.$file.' with new version.']); - } else { - $this->emit('\OC\Repair', 'warning', ['Could not replace '.$file.' with new version.']); - } - } - return true; - } - - /** - * Rerun the integrity check after the update since the repair step has - * repaired some invalid copied files. - */ - private function recheckIntegrity() { - \OC::$server->getIntegrityCodeChecker()->runInstanceVerification(); - } - - public function run() { - if($this->manuallyCopyThirdPartyFiles()) { - $this->emit('\OC\Repair', 'info', ['Start integrity recheck.']); - $this->recheckIntegrity(); - $this->emit('\OC\Repair', 'info', ['Finished integrity recheck.']); - } else { - $this->emit('\OC\Repair', 'info', ['Rechecking code integrity not necessary.']); - } - } -} - From f8979a9ee2bf76bc146b0723283f05c027da8bde Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 12 May 2016 16:24:56 +0200 Subject: [PATCH 260/286] cap the normalized path cache (#24390) --- lib/private/files/filesystem.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index ec9b537a35884..a72a63e076f87 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -58,6 +58,7 @@ namespace OC\Files; +use OC\Cache\CappedMemoryCache; use OC\Files\Config\MountProviderCollection; use OC\Files\Mount\MountPoint; use OC\Files\Storage\StorageFactory; @@ -81,7 +82,7 @@ class Filesystem { static private $usersSetup = array(); - static private $normalizedPathCache = array(); + static private $normalizedPathCache = null; static private $listeningForProviders = false; @@ -794,6 +795,10 @@ static public function hasUpdated($path, $time) { * @return string */ public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) { + if (is_null(self::$normalizedPathCache)) { + self::$normalizedPathCache = new CappedMemoryCache(); + } + /** * FIXME: This is a workaround for existing classes and files which call * this function with another type than a valid string. This From dfc0a7a4a60bf93f09c2ea210ebb440f1703a8a9 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 17 May 2016 17:03:42 +0200 Subject: [PATCH 261/286] Allow chunk GC mtime tolerance for unfinished part chunks Whenever part chunks are written, every fwrite in the write loop will reset the mtime to the current mtime. Only at the end will the touch() operation set the mtime to now + ttl, in the future. However the GC code is expecting that every chunk with mtime < now are old and must be deleted. This causes the GC to sometimes delete part chunks in which the write loop is slow. To fix this, a tolerance value is added in the GC code to allow for more time before a part chunk gets deleted. --- lib/private/cache/file.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/private/cache/file.php b/lib/private/cache/file.php index 989e05275b70e..38f88959bd75f 100644 --- a/lib/private/cache/file.php +++ b/lib/private/cache/file.php @@ -172,7 +172,9 @@ public function clear($prefix = '') { public function gc() { $storage = $this->getStorage(); if ($storage and $storage->is_dir('/')) { - $now = time(); + // extra hour safety, in case of stray part chunks that take longer to write, + // because touch() is only called after the chunk was finished + $now = time() - 3600; $dh = $storage->opendir('/'); if (!is_resource($dh)) { return null; From e36d70c0deba93f8b7e4291b0be713e3e5caddb6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 2 May 2016 14:18:46 +0200 Subject: [PATCH 262/286] free up memory when releasing the last shared lock --- lib/private/lock/abstractlockingprovider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/private/lock/abstractlockingprovider.php b/lib/private/lock/abstractlockingprovider.php index 7dee8c709a0af..81136c5ee4572 100644 --- a/lib/private/lock/abstractlockingprovider.php +++ b/lib/private/lock/abstractlockingprovider.php @@ -77,6 +77,9 @@ protected function markRelease($path, $type) { if ($type === self::LOCK_SHARED) { if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) { $this->acquiredLocks['shared'][$path]--; + if ($this->acquiredLocks['shared'][$path] === 0) { + unset($this->acquiredLocks['shared'][$path]); + } } } else if ($type === self::LOCK_EXCLUSIVE) { unset($this->acquiredLocks['exclusive'][$path]); From 5da9f10af260b1ae05174ffaf0b4976e3892305e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 29 Apr 2016 09:23:36 +0200 Subject: [PATCH 263/286] Remove the password from the validateUserPass() method as well --- lib/private/log.php | 2 +- tests/lib/logger.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/private/log.php b/lib/private/log.php index 9a2a2da906eb2..71114ce77ef25 100644 --- a/lib/private/log.php +++ b/lib/private/log.php @@ -284,7 +284,7 @@ public function logException(\Exception $exception, array $context = array()) { 'File' => $exception->getFile(), 'Line' => $exception->getLine(), ); - $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']); + $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword|validateUserPass)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']); $msg = isset($context['message']) ? $context['message'] : 'Exception'; $msg .= ': ' . json_encode($exception); $this->error($msg, $context); diff --git a/tests/lib/logger.php b/tests/lib/logger.php index 9c9cd9e672866..e6a0abfbf28d5 100644 --- a/tests/lib/logger.php +++ b/tests/lib/logger.php @@ -107,4 +107,19 @@ public function testDetectcheckPassword($user, $password) { $this->assertContains('checkPassword(*** username and password replaced ***)', $logLine); } } + + /** + * @dataProvider userAndPasswordData + */ + public function testDetectvalidateUserPass($user, $password) { + $e = new \Exception('test'); + $this->logger->logException($e); + $logLines = $this->getLogs(); + + foreach($logLines as $logLine) { + $this->assertNotContains($user, $logLine); + $this->assertNotContains($password, $logLine); + $this->assertContains('validateUserPass(*** username and password replaced ***)', $logLine); + } + } } From 3c73e54eb97b4e7ba5633b0e650b4cc95ec24c4b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 23 May 2016 10:09:22 +0200 Subject: [PATCH 264/286] Make sure that installed is a boolean --- lib/private/updater.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/updater.php b/lib/private/updater.php index 55d9a5bed2b9a..fc852991a13c4 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -227,6 +227,7 @@ public function upgrade() { $this->emit('\OC\Updater', 'resetLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]); $this->config->setSystemValue('loglevel', $logLevel); + $this->config->setSystemValue('installed', true); return $success; } From b30f4c279949a4820a8ffabeec968d14d64d3e8a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 23 May 2016 10:09:36 +0200 Subject: [PATCH 265/286] Make sure we evaluate installed like we do it everywhere --- status.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/status.php b/status.php index 86f1f68dde1c6..4afabbf2cd184 100644 --- a/status.php +++ b/status.php @@ -31,8 +31,8 @@ $systemConfig = \OC::$server->getSystemConfig(); - $installed = $systemConfig->getValue('installed') == 1; - $maintenance = $systemConfig->getValue('maintenance', false); + $installed = (bool) $systemConfig->getValue('installed', false); + $maintenance = (bool) $systemConfig->getValue('maintenance', false); $values=array( 'installed'=>$installed, 'maintenance' => $maintenance, From cb8b4740e3f43b33682b8ddfe5936bdbd7eb0260 Mon Sep 17 00:00:00 2001 From: Carla Schroder Date: Mon, 23 May 2016 09:25:51 -0700 Subject: [PATCH 266/286] clarify filesystem_check_changes in config.sample.php --- config/config.sample.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 2bc1909887728..27552512a8ae1 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1127,8 +1127,9 @@ 'quota_include_external_storage' => false, /** - * Specifies how often the filesystem is checked for changes made outside - * ownCloud. + * Specifies how often the local filesystem (the ownCloud data/ directory, and + * NFS mounts in data/) is checked for changes made outside ownCloud. This + * does not apply to external storages. * * 0 -> Never check the filesystem for outside changes, provides a performance * increase when it's certain that no changes are made directly to the From f29f85709a58559167a93b5e8aa966faf9eb0d8a Mon Sep 17 00:00:00 2001 From: Piotr Filiciak Date: Fri, 20 May 2016 18:16:44 +0200 Subject: [PATCH 267/286] Http Range requests support in downloads Http range requests support is required for video preview --- apps/files/ajax/download.php | 11 +- .../lib/controllers/sharecontroller.php | 13 +- lib/private/files.php | 143 ++++++++++++++++-- lib/private/files/view.php | 34 +++++ lib/public/Files/UnseekableException.php | 34 +++++ 5 files changed, 220 insertions(+), 15 deletions(-) create mode 100644 lib/public/Files/UnseekableException.php diff --git a/apps/files/ajax/download.php b/apps/files/ajax/download.php index 28ce4c6542e40..aedd86b641978 100644 --- a/apps/files/ajax/download.php +++ b/apps/files/ajax/download.php @@ -50,4 +50,13 @@ setcookie('ocDownloadStarted', $_GET['downloadStartSecret'], time() + 20, '/'); } -OC_Files::get($dir, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); +$server_params = array( 'head' => \OC::$server->getRequest()->getMethod() == 'HEAD' ); + +/** + * Http range requests support + */ +if (isset($_SERVER['HTTP_RANGE'])) { + $server_params['range'] = \OC::$server->getRequest()->getHeader('Range'); +} + +OC_Files::get($dir, $files_list, $server_params); diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index ea024b6016a1b..838332b8c8329 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -478,16 +478,25 @@ public function downloadShare($token, $files = null, $path = '', $downloadStartS $this->emitAccessShareHook($share); + $server_params = array( 'head' => $this->request->getMethod() == 'HEAD' ); + + /** + * Http range requests support + */ + if (isset($_SERVER['HTTP_RANGE'])) { + $server_params['range'] = $this->request->getHeader('Range'); + } + // download selected files if (!is_null($files) && $files !== '') { // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well // after dispatching the request which results in a "Cannot modify header information" notice. - OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); + OC_Files::get($originalSharePath, $files_list, $server_params); exit(); } else { // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well // after dispatching the request which results in a "Cannot modify header information" notice. - OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $_SERVER['REQUEST_METHOD'] == 'HEAD'); + OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params); exit(); } } diff --git a/lib/private/files.php b/lib/private/files.php index 9b6a1a4465f6a..6327a0895e6b2 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -16,6 +16,7 @@ * @author Thomas Müller * @author Victor Dubiniuk * @author Vincent Petry + * @author Piotr Filiciak * * @copyright Copyright (c) 2016, ownCloud, Inc. * @license AGPL-3.0 @@ -49,20 +50,48 @@ class OC_Files { const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB + + private static $MULTIPART_BOUNDARY = ''; + + /** + * @return string + */ + private static function getBoundary() { + if (empty(self::$MULTIPART_BOUNDARY)) { + self::$MULTIPART_BOUNDARY = md5(mt_rand()); + } + return self::$MULTIPART_BOUNDARY; + } + /** * @param string $filename * @param string $name + * @param array $rangeArray ('from'=>int,'to'=>int), ... */ - private static function sendHeaders($filename, $name) { + private static function sendHeaders($filename, $name, array $rangeArray) { OC_Response::setContentDispositionHeader($name, 'attachment'); - header('Content-Transfer-Encoding: binary'); + header('Content-Transfer-Encoding: binary', true); OC_Response::disableCaching(); $fileSize = \OC\Files\Filesystem::filesize($filename); $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)); - header('Content-Type: '.$type); if ($fileSize > -1) { - OC_Response::setContentLengthHeader($fileSize); + if (!empty($rangeArray)) { + header('HTTP/1.1 206 Partial Content', true); + header('Accept-Ranges: bytes', true); + if (count($rangeArray) > 1) { + $type = 'multipart/byteranges; boundary='.self::getBoundary(); + // no Content-Length header here + } + else { + header(sprintf('Content-Range: bytes %d-%d/%d', $rangeArray[0]['from'], $rangeArray[0]['to'], $fileSize), true); + OC_Response::setContentLengthHeader($rangeArray[0]['to'] - $rangeArray[0]['from'] + 1); + } + } + else { + OC_Response::setContentLengthHeader($fileSize); + } } + header('Content-Type: '.$type, true); } /** @@ -70,9 +99,9 @@ private static function sendHeaders($filename, $name) { * * @param string $dir * @param string $files ; separated list of files to download - * @param boolean $onlyHeader ; boolean to only send header of the request + * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header */ - public static function get($dir, $files, $onlyHeader = false) { + public static function get($dir, $files, $params = array( 'head' => false )) { $view = \OC\Files\Filesystem::getView(); $getType = self::FILE; @@ -86,7 +115,7 @@ public static function get($dir, $files, $onlyHeader = false) { if (!is_array($files)) { $filename = $dir . '/' . $files; if (!$view->is_dir($filename)) { - self::getSingleFile($view, $dir, $files, $onlyHeader); + self::getSingleFile($view, $dir, $files, $params); return; } } @@ -156,19 +185,78 @@ public static function get($dir, $files, $onlyHeader = false) { } } + /** + * @param string $rangeHeaderPos + * @param int $fileSize + * @return array $rangeArray ('from'=>int,'to'=>int), ... + */ + private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) { + $rArray=split(',', $rangeHeaderPos); + $minOffset = 0; + $ind = 0; + + $rangeArray = array(); + + foreach ($rArray as $value) { + $ranges = explode('-', $value); + if (is_numeric($ranges[0])) { + if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999 + $ranges[0] = $minOffset; + } + if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999 + $ind--; + $ranges[0] = $rangeArray[$ind]['from']; + } + } + + if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) { + // case: x-x + if ($ranges[1] >= $fileSize) { + $ranges[1] = $fileSize-1; + } + $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize ); + $minOffset = $ranges[1] + 1; + if ($minOffset >= $fileSize) { + break; + } + } + elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) { + // case: x- + $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize ); + break; + } + elseif (is_numeric($ranges[1])) { + // case: -x + if ($ranges[1] > $fileSize) { + $ranges[1] = $fileSize; + } + $rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize ); + break; + } + } + return $rangeArray; + } + /** * @param View $view * @param string $name * @param string $dir - * @param boolean $onlyHeader + * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header */ - private static function getSingleFile($view, $dir, $name, $onlyHeader) { + private static function getSingleFile($view, $dir, $name, $params) { $filename = $dir . '/' . $name; OC_Util::obEnd(); $view->lockFile($filename, ILockingProvider::LOCK_SHARED); + + $rangeArray = array(); + if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') { + $rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), + \OC\Files\Filesystem::filesize($filename)); + } + if (\OC\Files\Filesystem::isReadable($filename)) { - self::sendHeaders($filename, $name); + self::sendHeaders($filename, $name, $rangeArray); } elseif (!\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OC_Template('', '404', 'guest'); @@ -178,10 +266,41 @@ private static function getSingleFile($view, $dir, $name, $onlyHeader) { header("HTTP/1.0 403 Forbidden"); die('403 Forbidden'); } - if ($onlyHeader) { + if (isset($params['head']) && $params['head']) { return; } - $view->readfile($filename); + if (!empty($rangeArray)) { + try { + if (count($rangeArray) == 1) { + $view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']); + } + else { + // check if file is seekable (if not throw UnseekableException) + // we have to check it before body contents + $view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']); + + $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)); + + foreach ($rangeArray as $range) { + echo "\r\n--".self::getBoundary()."\r\n". + "Content-type: ".$type."\r\n". + "Content-range: bytes ".$range['from']."-".$range['to']."/".$range['size']."\r\n\r\n"; + $view->readfilePart($filename, $range['from'], $range['to']); + } + echo "\r\n--".self::getBoundary()."--\r\n"; + } + } catch (\OCP\Files\UnseekableException $ex) { + // file is unseekable + header_remove('Accept-Ranges'); + header_remove('Content-Range'); + header("HTTP/1.1 200 OK"); + self::sendHeaders($filename, $name, array()); + $view->readfile($filename); + } + } + else { + $view->readfile($filename); + } } /** diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 02c12c80a2071..5a66fdc5ffa2f 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -53,6 +53,7 @@ use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\ReservedWordException; +use OCP\Files\UnseekableException; use OCP\Files\Storage\ILockingStorage; use OCP\IUser; use OCP\Lock\ILockingProvider; @@ -423,6 +424,39 @@ public function readfile($path) { return false; } + /** + * @param string $path + * @param int $from + * @param int $to + * @return bool|mixed + * @throws \OCP\Files\InvalidPathException, \OCP\Files\UnseekableException + */ + public function readfilePart($path, $from, $to) { + $this->assertPathLength($path); + @ob_end_clean(); + $handle = $this->fopen($path, 'rb'); + if ($handle) { + if (fseek($handle, $from) === 0) { + $chunkSize = 8192; // 8 kB chunks + $end = $to + 1; + while (!feof($handle) && ftell($handle) < $end) { + $len = $end-ftell($handle); + if ($len > $chunkSize) { + $len = $chunkSize; + } + echo fread($handle, $len); + flush(); + } + $size = ftell($handle) - $from; + return $size; + } + else { + throw new \OCP\Files\UnseekableException('fseek error'); + } + } + return false; + } + /** * @param string $path * @return mixed diff --git a/lib/public/Files/UnseekableException.php b/lib/public/Files/UnseekableException.php new file mode 100644 index 0000000000000..fda936976903f --- /dev/null +++ b/lib/public/Files/UnseekableException.php @@ -0,0 +1,34 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +/** + * Public interface of ownCloud for apps to use. + * Files/UnseekableException class + */ + +// use OCP namespace for all classes that are considered public. +// This means that they should be used by apps instead of the internal ownCloud classes +namespace OCP\Files; + +/** + * Exception for seek problem + */ +class UnseekableException extends \Exception {} From 7a791c54726001fdebc8d891d8852139cc010fd9 Mon Sep 17 00:00:00 2001 From: Piotr Filiciak Date: Mon, 23 May 2016 15:17:00 +0200 Subject: [PATCH 268/286] Code style and doc fix --- lib/private/files.php | 12 ++++++------ lib/private/files/view.php | 8 ++++---- lib/public/Files/UnseekableException.php | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/private/files.php b/lib/private/files.php index 6327a0895e6b2..ad5ba6d94ae01 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -51,16 +51,16 @@ class OC_Files { const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB - private static $MULTIPART_BOUNDARY = ''; + private static $multipartBoundary = ''; /** * @return string */ private static function getBoundary() { - if (empty(self::$MULTIPART_BOUNDARY)) { - self::$MULTIPART_BOUNDARY = md5(mt_rand()); + if (empty(self::$multipartBoundary)) { + self::$multipartBoundary = md5(mt_rand()); } - return self::$MULTIPART_BOUNDARY; + return self::$multipartBoundary; } /** @@ -101,7 +101,7 @@ private static function sendHeaders($filename, $name, array $rangeArray) { * @param string $files ; separated list of files to download * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header */ - public static function get($dir, $files, $params = array( 'head' => false )) { + public static function get($dir, $files, $params = null) { $view = \OC\Files\Filesystem::getView(); $getType = self::FILE; @@ -115,7 +115,7 @@ public static function get($dir, $files, $params = array( 'head' => false )) { if (!is_array($files)) { $filename = $dir . '/' . $files; if (!$view->is_dir($filename)) { - self::getSingleFile($view, $dir, $files, $params); + self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params); return; } } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 5a66fdc5ffa2f..66562064ebeb8 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -429,7 +429,8 @@ public function readfile($path) { * @param int $from * @param int $to * @return bool|mixed - * @throws \OCP\Files\InvalidPathException, \OCP\Files\UnseekableException + * @throws \OCP\Files\InvalidPathException + * @throws \OCP\Files\UnseekableException */ public function readfilePart($path, $from, $to) { $this->assertPathLength($path); @@ -450,9 +451,8 @@ public function readfilePart($path, $from, $to) { $size = ftell($handle) - $from; return $size; } - else { - throw new \OCP\Files\UnseekableException('fseek error'); - } + + throw new \OCP\Files\UnseekableException('fseek error'); } return false; } diff --git a/lib/public/Files/UnseekableException.php b/lib/public/Files/UnseekableException.php index fda936976903f..b59f844ce2f34 100644 --- a/lib/public/Files/UnseekableException.php +++ b/lib/public/Files/UnseekableException.php @@ -30,5 +30,6 @@ /** * Exception for seek problem + * @since 9.1.0 */ class UnseekableException extends \Exception {} From 8c439643a168ff2214974c4834dc3894553fa403 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 25 May 2016 11:13:06 +0200 Subject: [PATCH 269/286] Lowercase class name for unseekableexception Because 9.1 was PSR-4 and the backport goes back to the old style --- .../UnseekableException.php => files/unseekableexception.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/public/{Files/UnseekableException.php => files/unseekableexception.php} (100%) diff --git a/lib/public/Files/UnseekableException.php b/lib/public/files/unseekableexception.php similarity index 100% rename from lib/public/Files/UnseekableException.php rename to lib/public/files/unseekableexception.php From 35c32ca721bd9541ac464689fb0c1c0876bb4a40 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 25 May 2016 13:40:34 +0200 Subject: [PATCH 270/286] Improve isLocal performance for SharedStorage --- apps/files_sharing/lib/sharedstorage.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 8f4888d20e21d..502f2bfbae679 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -737,9 +737,7 @@ public function setAvailability($available) { public function isLocal() { $this->init(); - $ownerPath = $this->ownerView->getPath($this->share['item_source']); - list($targetStorage) = $this->ownerView->resolvePath($ownerPath); - return $targetStorage->isLocal(); + return $this->sourceStorage->isLocal(); } public function getSourceStorage() { From 002a7f829461350a33496cd3a78b4e611d5d2727 Mon Sep 17 00:00:00 2001 From: Piotr Filiciak Date: Wed, 25 May 2016 15:38:48 +0200 Subject: [PATCH 271/286] replaced UnseekableException => NotPermittedException --- lib/private/files.php | 4 +-- lib/private/files/view.php | 6 ++-- lib/public/files/unseekableexception.php | 35 ------------------------ 3 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 lib/public/files/unseekableexception.php diff --git a/lib/private/files.php b/lib/private/files.php index ad5ba6d94ae01..639fd30b55486 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -275,7 +275,7 @@ private static function getSingleFile($view, $dir, $name, $params) { $view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']); } else { - // check if file is seekable (if not throw UnseekableException) + // check if file is seekable (if not throw NotPermittedException) // we have to check it before body contents $view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']); @@ -289,7 +289,7 @@ private static function getSingleFile($view, $dir, $name, $params) { } echo "\r\n--".self::getBoundary()."--\r\n"; } - } catch (\OCP\Files\UnseekableException $ex) { + } catch (\OCP\Files\NotPermittedException $ex) { // file is unseekable header_remove('Accept-Ranges'); header_remove('Content-Range'); diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 66562064ebeb8..bf49ea2148dff 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -53,7 +53,7 @@ use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\ReservedWordException; -use OCP\Files\UnseekableException; +use OCP\Files\NotPermittedException; use OCP\Files\Storage\ILockingStorage; use OCP\IUser; use OCP\Lock\ILockingProvider; @@ -430,7 +430,7 @@ public function readfile($path) { * @param int $to * @return bool|mixed * @throws \OCP\Files\InvalidPathException - * @throws \OCP\Files\UnseekableException + * @throws \OCP\Files\NotPermittedException */ public function readfilePart($path, $from, $to) { $this->assertPathLength($path); @@ -452,7 +452,7 @@ public function readfilePart($path, $from, $to) { return $size; } - throw new \OCP\Files\UnseekableException('fseek error'); + throw new \OCP\Files\NotPermittedException('fseek error'); } return false; } diff --git a/lib/public/files/unseekableexception.php b/lib/public/files/unseekableexception.php deleted file mode 100644 index b59f844ce2f34..0000000000000 --- a/lib/public/files/unseekableexception.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -/** - * Public interface of ownCloud for apps to use. - * Files/UnseekableException class - */ - -// use OCP namespace for all classes that are considered public. -// This means that they should be used by apps instead of the internal ownCloud classes -namespace OCP\Files; - -/** - * Exception for seek problem - * @since 9.1.0 - */ -class UnseekableException extends \Exception {} From b8c4233c7d78718db9160977073536c144411022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 30 May 2016 11:19:57 +0200 Subject: [PATCH 272/286] don't fail on "bad signature" during login. Most likely this happens because (#24837) the login password changed at the user back-end (e.g ldap). Such failures will be handled after login correctly by allowing the user to adjust the passwords --- apps/encryption/lib/keymanager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index 0accfb7900ac5..6720d19fe1b10 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -356,6 +356,13 @@ public function init($uid, $passPhrase) { return false; } catch (DecryptionFailedException $e) { return false; + } catch (\Exception $e) { + $this->log->warning( + 'Could not decrypt the private key from user "' . $uid . '"" during login. ' . + 'Assume password change on the user back-end. Error message: ' + . $e->getMessage() + ); + return false; } if ($privateKey) { From da0ee2ce3a74bb02720cb68d9a56a1a5011b6e43 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 30 May 2016 11:31:39 +0200 Subject: [PATCH 273/286] dont update search onResize (#24848) --- apps/files/js/filelist.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 47aff25678610..d34368a74d8b6 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -475,8 +475,6 @@ this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10); this.$table.find('>thead').width($('#app-content').width() - OC.Util.getScrollBarWidth()); - - this.updateSearch(); }, /** From abd8475336ef802e809d2ac5864353e2f7084093 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 30 May 2016 14:50:45 +0200 Subject: [PATCH 274/286] Only show message in the UI when the checker is enabled (#24773) --- lib/private/templatelayout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index 5afbd4495c457..df91ec9b41b91 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -72,7 +72,7 @@ public function __construct( $renderAs, $appId = '' ) { // Code integrity notification $integrityChecker = \OC::$server->getIntegrityCodeChecker(); - if(\OC_User::isAdminUser(\OC_User::getUser()) && !$integrityChecker->hasPassedCheck()) { + if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) { \OCP\Util::addScript('core', 'integritycheck-failed-notification'); } From 2516d07fdd2f915c5b7f9c3bc34c5c1c865390a4 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 31 May 2016 08:15:18 +0200 Subject: [PATCH 275/286] =?UTF-8?q?[stable9]=C2=A0Properly=20check=20for?= =?UTF-8?q?=20mbstring=20extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mb_detect_encoding is in the fallback we ship in the polyfill library, mb_strcut is not. Thus this lead to a false positive and ownCloud would just break. --- lib/private/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/util.php b/lib/private/util.php index 88d78ad83c635..894fe9aa59f58 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -731,7 +731,7 @@ public static function checkServer(\OCP\IConfig $config) { ), 'functions' => [ 'xml_parser_create' => 'libxml', - 'mb_detect_encoding' => 'mb multibyte', + 'mb_strcut' => 'mb multibyte', 'ctype_digit' => 'ctype', 'json_encode' => 'JSON', 'gd_info' => 'GD', From 9070fd2c03c2c922065baa7cd903ed6e97c2d514 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 31 May 2016 16:11:51 +0200 Subject: [PATCH 276/286] Add a warning when the transaction isolation level is not READ_COMMITED (#24915) --- settings/admin.php | 13 +++++++++++++ settings/templates/admin.php | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/settings/admin.php b/settings/admin.php index e0d3a907f4779..42ca7e3525fcb 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -100,6 +100,19 @@ $template->assign('encryptionReady', \OC::$server->getEncryptionManager()->isReady()); $template->assign('externalBackendsEnabled', $externalBackends); +/** @var \Doctrine\DBAL\Connection $connection */ +$connection = \OC::$server->getDatabaseConnection(); +try { + if ($connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { + $template->assign('invalidTransactionIsolationLevel', false); + } else { + $template->assign('invalidTransactionIsolationLevel', $connection->getTransactionIsolation() !== \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED); + } +} catch (\Doctrine\DBAL\DBALException $e) { + // ignore + $template->assign('invalidTransactionIsolationLevel', false); +} + $encryptionModules = \OC::$server->getEncryptionManager()->getEncryptionModules(); $defaultEncryptionModuleId = \OC::$server->getEncryptionManager()->getDefaultEncryptionModuleId(); diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 2f4461589da73..616ac2ab852fd 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -97,6 +97,15 @@ +
  • + t('Your database does not run with "READ COMMITED" transaction isolation level. This can cause problems when multiple actions are executed in parallel.')); ?> +
  • + From 2ca5f3f95787d9d40cf57f5e335ffd6107ebd781 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 27 May 2016 14:48:34 +0200 Subject: [PATCH 277/286] trigger size calculation after scanning --- lib/private/files/utils/scanner.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php index b013cbecabc63..f05805fe94a73 100644 --- a/lib/private/files/utils/scanner.php +++ b/lib/private/files/utils/scanner.php @@ -25,6 +25,7 @@ namespace OC\Files\Utils; +use OC\Files\Cache\Cache; use OC\Files\Filesystem; use OC\ForbiddenException; use OC\Hooks\PublicEmitter; @@ -170,6 +171,11 @@ public function scan($dir = '') { } try { $scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); + $cache = $storage->getCache(); + if ($cache instanceof Cache) { + // only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner + $cache->correctFolderSize($relativePath); + } } catch (StorageNotAvailableException $e) { $this->logger->error('Storage ' . $storage->getId() . ' not available'); $this->logger->logException($e); From 69e54bde1f065b220a9b083060c5b7c45dec6483 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 24 May 2016 09:23:25 +0200 Subject: [PATCH 278/286] Allow opening the password reset link in a new window when its a URL --- core/templates/login.php | 2 +- lib/private/util.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/templates/login.php b/core/templates/login.php index a12008295c47f..57ced760088db 100644 --- a/core/templates/login.php +++ b/core/templates/login.php @@ -57,7 +57,7 @@

    - + t('Wrong password. Reset it?')); ?> diff --git a/lib/private/util.php b/lib/private/util.php index 894fe9aa59f58..488eb8facfd59 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -968,7 +968,8 @@ public static function displayLoginPage($errors = array(), $messages = []) { } $parameters['canResetPassword'] = true; - if (!\OC::$server->getSystemConfig()->getValue('lost_password_link')) { + $parameters['resetPasswordLink'] = \OC::$server->getSystemConfig()->getValue('lost_password_link', ''); + if (!$parameters['resetPasswordLink']) { if (isset($_REQUEST['user'])) { $user = \OC::$server->getUserManager()->get($_REQUEST['user']); if ($user instanceof IUser) { From a08c9b352638b0d1a6eed320e7dec352b393be2b Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Wed, 1 Jun 2016 13:06:59 +0200 Subject: [PATCH 279/286] normalize path in getInternalPath --- lib/private/files/mount/mountpoint.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/private/files/mount/mountpoint.php b/lib/private/files/mount/mountpoint.php index b606c625cb148..58d8288c7b49c 100644 --- a/lib/private/files/mount/mountpoint.php +++ b/lib/private/files/mount/mountpoint.php @@ -188,6 +188,7 @@ public function getStorageId() { * @return string */ public function getInternalPath($path) { + $path = Filesystem::normalizePath($path); if ($this->mountPoint === $path or $this->mountPoint . '/' === $path) { $internalPath = ''; } else { From 8f04bf37939db43ee0e88503be41ee6243621a0c Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 1 Jun 2016 17:48:35 +0200 Subject: [PATCH 280/286] Backport of share id as string fix --- apps/files_sharing/lib/helper.php | 4 ++-- lib/private/share/share.php | 2 +- tests/lib/share/share.php | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php index e857974ae74d5..ee6af9939ed17 100644 --- a/apps/files_sharing/lib/helper.php +++ b/apps/files_sharing/lib/helper.php @@ -131,7 +131,7 @@ public static function authenticate($linkItem, $password = null) { $newHash = ''; if(\OC::$server->getHasher()->verify($password, $linkItem['share_with'], $newHash)) { // Save item id in session for future requests - \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']); + \OC::$server->getSession()->set('public_link_authenticated', (string) $linkItem['id']); /** * FIXME: Migrate old hashes to new hash format @@ -161,7 +161,7 @@ public static function authenticate($linkItem, $password = null) { else { // not authenticated ? if ( ! \OC::$server->getSession()->exists('public_link_authenticated') - || \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id']) { + || \OC::$server->getSession()->get('public_link_authenticated') !== (string)$linkItem['id']) { return false; } } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 3dcfa14079b83..d6bcbf902d54a 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -2477,7 +2477,7 @@ public static function checkPasswordProtectedShare(array $linkItem) { } if ( \OC::$server->getSession()->exists('public_link_authenticated') - && \OC::$server->getSession()->get('public_link_authenticated') === $linkItem['id'] ) { + && \OC::$server->getSession()->get('public_link_authenticated') === (string)$linkItem['id'] ) { return true; } diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php index 4519c33f9d189..859f017600de9 100644 --- a/tests/lib/share/share.php +++ b/tests/lib/share/share.php @@ -1144,7 +1144,7 @@ public function testUnshareAll() { * @param $item */ public function testCheckPasswordProtectedShare($expected, $item) { - \OC::$server->getSession()->set('public_link_authenticated', 100); + \OC::$server->getSession()->set('public_link_authenticated', '100'); $result = \OCP\Share::checkPasswordProtectedShare($item); $this->assertEquals($expected, $result); } @@ -1156,8 +1156,12 @@ function checkPasswordProtectedShareDataProvider() { array(true, array('share_with' => '')), array(true, array('share_with' => '1234567890', 'share_type' => '1')), array(true, array('share_with' => '1234567890', 'share_type' => 1)), + array(true, array('share_with' => '1234567890', 'share_type' => '3', 'id' => '100')), + array(true, array('share_with' => '1234567890', 'share_type' => 3, 'id' => '100')), array(true, array('share_with' => '1234567890', 'share_type' => '3', 'id' => 100)), array(true, array('share_with' => '1234567890', 'share_type' => 3, 'id' => 100)), + array(false, array('share_with' => '1234567890', 'share_type' => '3', 'id' => '101')), + array(false, array('share_with' => '1234567890', 'share_type' => 3, 'id' => '101')), array(false, array('share_with' => '1234567890', 'share_type' => '3', 'id' => 101)), array(false, array('share_with' => '1234567890', 'share_type' => 3, 'id' => 101)), ); From 0efe3ba62eeb0faf130bc92c4ca885139bc14d0a Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 1 Jun 2016 21:31:14 +0200 Subject: [PATCH 281/286] Use a capped memory cache for the user/group cache For #24403 When upgrading huge installations this can lead to memory problems as the cache will only grow and grow. Capping this memory will make sure we don't run out while during normal operation still basically cache everything. --- apps/user_ldap/group_ldap.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index eba39ca50f778..891c807cd7476 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -36,6 +36,7 @@ use OCA\user_ldap\lib\Access; use OCA\user_ldap\lib\BackendUtility; +use OC\Cache\CappedMemoryCache; class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { protected $enabled = false; @@ -43,12 +44,12 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface { /** * @var string[] $cachedGroupMembers array of users with gid as key */ - protected $cachedGroupMembers = array(); + protected $cachedGroupMembers; /** * @var string[] $cachedGroupsByMember array of groups with uid as key */ - protected $cachedGroupsByMember = array(); + protected $cachedGroupsByMember; public function __construct(Access $access) { parent::__construct($access); @@ -57,6 +58,9 @@ public function __construct(Access $access) { if(!empty($filter) && !empty($gassoc)) { $this->enabled = true; } + + $this->cachedGroupMembers = new CappedMemoryCache(); + $this->cachedGroupsByMember = new CappedMemoryCache(); } /** From 825d1c105d0ff256d214a5bdc3c4c2d7304c2499 Mon Sep 17 00:00:00 2001 From: Dmitry Popov Date: Tue, 24 May 2016 15:09:05 +0300 Subject: [PATCH 282/286] My fix for #24272, #23613, File not found when single file in a folder (#24800) * Fixed group share searching for members of multiple group. Issue #11808. * Fixed group share searching, continued. Avoid searching for empty group list in getItemSharedWithUser(). Broke tests in previous commit, #12030. * Simler check for group count. * Fix for https://github.com/owncloud/core/issues/24783 , described there * Now it's #24272, 24783 was a duplicate. Previous change was also not very good. Now we don't create ZIP with a single file inside. --- apps/files/js/filelist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index d34368a74d8b6..b79dd0f66f2a8 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -629,7 +629,7 @@ _onClickDownloadSelected: function(event) { var files; var dir = this.getCurrentDirectory(); - if (this.isAllSelected()) { + if (this.isAllSelected() && this.getSelectedFiles().length > 1) { files = OC.basename(dir); dir = OC.dirname(dir) || '/'; } From c433218aa1fb428ae88f49a3b291cd294061c5e1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 1 Jun 2016 16:30:37 +0200 Subject: [PATCH 283/286] Catch the ForbiddenException to make sure it gets handled --- apps/dav/lib/connector/sabre/filesplugin.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php index e973b4e86826e..bf9bee02578ea 100644 --- a/apps/dav/lib/connector/sabre/filesplugin.php +++ b/apps/dav/lib/connector/sabre/filesplugin.php @@ -27,6 +27,7 @@ namespace OCA\DAV\Connector\Sabre; +use OCP\Files\ForbiddenException; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\IFile; use \Sabre\DAV\PropFind; @@ -257,6 +258,8 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) } } catch (StorageNotAvailableException $e) { return false; + } catch (ForbiddenException $e) { + return false; } return false; }); From afb4c1e694b45810780b5ac17b7f35940c604e0c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 6 Jun 2016 13:48:38 +0200 Subject: [PATCH 284/286] Allow public upload when the quota is unlimited (#24988) --- apps/files_sharing/lib/controllers/sharecontroller.php | 2 +- lib/private/helper.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index 838332b8c8329..982ce1154a3f1 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -314,7 +314,7 @@ public function showShare($token, $path = '') { * The OC_Util methods require a view. This just uses the node API */ $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath()); - if ($freeSpace !== \OCP\Files\FileInfo::SPACE_UNKNOWN) { + if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) { $freeSpace = max($freeSpace, 0); } else { $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188 diff --git a/lib/private/helper.php b/lib/private/helper.php index 70c50bb7b4b9a..7a17352024915 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -500,7 +500,7 @@ public static function maxUploadFilesize($dir, $freeSpace = null) { */ public static function freeSpace($dir) { $freeSpace = \OC\Files\Filesystem::free_space($dir); - if ($freeSpace !== \OCP\Files\FileInfo::SPACE_UNKNOWN) { + if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) { $freeSpace = max($freeSpace, 0); return $freeSpace; } else { From 34ad3f7ada1363b887b58f171ba1fd5ba71a3447 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Mon, 6 Jun 2016 18:45:27 +0200 Subject: [PATCH 285/286] Remove "Help" link from personal sidebar At the moment we want to hide the help link from the personal sidebar as it contains the original ownCloud documentation. Once we have our own documentation with our proper branding and so on we can reenable this. --- lib/private/app.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/private/app.php b/lib/private/app.php index 5d0909de2a57a..a126b5b0495e5 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -381,7 +381,9 @@ public static function getSettingsNavigation() { $settings = array(); // by default, settings only contain the help menu - if (OC_Util::getEditionString() === '' && + /* + * FIXME: Add help sidebar back once documentation is properly branded. + * if (OC_Util::getEditionString() === '' && \OC::$server->getSystemConfig()->getValue('knowledgebaseenabled', true) == true ) { $settings = array( @@ -393,7 +395,7 @@ public static function getSettingsNavigation() { "icon" => $urlGenerator->imagePath("settings", "help.svg") ) ); - } + }*/ // if the user is logged-in if (OC_User::isLoggedIn()) { From bd82cd8b2ef8739f89343abb7cbb2880fccbb7ef Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 7 Jun 2016 19:53:35 +0200 Subject: [PATCH 286/286] Print error message again, when 3rdparty submodule is not initialized - old code used Response which attempted to use OC::$server which is not and cannot be intialised at this part of the code. --- lib/base.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index e77a07239c432..b24acf09f60e2 100644 --- a/lib/base.php +++ b/lib/base.php @@ -513,7 +513,9 @@ public static function init() { } catch (\RuntimeException $e) { if (!self::$CLI) { - OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + $claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']); + $protocol = in_array($claimedProtocol, ['HTTP/1.0', 'HTTP/1.1', 'HTTP/2']) ? $claimedProtocol : 'HTTP/1.1'; + header($protocol . ' ' . OC_Response::STATUS_SERVICE_UNAVAILABLE); } // we can't use the template error page here, because this needs the // DI container which isn't available yet