Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkp/pkp-lib#9456 Add user private notes #9549

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions classes/components/listPanels/PKPSelectReviewerListPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,17 @@ public function getConfig()
];

if (!empty($this->lastRoundReviewers)) {
$config['lastRoundReviewers'] = Repo::user()
$reviewers = Repo::user()
->getSchemaMap()
->summarizeManyReviewers($this->lastRoundReviewers)
->values()
->toArray();
$contextId = $this->getParams['contextId'];
foreach ($reviewers as $key => $reviewer) {
$userPrivateNote = Repo::userPrivateNote()->getUserPrivateNote($reviewer->getId(), $contextId);
$reviewers[$key]['userPrivateNote'] = $userPrivateNote?->getNote();
}
$config['lastRoundReviewers'] = $reviewers;
}

if (!empty($this->getParams)) {
Expand All @@ -147,6 +153,7 @@ public function getConfig()
$config['declinedReviewsLabel'] = __('reviewer.list.declinedReviews');
$config['emptyLabel'] = __('reviewer.list.empty');
$config['gossipLabel'] = __('user.gossip');
$config['userPrivateNotesLabel'] = __('user.private.notes');
$config['neverAssignedLabel'] = __('reviewer.list.neverAssigned');
$config['reassignLabel'] = __('reviewer.list.reassign');
$config['reassignWithNameLabel'] = __('reviewer.list.reassign.withName');
Expand All @@ -172,8 +179,12 @@ public function getItems($request)
$reviewers = $this->_getCollector()->getMany();
$items = [];
$map = Repo::user()->getSchemaMap();
$contextId = $request->getContext()->getId();
foreach ($reviewers as $reviewer) {
$items[] = $map->summarizeReviewer($reviewer);
$item = $map->summarizeReviewer($reviewer);
$userPrivateNote = Repo::userPrivateNote()->getUserPrivateNote($reviewer->getId(), $contextId);
$item['userPrivateNote'] = $userPrivateNote?->getNote();
$items[] = $item;
}

return $items;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,17 @@ public function gossip($args, $request)
return new JSONMessage(false, __('user.authorization.roleBasedAccessDenied'));
}

$userPrivateNote = Repo::userPrivateNote()->getUserPrivateNote($user->getId(), $request->getContext()->getId());
if (!$userPrivateNote) {
$userPrivateNote = Repo::userPrivateNote()->newDataObject([
'userId' => $user->getId(),
'contextId' => $request->getContext()->getId(),
'note' => ''
]);
}

$requestArgs = array_merge($this->getRequestArgs(), ['reviewAssignmentId' => $reviewAssignment->getId()]);
$reviewerGossipForm = new ReviewerGossipForm($user, $requestArgs);
$reviewerGossipForm = new ReviewerGossipForm($user, $userPrivateNote, $requestArgs);

// View form
if (!$request->isPost()) {
Expand Down
6 changes: 6 additions & 0 deletions classes/facades/Repo.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use PKP\log\event\Repository as EventLogRepository;
use PKP\submissionFile\Repository as SubmissionFileRepository;
use PKP\userGroup\Repository as UserGroupRepository;
use PKP\userPrivateNote\Repository as UserPrivateNoteRepository;

class Repo
{
Expand Down Expand Up @@ -90,6 +91,11 @@ public static function userGroup(): UserGroupRepository
return app(UserGroupRepository::class);
}

public static function userPrivateNote(): UserPrivateNoteRepository
{
return app(UserPrivateNoteRepository::class);
}

public static function eventLog(): EventLogRepository
{
return app(EventLogRepository::class);
Expand Down
56 changes: 56 additions & 0 deletions classes/migration/install/UserPrivateNotesMigration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/**
* @file classes/migration/install/UserPrivateNotesMigration.php
*
* Copyright (c) 2014-2023 Simon Fraser University
* Copyright (c) 2000-2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class UserPrivateNotesMigration
*
* @brief Describe database table structure for user private notes
*/

namespace PKP\migration\install;

use APP\core\Application;
use APP\facades\Repo;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema as Schema;
use PKP\migration\Migration;

class UserPrivateNotesMigration extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_private_notes', function (Blueprint $table) {
$table->comment('User private notes are an addition to the gossip, but this one is private to each context.');
$table->bigInteger('user_private_note_id')->autoIncrement();

$table->bigInteger('context_id');
$contextDao = Application::getContextDAO();
$table->foreign('context_id')->references($contextDao->primaryKeyColumn)->on($contextDao->tableName)->onDelete('cascade');

$table->bigInteger('user_id');
$userDao = Repo::user()->dao;
$table->foreign('user_id')->references($userDao->primaryKeyColumn)->on($userDao->table)->onDelete('cascade');

$table->unique(['context_id', 'user_id'], 'user_private_notes_unique');
$table->index(['context_id'], 'user_private_notes_context_id_foreign');

$table->string('note')->default('');
});
}

/**
* Reverse the migration.
*/
public function down(): void
{
Schema::drop('user_private_notes');
}
}
54 changes: 54 additions & 0 deletions classes/migration/upgrade/v3_5_0/I9456_UserPrivateNotes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

/**
* @file classes/migration/upgrade/v3_5_0/I9456_UserPrivateNotes.php
*
* Copyright (c) 2014-2023 Simon Fraser University
* Copyright (c) 2000-2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class I9456_UserPrivateNotes
*/

