Compare commits
62 Commits
enh/dashbo
...
stable1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f05a1c5dad | ||
|
|
bfbac67d2a | ||
|
|
2d763ae1b0 | ||
|
|
12d47f1159 | ||
|
|
d9b0e60cd8 | ||
|
|
9d57a380f7 | ||
|
|
869aba34d9 | ||
|
|
7cde6672a4 | ||
|
|
1e51113d90 | ||
|
|
2bed4eb18d | ||
|
|
42dac6e187 | ||
|
|
a0dc7d2e6a | ||
|
|
1463175981 | ||
|
|
7bdadc4b03 | ||
|
|
b9ee020732 | ||
|
|
ff7bf7d0cc | ||
|
|
17cf314738 | ||
|
|
76b20a9edc | ||
|
|
16a43c1b33 | ||
|
|
19edbfe777 | ||
|
|
df8d398284 | ||
|
|
8cbc18dc31 | ||
|
|
493907fe76 | ||
|
|
5ae22ec6de | ||
|
|
0b2af720a9 | ||
|
|
3911f1654e | ||
|
|
26cbf186f9 | ||
|
|
e7e42a52d7 | ||
|
|
7b287ff4d3 | ||
|
|
1ba007c070 | ||
|
|
0055527a49 | ||
|
|
cae007ad27 | ||
|
|
cbc6907f0a | ||
|
|
4753291390 | ||
|
|
a14a33d69c | ||
|
|
fd968d95d7 | ||
|
|
a34c3b0667 | ||
|
|
418536ceb1 | ||
|
|
4be27cc653 | ||
|
|
1e06aef4e6 | ||
|
|
4362fdf200 | ||
|
|
d14b4f5853 | ||
|
|
f289ab2d63 | ||
|
|
0ec265b1fb | ||
|
|
3836363ed4 | ||
|
|
517b3cbaf3 | ||
|
|
5fb0c401c8 | ||
|
|
0b06c0d180 | ||
|
|
aa38264d7b | ||
|
|
fa6f50d326 | ||
|
|
e193271376 | ||
|
|
d0d6b412ea | ||
|
|
9e438a9bb6 | ||
|
|
0fdffc19ae | ||
|
|
02595e6593 | ||
|
|
2115669ab5 | ||
|
|
8574c71aaf | ||
|
|
950e50120f | ||
|
|
1ec75e6b75 | ||
|
|
191b22fb23 | ||
|
|
6b8318d169 | ||
|
|
c8910fa395 |
55
.github/workflows/app-code-check.yml
vendored
55
.github/workflows/app-code-check.yml
vendored
@@ -1,55 +0,0 @@
|
||||
name: Nextcloud app code check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
env:
|
||||
APP_NAME: deck
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.4']
|
||||
server-versions: ['master', 'stable18', 'stable19', 'stable20']
|
||||
|
||||
name: AppCode check php${{ matrix.php-versions }}-${{ matrix.server-versions }}
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: App code check
|
||||
run: php occ app:check-code ${{ env.APP_NAME }}
|
||||
2
.github/workflows/appbuild.yml
vendored
2
.github/workflows/appbuild.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
2
.github/workflows/integration.yml
vendored
2
.github/workflows/integration.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
POSTGRES_DB: nextcloud
|
||||
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
mysql:
|
||||
image: mariadb
|
||||
image: mariadb:10.5
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
|
||||
4
.github/workflows/phpunit.yml
vendored
4
.github/workflows/phpunit.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
POSTGRES_DB: nextcloud
|
||||
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
mysql:
|
||||
image: mariadb
|
||||
image: mariadb:10.5
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, zip, gd
|
||||
coverage: none
|
||||
|
||||
- name: Set up PHPUnit
|
||||
|
||||
107
CHANGELOG.md
107
CHANGELOG.md
@@ -1,6 +1,89 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.2.11
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix release asset build
|
||||
|
||||
## 1.2.10
|
||||
|
||||
### Fixed
|
||||
|
||||
- #3394 Use displayname instead of uid for mentions (reopened against master)
|
||||
|
||||
### Other
|
||||
|
||||
- #3409 Keep exceptions http response generic
|
||||
|
||||
|
||||
## 1.2.9
|
||||
|
||||
### Other
|
||||
|
||||
- #3319 Additional check for stacks
|
||||
- #3226 Additional circle level check
|
||||
|
||||
|
||||
## 1.2.8
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#3090](https://github.com/nextcloud/deck/pull/3090) Always fetch attachments
|
||||
* [#3163](https://github.com/nextcloud/deck/pull/3163) Always log generic exceptions
|
||||
|
||||
|
||||
## 1.2.7
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2966](https://github.com/nextcloud/deck/pull/2966) Fix navigating to board details
|
||||
* [#2985](https://github.com/nextcloud/deck/pull/2985) Fix codemirror description width
|
||||
* [#2993](https://github.com/nextcloud/deck/pull/2993) Remove notification on unshare and add type hints
|
||||
* [#3007](https://github.com/nextcloud/deck/pull/3007) Only import debounce
|
||||
* [#3009](https://github.com/nextcloud/deck/pull/3009) Do not query the lookupserver when looking for sharees
|
||||
|
||||
|
||||
## 1.2.6 - 2021-04-07
|
||||
|
||||
### Fixed
|
||||
* [#2925](https://github.com/nextcloud/deck/pull/2925) Avoid reusing the existing route object to make navigation work properly
|
||||
* [#2947](https://github.com/nextcloud/deck/pull/2947) Fix bug when saving the description
|
||||
|
||||
|
||||
## 1.2.5 - 2021-03-05
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2845](https://github.com/nextcloud/deck/pull/2845) Search by mail on the board sharing input
|
||||
* [#2850](https://github.com/nextcloud/deck/pull/2850) Switch to Content-Disposition attachment and check for sane mimetypes
|
||||
* [#2860](https://github.com/nextcloud/deck/pull/2860) Properly pass the user to fetch circles when calling through occ
|
||||
|
||||
## 1.2.4 - 2021-02-02
|
||||
|
||||
### Fixed
|
||||
* [#2715](https://github.com/nextcloud/deck/pull/2715) Handle clicks on calendar entries
|
||||
* [#2752](https://github.com/nextcloud/deck/pull/2752) Remove invalid activity parameters
|
||||
* [#2755](https://github.com/nextcloud/deck/pull/2755) Properly set author for activity events that are triggered by cron
|
||||
* [#2757](https://github.com/nextcloud/deck/pull/2757) Remove repair step which is no longer needed as we cleanup properly
|
||||
* [#2758](https://github.com/nextcloud/deck/pull/2758) Fix deck activity emails not being translated
|
||||
|
||||
|
||||
## 1.2.3 - 2021-01-04
|
||||
|
||||
### Fixed
|
||||
* [#2622](https://github.com/nextcloud/deck/pull/2622) Fix gradient and stack header spacing for safari
|
||||
* [#2626](https://github.com/nextcloud/deck/pull/2626) Adding a description icon to cards when they contain a description without any checkmarks @MonkeySon
|
||||
* [#2659](https://github.com/nextcloud/deck/pull/2659) Matching color of description cursor with text color @JonFStr
|
||||
* [#2676](https://github.com/nextcloud/deck/pull/2676) Only load filter view when shown
|
||||
* [#2680](https://github.com/nextcloud/deck/pull/2680) Do not try to add change data if it doesn't exist
|
||||
* [#2681](https://github.com/nextcloud/deck/pull/2681) Filter out deleted stacks from results
|
||||
* [#2685](https://github.com/nextcloud/deck/pull/2685) Show all boards in move card dialog @jakobroehrl
|
||||
* [#2687](https://github.com/nextcloud/deck/pull/2687) 3dots no opacity @jakobroehrl
|
||||
* [#2688](https://github.com/nextcloud/deck/pull/2688) Title > boardname @jakobroehrl
|
||||
* [#2689](https://github.com/nextcloud/deck/pull/2689) Modal > bigger view wording @jakobroehrl
|
||||
|
||||
## 1.2.2 - 2020-11-24
|
||||
|
||||
### Fixed
|
||||
@@ -107,31 +190,31 @@ All notable changes to this project will be documented in this file.
|
||||
### Fixed
|
||||
|
||||
|
||||
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues @juliushaertl
|
||||
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments @juliushaertl
|
||||
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues
|
||||
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments
|
||||
|
||||
## 1.0.4 - 2020-06-26
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes @juliushaertl
|
||||
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes
|
||||
* [#2065](https://github.com/nextcloud/deck/pull/2065) Adding CSS rule for Markdown Blockquotes @reox
|
||||
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change @juliushaertl
|
||||
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar @juliushaertl
|
||||
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change
|
||||
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar
|
||||
|
||||
|
||||
## 1.0.3 - 2020-06-19
|
||||
|
||||
### Fixed
|
||||
|
||||
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule @juliushaertl
|
||||
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes @juliushaertl
|
||||
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues @juliushaertl
|
||||
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API @juliushaertl
|
||||
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card @juliushaertl
|
||||
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule
|
||||
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes
|
||||
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues
|
||||
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API
|
||||
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card
|
||||
* [#2029](https://github.com/nextcloud/deck/pull/2029) Fix wording : stack -> list @cloud2018
|
||||
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key @juliushaertl
|
||||
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling @juliushaertl
|
||||
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key
|
||||
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling
|
||||
* [#2010](https://github.com/nextcloud/deck/pull/2010) User documentation fixes @Nyco
|
||||
* [#1998](https://github.com/nextcloud/deck/pull/1998) Add Checklist explaination to the doc @4rnoP
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
||||
<id>deck</id>
|
||||
<name>Deck</name>
|
||||
<summary>Personal planning and team project organization</summary>
|
||||
@@ -17,12 +16,12 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>1.2.2</version>
|
||||
<version>1.2.11</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
<types>
|
||||
<dav />
|
||||
<dav/>
|
||||
</types>
|
||||
<category>organization</category>
|
||||
<category>office</category>
|
||||
@@ -36,18 +35,13 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
<nextcloud min-version="18" max-version="21" />
|
||||
<nextcloud min-version="18" max-version="20"/>
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
<job>OCA\Deck\Cron\ScheduledNotifications</job>
|
||||
<job>OCA\Deck\Cron\CardDescriptionActivity</job>
|
||||
</background-jobs>
|
||||
<repair-steps>
|
||||
<post-migration>
|
||||
<step>OCA\Deck\Migration\UnknownUsers</step>
|
||||
</post-migration>
|
||||
</repair-steps>
|
||||
<commands>
|
||||
<command>OCA\Deck\Command\UserExport</command>
|
||||
</commands>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
namespace OCA\Deck\Activity;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OCA\Deck\AppInfo\Application;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\Assignment;
|
||||
@@ -44,8 +45,8 @@ use OCP\Activity\IManager;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\Comments\IComment;
|
||||
use OCP\IL10N;
|
||||
use OCP\IUser;
|
||||
use OCP\L10N\IFactory;
|
||||
|
||||
class ActivityManager {
|
||||
public const DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED = 'DECK_NOAUTHOR_COMMENT_SYSTEM_ENFORCED';
|
||||
@@ -57,7 +58,7 @@ class ActivityManager {
|
||||
private $attachmentMapper;
|
||||
private $aclMapper;
|
||||
private $stackMapper;
|
||||
private $l10n;
|
||||
private $l10nFactory;
|
||||
|
||||
public const DECK_OBJECT_BOARD = 'deck_board';
|
||||
public const DECK_OBJECT_CARD = 'deck_card';
|
||||
@@ -111,7 +112,7 @@ class ActivityManager {
|
||||
StackMapper $stackMapper,
|
||||
AttachmentMapper $attachmentMapper,
|
||||
AclMapper $aclMapper,
|
||||
IL10N $l10n,
|
||||
IFactory $l10nFactory,
|
||||
$userId
|
||||
) {
|
||||
$this->manager = $manager;
|
||||
@@ -121,117 +122,119 @@ class ActivityManager {
|
||||
$this->stackMapper = $stackMapper;
|
||||
$this->attachmentMapper = $attachmentMapper;
|
||||
$this->aclMapper = $aclMapper;
|
||||
$this->l10n = $l10n;
|
||||
$this->l10nFactory = $l10nFactory;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $subjectIdentifier
|
||||
* @param string $subjectIdentifier
|
||||
* @param array $subjectParams
|
||||
* @param bool $ownActivity
|
||||
* @return string
|
||||
*/
|
||||
public function getActivityFormat($subjectIdentifier, $subjectParams = [], $ownActivity = false) {
|
||||
public function getActivityFormat($language, $subjectIdentifier, $subjectParams = [], $ownActivity = false) {
|
||||
$subject = '';
|
||||
$l = $this->l10nFactory->get(Application::APP_ID, $language);
|
||||
|
||||
switch ($subjectIdentifier) {
|
||||
case self::SUBJECT_BOARD_CREATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have created a new board {board}'): $this->l10n->t('{user} has created a new board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have created a new board {board}'): $l->t('{user} has created a new board {board}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_DELETE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have deleted the board {board}') : $this->l10n->t('{user} has deleted the board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have deleted the board {board}') : $l->t('{user} has deleted the board {board}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_RESTORE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have restored the board {board}') : $this->l10n->t('{user} has restored the board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have restored the board {board}') : $l->t('{user} has restored the board {board}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_SHARE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have shared the board {board} with {acl}') : $this->l10n->t('{user} has shared the board {board} with {acl}');
|
||||
$subject = $ownActivity ? $l->t('You have shared the board {board} with {acl}') : $l->t('{user} has shared the board {board} with {acl}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_UNSHARE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have removed {acl} from the board {board}') : $this->l10n->t('{user} has removed {acl} from the board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have removed {acl} from the board {board}') : $l->t('{user} has removed {acl} from the board {board}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_UPDATE_TITLE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have renamed the board {before} to {board}') : $this->l10n->t('{user} has renamed the board {before} to {board}');
|
||||
$subject = $ownActivity ? $l->t('You have renamed the board {before} to {board}') : $l->t('{user} has renamed the board {before} to {board}');
|
||||
break;
|
||||
case self::SUBJECT_BOARD_UPDATE_ARCHIVED:
|
||||
if (isset($subjectParams['after']) && $subjectParams['after']) {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have archived the board {board}') : $this->l10n->t('{user} has archived the board {before}');
|
||||
$subject = $ownActivity ? $l->t('You have archived the board {board}') : $l->t('{user} has archived the board {before}');
|
||||
} else {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have unarchived the board {board}') : $this->l10n->t('{user} has unarchived the board {before}');
|
||||
$subject = $ownActivity ? $l->t('You have unarchived the board {board}') : $l->t('{user} has unarchived the board {before}');
|
||||
}
|
||||
break;
|
||||
case self::SUBJECT_STACK_CREATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have created a new list {stack} on board {board}') : $this->l10n->t('{user} has created a new list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have created a new list {stack} on board {board}') : $l->t('{user} has created a new list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_STACK_UPDATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have created a new list {stack} on board {board}') : $this->l10n->t('{user} has created a new list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have created a new list {stack} on board {board}') : $l->t('{user} has created a new list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_STACK_UPDATE_TITLE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have renamed list {before} to {stack} on board {board}') : $this->l10n->t('{user} has renamed list {before} to {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have renamed list {before} to {stack} on board {board}') : $l->t('{user} has renamed list {before} to {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_STACK_DELETE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have deleted list {stack} on board {board}') : $this->l10n->t('{user} has deleted list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have deleted list {stack} on board {board}') : $l->t('{user} has deleted list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_CREATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have created card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has created card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have created card {card} in list {stack} on board {board}') : $l->t('{user} has created card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_DELETE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have deleted card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has deleted card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have deleted card {card} in list {stack} on board {board}') : $l->t('{user} has deleted card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_TITLE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have renamed the card {before} to {card}') : $this->l10n->t('{user} has renamed the card {before} to {card}');
|
||||
$subject = $ownActivity ? $l->t('You have renamed the card {before} to {card}') : $l->t('{user} has renamed the card {before} to {card}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_DESCRIPTION:
|
||||
if (!isset($subjectParams['before'])) {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have added a description to card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has added a description to card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have added a description to card {card} in list {stack} on board {board}') : $l->t('{user} has added a description to card {card} in list {stack} on board {board}');
|
||||
} else {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have updated the description of card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has updated the description of the card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have updated the description of card {card} in list {stack} on board {board}') : $l->t('{user} has updated the description of the card {card} in list {stack} on board {board}');
|
||||
}
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_ARCHIVE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have archived card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has archived card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have archived card {card} in list {stack} on board {board}') : $l->t('{user} has archived card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have unarchived card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has unarchived card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have unarchived card {card} in list {stack} on board {board}') : $l->t('{user} has unarchived card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
||||
if (!isset($subjectParams['after'])) {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have removed the due date of card {card}') : $this->l10n->t('{user} has removed the due date of card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have removed the due date of card {card}') : $l->t('{user} has removed the due date of card {card}');
|
||||
} elseif (!isset($subjectParams['before']) && isset($subjectParams['after'])) {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have set the due date of card {card} to {after}') : $this->l10n->t('{user} has set the due date of card {card} to {after}');
|
||||
$subject = $ownActivity ? $l->t('You have set the due date of card {card} to {after}') : $l->t('{user} has set the due date of card {card} to {after}');
|
||||
} else {
|
||||
$subject = $ownActivity ? $this->l10n->t('You have updated the due date of card {card} to {after}') : $this->l10n->t('{user} has updated the due date of card {card} to {after}');
|
||||
$subject = $ownActivity ? $l->t('You have updated the due date of card {card} to {after}') : $l->t('{user} has updated the due date of card {card} to {after}');
|
||||
}
|
||||
|
||||
break;
|
||||
case self::SUBJECT_LABEL_ASSIGN:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have added the tag {label} to card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has added the tag {label} to card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have added the tag {label} to card {card} in list {stack} on board {board}') : $l->t('{user} has added the tag {label} to card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_LABEL_UNASSING:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have removed the tag {label} from card {card} in list {stack} on board {board}') : $this->l10n->t('{user} has removed the tag {label} from card {card} in list {stack} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have removed the tag {label} from card {card} in list {stack} on board {board}') : $l->t('{user} has removed the tag {label} from card {card} in list {stack} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_USER_ASSIGN:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have assigned {assigneduser} to card {card} on board {board}') : $this->l10n->t('{user} has assigned {assigneduser} to card {card} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have assigned {assigneduser} to card {card} on board {board}') : $l->t('{user} has assigned {assigneduser} to card {card} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_USER_UNASSIGN:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have unassigned {assigneduser} from card {card} on board {board}') : $this->l10n->t('{user} has unassigned {assigneduser} from card {card} on board {board}');
|
||||
$subject = $ownActivity ? $l->t('You have unassigned {assigneduser} from card {card} on board {board}') : $l->t('{user} has unassigned {assigneduser} from card {card} on board {board}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_UPDATE_STACKID:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have moved the card {card} from list {stackBefore} to {stack}') : $this->l10n->t('{user} has moved the card {card} from list {stackBefore} to {stack}');
|
||||
$subject = $ownActivity ? $l->t('You have moved the card {card} from list {stackBefore} to {stack}') : $l->t('{user} has moved the card {card} from list {stackBefore} to {stack}');
|
||||
break;
|
||||
case self::SUBJECT_ATTACHMENT_CREATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have added the attachment {attachment} to card {card}') : $this->l10n->t('{user} has added the attachment {attachment} to card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have added the attachment {attachment} to card {card}') : $l->t('{user} has added the attachment {attachment} to card {card}');
|
||||
break;
|
||||
case self::SUBJECT_ATTACHMENT_UPDATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have updated the attachment {attachment} on card {card}') : $this->l10n->t('{user} has updated the attachment {attachment} on card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have updated the attachment {attachment} on card {card}') : $l->t('{user} has updated the attachment {attachment} on card {card}');
|
||||
break;
|
||||
case self::SUBJECT_ATTACHMENT_DELETE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have deleted the attachment {attachment} from card {card}') : $this->l10n->t('{user} has deleted the attachment {attachment} from card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have deleted the attachment {attachment} from card {card}') : $l->t('{user} has deleted the attachment {attachment} from card {card}');
|
||||
break;
|
||||
case self::SUBJECT_ATTACHMENT_RESTORE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have restored the attachment {attachment} to card {card}') : $this->l10n->t('{user} has restored the attachment {attachment} to card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have restored the attachment {attachment} to card {card}') : $l->t('{user} has restored the attachment {attachment} to card {card}');
|
||||
break;
|
||||
case self::SUBJECT_CARD_COMMENT_CREATE:
|
||||
$subject = $ownActivity ? $this->l10n->t('You have commented on card {card}') : $this->l10n->t('{user} has commented on card {card}');
|
||||
$subject = $ownActivity ? $l->t('You have commented on card {card}') : $l->t('{user} has commented on card {card}');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -402,15 +405,15 @@ class ActivityManager {
|
||||
if ($subject === self::SUBJECT_CARD_UPDATE_STACKID) {
|
||||
$subjectParams['stackBefore'] = $this->stackMapper->find($additionalParams['before']);
|
||||
$subjectParams['stack'] = $this->stackMapper->find($additionalParams['after']);
|
||||
unset($additionalParams['after'], $additionalParams['before']);
|
||||
}
|
||||
|
||||
$subjectParams['author'] = $this->userId;
|
||||
|
||||
$subjectParams['author'] = $author === null ? $this->userId : $author;
|
||||
|
||||
$event = $this->manager->generateEvent();
|
||||
$event->setApp('deck')
|
||||
->setType($eventType)
|
||||
->setAuthor($author === null ? $this->userId : $author)
|
||||
->setAuthor($subjectParams['author'])
|
||||
->setObject($objectType, (int)$object->getId(), $object->getTitle())
|
||||
->setSubject($subject, array_merge($subjectParams, $additionalParams))
|
||||
->setTimestamp(time());
|
||||
|
||||
@@ -143,12 +143,14 @@ class DeckProvider implements IProvider {
|
||||
$params = $this->parseParamForLabel($subjectParams, $params);
|
||||
$params = $this->parseParamForAssignedUser($subjectParams, $params);
|
||||
$params = $this->parseParamForAcl($subjectParams, $params);
|
||||
$params = $this->parseParamForChanges($subjectParams, $params, $event);
|
||||
if ($subjectIdentifier !== ActivityManager::SUBJECT_CARD_UPDATE_STACKID) {
|
||||
$params = $this->parseParamForChanges($subjectParams, $params, $event);
|
||||
}
|
||||
$params = $this->parseParamForComment($subjectParams, $params, $event);
|
||||
$params = $this->parseParamForDuedate($subjectParams, $params, $event);
|
||||
|
||||
try {
|
||||
$subject = $this->activityManager->getActivityFormat($subjectIdentifier, $subjectParams, $ownActivity);
|
||||
$subject = $this->activityManager->getActivityFormat($language, $subjectIdentifier, $subjectParams, $ownActivity);
|
||||
$this->setSubjects($event, $subject, $params);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
private $stackMapper;
|
||||
private $userManager;
|
||||
private $groupManager;
|
||||
private $logger;
|
||||
|
||||
private $circlesEnabled;
|
||||
|
||||
@@ -44,7 +45,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
AclMapper $aclMapper,
|
||||
StackMapper $stackMapper,
|
||||
IUserManager $userManager,
|
||||
IGroupManager $groupManager
|
||||
IGroupManager $groupManager,
|
||||
ILogger $logger
|
||||
) {
|
||||
parent::__construct($db, 'deck_boards', Board::class);
|
||||
$this->labelMapper = $labelMapper;
|
||||
@@ -52,6 +54,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
$this->stackMapper = $stackMapper;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles');
|
||||
}
|
||||
@@ -159,7 +162,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
}
|
||||
$circles = array_map(function ($circle) {
|
||||
return $circle->getUniqueId();
|
||||
}, \OCA\Circles\Api\v1\Circles::joinedCircles('', true));
|
||||
}, \OCA\Circles\Api\v1\Circles::joinedCircles($userId, true));
|
||||
if (count($circles) === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -238,7 +241,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
if ($user !== null) {
|
||||
return new User($user);
|
||||
}
|
||||
\OC::$server->getLogger()->debug('User ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
|
||||
$this->logger->debug('User ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
|
||||
return null;
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
|
||||
@@ -246,7 +249,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
if ($group !== null) {
|
||||
return new Group($group);
|
||||
}
|
||||
\OC::$server->getLogger()->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
|
||||
$this->logger->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
|
||||
return null;
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
|
||||
@@ -258,11 +261,12 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
|
||||
if ($circle) {
|
||||
return new Circle($circle);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->error('Failed to get circle details when building ACL', ['exception' => $e]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
\OC::$server->getLogger()->log(ILogger::WARN, 'Unknown permission type for mapping acl ' . $acl->getId());
|
||||
$this->logger->warning('Unknown permission type for mapping acl ' . $acl->getId());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,9 +29,16 @@ namespace OCA\Deck\Listeners;
|
||||
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\IRequest;
|
||||
use OCP\Util;
|
||||
|
||||
class BeforeTemplateRenderedListener implements IEventListener {
|
||||
private $request;
|
||||
|
||||
public function __construct(IRequest $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function handle(Event $event): void {
|
||||
if (!($event instanceof BeforeTemplateRenderedEvent)) {
|
||||
return;
|
||||
@@ -41,5 +48,9 @@ class BeforeTemplateRenderedListener implements IEventListener {
|
||||
return;
|
||||
}
|
||||
Util::addStyle('deck', 'deck');
|
||||
|
||||
if (strpos($this->request->getPathInfo(), '/apps/calendar') === 0) {
|
||||
Util::addScript('deck', 'calendar');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use OCP\Util;
|
||||
use OCP\IConfig;
|
||||
|
||||
@@ -41,6 +42,8 @@ class ExceptionMiddleware extends Middleware {
|
||||
private $logger;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
/** @var IRequest */
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* SharingMiddleware constructor.
|
||||
@@ -48,9 +51,10 @@ class ExceptionMiddleware extends Middleware {
|
||||
* @param ILogger $logger
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct(ILogger $logger, IConfig $config) {
|
||||
public function __construct(ILogger $logger, IConfig $config, IRequest $request) {
|
||||
$this->logger = $logger;
|
||||
$this->config = $config;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,45 +71,10 @@ class ExceptionMiddleware extends Middleware {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
if ($exception instanceof ConflictException) {
|
||||
if ($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
|
||||
$this->logger->logException($exception);
|
||||
}
|
||||
return new JSONResponse([
|
||||
'status' => $exception->getStatus(),
|
||||
'message' => $exception->getMessage(),
|
||||
'data' => $exception->getData(),
|
||||
], $exception->getStatus());
|
||||
}
|
||||
|
||||
if ($exception instanceof StatusException) {
|
||||
if ($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
|
||||
$this->logger->logException($exception);
|
||||
}
|
||||
|
||||
if ($controller instanceof OCSController) {
|
||||
$exception = new OCSException($exception->getMessage(), $exception->getStatus(), $exception);
|
||||
throw $exception;
|
||||
}
|
||||
return new JSONResponse([
|
||||
'status' => $exception->getStatus(),
|
||||
'message' => $exception->getMessage()
|
||||
], $exception->getStatus());
|
||||
}
|
||||
|
||||
if (strpos(get_class($controller), 'OCA\\Deck\\Controller\\') === 0) {
|
||||
$response = [
|
||||
'status' => 500,
|
||||
'message' => $exception->getMessage()
|
||||
];
|
||||
if ($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
|
||||
$this->logger->logException($exception);
|
||||
}
|
||||
if ($this->config->getSystemValue('debug', true) === true) {
|
||||
$response['exception'] = (array) $exception;
|
||||
}
|
||||
return new JSONResponse($response, 500);
|
||||
}
|
||||
$debugMode = $this->config->getSystemValue('debug', false);
|
||||
$exceptionMessage = $debugMode !== true
|
||||
? 'Internal server error: Please contact the server administrator if this error reappears multiple times, please include the request ID "' . $this->request->getId() . '" below in your report.'
|
||||
: $exception->getMessage();
|
||||
|
||||
// uncatched DoesNotExistExceptions will be thrown when the main entity is not found
|
||||
// we return a 403 so we don't leak information over existing entries
|
||||
@@ -116,6 +85,43 @@ class ExceptionMiddleware extends Middleware {
|
||||
'message' => 'Permission denied'
|
||||
], 403);
|
||||
}
|
||||
|
||||
if ($exception instanceof StatusException) {
|
||||
if ($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
|
||||
$this->logger->logException($exception);
|
||||
}
|
||||
|
||||
if ($exception instanceof ConflictException) {
|
||||
return new JSONResponse([
|
||||
'status' => $exception->getStatus(),
|
||||
'message' => $exception->getMessage(),
|
||||
'data' => $exception->getData(),
|
||||
], $exception->getStatus());
|
||||
}
|
||||
|
||||
if ($controller instanceof OCSController) {
|
||||
$exception = new OCSException($exception->getMessage(), $exception->getStatus(), $exception);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return new JSONResponse([
|
||||
'status' => $exception->getStatus(),
|
||||
'message' => $exception->getMessage(),
|
||||
], $exception->getStatus());
|
||||
}
|
||||
|
||||
if (strpos(get_class($controller), 'OCA\\Deck\\Controller\\') === 0) {
|
||||
$response = [
|
||||
'status' => 500,
|
||||
'message' => $exceptionMessage,
|
||||
'requestId' => $this->request->getId(),
|
||||
];
|
||||
$this->logger->logException($exception);
|
||||
if ($debugMode === true) {
|
||||
$response['exception'] = (array) $exception;
|
||||
}
|
||||
return new JSONResponse($response, 500);
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace OCA\Deck\Migration;
|
||||
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\Board;
|
||||
use OCA\Deck\Db\BoardMapper;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Migration\IRepairStep;
|
||||
use OCP\Migration\IOutput;
|
||||
|
||||
class UnknownUsers implements IRepairStep {
|
||||
private $userManager;
|
||||
private $groupManager;
|
||||
private $aclMapper;
|
||||
private $boardMapper;
|
||||
|
||||
public function __construct(IUserManager $userManager, IGroupManager $groupManager, AclMapper $aclMapper, BoardMapper $boardMapper) {
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->aclMapper = $aclMapper;
|
||||
$this->boardMapper = $boardMapper;
|
||||
}
|
||||
|
||||
/*
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName() {
|
||||
return 'Delete orphaned ACL rules';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
$boards = $this->boardMapper->findAll();
|
||||
/** @var Board $board */
|
||||
foreach ($boards as $board) {
|
||||
$acls = $this->aclMapper->findAll($board->getId());
|
||||
/** @var Acl $acl */
|
||||
foreach ($acls as $acl) {
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {
|
||||
$user = $this->userManager->get($acl->getParticipant());
|
||||
if ($user === null) {
|
||||
$this->aclMapper->delete($acl);
|
||||
}
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
|
||||
$group = $this->groupManager->get($acl->getParticipant());
|
||||
if ($group === null) {
|
||||
$this->aclMapper->delete($acl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
@@ -24,19 +27,24 @@
|
||||
namespace OCA\Deck\Notification;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use OCA\Deck\AppInfo\Application;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AssignmentMapper;
|
||||
use OCA\Deck\Db\Board;
|
||||
use OCA\Deck\Db\BoardMapper;
|
||||
use OCA\Deck\Db\Card;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Db\User;
|
||||
use OCA\Deck\Service\ConfigService;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\Comments\IComment;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
|
||||
class NotificationHelper {
|
||||
|
||||
@@ -80,10 +88,10 @@ class NotificationHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $card
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||
* @throws DoesNotExistException
|
||||
* @throws Exception thrown on invalid due date
|
||||
*/
|
||||
public function sendCardDuedate($card) {
|
||||
public function sendCardDuedate(Card $card): void {
|
||||
// check if notification has already been sent
|
||||
// ideally notifications should not be deleted once seen by the user so we can
|
||||
// also deliver due date notifications for users who have been added later to a board
|
||||
@@ -117,7 +125,7 @@ class NotificationHelper {
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setUser((string)$user->getUID())
|
||||
->setObject('card', $card->getId())
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setSubject('card-overdue', [
|
||||
$card->getTitle(), $board->getTitle()
|
||||
])
|
||||
@@ -128,25 +136,29 @@ class NotificationHelper {
|
||||
$this->cardMapper->markNotified($card);
|
||||
}
|
||||
|
||||
public function markDuedateAsRead($card) {
|
||||
public function markDuedateAsRead(Card $card): void {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setObject('card', $card->getId())
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setSubject('card-overdue', []);
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
}
|
||||
|
||||
public function sendCardAssigned($card, $userId) {
|
||||
public function sendCardAssigned(Card $card, string $userId): void {
|
||||
$boardId = $this->cardMapper->findBoardId($card->getId());
|
||||
$board = $this->getBoard($boardId);
|
||||
try {
|
||||
$board = $this->getBoard($boardId);
|
||||
} catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setUser((string) $userId)
|
||||
->setUser($userId)
|
||||
->setDateTime(new DateTime())
|
||||
->setObject('card', $card->getId())
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setSubject('card-assigned', [
|
||||
$card->getTitle(),
|
||||
$board->getTitle(),
|
||||
@@ -155,29 +167,56 @@ class NotificationHelper {
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
|
||||
public function markCardAssignedAsRead(Card $card, string $userId): void {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setUser($userId)
|
||||
->setObject('card', (string)$card->getId())
|
||||
->setSubject('card-assigned', []);
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send notifications that a board was shared with a user/group
|
||||
*
|
||||
* @param $boardId
|
||||
* @param Acl $acl
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function sendBoardShared($boardId, $acl) {
|
||||
$board = $this->getBoard($boardId);
|
||||
public function sendBoardShared(int $boardId, Acl $acl, bool $markAsRead = false): void {
|
||||
try {
|
||||
$board = $this->getBoard($boardId);
|
||||
} catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {
|
||||
$notification = $this->generateBoardShared($board, $acl->getParticipant());
|
||||
$this->notificationManager->notify($notification);
|
||||
if ($markAsRead) {
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
} else {
|
||||
$notification->setDateTime(new DateTime());
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
|
||||
$group = $this->groupManager->get($acl->getParticipant());
|
||||
if ($group === null) {
|
||||
return;
|
||||
}
|
||||
foreach ($group->getUsers() as $user) {
|
||||
if ($user->getUID() === $this->currentUser) {
|
||||
continue;
|
||||
}
|
||||
$notification = $this->generateBoardShared($board, $user->getUID());
|
||||
$this->notificationManager->notify($notification);
|
||||
if ($markAsRead) {
|
||||
$this->notificationManager->markProcessed($notification);
|
||||
} else {
|
||||
$notification->setDateTime(new DateTime());
|
||||
$this->notificationManager->notify($notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function sendMention(IComment $comment) {
|
||||
public function sendMention(IComment $comment): void {
|
||||
foreach ($comment->getMentions() as $mention) {
|
||||
$card = $this->cardMapper->find($comment->getObjectId());
|
||||
$boardId = $this->cardMapper->findBoardId($card->getId());
|
||||
@@ -194,27 +233,22 @@ class NotificationHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $boardId
|
||||
* @return Board
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||
* @throws DoesNotExistException
|
||||
* @throws MultipleObjectsReturnedException
|
||||
*/
|
||||
private function getBoard($boardId, bool $withLabels = false, bool $withAcl = false) {
|
||||
private function getBoard(int $boardId, bool $withLabels = false, bool $withAcl = false): Board {
|
||||
if (!array_key_exists($boardId, $this->boards)) {
|
||||
$this->boards[$boardId] = $this->boardMapper->find($boardId, $withLabels, $withAcl);
|
||||
}
|
||||
return $this->boards[$boardId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Board $board
|
||||
*/
|
||||
private function generateBoardShared($board, $userId) {
|
||||
|
||||
private function generateBoardShared(Board $board, string $userId): INotification {
|
||||
$notification = $this->notificationManager->createNotification();
|
||||
$notification
|
||||
->setApp('deck')
|
||||
->setUser((string) $userId)
|
||||
->setDateTime(new DateTime())
|
||||
->setObject('board', $board->getId())
|
||||
->setUser($userId)
|
||||
->setObject('board', (string)$board->getId())
|
||||
->setSubject('board-shared', [$board->getTitle(), $this->currentUser]);
|
||||
return $notification;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ class AssignmentService {
|
||||
* @var IEventDispatcher
|
||||
*/
|
||||
private $eventDispatcher;
|
||||
/** @var string|null */
|
||||
private $currentUser;
|
||||
|
||||
public function __construct(
|
||||
PermissionService $permissionService,
|
||||
@@ -138,8 +140,7 @@ class AssignmentService {
|
||||
}
|
||||
|
||||
|
||||
if ($userId !== $this->currentUser) {
|
||||
/* Notifyuser about the card assignment */
|
||||
if ($type === Assignment::TYPE_USER && $userId !== $this->currentUser) {
|
||||
$this->notificationHelper->sendCardAssigned($card, $userId);
|
||||
}
|
||||
|
||||
@@ -185,6 +186,9 @@ class AssignmentService {
|
||||
$assignment = $this->assignedUsersMapper->delete($assignment);
|
||||
$card = $this->cardMapper->find($cardId);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_USER_UNASSIGN, ['assigneduser' => $userId]);
|
||||
if ($type === Assignment::TYPE_USER && $userId !== $this->currentUser) {
|
||||
$this->notificationHelper->markCardAssignedAsRead($card, $userId);
|
||||
}
|
||||
$this->changeHelper->cardChanged($cardId);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
|
||||
@@ -532,11 +532,10 @@ class BoardService {
|
||||
$acl->setPermissionShare($share);
|
||||
$acl->setPermissionManage($manage);
|
||||
|
||||
/* Notify users about the shared board */
|
||||
$this->notificationHelper->sendBoardShared($boardId, $acl);
|
||||
|
||||
$newAcl = $this->aclMapper->insert($acl);
|
||||
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $newAcl, ActivityManager::SUBJECT_BOARD_SHARE);
|
||||
$this->notificationHelper->sendBoardShared((int)$boardId, $newAcl);
|
||||
$this->boardMapper->mapAcl($newAcl);
|
||||
$this->changeHelper->boardChanged($boardId);
|
||||
|
||||
@@ -628,6 +627,7 @@ class BoardService {
|
||||
}
|
||||
}
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $acl, ActivityManager::SUBJECT_BOARD_UNSHARE);
|
||||
$this->notificationHelper->sendBoardShared($acl->getBoardId(), $acl, true);
|
||||
$this->changeHelper->boardChanged($acl->getBoardId());
|
||||
|
||||
$version = \OCP\Util::getVersion()[0];
|
||||
|
||||
@@ -240,6 +240,7 @@ class CardService {
|
||||
$card->setDeletedAt(time());
|
||||
$this->cardMapper->update($card);
|
||||
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_DELETE);
|
||||
$this->notificationHelper->markDuedateAsRead($card);
|
||||
$this->changeHelper->cardChanged($card->getId(), false);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
@@ -322,6 +323,15 @@ class CardService {
|
||||
$card->setOrder($order);
|
||||
$card->setOwner($owner);
|
||||
$card->setDuedate($duedate);
|
||||
$resetDuedateNotification = false;
|
||||
if (
|
||||
$card->getDuedate() === null ||
|
||||
(new \DateTime($card->getDuedate())) != (new \DateTime($changes->getBefore()->getDuedate()))
|
||||
) {
|
||||
$card->setNotified(false);
|
||||
$resetDuedateNotification = true;
|
||||
}
|
||||
|
||||
if ($deletedAt !== null) {
|
||||
$card->setDeletedAt($deletedAt);
|
||||
}
|
||||
@@ -341,6 +351,9 @@ class CardService {
|
||||
|
||||
|
||||
$card = $this->cardMapper->update($card);
|
||||
if ($resetDuedateNotification) {
|
||||
$this->notificationHelper->markDuedateAsRead($card);
|
||||
}
|
||||
$this->changeHelper->cardChanged($card->getId(), true);
|
||||
|
||||
$this->eventDispatcher->dispatch(
|
||||
|
||||
@@ -26,6 +26,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Service;
|
||||
|
||||
use OCA\Circles\Api\v1\Circles;
|
||||
use OCP\App\IAppManager;
|
||||
|
||||
/**
|
||||
@@ -53,8 +54,8 @@ class CirclesService {
|
||||
}
|
||||
|
||||
try {
|
||||
\OCA\Circles\Api\v1\Circles::getMember($circleId, $userId, 1, true);
|
||||
return true;
|
||||
$member = \OCA\Circles\Api\v1\Circles::getMember($circleId, $userId, 1, true);
|
||||
return $member->getLevel() >= Circles::LEVEL_MEMBER;
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -27,10 +27,9 @@ use OCA\Deck\Db\Attachment;
|
||||
use OCA\Deck\Db\AttachmentMapper;
|
||||
use OCA\Deck\StatusException;
|
||||
use OCA\Deck\Exceptions\ConflictException;
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\StreamResponse;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
@@ -49,6 +48,7 @@ class FileService implements IAttachmentService {
|
||||
private $rootFolder;
|
||||
private $config;
|
||||
private $attachmentMapper;
|
||||
private $mimeTypeDetector;
|
||||
|
||||
public function __construct(
|
||||
IL10N $l10n,
|
||||
@@ -57,7 +57,8 @@ class FileService implements IAttachmentService {
|
||||
ILogger $logger,
|
||||
IRootFolder $rootFolder,
|
||||
IConfig $config,
|
||||
AttachmentMapper $attachmentMapper
|
||||
AttachmentMapper $attachmentMapper,
|
||||
IMimeTypeDetector $mimeTypeDetector
|
||||
) {
|
||||
$this->l10n = $l10n;
|
||||
$this->appData = $appData;
|
||||
@@ -66,6 +67,7 @@ class FileService implements IAttachmentService {
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->config = $config;
|
||||
$this->attachmentMapper = $attachmentMapper;
|
||||
$this->mimeTypeDetector = $mimeTypeDetector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,27 +227,14 @@ class FileService implements IAttachmentService {
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
* @return FileDisplayResponse|\OCP\AppFramework\Http\Response|StreamResponse
|
||||
* @return StreamResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function display(Attachment $attachment) {
|
||||
$file = $this->getFileFromRootFolder($attachment);
|
||||
if (method_exists($file, 'fopen')) {
|
||||
$response = new StreamResponse($file->fopen('r'));
|
||||
$response->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"');
|
||||
} else {
|
||||
$response = new FileDisplayResponse($file);
|
||||
}
|
||||
// We need those since otherwise chrome won't show the PDF file with CSP rule object-src 'none'
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=271452
|
||||
$policy = new ContentSecurityPolicy();
|
||||
$policy->addAllowedObjectDomain('\'self\'');
|
||||
$policy->addAllowedObjectDomain('blob:');
|
||||
$policy->addAllowedMediaDomain('\'self\'');
|
||||
$policy->addAllowedMediaDomain('blob:');
|
||||
$response->setContentSecurityPolicy($policy);
|
||||
|
||||
$response->addHeader('Content-Type', $file->getMimeType());
|
||||
$response = new StreamResponse($file->fopen('rb'));
|
||||
$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurldecode($file->getName()) . '"');
|
||||
$response->addHeader('Content-Type', $this->mimeTypeDetector->getSecureMimeType($file->getMimeType()));
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
namespace OCA\Deck\Service;
|
||||
|
||||
use OCA\Circles\Model\Member;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\Board;
|
||||
@@ -194,8 +195,8 @@ class PermissionService {
|
||||
|
||||
if ($this->circlesEnabled && $acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
|
||||
try {
|
||||
\OCA\Circles\Api\v1\Circles::getMember($acl->getParticipant(), $this->userId, 1, true);
|
||||
return $acl->getPermission($permission);
|
||||
$member = \OCA\Circles\Api\v1\Circles::getMember($acl->getParticipant(), $this->userId, 1, true);
|
||||
return $member->getLevel() >= Member::LEVEL_MEMBER && $acl->getPermission($permission);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->info('Member not found in circle that was accessed. This should not happen.');
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ class StackService {
|
||||
throw new BadRequestException('stack id must be a number');
|
||||
}
|
||||
|
||||
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_READ);
|
||||
$stack = $this->stackMapper->find($stackId);
|
||||
$cards = $this->cardMapper->findAll($stackId);
|
||||
foreach ($cards as $cardIndex => $card) {
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
namespace OCA\Deck;
|
||||
|
||||
/**
|
||||
* User facing exception that can be thrown with an error being reported to the frontend
|
||||
* or consumers of the API
|
||||
*
|
||||
* This exception is catched in the ExceptionMiddleware
|
||||
*/
|
||||
class StatusException extends \Exception {
|
||||
public function __construct($message) {
|
||||
parent::__construct($message);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"version": "1.2.11",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Härtl",
|
||||
@@ -129,4 +129,4 @@
|
||||
"<rootDir>/node_modules/jest-serializer-vue"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
:loading="isLoading || !!isSearching"
|
||||
:disabled="isLoading"
|
||||
track-by="multiselectKey"
|
||||
:internal-search="true"
|
||||
:internal-search="false"
|
||||
@input="clickAddAcl"
|
||||
@search-change="asyncFind">
|
||||
<template #noOptions>
|
||||
@@ -73,6 +73,7 @@ import { CollectionList } from 'nextcloud-vue-collections'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import debounce from 'lodash/debounce'
|
||||
|
||||
export default {
|
||||
name: 'SharingTabSidebar',
|
||||
@@ -148,18 +149,13 @@ export default {
|
||||
this.asyncFind('')
|
||||
},
|
||||
methods: {
|
||||
debouncedFind: debounce(async function(query) {
|
||||
this.isSearching = true
|
||||
await this.$store.dispatch('loadSharees', query)
|
||||
this.isSearching = false
|
||||
}, 300),
|
||||
async asyncFind(query) {
|
||||
// manual debounce to handle async searching more easily and have more control over the loading state
|
||||
const timestamp = (new Date()).getTime()
|
||||
if (!this.isSearching || timestamp > this.isSearching + 300) {
|
||||
this.isSearching = timestamp
|
||||
await this.$store.dispatch('loadSharees', query)
|
||||
|
||||
// only reset searching flag if the most recent search finished
|
||||
if (this.isSearching === timestamp) {
|
||||
this.isSearching = false
|
||||
}
|
||||
}
|
||||
await this.debouncedFind(query)
|
||||
},
|
||||
async clickAddAcl() {
|
||||
this.addAclForAPI = {
|
||||
|
||||
@@ -151,8 +151,13 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('fetchAttachments', this.cardId)
|
||||
watch: {
|
||||
cardId: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.$store.dispatch('fetchAttachments', this.cardId)
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleUploadFile(event) {
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
type="deck-card" />
|
||||
</div>
|
||||
|
||||
<Description :key="card.id" :card="card" />
|
||||
<Description :key="card.id" :card="card" @change="descriptionChanged" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -234,6 +234,9 @@ export default {
|
||||
this.initialize()
|
||||
},
|
||||
methods: {
|
||||
descriptionChanged(newDesc) {
|
||||
this.copiedCard.description = newDesc
|
||||
},
|
||||
async initialize() {
|
||||
if (!this.card) {
|
||||
return
|
||||
@@ -253,9 +256,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
setDue() {
|
||||
this.$store.dispatch('updateCardDue', this.copiedCard)
|
||||
},
|
||||
removeDue() {
|
||||
this.copiedCard.duedate = null
|
||||
this.$store.dispatch('updateCardDue', this.copiedCard)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<At ref="at"
|
||||
v-model="commentText"
|
||||
:members="members"
|
||||
name-key="uid"
|
||||
name-key="displayname"
|
||||
:tab-select="true">
|
||||
<template v-slot:item="s">
|
||||
<Avatar class="atwho-li--avatar" :user="s.item.uid" :size="24" />
|
||||
|
||||
@@ -205,6 +205,7 @@ export default {
|
||||
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description })
|
||||
this.descriptionLastEdit = 0
|
||||
this.descriptionSaving = false
|
||||
this.$emit('change', this.description)
|
||||
},
|
||||
updateDescription() {
|
||||
this.descriptionLastEdit = Date.now()
|
||||
@@ -292,6 +293,7 @@ h5 {
|
||||
padding: 0;
|
||||
background-color: var(--color-main-background);
|
||||
color: var(--color-main-text);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.CodeMirror-placeholder {
|
||||
|
||||
@@ -235,9 +235,7 @@ export default {
|
||||
try {
|
||||
const newBoard = await this.$store.dispatch('cloneBoard', this.board)
|
||||
this.loading = false
|
||||
const route = this.routeTo
|
||||
route.params.id = newBoard.id
|
||||
this.$router.push(route)
|
||||
this.$router.push({ name: 'board', params: { id: newBoard.id } })
|
||||
} catch (e) {
|
||||
OC.Notification.showTemporary(t('deck', 'An error occurred'))
|
||||
console.error(e)
|
||||
@@ -278,9 +276,7 @@ export default {
|
||||
)
|
||||
},
|
||||
actionDetails() {
|
||||
const route = this.routeTo
|
||||
route.name = 'board.details'
|
||||
this.$router.push(route)
|
||||
this.$router.push({ name: 'board.details', params: { id: this.board.id } })
|
||||
},
|
||||
applyEdit(e) {
|
||||
this.editing = false
|
||||
@@ -298,11 +294,6 @@ export default {
|
||||
cancelEdit(e) {
|
||||
this.editing = false
|
||||
},
|
||||
showSidebar() {
|
||||
const route = this.routeTo
|
||||
route.name = 'board.details'
|
||||
this.$router.push(route)
|
||||
},
|
||||
async updateSetting(key, value) {
|
||||
this.updateDueSetting = value
|
||||
const setting = {}
|
||||
|
||||
34
src/init-calendar.js
Normal file
34
src/init-calendar.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import { subscribe } from '@nextcloud/event-bus'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
subscribe('calendar:handle-todo-click', ({ calendarId, taskId }) => {
|
||||
const deckAppPrefix = 'app-generated--deck--board-'
|
||||
if (calendarId.startsWith(deckAppPrefix)) {
|
||||
const board = calendarId.substr(deckAppPrefix.length)
|
||||
const card = taskId.substr('card-'.length).replace('.ics', '')
|
||||
console.debug('[deck] Clicked task matches deck calendar pattern')
|
||||
window.location = generateUrl(`apps/deck/#/board/${board}/card/${card}`)
|
||||
}
|
||||
})
|
||||
@@ -414,7 +414,8 @@ export default new Vuex.Store({
|
||||
params.append('search', query)
|
||||
params.append('format', 'json')
|
||||
params.append('perPage', 20)
|
||||
params.append('itemType', [0, 1, 7])
|
||||
params.append('itemType', [0, 1, 4, 7])
|
||||
params.append('lookup', false)
|
||||
|
||||
const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params })
|
||||
commit('setSharees', response.data.ocs.data)
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.3.1@2feba22a005a18bf31d4c7b9bdb9252c73897476">
|
||||
<files psalm-version="4.3.2@57b53ff26237074fdf5cbcb034f7da5172be4524">
|
||||
<file src="lib/Activity/ActivityManager.php">
|
||||
<TypeDoesNotContainType occurrences="1">
|
||||
<code>$message !== null</code>
|
||||
</TypeDoesNotContainType>
|
||||
<UndefinedMagicMethod occurrences="9">
|
||||
<code>getArchived</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getStackId</code>
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Activity/DeckProvider.php">
|
||||
<InvalidScalarArgument occurrences="1">
|
||||
@@ -27,25 +15,6 @@
|
||||
<code>Application</code>
|
||||
</DuplicateClass>
|
||||
</file>
|
||||
<file src="lib/AppInfo/Application20.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>IBootstrap</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/AppInfo/ApplicationLegacy.php">
|
||||
<UndefinedInterfaceMethod occurrences="2">
|
||||
<code>listen</code>
|
||||
<code>listen</code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="lib/Collaboration/Resources/ResourceProviderCard.php">
|
||||
<UndefinedMagicMethod occurrences="4">
|
||||
<code>getAcl</code>
|
||||
<code>getOwner</code>
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Command/UserExport.php">
|
||||
<ImplementedReturnTypeMismatch occurrences="1">
|
||||
<code>void</code>
|
||||
@@ -89,13 +58,6 @@
|
||||
<code>$parentId</code>
|
||||
</InvalidScalarArgument>
|
||||
</file>
|
||||
<file src="lib/Controller/PageController.php">
|
||||
<MissingDependency occurrences="3">
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
</file>
|
||||
<file src="lib/Controller/StackApiController.php">
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>$modified !== null</code>
|
||||
@@ -104,21 +66,6 @@
|
||||
<code>Util</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Cron/CardDescriptionActivity.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>Job</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Cron/DeleteCron.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>Job</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Cron/ScheduledNotifications.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>Job</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/DAV/Calendar.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>ExternalCalendar</code>
|
||||
@@ -140,18 +87,6 @@
|
||||
<code>NotFound</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Dashboard/DeckWidget.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>IWidget</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Db/Acl.php">
|
||||
<UndefinedMagicMethod occurrences="3">
|
||||
<code>getPermissionEdit</code>
|
||||
<code>getPermissionManage</code>
|
||||
<code>getPermissionShare</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/AclMapper.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$aclId</code>
|
||||
@@ -161,60 +96,26 @@
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$cardId</code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedMagicMethod occurrences="9">
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/AttachmentMapper.php">
|
||||
<UndefinedMagicMethod occurrences="2">
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
</UndefinedMagicMethod>
|
||||
<UndefinedVariable occurrences="1">
|
||||
<code>$query</code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="lib/Db/Board.php">
|
||||
<UndefinedMagicMethod occurrences="1">
|
||||
<code>getLastModified</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/BoardMapper.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$boardId</code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedClass occurrences="1">
|
||||
<UndefinedClass occurrences="2">
|
||||
<code>\OCA\Circles\Api\v1\Circles</code>
|
||||
<code>\OCA\Circles\Api\v1\Circles</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="2">
|
||||
<code>setAcl</code>
|
||||
<code>setLabels</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/Card.php">
|
||||
<UndefinedClass occurrences="2">
|
||||
<code>VCalendar</code>
|
||||
<code>VCalendar</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="9">
|
||||
<code>getArchived</code>
|
||||
<code>getArchived</code>
|
||||
<code>getDescription</code>
|
||||
<code>getLabels</code>
|
||||
<code>getLabels</code>
|
||||
<code>getLastModified</code>
|
||||
<code>getLastModified</code>
|
||||
<code>getStackId</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/CardMapper.php">
|
||||
<ImplicitToStringCast occurrences="1">
|
||||
@@ -226,21 +127,6 @@
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$cardId</code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedMagicMethod occurrences="13">
|
||||
<code>getDescription</code>
|
||||
<code>getDescription</code>
|
||||
<code>getDuedate</code>
|
||||
<code>setCreatedAt</code>
|
||||
<code>setDatabaseType</code>
|
||||
<code>setDatabaseType</code>
|
||||
<code>setDescription</code>
|
||||
<code>setDescription</code>
|
||||
<code>setLabels</code>
|
||||
<code>setLastModified</code>
|
||||
<code>setLastModified</code>
|
||||
<code>setNotified</code>
|
||||
<code>setNotified</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/ChangeHelper.php">
|
||||
<UndefinedThisPropertyAssignment occurrences="3">
|
||||
@@ -269,69 +155,21 @@
|
||||
<code>\OCA\Circles\Model\Circle</code>
|
||||
</UndefinedDocblockClass>
|
||||
</file>
|
||||
<file src="lib/Db/Label.php">
|
||||
<UndefinedMagicMethod occurrences="1">
|
||||
<code>getLastModified</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/LabelMapper.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$labelId</code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedMagicMethod occurrences="2">
|
||||
<code>setLastModified</code>
|
||||
<code>setLastModified</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/RelationalEntity.php">
|
||||
<UndefinedMagicMethod occurrences="1">
|
||||
<code>getETag</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/Stack.php">
|
||||
<UndefinedClass occurrences="2">
|
||||
<code>VCalendar</code>
|
||||
<code>VCalendar</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="2">
|
||||
<code>getLastModified</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Db/StackMapper.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$stackId</code>
|
||||
</ParamNameMismatch>
|
||||
<UndefinedMagicMethod occurrences="1">
|
||||
<code>getBoardId</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Listeners/BeforeTemplateRenderedListener.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>BeforeTemplateRenderedEvent</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Migration/UnknownUsers.php">
|
||||
<UndefinedMagicMethod occurrences="4">
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Notification/NotificationHelper.php">
|
||||
<InvalidScalarArgument occurrences="1">
|
||||
<code>$board->getId()</code>
|
||||
</InvalidScalarArgument>
|
||||
<MissingDependency occurrences="1">
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
<UndefinedMagicMethod occurrences="3">
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Notification/Notifier.php">
|
||||
<RedundantCast occurrences="7">
|
||||
@@ -348,129 +186,18 @@
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>[]</code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<UndefinedClass occurrences="2">
|
||||
<code>IndexDocument</code>
|
||||
<code>SearchTemplate</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Search/BoardSearchResultEntry.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>SearchResultEntry</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Search/CardSearchResultEntry.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>SearchResultEntry</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Search/DeckProvider.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>IProvider</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Service/AssignmentService.php">
|
||||
<InvalidScalarArgument occurrences="2">
|
||||
<code>$cardId</code>
|
||||
<code>$cardId</code>
|
||||
</InvalidScalarArgument>
|
||||
<UndefinedMagicMethod occurrences="9">
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>setCardId</code>
|
||||
<code>setParticipant</code>
|
||||
<code>setType</code>
|
||||
</UndefinedMagicMethod>
|
||||
<UndefinedThisPropertyAssignment occurrences="1">
|
||||
<code>$this->currentUser</code>
|
||||
</UndefinedThisPropertyAssignment>
|
||||
<UndefinedThisPropertyFetch occurrences="1">
|
||||
<code>$this->currentUser</code>
|
||||
</UndefinedThisPropertyFetch>
|
||||
</file>
|
||||
<file src="lib/Service/AttachmentService.php">
|
||||
<MissingDependency occurrences="1">
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
<UndefinedMagicMethod occurrences="13">
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getData</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>setCardId</code>
|
||||
<code>setCreatedAt</code>
|
||||
<code>setCreatedBy</code>
|
||||
<code>setData</code>
|
||||
<code>setLastModified</code>
|
||||
<code>setLastModified</code>
|
||||
<code>setType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/BoardService.php">
|
||||
<InvalidArgument occurrences="6">
|
||||
<code>'\OCA\Deck\Board::onCreate'</code>
|
||||
<code>'\OCA\Deck\Board::onDelete'</code>
|
||||
<code>'\OCA\Deck\Board::onDelete'</code>
|
||||
<code>'\OCA\Deck\Board::onShareEdit'</code>
|
||||
<code>'\OCA\Deck\Board::onUpdate'</code>
|
||||
<code>'\OCA\Deck\Board::onUpdate'</code>
|
||||
</InvalidArgument>
|
||||
<MissingDependency occurrences="3">
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
<TooManyArguments occurrences="2">
|
||||
<code>findAll</code>
|
||||
<code>findAll</code>
|
||||
</TooManyArguments>
|
||||
<UndefinedMagicMethod occurrences="40">
|
||||
<code>getAcl</code>
|
||||
<code>getAcl</code>
|
||||
<code>getAcl</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getType</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setColor</code>
|
||||
<code>setColor</code>
|
||||
<code>setColor</code>
|
||||
<code>setColor</code>
|
||||
<code>setColor</code>
|
||||
<code>setLabels</code>
|
||||
<code>setOwner</code>
|
||||
<code>setOwner</code>
|
||||
<code>setParticipant</code>
|
||||
<code>setPermissionEdit</code>
|
||||
<code>setPermissionEdit</code>
|
||||
<code>setPermissionManage</code>
|
||||
<code>setPermissionManage</code>
|
||||
<code>setPermissionShare</code>
|
||||
<code>setPermissionShare</code>
|
||||
<code>setPermissions</code>
|
||||
<code>setPermissions</code>
|
||||
<code>setPermissions</code>
|
||||
<code>setPermissions</code>
|
||||
<code>setSettings</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/CardService.php">
|
||||
<TooFewArguments occurrences="1">
|
||||
@@ -479,52 +206,6 @@
|
||||
<UndefinedDocblockClass occurrences="1">
|
||||
<code>\OCP\AppFramework\Db\</code>
|
||||
</UndefinedDocblockClass>
|
||||
<UndefinedMagicMethod occurrences="44">
|
||||
<code>getArchived</code>
|
||||
<code>getArchived</code>
|
||||
<code>getArchived</code>
|
||||
<code>getArchived</code>
|
||||
<code>getArchived</code>
|
||||
<code>getDescription</code>
|
||||
<code>getDescription</code>
|
||||
<code>getDescription</code>
|
||||
<code>getDescriptionPrev</code>
|
||||
<code>getDescriptionPrev</code>
|
||||
<code>getLastEditor</code>
|
||||
<code>getLastEditor</code>
|
||||
<code>getLastEditor</code>
|
||||
<code>getOrder</code>
|
||||
<code>setArchived</code>
|
||||
<code>setArchived</code>
|
||||
<code>setArchived</code>
|
||||
<code>setAssignedUsers</code>
|
||||
<code>setAssignedUsers</code>
|
||||
<code>setAttachmentCount</code>
|
||||
<code>setAttachments</code>
|
||||
<code>setCommentsUnread</code>
|
||||
<code>setDeletedAt</code>
|
||||
<code>setDeletedAt</code>
|
||||
<code>setDescription</code>
|
||||
<code>setDescription</code>
|
||||
<code>setDescriptionPrev</code>
|
||||
<code>setDescriptionPrev</code>
|
||||
<code>setDuedate</code>
|
||||
<code>setDuedate</code>
|
||||
<code>setLabels</code>
|
||||
<code>setLastEditor</code>
|
||||
<code>setOrder</code>
|
||||
<code>setOrder</code>
|
||||
<code>setOwner</code>
|
||||
<code>setOwner</code>
|
||||
<code>setStackId</code>
|
||||
<code>setStackId</code>
|
||||
<code>setStackId</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
<code>setType</code>
|
||||
<code>setType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/CirclesService.php">
|
||||
<UndefinedClass occurrences="2">
|
||||
@@ -533,13 +214,6 @@
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="lib/Service/CommentService.php">
|
||||
<MissingDependency occurrences="5">
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
<UndefinedThisPropertyAssignment occurrences="2">
|
||||
<code>$this->cardMapper</code>
|
||||
<code>$this->permissionService</code>
|
||||
@@ -559,21 +233,8 @@
|
||||
<InvalidScalarArgument occurrences="1">
|
||||
<code>(int)$value</code>
|
||||
</InvalidScalarArgument>
|
||||
<MissingDependency occurrences="7">
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
</file>
|
||||
<file src="lib/Service/DefaultBoardService.php">
|
||||
<MissingDependency occurrences="2">
|
||||
<code>Application</code>
|
||||
<code>Application</code>
|
||||
</MissingDependency>
|
||||
<TypeDoesNotContainNull occurrences="6">
|
||||
<code>$color === false || $color === null</code>
|
||||
<code>$color === null</code>
|
||||
@@ -597,94 +258,17 @@
|
||||
<code>is_resource($content)</code>
|
||||
<code>is_resource($content)</code>
|
||||
</RedundantCondition>
|
||||
<UndefinedMagicMethod occurrences="10">
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getCardId</code>
|
||||
<code>getData</code>
|
||||
<code>getData</code>
|
||||
<code>setData</code>
|
||||
<code>setData</code>
|
||||
<code>setDeletedAt</code>
|
||||
<code>setExtendedData</code>
|
||||
<code>setLastModified</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/FullTextSearchService.php">
|
||||
<UndefinedClass occurrences="2">
|
||||
<code>DocumentAccess</code>
|
||||
<code>IndexDocument</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="4">
|
||||
<code>getDescription</code>
|
||||
<code>getDescription</code>
|
||||
<code>getTitle</code>
|
||||
<code>getTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/LabelService.php">
|
||||
<UndefinedMagicMethod occurrences="4">
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setColor</code>
|
||||
<code>setColor</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/OverviewService.php">
|
||||
<UndefinedMagicMethod occurrences="4">
|
||||
<code>setAssignedUsers</code>
|
||||
<code>setAttachmentCount</code>
|
||||
<code>setCommentsUnread</code>
|
||||
<code>setLabels</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/PermissionService.php">
|
||||
<UndefinedClass occurrences="2">
|
||||
<UndefinedClass occurrences="3">
|
||||
<code>Member</code>
|
||||
<code>\OCA\Circles\Api\v1\Circles</code>
|
||||
<code>\OCA\Circles\Api\v1\Circles</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="6">
|
||||
<code>getAcl</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getParticipant</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
<code>getType</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
<file src="lib/Service/StackService.php">
|
||||
<InvalidArgument occurrences="3">
|
||||
<code>'\OCA\Deck\Stack::onCreate'</code>
|
||||
<code>'\OCA\Deck\Stack::onDelete'</code>
|
||||
<code>'\OCA\Deck\Stack::onUpdate'</code>
|
||||
</InvalidArgument>
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>BadRquestException</code>
|
||||
</UndefinedClass>
|
||||
<UndefinedMagicMethod occurrences="14">
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getBoardId</code>
|
||||
<code>getOrder</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setBoardId</code>
|
||||
<code>setCards</code>
|
||||
<code>setDeletedAt</code>
|
||||
<code>setDeletedAt</code>
|
||||
<code>setOrder</code>
|
||||
<code>setOrder</code>
|
||||
<code>setTitle</code>
|
||||
<code>setTitle</code>
|
||||
</UndefinedMagicMethod>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
@@ -39,6 +39,7 @@ use OCP\Activity\IEvent;
|
||||
use OCP\Activity\IManager;
|
||||
use OCP\IL10N;
|
||||
use OCP\IUser;
|
||||
use OCP\L10N\IFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit_Framework_MockObject_MockObject as MockObject;
|
||||
|
||||
@@ -60,6 +61,8 @@ class ActivityManagerTest extends TestCase {
|
||||
private $attachmentMapper;
|
||||
/** @var AclMapper|MockObject */
|
||||
private $aclMapper;
|
||||
/** @var IFactory|MockObject */
|
||||
private $l10nFactory;
|
||||
/** @var IL10N|MockObject */
|
||||
private $l10n;
|
||||
/** @var string */
|
||||
@@ -73,6 +76,7 @@ class ActivityManagerTest extends TestCase {
|
||||
$this->stackMapper = $this->createMock(StackMapper::class);
|
||||
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
|
||||
$this->aclMapper = $this->createMock(AclMapper::class);
|
||||
$this->l10nFactory = $this->createMock(IFactory::class);
|
||||
$this->l10n = $this->createMock(IL10N::class);
|
||||
$this->activityManager = new ActivityManager(
|
||||
$this->manager,
|
||||
@@ -82,7 +86,7 @@ class ActivityManagerTest extends TestCase {
|
||||
$this->stackMapper,
|
||||
$this->attachmentMapper,
|
||||
$this->aclMapper,
|
||||
$this->l10n,
|
||||
$this->l10nFactory,
|
||||
$this->userId
|
||||
);
|
||||
}
|
||||
@@ -94,17 +98,20 @@ class ActivityManagerTest extends TestCase {
|
||||
->will($this->returnCallback(function ($s) {
|
||||
return $s;
|
||||
}));
|
||||
$this->l10nFactory->method('get')
|
||||
->with('deck', 'cz')
|
||||
->willReturn($this->l10n);
|
||||
|
||||
foreach ($managerClass->getConstants() as $constant => $value) {
|
||||
if (strpos($constant, 'SUBJECT') === 0) {
|
||||
$format = $this->activityManager->getActivityFormat($value, [], false);
|
||||
$format = $this->activityManager->getActivityFormat('cz', $value, [], false);
|
||||
if ($format !== '') {
|
||||
$this->assertStringContainsString('{user}', $format);
|
||||
} else {
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
print_r('No activity string found for '. $constant . PHP_EOL);
|
||||
}
|
||||
$format = $this->activityManager->getActivityFormat($value, [], true);
|
||||
$format = $this->activityManager->getActivityFormat('cz', $value, [], true);
|
||||
if ($format !== '') {
|
||||
$this->assertStringStartsWith('You', $format);
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
namespace OCA\Deck\Db;
|
||||
|
||||
use OCP\IGroupManager;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use Test\AppFramework\Db\MapperTestUtility;
|
||||
|
||||
@@ -54,7 +55,8 @@ class AclMapperTest extends MapperTestUtility {
|
||||
$this->aclMapper,
|
||||
\OC::$server->query(StackMapper::class),
|
||||
$this->userManager,
|
||||
$this->groupManager
|
||||
$this->groupManager,
|
||||
$this->createMock(ILogger::class)
|
||||
);
|
||||
|
||||
$this->boards = [
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace OCA\Deck\Db;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use Test\AppFramework\Db\MapperTestUtility;
|
||||
|
||||
@@ -61,7 +62,8 @@ class BoardMapperTest extends MapperTestUtility {
|
||||
\OC::$server->query(AclMapper::class),
|
||||
\OC::$server->query(StackMapper::class),
|
||||
$this->userManager,
|
||||
$this->groupManager
|
||||
$this->groupManager,
|
||||
$this->createMock(ILogger::class)
|
||||
);
|
||||
$this->aclMapper = \OC::$server->query(AclMapper::class);
|
||||
$this->labelMapper = \OC::$server->query(LabelMapper::class);
|
||||
|
||||
@@ -47,10 +47,12 @@ class ExceptionMiddlewareTest extends \Test\TestCase {
|
||||
public function setUp(): void {
|
||||
$this->logger = $this->createMock(ILogger::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->request = $this->createMock(IRequest::class);
|
||||
$this->controller = $this->createMock(Controller::class);
|
||||
$this->exceptionMiddleware = new ExceptionMiddleware(
|
||||
$this->logger,
|
||||
$this->config
|
||||
$this->config,
|
||||
$this->request
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,10 +83,11 @@ class ExceptionMiddlewareTest extends \Test\TestCase {
|
||||
}
|
||||
|
||||
public function testAfterExceptionFail() {
|
||||
$this->request->expects($this->any())->method('getId')->willReturn('abc123');
|
||||
// BoardService $boardService, PermissionService $permissionService, $userId
|
||||
$boardController = new BoardController('deck', $this->createMock(IRequest::class), $this->createMock(BoardService::class), $this->createMock(PermissionService::class), 'admin');
|
||||
$result = $this->exceptionMiddleware->afterException($boardController, 'bar', new \Exception('failed hard'));
|
||||
$this->assertEquals('failed hard', $result->getData()['message']);
|
||||
$result = $this->exceptionMiddleware->afterException($boardController, 'bar', new \Exception('other exception message'));
|
||||
$this->assertEquals('Internal server error: Please contact the server administrator if this error reappears multiple times, please include the request ID "abc123" below in your report.', $result->getData()['message']);
|
||||
$this->assertEquals(500, $result->getData()['status']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Deck\Migration;
|
||||
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\AclMapper;
|
||||
use OCA\Deck\Db\Board;
|
||||
use OCA\Deck\Db\BoardMapper;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Migration\IOutput;
|
||||
|
||||
class UnknownUserTest extends \Test\TestCase {
|
||||
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
/** @var IGroupManager */
|
||||
private $groupManager;
|
||||
/** @var AclMapper */
|
||||
private $aclMapper;
|
||||
/** @var BoardMapper */
|
||||
private $boardMapper;
|
||||
/** @var UnknownUsers */
|
||||
private $unknownUsers;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->userManager = $this->createMock(IUserManager::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->aclMapper = $this->createMock(AclMapper::class);
|
||||
$this->boardMapper = $this->createMock(BoardMapper::class);
|
||||
$this->unknownUsers = new UnknownUsers($this->userManager, $this->groupManager, $this->aclMapper, $this->boardMapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testGetName() {
|
||||
$this->assertEquals('Delete orphaned ACL rules', $this->unknownUsers->getName());
|
||||
}
|
||||
|
||||
public function testRun() {
|
||||
/** @var IOutput $output */
|
||||
$output = $this->createMock(IOutput::class);
|
||||
$boards = [
|
||||
$this->getBoard(1,'Test', 'admin'),
|
||||
];
|
||||
$acl = [
|
||||
$this->getAcl(Acl::PERMISSION_TYPE_USER, 'existing', 1),
|
||||
$this->getAcl(Acl::PERMISSION_TYPE_USER, 'not existing', 1),
|
||||
$this->getAcl(Acl::PERMISSION_TYPE_GROUP, 'existing', 1),
|
||||
$this->getAcl(Acl::PERMISSION_TYPE_GROUP, 'not existing', 1),
|
||||
];
|
||||
$this->aclMapper->expects($this->at(0))
|
||||
->method('findAll')
|
||||
->with(1)
|
||||
->willReturn($acl);
|
||||
|
||||
$this->userManager->expects($this->at(0))
|
||||
->method('get')
|
||||
->with('existing')
|
||||
->willReturn(true);
|
||||
$this->userManager->expects($this->at(1))
|
||||
->method('get')
|
||||
->with('not existing')
|
||||
->willReturn(null);
|
||||
$this->groupManager->expects($this->at(0))
|
||||
->method('get')
|
||||
->with('existing')
|
||||
->willReturn(true);
|
||||
$this->groupManager->expects($this->at(1))
|
||||
->method('get')
|
||||
->with('not existing')
|
||||
->willReturn(null);
|
||||
|
||||
$this->boardMapper->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn($boards);
|
||||
|
||||
$this->aclMapper->expects($this->at(1))
|
||||
->method('delete')
|
||||
->with($acl[1]);
|
||||
$this->aclMapper->expects($this->at(2))
|
||||
->method('delete')
|
||||
->with($acl[3]);
|
||||
|
||||
$this->unknownUsers->run($output);
|
||||
}
|
||||
|
||||
|
||||
/** @return Acl */
|
||||
public function getAcl($type = Acl::PERMISSION_TYPE_USER, $participant = 'admin', $boardId = 123) {
|
||||
$acl = new Acl();
|
||||
$acl->setParticipant($participant);
|
||||
$acl->setType($type);
|
||||
$acl->setBoardId($boardId);
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/** @return Board */
|
||||
public function getBoard($id, $title, $owner) {
|
||||
$board = new Board();
|
||||
$board->setId($id);
|
||||
$board->setTitle($title);
|
||||
$board->setOwner($owner);
|
||||
return $board;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,8 @@ class NotificationHelperTest extends \Test\TestCase {
|
||||
$card = Card::fromParams([
|
||||
'notified' => false,
|
||||
'id' => 123,
|
||||
'title' => 'MyCardTitle'
|
||||
'title' => 'MyCardTitle',
|
||||
'duedate' => '2020-12-24'
|
||||
]);
|
||||
$this->cardMapper->expects($this->once())
|
||||
->method('findBoardId')
|
||||
@@ -225,7 +226,8 @@ class NotificationHelperTest extends \Test\TestCase {
|
||||
$card = Card::fromParams([
|
||||
'notified' => false,
|
||||
'id' => 123,
|
||||
'title' => 'MyCardTitle'
|
||||
'title' => 'MyCardTitle',
|
||||
'duedate' => '2020-12-24'
|
||||
]);
|
||||
$card->setAssignedUsers([
|
||||
new User($users[0])
|
||||
@@ -323,7 +325,8 @@ class NotificationHelperTest extends \Test\TestCase {
|
||||
$card = Card::fromParams([
|
||||
'notified' => false,
|
||||
'id' => 123,
|
||||
'title' => 'MyCardTitle'
|
||||
'title' => 'MyCardTitle',
|
||||
'duedate' => '2020-12-24'
|
||||
]);
|
||||
$card->setAssignedUsers([
|
||||
new User($users[0])
|
||||
@@ -470,7 +473,7 @@ class NotificationHelperTest extends \Test\TestCase {
|
||||
->with(123)
|
||||
->willReturn($board);
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->expects($this->once())
|
||||
$user->expects($this->any())
|
||||
->method('getUID')
|
||||
->willReturn('userA');
|
||||
$group = $this->createMock(IGroup::class);
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace OCA\Deck\Service;
|
||||
|
||||
use OCA\Deck\Db\Attachment;
|
||||
use OCA\Deck\Db\AttachmentMapper;
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
use OCP\AppFramework\Http\StreamResponse;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\Files\SimpleFS\ISimpleFolder;
|
||||
@@ -57,6 +57,8 @@ class FileServiceTest extends TestCase {
|
||||
private $config;
|
||||
/** @var AttachmentMapper|MockObject */
|
||||
private $attachmentMapper;
|
||||
/** @var IMimeTypeDetector|MockObject */
|
||||
private $mimeTypeDetector;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
@@ -67,7 +69,8 @@ class FileServiceTest extends TestCase {
|
||||
$this->rootFolder = $this->createMock(IRootFolder::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->attachmentMapper = $this->createMock(AttachmentMapper::class);
|
||||
$this->fileService = new FileService($this->l10n, $this->appData, $this->request, $this->logger, $this->rootFolder, $this->config, $this->attachmentMapper);
|
||||
$this->mimeTypeDetector = $this->createMock(IMimeTypeDetector::class);
|
||||
$this->fileService = new FileService($this->l10n, $this->appData, $this->request, $this->logger, $this->rootFolder, $this->config, $this->attachmentMapper, $this->mimeTypeDetector);
|
||||
}
|
||||
|
||||
public function mockGetFolder($cardId) {
|
||||
@@ -268,51 +271,13 @@ class FileServiceTest extends TestCase {
|
||||
$file->expects($this->any())
|
||||
->method('fopen')
|
||||
->willReturn('fileresource');
|
||||
$this->mimeTypeDetector->expects($this->once())
|
||||
->method('getSecureMimeType')
|
||||
->willReturn('image/jpeg');
|
||||
$actual = $this->fileService->display($attachment);
|
||||
$expected = new StreamResponse('fileresource');
|
||||
$expected->addHeader('Content-Type', 'image/jpeg');
|
||||
$expected->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"');
|
||||
$policy = new ContentSecurityPolicy();
|
||||
$policy->addAllowedObjectDomain('\'self\'');
|
||||
$policy->addAllowedObjectDomain('blob:');
|
||||
$policy->addAllowedMediaDomain('\'self\'');
|
||||
$policy->addAllowedMediaDomain('blob:');
|
||||
$expected->setContentSecurityPolicy($policy);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function testDisplayPdf() {
|
||||
$this->config->expects($this->once())
|
||||
->method('getSystemValue')
|
||||
->willReturn('123');
|
||||
$appDataFolder = $this->createMock(Folder::class);
|
||||
$deckAppDataFolder = $this->createMock(Folder::class);
|
||||
$cardFolder = $this->createMock(Folder::class);
|
||||
$this->rootFolder->expects($this->once())->method('get')->willReturn($appDataFolder);
|
||||
$appDataFolder->expects($this->once())->method('get')->willReturn($deckAppDataFolder);
|
||||
$deckAppDataFolder->expects($this->once())->method('get')->willReturn($cardFolder);
|
||||
$attachment = $this->getAttachment();
|
||||
$file = $this->createMock(\OCP\Files\File::class);
|
||||
$cardFolder->expects($this->once())->method('get')->willReturn($file);
|
||||
$file->expects($this->any())
|
||||
->method('getMimeType')
|
||||
->willReturn('application/pdf');
|
||||
$file->expects($this->any())
|
||||
->method('getName')
|
||||
->willReturn('file1');
|
||||
$file->expects($this->any())
|
||||
->method('fopen')
|
||||
->willReturn('fileresource');
|
||||
$actual = $this->fileService->display($attachment);
|
||||
$expected = new StreamResponse('fileresource');
|
||||
$expected->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"');
|
||||
$expected->addHeader('Content-Type', 'application/pdf');
|
||||
$policy = new ContentSecurityPolicy();
|
||||
$policy->addAllowedObjectDomain('\'self\'');
|
||||
$policy->addAllowedObjectDomain('blob:');
|
||||
$policy->addAllowedMediaDomain('\'self\'');
|
||||
$policy->addAllowedMediaDomain('blob:');
|
||||
$expected->setContentSecurityPolicy($policy);
|
||||
$expected->addHeader('Content-Disposition', 'attachment; filename="' . rawurldecode($file->getName()) . '"');
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ const config = {
|
||||
entry: {
|
||||
collections: path.join(__dirname, 'src', 'init-collections.js'),
|
||||
dashboard: path.join(__dirname, 'src', 'init-dashboard.js'),
|
||||
calendar: path.join(__dirname, 'src', 'init-calendar.js'),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
|
||||
Reference in New Issue
Block a user