Skip to content

Commit e47bc74

Browse files
authored
Merge pull request #31 from radekgomola/main
Settings for journal managers
2 parents 62b95a9 + 84d7412 commit e47bc74

31 files changed

+285
-164
lines changed

PlagiarismPlugin.inc.php

+116-16
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function register($category, $path, $mainContextId = null) {
2020
$success = parent::register($category, $path, $mainContextId);
2121
$this->addLocaleData();
2222

23-
if ($success && Config::getVar('ithenticate', 'ithenticate') && $this->getEnabled()) {
23+
if ($success && $this->getEnabled()) {
2424
HookRegistry::register('submissionsubmitstep4form::execute', array($this, 'callback'));
2525
}
2626
return $success;
@@ -37,25 +37,65 @@ public function getDisplayName() {
3737
* @copydoc Plugin::getDescription()
3838
*/
3939
public function getDescription() {
40-
return Config::getVar('ithenticate', 'ithenticate')?__('plugins.generic.plagiarism.description'):__('plugins.generic.plagiarism.description.seeReadme');
40+
return __('plugins.generic.plagiarism.description');
4141
}
4242

4343
/**
4444
* @copydoc LazyLoadPlugin::getCanEnable()
4545
*/
46-
function getCanEnable() {
47-
if (!parent::getCanEnable()) return false;
48-
return Config::getVar('ithenticate', 'ithenticate');
46+
function getCanEnable($contextId = null) {
47+
return !Config::getVar('ithenticate', 'ithenticate');
48+
}
49+
50+
/**
51+
* @copydoc LazyLoadPlugin::getCanDisable()
52+
*/
53+
function getCanDisable($contextId = null) {
54+
return !Config::getVar('ithenticate', 'ithenticate');
4955
}
5056

5157
/**
5258
* @copydoc LazyLoadPlugin::getEnabled()
5359
*/
5460
function getEnabled($contextId = null) {
55-
if (!parent::getEnabled($contextId)) return false;
56-
return Config::getVar('ithenticate', 'ithenticate');
61+
return parent::getEnabled($contextId) || Config::getVar('ithenticate', 'ithenticate');
62+
}
63+
64+
/**
65+
* Fetch credentials from config.inc.php, if available
66+
* @return array username and password, or null(s)
67+
**/
68+
function getForcedCredentials() {
69+
$request = Application::getRequest();
70+
$context = $request->getContext();
71+
$contextPath = $context->getPath();
72+
$username = Config::getVar('ithenticate', 'username[' . $contextPath . ']',
73+
Config::getVar('ithenticate', 'username'));
74+
$password = Config::getVar('ithenticate', 'password[' . $contextPath . ']',
75+
Config::getVar('ithenticate', 'password'));
76+
return [$username, $password];
5777
}
5878

79+
/**
80+
* Send the editor an error message
81+
* @param $submissionid int
82+
* @param $message string
83+
* @return void
84+
**/
85+
public function sendErrorMessage($submissionid, $message) {
86+
$request = Application::getRequest();
87+
$context = $request->getContext();
88+
import('classes.notification.NotificationManager');
89+
$notificationManager = new NotificationManager();
90+
$roleDao = DAORegistry::getDAO('RoleDAO'); /* @var $roleDao RoleDAO */
91+
// Get the managers.
92+
$managers = $roleDao->getUsersByRoleId(ROLE_ID_MANAGER, $context->getId());
93+
while ($manager = $managers->next()) {
94+
$notificationManager->createTrivialNotification($manager->getId(), NOTIFICATION_TYPE_ERROR, array('contents' => __('plugins.generic.plagiarism.errorMessage', array('submissionId' => $submissionid, 'errorMessage' => $message))));
95+
}
96+
error_log('iThenticate submission '.$submissionid.' failed: '.$message);
97+
}
98+
5999
/**
60100
* Send submission files to iThenticate.
61101
* @param $hookName string
@@ -65,26 +105,35 @@ public function callback($hookName, $args) {
65105
$request = Application::getRequest();
66106
$context = $request->getContext();
67107
$contextPath = $context->getPath();
68-
$submissionDao = Application::getSubmissionDAO();
108+
$submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
69109
$submission = $submissionDao->getById($request->getUserVar('submissionId'));
70110
$publication = $submission->getCurrentPublication();
71111

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

74114
// try to get credentials for current context otherwise use default config
75-
$username = Config::getVar('ithenticate', 'username[' . $contextPath . ']',
76-
Config::getVar('ithenticate', 'username'));
77-
$password = Config::getVar('ithenticate', 'password[' . $contextPath . ']',
78-
Config::getVar('ithenticate', 'password'));
79-
$ithenticate = new \bsobbe\ithenticate\Ithenticate($username, $password);
115+
$contextId = $context->getId();
116+
list($username, $password) = $this->getForcedCredentials();
117+
if (empty($username) || empty($password)) {
118+
$username = $this->getSetting($contextId, 'ithenticateUser');
119+
$password = $this->getSetting($contextId, 'ithenticatePass');
120+
}
121+
122+
$ithenticate = null;
123+
try {
124+
$ithenticate = new \bsobbe\ithenticate\Ithenticate($username, $password);
125+
} catch (Exception $e) {
126+
$this->sendErrorMessage($submission->getId(), $e->getMessage());
127+
return false;
128+
}
80129
// Make sure there's a group list for this context, creating if necessary.
81130
$groupList = $ithenticate->fetchGroupList();
82131
$contextName = $context->getLocalizedName($context->getPrimaryLocale());
83132
if (!($groupId = array_search($contextName, $groupList))) {
84133
// No folder group found for the context; create one.
85134
$groupId = $ithenticate->createGroup($contextName);
86135
if (!$groupId) {
87-
error_log('Could not create folder group for context ' . $contextName . ' on iThenticate.');
136+
$this->sendErrorMessage($submission->getId(), 'Could not create folder group for context ' . $contextName . ' on iThenticate.');
88137
return false;
89138
}
90139
}
@@ -97,7 +146,7 @@ public function callback($hookName, $args) {
97146
true,
98147
true
99148
))) {
100-
error_log('Could not create folder for submission ID ' . $submission->getId() . ' on iThenticate.');
149+
$this->sendErrorMessage($submission->getId(), 'Could not create folder for submission ID ' . $submission->getId() . ' on iThenticate.');
101150
return false;
102151
}
103152

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

124173
return false;
125174
}
175+
176+
/**
177+
* @copydoc Plugin::getActions()
178+
*/
179+
function getActions($request, $verb) {
180+
$router = $request->getRouter();
181+
import('lib.pkp.classes.linkAction.request.AjaxModal');
182+
return array_merge(
183+
$this->getEnabled() ? array(
184+
new LinkAction(
185+
'settings',
186+
new AjaxModal(
187+
$router->url($request, null, null, 'manage', null, array('verb' => 'settings', 'plugin' => $this->getName(), 'category' => 'generic')),
188+
$this->getDisplayName()
189+
),
190+
__('manager.plugins.settings'),
191+
null
192+
),
193+
) : array(),
194+
parent::getActions($request, $verb)
195+
);
196+
}
197+
198+
/**
199+
* @copydoc Plugin::manage()
200+
*/
201+
function manage($args, $request) {
202+
switch ($request->getUserVar('verb')) {
203+
case 'settings':
204+
$context = $request->getContext();
205+
206+
AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER);
207+
$templateMgr = TemplateManager::getManager($request);
208+
$templateMgr->registerPlugin('function', 'plugin_url', array($this, 'smartyPluginUrl'));
209+
210+
$this->import('PlagiarismSettingsForm');
211+
$form = new PlagiarismSettingsForm($this, $context->getId());
212+
213+
if ($request->getUserVar('save')) {
214+
$form->readInputData();
215+
if ($form->validate()) {
216+
$form->execute();
217+
return new JSONMessage(true);
218+
}
219+
} else {
220+
$form->initData();
221+
}
222+
return new JSONMessage(true, $form->fetch($request));
223+
}
224+
return parent::manage($args, $request);
225+
}
126226
}
127227

128228
/**

PlagiarismSettingsForm.inc.php

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
import('lib.pkp.classes.form.Form');
4+
5+
class PlagiarismSettingsForm extends Form {
6+
7+
/** @var int */
8+
var $_contextId;
9+
10+
/** @var object */
11+
var $_plugin;
12+
13+
/**
14+
* Constructor
15+
* @param $plugin PlagiarismPlugin
16+
* @param $contextId int
17+
*/
18+
function __construct($plugin, $contextId) {
19+
$this->_contextId = $contextId;
20+
$this->_plugin = $plugin;
21+
22+
parent::__construct($plugin->getTemplateResource('settingsForm.tpl'));
23+
24+
$this->addCheck(new FormValidator($this, 'ithenticateUser', 'required', 'plugins.generic.plagiarism.manager.settings.usernameRequired'));
25+
$this->addCheck(new FormValidator($this, 'ithenticatePass', 'required', 'plugins.generic.plagiarism.manager.settings.passwordRequired'));
26+
27+
$this->addCheck(new FormValidatorPost($this));
28+
$this->addCheck(new FormValidatorCSRF($this));
29+
}
30+
31+
/**
32+
* Initialize form data.
33+
*/
34+
function initData() {
35+
list($username, $password) = $this->_plugin->getForcedCredentials();
36+
$this->_data = array(
37+
'ithenticateUser' => $this->_plugin->getSetting($this->_contextId, 'ithenticateUser'),
38+
'ithenticatePass' => $this->_plugin->getSetting($this->_contextId, 'ithenticatePass'),
39+
'ithenticateForced' => !empty($username) && !empty($password)
40+
);
41+
}
42+
43+
/**
44+
* Assign form data to user-submitted data.
45+
*/
46+
function readInputData() {
47+
$this->readUserVars(array('ithenticateUser', 'ithenticatePass'));
48+
}
49+
50+
/**
51+
* @copydoc Form::fetch()
52+
*/
53+
function fetch($request, $template = null, $display = false) {
54+
$templateMgr = TemplateManager::getManager($request);
55+
$templateMgr->assign('pluginName', $this->_plugin->getName());
56+
return parent::fetch($request, $template, $display);
57+
}
58+
59+
/**
60+
* @copydoc Form::execute()
61+
*/
62+
function execute(...$functionArgs) {
63+
$this->_plugin->updateSetting($this->_contextId, 'ithenticateUser', trim($this->getData('ithenticateUser'), "\"\';"), 'string');
64+
$this->_plugin->updateSetting($this->_contextId, 'ithenticatePass', trim($this->getData('ithenticatepass'), "\"\';"), 'string');
65+
parent::execute(...$functionArgs);
66+
}
67+
}

README.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# iThenticate Plagiarism Detector Plugin
2+
3+
For OJS/OMP/OPS 3.x
4+
5+
## Overview
6+
7+
This plugin permits automatic submission of uploaded manuscripts to the [iThenticate service](http://www.ithenticate.com/) for plagiarism checking.
8+
1. You need an account of ithenticate.com (costs involved)
9+
* paid via Crossref Similarity Check
10+
* or, paid directly to iThenticate
11+
2. Install the plugin via the Plugin Gallery in the Dashboard
12+
3. Configure the plugin (see below)
13+
* Enable the plugin via config.inc.php or in a specific journal/press/preprint context
14+
* Configure the plugin with the username and password you get from ithenticate.com
15+
* ![Example Settings configuration](ithenticate-settings.png)
16+
4. The author logs in and makes a submission
17+
* The submission files will be sent to iThenticate in Step 4 of the submission process
18+
5. The Editor logs in to ithenticate.com to see the submission
19+
* The submission will be found in a folder named by the Submission ID, under a Group named by the journal/press/preprint context
20+
* Click to see the report
21+
* ![Example report review](ithenticate-report.png)
22+
23+
Watch [the demo](https://www.ithenticate.com/demo) to know more about the features of iThenticate.
24+
25+
## Configuration
26+
27+
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.
28+
29+
The config.inc.php settings format is:
30+
31+
```
32+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33+
; iThenticate Plugin Settings ;
34+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35+
36+
[ithenticate]
37+
38+
; Enable iThenticate to submit manuscripts after submit step 4
39+
;ithenticate = On
40+
41+
; Credentials can be set by context : specify journal path
42+
; The username to access the API (usually an email address)
43+
;username[MyJournal_path] = "[email protected]"
44+
; The password to access the API
45+
;password[MyJournal_path] = "password"
46+
47+
; default credentials
48+
; The username to access the API (usually an email address)
49+
;username = "[email protected]"
50+
51+
; The password to access the API
52+
;password = "password"
53+
```
54+

README.txt

-23
This file was deleted.

ithenticate-report.png

37.8 KB
Loading

ithenticate-settings.png

17.9 KB
Loading

locale/ar_IQ/locale.po

-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,3 @@ msgstr "إضافة كشف السرقة الأدبية iThenticate"
1616

1717
msgid "plugins.generic.plagiarism.description"
1818
msgstr "أرسل كل طلبات التقديم إلى iThenticate للتحقق من إحتمالية وجود سرقات أدبية."
19-
20-
msgid "plugins.generic.plagiarism.description.seeReadme"
21-
msgstr "أرسل كل طلبات التقديم إلى iThenticate للتحقق من إحتمالية وجود سرقات أدبية. <strong>أنظر ملف README الخاص بهذه الإضافة لمعرفة إرشادات التنصيب.</strong>"

locale/bg_BG/locale.po

-6
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ msgstr ""
1212
"Plural-Forms: nplurals=2; plural=n != 1;\n"
1313
"X-Generator: Weblate 3.9.1\n"
1414

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

locale/ca_ES/locale.po

-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ msgstr ""
1111
"Plural-Forms: nplurals=2; plural=n != 1;\n"
1212
"X-Generator: Weblate 3.9.1\n"
1313

14-
msgid "plugins.generic.plagiarism.description.seeReadme"
15-
msgstr ""
16-
"Enviar totes les trameses a iThenticate per detectar possibles plagis. "
17-
"<strong>Llegiu el document README d'aquest mòdul per obtenir les "
18-
"instruccions d'instal·lació.</strong>"
19-
2014
msgid "plugins.generic.plagiarism.description"
2115
msgstr "Enviar totes les trameses a iThenticate per detectar possibles plagis."
2216

locale/cs_CZ/locale.po

-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ msgstr ""
1111
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
1212
"X-Generator: Weblate 3.9.1\n"
1313

14-
msgid "plugins.generic.plagiarism.description.seeReadme"
15-
msgstr ""
16-
"Poslat všechny příspěvky do iThenicate, aby byly zkntrolovány případné "
17-
"plagiáty. <strong>Přečtěte si dokument README, kde jsou pokyny pro "
18-
"instalaci.</strong>"
19-
2014
msgid "plugins.generic.plagiarism.description"
2115
msgstr ""
2216
"Odeslat všechny příspěvky do iThenticate ke kontrole možného plagiarismu."

0 commit comments

Comments
 (0)