Skip to content
Merged
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
11 changes: 10 additions & 1 deletion classes/components/listPanels/DoiListPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ protected function setAppConfig(array &$config): void
]
]
];

$config['filters'][] = [
'heading' => __('manager.dois.filters.workflow'),
'filters' => [
[
'title' => __('manager.dois.filters.inEditingOrPublished'),
'param' => 'inEditingOrPublished',
'value' => '1',
],
],
];
}
}
47 changes: 26 additions & 21 deletions classes/doi/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace APP\doi;

use APP\core\Application;
use APP\facades\Repo;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
Expand All @@ -38,62 +39,66 @@ class DAO extends \PKP\doi\DAO
public function getAllDepositableSubmissionIds(Context $context): Collection
{
$enabledDoiTypes = $context->getData(Context::SETTING_ENABLED_DOI_TYPES) ?? [];
$doiVersioning = (bool) $context->getData(Context::SETTING_DOI_VERSIONING);

$q = DB::table($this->table, 'd')
// Minor versions share their major version's DOIs, so a DOI can match several publications/objects
->leftJoin('publications as p', 'd.doi_id', '=', 'p.doi_id')
->leftJoin('submissions as s', 'p.publication_id', '=', 's.current_publication_id')
->leftJoin('submission_chapters as cd', 'd.doi_id', '=', 'cd.doi_id')
->leftJoin('publications as cp', 'cd.publication_id', '=', 'cp.publication_id')
->leftJoin('publication_formats as pfd', 'd.doi_id', '=', 'pfd.doi_id')
->leftJoin('publications as pfp', 'pfd.publication_id', '=', 'pfp.publication_id')
->leftJoin('submission_files as sfd', 'd.doi_id', '=', 'sfd.doi_id')
->where('d.context_id', '=', $context->getId())
->where(function (Builder $q) use ($enabledDoiTypes) {
->where(function (Builder $q) use ($enabledDoiTypes, $doiVersioning) {
// Publication DOIs
$q->when(in_array(Repo::doi()::TYPE_PUBLICATION, $enabledDoiTypes), function (Builder $q) {
$q->whereIn('d.doi_id', function (Builder $q) {
$q->when(in_array(Repo::doi()::TYPE_PUBLICATION, $enabledDoiTypes), function (Builder $q) use ($doiVersioning) {
$q->whereIn('d.doi_id', function (Builder $q) use ($doiVersioning) {
$q->select('p.doi_id')
->from('publications', 'p')
->leftJoin('submissions as s', 'p.publication_id', '=', 's.current_publication_id')
->whereColumn('p.publication_id', '=', 's.current_publication_id')
->whereNotNull('p.doi_id')
->where('p.status', '=', PKPPublication::STATUS_PUBLISHED);
$this->whereDepositablePublication($q, $doiVersioning);
});
});
// Chapter DOIs
$q->when(in_array(Repo::doi()::TYPE_CHAPTER, $enabledDoiTypes), function (Builder $q) {
$q->orWhereIn('d.doi_id', function (Builder $q) {
$q->when(in_array(Repo::doi()::TYPE_CHAPTER, $enabledDoiTypes), function (Builder $q) use ($doiVersioning) {
$q->orWhereIn('d.doi_id', function (Builder $q) use ($doiVersioning) {
$q->select('spc.doi_id')
->from('submission_chapters', 'spc')
->join('publications as p', 'spc.publication_id', '=', 'p.publication_id')
->leftJoin('submissions as s', 'p.publication_id', '=', 's.current_publication_id')
->whereColumn('p.publication_id', '=', 's.current_publication_id')
->whereNotNull('spc.doi_id')
->where('p.status', '=', PKPPublication::STATUS_PUBLISHED);
$this->whereDepositablePublication($q, $doiVersioning, false);
});
});
// Publication format DOIs
$q->when(in_array(Repo::doi()::TYPE_REPRESENTATION, $enabledDoiTypes), function (Builder $q) {
$q->orWhereIn('d.doi_id', function (Builder $q) {
$q->when(in_array(Repo::doi()::TYPE_REPRESENTATION, $enabledDoiTypes), function (Builder $q) use ($doiVersioning) {
$q->orWhereIn('d.doi_id', function (Builder $q) use ($doiVersioning) {
$q->select('pf.doi_id')
->from('publication_formats', 'pf')
->join('publications as p', 'pf.publication_id', '=', 'p.publication_id')
->leftJoin('submissions as s', 'p.publication_id', '=', 's.current_publication_id')
->whereColumn('p.publication_id', '=', 's.current_publication_id')
->whereNotNull('pf.doi_id')
->where('p.status', '=', PKPPublication::STATUS_PUBLISHED);
$this->whereDepositablePublication($q, $doiVersioning, false);
});
});
// Submission file DOIs
$q->when(in_array(Repo::doi()::TYPE_SUBMISSION_FILE, $enabledDoiTypes), function (Builder $q) {
$q->orWhereIn('d.doi_id', function (Builder $q) {
// Submission file DOIs, of the proof files of a publication format
$q->when(in_array(Repo::doi()::TYPE_SUBMISSION_FILE, $enabledDoiTypes), function (Builder $q) use ($doiVersioning) {
$q->orWhereIn('d.doi_id', function (Builder $q) use ($doiVersioning) {
$q->select('sf.doi_id')
->from('submission_files', 'sf')
->join('submissions as s', 's.submission_id', '=', 'sf.submission_id')
->leftJoin('publications as p', 's.current_publication_id', '=', 'p.publication_id')
->whereColumn('p.publication_id', '=', 's.current_publication_id')
->join('publication_formats as pf', 'sf.assoc_id', '=', 'pf.publication_format_id')
->join('publications as p', 'pf.publication_id', '=', 'p.publication_id')
->where('sf.assoc_type', '=', Application::ASSOC_TYPE_PUBLICATION_FORMAT)
->where('sf.file_stage', '=', SubmissionFile::SUBMISSION_FILE_PROOF)
->whereNotNull('sf.doi_id')
->where('p.status', '=', PKPPublication::STATUS_PUBLISHED);
$this->whereDepositablePublication($q, $doiVersioning, false);
});
});
})
->whereIn('d.status', [Doi::STATUS_UNREGISTERED, Doi::STATUS_ERROR, Doi::STATUS_STALE]);
return $q->get(['s.submission_id', 'd.doi_id']);
return $q->distinct()->get([DB::raw('COALESCE(p.submission_id, cp.submission_id, pfp.submission_id, sfd.submission_id) AS submission_id'), 'd.doi_id']);
}
}
64 changes: 9 additions & 55 deletions classes/doi/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,61 +113,12 @@ public function mintSubmissionFileDoi(SubmissionFile $submissionFile, Submission

public function getDoisForSubmission(int $submissionId): array
{
$doiIds = Collection::make();

$submission = Repo::submission()->get($submissionId);
/** @var Publication[] $publications */
$publications = [$submission->getCurrentPublication()];

/** @var PressDAO $contextDao */
$contextDao = Application::getContextDAO();
/** @var Press */
$context = $contextDao->getById($submission->getData('contextId'));

foreach ($publications as $publication) {
$publicationDoiId = $publication->getData('doiId');
if (!empty($publicationDoiId) && $context->isDoiTypeEnabled(self::TYPE_PUBLICATION)) {
$doiIds->add($publicationDoiId);
}

// Chapters
$chapters = $publication->getData('chapters');
foreach ($chapters as $chapter) {
$chapterDoiId = $chapter->getData('doiId');
if (!empty($chapterDoiId) && $context->isDoiTypeEnabled(self::TYPE_CHAPTER)) {
$doiIds->add($chapterDoiId);
}
}

// Publication formats
$publicationFormats = $publication->getData('publicationFormats');
foreach ($publicationFormats as $publicationFormat) {
$publicationFormatDoiId
= $publicationFormat->getData('doiId');
if (!empty($publicationFormatDoiId) && $context->isDoiTypeEnabled(self::TYPE_REPRESENTATION)) {
$doiIds->add($publicationFormatDoiId);
}
}

// Submission files
if ($context->isDoiTypeEnabled(self::TYPE_SUBMISSION_FILE)) {
$submissionFiles = Repo::submissionFile()
->getCollector()
->filterBySubmissionIds([$publication->getData('submissionId')])
->filterByFileStages([SubmissionFile::SUBMISSION_FILE_PROOF])
->getMany();

/** @var SubmissionFile $submissionFile */
foreach ($submissionFiles as $submissionFile) {
$submissionFileDoiId = $submissionFile->getData('doiId');
if (!empty($submissionFileDoiId)) {
$doiIds->add($submissionFileDoiId);
}
}
}
}

return $doiIds->unique()->toArray();
return collect($submission->getData('publications'))
->flatMap(fn (Publication $publication) => $this->getDoisForPublication($publication))
->unique()
->values()
->all();
}

/**
Expand Down Expand Up @@ -212,10 +163,13 @@ public function getDoisForPublication(Publication $publication): array

// Submission files
if ($context->isDoiTypeEnabled(self::TYPE_SUBMISSION_FILE)) {
$submissionFiles = Repo::submissionFile()
// Only the files of this version's publication formats
$publicationFormatIds = collect($publicationFormats)->map(fn (PublicationFormat $publicationFormat) => $publicationFormat->getId())->all();
$submissionFiles = empty($publicationFormatIds) ? [] : Repo::submissionFile()
->getCollector()
->filterBySubmissionIds([$publication->getData('submissionId')])
->filterByFileStages([SubmissionFile::SUBMISSION_FILE_PROOF])
->filterByAssoc(Application::ASSOC_TYPE_PUBLICATION_FORMAT, $publicationFormatIds)
->getMany();

/** @var SubmissionFile $submissionFile */
Expand Down
33 changes: 33 additions & 0 deletions classes/publication/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

use APP\core\Application;
use APP\monograph\ChapterDAO;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use PKP\core\interfaces\CollectorInterface;
use PKP\db\DAORegistry;
use PKP\submissionFile\SubmissionFile;

class DAO extends \PKP\publication\DAO
{
Expand Down Expand Up @@ -55,4 +58,34 @@ public function fromRow(object $row, array $ids, object $cache, ?CollectorInterf
$publication->setData('chapters', $chapterDao->getByPublicationId($publication->getId())->toArray());
return $publication;
}

/**
* @copydoc \PKP\publication\DAO::whereHasDoi()
*/
protected function whereHasDoi(Builder $q): Builder
{
return parent::whereHasDoi($q)
->orWhereExists(
fn (Builder $q) => $q->select(DB::raw(1))
->from('submission_chapters as spc')
->whereColumn('spc.publication_id', '=', 'p.publication_id')
->whereNotNull('spc.doi_id')
)
->orWhereExists(
fn (Builder $q) => $q->select(DB::raw(1))
->from('publication_formats as pf')
->whereColumn('pf.publication_id', '=', 'p.publication_id')
->where(
fn (Builder $q) => $q->whereNotNull('pf.doi_id')
->orWhereExists(
fn (Builder $q) => $q->select(DB::raw(1))
->from('submission_files as sf')
->where('sf.assoc_type', '=', Application::ASSOC_TYPE_PUBLICATION_FORMAT)
->whereColumn('sf.assoc_id', '=', 'pf.publication_format_id')
->where('sf.file_stage', '=', SubmissionFile::SUBMISSION_FILE_PROOF)
->whereNotNull('sf.doi_id')
)
)
);
}
}
27 changes: 25 additions & 2 deletions classes/publication/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use PKP\db\DAORegistry;
use PKP\doi\exceptions\DoiException;
use PKP\notification\Notification;
use PKP\observers\events\PublicationVersioned;
use PKP\plugins\Hook;
use PKP\publication\Collector;
use PKP\publication\PKPPublication;
Expand Down Expand Up @@ -252,6 +253,8 @@ public function version(Publication $publication, ?VersionStage $versionStage =
}
}

event(new PublicationVersioned($this->get($newId), $publication, Repo::submission()->get($submissionId), $context));

return $newId;
}

Expand Down Expand Up @@ -483,6 +486,24 @@ public function makeThumbnail($filePath, $thumbFileName, $maxWidth, $maxHeight)
imagedestroy($thumb);
}

/**
* Assign DOIs to a publication's new chapters, formats or files, if DOIs are assigned on item creation
*/
public function createDoisOnCreation(int $publicationId): void
{
$publication = $this->get($publicationId);
$submission = Repo::submission()->get($publication->getData('submissionId'));
// Objects added during the submission wizard get their DOIs on submit
if ($submission->getData('submissionProgress')) {
return;
}

$context = Application::getContextDAO()->getById($submission->getData('contextId'));
if (Repo::doi()->assignOnItemCreation($context)) {
$this->createDois($publication);
}
}

/** @copydoc \PKP\publication\Repository::createDois() */
public function createDois(Publication $publication): array
{
Expand Down Expand Up @@ -544,11 +565,13 @@ public function createDois(Publication $publication): array

// Submission files
if ($context->isDoiTypeEnabled(Repo::doi()::TYPE_SUBMISSION_FILE)) {
// Get all submission files assigned to a publication format
$submissionFiles = Repo::submissionFile()
// Only the files of this version's publication formats
$publicationFormatIds = collect($publicationFormats)->map(fn (PublicationFormat $publicationFormat) => $publicationFormat->getId())->all();
$submissionFiles = empty($publicationFormatIds) ? [] : Repo::submissionFile()
->getCollector()
->filterBySubmissionIds([$publication->getData('submissionId')])
->filterByFileStages([SubmissionFile::SUBMISSION_FILE_PROOF])
->filterByAssoc(Application::ASSOC_TYPE_PUBLICATION_FORMAT, $publicationFormatIds)
->getMany();

/** @var SubmissionFile $submissionFile */
Expand Down
23 changes: 19 additions & 4 deletions classes/submission/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,27 @@ protected function addHasDoisFilterToQuery(Builder $q)

/**
* APP-specific filtering for submissions that should be listed on the DOI management page.
* Those are:
* submissions in the workflow editing and production stage,
* submissions that have a published publication, and
* submissions whose sub objects have a DOI.
* Those are all submitted submissions that have not been declined, and all submissions in the
* copyediting or production stage, with a published publication or with a DOI. The latter
* can also be listed on their own (inEditingOrPublished).
*/
protected function addOnDoiPageFilterToQuery(Builder $q)
{
$q->where('s.submission_progress', '');
if ($this->inEditingOrPublished) {
$this->addInEditingPublishedOrWithDoisToQuery($q);
} else {
$q->where(function (Builder $q) {
$q->where('s.status', '!=', Submission::STATUS_DECLINED)
->orWhere(fn (Builder $q) => $this->addInEditingPublishedOrWithDoisToQuery($q));
});
}
}

/**
* Submissions in the copyediting or production stage, with a published publication or with a DOI
*/
protected function addInEditingPublishedOrWithDoisToQuery(Builder $q): void
{
$q->where(function (Builder $q) {
$q->whereIn('s.stage_id', [WORKFLOW_STAGE_ID_EDITING, WORKFLOW_STAGE_ID_PRODUCTION])
Expand Down
6 changes: 4 additions & 2 deletions classes/submission/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ public function createDois(Submission $submission): array

// Submission files
if ($context->isDoiTypeEnabled(Repo::doi()::TYPE_SUBMISSION_FILE)) {
// Get all submission files assigned to a publication format
$submissionFiles = Repo::submissionFile()
// Only the files of this version's publication formats
$publicationFormatIds = collect($publicationFormats)->map(fn (PublicationFormat $publicationFormat) => $publicationFormat->getId())->all();
$submissionFiles = empty($publicationFormatIds) ? [] : Repo::submissionFile()
->getCollector()
->filterBySubmissionIds([$publication->getData('submissionId')])
->filterByFileStages([SubmissionFile::SUBMISSION_FILE_PROOF])
->filterByAssoc(Application::ASSOC_TYPE_PUBLICATION_FORMAT, $publicationFormatIds)
->getMany();

/** @var SubmissionFile $submissionFile */
Expand Down
22 changes: 22 additions & 0 deletions classes/submissionFile/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ public function getCollector(): Collector
return App::makeWith(Collector::class, ['dao' => $this->dao]);
}

/** @copydoc SubmissionFileRepository::add() */
public function add(SubmissionFile $submissionFile): int
{
$submissionFileId = parent::add($submissionFile);

// Only proof files of a publication format get a DOI
if (
!$submissionFile->getData('doiId')
&& $submissionFile->getData('fileStage') == SubmissionFile::SUBMISSION_FILE_PROOF
&& $submissionFile->getData('assocType') == Application::ASSOC_TYPE_PUBLICATION_FORMAT
) {
$publicationId = DB::table('publication_formats')
->where('publication_format_id', '=', $submissionFile->getData('assocId'))
->value('publication_id');
if ($publicationId) {
Repo::publication()->createDoisOnCreation($publicationId);
}
}

return $submissionFileId;
}

public function getFileStages(): array
{
$stages = [
Expand Down
2 changes: 2 additions & 0 deletions controllers/grid/catalogEntry/form/PublicationFormatForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ public function execute(...$functionParams)
'publicationFormatName' => $publicationFormat->getData('name')
]);
Repo::eventLog()->add($logEntry);

Repo::publication()->createDoisOnCreation($this->getPublication()->getId());
}

return $representationId;
Expand Down
3 changes: 3 additions & 0 deletions controllers/grid/users/chapter/form/ChapterForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ public function execute(...$functionParams)
$this->getChapter()->getId()
);

// Also when its page is enabled later, as only chapters with a page get a DOI
Repo::publication()->createDoisOnCreation($this->getPublication()->getId());

return true;
}
}
Loading
Loading