1
0
mirror of https://github.com/PlagiarismCheck/moodle-plagiarism_pchkorg.git synced 2024-12-22 12:10:08 +00:00

Version v1.18

This commit is contained in:
Jane Adelmann 2018-11-01 16:21:14 +02:00
parent 45bf61b27b
commit 66c41a0b38
No known key found for this signature in database
GPG Key ID: 4448AC31D0972D2F
41 changed files with 3151 additions and 0 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
Plagiarism Check Plugin.
This plugin provide functionality for Plagiarismcheck.org service.
Plagiarismcheck.org is a sophisticated similarity search engine.
We advocate for bringing technology into academics to help instructors save time and motivate students write better papers.

1
amd/build/main.min.js vendored Normal file
View File

@ -0,0 +1 @@
define(["jquery"],function(a){return{checkReport:function(){window.console.log("loaded",a)}}});

33
amd/src/main.js Normal file
View File

@ -0,0 +1,33 @@
/**
* Activity form
*
* @package plagiarism_pchkorg
* @subpackage plagiarism
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/* jshint ignore:start */
define(['jquery'], function ($) {
return {
checkReport: function () {
var interval;
var data = {
'file': $('#plagcheck-loader').attr('data-file'),
'cmid': $('#plagcheck-loader').attr('data-cmid')
};
var checkStatus = function () {
$.post('/plagiarism/pchkorg/page/check.php', data, function (response) {
if (!response || !response.success) {
$('#plagcheck-loader').hide();
clearInterval(interval);
} else if (response.checked) {
$('#plagcheck-loader').hide();
clearInterval(interval);
window.location.href = response.location;
}
}, 'JSON');
};
interval = setInterval(checkStatus, 1000)
}
};
});

View File

@ -0,0 +1,3 @@
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 236 B

View File

@ -0,0 +1,3 @@
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 181 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" fill="#cecece" />
</svg>

After

Width:  |  Height:  |  Size: 173 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" fill="#888" />
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 170 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 331 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" fill="#4caf50" />
</svg>

After

Width:  |  Height:  |  Size: 173 B

View File

@ -0,0 +1 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M18.08,17.8C17.62,17.93 17.21,18 16.85,18C15.65,18 14.84,17.12 14.43,15.35H14.38C13.39,17.26 12,18.21 10.25,18.21C8.94,18.21 7.89,17.72 7.1,16.73C6.31,15.74 5.92,14.5 5.92,13C5.92,11.25 6.37,9.85 7.26,8.76C8.15,7.67 9.36,7.12 10.89,7.12C11.71,7.12 12.45,7.35 13.09,7.8C13.73,8.26 14.22,8.9 14.56,9.73H14.6L15.31,7.33H17.87L15.73,12.65C15.97,13.89 16.22,14.74 16.5,15.19C16.74,15.64 17.08,15.87 17.5,15.87C17.74,15.87 17.93,15.83 18.1,15.76L18.08,17.8M13.82,12.56C13.61,11.43 13.27,10.55 12.81,9.95C12.36,9.34 11.81,9.04 11.18,9.04C10.36,9.04 9.7,9.41 9.21,10.14C8.72,10.88 8.5,11.79 8.5,12.86C8.5,13.84 8.69,14.65 9.12,15.31C9.54,15.97 10.11,16.29 10.82,16.29C11.42,16.29 11.97,16 12.46,15.45C12.96,14.88 13.37,14.05 13.7,12.96L13.82,12.56Z" fill="#333" /></svg>

After

Width:  |  Height:  |  Size: 1009 B

View File

@ -0,0 +1,3 @@
<svg fill="#888888" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 280 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24">
<path d="M17,9H7V7H17M17,13H7V11H17M14,17H7V15H14M12,3A1,1 0 0,1 13,4A1,1 0 0,1 12,5A1,1 0 0,1 11,4A1,1 0 0,1 12,3M19,3H14.82C14.4,1.84 13.3,1 12,1C10.7,1 9.6,1.84 9.18,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3Z" fill="#333" />
</svg>

After

Width:  |  Height:  |  Size: 366 B

834
assets/viewer/plagCheck.css Normal file
View File

