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

Multiple author affiliations #10460

Open
wants to merge 113 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 98 commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
fa1f010
Eloquent model
GaziYucel Sep 20, 2024
0e13644
UI (work in progress)
GaziYucel Sep 20, 2024
60807c9
UI (work in progress)
GaziYucel Sep 20, 2024
a8b1bed
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Sep 23, 2024
b6af604
vuejs skeletion
GaziYucel Sep 23, 2024
d772744
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Sep 24, 2024
58f4abe
multiple-author-affiliations
GaziYucel Sep 24, 2024
08a55c0
Author Affiliations (work in progress)
GaziYucel Sep 26, 2024
81bf90f
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Sep 27, 2024
1a6ed69
Author Affiliations (work in progress)
GaziYucel Sep 27, 2024
9e359ff
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Sep 29, 2024
8f0af65
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 2, 2024
c762570
Author affiliations (work in progress)
GaziYucel Oct 3, 2024
454b300
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 4, 2024
44daa68
Author affiliations locale (work in progress)
GaziYucel Oct 4, 2024
c4eee42
Author affiliations locale (work in progress)
GaziYucel Oct 4, 2024
bcaabf9
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 7, 2024
d0c6b5c
get / set affiliation moved from identity to author and user
GaziYucel Oct 7, 2024
a0d1d10
Typo fixed PKP\affiliation\Affiliation > PKP\affiliation\Repository
GaziYucel Oct 7, 2024
758c1a8
Refactor AuthorAffiliations to Affiliations
GaziYucel Oct 7, 2024
5a42adb
Migration scripts
GaziYucel Oct 7, 2024
bddc094
Author Affiliations (work in progress)
GaziYucel Oct 7, 2024
e2b35ea
Author Affiliations (work in progress)
GaziYucel Oct 7, 2024
51bd801
Author Affiliations (work in progress)
GaziYucel Oct 7, 2024
7f026e2
Author Affiliations (work in progress)
GaziYucel Oct 7, 2024
7b178f5
Author affiliations (work in progress)
GaziYucel Oct 7, 2024
57a8e60
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 8, 2024
fd5c090
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
b52570f
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
8706bcd
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
77e6141
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
4e59a2c
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
50303e4
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
a2da59a
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
a804952
Author Affiliations (work in progress)
GaziYucel Oct 8, 2024
c8a5c7e
Author affiliations (work in progress)
GaziYucel Oct 8, 2024
93afa41
Author affiliations (work in progress)
GaziYucel Oct 8, 2024
ff43051
Author affiliations (work in progress)
GaziYucel Oct 9, 2024
7120f52
Author Affiliations (work in progress)
GaziYucel Oct 9, 2024
9851618
Author Affiliations (work in progress)
GaziYucel Oct 9, 2024
0e4b7a3
Author affiliations (work in progress)
GaziYucel Oct 9, 2024
f1986b9
Author Affiliations (work in progress)
GaziYucel Oct 9, 2024
bd98be2
Author affiliations (work in progress)
GaziYucel Oct 9, 2024
771b8b8
Author affiliations (work in progress)
GaziYucel Oct 9, 2024
858a63a
Author affiliations (work in progress)
GaziYucel Oct 9, 2024
5073b8b
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 10, 2024
bc21ee9
Author affiliations (work in progress)
GaziYucel Oct 10, 2024
46f5f68
Author Affiliations (work in progress)
GaziYucel Oct 10, 2024
4484eb4
Author Affiliations (work in progress)
GaziYucel Oct 10, 2024
00ef141
Author Affiliations (work in progress)
GaziYucel Oct 10, 2024
9a01107
Merge branch 'multiple-author-affiliations' of https://github.com/Gaz…
GaziYucel Oct 10, 2024
5f254b8
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 10, 2024
5f7582e
Merge branch 'multiple-author-affiliations' of https://github.com/Gaz…
GaziYucel Oct 10, 2024
18e00fd
ror-registry-data-cache
GaziYucel Oct 10, 2024
fbc52e8
Copyright year
GaziYucel Oct 10, 2024
f7a3f5b
Move position under biography
GaziYucel Oct 10, 2024
b316f4a
Whitespace
GaziYucel Oct 10, 2024
d866254
fixme: multiple-author-affiliations
GaziYucel Oct 10, 2024
a12f349
Make ror non required; isActive removed, should not be there
GaziYucel Oct 14, 2024
992012a
fixme: does not save is affiliations list is empty
GaziYucel Oct 14, 2024
8049b04
Merge conflict
GaziYucel Oct 21, 2024
63e2e61
Merge conflict
GaziYucel Oct 21, 2024
1a0b1fa
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 21, 2024
17b2316
Merge conflict reapply
GaziYucel Oct 21, 2024
65c5de5
Update ror data set cache after migration
GaziYucel Oct 21, 2024
69be1c2
Save empty affiliations; Form config currentLocale and supportedLocales
GaziYucel Oct 21, 2024
555df2c
Default value if null
GaziYucel Oct 21, 2024
2d6f7ab
Translations
GaziYucel Oct 21, 2024
067ab1a
saveAffiliations: insert, update, delete
GaziYucel Oct 21, 2024
8237869
Migrate affiliations to multiple affiliations
GaziYucel Oct 22, 2024
0a2c105
Migrate affiliations to multiple affiliations (finished)
GaziYucel Oct 22, 2024
bdf5363
Typo
GaziYucel Oct 23, 2024
fcc9d41
Typo
GaziYucel Oct 23, 2024
2137bae
Sort supported locales
GaziYucel Oct 23, 2024
c5e8fde
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 23, 2024
6218122
translations english
GaziYucel Oct 24, 2024
6a4d8d7
query name search => searchPhrase
GaziYucel Oct 24, 2024
91079d1
_data removed
GaziYucel Oct 24, 2024
dae710a
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 24, 2024
a002070
"_data" removed from api response
GaziYucel Oct 24, 2024
6da506b
remove temporary file
GaziYucel Oct 25, 2024
dd6ea42
displayLocale removed from schema
GaziYucel Oct 25, 2024
1b76d67
Bug fix
GaziYucel Oct 25, 2024
4689bae
copyright fix; phpdoc
GaziYucel Oct 25, 2024
af4503f
get mapped to schema
GaziYucel Oct 25, 2024
7676788
locale display names
GaziYucel Oct 25, 2024
7bc5035
Map affiliations to schema
GaziYucel Oct 25, 2024
f42bc8d
More places fixme: multiple-author-affiliations
GaziYucel Oct 25, 2024
1d7dc88
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 28, 2024
f022438
Multiple fixme issues implemented, cleanup, copyright
GaziYucel Oct 28, 2024
a64c28f
Multiple fixme issues implemented, cleanup, copyright
GaziYucel Oct 28, 2024
1f8abf5
setAffiliationsFromString for NativeXmlPKPAuthorFilter
GaziYucel Oct 29, 2024
732bd46
setAffiliationsFromString for NativeXmlPKPAuthorFilter
GaziYucel Oct 29, 2024
2199df7
Merge branch 'multiple-author-affiliations' of https://github.com/Gaz…
GaziYucel Oct 29, 2024
e3f9938
Error creating tables: foreign key first, then indexes.
GaziYucel Oct 29, 2024
72f8d73
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Oct 30, 2024
c1a513b
Typo
GaziYucel Nov 1, 2024
1606cbc
Map affiliations to schema
GaziYucel Nov 1, 2024
d490a47
Merge branch 'pkp:main' into multiple-author-affiliations
GaziYucel Nov 4, 2024
723eba2
Copyright years fixed
GaziYucel Nov 4, 2024
c9881ae
AdvancedSearchReviewerForm
GaziYucel Nov 5, 2024
e93b597
Separator changed from ", " to "; "
GaziYucel Nov 7, 2024
2a0d842
Review changes (work in progress)
GaziYucel Nov 7, 2024
e82bf5a
Fix: no need to index foreign key column
GaziYucel Nov 8, 2024
9fd8ae5
Adjustments for review of Bozana (work in progress)
GaziYucel Nov 11, 2024
6595073
Adjustments for review of Bozana (work in progress)
GaziYucel Nov 11, 2024
306b014
Adjustments for review of Bozana (work in progress)
GaziYucel Nov 11, 2024
f92025f
Validation for affiliations
GaziYucel Nov 12, 2024
5b0ebd3
Validation for affiliations: call validate method
GaziYucel Nov 12, 2024
1f7b649
Validation for affiliations: bugs validate method
GaziYucel Nov 12, 2024
d3b2014
Import / export logic
GaziYucel Nov 13, 2024
f06dc8b
LazyCollection > array
GaziYucel Nov 13, 2024
8e156a7
setAffiliationsFromString cleanup
GaziYucel Nov 13, 2024
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
146 changes: 146 additions & 0 deletions api/v1/rors/PKPRorController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<?php
/**
* @file api/v1/rors/PKPRorController.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPRorController
*
* @ingroup api_v1_rors
*
* @brief Controller class to handle API requests for ror operations.
*
*/