namespace PKP\migration\upgrade\v3_5_0;

use APP\core\Application;
use APP\facades\Repo;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use PKP\migration\Migration;

class I9456_UserPrivateNotes extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_private_notes', function (Blueprint $table) {
$table->comment('User private notes are an addition to the gossip, but this one is private to each context.');
$table->bigInteger('user_private_note_id')->autoIncrement();

$table->bigInteger('context_id');
$contextDao = Application::getContextDAO();
$table->foreign('context_id')->references($contextDao->primaryKeyColumn)->on($contextDao->tableName)->onDelete('cascade');

$table->bigInteger('user_id');
$userDao = Repo::user()->dao;
$table->foreign('user_id')->references($userDao->primaryKeyColumn)->on($userDao->table)->onDelete('cascade');

$table->unique(['context_id', 'user_id'], 'user_private_notes_unique');
$table->index(['context_id'], 'user_private_notes_context_id_foreign');

$table->string('note')->default('');
});
}

/**
* Reverse the migration.
*/
public function down(): void
{
Schema::drop('user_private_notes');
}
}
2 changes: 2 additions & 0 deletions classes/services/PKPSchemaService.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class PKPSchemaService
public const SCHEMA_SUBMISSION_FILE = 'submissionFile';
public const SCHEMA_USER = 'user';
public const SCHEMA_USER_GROUP = 'userGroup';
public const SCHEMA_USER_PRIVATE_NOTE = 'userPrivateNote';
public const SCHEMA_EVENT_LOG = 'eventLog';

/** @var array cache of schemas that have been loaded */
Expand Down Expand Up @@ -631,6 +632,7 @@ class_alias('\PKP\services\PKPSchemaService', '\PKPSchemaService');
'SCHEMA_SUBMISSION_FILE',
'SCHEMA_USER',
'SCHEMA_USER_GROUP',
'SCHEMA_USER_PRIVATE_NOTE',
] as $constantName) {
if (!defined($constantName)) {
define($constantName, constant('PKPSchemaService::' . $constantName));
Expand Down
167 changes: 167 additions & 0 deletions classes/userPrivateNote/Collector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/**
* @file classes/userPrivateNote/Collector.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class \PKP\userPrivateNote\Collector
*
* @brief A helper class to configure a Query Builder to get a collection of UserPrivateNote
*/

namespace PKP\userPrivateNote;

use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\LazyCollection;
use PKP\core\interfaces\CollectorInterface;
use PKP\plugins\Hook;

/**
* @template T of UserPrivateNote
*/
class Collector implements CollectorInterface
{
public const ORDERBY_ID = 'id';

public ?string $orderBy = null;

/** @var DAO */
public DAO $dao;

public ?array $userPrivateNoteIds = null;

public ?array $contextIds = null;

public ?array $userIds = null;

public ?int $count = null;

public ?int $offset = null;

public function __construct(DAO $dao)
{
$this->dao = $dao;
}

public function getCount(): int
{
return $this->dao->getCount($this);
}

/**
* @return Collection<int,int>
*/
public function getIds(): Collection
{
return $this->dao->getIds($this);
}

/**
* @copydoc DAO::getMany()
*
* @return LazyCollection<int,T>
*/
public function getMany(): LazyCollection
{
return $this->dao->getMany($this);
}

/**
* Filter by multiple ids
*/
public function filterByUserPrivateNoteIds(?array $ids): self
{
$this->userPrivateNoteIds = $ids;
return $this;
}

/**
* Filter by context IDs
*/
public function filterByContextIds(?array $contextIds): self
{
$this->contextIds = $contextIds;
return $this;
}

/**
* Filter by user ids
*/
public function filterByUserIds(?array $userIds): self
{
$this->userIds = $userIds;
return $this;
}

/**
* Include orderBy columns to the collector query
*/
public function orderBy(?string $orderBy): self
{
$this->orderBy = $orderBy;
return $this;
}

/**
* Limit the number of objects retrieved
*/
public function limit(?int $count): self
{
$this->count = $count;
return $this;
}

/**
* Offset the number of objects retrieved, for example to
* retrieve the second page of contents
*/
public function offset(?int $offset): self
{
$this->offset = $offset;
return $this;
}

/**
* @copydoc CollectorInterface::getQueryBuilder()
*
* @hook UserGroup::Collector [[&$q, $this]]
*/
public function getQueryBuilder(): Builder
{
$q = DB::table('user_private_notes as upn')
->select('upn.*');

if (isset($this->userPrivateNoteIds)) {
$q->whereIn('upn.user_private_note_id', $this->userPrivateNoteIds);
}

if (isset($this->contextIds)) {
$q->whereIn('upn.context_id', $this->contextIds);
}

if (isset($this->userIds)) {
$q->whereIn('upn.user_id', $this->userIds);
}

if (isset($this->count)) {
$q->limit($this->count);
}

if (isset($this->offset)) {
$q->offset($this->offset);
}

if ($this->orderBy == self::ORDERBY_ID) {
$q->orderBy('upn.user_private_note_id');
}

// Add app-specific query statements
Hook::call('UserPrivateNote::Collector', [&$q, $this]);

return $q;
}
}
Loading