@ -0,0 +1,834 @@
.pCheck-loader {
font-size: 0.625rem;
position: relative;
text-indent: -9999em;
border-top: 0.5em solid rgba(0, 0, 0, 0.1);
border-right: 0.5em solid rgba(0, 0, 0, 0.1);
border-bottom: 0.5em solid rgba(0, 0, 0, 0.1);
border-left: 0.5em solid #e56d67;
-webkit-transform: translateZ(0);
transform: translateZ(0);
will-change: rotate;
-webkit-animation: load 1s linear infinite;
animation: load 1s linear infinite;
margin: 0 auto; }
.pCheck-loader,
.pCheck-loader::after {
border-radius: 50%;
width: 2em;
height: 2em; }
@-webkit-keyframes load {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes load {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
.pCheck-brief-percent {
font-size: 0.875rem;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-right: 1px solid #efefef;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 8px 16px; }
.pCheck-brief-percent:first-child {
padding-left: 0; }
.pCheck-brief-percent:last-child {
border-right: none; }
.pCheck-brief-percent-type {
text-transform: capitalize;
font-weight: bold;
border-radius: 1rem;
font-size: 0.875rem; }
.pCheck-brief-percent-diagram {
width: 100%;
min-width: 120px;
height: 4px;
background-color: #efefef;
position: relative;
border-radius: 2px;
margin: 4px 0; }
.pCheck-brief-percent-diagram-type {
position: absolute;
left: 0;
top: 0;
height: 100%;
border-radius: 2px; }
.pCheck-brief-percent-sources {
font-size: 0.875rem; }
.pCheck-nodes-words {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-brief-percent-words {
color: #888;
font-size: 0.75rem; }
.pCheck-brief-percent-nodes {
color: #888;
font-size: 0.75rem; }
.pCheck-brief-summary {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 1rem; }
.pCheck-brief-title-total {
margin: 0;
font-weight: bold;
font-size: 1.25rem; }
.pCheck-brief-title-desc {
font-size: 0.75rem;
color: #888; }
.pCheck-brief-words {
margin-top: 8px; }
.pCheck-brief-briefItem {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0 1px; }
.pCheck-brief-briefItem:first-child {
padding-left: 0; }
.pCheck-brief-briefItem:hover {
cursor: help; }
.pCheck-brief-briefItem-color {
width: 100%;
border-radius: 2px;
height: 6px; }
.pCheck-brief-measureBriefLine {
width: 100%; }
.pCheck-brief-briefLine {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
width: 100%;
background-color: #fff;
margin: 4px 0 12px;
border-radius: 3px; }
.pCheck-brief {
width: 100%; }
.pCheck-brief-info {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
min-height: 101px; }
.pCheck-brief-title {
min-width: 240px; }
.pCheck-node {
font-size: 0.875rem;
margin: 0 8px 0 0;
font-family: inherit;
white-space: pre-wrap;
word-break: break-all;
display: inline;
padding: 0.1rem 0; }
.pCheck-node.pCheck-plagiarism.pCheck-matched:hover, .pCheck-node.pCheck-paraphrase.pCheck-matched:hover, .pCheck-node.pCheck-header.pCheck-matched:hover, .pCheck-node.pCheck-quote.pCheck-matched:hover, .pCheck-node.pCheck-reference.pCheck-matched:hover {
cursor: pointer;
color: #1976d2 !important;
border-color: transparent !important; }
.pCheck-node.pCheck-plagiarism.pCheck-filtered:hover, .pCheck-node.pCheck-paraphrase.pCheck-filtered:hover, .pCheck-node.pCheck-header.pCheck-filtered:hover, .pCheck-node.pCheck-quote.pCheck-filtered:hover, .pCheck-node.pCheck-reference.pCheck-filtered:hover {
cursor: text;
color: inherit !important; }
.pCheck-node.pCheck-header, .pCheck-node.pCheck-quote, .pCheck-node.pCheck-reference {
border-bottom-style: dashed !important; }
.pCheck-highlighted .pCheck-node.pCheck-unhighlighted {
color: inherit !important;
border-bottom: transparent !important; }
.pCheck-dropDown {
position: relative;
min-height: 22px;
min-width: 22px; }
.pCheck-dropDown.pCheck-bottom .pCheck-dropDown-list {
top: 0; }
.pCheck-dropDown.pCheck-top .pCheck-dropDown-list {
bottom: 0; }
.pCheck-dropDown-button {
width: 22px;
height: 22px;
border-radius: 50%;
background-image: url(d1af325a022bb1885a7869dad9eaa500.svg);
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center center; }
.pCheck-dropDown-button:hover {
cursor: pointer;
background-color: #b3e5fc; }
.pCheck-dropDown-list {
background-color: #fff;
position: absolute;
z-index: 32;
border-radius: 2px;
right: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
min-width: 100px;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-shadow: 0 4px 12px -4px #888;
box-shadow: 0 4px 12px -4px #888; }
.pCheck-source-filterItem {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 8px 16px 8px 12px;
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.pCheck-source-filterItem.pCheck-inactive .pCheck-source-filterItem-switch {
background-image: url(20288744996c2dc297e5b40186f339ae.svg); }
.pCheck-source-filterItem:last-child {
border-bottom: none; }
.pCheck-source-filterItem:hover {
cursor: pointer;
background-color: #efefef; }
.pCheck-source-filterItem-switch {
width: 22px;
height: 22px;
background-size: 18px 18px;
background-position: center center;
background-repeat: no-repeat;
background-image: url(6d872c8ed163708099999ace50567848.svg); }
.pCheck-source-filterItem-text {
display: block;
margin-right: 8px;
margin-left: 8px; }
.pCheck-source-filterItem-type {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 0;
margin-left: auto; }
.pCheck-source.pCheck-all {
border-bottom: 1px solid #efefef;
padding-bottom: 8px;
border-radius: 0; }
.pCheck-source.pCheck-all .pCheck-source-label,
.pCheck-source.pCheck-all .pCheck-source-name,
.pCheck-source.pCheck-all .pCheck-source-index {
opacity: 1; }
.pCheck-source.pCheck-all .pCheck-source-name {
padding-left: 4px;
padding-right: 0; }
.pCheck-source.pCheck-all .pCheck-dropDown-button {
background-image: url(189d30258cbfac64b38b693c383a7b31.svg); }
.pCheck-source-typeBadges {
margin-right: 0;
margin-left: auto; }
.pCheck-source-typeBadge {
font-size: 0.75rem;
margin: 0 2px;
font-weight: bold;
line-height: 62%; }
.pCheck-source-percent {
min-width: 52px;
padding: 0 4px;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.pCheck-source-action {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 8px 16px 8px 12px;
white-space: nowrap;
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.pCheck-source-action:hover {
cursor: pointer;
background-color: #efefef; }
.pCheck-source-action::before {
content: '';
width: 22px;
height: 22px;
background-size: 18px 18px;
background-position: center center;
background-repeat: no-repeat;
margin-right: 8px;
display: block;
background-image: url(20288744996c2dc297e5b40186f339ae.svg); }
.pCheck-source-action.pCheck-active::before {
background-image: url(6d872c8ed163708099999ace50567848.svg); }
.pCheck-source-link {
color: inherit;
text-decoration: none;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 8px 16px 8px 12px;
white-space: nowrap;
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.pCheck-source-link::before {
content: '';
width: 22px;
height: 22px;
background-size: 18px 18px;
background-position: center center;
background-repeat: no-repeat;
background-image: url(463d1ca07dcbf1c18745b2999af60e4b.svg);
margin-right: 8px; }
.pCheck-source-link:hover {
cursor: pointer;
background-color: #efefef; }
.pCheck-source-index {
min-width: 22px;
min-height: 22px;
color: #333;
border-radius: 50%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 0.75rem;
font-weight: bold;
margin: 0 4px 0 8px;
text-align: center;
background-color: #efefef; }
.pCheck-source-index:hover {
cursor: help; }
.pCheck-source-index.external, .pCheck-source-index.cache {
visibility: hidden; }
.pCheck-source-name {
display: block;
overflow: hidden;
text-overflow: ellipsis;
margin-left: 0;
margin-right: auto;
text-decoration: none; }
.pCheck-source-name.pCheck-link {
color: #0d47a1; }
.pCheck-source-name:hover {
cursor: pointer;
color: #1976d2; }
.pCheck-source-label {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
min-width: 84px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-source-label:hover {
cursor: pointer; }
.pCheck-source-checkbox {
outline: none;
min-width: 16px;
min-height: 16px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: transparent;
border: 1px solid #888;
border-radius: 2px; }
.pCheck-source-checkbox:hover {
cursor: pointer; }
.pCheck-source-checkbox:checked {
background: transparent url(6d872c8ed163708099999ace50567848.svg) center center no-repeat;
background-size: 12px 12px; }
.pCheck-highlighted .pCheck-source-label,
.pCheck-highlighted .pCheck-source-name,
.pCheck-highlighted .pCheck-source-index {
opacity: 0.4; }
.pCheck-source {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border-radius: 2px;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 4px;
margin-bottom: 4px;
font-size: 0.875rem;
line-height: 160%;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%; }
.pCheck-source.pCheck-active {
background-color: #b3e5fc; }
.pCheck-source.pCheck-highlighted .pCheck-source-label,
.pCheck-source.pCheck-highlighted .pCheck-source-name,
.pCheck-source.pCheck-highlighted .pCheck-source-index {
opacity: 1; }
.pCheck-source.pCheck-ignored {
background-color: #e1bee7; }
.pCheck-details-title {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-details-title-type {
padding: 4px 12px;
border-radius: 16px;
font-size: 0.75rem;
text-transform: uppercase;
color: #fff; }
.pCheck-details-title-title {
font-weight: bold;
margin-left: 8px; }
.pCheck-details-text {
padding-bottom: 8px; }
.pCheck-details-text-text {
font-size: 0.875rem;
padding: 16px 0; }
.pCheck-details-text-textInfo {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
font-size: 0.875rem; }
.pCheck-details-text-percent {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap; }
.pCheck-details-text-percent-text {
margin-left: 4px; }
.pCheck-details-text-words {
margin-left: 4px;
color: #888; }
.pCheck-details-text-textCopy {
padding: 6px 8px 6px 4px;
color: inherit;
background-color: #efefef;
border: none;
border-radius: 2px;
outline: none;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
font-size: 0.875rem; }
.pCheck-details-text-textCopy:hover {
cursor: pointer;
background-color: #b3e5fc; }
.pCheck-details-text-textCopy::before {
content: '';
width: 16px;
height: 16px;
display: block;
margin-right: 4px;
background-image: url(e1a427ae8d674f488554205093c3695f.svg);
background-position: center center;
background-repeat: no-repeat;
background-size: contain; }
.pCheck-details-text-textCopy.pCheck-copied::before {
background-image: url(7b6b06644be2e5537935b55a7e3141c9.svg); }
.pCheck-details-sourceItem-cos {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
color: #888;
min-width: 52px;
margin-right: 8px; }
.pCheck-details-sourceItem-cos::before {
content: '';
width: 18px;
height: 18px;
display: block;
background-image: url(8c9a309759d08c07e9ef4f7e2093e710.svg);
background-size: cover;
background-color: #efefef;
border-radius: 50%;
margin-right: 4px; }
.pCheck-details-sourceItem-single {
width: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-decoration: none;
color: #0d47a1;
padding: 4px 8px; }
.pCheck-details-sourceItem-single:hover {
color: #1976d2; }
.pCheck-details-sourceItem-single-icon {
margin-left: auto;
margin-right: 0;
background-image: url(463d1ca07dcbf1c18745b2999af60e4b.svg);
width: 22px;
height: 22px;
background-size: 18px 18px;
background-repeat: no-repeat;
background-position: center center; }
.pCheck-details-sourceItem-links {
margin-right: 0;
margin-left: auto;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-details-sourceItem-link {
color: inherit;
text-decoration: none;
white-space: nowrap;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-indent: -9999px; }
.pCheck-details-sourceItem-link::after {
content: '';
width: 22px;
height: 22px;
background-image: url(6fe578c1c8ac120206998fccdd3bac84.svg);
display: block;
background-position: center center;
background-size: 18px 18px;
background-repeat: no-repeat;
border-radius: 50%; }
.pCheck-details-sourceItem-link:hover::after {
background-color: #b3e5fc; }
.pCheck-details-sourceItem-multi {
width: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 4px 8px; }
.pCheck-details-sourceItem {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 0.875rem; }
.pCheck-details-sourceItem:hover {
background-color: #efefef; }
.pCheck-details-sourceItem .pCheck-source-index {
margin: 0 8px 0 0; }
.pCheck-nodeDetails-sourcesList-tabs {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
padding: 0;
border-bottom: 1px solid #cecece;
margin: 16px 0; }
.pCheck-nodeDetails-sourcesList-tab {
list-style-type: none;
font-size: 0.875rem;
padding: 4px 12px;
border-radius: 4px 4px 0 0;
margin-right: 4px;
outline: none;
background-color: #fff; }
.pCheck-nodeDetails-sourcesList-tab.pCheck-active {
position: relative;
bottom: -1px;
border: 1px solid #cecece;
border-bottom: none; }
.pCheck-nodeDetails-sourcesList-tab.pCheck-active:hover {
cursor: default;
background-color: #fff; }
.pCheck-nodeDetails-sourcesList-tab.pCheck-disabled {
color: #888; }
.pCheck-nodeDetails-sourcesList-tab.pCheck-disabled:hover {
cursor: default;
background-color: #fff; }
.pCheck-nodeDetails-sourcesList-tab:hover {
cursor: pointer;
background-color: #b3e5fc; }
.pCheck-details {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-details-overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 64;
opacity: 0.6;
background-color: rgba(0, 0, 0, 0.16); }
.pCheck-details-details {
width: 100%;
max-width: 620px;
max-height: 100%;
padding: 16px 32px 32px;
background-color: #fff;
border-radius: 2px;
-webkit-box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.12), 0 2px 2px 0 rgba(0, 0, 0, 0.12);
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.12), 0 2px 2px 0 rgba(0, 0, 0, 0.12);
z-index: 65; }
.pCheck-details-header {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-details-close {
width: 32px;
height: 32px;
border-radius: 50%;
background-image: url(18165c78c6d1452d17d41df86c8f7c48.svg);
background-repeat: no-repeat;
background-position: center center;
background-size: 18px 18px; }
.pCheck-details-close:hover {
cursor: pointer;
background-color: #efefef; }
.pCheck-workspace {
width: 100%;
height: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between; }
.pCheck-nodes {
padding: 0 24px 0 0;
-webkit-box-sizing: border-box;
box-sizing: border-box; }
.pCheck-sources-sticky {
overflow-y: auto; }
.pCheck-sources {
width: 320px;
min-width: 320px;
max-width: 320px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
top: 0; }
.pCheck-empty {
padding: 8px 16px 8px 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-size: 1rem;
border-bottom: 2px solid #efefef;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center; }
.pCheck-empty::before {
content: '';
width: 24px;
height: 24px;
display: block;
background-image: url(7b6b06644be2e5537935b55a7e3141c9.svg);
background-repeat: no-repeat;
background-position: center center;
margin-right: 4px; }
/*# sourceMappingURL=plagCheck.css.map*/

View File

@ -0,0 +1 @@
{"version":3,"file":"plagCheck.css","sources":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","sourceRoot":""}

File diff suppressed because one or more lines are too long

798
assets/viewer/report-viewer.min.css vendored Normal file
View File

@ -0,0 +1,798 @@
@import url(https://fonts.googleapis.com/css?family=Roboto);@charset "UTF-8";
* {
box-sizing: border-box; }
html {
font-family: "Roboto", sans-serif; }
body {
margin: 0; }
.RootLayout {
color: #333;
background: #fff;
height: auto;
width: 100%;
min-height: 100vh;
display: flex;
overflow-x: hidden; }
.RootLayout__content {
padding: 20px 40px;
flex-grow: 1;
flex-basis: 0;
max-width: 100%;
z-index: 0;
position: relative; }
@media only screen and (max-width: 1441px) {
.RootLayout__content {
padding: 20px 20px; } }
@media only screen and (min-width: 1025px) and (max-width: 1440px) {
.RootLayout__content {
padding: 20px 20px; } }
.OverlapBar {
position: absolute;
top: 0;
bottom: 0;
right: 12px;
width: 1px; }
.OverlapBar__overlap-part {
width: 1px;
background-color: #a13169; }
.SidebarInset {
background: #d7d7d7;
color: #333;
font-size: 15px;
line-height: 50px;
height: 50px;
opacity: 1;
padding: 0 10px;
text-transform: uppercase;
align-items: center;
display: flex; }
.SidebarInset:hover {
color: white; }
.SidebarInset:hover .SidebarInset__open-arrow {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -98px -89px;
height: 29px;
width: 18px; }
.SidebarInsetContainer {
border-top: 1px solid #cacaca;
overflow: hidden; }
.SidebarInsetContainer:first-child {
border-top: none; }
.SidebarInset__title {
flex-basis: 72%;
max-width: 72%; }
.SidebarInset__percent {
flex-basis: 16.667%;
max-width: 16.667%; }
.SidebarInset__open-arrow-container {
flex-basis: 8.333%;
max-width: 8.333%;
margin-left: 10px; }
.SidebarInset__open-arrow {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -80px -60px;
height: 29px;
width: 18px;
cursor: pointer;
margin-right: 3px; }
.SidebarInset__open-arrow-open {
transform: rotate(180deg); }
.SidebarInset__percent-text {
font-weight: 600; }
.SidebarInset__title-text {
display: inline-block;
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
font-weight: 400; }
.SidebarInset__title-text:after {
content: '';
display: inline-block;
height: 10px;
margin-left: 8px;
vertical-align: middle;
width: 25px; }
.SidebarInset-plag:hover {
background: #a13169; }
.SidebarInset-plag .SidebarInset__title-text:after {
background: url(wave-dc15a25d325f6e422665aaea4eee9834.svg?dc15a25d325f6e422665aaea4eee9834) 0 center repeat-x; }
.SidebarInse-quot:hover {
background: #639ec3; }
.SidebarInse-quot .SidebarInset__title-text:after {
background: url(wave-qu-8ff3a7579823f9099d975ad581dc134e.svg?8ff3a7579823f9099d975ad581dc134e) 0 center repeat-x; }
.SidebarInset-ref:hover {
background: #289870; }
.SidebarInset-ref .SidebarInset__title-text:after {
background: url(wave-rf-d7c35952140e971b52a5fbb5b5acf36d.svg?d7c35952140e971b52a5fbb5b5acf36d) 0 center repeat-x; }
.SidebarInset__title-button {
display: inline-block;
margin-right: 7px;
margin-left: -3px;
position: relative;
vertical-align: middle;
width: 25px;
border-radius: 8px;
cursor: pointer;
overflow: hidden; }
.SidebarInset__title-button-label {
border-radius: 8px;
cursor: pointer;
display: block;
overflow: hidden;
font-size: 16px; }
.SidebarInset__title-button-inner {
display: block;
transition: margin .2s ease-in 0s;
width: 200%;
font-weight: 600;
margin-left: 0; }
.SidebarInset__title-button-inner:after {
background-color: #EEEEEE;
color: #999999;
content: "";
padding-right: 10px;
text-align: right; }
.SidebarInset__title-button-inner:before, .SidebarInset__title-button-inner:after {
box-sizing: border-box;
color: white;
display: block;
float: left;
font-weight: bold;
font-size: 14px;
height: 14px;
line-height: 14px;
padding: 0;
width: 50%; }
.SidebarInset__title-button-inner:before {
background-color: #EEEEEE;
content: "";
color: #FFFFFF;
padding-left: 10px; }
.SidebarInset__title-button-switch {
background: #949494;
border: 1px solid #EEEEEE;
border-radius: 8px;
display: block;
margin: 0px;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
transition: all .2s ease-in 0s;
width: 14px;
font-weight: 600;
box-sizing: border-box; }
.SidebarInset__title-button-switch-checked {
background-color: #10b34c;
right: 0; }
.SidebarInset__content {
max-height: 0;
opacity: 0;
transition: .3s ease; }
.SidebarInset__content-open {
opacity: 1;
position: relative;
max-height: calc(100vh - 183px); }
@media only screen and (max-width: 1441px) {
.SidebarInset {
font-size: 14px; } }
.Report {
overflow: hidden;
position: relative;
margin: -20px -40px; }
@media only screen and (max-width: 1441px) {
.Report {
margin: -20px -20px; } }
@media only screen and (min-width: 1025px) and (max-width: 1440px) {
.Report {
margin: -20px -20px; } }
.ui-plagCheck-workspace-content {
width: 100%;
display: flex;
flex-direction: column;
margin-right: 320px;
height: 100vH; }
.ui-plagCheck-stats {
background: whitesmoke;
border-bottom: 1px solid #e5e5e5;
position: relative;
padding: 0 20px;
min-height: 95px;
display: flex;
align-items: center; }
.ui-plagCheck-stats-content {
display: flex;
align-items: center;
justify-content: space-between;
height: 101px;
max-width: 900px;
width: 100%;
margin: 0 auto; }
.ui-plagCheck-stats-matched-percent {
color: #a13169;
display: inline-block;
font-size: 62px;
font-weight: 600;
line-height: 68px;
margin-right: 10px; }
.ui-plagCheck-stats-matched-text {
color: #333;
display: inline-block;
font-size: 22px;
font-weight: 300;
line-height: 26px;
max-width: 180px;
position: relative;
text-transform: uppercase; }
.ui-plagCheck-nodes-scroll {
display: flex;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0; }
.ui-plagCheck-nodes-scroll-container {
max-width: 900px;
margin: 40px 20px;
text-align: left;
line-height: 26px;
word-wrap: break-word;
position: relative;
width: 100%; }
.ui-plagCheck-nodes-scroll-container-center {
display: flex;
justify-content: center; }
.ui-plagCheck-stats-matched-percent-symbol {
font-weight: 300; }
.ui-plagCheck-nodes-scroll-report-name {
font-weight: 700;
line-height: 44px;
margin-right: 20px;
margin-bottom: 20px;
vertical-align: middle;
font-size: 34px; }
.ui-plagcheck-custom-trumb {
background-color: #333;
opacity: 0.3;
border-radius: 2px;
width: 4px; }
.ui-plagCheck-workspace {
display: flex;
flex-flow: row nowrap;
justify-content: space-between; }
.ui-plagCheck-nodes {
box-sizing: border-box;
text-align: justify;
width: 100%;
flex: 1 1 100%;
position: relative; }
.ui-plagCheck-nodes:hover .ui-plagcheck-custom-trumb {
background: #306a8f;
opacity: .6; }
.ui-plagcheck-custom-track {
background-color: #ececec;
border-radius: 2px;
right: 5px;
top: 10px;
height: 93%;
position: absolute;
width: 4px; }
.ui-plagCheck-sources-sticky {
overflow-y: auto; }
.ui-plagCheck-sidebar-sources-container {
width: 98%; }
.ui-plagCheck-sidebar {
background: #ececec;
max-width: 320px;
position: absolute;
top: 0;
bottom: 0;
right: 0;
transition: .3s ease;
width: 100%; }
.ui-plagCheck-sidebar-open-button {
display: none; }
.ui-plagCheck-sidebar-button {
z-index: 1;
background: #8d2b5c;
border-radius: 4px 0 0 4px;
color: #fff;
cursor: pointer;
display: none;
font-size: 16px;
font-weight: 400;
height: 50px;
line-height: 50px;
position: absolute;
top: 98px;
left: -50px;
text-align: center;
width: 50px; }
.ui-plagCheck-sidebar-button:before {
color: white;
content: "%"; }
html body .SidebarInset__content-open .ui-plagCheck-sources-scroll {
position: relative; }
.ui-plagcheck-custom-sources-track {
border-radius: 2px;
right: 2px;
top: 10px;
height: 95%;
position: absolute;
width: 4px; }
.ui-plagcheck-custom-sources-trumb {
background-color: #333;
opacity: 0.3;
border-radius: 2px;
width: 4px; }
.ui-plagCheck-overlap-part-sources {
background: #a13169;
width: 2px; }
.ui-plagCheck-overlap-part-quSources {
background: #639ec3;
width: 2px; }
.ui-plagCheck-overlap-part-reSources {
background: #289870;
width: 2px; }
@media only screen and (max-width: 1441px) {
.ui-plagCheck-stats {
padding: 0 20px; }
.ui-plagCheck-stats-content {
height: 86px; }
.ui-plagCheck-stats {
padding: 0 20px; }
.ui-plagCheck-nodes-scroll-report-name {
font-size: 30px; }
.ui-plagCheck-sidebar {
max-width: 280px; }
.ui-plagCheck-workspace-content {
margin-right: 280px; }
.ui-plagCheck-stats-matched-percent {
font-size: 37px;
line-height: 37px; }
.ui-plagCheck-stats-matched-text {
font-size: 16px;
line-height: 18px; } }
@media only screen and (max-width: 1025px) {
.ui-plagCheck-stats {
min-height: 117px; }
.ui-plagCheck-nodes-scroll-report-name {
font-size: 24px;
margin-right: 0;
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis; }
.ui-plagCheck-workspace-content {
margin-right: 0;
height: 100vH; }
.ui-plagCheck-sidebar {
right: -280px; }
.ui-plagCheck-sidebar:after {
background: #333;
content: "";
position: fixed;
top: 0;
right: 0;
bottom: 0;
opacity: 0;
visibility: visible;
z-index: 0;
transition: .3s ease; }
.ui-plagCheck-sidebar-open {
right: 0; }
.ui-plagCheck-sidebar-open:after {
left: -1000px;
opacity: .3;
right: 280px; }
.ui-plagCheck-sidebar-button {
display: block; }
.ui-plagCheck-sidebar-open .ui-plagCheck-sidebar-button:before {
content: "\2716"; }
.ui-plagCheck-sidebar-open-button {
display: block; }
.ui-plagCheck-stats-matched-percent {
font-size: 42px;
line-height: 39px; }
.ui-plagCheck-stats-matched-text {
font-size: 18px;
font-weight: 400;
line-height: 18px; } }
@media only screen and (max-width: 1020px) {
.ui-plagCheck-workspace-content {
height: 100vH; } }
.ui-plagCheck-nodes-header {
margin-bottom: 20px; }
.ui-plagCheck-overlap-bar {
top: 10px;
height: 93%;
right: 12px;
width: 2px; }
@media only screen and (max-width: 641px) {
.ui-plagCheck-stats {
padding: 10px 20px;
overflow: hidden; } }
@media only screen and (max-width: 425px) {
.ui-plagCheck-stats {
padding: 0 10px;
position: relative;
height: 86px; }
.ui-plagCheck-stats-content {
padding-right: 10px; } }
.ui-plagCheck-node-isVisible {
display: inline; }
.ui-plagCheck-node {
font-size: 15px;
white-space: pre-wrap;
background-repeat: repeat-x;
background-position: bottom;
padding-top: 4px;
padding-bottom: 4px;
transition: all 0.3s cubic-bezier(0.51, -0.38, 1, 1);
vertical-align: top; }
.ui-plagCheck-node.quote {
background-color: #639ec3;
color: white; }
.ui-plagCheck-node.reference {
background-color: #289870;
color: white; }
.ui-plagCheck-node.active, .ui-plagCheck-node.ui-plagCheck-source:hover {
background-color: #a13169;
color: white; }
.ui-plagCheck-node-quSources {
background-image: url(wave-qu-8ff3a7579823f9099d975ad581dc134e.svg?8ff3a7579823f9099d975ad581dc134e);
font-weight: 400; }
.ui-plagCheck-node-reSources {
background-image: url(wave-rf-d7c35952140e971b52a5fbb5b5acf36d.svg?d7c35952140e971b52a5fbb5b5acf36d);
font-weight: 400; }
.ui-plagCheck-node-sources {
background-image: url(wave-dc15a25d325f6e422665aaea4eee9834.svg?dc15a25d325f6e422665aaea4eee9834);
font-weight: 400; }
@media only screen and (max-width: 426px) {
.ui-plagCheck-node {
line-height: 18px; } }
.checkIcon:before,
.checkIcon:after {
content: "";
height: 7px;
opacity: 0;
position: absolute;
top: 2px;
left: 1px;
transform-origin: center;
transform: rotate(-45deg);
width: 14px; }
.checkIcon:before {
transition: 0s ease opacity; }
.checkIcon:after {
top: 0px;
transform: rotate(-45deg) scale(0.9); }
.checkIcon-checked:before {
transition: .3s ease opacity;
opacity: 1; }
.checkIcon-checked:after {
opacity: 1; }
.ui-plagCheck-source {
display: flex;
flex-flow: row nowrap;
align-items: center;
line-height: 35px;
font-size: 15px;
padding: 0 10px;
position: relative;
z-index: 0;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.51, -0.38, 1, 1); }
.ui-plagCheck-source.highlighted {
background: #a13169;
color: #fff; }
.ui-plagCheck-source .ui-dropDown-options {
right: 0;
left: auto;
min-width: 160px; }
.ui-plagCheck-source.active .plagCheckSource-web-cache-icon, .ui-plagCheck-source:hover .plagCheckSource-web-cache-icon {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -1055px -1053px;
height: 15px;
width: 60px; }
.ui-plagCheck-source-disabled:hover {
background-color: rgba(211, 211, 211, 0.5); }
.ui-plagCheck-source-enabled.ui-plagCheck-source-sources.active, .ui-plagCheck-source-enabled.ui-plagCheck-source-sources.ui-plagCheck-source:hover {
background: #a13169;
color: #fff; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-sources.active .plagCheckSource-web-cache-icon, .ui-plagCheck-source-enabled.ui-plagCheck-source-sources.ui-plagCheck-source:hover .plagCheckSource-web-cache-icon {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -1055px -1053px;
height: 15px;
width: 60px; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-sources:hover {
color: #fff;
background-color: #a13169; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-sources:hover .plagCheckSource-web-cache-icon {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -1055px -1053px;
height: 15px;
width: 60px; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-quSources.active, .ui-plagCheck-source-enabled.ui-plagCheck-source-quSources.ui-plagCheck-source:hover {
background: #639ec3;
color: #fff; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-quSources.active .ui-plagCheck-source-a, .ui-plagCheck-source-enabled.ui-plagCheck-source-quSources.ui-plagCheck-source:hover .ui-plagCheck-source-a {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -2995px -3158px;
height: 23px;
width: 16px; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-quSources:hover {
color: #fff;
background-color: #639ec3; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-reSources.active, .ui-plagCheck-source-enabled.ui-plagCheck-source-reSources.ui-plagCheck-source:hover {
background: #289870;
color: #fff; }
.ui-plagCheck-source-enabled.ui-plagCheck-source-reSources:hover {
color: #fff;
background-color: #289870; }
.ui-plagCheck-source-checkbox {
outline: none;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-color: transparent;
border-radius: 2px;
cursor: pointer;
height: 19px;
min-width: 19px;
position: relative;
margin: 0;
margin-right: 10px;
overflow: hidden;
border: 2px solid #d0d0d0; }
.ui-plagCheck-source-checkbox:checked {
border: 2px solid transparent;
background: #dfdfdf; }
.ui-plagCheck-source-checkbox:hover {
cursor: pointer; }
.ui-plagCheck-source-title {
display: flex;
align-items: center;
width: 100%;
max-width: 65%; }
.ui-plagCheck-source-a {
display: block;
margin-left: 6px;
flex-basis: 8.333%;
max-width: 8.333%;
cursor: pointer; }
.ui-plagCheck-source-a-link {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -4113px -3962px;
height: 18px;
width: 18px;
opacity: 0.8; }
.ui-plagCheck-source-a-link:hover {
opacity: 1; }
.ui-plagCheck-source-external-link {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -2959px -3122px;
height: 18px;
width: 18px;
opacity: 0.8; }
.ui-plagCheck-source-external-link:hover {
opacity: 1; }
.ui-plagCheck-source-percent {
width: 100%;
max-width: 16.667%;
font-size: 12px;
font-weight: 600; }
html body .ui-plagCheck-source-name {
box-sizing: border-box;
font-size: 14px;
font-weight: 400;
margin: 0 5px 0 0;
overflow: hidden;
padding-right: 4px;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%; }
html body .ui-plagCheck-source-name:hover {
cursor: pointer;
color: inherit; }
.ui-plagCheck-source-links {
display: flex;
flex-flow: row nowrap;
width: 44px;
justify-content: flex-end;
margin-left: auto; }
.ui-plagCheck-source-options {
display: flex;
flex-flow: row nowrap;
padding: 0 4px; }
.plagCheckSource-web-cache-icon {
background: url(sprite-d4601b0b6de55a813269678618bcc950.svg?d4601b0b6de55a813269678618bcc950) no-repeat;
background-position: -995px -1038px;
height: 15px;
width: 60px;
min-width: 65px;
margin-right: 5px;
margin-left: -5px; }
.checkIcon:before, html body .RootLayout .CheckBox__input:before,
.checkIcon:after,
html body .RootLayout .CheckBox__input:after {
content: "";
height: 7px;
opacity: 0;
position: absolute;
top: 2px;
left: 1px;
transform-origin: center;
transform: rotate(-45deg);
width: 14px; }
.checkIcon:before, html body .RootLayout .CheckBox__input:before {
transition: 0s ease opacity; }
.checkIcon:after,
html body .RootLayout .CheckBox__input:after {
top: 0px;
transform: rotate(-45deg) scale(0.9); }
.checkIcon-checked:before, html body .RootLayout .CheckBox__input:checked:before {
transition: .3s ease opacity;
opacity: 1; }
.checkIcon-checked:after, html body .RootLayout .CheckBox__input:checked:after {
opacity: 1; }
html body .RootLayout .CheckBox__input {
position: relative;
-webkit-appearance: none;
background: transparent;
border: 1px solid #d0d0d0;
border-radius: 2px;
cursor: pointer;
height: 19px;
width: 19px;
transition: .2s ease-in;
outline: none;
overflow: hidden; }
html body .RootLayout .CheckBox__input:before {
top: 2px; }
html body .RootLayout .CheckBox__input:after {
top: 0px; }
html body .RootLayout .Checkbox-error {
border-color: #bf3c26;
box-shadow: 0px 0px 10px #bf3c26;
animation-name: errorZoom;
animation-duration: 0.3s; }
html body .RootLayout .CheckBox__input:before,
html body .RootLayout .CheckBox__input:after {
left: 1px; }
html body .RootLayout .CheckBox__input:checked {
border: 2px solid transparent; }
html body .RootLayout .CheckBox-document:checked {
background: #306a8f;
border: 2px solid #306a8f; }
html body .RootLayout .CheckBox-document:checked:before {
background: white; }
html body .RootLayout .CheckBox-document:checked:after {
background: #306a8f; }
html body .RootLayout .CheckBox-report:checked {
background: #dfdfdf; }
html body .RootLayout .CheckBox-report:checked:before {
background: #306a8f; }
html body .RootLayout .CheckBox-report:checked:after {
background: #dfdfdf; }
@keyframes errorZoom {
0% {
transform: scale(1); }
50% {
transform: scale(1.25); }
100% {
transform: scale(1); } }

1
assets/viewer/report-viewer.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id=ар_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="8px" height="4px"
viewBox="0 0 8 4" enable-background="new 0 0 8 4" xml:space="preserve">
<metadata>
<sfw xmlns="&ns_sfw;">
<slices></slices>
<sliceSourceBounds width="8" height="4" x="-1" y="-0.5" bottomLeftOrigin="true"></sliceSourceBounds>
</sfw>
</metadata>
<rect fill="#A13169" width="1" height="1"/>
<rect x="1" opacity="0.2" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="2" y="1" opacity="0.2" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="4" y="1" opacity="0.2" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="5" opacity="0.2" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="6" y="1" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="5" y="2" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="3" y="3" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="2" y="3" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="4" y="3" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="1" y="2" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect y="1" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="1" y="1" fill="#A13169" width="1" height="1"/>
<rect x="2" y="2" fill="#A13169" width="1" height="1"/>
<rect x="4" y="2" fill="#A13169" width="1" height="1"/>
<rect x="3" y="2" fill="#A13169" width="1" height="1"/>
<rect x="5" y="1" fill="#A13169" width="1" height="1"/>
<rect x="6" fill="#A13169" width="1" height="1"/>
<rect x="7" y="1" opacity="0.5" fill="#A13169" enable-background="new " width="1" height="1"/>
<rect x="7" fill="#A13169" width="1" height="1"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id=ар_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="8px" height="4px"
viewBox="0 0 8 4" enable-background="new 0 0 8 4" xml:space="preserve">
<metadata>
<sfw xmlns="&ns_sfw;">
<slices></slices>
<sliceSourceBounds width="8" height="4" x="-1" y="-0.5" bottomLeftOrigin="true"></sliceSourceBounds>
</sfw>
</metadata>
<rect fill="#639EC3" width="1" height="1"/>
<rect x="1" opacity="0.2" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="2" y="1" opacity="0.2" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="4" y="1" opacity="0.2" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="5" opacity="0.2" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="6" y="1" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="5" y="2" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="3" y="3" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="2" y="3" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="4" y="3" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="1" y="2" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect y="1" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="1" y="1" fill="#639EC3" width="1" height="1"/>
<rect x="2" y="2" fill="#639EC3" width="1" height="1"/>
<rect x="4" y="2" fill="#639EC3" width="1" height="1"/>
<rect x="3" y="2" fill="#639EC3" width="1" height="1"/>
<rect x="5" y="1" fill="#639EC3" width="1" height="1"/>
<rect x="6" fill="#639EC3" width="1" height="1"/>
<rect x="7" y="1" opacity="0.5" fill="#639EC3" enable-background="new " width="1" height="1"/>
<rect x="7" fill="#639EC3" width="1" height="1"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id=ар_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="8px" height="4px"
viewBox="0 0 8 4" enable-background="new 0 0 8 4" xml:space="preserve">
<metadata>
<sfw xmlns="&ns_sfw;">
<slices></slices>
<sliceSourceBounds width="8" height="4" x="-1" y="-0.5" bottomLeftOrigin="true"></sliceSourceBounds>
</sfw>
</metadata>
<rect fill="#289870" width="1" height="1"/>
<rect x="1" opacity="0.2" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="2" y="1" opacity="0.2" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="4" y="1" opacity="0.2" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="5" opacity="0.2" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="6" y="1" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="5" y="2" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="3" y="3" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="2" y="3" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="4" y="3" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="1" y="2" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect y="1" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="1" y="1" fill="#289870" width="1" height="1"/>
<rect x="2" y="2" fill="#289870" width="1" height="1"/>
<rect x="4" y="2" fill="#289870" width="1" height="1"/>
<rect x="3" y="2" fill="#289870" width="1" height="1"/>
<rect x="5" y="1" fill="#289870" width="1" height="1"/>
<rect x="6" fill="#289870" width="1" height="1"/>
<rect x="7" y="1" opacity="0.5" fill="#289870" enable-background="new " width="1" height="1"/>
<rect x="7" fill="#289870" width="1" height="1"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

179
component/ApiProvider.php Normal file
View File

@ -0,0 +1,179 @@
<?php
class ApiProvider
{
private $token;
/**
* @var string
*/
private $endpoint;
private $lastError;
/**
* @return mixed
*/
public function getLastError()
{
return $this->lastError;
}
/**
* @param mixed $lastError
*/
public function setLastError($lastError)
{
$this->lastError = $lastError;
}
public function __construct($token, $endpoint = 'https://plagiarismcheck.org')
{
$this->token = $token;
$this->endpoint = $endpoint;
}
private function generateParameters($data)
{
$peirs = [];
foreach ($data as $name => $value) {
$peirs[] = urlencode($name) . '=' . urlencode($value);
}
return implode('&', $peirs);
}
public function sendText($content, $mime, $filename)
{
$boundary = sprintf('PLAGCHECKBOUNDARY-%s', uniqid(time()));
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->endpoint . '/api/v1/text',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-API-TOKEN: ' . $this->token,
'Content-Type: multipart/form-data; boundary=' . $boundary
],
CURLOPT_POSTFIELDS => $this->getBody($boundary, $content, $mime, $filename),
]);
$response = curl_exec($ch);
curl_close($ch);
$id = null;
if ($json = json_decode($response)) {
if (isset($json->message)) {
$this->setLastError($json->message);
return null;
}
if (isset($json->success) && $json->success) {
$id = $json->data->text->id;
}
}
return $id;
}
private function getPart($name, $value, $boundary)
{
$eol = "\r\n";
$part = '--' . $boundary . $eol;
$part .= 'Content-Disposition: form-data; name="' . $name . '"' . $eol . $eol;
$part .= $value . $eol;
return $part;
}
private function getFilePart($name, $value, $mime, $filename, $boundary)
{
$eol = "\r\n";
$part = '--' . $boundary . $eol;
$part .= 'Content-Disposition: form-data; name="' . $name . '"; filename="'.$filename.'";' . $eol;
$part .= 'Content-Type: ' . $mime . $eol;
$part .= 'Content-Length: ' . strlen($value) . $eol . $eol;
$part .= $value . $eol;
return $part;
}
private function getBody($boundary, $content, $mime, $filename)
{
$eol = "\r\n";
$body = '';
$body .= $this->getPart('language', 'en', $boundary);
$body .= $this->getFilePart('text', $content, $mime, $filename, $boundary);
$body .= '--' . $boundary . '--' . $eol;
return $body;
}
public function checkText($textId)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->endpoint . '/api/v1/text/' . $textId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => false,
CURLOPT_HTTPHEADER => [
'X-API-TOKEN: ' . $this->token,
'Content-Type: application/x-www-form-urlencoded'
],
]);
$response = curl_exec($ch);
$id = null;
if ($json = json_decode($response)) {
if (5 == $json->data->state) {
$id = $json->data->report->id;
}
}
curl_close($ch);
return $id;
}
public function getReport($id)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->endpoint . '/api/v1/text/report/' . $id,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => false,
CURLOPT_HTTPHEADER => [
'X-API-TOKEN: ' . $this->token,
],
]);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
public function isSupportedMime($mime)
{
return in_array($mime, [
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/rtf',
'application/vnd.oasis.opendocument.text',
'text/plain',
'application/pdf',
], true);
}
}

View File

@ -0,0 +1,19 @@
<?php
class UrlGenerator
{
public function getCheckUrl($cmid, $fileid)
{
return new moodle_url(sprintf(
'/plagiarism/pchkorg/page/report.php?cmid=%s&file=%s',
intval($cmid),
intval($fileid)
)
);
}
public function getStatusUrl()
{
return new moodle_url('/plagiarism/pchkorg/page/status.php');
}
}

204
db/access.php Normal file
View File

@ -0,0 +1,204 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.');
}
$capabilities = [
'plagiarism/pchkorg:enable' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:viewsimilarity' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:viewreport' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:vieweditreport' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:resetfile' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
],
],
'plagiarism/pchkorg:checkfile' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
],
],
'plagiarism/pchkorg:changeenableunichecksetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changecheckalreadysubmittedassignmentsetting' => [
'riskbitmask' => RISK_CONFIG | RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changeaddsubmissiontolibrarysetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changesourcesforcomparisonsetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changesensitivitypercentagesetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changewordsensitivitysetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changeexcludecitationssetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changeshowstudentscoresetting' => [
'riskbitmask' => RISK_CONFIG | RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changeshowstudentreportsetting' => [
'riskbitmask' => RISK_CONFIG | RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changemaxsupportedarchivefilescountsetting' => [
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
],
'plagiarism/pchkorg:changesentstudentreportsetting' => [
'riskbitmask' => RISK_CONFIG | RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW
],
]
];

3
db/events.php Normal file
View File

@ -0,0 +1,3 @@
<?php
$observers = array();

30
db/install.php Normal file
View File

@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
function xmldb_plagiarism_pchkorg_install() {
global $DB;
$installed = $DB->get_record('config_plugins', ['plugin' => 'plagiarism_pchkorg', 'name' => 'version']);
return $installed ? true : false;
}
function xmldb_plagiarism_upgrade()
{
return true;
}

53
db/install.xml Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="plagiarism/pchkorg/db" VERSION="2018062000"
COMMENT="XMLDB file for Moodle plagiarism/pchkorg plugin"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="plagiarism_pchkorg_files" COMMENT="info about submitted files"
NEXT="plagiarism_pchkorg_config">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true"
NEXT="cm"/>
<FIELD NAME="cm" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false"
PREVIOUS="id" NEXT="userid"/>
<FIELD NAME="fileid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false"
PREVIOUS="cm" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false"
PREVIOUS="fileid" NEXT="externalid"/>
<FIELD NAME="state" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"
PREVIOUS="userid" NEXT="similarityscore"/>
<FIELD NAME="score" TYPE="float" NOTNULL="true" DEFAULT="0" SEQUENCE="false"
PREVIOUS="state" NEXT="attemptscount"/>
<FIELD NAME="created_at" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false"
PREVIOUS="score"/>
<FIELD NAME="textid" TYPE="int" LENGTH="11" NOTNULL="false" UNSIGNED="true" SEQUENCE="false"
PREVIOUS="score"/>
<FIELD NAME="reportid" TYPE="int" LENGTH="11" NOTNULL="false" UNSIGNED="true" SEQUENCE="false"
PREVIOUS="text_id"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="cm"/>
<KEY NAME="cm" TYPE="foreign" FIELDS="cm" REFTABLE="course_modules" REFFIELDS="id" PREVIOUS="primary"
NEXT="userid"/>
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="cm"/>
</KEYS>
</TABLE>
<TABLE NAME="plagiarism_pchkorg_config" COMMENT="config for modules"
PREVIOUS="plagiarism_pchkorg_files">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="cm"/>
<FIELD NAME="cm" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false"
PREVIOUS="id" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" UNSIGNED="true" SEQUENCE="false"
PREVIOUS="cm" NEXT="value"/>
<FIELD NAME="value" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="name"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="cm"/>
<KEY NAME="cm" TYPE="foreign" FIELDS="cm" REFTABLE="course_modules" REFFIELDS="id" PREVIOUS="primary"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>

36
form/plagiarism_form.php Normal file
View File

@ -0,0 +1,36 @@
<?php
class plagiarism_setup_form extends moodleform {
/// Define the form
function definition () {
global $CFG;
$mform = &$this->_form;
$mform->addElement(
'select',
$setting = 'pchkorg_use',
self::trans('pchkorg_use'),
[get_string('no'), get_string('yes')]
);
$mform->addHelpButton('pchkorg_use', 'pchkorg_use', 'plagiarism_pchkorg');
if (!isset($mform->exportValues()[$setting]) || is_null($mform->exportValues()[$setting])) {
$mform->setDefault($setting, false);
}
$mform->addElement('password', 'pchkorg_token', self::trans('pchkorg_token'));
$mform->addHelpButton('pchkorg_token', 'pchkorg_token', 'plagiarism_pchkorg');
$mform->addRule('pchkorg_token', null, 'required', null, 'client');
$mform->setType('pchkorg_token', PARAM_TEXT);
$this->add_action_buttons(true);
}
public static function trans($message, $param = null)
{
return get_string($message, 'plagiarism_pchkorg', $param);
}
}

29
form/send_text_form.php Normal file
View File

@ -0,0 +1,29 @@
<?php
//moodleform is defined in formslib.php
require_once("$CFG->libdir/formslib.php");
class send_text_form extends moodleform
{
//Add elements to form
public function definition()
{
global $CFG;
$mform = $this->_form; // Don't forget the underscore!
$mform->addElement('hidden', 'fileid', '');
$mform->setType('fileid', PARAM_INT);
$mform->addElement('hidden', 'cmid', '');
$mform->setType('cmid', PARAM_INT);
$this->add_action_buttons(false, get_string('pchkorg_submit', 'plagiarism_pchkorg'));
}
//Custom validation should be added here
function validation($data, $files)
{
return array();
}
}

View File

@ -0,0 +1,37 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package plagiarism_pchkorg
* @category plagiarism
* @author 2018, Denys Hirnyk <den.girnyk@gmail.com>
* @copyright PlagiarismCheck.org, https://plagiarismcheck.org/
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$string['pchkorg'] = 'PlagiarismCheck.org plugin';
$string['pluginname'] = 'PlagiarismCheck.org plugin';
$string['pchkorg_use'] = 'Enable plugin';
$string['pchkorg_use_help'] = 'Enable or Disable PlagiarismCheck.org plugin';
$string['pchkorg_module_use'] = 'Enable plugin in this module';
$string['pchkorg_module_use_help'] = 'Enable plugin in this module';
$string['pchkorg_token'] = 'API Token';
$string['pchkorg_token_help'] = 'You can receive your token by contact us';
$string['pchkorg_description'] = 'You can receive your token by contact us';
$string['pchkorg_submit'] = 'Submit';
$string['savedconfigsuccess'] = 'Settings had been changed';

204
lib.php Normal file
View File

@ -0,0 +1,204 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot.'/plagiarism/lib.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/accesslib.php');
require_once(__DIR__.'/model/ConfigModel.php');
require_once(__DIR__.'/model/FileModel.php');
require_once(__DIR__.'/component/UrlGenerator.php');
require_once(__DIR__.'/component/ApiProvider.php');
class plagiarism_plugin_pchkorg extends plagiarism_plugin
{
/**
* hook to allow plagiarism specific information to be displayed beside a submission
* @param array $linkarraycontains all relevant information for the plugin to generate a link
* @return string
*
*/
public function get_links($linkarray)
{
global $DB;
$fileModel = new FileModel($DB);
$configModel = new ConfigModel($DB);
$urlGenerator = new UrlGenerator();
$apiProvider = new ApiProvider($configModel->getSystemConfig('pchkorg_token'));
$config = $configModel->getSystemConfig('pchkorg_use');
if ('1' !== $config) {
return '';
}
//$userid, $file, $cmid, $course, $module
$cmid = $linkarray['cmid'];
$userid = $linkarray['userid'];
/** @var stored_file $file */
$file = $linkarray['file'];
if (!$configModel->isEnabledForModule($cmid)) {
return '';
}
if (!$apiProvider->isSupportedMime($file->get_mimetype())) {
return '';
}
$fileRecord = $fileModel->findFileByModuleAndFile($cmid, $file->get_id());
$checkUrl = $urlGenerator->getCheckUrl($cmid, $file->get_id());
if ($fileRecord) {
$label = sprintf('%.2f', $fileRecord->score) . '%';
} else {
$label = 'Check for plagiarism';
}
return sprintf(' <a href="%s">( %s )</a> ', $checkUrl->__toString(), $label);
}
/* hook to save plagiarism specific settings on a module settings page
* @param object $data - data from an mform submission.
*/
public function save_form_elements($data)
{
global $DB;
$configModel = new ConfigModel($DB);
$config = $configModel->getSystemConfig('pchkorg_use');
if ('1' != $config) {
return;
}
if (!isset($data->pchkorg_module_use)) {
return;
}
$records = $DB->get_records('plagiarism_pchkorg_config', array(
'cm' => $data->coursemodule
));
if (empty($records)) {
$insert = new \stdClass();
$insert->cm = $data->coursemodule;
$insert->name = 'pchkorg_module_use';
$insert->value = $data->pchkorg_module_use;
$DB->insert_record('plagiarism_pchkorg_config', $insert);
} else {
foreach ($records as $record) {
$record->value = $data->{$record->name};
$DB->update_record('plagiarism_pchkorg_config', $record);
}
}
}
/**
* hook to add plagiarism specific settings to a module settings page
* @param object $mform - Moodle form
* @param object $context - current context
* @param object $modulename
*/
public function get_form_elements_module($mform, $context, $modulename = '')
{
global $CFG, $DB;
$configModel = new ConfigModel($DB);
$config = $configModel->getSystemConfig('pchkorg_use');
if ('1' == $config) {
$defaultcmid = null;
$cm = optional_param('update', $defaultcmid, PARAM_INT);
if (null !== $cm) {
$records = $DB->get_records('plagiarism_pchkorg_config', array(
'cm' => $cm,
));
if (!empty($records)) {
foreach ($records as $record) {
$mform->setDefault($record->name, $record->value);
}
}
}
$mform->addElement('header', 'plagiarism_pchkorg', self::trans('pluginname'));
$mform->addElement(
'select',
$setting = 'pchkorg_module_use',
self::trans('pchkorg_module_use'),
[get_string('no'), get_string('yes')]
);
$mform->addHelpButton('pchkorg_module_use', 'pchkorg_module_use', 'plagiarism_pchkorg');
if (!isset($mform->exportValues()[$setting]) || is_null($mform->exportValues()[$setting])) {
$mform->setDefault($setting, '1');
}
}
}
/**
* hook to allow a disclosure to be printed notifying users what will happen with their submission
* @param int $cmid - course module id
* @return string
*/
public function print_disclosure($cmid)
{
global $OUTPUT, $DB;
$configModer = new ConfigModel($DB);
echo $OUTPUT->box_start('generalbox boxaligncenter', 'intro');
$formatoptions = new stdClass;
$formatoptions->noclean = true;
$text = $configModer->getSystemConfig('plagiarism_pchkorg');
echo format_text($text, FORMAT_MOODLE, $formatoptions);
echo $OUTPUT->box_end();
}
public static function trans($message, $param = null)
{
return get_string($message, 'plagiarism_pchkorg', $param);
}
/**
* hook to allow status of submitted files to be updated - called on grading/report pages.
*
* @param object $course - full Course object
* @param object $cm - full cm object
*/
public function update_status($course, $cm)
{
//called at top of submissions/grading pages - allows printing of admin style links or updating status
}
/**
* called by admin/cron.php
*
*/
public function cron()
{
//do any scheduled task stuff
}
}

77
model/ConfigModel.php Normal file
View File

@ -0,0 +1,77 @@
<?php
class ConfigModel
{
private $db;
public function __construct($DB)
{
$this->db = $DB;
}
public function fetchByModule($module)
{
return $this->db->get_records('plagiarism_pchkorg_config', array(
'cm' => $module,
));
}
public function isEnabledForModule($module)
{
$configs = $this->fetchByModule($module);
$enabled = false; // disabled by default
foreach ($configs as $record) {
switch ($record->name) {
case 'pchkorg_module_use':
$enabled = '1' == $record->value;
break;
default:
break;
}
}
return $enabled;
}
public function setSystemConfig($name, $value)
{
$this->db->delete_records('plagiarism_pchkorg_config', [
'cm' => 0,
'name' => $name,
]);
$record = new \stdClass();
$record->cn = 0;
$record->name = $name;
$record->value = $value;
$this->db->insert_record('plagiarism_pchkorg_config', $record);
}
public function getSystemConfig($name)
{
$records = $this->db->get_records('plagiarism_pchkorg_config', array(
'cm' => 0,
'name' => $name,
));
foreach ($records as $record) {
return $record->value;
}
return null;
}
public function getAllSystemConfig()
{
$records = $this->db->get_records('plagiarism_pchkorg_config', array(
'cm' => 0,
));
$map = [];
foreach ($records as $record) {
$map[$record->name] = $record->value;
}
return $map;
}
}

33
model/FileModel.php Normal file
View File

@ -0,0 +1,33 @@
<?php
class FileModel
{
private $db;
const STATE_SENT = 1;
const STATE_CHECKED = 2;
public function __construct($DB)
{
$this->db = $DB;
}
public function findFileByModuleAndFile($module, $fileid)
{
$where = new \stdClass();
$where->cm = $module;
$where->fileid = $fileid;
return $this->db->get_record('plagiarism_pchkorg_files', (array)$where);
}
public function create($fileRecord)
{
return $this->db->insert_record('plagiarism_pchkorg_files', $fileRecord);
}
public function update($fileRecord)
{
return $this->db->update_record('plagiarism_pchkorg_files', $fileRecord);
}
}

58
page/check.php Normal file
View File

@ -0,0 +1,58 @@
<?php
require_once(__DIR__ . '/../../../config.php');
require_once(__DIR__ . '/../lib.php');
require_once(__DIR__ . '/../form/send_text_form.php');
require_once(__DIR__ . '/../component/UrlGenerator.php');
require_once(__DIR__ . '/../component/ApiProvider.php');
global $PAGE, $CFG, $OUTPUT, $DB, $USER;
require_login();
$fileModel = new FileModel($DB);
$configModel = new ConfigModel($DB);
$urlGenerator = new UrlGenerator();
$apiProvider = new ApiProvider($configModel->getSystemConfig('pchkorg_token'));
$cmid = (int)required_param('cmid', PARAM_INT); // Course Module ID
$fileid = (int)required_param('file', PARAM_INT); // plagiarism file id.
$cm = get_coursemodule_from_id('', $cmid);
require_login($cm->course, true, $cm);
header('Content-Type: application/json');
// Prevent JS caching
$CFG->cachejs = false;
$PAGE->set_url($urlGenerator->getStatusUrl());
$fileRecord = $fileModel->findFileByModuleAndFile($cmid, $fileid);
if (!$fileRecord) {
echo json_encode([
'success' => false,
'message' => '404 can not find text'
]);
}
$reportid = $apiProvider->checkText($fileRecord->textid);
if ($checked = (null !== $reportid)) {
$report = $apiProvider->getReport($fileRecord->textid);
$json = json_decode($report);
$score = 0;
if (isset($json->data)
&& isset($json->data->report)
&& isset($json->data->report->percent)
) {
$score = $json->data->report->percent;
}
$fileRecord->reportid = $reportid;
$fileRecord->score = $score;
$fileModel->update($fileRecord);
}
echo json_encode([
'success' => true,
'checked' => $checked,
'location' =>sprintf(
'/plagiarism/pchkorg/page/report.php?cmid=%s&file=%s',
intval($cmid),
intval($fileid)
)
]);

118
page/report.php Normal file
View File

@ -0,0 +1,118 @@
<?php
require_once(__DIR__ . '/../../../config.php');
require_once(__DIR__ . '/../lib.php');
require_once(__DIR__ . '/../form/send_text_form.php');
require_once(__DIR__ . '/../component/UrlGenerator.php');
require_once(__DIR__ . '/../component/ApiProvider.php');
global $PAGE, $CFG, $OUTPUT, $DB, $USER;
require_login();
$fileModel = new FileModel($DB);
$configModel = new ConfigModel($DB);
$urlGenerator = new UrlGenerator();
$apiProvider = new ApiProvider($configModel->getSystemConfig('pchkorg_token'));
$cmid = (int)required_param('cmid', PARAM_INT); // Course Module ID
$fileid = (int)required_param('file', PARAM_INT); // plagiarism file id.
$cm = get_coursemodule_from_id('', $cmid);
require_login($cm->course, true, $cm);
$fs = get_file_storage();
$form = new send_text_form($currentUrl = $urlGenerator->getCheckUrl($cmid, $fileid));
// Prevent JS caching
$CFG->cachejs = false;
$PAGE->set_url($currentUrl);
$PAGE->set_pagelayout('report');
$PAGE->set_title('My modules page title');
$PAGE->set_heading('My modules page heading');
if ('POST' === $_SERVER['REQUEST_METHOD']) {// form submission
$data = $form->get_data();
$cmid = (int)$data->cmid;
$fileid = (int)$data->fileid;
$file = $fs->get_file_by_id($fileid);
if (!$file) {
//file not found
die('404 not exists');
}
$textid = $apiProvider->sendText(
$file->get_content(),
$file->get_mimetype(),
$file->get_filename()
);
$message = '';
if (null !== $textid) {
$fileRecord = new \stdClass();
$fileRecord->fileid = $fileid;
$fileRecord->cm = $cmid;
$fileRecord->userid = $USER->id;
$fileRecord->textid = $textid;
$fileRecord->state = FileModel::STATE_SENT;
$fileRecord->created_at = time();
$fileModel->create($fileRecord);
} else {
if ('Invalid token' === $apiProvider->getLastError()) {
$configModel->setSystemConfig('pchkorg_use', '0');
}
$message = $apiProvider->getLastError();
}
redirect($urlGenerator->getCheckUrl($cmid, $fileid), $message);
exit;
}
$file = $fs->get_file_by_id($fileid);
if (!$file) {
//file not found
die('404 not exists');
}
$fileRecord = $fileModel->findFileByModuleAndFile($cmid, $fileid);
if (!$fileRecord) {
$content = $file->get_content();
$mime = $file->get_mimetype();
if ($isSupported = $apiProvider->isSupportedMime($file->get_mimetype())) {
if ('plain/text' === $mime || 'text/plain' === $mime) {
$content = $content = $file->get_content();
} else {
$content = $file->get_filename();
}
$default = ['fileid' => $fileid, 'cmid' => $cmid];
$form->set_data($default);
}
require '../view/send_text.php';
} elseif (null !== $fileRecord->reportid) {
$report = $apiProvider->getReport($fileRecord->textid);
$json = json_decode($report);
$error = '';
if (isset($json->message)) {
$error = $json->message;
} else {
$data = json_encode($json);
}
require '../view/report.php';
} elseif (null !== $fileRecord->textid) {
$PAGE->requires->js_call_amd('plagiarism_pchkorg/main', 'checkReport');
require '../view/check_report.php';
}

75
settings.php Normal file
View File

@ -0,0 +1,75 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* pl * plagiarism.php - allows the admin to configure plagiarism stuff
*
* @package plagiarism_pchkorg
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(dirname(__FILE__)) . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/plagiarismlib.php');
require_once($CFG->dirroot.'/lib/formslib.php');
require_once($CFG->dirroot . '/plagiarism/pchkorg/lib.php');
require_once($CFG->dirroot . '/plagiarism/pchkorg/form/plagiarism_form.php');
require_once __DIR__ . '/lib.php';
global $DB;
$configModel = new ConfigModel($DB);
require_login();
admin_externalpage_setup('plagiarismpchkorg');
$context = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$mform = new plagiarism_setup_form();
$plagiarismplugin = new plagiarism_plugin_pchkorg();
if ($mform->is_cancelled()) {
redirect('');
}
echo $OUTPUT->header();
if (($data = $mform->get_data()) && confirm_sesskey()) {
if (!isset($data->pchkorg_use)) {
$data->pchkorg_use = 0;
}
foreach ($data as $field => $value) {
if (strpos($field, 'pchkorg') === 0) {
set_config($field, $value, 'plagiarism');
$configModel->setSystemConfig($field, $value);
}
}
$OUTPUT->notification(get_string('savedconfigsuccess', 'plagiarism_pchkorg'), 'notifysuccess');
}
$configModel = new ConfigModel($DB);
$plagiarismsettings = $configModel->getAllSystemConfig();
$mform->set_data($plagiarismsettings);
echo $OUTPUT->box_start('generalbox boxaligncenter', 'intro');
$mform->display();
echo $OUTPUT->box_end();
echo $OUTPUT->footer();

37
version.php Normal file
View File

@ -0,0 +1,37 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package plagiarism_pchkorg
* @category plagiarism
* @copyright PlagiarismCheck.org, https://plagiarismcheck.org/
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if (!isset($plugin)) {
$plugin = new stdClass();
}
$plugin->version = 2018103102;
$plugin->requires = 2017051501; // Requires Moodle 3.3 .
$plugin->release = 'v1.18';
$plugin->maturity = MATURITY_STABLE;
$plugin->component = 'plagiarism_pchkorg';
$plugin->dependencies = [
'mod_assign' => ANY_VERSION,
];

25
view/check_report.php Normal file
View File

@ -0,0 +1,25 @@
<?php
echo $OUTPUT->header();
?>
<style>
.loader {
border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid #3498db; /* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<div>
<div id="plagcheck-loader" data-cmid="<?php echo intval($cmid)?>" data-file="<?php echo intval($fileid)?>" class="loader"></div>
</div>
<?php
echo $OUTPUT->footer();

37
view/report.php Normal file
View File

@ -0,0 +1,37 @@
<?php
$PAGE->requires->css('/plagiarism/pchkorg/assets/viewer/report-viewer.min.css');
echo $OUTPUT->header();
?>
<div class="pCheck-container"></div>
<div id="report-root"></div>
<?php
if (empty($error)) {
?>
<script src="/plagiarism/pchkorg/assets/viewer/report-viewer.min.js"></script>
<script>
(function(window, document, ReportViewer, localData) {
var element = document.getElementById('report-root');
var widget = ReportViewer.create();
widget.init({
element: element,
localData: localData
});
})(window, window.document, window.ReportViewer, <?php echo empty($data) ? '{}': $data ?>);
</script>
<?
} elseif (isset($error)) {
?>
<h2>Error: <?php echo $error ?></h2>
<?
}
?>
<?php
echo $OUTPUT->footer();

35
view/send_text.php Normal file
View File

@ -0,0 +1,35 @@
<?php
echo $OUTPUT->header();
?>
<style>
.plagiarism-preview-content {
width: 800px;
height: 400px;
overflow-y: scroll;
}
.plagiarism-preview-content-inner {
/*white-space: pre;*/
}
</style>
<br/>
<div class="plagiarism-preview-content">
<div class="plagiarism-preview-content-inner">
<?php echo nl2br(htmlspecialchars($content, ENT_COMPAT | ENT_HTML401, $encoding = 'UTF-8')) ?>
</div>
</div>
<br/>
<div>
<?php
if ($isSupported) {
echo $form->display();
} else {
echo 'file not supported';
}
?>
</div>
<?php
echo $OUTPUT->footer();