namespace PKP\API\v1\rors;

use APP\facades\Repo;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Route;
use PKP\core\PKPBaseController;
use PKP\core\PKPRequest;
use PKP\plugins\Hook;
use PKP\security\authorization\ContextRequiredPolicy;
use PKP\security\authorization\PolicySet;
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
use PKP\security\authorization\UserRolesRequiredPolicy;
use PKP\security\Role;

class PKPRorController extends PKPBaseController
{
/** @var int The default number of rors to return in one request */
public const DEFAULT_COUNT = 30;

/** @var int The maximum number of rors to return in one request */
public const MAX_COUNT = 100;

/**
* @copydoc \PKP\core\PKPBaseController::getHandlerPath()
*/
public function getHandlerPath(): string
{
return 'rors';
}

/**
* @copydoc \PKP\core\PKPBaseController::getRouteGroupMiddleware()
*/
public function getRouteGroupMiddleware(): array
{
return [
'has.user',
'has.context',
self::roleAuthorizer([
Role::ROLE_ID_MANAGER,
]),
];
}

/**
* @copydoc \PKP\core\PKPBaseController::getGroupRoutes()
*/
public function getGroupRoutes(): void
{
Route::get('{rorId}', $this->get(...))
->name('ror.getRor')
->whereNumber('rorId');

Route::get('', $this->getMany(...))
->name('ror.getMany');
}

/**
* @copydoc \PKP\core\PKPBaseController::authorize()
*/
public function authorize(PKPRequest $request, array &$args, array $roleAssignments): bool
{
$this->addPolicy(new UserRolesRequiredPolicy($request), true);

$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);

$this->addPolicy(new ContextRequiredPolicy($request));

foreach ($roleAssignments as $role => $operations) {
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
}

$this->addPolicy($rolePolicy);

return parent::authorize($request, $args, $roleAssignments);
}

