diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2018-07-24 09:12:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-24 09:12:03 +0200 |
commit | b41d0d32e2183b8b241d3764f06a3b0f7d6b86c1 (patch) | |
tree | 915e14ceafed060f95255e8d2d7d4ad3ab3df7b5 /apps | |
parent | 241e5705cb85d24a9c3479c133fcc4d9c069d8c7 (diff) | |
parent | fee62fd20b01b08ffbc7120720ba3bad0a89be73 (diff) | |
download | nextcloud-server-b41d0d32e2183b8b241d3764f06a3b0f7d6b86c1.tar.gz nextcloud-server-b41d0d32e2183b8b241d3764f06a3b0f7d6b86c1.zip |
Merge pull request #10218 from nextcloud/share-comments
allow to add a personal note to a share
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/css/detailsView.scss | 6 | ||||
-rw-r--r-- | apps/files/css/files.scss | 3 | ||||
-rw-r--r-- | apps/files_sharing/css/public.scss | 5 | ||||
-rw-r--r-- | apps/files_sharing/css/sharetabview.scss | 367 | ||||
-rw-r--r-- | apps/files_sharing/lib/Controller/ShareAPIController.php | 15 | ||||
-rw-r--r-- | apps/files_sharing/lib/Controller/ShareController.php | 1 | ||||
-rw-r--r-- | apps/files_sharing/templates/public.php | 6 | ||||
-rw-r--r-- | apps/files_sharing/tests/Controller/ShareAPIControllerTest.php | 44 | ||||
-rw-r--r-- | apps/files_sharing/tests/Controller/ShareControllerTest.php | 5 | ||||
-rw-r--r-- | apps/sharebymail/lib/ShareByMailProvider.php | 61 | ||||
-rw-r--r-- | apps/sharebymail/tests/ShareByMailProviderTest.php | 18 |
11 files changed, 371 insertions, 160 deletions
diff --git a/apps/files/css/detailsView.scss b/apps/files/css/detailsView.scss index e0c1bbfa095..f64a3702850 100644 --- a/apps/files/css/detailsView.scss +++ b/apps/files/css/detailsView.scss @@ -7,12 +7,6 @@ clear: both; } -#app-sidebar .mainFileInfoView { - margin-right: 20px; /* accommodate for close icon */ - float:left; - display:block; - width: 100%; -} #app-sidebar .mainFileInfoView .icon { display: inline-block; diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 2a71af038cf..017253fdf8e 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -94,7 +94,8 @@ @include icon-color('star-dark', 'files', $color-black, 2, true); } .nav-icon-sharingin, -.nav-icon-sharingout { +.nav-icon-sharingout, +.nav-icon-shareoverview { @include icon-color('share', 'files', $color-black); } .nav-icon-sharinglinks { diff --git a/apps/files_sharing/css/public.scss b/apps/files_sharing/css/public.scss index 2e788a06c40..583912ad236 100644 --- a/apps/files_sharing/css/public.scss +++ b/apps/files_sharing/css/public.scss @@ -169,3 +169,8 @@ thead { opacity: .57; margin-top: 10px; } + +#note { + text-align: center; + padding: 10px; +} diff --git a/apps/files_sharing/css/sharetabview.scss b/apps/files_sharing/css/sharetabview.scss index b4b64daff2b..83790c9ec4f 100644 --- a/apps/files_sharing/css/sharetabview.scss +++ b/apps/files_sharing/css/sharetabview.scss @@ -2,143 +2,242 @@ min-height: 100px; } -.shareTabView .oneline { - white-space: nowrap; - position: relative; -} - -.shareTabView .shareWithLoading { - padding-left: 10px; - right: 35px; - top: 0px; -} - -.shareTabView .shareWithConfirm, -.shareTabView .clipboardButton, -.shareTabView .linkPass .icon-loading-small { - position: absolute; - right: -7px; - top: -2px; - padding: 14px; -} - -.shareTabView .shareWithConfirm { - opacity: .5; -} - -.shareTabView .shareWithField:focus ~ .shareWithConfirm { - opacity: 1; -} - -.shareTabView .linkMore { - position: absolute; - right: -7px; - top: -4px; - padding: 14px; -} - -/* fix the popup menu because the button is shifted and then the menu is not aligned */ -.shareTabView .popovermenu.socialSharingMenu { - right: -7px; -} - -.shareTabView .popovermenu .clipboardButton { - position: relative; - top: initial; - right: initial; - padding: 0; -} - -.shareTabView label { - white-space: nowrap; -} - -.shareTabView input[type="checkbox"] { - margin: 0 3px 0 8px; - vertical-align: middle; -} - -.shareTabView input[type="text"].shareWithField, -.shareTabView input[type="text"].emailField, -.shareTabView input[type="text"].linkText, -.shareTabView input[type="password"] { - width: 100%; - box-sizing: border-box; - padding-right: 32px; - text-overflow: ellipsis; -} - -.shareTabView form { - font-size: 100%; - margin-left: 0; - margin-right: 0; -} - -#shareWithList { +.share-autocomplete-item { + display: flex; + .autocomplete-item-text { + margin-left: 10px; + margin-right: 10px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + line-height: 32px; + vertical-align: middle; + } +} + +.shareTabView { + .oneline { + white-space: nowrap; + position: relative; + } + .shareWithLoading { + padding-left: 10px; + right: 35px; + top: 0px; + } + .shareWithConfirm, + .clipboardButton, + .linkPass .icon-loading-small { + position: absolute; + right: 2px; + top: 6px; + padding: 14px; + } + .shareWithConfirm { + opacity: 0.5; + } + .shareWithField:focus ~ .shareWithConfirm { + opacity: 1; + } + .linkMore { + position: absolute; + right: -7px; + top: -4px; + padding: 14px; + } + .popovermenu { + .datepicker { + margin-left: 35px; + } + .clipboardButton { + position: relative; + top: initial; + right: initial; + padding: 0; + } + .share-add { + input.share-note-delete { + display: none; + border: none; + background-color: transparent; + width: 44px !important; + padding: 0; + flex: 0 0 44px; + margin-left: auto; + } + } + // note + .share-note-form { + span.icon-note { + position: relative; + } + textarea.share-note { + margin: 0; + width: 200px; + min-height: 70px; + resize: none; + + input.share-note-submit { + position: absolute; + width: 44px !important; + height: 44px; + bottom: 0px; + right: 10px; + margin: 0; + background-color: transparent; + border: none; + opacity: .7; + &:hover, + &:focus, + &:active { + opacity: 1; + } + } + } + // fix for popover link share + &.share-note-link { + margin-bottom: 10px; + } + } + } + .linkPass .icon-loading-small { + margin-right: 0px; + } + .icon { + background-size: 16px 16px; + } + .shareWithList .icon-loading-small:not(.hidden) + span, + .linkShareView .icon-loading-small:not(.hidden) + input + label:before { + /* Hide if loader is visible */ + display: none !important; + } + input { + &[type='checkbox'] { + margin: 0 3px 0 8px; + vertical-align: middle; + } + &[type='text'] { + &.shareWithField, + &.emailField { + width: 100%; + box-sizing: border-box; + padding-right: 32px; + text-overflow: ellipsis; + } + } + &[type='text'].linkText + &[type='password'].linkPassText, + &[type='password'].passwordField { + width: 180px !important; + } + } + form { + font-size: 100%; + margin-left: 0; + margin-right: 0; + } + // share note on the sidebar + .share-note { + border-radius: var(--border-radius); + margin-bottom: 10px; + margin-left: 37px; + } +} + +// Sharing tab users list +.shareWithList { list-style-type: none; - padding: 0 0 16px; -} - -#shareWithList > li { - padding-top: 5px; - padding-bottom: 5px; - white-space: normal; + display: flex; + flex-direction: column; + > li { + height: 44px; + white-space: normal; + display: inline-flex; + align-items: center; + position: relative; + .avatar { + width: 32px; + height: 32px; + background-color: var(--color-background-darker); + } + } + .unshare img { + vertical-align: text-bottom; + /* properly align icons */ + } + .sharingOptionsGroup { + margin-left: auto; + display: flex; + align-items: center; + // can edit label + > .shareOption > label { + padding: 13px; + padding-right: 0; + } + // more menu + > .share-menu { + position: relative; + display: block; + .icon-more { + padding: 14px; + height: 16px; + width: 16px; + opacity: .5; + display: block; + cursor: pointer; + } + &:hover, + &:focus, + &:active { + .icon-more { + opacity: .7;; + } + } + } + } + .username { + padding: 0 8px; + } +} + +.ui-autocomplete { + /* limit dropdown height to 4 1/2 entries */ + max-height: 200px; + overflow-y: auto; + overflow-x: hidden; + z-index: 1550 !important; +} + +.notCreatable { + padding-left: 12px; + padding-top: 12px; + color: var(--color-text-lighter); +} + +.contactsmenu-popover { + left: -6px; + right: auto; + padding: 3px 6px; + top: 100%; + margin-top: 0; + li.hidden { + display: none !important; + } + &:after { + left: 8px; + right: auto; + } +} + +.reshare, +#link label, +#expiration label { display: inline-flex; align-items: center; + .avatar { + margin-right: 5px; + } } -#shareWithList .unshare img { - vertical-align: text-bottom; /* properly align icons */ -} - -#shareWithList .sharingOptionsGroup > a .icon { - padding: 7px; - vertical-align: middle; - opacity: .5; -} - -#shareWithList .sharingOptionsGroup .popovermenu:after { - right: 3px; -} - -#shareWithList label input[type=checkbox] { - margin-left: 0; +.resharerInfoView.subView { position: relative; -} -#shareWithList .username { - padding-right: 8px; - white-space: nowrap; - text-overflow: ellipsis; - display: inline-block; - overflow: hidden; - vertical-align: middle; -} -#shareWithList li .sharingOptionsGroup > .shareOption > label { - padding: 6px; - margin-right: 8px; - vertical-align: text-top; -} - -.shareTabView .icon-loading-small { - display: inline-block; - z-index: 1; - vertical-align: text-top; -} - -.shareTabView .shareWithList .icon-loading-small:not(.hidden) + span, -.shareTabView .linkShareView .icon-loading-small:not(.hidden) + input + label:before { - /* Hide if loader is visible */ - display: none !important; -} - -.linkShareView { - margin-top: 16px; -} - -.shareTabView .linkPass .icon-loading-small { - margin-right: 0px; -} - -.shareTabView .icon { - background-size: 16px 16px; -} +}
\ No newline at end of file diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index d30d5a05a22..33782d21b5f 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -144,6 +144,7 @@ class ShareAPIController extends OCSController { 'expiration' => null, 'token' => null, 'uid_file_owner' => $share->getShareOwner(), + 'note' => $share->getNote(), 'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(), ]; @@ -698,17 +699,21 @@ class ShareAPIController extends OCSController { * @param string $password * @param string $publicUpload * @param string $expireDate + * @param string $note * @return DataResponse - * @throws OCSNotFoundException + * @throws LockedException + * @throws NotFoundException * @throws OCSBadRequestException * @throws OCSForbiddenException + * @throws OCSNotFoundException */ public function updateShare( string $id, int $permissions = null, string $password = null, string $publicUpload = null, - string $expireDate = null + string $expireDate = null, + string $note = null ): DataResponse { try { $share = $this->getShareById($id); @@ -722,10 +727,14 @@ class ShareAPIController extends OCSController { throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist')); } - if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) { + if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null && $note === null) { throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given')); } + if($note !== null) { + $share->setNote($note); + } + /* * expirationdate, password and publicUpload only make sense for link shares */ diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index 0b30a599c7f..bd1331a0908 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -262,6 +262,7 @@ class ShareController extends AuthPublicShareController { $shareTmpl['owner'] = $share->getShareOwner(); $shareTmpl['filename'] = $share->getNode()->getName(); $shareTmpl['directory_path'] = $share->getTarget(); + $shareTmpl['note'] = $share->getNote(); $shareTmpl['mimetype'] = $share->getNode()->getMimetype(); $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype()); $shareTmpl['dirToken'] = $this->getToken(); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 476f0851547..81729c179fc 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -29,6 +29,12 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size); <input type="hidden" name="filesize" value="<?php p($_['nonHumanFileSize']); ?>" id="filesize"> <?php endif; ?> <input type="hidden" name="maxSizeAnimateGif" value="<?php p($_['maxSizeAnimateGif']); ?>" id="maxSizeAnimateGif"> +<?php if (isset($_['note']) && $_['note'] !== '') : ?> + <div id="note"> + <?php p($l->t('Note:')); p(' ' . $_['note']); ?> + </div> +<?php endif; ?> + <?php if (!isset($_['hideFileList']) || (isset($_['hideFileList']) && $_['hideFileList'] === false)) { ?> <div id="files-public-content"> <div id="preview"> diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 5d376f2d4f7..30041c3a27b 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -238,7 +238,7 @@ class ShareAPIControllerTest extends TestCase { */ public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions, - $shareTime, $expiration, $parent, $target, $mail_send, $token=null, + $shareTime, $expiration, $parent, $target, $mail_send, $note = '', $token=null, $password=null) { $share = $this->getMockBuilder(IShare::class)->getMock(); $share->method('getId')->willReturn($id); @@ -248,6 +248,7 @@ class ShareAPIControllerTest extends TestCase { $share->method('getShareOwner')->willReturn($shareOwner); $share->method('getNode')->willReturn($path); $share->method('getPermissions')->willReturn($permissions); + $share->method('getNote')->willReturn($note); $time = new \DateTime(); $time->setTimestamp($shareTime); $share->method('getShareTime')->willReturn($time); @@ -310,7 +311,8 @@ class ShareAPIControllerTest extends TestCase { null, 6, 'target', - 0 + 0, + 'personal note' ); $expected = [ 'id' => 100, @@ -334,6 +336,7 @@ class ShareAPIControllerTest extends TestCase { 'storage' => 101, 'mail_send' => 0, 'uid_file_owner' => 'ownerId', + 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myMimeType', ]; @@ -352,7 +355,8 @@ class ShareAPIControllerTest extends TestCase { null, 6, 'target', - 0 + 0, + 'personal note' ); $expected = [ 'id' => 101, @@ -376,6 +380,7 @@ class ShareAPIControllerTest extends TestCase { 'storage' => 101, 'mail_send' => 0, 'uid_file_owner' => 'ownerId', + 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myFolderMimeType', ]; @@ -396,6 +401,7 @@ class ShareAPIControllerTest extends TestCase { 6, 'target', 0, + 'personal note', 'token', 'password' ); @@ -422,6 +428,7 @@ class ShareAPIControllerTest extends TestCase { 'mail_send' => 0, 'url' => 'url', 'uid_file_owner' => 'ownerId', + 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myFolderMimeType', ]; @@ -455,7 +462,7 @@ class ShareAPIControllerTest extends TestCase { ->willReturn(true); $this->shareManager - ->expects($this->once()) + ->expects($this->any()) ->method('getShareById') ->with($share->getFullId(), 'currentUser') ->willReturn($share); @@ -501,6 +508,8 @@ class ShareAPIControllerTest extends TestCase { ['group', $group], ])); + $d = $ocs->getShare($share->getId())->getData()[0]; + $this->assertEquals($result, $ocs->getShare($share->getId())->getData()[0]); } @@ -1810,9 +1819,10 @@ class ShareAPIControllerTest extends TestCase { ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); - /* User backend down */ + // User backend down $result[] = [ [ 'id' => 42, @@ -1836,12 +1846,12 @@ class ShareAPIControllerTest extends TestCase { 'file_target' => 'myTarget', 'share_with' => 'recipient', 'share_with_displayname' => 'recipient', + 'note' => 'personal note', 'mail_send' => 0, 'mimetype' => 'myMimeType', ], $share, [], false ]; - - /* User backend up */ + // User backend up $result[] = [ [ 'id' => 42, @@ -1855,6 +1865,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'ownerDN', + 'note' => 'personal note', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -1883,9 +1894,9 @@ class ShareAPIControllerTest extends TestCase { ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); - - /* User backend down */ + // User backend down $result[] = [ [ 'id' => 42, @@ -1899,6 +1910,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => 'personal note', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -1915,6 +1927,7 @@ class ShareAPIControllerTest extends TestCase { ]; // with existing group + $share = \OC::$server->getShareManager()->newShare(); $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setSharedWith('recipientGroup') @@ -1924,6 +1937,7 @@ class ShareAPIControllerTest extends TestCase { ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); $result[] = [ @@ -1939,6 +1953,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => 'personal note', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -1964,6 +1979,7 @@ class ShareAPIControllerTest extends TestCase { ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); $result[] = [ [ @@ -1978,6 +1994,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => 'personal note', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -2004,6 +2021,7 @@ class ShareAPIControllerTest extends TestCase { ->setPassword('mypassword') ->setExpirationDate(new \DateTime('2001-01-02T00:00:00')) ->setToken('myToken') + ->setNote('personal note') ->setId(42); $result[] = [ @@ -2019,6 +2037,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => 'myToken', 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => 'personal note', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -2044,6 +2063,7 @@ class ShareAPIControllerTest extends TestCase { ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); $result[] = [ @@ -2059,6 +2079,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => 'personal note', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -2101,6 +2122,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -2142,6 +2164,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -2183,6 +2206,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -2207,6 +2231,7 @@ class ShareAPIControllerTest extends TestCase { ->setPermissions(\OCP\Constants::PERMISSION_READ) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') + ->setNote('personal note') ->setId(42); $result[] = [ @@ -2238,6 +2263,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', + 'note' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index fb417878647..a01560d0288 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -192,6 +192,9 @@ class ShareControllerTest extends \Test\TestCase { public function testShowShare() { + + $note = 'personal note'; + $this->shareController->setToken('token'); $owner = $this->getMockBuilder(IUser::class)->getMock(); @@ -210,6 +213,7 @@ class ShareControllerTest extends \Test\TestCase { $share->setPassword('password') ->setShareOwner('ownerUID') ->setNode($file) + ->setNote($note) ->setTarget('/file1.txt'); $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); @@ -283,6 +287,7 @@ class ShareControllerTest extends \Test\TestCase { 'shareUrl' => null, 'previewImage' => null, 'previewURL' => 'downloadURL', + 'note' => $note ); $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); diff --git a/apps/sharebymail/lib/ShareByMailProvider.php b/apps/sharebymail/lib/ShareByMailProvider.php index 1a1855b9c44..73e962e3292 100644 --- a/apps/sharebymail/lib/ShareByMailProvider.php +++ b/apps/sharebymail/lib/ShareByMailProvider.php @@ -506,6 +506,61 @@ class ShareByMailProvider implements IShareProvider { return true; } + protected function sendNote(IShare $share) { + + $recipient = $share->getSharedWith(); + + + $filename = $share->getNode()->getName(); + $initiator = $share->getSharedBy(); + $note = $share->getNote(); + + $initiatorUser = $this->userManager->get($initiator); + $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; + $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null; + + $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]); + $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]); + + $message = $this->mailer->createMessage(); + + $emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote'); + + $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName])); + $emailTemplate->addHeader(); + $emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading); + $emailTemplate->addBodyText(htmlspecialchars($note), $note); + + $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', + ['token' => $share->getToken()]); + $emailTemplate->addBodyButton( + $this->l->t('Open »%s«', [$filename]), + $link + ); + + // The "From" contains the sharers name + $instanceName = $this->defaults->getName(); + $senderName = $this->l->t( + '%1$s via %2$s', + [ + $initiatorDisplayName, + $instanceName + ] + ); + $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]); + if ($initiatorEmailAddress !== null) { + $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]); + $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan()); + } else { + $emailTemplate->addFooter(); + } + + $message->setTo([$recipient]); + $message->useTemplate($emailTemplate); + $this->mailer->send($message); + + } + /** * send auto generated password to the owner. This happens if the admin enforces * a password for mail shares and forbid to send the password by mail to the recipient @@ -662,8 +717,13 @@ class ShareByMailProvider implements IShareProvider { ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) ->set('password', $qb->createNamedParameter($share->getPassword())) ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) + ->set('note', $qb->createNamedParameter($share->getNote())) ->execute(); + if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') { + $this->sendNote($share); + } + return $share; } @@ -904,6 +964,7 @@ class ShareByMailProvider implements IShareProvider { ->setPermissions((int)$data['permissions']) ->setTarget($data['file_target']) ->setMailSend((bool)$data['mail_send']) + ->setNote($data['note']) ->setToken($data['token']); $shareTime = new \DateTime(); diff --git a/apps/sharebymail/tests/ShareByMailProviderTest.php b/apps/sharebymail/tests/ShareByMailProviderTest.php index 95d746cfb46..f0d99e6026c 100644 --- a/apps/sharebymail/tests/ShareByMailProviderTest.php +++ b/apps/sharebymail/tests/ShareByMailProviderTest.php @@ -342,15 +342,17 @@ class ShareByMailProviderTest extends TestCase { $uidOwner = 'user2'; $permissions = 1; $token = 'token'; + $note = 'personal note'; $instance = $this->getInstance(); - $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token); + $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $note); $this->share->expects($this->once())->method('getPermissions')->willReturn($permissions + 1); $this->share->expects($this->once())->method('getShareOwner')->willReturn($uidOwner); $this->share->expects($this->once())->method('getSharedBy')->willReturn($sharedBy); + $this->share->expects($this->any())->method('getNote')->willReturn($note); $this->share->expects($this->atLeastOnce())->method('getId')->willReturn($id); $this->assertSame($this->share, @@ -372,6 +374,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertSame($uidOwner, $result[0]['uid_owner']); $this->assertSame($permissions + 1, (int)$result[0]['permissions']); $this->assertSame($token, $result[0]['token']); + $this->assertSame($note, $result[0]['note']); } public function testDelete() { @@ -478,7 +481,7 @@ class ShareByMailProviderTest extends TestCase { $instance = $this->getInstance(['createShareObject']); $idMail = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token); - $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, \OCP\Share::SHARE_TYPE_LINK); + $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, '', \OCP\Share::SHARE_TYPE_LINK); $this->assertTrue($idMail !== $idPublic); @@ -490,9 +493,9 @@ class ShareByMailProviderTest extends TestCase { } ); - $this->assertInstanceOf('OCP\Share\IShare', - $instance->getShareByToken('token') - ); + $result = $instance->getShareByToken('token'); + + $this->assertInstanceOf('OCP\Share\IShare', $result); } /** @@ -511,7 +514,7 @@ class ShareByMailProviderTest extends TestCase { $instance = $this->getInstance(['createShareObject']); $idMail = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token); - $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, "token2", \OCP\Share::SHARE_TYPE_LINK); + $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, "token2", '', \OCP\Share::SHARE_TYPE_LINK); $this->assertTrue($idMail !== $idPublic); @@ -631,7 +634,7 @@ class ShareByMailProviderTest extends TestCase { $this->invokePrivate($instance, 'getRawShare', [$id+1]); } - private function createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $shareType = \OCP\Share::SHARE_TYPE_EMAIL) { + private function createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $note='', $shareType = \OCP\Share::SHARE_TYPE_EMAIL) { $qb = $this->connection->getQueryBuilder(); $qb->insert('share') ->setValue('share_type', $qb->createNamedParameter($shareType)) @@ -643,6 +646,7 @@ class ShareByMailProviderTest extends TestCase { ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy)) ->setValue('permissions', $qb->createNamedParameter($permissions)) ->setValue('token', $qb->createNamedParameter($token)) + ->setValue('note', $qb->createNamedParameter($note)) ->setValue('stime', $qb->createNamedParameter(time())); /* |