├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── README.md
├── TESTING.md
├── TROUBLESHOOTING.md
├── ajax.php
├── amd
├── build
│ ├── migration_tool_launch.min.js
│ ├── migration_tool_migrate.min.js
│ └── modal_migration_tool.min.js
└── src
│ ├── migration_tool_launch.js
│ ├── migration_tool_migrate.js
│ └── modal_migration_tool.js
├── backup
└── moodle2
│ ├── backup_turnitintooltwo_activity_task.class.php
│ ├── backup_turnitintooltwo_stepslib.php
│ ├── restore_turnitintooltwo_activity_task.class.php
│ └── restore_turnitintooltwo_stepslib.php
├── classes
├── digitalreceipt
│ ├── instructor_message.php
│ └── receipt_message.php
├── event
│ ├── add_submission.php
│ ├── delete_submission.php
│ ├── list_submissions.php
│ ├── migrate_assignment.php
│ └── view_submission.php
├── nonsubmitters
│ └── nonsubmitters_message.php
├── privacy
│ └── provider.php
├── task
│ └── turnitintooltwo_task.php
├── v1migration
│ └── v1migration.php
└── view
│ └── members.php
├── css
├── bootstrap.min.css
├── colorbox.css
├── fontawesome.min.css
├── hide_bg.css
├── jquery-ui-1.8.4.custom.css
├── jqueryui-editable.css
├── student_noscript.css
├── styles_block.css
├── tii-icon-webfont.css
└── tooltipster.css
├── db
├── access.php
├── install.php
├── install.xml
├── log.php
├── messages.php
├── tasks.php
└── upgrade.php
├── extras.php
├── fonts
├── tii-icon-webfont.eot
├── tii-icon-webfont.svg
├── tii-icon-webfont.ttf
└── tii-icon-webfont.woff
├── gulpfile.js
├── index.php
├── jquery
├── colorbox.css
├── jquery.colorbox.js
├── jquery.cookie.js
├── jquery.dataTables.columnFilter.js
├── jquery.dataTables.css
├── jquery.dataTables.js
├── jquery.dataTables.plugins.js
├── jquery.tooltipster.js
├── jqueryui-editable.css
├── jqueryui-editable.js
├── moment.js
├── plugins.php
├── tooltipster.css
├── turnitintooltwo-2025070302.js
├── turnitintooltwo-2025070302.min.js
├── turnitintooltwo-2025070302.min.js.map
├── turnitintooltwo_extra-2024120301.js
├── turnitintooltwo_extra-2024120301.min.js
├── turnitintooltwo_extra-2024120301.min.js.map
├── turnitintooltwo_settings-2025070302.js
├── turnitintooltwo_settings-2025070302.min.js
└── turnitintooltwo_settings-2025070302.min.js.map
├── lang
├── ar
│ └── turnitintooltwo.php
├── ca
│ └── turnitintooltwo.php
├── cs
│ └── turnitintooltwo.php
├── de
│ └── turnitintooltwo.php
├── en
│ └── turnitintooltwo.php
├── es
│ └── turnitintooltwo.php
├── fi
│ └── turnitintooltwo.php
├── fr
│ └── turnitintooltwo.php
├── it
│ └── turnitintooltwo.php
├── ja
│ └── turnitintooltwo.php
├── ko
│ └── turnitintooltwo.php
├── nl
│ └── turnitintooltwo.php
├── pl
│ └── turnitintooltwo.php
├── pt_br
│ └── turnitintooltwo.php
├── ro
│ └── turnitintooltwo.php
├── ru
│ └── turnitintooltwo.php
├── sv
│ └── turnitintooltwo.php
├── tr
│ └── turnitintooltwo.php
├── vi
│ └── turnitintooltwo.php
├── zh_cn
│ └── turnitintooltwo.php
└── zh_tw
│ └── turnitintooltwo.php
├── lib.php
├── mod_form.php
├── package-lock.json
├── package.json
├── pix
├── back_disabled.png
├── back_enabled.png
├── back_enabled_hover.png
├── bootstrap
│ ├── glyphicons-halflings-white.png
│ └── glyphicons-halflings.png
├── changelog
│ └── resetcourse.png
├── clear.png
├── clearpixel.gif
├── colorbox
│ ├── controls.png
│ └── loading.gif
├── doc-x-grey.png
├── enrolicon.gif
├── fileicon.gif
├── forward_disabled.png
├── forward_enabled.png
├── forward_enabled_hover.png
├── globe.png
├── icon-dot.png
├── icon-student-read.png
├── icon.gif
├── icon.png
├── jqueryui
│ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ ├── ui-bg_flat_75_ffffff_40x100.png
│ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ ├── ui-bg_glass_65_ffffff_1x400.png
│ ├── ui-bg_glass_75_dadada_1x400.png
│ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ ├── ui-bg_glass_95_fef1ec_1x400.png
│ ├── ui-bg_highlight-soft_75_cccccc_1x100.png
│ ├── ui-icons_222222_256x240.png
│ ├── ui-icons_2e83ff_256x240.png
│ ├── ui-icons_454545_256x240.png
│ ├── ui-icons_888888_256x240.png
│ └── ui-icons_cd0a0a_256x240.png
├── loader-lrg.gif
├── loader.gif
├── loading.gif
├── minus.gif
├── nextdisabled.png
├── nextenabled.png
├── order_down.gif
├── order_up.gif
├── peermark-reviews.png
├── peermark-settings.png
├── plus.gif
├── prevdisabled.png
├── prevenabled.png
├── printer.png
├── quickmark.png
├── receipt.png
├── refresh.gif
├── refreshfade.gif
├── rubric.png
├── sort_asc.png
├── sort_asc_disabled.png
├── sort_both.png
├── sort_desc.png
├── sort_desc_disabled.png
├── sortdown.png
├── sortnone.png
├── sortup.png
├── tick.png
├── tii-icon.png
└── tii-logo.png
├── sass
├── _other.scss
├── _utilities.scss
├── _variables.scss
├── partials
│ ├── _digital_receipt.scss
│ ├── _eula.scss
│ ├── _inbox.scss
│ ├── _listbar.scss
│ ├── _members.scss
│ ├── _modal.scss
│ ├── _part_details.scss
│ └── _table.scss
├── settings_partials
│ ├── _class_migration_tab.scss
│ └── _settings_tab.scss
└── styles.scss
├── sdk
├── api.class.php
├── assignmentsoap.class.php
├── classsoap.class.php
├── log.class.php
├── logger.php
├── lti.class.php
├── membershipsoap.class.php
├── oauthsimple.class.php
├── perflog.class.php
├── response.class.php
├── sdkexception.class.php
├── soap.class.php
├── submissionsoap.class.php
├── tiiassignment.class.php
├── tiiclass.class.php
├── tiiform.class.php
├── tiilti.class.php
├── tiimembership.class.php
├── tiipeermarkassignment.class.php
├── tiipseudouser.class.php
├── tiirubric.class.php
├── tiisubmission.class.php
├── tiiuser.class.php
├── usersoap.class.php
└── wsdl
│ ├── lis-coursesection.wsdl
│ ├── lis-lineitem.wsdl
│ ├── lis-membership.wsdl
│ ├── lis-person.wsdl
│ └── lis-result.wsdl
├── settings.php
├── settings_extras.php
├── settingslib.php
├── styles.css
├── styles.css.map
├── templates
└── modal_migration_tool.mustache
├── tests
└── unit
│ ├── classes
│ ├── digitalreceipt
│ │ ├── instructor_message_test.php
│ │ └── receipt_message_test.php
│ ├── nonsubmitters
│ │ └── nonsubmitters_message_test.php
│ ├── privacy
│ │ └── provider_test.php
│ ├── v1migration
│ │ └── v1migration_test.php
│ └── view
│ │ ├── members_test.php
│ │ └── turnitintooltwo_view_test.php
│ ├── generator
│ └── lib.php
│ ├── lib_test.php
│ ├── mod_form_test.php
│ ├── turnitintooltwo_assignment_test.php
│ ├── turnitintooltwo_comms_test.php
│ └── turnitintooltwo_submission_test.php
├── turnitintooltwo_assignment.class.php
├── turnitintooltwo_class.class.php
├── turnitintooltwo_comms.class.php
├── turnitintooltwo_form.class.php
├── turnitintooltwo_perflog.class.php
├── turnitintooltwo_submission.class.php
├── turnitintooltwo_user.class.php
├── turnitintooltwo_view.class.php
├── version.php
└── view.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .git
3 | .vscode/
4 |
5 | # Ignore Node.js modules
6 | node_modules/
7 | /.settings/
8 | /.buildpath
9 | /.project
10 | /.idea
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | sudo: false
4 |
5 | cache:
6 | directories:
7 | - $HOME/.composer/cache
8 |
9 | php:
10 | - 7.1
11 | - 7.2
12 |
13 | services:
14 | - mysql
15 | - postgresql
16 |
17 | env:
18 | global:
19 | - IGNORE_PATHS=sdk/,fonts/,pix/
20 | - IGNORE_NAMES=jquery*,moment.js,colorbox.css,tooltipster.css,*.min.css,*.min.js,tii-icon-webfont.css,styles.css,styles.css.map,gulpfile.js
21 | matrix:
22 | - DB=pgsql MOODLE_BRANCH=MOODLE_36_STABLE
23 | - DB=mysqli MOODLE_BRANCH=MOODLE_36_STABLE
24 | - DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE
25 | - DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE
26 | - DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE
27 | - DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE
28 |
29 | before_install:
30 | - phpenv config-rm xdebug.ini
31 | - cd ../..
32 | - composer selfupdate
33 | - composer create-project -n --no-dev --prefer-dist blackboard-open-source/moodle-plugin-ci ci ^1
34 | - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH"
35 |
36 | install:
37 | - moodle-plugin-ci install
38 |
39 | script:
40 | - moodle-plugin-ci phplint
41 | - moodle-plugin-ci phpmd
42 | - moodle-plugin-ci csslint
43 | - moodle-plugin-ci shifter
44 | - moodle-plugin-ci validate
45 | - moodle-plugin-ci phpunit
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Announcement - Issues page merged with Turnitin's support page
2 | ================
3 |
4 | In order to be able to better monitor incoming issues, we are consolidating the 3 issues pages for the 2 plagiarism plugins and Direct v2 with our existing support area.
5 |
6 | The support area is how our team currently monitors issues for every other area of Turnitin. Therefore, we will be closing the Issues pages. If you have issues with Turnitin Direct v2, please raise them here: https://helpcenter.turnitin.com/hc/en-us/requests/new
7 |
8 | The team appreciates your ongoing support and contributions. Thank you!
9 |
10 | Moodle Direct v2
11 | ================
12 |
13 | Please be aware that the **Develop** branch should not be considered production ready, although it contains the latest fixes and features it may contain bugs. It should be avoided in favour of the **Master** branch which is the latest available branch that has been through the QA process. Please make any pull requests you would like to make to the develop branch.
14 |
15 | To see what has changed in recent versions of Moodle Direct V2, see the [CHANGELOG](https://github.com/turnitin/moodle-mod_turnitintooltwo/blob/master/CHANGELOG.md).
16 |
17 | If you are having issues, please consult our [TROUBLE SHOOTING](https://github.com/turnitin/moodle-mod_turnitintooltwo/blob/master/TROUBLESHOOTING.md) page.
18 |
19 | Installation
20 | ------------
21 |
22 | Before installing these plugins firstly make sure you are logged in as an Administrator and that you are using Moodle 3.5 or higher.
23 |
24 | To install, all you need to do is copy all the files into the mod/turnitintooltwo directory on your moodle installation. You should then go to `"Site Administration" > "Notifications"` and follow the on screen instructions.
25 |
26 | To configure the plugin go to `"Site Administration" > "Plugins" > "Activity Modules" > "Turnitin Assignment 2"` and enter your Turnitin account Id, shared key and API URL.
27 |
28 | **Note:** *The API connection URL is different for this package to previous Turnitin plugins. It should be https://api.turnitin.com, https://api.turnitinuk.com. or https://sandbox.turnitin.com.*
29 |
30 | Testing
31 | -------
32 |
33 | Please see the [testing instructions](./TESTING.md) for detail instructions on running the unit tests.
34 |
35 | Contributions
36 | ------------------------------
37 |
38 | We welcome contributions to all elements of the plugin. Since launch we've had a number of users provide us with fixes and enhancements through either pull request or commits linked to from the issues page. If you are interested in contributing enhancements, or would like to solve an issue raised by another user, please feel free to make a pull request against the develop branch.
39 |
40 | ------------------------------
--------------------------------------------------------------------------------
/TESTING.md:
--------------------------------------------------------------------------------
1 | # Testing
2 | To run the unit tests you will require PHP, Composer, a working Moodle installation and an installed copy of the plugin. The following guide explains how to do this.
3 |
4 | ## Set up a local Moodle environment
5 | You may well have a local Moodle setup already. If so, skip this step.
6 |
7 | If not, the easiet way to get Moodle set up on a Mac is with the MAMP Moodle installers.
8 |
9 | Grab an installer for the latest stable version from here:
10 |
11 | [https://download.moodle.org/macosx/](https://download.moodle.org/macosx/)
12 |
13 | ## Set up PHP
14 |
15 | You will need PHP and [Composer](https://getcomposer.org/) installed.
16 |
17 | ## Install the plugin
18 | Grab a copy of the plugin.
19 |
20 | [https://github.com/turnitin/moodle-mod_turnitintooltwo](https://github.com/turnitin/moodle-mod_turnitintooltwo)
21 |
22 | Put the plugin in the `mod` folder inside your Moodle installation.
23 |
24 | Go to the admin notifications screen in Moodle to install the plugin.
25 |
26 | ## Prepare Moodle for running unit tests
27 |
28 | * `cd` into the root folder of your Moodle installation. From here run `composer install` to install the required dependencies.
29 |
30 | * Edit `config.php` in the root of the Moodle folder and add the `phpunit` config. The following works for the MAMP Moodle install mentioned above:
31 |
32 | ```
33 | $CFG->phpunit_prefix = 'phpu_';
34 | $CFG->phpunit_dataroot = '/Applications/MAMP/data/phpu_moodledata';
35 | $CFG->phpunit_dbtype = 'mysqli'; // 'pgsql', 'mariadb', 'mysqli', 'mssql', 'sqlsrv' or 'oci'
36 | $CFG->phpunit_dbhost = '127.0.0.1:8889'; // eg 'localhost' or 'db.isp.com' or IP
37 | $CFG->phpunit_dbname = 'moodle31'; // database name, eg moodle
38 | $CFG->phpunit_dbuser = 'moodle'; // your database username
39 | $CFG->phpunit_dbpass = 'moodle'; // your database password
40 | ```
41 |
42 | * Run `php admin/tool/phpunit/cli/init.php`
43 |
44 | ## Run the tests
45 |
46 | To run the test commands, make sure you are in the root directory of Moodle.
47 |
48 | Run the whole test suite:
49 |
50 | `vendor/bin/phpunit --testsuite mod_turnitintooltwo_testsuite`
51 |
52 | Run only a specific test file:
53 |
54 | `vendor/bin/phpunit -v mod/turnitintooltwo/tests/unit/classes/digitalreceipt/receipt_message_test.php`
55 |
56 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/amd/build/migration_tool_launch.min.js:
--------------------------------------------------------------------------------
1 | define(["jquery","core/templates","core/modal_factory","core/modal_events","mod_turnitintooltwo/modal_migration_tool","mod_turnitintooltwo/migration_tool_migrate"],function(a,b,c,d,e,f){return{migration_tool_launch:function(){a.ajax({dataType:"json",type:"POST",url:M.cfg.wwwroot+"/mod/turnitintooltwo/ajax.php",data:{action:"check_migrated",turnitintoolid:a("#migrate_type").data("turnitintoolid"),sesskey:M.cfg.sesskey},success:function(b){b.migrated===!0?window.location.href=M.cfg.wwwroot+"/mod/turnitintooltwo/view.php?id="+b.v2id:c.create({type:e.TYPE}).then(function(b){b.show(),2===a("#migrate_type").data("migratetype")&&(a(".asktomigrate").hide(),a(".migrating").show(),f.migration_tool_migrate(a("#migrate_type").data("courseid"),a("#migrate_type").data("turnitintoolid")))})}})}}});
--------------------------------------------------------------------------------
/amd/build/migration_tool_migrate.min.js:
--------------------------------------------------------------------------------
1 | define(["jquery"],function(a){return{migration_tool_migrate:function(b,c){a.ajax({dataType:"json",type:"POST",url:M.cfg.wwwroot+"/mod/turnitintooltwo/ajax.php",data:{action:"begin_migration",courseid:b,turnitintoolid:c,sesskey:M.cfg.sesskey},success:function(a){window.location.href=M.cfg.wwwroot+"/mod/turnitintooltwo/view.php?id="+a.id},error:function(b){var c=b.responseJSON;a("#turnitintool_style").prepend('
'+c.error+" "+c.message+"
")}})}}});
--------------------------------------------------------------------------------
/amd/build/modal_migration_tool.min.js:
--------------------------------------------------------------------------------
1 | define(["jquery","core/notification","core/custom_interaction_events","core/modal","core/modal_registry","core/modal_events","core/config","mod_turnitintooltwo/migration_tool_migrate"],function(a,b,c,d,e,f,g,h){var i=!1,j={MIGRATE_BUTTON:'[data-action="migrate-assignment"]',CANCEL_BUTTON:'[data-action="cancel"]'},k=function(a){d.call(this,a)};return k.TYPE="mod_turnitintooltwo-migration_tool",k.prototype=Object.create(d.prototype),k.prototype.constructor=k,k.prototype.registerEventListeners=function(){d.prototype.registerEventListeners.call(this),this.getModal().on(c.events.activate,j.MIGRATE_BUTTON,function(){a(".asktomigrate").hide(),a(".migrating").show(),h.migration_tool_migrate(a("#migrate_type").data("courseid"),a("#migrate_type").data("turnitintoolid"))}.bind(this)),this.getModal().on(c.events.activate,j.CANCEL_BUTTON,function(b,c){var d=a.Event(f.cancel);this.getRoot().trigger(d,this),d.isDefaultPrevented()||(this.hide(),c.originalEvent.preventDefault())}.bind(this))},i||(e.register(k.TYPE,k,"mod_turnitintooltwo/modal_migration_tool"),i=!0),k});
--------------------------------------------------------------------------------
/amd/src/migration_tool_launch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Javascript controller for launching the migration tool modal.
3 | *
4 | * @package turnitintooltwo
5 | * @copyright Turnitin
6 | * @author 2019 David Winn
7 | * @module mod_turnitintooltwo/migration_tool_launch
8 | */
9 |
10 | define(['jquery',
11 | 'core/templates',
12 | 'core/modal_factory',
13 | 'core/modal_events',
14 | 'mod_turnitintooltwo/modal_migration_tool',
15 | 'mod_turnitintooltwo/migration_tool_migrate'
16 | ],
17 | function($, Templates, ModalFactory, ModalEvents, ModalMigrationTool, MigrationToolMigrate) {
18 | return {
19 | migration_tool_launch: function() {
20 | // Check whether this assignment has been migrated in this session and redirect if so.
21 | $.ajax({
22 | "dataType": 'json',
23 | "type": "POST",
24 | "url": M.cfg.wwwroot + "/mod/turnitintooltwo/ajax.php",
25 | "data": {
26 | action: "check_migrated",
27 | turnitintoolid: $("#migrate_type").data("turnitintoolid"),
28 | sesskey: M.cfg.sesskey
29 | },
30 | "success": function(data) {
31 | if (data.migrated === true) {
32 | window.location.href = M.cfg.wwwroot + "/mod/turnitintooltwo/view.php?id="+data.v2id;
33 | } else {
34 | ModalFactory.create({
35 | type: ModalMigrationTool.TYPE
36 | })
37 | .then(function(modal) {
38 | modal.show();
39 |
40 | // During automatic migration, we don't need to ask to migrate.
41 | if ($('#migrate_type').data("migratetype") === 2) {
42 | $('.asktomigrate').hide();
43 | $('.migrating').show();
44 |
45 | MigrationToolMigrate.migration_tool_migrate(
46 | $("#migrate_type").data("courseid"),
47 | $("#migrate_type").data("turnitintoolid")
48 | );
49 | }
50 | });
51 | }
52 | }
53 | });
54 | }
55 | };
56 | }
57 | );
--------------------------------------------------------------------------------
/amd/src/migration_tool_migrate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Javascript module for handling the migration of an assignment.
3 | *
4 | * @package turnitintooltwo
5 | * @copyright Turnitin
6 | * @author 2019 David Winn
7 | * @module mod_turnitintooltwo/migration_tool_migrate
8 | */
9 |
10 | define(['jquery'],
11 | function($) {
12 | return {
13 | migration_tool_migrate: function(courseid, turnitintoolid) {
14 | $.ajax({
15 | "dataType": 'json',
16 | "type": "POST",
17 | url: M.cfg.wwwroot + "/mod/turnitintooltwo/ajax.php",
18 | "data": {action: "begin_migration", courseid: courseid, turnitintoolid: turnitintoolid, sesskey: M.cfg.sesskey},
19 | success: function(data) {
20 | window.location.href = M.cfg.wwwroot + "/mod/turnitintooltwo/view.php?id="+data.id;
21 | },
22 | error: function(error) {
23 | var data = error.responseJSON;
24 | $('#turnitintool_style')
25 | .prepend('' +
26 | data.error + ' ' + data.message + '
');
27 | }
28 | });
29 | }
30 | };
31 | }
32 | );
--------------------------------------------------------------------------------
/amd/src/modal_migration_tool.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Javascript controller for the migration tool modal.
3 | *
4 | * @package turnitintooltwo
5 | * @copyright Turnitin
6 | * @author 2019 David Winn
7 | * @module mod_turnitintooltwo/migration_tool
8 | */
9 |
10 | define([
11 | 'jquery',
12 | 'core/notification',
13 | 'core/custom_interaction_events',
14 | 'core/modal',
15 | 'core/modal_registry',
16 | 'core/modal_events',
17 | 'core/config',
18 | 'mod_turnitintooltwo/migration_tool_migrate'
19 | ],
20 | function($, Notification, CustomEvents, Modal, ModalRegistry, ModalEvents, Config, MigrationToolMigrate) {
21 |
22 | var registered = false;
23 | var SELECTORS = {
24 | MIGRATE_BUTTON: '[data-action="migrate-assignment"]',
25 | CANCEL_BUTTON: '[data-action="cancel"]'
26 | };
27 |
28 | /**
29 | * Constructor for the Modal.
30 | *
31 | * @param {object} root The root jQuery element for the modal
32 | */
33 | var ModalMigrationTool = function(root) {
34 | Modal.call(this, root);
35 | };
36 |
37 | ModalMigrationTool.TYPE = 'mod_turnitintooltwo-migration_tool';
38 | ModalMigrationTool.prototype = Object.create(Modal.prototype);
39 | ModalMigrationTool.prototype.constructor = ModalMigrationTool;
40 |
41 | /**
42 | * Set up all of the event handling for the modal.
43 | *
44 | * @method registerEventListeners
45 | */
46 | ModalMigrationTool.prototype.registerEventListeners = function() {
47 | // Apply parent event listeners.
48 | Modal.prototype.registerEventListeners.call(this);
49 |
50 | // Fired during a manual migration when clicking to migrate the assignment. Initiate the migration process.
51 | this.getModal().on(CustomEvents.events.activate, SELECTORS.MIGRATE_BUTTON, function() {
52 | $('.asktomigrate').hide();
53 | $('.migrating').show();
54 |
55 | MigrationToolMigrate.migration_tool_migrate(
56 | $("#migrate_type").data("courseid"),
57 | $("#migrate_type").data("turnitintoolid")
58 | );
59 | }.bind(this));
60 |
61 | // On cancel, then hide the modal.
62 | this.getModal().on(CustomEvents.events.activate, SELECTORS.CANCEL_BUTTON, function(e, data) {
63 |
64 | var cancelEvent = $.Event(ModalEvents.cancel);
65 | this.getRoot().trigger(cancelEvent, this);
66 |
67 | if (!cancelEvent.isDefaultPrevented()) {
68 | this.hide();
69 | data.originalEvent.preventDefault();
70 | }
71 | }.bind(this));
72 | };
73 |
74 | // Automatically register with the modal registry the first time this module is imported so that
75 | // you can create modals of this type using the modal factory.
76 | if (!registered) {
77 | ModalRegistry.register(ModalMigrationTool.TYPE, ModalMigrationTool, 'mod_turnitintooltwo/modal_migration_tool');
78 | registered = true;
79 | }
80 |
81 | return ModalMigrationTool;
82 | }
83 | );
--------------------------------------------------------------------------------
/backup/moodle2/backup_turnitintooltwo_activity_task.class.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 | require_once($CFG->dirroot . '/mod/turnitintooltwo/backup/moodle2/backup_turnitintooltwo_stepslib.php');
27 |
28 | /**
29 | * turnitintooltwo backup task that provides all the settings and steps to perform one
30 | * complete backup of the activity
31 | */
32 | class backup_turnitintooltwo_activity_task extends backup_activity_task {
33 |
34 | // Define (add) particular settings this activity can have.
35 | protected function define_my_settings() {
36 | // No particular settings for this activity.
37 | }
38 |
39 | // Define (add) particular steps this activity can have.
40 | protected function define_my_steps() {
41 | // Choice only has one structure step.
42 | $this->add_step(new backup_turnitintooltwo_activity_structure_step('turnitintooltwo_structure', 'turnitintooltwo.xml'));
43 | }
44 |
45 | // Code the transformations to perform in the activity in order to get transportable (encoded) links.
46 | static public function encode_content_links($content) {
47 | global $CFG;
48 |
49 | $base = preg_quote($CFG->wwwroot, "/");
50 |
51 | // Link to the list of turnitintooltwos.
52 | $search = "/(".$base."\/mod\/turnitintooltwo\/index.php\?id\=)([0-9]+)/";
53 | $content = preg_replace($search, '$@TURNITINTOOLTWOINDEX*$2@$', $content);
54 |
55 | // Link to turnitintooltwo view by moduleid.
56 | $search = "/(".$base."\/mod\/turnitintooltwo\/view.php\?id\=)([0-9]+)/";
57 | $content = preg_replace($search, '$@TURNITINTOOLTWOVIEWBYID*$2@$', $content);
58 |
59 | return $content;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/backup/moodle2/restore_turnitintooltwo_activity_task.class.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 | require_once($CFG->dirroot . '/mod/turnitintooltwo/backup/moodle2/restore_turnitintooltwo_stepslib.php');
27 |
28 | /**
29 | * Choice restore task that provides all the settings and steps to perform one
30 | * complete restore of the activity.
31 | */
32 | class restore_turnitintooltwo_activity_task extends restore_activity_task {
33 |
34 | /**
35 | * Define (add) particular settings this activity can have.
36 | */
37 | protected function define_my_settings() {
38 | // No particular settings for this activity.
39 | }
40 |
41 | /**
42 | * Define (add) particular steps this activity can have.
43 | */
44 | protected function define_my_steps() {
45 | // Choice only has one structure step.
46 | $this->add_step(new restore_turnitintooltwo_activity_structure_step('turnitintooltwo_structure', 'turnitintooltwo.xml'));
47 | }
48 |
49 | /**
50 | * Define the contents in the activity that must be
51 | * processed by the link decoder
52 | */
53 | static public function define_decode_contents() {
54 | $contents = array();
55 |
56 | $contents[] = new restore_decode_content('turnitintooltwo', array('intro'), 'turnitintooltwo');
57 |
58 | return $contents;
59 | }
60 |
61 | /**
62 | * Define the decoding rules for links belonging
63 | * to the activity to be executed by the link decoder
64 | */
65 | static public function define_decode_rules() {
66 | $rules = array();
67 |
68 | $rules[] = new restore_decode_rule('TURNITINTOOLTWOVIEWBYID', '/mod/turnitintooltwo/view.php?id=$1', 'course_module');
69 | $rules[] = new restore_decode_rule('TURNITINTOOLTWOINDEX', '/mod/turnitintooltwo/index.php?id=$1', 'course');
70 |
71 | return $rules;
72 | }
73 |
74 | /**
75 | * If no user data was restored after everything has been restored then
76 | * create a new course in Turnitin.
77 | */
78 | public function after_restore() {
79 | global $DB, $CFG;
80 |
81 | if (!empty($_SESSION['tii_course_reset'])) {
82 |
83 | $course = turnitintooltwo_assignment::get_course_data($_SESSION['course_id']);
84 |
85 | // Get the main site admin.
86 | $admins = explode(",", $CFG->siteadmins);
87 | $ownerid = $admins[0];
88 |
89 | // Get the number of assignments that already exist on this course that aren't part of recreation.
90 | $assignments = 0;
91 | if (!empty($_SESSION['assignments_to_create'])) {
92 | $modules = $_SESSION['assignments_to_create'];
93 | list($notinsql, $notinparams) = $DB->get_in_or_equal($modules, SQL_PARAMS_QM, 'param', false);
94 | $assignments = $DB->count_records_select('turnitintooltwo', " course = ? AND id ".
95 | $notinsql, array_merge(array($_SESSION['course_id']), $notinparams));
96 | }
97 |
98 | // Only recreate course on Turnitin if Turnitin Assignments don't exist on destination course.
99 | if ($assignments == 0) {
100 | // Remove Turnitin link from course.
101 | $turnitincourse = new stdClass();
102 | $turnitincourse->id = $course->tii_rel_id;
103 | $turnitincourse->turnitin_cid = 0;
104 | $DB->update_record('turnitintooltwo_courses', $turnitincourse);
105 |
106 | // Recreate course in Turnitin.
107 | $course->turnitin_cid = 0;
108 | $tmpassignment = new turnitintooltwo_assignment(0, '', '');
109 | $turnitincourse = $tmpassignment->create_tii_course($course, $ownerid);
110 |
111 | // Join the course as Instructor.
112 | $owner = new turnitintooltwo_user($ownerid, 'Instructor');
113 | $owner->join_user_to_class($turnitincourse->turnitin_cid);
114 | }
115 |
116 | unset($_SESSION['tii_course_reset']);
117 | unset($_SESSION['course_id']);
118 | }
119 |
120 | if (!empty($_SESSION['assignments_to_create'])) {
121 | foreach ($_SESSION["assignments_to_create"] as $newassignmentid) {
122 | $assignment = new turnitintooltwo_assignment($newassignmentid);
123 | $assignment->unlink_assignment();
124 | $assignment->edit_moodle_assignment(true, true);
125 | }
126 | unset($_SESSION['tii_assignment_reset']);
127 | unset($_SESSION['assignments_to_create']);
128 | }
129 |
130 | }
131 |
132 | /**
133 | * Define the restore log rules that will be applied by the {@link restore_logs_processor}
134 | * when restoring {@link restore_log_rule} objects.
135 | */
136 | static public function define_restore_log_rules() {
137 | $rules = array();
138 |
139 | $rules[] = new restore_log_rule('turnitintooltwo', 'view', 'view.php?id={course_module}', '{turnitintooltwo}');
140 | $rules[] = new restore_log_rule('turnitintooltwo', 'add', 'view.php?id={course_module}', '{turnitintooltwo}');
141 | $rules[] = new restore_log_rule('turnitintooltwo', 'update', 'view.php?id={course_module}', '{turnitintooltwo}');
142 | $rules[] = new restore_log_rule('turnitintooltwo', 'delete', 'view.php?id={course_module}', '{turnitintooltwo}');
143 | $rules[] = new restore_log_rule('turnitintooltwo', 'submit', 'view.php?id={course_module}', '{turnitintooltwo}');
144 |
145 | return $rules;
146 | }
147 |
148 | /**
149 | * Define the restore log rules that will be applied by the {@link restore_logs_processor}
150 | * when restoring {@link restore_log_rule} objects.
151 | */
152 | static public function define_restore_log_rules_for_course() {
153 | $rules = array();
154 | return $rules;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/classes/digitalreceipt/instructor_message.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | class instructor_message {
20 |
21 | /**
22 | * Build a modified receipt to send to instructors upon a submission being made.
23 | * This message must preserve the anonymity of a submission.
24 | *
25 | * @param array $input - used to build message
26 | * @return string
27 | */
28 | public function build_instructor_message($input) {
29 | $message = new stdClass();
30 | $message->submission_title = $input['submission_title'];
31 | $message->assignment_name = $input['assignment_name'];
32 | if ( isset($input['assignment_part']) ) {
33 | $message->assignment_part = ": " . $input['assignment_part'];
34 | } else {
35 | $message->assignment_part = "";
36 | }
37 | $message->course_fullname = $input['course_fullname'];
38 | $message->submission_date = $input['submission_date'];
39 | $message->submission_id = $input['submission_id'];
40 |
41 | return format_string(get_string('receipt_instructor_copy', 'turnitintooltwo', $message));
42 | }
43 |
44 | /**
45 | * Send instructor message to instructors on course.
46 | *
47 | * @param array $instructors
48 | * @param string $message
49 | * @return void
50 | */
51 | public function send_instructor_message($instructors, $message, $courseid) {
52 | global $CFG;
53 |
54 | $subject = get_string('receipt_instructor_copy_subject', 'turnitintooltwo');
55 |
56 | $eventdata = new \core\message\message();
57 |
58 | $eventdata->component = 'mod_turnitintooltwo';
59 | $eventdata->name = 'notify_instructor_of_submission'; // This is the message name from messages.php.
60 | $eventdata->userfrom = \core_user::get_noreply_user();
61 | $eventdata->subject = $subject;
62 | $eventdata->fullmessage = $message;
63 | $eventdata->fullmessageformat = FORMAT_HTML;
64 | $eventdata->fullmessagehtml = $message;
65 | $eventdata->smallmessage = '';
66 | $eventdata->notification = 1; // This is only set to 0 for personal messages between users.
67 |
68 | if ($CFG->branch >= 32) {
69 | $eventdata->courseid = $courseid;
70 | }
71 |
72 | foreach ($instructors as $instructor) {
73 |
74 | $eventdata->userto = $instructor->id;
75 | message_send($eventdata);
76 | }
77 | unset($instructor);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/classes/digitalreceipt/receipt_message.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | class receipt_message {
20 |
21 | /**
22 | * Send digital receipt to submitter
23 | *
24 | * @param string $message
25 | * @return void
26 | */
27 | public function send_message($userid, $message, $courseid) {
28 | global $CFG;
29 |
30 | $subject = get_string('digital_receipt_subject', 'turnitintooltwo');
31 |
32 | $eventdata = new \core\message\message();
33 |
34 | $eventdata->component = 'mod_turnitintooltwo';
35 | $eventdata->name = 'submission'; // This is the message name from messages.php.
36 | $eventdata->userfrom = \core_user::get_noreply_user();
37 | $eventdata->userto = $userid;
38 | $eventdata->subject = $subject;
39 | $eventdata->fullmessage = $message;
40 | $eventdata->fullmessageformat = FORMAT_HTML;
41 | $eventdata->fullmessagehtml = $message;
42 | $eventdata->smallmessage = '';
43 | $eventdata->notification = 1; // This is only set to 0 for personal messages between users.
44 |
45 | if ($CFG->branch >= 32) {
46 | $eventdata->courseid = $courseid;
47 | }
48 |
49 | message_send($eventdata);
50 | }
51 |
52 | /**
53 | * Build message to send to user
54 | *
55 | * @param array $input - used to build message
56 | * @return string
57 | */
58 | public function build_message($input) {
59 | $message = new stdClass();
60 | $message->firstname = $input['firstname'];
61 | $message->lastname = $input['lastname'];
62 | $message->submission_title = $input['submission_title'];
63 | $message->assignment_name = $input['assignment_name'];
64 | if ( isset($input['assignment_part']) ) {
65 | $message->assignment_part = ": " . $input['assignment_part'];
66 | } else {
67 | $message->assignment_part = "";
68 | }
69 | $message->course_fullname = $input['course_fullname'];
70 | $message->submission_date = $input['submission_date'];
71 | $message->submission_id = $input['submission_id'];
72 |
73 | return format_string(get_string('digital_receipt_message', 'turnitintooltwo', $message));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/classes/event/add_submission.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2012 iParadigms LLC *
20 | */
21 | namespace mod_turnitintooltwo\event;
22 |
23 | /*
24 | * Log event when paper is submitted either by student or instructor on behalf of student.
25 | */
26 |
27 | defined('MOODLE_INTERNAL') || die();
28 |
29 | class add_submission extends \core\event\base {
30 | protected function init() {
31 | $this->data['crud'] = 'c';
32 | $this->data['level'] = self::LEVEL_PARTICIPATING; // For 2.6, this appears to have been renamed to 'edulevel' in 2.7.
33 | $this->data['edulevel'] = self::LEVEL_PARTICIPATING;
34 | $this->data['objecttable'] = 'turnitintooltwo';
35 | }
36 |
37 | public static function get_name() {
38 | return get_string('addsubmission', 'mod_turnitintooltwo');
39 | }
40 |
41 | public function get_description() {
42 | return $this->other['desc'];
43 | }
44 |
45 | public function get_url() {
46 | return new \moodle_url('/mod/turnitintooltwo/view.php', array( 'id' => $this->objectid));
47 | }
48 |
49 | /**
50 | * Custom validation.
51 | *
52 | * @throws \coding_exception
53 | * @return void
54 | */
55 | protected function validate_data() {
56 | parent::validate_data();
57 | if (!isset($this->other['desc'])) {
58 | throw new \coding_exception('The \'desc\' value must be set in other.');
59 | }
60 |
61 | if ($this->contextlevel != CONTEXT_MODULE) {
62 | throw new \coding_exception('Context level must be CONTEXT_MODULE.');
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/classes/event/delete_submission.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | namespace mod_turnitintooltwo\event;
18 |
19 | /*
20 | * Log event when submission is deleted
21 | */
22 |
23 | defined('MOODLE_INTERNAL') || die();
24 |
25 | class delete_submission extends \core\event\base {
26 | protected function init() {
27 | $this->data['crud'] = 'd';
28 | $this->data['level'] = self::LEVEL_PARTICIPATING; // For 2.6, this appears to have been renamed to 'edulevel' in 2.7.
29 | $this->data['edulevel'] = self::LEVEL_PARTICIPATING;
30 | $this->data['objecttable'] = 'turnitintooltwo';
31 | }
32 |
33 | public static function get_name() {
34 | return get_string('deletesubmission', 'mod_turnitintooltwo');
35 | }
36 |
37 | public function get_description() {
38 | return $this->other['desc'];
39 | }
40 |
41 | public function get_url() {
42 | return new \moodle_url('/mod/turnitintooltwo/view.php', array( 'id' => $this->objectid));
43 | }
44 |
45 | /**
46 | * Custom validation.
47 | *
48 | * @throws \coding_exception
49 | * @return void
50 | */
51 | protected function validate_data() {
52 | parent::validate_data();
53 | if (!isset($this->other['desc'])) {
54 | throw new \coding_exception('The \'desc\' value must be set in other.');
55 | }
56 |
57 | if ($this->contextlevel != CONTEXT_MODULE) {
58 | throw new \coding_exception('Context level must be CONTEXT_MODULE.');
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/classes/event/list_submissions.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | namespace mod_turnitintooltwo\event;
18 |
19 | /*
20 | * Log event when
21 | */
22 |
23 | defined('MOODLE_INTERNAL') || die();
24 |
25 | class list_submissions extends \core\event\base {
26 | protected function init() {
27 | $this->data['crud'] = 'r';
28 | $this->data['level'] = self::LEVEL_PARTICIPATING; // For 2.6, this appears to have been renamed to 'edulevel' in 2.7.
29 | $this->data['edulevel'] = self::LEVEL_PARTICIPATING;
30 | $this->data['objecttable'] = 'turnitintooltwo';
31 | }
32 |
33 | public static function get_name() {
34 | return get_string('listsubmissions', 'mod_turnitintooltwo');
35 | }
36 |
37 | public function get_description() {
38 | return $this->other['desc'];
39 | }
40 |
41 | public function get_url() {
42 | return new \moodle_url('/mod/turnitintooltwo/view.php', array( 'id' => $this->objectid));
43 | }
44 |
45 | /**
46 | * Custom validation.
47 | *
48 | * @throws \coding_exception
49 | * @return void
50 | */
51 | protected function validate_data() {
52 | parent::validate_data();
53 | if (!isset($this->other['desc'])) {
54 | throw new \coding_exception('The \'desc\' value must be set in other.');
55 | }
56 |
57 | if ($this->contextlevel != CONTEXT_MODULE) {
58 | throw new \coding_exception('Context level must be CONTEXT_MODULE.');
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/classes/event/migrate_assignment.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2012 iParadigms LLC *
20 | */
21 | namespace mod_turnitintooltwo\event;
22 |
23 | /*
24 | * Log event when paper is submitted either by student or instructor on behalf of student.
25 | */
26 |
27 | defined('MOODLE_INTERNAL') || die();
28 |
29 | class migrate_assignment extends \core\event\base {
30 | protected function init() {
31 | $this->data['crud'] = 'c';
32 | $this->data['level'] = self::LEVEL_PARTICIPATING; // For 2.6, this appears to have been renamed to 'edulevel' in 2.7.
33 | $this->data['edulevel'] = self::LEVEL_PARTICIPATING;
34 | $this->data['objecttable'] = 'turnitintooltwo';
35 | }
36 |
37 | public static function get_name() {
38 | return get_string('migration_event_name', 'turnitintooltwo');
39 | }
40 |
41 | public function get_description() {
42 | return $this->other['desc'];
43 | }
44 |
45 | public function get_url() {
46 | return new \moodle_url('/mod/turnitintooltwo/view.php', array( 'id' => $this->objectid));
47 | }
48 |
49 | /**
50 | * Custom validation.
51 | *
52 | * @throws \coding_exception
53 | * @return void
54 | */
55 | protected function validate_data() {
56 | parent::validate_data();
57 | if (!isset($this->other['desc'])) {
58 | throw new \coding_exception('The \'desc\' value must be set in other.');
59 | }
60 |
61 | if ($this->contextlevel != CONTEXT_MODULE) {
62 | throw new \coding_exception('Context level must be CONTEXT_MODULE.');
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/classes/event/view_submission.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | namespace mod_turnitintooltwo\event;
18 |
19 | defined('MOODLE_INTERNAL') || die();
20 |
21 | class view_submission extends \core\event\base {
22 | protected function init() {
23 | $this->data['crud'] = 'r';
24 | $this->data['level'] = self::LEVEL_PARTICIPATING; // For 2.6, this appears to have been renamed to 'edulevel' in 2.7.
25 | $this->data['edulevel'] = self::LEVEL_PARTICIPATING;
26 | $this->data['objecttable'] = 'turnitintooltwo';
27 | }
28 |
29 | public static function get_name() {
30 | return get_string('viewsubmission', 'mod_turnitintooltwo');
31 | }
32 |
33 | public function get_description() {
34 | return $this->other['desc'];
35 | }
36 |
37 | public function get_url() {
38 | return new \moodle_url('/mod/turnitintooltwo/view.php', array( 'id' => $this->objectid));
39 | }
40 |
41 | /**
42 | * Custom validation.
43 | *
44 | * @throws \coding_exception
45 | * @return void
46 | */
47 | protected function validate_data() {
48 | parent::validate_data();
49 | if (!isset($this->other['desc'])) {
50 | throw new \coding_exception('The \'desc\' value must be set in other.');
51 | }
52 |
53 | if ($this->contextlevel != CONTEXT_MODULE) {
54 | throw new \coding_exception('Context level must be CONTEXT_MODULE.');
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/classes/nonsubmitters/nonsubmitters_message.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | class nonsubmitters_message {
20 |
21 | /**
22 | * Send non-submitters message to students.
23 | *
24 | * @param string $message
25 | * @return void
26 | */
27 | public function send_message($userid, $subject, $message, $courseid) {
28 | global $CFG;
29 |
30 | $eventdata = new \core\message\message();
31 | $eventdata->component = 'mod_turnitintooltwo';
32 | $eventdata->name = 'nonsubmitters'; // This is the message name from messages.php.
33 | $eventdata->userfrom = \core_user::get_noreply_user();
34 | $eventdata->userto = $userid;
35 | $eventdata->subject = $subject;
36 | $eventdata->fullmessage = $message;
37 | $eventdata->fullmessageformat = FORMAT_HTML;
38 | $eventdata->fullmessagehtml = $message;
39 | $eventdata->smallmessage = '';
40 | $eventdata->notification = 1; // This is only set to 0 for personal messages between users.
41 |
42 | if ($CFG->branch >= 32) {
43 | $eventdata->courseid = $courseid;
44 | }
45 |
46 | message_send($eventdata);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/classes/task/turnitintooltwo_task.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | namespace mod_turnitintooltwo\task;
18 |
19 | defined('MOODLE_INTERNAL') || die();
20 |
21 | /**
22 | * Library function for turnitintooltwo task function.
23 | */
24 |
25 | class turnitintooltwo_task extends \core\task\scheduled_task {
26 |
27 | public function get_name() {
28 | // Shown in admin screens.
29 | return get_string('task_name', 'mod_turnitintooltwo');
30 | }
31 |
32 | /**
33 | * Do the job.
34 | * Throw exceptions on errors (the job will be retried).
35 | */
36 | public function execute() {
37 | global $CFG, $tiitaskcall;
38 |
39 | // Run turnitintooltwo cron.
40 | require_once("{$CFG->dirroot}/mod/turnitintooltwo/lib.php");
41 | $tiitaskcall = true;
42 | turnitintooltwo_cron();
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/css/hide_bg.css:
--------------------------------------------------------------------------------
1 | html {
2 | background:none;
3 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/css/student_noscript.css:
--------------------------------------------------------------------------------
1 | .mod_turnitintooltwo_submissions_data_table {
2 | margin-top:16px;
3 | }
4 |
5 | .mod_turnitintooltwo_submissions_data_table th {
6 | border:1px solid #999999;
7 | }
8 |
9 | .mod_turnitintooltwo_submissions_data_table td {
10 | border:1px solid #999999;
11 | }
12 |
13 | .mod_turnitintooltwo #tabs ul#part_tabs_menu, .mod_turnitintooltwo a.toggle_summary, .mod_turnitintooltwo a.toggle_peermarks,
14 | .mod_turnitintooltwo a.toggle_peermark_instructions, .mod_turnitintooltwo .mod_turnitintooltwo_eula, .mod_turnitintooltwo_messages_inbox,
15 | .mod_turnitintooltwo .noscript_hide, .mod_turnitintooltwo .download_original_open, .mod_turnitintooltwo th.raw_data,
16 | .mod_turnitintooltwo td.raw_data, .mod_turnitintooltwo_submissions_data_table th.cpart,
17 | .mod_turnitintooltwo_submissions_data_table th.ccheckbox, .mod_turnitintooltwo_submissions_data_table td.c0,
18 | .mod_turnitintooltwo_submissions_data_table td.c1 {
19 | display:none;
20 | }
21 |
22 | .mod_turnitintooltwo .peermark_instructions {
23 | display: block;
24 | }
25 |
26 | .mod_turnitintooltwo .part_table {
27 | background:#EFEFEF;
28 | border:1px solid #DEDEDE;
29 | padding:10px;
30 | }
--------------------------------------------------------------------------------
/css/styles_block.css:
--------------------------------------------------------------------------------
1 | .block_turnitin .centered_cell {
2 | text-align:center;
3 | }
4 |
5 | .block_turnitin #block_loading {
6 | display:none;
7 | }
--------------------------------------------------------------------------------
/db/access.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2010 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | $capabilities = array(
25 |
26 | 'mod/turnitintooltwo:view' => array(
27 |
28 | 'captype' => 'read',
29 | 'contextlevel' => CONTEXT_MODULE,
30 | 'legacy' => array(
31 | 'guest' => CAP_ALLOW,
32 | 'student' => CAP_ALLOW,
33 | 'teacher' => CAP_ALLOW,
34 | 'editingteacher' => CAP_ALLOW
35 | )
36 | ),
37 |
38 | 'mod/turnitintooltwo:read' => array(
39 |
40 | 'captype' => 'read',
41 | 'contextlevel' => CONTEXT_MODULE,
42 | 'legacy' => array(
43 | 'student' => CAP_ALLOW,
44 | 'teacher' => CAP_ALLOW,
45 | 'editingteacher' => CAP_ALLOW
46 | )
47 | ),
48 |
49 | 'mod/turnitintooltwo:submit' => array(
50 |
51 | 'captype' => 'write',
52 | 'contextlevel' => CONTEXT_MODULE,
53 | 'legacy' => array(
54 | 'student' => CAP_ALLOW
55 | )
56 | ),
57 |
58 | 'mod/turnitintooltwo:grade' => array(
59 |
60 | 'captype' => 'write',
61 | 'contextlevel' => CONTEXT_MODULE,
62 | 'legacy' => array(
63 | 'teacher' => CAP_ALLOW,
64 | 'editingteacher' => CAP_ALLOW
65 | )
66 | ),
67 |
68 | 'mod/turnitintooltwo:addinstance' => array(
69 | 'riskbitmask' => RISK_XSS,
70 | 'captype' => 'write',
71 | 'contextlevel' => CONTEXT_MODULE,
72 |
73 | 'legacy' => array(
74 | 'teacher' => CAP_ALLOW,
75 | 'editingteacher' => CAP_ALLOW
76 | ),
77 | 'clonepermissionsfrom' => 'moodle/course:manageactivities'
78 | )
79 | );
--------------------------------------------------------------------------------
/db/install.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2019 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | /**
25 | * This method is called by Moodle after parsing install.xml upon installation of the plugin. It is only ran once.
26 | */
27 | function xmldb_turnitintooltwo_install() {
28 |
29 | if (v1installed()) {
30 | copyStudentPrivacySettings();
31 | }
32 | }
33 |
34 | /**
35 | * Check whether v1 is installed.
36 | */
37 | function v1installed() {
38 | global $DB;
39 |
40 | $module = $DB->get_record('config_plugins', array('plugin' => 'mod_turnitintool'));
41 | return boolval($module);
42 | }
43 |
44 | /**
45 | * If a Moodle administrator wants to use Moodle Direct V2 having already been using V1, we should copy across
46 | * the student privacy settings upon installation because they can't be changed once submissions have been made.
47 | *
48 | * @throws dml_exception
49 | */
50 | function copyStudentPrivacySettings() {
51 | global $DB;
52 |
53 | // We can't use get_config() as the config values from V1 aren't stored in mdl_config_plugins.
54 | $data = $DB->get_records_sql("SELECT name, value FROM {config} WHERE name LIKE 'turnitin_%'");
55 |
56 | // The student privacy settings we would like to copy across.
57 | $properties = array("enablepseudo", "pseudofirstname", "pseudolastname", "lastnamegen", "pseudosalt", "pseudoemaildomain");
58 |
59 | // Loop through each setting and set the value in V2.
60 | foreach ($properties as $property) {
61 | if (isset($data["turnitin_".$property])) {
62 | set_config($property, $data["turnitin_".$property]->value, 'turnitintooltwo');
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/db/log.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2010 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | $logs = array(
25 | array('module' => 'turnitintooltwo', 'action' => 'view', 'mtable' => 'turnitintooltwo', 'field' => 'name'),
26 | array('module' => 'turnitintooltwo', 'action' => 'add', 'mtable' => 'turnitintooltwo', 'field' => 'name'),
27 | array('module' => 'turnitintooltwo', 'action' => 'update', 'mtable' => 'turnitintooltwo', 'field' => 'name')
28 | );
--------------------------------------------------------------------------------
/db/messages.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2010 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 | $messageproviders = array (
24 | // Notify student with their digital receipt.
25 | 'submission' => array (
26 | ),
27 | // Notify nonsubmitters for an assignment.
28 | 'nonsubmitters' => array (),
29 | // Notify instructors with their copy of the digital receipt.
30 | 'notify_instructor_of_submission' => array (
31 | )
32 | );
--------------------------------------------------------------------------------
/db/tasks.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | */
20 |
21 | defined('MOODLE_INTERNAL') || die();
22 |
23 | $tasks = array(
24 | array(
25 | 'classname' => 'mod_turnitintooltwo\task\turnitintooltwo_task',
26 | 'blocking' => 0,
27 | 'minute' => '*/5',
28 | 'hour' => '*',
29 | 'day' => '*',
30 | 'dayofweek' => '*',
31 | 'month' => '*'
32 | )
33 | );
--------------------------------------------------------------------------------
/fonts/tii-icon-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/fonts/tii-icon-webfont.eot
--------------------------------------------------------------------------------
/fonts/tii-icon-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/fonts/tii-icon-webfont.ttf
--------------------------------------------------------------------------------
/fonts/tii-icon-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/fonts/tii-icon-webfont.woff
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | const sass = require('gulp-sass')(require('sass'));
3 |
4 | var minifyCss = require('gulp-clean-css');
5 | var sourcemaps = require('gulp-sourcemaps');
6 | var notify = require('gulp-notify');
7 | var uglify = require('gulp-uglify');
8 | var rename = require('gulp-rename');
9 |
10 | gulp.task('sass', function() {
11 | return gulp.src('./sass/styles.scss')
12 | .pipe(sourcemaps.init())
13 | .pipe(sass().on('error', sass.logError))
14 | .pipe(minifyCss())
15 | .pipe(sourcemaps.write('.'))
16 | .pipe(gulp.dest('.'))
17 | .pipe(notify("CSS Compiled!"));
18 | });
19 |
20 | gulp.task('jsmin', function() {
21 | return gulp.src(['./jquery/turnitintooltwo*.js', '!./jquery/turnitintooltwo*.min.js'])
22 | .pipe(sourcemaps.init())
23 | .pipe(uglify().on('error', function(e){
24 | console.log(e);
25 | }))
26 | .pipe(rename({suffix: '.min'}))
27 | .pipe(sourcemaps.write())
28 | .pipe(gulp.dest('./jquery/'))
29 | .pipe(notify('js minified'));
30 | });
31 |
32 | gulp.task('watch', function() {
33 | gulp.watch('./sass/**/*.scss', gulp.series('sass'));
34 | gulp.watch('./jquery/turnitintooltwo*.js', gulp.series('jsmin'));
35 | });
36 |
37 | gulp.task('default', gulp.series(['sass', 'jsmin', 'watch']));
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2010 iParadigms LLC
20 | */
21 |
22 | require_once(__DIR__."/../../config.php");
23 | require_once(__DIR__."/lib.php");
24 | require_once(__DIR__."/turnitintooltwo_view.class.php");
25 |
26 | $turnitintooltwoview = new turnitintooltwo_view();
27 |
28 | // Load Javascript and CSS.
29 | $turnitintooltwoview->load_page_components();
30 |
31 | $id = required_param('id', PARAM_INT); // Course id.
32 |
33 | // Configure URL correctly.
34 | $urlparams = array('id' => $id);
35 | $url = new moodle_url('/mod/turnitintooltwo/index.php', $urlparams);
36 |
37 | // Get course data.
38 | if (!$course = $DB->get_record("course", array("id" => $id))) {
39 | turnitintooltwo_print_error('courseiderror', 'turnitintooltwo');
40 | }
41 |
42 | require_login($course->id);
43 |
44 | // Print the header.
45 | $turnitintooltwoview->output_header($url, get_string("modulenameplural", "turnitintooltwo"), $SITE->fullname);
46 |
47 | echo $turnitintooltwoview->show_assignments($course);
48 |
49 | echo $OUTPUT->footer();
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/jquery/jquery.cookie.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Cookie Plugin v1.3.1
3 | * https://github.com/carhartl/jquery-cookie
4 | *
5 | * Copyright 2013 Klaus Hartl
6 | * Released under the MIT license
7 | */
8 | (function (factory) {
9 | if (typeof define === 'function' && define.amd && define.amd.jQuery) {
10 | // AMD. Register as anonymous module.
11 | define(['jquery'], factory);
12 | } else {
13 | // Browser globals.
14 | factory(jQuery);
15 | }
16 | }(function ($) {
17 |
18 | var pluses = /\+/g;
19 |
20 | function raw(s) {
21 | return s;
22 | }
23 |
24 | function decoded(s) {
25 | return decodeURIComponent(s.replace(pluses, ' '));
26 | }
27 |
28 | function converted(s) {
29 | if (s.indexOf('"') === 0) {
30 | // This is a quoted cookie as according to RFC2068, unescape.
31 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
32 | }
33 | try {
34 | return config.json ? JSON.parse(s) : s;
35 | } catch(er) {}
36 | }
37 |
38 | var config = $.cookie = function (key, value, options) {
39 |
40 | // Write.
41 | if (value !== undefined) {
42 | options = $.extend({}, config.defaults, options);
43 |
44 | if (typeof options.expires === 'number') {
45 | var days = options.expires, t = options.expires = new Date();
46 | t.setDate(t.getDate() + days);
47 | }
48 |
49 | value = config.json ? JSON.stringify(value) : String(value);
50 |
51 | return (document.cookie = [
52 | encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
53 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // Use expires attribute, max-age is not supported by IE.
54 | options.path ? '; path=' + options.path : '',
55 | options.domain ? '; domain=' + options.domain : '',
56 | options.secure ? '; secure' : ''
57 | ].join(''));
58 | }
59 |
60 | // Read.
61 | var decode = config.raw ? raw : decoded;
62 | var cookies = document.cookie.split('; ');
63 | var result = key ? undefined : {};
64 | for (var i = 0, l = cookies.length; i < l; i++) {
65 | var parts = cookies[i].split('=');
66 | var name = decode(parts.shift());
67 | var cookie = decode(parts.join('='));
68 |
69 | if (key && key === name) {
70 | result = converted(cookie);
71 | break;
72 | }
73 |
74 | if (!key) {
75 | result[name] = converted(cookie);
76 | }
77 | }
78 |
79 | return result;
80 | };
81 |
82 | config.defaults = {};
83 |
84 | $.removeCookie = function (key, options) {
85 | if ($.cookie(key) !== undefined) {
86 | $.cookie(key, '', $.extend(options, { expires: -1 }));
87 | return true;
88 | }
89 | return false;
90 | };
91 |
92 | }));
93 |
--------------------------------------------------------------------------------
/jquery/jquery.dataTables.plugins.js:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this template, choose Tools | Templates
3 | * and open the template in the editor.
4 | */
5 |
6 | $.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
7 | if(oSettings.oFeatures.bServerSide === false){
8 | var before = oSettings._iDisplayStart;
9 |
10 | oSettings.oApi._fnReDraw(oSettings);
11 |
12 | // Var iDisplayStart has been reset to zero - so lets change it back.
13 | oSettings._iDisplayStart = before;
14 | oSettings.oApi._fnCalculateEnd(oSettings);
15 | }
16 |
17 | // Draw the 'current' page.
18 | oSettings.oApi._fnDraw(oSettings);
19 | };
20 |
21 | $.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, fnCallback, bStandingRedraw) {
22 | if (typeof sNewSource != 'undefined' && sNewSource != null) {
23 | oSettings.sAjaxSource = sNewSource;
24 | }
25 | this.oApi._fnProcessingDisplay( oSettings, true );
26 | var that = this;
27 | var iStart = oSettings._iDisplayStart;
28 |
29 | oSettings.fnServerData(oSettings.sAjaxSource, null, function(json) {
30 | /* Clear the old information from the table */
31 | that.oApi._fnClearTable( oSettings );
32 |
33 | /* Got the data - add it to the table */
34 | for (var i = 0; i < json.aaData.length; i++) {
35 | that.oApi._fnAddData( oSettings, json.aaData[i] );
36 | }
37 |
38 | oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
39 | that.fnDraw(that);
40 |
41 | if (typeof bStandingRedraw != 'undefined' && bStandingRedraw === true) {
42 | oSettings._iDisplayStart = iStart;
43 | that.fnDraw(false);
44 | }
45 |
46 | that.oApi._fnProcessingDisplay(oSettings, false);
47 |
48 | /* Callback user function - for event handlers etc */
49 | if (typeof fnCallback == 'function' && fnCallback != null) {
50 | fnCallback(oSettings);
51 | }
52 | });
53 | };
54 |
55 | $.fn.dataTableExt.oApi.fnSetFilteringDelay = function ( oSettings, iDelay ) {
56 | var _that = this;
57 | this.each( function ( i ) {
58 | $.fn.dataTableExt.iApiIndex = i;
59 | iDelay = (iDelay && (/^[0-9]+$/.test(iDelay))) ? iDelay : 250;
60 |
61 | var $this = this, oTimerId;
62 | var anControl = $( 'input', _that.fnSettings().aanFeatures.f );
63 |
64 | anControl.unbind( 'keyup' ).bind( 'keyup', function() {
65 | var $$this = $this;
66 | window.clearTimeout(oTimerId);
67 |
68 | oTimerId = window.setTimeout(function() {
69 | $.fn.dataTableExt.iApiIndex = i;
70 | _that.fnFilter( anControl.val() );
71 | }, iDelay);
72 | });
73 |
74 | return this;
75 | } );
76 | return this;
77 | };
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/jquery/plugins.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | $plugins = array(
20 | 'turnitintooltwo-dataTables' => array('files' => array('jquery.dataTables.js', 'jquery.dataTables.css')),
21 | 'turnitintooltwo-dataTables_plugins' => array('files' => array('jquery.dataTables.plugins.js')),
22 | 'turnitintooltwo-turnitintooltwo' => array('files' => array('turnitintooltwo-2025070302.min.js')),
23 | 'turnitintooltwo-turnitintooltwo_extra' => array('files' => array('turnitintooltwo_extra-2024120301.min.js')),
24 | 'turnitintooltwo-turnitintooltwo_settings' => array('files' => array('turnitintooltwo_settings-2025070302.min.js')),
25 | 'turnitintooltwo-datatables_columnfilter' => array('files' => array('jquery.dataTables.columnFilter.js')),
26 | 'turnitintooltwo-cookie' => array('files' => array('jquery.cookie.js')),
27 | 'turnitintooltwo-colorbox' => array('files' => array('jquery.colorbox.js', 'colorbox.css')),
28 | 'turnitintooltwo-uieditable' => array('files' => array('jqueryui-editable.js', 'jqueryui-editable.css')),
29 | 'turnitintooltwo-moment' => array('files' => array('moment.js')),
30 | 'turnitintooltwo-tooltipster' => array('files' => array('tooltipster.js', 'tooltipster.css')),
31 | 'turnitintooltwo-migration_tool' => array('files' => array()) // Required as this is called from V1.
32 | );
--------------------------------------------------------------------------------
/jquery/turnitintooltwo_settings-2025070302.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This small piece of script is a workaround that's needed to add tabs in to
3 | * the settings page. They need to be removed from the settings form and placed
4 | * outside that containing fieldset.
5 | */
6 | $(document).ready(function($) {
7 | if ($('.settingsform fieldset div.formsettingheading').length > 0) {
8 | var tabmenu = $('.settingsform fieldset div.formsettingheading:first').html();
9 | if (tabmenu.indexOf("tabtree") >= 0) {
10 | $('.settingsform fieldset div.formsettingheading:first').remove();
11 | $('.settingsform h2:first').after(tabmenu);
12 | }
13 | }
14 |
15 | $('input[name="selectallcb"]').click(function() {
16 | if ($(this).prop('checked')) {
17 | $('.browser_checkbox').prop('checked', true);
18 | if ($('.browser_checkbox:checked').length > 0) {
19 | $('.create_checkboxes').slideDown();
20 | } else {
21 | $('.create_checkboxes').slideUp();
22 | }
23 | } else {
24 | $('.browser_checkbox').prop('checked', false);
25 | $('.create_checkboxes').slideUp();
26 | }
27 | });
28 |
29 | if ($('.test_connection').length > 0) {
30 | if ($('#id_s_turnitintooltwo_accountid').val() != '' || $('#id_s_turnitintooltwo_secretkey').val() != '') {
31 | $('.test_connection').show();
32 | $('#test_link').show();
33 | }
34 |
35 | $('#id_s_turnitintooltwo_accountid, #id_s_turnitintooltwo_secretkey, #id_s_turnitintooltwo_apiurl').keyup(function() {
36 | $('#testing_container').hide();
37 |
38 | var accountid = $('#id_s_turnitintooltwo_accountid').val();
39 | var accountshared = $('#id_s_turnitintooltwo_secretkey').val();
40 |
41 | // Make sure they aren't empty strings.
42 | accountid = accountid.trim();
43 | accountshared = accountshared.trim();
44 | if (accountid.length == 0 || accountshared.length == 0) {
45 | $('#test_result').hide();
46 | $('.test_connection').hide();
47 | } else {
48 | $('.test_connection').show();
49 | $('#test_link').show();
50 | }
51 | });
52 |
53 | $('#test_link').click(function() {
54 | $('#test_result').hide();
55 | $('input, #id_s_turnitintooltwo_apiurl').prop('disabled', true);
56 | $('#test_link').hide();
57 | $("#test_result").css('opacity', '');
58 | $('#test_result').removeClass('test_link_success test_link_fail');
59 | $('#testing_container').show();
60 |
61 | // Change Url depending on Settings page.
62 | url = M.cfg.wwwroot + "/mod/turnitintooltwo/ajax.php";
63 |
64 | var accountid = $('#id_s_turnitintooltwo_accountid').val();
65 | var accountshared = $('#id_s_turnitintooltwo_secretkey').val();
66 | var accounturl = $('#id_s_turnitintooltwo_apiurl').val();
67 |
68 | $.ajax({
69 | type: "POST",
70 | url: url,
71 | dataType: "json",
72 | data: {action: "test_connection", sesskey: M.cfg.sesskey, accountid: accountid, accountshared: accountshared, url: accounturl},
73 | success: function(data) {
74 | eval(data);
75 |
76 | $('#testing_container').hide();
77 |
78 | if (data.connection_status == "success") {
79 | $('#test_result').addClass('test_link_success');
80 | } else {
81 | $('#test_result').addClass('test_link_fail');
82 | }
83 |
84 | $('#test_result').html(data.msg);
85 | $('#test_result').show();
86 | $('#test_link').show();
87 | $('input, #id_s_turnitintooltwo_apiurl').prop('disabled', false);
88 | }
89 | });
90 | });
91 | }
92 | });
--------------------------------------------------------------------------------
/jquery/turnitintooltwo_settings-2025070302.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"turnitintooltwo_settings-2025070302.min.js.map","sources":["turnitintooltwo_settings-2025070302.js"],"names":["$","document","ready","tabmenu","length","html","indexOf","remove","after","click","this","prop","slideDown","slideUp","val","show","keyup","hide","accountid","accountshared","trim","css","removeClass","url","M","cfg","wwwroot","accounturl","ajax","type","dataType","data","action","sesskey","success","eval","connection_status","addClass","msg"],"mappings":"AAKAA,EAAEC,QAAQ,EAAEC,MAAM,SAASF,GACvB,IACQG,QADwD,EAA5DH,EAAE,+CAA+C,EAAEI,SAC/CD,QAAUH,EAAE,qDAAqD,EAAEK,KAAK,EAC1C,GAA9BF,QAAQG,QAAQ,SAAS,KACzBN,EAAE,qDAAqD,EAAEO,OAAO,EAChEP,EAAE,wBAAwB,EAAEQ,MAAML,OAAO,GAIjDH,EAAE,2BAA2B,EAAES,MAAM,WAC7BT,EAAEU,IAAI,EAAEC,KAAK,SAAS,GACtBX,EAAE,mBAAmB,EAAEW,KAAK,UAAW,CAAA,CAAI,EACC,EAAxCX,EAAE,2BAA2B,EAAEI,OAC/BJ,EAAE,oBAAoB,EAAEY,UAAU,EAElCZ,EAAE,oBAAoB,EAAEa,QAAQ,IAGpCb,EAAE,mBAAmB,EAAEW,KAAK,UAAW,CAAA,CAAK,EAC5CX,EAAE,oBAAoB,EAAEa,QAAQ,EAExC,CAAC,EAEkC,EAA/Bb,EAAE,kBAAkB,EAAEI,SAC4B,IAA9CJ,EAAE,iCAAiC,EAAEc,IAAI,GAAyD,IAA9Cd,EAAE,iCAAiC,EAAEc,IAAI,IAC7Fd,EAAE,kBAAkB,EAAEe,KAAK,EAC3Bf,EAAE,YAAY,EAAEe,KAAK,GAGzBf,EAAE,gGAAgG,EAAEgB,MAAM,WACtGhB,EAAE,oBAAoB,EAAEiB,KAAK,EAE7B,IAAIC,EAAYlB,EAAE,iCAAiC,EAAEc,IAAI,EACrDK,EAAgBnB,EAAE,iCAAiC,EAAEc,IAAI,EAG7DI,EAAYA,EAAUE,KAAK,EAC3BD,EAAgBA,EAAcC,KAAK,EACX,GAApBF,EAAUd,QAAuC,GAAxBe,EAAcf,QACvCJ,EAAE,cAAc,EAAEiB,KAAK,EACvBjB,EAAE,kBAAkB,EAAEiB,KAAK,IAE3BjB,EAAE,kBAAkB,EAAEe,KAAK,EAC3Bf,EAAE,YAAY,EAAEe,KAAK,EAE7B,CAAC,EAEDf,EAAE,YAAY,EAAES,MAAM,WAClBT,EAAE,cAAc,EAAEiB,KAAK,EACvBjB,EAAE,qCAAqC,EAAEW,KAAK,WAAY,CAAA,CAAI,EAC9DX,EAAE,YAAY,EAAEiB,KAAK,EACrBjB,EAAE,cAAc,EAAEqB,IAAI,UAAW,EAAE,EACnCrB,EAAE,cAAc,EAAEsB,YAAY,kCAAkC,EAChEtB,EAAE,oBAAoB,EAAEe,KAAK,EAG7BQ,IAAMC,EAAEC,IAAIC,QAAU,gCAEtB,IAAIR,UAAYlB,EAAE,iCAAiC,EAAEc,IAAI,EACrDK,cAAgBnB,EAAE,iCAAiC,EAAEc,IAAI,EACzDa,WAAa3B,EAAE,8BAA8B,EAAEc,IAAI,EAEvDd,EAAE4B,KAAK,CACHC,KAAM,OACNN,IAAKA,IACLO,SAAU,OACVC,KAAM,CAACC,OAAQ,kBAAmBC,QAAST,EAAEC,IAAIQ,QAASf,UAAWA,UAAWC,cAAeA,cAAeI,IAAKI,UAAU,EAC7HO,QAAS,SAASH,MACdI,KAAKJ,IAAI,EAET/B,EAAE,oBAAoB,EAAEiB,KAAK,EAEC,WAA1Bc,KAAKK,kBACLpC,EAAE,cAAc,EAAEqC,SAAS,mBAAmB,EAE9CrC,EAAE,cAAc,EAAEqC,SAAS,gBAAgB,EAG/CrC,EAAE,cAAc,EAAEK,KAAK0B,KAAKO,GAAG,EAC/BtC,EAAE,cAAc,EAAEe,KAAK,EACvBf,EAAE,YAAY,EAAEe,KAAK,EACrBf,EAAE,qCAAqC,EAAEW,KAAK,WAAY,CAAA,CAAK,CACnE,CACJ,CAAC,CACL,CAAC,EAET,CAAC"}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turnitintooltwo",
3 | "version": "1.0.0",
4 | "description": "Moodle Direct v2 ================",
5 | "homepage": "https://github.com/turnitin/moodle-mod_turnitintooltwo#readme",
6 | "bugs": {
7 | "url": "https://github.com/turnitin/moodle-mod_turnitintooltwo/issues"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/turnitin/moodle-mod_turnitintooltwo.git"
12 | },
13 | "license": "GPL-3.0",
14 | "author": "",
15 | "type": "commonjs",
16 | "main": "gulpfile.js",
17 | "directories": {
18 | "test": "tests"
19 | },
20 | "overrides": {
21 | "gulp-sourcemaps": {
22 | "postcss": ">=8.4.31"
23 | }
24 | },
25 | "scripts": {
26 | "test": "echo \"Error: no test specified\" && exit 1"
27 | },
28 | "devDependencies": {
29 | "gulp": "^5.0.1",
30 | "gulp-clean-css": "^4.3.0",
31 | "gulp-notify": "^5.0.0",
32 | "gulp-rename": "^2.1.0",
33 | "gulp-sass": "^6.0.1",
34 | "gulp-sourcemaps": "^3.0.0",
35 | "gulp-uglify": "^3.0.2",
36 | "sass": "^1.89.2"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/pix/back_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/back_disabled.png
--------------------------------------------------------------------------------
/pix/back_enabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/back_enabled.png
--------------------------------------------------------------------------------
/pix/back_enabled_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/back_enabled_hover.png
--------------------------------------------------------------------------------
/pix/bootstrap/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/bootstrap/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/pix/bootstrap/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/bootstrap/glyphicons-halflings.png
--------------------------------------------------------------------------------
/pix/changelog/resetcourse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/changelog/resetcourse.png
--------------------------------------------------------------------------------
/pix/clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/clear.png
--------------------------------------------------------------------------------
/pix/clearpixel.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/clearpixel.gif
--------------------------------------------------------------------------------
/pix/colorbox/controls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/colorbox/controls.png
--------------------------------------------------------------------------------
/pix/colorbox/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/colorbox/loading.gif
--------------------------------------------------------------------------------
/pix/doc-x-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/doc-x-grey.png
--------------------------------------------------------------------------------
/pix/enrolicon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/enrolicon.gif
--------------------------------------------------------------------------------
/pix/fileicon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/fileicon.gif
--------------------------------------------------------------------------------
/pix/forward_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/forward_disabled.png
--------------------------------------------------------------------------------
/pix/forward_enabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/forward_enabled.png
--------------------------------------------------------------------------------
/pix/forward_enabled_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/forward_enabled_hover.png
--------------------------------------------------------------------------------
/pix/globe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/globe.png
--------------------------------------------------------------------------------
/pix/icon-dot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/icon-dot.png
--------------------------------------------------------------------------------
/pix/icon-student-read.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/icon-student-read.png
--------------------------------------------------------------------------------
/pix/icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/icon.gif
--------------------------------------------------------------------------------
/pix/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/icon.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/pix/jqueryui/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/jqueryui/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/pix/loader-lrg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/loader-lrg.gif
--------------------------------------------------------------------------------
/pix/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/loader.gif
--------------------------------------------------------------------------------
/pix/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/loading.gif
--------------------------------------------------------------------------------
/pix/minus.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/minus.gif
--------------------------------------------------------------------------------
/pix/nextdisabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/nextdisabled.png
--------------------------------------------------------------------------------
/pix/nextenabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/nextenabled.png
--------------------------------------------------------------------------------
/pix/order_down.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/order_down.gif
--------------------------------------------------------------------------------
/pix/order_up.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/order_up.gif
--------------------------------------------------------------------------------
/pix/peermark-reviews.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/peermark-reviews.png
--------------------------------------------------------------------------------
/pix/peermark-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/peermark-settings.png
--------------------------------------------------------------------------------
/pix/plus.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/plus.gif
--------------------------------------------------------------------------------
/pix/prevdisabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/prevdisabled.png
--------------------------------------------------------------------------------
/pix/prevenabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/prevenabled.png
--------------------------------------------------------------------------------
/pix/printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/printer.png
--------------------------------------------------------------------------------
/pix/quickmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/quickmark.png
--------------------------------------------------------------------------------
/pix/receipt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/receipt.png
--------------------------------------------------------------------------------
/pix/refresh.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/refresh.gif
--------------------------------------------------------------------------------
/pix/refreshfade.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/refreshfade.gif
--------------------------------------------------------------------------------
/pix/rubric.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/rubric.png
--------------------------------------------------------------------------------
/pix/sort_asc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sort_asc.png
--------------------------------------------------------------------------------
/pix/sort_asc_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sort_asc_disabled.png
--------------------------------------------------------------------------------
/pix/sort_both.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sort_both.png
--------------------------------------------------------------------------------
/pix/sort_desc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sort_desc.png
--------------------------------------------------------------------------------
/pix/sort_desc_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sort_desc_disabled.png
--------------------------------------------------------------------------------
/pix/sortdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sortdown.png
--------------------------------------------------------------------------------
/pix/sortnone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sortnone.png
--------------------------------------------------------------------------------
/pix/sortup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/sortup.png
--------------------------------------------------------------------------------
/pix/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/tick.png
--------------------------------------------------------------------------------
/pix/tii-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/tii-icon.png
--------------------------------------------------------------------------------
/pix/tii-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turnitin/moodle-mod_turnitintooltwo/67c2632ce32730196e4d1d5cc92d6db60faeb9ce/pix/tii-logo.png
--------------------------------------------------------------------------------
/sass/_utilities.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * Helpers and general styles
3 | */
4 |
5 | /*
6 | * Lets us clear floats for older moodles
7 | */
8 | .clearfix:after {
9 | content: ".";
10 | visibility: hidden;
11 | display: block;
12 | height: 0;
13 | clear: both;
14 | }
15 |
16 | .sr-only {
17 | position: absolute;
18 | width: 1px;
19 | height: 1px;
20 | padding: 0;
21 | margin: -1px;
22 | overflow: hidden;
23 | clip: rect(0,0,0,0);
24 | border: 0;
25 | }
26 |
27 | h3.main {
28 | line-height: 40px;
29 | }
30 |
31 | .mod_turnitintooltwo {
32 | .fitem_fbutton {
33 | padding-top:12px;
34 | }
35 |
36 | span.dimmed {
37 | color:#999999;
38 | }
39 |
40 | #assignmentBrowserTable_wrapper {
41 | padding: 10px;
42 | }
43 |
44 | .nowrap {
45 | white-space:nowrap;
46 | }
47 |
48 | .italic {
49 | font-style: italic;
50 | }
51 |
52 | .underline {
53 | text-decoration: underline;
54 | }
55 |
56 | .bold,
57 | #or_container {
58 | font-weight:bold;
59 | }
60 |
61 | span.link {
62 | color: #0000FF;
63 | }
64 | }
--------------------------------------------------------------------------------
/sass/_variables.scss:
--------------------------------------------------------------------------------
1 | // Colours
2 | $light-grey: #EFEFEF;
3 | $dark-grey: #A8A8A8;
4 | $light-blue: #bbe6ff;
5 | $light-blue2: #6fcaff;
6 | $gm-blue: #0070A8;
7 | $white: #fff;
8 | $red: #B94A48;
9 | $green: #19B719;
10 | $hover-blue: #00699e;
11 |
12 | // Digital Receipt Success;
13 | $bright-red: #CC0000;
14 |
15 | // Table border colours
16 | $border-color: $light-grey;
17 |
18 | // Odd / Even colours for table
19 | $odd-color: $light-grey;
20 | $even-color: $white;
21 |
22 | // Table padding
23 | $table-padding: 15px;
24 | $table-head-padding: $table-padding - 5px;
--------------------------------------------------------------------------------
/sass/partials/_digital_receipt.scss:
--------------------------------------------------------------------------------
1 | .mod_turnitintooltwo_digital_receipt {
2 | display: inline-block;
3 | width: 150px;
4 | }
5 |
6 | #mod_turnitintooltwo #box_receipt {
7 | padding:20px;
8 | }
9 |
10 | #mod_turnitintooltwo #box_receipt .icon {
11 | width:64px;
12 | height:64px;
13 | }
14 |
15 | #mod_turnitintooltwo_digital_receipt_box {
16 | padding: 20px;
17 | background: #fff;
18 |
19 | .mod_turnitintooltwo_logo {
20 | display: block;
21 | margin: 0 auto;
22 | width: 214px;
23 | height: 68px;
24 | }
25 |
26 | #mod_turnitintooltwo_receipt_print {
27 | text-align: right;
28 | display: block;
29 | }
30 |
31 | }
32 |
33 | #mod_turnitintooltwo_upload_success {
34 | color: $bright-red;
35 | }
--------------------------------------------------------------------------------
/sass/partials/_eula.scss:
--------------------------------------------------------------------------------
1 | .mod_turnitintooltwo_eula_text {
2 | padding-top: 15px;
3 | text-align: center;
4 | }
5 |
6 | .mod_turnitintooltwo_eula input[type="submit"] {
7 | margin: 0;
8 | }
9 |
10 | .mod_turnitintooltwo_eula {
11 | cursor:pointer;
12 | text-decoration: underline;
13 | text-align: center;
14 | border: 1px solid $bright-red;
15 | padding: 12px 12px 12px;
16 | color: $bright-red;
17 | margin-top:12px;
18 | margin-bottom:16px !important;
19 | font-size: 14px;
20 | font-weight: bold;
21 | display: block;
22 | }
23 |
24 | noscript.mod_turnitintooltwo_eula_noscript {
25 | border: 1px solid $bright-red;
26 | padding: 8px;
27 | background: $white;
28 | width: 99%;
29 | text-align:center;
30 | display:block;
31 | margin:16px 6px;
32 | line-height: 28px;
33 | }
34 |
35 | .mod_turnitintooltwo_eula_warn {
36 | color: $bright-red;
37 | }
--------------------------------------------------------------------------------
/sass/partials/_inbox.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * Tabs on inbox page - this is overriding jquery datatables styles.
3 | */
4 | .mod_turnitintooltwo .ui-widget-header {
5 | background: $light-grey !important;
6 | border: 0 !important;
7 | margin-bottom: 6px !important;
8 | }
9 |
10 | .mod_turnitintooltwo .ui-widget-content {
11 | border: 0 !important;
12 | }
13 |
14 | .mod_turnitintooltwo .ui-tabs .ui-tabs-panel {
15 | padding: 0 !important;
16 | }
17 |
18 | .mod_turnitintooltwo .ui-tabs .ui-tabs-nav {
19 | padding: 10px 10px 0 !important;
20 | }
21 |
22 | /*
23 | * Unanonymise form in modal
24 | */
25 | .mod_turnitintooltwo_unanonymise_form {
26 | background: #FFFFFF;
27 | padding: 12px 12px 0;
28 | height: 100%;
29 | overflow: hidden
30 | }
31 |
32 | #mod_turnitintooltwo_unanonymise_desc {
33 | text-align: center;
34 | font-weight: bold;
35 | display: block;
36 | margin-bottom: 10px;
37 | }
38 |
39 | .mod_turnitintooltwo_unanonymise_form textarea {
40 | height: 90px;
41 | width: 80%;
42 | }
43 |
44 | /*
45 | * Email non submitters form
46 | */
47 |
48 | .mod_turnitintooltwo_nonsubmittersform textarea {
49 | height: 90px;
50 | width: 80%;
51 | }
52 |
53 | .mod_turnitintooltwo_general_warning {
54 | margin-top: 8px;
55 | }
56 |
57 | .mod_turnitintooltwo_nonsubmittersformsuccessmsg {
58 | text-align: center;
59 | padding-top: 46px;
60 | }
61 |
62 | #mod_turnitintooltwo_download_links {
63 | margin-left: 15px;
64 | top: -5px;
65 | }
66 |
67 | #mod_turnitintooltwo_rubric_view_form {
68 | padding-left: 6px;
69 | }
70 |
71 | .mod_turnitintooltwo_peermark-loading-span img.icon {
72 | margin-right: 0px;
73 | }
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/sass/partials/_members.scss:
--------------------------------------------------------------------------------
1 | .mod_turnitintooltwo_members {
2 | // Overwrite datatables CSS for loading message to cover the whole table
3 | // accurately. By default datatables centers the loading message vertically
4 | // and horizontally but it is only the size of the message meaning a user
5 | // can click the content being loaded behind the message as the loading mask
6 | // won't cover it all. Fix is to create a loading mask that covers all the
7 | // loading content and position the message within the mask
8 | .dataTables_wrapper .dataTables_processing {
9 | // cover entire table that is loading
10 | top: 0px;
11 | left: 0px;
12 | right: 0px;
13 | height: 100%;
14 | margin: 0px;
15 | padding: 0px;
16 |
17 | .loading-message {
18 | // position message within loading element
19 | position: absolute;
20 | top: 50%;
21 | left: 0px;
22 | right: 0px;
23 | margin-top: -10px; // half line-height
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/sass/partials/_modal.scss:
--------------------------------------------------------------------------------
1 | /*
2 | 1. Styles within modal
3 | 2. Styles for actual colorbox modal
4 | 3. Styles for close bar at the top
5 | */
6 |
7 | /*
8 | * 1. Within the modal
9 | */
10 |
11 | .mod_turnitintooltwo #id_submissiontext {
12 | width: 80%;
13 | height: 320px;
14 | }
15 |
16 | /*
17 | * 2. Colorbox modal iframe
18 | */
19 | #colorbox {
20 | margin-top: 60px;
21 | outline: 0 !important;
22 | overflow: visible !important;
23 | }
24 |
25 | .cboxIframe {
26 | border-radius: 5px;
27 | }
28 |
29 | #cboxContent {
30 | margin-top: 0 !important;
31 | }
32 |
33 | /*
34 | * 3. Modal close bar
35 | */
36 | #tii_close_bar {
37 | position: fixed;
38 | z-index: 9999;
39 | right: 0;
40 | top: 0;
41 | width: 100%;
42 | height: 45px;
43 | background: rgba(0, 0, 0, .3);
44 |
45 | a {
46 | color: #fff;
47 | display: block;
48 | background: #000;
49 | width: 100px;
50 | text-align: center;
51 | float: right;
52 | text-decoration: none;
53 | height: 45px;
54 | line-height: 43px;
55 | }
56 | }
--------------------------------------------------------------------------------
/sass/partials/_part_details.scss:
--------------------------------------------------------------------------------
1 | .mod_turnitintooltwo_part_details {
2 | font-size: 13px;
3 | margin-bottom:0px;
4 | width:100%;
5 | border: 1px solid $border-color;
6 |
7 | tr {
8 | border-right: 1px solid $border-color;
9 | }
10 |
11 | th {
12 | padding: 6px 12px 6px;
13 | border-bottom: 1px solid $border-color;
14 | }
15 |
16 | td {
17 | border: 1px solid $border-color;
18 | border-top: 0;
19 | padding: 12px 12px 4px;
20 | }
21 |
22 | td.data,
23 | td.export_data,
24 | td.rubric_qm {
25 | text-align: center;
26 | }
27 |
28 | td.export_data {
29 | padding-top:12px;
30 | }
31 |
32 | td.introduction_cell {
33 | border:0;
34 | padding:0;
35 | }
36 |
37 | td.peermarks {
38 | border:0;
39 | }
40 |
41 | td.peermark_assignments_cell {
42 | padding:0;
43 | border:0;
44 | }
45 |
46 | .editable-click {
47 | border:none;
48 | position: relative;
49 | padding-right: 24px;
50 |
51 | &:hover {
52 | border-bottom: 0 !important;
53 | }
54 | }
55 |
56 | .editor-pencil {
57 | padding-left: 25px;
58 | }
59 |
60 | /*
61 | * Introduction (summary section)
62 | */
63 | .introduction,
64 | .peermark_instructions {
65 | padding: 6px 10px;
66 | border-bottom: 1px solid $border-color;
67 | display: none;
68 | }
69 |
70 | .introduction h2 {
71 | margin: 8px 0;
72 | }
73 |
74 | .introduction p {
75 | margin: 6px 0;
76 | }
77 |
78 | /*
79 | * Export options
80 | */
81 | .row_export_xls,
82 | .row_export_pdf,
83 | .row_export_orig,
84 | .mod_turnitintooltwo_zip_open,
85 | .row_rubric_manager,
86 | .row_quickmark_manager {
87 | display:inline;
88 | }
89 |
90 | .toggle_peermark_instructions img {
91 | display: block;
92 | }
93 |
94 | .toggle_summary,
95 | .toggle_peermarks,
96 | .toggle_peermark_instructions {
97 | cursor: pointer;
98 | float:left;
99 | position: relative;
100 | top:-3px;
101 | margin-right:8px;
102 | }
103 |
104 | .peermark_header {
105 | margin-bottom:8px;
106 | float:left;
107 | }
108 | }
109 |
110 | #turnitin_sync_all_grades {
111 | float: right;
112 | font-size: 16px;
113 | }
114 |
115 | .turnitin_sync_grades, .turnitin_syncing_grades {
116 | cursor: pointer;
117 | margin-bottom: 20px;
118 | }
119 |
120 | .turnitin_syncing_grades {
121 | display: none;
122 | }
123 |
124 | .mod_turnitintooltwo_peermark_details {
125 | width: 100%;
126 | border-top: 1px solid $border-color;
127 |
128 | td {
129 | padding:8px 12px;
130 | border-bottom-width: 0;
131 | }
132 |
133 | td.peermark_instructions_cell {
134 | border:0;
135 | padding:0;
136 | }
137 | }
138 |
139 | .mod_turnitintooltwo_quickmark_manager_launch {
140 | padding: 2px 0 2px 30px;
141 | height: 20px;
142 | color: #0070A8 !important;
143 | }
144 |
145 | .mod_turnitintooltwo_rubric_manager_launch,
146 | .mod_turnitintooltwo_rubric_view_launch {
147 | padding:4px 0px 4px 0px;
148 | line-height: 22px;
149 | color: #0070A8 !important;
150 | }
151 |
152 | .tii_peermark_manager_launch {
153 | color: #009900 !important;
154 | }
155 |
156 | .tii_peermark_reviews_launch {
157 | color: #009900 !important;
158 | }
159 |
160 | .tii_peermark_manager_launch,
161 | .tii_peermark_reviews_launch {
162 | padding: 4px 0 4px 46px;
163 | height: 22px;
164 | }
165 |
166 | .mod_turnitintooltwo .peermark_loading_row {
167 | text-align: center;
168 | margin:0 auto 8px;
169 | }
170 |
171 | @media screen and (max-width: 1400px) {
172 | td.cell {
173 | position: relative;
174 | }
175 |
176 | .mod_turnitintooltwo_part_details .editable-click {
177 | position: unset;
178 | &:before {
179 | top: 5px;
180 | right: 5px;
181 | }
182 | }
183 | }
--------------------------------------------------------------------------------
/sass/partials/_table.scss:
--------------------------------------------------------------------------------
1 | /*
2 | 1. DataTable Table
3 | 2. DataTable Pagination
4 | 3. Score colour
5 | */
6 |
7 |
8 | /*
9 | * 1. Table styles and related
10 | */
11 | .mod_turnitintooltwo_submissions_data_table,
12 | #mod_turnitintooltwo_course_browser_table {
13 | width:100%;
14 | font-size: 13px;
15 | border:1px solid $border-color;
16 | width:100% !important;
17 | margin-top: 6px !important;
18 |
19 | .ccheckbox {
20 | text-align: center;
21 | padding: 8px 10px 2px !important;
22 | }
23 |
24 | .odd {
25 | background: $odd-color !important;
26 |
27 | .sorting_1 {
28 | background: darken($odd-color, 3%) !important;
29 | }
30 | }
31 |
32 | .even {
33 | background: $even-color !important;
34 |
35 | .sorting_1 {
36 | background: darken($even-color, 2%) !important;
37 | }
38 | }
39 |
40 | a {
41 | text-decoration: none;
42 | }
43 |
44 | thead th {
45 | border-bottom: 0 !important;
46 | }
47 |
48 | th {
49 | padding: $table-head-padding 20px !important;
50 | }
51 |
52 | td {
53 | padding: $table-padding 10px !important;
54 | font-size: 13px;
55 | vertical-align: top;
56 | }
57 |
58 | .sorting_disabled {
59 | cursor: default;
60 | }
61 |
62 | .left {
63 | text-align: left;
64 | }
65 |
66 | .right {
67 | text-align: right;
68 | }
69 |
70 | .grademark_open,
71 | .grademark_grade,
72 | .origreport_score {
73 | float:right;
74 | }
75 |
76 | .grademark_grade,
77 | .origreport_score {
78 | padding-right:8px;
79 | }
80 |
81 | th.narrow,
82 | td.narrow {
83 | width: 60px;
84 | }
85 |
86 | .submit_nothing, .submission_title, .delete_paper {
87 | cursor: pointer;
88 | }
89 |
90 | .score_colour {
91 | width:36px;
92 | display:inline-block;
93 | float:right;
94 | }
95 |
96 | .late_submission {
97 | color: #d31900;
98 | }
99 |
100 | #tii_digital_receipt_icon {
101 | margin-top: -3px;
102 | margin-right: 5px;
103 | }
104 | }
105 |
106 | /*
107 | * 2. DataTables pagination
108 | */
109 | .dataTables_paginate {
110 | margin-top: 6px;
111 | font-size:12px;
112 | float: right;
113 |
114 | a {
115 | display: inline-block;
116 | border: 1px solid $border-color;
117 | padding: 2px 5px;
118 | background-position: left -2px;
119 | }
120 |
121 | .current {
122 | background: #EFEFEF;
123 | }
124 |
125 | span a {
126 | border-right: 0;
127 | }
128 |
129 | .previous {
130 | border-right: 0;
131 | }
132 |
133 | }
134 |
135 | .dataTables_info {
136 | float:left;
137 | clear:none;
138 | margin-top: 8px;
139 | text-transform: uppercase;
140 | font-size: 11px;
141 | }
142 |
143 |
144 | /*
145 | * 3. Score colour for originality report.
146 | */
147 | .mod_turnitintooltwo .score_colour_ { background: #999999; }
148 | .mod_turnitintooltwo .score_colour_0 { background: #3552B7; }
149 | .mod_turnitintooltwo .score_colour_10 { background: #617B8D; }
150 | .mod_turnitintooltwo .score_colour_20 { background: #A1B556; }
151 | .mod_turnitintooltwo .score_colour_30 { background: #DAE235; }
152 | .mod_turnitintooltwo .score_colour_40 { background: #EDAC28; }
153 | .mod_turnitintooltwo .score_colour_50 { background: #EDD42F; }
154 | .mod_turnitintooltwo .score_colour_60 { background: #ECAD28; }
155 | .mod_turnitintooltwo .score_colour_70 { background: #E15A21; }
156 | .mod_turnitintooltwo .score_colour_80 { background: #E05A21; }
157 | .mod_turnitintooltwo .score_colour_90 { background: #DC4321; }
158 | .mod_turnitintooltwo .score_colour_100 { background: #DB4221; }
159 |
160 |
161 | .mod_turnitintooltwo .enrol_link {
162 | padding: 6px 18px 0 0;
163 | }
--------------------------------------------------------------------------------
/sass/settings_partials/_class_migration_tab.scss:
--------------------------------------------------------------------------------
1 | /*
2 | Located at mod/turnitintooltwo/settings_extras.php?cmd=courses
3 | */
4 |
5 | .mod_turnitintooltwo_edit_course_end_date_form {
6 | padding: 12px 12px 0;
7 | background: $white;
8 | height: 100%;
9 | overflow: hidden;
10 |
11 | #edit_end_date_desc {
12 | text-align: center;
13 | margin-bottom: 20px;
14 | }
15 |
16 | .fitemtitle {
17 | float: none !important;
18 | text-align: center !important;
19 | width: 100% !important;
20 | display: block !important;
21 | }
22 |
23 | .fdate_selector {
24 | float: none !important;
25 | display: block !important;
26 | margin: 0 auto !important;
27 | width: 256px !important;
28 | }
29 |
30 | .fbutton {
31 | width: 100% !important;
32 | margin: 0 !important;
33 | }
34 |
35 | #id_save_end_date {
36 | margin: 0 auto !important;
37 | display: block !important;
38 | }
39 | }
--------------------------------------------------------------------------------
/sass/settings_partials/_settings_tab.scss:
--------------------------------------------------------------------------------
1 | #page-admin-setting-modsettingturnitintooltwo {
2 |
3 | #test_link,
4 | #testing_container {
5 | margin-bottom:8px;
6 | }
7 |
8 | #test_link img {
9 | position: relative;
10 | top:4px;
11 | }
12 |
13 | #test_result {
14 | margin: 4px 0 0;
15 | padding: 5px 10px;
16 | width: 500px;
17 | text-align: center;
18 | }
19 |
20 | .test_link_success {
21 | border: 1px solid #00CC00;
22 | background: #C3FDB8;
23 | }
24 |
25 | .test_link_fail {
26 | border:1px solid #CC0000;
27 | background: #E77471;
28 | }
29 |
30 | .smallicon {
31 | vertical-align: middle;
32 | }
33 |
34 | // Upgrade
35 | .tii_upgrade_check,
36 | .tii_upgrading_check {
37 | font-size: 12px;
38 | }
39 |
40 | .tii_upgrade_check {
41 | text-decoration: underline;
42 | cursor: pointer;
43 | }
44 |
45 | .tii_upgrade_check,
46 | .tii_upgrading_check {
47 | width: 30px;
48 | height: 30px;
49 | display: inline-block;
50 | }
51 | .tii_upgrade_check img,
52 | .tii_upgrading_check img {
53 | padding: 0 0 5px 5px;
54 | vertical-align: middle;
55 | }
56 |
57 | .tii_upgrading_check img {
58 | position: relative;
59 | top: 3px;
60 | }
61 | }
--------------------------------------------------------------------------------
/sass/styles.scss:
--------------------------------------------------------------------------------
1 | @import "variables";
2 |
3 | @import "utilities";
4 |
5 | // Partials
6 | @import "partials/listbar";
7 | @import "partials/table";
8 | @import "partials/part_details";
9 | @import "partials/modal";
10 | @import "partials/eula";
11 | @import "partials/digital_receipt";
12 | @import "partials/inbox";
13 | @import "partials/members";
14 |
15 | // Settings Page Partials
16 | @import "settings_partials/class_migration_tab";
17 | @import "settings_partials/settings_tab";
18 |
19 | // Other - Got nowhere to go
20 | @import "other";
21 |
--------------------------------------------------------------------------------
/sdk/log.class.php:
--------------------------------------------------------------------------------
1 | rotateLogs( $filepath );
20 | parent::setDateFormat( 'Y-m-d G:i:s O' );
21 | parent::__construct($filepath, self::LOGLEVEL);
22 | }
23 |
24 | private function rotateLogs( $filepath ) {
25 | if ( !file_exists( $filepath ) ) {
26 | mkdir( $filepath, 0777, true );
27 | }
28 | $dir=opendir( $filepath );
29 | $files=array();
30 | while ($entry=readdir( $dir )) {
31 | if ( substr( basename( $entry ) ,0 ,1 )!='.' AND substr_count(basename( $entry ),parent::PREFIX ) > 0 ) {
32 | $files[]=basename( $entry );
33 | }
34 | }
35 | sort( $files );
36 | for ($i=0; $i
--------------------------------------------------------------------------------
/sdk/perflog.class.php:
--------------------------------------------------------------------------------
1 | start_time = microtime(true);
9 | }
10 |
11 | public function stop_timer($ch) {
12 | $total_response_time = (microtime(true) - $this->start_time);
13 | $this->log($ch, $total_response_time);
14 | }
15 |
16 | protected function log($ch, $total_response_time) {
17 | // Override this method to implement your own logging.
18 | }
19 |
20 | }
21 |
22 | //?>
--------------------------------------------------------------------------------
/sdk/sdkexception.class.php:
--------------------------------------------------------------------------------
1 | setFaultCode( $faultcode ); //$this->faultcode = $faultcode;
23 | $this->setMessage( $message );
24 | $this->setOutputTitle( 'Turnitin SDK Exception' );
25 | $logger = new TurnitinLogger( $logpath );
26 | if ( $logger ) $logger->logError( $this->getOutputTitle() . ': ' . $this->getFaultCode() . ' - ' . $this->getMessage() );
27 | }
28 |
29 | /**
30 | * @ignore
31 | *
32 | * @param string $message
33 | */
34 | private function setMessage( $message ) {
35 | $this->message = $message;
36 | }
37 |
38 | /**
39 | * @ignore
40 | *
41 | * @param string $outputtitle
42 | */
43 | private function setOutputTitle( $outputtitle ) {
44 | $this->outputtitle = $outputtitle;
45 | }
46 |
47 | /**
48 | * @ignore
49 | *
50 | * @return string
51 | */
52 | private function getOutputTitle() {
53 | return $this->outputtitle;
54 | }
55 |
56 | /**
57 | * @ignore
58 | *
59 | * @param string $faultcode
60 | */
61 | private function setFaultCode( $faultcode ) {
62 | $this->faultcode = $faultcode;
63 | }
64 |
65 | /**
66 | * Get the API Fault Code
67 | *
68 | * Possible Fault Code strings:
69 | *
70 | * invaliddata
71 | * unknownobject
72 | * nosourcedids
73 | * unauthorizedrequest
74 | * deletefailure
75 | * unknownvocabulary
76 | * targetreadfailure
77 | * apiconnecterror
78 | * Authentication Fault
79 | *
80 | *
81 | * @return string
82 | */
83 | public function getFaultCode() {
84 | return $this->faultcode;
85 | }
86 |
87 | }
88 |
89 | //?>
--------------------------------------------------------------------------------
/sdk/tiiform.class.php:
--------------------------------------------------------------------------------
1 | hasbutton ) ) ? true : $this->hasbutton;
21 | }
22 |
23 | /**
24 | * Determines if the LTI form output should have a submit button
25 | *
26 | * @param type $hasbutton
27 | */
28 | public function setHasButton( $hasbutton) {
29 | $this->hasbutton = $hasbutton;
30 | }
31 |
32 | /**
33 | * Get the Button Text for an LTI Launch submit button
34 | *
35 | * @return string
36 | */
37 | public function getButtonText() {
38 | return $this->buttontext;
39 | }
40 |
41 | /**
42 | * Set the Button Text for an LTI Launch submit button
43 | *
44 | * @param string $buttontext
45 | */
46 | public function setButtonText( $buttontext ) {
47 | $this->buttontext = $buttontext;
48 | }
49 |
50 | /**
51 | * Get the Button Style for an LTI Launch submit button
52 | *
53 | * @return string
54 | */
55 | public function getButtonStyle() {
56 | return $this->buttonstyle;
57 | }
58 |
59 | /**
60 | * Set the Button Style for an LTI Launch submit button
61 | *
62 | * @param string $buttonstyle
63 | */
64 | public function setButtonStyle( $buttonstyle ) {
65 | $this->buttonstyle = $buttonstyle;
66 | }
67 |
68 | /**
69 | * Get the Form Target for an LTI Launch
70 | *
71 | * A window target to display the LTI launch destination screen in
72 | *
73 | * @return string
74 | */
75 | public function getFormTarget() {
76 | return isset( $this->formtarget ) ? $this->formtarget : '_blank';
77 | }
78 |
79 | /**
80 | * Set the Form Target for an LTI Launch
81 | *
82 | * A window target to display the LTI launch destination screen in
83 | *
84 | * @param string $formtarget
85 | */
86 | public function setFormTarget( $formtarget ) {
87 | $this->formtarget = $formtarget;
88 | }
89 |
90 | /**
91 | * Gets a the Boolean WideMode, this boolean determines the layout of the LTI UI, by default the view will be fixed width 'modal' output.
92 | * By setting WideMode to true the layout will be not be fixed width and will stretch to fit the window / frame
93 | *
94 | * @return boolean
95 | */
96 | public function getWideMode() {
97 | return (boolean)(integer)$this->widemode;
98 | }
99 |
100 | /**
101 | * Sets a the Boolean WideMode, this boolean determines the layout of the LTI UI, by default the view will be fixed width 'modal' output.
102 | * By setting WideMode to true the layout will be not be fixed width and will stretch to fit the window / frame
103 | *
104 | * @param boolean $widemode
105 | */
106 | public function setWideMode( $widemode ) {
107 | $this->widemode = $widemode;
108 | }
109 |
110 | }
111 |
112 | //?>
--------------------------------------------------------------------------------
/sdk/tiimembership.class.php:
--------------------------------------------------------------------------------
1 | membershipid = $membershipid;
32 | }
33 |
34 | /**
35 | * Get the Membership ID for this Membership
36 | *
37 | * The membership ID is the ID Turnitin uses to identify an enrollment on a class
38 | *
39 | * @param integer $membershipid
40 | */
41 | public function getMembershipId() {
42 | return $this->membershipid;
43 | }
44 |
45 | /**
46 | * Set an array of Membership IDs for this Membership data object
47 | *
48 | * The membership ID is the ID Turnitin uses to identify an enrollment on a class
49 | *
50 | * @param array $membershipids
51 | */
52 | public function setMembershipIds( $membershipids ) {
53 | $this->membershipids = $membershipids;
54 | }
55 |
56 | /**
57 | * Get an array of Membership IDs for this Membership data object
58 | *
59 | * The membership ID is the ID Turnitin uses to identify an enrollment on a class
60 | *
61 | * @return array
62 | */
63 | public function getMembershipIds() {
64 | return $this->membershipids;
65 | }
66 |
67 | /**
68 | * Set the User ID for this Membership
69 | *
70 | * The User ID of the User enrolled on this Class
71 | *
72 | * @return integer
73 | */
74 | public function setUserId( $userid ) {
75 | $this->userid = $userid;
76 | }
77 |
78 | /**
79 | * Get the User ID for this Membership
80 | *
81 | * The User ID of the User enrolled on this Class
82 | *
83 | * @return integer
84 | */
85 | public function getUserId() {
86 | return $this->userid;
87 | }
88 |
89 | /**
90 | * Set the Class ID for this Membership
91 | *
92 | * The Class ID a User is enrolled on
93 | *
94 | * @param integer $classid
95 | */
96 | public function setClassId( $classid ) {
97 | $this->classid = $classid;
98 | }
99 |
100 | /**
101 | * Get the Class ID for this Membership
102 | *
103 | * The Class ID a User is enrolled on
104 | *
105 | * @return integer
106 | */
107 | public function getClassId() {
108 | return $this->classid;
109 | }
110 |
111 | /**
112 | * Set the Role for this Membership
113 | *
114 | * The Role the user is enrolled on the Class as, Learner or Instructor
115 | *
116 | * @param string $role
117 | */
118 | public function setRole( $role ) {
119 | switch ( strtolower( $role ) ) {
120 | case 'student':
121 | $role = 'Learner';
122 | break;
123 | case 'learner':
124 | $role = 'Learner';
125 | break;
126 | case 'instructor':
127 | $role = 'Instructor';
128 | break;
129 | }
130 | $this->role = $role;
131 | }
132 |
133 | /**
134 | * Get the Role for this Membership
135 | *
136 | * The Role the user is enrolled on the Class as, Learner or Instructor
137 | *
138 | * @return string
139 | */
140 | public function getRole() {
141 | return $this->role;
142 | }
143 |
144 | }
145 |
146 | //?>
--------------------------------------------------------------------------------
/sdk/tiipseudouser.class.php:
--------------------------------------------------------------------------------
1 | setPseudoDomain( $pseudodomain );
31 | }
32 |
33 | /**
34 | * Set the Email Address for this Pseudo User
35 | *
36 | * Takes a real LMS email address which is converted into a fake / pseudo email address when retrieved.
37 | * This function is mainly useful when personally identifiable user data should not be transmitted and stored in Turnitin.
38 | *
39 | * @return string
40 | */
41 | public function setEmail($email) {
42 | $this->email = $email;
43 | }
44 |
45 | /**
46 | * Get the Email Address for this Pseudo User
47 | *
48 | * This function returns a fake user email, created using the pseudo domain and pseudo salt to SHA hash
49 | * the email address and form a fake / pseudo email address by combining the hash with the Pseudo Domain
50 | *
51 | * @return string
52 | */
53 | public function getEmail() {
54 | if ( substr( $this->pseudodomain, 0, 1 ) != '@' ) {
55 | $this->pseudodomain = '@' . $this->pseudodomain;
56 | }
57 | return sha1( $this->email.$this->pseudosalt ) . $this->pseudodomain;
58 | }
59 |
60 | /**
61 | * Get the Pseudo Domain for this Pseudo User
62 | *
63 | * @return string
64 | */
65 | public function getPseudoDomain() {
66 | return $this->pseudodomain;
67 | }
68 |
69 | /**
70 | * Set the Pseudo Domain for this Pseudo User
71 | *
72 | * @param string $pseudodomain
73 | */
74 | private function setPseudoDomain($pseudodomain) {
75 | $this->pseudodomain = $pseudodomain;
76 | }
77 |
78 | /**
79 | * Get the Pseudo Salt for this Pseudo User
80 | *
81 | * A salt string to use in order to make the Pseudo User Email address less reproducable
82 | *
83 | * @return text
84 | */
85 | public function getPseudoSalt() {
86 | return $this->pseudosalt;
87 | }
88 |
89 | /**
90 | * Set the Pseudo Salt for this Pseudo User
91 | *
92 | * A salt string to use in order to make the Pseudo User Email address less reproducable
93 | *
94 | * @param text $pseudosalt
95 | */
96 | public function setPseudoSalt($pseudosalt) {
97 | $this->pseudosalt = $pseudosalt;
98 | }
99 |
100 | }
101 |
102 | //?>
--------------------------------------------------------------------------------
/sdk/tiirubric.class.php:
--------------------------------------------------------------------------------
1 | rubricid;
29 | }
30 |
31 | /**
32 | * Set the Id for this Rubric
33 | *
34 | * @param integer $rubricid
35 | */
36 | public function setRubricId($rubricid) {
37 | $this->rubricid = $rubricid;
38 | }
39 |
40 | /**
41 | * Get the Name for this Rubric
42 | *
43 | * @return text
44 | */
45 | public function getRubricName() {
46 | return $this->rubricname;
47 | }
48 |
49 | /**
50 | * Set the Name for this Rubric
51 | *
52 | * @param text $rubricname
53 | */
54 | public function setRubricName($rubricname) {
55 | $this->rubricname = $rubricname;
56 | }
57 |
58 | /**
59 | * Get the Rubric Group Name
60 | *
61 | * @return text
62 | */
63 | public function getRubricGroupName() {
64 | return $this->rubricgroupname;
65 | }
66 |
67 | /**
68 | * Set the Group Name for this Rubric
69 | *
70 | * @param text $rubricgroupname
71 | */
72 | public function setRubricGroupName($rubricgroupname) {
73 | $this->rubricgroupname = $rubricgroupname;
74 | }
75 | }
76 |
77 | //?>
--------------------------------------------------------------------------------
/settingslib.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * LDAP enrolment plugin admin setting classes
19 | *
20 | * @package mod_turnitintooltwo
21 | * @author John McGettrick
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 | */
24 |
25 | defined('MOODLE_INTERNAL') || die();
26 |
27 | class admin_setting_configtext_int_only extends admin_setting_configtext {
28 |
29 | /**
30 | * Config text constructor
31 | *
32 | * @param string $name unique ascii name, 'mysetting' for settings in config, 'myplugin/mysetting' for config_plugins.
33 | * @param string $visiblename localised
34 | * @param string $description long localised info
35 | * @param string $defaultsetting
36 | * @param int $size default field size
37 | */
38 | public function __construct($name, $visiblename, $description, $defaultsetting, $size=null) {
39 | $this->paramtype = PARAM_INT;
40 | $this->size = (!is_null($size)) ? $size : 30;
41 |
42 | admin_setting::__construct($name, $visiblename, $description, $defaultsetting);
43 | }
44 |
45 | public function write_setting($data) {
46 | $data = trim($data);
47 | $validated = $this->validate($data);
48 | if ($validated !== true) {
49 | return $validated;
50 | }
51 | return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin'));
52 | }
53 |
54 | public function validate($data) {
55 | global $PAGE;
56 |
57 | // Don't force the plugin to be fully set up when initializing PHPUNIT tests environment.
58 | if (defined('PHPUNIT_UTIL') && strlen($data) === 0) {
59 | return true;
60 | }
61 |
62 | // Don't force the plugin to be fully set up when installing.
63 | if ($PAGE->pagelayout === 'maintenance' && strlen($data) === 0) {
64 | return true;
65 | }
66 | return parent::validate($data);
67 | }
68 | }
69 |
70 | class admin_setting_config_tii_secret_key extends admin_setting_configpasswordunmask {
71 |
72 | /**
73 | * Validate data before storage
74 | * @param string data
75 | * @return mixed true if ok string if error found
76 | */
77 | public function validate($data) {
78 | global $PAGE;
79 |
80 | // Don't force the plugin to be fully set up when initializing PHPUNIT tests environment.
81 | if (defined('PHPUNIT_UTIL') && strlen($data) === 0) {
82 | return true;
83 | }
84 |
85 | // Don't force the plugin to be fully set up when installing.
86 | if ($PAGE->pagelayout === 'maintenance' && strlen($data) === 0) {
87 | return true;
88 | }
89 |
90 | $cleaned = clean_param($data, $this->paramtype);
91 | if ("$data" === "$cleaned") { // Implicit conversion to string is needed to do exact comparison.
92 | return true;
93 | } else {
94 | return get_string('validateerror', 'admin');
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/templates/modal_migration_tool.mustache:
--------------------------------------------------------------------------------
1 | {{< core/modal }}
2 | {{$title}}
3 |
6 | {{/title}}
7 | {{$body}}
8 |
9 |
{{# str }} migrationtoolinfo, turnitintooltwo {{/ str }}
10 |
11 |
12 |
{{# str }} migrating, turnitintooltwo {{/ str }}
13 |
14 |
15 |
16 |
{{# str }} migrationredirect, turnitintooltwo {{/ str }}
17 |
18 | {{/body}}
19 | {{$footer}}
20 |
21 | {{# str }} migrateassignment, turnitintooltwo {{/ str }}
22 | {{#str}} dontmigrateassignment, turnitintooltwo {{/str}}
23 |
24 | {{/footer}}
25 | {{/ core/modal }}
--------------------------------------------------------------------------------
/tests/unit/classes/digitalreceipt/instructor_message_test.php:
--------------------------------------------------------------------------------
1 | dirroot . '/mod/turnitintooltwo/classes/digitalreceipt/instructor_message.php');
7 |
8 | /**
9 | * Tests for classes/digitalreceipt/instructor_message
10 | *
11 | * @package turnitintooltwo
12 | */
13 | class mod_turnitintooltwo_instructor_message_testcase extends advanced_testcase {
14 |
15 | /**
16 | * Test data being passed in will generate the correct output text.
17 | */
18 | public function test_build_instructor_message() {
19 | $instructormessage = new instructor_message();
20 |
21 | $data = [
22 | 'submission_title' => 'Foo',
23 | 'assignment_name' => 'Bar',
24 | 'course_fullname' => 'Foobar',
25 | 'submission_date' => '01-09-1994',
26 | 'submission_id' => '1234567'
27 | ];
28 |
29 | $this->assertEquals(
30 | format_string('A submission entitled Foo has been made to assignment Bar in the class Foobar . Submission ID: 1234567 Submission Date: 01-09-1994 '),
31 | $instructormessage->build_instructor_message($data)
32 | );
33 | }
34 |
35 | /**
36 | * Test data being passed in will generate the correct output text, with assignment part.
37 | */
38 | public function test_build_instructor_message_with_assignment_part() {
39 | $instructor_message = new instructor_message();
40 |
41 | $data = [
42 | 'submission_title' => 'Foo',
43 | 'assignment_name' => 'Bar',
44 | 'course_fullname' => 'Foobar',
45 | 'submission_date' => '01-09-1994',
46 | 'submission_id' => '1234567',
47 | 'assignment_part' => 'Part 2'
48 | ];
49 |
50 | $this->assertEquals(
51 | format_string('A submission entitled Foo has been made to assignment Bar: Part 2 in the class Foobar . Submission ID: 1234567 Submission Date: 01-09-1994 '),
52 | $instructor_message->build_instructor_message($data)
53 | );
54 | }
55 |
56 | /**
57 | * Test that multiple messages get sent for instructors.
58 | */
59 | public function test_send_instructor_message() {
60 | $this->resetAfterTest();
61 | $this->preventResetByRollback();
62 |
63 | $sink = $this->redirectMessages();
64 |
65 | $instructormessage = new instructor_message();
66 |
67 | // Generate two new users to send messages to.
68 | $user1 = $this->getDataGenerator()->create_user();
69 | $user2 = $this->getDataGenerator()->create_user();
70 |
71 | $instructors = [
72 | $user1,
73 | $user2
74 | ];
75 |
76 | // Send message to both instructors.
77 | $instructormessage->send_instructor_message($instructors, 'Instructor Message', 123);
78 |
79 | $messages = $sink->get_messages();
80 |
81 | $this->assertEquals(2, count($messages));
82 | $this->assertEquals('Instructor Message', $messages[0]->fullmessage);
83 | $this->assertEquals('Instructor Message', $messages[1]->fullmessage);
84 |
85 | $this->assertEquals($user1->id, $messages[0]->useridto);
86 | $this->assertEquals($user2->id, $messages[1]->useridto);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/tests/unit/classes/digitalreceipt/receipt_message_test.php:
--------------------------------------------------------------------------------
1 | dirroot . '/mod/turnitintooltwo/classes/digitalreceipt/receipt_message.php');
11 |
12 | class mod_turnitintooltwo_receipt_message_testcase extends advanced_testcase {
13 |
14 | public function test_send_message() {
15 | global $DB;
16 |
17 | $this->resetAfterTest(); // Reset the DB when finished
18 | $this->preventResetByRollback(); // Messaging doesn't support rollback
19 |
20 | $sink = $this->redirectMessages(); // Collect the emails
21 |
22 | $userOne = $this->getDataGenerator()->create_user();
23 |
24 | $receipt_message = new receipt_message();
25 |
26 | $receipt_message->send_message($userOne, "Test message for email", 123);
27 |
28 | $this->assertEquals(1, $sink->count()); // One email sent
29 |
30 | $messages = $sink->get_messages();
31 |
32 | // Correct user was sent an email
33 | $this->assertEquals($userOne->id, $messages[0]->useridto);
34 | $this->assertEquals("This is your Turnitin Digital Receipt", $messages[0]->subject);
35 | $this->assertEquals("Test message for email", $messages[0]->fullmessage);
36 | $this->assertEquals("Test message for email", $messages[0]->fullmessagehtml);
37 | $this->assertEquals(1, $messages[0]->fullmessageformat); // HTML format
38 | }
39 |
40 | public function test_build_message_single_part() {
41 |
42 | $receipt_message = new receipt_message();
43 |
44 | $date = date('c');
45 |
46 | $message = [];
47 | $message['firstname'] = 'test_user_firstname';
48 | $message['lastname'] = 'test_user_lastname';
49 | $message['submission_title'] = 'test submission title';
50 | $message['assignment_name'] = 'test assignment name';
51 | $message['course_fullname'] = 'test course name';
52 | $message['submission_date'] = $date;
53 | $message['submission_id'] = '12345';
54 |
55 | $response = $receipt_message->build_message($message);
56 |
57 | $message_text = format_string("Dear %s %s, 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. Thank you for using Turnitin, The Turnitin Team");
58 |
59 | $this->assertEquals(sprintf($message_text, $message['firstname'], $message['lastname'], $message['submission_title'], $message['assignment_name'], $message['course_fullname'], $date, $message['submission_id']) , $response);
60 | }
61 |
62 | public function test_build_message_multi_part() {
63 | $receipt_message = new receipt_message();
64 |
65 | $date = date('c');
66 |
67 | $message = [];
68 | $message['firstname'] = 'test_user_firstname';
69 | $message['lastname'] = 'test_user_lastname';
70 | $message['submission_title'] = 'test submission title';
71 | $message['assignment_name'] = 'test assignment name';
72 | $message['assignment_part'] = 'assignment_part';
73 | $message['course_fullname'] = 'test course name';
74 | $message['submission_date'] = $date;
75 | $message['submission_id'] = '12345';
76 |
77 | $response = $receipt_message->build_message($message);
78 |
79 | $messagetext = format_string("Dear %s %s, 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 |
--------------------------------------------------------------------------------
/tests/unit/classes/nonsubmitters/nonsubmitters_message_test.php:
--------------------------------------------------------------------------------
1 | dirroot . '/mod/turnitintooltwo/classes/nonsubmitters/nonsubmitters_message.php');
7 |
8 | /**
9 | * Tests for classes/digitalreceipt/nonsubmitters_message
10 | *
11 | * @package turnitintooltwo
12 | */
13 | class mod_turnitintooltwo_nonsubmitter_message_testcase extends advanced_testcase {
14 |
15 | /**
16 | * Test that non submitter messages send.
17 | */
18 | public function test_send_instructor_message() {
19 | $this->resetAfterTest();
20 | $this->preventResetByRollback();
21 |
22 | $sink = $this->redirectMessages();
23 |
24 | $nonsubmitters_message = new nonsubmitters_message();
25 |
26 | // Generate two new users to send messages to.
27 | $user1 = $this->getDataGenerator()->create_user();
28 |
29 | // Send message to both instructors.
30 | $nonsubmitters_message->send_message($user1->id, 'Nonsubmitters Subject', 'Nonsubmitters Message', 1);
31 |
32 | $messages = $sink->get_messages();
33 |
34 | $this->assertEquals(1, count($messages));
35 | $this->assertEquals('Nonsubmitters Subject', $messages[0]->subject);
36 | $this->assertEquals('Nonsubmitters Message', $messages[0]->fullmessage);
37 | $this->assertEquals($user1->id, $messages[0]->useridto);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/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('')
80 | ->withConsecutive(
81 | [$this->equalTo('fakemodule'), $this->equalTo('faketiiassignment'), $this->equalTo('Learner')],
82 | [$this->equalTo('fakemodule'), $this->equalTo('faketiiassignment'), $this->equalTo('Instructor')],
83 | [$this->equalTo('fakemodule'), $this->equalTo('faketiiassignment'), $this->equalTo('Learner')],
84 | [$this->equalTo('fakemodule'), $this->equalTo('faketiiassignment'), $this->equalTo('Learner')]
85 | );
86 |
87 | // create out members view instance passing our stubbed turnitin two
88 | // view class instance
89 | $members = new members_view('fakecourse', 'fakemodule', $observer, 'faketiiassignment');
90 |
91 | // check with valid Learner role
92 | $table = $members->build_members_table('students');
93 | $this->assertEquals('', $table);
94 |
95 | // check with valid Instructor role
96 | $table = $members->build_members_table('tutors');
97 | $this->assertEquals('', $table);
98 |
99 | // check no role falls back to Learner
100 | $table = $members->build_members_table();
101 | $this->assertEquals('', $table);
102 |
103 | // check invalid role falls back to Learner
104 | $table = $members->build_members_table('foobar');
105 | $this->assertEquals('', $table);
106 | }
107 |
108 | /**
109 | * Test given a display role the correct add tutors form is generated.
110 | */
111 | public function test_build_add_tutors_form() {
112 | // fake/stub a turnitin two view class and method to render the add
113 | // tutors form
114 | $faketiiview = $this->getMockBuilder(turnitintooltwo_view::class)
115 | ->setMethods(['show_add_tii_tutors_form'])
116 | ->getMock();
117 |
118 | // add assertions that the generate add tutors form is called as
119 | // expected
120 | $faketiiview->expects($this->once())
121 | ->method('show_add_tii_tutors_form')
122 | ->willReturn('')
123 | ->withConsecutive(
124 | [$this->equalTo('fakemodule'), $this->equalTo('faketutors')]
125 | );
126 |
127 | // fake/stub a fake tii assignment
128 | $faketiiassignment = $this->getMockBuilder(turnitintooltwo_assignment::class)
129 | ->disableOriginalConstructor()
130 | ->setMethods(['get_tii_users_by_role'])
131 | ->getMock();
132 |
133 | // make assignment get users by role to always return something, we
134 | // check that our tii two view stub gets called with the result of this
135 | // stub.
136 | $faketiiassignment->expects($this->once())
137 | ->method('get_tii_users_by_role')
138 | ->willReturn('faketutors');
139 |
140 | // create our members view class instance with the fake tii view and
141 | // assignment
142 | $members = new members_view(null, 'fakemodule', $faketiiview, $faketiiassignment);
143 |
144 | // test when not displaying tutor members
145 | $form = $members->build_add_tutors_form("foobar");
146 | $this->assertEquals('', $form);
147 |
148 | // test when displaying tutor members
149 | $form = $members->build_add_tutors_form("tutors");
150 | $this->assertEquals('', $form);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/tests/unit/mod_form_test.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * Unit tests for (some of) turnitintooltwo/mod_form.php.
19 | *
20 | * @package turnitintooltwo
21 | * @copyright 2018 Turnitin
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 | */
24 |
25 | global $CFG;
26 |
27 | require_once($CFG->dirroot . '/mod/turnitintooltwo/mod_form.php');
28 |
29 | class mod_form_test extends advanced_testcase {
30 |
31 | /**
32 | * Test that when current has a submitpapers the submitpapers from the config is not used.
33 | * I.E. instructor default overrides the system default
34 | */
35 | public function test_should_populate_submitpapersto_to_the_value_in_current_when_submitpapersto_not_null() {
36 | $this->resetAfterTest();
37 |
38 | $current = new stdClass();
39 | $current->submitpapersto = 1;
40 |
41 | // Test that System Default is not applied
42 | set_config('default_submitpapersto', 0, 'turnitintooltwo');
43 |
44 | $current = mod_turnitintooltwo_mod_form::populate_submitpapersto($current);
45 |
46 | $this->assertEquals($current->submitpapersto, 1);
47 | }
48 |
49 | /**
50 | * Test that when current does not have a submitpapers the submitpapers from the config is used.
51 | * I.E. when there is no instructor default the system default is used
52 | */
53 | public function test_should_populate_submitpapersto_to_the_value_in_config_when_submitpapersto_null() {
54 | $this->resetAfterTest();
55 |
56 | $current = new stdClass();
57 | $current->submitpapersto = null;
58 |
59 | // Test that System Default is not applied
60 | set_config('default_submitpapersto', 0, 'turnitintooltwo');
61 |
62 | $current = mod_turnitintooltwo_mod_form::populate_submitpapersto($current);
63 |
64 | $this->assertEquals($current->submitpapersto, 0);
65 | }
66 | }
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/tests/unit/turnitintooltwo_comms_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_comms.class.php');
29 |
30 | /**
31 | * Tests for API comms class
32 | *
33 | * @package turnitintooltwo
34 | */
35 | class mod_turnitintooltwo_comms_testcase extends advanced_testcase {
36 |
37 | public function test_handle_exceptions() {
38 | global $CFG;
39 |
40 | $this->resetAfterTest();
41 |
42 | // Set Turnitin account values in config as they are used in comms.
43 | set_config('apiurl', 'http://invalid', 'turnitintooltwo');
44 | set_config('accountid', '1001', 'turnitintooltwo');
45 | set_config('secretkey', 'ABCDEFGH', 'turnitintooltwo');
46 |
47 | // Throw fake exception.
48 | try {
49 | throw new Exception("Throw a fake exception for testing.");
50 | } catch(Exception $e) {
51 | }
52 |
53 | $turnitintooltwocomms = new turnitintooltwo_comms();
54 | // Check error string with debugging set to developer level.
55 | $CFG->debug = DEBUG_DEVELOPER;
56 | $errorstring = $turnitintooltwocomms->handle_exceptions($e, "", false, true);
57 |
58 | // Error string should contain the file, line and the message.
59 | if (is_callable(array($e, 'getFile'))) {
60 | $this->assertStringContainsString($e->getFile(), $errorstring);
61 | }
62 | if (is_callable(array($e, 'getLine'))) {
63 | $this->assertStringContainsString((string)$e->getLine(), $errorstring);
64 | }
65 | if (is_callable(array($e, 'getMessage'))) {
66 | $this->assertStringContainsString($e->getMessage(), $errorstring);
67 | }
68 |
69 | // Check error string with debugging set to normal level.
70 | $CFG->debug = DEBUG_NONE;
71 | $errorstring = $turnitintooltwocomms->handle_exceptions($e, "", false, true);
72 |
73 | // Error string should not contain the file and line, only the message.
74 | if (is_callable(array($e, 'getFile'))) {
75 | $this->assertStringNotContainsString($e->getFile(), $errorstring);
76 | }
77 | if (is_callable(array($e, 'getLine'))) {
78 | $this->assertStringNotContainsString((string)$e->getLine(), $errorstring);
79 | }
80 | if (is_callable(array($e, 'getMessage'))) {
81 | $this->assertStringContainsString($e->getMessage(), $errorstring);
82 | }
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/turnitintooltwo_class.class.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2012 iParadigms LLC *
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | require_once(__DIR__.'/turnitintooltwo_comms.class.php');
25 |
26 | class turnitintooltwo_class {
27 |
28 | private $id;
29 | private $turnitinid;
30 | private $title;
31 | private $turnitintitle;
32 | public $sharedrubrics;
33 |
34 | public function __construct($id) {
35 | global $DB;
36 |
37 | $this->id = $id;
38 |
39 | if ($turnitincourse = $DB->get_record('turnitintooltwo_courses',
40 | array("courseid" => $id, "course_type" => "TT"))) {
41 | $this->turnitinid = $turnitincourse->turnitin_cid;
42 | $this->turnitintitle = $turnitincourse->turnitin_ctl;
43 | }
44 | }
45 |
46 | /**
47 | * Update class from Turnitin, mainly to get shared rubrics
48 | *
49 | * @return void
50 | */
51 | public function read_class_from_tii() {
52 | // Initialise Comms Object.
53 | $turnitincomms = new turnitintooltwo_comms();
54 | $turnitincall = $turnitincomms->initialise_api();
55 |
56 | $tiiclass = new TiiClass();
57 |
58 | try {
59 | $tiiclass->setClassId($this->turnitinid);
60 | $response = $turnitincall->readClass($tiiclass);
61 | $readclass = $response->getClass();
62 |
63 | $rubrics = $readclass->getSharedRubrics();
64 | $rubricarray = array();
65 | foreach ($rubrics as $rubric) {
66 | $rubricarray[$rubric->getRubricGroupName()][$rubric->getRubricId()] = $rubric->getRubricName();
67 | }
68 |
69 | $this->sharedrubrics = $rubricarray;
70 |
71 | } catch (Exception $e) {
72 | $turnitincomms->handle_exceptions($e, 'coursegeterror', false);
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/turnitintooltwo_perflog.class.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | defined('MOODLE_INTERNAL') || die();
18 |
19 | require_once(__DIR__.'/sdk/perflog.class.php');
20 | require_once(__DIR__.'/lib.php');
21 |
22 | class turnitintooltwo_performancelog extends PerformanceLog {
23 |
24 | /**
25 | * Log networking performance details of an individual request
26 | *
27 | * @param resource $ch The cURL handle corresponding to the request to log
28 | * @param float $totalresponsetime Total time taken for the request in seconds
29 | */
30 | protected function log($ch, $totalresponsetime) {
31 | global $CFG, $USER, $action;
32 |
33 | static $config;
34 | if (empty($config)) {
35 | $config = turnitintooltwo_admin_config();
36 | }
37 |
38 | if ($config->enableperformancelogs) {
39 | // We only keep 10 log files, delete any additional files.
40 | $prefix = "perflog_";
41 |
42 | $dirpath = $CFG->tempdir."/turnitintooltwo/logs";
43 | if (!file_exists($dirpath)) {
44 | mkdir($dirpath, 0777, true);
45 | }
46 | $dir = opendir($dirpath);
47 | $files = array();
48 | while ($entry = readdir($dir)) {
49 | if (substr(basename($entry), 0, 1) != "." AND substr_count(basename($entry), $prefix) > 0) {
50 | $files[] = basename($entry);
51 | }
52 | }
53 | sort($files);
54 | for ($i = 0; $i < count($files) - 10; $i++) {
55 | unlink($dirpath."/".$files[$i]);
56 | }
57 |
58 | // Prepare string.
59 | $str = '';
60 | if (!empty($action)) {
61 | $str .= " - $action";
62 | } else {
63 | $do = (!empty($_REQUEST['do'])) ? $_REQUEST['do'] : '';
64 | if (!empty($do)) {
65 | $str .= " - {$do}";
66 | }
67 | }
68 | $httpstatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
69 | $str .= " - HTTP:" . $httpstatus;
70 | if ($httpstatus === 0 && curl_getinfo($ch, CURLINFO_SIZE_UPLOAD) === 0) {
71 | // CURLINFO_CONNECT_TIME is not reliable when the request fails to connect.
72 | $connecttime = $totalresponsetime;
73 | } else {
74 | $connecttime = curl_getinfo($ch, CURLINFO_CONNECT_TIME);
75 | }
76 | $str .= " - connect:" . sprintf('%0.3f', $connecttime);
77 | $str .= " - total:" . sprintf('%0.3f', $totalresponsetime);
78 | $str .= " - up:" . curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
79 | $str .= " - down:" . curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
80 | $str .= " - userid:" . $USER->id;
81 | if (array_key_exists('REQUEST_URI', $_SERVER)) {
82 | $str .= " - " . $_SERVER['REQUEST_URI'];
83 | }
84 |
85 | if ($httpstatus === 0) {
86 | $str .= " - " . curl_error($ch);
87 | }
88 |
89 | // Write to log file.
90 | $filepath = $dirpath."/".$prefix.gmdate('Y-m-d', time()).".txt";
91 | $file = fopen($filepath, 'a');
92 | $output = date('Y-m-d H:i:s O') . $str . "\r\n";
93 | fwrite($file, $output);
94 | fclose($file);
95 | }
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/version.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * @package turnitintooltwo
19 | * @copyright 2012 iParadigms LLC
20 | */
21 |
22 | defined('MOODLE_INTERNAL') || die();
23 |
24 | if (empty($plugin)) {
25 | $plugin = new StdClass();
26 | }
27 |
28 | $plugin->version = 2025072901;
29 | $plugin->release = "4.1+";
30 | $plugin->requires = 2022112800; // Require Moodle 4.1.0+
31 | $plugin->component = 'mod_turnitintooltwo';
32 | $plugin->maturity = MATURITY_STABLE;
33 |
34 | global $CFG;
35 | $plugin->cron = 0;
36 | if (!empty($CFG->version)) {
37 | $plugin->cron = ($CFG->version > 2014051200) ? 0 : 1800;
38 | }
39 |
--------------------------------------------------------------------------------