/**
* Get a single ror
*/
public function get(Request $illuminateRequest): JsonResponse
{
if (!Repo::ror()->exists((int) $illuminateRequest->route('rorId'), $this->getRequest()->getContext()->getId())) {
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
return response()->json([
'error' => __('api.rors.404.rorNotFound')
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
], Response::HTTP_OK);
}

$ror = Repo::ror()->get((int) $illuminateRequest->route('rorId'));

return response()->json(Repo::ror()->getSchemaMap()->map($ror), Response::HTTP_OK);
}

/**
* Get a collection of rors
*
* @hook API::rors::params [[$collector, $illuminateRequest]]
*/
public function getMany(Request $illuminateRequest): JsonResponse
{
$collector = Repo::ror()->getCollector()
->limit(self::DEFAULT_COUNT)
->offset(0);

foreach ($illuminateRequest->query() as $param => $val) {
switch ($param) {
case 'count':
$collector->limit(min((int) $val, self::MAX_COUNT));
break;
case 'offset':
$collector->offset((int) $val);
break;
case 'searchPhrase':
$collector->filterBySearchPhrase($val);
break;
}
}

Hook::call('API::rors::params', [$collector, $illuminateRequest]);

$rors = $collector->getMany();

return response()->json([
'itemsMax' => $collector->getCount(),
'items' => Repo::ror()->getSchemaMap()->summarizeMany($rors->values())->values(),
], Response::HTTP_OK);
}
}
6 changes: 3 additions & 3 deletions api/v1/submissions/PKPSubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
/**
* @file api/v1/submissions/PKPSubmissionController.php
*
* Copyright (c) 2023 Simon Fraser University
* Copyright (c) 2023 John Willinsky
* Copyright (c) 2023-2024 Simon Fraser University
* Copyright (c) 2023-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPSubmissionController
Expand Down Expand Up @@ -666,7 +666,7 @@ public function add(Request $illuminateRequest): JsonResponse

// Create an author record from the submitter's user account
if ($submitAsUserGroup->getRoleId() === Role::ROLE_ID_AUTHOR) {
$author = Repo::author()->newAuthorFromUser($request->getUser());
$author = Repo::author()->newAuthorFromUser($request->getUser(), $submission->getDefaultLocale());
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
$author->setData('publicationId', $publication->getId());
$author->setUserGroupId($submitAsUserGroup->getId());
$authorId = Repo::author()->add($author);
Expand Down
47 changes: 47 additions & 0 deletions classes/affiliation/Affiliation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* @file classes/affiliation/Affiliation.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Affiliation
*
* @ingroup affiliation
*
* @see DAO
*
* @brief Basic class describing a affiliation.
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
*/

