Skip to content

Commit

Permalink
Merge pull request #31 from radekgomola/main
Browse files Browse the repository at this point in the history
Settings for journal managers
  • Loading branch information
asmecher authored Jul 13, 2022
2 parents 62b95a9 + 84d7412 commit e47bc74
Show file tree
Hide file tree
Showing 31 changed files with 285 additions and 164 deletions.
132 changes: 116 additions & 16 deletions PlagiarismPlugin.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function register($category, $path, $mainContextId = null) {
$success = parent::register($category, $path, $mainContextId);
$this->addLocaleData();

if ($success && Config::getVar('ithenticate', 'ithenticate') && $this->getEnabled()) {
if ($success && $this->getEnabled()) {
HookRegistry::register('submissionsubmitstep4form::execute', array($this, 'callback'));
}
return $success;
Expand All @@ -37,25 +37,65 @@ public function getDisplayName() {
* @copydoc Plugin::getDescription()
*/
public function getDescription() {
return Config::getVar('ithenticate', 'ithenticate')?__('plugins.generic.plagiarism.description'):__('plugins.generic.plagiarism.description.seeReadme');
return __('plugins.generic.plagiarism.description');
}

/**
* @copydoc LazyLoadPlugin::getCanEnable()
*/
function getCanEnable() {
if (!parent::getCanEnable()) return false;
return Config::getVar('ithenticate', 'ithenticate');
function getCanEnable($contextId = null) {
return !Config::getVar('ithenticate', 'ithenticate');
}

/**
* @copydoc LazyLoadPlugin::getCanDisable()
*/
function getCanDisable($contextId = null) {
return !Config::getVar('ithenticate', 'ithenticate');
}

/**
* @copydoc LazyLoadPlugin::getEnabled()
*/
function getEnabled($contextId = null) {
if (!parent::getEnabled($contextId)) return false;
return Config::getVar('ithenticate', 'ithenticate');
return parent::getEnabled($contextId) || Config::getVar('ithenticate', 'ithenticate');
}

/**
* Fetch credentials from config.inc.php, if available
* @return array username and password, or null(s)
**/
function getForcedCredentials() {
$request = Application::getRequest();
$context = $request->getContext();
$contextPath = $context->getPath();
$username = Config::getVar('ithenticate', 'username[' . $contextPath . ']',
Config::getVar('ithenticate', 'username'));
$password = Config::getVar('ithenticate', 'password[' . $contextPath . ']',
Config::getVar('ithenticate', 'password'));
return [$username, $password];
}

/**
* Send the editor an error message
* @param $submissionid int
* @param $message string
* @return void
**/
public function sendErrorMessage($submissionid, $message) {
$request = Application::getRequest();
$context = $request->getContext();
import('classes.notification.NotificationManager');
$notificationManager = new NotificationManager();
$roleDao = DAORegistry::getDAO('RoleDAO'); /* @var $roleDao RoleDAO */
// Get the managers.
$managers = $roleDao->getUsersByRoleId(ROLE_ID_MANAGER, $context->getId());
while ($manager = $managers->next()) {
$notificationManager->createTrivialNotification($manager->getId(), NOTIFICATION_TYPE_ERROR, array('contents' => __('plugins.generic.plagiarism.errorMessage', array('submissionId' => $submissionid, 'errorMessage' => $message))));
}
error_log('iThenticate submission '.$submissionid.' failed: '.$message);
}

/**
* Send submission files to iThenticate.
* @param $hookName string
Expand All @@ -65,26 +105,35 @@ public function callback($hookName, $args) {
$request = Application::getRequest();
$context = $request->getContext();
$contextPath = $context->getPath();
$submissionDao = Application::getSubmissionDAO();
$submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
$submission = $submissionDao->getById($request->getUserVar('submissionId'));
$publication = $submission->getCurrentPublication();

require_once(dirname(__FILE__) . '/vendor/autoload.php');

// try to get credentials for current context otherwise use default config
$username = Config::getVar('ithenticate', 'username[' . $contextPath . ']',
Config::getVar('ithenticate', 'username'));
$password = Config::getVar('ithenticate', 'password[' . $contextPath . ']',
Config::getVar('ithenticate', 'password'));
$ithenticate = new \bsobbe\ithenticate\Ithenticate($username, $password);
$contextId = $context->getId();
list($username, $password) = $this->getForcedCredentials();
if (empty($username) || empty($password)) {
$username = $this->getSetting($contextId, 'ithenticateUser');
$password = $this->getSetting($contextId, 'ithenticatePass');
}

$ithenticate = null;
try {
$ithenticate = new \bsobbe\ithenticate\Ithenticate($username, $password);
} catch (Exception $e) {
$this->sendErrorMessage($submission->getId(), $e->getMessage());
return false;
}
// Make sure there's a group list for this context, creating if necessary.
$groupList = $ithenticate->fetchGroupList();
$contextName = $context->getLocalizedName($context->getPrimaryLocale());
if (!($groupId = array_search($contextName, $groupList))) {
// No folder group found for the context; create one.
$groupId = $ithenticate->createGroup($contextName);
if (!$groupId) {
error_log('Could not create folder group for context ' . $contextName . ' on iThenticate.');
$this->sendErrorMessage($submission->getId(), 'Could not create folder group for context ' . $contextName . ' on iThenticate.');
return false;
}
}
Expand All @@ -97,7 +146,7 @@ public function callback($hookName, $args) {
true,
true
))) {
error_log('Could not create folder for submission ID ' . $submission->getId() . ' on iThenticate.');
$this->sendErrorMessage($submission->getId(), 'Could not create folder for submission ID ' . $submission->getId() . ' on iThenticate.');
return false;
}

Expand All @@ -117,12 +166,63 @@ public function callback($hookName, $args) {
Services::get('file')->fs->read($file->path),
$folderId
)) {
error_log('Could not submit "' . $submissionFile->getData('path') . '" to iThenticate.');
$this->sendErrorMessage($submission->getId(), 'Could not submit "' . $submissionFile->getData('path') . '" to iThenticate.');
}
}

return false;
}

/**
* @copydoc Plugin::getActions()
*/
function getActions($request, $verb) {
$router = $request->getRouter();
import('lib.pkp.classes.linkAction.request.AjaxModal');
return array_merge(
$this->getEnabled() ? array(
new LinkAction(
'settings',
new AjaxModal(
$router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')),
$this->getDisplayName()
),
__('manager.plugins.settings'),
null
),
) : 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'));

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

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

/**
Expand Down
67 changes: 67 additions & 0 deletions PlagiarismSettingsForm.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

import('lib.pkp.classes.form.Form');

class PlagiarismSettingsForm extends Form {

/** @var int */
var $_contextId;

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

/**
* Constructor
* @param $plugin PlagiarismPlugin
* @param $contextId int
*/
function __construct($plugin, $contextId) {
$this->_contextId = $contextId;
$this->_plugin = $plugin;

parent::__construct($plugin->getTemplateResource('settingsForm.tpl'));

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

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

/**
* Initialize form data.
*/
function initData() {
list($username, $password) = $this->_plugin->getForcedCredentials();
$this->_data = array(
'ithenticateUser' => $this->_plugin->getSetting($this->_contextId, 'ithenticateUser'),
'ithenticatePass' => $this->_plugin->getSetting($this->_contextId, 'ithenticatePass'),
'ithenticateForced' => !empty($username) && !empty($password)
);
}

/**
* Assign form data to user-submitted data.
*/
function readInputData() {
$this->readUserVars(array('ithenticateUser', 'ithenticatePass'));
}

/**
* @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->_contextId, 'ithenticateUser', trim($this->getData('ithenticateUser'), "\"\';"), 'string');
$this->_plugin->updateSetting($this->_contextId, 'ithenticatePass', trim($this->getData('ithenticatepass'), "\"\';"), 'string');
parent::execute(...$functionArgs);
}
}
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# iThenticate Plagiarism Detector Plugin

For OJS/OMP/OPS 3.x

## Overview

This plugin permits automatic submission of uploaded manuscripts to the [iThenticate service](http://www.ithenticate.com/) for plagiarism checking.
1. You need an account of ithenticate.com (costs involved)
* paid via Crossref Similarity Check
* or, paid directly to iThenticate
2. Install the plugin via the Plugin Gallery in the Dashboard
3. Configure the plugin (see below)
* Enable the plugin via config.inc.php or in a specific journal/press/preprint context
* Configure the plugin with the username and password you get from ithenticate.com
* ![Example Settings configuration](ithenticate-settings.png)
4. The author logs in and makes a submission
* The submission files will be sent to iThenticate in Step 4 of the submission process
5. The Editor logs in to ithenticate.com to see the submission
* The submission will be found in a folder named by the Submission ID, under a Group named by the journal/press/preprint context
* Click to see the report
* ![Example report review](ithenticate-report.png)

Watch [the demo](https://www.ithenticate.com/demo) to know more about the features of iThenticate.

## Configuration

You may set the credentials in config.inc.php, or you may set the credentials per-journal in the plugin settings. If credentials are present in config.inc.php, they will override those entered in the plugin settings form.

The config.inc.php settings format is:

```
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; iThenticate Plugin Settings ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[ithenticate]
; Enable iThenticate to submit manuscripts after submit step 4
;ithenticate = On
; Credentials can be set by context : specify journal path
; The username to access the API (usually an email address)
;username[MyJournal_path] = "[email protected]"
; The password to access the API
;password[MyJournal_path] = "password"
; default credentials
; The username to access the API (usually an email address)
;username = "[email protected]"
; The password to access the API
;password = "password"
```

23 changes: 0 additions & 23 deletions README.txt

This file was deleted.

Binary file added ithenticate-report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ithenticate-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions locale/ar_IQ/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,3 @@ msgstr "إضافة كشف السرقة الأدبية iThenticate"

msgid "plugins.generic.plagiarism.description"
msgstr "أرسل كل طلبات التقديم إلى iThenticate للتحقق من إحتمالية وجود سرقات أدبية."

msgid "plugins.generic.plagiarism.description.seeReadme"
msgstr "أرسل كل طلبات التقديم إلى iThenticate للتحقق من إحتمالية وجود سرقات أدبية. <strong>أنظر ملف README الخاص بهذه الإضافة لمعرفة إرشادات التنصيب.</strong>"
6 changes: 0 additions & 6 deletions locale/bg_BG/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.9.1\n"

msgid "plugins.generic.plagiarism.description.seeReadme"
msgstr ""
"Изпращане на всички материали на iThenticate, за да бъдат проверени за "
"възможно плагиатство. <strong>Вижте документа README за тази добовка за "
"инструкции за инсталиране.</strong>"

msgid "plugins.generic.plagiarism.description"
msgstr ""
"Изпращане на всички материали на iThenticate, за да бъдат проверени за "
Expand Down
6 changes: 0 additions & 6 deletions locale/ca_ES/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.9.1\n"

msgid "plugins.generic.plagiarism.description.seeReadme"
msgstr ""
"Enviar totes les trameses a iThenticate per detectar possibles plagis. "
"<strong>Llegiu el document README d'aquest mòdul per obtenir les "
"instruccions d'instal·lació.</strong>"

msgid "plugins.generic.plagiarism.description"
msgstr "Enviar totes les trameses a iThenticate per detectar possibles plagis."

Expand Down
6 changes: 0 additions & 6 deletions locale/cs_CZ/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 3.9.1\n"

msgid "plugins.generic.plagiarism.description.seeReadme"
msgstr ""
"Poslat všechny příspěvky do iThenicate, aby byly zkntrolovány případné "
"plagiáty. <strong>Přečtěte si dokument README, kde jsou pokyny pro "
"instalaci.</strong>"

msgid "plugins.generic.plagiarism.description"
msgstr ""
"Odeslat všechny příspěvky do iThenticate ke kontrole možného plagiarismu."
Expand Down
Loading

0 comments on commit e47bc74

Please sign in to comment.