Jump to table of contents

Release Notebook for OJS/OMP/OPS 3.3

OJS, OMP and OPS 3.3 was released on February 1, 2021. 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.

PHP 7.3+ #

The minimum required version of PHP will be 7.3 or above, following PHP’s version support schedule.

ADODB replaced #

OJS/OMP/OPS now use Laravel’s Illuminate\Database toolset instead of ADODB to execute database queries. Previous releases relied on ADODB for DAO-based query execution.

Update connection_charset #

The connection_charset setting in the config file can no longer be set to Off. It must be set to match the client_charset of your database.

Note the small difference when defining the UTF 8 character set.

; Client output/input character set
client_charset = utf-8

; Database connection character set
connection_charset = utf8

DAOs #

DAOs should make use of the Illuminate\Database toolset to execute database queries whenever possible.

The ADODB library is still included in OJS/OMP/OPS 3.3.x for older upgrades, but it will be removed entirely in the future.

The following is an example of how a DAO should use Illuminate\Database.

use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Support\Collection;

class ExampleDAO extends DAO {

	function getExamples(int $contextId) : Collection {
		return Capsule::table('example')
			->where('context_id', $contextId)

DAOResultFactory #

The DAOResultFactory is deprecated and should not be used for new code. Many of the common DAO methods are still used to execute raw queries, such as retrieve() and retrieveRange(). Any code that uses these methods will eventually be replaced with the QueryBuilder.

When a DAOResultFactory is still used, you may need to convert the result set to an array in order to count or loop over the results.

Replace calls to $result->getCount(). It is not recommended to count results based on an iterator function like count. Instead, an explicit COUNT SQL query should be used.

When counting on an iterator can not be avoided, the query SQL and parameters can be provided to the DAOResultFactory constructor. However, this approach is deprecated and will need to be rewritten in the future.

Refactor calls to $result->wasEmpty(). They are generally unnecessary.

// WARNING: This can be inefficient for large sets of information.
$items = $result->toArray();
if (empty($items)) {

Smarty templates that use {iterate} on a DAOResultFactory need to be modified to use {foreach} on an array.

	'reviewRounds' => $result->toArray(),
{foreach from=$reviewRounds item=reviewRound}

Read more details about how DAOResultFactory has changed.

Plugin schemas #

The XML schema management tools have been replaced with Laravel Migrations. Plugins that create their own tables will need to convert their schema files to a migration.

Use the command line tool to convert a schema to a migration.

php lib/pkp/tools/xmlSchemaToMigration.php <schema.xml> <MigrationClassName> > <MigrationClassName>.php

This will generate (to stdout) a class file that can be add to your plugin’s source code.

Add a method to the plugin class to run the migration when the plugin is installed.

function getInstallMigration() {
	return new MyMigration();

See an example in this commit.

Upgrades from 2.x #

Migration scripts from 2.x have been removed. Upgrades from OJS 2.x will need to run a two-step process. First, upgrade from OJS 2.x to OJS 3.2. Then, upgrade from OJS 3.2 to to OJS 3.3 or newer.

Submission files #

Submission files have been refactored to reduce file duplication and simplify how files are managed. Some of the major changes include:

  • A File service class is used to read and write files.
  • A Submission File service class replaces the SubmissionFileManager.
  • Endpoints were added to the REST API to read and write submission files.
  • The SubmissionArtworkFile and SupplementaryFile classes and their associated DAO delegates were removed. All submission files use the SubmissionFile class.

Read the full documentation on Submission Files.

Default content removed #

When creating a journal, press or preprint server with version 3.2.x, default content was installed for every language supported by the site. Multi-tenant instances which run journals across many different languages had settings created for languages that are not supported by that context.

When updating to 3.3, any data stored for the following settings in locales that are not part of that context’s supportedFormLocales will be removed:

  • authorInformation
  • librarianInformation
  • openAccessPolicy
  • privacyStatement
  • readerInformation
  • submissionChecklist
  • clockssLicense
  • lockssLicense

Guzzle replaces cURL #

Remote requests now use Guzzle instead of cURL. The PKPCurlHelper class has been removed and the [proxy] settings in the config.inc.php file have changed.

The following example shows how to get and use a Guzzle client configured with the appropriate proxy settings.

$client = Application::get()->getHttpClient();
$response = $client->request('GET', 'http://some-url-here');
$body = $response->getBody();

View the new proxy config and a commit with several code migrations from cURL to Guzzle.

Review types #

The constants for review types have been changed to remove ableist terminology.

3.2 3.3+

Context paths #

The urlPath of a journal, press or preprint server may now contain capital letters. If you are using a .htaccess file to route requests based on the urlPath, you may need to modify the regex that detects the context path to include capital letters.

Removed CDN config #

The enable_cdn configuration option was removed. Font and script assets are all loaded from files on the same server.

As part of this change, two additional constants have been removed:


This decision was taken because the introduction of cache partitioning in browsers negates the performance benefits of using a CDN for these files. Removing the option also improves the privacy of our software in its default configuration.

Default theme accessibility #

The default theme has been modified according to recommendations from an audit that was conducted by an accessibility expert. The following list is an overview of changes that may effect custom themes that use the default templates or child themes of the default theme:

  • All font sizes now use rems.
  • Additional :focus styles applied to elements in the header.
  • The quick search in the header has been changed to a link to the advanced search page.
  • The HTML markup of the advanced search form has changed significantly.
  • When registering a new account, reviewer interests no longer feature autosuggest. Interests can be entered in a comma-separated list.
  • Search results are returned in a list with <ul> and <li> elements.
  • Headings, such as <h1> and <h2>, have been adjusted for consistency.
  • Custom blocks now require a title. The title can be hidden in the block configuration but must be an accurate title for the block to comply with accessibility requirements.

New API endpoints #

Several new API endpoints have been added to read and write submission files. View the API Reference.

Editorial UI #

Our UI Library continues to grow and the editorial UI now uses Vue.js components for the header and navigation menu. Read our new Frontend documentation, especially the sections on the UI Library and Forms.

New UI components #

Our UI Library continues to grow. Explore some of the changes in the UI Library like the new Modals, refactored ListPanels, and the Notify utility.