namespace PKP\affiliation;

use PKP\core\DataObject;

class Affiliation extends DataObject
{
/**
* Get author id
*/
public function getAuthorId()
{
return $this->getData('authorId');
}

/**
* Get the ROR
*
* @return string|null
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
*/
public function getROR(): ?string
{
return $this->getData('ror');
}

/** @copydoc DataObject::getLocalizedGivenName() */
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
public function getLocalizedName(): mixed
{
return $this->getLocalizedData('name');
}
}
155 changes: 155 additions & 0 deletions classes/affiliation/Collector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* @file classes/affiliation/Collector.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Collector
*
* @brief A helper class to configure a Query Builder to get a collection of rors
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
*/

namespace PKP\affiliation;

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 Affiliation
*/
class Collector implements CollectorInterface
{
/** @var DAO */
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
public DAO $dao;

public ?int $count = null;

public ?int $offset = null;

/** @var int[]|null */
public ?array $authorIds = null;

/** Get affiliations with a name */
public ?string $name = null;

public ?string $searchPhrase = 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 authors
*/
public function filterByAuthorIds(?array $authorIds): self
{
$this->authorIds = $authorIds;
return $this;
}

/**
* Filter by affiliation name.
*
* @param string|null $name
*
* @return $this
GaziYucel marked this conversation as resolved.
Show resolved Hide resolved
*/
public function filterByName(?string $name): self
{
$this->name = $name;
return $this;
}

/**
* Filter rors by those matching a search query
*/
public function searchPhrase(?string $phrase): self
{
$this->searchPhrase = $phrase;
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()
*/
public function getQueryBuilder(): Builder
{
$qb = DB::table($this->dao->table . ' as a')
->select('a.*');

if (!is_null($this->count)) {
$qb->limit($this->count);
}

if (!is_null($this->offset)) {
$qb->offset($this->offset);
}

if (!is_null($this->authorIds)) {
$qb->whereIn('a.author_id', $this->authorIds);
}

$qb->when($this->name !== null, function (Builder $qb) {
$qb->whereIn('a.author_affiliation_id', function (Builder $qb) {
$qb->select('author_affiliation_id')
->from($this->dao->settingsTable)
->where('setting_name', '=', 'name')
->where('setting_value', $this->name);
});
});

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

return $qb;
}
}
Loading