OJS and OMP v3.2 were released on 29 February, 2020. This release notebook provides technical guidance on changes that will impact software developers, plugin and theme authors, and anyone who works with the application codebase.
This release introduces article and monograph versioning. This is a significant breaking change that will impact almost all third-party code. When a submission is published, changes to the publication can only be made by creating and publishing a new version of that submission.
To accomplish this, a new Publication
object has been introduced which stores a submission’s title, metadata, contributors, galleys and any data related to the published submission.
When a new version is created, a deep copy of the publication is created including attached objects such as authors and galleys. Hooks are available to clone additional objects which you may need to associate with the publication.
Read our guidance on working with publication versions. Learn how this will impact custom themes. And view the documentation for changes to the REST API endpoints.
The PublishedArticle
and PublishedMonograph
objects have been removed. Check the submission’s status to determine if it is published.
if ($submission->getData('status') === STATUS_PUBLISHED) {
// submission is published
}
The PublishedArticleDAO
and PublishedMonographDAO
DAOs have also been removed. Published submissions should be retrieved by using the status
argument of the submission service.
$publishedSubmissions = Services::get('submission')
->getMany(['status' => STATUS_PUBLISHED]);
The data of a PublishedArticle
or PublishedMonograph
has been migrated to the Publication
object. See publication versions.
Most of the helper methods for the Submission
class have been deprecated and may be removed in the near future.
// Deprecated
$abstract = $submission->getLocalizedAbstract();
// Use this instead
$abstract = $submission->getCurrentPublication()->getLocalizedData('abstract');
Some helper methods are still available on the Publication
object.
// Deprecated
$title = $submission->getLocalizedTitle();
// Use this instead
$title = $submission->getCurrentPublication()->getLocalizedTitle();
The published_submissions
table has been removed. Most of the data is now available in the publications
table. The following table names have changed:
submission_categories
is now publication_categories
submission_galley_settings
is now publication_galley_settings
submission_galleys
is now publication_galleys
Translation files have been converted from xml
to po
files and all translations should be submitted through our Weblate translation server.
Existing xml
translation files will continue to work, but compatibility may be removed at any time in the future. Convert an xml
translation file to po
format by using lib/pkp/tools/xmlToPo.php
(for the locale files) and lib/pkp/tools/xmlEmailsToPo.php
(for email templates).
Using translations in the application has not changed and should still use the __('example.phrase')
syntax.
Email templates have been converted to po
format so that they can be translated using our Weblate translation server. This effects all email templates shipped with OJS and OMP as well as any email templates in plugins.
Existing XML email templates will continue to work, but compatibility may be removed at any time in the future. The following pull request shows how the email templates were converted for the Orcid plugin.
In OJS, a Submission
or Publication
will be set to STATUS_SCHEDULED
when it has been approved for publication in an issue that is not yet published. It will be granted STATUS_PUBLISHED
when the issue is published.
In OMP, STATUS_SCHEDULED
will be set when a Publication
has been approved for publication with a datePublished
that is in the future. A scheduled task has been introduced to grant STATUS_PUBLISHED
when the date has been reached.
A Submission
’s status will be updated automatically when any of its Publication
objects have been published or unpublished. Never set the status
directly for submissions and publications. Instead, use Services::get('publication')->publish($publication)
and Services::get('publication')->unpublish($publication)
to ensure the correct hooks are fired and the submission’s status
is kept in sync.
Once a Submission
has been published, it will remain STATUS_PUBLISHED
as long as one Publication
object is published.
We now use Cypress for our integration testing. This applies to the full suite of tests for OJS and OMP as well as plugin integration tests (see Static Pages).
Learn more in our documentation on testing.
A Service class’s getMany()
method now returns a DAOResultIterator
instead of an array. The iterator can be used like an array in foreach
loops:
$contextsIterator = Services::get('context')->getMany(['isEnabled' => true]);
foreach ($contextsIterator as $context) {
$names[] = $context->getLocalizedData('name');
}
However, a DAOResultIterator
is not an array. It can not be looped over twice and it can not be used with the array_map
, array_filter
or array_reduce
functions.
Use count()
instead of !empty()
to check if any results were found.
$contextsIterator = Services::get('context')->getMany(['isEnabled' => true]);
if (count($contextsIterator)) {
// one or more contexts were found
}
Our documentation has been updated to reflect this change as well as new methods for the Service and QueryBuilder classes to help you retrieve data.
New service classes are available to help you retrieve and calculate statistics about your journal or press. The PKPStatsService
will help extract data on visits to journals, articles and galleys. And the PKPStatsEditorialService
will help you calculate data on submissions received, accepted and published, and how long authors must wait for editorial decisions.
Read more about working with reader and editorial statistics. You may also retrieve stats through the API.
Several new API endpoints have been introduced. Endpoints are now available to:
Read the API Reference.
A new setting, api_secret_key
, must be set in the config.inc.php
file in order to use the API with an API Token.
An unsubscribe link is now sent with each automated email. A new setting, signed_page_key_secret
must be set in the config.inc.php
file in order for this link to work.
Our new architecture for building forms is now in use. These forms can be found in the journal settings as well as the new publication forms in the workflow.
Forms using this architecture can be built field-by-field from PHP classes on the server side.
$exampleForm = new \PKP\components\forms\FormComponent(
'exampleForm', // unique form id
'PUT', // POST or PUT
'http://...', // URL to API endpoint to process the form
__('success.message'), // Message to display on success
$locales, // Array of locales to support
);
$exampleForm->addField(new FieldText('name', [
'label' => __('manager.setup.contextTitle'),
'value' => $context->getData('name'),
]))
->addField(new FieldText('acronym', [
'label' => __('manager.setup.contextInitials'),
'value' => $context->getData('acronym'),
]));
Each form provides a hook so that you can extend it in a plugin.
\HookRegistry::register('Form::config::before', function($hookName, $form) {
if ($form->id === 'exampleForm') {
$form->addField(new FieldText('itemsPerPage', [
'label' => __('common.itemsPerPage'),
'value' => $context->getData('itemsPerPage'),
]));
}
return false;
});
All supported form fields extend the Field
class. A class can be found for each field component described in the UI Library.
Our plan is to migrate all of our forms to this architecture. Further documentation is in progress which will describe how the forms interact with the Vue.js components and the REST API.
The Article
and Monograph
objects were renamed to Submission
. This should help us share code between the applications.
Theme options now support all of the form field types in our UI Library except the image and file upload fields. Read our updated theming guide.
We have replaced our local tools for deriving ISO codes for languages, countries and currencies with php-isocodes.
Our UI Library is growing rapidly as we transition our editorial backend to Vue.js. Explore all of the components available in the UI Library.