You have successfully submitted the file %s to the assignment %s in the class %s on %s. Your submission id is %s. Your full digital receipt can be viewed and printed from the assignment inbox or from the print/download button in the document viewer.
You have successfully submitted the file %s to the assignment %s: %s in the class %s on %s. Your submission id is %s. Your full digital receipt can be viewed and printed from the assignment inbox or from the print/download button in the document viewer.
Thank you for using Turnitin,
The Turnitin Team");
80 |
81 | $this->assertEquals(sprintf($messagetext, $message['firstname'], $message['lastname'],
82 | $message['submission_title'], $message['assignment_name'], $message['assignment_part'],
83 | $message['course_fullname'], $date, $message['submission_id']), $response);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/css/colorbox.css:
--------------------------------------------------------------------------------
1 | /*
2 | ColorBox Core Style:
3 | The following CSS is consistent between example themes and should not be altered.
4 | */
5 | #colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
6 | #cboxOverlay{position:fixed; width:100%; height:100%;}
7 | #cboxMiddleLeft, #cboxBottomLeft{clear:left;}
8 | #cboxContent{position:relative;}
9 | #cboxLoadedContent{overflow:auto;}
10 | #cboxTitle{margin:0;}
11 | #cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
12 | #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
13 | .cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
14 | .cboxIframe{width:100%; height:100%; display:block; border:0;}
15 | #colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
16 |
17 | /*
18 | User Style:
19 | Change the following styles to modify the appearance of ColorBox. They are
20 | ordered & tabbed in a way that represents the nesting of the generated HTML.
21 | */
22 | #cboxOverlay{background:#000;}
23 | #colorbox{}
24 | #cboxContent{margin-top:32px; overflow:visible;}
25 | .cboxIframe{background:none;}/*#FFF*/
26 | #cboxError{padding:50px; border:1px solid #ccc;}
27 | #cboxLoadedContent{background:none; padding:1px;}
28 | #cboxLoadingGraphic{background:url(../pix/colorbox/loading.gif) no-repeat center center;}
29 | #cboxLoadingOverlay{background:none;}
30 | #cboxTitle{position:absolute; top:-22px; left:0; color:#000; display:none !important;}
31 | #cboxCurrent{position:absolute; top:-22px; right:205px; text-indent:-9999px;}
32 | #cboxClose{text-indent:-9999px; width:20px; height:20px; position:absolute; top:-20px; background:url(../pix/colorbox/controls.png) no-repeat 0 0;}
33 | #cboxClose{background-position:-50px 0px; right:0;}
34 | #cboxClose:hover{background-position:-50px -25px;}
35 |
36 |
37 | iframe html{background:none;}
38 |
39 | /* Messages Inbox, Migration, Upload, Rubric and Quickmark boxes */
40 | .messages #cboxLoadedContent, .messages .cboxIframe, .rubric_manager #cboxLoadedContent, .rubric_manager .cboxIframe, .quickmark_manager #cboxLoadedContent, .quickmark_manager .cboxIframe,
41 | .peermark_reviews #cboxLoadedContent, .peermark_reviews .cboxIframe, .peermark_manager #cboxLoadedContent, .peermark_manager .cboxIframe { background:none; }
42 |
43 | .migration #cboxLoadedContent, .migration #cboxIframe, .downloadpdf_window #cboxLoadedContent, .downloadpdf_window .cboxIframe,
44 | .gmpdfzip_window #cboxLoadedContent, .gmpdfzip_window .cboxIframe, .course_creation #cboxLoadedContent, .course_creation #cboxIframe {
45 | background: #FFF;
46 | }
47 |
48 | #cboxClose { text-indent:-36px; display:none; }
49 |
50 | .messages #cboxClose, .tii_unanonymise_reveal_form #cboxClose, .downloadpdf_window #cboxClose, .gmpdfzip_window #cboxClose, .rubric_manager #cboxClose,
51 | .rubric_view #cboxClose, .quickmark_manager #cboxClose, .peermark_manager #cboxClose, .peermark_reviews #cboxClose, .course_creation #cboxClose,
52 | .tii_unanonymise_reveal_form #cboxClose, .tii_unanonymise_reveal_form #cboxClose, .migration #cboxClose {
53 | display:none !important;
54 | }
55 |
56 | .upload #cboxClose {
57 | top: 2px;
58 | }
59 |
60 | .upload #cboxClose .closeText {
61 | position: relative;
62 | top: 2px;
63 | }
64 |
65 | .tii_unanonymise_reveal_form #cboxLoadedContent, .edit_end_date_form #cboxLoadedContent {
66 | height:100%;
67 | overflow: hidden !important;
68 | }
69 |
70 | #cboxOverlay{
71 | z-index:9997;
72 | }
73 |
74 | .loading_gif {
75 | padding:16px;
76 | margin:0 auto;
77 | position: absolute;
78 | top: 48%;
79 | left: 48%;
80 | background:url(../pix/colorbox/loading.gif) no-repeat center center #000;
81 | height: 32px;
82 | width: 32px;
83 | -moz-border-radius: 12px;
84 | -webkit-border-radius: 12px;
85 | -khtml-border-radius: 12px;
86 | border-radius: 12px;
87 | z-index:9998;
88 | }
89 |
90 | .tii_unanonymise_reveal_form #cboxClose, .edit_end_date_form #cboxClose {
91 | top: 4px;
92 | right:4px;
93 | }
94 |
95 | .edit_end_date_form #cboxLoadedContent .mform .fitem .fitemtitle {
96 | width: 25%;
97 | }
98 |
99 | .edit_end_date_form #cboxLoadedContent .mform .fitem .felement {
100 | width: 70%;
101 | }
102 |
103 | .edit_end_date_form #cboxLoadedContent .mform .fitem fieldset.felement {
104 | margin-left: 25%;
105 | }
--------------------------------------------------------------------------------
/TROUBLESHOOTING.md:
--------------------------------------------------------------------------------
1 | #Moodle Direct V2 Troubleshooting
2 |
3 | 1) You may need to ensure that within your designated moodledata directory; the turnitintooltwo subdirectory and the subsequent logs subdirectory have the correct permissions to be able to create directories and files.
4 |
5 | 2) You may need to ensure that the turnitintooltwo directory within your designated data directory and it's logs subdirectory have the correct permissions to be able to create directories and files.
6 |
7 | 3) Pop-ups will need to be enabled on the browser being used if access to the Turnitin Document Viewer is required.
8 |
9 | 4) There have been very isolated reports of the settings not showing for the Plagiarism plugin despite it being enabled, this is due to it not showing in Moodle cache. The solution is for an administrator to purge all caches and it should then appear.
10 |
11 | ##Required PHP Extensions
12 |
13 | In order for the module to work correctly you must enable the following PHP extensions:
14 |
15 | **cURL**
16 |
17 | >You must enable support for cURL in your php.ini file. To do this locate the following line in your php.ini file:
18 |
19 | >;extension=php_curl.dll
20 | >OR
21 | >;extension=php_curl.so
22 |
23 | >Remove the semi-colon at the start of the line to activate the php cURL extension. Once you have done this you will need to restart your web server service.
24 |
25 | >More information on cURL and more detailed instructions for installing it can be found here: http://uk3.php.net/curl
26 |
27 |
28 | **XMLWriter**
29 |
30 | >This is normally enabled by default but if PHP was compiled with --disable-xmlreader set then you will need to recompile PHP without --disable-xmlreader set.
31 |
32 |
33 | **MBstring**
34 |
35 | >You may be able to enable this setting by uncommenting the extension listing in your php.ini file:
36 |
37 | >;extension=php_mbstring.dll
38 |
39 | >Remove the semi-colon at the start of the line to activate the MBstring extension. Once you have done this you will need to restart your web server service.
40 |
41 | >If you can't find this line in your php.ini file then you may need to install the php-mbstring first. For further information see: http://php.net/manual/en/mbstring.installation.php
42 |
43 | **fileinfo**
44 |
45 | >This extension is enabled by default as of PHP 5.3.0. Windows users must include the bundled php_fileinfo.dll DLL file in php.ini to enable this extension.
46 |
47 | >For further information see http://php.net/manual/en/fileinfo.installation.php.
48 |
49 | **SOAP**
50 |
51 | >To enable SOAP support, configure PHP with --enable-soap.
52 |
53 | >For futher information see http://php.net/manual/en/intro.soap.php.
54 |
55 | ##cURL Connectivity
56 |
57 | If you encounter connectivity issues (error: Turnitin API Base URL incorrect or unavailable) this could be related to a CA certificate being unavailable to cURL.
58 |
59 | If cURL has an out of date (or no) CA certificates, the interaction with Turnitin will fail due to cURL performing peer SSL certificate verification and not being able to verify the Turnitin SSL certificate.
60 | Until cURL 7.18.0 some CA certificates were provided, but after 7.18.0 no cs certificates have been provided at all. Because of this, the Moodle server administrator would need to ensure that an up to date CA certificate bundle is used. To be clear, Moodle doesn't need an SSL certificate, however, it needs to have the certificate bundle in place so cURL can recognize the SSL certificates of Turnitin.
61 |
62 | Information on how to install a certificate bundle is available via the URLs below. Note that the URLs are third party sites and not affiliated with Turnitin or iParadigms in any way:
63 |
64 | Information for Linux environments: http://docs.moodle.org/26/en/SSL_certificate_for_moodle.org
65 |
66 | Information for Windows environments: http://curl.haxx.se/docs/sslcerts.html
67 |
68 | ##WSDL
69 |
70 | We have had reported issues with users not being able to parse the WSDL files that the API requires. The relevant error message starts “PHP Fatal error: SOAP-ERROR: Parsing WSDL: ….”
71 |
72 | From version 2014012405 onwards we have bundled the WSDL files with the plugin download, however the issue does still occur for some users. This is due to a PHP bug with libxml_disable_entity_loader() being set to true and preventing external entities from being loaded. If this is set by a PHP script then PHP uses this value for all processes on the server. For further information see: https://bugs.php.net/bug.php?id=64938.
73 |
74 | To fix this, you need to add the following line to your to your moodle config.php:
75 |
76 | libxml_disable_entity_loader(false);
77 |
78 | Thanks to Dan Marsden for the information and solution.
79 |
--------------------------------------------------------------------------------
/jquery/colorbox.css:
--------------------------------------------------------------------------------
1 | /*
2 | ColorBox Core Style:
3 | The following CSS is consistent between example themes and should not be altered.
4 | */
5 | #colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
6 | #cboxOverlay{position:fixed; width:100%; height:100%;}
7 | #cboxMiddleLeft, #cboxBottomLeft{clear:left;}
8 | #cboxContent{position:relative;}
9 | #cboxLoadedContent{overflow:auto;}
10 | #cboxTitle{margin:0;}
11 | #cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
12 | #cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
13 | .cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
14 | .cboxIframe{width:100%; height:100%; display:block; border:0;}
15 | #colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
16 |
17 | /*
18 | User Style:
19 | Change the following styles to modify the appearance of ColorBox. They are
20 | ordered & tabbed in a way that represents the nesting of the generated HTML.
21 | */
22 | #cboxOverlay{background:#000;}
23 | #colorbox{}
24 | #cboxContent{margin-top:32px; overflow:visible;}
25 | .cboxIframe{background:none;}/*#FFF*/
26 | #cboxError{padding:50px; border:1px solid #ccc;}
27 | #cboxLoadedContent{background:none; padding:1px;}
28 | #cboxLoadingGraphic{background:url(../../../mod/turnitintooltwo/pix/colorbox/loading.gif) no-repeat center center;}
29 | #cboxLoadingOverlay{background:none;}
30 | #cboxTitle{position:absolute; top:-22px; left:0; color:#000; display:none !important;}
31 | #cboxCurrent{position:absolute; top:-22px; right:205px; text-indent:-9999px;}
32 | #cboxClose{text-indent:-9999px; width:20px; height:20px; position:absolute; top:-20px; background:url(../../../mod/turnitintooltwo/pix/colorbox/controls.png) no-repeat 0 0;}
33 | #cboxClose{background-position:-50px 0px; right:0;}
34 | #cboxClose:hover{background-position:-50px -25px;}
35 |
36 |
37 | iframe html{background:none;}
38 |
39 | /* Messages Inbox, Migration, Upload, Rubric and Quickmark boxes */
40 | .messages #cboxLoadedContent, .messages .cboxIframe, .rubric_manager #cboxLoadedContent, .rubric_manager .cboxIframe, .quickmark_manager #cboxLoadedContent, .quickmark_manager .cboxIframe,
41 | .peermark_reviews #cboxLoadedContent, .peermark_reviews .cboxIframe, .peermark_manager #cboxLoadedContent, .peermark_manager .cboxIframe { background:none; }
42 |
43 | .migration #cboxLoadedContent, .migration #cboxIframe, .downloadpdf_window #cboxLoadedContent, .downloadpdf_window .cboxIframe,
44 | .gmpdfzip_window #cboxLoadedContent, .gmpdfzip_window .cboxIframe, .course_creation #cboxLoadedContent, .course_creation #cboxIframe {
45 | background: #FFF;
46 | }
47 |
48 | #cboxClose { text-indent:-36px; display:none; }
49 |
50 | .messages #cboxClose, .tii_unanonymise_reveal_form #cboxClose, .downloadpdf_window #cboxClose, .gmpdfzip_window #cboxClose, .rubric_manager #cboxClose,
51 | .rubric_view #cboxClose, .quickmark_manager #cboxClose, .peermark_manager #cboxClose, .peermark_reviews #cboxClose, .course_creation #cboxClose,
52 | .tii_unanonymise_reveal_form #cboxClose, .tii_unanonymise_reveal_form #cboxClose, .migration #cboxClose {
53 | display:none !important;
54 | }
55 |
56 | .upload #cboxClose {
57 | top: 2px;
58 | }
59 |
60 | .upload #cboxClose .closeText {
61 | position: relative;
62 | top: 2px;
63 | }
64 |
65 | .tii_unanonymise_reveal_form #cboxLoadedContent, .edit_end_date_form #cboxLoadedContent {
66 | height:100%;
67 | overflow: hidden !important;
68 | }
69 |
70 | #cboxOverlay{
71 | z-index:9997;
72 | }
73 |
74 | .loading_gif {
75 | padding:16px;
76 | margin:0 auto;
77 | position: absolute;
78 | top: 48%;
79 | left: 48%;
80 | background:url(../../../mod/turnitintooltwo/pix/colorbox/loading.gif) no-repeat center center #000;
81 | height: 32px;
82 | width: 32px;
83 | -moz-border-radius: 12px;
84 | -webkit-border-radius: 12px;
85 | -khtml-border-radius: 12px;
86 | border-radius: 12px;
87 | z-index:9998;
88 | }
89 |
90 | .unanonymise_reveal_form #cboxClose, .edit_end_date_form #cboxClose {
91 | top: 4px;
92 | right:4px;
93 | }
94 |
95 | .edit_end_date_form #cboxLoadedContent .mform .fitem .fitemtitle {
96 | width: 25%;
97 | }
98 |
99 | .edit_end_date_form #cboxLoadedContent .mform .fitem .felement {
100 | width: 70%;
101 | }
102 |
103 | .edit_end_date_form #cboxLoadedContent .mform .fitem fieldset.felement {
104 | margin-left: 25%;
105 | }
--------------------------------------------------------------------------------
/css/jqueryui-editable.css:
--------------------------------------------------------------------------------
1 | /*! X-editable - v1.4.3
2 | * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3 | * http://github.com/vitalets/x-editable
4 | * Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
5 |
6 | .editableform {
7 | margin-bottom: 0; /* overwrites bootstrap margin */
8 | }
9 |
10 | .editableform .control-group {
11 | margin-bottom: 0; /* overwrites bootstrap margin */
12 | white-space: nowrap; /* prevent wrapping buttons on new line */
13 | line-height: 20px; /* overwriting bootstrap line-height. See #133 */
14 | }
15 |
16 | .editable-buttons {
17 | display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
18 | vertical-align: top;
19 | margin-left: 7px;
20 | /* inline-block emulation for IE7*/
21 | zoom: 1;
22 | *display: inline;
23 | }
24 |
25 |
26 |
27 | .editable-input {
28 | vertical-align: top;
29 | display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
30 | width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
31 | white-space: normal; /* reset white-space decalred in parent*/
32 | /* display-inline emulation for IE7*/
33 | zoom: 1;
34 | *display: inline;
35 | }
36 |
37 | .editable-buttons .editable-cancel {
38 | margin-left: 7px;
39 | }
40 |
41 | /*for jquery-ui buttons need set height to look more pretty*/
42 | .editable-buttons button.ui-button-icon-only {
43 | height: 24px;
44 | width: 30px;
45 | }
46 |
47 | .editableform-loading {
48 | background: url('../pix/loading.gif') center center no-repeat;
49 | height: 25px;
50 | width: auto;
51 | min-width: 25px;
52 | }
53 |
54 | .editable-inline .editableform-loading {
55 | background-position: center 0px;
56 | }
57 |
58 | .editable-error-block {
59 | max-width: 300px;
60 | margin: 5px 0 0 0;
61 | width: auto;
62 | white-space: normal;
63 | }
64 |
65 | /*add padding for jquery ui*/
66 | .editable-error-block.ui-state-error {
67 | padding: 3px;
68 | }
69 |
70 | .editable-error {
71 | color: red;
72 | }
73 |
74 | .editableform .editable-date {
75 | padding: 0;
76 | margin: 0;
77 | float: left;
78 | }
79 |
80 |
81 | /* checklist vertical alignment */
82 | .editable-checklist label input[type="checkbox"],
83 | .editable-checklist label span {
84 | vertical-align: middle;
85 | margin: 0;
86 | }
87 |
88 | .editable-checklist label {
89 | white-space: nowrap;
90 | }
91 |
92 | /* set exact width of textarea to fit buttons toolbar */
93 | .editable-wysihtml5 {
94 | width: 566px;
95 | height: 250px;
96 | }
97 |
98 | /* clear button shown as link in date inputs */
99 | .editable-clear {
100 | clear: both;
101 | font-size: 0.9em;
102 | text-decoration: none;
103 | text-align: right;
104 | }
105 |
106 | /* IOS-style clear button for text inputs */
107 | .editable-clear-x {
108 | background: url('../pix/clear.png') center center no-repeat;
109 | display: block;
110 | width: 13px;
111 | height: 13px;
112 | position: absolute;
113 | opacity: 0.6;
114 | z-index: 100;
115 |
116 | }
117 |
118 | .editable-clear-x:hover {
119 | opacity: 1;
120 | }
121 | .editable-container {
122 | max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
123 | }
124 |
125 | .editable-container.popover {
126 | /* width: 300px;*/ /* debug */
127 | width: auto; /* without this rule popover does not stretch */
128 | }
129 |
130 | .editable-container.editable-inline {
131 | display: inline-block;
132 | vertical-align: middle;
133 | width: auto;
134 | /* inline-block emulation for IE7*/
135 | zoom: 1;
136 | *display: inline;
137 | }
138 |
139 | .editable-container.ui-widget {
140 | font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
141 | }
142 | .editable-click,
143 | a.editable-click,
144 | a.editable-click:hover {
145 | text-decoration: none;
146 | border-bottom: dashed 1px #0088cc;
147 | }
148 |
149 | .editable-click.editable-disabled,
150 | a.editable-click.editable-disabled,
151 | a.editable-click.editable-disabled:hover {
152 | color: #585858;
153 | cursor: default;
154 | border-bottom: none;
155 | }
156 |
157 | .editable-empty, .editable-empty:hover{
158 | font-style: italic;
159 | color: #DD1144;
160 | border-bottom: none;
161 | text-decoration: none;
162 | }
163 |
164 | .editable-unsaved {
165 | font-weight: bold;
166 | }
167 |
168 | .editable-unsaved:after {
169 | /* content: '*'*/
170 | }
171 |
172 | /*see https://github.com/vitalets/x-editable/issues/139 */
173 | .form-horizontal .editable
174 | {
175 | padding-top: 5px;
176 | display:inline-block;
177 | }
178 |
179 |
--------------------------------------------------------------------------------
/jquery/jqueryui-editable.css:
--------------------------------------------------------------------------------
1 | /*! X-editable - v1.4.3
2 | * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3 | * http://github.com/vitalets/x-editable
4 | * Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
5 |
6 | .editableform {
7 | margin-bottom: 0; /* overwrites bootstrap margin */
8 | }
9 |
10 | .editableform .control-group {
11 | margin-bottom: 0; /* overwrites bootstrap margin */
12 | white-space: nowrap; /* prevent wrapping buttons on new line */
13 | line-height: 20px; /* overwriting bootstrap line-height. See #133 */
14 | }
15 |
16 | .editable-buttons {
17 | display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
18 | vertical-align: top;
19 | margin-left: 7px;
20 | /* inline-block emulation for IE7*/
21 | zoom: 1;
22 | *display: inline;
23 | }
24 |
25 |
26 |
27 | .editable-input {
28 | vertical-align: top;
29 | display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
30 | width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
31 | white-space: normal; /* reset white-space decalred in parent*/
32 | /* display-inline emulation for IE7*/
33 | zoom: 1;
34 | *display: inline;
35 | }
36 |
37 | .editable-buttons .editable-cancel {
38 | margin-left: 7px;
39 | }
40 |
41 | /*for jquery-ui buttons need set height to look more pretty*/
42 | .editable-buttons button.ui-button-icon-only {
43 | height: 24px;
44 | width: 30px;
45 | }
46 |
47 | .editableform-loading {
48 | background: url('../../../mod/turnitintooltwo/pix/loading.gif') center center no-repeat;
49 | height: 25px;
50 | width: auto;
51 | min-width: 25px;
52 | }
53 |
54 | .editable-inline .editableform-loading {
55 | background-position: center 0px;
56 | }
57 |
58 | .editable-error-block {
59 | max-width: 300px;
60 | margin: 5px 0 0 0;
61 | width: auto;
62 | white-space: normal;
63 | }
64 |
65 | /*add padding for jquery ui*/
66 | .editable-error-block.ui-state-error {
67 | padding: 3px;
68 | }
69 |
70 | .editable-error {
71 | color: red;
72 | }
73 |
74 | .editableform .editable-date {
75 | padding: 0;
76 | margin: 0;
77 | float: left;
78 | }
79 |
80 |
81 | /* checklist vertical alignment */
82 | .editable-checklist label input[type="checkbox"],
83 | .editable-checklist label span {
84 | vertical-align: middle;
85 | margin: 0;
86 | }
87 |
88 | .editable-checklist label {
89 | white-space: nowrap;
90 | }
91 |
92 | /* set exact width of textarea to fit buttons toolbar */
93 | .editable-wysihtml5 {
94 | width: 566px;
95 | height: 250px;
96 | }
97 |
98 | /* clear button shown as link in date inputs */
99 | .editable-clear {
100 | clear: both;
101 | font-size: 0.9em;
102 | text-decoration: none;
103 | text-align: right;
104 | }
105 |
106 | /* IOS-style clear button for text inputs */
107 | .editable-clear-x {
108 | background: url('../../../mod/turnitintooltwo/pix/clear.png') center center no-repeat;
109 | display: block;
110 | width: 13px;
111 | height: 13px;
112 | position: absolute;
113 | opacity: 0.6;
114 | z-index: 100;
115 |
116 | }
117 |
118 | .editable-clear-x:hover {
119 | opacity: 1;
120 | }
121 | .editable-container {
122 | max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
123 | }
124 |
125 | .editable-container.popover {
126 | /* width: 300px;*/ /* debug */
127 | width: auto; /* without this rule popover does not stretch */
128 | }
129 |
130 | .editable-container.editable-inline {
131 | display: inline-block;
132 | vertical-align: middle;
133 | width: auto;
134 | /* inline-block emulation for IE7*/
135 | zoom: 1;
136 | *display: inline;
137 | }
138 |
139 | .editable-container.ui-widget {
140 | font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
141 | }
142 | .editable-click,
143 | a.editable-click,
144 | a.editable-click:hover {
145 | text-decoration: none;
146 | border-bottom: dashed 1px #0088cc;
147 | }
148 |
149 | .editable-click.editable-disabled,
150 | a.editable-click.editable-disabled,
151 | a.editable-click.editable-disabled:hover {
152 | color: #585858;
153 | cursor: default;
154 | border-bottom: none;
155 | }
156 |
157 | .editable-empty, .editable-empty:hover{
158 | font-style: italic;
159 | color: #DD1144;
160 | border-bottom: none;
161 | text-decoration: none;
162 | }
163 |
164 | .editable-unsaved {
165 | font-weight: bold;
166 | }
167 |
168 | .editable-unsaved:after {
169 | /* content: '*'*/
170 | }
171 |
172 | /*see https://github.com/vitalets/x-editable/issues/139 */
173 | .form-horizontal .editable
174 | {
175 | padding-top: 5px;
176 | display:inline-block;
177 | }
178 |
179 |
--------------------------------------------------------------------------------
/tests/unit/turnitintooltwo_submission_test.php:
--------------------------------------------------------------------------------
1 | dirroot . '/mod/turnitintooltwo/turnitintooltwo_assignment.class.php');
9 | require_once($CFG->dirroot . '/mod/turnitintooltwo/turnitintooltwo_submission.class.php');
10 | require_once($CFG->dirroot . '/webservice/tests/helpers.php');
11 | require_once($CFG->dirroot . '/mod/lti/lib.php');
12 | require_once($CFG->dirroot . '/course/lib.php');
13 |
14 | /**
15 | * Tests for classes/view/members
16 | *
17 | * @package turnitintooltwo
18 | */
19 | class mod_turnitintooltwo_submission_testcase extends advanced_testcase {
20 | /**
21 | * Test create submission function returns the expected bollean given a data array.
22 | */
23 | public function test_create_submission() {
24 | global $DB;
25 |
26 | $this->resetAfterTest();
27 |
28 | $turnitintooltwo = new stdClass();
29 | $turnitintooltwo->id = 1;
30 |
31 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
32 |
33 | $submission = new turnitintooltwo_submission(0, "moodle", $turnitintooltwoassignment, 1);
34 |
35 | $data = array();
36 | $data['submissiontype'] = 1;
37 | $data['submissiontext'] = "Submission text";
38 | $data['submissiontitle'] = "Submission title";
39 | $data['studentsname'] = 1;
40 | $data['submissionpart'] = 1;
41 | $data['submissionagreement'] = 1;
42 |
43 | $response = $submission->create_submission($data);
44 |
45 | $this->assertEquals($response, true);
46 |
47 | /**
48 | * Test where create_submissions is false.
49 | * First we stub the class,
50 | * Then we stub the method insert_submission() to always return false.
51 | * Then we call our stubbed class with the method we want to test.
52 | */
53 | // Create a stub
54 | $stub = $this->getMockBuilder('turnitintooltwo_submission')
55 | ->getMock();
56 |
57 | // Configure the stub.
58 | $stub->method('insert_submission')
59 | ->willReturn(false);
60 |
61 | $response = $stub->create_submission($data);
62 |
63 | $this->assertEquals($response, false);
64 | }
65 |
66 | /**
67 | * Test create submission function returns the expected bollean given a data array.
68 | */
69 | public function test_insert_submission() {
70 | global $DB;
71 |
72 | $this->resetAfterTest();
73 |
74 | $turnitintooltwo = new stdClass();
75 | $turnitintooltwo->id = 1;
76 |
77 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
78 |
79 | $submission = new turnitintooltwo_submission(0, "moodle", $turnitintooltwoassignment, 1);
80 |
81 | $data = new stdClass();
82 | $data->userid = 1;
83 | $data->turnitintooltwoid = 1;
84 | $data->submission_part = 1;
85 | $data->submission_title = "Submission title";
86 | $data->submission_type = 1;
87 | $data->submission_objectid = null;
88 | $data->submission_unanon = 0;
89 | $data->submission_grade = null;
90 | $data->submission_gmimaged = 0;
91 | $data->submission_hash = $data->userid.'_'.$data->turnitintooltwoid.'_'.$data->submission_part;
92 |
93 | $response = $submission->insert_submission($data);
94 | $this->assertEquals($response, true);
95 |
96 | $response = $submission->insert_submission("");
97 | $this->assertEquals($response, false);
98 | }
99 |
100 | public function test_count_graded_submissions() {
101 | global $DB;
102 |
103 | $this->resetAfterTest();
104 |
105 | $turnitintooltwo = new stdClass();
106 | $turnitintooltwo->id = 1;
107 |
108 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
109 |
110 | $submission = new turnitintooltwo_submission(0, "moodle", $turnitintooltwoassignment, 1);
111 |
112 | $data = new stdClass();
113 | $data->userid = 1;
114 | $data->turnitintooltwoid = $turnitintooltwo->id;
115 | $data->submission_part = 1;
116 | $data->submission_title = "Submission title";
117 | $data->submission_type = 1;
118 | $data->submission_objectid = null;
119 | $data->submission_unanon = 0;
120 | $data->submission_grade = 75;
121 | $data->submission_gmimaged = 0;
122 | $data->submission_hash = $data->userid.'_'.$data->turnitintooltwoid.'_'.$data->submission_part;
123 |
124 | $response = $submission->insert_submission($data);
125 | $count = $submission->count_graded_submissions($turnitintooltwo->id);
126 |
127 | $this->assertEquals($count, 1);
128 |
129 | // Testing when there is no grades
130 | $submissionrecord = $DB->get_record('turnitintooltwo_submissions', array('turnitintooltwoid' => $turnitintooltwo->id));
131 | $DB->update_record('turnitintooltwo_submissions', array('id' => $submissionrecord->id, 'submission_grade' => 0));
132 |
133 | $count = $submission->count_graded_submissions($turnitintooltwo->id);
134 |
135 | $this->assertEquals($count, 0);
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/sass/partials/_listbar.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * Listbar - Contains datatables links, dropdowns and search
3 | */
4 |
5 | .mod_turnitintooltwo_listbar-container {
6 | display: table;
7 | width: 100%;
8 | }
9 |
10 | .mod_turnitintooltwo_listbar {
11 | background: #fff;
12 | border: 1px solid $border-color;
13 | position: relative;
14 | display: table-cell;
15 | vertical-align: middle;
16 | padding: 10px;
17 |
18 | label,
19 | input,
20 | select {
21 | margin: 0;
22 | }
23 |
24 | select,
25 | input {
26 | height: 30px;
27 | padding: 0 5px;
28 | border: 1px solid #EFEFEF;
29 | -webkit-border-radius: 4px;
30 | -moz-border-radius: 4px;
31 | border-radius: 4px;
32 | background: #fff;
33 | }
34 |
35 | .mod_turnitintooltwo_refresh_link,
36 | .mod_turnitintooltwo_refreshing_link,
37 | .mod_turnitintooltwo_nonsubmitters_link {
38 | float: right;
39 | margin-left: 30px;
40 | padding: 5px 0;
41 | width: 195px;
42 | }
43 |
44 | .mod_turnitintooltwo_nonsubmitters_link {
45 | text-decoration: none;
46 | display: none;
47 | }
48 |
49 | /*
50 | * Messages inbox link in listbar
51 | */
52 | .mod_turnitintooltwo_messages_inbox {
53 | float: right;
54 | margin-left: 30px;
55 | padding: 5px 0;
56 | text-decoration: none;
57 | }
58 |
59 | .mod_turnitintooltwo_messages_loading {
60 | float: none !important;
61 | margin: 0 !important;
62 | }
63 |
64 | // Zip file download links
65 | .mod_turnitintooltwo_zip_downloads {
66 | float: left;
67 | position: relative;
68 | top: 4px;
69 | height: 22px;
70 |
71 | img {
72 | position: relative;
73 | top: 4px;
74 | left: -2px;
75 | }
76 |
77 | div.mod_turnitintooltwo_origchecked_zip_open,
78 | a.mod_turnitintooltwo_gmpdfzip_box {
79 | padding: 3px 16px;
80 | display: block;
81 | }
82 |
83 | a.mod_turnitintooltwo_gmpdfzip_box:hover {
84 | background: $hover-blue;
85 | color: $white;
86 | }
87 |
88 | .mod_turnitintooltwo_zip_open {
89 | display: inline;
90 | }
91 |
92 | .mod_turnitintooltwo_dropdown-menu .mod_turnitintooltwo_origchecked_zip_open:hover {
93 | background-color: $hover-blue;
94 | display: block;
95 | line-height: 20px;
96 | color: $white;
97 | font-weight: normal;
98 | }
99 |
100 | .mod_turnitintooltwo_dropdown-menu {
101 | white-space: nowrap;
102 | margin-top: 2px !important;
103 | }
104 | }
105 |
106 | /*
107 | * DataTables filter (search bar)
108 | */
109 | .dataTables_filter {
110 | float: right !important;
111 | text-align: left !important;
112 | }
113 |
114 | /*
115 | * DataTables length (how many per page)
116 | */
117 | .dataTables_length {
118 | float: left !important;
119 | }
120 | }
121 |
122 | @media screen and (max-width: 1500px) {
123 | .dataTables_filter {
124 | input[type="search"] {
125 | max-width: 150px;
126 | }
127 | }
128 | }
129 |
130 | @media screen and (max-width: 1460px) {
131 | .mod_turnitintooltwo_listbar {
132 | font-size: 13px;
133 | }
134 | }
135 |
136 | @media screen and (max-width: 1350px) {
137 | .dataTables_filter {
138 | input[type="search"] {
139 | max-width: 80px;
140 | }
141 | }
142 |
143 | .mod_turnitintooltwo_listbar .mod_turnitintooltwo_messages_inbox,
144 | .mod_turnitintooltwo_listbar .mod_turnitintooltwo_refresh_link {
145 | margin-left: 5px;
146 | width: auto;
147 | }
148 |
149 | .mod_turnitintooltwo_listbar .mod_turnitintooltwo_refresh_link {
150 | padding-left: 5px;
151 | padding-right: 5px;
152 | }
153 |
154 | .mod_turnitintooltwo_listbar {
155 | #mod_turnitintooltwo_download_links {
156 | margin-left: 5px;
157 |
158 | .btn.dropdown-toggle {
159 | padding-left: 6px;
160 | padding-right: 6px;
161 | }
162 | }
163 | }
164 | }
165 |
166 | @media screen and (max-width: 1260px) {
167 | .mod_turnitintooltwo_listbar {
168 | font-size: 12px;
169 |
170 | .mod_turnitintooltwo_nonsubmitters_link {
171 | width: auto;
172 | margin-left: 0;
173 | padding: 5px 5px;
174 | }
175 | }
176 |
177 | .dataTables_filter {
178 | input[type="search"] {
179 | max-width: 95px;
180 | }
181 | }
182 |
183 | .mod_turnitintooltwo_listbar {
184 | #mod_turnitintooltwo_download_links {
185 | .btn.dropdown-toggle {
186 | padding-right: 0;
187 | }
188 | }
189 | }
190 | }
191 |
192 | // do not support Firefox
193 | @media screen and (max-width: 1024px) and (min-resolution: 1.1dppx) {
194 | .mod_turnitintooltwo_listbar {
195 | font-size: 11px;
196 | }
197 | .dataTables_filter input[type=search] {
198 | max-width: 45px;
199 | }
200 | }
--------------------------------------------------------------------------------
/tests/unit/turnitintooltwo_assignment_test.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * Unit tests for (some of) mod/turnitintooltwo/view.php.
19 | *
20 | * @package mod_turnitintooltwo
21 | * @copyright 2017 Turnitin
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 | */
24 |
25 | defined('MOODLE_INTERNAL') || die();
26 |
27 | global $CFG;
28 | require_once($CFG->dirroot . '/mod/turnitintooltwo/turnitintooltwo_assignment.class.php');
29 |
30 | /**
31 | * Tests for inbox
32 | *
33 | * @package turnitintooltwo
34 | */
35 | class mod_turnitintooltwo_assignment_testcase extends advanced_testcase {
36 |
37 | /**
38 | * Test that the title is truncated to the passed in limit.
39 | */
40 | public function test_truncate_title() {
41 | $turnitintooltwo = new stdClass();
42 | $turnitintooltwo->id = 1;
43 |
44 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
45 |
46 | // Test that a string under the limit is returned with a suffix added.
47 | $originaltitle = 'Test String';
48 | $expectedtitle = 'Test String (Moodle TT)';
49 | $limit = 100;
50 | $title = $turnitintooltwoassignment->truncate_title($originaltitle, $limit, 'TT');
51 | $this->assertEquals($expectedtitle, $title);
52 | $this->assertLessThan($limit, strlen($title));
53 |
54 | // Test that a string over the limit is returned truncated with a suffix added and is equal to the limit in length.
55 | $originaltitle = 'Test String is truncated and has a suffix added on the end with brackets showing the moodle coursetype';
56 | $limit = 30;
57 | $title = $turnitintooltwoassignment->truncate_title($originaltitle, $limit, 'TT');
58 | $this->assertStringContainsString('Test String', $title);
59 | $this->assertStringNotContainsString('added on the end', $title);
60 | $this->assertStringContainsString('... (Moodle TT)', $title);
61 | $this->assertEquals($limit, strlen($title));
62 | }
63 |
64 | /**
65 | * Test that a checkbox field is initialised and not overwritten if already set.
66 | */
67 | public function test_set_checkbox_field() {
68 | $turnitintooltwo = new stdClass();
69 | $turnitintooltwo->id = 1;
70 |
71 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
72 | $turnitintooltwoassignment->set_checkbox_field('testvar1');
73 |
74 | // Verify that checkbox fields are set to 0 by default.
75 | $this->assertEquals(0, $turnitintooltwoassignment->turnitintooltwo->testvar1);
76 |
77 | // Verify that checkbox fields are set to passed in value.
78 | $value = 20;
79 | $turnitintooltwoassignment->set_checkbox_field('testvar2', $value);
80 | $this->assertEquals($value, $turnitintooltwoassignment->turnitintooltwo->testvar2);
81 |
82 | // Set checkbox fields.
83 | $turnitintooltwoassignment->turnitintooltwo->testvar1 = 1;
84 |
85 | // Verify that checkbox fields aren't changed as they are already set.
86 | $turnitintooltwoassignment->set_checkbox_field('testvar1');
87 | $this->assertEquals(1, $turnitintooltwoassignment->turnitintooltwo->testvar1);
88 | }
89 |
90 | /**
91 | * Test that the course returned is the one we expect.
92 | */
93 | public function test_course_data() {
94 | global $DB;
95 |
96 | $this->resetAfterTest();
97 |
98 | $turnitintooltwo = new stdClass();
99 | $turnitintooltwo->id = 1;
100 |
101 | $turnitintooltwoassignment = new turnitintooltwo_assignment(0, $turnitintooltwo);
102 |
103 | // Create a V2 course.
104 | $course = new stdClass();
105 | $course->courseid = 1;
106 | $course->ownerid = 1;
107 | $course->turnitin_ctl = "Test Course";
108 | $course->turnitin_cid = 10;
109 | $course->course_type = "TT";
110 |
111 | // Insert the course to the turnitintooltwo courses table.
112 | $DB->insert_record('turnitintooltwo_courses', $course);
113 |
114 | // Test that we return the correct course when calling get_course_data with course type TT.
115 | $response = $turnitintooltwoassignment->get_course_data(1, "TT");
116 | $this->assertEquals(10, $response->turnitin_cid);
117 | $this->assertEquals("TT", $response->course_type);
118 |
119 | // Insert a new V2 course.
120 | $course->turnitin_cid = 20;
121 | $course->course_type = "V1";
122 | $DB->insert_record('turnitintooltwo_courses', $course);
123 |
124 | // Test course type V1
125 | $response = $turnitintooltwoassignment->get_course_data(1, "V1");
126 | $this->assertEquals(20, $response->turnitin_cid);
127 | $this->assertEquals("V1", $response->course_type);
128 | }
129 | }
--------------------------------------------------------------------------------
/classes/view/members.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | /**
20 | * Members view class deals with generating the HTM for the members table. It
21 | * can generate members table for either tutors or students in a course by
22 | * calling the "build_members_view" method. Defaults to rendering the students
23 | * members table if no display role is given.
24 | */
25 | class members_view {
26 | public $course;
27 | public $coursemodule;
28 | public $turnitintooltwoassignment;
29 | public $turnitintooltwoview;
30 |
31 | public function __construct($course=null, $coursemodule=null, $turnitintooltwoview=null, $turnitintooltwoassignment=null) {
32 | $this->course = $course;
33 | $this->coursemodule = $coursemodule;
34 | $this->turnitintooltwoview = $turnitintooltwoview;
35 | $this->turnitintooltwoassignment = $turnitintooltwoassignment;
36 | }
37 |
38 | /**
39 | * Method that generates the members view HTML. Depending on the displayrole
40 | * passed will generate the HTML for the users with that role.
41 | * @return string Members HTML for a role
42 | */
43 | public function build_members_view($displayrole = "students") {
44 | $istutor = $this->is_tutor();
45 |
46 | if (!$istutor) {
47 | turnitintooltwo_print_error('permissiondeniederror', 'turnitintooltwo');
48 | exit();
49 | }
50 |
51 | $wrapperclass = $displayrole == "tutors" ? "members-instructors" : "members-students";
52 |
53 | // Wrapper element for strong CSS selectors.
54 | $output = html_writer::start_tag("div", array("class" => "mod_turnitintooltwo_members " . $wrapperclass));
55 |
56 | $output .= $this->build_intro_message($displayrole);
57 | $output .= $this->build_members_table($displayrole);
58 | $output .= $this->build_add_tutors_form($displayrole);
59 |
60 | $output .= html_writer::end_tag("div");
61 |
62 | return $output;
63 | }
64 |
65 | /**
66 | * Util method to check if the current user is an instructor by checking if
67 | * they can grade.
68 | * @return boolean Bool if the current user is an instructor
69 | */
70 | public function is_tutor () {
71 | return has_capability('mod/turnitintooltwo:grade', context_module::instance($this->coursemodule->id));
72 | }
73 |
74 | /**
75 | * Returns the Turnitin role for the display role passed in the query param
76 | * "do" (tutors or students) to view.php.
77 | * @param string $displayrole The do action passed to view.php when
78 | * displaying members
79 | * @return string Turnitin role that maps to the display role
80 | */
81 | public function get_role_for_display_role ($displayrole) {
82 | return $displayrole == "tutors" ? 'Instructor' : 'Learner';
83 | }
84 |
85 | /**
86 | * Generates HTM for the message that is displayed above the members table.
87 | * This differs depending on if we're showing the student members or
88 | * instructor members.
89 | * @param string $displayrole Role of the members we want to display for
90 | * @return string HTML message to display before the members
91 | * table
92 | */
93 | public function build_intro_message ($displayrole = "students") {
94 | global $OUTPUT;
95 |
96 | if ($displayrole == "tutors") {
97 | $introtextkey = 'turnitintutors_desc';
98 | } else {
99 | $introtextkey = 'turnitinstudents_desc';
100 | }
101 |
102 | $introtext = get_string($introtextkey, 'turnitintooltwo');
103 |
104 | return $OUTPUT->box($introtext, 'message message-members-intro');
105 | }
106 |
107 | /**
108 | * Generates the HTML for the members table given a role will generate for
109 | * either the course students or instructors.
110 | * @param string $role Members with this role to display
111 | * @return string HTML of the members table
112 | */
113 | public function build_members_table ($displayrole="students") {
114 | $turnitintooltwoassignment = $this->turnitintooltwoassignment;
115 | $turnitintooltwoview = $this->turnitintooltwoview;
116 | $coursemodule = $this->coursemodule;
117 | $role = $this->get_role_for_display_role($displayrole);
118 |
119 | return $turnitintooltwoview->init_tii_member_by_role_table($coursemodule, $turnitintooltwoassignment, $role);
120 | }
121 |
122 | /**
123 | * Generates the HTML for the add tutors form that is displayed under the
124 | * members table. Only generates the form for the display role "tutors"
125 | * otherwise will return an empty string (i.e. display nothing).
126 | * @param string $displayrole Which members table is being shown
127 | * @return string HTML for add tutors form to display
128 | */
129 | public function build_add_tutors_form ($displayrole) {
130 | // early escape only show the add tutors in the tutors members list
131 | if ($displayrole != "tutors") {
132 | return "";
133 | }
134 |
135 | $tutors = $this->turnitintooltwoassignment->get_tii_users_by_role("Instructor", "mdl");
136 | return $this->turnitintooltwoview->show_add_tii_tutors_form($this->coursemodule, $tutors);
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/backup/moodle2/backup_turnitintooltwo_stepslib.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package moodlecore
19 | * @subpackage backup-moodle2
20 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 | */
23 |
24 | defined('MOODLE_INTERNAL') || die();
25 |
26 | // Define all the backup steps that will be used by the backup_assignment_activity_task.
27 | // This is the Complete assignment structure for backup, with file and id annotations.
28 |
29 | require_once($CFG->dirroot."/mod/turnitintooltwo/lib.php");
30 |
31 | class backup_turnitintooltwo_activity_structure_step extends backup_activity_structure_step {
32 |
33 | protected function define_structure() {
34 | // Required otherwise Moodle unit test core_calendar_container_testcase calendar/tests/container_test.php will fail.
35 | if (defined('PHPUNIT_TEST') && PHPUNIT_TEST) {
36 | set_config('accountid', 'NULL', 'turnitintooltwo');
37 | }
38 |
39 | $config = turnitintooltwo_admin_config();
40 |
41 | // To know if we are including userinfo.
42 | $userinfo = $this->get_setting_value('userinfo');
43 |
44 | // Define each element separated.
45 | $turnitintooltwo = new backup_nested_element('turnitintooltwo', array('id'), array(
46 | 'type', 'name', 'grade', 'numparts', 'tiiaccount', 'defaultdtstart', 'defaultdtdue', 'defaultdtpost',
47 | 'anon', 'portfolio', 'allowlate', 'reportgenspeed', 'submitpapersto', 'spapercheck', 'internetcheck',
48 | 'journalcheck', 'institution_check', 'maxfilesize', 'intro', 'introformat', 'timecreated', 'timemodified',
49 | 'studentreports', 'dateformat', 'usegrademark', 'gradedisplay', 'autoupdates', 'commentedittime', 'commentmaxsize',
50 | 'autosubmission', 'shownonsubmission', 'excludebiblio', 'excludequoted', 'excludevalue', 'excludetype',
51 | 'transmatch', 'rubric', 'allownonor'
52 | ));
53 |
54 | $parts = new backup_nested_element('parts');
55 |
56 | $part = new backup_nested_element('part', array('id'), array(
57 | 'turnitintooltwoid', 'partname', 'tiiassignid', 'dtstart', 'dtdue',
58 | 'dtpost', 'maxmarks', 'deleted', 'migrated'));
59 |
60 | $courses = new backup_nested_element('courses');
61 |
62 | $course = new backup_nested_element('course', array('id'), array(
63 | 'courseid', 'ownerid', 'ownertiiuid', 'owneremail', 'ownerfn',
64 | 'ownerln', 'ownerun', 'turnitin_ctl', 'turnitin_cid', 'course_type'));
65 |
66 | $submissions = new backup_nested_element('submissions');
67 |
68 | $submission = new backup_nested_element('submission', array('id'), array(
69 | 'userid', 'submission_part', 'submission_title', 'submission_type', 'submission_filename',
70 | 'submission_objectid', 'submission_score', 'submission_grade', 'submission_gmimaged', 'submission_attempts',
71 | 'submission_modified', 'submission_parent', 'submission_nmuserid', 'submission_nmfirstname',
72 | 'submission_nmlastname', 'submission_unanon', 'submission_anonreason', 'submission_transmatch',
73 | 'submission_orcapable', 'submission_acceptnothing', 'tiiuserid'));
74 |
75 | // Build the tree.
76 | $submissions->add_child($submission);
77 | $parts->add_child($part);
78 | $turnitintooltwo->add_child($parts);
79 | $turnitintooltwo->add_child($course);
80 | $turnitintooltwo->add_child($submissions);
81 |
82 | // Define sources.
83 | $turnitintooltwo->set_source_table('turnitintooltwo', array('id' => backup::VAR_ACTIVITYID));
84 | $values['tiiaccount'] = $config->accountid;
85 | $turnitintooltwo->fill_values($values);
86 |
87 | $part->set_source_table('turnitintooltwo_parts', array('turnitintooltwoid' => backup::VAR_ACTIVITYID), 'id');
88 |
89 | $course->set_source_sql("
90 | SELECT t.id, t.courseid, t.ownerid, tu.turnitin_uid AS ownertiiuid,
91 | u.email AS owneremail, u.firstname AS ownerfn, u.lastname AS ownerln,
92 | u.username AS ownerun, t.turnitin_ctl, t.turnitin_cid
93 | FROM {turnitintooltwo_courses} t, {user} u, {turnitintooltwo_users} tu
94 | WHERE t.ownerid=u.id AND tu.userid=t.ownerid AND t.courseid = ? AND t.course_type = 'TT'",
95 | array(backup::VAR_COURSEID));
96 |
97 | // All the rest of elements only happen if we are including user info.
98 | if ($userinfo) {
99 | $submission->set_source_sql('
100 | SELECT s.*, tu.turnitin_uid AS tiiuserid
101 | FROM {turnitintooltwo_submissions} s, {turnitintooltwo_users} tu
102 | WHERE s.userid=tu.userid AND s.turnitintooltwoid = ?',
103 | array(backup::VAR_ACTIVITYID));
104 | }
105 |
106 | // Define id annotations.
107 | $submission->annotate_ids('user', 'userid');
108 |
109 | // Define file annotations.
110 | $turnitintooltwo->annotate_files('mod_turnitintooltwo', 'intro', null); // This file area hasn't itemid.
111 | $submission->annotate_files('mod_turnitintooltwo', 'submissions', 'id');
112 |
113 | // Return the root element (turnitintooltwo), wrapped into standard activity structure.
114 | return $this->prepare_activity_structure($turnitintooltwo);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/turnitintooltwo_form.class.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2012 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | require_once($CFG->libdir."/formslib.php");
25 |
26 | class turnitintooltwo_form extends moodleform {
27 |
28 | /**
29 | * The form definition contains a customdata array. This contains all the elements as an array,
30 | * each element is passed with data in the following format:
31 | * array(type e.g. "text", id/name of element, label string, string identifier for help text,
32 | * options (e.g. for select, advcheckbox or file upload), rule, rule error msg, param_type,
33 | * array for disabled if rule (dependent field, condition, value)
34 | *
35 | * @global type $CFG
36 | */
37 | public function definition() {
38 | $mform =& $this->_form;
39 |
40 | foreach ($this->_customdata["elements"] as $element) {
41 | switch ($element[0]) {
42 | case "static":
43 | case "select":
44 | case "date_time_selector":
45 | case "date_selector":
46 | $mform->addElement($element[0], $element[1], $element[2], $element[4]);
47 | break;
48 | case "filemanager":
49 | $mform->addElement($element[0], $element[1], $element[2], '', $element[4]);
50 | break;
51 | case "html":
52 | $mform->addElement($element[0], $element[1]);
53 | break;
54 | case "advcheckbox":
55 | $labelbefore = $element[2];
56 | $labelafter = null;
57 | if (!empty($this->_customdata["checkbox_label_after"])) {
58 | $labelbefore = null;
59 | $labelafter = $element[2];
60 | }
61 | $mform->addElement($element[0], $element[1], $labelbefore, $labelafter, null, $element[4]);
62 | break;
63 | case "hidden":
64 | case "text":
65 | $mform->addElement($element[0], $element[1], $element[2]);
66 | $mform->setType($element[1], PARAM_RAW);
67 | break;
68 | default:
69 | $mform->addElement($element[0], $element[1], $element[2]);
70 | break;
71 | }
72 |
73 | // Set form data. Only used for submission form.
74 | if (isset($_SESSION['form_data']->{$element[1]})) {
75 | $mform->setDefault($element[1], $_SESSION['form_data']->{$element[1]});
76 | }
77 |
78 | if (!empty($element[3])) {
79 | $mform->addHelpButton($element[1], $element[3], 'turnitintooltwo');
80 | }
81 |
82 | if (!empty($element[5])) {
83 | $mform->setType($element[1], PARAM_TEXT);
84 | $mform->addRule($element[1], $element[6], $element[5], null, 'client');
85 | }
86 |
87 | if (!empty($element[7])) {
88 | $disabledif = $element[7];
89 | $mform->disabledIf($element[1], $disabledif[0], $disabledif[1], $disabledif[2]);
90 | }
91 | }
92 |
93 | // Apply a class to the form if specified.
94 | if (isset($this->_customdata["class"])) {
95 | $mform->_formname = $this->_customdata["class"];
96 | }
97 |
98 | // Show the moodleform standard submit and cancel buttons.
99 | if (!isset($this->_customdata["hide_submit"])) {
100 | $submitlabel = null;
101 | if (isset($this->_customdata["submit_label"])) {
102 | $submitlabel = $this->_customdata["submit_label"];
103 | }
104 | if (!isset($this->_customdata["show_cancel"])) {
105 | $this->_customdata["show_cancel"] = "true";
106 | }
107 |
108 | $this->add_action_buttons($this->_customdata["show_cancel"], $submitlabel);
109 | }
110 |
111 | // Disable the form change checker - added in 2.3.2.
112 | if (is_callable(array($mform, 'disable_form_change_checker'))) {
113 | if (isset($this->_customdata["disable_form_change_checker"])) {
114 | $mform->disable_form_change_checker();
115 | }
116 | }
117 |
118 | // Show multiple submit buttons if needed.
119 | if (isset($this->_customdata["multi_submit_buttons"])) {
120 | $buttonarray = array();
121 | foreach ($this->_customdata["multi_submit_buttons"] as $btn) {
122 | $buttonarray[] = &$mform->createElement('submit', $btn[0], $btn[1]);
123 | }
124 |
125 | $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
126 | }
127 | }
128 |
129 | /**
130 | * Display the form, saving the contents of the output buffer overiding Moodle's
131 | * display function that prints to screen when called
132 | *
133 | * @return the form as an object to print to screen at our convenience
134 | */
135 | public function display() {
136 | ob_start();
137 | parent::display();
138 | $form = ob_get_contents();
139 | ob_end_clean();
140 |
141 | return $form;
142 | }
143 | }
144 |
145 | class turnitin_plagiarism_plugin_form extends moodleform {
146 |
147 | // Define the form.
148 | public function definition () {
149 | global $CFG;
150 |
151 | $mform =& $this->_form;
152 |
153 | require_once($CFG->dirroot.'/plagiarism/turnitin/turnitinplugin_view.class.php');
154 |
155 | $turnitinpluginview = new turnitinplugin_view();
156 | $turnitinpluginview->add_elements_to_settings_form($mform, array(), "defaults");
157 |
158 | $this->add_action_buttons(true);
159 | }
160 | }
--------------------------------------------------------------------------------
/tests/unit/classes/view/members_test.php:
--------------------------------------------------------------------------------
1 | dirroot . '/mod/turnitintooltwo/classes/view/members.php');
7 | require_once($CFG->dirroot . '/mod/turnitintooltwo/turnitintooltwo_assignment.class.php');
8 | require_once($CFG->dirroot . '/mod/turnitintooltwo/turnitintooltwo_view.class.php');
9 | require_once($CFG->dirroot . '/webservice/tests/helpers.php');
10 | require_once($CFG->dirroot . '/mod/lti/lib.php');
11 |
12 | /**
13 | * Tests for classes/view/members
14 | *
15 | * @package turnitintooltwo
16 | */
17 | class mod_turnitintooltwo_view_members_testcase extends advanced_testcase {
18 | /**
19 | * Test display role given returns as the expected Turnitin role
20 | */
21 | public function test_get_role_for_display_role() {
22 | $members = new members_view();
23 |
24 | $role = $members->get_role_for_display_role(null);
25 | $this->assertEquals('Learner', $role);
26 |
27 | $role = $members->get_role_for_display_role("tutors");
28 | $this->assertEquals('Instructor', $role);
29 |
30 | $role = $members->get_role_for_display_role("students");
31 | $this->assertEquals('Learner', $role);
32 |
33 | $role = $members->get_role_for_display_role("foobar");
34 | $this->assertEquals('Learner', $role);
35 | }
36 |
37 | /**
38 | * Test given a role the correct intro message for the members view is
39 | * generated.
40 | */
41 | public function test_build_intro_message() {
42 | $members = new members_view();
43 |
44 | $actualmessage = $members->build_intro_message();
45 | $expectedmessagetext = get_string('turnitinstudents_desc', 'turnitintooltwo');
46 |
47 | $this->assertStringContainsString($expectedmessagetext, $actualmessage);
48 |
49 | $actualmessage = $members->build_intro_message("students");
50 | $expectedmessagetext = get_string("turnitinstudents_desc", "turnitintooltwo");
51 |
52 | $this->assertStringContainsString($expectedmessagetext, $actualmessage);
53 |
54 | $actualmessage = $members->build_intro_message("foobar");
55 | $expectedmessagetext = get_string("turnitinstudents_desc", "turnitintooltwo");
56 |
57 | $this->assertStringContainsString($expectedmessagetext, $actualmessage);
58 |
59 | $actualmessage = $members->build_intro_message("tutors");
60 | $expectedmessagetext = get_string("turnitintutors_desc", "turnitintooltwo");
61 |
62 | $this->assertStringContainsString($expectedmessagetext, $actualmessage);
63 | }
64 |
65 | /**
66 | * Test given a display role the correct table HTML is generated
67 | */
68 | public function test_build_members_table() {
69 | // fake/stub a turnitin two view class and the method to render the
70 | // table
71 | $observer = $this->getMockBuilder(turnitintooltwo_view::class)
72 | ->setMethods(['init_tii_member_by_role_table'])
73 | ->getMock();
74 |
75 | // add assertions to the turnitin two view class method that renders the
76 | // members table is called with the expected arguments
77 | $observer->expects($this->exactly(4))
78 | ->method('init_tii_member_by_role_table')
79 | ->willReturn('