iThenticate one account per journal?


I am just looking for confirmation that the iThenticate plugin works per OJS install, not per journal.
We are running OJS

Thank you,

Hi @gabriela,

Currently it’s configured (e.g. credentials) per installation, but it’s enabled/disabled separately on each journal. (There’s a request to give more control to each journal here: multiple journal support · Issue #8 · asmecher/plagiarism · GitHub)

Alec Smecher
Public Knowledge Project Team

Thank you Alec.

Best wishes,

Hi @asmecher, we are having the same problem described in github, and we tried to fix it with the support of crossref and iThenticate. We failed, but now we have an idea for a (we hope) minor change of the plugin that we think could fix the problem.
In iThenticate there is the possibility to share folders, but only the submission folders and not the first.level journal-named folders: if the journal folders were shareable, we could create in iThenticate one user for each journal, share with this user the journal folder and that user could see all (and only) the submission subfolders related to his journal.
I had a look to the file of the plugin, and I think that a change could be made between rows 91 and 100 to make the plugin create a journal-named folder between the “folder group” (you name this way in row 85 the unshareable folder, I suppose) and the submission folders.
This change will result in a iThenticate strcture like this:

  • folder group (journal-named, unshareable, actually created by the plugin)
    – journal folder (journal-named, shareable, actually the plugin doesn’t create it)
    — submission folders (submission+submissionID-named, actually created by the plugin)
    I hope I was clear and that the change I suggest is possible: if you think so and give some advise I can try and test the change myself.
    Best regards
1 Like

Hi, we made some tests and iThenticate does not allow the creation of subfolders.
@asmecher, can you give some hints on the effort needed for giving more control to each journal as requested here, so we can see if we can work on it?
Best regards

Hi @bolelligallevi,

At the moment, the iThenticate credentials are fetched from the OJS configuration file:

My recommendation would be to add a settings form for the plugin, e.g. following the pattern used by plugins like the Google Analytics plugin (settings form class), so that when a journal has a settings form with values entered into it they override the settings. Happy to review pull requests to achieve this!

Alec Smecher
Public Knowledge Project Team


I made changes in this plugin to have one different account for every journal.

you need to add these lines to file “” into callback function:

        $journal = & $request->getJournal();
        $journalId = $journal->getId();
        $user = $this->getSetting($journalId, 'ithenticate_user');
        $pass = $this->getSetting($journalId, 'ithenticate_pass');

Then it looks like this:

 public function callback($hookName, $args) {
        $request = Application::getRequest();
        $context = $request->getContext();
        $submissionDao = Application::getSubmissionDAO();
        $submission = $submissionDao->getById($request->getUserVar('submissionId'));
        $publication = $submission->getCurrentPublication();

        require_once(dirname(__FILE__) . '/vendor/autoload.php');
        $journal = & $request->getJournal();
        $journalId = $journal->getId();
        $user = $this->getSetting($journalId, 'ithenticate_user');
        $pass = $this->getSetting($journalId, 'ithenticate_pass');
        $ithenticate = new \bsobbe\ithenticate\Ithenticate(

And add some new functions there:

     * @copydoc Plugin::getActions()
    function getActions($request, $verb) {
        $router = $request->getRouter();
        return array_merge(
                $this->getEnabled() ? array(
            new LinkAction(
                    new AjaxModal(
                            $router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')),
                ) : array(),
                parent::getActions($request, $verb)

     * @copydoc Plugin::manage()
    function manage($args, $request) {
        switch ($request->getUserVar('verb')) {
            case 'settings':
                $context = $request->getContext();

                AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER);
                $templateMgr = TemplateManager::getManager($request);
                $templateMgr->registerPlugin('function', 'plugin_url', array($this, 'smartyPluginUrl'));

                $form = new PlagiarismSettingsForm($this, $context->getId());

                if ($request->getUserVar('save')) {
                    if ($form->validate()) {
                        return new JSONMessage(true);
                } else {
                return new JSONMessage(true, $form->fetch($request));
        return parent::manage($args, $request);

Now you need files for handle plugin settings and setting template file.
So into the plugin folder you need to add file “


class PlagiarismSettingsForm extends Form {

	/** @var int */
	var $_journalId;

	/** @var object */
	var $_plugin;

	 * Constructor
	 * @param $plugin CitedByPlugin
	 * @param $journalId int
	function __construct($plugin, $journalId) {
		$this->_journalId = $journalId;
		$this->_plugin = $plugin;

                $this->addCheck(new FormValidator($this, 'ithenticate_user', 'required', 'plugins.generic.plagiarism.manager.settings.usernameRequired'));
		$this->addCheck(new FormValidator($this, 'ithenticate_pass', 'required', 'plugins.generic.plagiarism.manager.settings.passwordRequired'));

		$this->addCheck(new FormValidatorPost($this));
		$this->addCheck(new FormValidatorCSRF($this));

	 * Initialize form data.
	function initData() {
		$this->_data = array(
                        'ithenticate_user' => $this->_plugin->getSetting($this->_journalId, 'ithenticate_user'),
			'ithenticate_pass' => $this->_plugin->getSetting($this->_journalId, 'ithenticate_pass'),

	 * Assign form data to user-submitted data.
	function readInputData() {

	 * @copydoc Form::fetch()
	function fetch($request, $template = null, $display = false) {
		$templateMgr = TemplateManager::getManager($request);
		$templateMgr->assign('pluginName', $this->_plugin->getName());
		return parent::fetch($request, $template, $display);

	 * @copydoc Form::execute()
	function execute(...$functionArgs) {
                $this->_plugin->updateSetting($this->_journalId, 'ithenticate_user', trim($this->getData('ithenticate_user'), "\"\';"), 'string');
		$this->_plugin->updateSetting($this->_journalId, 'ithenticate_pass', trim($this->getData('ithenticate_pass'), "\"\';"), 'string');

And add template file into subfolder “templates/settingsForm.tpl

	$(function() {ldelim}
		// Attach the form handler.

<form class="pkp_form" id="plagiarismSettingsForm" method="post" action="{url router=$smarty.const.ROUTE_COMPONENT op="manage" category="generic" plugin=$pluginName verb="settings" save=true}">
	{include file="controllers/notification/inPlaceNotification.tpl" notificationId="plagiarismSettingsFormNotification"}

	<div id="description">{translate key="plugins.generic.plagiarism.manager.settings.description"}</div>

	{fbvFormArea id="webFeedSettingsFormArea"}
            {fbvElement type="text" id="ithenticate_user" value=$ithenticate_user label="plugins.generic.plagiarism.manager.settings.username"}
            {fbvElement type="text" id="ithenticate_pass" value=$ithenticate_pass label="plugins.generic.plagiarism.manager.settings.password"}


	<p><span class="formRequired">{translate key="common.requiredField"}</span></p>

This fork for us :slight_smile:
Your welcome,

Hi @Radek, before seeing your answer and the last update to the plugin (managing journal credentials in the config file by github user forgive38) we worked on plagiarism plugin to manage a per journal handling of the ithenticate reports.

We decided to continue using only one user stored in to create all the reports, but when a report is created the plugin will share it with the journal user (creating it if necessary): we think it’s the most secure solution, because only one ithenticate user/password can create reports and delete them and such credentials are keep safe in config file; moreover, does not require to write and mantain journal users and passwords in the config file, and in a platform with many journals admins can prevent journals editorial teams from deleting their reports.

My collegue @joelfan has finished working on the bsobbe library to add the missing ithenticate apis, resolving in creating a fork (the iThenticateWithUserManagement
because bsobbe has not much time to work on his library.

We planned to handle journal users (in this sharing logic passwords are not required in OJS) in a settings form, but this part has not been done yet because the plugin works even without it (when a user is created ithenticate send user and password to the journal mail, and the password is not required for sharing).

We would like to understand if all these contributions (forgive38’s, @Radek’s and ours) can be merged so that the result is a plugin usable in all these situations:

  • storing all credentials in config file (as now);
  • storing all credentials in setting page (as @Radek’s solution)
  • storing only creating credentials in config and journal mail in settings (as our plugin is planned to do)

Before going on we would like to have an opinion on such scenario, mainly from @asmecher, @radek, @ctgraham (because of his issue) but all interested users are wellcome, to understand if it’s interesting and can be adopted by the community.

Best regards

Hi, @bolelligallevi , I’m glad to see the addition of the iThenticate user APIs to the library.

Within the University of Pittsburgh, we have been wondering how we can use this plugin across dozens of journals. There was some interest in using the same credentials across all installations, but this would cause conflicts when the plugin names folders with the submission id, and because the API is limited to 1000 folders.

We were also interested in the availability of the service to support administration of users and groups. I wonder if credits could be added at a parent account level, and available to users / groups under that account’s management. This way, iThenticate accounts would still be individually owned and accessed, and utilized within OJS’s plugin. Perhaps sharing could be done within iThenticate itself as well?

Regarding the code change, by renaming the class (and perhaps with a change in line endings), it is very difficult to see what specifically has changed in the code between the bsobbe and the joelfan repositories:

Can you alter this so that it forms a clean pull request to bsobbe repo? This way, we can modify the iThenticate class rather than creating a new iThenticateWithUserMangement class. The maintainer seems open to this, but even if not accepted as a pull request, the joelfan repo can become a direct replacement via composer.

Hi @ctgraham, there is already a pull request in bsobbe’s repo, @joelfan has also made a new class because no managing of the pull request.
Can you give more details on the plugin’s name folder issue? The submission id is unique…
On the API limit, how do you suggest to overcome it?
We would like to have more infos on administration of users and groups you are interested in. What the plugin should do? What could be done on iThenticate?
Best regards

there is already a pull request in bsobbe’s repo, @joelfan has also made a new class because no managing of the pull request.

The existing pull request marks all of and Ithenticate.php as changed files:

This would be better as a “clean” pull request which only marks as changed those lines which were added / modified / deleted. To do this, avoid changing the name of the class file, and avoid changing the whitespace (spaces, newlines) in the files.

This is valuable even if it never gets merged, as the branch in the joelfan repo can be referenced directly in composer as a drop-in replacement for the bsobbe repo.

Can you give more details on the plugin’s name folder issue? The submission id is unique…

One of our considerations was: “can we use the same username and password in multiple OJS installs?”. The answer to this is “no”, because the submissions are foldered by id, and each install will have a different submission with the same id.

On the API limit, how do you suggest to overcome it?

This was primarily a concern with the above desire to use a single account in very large installs. I think the use of one account per journal helps here. For very large journals, we may need to consider additional subfolders and folder groups.

We would like to have more infos on administration of users and groups you are interested in. What the plugin should do? What could be done on iThenticate?

I wonder if a user manager in iThenticate could create a user group of multiple editors who all have access to a shared folder. I wonder if the OJS plugin could specify the folder, and place all of the submissions in that folder. If so, the editorial sharing could happen within iThenticate. This would, however, require additional account management, as an editor would have both an OJS account, and an iThenticate account. The idea of sharing email links also seems attractive, as you describe this as not requiring an iThenticate account.

I haven’t personally tested either approach.

Best regards

Thanks again for your contribution here!

Hi @ctgraham, @joelfan made these:

  • forked bsobbe adding proxy, user management and php8, you can find it here; he closed the pull request to bsobbe that didn’t reach attention;
  • forked (here GitHub - joelfan/plagiarism: Plagiarism checker plugin for OJS/OMP 3.2) the 1.0.3 version of the plugin (because we have OJS 3.2), adding the @Radek settings to manage the journal credentials from UI instead of config file, but maintaining there one user and password to make possible using them to create a new user from the plugin. In other words, if the plugin match the settings credentials with a iThenticate user, send the submission to that iThenticate user, if not uses the credentials in config file to create a new iThenticate user and send submissions to the new created user.
    The plugin still has some issues: it works, but we did not finish to manage all errors, PHP requirements, and so on.
    We stopped working because we are planning to move to 3.3, where we noticed that something is changed so we would like to finish the job on the 1.0.5 version of the plugin, where there are a few issues and pull requests.
    We would like to have an opinion from you and from all interested members of the community (mainly from users directly involved in the plagiarism plugin as you, @asmecher, @Radek, @gabriela…), to be sure that what we our job fits the common needs before going on.
    Best regards

Hi, @bolelligallevi , I see @joelfan 's comment on:

As I describe there, it would be helpful to get a better view into your proposed changes to support multiple accounts. A team including @Radek and myself discussed your proposal with interest at the PKP Sprint in Helsinki, but we were unable to get a clear picture.

To us, it seemed like most of the workflow you described would better fit within iThenticate itself, but we were mostly speculating without a view into your code.

We wondered if editorial staff should be able to add an iThenticate username into their OJS/OPS/OMP profile. If the iThenticate username was present, the plagiarism plugin could share the uploaded folder to that user when the editor was assigned to the submission.

We are looking forward to working on a common understanding of community needs.

Hi @ctgraham, @joelfan is answering on github about the code.
Regarding the plugin sharing the uploaded folder to an iThenticate user assigned to an editor, we think the problem is in iThenticate sharing limits, the same preventing using a single user for uploading as we tried to do before.
Best regards

Estimados Señores:

Por si le sirviera para futuras actualizaciones, agradeceríamos que este plugin no hiciera el envío automático desde el paso cuarto (confirmación) del envío de artículos por el autor. Ya que muchas veces los trabajos quedan incompletos, se mandan varias veces con modificaciones y en muchas ocasiones no pasan ni la revisión preliminar del editor antes de pasar a revisión por pares y son rechazados. Y como bien se ha dicho en alguna ocasión estos envíos son de pagos y todo cuenta. Por lo que pensamos que sería más eficiente el que se mandara el archivo a Ithenticate una vez se hubiera seleccionado para su revisión por pares. Personalmente la fase de flujo de trabajo desde la cual nos gustaría se mandara sería la editorial, ya que se habría pasado un nuevo cribado de revisión y aquellos que no lo hubiesen pasado no se mandarían, y en el proceso se podría indicar ya un sólo archivo, que sería el que se mandaría revisar. Esperamos lo puedan tener en cuenta. Gracias

Dear Sirs:

In case it would be useful for future updates, we would appreciate that this plugin does not make the automatic submission from the fourth step (confirmation) of the submission of articles by the author. Since many times the papers are incomplete, are sent several times with modifications and often do not even pass the preliminary review of the editor before going to peer review and are rejected. And as it has been said on some occasions, these submissions are for payment and everything counts. So we thought it would be more efficient to send the file to Ithenticate once it has been selected for peer review. Personally, the workflow phase from which we would like to send it would be the editorial, since it would have passed a new review screening and those that had not passed it would not be sent, and in the process it would be possible to indicate only one file, which would be the one that would be sent for review. We hope you can take this into account. Thank you