Continuous publication

Hi community!

I am currently the technical manager of the Universidad Nacional de Lanus’ journals portal.

During this year we made the migration to OJS 3 and due to the constant evolution of the editorial process we were asked to publish the articles from this year on a continuous basis and not structured in sections.

At first, we created a volume that would be used to publish the articles one by one, in our case - Vol. 15 (2019).

Then, it was necessary to modify a query to the database in one of the DAO files that I will detail later and by creating a variable, send it to the template that will use this information.

In this way, having the information in the template, we made a static comparison to show the volumes from now on continuous, keeping the archive in its classic structure of volume and number.

It is important to have personalization options that allow you to manage journal publications in a classic, continuous or both.

The solution we implement is simple and static but it is useful to visualize that with minimal changes, a need that is becoming a global trend can be satisfied in the next release of OJS.

The modified files on this implementation are:

/classes/article/PublishedArticleDAO.inc.php

Added a function that allows to obtain the articles in a continuous way organized by date, section and sequence, whose return is used by the file IssueHandler.inc.php and then by a design template.

function getPublishedArticlesContinuous($issueId) {
	$params = array_merge(
   $this->getFetchParameters(),
		array(
			(int) $issueId,
			(int) $issueId
		)
	);

	$sql = 'SELECT DISTINCT
			ps.*,
			s.*,
			COALESCE(o.seq, ps.seq) AS section_seq,
			ps.seq,
			' . $this->getFetchColumns() . '
		FROM    published_submissions ps
			LEFT JOIN submissions s ON ps.submission_id = s.submission_id
			' . $this->getFetchJoins() . '
			LEFT JOIN custom_section_orders o ON (s.section_id = o.section_id AND o.issue_id = ?)
		WHERE    ps.submission_id = s.submission_id
			AND ps.issue_id = ?
			AND s.status <> ' . STATUS_DECLINED . '
		ORDER BY ps.date_published DESC, section_seq ASC, ps.seq ASC';

	$result = $this->retrieve($sql, $params);

	$publishedArticles = array();
	while (!$result->EOF) {
		$publishedArticles[] = $this->_fromRow($result->GetRowAssoc(false));
		$result->MoveNext();
	}

	$result->Close();
	return $publishedArticles;
}

/pages/issue/IssueHandler.inc.php

We added a line that allows a variable of the Array type that contains the articles to be available, organized by date, section and sequence, from the design. Aggregated line commented.

static function _setupIssueTemplate($request, $issue, $showToc = false) {
	$journal = $request->getJournal();
	$user = $request->getUser();
	$templateMgr = TemplateManager::getManager($request);

	// Determine pre-publication access
	// FIXME: Do that. (Bug #8278)

	$templateMgr->assign(array(
   'issueIdentification' => $issue->getIssueIdentification(),
		'issueTitle' => $issue->getLocalizedTitle(),
		'issueSeries' => $issue->getIssueIdentification(array('showTitle' => false)),
	));

	$locale = AppLocale::getLocale();

	$templateMgr->assign(array(
		'locale' => $locale,
	));

	$issueGalleyDao = DAORegistry::getDAO('IssueGalleyDAO');
	$publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');

	$genreDao = DAORegistry::getDAO('GenreDAO');
	$primaryGenres = $genreDao->getPrimaryByContextId($journal->getId())->toArray();
	$primaryGenreIds = array_map(function($genre) {
		return $genre->getId();
	}, $primaryGenres);

	$templateMgr->assign(array(
		'issue' => $issue,
		'issueGalleys' => $issueGalleyDao->getByIssueId($issue->getId()),
		'publishedArticles' => $publishedArticleDao->getPublishedArticlesInSections($issue->getId(), true),
		'publishedArticlesContinuous' => **$publishedArticleDao->getPublishedArticlesContinuous($issue->getId()), // AGGREGATED **
		'primaryGenreIds' => $primaryGenreIds,
	));

	// Subscription Access
	import('classes.issue.IssueAction');
	$issueAction = new IssueAction();
	$subscriptionRequired = $issueAction->subscriptionRequired($issue, $journal);
	$subscribedUser = $issueAction->subscribedUser($user, $journal);
	$subscribedDomain = $issueAction->subscribedDomain($request, $journal);

	if ($subscriptionRequired && !$subscribedUser && !$subscribedDomain) {
		$templateMgr->assign('subscriptionExpiryPartial', true);

		// Partial subscription expiry for issue
		$partial = $issueAction->subscribedUser($user, $journal, $issue->getId());
		if (!$partial) $issueAction->subscribedDomain($request, $journal, $issue->getId());
		$templateMgr->assign('issueExpiryPartial', $partial);

		// Partial subscription expiry for articles
		$publishedArticleDao = DAORegistry::getDAO('PublishedArticleDAO');
		$publishedArticlesTemp = $publishedArticleDao->getPublishedArticles($issue->getId());

		$articleExpiryPartial = array();
		foreach ($publishedArticlesTemp as $publishedArticle) {
			$partial = $issueAction->subscribedUser($user, $journal, $issue->getId(), $publishedArticle->getId());
			if (!$partial) $issueAction->subscribedDomain($request, $journal, $issue->getId(), $publishedArticle->getId());
			$articleExpiryPartial[$publishedArticle->getId()] = $partial;
		}
		$templateMgr->assign('articleExpiryPartial', $articleExpiryPartial);
	}

	$templateMgr->assign(array(
		'hasAccess' => !$subscriptionRequired || $issue->getAccessStatus() == ISSUE_ACCESS_OPEN || $subscribedUser || $subscribedDomain
	));

	import('classes.payment.ojs.OJSPaymentManager');
	$paymentManager = Application::getPaymentManager($journal);
	if ( $paymentManager->onlyPdfEnabled() ) {
		$templateMgr->assign('restrictOnlyPdf', true);
	}
	if ( $paymentManager->purchaseArticleEnabled() ) {
		$templateMgr->assign('purchaseArticleEnabled', true);
	}
}

All the above mentioned is implemented on production for one of our journals at “Published 2019” tab.

http://revistas.unla.edu.ar/saludcolectiva/
http://revistas.unla.edu.ar/saludcolectiva/issue/view/137

@asmecher

Regards,
Diego
https://forum.pkp.sfu.ca/t/continuous-publication/53571
forum.pkp.sfu.ca
crawl=CC-MAIN-2019-35
14832
application/http; msgtype=response
sha1:B3X4LIKFWY3GK5COFPCQ34R5ZIEDGNBN
<urn:uuid:d9e62632-9078-481e-8804-0719aff6c506>
2019-08-23T07:02:55Z
142.58.129.152
text/html
sha1:ADPQA5XQZMFJ4GPHA6CBHJDBZMYD667H
<urn:uuid:819ba33f-e815-415c-b9cb-79b1e964665a>
https://forum.pkp.sfu.ca/t/continuous-publication/53571
response
<urn:uuid:6b6c48ba-6388-44f7-a10d-880f79eefb52>
isPartOf: CC-MAIN-2019-35
publisher: Common Crawl
description: Wide crawl of the web for August 2019
operator: Common Crawl Admin (info@commoncrawl.org)
hostname: ip-10-67-67-15.ec2.internal
software: Apache Nutch 1.15 (modified, https://github.com/commoncrawl/nutch/)
robots: checked via crawler-commons 1.1-SNAPSHOT (https://github.com/crawler-commons/crawler-commons)
format: WARC File Format 1.1
conformsTo: http://iipc.github.io/warc-specifications/specifications/warc-format/warc-1.1/