diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml deleted file mode 100644 index a19a201..0000000 --- a/.github/workflows/moodle-ci.yml +++ /dev/null @@ -1,120 +0,0 @@ -name: Moodle Plugin CI - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-18.04 - - services: - postgres: - image: postgres:9.6 - env: - POSTGRES_USER: 'postgres' - POSTGRES_HOST_AUTH_METHOD: 'trust' - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 - mariadb: - image: mariadb:10.5 - env: - MYSQL_USER: 'root' - MYSQL_ALLOW_EMPTY_PASSWORD: "true" - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 3 - - strategy: - fail-fast: false - matrix: - include: - - php: '7.4' - moodle-branch: 'MOODLE_311_STABLE' - database: pgsql - - php: '7.4' - moodle-branch: 'MOODLE_311_STABLE' - database: mariadb - - php: '7.3' - moodle-branch: 'MOODLE_311_STABLE' - database: pgsql - - php: '7.3' - moodle-branch: 'MOODLE_311_STABLE' - database: mariadb - - steps: - - name: Check out repository code - uses: actions/checkout@v2 - with: - path: plugin - - - name: Setup PHP ${{ matrix.php }} - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - coverage: none - - - name: Initialise moodle-plugin-ci - run: | - composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3 - echo $(cd ci/bin; pwd) >> $GITHUB_PATH - echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH - sudo locale-gen en_AU.UTF-8 - echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV - - - name: Install moodle-plugin-ci - run: moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1 - env: - DB: ${{ matrix.database }} - MOODLE_BRANCH: ${{ matrix.moodle-branch }} - MUSTACHE_IGNORE_NAMES: 'mobile_*.mustache' - - - name: PHP Lint - if: ${{ always() }} - run: moodle-plugin-ci phplint - - - name: PHP Copy/Paste Detector - continue-on-error: true # This step will show errors but will not fail - if: ${{ always() }} - run: moodle-plugin-ci phpcpd - - - name: PHP Mess Detector - continue-on-error: true # This step will show errors but will not fail - if: ${{ always() }} - run: moodle-plugin-ci phpmd - - - name: Moodle Code Checker - if: ${{ always() }} - run: moodle-plugin-ci codechecker --max-warnings 0 - - - name: Moodle PHPDoc Checker - if: ${{ always() }} - run: moodle-plugin-ci phpdoc - - - name: Validating - if: ${{ always() }} - run: moodle-plugin-ci validate - - - name: Check upgrade savepoints - if: ${{ always() }} - run: moodle-plugin-ci savepoints - - - name: Mustache Lint - if: ${{ always() }} - run: moodle-plugin-ci mustache - - - name: Grunt - if: ${{ always() }} - run: moodle-plugin-ci grunt --max-lint-warnings 0 - - - name: PHPUnit tests - if: ${{ always() }} - run: | - moodle-plugin-ci phpunit - cd moodle - vendor/bin/phpunit --fail-on-risky --disallow-test-output --filter tool_dataprivacy_metadata_registry_testcase - vendor/bin/phpunit --fail-on-risky --disallow-test-output --filter core_externallib_testcase - vendor/bin/phpunit --fail-on-risky --disallow-test-output --testsuite core_privacy_testsuite --filter provider_testcase - - - name: Behat features - if: ${{ always() }} - run: moodle-plugin-ci behat --profile chrome diff --git a/CHANGES.md b/CHANGES.md deleted file mode 100644 index 0fca689..0000000 --- a/CHANGES.md +++ /dev/null @@ -1,299 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -Note - All hash comments refer to the issue number. Eg. #169 refers to https://github.com/mdjnelson/moodle-mod_customcert/issues/169. - -## [3.11.2] - 2021-??-?? - -### Fixed -- Fix places not using the multi-language filter (#433). -- Fix user IDs in the issue table not being mapped during restore (#449). -- Fix emails displaying HTML entities encoded (#457). -- Fix error message when we have custom profile fields (#465). -- Respect multiple languages in manage template page title (#467). - -### Added -- You can now choose the course short or full name to display (#415). -- You can now select the alignment for all text elements (#121). - -## [3.11.1] - 2021-06-13 - -### Fixed -- Usage of deprecated functions (#423) - -## [3.10.1] - 2021-06-13 - -### Added -- Usage of github actions (#407). -- The ability to show the description on the course page (#406). -- The ability to choose how to deliver the certificate (#401). - -### Fixed -- Managers are now able to download their students' certificates (#412). -- Users being able to view the certificate before the required time set (#403). -- Fixed the issue with displaying PDF when debugging is ON (#420). -- Using incorrect context when sending emails (#402). -- Use `cron_setup_user` when sending emails (#414). - -## [3.8.5] - 2020-11-26 - -### Added - -- Added ability to select outcomes in the Grade element (#329). -- The Grade Item Name element now works with all grade items, whereas before it was just activities (#346). -- Added enrolment start and end dates to the date element (#328). -- Added username to userfield form element (#390). - -### Changed - -- Removed unnecessary and confusing 'exampledata' string. -- Do not email those who can manage the certificate (#376). -- Do not force the PDF to be downloaded, instead send the file inline to the browser (#153). -- Updated the 'emailstudents_help', 'emailteachers_help' and 'emailothers_help' strings to warn users about prematurely emailing the certificate (#276). -- Do not email out certificates that contain no elements (#276). - -### Fixed - -- Certificates now get marked as viewed via the mobile app (#342). -- Custom fields not displaying properly (#359). -- Fix repositioning elements page when resizing the browser (#343). -- Prevent error when duplicate issues exist when using the code element (#363). -- Implemented get_objectid_mapping for the course_module_viewed.php event to avoid warning (#374). -- Fixed exception being thrown when loading a template that has an image element but no image selected (#369). -- Fixed issue with PDF being generated without a name (#333). - -## [3.8.4] - 2020-03-12 - -### Added - -- Added extra Behat steps for new elements (#309). - -### Changed - -- When copying a site template the site images are also copied to the course context and then those copied images are used. - Before, the elements would simply point to the site images. However, this meant when performing a backup/restore the - images were not stored in the backup file (#298). - -### Fixed - -- Fixed the displaying of names of a custom user field (#326). -- Do not allow '0' as a value for width or height in QR code (#321). - -## [3.8.3] - 2020-03-09 - -### Fixed - -- Fixed foreign key violation (#331). - -## [3.8.2] - 2019-12-16 - -### Added - -- Added subplugins.json file (#312). -- Re-added 'code' column to user report (#264). -- Add 'userfullname' variable for email subject (#316). - -### Fixed - -- Do not fail if multiple certificate issues (#304) and (#295). - -## [3.7.1] - 2019-06-17 - -### Added - -- Added new custom course field element (#274). -- Added ability to specify the current date for date related elements (#289). - -### Changed - -- String improvements for the 'Date range' element. - -### Fixed - -- Use negative numbers for constants in the 'Date range' element. The reason being that we may have a module - that has an id matching one of these positive values. Sites which are using the 'Date range' element (sites - which are **not** using this element do **not** have to do anything) will need to re-edit each element, select - the date item again and save. An upgrade step was not created because it is impossible to tell if the site does - actually want the constant or if they actually want the date for the module. - -## [3.6.2] - 2019-05-28 - -### Changed - -- Always send emails from the 'noreplyuser' (#165). - -### Added - -- Added QR code element (#146). -- Added Date range element (#185). -- Added the number of certificates issued above the report (#266). -- Added new capability to control who can be issued a certificate (#270). - -### Fixed - -- Failures when running unit tests for multiple activities (#282). -- Check that a certificate is valid before downloading on 'My certificates' page (#269). - -## [3.6.1] - 2018-12-31 - -### Changed - -- Make it clear what element values are just an example when previewing the PDF (#144). - -### Fixed - -- Missing implementation for privacy provider (#260). -- Use course module context when calling format_string/text (#200). -- Exception being thrown when adding the 'teachername' element to site template (#261). - -## [3.5.5] - 2018-12-20 -### Added - -- GDPR: Add support for removal of users from a context (see MDL-62560) (#252). -- Images can be made transparent (#186). -- Set default values of activity instance settings (#180). -- Allow element plugins to control if they can be added to a certificate (#225). -- Allow element plugins to have their own admin settings (#213). -- Added plaintext language variants for email bodies (#231). -- Added possibility to selectively disable activity instance settings (#179). - -### Changed - -- Allow verification of deleted users (#159). -- The 'element' field in the 'customcert_elements' table has been changed from a Text field to varchar(255) (#241). -- The 'Completion date' option in the 'date' element is only displayed when completion is enabled (#160). -- Instead of assuming 2 decimal points for percentages, we now make use of the decimal value setting, which the - function `grade_format_gradevalue` does by default if no decimal value is passed. - -### Fixed - -- Issue with scales not displaying correctly (#242). -- The report now respects the setting 'Show user identity' (#224). -- Removed incorrect course reset logic (#223). -- Description strings referring to the wrong setting (#254). - -## [3.5.4] - 2018-07-13 -### Fixed - -- Use custom fonts if present (#211). -- Fix broken SQL on Oracle in the email certificate task (#187). -- Fixed exception when clicking 'Add page' when template has not been saved (#154). -- Only email teachers who are enrolled within the course (#176). -- Only display teachers who are enrolled within the course in the dropdown (#171). - -### Changed - -- Multiple UX improvements to both the browser and mobile views (#207). - - One big change here is combining the report and activity view page into one. -- Allow short dates with leading zeros (#210). - -## [3.5.3] - 2018-06-26 -### Fixed - -- Respect filters in the 'My certificates' and 'Verify certificate' pages (#197). -- Fixed reference to 'mod/certificate' capability. - -### Changed - -- Multiple UX improvements to both the browser and mobile views (#203). - -## [3.5.2] - 2018-06-07 -### Fixed - -- Hotfix to prevent misalignment of 'text' elements after last release (#196). - -## [3.5.1] - 2018-06-06 -### Added -- Mobile app support (#70). -``` - This allows students to view the activity and download - their certificate. It also allows teachers to view the - list of issued certificates, with the ability to revoke - any. - - This is for the soon-to-be released Moodle Mobile v3.5.0 - (not to be confused with your Moodle site version) and - will not work on Mobile versions earlier than this. - - If you are running a Moodle site on version 3.4 or below - you will need to install the local_mobile plugin in order - for this to work. - - If you are running a Moodle site on version 3.0 or below - then you will need to upgrade. -``` -- More font sizes (#148). -- Added new download icon. -``` - This was done because the core 'import' icon was mapped - to the Font Awesome icon 'fa-level-up' which did not look - appropriate. So, a new icon was added and that was mapped - to the 'fa-download' icon. -``` -### Fixed -- No longer display the 'action' column and user picture URL when downloading the user report (#192). -- Elements no longer ignore filters (#170). - -## [3.4.1] - 2018-05-17 -### Added -- GDPR Compliance (#189). - -### Fixed -- Race condition on certificate issues in scheduled task (#173). -- Ensure we backup the 'verifyany' setting (#169). -- Fixed encoding content links used by restore (#166). - -## [3.3.9] - 2017-11-13 -### Added -- Added capability ```mod/customcert:verifyallcertificates``` that provides a user with the ability to verify any certificate - on the site by simply visiting the ```mod/customcert/verify_certificate.php``` page, rather than having to go to the - verification link for each certificate. -- Added site setting ```customcert/verifyallcertificates``` which when enabled allows any person (including users not logged in) - to be able to verify any certificate on the site, rather than having to go to the verification link for each certificate. - However, this only applies to certificates where ```Allow anyone to verify a certificate``` has been set to ```Yes``` in the - certificate settings. -- You can now display the grade and date of all grade items, not just the course and course activities. -- Text has been added above the ```My certificates``` list to explain that it contains certificates that have been issued to - avoid confusion as to why certificates may not be appearing. - -### Changed -- The course full name is now used in emails. - -### Fixed -- Added missing string used in course reset. - -## [3.3.8] - 2017-09-04 -### Added -- New digital signature element (uses existing functionality in the TCPDF library). -- Ability to duplicate site templates via the manage templates page. -- Ability to delete issued certificates for individual users on the course report page. - -### Changed -- Removed usage of magic getter and abuse of ```$this->element```. The variable ```$this->element``` will still be - accessible by any third-party element plugins, though this is discouraged and the appropriate ```get_xxx()``` - method should be used instead. Using ```$this->element``` in ```definition_after_data()``` will no longer work. - Please explicitly set the value of any custom fields you have in the form. - -### Fixed -- Added missing ```confirm_sesskey()``` checks. -- Minor bug fixes. - -## [3.3.7] - 2017-08-11 -### Added -- Added much needed Behat test coverage. - -### Changed -- Minor language string changes. -- Made changes to the UI when editing a certificate. - - Moved the 'Add element' submit button below the list of elements. - - Added icon next to the 'Delete page' link. - - Changed the 'Add page' button to a link, added an icon and moved it's location to the right. - - Do not make all submit buttons primary. MDL-59740 needs to be applied to your Moodle install in order to notice the change. - -### Fixed -- Issue where the date an activity was graded was not displaying at all. - -## [3.3.6] - 2017-08-05 -### Changed -- Renamed the column 'size' in the table 'customcert_elements' to 'fontsize' due to 'size' being a reserved word in Oracle. diff --git a/ajax.php b/ajax.php deleted file mode 100644 index b5b454d..0000000 --- a/ajax.php +++ /dev/null @@ -1,57 +0,0 @@ -. - -/** - * Handles AJAX requests for the customcert module. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once(__DIR__ . '/../../config.php'); - -if (!defined('AJAX_SCRIPT')) { - define('AJAX_SCRIPT', true); -} - -$tid = required_param('tid', PARAM_INT); -$values = required_param('values', PARAM_RAW); -$values = json_decode($values); - -// Make sure the template exists. -$template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); - -// Set the template. -$template = new \mod_customcert\template($template); -// Perform checks. -if ($cm = $template->get_cm()) { - $courseid = $cm->course; - require_login($courseid, false, $cm); -} else { - require_login(); -} -// Make sure the user has the required capabilities. -$template->require_manage(); - -// Loop through the data. -foreach ($values as $value) { - $element = new stdClass(); - $element->id = $value->id; - $element->posx = $value->posx; - $element->posy = $value->posy; - $DB->update_record('customcert_elements', $element); -} diff --git a/amd/build/dialogue.min.js b/amd/build/dialogue.min.js deleted file mode 100644 index 620d175..0000000 --- a/amd/build/dialogue.min.js +++ /dev/null @@ -1,2 +0,0 @@ -define ("mod_customcert/dialogue",["core/yui"],function(a){var b=function(b,c,d,e,f){this.yuiDialogue=null;var g=this;if("undefined"==typeof f){f=!1}a.use("moodle-core-notification","timers",function(){var h="480px";if(f){h="800px"}g.yuiDialogue=new M.core.dialogue({headerContent:b,bodyContent:c,draggable:!0,visible:!1,center:!0,modal:!0,width:h});g.yuiDialogue.after("visibleChange",function(b){if(b.newVal){if("undefined"!=typeof d){a.soon(function(){d(g);g.yuiDialogue.centerDialogue()})}}else{if("undefined"!=typeof e){a.soon(function(){e(g)})}}});g.yuiDialogue.show()})};b.prototype.close=function(){this.yuiDialogue.hide();this.yuiDialogue.destroy()};b.prototype.getContent=function(){return this.yuiDialogue.bodyNode.getDOMNode()};return b}); -//# sourceMappingURL=dialogue.min.js.map diff --git a/amd/build/dialogue.min.js.map b/amd/build/dialogue.min.js.map deleted file mode 100644 index 8986766..0000000 --- a/amd/build/dialogue.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../src/dialogue.js"],"names":["define","Y","dialogue","title","content","afterShow","afterHide","wide","yuiDialogue","parent","use","width","M","core","headerContent","bodyContent","draggable","visible","center","modal","after","e","newVal","soon","centerDialogue","show","prototype","close","hide","destroy","getContent","bodyNode","getDOMNode"],"mappings":"AAuBAA,OAAM,2BAAC,CAAC,UAAD,CAAD,CAAe,SAASC,CAAT,CAAY,CAW7B,GAAIC,CAAAA,CAAQ,CAAG,SAASC,CAAT,CAAgBC,CAAhB,CAAyBC,CAAzB,CAAoCC,CAApC,CAA+CC,CAA/C,CAAqD,CAChE,KAAKC,WAAL,CAAmB,IAAnB,CACA,GAAIC,CAAAA,CAAM,CAAG,IAAb,CAGA,GAAmB,WAAf,QAAOF,CAAAA,CAAX,CAAgC,CAC5BA,CAAI,GACP,CAEDN,CAAC,CAACS,GAAF,CAAM,0BAAN,CAAkC,QAAlC,CAA4C,UAAW,CACnD,GAAIC,CAAAA,CAAK,CAAG,OAAZ,CACA,GAAIJ,CAAJ,CAAU,CACNI,CAAK,CAAG,OACX,CAEDF,CAAM,CAACD,WAAP,CAAqB,GAAII,CAAAA,CAAC,CAACC,IAAF,CAAOX,QAAX,CAAoB,CACrCY,aAAa,CAAEX,CADsB,CAErCY,WAAW,CAAEX,CAFwB,CAGrCY,SAAS,GAH4B,CAIrCC,OAAO,GAJ8B,CAKrCC,MAAM,GAL+B,CAMrCC,KAAK,GANgC,CAOrCR,KAAK,CAAEA,CAP8B,CAApB,CAArB,CAUAF,CAAM,CAACD,WAAP,CAAmBY,KAAnB,CAAyB,eAAzB,CAA0C,SAASC,CAAT,CAAY,CAClD,GAAIA,CAAC,CAACC,MAAN,CAAc,CAGV,GAA0B,WAArB,QAAOjB,CAAAA,CAAZ,CAAwC,CACpCJ,CAAC,CAACsB,IAAF,CAAO,UAAW,CACdlB,CAAS,CAACI,CAAD,CAAT,CACAA,CAAM,CAACD,WAAP,CAAmBgB,cAAnB,EACH,CAHD,CAIH,CACJ,CATD,IASO,CACH,GAA0B,WAArB,QAAOlB,CAAAA,CAAZ,CAAwC,CACpCL,CAAC,CAACsB,IAAF,CAAO,UAAW,CACdjB,CAAS,CAACG,CAAD,CACZ,CAFD,CAGH,CACJ,CACJ,CAjBD,EAmBAA,CAAM,CAACD,WAAP,CAAmBiB,IAAnB,EACH,CApCD,CAqCH,CA9CD,CAmDAvB,CAAQ,CAACwB,SAAT,CAAmBC,KAAnB,CAA2B,UAAW,CAClC,KAAKnB,WAAL,CAAiBoB,IAAjB,GACA,KAAKpB,WAAL,CAAiBqB,OAAjB,EACH,CAHD,CAUA3B,CAAQ,CAACwB,SAAT,CAAmBI,UAAnB,CAAgC,UAAW,CACvC,MAAO,MAAKtB,WAAL,CAAiBuB,QAAjB,CAA0BC,UAA1B,EACV,CAFD,CAIA,MAAO9B,CAAAA,CACV,CA7EK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Wrapper for the YUI M.core.notification class. Allows us to\n * use the YUI version in AMD code until it is replaced.\n *\n * @module mod_customcert/dialogue\n * @copyright 2016 Mark Nelson \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/yui'], function(Y) {\n\n /**\n * Constructor\n *\n * @param {String} title Title for the window.\n * @param {String} content The content for the window.\n * @param {function} afterShow Callback executed after the window is opened.\n * @param {function} afterHide Callback executed after the window is closed.\n * @param {Boolean} wide Specify we want an extra wide dialogue (the size is standard, but wider than the default).\n */\n var dialogue = function(title, content, afterShow, afterHide, wide) {\n this.yuiDialogue = null;\n var parent = this;\n\n // Default for wide is false.\n if (typeof wide == 'undefined') {\n wide = false;\n }\n\n Y.use('moodle-core-notification', 'timers', function() {\n var width = '480px';\n if (wide) {\n width = '800px';\n }\n\n parent.yuiDialogue = new M.core.dialogue({\n headerContent: title,\n bodyContent: content,\n draggable: true,\n visible: false,\n center: true,\n modal: true,\n width: width\n });\n\n parent.yuiDialogue.after('visibleChange', function(e) {\n if (e.newVal) {\n // Delay the callback call to the next tick, otherwise it can happen that it is\n // executed before the dialogue constructor returns.\n if ((typeof afterShow !== 'undefined')) {\n Y.soon(function() {\n afterShow(parent);\n parent.yuiDialogue.centerDialogue();\n });\n }\n } else {\n if ((typeof afterHide !== 'undefined')) {\n Y.soon(function() {\n afterHide(parent);\n });\n }\n }\n });\n\n parent.yuiDialogue.show();\n });\n };\n\n /**\n * Close this window.\n */\n dialogue.prototype.close = function() {\n this.yuiDialogue.hide();\n this.yuiDialogue.destroy();\n };\n\n /**\n * Get content.\n *\n * @returns {HTMLElement}\n */\n dialogue.prototype.getContent = function() {\n return this.yuiDialogue.bodyNode.getDOMNode();\n };\n\n return dialogue;\n});\n"],"file":"dialogue.min.js"} \ No newline at end of file diff --git a/amd/build/rearrange-area.min.js b/amd/build/rearrange-area.min.js deleted file mode 100644 index 36faa3a..0000000 --- a/amd/build/rearrange-area.min.js +++ /dev/null @@ -1,2 +0,0 @@ -define ("mod_customcert/rearrange-area",["jquery","core/yui","core/fragment","mod_customcert/dialogue","core/notification","core/str","core/templates","core/ajax"],function(a,b,c,d,f,g,h,i){var j=function(b){this._node=a(b);this._setEvents()};j.prototype.CUSTOMCERT_REF_POINT_TOPLEFT=0;j.prototype.CUSTOMCERT_REF_POINT_TOPCENTER=1;j.prototype.CUSTOMCERT_REF_POINT_TOPRIGHT=2;j.prototype.PIXELSINMM=3.779527559055;j.prototype._setEvents=function(){this._node.on("click",".element",this._editElement.bind(this))};j.prototype._editElement=function(a){var e=a.currentTarget.id.substr(8),h=this._node.attr("data-contextid");c.loadFragment("mod_customcert","editelement",h,{elementid:e}).done(function(a,c){g.get_string("editelement","mod_customcert").done(function(f){b.use("moodle-core-formchangechecker",function(){new d(f,"
",this._editElementDialogueConfig.bind(this,e,a,c),void 0,!0)}.bind(this))}.bind(this))}.bind(this)).fail(f.exception)};j.prototype._editElementDialogueConfig=function(b,c,d,g){h.replaceNode("#elementcontent",c,d);this._setPositionInForm(b);var i=a(g.getContent());i.on("click","#id_submitbutton",function(c){M.core_formchangechecker.reset_form_dirty_state();this._saveElement(b).then(function(){this._getElementHTML(b).done(function(c){var d=this._node.find("#element-"+b),e=parseInt(a("#id_refpoint").val()),f="";if(e==this.CUSTOMCERT_REF_POINT_TOPLEFT){f="refpoint-left"}else if(e==this.CUSTOMCERT_REF_POINT_TOPCENTER){f="refpoint-center"}else if(e==this.CUSTOMCERT_REF_POINT_TOPRIGHT){f="refpoint-right"}d.empty().append(c);d.removeClass();d.addClass("element "+f);d.attr("data-refpoint",e);var h=a("#editelementform #id_posx").val(),i=a("#editelementform #id_posy").val();this._setPosition(b,e,h,i);g.close()}.bind(this))}.bind(this)).fail(f.exception);c.preventDefault()}.bind(this));i.on("click","#id_cancel",function(a){g.close();a.preventDefault()})};j.prototype._setPosition=function(a,c,d,e){var f=b.one("#element-"+a);d=b.one("#pdf").getX()+d*this.PIXELSINMM;e=b.one("#pdf").getY()+e*this.PIXELSINMM;var g=parseFloat(f.getComputedStyle("width")),h=f.width*this.PIXELSINMM;if(h&&g>h){g=h}switch(c){case this.CUSTOMCERT_REF_POINT_TOPCENTER:d-=g/2;break;case this.CUSTOMCERT_REF_POINT_TOPRIGHT:d=d-g+2;break;}f.setX(d);f.setY(e)};j.prototype._setPositionInForm=function(c){var d=a("#editelementform #id_posx"),e=a("#editelementform #id_posy");if(d.length&&e.length){var f=b.one("#element-"+c),g=f.getX()-b.one("#pdf").getX(),h=f.getY()-b.one("#pdf").getY(),i=parseInt(f.getData("refpoint")),j=parseFloat(f.getComputedStyle("width"));switch(i){case this.CUSTOMCERT_REF_POINT_TOPCENTER:g+=j/2;break;case this.CUSTOMCERT_REF_POINT_TOPRIGHT:g+=j;break;}g=Math.round(parseFloat(g/this.PIXELSINMM));h=Math.round(parseFloat(h/this.PIXELSINMM));d.val(g);e.val(h)}};j.prototype._getElementHTML=function(a){var b=this._node.attr("data-templateid"),c=i.call([{methodname:"mod_customcert_get_element_html",args:{templateid:b,elementid:a}}]);return c[0]};j.prototype._saveElement=function(b){var c=this._node.attr("data-templateid"),d=a("#editelementform").serializeArray(),e=i.call([{methodname:"mod_customcert_save_element",args:{templateid:c,elementid:b,values:d}}]);return e[0]};return{init:function init(a){new j(a)}}}); -//# sourceMappingURL=rearrange-area.min.js.map diff --git a/amd/build/rearrange-area.min.js.map b/amd/build/rearrange-area.min.js.map deleted file mode 100644 index 90a5924..0000000 --- a/amd/build/rearrange-area.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../src/rearrange-area.js"],"names":["define","$","Y","fragment","Dialogue","notification","str","template","ajax","RearrangeArea","selector","_node","_setEvents","prototype","CUSTOMCERT_REF_POINT_TOPLEFT","CUSTOMCERT_REF_POINT_TOPCENTER","CUSTOMCERT_REF_POINT_TOPRIGHT","PIXELSINMM","on","_editElement","bind","event","elementid","currentTarget","id","substr","contextid","attr","loadFragment","done","html","js","get_string","title","use","_editElementDialogueConfig","fail","exception","popup","replaceNode","_setPositionInForm","body","getContent","e","M","core_formchangechecker","reset_form_dirty_state","_saveElement","then","_getElementHTML","elementNode","find","refpoint","parseInt","val","refpointClass","empty","append","removeClass","addClass","posx","posy","_setPosition","close","preventDefault","element","one","getX","getY","nodewidth","parseFloat","getComputedStyle","maxwidth","width","setX","setY","posxelement","posyelement","length","getData","Math","round","templateid","promises","call","methodname","args","inputs","serializeArray","values","init"],"mappings":"AAsBAA,OAAM,iCAAC,CAAC,QAAD,CAAW,UAAX,CAAuB,eAAvB,CAAwC,yBAAxC,CAAmE,mBAAnE,CACC,UADD,CACa,gBADb,CAC+B,WAD/B,CAAD,CAEE,SAASC,CAAT,CAAYC,CAAZ,CAAeC,CAAf,CAAyBC,CAAzB,CAAmCC,CAAnC,CAAiDC,CAAjD,CAAsDC,CAAtD,CAAgEC,CAAhE,CAAsE,CAOlE,GAAIC,CAAAA,CAAa,CAAG,SAASC,CAAT,CAAmB,CACnC,KAAKC,KAAL,CAAaV,CAAC,CAACS,CAAD,CAAd,CACA,KAAKE,UAAL,EACH,CAHD,CAKAH,CAAa,CAACI,SAAd,CAAwBC,4BAAxB,CAAuD,CAAvD,CACAL,CAAa,CAACI,SAAd,CAAwBE,8BAAxB,CAAyD,CAAzD,CACAN,CAAa,CAACI,SAAd,CAAwBG,6BAAxB,CAAwD,CAAxD,CACAP,CAAa,CAACI,SAAd,CAAwBI,UAAxB,CAAqC,cAArC,CAEAR,CAAa,CAACI,SAAd,CAAwBD,UAAxB,CAAqC,UAAW,CAC5C,KAAKD,KAAL,CAAWO,EAAX,CAAc,OAAd,CAAuB,UAAvB,CAAmC,KAAKC,YAAL,CAAkBC,IAAlB,CAAuB,IAAvB,CAAnC,CACH,CAFD,CAIAX,CAAa,CAACI,SAAd,CAAwBM,YAAxB,CAAuC,SAASE,CAAT,CAAgB,IAC/CC,CAAAA,CAAS,CAAGD,CAAK,CAACE,aAAN,CAAoBC,EAApB,CAAuBC,MAAvB,CAA8B,CAA9B,CADmC,CAE/CC,CAAS,CAAG,KAAKf,KAAL,CAAWgB,IAAX,CAAgB,gBAAhB,CAFmC,CAOnDxB,CAAQ,CAACyB,YAAT,CAAsB,gBAAtB,CAAwC,aAAxC,CAAuDF,CAAvD,CAJa,CACT,UAAaJ,CADJ,CAIb,EAA0EO,IAA1E,CAA+E,SAASC,CAAT,CAAeC,CAAf,CAAmB,CAC9FzB,CAAG,CAAC0B,UAAJ,CAAe,aAAf,CAA8B,gBAA9B,EAAgDH,IAAhD,CAAqD,SAASI,CAAT,CAAgB,CACjE/B,CAAC,CAACgC,GAAF,CAAM,+BAAN,CAAuC,UAAW,CAC9C,GAAI9B,CAAAA,CAAJ,CACI6B,CADJ,CAEI,iCAFJ,CAGI,KAAKE,0BAAL,CAAgCf,IAAhC,CAAqC,IAArC,CAA2CE,CAA3C,CAAsDQ,CAAtD,CAA4DC,CAA5D,CAHJ,WAOH,CARsC,CAQrCX,IARqC,CAQhC,IARgC,CAAvC,CASH,CAVoD,CAUnDA,IAVmD,CAU9C,IAV8C,CAArD,CAWH,CAZ8E,CAY7EA,IAZ6E,CAYxE,IAZwE,CAA/E,EAYcgB,IAZd,CAYmB/B,CAAY,CAACgC,SAZhC,CAaH,CApBD,CAsBA5B,CAAa,CAACI,SAAd,CAAwBsB,0BAAxB,CAAqD,SAASb,CAAT,CAAoBQ,CAApB,CAA0BC,CAA1B,CAA8BO,CAA9B,CAAqC,CAEtF/B,CAAQ,CAACgC,WAAT,CAAqB,iBAArB,CAAwCT,CAAxC,CAA8CC,CAA9C,EAIA,KAAKS,kBAAL,CAAwBlB,CAAxB,EAGA,GAAImB,CAAAA,CAAI,CAAGxC,CAAC,CAACqC,CAAK,CAACI,UAAN,EAAD,CAAZ,CACAD,CAAI,CAACvB,EAAL,CAAQ,OAAR,CAAiB,kBAAjB,CAAqC,SAASyB,CAAT,CAAY,CAE7CC,CAAC,CAACC,sBAAF,CAAyBC,sBAAzB,GAEA,KAAKC,YAAL,CAAkBzB,CAAlB,EAA6B0B,IAA7B,CAAkC,UAAW,CAEzC,KAAKC,eAAL,CAAqB3B,CAArB,EAAgCO,IAAhC,CAAqC,SAASC,CAAT,CAAe,IAC5CoB,CAAAA,CAAW,CAAG,KAAKvC,KAAL,CAAWwC,IAAX,CAAgB,YAAc7B,CAA9B,CAD8B,CAE5C8B,CAAQ,CAAGC,QAAQ,CAACpD,CAAC,CAAC,cAAD,CAAD,CAAkBqD,GAAlB,EAAD,CAFyB,CAG5CC,CAAa,CAAG,EAH4B,CAIhD,GAAIH,CAAQ,EAAI,KAAKtC,4BAArB,CAAmD,CAC/CyC,CAAa,CAAG,eACnB,CAFD,IAEO,IAAIH,CAAQ,EAAI,KAAKrC,8BAArB,CAAqD,CACxDwC,CAAa,CAAG,iBACnB,CAFM,IAEA,IAAIH,CAAQ,EAAI,KAAKpC,6BAArB,CAAoD,CACvDuC,CAAa,CAAG,gBACnB,CACDL,CAAW,CAACM,KAAZ,GAAoBC,MAApB,CAA2B3B,CAA3B,EAEAoB,CAAW,CAACQ,WAAZ,GACAR,CAAW,CAACS,QAAZ,CAAqB,WAAaJ,CAAlC,EACAL,CAAW,CAACvB,IAAZ,CAAiB,eAAjB,CAAkCyB,CAAlC,EAfgD,GAiB5CQ,CAAAA,CAAI,CAAG3D,CAAC,CAAC,2BAAD,CAAD,CAA+BqD,GAA/B,EAjBqC,CAkB5CO,CAAI,CAAG5D,CAAC,CAAC,2BAAD,CAAD,CAA+BqD,GAA/B,EAlBqC,CAmBhD,KAAKQ,YAAL,CAAkBxC,CAAlB,CAA6B8B,CAA7B,CAAuCQ,CAAvC,CAA6CC,CAA7C,EAEAvB,CAAK,CAACyB,KAAN,EACH,CAtBoC,CAsBnC3C,IAtBmC,CAsB9B,IAtB8B,CAArC,CAuBH,CAzBiC,CAyBhCA,IAzBgC,CAyB3B,IAzB2B,CAAlC,EAyBcgB,IAzBd,CAyBmB/B,CAAY,CAACgC,SAzBhC,EA0BAM,CAAC,CAACqB,cAAF,EACH,CA/BoC,CA+BnC5C,IA/BmC,CA+B9B,IA/B8B,CAArC,EAiCAqB,CAAI,CAACvB,EAAL,CAAQ,OAAR,CAAiB,YAAjB,CAA+B,SAASyB,CAAT,CAAY,CACvCL,CAAK,CAACyB,KAAN,GACApB,CAAC,CAACqB,cAAF,EACH,CAHD,CAIH,CA/CD,CAiDAvD,CAAa,CAACI,SAAd,CAAwBiD,YAAxB,CAAuC,SAASxC,CAAT,CAAoB8B,CAApB,CAA8BQ,CAA9B,CAAoCC,CAApC,CAA0C,CAC7E,GAAII,CAAAA,CAAO,CAAG/D,CAAC,CAACgE,GAAF,CAAM,YAAc5C,CAApB,CAAd,CAEAsC,CAAI,CAAG1D,CAAC,CAACgE,GAAF,CAAM,MAAN,EAAcC,IAAd,GAAuBP,CAAI,CAAG,KAAK3C,UAA1C,CACA4C,CAAI,CAAG3D,CAAC,CAACgE,GAAF,CAAM,MAAN,EAAcE,IAAd,GAAuBP,CAAI,CAAG,KAAK5C,UAA1C,CAJ6E,GAKzEoD,CAAAA,CAAS,CAAGC,UAAU,CAACL,CAAO,CAACM,gBAAR,CAAyB,OAAzB,CAAD,CALmD,CAMzEC,CAAQ,CAAGP,CAAO,CAACQ,KAAR,CAAgB,KAAKxD,UANyC,CAQ7E,GAAIuD,CAAQ,EAAKH,CAAS,CAAGG,CAA7B,CAAwC,CACpCH,CAAS,CAAGG,CACf,CAED,OAAQpB,CAAR,EACI,IAAK,MAAKrC,8BAAV,CACI6C,CAAI,EAAIS,CAAS,CAAG,CAApB,CACA,MACJ,IAAK,MAAKrD,6BAAV,CACI4C,CAAI,CAAGA,CAAI,CAAGS,CAAP,CAAmB,CAA1B,CACA,MANR,CASAJ,CAAO,CAACS,IAAR,CAAad,CAAb,EACAK,CAAO,CAACU,IAAR,CAAad,CAAb,CACH,CAvBD,CAyBApD,CAAa,CAACI,SAAd,CAAwB2B,kBAAxB,CAA6C,SAASlB,CAAT,CAAoB,IACzDsD,CAAAA,CAAW,CAAG3E,CAAC,CAAC,2BAAD,CAD0C,CAEzD4E,CAAW,CAAG5E,CAAC,CAAC,2BAAD,CAF0C,CAI7D,GAAI2E,CAAW,CAACE,MAAZ,EAAsBD,CAAW,CAACC,MAAtC,CAA8C,IACtCb,CAAAA,CAAO,CAAG/D,CAAC,CAACgE,GAAF,CAAM,YAAc5C,CAApB,CAD4B,CAEtCsC,CAAI,CAAGK,CAAO,CAACE,IAAR,GAAiBjE,CAAC,CAACgE,GAAF,CAAM,MAAN,EAAcC,IAAd,EAFc,CAGtCN,CAAI,CAAGI,CAAO,CAACG,IAAR,GAAiBlE,CAAC,CAACgE,GAAF,CAAM,MAAN,EAAcE,IAAd,EAHc,CAItChB,CAAQ,CAAGC,QAAQ,CAACY,CAAO,CAACc,OAAR,CAAgB,UAAhB,CAAD,CAJmB,CAKtCV,CAAS,CAAGC,UAAU,CAACL,CAAO,CAACM,gBAAR,CAAyB,OAAzB,CAAD,CALgB,CAO1C,OAAQnB,CAAR,EACI,IAAK,MAAKrC,8BAAV,CACI6C,CAAI,EAAIS,CAAS,CAAG,CAApB,CACA,MACJ,IAAK,MAAKrD,6BAAV,CACI4C,CAAI,EAAIS,CAAR,CACA,MANR,CASAT,CAAI,CAAGoB,IAAI,CAACC,KAAL,CAAWX,UAAU,CAACV,CAAI,CAAG,KAAK3C,UAAb,CAArB,CAAP,CACA4C,CAAI,CAAGmB,IAAI,CAACC,KAAL,CAAWX,UAAU,CAACT,CAAI,CAAG,KAAK5C,UAAb,CAArB,CAAP,CAEA2D,CAAW,CAACtB,GAAZ,CAAgBM,CAAhB,EACAiB,CAAW,CAACvB,GAAZ,CAAgBO,CAAhB,CACH,CACJ,CA1BD,CA4BApD,CAAa,CAACI,SAAd,CAAwBoC,eAAxB,CAA0C,SAAS3B,CAAT,CAAoB,IAEtD4D,CAAAA,CAAU,CAAG,KAAKvE,KAAL,CAAWgB,IAAX,CAAgB,iBAAhB,CAFyC,CAKtDwD,CAAQ,CAAG3E,CAAI,CAAC4E,IAAL,CAAU,CAAC,CACtBC,UAAU,CAAE,iCADU,CAEtBC,IAAI,CAAE,CACFJ,UAAU,CAAEA,CADV,CAEF5D,SAAS,CAAEA,CAFT,CAFgB,CAAD,CAAV,CAL2C,CAc1D,MAAO6D,CAAAA,CAAQ,CAAC,CAAD,CAClB,CAfD,CAiBA1E,CAAa,CAACI,SAAd,CAAwBkC,YAAxB,CAAuC,SAASzB,CAAT,CAAoB,IAEnD4D,CAAAA,CAAU,CAAG,KAAKvE,KAAL,CAAWgB,IAAX,CAAgB,iBAAhB,CAFsC,CAGnD4D,CAAM,CAAGtF,CAAC,CAAC,kBAAD,CAAD,CAAsBuF,cAAtB,EAH0C,CAMnDL,CAAQ,CAAG3E,CAAI,CAAC4E,IAAL,CAAU,CAAC,CACtBC,UAAU,CAAE,6BADU,CAEtBC,IAAI,CAAE,CACFJ,UAAU,CAAEA,CADV,CAEF5D,SAAS,CAAEA,CAFT,CAGFmE,MAAM,CAAEF,CAHN,CAFgB,CAAD,CAAV,CANwC,CAgBvD,MAAOJ,CAAAA,CAAQ,CAAC,CAAD,CAClB,CAjBD,CAmBA,MAAO,CACHO,IAAI,CAAE,cAAShF,CAAT,CAAmB,CACrB,GAAID,CAAAA,CAAJ,CAAkBC,CAAlB,CACH,CAHE,CAKV,CA5LH,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * AMD module used when rearranging a custom certificate.\n *\n * @module mod_customcert/rearrange-area\n * @copyright 2016 Mark Nelson \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/yui', 'core/fragment', 'mod_customcert/dialogue', 'core/notification',\n 'core/str', 'core/templates', 'core/ajax'],\n function($, Y, fragment, Dialogue, notification, str, template, ajax) {\n\n /**\n * RearrangeArea class.\n *\n * @param {String} selector The rearrange PDF selector\n */\n var RearrangeArea = function(selector) {\n this._node = $(selector);\n this._setEvents();\n };\n\n RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPLEFT = 0;\n RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPCENTER = 1;\n RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPRIGHT = 2;\n RearrangeArea.prototype.PIXELSINMM = 3.779527559055;\n\n RearrangeArea.prototype._setEvents = function() {\n this._node.on('click', '.element', this._editElement.bind(this));\n };\n\n RearrangeArea.prototype._editElement = function(event) {\n var elementid = event.currentTarget.id.substr(8);\n var contextid = this._node.attr('data-contextid');\n var params = {\n 'elementid': elementid\n };\n\n fragment.loadFragment('mod_customcert', 'editelement', contextid, params).done(function(html, js) {\n str.get_string('editelement', 'mod_customcert').done(function(title) {\n Y.use('moodle-core-formchangechecker', function() {\n new Dialogue(\n title,\n '
',\n this._editElementDialogueConfig.bind(this, elementid, html, js),\n undefined,\n true\n );\n }.bind(this));\n }.bind(this));\n }.bind(this)).fail(notification.exception);\n };\n\n RearrangeArea.prototype._editElementDialogueConfig = function(elementid, html, js, popup) {\n // Place the content in the dialogue.\n template.replaceNode('#elementcontent', html, js);\n\n // We may have dragged the element changing it's position.\n // Ensure the form has the current up-to-date location.\n this._setPositionInForm(elementid);\n\n // Add events for when we save, close and cancel the page.\n var body = $(popup.getContent());\n body.on('click', '#id_submitbutton', function(e) {\n // Do not want to ask the user if they wish to stay on page after saving.\n M.core_formchangechecker.reset_form_dirty_state();\n // Save the data.\n this._saveElement(elementid).then(function() {\n // Update the DOM to reflect the adjusted value.\n this._getElementHTML(elementid).done(function(html) {\n var elementNode = this._node.find('#element-' + elementid);\n var refpoint = parseInt($('#id_refpoint').val());\n var refpointClass = '';\n if (refpoint == this.CUSTOMCERT_REF_POINT_TOPLEFT) {\n refpointClass = 'refpoint-left';\n } else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPCENTER) {\n refpointClass = 'refpoint-center';\n } else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPRIGHT) {\n refpointClass = 'refpoint-right';\n }\n elementNode.empty().append(html);\n // Update the ref point.\n elementNode.removeClass();\n elementNode.addClass('element ' + refpointClass);\n elementNode.attr('data-refpoint', refpoint);\n // Move the element.\n var posx = $('#editelementform #id_posx').val();\n var posy = $('#editelementform #id_posy').val();\n this._setPosition(elementid, refpoint, posx, posy);\n // All done.\n popup.close();\n }.bind(this));\n }.bind(this)).fail(notification.exception);\n e.preventDefault();\n }.bind(this));\n\n body.on('click', '#id_cancel', function(e) {\n popup.close();\n e.preventDefault();\n });\n };\n\n RearrangeArea.prototype._setPosition = function(elementid, refpoint, posx, posy) {\n var element = Y.one('#element-' + elementid);\n\n posx = Y.one('#pdf').getX() + posx * this.PIXELSINMM;\n posy = Y.one('#pdf').getY() + posy * this.PIXELSINMM;\n var nodewidth = parseFloat(element.getComputedStyle('width'));\n var maxwidth = element.width * this.PIXELSINMM;\n\n if (maxwidth && (nodewidth > maxwidth)) {\n nodewidth = maxwidth;\n }\n\n switch (refpoint) {\n case this.CUSTOMCERT_REF_POINT_TOPCENTER:\n posx -= nodewidth / 2;\n break;\n case this.CUSTOMCERT_REF_POINT_TOPRIGHT:\n posx = posx - nodewidth + 2;\n break;\n }\n\n element.setX(posx);\n element.setY(posy);\n };\n\n RearrangeArea.prototype._setPositionInForm = function(elementid) {\n var posxelement = $('#editelementform #id_posx');\n var posyelement = $('#editelementform #id_posy');\n\n if (posxelement.length && posyelement.length) {\n var element = Y.one('#element-' + elementid);\n var posx = element.getX() - Y.one('#pdf').getX();\n var posy = element.getY() - Y.one('#pdf').getY();\n var refpoint = parseInt(element.getData('refpoint'));\n var nodewidth = parseFloat(element.getComputedStyle('width'));\n\n switch (refpoint) {\n case this.CUSTOMCERT_REF_POINT_TOPCENTER:\n posx += nodewidth / 2;\n break;\n case this.CUSTOMCERT_REF_POINT_TOPRIGHT:\n posx += nodewidth;\n break;\n }\n\n posx = Math.round(parseFloat(posx / this.PIXELSINMM));\n posy = Math.round(parseFloat(posy / this.PIXELSINMM));\n\n posxelement.val(posx);\n posyelement.val(posy);\n }\n };\n\n RearrangeArea.prototype._getElementHTML = function(elementid) {\n // Get the variables we need.\n var templateid = this._node.attr('data-templateid');\n\n // Call the web service to get the updated element.\n var promises = ajax.call([{\n methodname: 'mod_customcert_get_element_html',\n args: {\n templateid: templateid,\n elementid: elementid\n }\n }]);\n\n // Return the promise.\n return promises[0];\n };\n\n RearrangeArea.prototype._saveElement = function(elementid) {\n // Get the variables we need.\n var templateid = this._node.attr('data-templateid');\n var inputs = $('#editelementform').serializeArray();\n\n // Call the web service to save the element.\n var promises = ajax.call([{\n methodname: 'mod_customcert_save_element',\n args: {\n templateid: templateid,\n elementid: elementid,\n values: inputs\n }\n }]);\n\n // Return the promise.\n return promises[0];\n };\n\n return {\n init: function(selector) {\n new RearrangeArea(selector);\n }\n };\n }\n );\n"],"file":"rearrange-area.min.js"} \ No newline at end of file diff --git a/amd/src/dialogue.js b/amd/src/dialogue.js deleted file mode 100644 index 6bb9347..0000000 --- a/amd/src/dialogue.js +++ /dev/null @@ -1,101 +0,0 @@ -// This file is part of Moodle - http://moodle.org/ -// -// Moodle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Moodle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Moodle. If not, see . - -/** - * Wrapper for the YUI M.core.notification class. Allows us to - * use the YUI version in AMD code until it is replaced. - * - * @module mod_customcert/dialogue - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define(['core/yui'], function(Y) { - - /** - * Constructor - * - * @param {String} title Title for the window. - * @param {String} content The content for the window. - * @param {function} afterShow Callback executed after the window is opened. - * @param {function} afterHide Callback executed after the window is closed. - * @param {Boolean} wide Specify we want an extra wide dialogue (the size is standard, but wider than the default). - */ - var dialogue = function(title, content, afterShow, afterHide, wide) { - this.yuiDialogue = null; - var parent = this; - - // Default for wide is false. - if (typeof wide == 'undefined') { - wide = false; - } - - Y.use('moodle-core-notification', 'timers', function() { - var width = '480px'; - if (wide) { - width = '800px'; - } - - parent.yuiDialogue = new M.core.dialogue({ - headerContent: title, - bodyContent: content, - draggable: true, - visible: false, - center: true, - modal: true, - width: width - }); - - parent.yuiDialogue.after('visibleChange', function(e) { - if (e.newVal) { - // Delay the callback call to the next tick, otherwise it can happen that it is - // executed before the dialogue constructor returns. - if ((typeof afterShow !== 'undefined')) { - Y.soon(function() { - afterShow(parent); - parent.yuiDialogue.centerDialogue(); - }); - } - } else { - if ((typeof afterHide !== 'undefined')) { - Y.soon(function() { - afterHide(parent); - }); - } - } - }); - - parent.yuiDialogue.show(); - }); - }; - - /** - * Close this window. - */ - dialogue.prototype.close = function() { - this.yuiDialogue.hide(); - this.yuiDialogue.destroy(); - }; - - /** - * Get content. - * - * @returns {HTMLElement} - */ - dialogue.prototype.getContent = function() { - return this.yuiDialogue.bodyNode.getDOMNode(); - }; - - return dialogue; -}); diff --git a/amd/src/rearrange-area.js b/amd/src/rearrange-area.js deleted file mode 100644 index 1099d25..0000000 --- a/amd/src/rearrange-area.js +++ /dev/null @@ -1,212 +0,0 @@ -// This file is part of Moodle - http://moodle.org/ -// -// Moodle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Moodle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Moodle. If not, see . - -/** - * AMD module used when rearranging a custom certificate. - * - * @module mod_customcert/rearrange-area - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define(['jquery', 'core/yui', 'core/fragment', 'mod_customcert/dialogue', 'core/notification', - 'core/str', 'core/templates', 'core/ajax'], - function($, Y, fragment, Dialogue, notification, str, template, ajax) { - - /** - * RearrangeArea class. - * - * @param {String} selector The rearrange PDF selector - */ - var RearrangeArea = function(selector) { - this._node = $(selector); - this._setEvents(); - }; - - RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPLEFT = 0; - RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPCENTER = 1; - RearrangeArea.prototype.CUSTOMCERT_REF_POINT_TOPRIGHT = 2; - RearrangeArea.prototype.PIXELSINMM = 3.779527559055; - - RearrangeArea.prototype._setEvents = function() { - this._node.on('click', '.element', this._editElement.bind(this)); - }; - - RearrangeArea.prototype._editElement = function(event) { - var elementid = event.currentTarget.id.substr(8); - var contextid = this._node.attr('data-contextid'); - var params = { - 'elementid': elementid - }; - - fragment.loadFragment('mod_customcert', 'editelement', contextid, params).done(function(html, js) { - str.get_string('editelement', 'mod_customcert').done(function(title) { - Y.use('moodle-core-formchangechecker', function() { - new Dialogue( - title, - '
', - this._editElementDialogueConfig.bind(this, elementid, html, js), - undefined, - true - ); - }.bind(this)); - }.bind(this)); - }.bind(this)).fail(notification.exception); - }; - - RearrangeArea.prototype._editElementDialogueConfig = function(elementid, html, js, popup) { - // Place the content in the dialogue. - template.replaceNode('#elementcontent', html, js); - - // We may have dragged the element changing it's position. - // Ensure the form has the current up-to-date location. - this._setPositionInForm(elementid); - - // Add events for when we save, close and cancel the page. - var body = $(popup.getContent()); - body.on('click', '#id_submitbutton', function(e) { - // Do not want to ask the user if they wish to stay on page after saving. - M.core_formchangechecker.reset_form_dirty_state(); - // Save the data. - this._saveElement(elementid).then(function() { - // Update the DOM to reflect the adjusted value. - this._getElementHTML(elementid).done(function(html) { - var elementNode = this._node.find('#element-' + elementid); - var refpoint = parseInt($('#id_refpoint').val()); - var refpointClass = ''; - if (refpoint == this.CUSTOMCERT_REF_POINT_TOPLEFT) { - refpointClass = 'refpoint-left'; - } else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPCENTER) { - refpointClass = 'refpoint-center'; - } else if (refpoint == this.CUSTOMCERT_REF_POINT_TOPRIGHT) { - refpointClass = 'refpoint-right'; - } - elementNode.empty().append(html); - // Update the ref point. - elementNode.removeClass(); - elementNode.addClass('element ' + refpointClass); - elementNode.attr('data-refpoint', refpoint); - // Move the element. - var posx = $('#editelementform #id_posx').val(); - var posy = $('#editelementform #id_posy').val(); - this._setPosition(elementid, refpoint, posx, posy); - // All done. - popup.close(); - }.bind(this)); - }.bind(this)).fail(notification.exception); - e.preventDefault(); - }.bind(this)); - - body.on('click', '#id_cancel', function(e) { - popup.close(); - e.preventDefault(); - }); - }; - - RearrangeArea.prototype._setPosition = function(elementid, refpoint, posx, posy) { - var element = Y.one('#element-' + elementid); - - posx = Y.one('#pdf').getX() + posx * this.PIXELSINMM; - posy = Y.one('#pdf').getY() + posy * this.PIXELSINMM; - var nodewidth = parseFloat(element.getComputedStyle('width')); - var maxwidth = element.width * this.PIXELSINMM; - - if (maxwidth && (nodewidth > maxwidth)) { - nodewidth = maxwidth; - } - - switch (refpoint) { - case this.CUSTOMCERT_REF_POINT_TOPCENTER: - posx -= nodewidth / 2; - break; - case this.CUSTOMCERT_REF_POINT_TOPRIGHT: - posx = posx - nodewidth + 2; - break; - } - - element.setX(posx); - element.setY(posy); - }; - - RearrangeArea.prototype._setPositionInForm = function(elementid) { - var posxelement = $('#editelementform #id_posx'); - var posyelement = $('#editelementform #id_posy'); - - if (posxelement.length && posyelement.length) { - var element = Y.one('#element-' + elementid); - var posx = element.getX() - Y.one('#pdf').getX(); - var posy = element.getY() - Y.one('#pdf').getY(); - var refpoint = parseInt(element.getData('refpoint')); - var nodewidth = parseFloat(element.getComputedStyle('width')); - - switch (refpoint) { - case this.CUSTOMCERT_REF_POINT_TOPCENTER: - posx += nodewidth / 2; - break; - case this.CUSTOMCERT_REF_POINT_TOPRIGHT: - posx += nodewidth; - break; - } - - posx = Math.round(parseFloat(posx / this.PIXELSINMM)); - posy = Math.round(parseFloat(posy / this.PIXELSINMM)); - - posxelement.val(posx); - posyelement.val(posy); - } - }; - - RearrangeArea.prototype._getElementHTML = function(elementid) { - // Get the variables we need. - var templateid = this._node.attr('data-templateid'); - - // Call the web service to get the updated element. - var promises = ajax.call([{ - methodname: 'mod_customcert_get_element_html', - args: { - templateid: templateid, - elementid: elementid - } - }]); - - // Return the promise. - return promises[0]; - }; - - RearrangeArea.prototype._saveElement = function(elementid) { - // Get the variables we need. - var templateid = this._node.attr('data-templateid'); - var inputs = $('#editelementform').serializeArray(); - - // Call the web service to save the element. - var promises = ajax.call([{ - methodname: 'mod_customcert_save_element', - args: { - templateid: templateid, - elementid: elementid, - values: inputs - } - }]); - - // Return the promise. - return promises[0]; - }; - - return { - init: function(selector) { - new RearrangeArea(selector); - } - }; - } - ); diff --git a/backup/moodle2/backup_customcert_activity_task.class.php b/backup/moodle2/backup_customcert_activity_task.class.php index a4f2ae6..4aec8e7 100644 --- a/backup/moodle2/backup_customcert_activity_task.class.php +++ b/backup/moodle2/backup_customcert_activity_task.class.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); -require_once($CFG->dirroot . '/mod/customcert/backup/moodle2/backup_customcert_stepslib.php'); +require_once($CFG->dirroot . '/mod/htmlcert/backup/moodle2/backup_htmlcert_stepslib.php'); /** * Handles creating tasks to peform in order to create the backup. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class backup_customcert_activity_task extends backup_activity_task { +class backup_htmlcert_activity_task extends backup_activity_task { /** * Define particular settings this activity can have. @@ -46,8 +46,8 @@ class backup_customcert_activity_task extends backup_activity_task { * Define particular steps this activity can have. */ protected function define_my_steps() { - // The customcert only has one structure step. - $this->add_step(new backup_customcert_activity_structure_step('customcert_structure', 'customcert.xml')); + // The htmlcert only has one structure step. + $this->add_step(new backup_htmlcert_activity_structure_step('htmlcert_structure', 'htmlcert.xml')); } /** @@ -61,13 +61,13 @@ class backup_customcert_activity_task extends backup_activity_task { $base = preg_quote($CFG->wwwroot, "/"); - // Link to the list of customcerts. - $search = "/(".$base."\/mod\/customcert\/index.php\?id\=)([0-9]+)/"; - $content = preg_replace($search, '$@CUSTOMCERTINDEX*$2@$', $content); + // Link to the list of htmlcerts. + $search = "/(".$base."\/mod\/htmlcert\/index.php\?id\=)([0-9]+)/"; + $content = preg_replace($search, '$@HTMLCERTINDEX*$2@$', $content); - // Link to customcert view by moduleid. - $search = "/(".$base."\/mod\/customcert\/view.php\?id\=)([0-9]+)/"; - $content = preg_replace($search, '$@CUSTOMCERTVIEWBYID*$2@$', $content); + // Link to htmlcert view by moduleid. + $search = "/(".$base."\/mod\/htmlcert\/view.php\?id\=)([0-9]+)/"; + $content = preg_replace($search, '$@HTMLCERTVIEWBYID*$2@$', $content); return $content; } diff --git a/backup/moodle2/backup_customcert_stepslib.php b/backup/moodle2/backup_customcert_stepslib.php index 7c01ee0..43282af 100644 --- a/backup/moodle2/backup_customcert_stepslib.php +++ b/backup/moodle2/backup_customcert_stepslib.php @@ -1,5 +1,5 @@ . /** - * Define all the backup steps that will be used by the backup_customcert_activity_task. + * Define all the backup steps that will be used by the backup_htmlcert_activity_task. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); /** - * Define the complete customcert structure for backup, with file and id annotations. + * Define the complete htmlcert structure for backup, with file and id annotations. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class backup_customcert_activity_structure_step extends backup_activity_structure_step { +class backup_htmlcert_activity_structure_step extends backup_activity_structure_step { /** * Define the structure of the backup file. @@ -41,7 +41,7 @@ class backup_customcert_activity_structure_step extends backup_activity_structur protected function define_structure() { // The instance. - $customcert = new backup_nested_element('customcert', array('id'), array( + $htmlcert = new backup_nested_element('htmlcert', array('id'), array( 'templateid', 'name', 'intro', 'introformat', 'requiredtime', 'verifyany', 'emailstudents', 'emailteachers', 'emailothers', 'protection', 'timecreated', 'timemodified')); @@ -49,56 +49,35 @@ class backup_customcert_activity_structure_step extends backup_activity_structur $template = new backup_nested_element('template', array('id'), array( 'name', 'contextid', 'timecreated', 'timemodified')); - // The pages. - $pages = new backup_nested_element('pages'); - $page = new backup_nested_element('page', array('id'), array( - 'templateid', 'width', 'height', 'leftmargin', 'rightmargin', - 'sequence', 'timecreated', 'timemodified')); - - // The elements. - $element = new backup_nested_element('element', array('id'), array( - 'pageid', 'name', 'element', 'data', 'font', 'fontsize', - 'colour', 'posx', 'posy', 'width', 'refpoint', 'sequence', - 'alignment', 'timecreated', 'timemodified')); - // The issues. $issues = new backup_nested_element('issues'); $issue = new backup_nested_element('issue', array('id'), array( - 'customcertid', 'userid', 'timecreated', 'emailed', 'code')); + 'htmlcertid', 'userid', 'timecreated', 'emailed', 'code')); // Build the tree. - $customcert->add_child($issues); + $htmlcert->add_child($issues); $issues->add_child($issue); - $customcert->add_child($template); - $template->add_child($pages); - $pages->add_child($page); - $page->add_child($element); + $htmlcert->add_child($template); // Define sources. - $customcert->set_source_table('customcert', array('id' => backup::VAR_ACTIVITYID)); + $htmlcert->set_source_table('htmlcert', array('id' => backup::VAR_ACTIVITYID)); // Define template source. - $template->set_source_table('customcert_templates', array('contextid' => backup::VAR_CONTEXTID)); - - // Define page source. - $page->set_source_table('customcert_pages', array('templateid' => backup::VAR_PARENTID)); - - // Define element source, each element belongs to a page. - $element->set_source_table('customcert_elements', array('pageid' => backup::VAR_PARENTID)); + $template->set_source_table('htmlcert_templates', array('contextid' => backup::VAR_CONTEXTID)); // If we are including user info then save the issues. if ($this->get_setting_value('userinfo')) { - $issue->set_source_table('customcert_issues', array('customcertid' => backup::VAR_ACTIVITYID)); + $issue->set_source_table('htmlcert_issues', array('htmlcertid' => backup::VAR_ACTIVITYID)); } // Annotate the user id's where required. $issue->annotate_ids('user', 'userid'); // Define file annotations. - $customcert->annotate_files('mod_customcert', 'intro', null); - $customcert->annotate_files('mod_customcert', 'image', null, context_course::instance($this->get_courseid())->id); + $htmlcert->annotate_files('mod_htmlcert', 'intro', null); + $htmlcert->annotate_files('mod_htmlcert', 'image', null, context_course::instance($this->get_courseid())->id); - // Return the root element (customcert), wrapped into standard activity structure. - return $this->prepare_activity_structure($customcert); + // Return the root element (htmlcert), wrapped into standard activity structure. + return $this->prepare_activity_structure($htmlcert); } } diff --git a/backup/moodle2/restore_customcert_activity_task.class.php b/backup/moodle2/restore_customcert_activity_task.class.php index d21228e..c2680a3 100644 --- a/backup/moodle2/restore_customcert_activity_task.class.php +++ b/backup/moodle2/restore_customcert_activity_task.class.php @@ -1,5 +1,5 @@ . /** - * Define all the restore steps that will be used by the restore_customcert_activity_task. + * Define all the restore steps that will be used by the restore_htmlcert_activity_task. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); -require_once($CFG->dirroot . '/mod/customcert/backup/moodle2/restore_customcert_stepslib.php'); +require_once($CFG->dirroot . '/mod/htmlcert/backup/moodle2/restore_htmlcert_stepslib.php'); /** * The class definition for assigning tasks that provide the settings and steps to perform a restore of the activity. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class restore_customcert_activity_task extends restore_activity_task { +class restore_htmlcert_activity_task extends restore_activity_task { /** * Define particular settings this activity can have. @@ -46,8 +46,8 @@ class restore_customcert_activity_task extends restore_activity_task { * Define particular steps this activity can have. */ protected function define_my_steps() { - // The customcert only has one structure step. - $this->add_step(new restore_customcert_activity_structure_step('customcert_structure', 'customcert.xml')); + // The htmlcert only has one structure step. + $this->add_step(new restore_htmlcert_activity_structure_step('htmlcert_structure', 'htmlcert.xml')); } /** @@ -56,7 +56,7 @@ class restore_customcert_activity_task extends restore_activity_task { public static function define_decode_contents() { $contents = array(); - $contents[] = new restore_decode_content('customcert', array('intro'), 'customcert'); + $contents[] = new restore_decode_content('htmlcert', array('intro'), 'htmlcert'); return $contents; } @@ -67,8 +67,8 @@ class restore_customcert_activity_task extends restore_activity_task { public static function define_decode_rules() { $rules = array(); - $rules[] = new restore_decode_rule('CUSTOMCERTVIEWBYID', '/mod/customcert/view.php?id=$1', 'course_module'); - $rules[] = new restore_decode_rule('CUSTOMCERTINDEX', '/mod/customcert/index.php?id=$1', 'course'); + $rules[] = new restore_decode_rule('HTMLCERTVIEWBYID', '/mod/htmlcert/view.php?id=$1', 'course_module'); + $rules[] = new restore_decode_rule('HTMLCERTINDEX', '/mod/htmlcert/index.php?id=$1', 'course'); return $rules; @@ -76,46 +76,28 @@ class restore_customcert_activity_task extends restore_activity_task { /** * Define the restore log rules that will be applied by the {@see restore_logs_processor} when restoring - * customcert logs. It must return one array of {@see restore_log_rule} objects. + * htmlcert logs. It must return one array of {@see restore_log_rule} objects. * * @return array the restore log rules */ public static function define_restore_log_rules() { $rules = array(); - $rules[] = new restore_log_rule('customcert', 'add', 'view.php?id={course_module}', '{customcert}'); - $rules[] = new restore_log_rule('customcert', 'update', 'view.php?id={course_module}', '{customcert}'); - $rules[] = new restore_log_rule('customcert', 'view', 'view.php?id={course_module}', '{customcert}'); - $rules[] = new restore_log_rule('customcert', 'received', 'view.php?id={course_module}', '{customcert}'); - $rules[] = new restore_log_rule('customcert', 'view report', 'view.php?id={course_module}', '{customcert}'); + $rules[] = new restore_log_rule('htmlcert', 'add', 'view.php?id={course_module}', '{htmlcert}'); + $rules[] = new restore_log_rule('htmlcert', 'update', 'view.php?id={course_module}', '{htmlcert}'); + $rules[] = new restore_log_rule('htmlcert', 'view', 'view.php?id={course_module}', '{htmlcert}'); + $rules[] = new restore_log_rule('htmlcert', 'received', 'view.php?id={course_module}', '{htmlcert}'); + $rules[] = new restore_log_rule('htmlcert', 'view report', 'view.php?id={course_module}', '{htmlcert}'); return $rules; } /** * This function is called after all the activities in the backup have been restored. This allows us to get - * the new course module ids, as they may have been restored after the customcert module, meaning no id + * the new course module ids, as they may have been restored after the htmlcert module, meaning no id * was available at the time. */ public function after_restore() { global $DB; - - // Get the customcert elements. - $sql = "SELECT e.* - FROM {customcert_elements} e - INNER JOIN {customcert_pages} p - ON e.pageid = p.id - INNER JOIN {customcert} c - ON p.templateid = c.templateid - WHERE c.id = :customcertid"; - if ($elements = $DB->get_records_sql($sql, array('customcertid' => $this->get_activityid()))) { - // Go through the elements for the certificate. - foreach ($elements as $e) { - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($e)) { - $e->after_restore($this); - } - } - } } } diff --git a/backup/moodle2/restore_customcert_stepslib.php b/backup/moodle2/restore_customcert_stepslib.php index 92afa28..3c100db 100644 --- a/backup/moodle2/restore_customcert_stepslib.php +++ b/backup/moodle2/restore_customcert_stepslib.php @@ -1,5 +1,5 @@ . /** - * Define all the restore steps that will be used by the restore_customcert_activity_task. + * Define all the restore steps that will be used by the restore_htmlcert_activity_task. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); /** - * Define the complete customcert structure for restore, with file and id annotations. + * Define the complete htmlcert structure for restore, with file and id annotations. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class restore_customcert_activity_structure_step extends restore_activity_structure_step { +class restore_htmlcert_activity_structure_step extends restore_activity_structure_step { /** * Define the different items to restore. @@ -42,21 +42,15 @@ class restore_customcert_activity_structure_step extends restore_activity_struct // The array used to store the path to the items we want to restore. $paths = array(); - // The customcert instance. - $paths[] = new restore_path_element('customcert', '/activity/customcert'); + // The htmlcert instance. + $paths[] = new restore_path_element('htmlcert', '/activity/htmlcert'); // The templates. - $paths[] = new restore_path_element('customcert_template', '/activity/customcert/template'); - - // The pages. - $paths[] = new restore_path_element('customcert_page', '/activity/customcert/template/pages/page'); - - // The elements. - $paths[] = new restore_path_element('customcert_element', '/activity/customcert/template/pages/page/element'); + $paths[] = new restore_path_element('htmlcert_template', '/activity/htmlcert/template'); // Check if we want the issues as well. if ($this->get_setting_value('userinfo')) { - $paths[] = new restore_path_element('customcert_issue', '/activity/customcert/issues/issue'); + $paths[] = new restore_path_element('htmlcert_issue', '/activity/htmlcert/issues/issue'); } // Return the paths wrapped into standard activity structure. @@ -64,11 +58,11 @@ class restore_customcert_activity_structure_step extends restore_activity_struct } /** - * Handles restoring the customcert activity. + * Handles restoring the htmlcert activity. * - * @param stdClass $data the customcert data + * @param stdClass $data the htmlcert data */ - protected function process_customcert($data) { + protected function process_htmlcert($data) { global $DB; $data = (object) $data; @@ -76,19 +70,19 @@ class restore_customcert_activity_structure_step extends restore_activity_struct $data->timecreated = $this->apply_date_offset($data->timecreated); $data->timemodified = $this->apply_date_offset($data->timemodified); - // Insert the customcert record. - $newitemid = $DB->insert_record('customcert', $data); + // Insert the htmlcert record. + $newitemid = $DB->insert_record('htmlcert', $data); // Immediately after inserting record call this. $this->apply_activity_instance($newitemid); } /** - * Handles restoring a customcert page. + * Handles restoring a htmlcert templage. * - * @param stdClass $data the customcert data + * @param stdClass $data the htmlcert data */ - protected function process_customcert_template($data) { + protected function process_htmlcert_template($data) { global $DB; $data = (object) $data; @@ -98,71 +92,33 @@ class restore_customcert_activity_structure_step extends restore_activity_struct $data->timecreated = $this->apply_date_offset($data->timecreated); $data->timemodified = $this->apply_date_offset($data->timemodified); - $newitemid = $DB->insert_record('customcert_templates', $data); - $this->set_mapping('customcert_template', $oldid, $newitemid); + $newitemid = $DB->insert_record('htmlcert_templates', $data); + $this->set_mapping('htmlcert_template', $oldid, $newitemid); - // Update the template id for the customcert. - $customcert = new stdClass(); - $customcert->id = $this->get_new_parentid('customcert'); - $customcert->templateid = $newitemid; - $DB->update_record('customcert', $customcert); + // Update the template id for the htmlcert. + $htmlcert = new stdClass(); + $htmlcert->id = $this->get_new_parentid('htmlcert'); + $htmlcert->templateid = $newitemid; + $DB->update_record('htmlcert', $htmlcert); } /** - * Handles restoring a customcert template. + * Handles restoring a htmlcert issue. * - * @param stdClass $data the customcert data + * @param stdClass $data the htmlcert data */ - protected function process_customcert_page($data) { + protected function process_htmlcert_issue($data) { global $DB; $data = (object) $data; $oldid = $data->id; - $data->templateid = $this->get_new_parentid('customcert_template'); - $data->timecreated = $this->apply_date_offset($data->timecreated); - $data->timemodified = $this->apply_date_offset($data->timemodified); - - $newitemid = $DB->insert_record('customcert_pages', $data); - $this->set_mapping('customcert_page', $oldid, $newitemid); - } - - /** - * Handles restoring a customcert element. - * - * @param stdclass $data the customcert data - */ - protected function process_customcert_element($data) { - global $DB; - - $data = (object) $data; - $oldid = $data->id; - - $data->pageid = $this->get_new_parentid('customcert_page'); - $data->timecreated = $this->apply_date_offset($data->timecreated); - $data->timemodified = $this->apply_date_offset($data->timemodified); - - $newitemid = $DB->insert_record('customcert_elements', $data); - $this->set_mapping('customcert_element', $oldid, $newitemid); - } - - /** - * Handles restoring a customcert issue. - * - * @param stdClass $data the customcert data - */ - protected function process_customcert_issue($data) { - global $DB; - - $data = (object) $data; - $oldid = $data->id; - - $data->customcertid = $this->get_new_parentid('customcert'); + $data->htmlcertid = $this->get_new_parentid('htmlcert'); $data->timecreated = $this->apply_date_offset($data->timecreated); $data->userid = $this->get_mappingid('user', $data->userid); - $newitemid = $DB->insert_record('customcert_issues', $data); - $this->set_mapping('customcert_issue', $oldid, $newitemid); + $newitemid = $DB->insert_record('htmlcert_issues', $data); + $this->set_mapping('htmlcert_issue', $oldid, $newitemid); } /** @@ -172,9 +128,9 @@ class restore_customcert_activity_structure_step extends restore_activity_struct parent::after_execute(); // Add the files. - $this->add_related_files('mod_customcert', 'intro', null); + $this->add_related_files('mod_htmlcert', 'intro', null); // Note - we can't use get_old_contextid() as it refers to the module context. - $this->add_related_files('mod_customcert', 'image', null, $this->get_task()->get_info()->original_course_contextid); + $this->add_related_files('mod_htmlcert', 'image', null, $this->get_task()->get_info()->original_course_contextid); } } diff --git a/classes/admin_setting_link.php b/classes/admin_setting_link.php index f06090a..f099fdb 100644 --- a/classes/admin_setting_link.php +++ b/classes/admin_setting_link.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die(); @@ -31,8 +31,8 @@ require_once($CFG->libdir.'/adminlib.php'); /** * Class extends admin setting class to allow/process an uploaded file * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class admin_setting_link extends \admin_setting_configtext { diff --git a/classes/certificate.php b/classes/certificate.php index 5a4071b..0c24fe6 100644 --- a/classes/certificate.php +++ b/classes/certificate.php @@ -1,5 +1,5 @@ . /** - * Provides functionality needed by customcert activities. + * Provides functionality needed by htmlcert activities. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die(); @@ -31,8 +31,8 @@ defined('MOODLE_INTERNAL') || die(); * * Helper functionality for certificates. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class certificate { @@ -64,12 +64,12 @@ class certificate { /** * @var int the number of issues that will be displayed on each page in the report - * If you want to display all customcerts on a page set this to 0. + * If you want to display all htmlcerts on a page set this to 0. */ - const CUSTOMCERT_PER_PAGE = '50'; + const HTMLCERT_PER_PAGE = '50'; /** - * Handles setting the protection field for the customcert + * Handles setting the protection field for the htmlcert * * @param \stdClass $data * @return string the value to insert into the protection field @@ -92,7 +92,7 @@ class certificate { } /** - * Handles uploading an image for the customcert module. + * Handles uploading an image for the htmlcert module. * * @param int $draftitemid the draft area containing the files * @param int $contextid the context we are storing this image in @@ -103,69 +103,7 @@ class certificate { // Save the file if it exists that is currently in the draft area. require_once($CFG->dirroot . '/lib/filelib.php'); - file_save_draft_area_files($draftitemid, $contextid, 'mod_customcert', $filearea, 0); - } - - /** - * Return the list of possible fonts to use. - */ - public static function get_fonts() { - global $CFG; - - require_once($CFG->libdir . '/pdflib.php'); - - $arrfonts = []; - $pdf = new \pdf(); - $fontfamilies = $pdf->get_font_families(); - foreach ($fontfamilies as $fontfamily => $fontstyles) { - foreach ($fontstyles as $fontstyle) { - $fontstyle = strtolower($fontstyle); - if ($fontstyle == 'r') { - $filenamewoextension = $fontfamily; - } else { - $filenamewoextension = $fontfamily . $fontstyle; - } - $fullpath = \TCPDF_FONTS::_getfontpath() . $filenamewoextension; - // Set the name of the font to null, the include next should then set this - // value, if it is not set then the file does not include the necessary data. - $name = null; - // Some files include a display name, the include next should then set this - // value if it is present, if not then $name is used to create the display name. - $displayname = null; - // Some of the TCPDF files include files that are not present, so we have to - // suppress warnings, this is the TCPDF libraries fault, grrr. - @include($fullpath . '.php'); - // If no $name variable in file, skip it. - if (is_null($name)) { - continue; - } - // Check if there is no display name to use. - if (is_null($displayname)) { - // Format the font name, so "FontName-Style" becomes "Font Name - Style". - $displayname = preg_replace("/([a-z])([A-Z])/", "$1 $2", $name); - $displayname = preg_replace("/([a-zA-Z])-([a-zA-Z])/", "$1 - $2", $displayname); - } - - $arrfonts[$filenamewoextension] = $displayname; - } - } - ksort($arrfonts); - - return $arrfonts; - } - - /** - * Return the list of possible font sizes to use. - */ - public static function get_font_sizes() { - // Array to store the sizes. - $sizes = array(); - - for ($i = 1; $i <= 200; $i++) { - $sizes[$i] = $i; - } - - return $sizes; + file_save_draft_area_files($draftitemid, $contextid, 'mod_htmlcert', $filearea, 0); } /** @@ -245,9 +183,9 @@ class certificate { } /** - * Returns a list of issued customcerts. + * Returns a list of issued htmlcerts. * - * @param int $customcertid + * @param int $htmlcertid * @param bool $groupmode are we in group mode * @param \stdClass $cm the course module * @param int $limitfrom @@ -255,7 +193,7 @@ class certificate { * @param string $sort * @return array the users */ - public static function get_issues($customcertid, $groupmode, $cm, $limitfrom, $limitnum, $sort = '') { + public static function get_issues($htmlcertid, $groupmode, $cm, $limitfrom, $limitnum, $sort = '') { global $DB; // Get the conditional SQL. @@ -266,8 +204,8 @@ class certificate { return array(); } - // Add the conditional SQL and the customcertid to form all used parameters. - $allparams = $conditionsparams + array('customcertid' => $customcertid); + // Add the conditional SQL and the htmlcertid to form all used parameters. + $allparams = $conditionsparams + array('htmlcertid' => $htmlcertid); // Return the issues. $context = \context_module::instance($cm->id); @@ -282,10 +220,10 @@ class certificate { $allparams = array_merge($allparams, $userfieldsparams); $sql = "SELECT ci.id as issueid, ci.code, ci.timecreated $userfieldsselects FROM {user} u - INNER JOIN {customcert_issues} ci ON u.id = ci.userid + INNER JOIN {htmlcert_issues} ci ON u.id = ci.userid $userfieldsjoin WHERE u.deleted = 0 - AND ci.customcertid = :customcertid + AND ci.htmlcertid = :htmlcertid $conditionssql"; if ($sort) { $sql .= "ORDER BY " . $sort; @@ -297,14 +235,14 @@ class certificate { } /** - * Returns the total number of issues for a given customcert. + * Returns the total number of issues for a given htmlcert. * - * @param int $customcertid + * @param int $htmlcertid * @param \stdClass $cm the course module * @param bool $groupmode the group mode * @return int the number of issues */ - public static function get_number_of_issues($customcertid, $cm, $groupmode) { + public static function get_number_of_issues($htmlcertid, $cm, $groupmode) { global $DB; // Get the conditional SQL. @@ -315,16 +253,16 @@ class certificate { return 0; } - // Add the conditional SQL and the customcertid to form all used parameters. - $allparams = $conditionsparams + array('customcertid' => $customcertid); + // Add the conditional SQL and the htmlcertid to form all used parameters. + $allparams = $conditionsparams + array('htmlcertid' => $htmlcertid); // Return the number of issues. $sql = "SELECT COUNT(u.id) as count FROM {user} u - INNER JOIN {customcert_issues} ci + INNER JOIN {htmlcert_issues} ci ON u.id = ci.userid WHERE u.deleted = 0 - AND ci.customcertid = :customcertid + AND ci.htmlcertid = :htmlcertid $conditionssql"; return $DB->count_records_sql($sql, $allparams); } @@ -339,13 +277,13 @@ class certificate { public static function get_conditional_issues_sql($cm, $groupmode) { global $DB, $USER; - // Get all users that can manage this customcert to exclude them from the report. + // Get all users that can manage this htmlcert to exclude them from the report. $context = \context_module::instance($cm->id); $conditionssql = ''; $conditionsparams = array(); // Get all users that can manage this certificate to exclude them from the report. - $certmanagers = array_keys(get_users_by_capability($context, 'mod/customcert:manage', 'u.id')); + $certmanagers = array_keys(get_users_by_capability($context, 'mod/htmlcert:manage', 'u.id')); $certmanagers = array_merge($certmanagers, array_keys(get_admins())); list($sql, $params) = $DB->get_in_or_equal($certmanagers, SQL_PARAMS_NAMED, 'cert'); $conditionssql .= "AND NOT u.id $sql \n"; @@ -402,9 +340,9 @@ class certificate { global $DB; $sql = "SELECT COUNT(*) - FROM {customcert} c - INNER JOIN {customcert_issues} ci - ON c.id = ci.customcertid + FROM {htmlcert} c + INNER JOIN {htmlcert_issues} ci + ON c.id = ci.htmlcertid WHERE ci.userid = :userid"; return $DB->count_records_sql($sql, array('userid' => $userid)); } @@ -426,9 +364,9 @@ class certificate { } $sql = "SELECT c.id, c.name, co.fullname as coursename, ci.code, ci.timecreated - FROM {customcert} c - INNER JOIN {customcert_issues} ci - ON c.id = ci.customcertid + FROM {htmlcert} c + INNER JOIN {htmlcert_issues} ci + ON c.id = ci.htmlcertid INNER JOIN {course} co ON c.course = co.id WHERE ci.userid = :userid @@ -448,13 +386,13 @@ class certificate { $issue = new \stdClass(); $issue->userid = $userid; - $issue->customcertid = $certificateid; + $issue->htmlcertid = $certificateid; $issue->code = self::generate_code(); $issue->emailed = 0; $issue->timecreated = time(); // Insert the record into the database. - return $DB->insert_record('customcert_issues', $issue); + return $DB->insert_record('htmlcert_issues', $issue); } /** @@ -468,7 +406,7 @@ class certificate { $uniquecodefound = false; $code = random_string(10); while (!$uniquecodefound) { - if (!$DB->record_exists('customcert_issues', array('code' => $code))) { + if (!$DB->record_exists('htmlcert_issues', array('code' => $code))) { $uniquecodefound = true; } else { $code = random_string(10); diff --git a/classes/edit_element_form.php b/classes/edit_element_form.php deleted file mode 100644 index a08497d..0000000 --- a/classes/edit_element_form.php +++ /dev/null @@ -1,98 +0,0 @@ -. - -/** - * This file contains the form for handling editing a customcert element. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_customcert; - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -require_once($CFG->dirroot . '/course/moodleform_mod.php'); -require_once($CFG->dirroot . '/mod/customcert/includes/colourpicker.php'); - -\MoodleQuickForm::registerElementType('customcert_colourpicker', - $CFG->dirroot . '/mod/customcert/includes/colourpicker.php', 'MoodleQuickForm_customcert_colourpicker'); - -/** - * The form for handling editing a customcert element. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class edit_element_form extends \moodleform { - - /** - * @var \mod_customcert\element The element object. - */ - protected $element; - - /** - * Form definition. - */ - public function definition() { - $mform =& $this->_form; - - $mform->updateAttributes(array('id' => 'editelementform')); - - $element = $this->_customdata['element']; - - // Add the field for the name of the element, this is required for all elements. - $mform->addElement('text', 'name', get_string('elementname', 'customcert'), 'maxlength="255"'); - $mform->setType('name', PARAM_TEXT); - $mform->setDefault('name', get_string('pluginname', 'customcertelement_' . $element->element)); - $mform->addRule('name', get_string('required'), 'required', null, 'client'); - $mform->addHelpButton('name', 'elementname', 'customcert'); - - $this->element = \mod_customcert\element_factory::get_element_instance($element); - $this->element->set_edit_element_form($this); - $this->element->render_form_elements($mform); - - $this->add_action_buttons(true); - } - - /** - * Fill in the current page data for this customcert. - */ - public function definition_after_data() { - $this->element->definition_after_data($this->_form); - } - - /** - * Validation. - * - * @param array $data - * @param array $files - * @return array the errors that were found - */ - public function validation($data, $files) { - $errors = array(); - - if (\core_text::strlen($data['name']) > 255) { - $errors['name'] = get_string('nametoolong', 'customcert'); - } - - $errors += $this->element->validate_form_elements($data, $files); - - return $errors; - } -} diff --git a/classes/edit_form.php b/classes/edit_form.php index f091998..1c50c32 100644 --- a/classes/edit_form.php +++ b/classes/edit_form.php @@ -1,5 +1,5 @@ . /** - * This file contains the form for handling the layout of the customcert instance. + * This file contains the form for handling the layout of the htmlcert instance. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); require_once($CFG->dirroot . '/course/moodleform_mod.php'); -require_once($CFG->dirroot . '/mod/customcert/includes/colourpicker.php'); - -\MoodleQuickForm::registerElementType('customcert_colourpicker', - $CFG->dirroot . '/mod/customcert/includes/colourpicker.php', 'MoodleQuickForm_customcert_colourpicker'); /** - * The form for handling the layout of the customcert instance. + * The form for handling the layout of the htmlcert instance. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class edit_form extends \moodleform { @@ -46,11 +42,6 @@ class edit_form extends \moodleform { */ protected $tid = null; - /** - * @var int The total number of pages for this cert. - */ - protected $numpages = 1; - /** * Form definition. */ @@ -59,46 +50,18 @@ class edit_form extends \moodleform { $mform =& $this->_form; - $mform->addElement('text', 'name', get_string('name', 'customcert'), 'maxlength="255"'); + $mform->addElement('text', 'name', get_string('name', 'htmlcert'), 'maxlength="255"'); $mform->setType('name', PARAM_TEXT); $mform->addRule('name', null, 'required'); - // Get the number of pages for this module. - if (isset($this->_customdata['tid'])) { - $this->tid = $this->_customdata['tid']; - if ($pages = $DB->get_records('customcert_pages', array('templateid' => $this->tid), 'sequence')) { - $this->numpages = count($pages); - foreach ($pages as $p) { - $this->add_customcert_page_elements($p); - } - } - } else { // Add a new template. - // Create a 'fake' page to display the elements on - not yet saved in the DB. - $page = new \stdClass(); - $page->id = 0; - $page->sequence = 1; - $this->add_customcert_page_elements($page); - } - - // Link to add another page, only display it when the template has been created. - if (isset($this->_customdata['tid'])) { - $addpagelink = new \moodle_url('/mod/customcert/edit.php', - array( - 'tid' => $this->tid, - 'aid' => 1, - 'action' => 'addpage', - 'sesskey' => sesskey() - ) - ); - $icon = $OUTPUT->pix_icon('t/switch_plus', get_string('addcertpage', 'customcert')); - $addpagehtml = \html_writer::link($addpagelink, $icon . get_string('addcertpage', 'customcert')); - $mform->addElement('html', \html_writer::tag('div', $addpagehtml, array('class' => 'addpage'))); - } + $mform->addElement('text', 'html', get_string('html', 'htmlcert')); + $mform->setType('html', PARAM_TEXT); + $mform->addRule('html', null, 'required'); // Add the submit buttons. $group = array(); $group[] = $mform->createElement('submit', 'submitbtn', get_string('savechanges')); - $group[] = $mform->createElement('submit', 'previewbtn', get_string('savechangespreview', 'customcert'), array(), false); + $group[] = $mform->createElement('submit', 'previewbtn', get_string('savechangespreview', 'htmlcert'), array(), false); $mform->addElement('group', 'submitbtngroup', '', $group, '', false); $mform->addElement('hidden', 'tid'); @@ -107,34 +70,11 @@ class edit_form extends \moodleform { } /** - * Fill in the current page data for this customcert. + * Fill in the current page data for this htmlcert. */ public function definition_after_data() { global $DB; - $mform = $this->_form; - - // Check that we are updating a current customcert. - if ($this->tid) { - // Get the pages for this customcert. - if ($pages = $DB->get_records('customcert_pages', array('templateid' => $this->tid))) { - // Loop through the pages. - foreach ($pages as $p) { - // Set the width. - $element = $mform->getElement('pagewidth_' . $p->id); - $element->setValue($p->width); - // Set the height. - $element = $mform->getElement('pageheight_' . $p->id); - $element->setValue($p->height); - // Set the left margin. - $element = $mform->getElement('pageleftmargin_' . $p->id); - $element->setValue($p->leftmargin); - // Set the right margin. - $element = $mform->getElement('pagerightmargin_' . $p->id); - $element->setValue($p->rightmargin); - } - } - } } /** @@ -148,39 +88,7 @@ class edit_form extends \moodleform { $errors = parent::validation($data, $files); if (\core_text::strlen($data['name']) > 255) { - $errors['name'] = get_string('nametoolong', 'customcert'); - } - - // Go through the data and check any width, height or margin values. - foreach ($data as $key => $value) { - if (strpos($key, 'pagewidth_') !== false) { - $page = str_replace('pagewidth_', '', $key); - $widthid = 'pagewidth_' . $page; - // Validate that the width is a valid value. - if ((!isset($data[$widthid])) || (!is_numeric($data[$widthid])) || ($data[$widthid] <= 0)) { - $errors[$widthid] = get_string('invalidwidth', 'customcert'); - } - } - if (strpos($key, 'pageheight_') !== false) { - $page = str_replace('pageheight_', '', $key); - $heightid = 'pageheight_' . $page; - // Validate that the height is a valid value. - if ((!isset($data[$heightid])) || (!is_numeric($data[$heightid])) || ($data[$heightid] <= 0)) { - $errors[$heightid] = get_string('invalidheight', 'customcert'); - } - } - if (strpos($key, 'pageleftmargin_') !== false) { - // Validate that the left margin is a valid value. - if (isset($data[$key]) && ($data[$key] < 0)) { - $errors[$key] = get_string('invalidmargin', 'customcert'); - } - } - if (strpos($key, 'pagerightmargin_') !== false) { - // Validate that the right margin is a valid value. - if (isset($data[$key]) && ($data[$key] < 0)) { - $errors[$key] = get_string('invalidmargin', 'customcert'); - } - } + $errors['name'] = get_string('nametoolong', 'htmlcert'); } return $errors; @@ -189,126 +97,28 @@ class edit_form extends \moodleform { /** * Adds the page elements to the form. * - * @param \stdClass $page the customcert page + * @param \stdClass $page the htmlcert page */ - protected function add_customcert_page_elements($page) { + protected function add_htmlcert_page_elements($page) { global $DB, $OUTPUT; // Create the form object. $mform =& $this->_form; - if ($this->numpages > 1) { - $mform->addElement('header', 'page_' . $page->id, get_string('page', 'customcert', $page->sequence)); - } - - $editlink = '/mod/customcert/edit.php'; + $editlink = '/mod/htmlcert/edit.php'; $editlinkparams = array('tid' => $this->tid, 'sesskey' => sesskey()); - $editelementlink = '/mod/customcert/edit_element.php'; - $editelementlinkparams = array('tid' => $this->tid, 'sesskey' => sesskey()); - // Place the ordering arrows. - // Only display the move up arrow if it is not the first. - if ($page->sequence > 1) { - $url = new \moodle_url($editlink, $editlinkparams + array('action' => 'pmoveup', 'aid' => $page->id)); - $mform->addElement('html', $OUTPUT->action_icon($url, new \pix_icon('t/up', get_string('moveup')))); - } - // Only display the move down arrow if it is not the last. - if ($page->sequence < $this->numpages) { - $url = new \moodle_url($editlink, $editlinkparams + array('action' => 'pmovedown', 'aid' => $page->id)); - $mform->addElement('html', $OUTPUT->action_icon($url, new \pix_icon('t/down', get_string('movedown')))); - } + $mform->addElement('text', 'pagewidth', get_string('width', 'htmlcert')); + $mform->setType('pagewidth', PARAM_INT); + $mform->setDefault('pagewidth', '210'); + $mform->addRule('pagewidth', null, 'required', null, 'client'); + $mform->addHelpButton('pagewidth', 'width', 'htmlcert'); - $mform->addElement('text', 'pagewidth_' . $page->id, get_string('width', 'customcert')); - $mform->setType('pagewidth_' . $page->id, PARAM_INT); - $mform->setDefault('pagewidth_' . $page->id, '210'); - $mform->addRule('pagewidth_' . $page->id, null, 'required', null, 'client'); - $mform->addHelpButton('pagewidth_' . $page->id, 'width', 'customcert'); + $mform->addElement('text', 'pageheight', get_string('height', 'htmlcert')); + $mform->setType('pageheight', PARAM_INT); + $mform->setDefault('pageheight', '297'); + $mform->addRule('pageheight', null, 'required', null, 'client'); + $mform->addHelpButton('pageheight', 'height', 'htmlcert'); - $mform->addElement('text', 'pageheight_' . $page->id, get_string('height', 'customcert')); - $mform->setType('pageheight_' . $page->id, PARAM_INT); - $mform->setDefault('pageheight_' . $page->id, '297'); - $mform->addRule('pageheight_' . $page->id, null, 'required', null, 'client'); - $mform->addHelpButton('pageheight_' . $page->id, 'height', 'customcert'); - - $mform->addElement('text', 'pageleftmargin_' . $page->id, get_string('leftmargin', 'customcert')); - $mform->setType('pageleftmargin_' . $page->id, PARAM_INT); - $mform->setDefault('pageleftmargin_' . $page->id, 0); - $mform->addHelpButton('pageleftmargin_' . $page->id, 'leftmargin', 'customcert'); - - $mform->addElement('text', 'pagerightmargin_' . $page->id, get_string('rightmargin', 'customcert')); - $mform->setType('pagerightmargin_' . $page->id, PARAM_INT); - $mform->setDefault('pagerightmargin_' . $page->id, 0); - $mform->addHelpButton('pagerightmargin_' . $page->id, 'rightmargin', 'customcert'); - - // Check if there are elements to add. - if ($elements = $DB->get_records('customcert_elements', array('pageid' => $page->id), 'sequence ASC')) { - // Get the total number of elements. - $numelements = count($elements); - // Create a table to display these elements. - $table = new \html_table(); - $table->attributes = array('class' => 'generaltable elementstable'); - $table->head = array(get_string('name', 'customcert'), get_string('type', 'customcert'), get_string('actions')); - $table->align = array('left', 'left', 'left'); - // Loop through and add the elements to the table. - foreach ($elements as $element) { - $elementname = new \core\output\inplace_editable('mod_customcert', 'elementname', $element->id, - true, format_string($element->name), $element->name); - - $row = new \html_table_row(); - $row->cells[] = $OUTPUT->render($elementname); - $row->cells[] = $element->element; - // Link to edit this element. - $link = new \moodle_url($editelementlink, $editelementlinkparams + array('id' => $element->id, - 'action' => 'edit')); - $icons = $OUTPUT->action_icon($link, new \pix_icon('t/edit', get_string('edit')), null, - array('class' => 'action-icon edit-icon')); - // Link to delete the element. - $link = new \moodle_url($editlink, $editlinkparams + array('action' => 'deleteelement', - 'aid' => $element->id)); - $icons .= $OUTPUT->action_icon($link, new \pix_icon('t/delete', get_string('delete')), null, - array('class' => 'action-icon delete-icon')); - // Now display any moving arrows if they are needed. - if ($numelements > 1) { - // Only display the move up arrow if it is not the first. - $moveicons = ''; - if ($element->sequence > 1) { - $url = new \moodle_url($editlink, $editlinkparams + array('action' => 'emoveup', - 'aid' => $element->id)); - $moveicons .= $OUTPUT->action_icon($url, new \pix_icon('t/up', get_string('moveup'))); - } - // Only display the move down arrow if it is not the last. - if ($element->sequence < $numelements) { - $url = new \moodle_url($editlink, $editlinkparams + array('action' => 'emovedown', - 'aid' => $element->id)); - $moveicons .= $OUTPUT->action_icon($url, new \pix_icon('t/down', get_string('movedown'))); - } - $icons .= $moveicons; - } - $row->cells[] = $icons; - $table->data[] = $row; - } - // Create link to order the elements. - $link = \html_writer::link(new \moodle_url('/mod/customcert/rearrange.php', array('pid' => $page->id)), - get_string('rearrangeelements', 'customcert')); - // Add the table to the form. - $mform->addElement('static', 'elements_' . $page->id, get_string('elements', 'customcert'), \html_writer::table($table) - . \html_writer::tag( 'div', $link)); - $mform->addHelpButton('elements_' . $page->id, 'elements', 'customcert'); - } - - $group = array(); - $group[] = $mform->createElement('select', 'element_' . $page->id, '', element_helper::get_available_element_types()); - $group[] = $mform->createElement('submit', 'addelement_' . $page->id, get_string('addelement', 'customcert'), - array(), false); - $mform->addElement('group', 'elementgroup', '', $group, '', false); - - // Add option to delete this page if there is more than one page. - if ($this->numpages > 1) { - // Link to delete the page. - $deletelink = new \moodle_url($editlink, $editlinkparams + array('action' => 'deletepage', 'aid' => $page->id)); - $icon = $OUTPUT->pix_icon('t/delete', get_string('deletecertpage', 'customcert')); - $deletepagehtml = \html_writer::link($deletelink, $icon . get_string('deletecertpage', 'customcert')); - $mform->addElement('html', \html_writer::tag('div', $deletepagehtml, array('class' => 'deletebutton'))); - } } } diff --git a/classes/element.php b/classes/element.php deleted file mode 100644 index ea77e4a..0000000 --- a/classes/element.php +++ /dev/null @@ -1,502 +0,0 @@ -. - -/** - * The base class for the customcert elements. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_customcert; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Class element - * - * All customcert element plugins are based on this class. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -abstract class element { - - /** - * @var string The left alignment constant. - */ - const ALIGN_LEFT = 'L'; - - /** - * @var string The centered alignment constant. - */ - const ALIGN_CENTER = 'C'; - - /** - * @var string The right alignment constant. - */ - const ALIGN_RIGHT = 'R'; - - /** - * @var \stdClass $element The data for the element we are adding - do not use, kept for legacy reasons. - */ - protected $element; - - /** - * @var int The id. - */ - protected $id; - - /** - * @var int The page id. - */ - protected $pageid; - - /** - * @var string The name. - */ - protected $name; - - /** - * @var mixed The data. - */ - protected $data; - - /** - * @var string The font name. - */ - protected $font; - - /** - * @var int The font size. - */ - protected $fontsize; - - /** - * @var string The font colour. - */ - protected $colour; - - /** - * @var int The position x. - */ - protected $posx; - - /** - * @var int The position y. - */ - protected $posy; - - /** - * @var int The width. - */ - protected $width; - - /** - * @var int The refpoint. - */ - protected $refpoint; - - /** - * @var string The alignment. - */ - protected $alignment; - - /** - * @var bool $showposxy Show position XY form elements? - */ - protected $showposxy; - - /** - * @var edit_element_form Element edit form instance. - */ - private $editelementform; - - /** - * Constructor. - * - * @param \stdClass $element the element data - */ - public function __construct($element) { - $showposxy = get_config('customcert', 'showposxy'); - - // Keeping this for legacy reasons so we do not break third-party elements. - $this->element = clone($element); - - $this->id = $element->id; - $this->pageid = $element->pageid; - $this->name = $element->name; - $this->data = $element->data; - $this->font = $element->font; - $this->fontsize = $element->fontsize; - $this->colour = $element->colour; - $this->posx = $element->posx; - $this->posy = $element->posy; - $this->width = $element->width; - $this->refpoint = $element->refpoint; - $this->showposxy = isset($showposxy) && $showposxy; - $this->set_alignment($element->alignment ?? self::ALIGN_LEFT); - } - - /** - * Returns the id. - * - * @return int - */ - public function get_id() { - return $this->id; - } - - /** - * Returns the page id. - * - * @return int - */ - public function get_pageid() { - return $this->pageid; - } - - /** - * Returns the name. - * - * @return int - */ - public function get_name() { - return $this->name; - } - - /** - * Returns the data. - * - * @return mixed - */ - public function get_data() { - return $this->data; - } - - /** - * Returns the font name. - * - * @return string - */ - public function get_font() { - return $this->font; - } - - /** - * Returns the font size. - * - * @return int - */ - public function get_fontsize() { - return $this->fontsize; - } - - /** - * Returns the font colour. - * - * @return string - */ - public function get_colour() { - return $this->colour; - } - - /** - * Returns the position x. - * - * @return int - */ - public function get_posx() { - return $this->posx; - } - - /** - * Returns the position y. - * - * @return int - */ - public function get_posy() { - return $this->posy; - } - - /** - * Returns the width. - * - * @return int - */ - public function get_width() { - return $this->width; - } - - /** - * Returns the refpoint. - * - * @return int - */ - public function get_refpoint() { - return $this->refpoint; - } - - /** - * Returns the alignment. - * - * @return string The current alignment value. - */ - public function get_alignment() { - return $this->alignment ?? self::ALIGN_LEFT; - } - - /** - * Sets the alignment. - * - * @param string $alignment The new alignment. - * - * @throws \InvalidArgumentException if the provided new alignment is not valid. - */ - protected function set_alignment(string $alignment) { - $validvalues = array(self::ALIGN_LEFT, self::ALIGN_CENTER, self::ALIGN_RIGHT); - if (!in_array($alignment, $validvalues)) { - throw new \InvalidArgumentException("'$alignment' is not a valid alignment value. It has to be one of " . - implode(', ', $validvalues)); - } - $this->alignment = $alignment; - } - - /** - * This function renders the form elements when adding a customcert element. - * Can be overridden if more functionality is needed. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public function render_form_elements($mform) { - // Render the common elements. - element_helper::render_form_element_font($mform); - element_helper::render_form_element_colour($mform); - if ($this->showposxy) { - element_helper::render_form_element_position($mform); - } - element_helper::render_form_element_width($mform); - element_helper::render_form_element_refpoint($mform); - element_helper::render_form_element_alignment($mform); - } - - /** - * Sets the data on the form when editing an element. - * Can be overridden if more functionality is needed. - * - * @param edit_element_form $mform the edit_form instance - */ - public function definition_after_data($mform) { - // Loop through the properties of the element and set the values - // of the corresponding form element, if it exists. - $properties = [ - 'name' => $this->name, - 'font' => $this->font, - 'fontsize' => $this->fontsize, - 'colour' => $this->colour, - 'posx' => $this->posx, - 'posy' => $this->posy, - 'width' => $this->width, - 'refpoint' => $this->refpoint, - 'alignment' => $this->get_alignment() - ]; - foreach ($properties as $property => $value) { - if (!is_null($value) && $mform->elementExists($property)) { - $element = $mform->getElement($property); - $element->setValue($value); - } - } - } - - /** - * Performs validation on the element values. - * Can be overridden if more functionality is needed. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - $errors = array(); - - // Common validation methods. - $errors += element_helper::validate_form_element_colour($data); - if ($this->showposxy) { - $errors += element_helper::validate_form_element_position($data); - } - $errors += element_helper::validate_form_element_width($data); - - return $errors; - } - - /** - * Handles saving the form elements created by this element. - * Can be overridden if more functionality is needed. - * - * @param \stdClass $data the form data - * @return bool true of success, false otherwise. - */ - public function save_form_elements($data) { - global $DB; - - // Get the data from the form. - $element = new \stdClass(); - $element->name = $data->name; - $element->data = $this->save_unique_data($data); - $element->font = $data->font ?? null; - $element->fontsize = $data->fontsize ?? null; - $element->colour = $data->colour ?? null; - if ($this->showposxy) { - $element->posx = $data->posx ?? null; - $element->posy = $data->posy ?? null; - } - $element->width = $data->width ?? null; - $element->refpoint = $data->refpoint ?? null; - $element->alignment = $data->alignment ?? self::ALIGN_LEFT; - $element->timemodified = time(); - - // Check if we are updating, or inserting a new element. - if (!empty($this->id)) { // Must be updating a record in the database. - $element->id = $this->id; - return $DB->update_record('customcert_elements', $element); - } else { // Must be adding a new one. - $element->element = $data->element; - $element->pageid = $data->pageid; - $element->sequence = \mod_customcert\element_helper::get_element_sequence($element->pageid); - $element->timecreated = time(); - return $DB->insert_record('customcert_elements', $element, false); - } - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * Can be overridden if more functionality is needed. - * - * @param \stdClass $data the form data - * @return string the unique data to save - */ - public function save_unique_data($data) { - return ''; - } - - /** - * This handles copying data from another element of the same type. - * Can be overridden if more functionality is needed. - * - * @param \stdClass $data the form data - * @return bool returns true if the data was copied successfully, false otherwise - */ - public function copy_element($data) { - return true; - } - - /** - * This defines if an element plugin can be added to a certificate. - * Can be overridden if an element plugin wants to take over the control. - * - * @return bool returns true if the element can be added, false otherwise - */ - public static function can_add() { - return true; - } - - /** - * Handles rendering the element on the pdf. - * - * Must be overridden. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - abstract public function render($pdf, $preview, $user); - - /** - * Render the element in html. - * - * Must be overridden. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - abstract public function render_html(); - - /** - * Handles deleting any data this element may have introduced. - * Can be overridden if more functionality is needed. - * - * @return bool success return true if deletion success, false otherwise - */ - public function delete() { - global $DB; - - return $DB->delete_records('customcert_elements', array('id' => $this->id)); - } - - /** - * This function is responsible for handling the restoration process of the element. - * - * For example, the function may save data that is related to another course module, this - * data will need to be updated if we are restoring the course as the course module id will - * be different in the new course. - * - * @param \restore_customcert_activity_task $restore - */ - public function after_restore($restore) { - - } - - /** - * Magic getter for read only access. - * - * @param string $name - */ - public function __get($name) { - debugging('Please call the appropriate get_* function instead of relying on magic getters', DEBUG_DEVELOPER); - if (property_exists($this->element, $name)) { - return $this->element->$name; - } - } - - /** - * Set edit form instance for the custom cert element. - * - * @param \mod_customcert\edit_element_form $editelementform - */ - public function set_edit_element_form(edit_element_form $editelementform) { - $this->editelementform = $editelementform; - } - - /** - * Get edit form instance for the custom cert element. - * - * @return \mod_customcert\edit_element_form - */ - public function get_edit_element_form() { - if (empty($this->editelementform)) { - throw new \coding_exception('Edit element form instance is not set.'); - } - - return $this->editelementform; - } - -} diff --git a/classes/element_factory.php b/classes/element_factory.php deleted file mode 100644 index 5e43591..0000000 --- a/classes/element_factory.php +++ /dev/null @@ -1,71 +0,0 @@ -. - -/** - * Contains the factory class responsible for creating custom certificate instances. - * - * @package mod_customcert - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_customcert; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The factory class responsible for creating custom certificate instances. - * - * @package mod_customcert - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element_factory { - - /** - * Returns an instance of the element class. - * - * @param \stdClass $element the element - * @return \mod_customcert\element|bool returns the instance of the element class, or false if element - * class does not exists. - */ - public static function get_element_instance($element) { - // Get the class name. - $classname = '\\customcertelement_' . $element->element . '\\element'; - - $data = new \stdClass(); - $data->id = $element->id ?? null; - $data->pageid = $element->pageid ?? null; - $data->name = $element->name ?? get_string('pluginname', 'customcertelement_' . $element->element); - $data->element = $element->element; - $data->data = $element->data ?? null; - $data->font = $element->font ?? null; - $data->fontsize = $element->fontsize ?? null; - $data->colour = $element->colour ?? null; - $data->posx = $element->posx ?? null; - $data->posy = $element->posy ?? null; - $data->width = $element->width ?? null; - $data->refpoint = $element->refpoint ?? null; - $data->alignment = $element->alignment ?? null; - - // Ensure the necessary class exists. - if (class_exists($classname)) { - return new $classname($data); - } - - return false; - } -} diff --git a/classes/element_helper.php b/classes/element_helper.php deleted file mode 100644 index 7053dc5..0000000 --- a/classes/element_helper.php +++ /dev/null @@ -1,627 +0,0 @@ -. - -/** - * Provides useful functions related to elements. - * - * @package mod_customcert - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_customcert; - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir . '/grade/constants.php'); -require_once($CFG->dirroot . '/grade/lib.php'); -require_once($CFG->dirroot . '/grade/querylib.php'); - -/** - * Class helper. - * - * Provides useful functions related to elements. - * - * @package mod_customcert - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element_helper { - - /** - * @var int the top-left of element - */ - const CUSTOMCERT_REF_POINT_TOPLEFT = 0; - - /** - * @var int the top-center of element - */ - const CUSTOMCERT_REF_POINT_TOPCENTER = 1; - - /** - * @var int the top-left of element - */ - const CUSTOMCERT_REF_POINT_TOPRIGHT = 2; - - /** - * Common behaviour for rendering specified content on the pdf. - * - * @param \pdf $pdf the pdf object - * @param \mod_customcert\element $element the customcert element - * @param string $content the content to render - */ - public static function render_content($pdf, $element, $content) { - list($font, $attr) = self::get_font($element); - $pdf->setFont($font, $attr, $element->get_fontsize()); - $fontcolour = \TCPDF_COLORS::convertHTMLColorToDec($element->get_colour(), $fontcolour); - $pdf->SetTextColor($fontcolour['R'], $fontcolour['G'], $fontcolour['B']); - - $x = $element->get_posx(); - $y = $element->get_posy(); - $w = $element->get_width(); - $refpoint = $element->get_refpoint(); - $actualwidth = $pdf->GetStringWidth($content); - $alignment = $element->get_alignment(); - - if ($w and $w < $actualwidth) { - $actualwidth = $w; - } - - switch ($refpoint) { - case self::CUSTOMCERT_REF_POINT_TOPRIGHT: - $x = $element->get_posx() - $actualwidth; - if ($x < 0) { - $x = 0; - $w = $element->get_posx(); - } else { - $w = $actualwidth; - } - break; - case self::CUSTOMCERT_REF_POINT_TOPCENTER: - $x = $element->get_posx() - $actualwidth / 2; - if ($x < 0) { - $x = 0; - $w = $element->get_posx() * 2; - } else { - $w = $actualwidth; - } - break; - } - - if ($w) { - $w += 0.0001; - } - $pdf->setCellPaddings(0, 0, 0, 0); - $pdf->writeHTMLCell($w, 0, $x, $y, $content, 0, 0, false, true, $alignment); - } - - /** - * Common behaviour for rendering specified content on the drag and drop page. - * - * @param \mod_customcert\element $element the customcert element - * @param string $content the content to render - * @return string the html - */ - public static function render_html_content($element, $content) { - list($font, $attr) = self::get_font($element); - $fontstyle = 'font-family: ' . $font; - if (strpos($attr, 'B') !== false) { - $fontstyle .= '; font-weight: bold'; - } - if (strpos($attr, 'I') !== false) { - $fontstyle .= '; font-style: italic'; - } - - $style = $fontstyle . '; color: ' . $element->get_colour() . '; font-size: ' . $element->get_fontsize() . 'pt;'; - if ($element->get_width()) { - $style .= ' width: ' . $element->get_width() . 'mm'; - } - return \html_writer::div($content, '', array('style' => $style)); - } - - /** - * Helper function to render the font elements. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_font($mform) { - $mform->addElement('select', 'font', get_string('font', 'customcert'), \mod_customcert\certificate::get_fonts()); - $mform->setType('font', PARAM_TEXT); - $mform->setDefault('font', 'times'); - $mform->addHelpButton('font', 'font', 'customcert'); - $mform->addElement('select', 'fontsize', get_string('fontsize', 'customcert'), - \mod_customcert\certificate::get_font_sizes()); - $mform->setType('fontsize', PARAM_INT); - $mform->setDefault('fontsize', 12); - $mform->addHelpButton('fontsize', 'fontsize', 'customcert'); - } - - /** - * Helper function to render the colour elements. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_colour($mform) { - $mform->addElement('customcert_colourpicker', 'colour', get_string('fontcolour', 'customcert')); - $mform->setType('colour', PARAM_RAW); // Need to validate that this is a valid colour. - $mform->setDefault('colour', '#000000'); - $mform->addHelpButton('colour', 'fontcolour', 'customcert'); - } - - /** - * Helper function to render the position elements. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_position($mform) { - $mform->addElement('text', 'posx', get_string('posx', 'customcert'), array('size' => 10)); - $mform->setType('posx', PARAM_INT); - $mform->setDefault('posx', 0); - $mform->addHelpButton('posx', 'posx', 'customcert'); - $mform->addElement('text', 'posy', get_string('posy', 'customcert'), array('size' => 10)); - $mform->setType('posy', PARAM_INT); - $mform->setDefault('posy', 0); - $mform->addHelpButton('posy', 'posy', 'customcert'); - } - - /** - * Helper function to render the width element. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_width($mform) { - $mform->addElement('text', 'width', get_string('elementwidth', 'customcert'), array('size' => 10)); - $mform->setType('width', PARAM_INT); - $mform->setDefault('width', 0); - $mform->addHelpButton('width', 'elementwidth', 'customcert'); - } - - /** - * Helper function to render the refpoint element. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_refpoint($mform) { - $refpointoptions = array(); - $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPLEFT] = get_string('topleft', 'customcert'); - $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPCENTER] = get_string('topcenter', 'customcert'); - $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPRIGHT] = get_string('topright', 'customcert'); - - $mform->addElement('select', 'refpoint', get_string('refpoint', 'customcert'), $refpointoptions); - $mform->setType('refpoint', PARAM_INT); - $mform->setDefault('refpoint', self::CUSTOMCERT_REF_POINT_TOPCENTER); - $mform->addHelpButton('refpoint', 'refpoint', 'customcert'); - } - - /** - * Helper function to render the alignment form element. - * - * @param \MoodleQuickForm $mform the edit_form instance. - */ - public static function render_form_element_alignment($mform) { - $alignmentoptions = array(); - $alignmentoptions[element::ALIGN_LEFT] = get_string('alignleft', 'customcert'); - $alignmentoptions[element::ALIGN_CENTER] = get_string('aligncenter', 'customcert'); - $alignmentoptions[element::ALIGN_RIGHT] = get_string('alignright', 'customcert'); - - $mform->addElement('select', 'alignment', get_string('alignment', 'customcert'), $alignmentoptions); - $mform->setType('alignment', PARAM_ALPHA); - $mform->setDefault('alignment', element::ALIGN_LEFT); - $mform->addHelpButton('alignment', 'alignment', 'customcert'); - } - - /** - * Helper function to performs validation on the colour element. - * - * @param array $data the submitted data - * @return array the validation errors - */ - public static function validate_form_element_colour($data) { - $errors = array(); - // Validate the colour. - if (!self::validate_colour($data['colour'])) { - $errors['colour'] = get_string('invalidcolour', 'customcert'); - } - return $errors; - } - - /** - * Helper function to performs validation on the position elements. - * - * @param array $data the submitted data - * @return array the validation errors - */ - public static function validate_form_element_position($data) { - $errors = array(); - - // Check if posx is not set, or not numeric or less than 0. - if ((!isset($data['posx'])) || (!is_numeric($data['posx'])) || ($data['posx'] < 0)) { - $errors['posx'] = get_string('invalidposition', 'customcert', 'X'); - } - // Check if posy is not set, or not numeric or less than 0. - if ((!isset($data['posy'])) || (!is_numeric($data['posy'])) || ($data['posy'] < 0)) { - $errors['posy'] = get_string('invalidposition', 'customcert', 'Y'); - } - - return $errors; - } - - /** - * Helper function to perform validation on the width element. - * - * @param array $data the submitted data - * @return array the validation errors - */ - public static function validate_form_element_width($data) { - $errors = array(); - - // Check if width is less than 0. - if (isset($data['width']) && $data['width'] < 0) { - $errors['width'] = get_string('invalidelementwidth', 'customcert'); - } - - return $errors; - } - - /** - * Returns the font used for this element. - * - * @param \mod_customcert\element $element the customcert element - * @return array the font and font attributes - */ - public static function get_font($element) { - // Variable for the font. - $font = $element->get_font(); - // Get the last two characters of the font name. - $fontlength = strlen($font); - $lastchar = $font[$fontlength - 1]; - $secondlastchar = $font[$fontlength - 2]; - // The attributes of the font. - $attr = ''; - // Check if the last character is 'i'. - if ($lastchar == 'i') { - // Remove the 'i' from the font name. - $font = substr($font, 0, -1); - // Check if the second last char is b. - if ($secondlastchar == 'b') { - // Remove the 'b' from the font name. - $font = substr($font, 0, -1); - $attr .= 'B'; - } - $attr .= 'I'; - } else if ($lastchar == 'b') { - // Remove the 'b' from the font name. - $font = substr($font, 0, -1); - $attr .= 'B'; - } - return array($font, $attr); - } - - /** - * Validates the colour selected. - * - * @param string $colour - * @return bool returns true if the colour is valid, false otherwise - */ - public static function validate_colour($colour) { - // List of valid HTML colour names. - $colournames = array( - 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', - 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', - 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', - 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', - 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', - 'darkgrey', 'darkgreen', 'darkkhaki', 'darkmagenta', - 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', - 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', - 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', - 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', - 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', - 'ghostwhite', 'gold', 'goldenrod', 'gray', 'grey', 'green', - 'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo', - 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', - 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', - 'lightgoldenrodyellow', 'lightgray', 'lightgrey', 'lightgreen', - 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', - 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', - 'lime', 'limegreen', 'linen', 'magenta', 'maroon', - 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', - 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', - 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', - 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', - 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', - 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', - 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', - 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', - 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', - 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', - 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', - 'whitesmoke', 'yellow', 'yellowgreen' - ); - - if (preg_match('/^#?([[:xdigit:]]{3}){1,2}$/', $colour)) { - return true; - } else if (in_array(strtolower($colour), $colournames)) { - return true; - } - - return false; - } - - /** - * Helper function that returns the sequence on a specified customcert page for a - * newly created element. - * - * @param int $pageid the id of the page we are adding this element to - * @return int the element number - */ - public static function get_element_sequence($pageid) { - global $DB; - - // Set the sequence of the element we are creating. - $sequence = 1; - // Check if there already elements that exist, if so, overwrite value. - $sql = "SELECT MAX(sequence) as maxsequence - FROM {customcert_elements} - WHERE pageid = :id"; - // Get the current max sequence on this page and add 1 to get the new sequence. - if ($maxseq = $DB->get_record_sql($sql, array('id' => $pageid))) { - $sequence = $maxseq->maxsequence + 1; - } - - return $sequence; - } - - /** - * Helper function that returns the course id for this element. - * - * @param int $elementid The element id - * @return int The course id - */ - public static function get_courseid($elementid) { - global $DB, $SITE; - - $sql = "SELECT course - FROM {customcert} c - INNER JOIN {customcert_pages} cp - ON c.templateid = cp.templateid - INNER JOIN {customcert_elements} ce - ON cp.id = ce.pageid - WHERE ce.id = :elementid"; - - // Check if there is a course associated with this element. - if ($course = $DB->get_record_sql($sql, array('elementid' => $elementid))) { - return $course->course; - } else { // Must be in a site template. - return $SITE->id; - } - } - - /** - * Helper function that returns the context for this element. - * - * @param int $elementid The element id - * @return \context The context - */ - public static function get_context(int $elementid) : \context { - global $DB; - - $sql = "SELECT ct.contextid - FROM {customcert_templates} ct - INNER JOIN {customcert_pages} cp - ON ct.id = cp.templateid - INNER JOIN {customcert_elements} ce - ON cp.id = ce.pageid - WHERE ce.id = :elementid"; - $contextid = $DB->get_field_sql($sql, array('elementid' => $elementid), MUST_EXIST); - - return \context::instance_by_id($contextid); - } - - /** - * Return the list of possible elements to add. - * - * @return array the list of element types that can be used. - */ - public static function get_available_element_types() { - global $CFG; - - // Array to store the element types. - $options = array(); - - // Check that the directory exists. - $elementdir = "$CFG->dirroot/mod/customcert/element"; - if (file_exists($elementdir)) { - // Get directory contents. - $elementfolders = new \DirectoryIterator($elementdir); - // Loop through the elements folder. - foreach ($elementfolders as $elementfolder) { - // If it is not a directory or it is '.' or '..', skip it. - if (!$elementfolder->isDir() || $elementfolder->isDot()) { - continue; - } - // Check that the standard class exists, if not we do - // not want to display it as an option as it will not work. - $foldername = $elementfolder->getFilename(); - // Get the class name. - $classname = '\\customcertelement_' . $foldername . '\\element'; - // Ensure the necessary class exists. - if (class_exists($classname)) { - // Additionally, check if the user is allowed to add the element at all. - if ($classname::can_add()) { - $component = "customcertelement_{$foldername}"; - $options[$foldername] = get_string('pluginname', $component); - } - } - } - } - - \core_collator::asort($options); - return $options; - } - - /** - * Helper function to return all the grades items for a given course. - * - * @param \stdClass $course The course we want to return the grade items for - * @return array the array of gradeable items in the course - */ - public static function get_grade_items($course) { - // Array to store the grade items. - $arrgradeitems = array(); - - // Get other non-module related grade items. - if ($gradeitems = \grade_item::fetch_all(['courseid' => $course->id])) { - foreach ($gradeitems as $gi) { - if ($gi->is_course_item()) { - continue; // Skipping for legacy reasons - this was added to individual elements. - } - - if ($gi->is_external_item()) { - $cm = get_coursemodule_from_instance($gi->itemmodule, $gi->iteminstance, $course->id); - $modcontext = \context_module::instance($cm->id); - $modname = format_string($cm->name, true, array('context' => $modcontext)); - } - - if ($gi->is_external_item() && !$gi->is_outcome_item()) { - // Due to legacy reasons we are storing the course module ID here rather than the grade item id. - // If we were to change we would need to provide upgrade steps to convert cm->id to gi->id. - $arrgradeitems[$cm->id] = get_string('activity', 'mod_customcert') . ' : ' . $gi->get_name(); - } else if ($gi->is_external_item() && $gi->is_outcome_item()) { - // Get the name of the activity. - $optionname = get_string('gradeoutcome', 'mod_customcert') . ' : ' . $modname . " - " . $gi->get_name(); - $arrgradeitems['gradeitem:' . $gi->id] = $optionname; - } else { - $arrgradeitems['gradeitem:' . $gi->id] = get_string('gradeitem', 'grades') . ' : ' . $gi->get_name(true); - } - } - - // Alphabetise this. - asort($arrgradeitems); - } - - return $arrgradeitems; - } - - /** - * Helper function to return the grade information for a course for a specified user. - * - * @param int $courseid - * @param int $gradeformat - * @param int $userid - * @return grade_information|bool the grade information, or false if there is none. - */ - public static function get_course_grade_info($courseid, $gradeformat, $userid) { - $courseitem = \grade_item::fetch_course_item($courseid); - - if (!$courseitem) { - return false; - } - - $grade = new \grade_grade(array('itemid' => $courseitem->id, 'userid' => $userid)); - - return new grade_information( - $courseitem->get_name(), - $grade->finalgrade, - grade_format_gradevalue($grade->finalgrade, $courseitem, true, $gradeformat), - $grade->get_dategraded() - ); - } - - /** - * Helper function to return the grade information for a module for a specified user. - * - * @param int $cmid - * @param int $gradeformat - * @param int $userid - * @return grade_information|bool the grade information, or false if there is none. - */ - public static function get_mod_grade_info($cmid, $gradeformat, $userid) { - global $DB; - - if (!$cm = $DB->get_record('course_modules', array('id' => $cmid))) { - return false; - } - - if (!$module = $DB->get_record('modules', array('id' => $cm->module))) { - return false; - } - - $params = [ - 'itemtype' => 'mod', - 'itemmodule' => $module->name, - 'iteminstance' => $cm->instance, - 'courseid' => $cm->course, - 'itemnumber' => 0 - ]; - $gradeitem = \grade_item::fetch($params); - - if (empty($gradeitem)) { - return false; - } - - $grade = grade_get_grades( - $cm->course, - 'mod', - $module->name, - $cm->instance, - $userid - ); - - if (!isset($grade->items[0]->grades[$userid])) { - return false; - } - - $gradebookgrade = $grade->items[0]->grades[$userid]; - - $dategraded = null; - if (!empty($gradebookgrade->dategraded)) { - $dategraded = $gradebookgrade->dategraded; - } - - $displaygrade = grade_format_gradevalue($gradebookgrade->grade, $gradeitem, true, $gradeformat); - - return new grade_information( - $gradeitem->get_name(), - $gradebookgrade->grade, - $displaygrade, - $dategraded - ); - } - - /** - * Helper function to return the grade information for a grade item for a specified user. - * - * @param int $gradeitemid - * @param int $gradeformat - * @param int $userid - * @return grade_information|bool the grade information, or false if there is none. - */ - public static function get_grade_item_info($gradeitemid, $gradeformat, $userid) { - if (!$gradeitem = \grade_item::fetch(['id' => $gradeitemid])) { - return false; - } - - $grade = new \grade_grade(array('itemid' => $gradeitem->id, 'userid' => $userid)); - - return new grade_information( - $gradeitem->get_name(), - $grade->finalgrade, - grade_format_gradevalue($grade->finalgrade, $gradeitem, true, $gradeformat), - $grade->get_dategraded() - ); - } -} diff --git a/classes/event/course_module_instance_list_viewed.php b/classes/event/course_module_instance_list_viewed.php index f11c1bd..8e6f91b 100644 --- a/classes/event/course_module_instance_list_viewed.php +++ b/classes/event/course_module_instance_list_viewed.php @@ -17,20 +17,20 @@ /** * Contains the course module instance list viewed event class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\event; +namespace mod_htmlcert\event; defined('MOODLE_INTERNAL') || die(); /** * The course module instance list viewed event class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { diff --git a/classes/event/course_module_viewed.php b/classes/event/course_module_viewed.php index 2393192..97619db 100644 --- a/classes/event/course_module_viewed.php +++ b/classes/event/course_module_viewed.php @@ -17,20 +17,20 @@ /** * Contains the course module viewed event class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\event; +namespace mod_htmlcert\event; defined('MOODLE_INTERNAL') || die(); /** * The course module viewed event class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class course_module_viewed extends \core\event\course_module_viewed { @@ -39,7 +39,7 @@ class course_module_viewed extends \core\event\course_module_viewed { * Initialises the event. */ protected function init() { - $this->data['objecttable'] = 'customcert'; + $this->data['objecttable'] = 'htmlcert'; parent::init(); } @@ -49,7 +49,7 @@ class course_module_viewed extends \core\event\course_module_viewed { * @return string[] */ public static function get_objectid_mapping() { - return array('db' => 'customcert', 'restore' => 'customcert'); + return array('db' => 'htmlcert', 'restore' => 'htmlcert'); } /** diff --git a/classes/external.php b/classes/external.php index b428848..46d9e70 100644 --- a/classes/external.php +++ b/classes/external.php @@ -17,11 +17,11 @@ /** * This is the external API for this tool. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die(); require_once("$CFG->libdir/externallib.php"); @@ -29,152 +29,10 @@ require_once("$CFG->libdir/externallib.php"); /** * This is the external API for this tool. * - * @copyright 2016 Mark Nelson + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class external extends \external_api { - - /** - * Returns the save_element() parameters. - * - * @return \external_function_parameters - */ - public static function save_element_parameters() { - return new \external_function_parameters( - array( - 'templateid' => new \external_value(PARAM_INT, 'The template id'), - 'elementid' => new \external_value(PARAM_INT, 'The element id'), - 'values' => new \external_multiple_structure( - new \external_single_structure( - array( - 'name' => new \external_value(PARAM_ALPHANUMEXT, 'The field to update'), - 'value' => new \external_value(PARAM_RAW, 'The value of the field'), - ) - ) - ) - ) - ); - } - - /** - * Handles saving element data. - * - * @param int $templateid The template id. - * @param int $elementid The element id. - * @param array $values The values to save - * @return array - */ - public static function save_element($templateid, $elementid, $values) { - global $DB; - - $params = array( - 'templateid' => $templateid, - 'elementid' => $elementid, - 'values' => $values - ); - self::validate_parameters(self::save_element_parameters(), $params); - - $template = $DB->get_record('customcert_templates', array('id' => $templateid), '*', MUST_EXIST); - $element = $DB->get_record('customcert_elements', array('id' => $elementid), '*', MUST_EXIST); - - // Set the template. - $template = new \mod_customcert\template($template); - - // Perform checks. - if ($cm = $template->get_cm()) { - self::validate_context(\context_module::instance($cm->id)); - } else { - self::validate_context(\context_system::instance()); - } - // Make sure the user has the required capabilities. - $template->require_manage(); - - // Set the values we are going to save. - $data = new \stdClass(); - $data->id = $element->id; - $data->name = $element->name; - foreach ($values as $value) { - $field = $value['name']; - $data->$field = $value['value']; - } - - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - return $e->save_form_elements($data); - } - - return false; - } - - /** - * Returns the save_element result value. - * - * @return \external_value - */ - public static function save_element_returns() { - return new \external_value(PARAM_BOOL, 'True if successful, false otherwise'); - } - - /** - * Returns get_element() parameters. - * - * @return \external_function_parameters - */ - public static function get_element_html_parameters() { - return new \external_function_parameters( - array( - 'templateid' => new \external_value(PARAM_INT, 'The template id'), - 'elementid' => new \external_value(PARAM_INT, 'The element id'), - ) - ); - } - - /** - * Handles return the element's HTML. - * - * @param int $templateid The template id - * @param int $elementid The element id. - * @return string - */ - public static function get_element_html($templateid, $elementid) { - global $DB; - - $params = array( - 'templateid' => $templateid, - 'elementid' => $elementid - ); - self::validate_parameters(self::get_element_html_parameters(), $params); - - $template = $DB->get_record('customcert_templates', array('id' => $templateid), '*', MUST_EXIST); - $element = $DB->get_record('customcert_elements', array('id' => $elementid), '*', MUST_EXIST); - - // Set the template. - $template = new \mod_customcert\template($template); - - // Perform checks. - if ($cm = $template->get_cm()) { - self::validate_context(\context_module::instance($cm->id)); - } else { - self::validate_context(\context_system::instance()); - } - - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - return $e->render_html(); - } - - return ''; - } - - /** - * Returns the get_element result value. - * - * @return \external_value - */ - public static function get_element_html_returns() { - return new \external_value(PARAM_RAW, 'The HTML'); - } - /** * Returns the delete_issue() parameters. * @@ -190,7 +48,7 @@ class external extends \external_api { } /** - * Handles deleting a customcert issue. + * Handles deleting a htmlcert issue. * * @param int $certificateid The certificate id. * @param int $issueid The issue id. @@ -205,18 +63,18 @@ class external extends \external_api { ]; self::validate_parameters(self::delete_issue_parameters(), $params); - $certificate = $DB->get_record('customcert', ['id' => $certificateid], '*', MUST_EXIST); - $issue = $DB->get_record('customcert_issues', ['id' => $issueid, 'customcertid' => $certificateid], '*', MUST_EXIST); + $certificate = $DB->get_record('htmlcert', ['id' => $certificateid], '*', MUST_EXIST); + $issue = $DB->get_record('htmlcert_issues', ['id' => $issueid, 'htmlcertid' => $certificateid], '*', MUST_EXIST); - $cm = get_coursemodule_from_instance('customcert', $certificate->id, 0, false, MUST_EXIST); + $cm = get_coursemodule_from_instance('htmlcert', $certificate->id, 0, false, MUST_EXIST); // Make sure the user has the required capabilities. $context = \context_module::instance($cm->id); self::validate_context($context); - require_capability('mod/customcert:manage', $context); + require_capability('mod/htmlcert:manage', $context); // Delete the issue. - return $DB->delete_records('customcert_issues', ['id' => $issue->id]); + return $DB->delete_records('htmlcert_issues', ['id' => $issue->id]); } /** diff --git a/classes/grade_information.php b/classes/grade_information.php index df9075f..1d84275 100644 --- a/classes/grade_information.php +++ b/classes/grade_information.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die(); /** * The class that provides a grade object to be used by elements for display purposes. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2017 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/classes/helper.php b/classes/helper.php index 30267f6..04d40d3 100644 --- a/classes/helper.php +++ b/classes/helper.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2021 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; use core_user\fields; @@ -33,8 +33,8 @@ defined('MOODLE_INTERNAL') || die(); * * Helper functionality for this module. * - * @package mod_customcert - * @copyright 2021 Mark Nelson + * @package mod_htmlcert + * @copyright 2021 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { diff --git a/classes/load_template_form.php b/classes/load_template_form.php index ef9a8d7..8e9b279 100644 --- a/classes/load_template_form.php +++ b/classes/load_template_form.php @@ -1,5 +1,5 @@ . /** - * This file contains the form for loading customcert templates. + * This file contains the form for loading htmlcert templates. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); require_once($CFG->libdir . '/formslib.php'); /** - * The form for loading customcert templates. + * The form for loading htmlcert templates. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2013 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -49,16 +49,16 @@ class load_template_form extends \moodleform { $context = $this->_customdata['context']; $syscontext = \context_system::instance(); - $mform->addElement('header', 'loadtemplateheader', get_string('loadtemplate', 'customcert')); + $mform->addElement('header', 'loadtemplateheader', get_string('loadtemplate', 'htmlcert')); // Display a link to the manage templates page. - if ($context->contextlevel != CONTEXT_SYSTEM && has_capability('mod/customcert:manage', $syscontext)) { - $link = \html_writer::link(new \moodle_url('/mod/customcert/manage_templates.php'), - get_string('managetemplates', 'customcert')); + if ($context->contextlevel != CONTEXT_SYSTEM && has_capability('mod/htmlcert:manage', $syscontext)) { + $link = \html_writer::link(new \moodle_url('/mod/htmlcert/manage_templates.php'), + get_string('managetemplates', 'htmlcert')); $mform->addElement('static', 'managetemplates', '', $link); } - $arrtemplates = $DB->get_records_menu('customcert_templates', ['contextid' => $syscontext->id], 'name ASC', 'id, name'); + $arrtemplates = $DB->get_records_menu('htmlcert_templates', ['contextid' => $syscontext->id], 'name ASC', 'id, name'); if ($arrtemplates) { $templates = []; foreach ($arrtemplates as $key => $template) { @@ -66,11 +66,11 @@ class load_template_form extends \moodleform { } $group = array(); $group[] = $mform->createElement('select', 'ltid', '', $templates); - $group[] = $mform->createElement('submit', 'loadtemplatesubmit', get_string('load', 'customcert')); + $group[] = $mform->createElement('submit', 'loadtemplatesubmit', get_string('load', 'htmlcert')); $mform->addElement('group', 'loadtemplategroup', '', $group, '', false); $mform->setType('ltid', PARAM_INT); } else { - $msg = \html_writer::tag('div', get_string('notemplates', 'customcert'), array('class' => 'alert')); + $msg = \html_writer::tag('div', get_string('notemplates', 'htmlcert'), array('class' => 'alert')); $mform->addElement('static', 'notemplates', '', $msg); } } diff --git a/classes/manage_templates_table.php b/classes/manage_templates_table.php index 58b8acb..3908dc0 100644 --- a/classes/manage_templates_table.php +++ b/classes/manage_templates_table.php @@ -17,12 +17,12 @@ /** * The table that displays the templates in a given context. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die; @@ -33,8 +33,8 @@ require_once($CFG->libdir . '/tablelib.php'); /** * Class for the table that displays the templates in a given context. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class manage_templates_table extends \table_sql { @@ -50,7 +50,7 @@ class manage_templates_table extends \table_sql { * @param \context $context */ public function __construct($context) { - parent::__construct('mod_customcert_manage_templates_table'); + parent::__construct('mod_htmlcert_manage_templates_table'); $columns = [ 'name', @@ -90,11 +90,11 @@ class manage_templates_table extends \table_sql { global $OUTPUT; // Link to edit the template. - $editlink = new \moodle_url('/mod/customcert/edit.php', array('tid' => $template->id)); + $editlink = new \moodle_url('/mod/htmlcert/edit.php', array('tid' => $template->id)); $editicon = $OUTPUT->action_icon($editlink, new \pix_icon('t/edit', get_string('edit'))); // Link to duplicate the template. - $duplicatelink = new \moodle_url('/mod/customcert/manage_templates.php', + $duplicatelink = new \moodle_url('/mod/htmlcert/manage_templates.php', array( 'tid' => $template->id, 'action' => 'duplicate', @@ -105,7 +105,7 @@ class manage_templates_table extends \table_sql { array('class' => 'action-icon duplicate-icon')); // Link to delete the template. - $deletelink = new \moodle_url('/mod/customcert/manage_templates.php', + $deletelink = new \moodle_url('/mod/htmlcert/manage_templates.php', array( 'tid' => $template->id, 'action' => 'delete', @@ -127,11 +127,11 @@ class manage_templates_table extends \table_sql { public function query_db($pagesize, $useinitialsbar = true) { global $DB; - $total = $DB->count_records('customcert_templates', array('contextid' => $this->context->id)); + $total = $DB->count_records('htmlcert_templates', array('contextid' => $this->context->id)); $this->pagesize($pagesize, $total); - $this->rawdata = $DB->get_records('customcert_templates', array('contextid' => $this->context->id), + $this->rawdata = $DB->get_records('htmlcert_templates', array('contextid' => $this->context->id), $this->get_sql_sort(), '*', $this->get_page_start(), $this->get_page_size()); // Set initial bars. diff --git a/classes/my_certificates_table.php b/classes/my_certificates_table.php index 8da1473..b8d349d 100644 --- a/classes/my_certificates_table.php +++ b/classes/my_certificates_table.php @@ -17,12 +17,12 @@ /** * The report that displays the certificates the user has throughout the site. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die; @@ -33,7 +33,7 @@ require_once($CFG->libdir . '/tablelib.php'); /** * Class for the report that displays the certificates the user has throughout the site. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2016 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -51,7 +51,7 @@ class my_certificates_table extends \table_sql { * @param string|null $download The file type, null if we are not downloading */ public function __construct($userid, $download = null) { - parent::__construct('mod_customcert_report_table'); + parent::__construct('mod_htmlcert_report_table'); $columns = array( 'name', @@ -62,13 +62,13 @@ class my_certificates_table extends \table_sql { $headers = array( get_string('name'), get_string('course'), - get_string('receiveddate', 'customcert'), - get_string('code', 'customcert') + get_string('receiveddate', 'htmlcert'), + get_string('code', 'htmlcert') ); // Check if we were passed a filename, which means we want to download it. if ($download) { - $this->is_downloading($download, 'customcert-report'); + $this->is_downloading($download, 'htmlcert-report'); } if (!$this->is_downloading()) { @@ -94,7 +94,7 @@ class my_certificates_table extends \table_sql { * @return string */ public function col_name($certificate) { - $cm = get_coursemodule_from_instance('customcert', $certificate->id); + $cm = get_coursemodule_from_instance('htmlcert', $certificate->id); $context = \context_module::instance($cm->id); return format_string($certificate->name, true, ['context' => $context]); @@ -107,7 +107,7 @@ class my_certificates_table extends \table_sql { * @return string */ public function col_coursename($certificate) { - $cm = get_coursemodule_from_instance('customcert', $certificate->id); + $cm = get_coursemodule_from_instance('htmlcert', $certificate->id); $context = \context_module::instance($cm->id); return format_string($certificate->coursename, true, ['context' => $context]); @@ -142,8 +142,8 @@ class my_certificates_table extends \table_sql { public function col_download($certificate) { global $OUTPUT; - $icon = new \pix_icon('download', get_string('download'), 'customcert'); - $link = new \moodle_url('/mod/customcert/my_certificates.php', + $icon = new \pix_icon('download', get_string('download'), 'htmlcert'); + $link = new \moodle_url('/mod/htmlcert/my_certificates.php', array('userid' => $this->userid, 'certificateid' => $certificate->id, 'downloadcert' => '1')); diff --git a/classes/output/email/renderer.php b/classes/output/email/renderer.php index e1295e7..91dd0af 100644 --- a/classes/output/email/renderer.php +++ b/classes/output/email/renderer.php @@ -17,23 +17,23 @@ /** * Email certificate as html renderer. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output\email; +namespace mod_htmlcert\output\email; defined('MOODLE_INTERNAL') || die(); /** * Email certificate as html renderer. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class renderer extends \mod_customcert\output\renderer { +class renderer extends \mod_htmlcert\output\renderer { /** * The template name for this renderer. diff --git a/classes/output/email/renderer_textemail.php b/classes/output/email/renderer_textemail.php index 7ef8f2c..625ff9c 100644 --- a/classes/output/email/renderer_textemail.php +++ b/classes/output/email/renderer_textemail.php @@ -17,23 +17,23 @@ /** * Email certificate as text renderer. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output\email; +namespace mod_htmlcert\output\email; defined('MOODLE_INTERNAL') || die(); /** * Email certificate as text renderer. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class renderer_textemail extends \mod_customcert\output\renderer { +class renderer_textemail extends \mod_htmlcert\output\renderer { /** * The template name for this renderer. diff --git a/classes/output/email_certificate.php b/classes/output/email_certificate.php index 3020caa..80b03d5 100644 --- a/classes/output/email_certificate.php +++ b/classes/output/email_certificate.php @@ -17,12 +17,12 @@ /** * Email certificate renderable. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output; +namespace mod_htmlcert\output; defined('MOODLE_INTERNAL') || die(); @@ -100,17 +100,17 @@ class email_certificate implements \renderable, \templatable { $info->coursefullname = $this->coursefullname; if ($this->isstudent) { - $data->emailgreeting = get_string('emailstudentgreeting', 'customcert', $this->userfullname); - $data->emailbody = get_string('emailstudentbody', 'customcert', $info); - $data->emailbodyplaintext = get_string('emailstudentbodyplaintext', 'customcert', $info); - $data->emailcertificatelink = new \moodle_url('/mod/customcert/view.php', array('id' => $this->cmid)); - $data->emailcertificatetext = get_string('emailstudentcertificatelinktext', 'customcert'); + $data->emailgreeting = get_string('emailstudentgreeting', 'htmlcert', $this->userfullname); + $data->emailbody = get_string('emailstudentbody', 'htmlcert', $info); + $data->emailbodyplaintext = get_string('emailstudentbodyplaintext', 'htmlcert', $info); + $data->emailcertificatelink = new \moodle_url('/mod/htmlcert/view.php', array('id' => $this->cmid)); + $data->emailcertificatetext = get_string('emailstudentcertificatelinktext', 'htmlcert'); } else { - $data->emailgreeting = get_string('emailnonstudentgreeting', 'customcert'); - $data->emailbody = get_string('emailnonstudentbody', 'customcert', $info); - $data->emailbodyplaintext = get_string('emailnonstudentbodyplaintext', 'customcert', $info); - $data->emailcertificatelink = new \moodle_url('/mod/customcert/view.php', array('id' => $this->cmid)); - $data->emailcertificatetext = get_string('emailnonstudentcertificatelinktext', 'customcert'); + $data->emailgreeting = get_string('emailnonstudentgreeting', 'htmlcert'); + $data->emailbody = get_string('emailnonstudentbody', 'htmlcert', $info); + $data->emailbodyplaintext = get_string('emailnonstudentbodyplaintext', 'htmlcert', $info); + $data->emailcertificatelink = new \moodle_url('/mod/htmlcert/view.php', array('id' => $this->cmid)); + $data->emailcertificatetext = get_string('emailnonstudentcertificatelinktext', 'htmlcert'); } return $data; diff --git a/classes/output/mobile.php b/classes/output/mobile.php index e4d3eda..c0b6b28 100644 --- a/classes/output/mobile.php +++ b/classes/output/mobile.php @@ -17,12 +17,12 @@ /** * Contains the mobile output class for the custom certificate. * - * @package mod_customcert - * @copyright 2018 Mark Nelson + * @package mod_htmlcert + * @copyright 2018 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output; +namespace mod_htmlcert\output; defined('MOODLE_INTERNAL') || die(); @@ -50,34 +50,34 @@ class mobile { $groupid = empty($args->group) ? 0 : (int) $args->group; // By default, group 0. // Capabilities check. - $cm = get_coursemodule_from_id('customcert', $cmid); + $cm = get_coursemodule_from_id('htmlcert', $cmid); $context = \context_module::instance($cm->id); - self::require_capability($cm, $context, 'mod/customcert:view'); + self::require_capability($cm, $context, 'mod/htmlcert:view'); // Set some variables we are going to be using. - $certificate = $DB->get_record('customcert', ['id' => $cm->instance], '*', MUST_EXIST); + $certificate = $DB->get_record('htmlcert', ['id' => $cm->instance], '*', MUST_EXIST); $certificate->name = format_string($certificate->name); list($certificate->intro, $certificate->introformat) = external_format_text($certificate->intro, - $certificate->introformat, $context->id, 'mod_customcert', 'intro'); + $certificate->introformat, $context->id, 'mod_htmlcert', 'intro'); // Get any issues this person may have. $issue = false; - if ($issues = $DB->get_records('customcert_issues', ['userid' => $USER->id, 'customcertid' => $certificate->id], + if ($issues = $DB->get_records('htmlcert_issues', ['userid' => $USER->id, 'htmlcertid' => $certificate->id], 'timecreated DESC')) { $issue = reset($issues); } $requiredtimemet = true; - $canmanage = has_capability('mod/customcert:manage', $context); + $canmanage = has_capability('mod/htmlcert:manage', $context); if ($certificate->requiredtime && !$canmanage) { - if (\mod_customcert\certificate::get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { + if (\mod_htmlcert\certificate::get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { $requiredtimemet = false; } } $fileurl = ""; if ($requiredtimemet) { - $fileurl = new \moodle_url('/mod/customcert/mobile/pluginfile.php', ['certificateid' => $certificate->id, + $fileurl = new \moodle_url('/mod/htmlcert/mobile/pluginfile.php', ['certificateid' => $certificate->id, 'userid' => $USER->id]); $fileurl = $fileurl->out(true); } @@ -85,7 +85,7 @@ class mobile { $showreport = false; $groups = []; $recipients = []; - if (has_capability('mod/customcert:viewreport', $context)) { + if (has_capability('mod/htmlcert:viewreport', $context)) { $showreport = true; // Get the groups (if any) to display - also sets active group. @@ -95,10 +95,10 @@ class mobile { $groupmode = 'aag'; } - $recipients = \mod_customcert\certificate::get_issues($certificate->id, $groupmode, $cm, 0, 0); + $recipients = \mod_htmlcert\certificate::get_issues($certificate->id, $groupmode, $cm, 0, 0); foreach ($recipients as $recipient) { $recipient->displayname = fullname($recipient); - $recipient->fileurl = new \moodle_url('/mod/customcert/mobile/pluginfile.php', ['certificateid' => $certificate->id, + $recipient->fileurl = new \moodle_url('/mod/htmlcert/mobile/pluginfile.php', ['certificateid' => $certificate->id, 'userid' => $recipient->id]); } } @@ -123,7 +123,7 @@ class mobile { 'templates' => [ [ 'id' => 'main', - 'html' => $OUTPUT->render_from_template("mod_customcert/mobile_view_activity_page_$versionname", $data), + 'html' => $OUTPUT->render_from_template("mod_htmlcert/mobile_view_activity_page_$versionname", $data), ], ], 'javascript' => '', diff --git a/classes/output/renderer.php b/classes/output/renderer.php index c8eeb37..bf621c9 100644 --- a/classes/output/renderer.php +++ b/classes/output/renderer.php @@ -17,12 +17,12 @@ /** * Contains renderer class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output; +namespace mod_htmlcert\output; defined('MOODLE_INTERNAL') || die(); @@ -31,8 +31,8 @@ use plugin_renderer_base; /** * Renderer class. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class renderer extends plugin_renderer_base { @@ -42,12 +42,12 @@ class renderer extends plugin_renderer_base { * * Defer to template. * - * @param \mod_customcert\output\verify_certificate_results $page + * @param \mod_htmlcert\output\verify_certificate_results $page * @return string html for the page */ public function render_verify_certificate_results(verify_certificate_results $page) { $data = $page->export_for_template($this); - return parent::render_from_template('mod_customcert/verify_certificate_results', $data); + return parent::render_from_template('mod_htmlcert/verify_certificate_results', $data); } /** @@ -58,6 +58,6 @@ class renderer extends plugin_renderer_base { */ public function render_email_certificate(email_certificate $certificate) { $data = $certificate->export_for_template($this); - return $this->render_from_template('mod_customcert/' . $this->get_template_name(), $data); + return $this->render_from_template('mod_htmlcert/' . $this->get_template_name(), $data); } } diff --git a/classes/output/verify_certificate_result.php b/classes/output/verify_certificate_result.php index f421eb7..428d20e 100644 --- a/classes/output/verify_certificate_result.php +++ b/classes/output/verify_certificate_result.php @@ -17,12 +17,12 @@ /** * Contains class used to prepare a verification result for display. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2017 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output; +namespace mod_htmlcert\output; defined('MOODLE_INTERNAL') || die(); @@ -32,7 +32,7 @@ use templatable; /** * Class to prepare a verification result for display. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2017 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -69,7 +69,7 @@ class verify_certificate_result implements templatable, renderable { * @param \stdClass $result */ public function __construct($result) { - $cm = get_coursemodule_from_instance('customcert', $result->certificateid); + $cm = get_coursemodule_from_instance('htmlcert', $result->certificateid); $context = \context_module::instance($cm->id); $this->userprofileurl = new \moodle_url('/user/view.php', array('id' => $result->userid, diff --git a/classes/output/verify_certificate_results.php b/classes/output/verify_certificate_results.php index d77fe04..7d50092 100644 --- a/classes/output/verify_certificate_results.php +++ b/classes/output/verify_certificate_results.php @@ -17,12 +17,12 @@ /** * Contains class used to prepare verification results for display. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\output; +namespace mod_htmlcert\output; defined('MOODLE_INTERNAL') || die(); @@ -32,8 +32,8 @@ use templatable; /** * Class to prepare verification results for display. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class verify_certificate_results implements templatable, renderable { @@ -61,9 +61,9 @@ class verify_certificate_results implements templatable, renderable { public function __construct($result) { $this->success = $result->success; if ($this->success) { - $this->message = get_string('verified', 'customcert'); + $this->message = get_string('verified', 'htmlcert'); } else { - $this->message = get_string('notverified', 'customcert'); + $this->message = get_string('notverified', 'htmlcert'); } $this->issues = $result->issues; } diff --git a/classes/page_helper.php b/classes/page_helper.php index fd21757..197bed0 100644 --- a/classes/page_helper.php +++ b/classes/page_helper.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die(); @@ -31,8 +31,8 @@ defined('MOODLE_INTERNAL') || die(); * * Provides useful functions. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class page_helper { @@ -56,7 +56,7 @@ class page_helper { $PAGE->set_pagelayout('admin'); $PAGE->set_heading($SITE->fullname); - $urloverride = new \moodle_url('/admin/settings.php?section=modsettingcustomcert'); + $urloverride = new \moodle_url('/admin/settings.php?section=modsettinghtmlcert'); \navigation_node::override_active_url($urloverride); } else { $PAGE->set_heading(format_string($COURSE->fullname)); diff --git a/classes/plugininfo/customcertelement.php b/classes/plugininfo/customcertelement.php deleted file mode 100644 index 5eeeab4..0000000 --- a/classes/plugininfo/customcertelement.php +++ /dev/null @@ -1,87 +0,0 @@ -. - -/** - * Subplugin info class. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace mod_customcert\plugininfo; - -use core\plugininfo\base; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Subplugin info class. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class customcertelement extends base { - - /** - * Do not allow users to uninstall these plugins as it could cause customcerts to break. - * - * @return bool - */ - public function is_uninstall_allowed() { - return false; - } - - /** - * Loads plugin settings to the settings tree. - * - * @param \part_of_admin_tree $adminroot - * @param string $parentnodename - * @param bool $hassiteconfig whether the current user has moodle/site:config capability - */ - public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { - global $CFG, $USER, $DB, $OUTPUT, $PAGE; - $ADMIN = $adminroot; - $plugininfo = $this; - - if (!$this->is_installed_and_upgraded()) { - return; - } - - if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) { - return; - } - - $section = $this->get_settings_section_name(); - $settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', false); - - include($this->full_path('settings.php')); - $ADMIN->add($parentnodename, $settings); - } - - /** - * Get the settings section name. - * - * @return null|string the settings section name. - */ - public function get_settings_section_name() { - if (file_exists($this->full_path('settings.php'))) { - return 'customcertelement_' . $this->name; - } else { - return null; - } - } -} diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 29bebc6..7d82da7 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -15,13 +15,13 @@ // along with Moodle. If not, see . /** - * Privacy Subsystem implementation for mod_customcert. + * Privacy Subsystem implementation for mod_htmlcert. * - * @package mod_customcert - * @copyright 2018 Mark Nelson + * @package mod_htmlcert + * @copyright 2018 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\privacy; +namespace mod_htmlcert\privacy; use core_privacy\local\metadata\collection; use core_privacy\local\request\approved_contextlist; @@ -35,7 +35,7 @@ use core_privacy\local\request\writer; defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem implementation for mod_customcert. + * Privacy Subsystem implementation for mod_htmlcert. * * @copyright 2018 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -53,15 +53,15 @@ class provider implements */ public static function get_metadata(collection $items) : collection { $items->add_database_table( - 'customcert_issues', + 'htmlcert_issues', [ - 'userid' => 'privacy:metadata:customcert_issues:userid', - 'customcertid' => 'privacy:metadata:customcert_issues:customcertid', - 'code' => 'privacy:metadata:customcert_issues:code', - 'emailed' => 'privacy:metadata:customcert_issues:emailed', - 'timecreated' => 'privacy:metadata:customcert_issues:timecreated', + 'userid' => 'privacy:metadata:htmlcert_issues:userid', + 'htmlcertid' => 'privacy:metadata:htmlcert_issues:htmlcertid', + 'code' => 'privacy:metadata:htmlcert_issues:code', + 'emailed' => 'privacy:metadata:htmlcert_issues:emailed', + 'timecreated' => 'privacy:metadata:htmlcert_issues:timecreated', ], - 'privacy:metadata:customcert_issues' + 'privacy:metadata:htmlcert_issues' ); return $items; @@ -82,14 +82,14 @@ class provider implements INNER JOIN {modules} m ON m.id = cm.module AND m.name = :modulename - INNER JOIN {customcert} customcert - ON customcert.id = cm.instance - INNER JOIN {customcert_issues} customcertissues - ON customcertissues.customcertid = customcert.id - WHERE customcertissues.userid = :userid"; + INNER JOIN {htmlcert} htmlcert + ON htmlcert.id = cm.instance + INNER JOIN {htmlcert_issues} htmlcertissues + ON htmlcertissues.htmlcertid = htmlcert.id + WHERE htmlcertissues.userid = :userid"; $params = [ - 'modulename' => 'customcert', + 'modulename' => 'htmlcert', 'contextlevel' => CONTEXT_MODULE, 'userid' => $userid, ]; @@ -112,19 +112,19 @@ class provider implements } // Fetch all users who have a custom certificate. - $sql = "SELECT customcertissues.userid + $sql = "SELECT htmlcertissues.userid FROM {course_modules} cm JOIN {modules} m ON m.id = cm.module AND m.name = :modname - JOIN {customcert} customcert - ON customcert.id = cm.instance - JOIN {customcert_issues} customcertissues - ON customcertissues.customcertid = customcert.id + JOIN {htmlcert} htmlcert + ON htmlcert.id = cm.instance + JOIN {htmlcert_issues} htmlcertissues + ON htmlcertissues.htmlcertid = htmlcert.id WHERE cm.id = :cmid"; $params = [ 'cmid' => $context->instanceid, - 'modname' => 'customcert', + 'modname' => 'htmlcert', ]; $userlist->add_from_sql('userid', $sql, $params); @@ -152,22 +152,22 @@ class provider implements $user = $contextlist->get_user(); - // Get all the customcert activities associated with the above course modules. - $customcertidstocmids = self::get_customcert_ids_to_cmids_from_cmids($cmids); + // Get all the htmlcert activities associated with the above course modules. + $htmlcertidstocmids = self::get_htmlcert_ids_to_cmids_from_cmids($cmids); - list($insql, $inparams) = $DB->get_in_or_equal(array_keys($customcertidstocmids), SQL_PARAMS_NAMED); + list($insql, $inparams) = $DB->get_in_or_equal(array_keys($htmlcertidstocmids), SQL_PARAMS_NAMED); $params = array_merge($inparams, ['userid' => $user->id]); - $recordset = $DB->get_recordset_select('customcert_issues', "customcertid $insql AND userid = :userid", + $recordset = $DB->get_recordset_select('htmlcert_issues', "htmlcertid $insql AND userid = :userid", $params, 'timecreated, id ASC'); - self::recordset_loop_and_export($recordset, 'customcertid', [], function($carry, $record) { + self::recordset_loop_and_export($recordset, 'htmlcertid', [], function($carry, $record) { $carry[] = [ 'code' => $record->code, 'emailed' => transform::yesno($record->emailed), 'timecreated' => transform::datetime($record->timecreated) ]; return $carry; - }, function($customcertid, $data) use ($user, $customcertidstocmids) { - $context = \context_module::instance($customcertidstocmids[$customcertid]); + }, function($htmlcertid, $data) use ($user, $htmlcertidstocmids) { + $context = \context_module::instance($htmlcertidstocmids[$htmlcertid]); $contextdata = helper::get_context_data($context, $user); $finaldata = (object) array_merge((array) $contextdata, ['issues' => $data]); helper::export_context_files($context, $user); @@ -187,11 +187,11 @@ class provider implements return; } - if (!$cm = get_coursemodule_from_id('customcert', $context->instanceid)) { + if (!$cm = get_coursemodule_from_id('htmlcert', $context->instanceid)) { return; } - $DB->delete_records('customcert_issues', ['customcertid' => $cm->instance]); + $DB->delete_records('htmlcert_issues', ['htmlcertid' => $cm->instance]); } /** @@ -212,7 +212,7 @@ class provider implements continue; } $instanceid = $DB->get_field('course_modules', 'instance', ['id' => $context->instanceid], MUST_EXIST); - $DB->delete_records('customcert_issues', ['customcertid' => $instanceid, 'userid' => $userid]); + $DB->delete_records('htmlcert_issues', ['htmlcertid' => $instanceid, 'userid' => $userid]); } } @@ -229,39 +229,39 @@ class provider implements return; } - $cm = get_coursemodule_from_id('customcert', $context->instanceid); + $cm = get_coursemodule_from_id('htmlcert', $context->instanceid); if (!$cm) { - // Only customcert module will be handled. + // Only htmlcert module will be handled. return; } $userids = $userlist->get_userids(); list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); - $select = "customcertid = :customcertid AND userid $usersql"; - $params = ['customcertid' => $cm->instance] + $userparams; - $DB->delete_records_select('customcert_issues', $select, $params); + $select = "htmlcertid = :htmlcertid AND userid $usersql"; + $params = ['htmlcertid' => $cm->instance] + $userparams; + $DB->delete_records_select('htmlcert_issues', $select, $params); } /** - * Return a list of Customcert IDs mapped to their course module ID. + * Return a list of htmlcert IDs mapped to their course module ID. * * @param array $cmids The course module IDs. - * @return array In the form of [$customcertid => $cmid]. + * @return array In the form of [$htmlcertid => $cmid]. */ - protected static function get_customcert_ids_to_cmids_from_cmids(array $cmids) { + protected static function get_htmlcert_ids_to_cmids_from_cmids(array $cmids) { global $DB; list($insql, $inparams) = $DB->get_in_or_equal($cmids, SQL_PARAMS_NAMED); - $sql = "SELECT customcert.id, cm.id AS cmid - FROM {customcert} customcert + $sql = "SELECT htmlcert.id, cm.id AS cmid + FROM {htmlcert} htmlcert JOIN {modules} m ON m.name = :modulename JOIN {course_modules} cm - ON cm.instance = customcert.id + ON cm.instance = htmlcert.id AND cm.module = m.id WHERE cm.id $insql"; - $params = array_merge($inparams, ['modulename' => 'customcert']); + $params = array_merge($inparams, ['modulename' => 'htmlcert']); return $DB->get_records_sql_menu($sql, $params); } diff --git a/classes/report_table.php b/classes/report_table.php index 40cc4ab..8fd23cc 100644 --- a/classes/report_table.php +++ b/classes/report_table.php @@ -17,12 +17,12 @@ /** * The report that displays issued certificates. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die; @@ -33,16 +33,16 @@ require_once($CFG->libdir . '/tablelib.php'); /** * Class for the report that displays issued certificates. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class report_table extends \table_sql { /** - * @var int $customcertid The custom certificate id + * @var int $htmlcertid The custom certificate id */ - protected $customcertid; + protected $htmlcertid; /** * @var \stdClass $cm The course module. @@ -57,13 +57,13 @@ class report_table extends \table_sql { /** * Sets up the table. * - * @param int $customcertid + * @param int $htmlcertid * @param \stdClass $cm the course module * @param bool $groupmode are we in group mode? * @param string|null $download The file type, null if we are not downloading */ - public function __construct($customcertid, $cm, $groupmode, $download = null) { - parent::__construct('mod_customcert_report_table'); + public function __construct($htmlcertid, $cm, $groupmode, $download = null) { + parent::__construct('mod_htmlcert_report_table'); $context = \context_module::instance($cm->id); $extrafields = \core_user\fields::for_identity($context)->get_required_fields(); @@ -81,12 +81,12 @@ class report_table extends \table_sql { foreach ($extrafields as $extrafield) { $headers[] = \core_user\fields::get_display_name($extrafield); } - $headers[] = get_string('receiveddate', 'customcert'); - $headers[] = get_string('code', 'customcert'); + $headers[] = get_string('receiveddate', 'htmlcert'); + $headers[] = get_string('code', 'htmlcert'); // Check if we were passed a filename, which means we want to download it. if ($download) { - $this->is_downloading($download, 'customcert-report'); + $this->is_downloading($download, 'htmlcert-report'); } if (!$this->is_downloading()) { @@ -94,7 +94,7 @@ class report_table extends \table_sql { $headers[] = get_string('file'); } - if (!$this->is_downloading() && has_capability('mod/customcert:manage', $context)) { + if (!$this->is_downloading() && has_capability('mod/htmlcert:manage', $context)) { $columns[] = 'actions'; $headers[] = ''; } @@ -107,7 +107,7 @@ class report_table extends \table_sql { $this->no_sorting('download'); $this->is_downloadable(true); - $this->customcertid = $customcertid; + $this->htmlcertid = $htmlcertid; $this->cm = $cm; $this->groupmode = $groupmode; } @@ -157,8 +157,8 @@ class report_table extends \table_sql { public function col_download($user) { global $OUTPUT; - $icon = new \pix_icon('download', get_string('download'), 'customcert'); - $link = new \moodle_url('/mod/customcert/view.php', + $icon = new \pix_icon('download', get_string('download'), 'htmlcert'); + $link = new \moodle_url('/mod/htmlcert/view.php', [ 'id' => $this->cm->id, 'downloadissue' => $user->id @@ -178,7 +178,7 @@ class report_table extends \table_sql { global $OUTPUT; $icon = new \pix_icon('i/delete', get_string('delete')); - $link = new \moodle_url('/mod/customcert/view.php', + $link = new \moodle_url('/mod/htmlcert/view.php', [ 'id' => $this->cm->id, 'deleteissue' => $user->issueid, @@ -196,11 +196,11 @@ class report_table extends \table_sql { * @param bool $useinitialsbar do you want to use the initials bar. */ public function query_db($pagesize, $useinitialsbar = true) { - $total = \mod_customcert\certificate::get_number_of_issues($this->customcertid, $this->cm, $this->groupmode); + $total = \mod_htmlcert\certificate::get_number_of_issues($this->htmlcertid, $this->cm, $this->groupmode); $this->pagesize($pagesize, $total); - $this->rawdata = \mod_customcert\certificate::get_issues($this->customcertid, $this->groupmode, $this->cm, + $this->rawdata = \mod_htmlcert\certificate::get_issues($this->htmlcertid, $this->groupmode, $this->cm, $this->get_page_start(), $this->get_page_size(), $this->get_sql_sort()); // Set initial bars. @@ -214,7 +214,7 @@ class report_table extends \table_sql { */ public function download() { \core\session\manager::write_close(); - $total = \mod_customcert\certificate::get_number_of_issues($this->customcertid, $this->cm, $this->groupmode); + $total = \mod_htmlcert\certificate::get_number_of_issues($this->htmlcertid, $this->cm, $this->groupmode); $this->out($total, false); exit; } diff --git a/classes/search/activity.php b/classes/search/activity.php index f3c85c1..587f464 100644 --- a/classes/search/activity.php +++ b/classes/search/activity.php @@ -1,5 +1,5 @@ . /** - * Search area for mod_customcert activities. + * Search area for mod_htmlcert activities. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\search; +namespace mod_htmlcert\search; defined('MOODLE_INTERNAL') || die(); /** - * Search area for mod_customcert activities. + * Search area for mod_htmlcert activities. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class activity extends \core_search\base_activity { diff --git a/classes/task/email_certificate_task.php b/classes/task/email_certificate_task.php index 40ee156..1581ffc 100644 --- a/classes/task/email_certificate_task.php +++ b/classes/task/email_certificate_task.php @@ -17,21 +17,21 @@ /** * A scheduled task for emailing certificates. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert\task; +namespace mod_htmlcert\task; -use mod_customcert\helper; +use mod_htmlcert\helper; defined('MOODLE_INTERNAL') || die(); /** * A scheduled task for emailing certificates. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class email_certificate_task extends \core\task\scheduled_task { @@ -42,7 +42,7 @@ class email_certificate_task extends \core\task\scheduled_task { * @return string */ public function get_name() { - return get_string('taskemailcertificate', 'customcert'); + return get_string('taskemailcertificate', 'htmlcert'); } /** @@ -55,205 +55,192 @@ class email_certificate_task extends \core\task\scheduled_task { $emailotherslengthsql = $DB->sql_length('c.emailothers'); $sql = "SELECT c.*, ct.id as templateid, ct.name as templatename, ct.contextid, co.id as courseid, co.fullname as coursefullname, co.shortname as courseshortname - FROM {customcert} c - JOIN {customcert_templates} ct + FROM {htmlcert} c + JOIN {htmlcert_templates} ct ON c.templateid = ct.id JOIN {course} co ON c.course = co.id WHERE (c.emailstudents = :emailstudents OR c.emailteachers = :emailteachers OR $emailotherslengthsql >= 3)"; - if (!$customcerts = $DB->get_records_sql($sql, array('emailstudents' => 1, 'emailteachers' => 1))) { + if (!$htmlcerts = $DB->get_records_sql($sql, array('emailstudents' => 1, 'emailteachers' => 1))) { return; } // The renderers used for sending emails. - $htmlrenderer = $PAGE->get_renderer('mod_customcert', 'email', 'htmlemail'); - $textrenderer = $PAGE->get_renderer('mod_customcert', 'email', 'textemail'); - foreach ($customcerts as $customcert) { - // Do not process an empty certificate. - $sql = "SELECT ce.* - FROM {customcert_elements} ce - JOIN {customcert_pages} cp - ON cp.id = ce.pageid - JOIN {customcert_templates} ct - ON ct.id = cp.templateid - WHERE ct.contextid = :contextid"; - if (!$DB->record_exists_sql($sql, ['contextid' => $customcert->contextid])) { + $htmlrenderer = $PAGE->get_renderer('mod_htmlcert', 'email', 'htmlemail'); + $textrenderer = $PAGE->get_renderer('mod_htmlcert', 'email', 'textemail'); + + // Get the context. + $context = \context::instance_by_id($htmlcert->contextid); + + // Set the $PAGE context - this ensure settings, such as language, are kept and don't default to the site settings. + $PAGE->set_context($context); + + // Get the person we are going to send this email on behalf of. + $userfrom = \core_user::get_noreply_user(); + + // Store teachers for later. + $teachers = get_enrolled_users($context, 'moodle/course:update'); + + $courseshortname = format_string($htmlcert->courseshortname, true, array('context' => $context)); + $coursefullname = format_string($htmlcert->coursefullname, true, array('context' => $context)); + $certificatename = format_string($htmlcert->name, true, array('context' => $context)); + + // Used to create the email subject. + $info = new \stdClass; + $info->coursename = $courseshortname; // Added for BC, so users who have edited the string don't lose this value. + $info->courseshortname = $courseshortname; + $info->coursefullname = $coursefullname; + $info->certificatename = $certificatename; + + // Get a list of all the issues. + $userfields = helper::get_all_user_name_fields('u'); + $sql = "SELECT u.id, u.username, $userfields, u.email, ci.id as issueid, ci.emailed + FROM {htmlcert_issues} ci + JOIN {user} u + ON ci.userid = u.id + WHERE ci.htmlcertid = :htmlcertid"; + $issuedusers = $DB->get_records_sql($sql, array('htmlcertid' => $htmlcert->id)); + + // Now, get a list of users who can access the certificate but have not yet. + $enrolledusers = get_enrolled_users(\context_course::instance($htmlcert->courseid), 'mod/htmlcert:view'); + foreach ($enrolledusers as $enroluser) { + // Check if the user has already been issued. + if (in_array($enroluser->id, array_keys((array) $issuedusers))) { continue; } - // Get the context. - $context = \context::instance_by_id($customcert->contextid); - - // Set the $PAGE context - this ensure settings, such as language, are kept and don't default to the site settings. - $PAGE->set_context($context); - - // Get the person we are going to send this email on behalf of. - $userfrom = \core_user::get_noreply_user(); - - // Store teachers for later. - $teachers = get_enrolled_users($context, 'moodle/course:update'); - - $courseshortname = format_string($customcert->courseshortname, true, array('context' => $context)); - $coursefullname = format_string($customcert->coursefullname, true, array('context' => $context)); - $certificatename = format_string($customcert->name, true, array('context' => $context)); - - // Used to create the email subject. - $info = new \stdClass; - $info->coursename = $courseshortname; // Added for BC, so users who have edited the string don't lose this value. - $info->courseshortname = $courseshortname; - $info->coursefullname = $coursefullname; - $info->certificatename = $certificatename; - - // Get a list of all the issues. - $userfields = helper::get_all_user_name_fields('u'); - $sql = "SELECT u.id, u.username, $userfields, u.email, ci.id as issueid, ci.emailed - FROM {customcert_issues} ci - JOIN {user} u - ON ci.userid = u.id - WHERE ci.customcertid = :customcertid"; - $issuedusers = $DB->get_records_sql($sql, array('customcertid' => $customcert->id)); - - // Now, get a list of users who can access the certificate but have not yet. - $enrolledusers = get_enrolled_users(\context_course::instance($customcert->courseid), 'mod/customcert:view'); - foreach ($enrolledusers as $enroluser) { - // Check if the user has already been issued. - if (in_array($enroluser->id, array_keys((array) $issuedusers))) { - continue; - } - - // Now check if the certificate is not visible to the current user. - $cm = get_fast_modinfo($customcert->courseid, $enroluser->id)->instances['customcert'][$customcert->id]; - if (!$cm->uservisible) { - continue; - } - - // Don't want to email those with the capability to manage the certificate. - if (has_capability('mod/customcert:manage', $context, $enroluser->id)) { - continue; - } - - // Only email those with the capability to receive the certificate. - if (!has_capability('mod/customcert:receiveissue', $context, $enroluser->id)) { - continue; - } - - // Check that they have passed the required time. - if (!empty($customcert->requiredtime)) { - if (\mod_customcert\certificate::get_course_time($customcert->courseid, - $enroluser->id) < ($customcert->requiredtime * 60)) { - continue; - } - } - - // Ensure the cert hasn't already been issued, e.g via the UI (view.php) - a race condition. - $issueid = $DB->get_field('customcert_issues', 'id', - array('userid' => $enroluser->id, 'customcertid' => $customcert->id), IGNORE_MULTIPLE); - if (empty($issueid)) { - // Ok, issue them the certificate. - $issueid = \mod_customcert\certificate::issue_certificate($customcert->id, $enroluser->id); - } - - // Add them to the array so we email them. - $enroluser->issueid = $issueid; - $enroluser->emailed = 0; - $issuedusers[] = $enroluser; - } - - // Remove all the users who have already been emailed. - foreach ($issuedusers as $key => $issueduser) { - if ($issueduser->emailed) { - unset($issuedusers[$key]); - } - } - - // If there are no users to email we can return early. - if (!$issuedusers) { + // Now check if the certificate is not visible to the current user. + $cm = get_fast_modinfo($htmlcert->courseid, $enroluser->id)->instances['htmlcert'][$htmlcert->id]; + if (!$cm->uservisible) { continue; } - // Create a directory to store the PDF we will be sending. - $tempdir = make_temp_directory('certificate/attachment'); - if (!$tempdir) { - return; + // Don't want to email those with the capability to manage the certificate. + if (has_capability('mod/htmlcert:manage', $context, $enroluser->id)) { + continue; } - // Now, email the people we need to. - foreach ($issuedusers as $user) { - // Set up the user. - cron_setup_user($user); + // Only email those with the capability to receive the certificate. + if (!has_capability('mod/htmlcert:receiveissue', $context, $enroluser->id)) { + continue; + } - $userfullname = fullname($user); - $info->userfullname = $userfullname; + // Check that they have passed the required time. + if (!empty($htmlcert->requiredtime)) { + if (\mod_htmlcert\certificate::get_course_time($htmlcert->courseid, + $enroluser->id) < ($htmlcert->requiredtime * 60)) { + continue; + } + } - // Now, get the PDF. - $template = new \stdClass(); - $template->id = $customcert->templateid; - $template->name = $customcert->templatename; - $template->contextid = $customcert->contextid; - $template = new \mod_customcert\template($template); - $filecontents = $template->generate_pdf(false, $user->id, true); + // Ensure the cert hasn't already been issued, e.g via the UI (view.php) - a race condition. + $issueid = $DB->get_field('htmlcert_issues', 'id', + array('userid' => $enroluser->id, 'htmlcertid' => $htmlcert->id), IGNORE_MULTIPLE); + if (empty($issueid)) { + // Ok, issue them the certificate. + $issueid = \mod_htmlcert\certificate::issue_certificate($htmlcert->id, $enroluser->id); + } - // Set the name of the file we are going to send. - $filename = $courseshortname . '_' . $certificatename; - $filename = \core_text::entities_to_utf8($filename); - $filename = strip_tags($filename); - $filename = rtrim($filename, '.'); - $filename = str_replace('&', '_', $filename) . '.pdf'; + // Add them to the array so we email them. + $enroluser->issueid = $issueid; + $enroluser->emailed = 0; + $issuedusers[] = $enroluser; + } - // Create the file we will be sending. - $tempfile = $tempdir . '/' . md5(microtime() . $user->id) . '.pdf'; - file_put_contents($tempfile, $filecontents); + // Remove all the users who have already been emailed. + foreach ($issuedusers as $key => $issueduser) { + if ($issueduser->emailed) { + unset($issuedusers[$key]); + } + } - if ($customcert->emailstudents) { - $renderable = new \mod_customcert\output\email_certificate(true, $userfullname, $courseshortname, - $coursefullname, $certificatename, $customcert->contextid); + // If there are no users to email we can return early. + if (!$issuedusers) { + continue; + } - $subject = get_string('emailstudentsubject', 'customcert', $info); - $message = $textrenderer->render($renderable); - $messagehtml = $htmlrenderer->render($renderable); - email_to_user($user, fullname($userfrom), html_entity_decode($subject), $message, $messagehtml, + // Create a directory to store the PDF we will be sending. + $tempdir = make_temp_directory('certificate/attachment'); + if (!$tempdir) { + return; + } + + // Now, email the people we need to. + foreach ($issuedusers as $user) { + // Set up the user. + cron_setup_user($user); + + $userfullname = fullname($user); + $info->userfullname = $userfullname; + + // Now, get the PDF. + $template = new \stdClass(); + $template->id = $htmlcert->templateid; + $template->name = $htmlcert->templatename; + $template->contextid = $htmlcert->contextid; + $template = new \mod_htmlcert\template($template); + $filecontents = $template->generate_pdf(false, $user->id, true); + + // Set the name of the file we are going to send. + $filename = $courseshortname . '_' . $certificatename; + $filename = \core_text::entities_to_utf8($filename); + $filename = strip_tags($filename); + $filename = rtrim($filename, '.'); + $filename = str_replace('&', '_', $filename) . '.pdf'; + + // Create the file we will be sending. + $tempfile = $tempdir . '/' . md5(microtime() . $user->id) . '.pdf'; + file_put_contents($tempfile, $filecontents); + + if ($htmlcert->emailstudents) { + $renderable = new \mod_htmlcert\output\email_certificate(true, $userfullname, $courseshortname, + $coursefullname, $certificatename, $htmlcert->contextid); + + $subject = get_string('emailstudentsubject', 'htmlcert', $info); + $message = $textrenderer->render($renderable); + $messagehtml = $htmlrenderer->render($renderable); + email_to_user($user, fullname($userfrom), html_entity_decode($subject), $message, $messagehtml, + $tempfile, $filename); + } + + if ($htmlcert->emailteachers) { + $renderable = new \mod_htmlcert\output\email_certificate(false, $userfullname, $courseshortname, + $coursefullname, $certificatename, $htmlcert->contextid); + + $subject = get_string('emailnonstudentsubject', 'htmlcert', $info); + $message = $textrenderer->render($renderable); + $messagehtml = $htmlrenderer->render($renderable); + foreach ($teachers as $teacher) { + email_to_user($teacher, fullname($userfrom), html_entity_decode($subject), $message, $messagehtml, $tempfile, $filename); } - - if ($customcert->emailteachers) { - $renderable = new \mod_customcert\output\email_certificate(false, $userfullname, $courseshortname, - $coursefullname, $certificatename, $customcert->contextid); - - $subject = get_string('emailnonstudentsubject', 'customcert', $info); - $message = $textrenderer->render($renderable); - $messagehtml = $htmlrenderer->render($renderable); - foreach ($teachers as $teacher) { - email_to_user($teacher, fullname($userfrom), html_entity_decode($subject), $message, $messagehtml, - $tempfile, $filename); - } - } - - if (!empty($customcert->emailothers)) { - $others = explode(',', $customcert->emailothers); - foreach ($others as $email) { - $email = trim($email); - if (validate_email($email)) { - $renderable = new \mod_customcert\output\email_certificate(false, $userfullname, - $courseshortname, $coursefullname, $certificatename, $customcert->contextid); - - $subject = get_string('emailnonstudentsubject', 'customcert', $info); - $message = $textrenderer->render($renderable); - $messagehtml = $htmlrenderer->render($renderable); - - $emailuser = new \stdClass(); - $emailuser->id = -1; - $emailuser->email = $email; - email_to_user($emailuser, fullname($userfrom), html_entity_decode($subject), $message, - $messagehtml, $tempfile, $filename); - } - } - } - - // Set the field so that it is emailed. - $DB->set_field('customcert_issues', 'emailed', 1, array('id' => $user->issueid)); } + + if (!empty($htmlcert->emailothers)) { + $others = explode(',', $htmlcert->emailothers); + foreach ($others as $email) { + $email = trim($email); + if (validate_email($email)) { + $renderable = new \mod_htmlcert\output\email_certificate(false, $userfullname, + $courseshortname, $coursefullname, $certificatename, $htmlcert->contextid); + + $subject = get_string('emailnonstudentsubject', 'htmlcert', $info); + $message = $textrenderer->render($renderable); + $messagehtml = $htmlrenderer->render($renderable); + + $emailuser = new \stdClass(); + $emailuser->id = -1; + $emailuser->email = $email; + email_to_user($emailuser, fullname($userfrom), html_entity_decode($subject), $message, + $messagehtml, $tempfile, $filename); + } + } + } + + // Set the field so that it is emailed. + $DB->set_field('htmlcert_issues', 'emailed', 1, array('id' => $user->issueid)); } } } diff --git a/classes/template.php b/classes/template.php index ded8163..59bfffd 100644 --- a/classes/template.php +++ b/classes/template.php @@ -15,22 +15,26 @@ // along with Moodle. If not, see . /** - * Class represents a customcert template. + * Class represents a htmlcert template. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; + +require_once(__DIR__ . "/../vendor/autoload.php"); + +use mikehaertl\wkhtmlto\Pdf; defined('MOODLE_INTERNAL') || die(); /** - * Class represents a customcert template. + * Class represents a htmlcert template. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class template { @@ -50,6 +54,8 @@ class template { */ protected $contextid; + protected $html; + /** * The constructor. * @@ -59,6 +65,7 @@ class template { $this->id = $template->id; $this->name = $template->name; $this->contextid = $template->contextid; + $this->html = $template->html; } /** @@ -72,74 +79,10 @@ class template { $savedata = new \stdClass(); $savedata->id = $this->id; $savedata->name = $data->name; + $savedata->html = $data->html; $savedata->timemodified = time(); - $DB->update_record('customcert_templates', $savedata); - } - - /** - * Handles adding another page to the template. - * - * @return int the id of the page - */ - public function add_page() { - global $DB; - - // Set the page number to 1 to begin with. - $sequence = 1; - // Get the max page number. - $sql = "SELECT MAX(sequence) as maxpage - FROM {customcert_pages} cp - WHERE cp.templateid = :templateid"; - if ($maxpage = $DB->get_record_sql($sql, array('templateid' => $this->id))) { - $sequence = $maxpage->maxpage + 1; - } - - // New page creation. - $page = new \stdClass(); - $page->templateid = $this->id; - $page->width = '210'; - $page->height = '297'; - $page->sequence = $sequence; - $page->timecreated = time(); - $page->timemodified = $page->timecreated; - - // Insert the page. - return $DB->insert_record('customcert_pages', $page); - } - - /** - * Handles saving page data. - * - * @param \stdClass $data the template data - */ - public function save_page($data) { - global $DB; - - // Set the time to a variable. - $time = time(); - - // Get the existing pages and save the page data. - if ($pages = $DB->get_records('customcert_pages', array('templateid' => $data->tid))) { - // Loop through existing pages. - foreach ($pages as $page) { - // Get the name of the fields we want from the form. - $width = 'pagewidth_' . $page->id; - $height = 'pageheight_' . $page->id; - $leftmargin = 'pageleftmargin_' . $page->id; - $rightmargin = 'pagerightmargin_' . $page->id; - // Create the page data to update the DB with. - $p = new \stdClass(); - $p->id = $page->id; - $p->width = $data->$width; - $p->height = $data->$height; - $p->leftmargin = $data->$leftmargin; - $p->rightmargin = $data->$rightmargin; - $p->timemodified = $time; - // Update the page. - $DB->update_record('customcert_pages', $p); - } - } + $DB->update_record('htmlcert_templates', $savedata); } /** @@ -150,101 +93,13 @@ class template { public function delete() { global $DB; - // Delete the elements. - $sql = "SELECT e.* - FROM {customcert_elements} e - INNER JOIN {customcert_pages} p - ON e.pageid = p.id - WHERE p.templateid = :templateid"; - if ($elements = $DB->get_records_sql($sql, array('templateid' => $this->id))) { - foreach ($elements as $element) { - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - $e->delete(); - } else { - // The plugin files are missing, so just remove the entry from the DB. - $DB->delete_records('customcert_elements', array('id' => $element->id)); - } - } - } - - // Delete the pages. - if (!$DB->delete_records('customcert_pages', array('templateid' => $this->id))) { - return false; - } - - // Now, finally delete the actual template. - if (!$DB->delete_records('customcert_templates', array('id' => $this->id))) { + if (!$DB->delete_records('htmlcert_templates', array('id' => $this->id))) { return false; } return true; } - /** - * Handles deleting a page from the template. - * - * @param int $pageid the template page - */ - public function delete_page($pageid) { - global $DB; - - // Get the page. - $page = $DB->get_record('customcert_pages', array('id' => $pageid), '*', MUST_EXIST); - - // Delete this page. - $DB->delete_records('customcert_pages', array('id' => $page->id)); - - // The element may have some extra tasks it needs to complete to completely delete itself. - if ($elements = $DB->get_records('customcert_elements', array('pageid' => $page->id))) { - foreach ($elements as $element) { - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - $e->delete(); - } else { - // The plugin files are missing, so just remove the entry from the DB. - $DB->delete_records('customcert_elements', array('id' => $element->id)); - } - } - } - - // Now we want to decrease the page number values of - // the pages that are greater than the page we deleted. - $sql = "UPDATE {customcert_pages} - SET sequence = sequence - 1 - WHERE templateid = :templateid - AND sequence > :sequence"; - $DB->execute($sql, array('templateid' => $this->id, 'sequence' => $page->sequence)); - } - - /** - * Handles deleting an element from the template. - * - * @param int $elementid the template page - */ - public function delete_element($elementid) { - global $DB; - - // Ensure element exists and delete it. - $element = $DB->get_record('customcert_elements', array('id' => $elementid), '*', MUST_EXIST); - - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - $e->delete(); - } else { - // The plugin files are missing, so just remove the entry from the DB. - $DB->delete_records('customcert_elements', array('id' => $elementid)); - } - - // Now we want to decrease the sequence numbers of the elements - // that are greater than the element we deleted. - $sql = "UPDATE {customcert_elements} - SET sequence = sequence - 1 - WHERE pageid = :pageid - AND sequence > :sequence"; - $DB->execute($sql, array('pageid' => $element->pageid, 'sequence' => $element->sequence)); - } - /** * Generate the PDF for the template. * @@ -262,72 +117,70 @@ class template { $user = \core_user::get_user($userid); } - require_once($CFG->libdir . '/pdflib.php'); + $htmlcert = $DB->get_record('htmlcert', ['templateid' => $this->id]); - // Get the pages for the template, there should always be at least one page for each template. - if ($pages = $DB->get_records('customcert_pages', array('templateid' => $this->id), 'sequence ASC')) { - // Create the pdf object. - $pdf = new \pdf(); + $pdf = new Pdf(array( + "disable-smart-shrinking", + "margin-bottom" => "0", + "margin-right" => "0", + "margin-left" => "0", + "margin-top" => "0" + )); - $customcert = $DB->get_record('customcert', ['templateid' => $this->id]); + $html = $this->html; - // If the template belongs to a certificate then we need to check what permissions we set for it. - if (!empty($customcert->protection)) { - $protection = explode(', ', $customcert->protection); - $pdf->SetProtection($protection); + $context = \context_user::instance($user->id); + $fs = get_file_storage(); + $files = $fs->get_area_files($context->id, 'user', 'icon', 0); + + $file = null; + + $content = ""; + foreach ($files as $filefound) { + if (!$filefound->is_directory()) { + $file = $filefound; + break; } + } - if (empty($customcert->deliveryoption)) { - $deliveryoption = certificate::DELIVERY_OPTION_INLINE; - } else { - $deliveryoption = $customcert->deliveryoption; - } + if ($file) { + $location = make_request_directory() . '/target'; + $content = $file->get_content(); + } - // Remove full-stop at the end, if it exists, to avoid "..pdf" being created and being filtered by clean_filename. - $filename = rtrim(format_string($this->name, true, ['context' => $this->get_context()]), '.'); + $html = str_replace("__PROFILEPIC__", 'data: ' . mime_content_type($file) . ';base64,' . $content, $html); - $pdf->setPrintHeader(false); - $pdf->setPrintFooter(false); - $pdf->SetTitle($filename); - $pdf->SetAutoPageBreak(true, 0); + $html = str_replace("__NAME__", $user->firstname . " " . $user->lastname, $html); - // This is the logic the TCPDF library uses when processing the name. This makes names - // such as 'الشهادة' become empty, so set a default name in these cases. - $filename = preg_replace('/[\s]+/', '_', $filename); - $filename = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $filename); + if ($preview) { + $code = \mod_htmlcert\certificate::generate_code(); + } else { + $issue = $DB->get_record('htmlcert_issues', array('userid' => $user->id, 'htmlcertid' => $htmlcert->id), + '*', IGNORE_MULTIPLE); + $code = $issue->code; + } - if (empty($filename)) { - $filename = get_string('certificate', 'customcert'); - } + $html = str_replace("__CERTNUM__", $code, $html); - $filename = clean_filename($filename . '.pdf'); - // Loop through the pages and display their content. - foreach ($pages as $page) { - // Add the page to the PDF. - if ($page->width > $page->height) { - $orientation = 'L'; - } else { - $orientation = 'P'; - } - $pdf->AddPage($orientation, array($page->width, $page->height)); - $pdf->SetMargins($page->leftmargin, 0, $page->rightmargin); - // Get the elements for the page. - if ($elements = $DB->get_records('customcert_elements', array('pageid' => $page->id), 'sequence ASC')) { - // Loop through and display. - foreach ($elements as $element) { - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - $e->render($pdf, $preview, $user); - } - } - } - } + $courseid = $htmlcert->course || $SITE->id; - if ($return) { - return $pdf->Output('', 'S'); - } + $course = get_course($courseid); + $coursename = $course->fullname; - $pdf->Output($filename, $deliveryoption); + $html = str_replace("__COURSE__", $coursename, $html); + + $date = $issue->timecreated; + + $html = str_replace("__DATE__", userdate($date, '%B %d, %Y'), $html); + + $html = str_replace("__PIN__", $user->profile["pin"], $html); + + $pdf->addPage($html); + $pdf->send(); + die($pdf->getError()); + + if ($return) { + return $pdf->toString(); } } @@ -339,78 +192,10 @@ class template { public function copy_to_template($copytotemplateid) { global $DB; - // Get the pages for the template, there should always be at least one page for each template. - if ($templatepages = $DB->get_records('customcert_pages', array('templateid' => $this->id))) { - // Loop through the pages. - foreach ($templatepages as $templatepage) { - $page = clone($templatepage); - $page->templateid = $copytotemplateid; - $page->timecreated = time(); - $page->timemodified = $page->timecreated; - // Insert into the database. - $page->id = $DB->insert_record('customcert_pages', $page); - // Now go through the elements we want to load. - if ($templateelements = $DB->get_records('customcert_elements', array('pageid' => $templatepage->id))) { - foreach ($templateelements as $templateelement) { - $element = clone($templateelement); - $element->pageid = $page->id; - $element->timecreated = time(); - $element->timemodified = $element->timecreated; - // Ok, now we want to insert this into the database. - $element->id = $DB->insert_record('customcert_elements', $element); - // Load any other information the element may need to for the template. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - if (!$e->copy_element($templateelement)) { - // Failed to copy - delete the element. - $e->delete(); - } - } - } - } - } - } - } - - /** - * Handles moving an item on a template. - * - * @param string $itemname the item we are moving - * @param int $itemid the id of the item - * @param string $direction the direction - */ - public function move_item($itemname, $itemid, $direction) { - global $DB; - - $table = 'customcert_'; - if ($itemname == 'page') { - $table .= 'pages'; - } else { // Must be an element. - $table .= 'elements'; - } - - if ($moveitem = $DB->get_record($table, array('id' => $itemid))) { - // Check which direction we are going. - if ($direction == 'up') { - $sequence = $moveitem->sequence - 1; - } else { // Must be down. - $sequence = $moveitem->sequence + 1; - } - - // Get the item we will be swapping with. Make sure it is related to the same template (if it's - // a page) or the same page (if it's an element). - if ($itemname == 'page') { - $params = array('templateid' => $moveitem->templateid); - } else { // Must be an element. - $params = array('pageid' => $moveitem->pageid); - } - $swapitem = $DB->get_record($table, $params + array('sequence' => $sequence)); - } - - // Check that there is an item to move, and an item to swap it with. - if ($moveitem && !empty($swapitem)) { - $DB->set_field($table, 'sequence', $swapitem->sequence, array('id' => $moveitem->id)); - $DB->set_field($table, 'sequence', $moveitem->sequence, array('id' => $swapitem->id)); - } + $copytotemplate = $DB->get_record('htmlcert_templates', array('id' => $copytotemplateid)); + $copytotemplate->html = $this->html; + $DB->update_record('htmlcert_templates', $copytotemplate); + } /** @@ -431,6 +216,10 @@ class template { return $this->name; } + public function get_html() { + return $this->html; + } + /** * Returns the context id. * @@ -457,7 +246,7 @@ class template { public function get_cm() { $context = $this->get_context(); if ($context->contextlevel === CONTEXT_MODULE) { - return get_coursemodule_from_id('customcert', $context->instanceid, 0, false, MUST_EXIST); + return get_coursemodule_from_id('htmlcert', $context->instanceid, 0, false, MUST_EXIST); } return null; @@ -469,7 +258,7 @@ class template { * @throws \required_capability_exception if the user does not have the necessary capabilities (ie. Fred) */ public function require_manage() { - require_capability('mod/customcert:manage', $this->get_context()); + require_capability('mod/htmlcert:manage', $this->get_context()); } /** @@ -477,7 +266,7 @@ class template { * * @param string $templatename the name of the template * @param int $contextid the context id - * @return \mod_customcert\template the template object + * @return \mod_htmlcert\template the template object */ public static function create($templatename, $contextid) { global $DB; @@ -487,8 +276,8 @@ class template { $template->contextid = $contextid; $template->timecreated = time(); $template->timemodified = $template->timecreated; - $template->id = $DB->insert_record('customcert_templates', $template); + $template->id = $DB->insert_record('htmlcert_templates', $template); - return new \mod_customcert\template($template); + return new \mod_htmlcert\template($template); } } diff --git a/classes/upload_image_form.php b/classes/upload_image_form.php index 4422897..6e6fe27 100644 --- a/classes/upload_image_form.php +++ b/classes/upload_image_form.php @@ -1,5 +1,5 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); @@ -31,7 +31,7 @@ require_once($CFG->libdir.'/formslib.php'); /** * Handles uploading files. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2013 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -51,23 +51,23 @@ class upload_image_form extends \moodleform { 'maxbytes' => $CFG->maxbytes, 'subdirs' => 1, 'accepted_types' => 'image'); - $mform->addElement('filemanager', 'customcertimage', get_string('uploadimage', 'customcert'), '', + $mform->addElement('filemanager', 'htmlcertimage', get_string('uploadimage', 'htmlcert'), '', $this->filemanageroptions); $this->add_action_buttons(); } /** - * Fill in the current page data for this customcert. + * Fill in the current page data for this htmlcert. */ public function definition_after_data() { $mform = $this->_form; // Editing existing instance - copy existing files into draft area. - $draftitemid = file_get_submitted_draft_itemid('customcertimage'); - file_prepare_draft_area($draftitemid, \context_system::instance()->id, 'mod_customcert', 'image', 0, + $draftitemid = file_get_submitted_draft_itemid('htmlcertimage'); + file_prepare_draft_area($draftitemid, \context_system::instance()->id, 'mod_htmlcert', 'image', 0, $this->filemanageroptions); - $element = $mform->getElement('customcertimage'); + $element = $mform->getElement('htmlcertimage'); $element->setValue($draftitemid); } } diff --git a/classes/verify_certificate_form.php b/classes/verify_certificate_form.php index 15ce6b8..388e251 100644 --- a/classes/verify_certificate_form.php +++ b/classes/verify_certificate_form.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace mod_customcert; +namespace mod_htmlcert; defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); @@ -31,8 +31,8 @@ require_once($CFG->libdir . '/formslib.php'); /** * The form for verifying a certificate. * - * @package mod_customcert - * @copyright 2017 Mark Nelson + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class verify_certificate_form extends \moodleform { @@ -43,10 +43,10 @@ class verify_certificate_form extends \moodleform { public function definition() { $mform =& $this->_form; - $mform->addElement('text', 'code', get_string('code', 'customcert')); + $mform->addElement('text', 'code', get_string('code', 'htmlcert')); $mform->setType('code', PARAM_ALPHANUM); - $mform->addElement('submit', 'verify', get_string('verify', 'customcert')); + $mform->addElement('submit', 'verify', get_string('verify', 'htmlcert')); } /** @@ -60,7 +60,7 @@ class verify_certificate_form extends \moodleform { $errors = array(); if ($data['code'] === '') { - $errors['code'] = get_string('invalidcode', 'customcert'); + $errors['code'] = get_string('invalidcode', 'htmlcert'); } return $errors; diff --git a/composer.json b/composer.json index f072256..ad72fe1 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,5 @@ { - "name": "mdjnelson/moodle-mod_customcert", - "type": "moodle-mod", "require": { - "composer/installers": "~1.0" - }, - "extra": { - "installer-name": "customcert" + "mikehaertl/phpwkhtmltopdf": "^2.5" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..0235af5 --- /dev/null +++ b/composer.lock @@ -0,0 +1,160 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "7f2a6587c80faa77c0f646f7f2ea6165", + "packages": [ + { + "name": "mikehaertl/php-shellcommand", + "version": "1.6.4", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-shellcommand.git", + "reference": "3488d7803df1e8f1a343d3d0ca452d527ad8d5e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-shellcommand/zipball/3488d7803df1e8f1a343d3d0ca452d527ad8d5e5", + "reference": "3488d7803df1e8f1a343d3d0ca452d527ad8d5e5", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <=9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\shellcommand\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "An object oriented interface to shell commands", + "keywords": [ + "shell" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-shellcommand/issues", + "source": "https://github.com/mikehaertl/php-shellcommand/tree/1.6.4" + }, + "time": "2021-03-17T06:54:33+00:00" + }, + { + "name": "mikehaertl/php-tmpfile", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-tmpfile.git", + "reference": "70a5b70b17bc0d9666388e6a551ecc93d0b40a10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-tmpfile/zipball/70a5b70b17bc0d9666388e6a551ecc93d0b40a10", + "reference": "70a5b70b17bc0d9666388e6a551ecc93d0b40a10", + "shasum": "" + }, + "require-dev": { + "php": ">=5.3.0", + "phpunit/phpunit": ">4.0 <=9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\tmp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A convenience class for temporary files", + "keywords": [ + "files" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-tmpfile/issues", + "source": "https://github.com/mikehaertl/php-tmpfile/tree/1.2.1" + }, + "time": "2021-03-01T18:26:25+00:00" + }, + { + "name": "mikehaertl/phpwkhtmltopdf", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/phpwkhtmltopdf.git", + "reference": "17ee71341591415d942774eda2c98d8ba7ea9e90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/phpwkhtmltopdf/zipball/17ee71341591415d942774eda2c98d8ba7ea9e90", + "reference": "17ee71341591415d942774eda2c98d8ba7ea9e90", + "shasum": "" + }, + "require": { + "mikehaertl/php-shellcommand": "^1.5.0", + "mikehaertl/php-tmpfile": "^1.2.1", + "php": ">=5.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "mikehaertl\\wkhtmlto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Haertl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A slim PHP wrapper around wkhtmltopdf with an easy to use and clean OOP interface", + "homepage": "http://mikehaertl.github.com/phpwkhtmltopdf/", + "keywords": [ + "pdf", + "wkhtmltoimage", + "wkhtmltopdf" + ], + "support": { + "issues": "https://github.com/mikehaertl/phpwkhtmltopdf/issues", + "source": "https://github.com/mikehaertl/phpwkhtmltopdf/tree/2.5.0" + }, + "time": "2021-03-01T19:41:06+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/db/access.php b/db/access.php index eaea4f8..5380b89 100644 --- a/db/access.php +++ b/db/access.php @@ -1,5 +1,5 @@ . /** - * Customcert module capability definition + * htmlcert module capability definition * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -26,7 +26,7 @@ defined('MOODLE_INTERNAL') || die(); $capabilities = array( - 'mod/customcert:addinstance' => array( + 'mod/htmlcert:addinstance' => array( 'riskbitmask' => RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, @@ -37,7 +37,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:view' => array( + 'mod/htmlcert:view' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, @@ -49,7 +49,7 @@ $capabilities = array( ) ), - 'mod/customcert:manage' => array( + 'mod/htmlcert:manage' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, @@ -60,7 +60,7 @@ $capabilities = array( ) ), - 'mod/customcert:receiveissue' => array( + 'mod/htmlcert:receiveissue' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( @@ -68,7 +68,7 @@ $capabilities = array( ) ), - 'mod/customcert:viewreport' => array( + 'mod/htmlcert:viewreport' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, @@ -79,7 +79,7 @@ $capabilities = array( ) ), - 'mod/customcert:viewallcertificates' => array( + 'mod/htmlcert:viewallcertificates' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( @@ -87,7 +87,7 @@ $capabilities = array( ) ), - 'mod/customcert:verifycertificate' => array( + 'mod/htmlcert:verifycertificate' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( @@ -97,7 +97,7 @@ $capabilities = array( ) ), - 'mod/customcert:verifyallcertificates' => array( + 'mod/htmlcert:verifyallcertificates' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( @@ -105,7 +105,7 @@ $capabilities = array( ) ), - 'mod/customcert:manageemailstudents' => array( + 'mod/htmlcert:manageemailstudents' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( @@ -115,7 +115,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:manageemailteachers' => array( + 'mod/htmlcert:manageemailteachers' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( @@ -125,7 +125,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:manageemailothers' => array( + 'mod/htmlcert:manageemailothers' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( @@ -135,7 +135,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:manageverifyany' => array( + 'mod/htmlcert:manageverifyany' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( @@ -145,7 +145,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:managerequiredtime' => array( + 'mod/htmlcert:managerequiredtime' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( @@ -155,7 +155,7 @@ $capabilities = array( 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), - 'mod/customcert:manageprotection' => array( + 'mod/htmlcert:manageprotection' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( diff --git a/db/install.xml b/db/install.xml index f6368b3..e846178 100644 --- a/db/install.xml +++ b/db/install.xml @@ -1,10 +1,10 @@ - - +
@@ -23,76 +23,36 @@ - - + +
- +
+ - +
- +
- + - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - + +
diff --git a/db/log.php b/db/log.php index 9b3790c..41a9486 100644 --- a/db/log.php +++ b/db/log.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $logs = array( - array('module' => 'customcert', 'action' => 'view', 'mtable' => 'customcert', 'field' => 'name'), - array('module' => 'customcert', 'action' => 'add', 'mtable' => 'customcert', 'field' => 'name'), - array('module' => 'customcert', 'action' => 'update', 'mtable' => 'customcert', 'field' => 'name'), - array('module' => 'customcert', 'action' => 'received', 'mtable' => 'customcert', 'field' => 'name'), + array('module' => 'htmlcert', 'action' => 'view', 'mtable' => 'htmlcert', 'field' => 'name'), + array('module' => 'htmlcert', 'action' => 'add', 'mtable' => 'htmlcert', 'field' => 'name'), + array('module' => 'htmlcert', 'action' => 'update', 'mtable' => 'htmlcert', 'field' => 'name'), + array('module' => 'htmlcert', 'action' => 'received', 'mtable' => 'htmlcert', 'field' => 'name'), ); diff --git a/db/mobile.php b/db/mobile.php index 3348dc9..58c30a2 100644 --- a/db/mobile.php +++ b/db/mobile.php @@ -17,38 +17,38 @@ /** * Defines mobile handlers. * - * @package mod_customcert - * @copyright 2018 Mark Nelson + * @package mod_htmlcert + * @copyright 2018 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $addons = [ - 'mod_customcert' => [ // Plugin identifier. + 'mod_htmlcert' => [ // Plugin identifier. 'handlers' => [ // Different places where the plugin will display content. 'issueview' => [ // Handler unique name. 'displaydata' => [ - 'icon' => $CFG->wwwroot . '/mod/customcert/pix/icon.png', - 'class' => 'core-course-module-customcert-handler', + 'icon' => $CFG->wwwroot . '/mod/htmlcert/pix/icon.png', + 'class' => 'core-course-module-htmlcert-handler', ], 'delegate' => 'CoreCourseModuleDelegate', // Delegate (where to display the link to the plugin). - 'method' => 'mobile_view_activity', // Main function in \mod_customcert\output\mobile. + 'method' => 'mobile_view_activity', // Main function in \mod_htmlcert\output\mobile. 'styles' => [ - 'url' => '/mod/customcert/mobile/styles.css', + 'url' => '/mod/htmlcert/mobile/styles.css', 'version' => 1 ] ] ], 'lang' => [ // Language strings that are used in all the handlers. - ['deleteissueconfirm', 'customcert'], - ['getcustomcert', 'customcert'], - ['listofissues', 'customcert'], + ['deleteissueconfirm', 'htmlcert'], + ['gethtmlcert', 'htmlcert'], + ['listofissues', 'htmlcert'], ['nothingtodisplay', 'moodle'], - ['notissued', 'customcert'], - ['pluginname', 'customcert'], - ['receiveddate', 'customcert'], - ['requiredtimenotmet', 'customcert'], + ['notissued', 'htmlcert'], + ['pluginname', 'htmlcert'], + ['receiveddate', 'htmlcert'], + ['requiredtimenotmet', 'htmlcert'], ['selectagroup', 'moodle'] ] ] diff --git a/db/services.php b/db/services.php index 923d842..4ed0a61 100644 --- a/db/services.php +++ b/db/services.php @@ -15,18 +15,18 @@ // along with Moodle. If not, see . /** - * Web service for mod customcert. + * Web service for mod htmlcert. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $functions = array( - 'mod_customcert_delete_issue' => array( - 'classname' => 'mod_customcert\external', + 'mod_htmlcert_delete_issue' => array( + 'classname' => 'mod_htmlcert\external', 'methodname' => 'delete_issue', 'classpath' => '', 'description' => 'Delete an issue for a certificate', @@ -34,16 +34,16 @@ $functions = array( 'ajax' => true, 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), - 'mod_customcert_save_element' => array( - 'classname' => 'mod_customcert\external', + 'mod_htmlcert_save_element' => array( + 'classname' => 'mod_htmlcert\external', 'methodname' => 'save_element', 'classpath' => '', 'description' => 'Saves data for an element', 'type' => 'write', 'ajax' => true ), - 'mod_customcert_get_element_html' => array( - 'classname' => 'mod_customcert\external', + 'mod_htmlcert_get_element_html' => array( + 'classname' => 'mod_htmlcert\external', 'methodname' => 'get_element_html', 'classpath' => '', 'description' => 'Returns the HTML to display for an element', diff --git a/db/subplugins.json b/db/subplugins.json deleted file mode 100644 index 7ce4aca..0000000 --- a/db/subplugins.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "plugintypes": { - "customcertelement": "mod\/customcert\/element" - } -} diff --git a/db/tasks.php b/db/tasks.php index 91f6e2a..f0fc409 100644 --- a/db/tasks.php +++ b/db/tasks.php @@ -15,11 +15,11 @@ // along with Moodle. If not, see . /** - * Definition of customcert scheduled tasks. + * Definition of htmlcert scheduled tasks. * - * @package mod_customcert + * @package mod_htmlcert * @category task - * @copyright 2017 Mark Nelson + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -27,7 +27,7 @@ defined('MOODLE_INTERNAL') || die(); $tasks = array( array( - 'classname' => 'mod_customcert\task\email_certificate_task', + 'classname' => 'mod_htmlcert\task\email_certificate_task', 'blocking' => 0, 'minute' => '*', 'hour' => '*', diff --git a/db/upgrade.php b/db/upgrade.php deleted file mode 100644 index 701e819..0000000 --- a/db/upgrade.php +++ /dev/null @@ -1,191 +0,0 @@ -. - -/** - * Customcert module upgrade code. - * - * @package mod_customcert - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die; - -/** - * Customcert module upgrade code. - * - * @param int $oldversion the version we are upgrading from - * @return bool always true - */ -function xmldb_customcert_upgrade($oldversion) { - global $DB; - - $dbman = $DB->get_manager(); - - if ($oldversion < 2016120503) { - - $table = new xmldb_table('customcert_templates'); - $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'id'); - $dbman->change_field_precision($table, $field); - - // Savepoint reached. - upgrade_mod_savepoint(true, 2016120503, 'customcert'); - } - - if ($oldversion < 2016120505) { - $table = new xmldb_table('customcert'); - $field = new xmldb_field('emailstudents', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'requiredtime'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - $field = new xmldb_field('emailteachers', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'emailstudents'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - $field = new xmldb_field('emailothers', XMLDB_TYPE_TEXT, null, null, null, null, null, 'emailteachers'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - $table = new xmldb_table('customcert_issues'); - $field = new xmldb_field('emailed', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'code'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - // Savepoint reached. - upgrade_mod_savepoint(true, 2016120505, 'customcert'); - } - - if ($oldversion < 2017050501) { - // Remove any duplicate rows from customcert issue table. - // This SQL fetches the id of those records which have duplicate customcert issues. - // This doesn't return the first issue. - $fromclause = "FROM ( - SELECT min(id) AS minid, userid, customcertid - FROM {customcert_issues} - GROUP BY userid, customcertid - ) minid - JOIN {customcert_issues} ci - ON ci.userid = minid.userid - AND ci.customcertid = minid.customcertid - AND ci.id > minid.minid"; - - // Get the records themselves. - $getduplicatessql = "SELECT ci.id $fromclause ORDER BY minid"; - if ($records = $DB->get_records_sql($getduplicatessql)) { - // Delete them. - $ids = implode(',', array_keys($records)); - $DB->delete_records_select('customcert_issues', "id IN ($ids)"); - } - - // Savepoint reached. - upgrade_mod_savepoint(true, 2017050501, 'customcert'); - } - - if ($oldversion < 2017050502) { - // Add column for new 'verifycertificateanyone' setting. - $table = new xmldb_table('customcert'); - $field = new xmldb_field('verifyany', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', - 'requiredtime'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - // Savepoint reached. - upgrade_mod_savepoint(true, 2017050502, 'customcert'); - } - - if ($oldversion < 2017050506) { - $table = new xmldb_table('customcert_elements'); - $field = new xmldb_field('size'); - - // Rename column as it is a reserved word in Oracle. - if ($dbman->field_exists($table, $field)) { - $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'font'); - $dbman->rename_field($table, $field, 'fontsize'); - } - - // Savepoint reached. - upgrade_mod_savepoint(true, 2017050506, 'customcert'); - } - - if ($oldversion < 2018051705) { - $table = new xmldb_table('customcert_elements'); - $field = new xmldb_field('element', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'name'); - - // Alter the 'element' column to be characters, rather than text. - $dbman->change_field_type($table, $field); - - // Savepoint reached. - upgrade_mod_savepoint(true, 2018051705, 'customcert'); - } - - if ($oldversion < 2019111803) { - $table = new xmldb_table('customcert'); - $index = new xmldb_index('templateid', XMLDB_INDEX_UNIQUE, ['templateid']); - if ($dbman->index_exists($table, $index)) { - $dbman->drop_index($table, $index); - } - $key = new xmldb_key('templateid', XMLDB_KEY_FOREIGN, ['templateid'], 'customcert_templates', ['id']); - $dbman->add_key($table, $key); - - $table = new xmldb_table('customcert_pages'); - $index = new xmldb_index('templateid', XMLDB_INDEX_UNIQUE, ['templateid']); - if ($dbman->index_exists($table, $index)) { - $dbman->drop_index($table, $index); - } - $key = new xmldb_key('templateid', XMLDB_KEY_FOREIGN, ['templateid'], 'customcert_templates', ['id']); - $dbman->add_key($table, $key); - - upgrade_mod_savepoint(true, 2019111803, 'customcert'); - } - - if ($oldversion < 2020110901) { - $table = new xmldb_table('customcert'); - $field = new xmldb_field('deliveryoption', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'verifyany'); - - // Conditionally launch add field. - if (!$dbman->field_exists($table, $field)) { - $dbman->add_field($table, $field); - } - - upgrade_mod_savepoint(true, 2020110901, 'customcert'); - } - - if ($oldversion < 2021051702) { - $table = new xmldb_table('customcert_elements'); - $field = new xmldb_field('alignment', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, 'L', 'refpoint'); - - $dbman->add_field($table, $field); - - upgrade_mod_savepoint(true, 2021051702, 'customcert'); // Replace with the actual version number. - } - - return true; -} diff --git a/edit.php b/edit.php index c84ca08..6185991 100644 --- a/edit.php +++ b/edit.php @@ -1,5 +1,5 @@ . /** - * Edit the customcert settings. + * Edit the htmlcert settings. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -34,26 +34,26 @@ $confirm = optional_param('confirm', 0, PARAM_INT); // Edit an existing template. if ($tid) { // Create the template object. - $template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); - $template = new \mod_customcert\template($template); + $template = $DB->get_record('htmlcert_templates', array('id' => $tid), '*', MUST_EXIST); + $template = new \mod_htmlcert\template($template); // Set the context. $contextid = $template->get_contextid(); // Set the page url. - $pageurl = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); + $pageurl = new moodle_url('/mod/htmlcert/edit.php', array('tid' => $tid)); } else { // Adding a new template. // Need to supply the contextid. $contextid = required_param('contextid', PARAM_INT); // Set the page url. - $pageurl = new moodle_url('/mod/customcert/edit.php', array('contextid' => $contextid)); + $pageurl = new moodle_url('/mod/htmlcert/edit.php', array('contextid' => $contextid)); } $context = context::instance_by_id($contextid); if ($context->contextlevel == CONTEXT_MODULE) { - $cm = get_coursemodule_from_id('customcert', $context->instanceid, 0, false, MUST_EXIST); + $cm = get_coursemodule_from_id('htmlcert', $context->instanceid, 0, false, MUST_EXIST); require_login($cm->course, false, $cm); - $customcert = $DB->get_record('customcert', ['id' => $cm->instance], '*', MUST_EXIST); - $title = $customcert->name; + $htmlcert = $DB->get_record('htmlcert', ['id' => $cm->instance], '*', MUST_EXIST); + $title = $htmlcert->name; $heading = format_string($title); } else { require_login(); @@ -61,173 +61,40 @@ if ($context->contextlevel == CONTEXT_MODULE) { $heading = $title; } -require_capability('mod/customcert:manage', $context); +require_capability('mod/htmlcert:manage', $context); // Set up the page. -\mod_customcert\page_helper::page_setup($pageurl, $context, $title); +\mod_htmlcert\page_helper::page_setup($pageurl, $context, $title); if ($context->contextlevel == CONTEXT_SYSTEM) { // We are managing a template - add some navigation. - $PAGE->navbar->add(get_string('managetemplates', 'customcert'), - new moodle_url('/mod/customcert/manage_templates.php')); + $PAGE->navbar->add(get_string('managetemplates', 'htmlcert'), + new moodle_url('/mod/htmlcert/manage_templates.php')); if (!$tid) { - $PAGE->navbar->add(get_string('editcustomcert', 'customcert')); + $PAGE->navbar->add(get_string('edithtmlcert', 'htmlcert')); } else { - $PAGE->navbar->add(get_string('editcustomcert', 'customcert'), - new moodle_url('/mod/customcert/edit.php', ['tid' => $tid])); + $PAGE->navbar->add(get_string('edithtmlcert', 'htmlcert'), + new moodle_url('/mod/htmlcert/edit.php', ['tid' => $tid])); } } -// Flag to determine if we are deleting anything. -$deleting = false; - if ($tid) { - if ($action && confirm_sesskey()) { - switch ($action) { - case 'pmoveup' : - $template->move_item('page', $actionid, 'up'); - break; - case 'pmovedown' : - $template->move_item('page', $actionid, 'down'); - break; - case 'emoveup' : - $template->move_item('element', $actionid, 'up'); - break; - case 'emovedown' : - $template->move_item('element', $actionid, 'down'); - break; - case 'addpage' : - $template->add_page(); - $url = new \moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - redirect($url); - break; - case 'deletepage' : - if (!empty($confirm)) { // Check they have confirmed the deletion. - $template->delete_page($actionid); - $url = new \moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - redirect($url); - } else { - // Set deletion flag to true. - $deleting = true; - // Create the message. - $message = get_string('deletepageconfirm', 'customcert'); - // Create the link options. - $nourl = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - $yesurl = new moodle_url('/mod/customcert/edit.php', - array( - 'tid' => $tid, - 'action' => 'deletepage', - 'aid' => $actionid, - 'confirm' => 1, - 'sesskey' => sesskey() - ) - ); - } - break; - case 'deleteelement' : - if (!empty($confirm)) { // Check they have confirmed the deletion. - $template->delete_element($actionid); - } else { - // Set deletion flag to true. - $deleting = true; - // Create the message. - $message = get_string('deleteelementconfirm', 'customcert'); - // Create the link options. - $nourl = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - $yesurl = new moodle_url('/mod/customcert/edit.php', - array( - 'tid' => $tid, - 'action' => 'deleteelement', - 'aid' => $actionid, - 'confirm' => 1, - 'sesskey' => sesskey() - ) - ); - } - break; - } - } -} - -// Check if we are deleting either a page or an element. -if ($deleting) { - // Show a confirmation page. - $PAGE->navbar->add(get_string('deleteconfirm', 'customcert')); - echo $OUTPUT->header(); - echo $OUTPUT->heading($heading); - echo $OUTPUT->confirm($message, $yesurl, $nourl); - echo $OUTPUT->footer(); - exit(); -} - -if ($tid) { - $mform = new \mod_customcert\edit_form($pageurl, array('tid' => $tid)); + $mform = new \mod_htmlcert\edit_form($pageurl, array('tid' => $tid)); // Set the name for the form. $mform->set_data(array('name' => $template->get_name())); } else { - $mform = new \mod_customcert\edit_form($pageurl); + $mform = new \mod_htmlcert\edit_form($pageurl); } if ($data = $mform->get_data()) { // If there is no id, then we are creating a template. if (!$tid) { - $template = \mod_customcert\template::create($data->name, $contextid); - - // Create a page for this template. - $pageid = $template->add_page(); - - // Associate all the data from the form to the newly created page. - $width = 'pagewidth_' . $pageid; - $height = 'pageheight_' . $pageid; - $leftmargin = 'pageleftmargin_' . $pageid; - $rightmargin = 'pagerightmargin_' . $pageid; - $rightmargin = 'pagerightmargin_' . $pageid; - - $data->$width = $data->pagewidth_0; - $data->$height = $data->pageheight_0; - $data->$leftmargin = $data->pageleftmargin_0; - $data->$rightmargin = $data->pagerightmargin_0; - - // We may also have clicked to add an element, so these need changing as well. - if (isset($data->element_0) && isset($data->addelement_0)) { - $element = 'element_' . $pageid; - $addelement = 'addelement_' . $pageid; - $data->$element = $data->element_0; - $data->$addelement = $data->addelement_0; - - // Need to remove the temporary element and add element placeholders so we - // don't try add an element to the wrong page. - unset($data->element_0); - unset($data->addelement_0); - } + $template = \mod_htmlcert\template::create($data->name, $contextid); } // Save any data for the template. $template->save($data); - // Save any page data. - $template->save_page($data); - - // Loop through the data. - foreach ($data as $key => $value) { - // Check if they chose to add an element to a page. - if (strpos($key, 'addelement_') !== false) { - // Get the page id. - $pageid = str_replace('addelement_', '', $key); - // Get the element. - $element = "element_" . $pageid; - $element = $data->$element; - // Create the URL to redirect to to add this element. - $params = array(); - $params['tid'] = $template->get_id(); - $params['action'] = 'add'; - $params['element'] = $element; - $params['pageid'] = $pageid; - $url = new moodle_url('/mod/customcert/edit_element.php', $params); - redirect($url); - } - } - // Check if we want to preview this custom certificate. if (!empty($data->previewbtn)) { $template->generate_pdf(true); @@ -235,7 +102,7 @@ if ($data = $mform->get_data()) { } // Redirect to the editing page to show form with recent updates. - $url = new moodle_url('/mod/customcert/edit.php', array('tid' => $template->get_id())); + $url = new moodle_url('/mod/htmlcert/edit.php', array('tid' => $template->get_id())); redirect($url); } @@ -243,8 +110,8 @@ echo $OUTPUT->header(); echo $OUTPUT->heading($heading); $mform->display(); if ($tid && $context->contextlevel == CONTEXT_MODULE) { - $loadtemplateurl = new moodle_url('/mod/customcert/load_template.php', array('tid' => $tid)); - $loadtemplateform = new \mod_customcert\load_template_form($loadtemplateurl, array('context' => $context), 'post', + $loadtemplateurl = new moodle_url('/mod/htmlcert/load_template.php', array('tid' => $tid)); + $loadtemplateform = new \mod_htmlcert\load_template_form($loadtemplateurl, array('context' => $context), 'post', '', array('id' => 'loadtemplateform')); $loadtemplateform->display(); } diff --git a/edit_element.php b/edit_element.php deleted file mode 100644 index e8aba70..0000000 --- a/edit_element.php +++ /dev/null @@ -1,108 +0,0 @@ -. - -/** - * Edit a customcert element. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once('../../config.php'); - -$tid = required_param('tid', PARAM_INT); -$action = required_param('action', PARAM_ALPHA); - -$template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); - -// Set the template object. -$template = new \mod_customcert\template($template); - -// Perform checks. -if ($cm = $template->get_cm()) { - require_login($cm->course, false, $cm); -} else { - require_login(); -} -// Make sure the user has the required capabilities. -$template->require_manage(); - -if ($template->get_context()->contextlevel == CONTEXT_MODULE) { - $customcert = $DB->get_record('customcert', ['id' => $cm->instance], '*', MUST_EXIST); - $title = $customcert->name; - $heading = format_string($title); -} else { - $title = $SITE->fullname; - $heading = $title; -} - -if ($action == 'edit') { - // The id of the element must be supplied if we are currently editing one. - $id = required_param('id', PARAM_INT); - $element = $DB->get_record('customcert_elements', array('id' => $id), '*', MUST_EXIST); - $pageurl = new moodle_url('/mod/customcert/edit_element.php', array('id' => $id, 'tid' => $tid, 'action' => $action)); -} else { // Must be adding an element. - // We need to supply what element we want added to what page. - $pageid = required_param('pageid', PARAM_INT); - $element = new stdClass(); - $element->element = required_param('element', PARAM_ALPHA); - $pageurl = new moodle_url('/mod/customcert/edit_element.php', array('tid' => $tid, 'element' => $element->element, - 'pageid' => $pageid, 'action' => $action)); -} - -// Set up the page. -\mod_customcert\page_helper::page_setup($pageurl, $template->get_context(), $title); - -// Additional page setup. -if ($template->get_context()->contextlevel == CONTEXT_SYSTEM) { - $PAGE->navbar->add(get_string('managetemplates', 'customcert'), - new moodle_url('/mod/customcert/manage_templates.php')); -} -$PAGE->navbar->add(get_string('editcustomcert', 'customcert'), new moodle_url('/mod/customcert/edit.php', - array('tid' => $tid))); -$PAGE->navbar->add(get_string('editelement', 'customcert')); - -$mform = new \mod_customcert\edit_element_form($pageurl, array('element' => $element)); - -// Check if they cancelled. -if ($mform->is_cancelled()) { - $url = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - redirect($url); -} - -if ($data = $mform->get_data()) { - // Set the id, or page id depending on if we are editing an element, or adding a new one. - if ($action == 'edit') { - $data->id = $id; - } else { - $data->pageid = $pageid; - } - // Set the element variable. - $data->element = $element->element; - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($data)) { - $e->save_form_elements($data); - } - - $url = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); - redirect($url); -} - -echo $OUTPUT->header(); -echo $OUTPUT->heading($heading); -$mform->display(); -echo $OUTPUT->footer(); diff --git a/element/bgimage/classes/element.php b/element/bgimage/classes/element.php deleted file mode 100644 index a4c36e8..0000000 --- a/element/bgimage/classes/element.php +++ /dev/null @@ -1,130 +0,0 @@ -. - -/** - * This file contains the customcert element background image's core interaction API. - * - * @package customcertelement_bgimage - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_bgimage; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element background image's core interaction API. - * - * @package customcertelement_bgimage - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \customcertelement_image\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('select', 'fileid', get_string('image', 'customcertelement_image'), self::get_images()); - $mform->addElement('filemanager', 'customcertimage', get_string('uploadimage', 'customcert'), '', - $this->filemanageroptions); - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - return array(); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - // If there is no file, we have nothing to display. - if (empty($imageinfo->filename)) { - return; - } - - if ($file = $this->get_file()) { - $location = make_request_directory() . '/target'; - $file->copy_content_to($location); - - // Set the image to the size of the PDF page. - $mimetype = $file->get_mimetype(); - if ($mimetype == 'image/svg+xml') { - $pdf->ImageSVG($location, 0, 0, $pdf->getPageWidth(), $pdf->getPageHeight()); - } else { - $pdf->Image($location, 0, 0, $pdf->getPageWidth(), $pdf->getPageHeight()); - } - } - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - global $DB; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return ''; - } - - $imageinfo = json_decode($this->get_data()); - - // If there is no file, we have nothing to display. - if (empty($imageinfo->filename)) { - return ''; - } - - if ($file = $this->get_file()) { - $url = \moodle_url::make_pluginfile_url($file->get_contextid(), 'mod_customcert', 'image', $file->get_itemid(), - $file->get_filepath(), $file->get_filename()); - // Get the page we are rendering this on. - $page = $DB->get_record('customcert_pages', array('id' => $this->get_pageid()), '*', MUST_EXIST); - - // Set the image to the size of the page. - $style = 'width: ' . $page->width . 'mm; height: ' . $page->height . 'mm'; - return \html_writer::tag('img', '', array('src' => $url, 'style' => $style)); - } - } -} - diff --git a/element/bgimage/classes/privacy/provider.php b/element/bgimage/classes/privacy/provider.php deleted file mode 100644 index 61a2082..0000000 --- a/element/bgimage/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_bgimage. - * - * @package customcertelement_bgimage - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_bgimage\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_bgimage implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/bgimage/db/upgrade.php b/element/bgimage/db/upgrade.php deleted file mode 100644 index 900c24e..0000000 --- a/element/bgimage/db/upgrade.php +++ /dev/null @@ -1,66 +0,0 @@ -. - -/** - * Customcert background image element upgrade code. - * - * @package customcertelement_bgimage - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die; - -/** - * Customcert background image element upgrade code. - * - * @param int $oldversion the version we are upgrading from - * @return bool always true - */ -function xmldb_customcertelement_bgimage_upgrade($oldversion) { - global $DB; - - if ($oldversion < 2016120501) { - // Go through each 'image' element and update the file stored information. - if ($images = $DB->get_records_select('customcert_elements', $DB->sql_compare_text('element') . ' = \'bgimage\'')) { - // Create a file storage instance we are going to use to create pathname hashes. - $fs = get_file_storage(); - // Go through and update the details. - foreach ($images as $image) { - // Get the current data we have stored for this element. - $elementinfo = json_decode($image->data); - if ($file = $fs->get_file_by_hash($elementinfo->pathnamehash)) { - $arrtostore = array( - 'contextid' => $file->get_contextid(), - 'filearea' => $file->get_filearea(), - 'itemid' => $file->get_itemid(), - 'filepath' => $file->get_filepath(), - 'filename' => $file->get_filename(), - 'width' => (int) $elementinfo->width, - 'height' => (int) $elementinfo->height - ); - $arrtostore = json_encode($arrtostore); - $DB->set_field('customcert_elements', 'data', $arrtostore, array('id' => $image->id)); - } - } - } - - // Savepoint reached. - upgrade_plugin_savepoint(true, 2016120501, 'customcertelement', 'bgimage'); - } - - return true; -} diff --git a/element/bgimage/lang/en/customcertelement_bgimage.php b/element/bgimage/lang/en/customcertelement_bgimage.php deleted file mode 100644 index 467bfa2..0000000 --- a/element/bgimage/lang/en/customcertelement_bgimage.php +++ /dev/null @@ -1,26 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_bgimage', language 'en'. - * - * @package customcertelement_bgimage - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Background image'; -$string['privacy:metadata'] = 'The Background image plugin does not store any personal data.'; diff --git a/element/bgimage/version.php b/element/bgimage/version.php deleted file mode 100644 index 7466f20..0000000 --- a/element/bgimage/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the background image plugin. - * - * @package customcertelement_bgimage - * @copyright 2016 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_bgimage'; diff --git a/element/border/classes/element.php b/element/border/classes/element.php deleted file mode 100644 index a33f831..0000000 --- a/element/border/classes/element.php +++ /dev/null @@ -1,126 +0,0 @@ -. - -/** - * This file contains the customcert element border's core interaction API. - * - * @package customcertelement_border - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_border; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element border's core interaction API. - * - * @package customcertelement_border - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - // We want to define the width of the border. - $mform->addElement('text', 'width', get_string('width', 'customcertelement_border'), array('size' => 10)); - $mform->setType('width', PARAM_INT); - $mform->addHelpButton('width', 'width', 'customcertelement_border'); - - // The only other thing to define is the colour we want the border to be. - \mod_customcert\element_helper::render_form_element_colour($mform); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - $colour = \TCPDF_COLORS::convertHTMLColorToDec($this->get_colour(), $colour); - $pdf->SetLineStyle(array('width' => $this->get_data(), 'color' => $colour)); - $pdf->Line(0, 0, $pdf->getPageWidth(), 0); - $pdf->Line($pdf->getPageWidth(), 0, $pdf->getPageWidth(), $pdf->getPageHeight()); - $pdf->Line(0, $pdf->getPageHeight(), $pdf->getPageWidth(), $pdf->getPageHeight()); - $pdf->Line(0, 0, 0, $pdf->getPageHeight()); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - return ''; - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - $errors = array(); - - // Check if width is not set, or not numeric or less than 0. - if ((!isset($data['width'])) || (!is_numeric($data['width'])) || ($data['width'] <= 0)) { - $errors['width'] = get_string('invalidwidth', 'customcertelement_border'); - } - - // Validate the colour. - $errors += \mod_customcert\element_helper::validate_form_element_colour($data); - - return $errors; - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('width'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - return $data->width; - } -} diff --git a/element/border/classes/privacy/provider.php b/element/border/classes/privacy/provider.php deleted file mode 100644 index 0aa2b0a..0000000 --- a/element/border/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_border. - * - * @package customcertelement_border - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_border\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_border implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/border/lang/en/customcertelement_border.php b/element/border/lang/en/customcertelement_border.php deleted file mode 100644 index b3e6aed..0000000 --- a/element/border/lang/en/customcertelement_border.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_border', language 'en'. - * - * @package customcertelement_border - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Border'; -$string['privacy:metadata'] = 'The Border plugin does not store any personal data.'; -$string['invalidwidth'] = 'The width has to be a valid number greater than 0.'; -$string['width'] = 'Width'; -$string['width_help'] = 'Width of the border in mm.'; diff --git a/element/border/version.php b/element/border/version.php deleted file mode 100644 index ff6839f..0000000 --- a/element/border/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the border plugin. - * - * @package customcertelement_border - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_border'; diff --git a/element/categoryname/classes/element.php b/element/categoryname/classes/element.php deleted file mode 100644 index 48d1578..0000000 --- a/element/categoryname/classes/element.php +++ /dev/null @@ -1,82 +0,0 @@ -. - -/** - * This file contains the customcert element categoryname's core interaction API. - * - * @package customcertelement_categoryname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_categoryname; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element categoryname's core interaction API. - * - * @package customcertelement_categoryname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_category_name()); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - return \mod_customcert\element_helper::render_html_content($this, $this->get_category_name()); - } - - /** - * Helper function that returns the category name. - * - * @return string - */ - protected function get_category_name() : string { - global $DB, $SITE; - - $courseid = \mod_customcert\element_helper::get_courseid($this->get_id()); - $course = get_course($courseid); - $context = \mod_customcert\element_helper::get_context($this->get_id()); - - // Check that there is a course category available. - if (!empty($course->category)) { - $categoryname = $DB->get_field('course_categories', 'name', array('id' => $course->category), MUST_EXIST); - } else { // Must be in a site template. - $categoryname = $SITE->fullname; - } - - return format_string($categoryname, true, ['context' => $context]); - } -} diff --git a/element/categoryname/classes/privacy/provider.php b/element/categoryname/classes/privacy/provider.php deleted file mode 100644 index bcdb8a7..0000000 --- a/element/categoryname/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_categoryname. - * - * @package customcertelement_categoryname - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_categoryname\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_categoryname implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/categoryname/lang/en/customcertelement_categoryname.php b/element/categoryname/lang/en/customcertelement_categoryname.php deleted file mode 100644 index a3c444d..0000000 --- a/element/categoryname/lang/en/customcertelement_categoryname.php +++ /dev/null @@ -1,26 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_categoryname', language 'en'. - * - * @package customcertelement_categoryname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Category name'; -$string['privacy:metadata'] = 'The Category name plugin does not store any personal data.'; diff --git a/element/categoryname/version.php b/element/categoryname/version.php deleted file mode 100644 index c921e43..0000000 --- a/element/categoryname/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the categoryname plugin. - * - * @package customcertelement_categoryname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_categoryname'; diff --git a/element/code/classes/element.php b/element/code/classes/element.php deleted file mode 100644 index 0dcb3d2..0000000 --- a/element/code/classes/element.php +++ /dev/null @@ -1,77 +0,0 @@ -. - -/** - * This file contains the customcert element code's core interaction API. - * - * @package customcertelement_code - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_code; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element code's core interaction API. - * - * @package customcertelement_code - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $DB; - - if ($preview) { - $code = \mod_customcert\certificate::generate_code(); - } else { - // Get the page. - $page = $DB->get_record('customcert_pages', array('id' => $this->get_pageid()), '*', MUST_EXIST); - // Get the customcert this page belongs to. - $customcert = $DB->get_record('customcert', array('templateid' => $page->templateid), '*', MUST_EXIST); - // Now we can get the issue for this user. - $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $customcert->id), - '*', IGNORE_MULTIPLE); - $code = $issue->code; - } - - \mod_customcert\element_helper::render_content($pdf, $this, $code); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - $code = \mod_customcert\certificate::generate_code(); - - return \mod_customcert\element_helper::render_html_content($this, $code); - } -} diff --git a/element/code/classes/privacy/provider.php b/element/code/classes/privacy/provider.php deleted file mode 100644 index cbdbb50..0000000 --- a/element/code/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_code. - * - * @package customcertelement_code - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_code\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_code implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/code/lang/en/customcertelement_code.php b/element/code/lang/en/customcertelement_code.php deleted file mode 100644 index e67616c..0000000 --- a/element/code/lang/en/customcertelement_code.php +++ /dev/null @@ -1,26 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_code', language 'en'. - * - * @package customcertelement_code - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Code'; -$string['privacy:metadata'] = 'The Code plugin does not store any personal data.'; diff --git a/element/code/version.php b/element/code/version.php deleted file mode 100644 index 67f6d5d..0000000 --- a/element/code/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the code plugin. - * - * @package customcertelement_code - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_code'; diff --git a/element/coursefield/classes/element.php b/element/coursefield/classes/element.php deleted file mode 100644 index 71e3f21..0000000 --- a/element/coursefield/classes/element.php +++ /dev/null @@ -1,154 +0,0 @@ -. - -/** - * This file contains the customcert element coursefield's core interaction API. - * - * @package customcertelement_coursefield - * @copyright 2019 Catalyst IT - * @author Dan Marsden - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_coursefield; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element coursefield's core interaction API. - * - * @package customcertelement_coursefield - * @copyright 2019 Catalyst IT - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit form instance - */ - public function render_form_elements($mform) { - // Get the user profile fields. - $coursefields = array( - 'fullname' => get_string('fullnamecourse'), - 'shortname' => get_string('shortnamecourse'), - 'idnumber' => get_string('idnumbercourse') - ); - // Get the course custom fields. - $arrcustomfields = array(); - $handler = \core_course\customfield\course_handler::create(); - $customfields = $handler->get_fields(); - - foreach ($customfields as $field) { - $arrcustomfields[$field->get('id')] = $field->get_formatted_name(); - } - - // Combine the two. - $fields = $coursefields + $arrcustomfields; - \core_collator::asort($fields); - - // Create the select box where the user field is selected. - $mform->addElement('select', 'coursefield', get_string('coursefield', 'customcertelement_coursefield'), $fields); - $mform->setType('coursefield', PARAM_ALPHANUM); - $mform->addHelpButton('coursefield', 'coursefield', 'customcertelement_coursefield'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - return $data->coursefield; - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - - $courseid = \mod_customcert\element_helper::get_courseid($this->id); - $course = get_course($courseid); - - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_course_field_value($course, $preview)); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - */ - public function render_html() { - global $COURSE; - - return \mod_customcert\element_helper::render_html_content($this, $this->get_course_field_value($COURSE, true)); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('coursefield'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * Helper function that returns the field value in a human-readable format. - * - * @param \stdClass $course the course we are rendering this for - * @param bool $preview Is this a preview? - * @return string - */ - protected function get_course_field_value(\stdClass $course, bool $preview) : string { - - // The user field to display. - $field = $this->get_data(); - // The value to display - we always want to show a value here so it can be repositioned. - if ($preview) { - $value = $field; - } else { - $value = ''; - } - if (is_number($field)) { // Must be a custom course profile field. - $handler = \core_course\customfield\course_handler::create(); - $data = $handler->get_instance_data($course->id, true); - if (!empty($data[$field])) { - $value = $data[$field]->export_value(); - } - - } else if (!empty($course->$field)) { // Field in the course table. - $value = $course->$field; - } - - $context = \mod_customcert\element_helper::get_context($this->get_id()); - return format_string($value, true, ['context' => $context]); - } -} diff --git a/element/coursefield/classes/privacy/provider.php b/element/coursefield/classes/privacy/provider.php deleted file mode 100644 index ee8fdd4..0000000 --- a/element/coursefield/classes/privacy/provider.php +++ /dev/null @@ -1,47 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_coursefield. - * - * @package customcertelement_coursefield - * @copyright 2019 Catalyst IT - * @author Dan Marsden - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_coursefield\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_coursefield implementing null_provider. - * - * @copyright 2019 Catalyst IT - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/coursefield/lang/en/customcertelement_coursefield.php b/element/coursefield/lang/en/customcertelement_coursefield.php deleted file mode 100644 index 62420b7..0000000 --- a/element/coursefield/lang/en/customcertelement_coursefield.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_coursefield', language 'en'. - * - * @package customcertelement_coursefield - * @copyright 2019 Catalyst IT - * @author Dan Marsden - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Course field'; -$string['privacy:metadata'] = 'The course field plugin does not store any personal data.'; -$string['coursefield'] = 'Course field'; -$string['coursefield_help'] = 'This is the course field that will be displayed on the PDF.'; diff --git a/element/coursefield/version.php b/element/coursefield/version.php deleted file mode 100644 index 93d123c..0000000 --- a/element/coursefield/version.php +++ /dev/null @@ -1,30 +0,0 @@ -. - -/** - * This file contains the version information for the coursefield plugin. - * - * @package customcertelement_coursefield - * @copyright 2019 Catalyst IT - * @author Dan Marsden - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_coursefield'; diff --git a/element/coursename/classes/element.php b/element/coursename/classes/element.php deleted file mode 100644 index a5b274d..0000000 --- a/element/coursename/classes/element.php +++ /dev/null @@ -1,142 +0,0 @@ -. - -/** - * This file contains the customcert element coursename's core interaction API. - * - * @package customcertelement_coursename - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_coursename; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element coursename's core interaction API. - * - * @package customcertelement_coursename - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * The course short name. - */ - const COURSE_SHORT_NAME = 1; - - /** - * The course fullname. - */ - const COURSE_FULL_NAME = 2; - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - // The course name display options. - $mform->addElement('select', 'coursenamedisplay', get_string('coursenamedisplay', 'customcertelement_coursename'), - self::get_course_name_display_options()); - $mform->setType('coursenamedisplay', PARAM_INT); - $mform->addHelpButton('coursenamedisplay', 'coursenamedisplay', 'customcertelement_coursename'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - return $data->coursenamedisplay; - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_course_name_detail()); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - return \mod_customcert\element_helper::render_html_content($this, $this->get_course_name_detail()); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('coursenamedisplay'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * Helper function that returns the selected course name detail (i.e. name or short description) for display. - * - * @return string - */ - protected function get_course_name_detail(): string { - $courseid = \mod_customcert\element_helper::get_courseid($this->get_id()); - $course = get_course($courseid); - $context = \mod_customcert\element_helper::get_context($this->get_id()); - - // The name field to display. - $field = $this->get_data(); - // The name value to display. - $value = $course->fullname; - if ($field == self::COURSE_SHORT_NAME) { - $value = $course->shortname; - } - - return format_string($value, true, ['context' => $context]); - } - - /** - * Helper function to return all the possible name display options. - * - * @return array returns an array of name options - */ - public static function get_course_name_display_options(): array { - return [ - self::COURSE_FULL_NAME => get_string('coursefullname', 'customcertelement_coursename'), - self::COURSE_SHORT_NAME => get_string('courseshortname', 'customcertelement_coursename') - ]; - } -} diff --git a/element/coursename/classes/privacy/provider.php b/element/coursename/classes/privacy/provider.php deleted file mode 100644 index 1c2d02a..0000000 --- a/element/coursename/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_coursename. - * - * @package customcertelement_coursename - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_coursename\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_coursename implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/coursename/lang/en/customcertelement_coursename.php b/element/coursename/lang/en/customcertelement_coursename.php deleted file mode 100644 index d6b80d3..0000000 --- a/element/coursename/lang/en/customcertelement_coursename.php +++ /dev/null @@ -1,31 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_coursename', language 'en'. - * - * @package customcertelement_coursename - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['coursenamedisplay'] = 'Type'; -$string['coursenamedisplay_help'] = 'Display the course full name or short name?'; -$string['coursefullname'] = 'Full name'; -$string['courseshortname'] = 'Short name'; -$string['pluginname'] = 'Course name'; -$string['privacy:metadata'] = 'The Course name plugin does not store any personal data.'; - diff --git a/element/coursename/version.php b/element/coursename/version.php deleted file mode 100644 index 5e8bfc2..0000000 --- a/element/coursename/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the coursename plugin. - * - * @package customcertelement_coursename - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_coursename'; diff --git a/element/date/classes/element.php b/element/date/classes/element.php deleted file mode 100644 index 5c0fb45..0000000 --- a/element/date/classes/element.php +++ /dev/null @@ -1,409 +0,0 @@ -. - -/** - * This file contains the customcert element date's core interaction API. - * - * @package customcertelement_date - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_date; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Date - Course grade date - */ -define('CUSTOMCERT_DATE_COURSE_GRADE', '0'); - -/** - * Date - Issue - */ -define('CUSTOMCERT_DATE_ISSUE', '-1'); - -/** - * Date - Completion - */ -define('CUSTOMCERT_DATE_COMPLETION', '-2'); - -/** - * Date - Course start - */ -define('CUSTOMCERT_DATE_COURSE_START', '-3'); - -/** - * Date - Course end - */ -define('CUSTOMCERT_DATE_COURSE_END', '-4'); - -/** - * Date - Current date - */ -define('CUSTOMCERT_DATE_CURRENT_DATE', '-5'); - -/** - * Date - Enrollment start - */ -define('CUSTOMCERT_DATE_ENROLMENT_START', '-6'); - -/** - * Date - Entrollment end - */ -define('CUSTOMCERT_DATE_ENROLMENT_END', '-7'); - -require_once($CFG->dirroot . '/lib/grade/constants.php'); - -/** - * The customcert element date's core interaction API. - * - * @package customcertelement_date - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - global $CFG, $COURSE; - - // Get the possible date options. - $dateoptions = array(); - $dateoptions[CUSTOMCERT_DATE_ISSUE] = get_string('issueddate', 'customcertelement_date'); - $dateoptions[CUSTOMCERT_DATE_CURRENT_DATE] = get_string('currentdate', 'customcertelement_date'); - $completionenabled = $CFG->enablecompletion && ($COURSE->id == SITEID || $COURSE->enablecompletion); - if ($completionenabled) { - $dateoptions[CUSTOMCERT_DATE_COMPLETION] = get_string('completiondate', 'customcertelement_date'); - } - $dateoptions[CUSTOMCERT_DATE_ENROLMENT_START] = get_string('enrolmentstartdate', 'customcertelement_date'); - $dateoptions[CUSTOMCERT_DATE_ENROLMENT_END] = get_string('enrolmentenddate', 'customcertelement_date'); - - $dateoptions[CUSTOMCERT_DATE_COURSE_START] = get_string('coursestartdate', 'customcertelement_date'); - $dateoptions[CUSTOMCERT_DATE_COURSE_END] = get_string('courseenddate', 'customcertelement_date'); - $dateoptions[CUSTOMCERT_DATE_COURSE_GRADE] = get_string('coursegradedate', 'customcertelement_date'); - $dateoptions = $dateoptions + \mod_customcert\element_helper::get_grade_items($COURSE); - - $mform->addElement('select', 'dateitem', get_string('dateitem', 'customcertelement_date'), $dateoptions); - $mform->addHelpButton('dateitem', 'dateitem', 'customcertelement_date'); - - $mform->addElement('select', 'dateformat', get_string('dateformat', 'customcertelement_date'), self::get_date_formats()); - $mform->addHelpButton('dateformat', 'dateformat', 'customcertelement_date'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - // Array of data we will be storing in the database. - $arrtostore = array( - 'dateitem' => $data->dateitem, - 'dateformat' => $data->dateformat - ); - - // Encode these variables before saving into the DB. - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $DB; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $courseid = \mod_customcert\element_helper::get_courseid($this->id); - - // Decode the information stored in the database. - $dateinfo = json_decode($this->get_data()); - $dateitem = $dateinfo->dateitem; - $dateformat = $dateinfo->dateformat; - - // If we are previewing this certificate then just show a demonstration date. - if ($preview) { - $date = time(); - } else { - // Get the page. - $page = $DB->get_record('customcert_pages', array('id' => $this->get_pageid()), '*', MUST_EXIST); - // Get the customcert this page belongs to. - $customcert = $DB->get_record('customcert', array('templateid' => $page->templateid), '*', MUST_EXIST); - // Now we can get the issue for this user. - $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $customcert->id), - '*', IGNORE_MULTIPLE); - - if ($dateitem == CUSTOMCERT_DATE_ISSUE) { - $date = $issue->timecreated; - } else if ($dateitem == CUSTOMCERT_DATE_CURRENT_DATE) { - $date = time(); - } else if ($dateitem == CUSTOMCERT_DATE_COMPLETION) { - // Get the last completion date. - $sql = "SELECT MAX(c.timecompleted) as timecompleted - FROM {course_completions} c - WHERE c.userid = :userid - AND c.course = :courseid"; - if ($timecompleted = $DB->get_record_sql($sql, array('userid' => $issue->userid, 'courseid' => $courseid))) { - if (!empty($timecompleted->timecompleted)) { - $date = $timecompleted->timecompleted; - } - } - } else if ($dateitem == CUSTOMCERT_DATE_ENROLMENT_START) { - // Get the enrolment start date. - $sql = "SELECT ue.timestart FROM {enrol} e JOIN {user_enrolments} ue ON ue.enrolid = e.id - WHERE e.courseid = :courseid - AND ue.userid = :userid"; - if ($timestart = $DB->get_record_sql($sql, array('userid' => $issue->userid, 'courseid' => $courseid))) { - if (!empty($timestart->timestart)) { - $date = $timestart->timestart; - } - } - } else if ($dateitem == CUSTOMCERT_DATE_ENROLMENT_END) { - // Get the enrolment end date. - $sql = "SELECT ue.timeend FROM {enrol} e JOIN {user_enrolments} ue ON ue.enrolid = e.id - WHERE e.courseid = :courseid - AND ue.userid = :userid"; - if ($timeend = $DB->get_record_sql($sql, array('userid' => $issue->userid, 'courseid' => $courseid))) { - if (!empty($timeend->timeend)) { - $date = $timeend->timeend; - } - } - } else if ($dateitem == CUSTOMCERT_DATE_COURSE_START) { - $date = $DB->get_field('course', 'startdate', array('id' => $courseid)); - } else if ($dateitem == CUSTOMCERT_DATE_COURSE_END) { - $date = $DB->get_field('course', 'enddate', array('id' => $courseid)); - } else { - if ($dateitem == CUSTOMCERT_DATE_COURSE_GRADE) { - $grade = \mod_customcert\element_helper::get_course_grade_info( - $courseid, - GRADE_DISPLAY_TYPE_DEFAULT, - $user->id - ); - } else if (strpos($dateitem, 'gradeitem:') === 0) { - $gradeitemid = substr($dateitem, 10); - $grade = \mod_customcert\element_helper::get_grade_item_info( - $gradeitemid, - $dateitem, - $user->id - ); - } else { - $grade = \mod_customcert\element_helper::get_mod_grade_info( - $dateitem, - GRADE_DISPLAY_TYPE_DEFAULT, - $user->id - ); - } - - if ($grade && !empty($grade->get_dategraded())) { - $date = $grade->get_dategraded(); - } - } - } - - // Ensure that a date has been set. - if (!empty($date)) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_date_format_string($date, $dateformat)); - } - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - // Decode the information stored in the database. - $dateinfo = json_decode($this->get_data()); - $dateformat = $dateinfo->dateformat; - - return \mod_customcert\element_helper::render_html_content($this, $this->get_date_format_string(time(), $dateformat)); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - // Set the item and format for this element. - if (!empty($this->get_data())) { - $dateinfo = json_decode($this->get_data()); - - $element = $mform->getElement('dateitem'); - $element->setValue($dateinfo->dateitem); - - $element = $mform->getElement('dateformat'); - $element->setValue($dateinfo->dateformat); - } - - parent::definition_after_data($mform); - } - - /** - * This function is responsible for handling the restoration process of the element. - * - * We will want to update the course module the date element is pointing to as it will - * have changed in the course restore. - * - * @param \restore_customcert_activity_task $restore - */ - public function after_restore($restore) { - global $DB; - - $dateinfo = json_decode($this->get_data()); - if ($newitem = \restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $dateinfo->dateitem)) { - $dateinfo->dateitem = $newitem->newitemid; - $DB->set_field('customcert_elements', 'data', $this->save_unique_data($dateinfo), array('id' => $this->get_id())); - } - } - - /** - * Helper function to return all the date formats. - * - * @return array the list of date formats - */ - public static function get_date_formats() { - // Hard-code date so users can see the difference between short dates with and without the leading zero. - // Eg. 06/07/18 vs 6/07/18. - $date = 1530849658; - - $suffix = self::get_ordinal_number_suffix(userdate($date, '%d')); - - $dateformats = [ - 1 => userdate($date, '%B %d, %Y'), - 2 => userdate($date, '%B %d' . $suffix . ', %Y') - ]; - - $strdateformats = [ - 'strftimedate', - 'strftimedatefullshort', - 'strftimedatefullshortwleadingzero', - 'strftimedateshort', - 'strftimedatetime', - 'strftimedatetimeshort', - 'strftimedatetimeshortwleadingzero', - 'strftimedaydate', - 'strftimedaydatetime', - 'strftimedayshort', - 'strftimedaytime', - 'strftimemonthyear', - 'strftimerecent', - 'strftimerecentfull', - 'strftimetime' - ]; - - foreach ($strdateformats as $strdateformat) { - if ($strdateformat == 'strftimedatefullshortwleadingzero') { - $dateformats[$strdateformat] = userdate($date, get_string('strftimedatefullshort', 'langconfig'), 99, false); - } else if ($strdateformat == 'strftimedatetimeshortwleadingzero') { - $dateformats[$strdateformat] = userdate($date, get_string('strftimedatetimeshort', 'langconfig'), 99, false); - } else { - $dateformats[$strdateformat] = userdate($date, get_string($strdateformat, 'langconfig')); - } - } - - return $dateformats; - } - - /** - * Returns the date in a readable format. - * - * @param int $date - * @param string $dateformat - * @return string - */ - protected function get_date_format_string($date, $dateformat) { - // Keeping for backwards compatibility. - if (is_number($dateformat)) { - switch ($dateformat) { - case 1: - $certificatedate = userdate($date, '%B %d, %Y'); - break; - case 2: - $suffix = self::get_ordinal_number_suffix(userdate($date, '%d')); - $certificatedate = userdate($date, '%B %d' . $suffix . ', %Y'); - break; - case 3: - $certificatedate = userdate($date, '%d %B %Y'); - break; - case 4: - $certificatedate = userdate($date, '%B %Y'); - break; - default: - $certificatedate = userdate($date, get_string('strftimedate', 'langconfig')); - } - } - - // Ok, so we must have been passed the actual format in the lang file. - if (!isset($certificatedate)) { - if ($dateformat == 'strftimedatefullshortwleadingzero') { - $certificatedate = userdate($date, get_string('strftimedatefullshort', 'langconfig'), 99, false); - } else if ($dateformat == 'strftimedatetimeshortwleadingzero') { - $certificatedate = userdate($date, get_string('strftimedatetimeshort', 'langconfig'), 99, false); - } else { - $certificatedate = userdate($date, get_string($dateformat, 'langconfig')); - } - } - - return $certificatedate; - } - - /** - * Helper function to return the suffix of the day of - * the month, eg 'st' if it is the 1st of the month. - * - * @param int $day the day of the month - * @return string the suffix. - */ - protected static function get_ordinal_number_suffix($day) { - if (!in_array(($day % 100), array(11, 12, 13))) { - switch ($day % 10) { - // Handle 1st, 2nd, 3rd. - case 1: - return get_string('numbersuffix_st_as_in_first', 'customcertelement_date'); - case 2: - return get_string('numbersuffix_nd_as_in_second', 'customcertelement_date'); - case 3: - return get_string('numbersuffix_rd_as_in_third', 'customcertelement_date'); - } - } - return 'th'; - } -} diff --git a/element/date/classes/privacy/provider.php b/element/date/classes/privacy/provider.php deleted file mode 100644 index 1ce5f23..0000000 --- a/element/date/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_date. - * - * @package customcertelement_date - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_date\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_date implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/date/lang/en/customcertelement_date.php b/element/date/lang/en/customcertelement_date.php deleted file mode 100644 index 8c34616..0000000 --- a/element/date/lang/en/customcertelement_date.php +++ /dev/null @@ -1,42 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_date', language 'en'. - * - * @package customcertelement_date - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['completiondate'] = 'Completion date'; -$string['courseenddate'] = 'Course end date'; -$string['coursegradedate'] = 'Course grade date'; -$string['coursestartdate'] = 'Course start date'; -$string['enrolmentenddate'] = 'Enrolment end date'; -$string['enrolmentstartdate'] = 'Enrolment start date'; -$string['currentdate'] = 'Current date'; -$string['dateformat'] = 'Date format'; -$string['dateformat_help'] = 'This is the format of the date that will be displayed'; -$string['dateitem'] = 'Date item'; -$string['dateitem_help'] = 'This will be the date that is printed on the certificate'; -$string['issueddate'] = 'Issued date'; -$string['pluginname'] = 'Date'; -$string['privacy:metadata'] = 'The Date plugin does not store any personal data.'; -$string['numbersuffix_nd_as_in_second'] = 'nd'; -$string['numbersuffix_rd_as_in_third'] = 'rd'; -$string['numbersuffix_st_as_in_first'] = 'st'; -$string['userdateformat'] = 'User date format'; diff --git a/element/date/version.php b/element/date/version.php deleted file mode 100644 index c0b7a86..0000000 --- a/element/date/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the date plugin. - * - * @package customcertelement_date - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_date'; diff --git a/element/daterange/classes/element.php b/element/daterange/classes/element.php deleted file mode 100644 index 0e45ca4..0000000 --- a/element/daterange/classes/element.php +++ /dev/null @@ -1,731 +0,0 @@ -. - -/** - * This file contains the customcert date range element. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_daterange; - -use \mod_customcert\element_helper; - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -require_once($CFG->dirroot . '/lib/grade/constants.php'); - -/** - * The customcert date range element. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * Max recurring period in seconds. - */ - const MAX_RECURRING_PERIOD = 31556926; // 12 months. - - /** - * Current year placeholder string. - */ - const CURRENT_YEAR_PLACEHOLDER = '{{current_year}}'; - - /** - * First year in a date range placeholder string. - */ - const RANGE_FIRST_YEAR_PLACEHOLDER = '{{range_first_year}}'; - - /** - * Last year in a date range placeholder string. - */ - const RANGE_LAST_YEAR_PLACEHOLDER = '{{range_last_year}}'; - - /** - * First year in a date range placeholder string. - */ - const RECUR_RANGE_FIRST_YEAR_PLACEHOLDER = '{{recurring_range_first_year}}'; - - /** - * Last year in a date range placeholder string. - */ - const RECUR_RANGE_LAST_YEAR_PLACEHOLDER = '{{recurring_range_last_year}}'; - - /** - * A year in the user's date. - */ - const DATE_YEAR_PLACEHOLDER = '{{date_year}}'; - - /** - * Date - Issue - */ - const DATE_ISSUE = -1; - - /** - * Date - Completion - */ - const DATE_COMPLETION = -2; - - /** - * Date - Course start - */ - const DATE_COURSE_START = -3; - - /** - * Date - Course end - */ - const DATE_COURSE_END = -4; - - /** - * Date - Course grade date - */ - const DATE_COURSE_GRADE = -5; - - /** - * Date - Course current date - */ - const DATE_CURRENT_DATE = -6; - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit form instance - */ - public function render_form_elements($mform) { - global $COURSE; - - // Get the possible date options. - $dateoptions = array(); - $dateoptions[self::DATE_ISSUE] = get_string('issueddate', 'customcertelement_daterange'); - $dateoptions[self::DATE_CURRENT_DATE] = get_string('currentdate', 'customcertelement_daterange'); - $dateoptions[self::DATE_COMPLETION] = get_string('completiondate', 'customcertelement_daterange'); - $dateoptions[self::DATE_COURSE_START] = get_string('coursestartdate', 'customcertelement_daterange'); - $dateoptions[self::DATE_COURSE_END] = get_string('courseenddate', 'customcertelement_daterange'); - $dateoptions[self::DATE_COURSE_GRADE] = get_string('coursegradedate', 'customcertelement_daterange'); - - $dateoptions = $dateoptions + element_helper::get_grade_items($COURSE); - - $mform->addElement('select', 'dateitem', get_string('dateitem', 'customcertelement_daterange'), $dateoptions); - $mform->addHelpButton('dateitem', 'dateitem', 'customcertelement_daterange'); - - parent::render_form_elements($mform); - - $mform->addElement('header', 'dateranges', get_string('dateranges', 'customcertelement_daterange')); - $mform->addElement('static', 'help', '', get_string('help', 'customcertelement_daterange')); - $mform->addElement('static', 'placeholders', '', get_string('placeholders', 'customcertelement_daterange')); - - $mform->addElement('text', 'fallbackstring', get_string('fallbackstring', 'customcertelement_daterange')); - $mform->addHelpButton('fallbackstring', 'fallbackstring', 'customcertelement_daterange'); - $mform->setType('fallbackstring', PARAM_NOTAGS); - - if (empty($this->get_decoded_data()->dateranges)) { - $repeats = 1; - } else { - $repeats = count($this->get_decoded_data()->dateranges); - } - - $ranges = []; - - $ranges[] = $mform->createElement('html', '
'); - - $ranges[] = $mform->createElement( - 'date_selector', - 'startdate', - get_string('start', 'customcertelement_daterange') - ); - - $ranges[] = $mform->createElement( - 'date_selector', - 'enddate', - get_string('end', 'customcertelement_daterange') - ); - - $ranges[] = $mform->createElement( - 'checkbox', - 'recurring', - get_string('recurring', 'customcertelement_daterange') - ); - - $ranges[] = $mform->createElement( - 'text', - 'datestring', - get_string('datestring', 'customcertelement_daterange'), - ['class' => 'datestring'] - ); - - $ranges[] = $mform->createElement( - 'advcheckbox', - 'rangedelete', - get_string('setdeleted', 'customcertelement_daterange'), - '', - [], - [0, 1] - ); - - $rangeoptions = array(); - $rangeoptions['startdate']['type'] = PARAM_INT; - $rangeoptions['enddate']['type'] = PARAM_INT; - $rangeoptions['recurring']['type'] = PARAM_INT; - $rangeoptions['recurring']['helpbutton'] = ['recurring', 'customcertelement_daterange']; - $rangeoptions['datestring']['type'] = PARAM_NOTAGS; - $rangeoptions['rangedelete']['type'] = PARAM_BOOL; - - $addstring = get_string('addrange', 'customcertelement_daterange'); - $this->get_edit_element_form()->repeat_elements($ranges, $repeats, $rangeoptions, 'repeats', 'add', 1, $addstring, true); - } - - /** - * A helper function to build consistent form element name. - * - * @param string $name - * @param string $num - * - * @return string - */ - protected function build_element_name($name, $num) { - return $name . '[' . $num . ']'; - } - - /** - * Get decoded data stored in DB. - * - * @return \stdClass - */ - protected function get_decoded_data() { - return json_decode($this->get_data()); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data()) && !$mform->isSubmitted()) { - $element = $mform->getElement('dateitem'); - $element->setValue($this->get_decoded_data()->dateitem); - - $element = $mform->getElement('fallbackstring'); - $element->setValue($this->get_decoded_data()->fallbackstring); - - foreach ($this->get_decoded_data()->dateranges as $key => $range) { - $mform->setDefault($this->build_element_name('startdate', $key), $range->startdate); - $mform->setDefault($this->build_element_name('enddate', $key), $range->enddate); - $mform->setDefault($this->build_element_name('datestring', $key), $range->datestring); - $mform->setDefault($this->build_element_name('recurring', $key), $range->recurring); - } - } - - parent::definition_after_data($mform); - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - $errors = parent::validate_form_elements($data, $files); - - // Check if at least one range is set. - $error = get_string('error:atleastone', 'customcertelement_daterange'); - - for ($i = 0; $i < $data['repeats']; $i++) { - if (empty($data['rangedelete'][$i])) { - $error = ''; - } - } - - if (!empty($error)) { - $errors['help'] = $error; - } - - // Check that datestring is set dataranges what aren't need to be deleted. - for ($i = 0; $i < $data['repeats']; $i++) { - // Skip elements that needs to be deleted. - if (!empty($data['rangedelete'][$i])) { - continue; - } - - if (empty($data['datestring'][$i])) { - $name = $this->build_element_name('datestring', $i); - $errors[$name] = get_string('error:datestring', 'customcertelement_daterange'); - } - - // Check that end date is correctly set. - if ( $data['startdate'][$i] >= $data['enddate'][$i] ) { - $errors[$this->build_element_name('enddate', $i)] = get_string('error:enddate', 'customcertelement_daterange'); - } - - $rangeperiod = $data['enddate'][$i] - $data['startdate'][$i]; - - // Check that recurring dateranges are not longer than 12 months. - if (!empty($data['recurring'][$i]) && $rangeperiod >= self::MAX_RECURRING_PERIOD ) { - $errors[$this->build_element_name('enddate', $i)] = get_string('error:recurring', 'customcertelement_daterange'); - } - } - - return $errors; - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - $arrtostore = array( - 'dateitem' => $data->dateitem, - 'fallbackstring' => $data->fallbackstring, - 'dateranges' => [], - ); - - for ($i = 0; $i < $data->repeats; $i++) { - if (empty($data->rangedelete[$i])) { - $arrtostore['dateranges'][] = [ - 'startdate' => $data->startdate[$i], - 'enddate' => $data->enddate[$i], - 'datestring' => $data->datestring[$i], - 'recurring' => !empty($data->recurring[$i]), - ]; - } - } - - // Encode these variables before saving into the DB. - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $DB; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $courseid = element_helper::get_courseid($this->id); - $dateitem = $this->get_decoded_data()->dateitem; - - // If we are previewing this certificate then just show a demonstration date. - if ($preview) { - $date = time(); - } else { - // Get the page. - $page = $DB->get_record('customcert_pages', array('id' => $this->get_pageid()), '*', MUST_EXIST); - // Get the customcert this page belongs to. - $customcert = $DB->get_record('customcert', array('templateid' => $page->templateid), '*', MUST_EXIST); - // Now we can get the issue for this user. - $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $customcert->id), - '*', MUST_EXIST); - - switch ($dateitem) { - case self::DATE_ISSUE: - $date = $issue->timecreated; - break; - - case self::DATE_CURRENT_DATE: - $date = time(); - break; - - case self::DATE_COMPLETION: - // Get the last completion date. - $sql = "SELECT MAX(c.timecompleted) as timecompleted - FROM {course_completions} c - WHERE c.userid = :userid - AND c.course = :courseid"; - if ($timecompleted = $DB->get_record_sql($sql, array('userid' => $issue->userid, 'courseid' => $courseid))) { - if (!empty($timecompleted->timecompleted)) { - $date = $timecompleted->timecompleted; - } - } - break; - - case self::DATE_COURSE_START: - $date = $DB->get_field('course', 'startdate', array('id' => $courseid)); - break; - - case self::DATE_COURSE_END: - $date = $DB->get_field('course', 'enddate', array('id' => $courseid)); - break; - - case self::DATE_COURSE_GRADE: - $grade = element_helper::get_course_grade_info( - $courseid, - GRADE_DISPLAY_TYPE_DEFAULT, $user->id - ); - if ($grade && !empty($grade->get_dategraded())) { - $date = $grade->get_dategraded(); - } - break; - - default: - if (strpos($dateitem, 'gradeitem:') === 0) { - $gradeitemid = substr($dateitem, 10); - $grade = element_helper::get_grade_item_info( - $gradeitemid, - $dateitem, - $user->id - ); - } else { - $grade = element_helper::get_mod_grade_info( - $dateitem, - GRADE_DISPLAY_TYPE_DEFAULT, - $user->id - ); - } - if ($grade && !empty($grade->get_dategraded())) { - $date = $grade->get_dategraded(); - } - break; - } - } - - // Ensure that a date has been set. - if (!empty($date)) { - element_helper::render_content($pdf, $this, $this->get_daterange_string($date)); - } - } - - /** - * Get daterange string. - * - * @param int $date Unix stamp date. - * - * @return string - */ - protected function get_daterange_string($date) { - $matchedrange = null; - $outputstring = ''; - $formatdata = []; - $formatdata['date'] = $date; - - foreach ($this->get_decoded_data()->dateranges as $key => $range) { - if ($this->is_recurring_range($range)) { - if ($matchedrange = $this->get_matched_recurring_range($date, $range)) { - $outputstring = $matchedrange->datestring; - $formatdata['range'] = $range; - $formatdata['recurringrange'] = $matchedrange; - break; - } - } else { - if ($this->is_date_in_range($date, $range)) { - $outputstring = $range->datestring; - $formatdata['range'] = $range; - break; - } - } - } - - if (empty($outputstring) && !empty($this->get_decoded_data()->fallbackstring)) { - $outputstring = $this->get_decoded_data()->fallbackstring; - } - - return $this->format_date_string($outputstring, $formatdata); - } - - /** - * Returns whether or not a range is recurring. - * - * @param \stdClass $range Range object. - * - * @return bool - */ - protected function is_recurring_range(\stdClass $range) { - return !empty($range->recurring); - } - - /** - * Check if the provided date is in the date range. - * - * @param int $date Unix timestamp date to check. - * @param \stdClass $range Range object. - * - * @return bool - */ - protected function is_date_in_range($date, \stdClass $range) { - return ($date >= $range->startdate && $date <= $range->enddate); - } - - /** - * Check if provided date is in the recurring date range. - * - * @param int $date Unix timestamp date to check. - * @param \stdClass $range Range object. - * - * @return bool - */ - protected function is_date_in_recurring_range($date, \stdClass $range) { - $intdate = $this->build_number_from_date($date); - $intstart = $this->build_number_from_date($range->startdate); - $intend = $this->build_number_from_date($range->enddate); - - if (!$this->has_turn_of_the_year($range)) { - if ($intdate >= $intstart && $intdate <= $intend) { - return true; - } - } else { - if ($intdate >= $intstart && $intdate >= $intend) { - return true; - } - - if ($intdate <= $intstart && $intdate <= $intend) { - return true; - } - } - - return false; - } - - /** - * Check if provided recurring range has a turn of the year. - * - * @param \stdClass $reccurringrange Range object. - * - * @return bool - */ - protected function has_turn_of_the_year(\stdClass $reccurringrange) { - return date('Y', $reccurringrange->startdate) != date('Y', $reccurringrange->enddate); - } - - /** - * Check if provided date is in the start year of the recurring range with a turn of the year. - * - * @param int $date Unix timestamp date to check. - * @param \stdClass $range Range object. - * - * @return bool - */ - protected function in_start_year($date, \stdClass $range) { - $intdate = $this->build_number_from_date($date); - $intstart = $this->build_number_from_date($range->startdate); - $intend = $this->build_number_from_date($range->enddate); - - return $intdate >= $intstart && $intdate >= $intend; - } - - /** - * Check if provided date is in the end year of the recurring range with a turn of the year. - * - * @param int $date Unix timestamp date to check. - * @param \stdClass $range Range object. - * - * @return bool - */ - protected function in_end_year($date, \stdClass $range) { - $intdate = $this->build_number_from_date($date); - $intstart = $this->build_number_from_date($range->startdate); - $intend = $this->build_number_from_date($range->enddate); - - return $intdate <= $intstart && $intdate <= $intend; - } - - /** - * Return matched recurring date range. - * - * As recurring date ranges do not depend on the year, - * we will use a date's year to build a new matched recurring date range with - * start year and end year. This is required to replace placeholders like range_first_year and range_last_year. - * - * @param int $date Unix timestamp date to check. - * @param \stdClass $range Range object. - * - * @return \stdClass || null - */ - protected function get_matched_recurring_range($date, \stdClass $range) { - if (!$this->is_date_in_recurring_range($date, $range)) { - return null; - } - - $matchedrage = clone $range; - - if ($this->has_turn_of_the_year($matchedrage)) { - - if ($this->in_start_year($date, $matchedrage)) { - $startyear = date('Y', $date); - $endyear = $startyear + 1; - $matchedrage->startdate = strtotime(date('d.m.', $matchedrage->startdate) . $startyear); - $matchedrage->enddate = strtotime(date('d.m.', $matchedrage->enddate) . $endyear); - - return $matchedrage; - } - - if ($this->in_end_year($date, $matchedrage)) { - $endyear = date('Y', $date); - $startyear = $endyear - 1; - $matchedrage->startdate = strtotime(date('d.m.', $matchedrage->startdate) . $startyear); - $matchedrage->enddate = strtotime(date('d.m.', $matchedrage->enddate) . $endyear); - - return $matchedrage; - } - } else { - $matchedrage->startdate = strtotime(date('d.m.', $matchedrage->startdate) . date('Y', $date)); - $matchedrage->enddate = strtotime(date('d.m.', $matchedrage->enddate) . date('Y', $date)); - - return $matchedrage; - } - - return null; - } - - /** - * Build number representation of the provided date. - * - * @param int $date Unix timestamp date to check. - * - * @return int - */ - protected function build_number_from_date($date) { - return (int)date('md', $date); - } - - /** - * Format date string based on different types of placeholders. - * - * @param string $datestring The date string - * @param array $formatdata A list of format data. - * - * @return string - */ - protected function format_date_string($datestring, array $formatdata) { - foreach ($this->get_placeholders() as $search => $replace) { - $datestring = str_replace($search, $replace, $datestring); - } - - if (!empty($formatdata['date'])) { - foreach ($this->get_date_placeholders($formatdata['date']) as $search => $replace) { - $datestring = str_replace($search, $replace, $datestring); - } - } - - if (!empty($formatdata['range'])) { - foreach ($this->get_range_placeholders($formatdata['range']) as $search => $replace) { - $datestring = str_replace($search, $replace, $datestring); - } - } - - if (!empty($formatdata['recurringrange'])) { - foreach ($this->get_recurring_range_placeholders($formatdata['recurringrange']) as $search => $replace) { - $datestring = str_replace($search, $replace, $datestring); - } - } - - return $datestring; - } - - /** - * Return a list of placeholders to replace in date string as search => $replace pairs. - * - * @return array - */ - protected function get_placeholders() { - return [ - self::CURRENT_YEAR_PLACEHOLDER => date('Y', time()), - ]; - } - - /** - * Return a list of user's date related placeholders to replace in date string as search => $replace pairs. - - * @param int $date Unix timestamp date to check. - * - * @return array - */ - protected function get_date_placeholders($date) { - return [ - self::DATE_YEAR_PLACEHOLDER => date('Y', $date), - ]; - } - - /** - * Return a list of range related placeholders to replace in date string as search => $replace pairs. - * - * @param \stdClass $range - * - * @return array - */ - protected function get_range_placeholders(\stdClass $range) { - return [ - self::RANGE_FIRST_YEAR_PLACEHOLDER => date('Y', $range->startdate), - self::RANGE_LAST_YEAR_PLACEHOLDER => date('Y', $range->enddate), - ]; - } - - /** - * Return a list of recurring range s placeholders to replace in date string as search => $replace pairs. - * - * @param \stdClass $range - * - * @return array - */ - protected function get_recurring_range_placeholders(\stdClass $range) { - return [ - self::RECUR_RANGE_FIRST_YEAR_PLACEHOLDER => date('Y', $range->startdate), - self::RECUR_RANGE_LAST_YEAR_PLACEHOLDER => date('Y', $range->enddate), - ]; - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - return element_helper::render_html_content($this, get_string('preview', 'customcertelement_daterange', $this->get_name())); - } - - /** - * This function is responsible for handling the restoration process of the element. - * - * We will want to update the course module the date element is pointing to as it will - * have changed in the course restore. - * - * @param \restore_customcert_activity_task $restore - */ - public function after_restore($restore) { - global $DB; - - $data = $this->get_decoded_data(); - if ($newitem = \restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $data->dateitem)) { - $data->dateitem = $newitem->newitemid; - $DB->set_field('customcert_elements', 'data', $this->save_unique_data($data), array('id' => $this->get_id())); - } - } - -} diff --git a/element/daterange/classes/privacy/provider.php b/element/daterange/classes/privacy/provider.php deleted file mode 100644 index 482f40f..0000000 --- a/element/daterange/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_daterange. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_daterange\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_daterange implementing null_provider. - * - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/daterange/lang/en/customcertelement_daterange.php b/element/daterange/lang/en/customcertelement_daterange.php deleted file mode 100644 index 551ee31..0000000 --- a/element/daterange/lang/en/customcertelement_daterange.php +++ /dev/null @@ -1,53 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_daterange', language 'en'. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$string['addrange'] = 'Add another range'; -$string['completiondate'] = 'Completion date'; -$string['courseenddate'] = 'Course end date'; -$string['coursegradedate'] = 'Course grade date'; -$string['coursestartdate'] = 'Course start date'; -$string['currentdate'] = 'Current date'; -$string['dateitem'] = 'Date item'; -$string['dateitem_help'] = 'This will be the date that is printed on the certificate'; -$string['dateranges'] = 'Date ranges'; -$string['datestring'] = 'String'; -$string['end'] = 'End'; -$string['error:atleastone'] = 'You must have at least one date range configured'; -$string['error:datestring'] = 'You must provide string representation for the date range'; -$string['error:enddate'] = 'End date must occur after the start date'; -$string['error:recurring'] = 'Recurring range must not be longer than 12 months'; -$string['fallbackstring'] = 'Fallback string'; -$string['fallbackstring_help'] = 'This string will be displayed if no date range applies to a date. If the fallback string is not set, then there will be no output at all.'; -$string['help'] = 'Configure a string representation for your date ranges.

If your ranges overlap the first matched date range will be applied.'; -$string['issueddate'] = 'Issued date'; -$string['placeholders'] = 'The following placeholders can be used in the string representation or fallback string.

{{range_first_year}} - first year of the matched range,
{{range_last_year}} - last year of the matched range,
{{recurring_range_first_year}} - first year of the matched recurring period,
{{recurring_range_last_year}} - last year of the matched recurring period,
{{current_year}} - the current year,
{{date_year}} - a year of the users\'s date.'; -$string['pluginname'] = 'Date range'; -$string['preview'] = 'Preview {$a}'; -$string['privacy:metadata'] = 'The Date range plugin does not store any personal data.'; -$string['recurring'] = 'Recurring'; -$string['recurring_help'] = 'If you mark a date range as recurring then the configured year will not be considered.'; -$string['setdeleted'] = 'Delete'; -$string['start'] = 'Start'; diff --git a/element/daterange/tests/element_test.php b/element/daterange/tests/element_test.php deleted file mode 100644 index eb58cdd..0000000 --- a/element/daterange/tests/element_test.php +++ /dev/null @@ -1,248 +0,0 @@ -. - -/** - * Test datarange element. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -defined('MOODLE_INTERNAL') || die(); - -global $CFG; - -require_once($CFG->dirroot . '/mod/customcert/element/daterange/tests/fixtures/fake_datarange_element.php'); - -/** - * Test datarange element. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class customcertelement_daterange_element_test extends advanced_testcase { - - /** - * Helper function to build element data. - * - * @param stdClass $data Element data. - * - * @return object - */ - protected function build_element_data(stdClass $data) { - return (object) [ - 'id' => 1, - 'pageid' => 1, - 'name' => 'Test', - 'data' => json_encode($data), - 'font' => 'Font', - 'fontsize' => 1, - 'colour' => '#EEE', - 'posx' => 0, - 'posy' => 0, - 'width' => 100, - 'refpoint' => 1 - ]; - } - - /** - * Helper function to build datarange data. - * - * @param array $dataranges A list of dataranges. - * @param string $fallbackstring Fall back string. - * - * @return object - */ - protected function build_datarange_data(array $dataranges, $fallbackstring = '') { - return (object) [ - 'dateitem' => 1, - 'fallbackstring' => $fallbackstring, - 'numranges' => count($dataranges), - 'dateranges' => $dataranges, - ]; - } - - /** - * A helper function to get datarange element for testing. - * - * @param array $dataranges A list of dataranges. - * @param string $fallbackstring Fall back strin - * - * @return \fake_datarange_element - */ - protected function get_datarange_element(array $dataranges, $fallbackstring = '') { - $datarangedata = $this->build_datarange_data($dataranges, $fallbackstring); - $elementdata = $this->build_element_data($datarangedata); - - return new fake_datarange_element($elementdata); - } - - /** - * Data provider for test_get_daterange_string_for_recurring_ranges. - * @return array - */ - public function get_test_get_daterange_string_for_recurring_ranges_data_provider() { - return [ - ['1.11.2016', 'WS 2016/2017'], - ['1.11.2017', 'WS 2017/2018'], - ['1.11.2018', 'WS 2018/2019'], - ['1.11.2019', 'WS 2019/2020'], - ['1.02.2017', 'WS 2016/2017'], - ['1.02.2018', 'WS 2017/2018'], - ['1.02.2019', 'WS 2018/2019'], - ['1.02.2020', 'WS 2019/2020'], - ['1.05.2016', 'SS 2016'], - ['1.05.2017', 'SS 2017'], - ['1.05.2018', 'SS 2018'], - ['1.05.2019', 'SS 2019'], - ]; - } - - /** - * Test get correct strings for recurring ranges. - * - * @dataProvider get_test_get_daterange_string_for_recurring_ranges_data_provider - * - * @param string $date Date to test. - * @param string $expected Expected result. - */ - public function test_get_daterange_string_for_recurring_ranges($date, $expected) { - $dateranges = [ - (object)[ - 'startdate' => strtotime('01.04.2017'), - 'enddate' => strtotime('30.09.2017'), - 'datestring' => 'SS {{date_year}}', - 'recurring' => true, - ], - (object)[ - 'startdate' => strtotime('01.10.2017'), - 'enddate' => strtotime('31.03.2018'), - 'datestring' => 'WS {{recurring_range_first_year}}/{{recurring_range_last_year}}', - 'recurring' => true, - ], - ]; - - $element = $this->get_datarange_element($dateranges); - $date = strtotime($date); - $this->assertEquals($expected, $element->get_daterange_string($date)); - } - - /** - * Test that first found element matched. - */ - public function test_that_first_matched_range_applied_first() { - $dateranges = [ - (object)[ - 'startdate' => strtotime('01.04.2017'), - 'enddate' => strtotime('30.09.2017'), - 'datestring' => 'First range', - 'recurring' => false, - ], - (object)[ - 'startdate' => strtotime('01.05.2017'), - 'enddate' => strtotime('01.07.2018'), - 'datestring' => 'Second range', - 'recurring' => false, - ], - ]; - - $element = $this->get_datarange_element($dateranges); - $date = strtotime('1.06.2017'); - $this->assertEquals('First range', $element->get_daterange_string($date)); - } - - /** - * Test that placeholders correctly applied to matched range and fall back string. - */ - public function test_placeholders_and_fall_back_string() { - $dateranges = [ - (object)[ - 'startdate' => strtotime('01.04.2017'), - 'enddate' => strtotime('30.09.2018'), - 'datestring' => '{{current_year}} - {{range_first_year}} - {{range_last_year}} - {{date_year}}', - 'recurring' => false, - ], - ]; - - $fallbackstring = '{{current_year}} - {{range_first_year}} - {{range_last_year}} - {{date_year}}'; - $element = $this->get_datarange_element($dateranges, $fallbackstring); - - $date = strtotime('1.01.2000'); - $expected = date('Y', time()) . ' - {{range_first_year}} - {{range_last_year}} - 2000'; - $this->assertEquals($expected, $element->get_daterange_string($date)); - - $date = strtotime('1.07.2017'); - $expected = date('Y', time()) . ' - 2017 - 2018 - 2017'; - $this->assertEquals($expected, $element->get_daterange_string($date)); - } - - /** - * Test that nothing will be displayed if not matched and empty fall back string. - */ - public function test_nothing_will_be_displayed_if_empty_fallback_string() { - $dateranges = [ - (object)[ - 'startdate' => strtotime('01.04.2017'), - 'enddate' => strtotime('30.09.2018'), - 'datestring' => '{{current_year}} - {{range_first_year}} - {{range_last_year}} - {{date_year}}', - 'recurring' => false, - ], - ]; - - $fallbackstring = ''; - $element = $this->get_datarange_element($dateranges, $fallbackstring); - - $date = strtotime('1.07.2011'); - $this->assertEquals($fallbackstring, $element->get_daterange_string($date)); - } - - /** - * Test that display recurring_range_first_year and recurring_range_last_year placeholders. - */ - public function test_recurring_range_first_year_and_recurring_range_last_year_placeholders() { - $datestring = '{{range_first_year}}-{{range_last_year}}-{{recurring_range_first_year}}-{{recurring_range_last_year}}'; - $dateranges = [ - (object) [ - 'startdate' => strtotime('01.04.2017'), - 'enddate' => strtotime('30.09.2017'), - 'datestring' => $datestring, - 'recurring' => true, - ], - (object)[ - 'startdate' => strtotime('01.10.2017'), - 'enddate' => strtotime('31.03.2018'), - 'datestring' => $datestring, - 'recurring' => true, - ], - ]; - - $element = $this->get_datarange_element($dateranges); - - $date = strtotime('1.05.2020'); - $this->assertEquals('2017-2017-2020-2020', $element->get_daterange_string($date)); - - $date = strtotime('1.05.2024'); - $this->assertEquals('2017-2017-2024-2024', $element->get_daterange_string($date)); - - $date = strtotime('1.02.2020'); - $this->assertEquals('2017-2018-2019-2020', $element->get_daterange_string($date)); - - $date = strtotime('1.02.2024'); - $this->assertEquals('2017-2018-2023-2024', $element->get_daterange_string($date)); - } - -} diff --git a/element/daterange/tests/fixtures/fake_datarange_element.php b/element/daterange/tests/fixtures/fake_datarange_element.php deleted file mode 100644 index e39b3a2..0000000 --- a/element/daterange/tests/fixtures/fake_datarange_element.php +++ /dev/null @@ -1,47 +0,0 @@ -. - -/** - * Fake datarange element for testing. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Fake datarange element for testing. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class fake_datarange_element extends \customcertelement_daterange\element { - - /** - * Override protected method for testing. - * - * @param int $date - * - * @return string - */ - public function get_daterange_string($date) { - $result = parent::get_daterange_string($date); - return $result; - } -} diff --git a/element/daterange/version.php b/element/daterange/version.php deleted file mode 100644 index fc06a86..0000000 --- a/element/daterange/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the date plugin. - * - * @package customcertelement_daterange - * @copyright 2018 Dmitrii Metelkin - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_daterange'; diff --git a/element/digitalsignature/classes/element.php b/element/digitalsignature/classes/element.php deleted file mode 100644 index 178d2d4..0000000 --- a/element/digitalsignature/classes/element.php +++ /dev/null @@ -1,338 +0,0 @@ -. - -/** - * This file contains the customcert element digitial signature's core interaction API. - * - * @package customcertelement_digitalsignature - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_digitalsignature; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element digital signature's core interaction API. - * - * @package customcertelement_digitalsignature - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \customcertelement_image\element { - - /** - * @var array The file manager options for the certificate. - */ - protected $signaturefilemanageroptions = array(); - - /** - * Constructor. - * - * @param \stdClass $element the element data - */ - public function __construct($element) { - global $COURSE; - - $this->signaturefilemanageroptions = [ - 'maxbytes' => $COURSE->maxbytes, - 'subdirs' => 1, - 'accepted_types' => ['.crt'] - ]; - - parent::__construct($element); - } - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('select', 'fileid', get_string('image', 'customcertelement_image'), self::get_images()); - - $mform->addElement('select', 'signaturefileid', get_string('digitalsignature', 'customcertelement_digitalsignature'), - self::get_signatures()); - - $mform->addElement('text', 'signaturename', get_string('signaturename', 'customcertelement_digitalsignature')); - $mform->setType('signaturename', PARAM_TEXT); - $mform->setDefault('signaturename', ''); - - $mform->addElement('passwordunmask', 'signaturepassword', - get_string('signaturepassword', 'customcertelement_digitalsignature')); - $mform->setType('signaturepassword', PARAM_TEXT); - $mform->setDefault('signaturepassword', ''); - - $mform->addElement('text', 'signaturelocation', get_string('signaturelocation', 'customcertelement_digitalsignature')); - $mform->setType('signaturelocation', PARAM_TEXT); - $mform->setDefault('signaturelocation', ''); - - $mform->addElement('text', 'signaturereason', get_string('signaturereason', 'customcertelement_digitalsignature')); - $mform->setType('signaturereason', PARAM_TEXT); - $mform->setDefault('signaturereason', ''); - - $mform->addElement('text', 'signaturecontactinfo', - get_string('signaturecontactinfo', 'customcertelement_digitalsignature')); - $mform->setType('signaturecontactinfo', PARAM_TEXT); - $mform->setDefault('signaturecontactinfo', ''); - - $mform->addElement('text', 'width', get_string('width', 'customcertelement_image'), array('size' => 10)); - $mform->setType('width', PARAM_INT); - $mform->setDefault('width', 0); - $mform->addHelpButton('width', 'width', 'customcertelement_image'); - - $mform->addElement('text', 'height', get_string('height', 'customcertelement_image'), array('size' => 10)); - $mform->setType('height', PARAM_INT); - $mform->setDefault('height', 0); - $mform->addHelpButton('height', 'height', 'customcertelement_image'); - - if (get_config('customcert', 'showposxy')) { - \mod_customcert\element_helper::render_form_element_position($mform); - } - - $mform->addElement('filemanager', 'customcertimage', get_string('uploadimage', 'customcert'), '', - $this->filemanageroptions); - - $mform->addElement('filemanager', 'digitalsignature', - get_string('uploaddigitalsignature', 'customcertelement_digitalsignature'), '', - $this->signaturefilemanageroptions); - } - - /** - * Handles saving the form elements created by this element. - * Can be overridden if more functionality is needed. - * - * @param \stdClass $data the form data - * @return bool true of success, false otherwise. - */ - public function save_form_elements($data) { - global $COURSE, $SITE; - - // Set the context. - if ($COURSE->id == $SITE->id) { - $context = \context_system::instance(); - } else { - $context = \context_course::instance($COURSE->id); - } - - // Handle file uploads. - \mod_customcert\certificate::upload_files($data->customcertimage, $context->id); - - // Handle file certificate uploads. - \mod_customcert\certificate::upload_files($data->digitalsignature, $context->id, 'signature'); - - return parent::save_form_elements($data); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - $arrtostore = [ - 'signaturename' => $data->signaturename, - 'signaturepassword' => $data->signaturepassword, - 'signaturelocation' => $data->signaturelocation, - 'signaturereason' => $data->signaturereason, - 'signaturecontactinfo' => $data->signaturecontactinfo, - 'width' => !empty($data->width) ? (int) $data->width : 0, - 'height' => !empty($data->height) ? (int) $data->height : 0 - ]; - - // Array of data we will be storing in the database. - $fs = get_file_storage(); - - if (!empty($data->fileid)) { - if ($file = $fs->get_file_by_id($data->fileid)) { - $arrtostore += [ - 'contextid' => $file->get_contextid(), - 'filearea' => $file->get_filearea(), - 'itemid' => $file->get_itemid(), - 'filepath' => $file->get_filepath(), - 'filename' => $file->get_filename(), - ]; - } - } - - if (!empty($data->signaturefileid)) { - if ($signaturefile = $fs->get_file_by_id($data->signaturefileid)) { - $arrtostore += [ - 'signaturecontextid' => $signaturefile->get_contextid(), - 'signaturefilearea' => $signaturefile->get_filearea(), - 'signatureitemid' => $signaturefile->get_itemid(), - 'signaturefilepath' => $signaturefile->get_filepath(), - 'signaturefilename' => $signaturefile->get_filename() - ]; - } - } - - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - // If there is no file, we have nothing to display. - if (empty($imageinfo->filename)) { - return; - } - - // If there is no signature file, we have nothing to display. - if (empty($imageinfo->signaturefilename)) { - return; - } - - if ($file = $this->get_file()) { - $location = make_request_directory() . '/target'; - $file->copy_content_to($location); - - $mimetype = $file->get_mimetype(); - if ($mimetype == 'image/svg+xml') { - $pdf->ImageSVG($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } else { - $pdf->Image($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } - } - - if ($signaturefile = $this->get_signature_file()) { - $location = make_request_directory() . '/target'; - $signaturefile->copy_content_to($location); - $info = [ - 'Name' => $imageinfo->signaturename, - 'Location' => $imageinfo->signaturelocation, - 'Reason' => $imageinfo->signaturereason, - 'ContactInfo' => $imageinfo->signaturecontactinfo - ]; - $pdf->setSignature('file://' . $location, '', $imageinfo->signaturepassword, '', 2, $info); - $pdf->setSignatureAppearance($this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - global $COURSE, $SITE; - - // Set the context. - if ($COURSE->id == $SITE->id) { - $context = \context_system::instance(); - } else { - $context = \context_course::instance($COURSE->id); - } - - if (!empty($this->get_data())) { - $imageinfo = json_decode($this->get_data()); - - $element = $mform->getElement('signaturename'); - $element->setValue($imageinfo->signaturename); - - $element = $mform->getElement('signaturepassword'); - $element->setValue($imageinfo->signaturepassword); - - $element = $mform->getElement('signaturelocation'); - $element->setValue($imageinfo->signaturelocation); - - $element = $mform->getElement('signaturereason'); - $element->setValue($imageinfo->signaturereason); - - $element = $mform->getElement('signaturecontactinfo'); - $element->setValue($imageinfo->signaturecontactinfo); - - if (!empty($imageinfo->signaturefilename)) { - if ($signaturefile = $this->get_signature_file()) { - $element = $mform->getElement('signaturefileid'); - $element->setValue($signaturefile->get_id()); - } - } - } - - // Editing existing instance - copy existing files into draft area. - $draftitemid = file_get_submitted_draft_itemid('digitalsignature'); - file_prepare_draft_area($draftitemid, $context->id, 'mod_customcert', 'signature', 0, - $this->signaturefilemanageroptions); - $element = $mform->getElement('digitalsignature'); - $element->setValue($draftitemid); - - parent::definition_after_data($mform); - } - - /** - * Return the list of possible images to use. - * - * @return array the list of images that can be used - */ - public static function get_signatures() { - global $COURSE; - - // Create file storage object. - $fs = get_file_storage(); - - // The array used to store the digital signatures. - $arrfiles = array(); - // Loop through the files uploaded in the system context. - if ($files = $fs->get_area_files(\context_system::instance()->id, 'mod_customcert', 'signature', false, - 'filename', false)) { - foreach ($files as $hash => $file) { - $arrfiles[$file->get_id()] = $file->get_filename(); - } - } - // Loop through the files uploaded in the course context. - if ($files = $fs->get_area_files(\context_course::instance($COURSE->id)->id, 'mod_customcert', 'signature', false, - 'filename', false)) { - foreach ($files as $hash => $file) { - $arrfiles[$file->get_id()] = $file->get_filename(); - } - } - - \core_collator::asort($arrfiles); - $arrfiles = array('0' => get_string('nosignature', 'customcertelement_digitalsignature')) + $arrfiles; - - return $arrfiles; - } - - /** - * Fetch stored file. - * - * @return \stored_file|bool stored_file instance if exists, false if not - */ - public function get_signature_file() { - $imageinfo = json_decode($this->get_data()); - - $fs = get_file_storage(); - - return $fs->get_file($imageinfo->signaturecontextid, 'mod_customcert', $imageinfo->signaturefilearea, - $imageinfo->signatureitemid, $imageinfo->signaturefilepath, $imageinfo->signaturefilename); - } -} diff --git a/element/digitalsignature/classes/privacy/provider.php b/element/digitalsignature/classes/privacy/provider.php deleted file mode 100644 index 6e46add..0000000 --- a/element/digitalsignature/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_digitalsignature. - * - * @package customcertelement_digitalsignature - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_digitalsignature\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_digitalsignature implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/digitalsignature/lang/en/customcertelement_digitalsignature.php b/element/digitalsignature/lang/en/customcertelement_digitalsignature.php deleted file mode 100644 index 81661f4..0000000 --- a/element/digitalsignature/lang/en/customcertelement_digitalsignature.php +++ /dev/null @@ -1,34 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_digitalsignature', language 'en'. - * - * @package customcertelement_digitalsignature - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['digitalsignature'] = 'Digital signature'; -$string['nosignature'] = 'No signature'; -$string['pluginname'] = 'Digital signature'; -$string['privacy:metadata'] = 'The Digital signature plugin does not store any personal data.'; -$string['signaturename'] = 'Signature name'; -$string['signaturepassword'] = 'Signature password'; -$string['signaturelocation'] = 'Signature location'; -$string['signaturereason'] = 'Signature reason'; -$string['signaturecontactinfo'] = 'Signature contact info'; -$string['uploaddigitalsignature'] = 'Upload digital signature'; diff --git a/element/digitalsignature/version.php b/element/digitalsignature/version.php deleted file mode 100644 index d78d440..0000000 --- a/element/digitalsignature/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the digital signature plugin. - * - * @package customcertelement_digitalsignature - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_digitalsignature'; diff --git a/element/grade/classes/element.php b/element/grade/classes/element.php deleted file mode 100644 index 9dd6f28..0000000 --- a/element/grade/classes/element.php +++ /dev/null @@ -1,218 +0,0 @@ -. - -/** - * This file contains the customcert element grade's core interaction API. - * - * @package customcertelement_grade - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_grade; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Grade - Course - */ -define('CUSTOMCERT_GRADE_COURSE', '0'); - -/** - * The customcert element grade's core interaction API. - * - * @package customcertelement_grade - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - global $COURSE; - - // Get the grade items we can display. - $gradeitems = array(); - $gradeitems[CUSTOMCERT_GRADE_COURSE] = get_string('coursegrade', 'customcertelement_grade'); - $gradeitems = $gradeitems + \mod_customcert\element_helper::get_grade_items($COURSE); - - // The grade items. - $mform->addElement('select', 'gradeitem', get_string('gradeitem', 'customcertelement_grade'), $gradeitems); - $mform->addHelpButton('gradeitem', 'gradeitem', 'customcertelement_grade'); - - // The grade format. - $mform->addElement('select', 'gradeformat', get_string('gradeformat', 'customcertelement_grade'), - self::get_grade_format_options()); - $mform->setType('gradeformat', PARAM_INT); - $mform->addHelpButton('gradeformat', 'gradeformat', 'customcertelement_grade'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data. - * @return string the json encoded array - */ - public function save_unique_data($data) { - // Array of data we will be storing in the database. - $arrtostore = array( - 'gradeitem' => $data->gradeitem, - 'gradeformat' => $data->gradeformat - ); - - // Encode these variables before saving into the DB. - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $courseid = \mod_customcert\element_helper::get_courseid($this->id); - - // Decode the information stored in the database. - $gradeinfo = json_decode($this->get_data()); - $gradeitem = $gradeinfo->gradeitem; - $gradeformat = $gradeinfo->gradeformat; - - // If we are previewing this certificate then just show a demonstration grade. - if ($preview) { - $courseitem = \grade_item::fetch_course_item($courseid); - $grade = grade_format_gradevalue('100', $courseitem, true, $gradeinfo->gradeformat);; - } else { - if ($gradeitem == CUSTOMCERT_GRADE_COURSE) { - $grade = \mod_customcert\element_helper::get_course_grade_info( - $courseid, - $gradeformat, - $user->id - ); - } else if (strpos($gradeitem, 'gradeitem:') === 0) { - $gradeitemid = substr($gradeitem, 10); - $grade = \mod_customcert\element_helper::get_grade_item_info( - $gradeitemid, - $gradeformat, - $user->id - ); - } else { - $grade = \mod_customcert\element_helper::get_mod_grade_info( - $gradeitem, - $gradeformat, - $user->id - ); - } - - if ($grade) { - $grade = $grade->get_displaygrade(); - } - } - - \mod_customcert\element_helper::render_content($pdf, $this, $grade); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - global $COURSE; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - // Decode the information stored in the database. - $gradeinfo = json_decode($this->get_data()); - - $courseitem = \grade_item::fetch_course_item($COURSE->id); - - $grade = grade_format_gradevalue('100', $courseitem, true, $gradeinfo->gradeformat); - - return \mod_customcert\element_helper::render_html_content($this, $grade); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - // Set the item and format for this element. - if (!empty($this->get_data())) { - $gradeinfo = json_decode($this->get_data()); - - $element = $mform->getElement('gradeitem'); - $element->setValue($gradeinfo->gradeitem); - - $element = $mform->getElement('gradeformat'); - $element->setValue($gradeinfo->gradeformat); - } - - parent::definition_after_data($mform); - } - - /** - * This function is responsible for handling the restoration process of the element. - * - * We will want to update the course module the grade element is pointing to as it will - * have changed in the course restore. - * - * @param \restore_customcert_activity_task $restore - */ - public function after_restore($restore) { - global $DB; - - $gradeinfo = json_decode($this->get_data()); - if ($newitem = \restore_dbops::get_backup_ids_record($restore->get_restoreid(), 'course_module', $gradeinfo->gradeitem)) { - $gradeinfo->gradeitem = $newitem->newitemid; - $DB->set_field('customcert_elements', 'data', $this->save_unique_data($gradeinfo), array('id' => $this->get_id())); - } - } - - /** - * Helper function to return all the possible grade formats. - * - * @return array returns an array of grade formats - */ - public static function get_grade_format_options() { - $gradeformat = array(); - $gradeformat[GRADE_DISPLAY_TYPE_REAL] = get_string('gradepoints', 'customcertelement_grade'); - $gradeformat[GRADE_DISPLAY_TYPE_PERCENTAGE] = get_string('gradepercent', 'customcertelement_grade'); - $gradeformat[GRADE_DISPLAY_TYPE_LETTER] = get_string('gradeletter', 'customcertelement_grade'); - - return $gradeformat; - } -} diff --git a/element/grade/classes/privacy/provider.php b/element/grade/classes/privacy/provider.php deleted file mode 100644 index 2f6b295..0000000 --- a/element/grade/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_grade. - * - * @package customcertelement_grade - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_grade\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_grade implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/grade/lang/en/customcertelement_grade.php b/element/grade/lang/en/customcertelement_grade.php deleted file mode 100644 index 9039329..0000000 --- a/element/grade/lang/en/customcertelement_grade.php +++ /dev/null @@ -1,36 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_grade', language 'en'. - * - * @package customcertelement_grade - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['coursegrade'] = 'Course grade'; -$string['gradeitem'] = 'Grade item'; -$string['gradeitem_help'] = 'The grade item you wish to display the grade of.'; -$string['gradeformat'] = 'Grade format'; -$string['gradeformat_help'] = 'The format you wish to use when displaying the grade.'; -$string['gradeitem'] = 'Grade item'; -$string['gradepercent'] = 'Percentage'; -$string['gradepoints'] = 'Points'; -$string['gradeletter'] = 'Letter'; -$string['pluginname'] = 'Grade'; -$string['previewgrade'] = 'Preview grade'; -$string['privacy:metadata'] = 'The Grade plugin does not store any personal data.'; diff --git a/element/grade/version.php b/element/grade/version.php deleted file mode 100644 index 49c2cbe..0000000 --- a/element/grade/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the grade plugin. - * - * @package customcertelement_grade - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_grade'; diff --git a/element/gradeitemname/classes/element.php b/element/gradeitemname/classes/element.php deleted file mode 100644 index 3ffc4d8..0000000 --- a/element/gradeitemname/classes/element.php +++ /dev/null @@ -1,149 +0,0 @@ -. - -/** - * This file contains the customcert element gradeitemname's core interaction API. - * - * @package customcertelement_gradeitemname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_gradeitemname; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element gradeitemname's core interaction API. - * - * @package customcertelement_gradeitemname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - global $COURSE; - - $mform->addElement('select', 'gradeitem', get_string('gradeitem', 'customcertelement_gradeitemname'), - \mod_customcert\element_helper::get_grade_items($COURSE)); - $mform->addHelpButton('gradeitem', 'gradeitem', 'customcertelement_gradeitemname'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - if (!empty($data->gradeitem)) { - return $data->gradeitem; - } - - return ''; - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - // Check that the grade item is not empty. - if (!empty($this->get_data())) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_grade_item_name()); - } - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - // Check that the grade item is not empty. - if (!empty($this->get_data())) { - return \mod_customcert\element_helper::render_html_content($this, $this->get_grade_item_name()); - } - - return ''; - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('gradeitem'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * Helper function that returns the grade item name. - * - * @return string - */ - protected function get_grade_item_name() : string { - global $DB; - - $gradeitem = $this->get_data(); - - if (strpos($gradeitem, 'gradeitem:') === 0) { - $gradeitemid = substr($gradeitem, 10); - $gradeitem = \grade_item::fetch(['id' => $gradeitemid]); - - return $gradeitem->get_name(); - } else { - if (!$cm = $DB->get_record('course_modules', array('id' => $gradeitem))) { - return ''; - } - - if (!$module = $DB->get_record('modules', array('id' => $cm->module))) { - return ''; - } - - $params = [ - 'itemtype' => 'mod', - 'itemmodule' => $module->name, - 'iteminstance' => $cm->instance, - 'courseid' => $cm->course, - 'itemnumber' => 0 - ]; - - $gradeitem = \grade_item::fetch($params); - - return $gradeitem->get_name(); - } - } -} diff --git a/element/gradeitemname/classes/privacy/provider.php b/element/gradeitemname/classes/privacy/provider.php deleted file mode 100644 index 8cf3b95..0000000 --- a/element/gradeitemname/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_gradeitemname. - * - * @package customcertelement_gradeitemname - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_gradeitemname\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_gradeitemname implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/gradeitemname/lang/en/customcertelement_gradeitemname.php b/element/gradeitemname/lang/en/customcertelement_gradeitemname.php deleted file mode 100644 index f76c40f..0000000 --- a/element/gradeitemname/lang/en/customcertelement_gradeitemname.php +++ /dev/null @@ -1,28 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_gradeitemname', language 'en'. - * - * @package customcertelement_gradeitemname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['gradeitem'] = 'Grade item'; -$string['gradeitem_help'] = 'The name of the selected item will be displayed on the PDF.'; -$string['pluginname'] = 'Grade item name'; -$string['privacy:metadata'] = 'The Grade item name plugin does not store any personal data.'; diff --git a/element/gradeitemname/version.php b/element/gradeitemname/version.php deleted file mode 100644 index a802b9c..0000000 --- a/element/gradeitemname/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the gradeitemname plugin. - * - * @package customcertelement_gradeitemname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_gradeitemname'; diff --git a/element/image/classes/element.php b/element/image/classes/element.php deleted file mode 100644 index 5323273..0000000 --- a/element/image/classes/element.php +++ /dev/null @@ -1,457 +0,0 @@ -. - -/** - * This file contains the customcert element image's core interaction API. - * - * @package customcertelement_image - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_image; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element image's core interaction API. - * - * @package customcertelement_image - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * @var array The file manager options. - */ - protected $filemanageroptions = array(); - - /** - * Constructor. - * - * @param \stdClass $element the element data - */ - public function __construct($element) { - global $COURSE; - - $this->filemanageroptions = array( - 'maxbytes' => $COURSE->maxbytes, - 'subdirs' => 1, - 'accepted_types' => 'image' - ); - - parent::__construct($element); - } - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('select', 'fileid', get_string('image', 'customcertelement_image'), self::get_images()); - - $mform->addElement('text', 'width', get_string('width', 'customcertelement_image'), array('size' => 10)); - $mform->setType('width', PARAM_INT); - $mform->setDefault('width', 0); - $mform->addHelpButton('width', 'width', 'customcertelement_image'); - - $mform->addElement('text', 'height', get_string('height', 'customcertelement_image'), array('size' => 10)); - $mform->setType('height', PARAM_INT); - $mform->setDefault('height', 0); - $mform->addHelpButton('height', 'height', 'customcertelement_image'); - - $alphachannelvalues = [ - '0' => 0, - '0.1' => 0.1, - '0.2' => 0.2, - '0.3' => 0.3, - '0.4' => 0.4, - '0.5' => 0.5, - '0.6' => 0.6, - '0.7' => 0.7, - '0.8' => 0.8, - '0.9' => 0.9, - '1' => 1 - ]; - $mform->addElement('select', 'alphachannel', get_string('alphachannel', 'customcertelement_image'), $alphachannelvalues); - $mform->setType('alphachannel', PARAM_FLOAT); - $mform->setDefault('alphachannel', 1); - $mform->addHelpButton('alphachannel', 'alphachannel', 'customcertelement_image'); - - if (get_config('customcert', 'showposxy')) { - \mod_customcert\element_helper::render_form_element_position($mform); - } - - $mform->addElement('filemanager', 'customcertimage', get_string('uploadimage', 'customcert'), '', - $this->filemanageroptions); - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - $errors = array(); - - // Check if width is not set, or not numeric or less than 0. - if ((!isset($data['width'])) || (!is_numeric($data['width'])) || ($data['width'] < 0)) { - $errors['width'] = get_string('invalidwidth', 'customcertelement_image'); - } - - // Check if height is not set, or not numeric or less than 0. - if ((!isset($data['height'])) || (!is_numeric($data['height'])) || ($data['height'] < 0)) { - $errors['height'] = get_string('invalidheight', 'customcertelement_image'); - } - - // Validate the position. - if (get_config('customcert', 'showposxy')) { - $errors += \mod_customcert\element_helper::validate_form_element_position($data); - } - - return $errors; - } - - /** - * Handles saving the form elements created by this element. - * Can be overridden if more functionality is needed. - * - * @param \stdClass $data the form data - * @return bool true of success, false otherwise. - */ - public function save_form_elements($data) { - global $COURSE, $SITE; - - // Set the context. - if ($COURSE->id == $SITE->id) { - $context = \context_system::instance(); - } else { - $context = \context_course::instance($COURSE->id); - } - - // Handle file uploads. - \mod_customcert\certificate::upload_files($data->customcertimage, $context->id); - - return parent::save_form_elements($data); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - $arrtostore = [ - 'width' => !empty($data->width) ? (int) $data->width : 0, - 'height' => !empty($data->height) ? (int) $data->height : 0 - ]; - - if (isset($data->alphachannel)) { - $arrtostore['alphachannel'] = (float) $data->alphachannel; - } - - if (!empty($data->fileid)) { - // Array of data we will be storing in the database. - $fs = get_file_storage(); - if ($file = $fs->get_file_by_id($data->fileid)) { - $arrtostore += [ - 'contextid' => $file->get_contextid(), - 'filearea' => $file->get_filearea(), - 'itemid' => $file->get_itemid(), - 'filepath' => $file->get_filepath(), - 'filename' => $file->get_filename(), - ]; - } - } - - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - // If there is no file, we have nothing to display. - if (empty($imageinfo->filename)) { - return; - } - - if ($file = $this->get_file()) { - $location = make_request_directory() . '/target'; - $file->copy_content_to($location); - - // Check if the alpha channel is set, if it is, use it. - if (isset($imageinfo->alphachannel)) { - $pdf->SetAlpha($imageinfo->alphachannel); - } - - $mimetype = $file->get_mimetype(); - if ($mimetype == 'image/svg+xml') { - $pdf->ImageSVG($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } else { - $pdf->Image($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } - - // Restore to full opacity. - $pdf->SetAlpha(1); - } - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return ''; - } - - $imageinfo = json_decode($this->get_data()); - - // If there is no file, we have nothing to display. - if (empty($imageinfo->filename)) { - return ''; - } - - // Get the image. - $fs = get_file_storage(); - if ($file = $fs->get_file($imageinfo->contextid, 'mod_customcert', $imageinfo->filearea, $imageinfo->itemid, - $imageinfo->filepath, $imageinfo->filename)) { - $url = \moodle_url::make_pluginfile_url($file->get_contextid(), 'mod_customcert', 'image', $file->get_itemid(), - $file->get_filepath(), $file->get_filename()); - $fileimageinfo = $file->get_imageinfo(); - $whratio = $fileimageinfo['width'] / $fileimageinfo['height']; - // The size of the images to use in the CSS style. - $style = ''; - if ($imageinfo->width === 0 && $imageinfo->height === 0) { - $style .= 'width: ' . $fileimageinfo['width'] . 'px; '; - $style .= 'height: ' . $fileimageinfo['height'] . 'px'; - } else if ($imageinfo->width === 0) { // Then the height must be set. - // We must get the width based on the height to keep the ratio. - $style .= 'width: ' . ($imageinfo->height * $whratio) . 'mm; '; - $style .= 'height: ' . $imageinfo->height . 'mm'; - } else if ($imageinfo->height === 0) { // Then the width must be set. - $style .= 'width: ' . $imageinfo->width . 'mm; '; - // We must get the height based on the width to keep the ratio. - $style .= 'height: ' . ($imageinfo->width / $whratio) . 'mm'; - } else { // Must both be set. - $style .= 'width: ' . $imageinfo->width . 'mm; '; - $style .= 'height: ' . $imageinfo->height . 'mm'; - } - - return \html_writer::tag('img', '', array('src' => $url, 'style' => $style)); - } - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - global $COURSE, $SITE; - - // Set the image, width, height and alpha channel for this element. - if (!empty($this->get_data())) { - $imageinfo = json_decode($this->get_data()); - if (!empty($imageinfo->filename)) { - if ($file = $this->get_file()) { - $element = $mform->getElement('fileid'); - $element->setValue($file->get_id()); - } - } - - if (isset($imageinfo->width) && $mform->elementExists('width')) { - $element = $mform->getElement('width'); - $element->setValue($imageinfo->width); - } - - if (isset($imageinfo->height) && $mform->elementExists('height')) { - $element = $mform->getElement('height'); - $element->setValue($imageinfo->height); - } - - if (isset($imageinfo->alphachannel) && $mform->elementExists('alphachannel')) { - $element = $mform->getElement('alphachannel'); - $element->setValue($imageinfo->alphachannel); - } - } - - // Set the context. - if ($COURSE->id == $SITE->id) { - $context = \context_system::instance(); - } else { - $context = \context_course::instance($COURSE->id); - } - - // Editing existing instance - copy existing files into draft area. - $draftitemid = file_get_submitted_draft_itemid('customcertimage'); - file_prepare_draft_area($draftitemid, $context->id, 'mod_customcert', 'image', 0, $this->filemanageroptions); - $element = $mform->getElement('customcertimage'); - $element->setValue($draftitemid); - - parent::definition_after_data($mform); - } - - /** - * This function is responsible for handling the restoration process of the element. - * - * We will want to update the file's pathname hash. - * - * @param \restore_customcert_activity_task $restore - */ - public function after_restore($restore) { - global $DB; - - // Get the current data we have stored for this element. - $elementinfo = json_decode($this->get_data()); - - // Update the context. - $elementinfo->contextid = \context_course::instance($restore->get_courseid())->id; - - // Encode again before saving. - $elementinfo = json_encode($elementinfo); - - // Perform the update. - $DB->set_field('customcert_elements', 'data', $elementinfo, array('id' => $this->get_id())); - } - - /** - * Fetch stored file. - * - * @return \stored_file|bool stored_file instance if exists, false if not - */ - public function get_file() { - $imageinfo = json_decode($this->get_data()); - - $fs = get_file_storage(); - - return $fs->get_file($imageinfo->contextid, 'mod_customcert', $imageinfo->filearea, $imageinfo->itemid, - $imageinfo->filepath, $imageinfo->filename); - } - - /** - * Return the list of possible images to use. - * - * @return array the list of images that can be used - */ - public static function get_images() { - global $COURSE; - - // Create file storage object. - $fs = get_file_storage(); - - // The array used to store the images. - $arrfiles = array(); - // Loop through the files uploaded in the system context. - if ($files = $fs->get_area_files(\context_system::instance()->id, 'mod_customcert', 'image', false, 'filename', false)) { - foreach ($files as $hash => $file) { - $arrfiles[$file->get_id()] = get_string('systemimage', 'customcertelement_image', $file->get_filename()); - } - } - // Loop through the files uploaded in the course context. - if ($files = $fs->get_area_files(\context_course::instance($COURSE->id)->id, 'mod_customcert', 'image', false, - 'filename', false)) { - foreach ($files as $hash => $file) { - $arrfiles[$file->get_id()] = get_string('courseimage', 'customcertelement_image', $file->get_filename()); - } - } - - \core_collator::asort($arrfiles); - $arrfiles = array('0' => get_string('noimage', 'customcert')) + $arrfiles; - - return $arrfiles; - } - - /** - * This handles copying data from another element of the same type. - * - * @param \stdClass $data the form data - * @return bool returns true if the data was copied successfully, false otherwise - */ - public function copy_element($data) { - global $COURSE, $DB, $SITE; - - $imagedata = json_decode($data->data); - - // If we are in the site context we don't have to do anything, the image is already there. - if ($COURSE->id == $SITE->id) { - return true; - } - - $coursecontext = \context_course::instance($COURSE->id); - $systemcontext = \context_system::instance(); - - $fs = get_file_storage(); - - // Check that a file has been selected. - if (isset($imagedata->filearea)) { - // If the course file doesn't exist, copy the system file to the course context. - if (!$coursefile = $fs->get_file( - $coursecontext->id, - 'mod_customcert', - $imagedata->filearea, - $imagedata->itemid, - $imagedata->filepath, - $imagedata->filename - )) { - $systemfile = $fs->get_file( - $systemcontext->id, - 'mod_customcert', - $imagedata->filearea, - $imagedata->itemid, - $imagedata->filepath, - $imagedata->filename - ); - - // We want to update the context of the file if it doesn't exist in the course context. - $fieldupdates = [ - 'contextid' => $coursecontext->id - ]; - $coursefile = $fs->create_file_from_storedfile($fieldupdates, $systemfile); - } - - // Set the image to the copied file in the course. - $imagedata->fileid = $coursefile->get_id(); - $DB->set_field('customcert_elements', 'data', $this->save_unique_data($imagedata), ['id' => $this->get_id()]); - } - - return true; - } -} diff --git a/element/image/classes/privacy/provider.php b/element/image/classes/privacy/provider.php deleted file mode 100644 index f800d6c..0000000 --- a/element/image/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_image. - * - * @package customcertelement_image - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_image\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_image implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/image/db/upgrade.php b/element/image/db/upgrade.php deleted file mode 100644 index ec5db8d..0000000 --- a/element/image/db/upgrade.php +++ /dev/null @@ -1,66 +0,0 @@ -. - -/** - * Customcert image element upgrade code. - * - * @package customcertelement_image - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die; - -/** - * Customcert image element upgrade code. - * - * @param int $oldversion the version we are upgrading from - * @return bool always true - */ -function xmldb_customcertelement_image_upgrade($oldversion) { - global $DB; - - if ($oldversion < 2016120501) { - // Go through each 'image' element and update the file stored information. - if ($images = $DB->get_records_select('customcert_elements', $DB->sql_compare_text('element') . ' = \'image\'')) { - // Create a file storage instance we are going to use to create pathname hashes. - $fs = get_file_storage(); - // Go through and update the details. - foreach ($images as $image) { - // Get the current data we have stored for this element. - $elementinfo = json_decode($image->data); - if ($file = $fs->get_file_by_hash($elementinfo->pathnamehash)) { - $arrtostore = array( - 'contextid' => $file->get_contextid(), - 'filearea' => $file->get_filearea(), - 'itemid' => $file->get_itemid(), - 'filepath' => $file->get_filepath(), - 'filename' => $file->get_filename(), - 'width' => (int) $elementinfo->width, - 'height' => (int) $elementinfo->height - ); - $arrtostore = json_encode($arrtostore); - $DB->set_field('customcert_elements', 'data', $arrtostore, array('id' => $image->id)); - } - } - } - - // Savepoint reached. - upgrade_plugin_savepoint(true, 2016120501, 'customcertelement', 'image'); - } - - return true; -} diff --git a/element/image/lang/en/customcertelement_image.php b/element/image/lang/en/customcertelement_image.php deleted file mode 100644 index 8842250..0000000 --- a/element/image/lang/en/customcertelement_image.php +++ /dev/null @@ -1,37 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_image', language 'en'. - * - * @package customcertelement_image - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['alphachannel'] = 'Alpha channel'; -$string['alphachannel_help'] = 'This value determines how transparent the image is. You can set the alpha channel from 0 (fully transparent) to 1 (fully opaque).'; -$string['courseimage'] = 'Course image: {$a}'; -$string['height'] = 'Height'; -$string['height_help'] = 'Height of the image in mm. If equal to zero, it is automatically calculated.'; -$string['image'] = 'Image'; -$string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.'; -$string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.'; -$string['pluginname'] = 'Image'; -$string['privacy:metadata'] = 'The Image plugin does not store any personal data.'; -$string['systemimage'] = 'Site image: {$a}'; -$string['width'] = 'Width'; -$string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.'; diff --git a/element/image/version.php b/element/image/version.php deleted file mode 100644 index 56403c9..0000000 --- a/element/image/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the image plugin. - * - * @package customcertelement_image - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_image'; diff --git a/element/qrcode/classes/element.php b/element/qrcode/classes/element.php deleted file mode 100644 index 0453ce4..0000000 --- a/element/qrcode/classes/element.php +++ /dev/null @@ -1,208 +0,0 @@ -. - -/** - * This file contains the customcert element QR code's core interaction API. - * - * @package customcertelement_qrcode - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_qrcode; - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir . '/tcpdf/tcpdf_barcodes_2d.php'); - -/** - * The customcert element QR code's core interaction API. - * - * @package customcertelement_qrcode - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * @var string The barcode type. - */ - const BARCODETYPE = 'QRCODE'; - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - \mod_customcert\element_helper::render_form_element_width($mform); - - $mform->addElement('text', 'height', get_string('height', 'customcertelement_qrcode'), array('size' => 10)); - $mform->setType('height', PARAM_INT); - $mform->setDefault('height', 0); - $mform->addHelpButton('height', 'height', 'customcertelement_qrcode'); - - if ($this->showposxy) { - \mod_customcert\element_helper::render_form_element_position($mform); - } - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - $errors = []; - - // Check if height is not set, or not numeric or less than 0. - if ((!isset($data['height'])) || (!is_numeric($data['height'])) || ($data['height'] <= 0)) { - $errors['height'] = get_string('invalidheight', 'mod_customcert'); - } - - if ((!isset($data['width'])) || (!is_numeric($data['width'])) || ($data['width'] <= 0)) { - $errors['width'] = get_string('invalidwidth', 'mod_customcert'); - } - - if ($this->showposxy) { - $errors += \mod_customcert\element_helper::validate_form_element_position($data); - } - - $errors += \mod_customcert\element_helper::validate_form_element_width($data); - - return $errors; - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - $arrtostore = [ - 'width' => !empty($data->width) ? (int)$data->width : 0, - 'height' => !empty($data->height) ? (int)$data->height : 0 - ]; - - return json_encode($arrtostore); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - parent::definition_after_data($mform); - - // Set the image, width, height and alpha channel for this element. - if (!empty($this->get_data())) { - $imageinfo = json_decode($this->get_data()); - - if (!empty($imageinfo->height)) { - $element = $mform->getElement('height'); - $element->setValue($imageinfo->height); - } - } - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $DB; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - if ($preview) { - // Generate the URL to verify this. - $qrcodeurl = new \moodle_url('/'); - $qrcodeurl = $qrcodeurl->out(false); - } else { - // Get the information we need. - $sql = "SELECT c.id, ct.contextid, ci.code - FROM {customcert_issues} ci - JOIN {customcert} c - ON ci.customcertid = c.id - JOIN {customcert_templates} ct - ON c.templateid = ct.id - JOIN {customcert_pages} cp - ON cp.templateid = ct.id - WHERE ci.userid = :userid - AND cp.id = :pageid"; - - // Now we can get the issue for this user. - $issue = $DB->get_record_sql($sql, array('userid' => $user->id, 'pageid' => $this->get_pageid()), - '*', MUST_EXIST); - $code = $issue->code; - - // Generate the URL to verify this. - $qrcodeurl = new \moodle_url('/mod/customcert/verify_certificate.php', - [ - 'contextid' => $issue->contextid, - 'code' => $code, - 'qrcode' => 1 - ] - ); - $qrcodeurl = $qrcodeurl->out(false); - } - - $barcode = new \TCPDF2DBarcode($qrcodeurl, self::BARCODETYPE); - $image = $barcode->getBarcodePngData($imageinfo->width, $imageinfo->height); - - $location = make_request_directory() . '/target'; - file_put_contents($location, $image); - - $pdf->Image($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - $qrcodeurl = new \moodle_url('/'); - $qrcodeurl = $qrcodeurl->out(false); - - $barcode = new \TCPDF2DBarcode($qrcodeurl, self::BARCODETYPE); - return $barcode->getBarcodeHTML($imageinfo->width / 10, $imageinfo->height / 10); - } -} diff --git a/element/qrcode/classes/privacy/provider.php b/element/qrcode/classes/privacy/provider.php deleted file mode 100644 index e4a0ee1..0000000 --- a/element/qrcode/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_qrcode. - * - * @package customcertelement_qrcode - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_qrcode\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_qrcode implementing null_provider. - * - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/qrcode/lang/en/customcertelement_qrcode.php b/element/qrcode/lang/en/customcertelement_qrcode.php deleted file mode 100644 index ebca7b5..0000000 --- a/element/qrcode/lang/en/customcertelement_qrcode.php +++ /dev/null @@ -1,30 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_qrcode', language 'en'. - * - * @package customcertelement_qrcode - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['height'] = 'Height'; -$string['height_help'] = 'Height help'; -$string['pluginname'] = 'QR code'; -$string['privacy:metadata'] = 'The QR code plugin does not store any personal data.'; -$string['width'] = 'Width'; -$string['width_help'] = 'width help'; diff --git a/element/qrcode/version.php b/element/qrcode/version.php deleted file mode 100644 index 060dc04..0000000 --- a/element/qrcode/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the QR code plugin. - * - * @package customcertelement_qrcode - * @copyright 2019 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_qrcode'; diff --git a/element/studentname/classes/element.php b/element/studentname/classes/element.php deleted file mode 100644 index c70e20a..0000000 --- a/element/studentname/classes/element.php +++ /dev/null @@ -1,62 +0,0 @@ -. - -/** - * This file contains the customcert element studentname's core interaction API. - * - * @package customcertelement_studentname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_studentname; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element studentname's core interaction API. - * - * @package customcertelement_studentname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - \mod_customcert\element_helper::render_content($pdf, $this, fullname($user)); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - global $USER; - - return \mod_customcert\element_helper::render_html_content($this, fullname($USER)); - } -} diff --git a/element/studentname/classes/privacy/provider.php b/element/studentname/classes/privacy/provider.php deleted file mode 100644 index a7ae402..0000000 --- a/element/studentname/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_studentname. - * - * @package customcertelement_studentname - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_studentname\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_studentname implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/studentname/lang/en/customcertelement_studentname.php b/element/studentname/lang/en/customcertelement_studentname.php deleted file mode 100644 index 9e6fd3f..0000000 --- a/element/studentname/lang/en/customcertelement_studentname.php +++ /dev/null @@ -1,26 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_studentname', language 'en'. - * - * @package customcertelement_studentname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Student name'; -$string['privacy:metadata'] = 'The Student name plugin does not store any personal data.'; diff --git a/element/studentname/version.php b/element/studentname/version.php deleted file mode 100644 index ea14613..0000000 --- a/element/studentname/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the studentname plugin. - * - * @package customcertelement_studentname - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_studentname'; diff --git a/element/teachername/classes/element.php b/element/teachername/classes/element.php deleted file mode 100644 index 8432e9d..0000000 --- a/element/teachername/classes/element.php +++ /dev/null @@ -1,135 +0,0 @@ -. - -/** - * This file contains the customcert element teachername's core interaction API. - * - * @package customcertelement_teachername - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_teachername; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element teachername's core interaction API. - * - * @package customcertelement_teachername - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('select', 'teacher', get_string('teacher', 'customcertelement_teachername'), - $this->get_list_of_teachers()); - $mform->addHelpButton('teacher', 'teacher', 'customcertelement_teachername'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - if (!empty($data->teacher)) { - return $data->teacher; - } - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $DB; - - $teacher = $DB->get_record('user', array('id' => $this->get_data())); - $teachername = fullname($teacher); - - \mod_customcert\element_helper::render_content($pdf, $this, $teachername); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - global $DB; - - $teacher = $DB->get_record('user', array('id' => $this->get_data())); - $teachername = fullname($teacher); - - return \mod_customcert\element_helper::render_html_content($this, $teachername); - } - - /** - * Helper function to return the teachers for this course. - * - * @return array the list of teachers - */ - protected function get_list_of_teachers() { - global $PAGE; - - // Return early if we are in a site template. - if ($PAGE->context->id == \context_system::instance()->id) { - return []; - } - - // The list of teachers to return. - $teachers = array(); - - // Now return all users who can manage the customcert in this context. - if ($users = get_enrolled_users($PAGE->context, 'mod/customcert:manage')) { - foreach ($users as $user) { - $teachers[$user->id] = fullname($user); - } - } - - return $teachers; - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('teacher'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } -} diff --git a/element/teachername/classes/privacy/provider.php b/element/teachername/classes/privacy/provider.php deleted file mode 100644 index 800c91f..0000000 --- a/element/teachername/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_teachername. - * - * @package customcertelement_teachername - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_teachername\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_teachername implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/teachername/lang/en/customcertelement_teachername.php b/element/teachername/lang/en/customcertelement_teachername.php deleted file mode 100644 index 48265bc..0000000 --- a/element/teachername/lang/en/customcertelement_teachername.php +++ /dev/null @@ -1,28 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_teachername', language 'en'. - * - * @package customcertelement_teachername - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Teacher name'; -$string['privacy:metadata'] = 'The Teacher name plugin does not store any personal data.'; -$string['teacher'] = 'Teacher'; -$string['teacher_help'] = 'This is the teacher name that will be displayed.'; diff --git a/element/teachername/version.php b/element/teachername/version.php deleted file mode 100644 index f32baa1..0000000 --- a/element/teachername/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the teachername plugin. - * - * @package customcertelement_teachername - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_teachername'; diff --git a/element/text/classes/element.php b/element/text/classes/element.php deleted file mode 100644 index 0f2adf9..0000000 --- a/element/text/classes/element.php +++ /dev/null @@ -1,107 +0,0 @@ -. - -/** - * This file contains the customcert element text's core interaction API. - * - * @package customcertelement_text - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_text; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element text's core interaction API. - * - * @package customcertelement_text - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('textarea', 'text', get_string('text', 'customcertelement_text')); - $mform->setType('text', PARAM_RAW); - $mform->addHelpButton('text', 'text', 'customcertelement_text'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - return $data->text; - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_text()); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - return \mod_customcert\element_helper::render_html_content($this, $this->get_text()); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('text'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * Helper function that returns the text. - * - * @return string - */ - protected function get_text() : string { - $context = \mod_customcert\element_helper::get_context($this->get_id()); - return format_text($this->get_data(), FORMAT_HTML, ['context' => $context]); - } -} diff --git a/element/text/classes/privacy/provider.php b/element/text/classes/privacy/provider.php deleted file mode 100644 index 19ca3e3..0000000 --- a/element/text/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_text. - * - * @package customcertelement_text - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_text\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_text implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/text/lang/en/customcertelement_text.php b/element/text/lang/en/customcertelement_text.php deleted file mode 100644 index 077b85a..0000000 --- a/element/text/lang/en/customcertelement_text.php +++ /dev/null @@ -1,28 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_text', language 'en'. - * - * @package customcertelement_text - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'Text'; -$string['privacy:metadata'] = 'The Text plugin does not store any personal data.'; -$string['text'] = 'Text'; -$string['text_help'] = 'This is the text that will display on the PDF.'; diff --git a/element/text/version.php b/element/text/version.php deleted file mode 100644 index 0f10991..0000000 --- a/element/text/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the text plugin. - * - * @package customcertelement_text - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_text'; diff --git a/element/userfield/classes/element.php b/element/userfield/classes/element.php deleted file mode 100644 index 5e91637..0000000 --- a/element/userfield/classes/element.php +++ /dev/null @@ -1,166 +0,0 @@ -. - -/** - * This file contains the customcert element userfield's core interaction API. - * - * @package customcertelement_userfield - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_userfield; - -use core_user\fields; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element userfield's core interaction API. - * - * @package customcertelement_userfield - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - // Get the user profile fields. - $userfields = array( - 'firstname' => fields::get_display_name('firstname'), - 'lastname' => fields::get_display_name('lastname'), - 'username' => fields::get_display_name('username'), - 'email' => fields::get_display_name('email'), - 'city' => fields::get_display_name('city'), - 'country' => fields::get_display_name('country'), - 'url' => fields::get_display_name('url'), - 'skype' => fields::get_display_name('skype'), - 'idnumber' => fields::get_display_name('idnumber'), - 'institution' => fields::get_display_name('institution'), - 'department' => fields::get_display_name('department'), - 'phone1' => fields::get_display_name('phone1'), - 'phone2' => fields::get_display_name('phone2'), - 'address' => fields::get_display_name('address') - ); - // Get the user custom fields. - $arrcustomfields = \availability_profile\condition::get_custom_profile_fields(); - $customfields = array(); - foreach ($arrcustomfields as $key => $customfield) { - $customfields[$customfield->id] = $customfield->name; - } - // Combine the two. - $fields = $userfields + $customfields; - \core_collator::asort($fields); - - // Create the select box where the user field is selected. - $mform->addElement('select', 'userfield', get_string('userfield', 'customcertelement_userfield'), $fields); - $mform->setType('userfield', PARAM_ALPHANUM); - $mform->addHelpButton('userfield', 'userfield', 'customcertelement_userfield'); - - parent::render_form_elements($mform); - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the text - */ - public function save_unique_data($data) { - return $data->userfield; - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - \mod_customcert\element_helper::render_content($pdf, $this, $this->get_user_field_value($user, $preview)); - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - */ - public function render_html() { - global $USER; - - return \mod_customcert\element_helper::render_html_content($this, $this->get_user_field_value($USER, true)); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - if (!empty($this->get_data())) { - $element = $mform->getElement('userfield'); - $element->setValue($this->get_data()); - } - parent::definition_after_data($mform); - } - - /** - * Helper function that returns the text. - * - * @param \stdClass $user the user we are rendering this for - * @param bool $preview Is this a preview? - * @return string - */ - protected function get_user_field_value(\stdClass $user, bool $preview) : string { - global $CFG, $DB; - - // The user field to display. - $field = $this->get_data(); - // The value to display - we always want to show a value here so it can be repositioned. - if ($preview) { - $value = $field; - } else { - $value = ''; - } - if (is_number($field)) { // Must be a custom user profile field. - if ($field = $DB->get_record('user_info_field', array('id' => $field))) { - // Found the field name, let's update the value to display. - $value = $field->name; - $file = $CFG->dirroot . '/user/profile/field/' . $field->datatype . '/field.class.php'; - if (file_exists($file)) { - require_once($CFG->dirroot . '/user/profile/lib.php'); - require_once($file); - $class = "profile_field_{$field->datatype}"; - $field = new $class($field->id, $user->id); - $value = $field->display_data(); - } - } - } else if (!empty($user->$field)) { // Field in the user table. - $value = $user->$field; - } - - $context = \mod_customcert\element_helper::get_context($this->get_id()); - return format_string($value, true, ['context' => $context]); - } -} diff --git a/element/userfield/classes/privacy/provider.php b/element/userfield/classes/privacy/provider.php deleted file mode 100644 index 4669a86..0000000 --- a/element/userfield/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_userfield. - * - * @package customcertelement_userfield - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_userfield\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_userfield implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/userfield/lang/en/customcertelement_userfield.php b/element/userfield/lang/en/customcertelement_userfield.php deleted file mode 100644 index 7b3cb44..0000000 --- a/element/userfield/lang/en/customcertelement_userfield.php +++ /dev/null @@ -1,28 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_userfield', language 'en'. - * - * @package customcertelement_userfield - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'User field'; -$string['privacy:metadata'] = 'The User field plugin does not store any personal data.'; -$string['userfield'] = 'User field'; -$string['userfield_help'] = 'This is the user field that will be displayed on the PDF.'; diff --git a/element/userfield/version.php b/element/userfield/version.php deleted file mode 100644 index 98be1ac..0000000 --- a/element/userfield/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the userfield plugin. - * - * @package customcertelement_userfield - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_userfield'; diff --git a/element/userpicture/classes/element.php b/element/userpicture/classes/element.php deleted file mode 100644 index 898bdc4..0000000 --- a/element/userpicture/classes/element.php +++ /dev/null @@ -1,209 +0,0 @@ -. - -/** - * This file contains the customcert element userpicture's core interaction API. - * - * @package customcertelement_userpicture - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_userpicture; - -defined('MOODLE_INTERNAL') || die(); - -/** - * The customcert element userpicture's core interaction API. - * - * @package customcertelement_userpicture - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class element extends \mod_customcert\element { - - /** - * This function renders the form elements when adding a customcert element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function render_form_elements($mform) { - $mform->addElement('text', 'width', get_string('width', 'customcertelement_userpicture'), array('size' => 10)); - $mform->setType('width', PARAM_INT); - $mform->setDefault('width', 0); - $mform->addHelpButton('width', 'width', 'customcertelement_userpicture'); - - $mform->addElement('text', 'height', get_string('height', 'customcertelement_userpicture'), array('size' => 10)); - $mform->setType('height', PARAM_INT); - $mform->setDefault('height', 0); - $mform->addHelpButton('height', 'height', 'customcertelement_userpicture'); - - if (get_config('customcert', 'showposxy')) { - \mod_customcert\element_helper::render_form_element_position($mform); - } - } - - /** - * Performs validation on the element values. - * - * @param array $data the submitted data - * @param array $files the submitted files - * @return array the validation errors - */ - public function validate_form_elements($data, $files) { - // Array to return the errors. - $errors = array(); - - // Check if width is not set, or not numeric or less than 0. - if ((!isset($data['width'])) || (!is_numeric($data['width'])) || ($data['width'] < 0)) { - $errors['width'] = get_string('invalidwidth', 'customcertelement_userpicture'); - } - - // Check if height is not set, or not numeric or less than 0. - if ((!isset($data['height'])) || (!is_numeric($data['height'])) || ($data['height'] < 0)) { - $errors['height'] = get_string('invalidheight', 'customcertelement_userpicture'); - } - - // Validate the position. - if (get_config('customcert', 'showposxy')) { - $errors += \mod_customcert\element_helper::validate_form_element_position($data); - } - - return $errors; - } - - /** - * This will handle how form data will be saved into the data column in the - * customcert_elements table. - * - * @param \stdClass $data the form data - * @return string the json encoded array - */ - public function save_unique_data($data) { - // Array of data we will be storing in the database. - $arrtostore = array( - 'width' => (int) $data->width, - 'height' => (int) $data->height - ); - - return json_encode($arrtostore); - } - - /** - * Handles rendering the element on the pdf. - * - * @param \pdf $pdf the pdf object - * @param bool $preview true if it is a preview, false otherwise - * @param \stdClass $user the user we are rendering this for - */ - public function render($pdf, $preview, $user) { - global $CFG; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return; - } - - $imageinfo = json_decode($this->get_data()); - - $context = \context_user::instance($user->id); - - // Get files in the user icon area. - $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'user', 'icon', 0); - - // Get the file we want to display. - $file = null; - foreach ($files as $filefound) { - if (!$filefound->is_directory()) { - $file = $filefound; - break; - } - } - - // Show image if we found one. - if ($file) { - $location = make_request_directory() . '/target'; - $file->copy_content_to($location); - $pdf->Image($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } else if ($preview) { // Can't find an image, but we are in preview mode then display default pic. - $location = $CFG->dirroot . '/pix/u/f1.png'; - $pdf->Image($location, $this->get_posx(), $this->get_posy(), $imageinfo->width, $imageinfo->height); - } - } - - /** - * Render the element in html. - * - * This function is used to render the element when we are using the - * drag and drop interface to position it. - * - * @return string the html - */ - public function render_html() { - global $PAGE, $USER; - - // If there is no element data, we have nothing to display. - if (empty($this->get_data())) { - return ''; - } - - $imageinfo = json_decode($this->get_data()); - - // Get the image. - $userpicture = new \user_picture($USER); - $userpicture->size = 1; - $url = $userpicture->get_url($PAGE)->out(false); - - // The size of the images to use in the CSS style. - $style = ''; - if ($imageinfo->width === 0 && $imageinfo->height === 0) { - // Put this in so code checker doesn't complain. - $style .= ''; - } else if ($imageinfo->width === 0) { // Then the height must be set. - $style .= 'width: ' . $imageinfo->height . 'mm; '; - $style .= 'height: ' . $imageinfo->height . 'mm'; - } else if ($imageinfo->height === 0) { // Then the width must be set. - $style .= 'width: ' . $imageinfo->width . 'mm; '; - $style .= 'height: ' . $imageinfo->width . 'mm'; - } else { // Must both be set. - $style .= 'width: ' . $imageinfo->width . 'mm; '; - $style .= 'height: ' . $imageinfo->height . 'mm'; - } - - return \html_writer::tag('img', '', array('src' => $url, 'style' => $style)); - } - - /** - * Sets the data on the form when editing an element. - * - * @param \MoodleQuickForm $mform the edit_form instance - */ - public function definition_after_data($mform) { - // Set the image, width and height for this element. - if (!empty($this->get_data())) { - $imageinfo = json_decode($this->get_data()); - - $element = $mform->getElement('width'); - $element->setValue($imageinfo->width); - - $element = $mform->getElement('height'); - $element->setValue($imageinfo->height); - } - - parent::definition_after_data($mform); - } -} diff --git a/element/userpicture/classes/privacy/provider.php b/element/userpicture/classes/privacy/provider.php deleted file mode 100644 index 8b0b3f0..0000000 --- a/element/userpicture/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy Subsystem implementation for customcertelement_userpicture. - * - * @package customcertelement_userpicture - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace customcertelement_userpicture\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for customcertelement_userpicture implementing null_provider. - * - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/element/userpicture/lang/en/customcertelement_userpicture.php b/element/userpicture/lang/en/customcertelement_userpicture.php deleted file mode 100644 index bd32cb3..0000000 --- a/element/userpicture/lang/en/customcertelement_userpicture.php +++ /dev/null @@ -1,32 +0,0 @@ -. - -/** - * Strings for component 'customcertelement_userpicture', language 'en'. - * - * @package customcertelement_userpicture - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['height'] = 'Height'; -$string['height_help'] = 'Height of the image in mm. If equal to zero, it is automatically calculated.'; -$string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.'; -$string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.'; -$string['pluginname'] = 'User picture'; -$string['privacy:metadata'] = 'The User picture plugin does not store any personal data.'; -$string['width'] = 'Width'; -$string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.'; diff --git a/element/userpicture/version.php b/element/userpicture/version.php deleted file mode 100644 index d781451..0000000 --- a/element/userpicture/version.php +++ /dev/null @@ -1,29 +0,0 @@ -. - -/** - * This file contains the version information for the userpicture plugin. - * - * @package customcertelement_userpicture - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -$plugin->version = 2021051700; // The current module version (Date: YYYYMMDDXX). -$plugin->requires = 2021051700; // Requires this Moodle version (3.11). -$plugin->component = 'customcertelement_userpicture'; diff --git a/includes/colourpicker.php b/includes/colourpicker.php deleted file mode 100644 index cad6e2c..0000000 --- a/includes/colourpicker.php +++ /dev/null @@ -1,86 +0,0 @@ -. - -/** - * This file contains the form element for handling the colour picker. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -require_once($CFG->dirroot . '/lib/form/editor.php'); - -/** - * Form element for handling the colour picker. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class moodlequickform_customcert_colourpicker extends moodlequickform_editor { - - /** - * Sets the value of the form element - * - * @param string $value - */ - public function setvalue($value) { - $this->updateAttributes(array('value' => $value)); - } - - /** - * Gets the value of the form element - */ - public function getvalue() { - return $this->getAttribute('value'); - } - - /** - * Returns the html string to display this element. - * - * @return string - */ - public function tohtml() { - global $PAGE, $OUTPUT; - - $PAGE->requires->js_init_call('M.util.init_colour_picker', array($this->getAttribute('id'), null)); - $content = ''; - $content .= html_writer::start_tag('div', array('class' => 'form-colourpicker defaultsnext')); - $content .= html_writer::tag('div', $OUTPUT->pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', - array('class' => 'loadingicon')), array('class' => 'admin_colourpicker clearfix')); - $content .= html_writer::empty_tag('input', array('type' => 'text', 'id' => $this->getAttribute('id'), - 'name' => $this->getName(), 'value' => $this->getValue(), 'size' => '12')); - $content .= html_writer::end_tag('div'); - - return $content; - } - - /** - * Function to export the renderer data in a format that is suitable for a mustache template. - * - * @param \renderer_base $output Used to do a final render of any components that need to be rendered for export. - * @return \stdClass|array - */ - public function export_for_template(renderer_base $output) { - $context = $this->export_for_template_base($output); - $context['html'] = $this->toHtml(); - - return $context; - } -} diff --git a/index.php b/index.php index 1ab05ed..e24ca34 100644 --- a/index.php +++ b/index.php @@ -1,5 +1,5 @@ . /** - * This page lists all the instances of customcert in a particular course. + * This page lists all the instances of htmlcert in a particular course. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -32,25 +32,25 @@ $course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST); require_login($course); // Set up the page variables. -$pageurl = new moodle_url('/mod/customcert/index.php', array('id' => $course->id)); -\mod_customcert\page_helper::page_setup($pageurl, context_course::instance($id), - get_string('modulenameplural', 'customcert')); +$pageurl = new moodle_url('/mod/htmlcert/index.php', array('id' => $course->id)); +\mod_htmlcert\page_helper::page_setup($pageurl, context_course::instance($id), + get_string('modulenameplural', 'htmlcert')); // Additional page setup needed. $PAGE->set_pagelayout('incourse'); -$PAGE->navbar->add(get_string('modulenameplural', 'customcert')); +$PAGE->navbar->add(get_string('modulenameplural', 'htmlcert')); // Add the page view to the Moodle log. -$event = \mod_customcert\event\course_module_instance_list_viewed::create(array( +$event = \mod_htmlcert\event\course_module_instance_list_viewed::create(array( 'context' => context_course::instance($course->id) )); $event->add_record_snapshot('course', $course); $event->trigger(); -// Get the customcerts, if there are none display a notice. -if (!$customcerts = get_all_instances_in_course('customcert', $course)) { +// Get the htmlcerts, if there are none display a notice. +if (!$htmlcerts = get_all_instances_in_course('htmlcert', $course)) { echo $OUTPUT->header(); - notice(get_string('nocustomcerts', 'customcert'), new moodle_url('/course/view.php', array('id' => $course->id))); + notice(get_string('nohtmlcerts', 'htmlcert'), new moodle_url('/course/view.php', array('id' => $course->id))); echo $OUTPUT->footer(); exit(); } @@ -60,37 +60,37 @@ $table = new html_table(); if ($usesections = course_format_uses_sections($course->format)) { $table->head = array(get_string('sectionname', 'format_'.$course->format), get_string('name'), - get_string('receiveddate', 'customcert')); + get_string('receiveddate', 'htmlcert')); } else { - $table->head = array(get_string('name'), get_string('receiveddate', 'customcert')); + $table->head = array(get_string('name'), get_string('receiveddate', 'htmlcert')); } $currentsection = ''; -foreach ($customcerts as $customcert) { - // Check if the customcert is visible, if so show text as normal, else show it as dimmed. - if ($customcert->visible) { - $link = html_writer::tag('a', $customcert->name, array('href' => new moodle_url('/mod/customcert/view.php', - array('id' => $customcert->coursemodule)))); +foreach ($htmlcerts as $htmlcert) { + // Check if the htmlcert is visible, if so show text as normal, else show it as dimmed. + if ($htmlcert->visible) { + $link = html_writer::tag('a', $htmlcert->name, array('href' => new moodle_url('/mod/htmlcert/view.php', + array('id' => $htmlcert->coursemodule)))); } else { - $link = html_writer::tag('a', $customcert->name, array('class' => 'dimmed', - 'href' => new moodle_url('/mod/customcert/view.php', array('id' => $customcert->coursemodule)))); + $link = html_writer::tag('a', $htmlcert->name, array('class' => 'dimmed', + 'href' => new moodle_url('/mod/htmlcert/view.php', array('id' => $htmlcert->coursemodule)))); } // If we are at a different section then print a horizontal rule. - if ($customcert->section !== $currentsection) { + if ($htmlcert->section !== $currentsection) { if ($currentsection !== '') { $table->data[] = 'hr'; } - $currentsection = $customcert->section; + $currentsection = $htmlcert->section; } // Check if there is was an issue provided for this user. - if ($certrecord = $DB->get_record('customcert_issues', array('userid' => $USER->id, 'customcertid' => $customcert->id))) { + if ($certrecord = $DB->get_record('htmlcert_issues', array('userid' => $USER->id, 'htmlcertid' => $htmlcert->id))) { $issued = userdate($certrecord->timecreated); } else { - $issued = get_string('notissued', 'customcert'); + $issued = get_string('notissued', 'htmlcert'); } // Only display the section column if the course format uses sections. if ($usesections) { - $table->data[] = array($customcert->section, $link, $issued); + $table->data[] = array($htmlcert->section, $link, $issued); } else { $table->data[] = array($link, $issued); } diff --git a/lang/en/customcert.php b/lang/en/htmlcert.php similarity index 86% rename from lang/en/customcert.php rename to lang/en/htmlcert.php index fbc5464..63619c8 100644 --- a/lang/en/customcert.php +++ b/lang/en/htmlcert.php @@ -1,5 +1,5 @@ . /** - * Language strings for the customcert module. + * Language strings for the htmlcert module. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -39,21 +39,21 @@ $string['coursetimereq'] = 'Required minutes in course'; $string['coursetimereq_help'] = 'Enter here the minimum amount of time, in minutes, that a student must be logged into the course before they will be able to receive the certificate.'; $string['createtemplate'] = 'Create template'; -$string['customcert:addinstance'] = 'Add a new custom certificate instance'; -$string['customcert:manage'] = 'Manage a custom certificate'; -$string['customcert:manageemailstudents'] = 'Manage email students setting'; -$string['customcert:manageemailteachers'] = 'Manage email teachers setting'; -$string['customcert:manageemailothers'] = 'Manage email others setting'; -$string['customcert:manageverifyany'] = 'Manage verification setting'; -$string['customcert:managerequiredtime'] = 'Manage time required setting'; -$string['customcert:manageprotection'] = 'Manage protection setting'; -$string['customcert:receiveissue'] = 'Receive a certificate'; -$string['customcert:view'] = 'View a custom certificate'; -$string['customcert:viewreport'] = 'View course report'; -$string['customcert:viewallcertificates'] = 'View all certificates'; -$string['customcert:verifyallcertificates'] = 'Verify all certificates on the site'; -$string['customcert:verifycertificate'] = 'Verify a certificate'; -$string['customcertsettings'] = 'Custom certificate settings'; +$string['htmlcert:addinstance'] = 'Add a new custom certificate instance'; +$string['htmlcert:manage'] = 'Manage a custom certificate'; +$string['htmlcert:manageemailstudents'] = 'Manage email students setting'; +$string['htmlcert:manageemailteachers'] = 'Manage email teachers setting'; +$string['htmlcert:manageemailothers'] = 'Manage email others setting'; +$string['htmlcert:manageverifyany'] = 'Manage verification setting'; +$string['htmlcert:managerequiredtime'] = 'Manage time required setting'; +$string['htmlcert:manageprotection'] = 'Manage protection setting'; +$string['htmlcert:receiveissue'] = 'Receive a certificate'; +$string['htmlcert:view'] = 'View a custom certificate'; +$string['htmlcert:viewreport'] = 'View course report'; +$string['htmlcert:viewallcertificates'] = 'View all certificates'; +$string['htmlcert:verifyallcertificates'] = 'Verify all certificates on the site'; +$string['htmlcert:verifycertificate'] = 'Verify a certificate'; +$string['htmlcertsettings'] = 'Custom certificate settings'; $string['deletecertpage'] = 'Delete page'; $string['deleteconfirm'] = 'Delete confirmation'; $string['deleteelement'] = 'Delete element'; @@ -69,7 +69,7 @@ $string['description'] = 'Description'; $string['duplicate'] = 'Duplicate'; $string['duplicateconfirm'] = 'Duplicate confirmation'; $string['duplicatetemplateconfirm'] = 'Are you sure you want to duplicate this certificate template?'; -$string['editcustomcert'] = 'Edit certificate'; +$string['edithtmlcert'] = 'Edit certificate'; $string['editelement'] = 'Edit element'; $string['edittemplate'] = 'Edit template'; $string['elementname'] = 'Element name'; @@ -104,7 +104,7 @@ $string['fontcolour'] = 'Colour'; $string['fontcolour_help'] = 'The colour of the font.'; $string['fontsize'] = 'Size'; $string['fontsize_help'] = 'The size of the font in points.'; -$string['getcustomcert'] = 'View certificate'; +$string['gethtmlcert'] = 'View certificate'; $string['gradeoutcome'] = 'Outcome'; $string['height'] = 'Height'; $string['height_help'] = 'This is the height of the certificate PDF in mm. For reference an A4 piece of paper is 297mm high and a letter is 279mm high.'; @@ -133,7 +133,7 @@ $string['mycertificates'] = 'My certificates'; $string['mycertificatesdescription'] = 'These are the certificates you have been issued by either email or downloading manually.'; $string['name'] = 'Name'; $string['nametoolong'] = 'You have exceeded the maximum length allowed for the name'; -$string['nocustomcerts'] = 'There are no certificates for this course'; +$string['nohtmlcerts'] = 'There are no certificates for this course'; $string['noimage'] = 'No image'; $string['norecipients'] = 'No recipients'; $string['notemplates'] = 'No templates'; @@ -155,12 +155,12 @@ $string['preventprint_desc'] = 'Enable protection from print action.'; $string['preventmodify'] = 'Prevent modify'; $string['preventmodify_desc'] = 'Enable protection from modify action.'; $string['print'] = 'Print'; -$string['privacy:metadata:customcert_issues'] = 'The list of issued certificates'; -$string['privacy:metadata:customcert_issues:code'] = 'The code that belongs to the certificate'; -$string['privacy:metadata:customcert_issues:customcertid'] = 'The ID of the certificate'; -$string['privacy:metadata:customcert_issues:emailed'] = 'Whether or not the certificate was emailed'; -$string['privacy:metadata:customcert_issues:timecreated'] = 'The time the certificate was issued'; -$string['privacy:metadata:customcert_issues:userid'] = 'The ID of the user who was issued the certificate'; +$string['privacy:metadata:htmlcert_issues'] = 'The list of issued certificates'; +$string['privacy:metadata:htmlcert_issues:code'] = 'The code that belongs to the certificate'; +$string['privacy:metadata:htmlcert_issues:htmlcertid'] = 'The ID of the certificate'; +$string['privacy:metadata:htmlcert_issues:emailed'] = 'Whether or not the certificate was emailed'; +$string['privacy:metadata:htmlcert_issues:timecreated'] = 'The time the certificate was issued'; +$string['privacy:metadata:htmlcert_issues:userid'] = 'The ID of the user who was issued the certificate'; $string['rearrangeelements'] = 'Reposition elements'; $string['rearrangeelementsheading'] = 'Drag and drop elements to change where they are positioned on the certificate.'; $string['receiveddate'] = 'Awarded on'; diff --git a/lib.php b/lib.php index db784ee..086619f 100644 --- a/lib.php +++ b/lib.php @@ -1,5 +1,5 @@ . /** - * Customcert module core interaction API + * htmlcert module core interaction API * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); /** - * Add customcert instance. + * Add htmlcert instance. * * @param stdClass $data - * @param mod_customcert_mod_form $mform - * @return int new customcert instance id + * @param mod_htmlcert_mod_form $mform + * @return int new htmlcert instance id */ -function customcert_add_instance($data, $mform) { +function htmlcert_add_instance($data, $mform) { global $DB; - // Create a template for this customcert to use. + // Create a template for this htmlcert to use. $context = context_module::instance($data->coursemodule); - $template = \mod_customcert\template::create($data->name, $context->id); + $template = \mod_htmlcert\template::create($data->name, $context->id); // Add the data to the DB. $data->templateid = $template->get_id(); - $data->protection = \mod_customcert\certificate::set_protection($data); + $data->protection = \mod_htmlcert\certificate::set_protection($data); $data->timecreated = time(); $data->timemodified = $data->timecreated; - $data->id = $DB->insert_record('customcert', $data); + $data->id = $DB->insert_record('htmlcert', $data); - // Add a page to this customcert. + // Add a page to this htmlcert. $template->add_page(); return $data->id; } /** - * Update customcert instance. + * Update htmlcert instance. * * @param stdClass $data - * @param mod_customcert_mod_form $mform + * @param mod_htmlcert_mod_form $mform * @return bool true */ -function customcert_update_instance($data, $mform) { +function htmlcert_update_instance($data, $mform) { global $DB; - $data->protection = \mod_customcert\certificate::set_protection($data); + $data->protection = \mod_htmlcert\certificate::set_protection($data); $data->timemodified = time(); $data->id = $data->instance; - return $DB->update_record('customcert', $data); + return $DB->update_record('htmlcert', $data); } /** @@ -76,36 +76,36 @@ function customcert_update_instance($data, $mform) { * @param int $id * @return bool true if successful */ -function customcert_delete_instance($id) { +function htmlcert_delete_instance($id) { global $CFG, $DB; - // Ensure the customcert exists. - if (!$customcert = $DB->get_record('customcert', array('id' => $id))) { + // Ensure the htmlcert exists. + if (!$htmlcert = $DB->get_record('htmlcert', array('id' => $id))) { return false; } // Get the course module as it is used when deleting files. - if (!$cm = get_coursemodule_from_instance('customcert', $id)) { + if (!$cm = get_coursemodule_from_instance('htmlcert', $id)) { return false; } - // Delete the customcert instance. - if (!$DB->delete_records('customcert', array('id' => $id))) { + // Delete the htmlcert instance. + if (!$DB->delete_records('htmlcert', array('id' => $id))) { return false; } // Now, delete the template associated with this certificate. - if ($template = $DB->get_record('customcert_templates', array('id' => $customcert->templateid))) { - $template = new \mod_customcert\template($template); + if ($template = $DB->get_record('htmlcert_templates', array('id' => $htmlcert->templateid))) { + $template = new \mod_htmlcert\template($template); $template->delete(); } - // Delete the customcert issues. - if (!$DB->delete_records('customcert_issues', array('customcertid' => $id))) { + // Delete the htmlcert issues. + if (!$DB->delete_records('htmlcert_issues', array('htmlcertid' => $id))) { return false; } - // Delete any files associated with the customcert. + // Delete any files associated with the htmlcert. $context = context_module::instance($cm->id); $fs = get_file_storage(); $fs->delete_area_files($context->id); @@ -115,24 +115,24 @@ function customcert_delete_instance($id) { /** * This function is used by the reset_course_userdata function in moodlelib. - * This function will remove all posts from the specified customcert + * This function will remove all posts from the specified htmlcert * and clean up any related data. * * @param stdClass $data the data submitted from the reset course. * @return array status array */ -function customcert_reset_userdata($data) { +function htmlcert_reset_userdata($data) { global $DB; - $componentstr = get_string('modulenameplural', 'customcert'); + $componentstr = get_string('modulenameplural', 'htmlcert'); $status = array(); - if (!empty($data->reset_customcert)) { + if (!empty($data->reset_htmlcert)) { $sql = "SELECT cert.id - FROM {customcert} cert + FROM {htmlcert} cert WHERE cert.course = :courseid"; - $DB->delete_records_select('customcert_issues', "customcertid IN ($sql)", array('courseid' => $data->courseid)); - $status[] = array('component' => $componentstr, 'item' => get_string('deleteissuedcertificates', 'customcert'), + $DB->delete_records_select('htmlcert_issues', "htmlcertid IN ($sql)", array('courseid' => $data->courseid)); + $status[] = array('component' => $componentstr, 'item' => get_string('deleteissuedcertificates', 'htmlcert'), 'error' => false); } @@ -141,13 +141,13 @@ function customcert_reset_userdata($data) { /** * Implementation of the function for printing the form elements that control - * whether the course reset functionality affects the customcert. + * whether the course reset functionality affects the htmlcert. * - * @param mod_customcert_mod_form $mform form passed by reference + * @param mod_htmlcert_mod_form $mform form passed by reference */ -function customcert_reset_course_form_definition(&$mform) { - $mform->addElement('header', 'customcertheader', get_string('modulenameplural', 'customcert')); - $mform->addElement('advcheckbox', 'reset_customcert', get_string('deleteissuedcertificates', 'customcert')); +function htmlcert_reset_course_form_definition(&$mform) { + $mform->addElement('header', 'htmlcertheader', get_string('modulenameplural', 'htmlcert')); + $mform->addElement('advcheckbox', 'reset_htmlcert', get_string('deleteissuedcertificates', 'htmlcert')); } /** @@ -156,54 +156,54 @@ function customcert_reset_course_form_definition(&$mform) { * @param stdClass $course * @return array */ -function customcert_reset_course_form_defaults($course) { - return array('reset_customcert' => 1); +function htmlcert_reset_course_form_defaults($course) { + return array('reset_htmlcert' => 1); } /** - * Returns information about received customcert. + * Returns information about received htmlcert. * Used for user activity reports. * * @param stdClass $course * @param stdClass $user * @param stdClass $mod - * @param stdClass $customcert + * @param stdClass $htmlcert * @return stdClass the user outline object */ -function customcert_user_outline($course, $user, $mod, $customcert) { +function htmlcert_user_outline($course, $user, $mod, $htmlcert) { global $DB; $result = new stdClass(); - if ($issue = $DB->get_record('customcert_issues', array('customcertid' => $customcert->id, 'userid' => $user->id))) { - $result->info = get_string('receiveddate', 'customcert'); + if ($issue = $DB->get_record('htmlcert_issues', array('htmlcertid' => $htmlcert->id, 'userid' => $user->id))) { + $result->info = get_string('receiveddate', 'htmlcert'); $result->time = $issue->timecreated; } else { - $result->info = get_string('notissued', 'customcert'); + $result->info = get_string('notissued', 'htmlcert'); } return $result; } /** - * Returns information about received customcert. + * Returns information about received htmlcert. * Used for user activity reports. * * @param stdClass $course * @param stdClass $user * @param stdClass $mod - * @param stdClass $customcert + * @param stdClass $htmlcert * @return string the user complete information */ -function customcert_user_complete($course, $user, $mod, $customcert) { +function htmlcert_user_complete($course, $user, $mod, $htmlcert) { global $DB, $OUTPUT; - if ($issue = $DB->get_record('customcert_issues', array('customcertid' => $customcert->id, 'userid' => $user->id))) { + if ($issue = $DB->get_record('htmlcert_issues', array('htmlcertid' => $htmlcert->id, 'userid' => $user->id))) { echo $OUTPUT->box_start(); - echo get_string('receiveddate', 'customcert') . ": "; + echo get_string('receiveddate', 'htmlcert') . ": "; echo userdate($issue->timecreated); echo $OUTPUT->box_end(); } else { - print_string('notissued', 'customcert'); + print_string('notissued', 'htmlcert'); } } @@ -218,7 +218,7 @@ function customcert_user_complete($course, $user, $mod, $customcert) { * @param bool $forcedownload * @return bool|null false if file not found, does not return anything if found - just send the file */ -function customcert_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { +function htmlcert_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG; require_once($CFG->libdir . '/filelib.php'); @@ -227,12 +227,12 @@ function customcert_pluginfile($course, $cm, $context, $filearea, $args, $forced if ($filearea === 'image') { if ($context->contextlevel == CONTEXT_MODULE) { require_login($course, false, $cm); - } else if ($context->contextlevel == CONTEXT_SYSTEM && !has_capability('mod/customcert:manage', $context)) { + } else if ($context->contextlevel == CONTEXT_SYSTEM && !has_capability('mod/htmlcert:manage', $context)) { return false; } $relativepath = implode('/', $args); - $fullpath = '/' . $context->id . '/mod_customcert/image/' . $relativepath; + $fullpath = '/' . $context->id . '/mod_htmlcert/image/' . $relativepath; $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -256,7 +256,7 @@ function customcert_pluginfile($course, $cm, $context, $filearea, $args, $forced * @param string $feature FEATURE_xx constant for requested feature * @return mixed True if module supports feature, null if doesn't know */ -function customcert_supports($feature) { +function htmlcert_supports($feature) { switch ($feature) { case FEATURE_GROUPS: return true; @@ -276,27 +276,27 @@ function customcert_supports($feature) { } /** - * Used for course participation report (in case customcert is added). + * Used for course participation report (in case htmlcert is added). * * @return array */ -function customcert_get_view_actions() { +function htmlcert_get_view_actions() { return array('view', 'view all', 'view report'); } /** - * Used for course participation report (in case customcert is added). + * Used for course participation report (in case htmlcert is added). * * @return array */ -function customcert_get_post_actions() { +function htmlcert_get_post_actions() { return array('received'); } /** * Function to be run periodically according to the moodle cron. */ -function customcert_cron() { +function htmlcert_cron() { return true; } @@ -306,14 +306,14 @@ function customcert_cron() { * @param array $args List of named arguments for the fragment loader. * @return string */ -function mod_customcert_output_fragment_editelement($args) { +function mod_htmlcert_output_fragment_editelement($args) { global $DB; // Get the element. - $element = $DB->get_record('customcert_elements', array('id' => $args['elementid']), '*', MUST_EXIST); + $element = $DB->get_record('htmlcert_elements', array('id' => $args['elementid']), '*', MUST_EXIST); - $pageurl = new moodle_url('/mod/customcert/rearrange.php', array('pid' => $element->pageid)); - $form = new \mod_customcert\edit_element_form($pageurl, array('element' => $element)); + $pageurl = new moodle_url('/mod/htmlcert/rearrange.php', array('pid' => $element->pageid)); + $form = new \mod_htmlcert\edit_element_form($pageurl, array('element' => $element)); return $form->render(); } @@ -325,12 +325,12 @@ function mod_customcert_output_fragment_editelement($args) { * context when this is called. * * @param settings_navigation $settings - * @param navigation_node $customcertnode + * @param navigation_node $htmlcertnode */ -function customcert_extend_settings_navigation(settings_navigation $settings, navigation_node $customcertnode) { +function htmlcert_extend_settings_navigation(settings_navigation $settings, navigation_node $htmlcertnode) { global $DB, $PAGE; - $keys = $customcertnode->get_children_key_list(); + $keys = $htmlcertnode->get_children_key_list(); $beforekey = null; $i = array_search('modedit', $keys); if ($i === false and array_key_exists(0, $keys)) { @@ -339,25 +339,25 @@ function customcert_extend_settings_navigation(settings_navigation $settings, na $beforekey = $keys[$i + 1]; } - if (has_capability('mod/customcert:manage', $PAGE->cm->context)) { + if (has_capability('mod/htmlcert:manage', $PAGE->cm->context)) { // Get the template id. - $templateid = $DB->get_field('customcert', 'templateid', array('id' => $PAGE->cm->instance)); - $node = navigation_node::create(get_string('editcustomcert', 'customcert'), - new moodle_url('/mod/customcert/edit.php', array('tid' => $templateid)), - navigation_node::TYPE_SETTING, null, 'mod_customcert_edit', + $templateid = $DB->get_field('htmlcert', 'templateid', array('id' => $PAGE->cm->instance)); + $node = navigation_node::create(get_string('edithtmlcert', 'htmlcert'), + new moodle_url('/mod/htmlcert/edit.php', array('tid' => $templateid)), + navigation_node::TYPE_SETTING, null, 'mod_htmlcert_edit', new pix_icon('t/edit', '')); - $customcertnode->add_node($node, $beforekey); + $htmlcertnode->add_node($node, $beforekey); } - if (has_capability('mod/customcert:verifycertificate', $PAGE->cm->context)) { - $node = navigation_node::create(get_string('verifycertificate', 'customcert'), - new moodle_url('/mod/customcert/verify_certificate.php', array('contextid' => $PAGE->cm->context->id)), - navigation_node::TYPE_SETTING, null, 'mod_customcert_verify_certificate', + if (has_capability('mod/htmlcert:verifycertificate', $PAGE->cm->context)) { + $node = navigation_node::create(get_string('verifycertificate', 'htmlcert'), + new moodle_url('/mod/htmlcert/verify_certificate.php', array('contextid' => $PAGE->cm->context->id)), + navigation_node::TYPE_SETTING, null, 'mod_htmlcert_verify_certificate', new pix_icon('t/check', '')); - $customcertnode->add_node($node, $beforekey); + $htmlcertnode->add_node($node, $beforekey); } - return $customcertnode->trim_if_empty(); + return $htmlcertnode->trim_if_empty(); } /** @@ -369,10 +369,10 @@ function customcert_extend_settings_navigation(settings_navigation $settings, na * @param stdClass $course Course object * @return bool */ -function mod_customcert_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) { - $url = new moodle_url('/mod/customcert/my_certificates.php', array('userid' => $user->id)); - $node = new core_user\output\myprofile\node('miscellaneous', 'mycustomcerts', - get_string('mycertificates', 'customcert'), null, $url); +function mod_htmlcert_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) { + $url = new moodle_url('/mod/htmlcert/my_certificates.php', array('userid' => $user->id)); + $node = new core_user\output\myprofile\node('miscellaneous', 'myhtmlcerts', + get_string('mycertificates', 'htmlcert'), null, $url); $tree->add_node($node); } @@ -384,16 +384,16 @@ function mod_customcert_myprofile_navigation(core_user\output\myprofile\tree $tr * @param string $newvalue * @return \core\output\inplace_editable */ -function mod_customcert_inplace_editable($itemtype, $itemid, $newvalue) { +function mod_htmlcert_inplace_editable($itemtype, $itemid, $newvalue) { global $DB, $PAGE; if ($itemtype === 'elementname') { - $element = $DB->get_record('customcert_elements', array('id' => $itemid), '*', MUST_EXIST); - $page = $DB->get_record('customcert_pages', array('id' => $element->pageid), '*', MUST_EXIST); - $template = $DB->get_record('customcert_templates', array('id' => $page->templateid), '*', MUST_EXIST); + $element = $DB->get_record('htmlcert_elements', array('id' => $itemid), '*', MUST_EXIST); + $page = $DB->get_record('htmlcert_pages', array('id' => $element->pageid), '*', MUST_EXIST); + $template = $DB->get_record('htmlcert_templates', array('id' => $page->templateid), '*', MUST_EXIST); // Set the template object. - $template = new \mod_customcert\template($template); + $template = new \mod_htmlcert\template($template); // Perform checks. if ($cm = $template->get_cm()) { require_login($cm->course, false, $cm); @@ -408,9 +408,9 @@ function mod_customcert_inplace_editable($itemtype, $itemid, $newvalue) { $updateelement = new stdClass(); $updateelement->id = $element->id; $updateelement->name = clean_param($newvalue, PARAM_TEXT); - $DB->update_record('customcert_elements', $updateelement); + $DB->update_record('htmlcert_elements', $updateelement); - return new \core\output\inplace_editable('mod_customcert', 'elementname', $element->id, true, + return new \core\output\inplace_editable('mod_htmlcert', 'elementname', $element->id, true, $updateelement->name, $updateelement->name); } } @@ -418,8 +418,8 @@ function mod_customcert_inplace_editable($itemtype, $itemid, $newvalue) { /** * Get icon mapping for font-awesome. */ -function mod_customcert_get_fontawesome_icon_map() { +function mod_htmlcert_get_fontawesome_icon_map() { return [ - 'mod_customcert:download' => 'fa-download' + 'mod_htmlcert:download' => 'fa-download' ]; } diff --git a/load_template.php b/load_template.php index 3e4bcce..2c28b92 100644 --- a/load_template.php +++ b/load_template.php @@ -1,5 +1,5 @@ . /** - * Handles loading a customcert template. + * Handles loading a htmlcert template. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -28,11 +28,11 @@ $tid = required_param('tid', PARAM_INT); $ltid = required_param('ltid', PARAM_INT); // The template to load. $confirm = optional_param('confirm', 0, PARAM_INT); -$template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); -$template = new \mod_customcert\template($template); +$template = $DB->get_record('htmlcert_templates', array('id' => $tid), '*', MUST_EXIST); +$template = new \mod_htmlcert\template($template); -$loadtemplate = $DB->get_record('customcert_templates', array('id' => $ltid), '*', MUST_EXIST); -$loadtemplate = new \mod_customcert\template($loadtemplate); +$loadtemplate = $DB->get_record('htmlcert_templates', array('id' => $ltid), '*', MUST_EXIST); +$loadtemplate = new \mod_htmlcert\template($loadtemplate); if ($cm = $template->get_cm()) { require_login($cm->course, false, $cm); @@ -42,8 +42,8 @@ if ($cm = $template->get_cm()) { $template->require_manage(); if ($template->get_context()->contextlevel == CONTEXT_MODULE) { - $customcert = $DB->get_record('customcert', ['id' => $cm->instance], '*', MUST_EXIST); - $title = $customcert->name; + $htmlcert = $DB->get_record('htmlcert', ['id' => $cm->instance], '*', MUST_EXIST); + $title = $htmlcert->name; $heading = format_string($title); } else { $title = $SITE->fullname; @@ -54,47 +54,47 @@ if ($template->get_context()->contextlevel == CONTEXT_MODULE) { if ($confirm && confirm_sesskey()) { // First, remove all the existing elements and pages. $sql = "SELECT e.* - FROM {customcert_elements} e - INNER JOIN {customcert_pages} p + FROM {htmlcert_elements} e + INNER JOIN {htmlcert_pages} p ON e.pageid = p.id WHERE p.templateid = :templateid"; if ($elements = $DB->get_records_sql($sql, array('templateid' => $template->get_id()))) { foreach ($elements as $element) { // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { + if ($e = \mod_htmlcert\element_factory::get_element_instance($element)) { $e->delete(); } } } // Delete the pages. - $DB->delete_records('customcert_pages', array('templateid' => $template->get_id())); + $DB->delete_records('htmlcert_pages', array('templateid' => $template->get_id())); // Copy the items across. $loadtemplate->copy_to_template($template->get_id()); // Redirect. - $url = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); + $url = new moodle_url('/mod/htmlcert/edit.php', array('tid' => $tid)); redirect($url); } // Create the link options. -$nourl = new moodle_url('/mod/customcert/edit.php', array('tid' => $tid)); -$yesurl = new moodle_url('/mod/customcert/load_template.php', array('tid' => $tid, +$nourl = new moodle_url('/mod/htmlcert/edit.php', array('tid' => $tid)); +$yesurl = new moodle_url('/mod/htmlcert/load_template.php', array('tid' => $tid, 'ltid' => $ltid, 'confirm' => 1, 'sesskey' => sesskey())); -$pageurl = new moodle_url('/mod/customcert/load_template.php', array('tid' => $tid, 'ltid' => $ltid)); -\mod_customcert\page_helper::page_setup($pageurl, $template->get_context(), $title); +$pageurl = new moodle_url('/mod/htmlcert/load_template.php', array('tid' => $tid, 'ltid' => $ltid)); +\mod_htmlcert\page_helper::page_setup($pageurl, $template->get_context(), $title); -$str = get_string('editcustomcert', 'customcert'); -$link = new moodle_url('/mod/customcert/edit.php', array('tid' => $template->get_id())); +$str = get_string('edithtmlcert', 'htmlcert'); +$link = new moodle_url('/mod/htmlcert/edit.php', array('tid' => $template->get_id())); $PAGE->navbar->add($str, new \action_link($link, $str)); -$PAGE->navbar->add(get_string('loadtemplate', 'customcert')); +$PAGE->navbar->add(get_string('loadtemplate', 'htmlcert')); // Show a confirmation page. echo $OUTPUT->header(); echo $OUTPUT->heading($heading); -echo $OUTPUT->confirm(get_string('loadtemplatemsg', 'customcert'), $yesurl, $nourl); +echo $OUTPUT->confirm(get_string('loadtemplatemsg', 'htmlcert'), $yesurl, $nourl); echo $OUTPUT->footer(); diff --git a/load_template_cli.php b/load_template_cli.php new file mode 100644 index 0000000..4afb51c --- /dev/null +++ b/load_template_cli.php @@ -0,0 +1,40 @@ +. + +define('CLI_SCRIPT', true); +require_once('../../config.php'); + +$tid = $argv[1]; +$ltid = $argv[2]; + +$template = $DB->get_record('htmlcert_templates', array('id' => $tid), '*', MUST_EXIST); +$template = new \mod_htmlcert\template($template); + +$loadtemplate = $DB->get_record('htmlcert_templates', array('id' => $ltid), '*', MUST_EXIST); +$loadtemplate = new \mod_htmlcert\template($loadtemplate); + +$cm = $template->get_cm(); + +if ($template->get_context()->contextlevel == CONTEXT_MODULE) { + $htmlcert = $DB->get_record('htmlcert', ['id' => $cm->instance], '*', MUST_EXIST); + $title = $htmlcert->name; + $heading = format_string($title); +} else { + $title = $SITE->fullname; + $heading = $title; +} + +$loadtemplate->copy_to_template($template->get_id()); diff --git a/manage_templates.php b/manage_templates.php index e57a72b..57b7a40 100644 --- a/manage_templates.php +++ b/manage_templates.php @@ -1,5 +1,5 @@ . /** - * Manage customcert templates. + * Manage htmlcert templates. * - * @package mod_customcert - * @copyright 2016 Mark Nelson + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -37,35 +37,35 @@ if ($action) { } if ($tid) { - $template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); - $template = new \mod_customcert\template($template); + $template = $DB->get_record('htmlcert_templates', array('id' => $tid), '*', MUST_EXIST); + $template = new \mod_htmlcert\template($template); } $context = context::instance_by_id($contextid); require_login(); -require_capability('mod/customcert:manage', $context); +require_capability('mod/htmlcert:manage', $context); $title = $SITE->fullname; // Set up the page. -$pageurl = new moodle_url('/mod/customcert/manage_templates.php'); -\mod_customcert\page_helper::page_setup($pageurl, $context, $title); +$pageurl = new moodle_url('/mod/htmlcert/manage_templates.php'); +\mod_htmlcert\page_helper::page_setup($pageurl, $context, $title); // Additional page setup. if ($tid && $action && confirm_sesskey()) { - $PAGE->navbar->add(get_string('managetemplates', 'customcert'), - new moodle_url('/mod/customcert/manage_templates.php')); + $PAGE->navbar->add(get_string('managetemplates', 'htmlcert'), + new moodle_url('/mod/htmlcert/manage_templates.php')); } else { - $PAGE->navbar->add(get_string('managetemplates', 'customcert')); + $PAGE->navbar->add(get_string('managetemplates', 'htmlcert')); } $heading = format_string($title, true, ['context' => $context]); if ($tid) { if ($action && confirm_sesskey()) { - $nourl = new moodle_url('/mod/customcert/manage_templates.php'); - $yesurl = new moodle_url('/mod/customcert/manage_templates.php', + $nourl = new moodle_url('/mod/htmlcert/manage_templates.php'); + $yesurl = new moodle_url('/mod/htmlcert/manage_templates.php', array( 'tid' => $tid, 'action' => $action, @@ -78,8 +78,8 @@ if ($tid) { if ($action == 'delete') { if (!$confirm) { // Show a confirmation page. - $PAGE->navbar->add(get_string('deleteconfirm', 'customcert')); - $message = get_string('deletetemplateconfirm', 'customcert'); + $PAGE->navbar->add(get_string('deleteconfirm', 'htmlcert')); + $message = get_string('deletetemplateconfirm', 'htmlcert'); echo $OUTPUT->header(); echo $OUTPUT->heading($heading); echo $OUTPUT->confirm($message, $yesurl, $nourl); @@ -91,12 +91,12 @@ if ($tid) { $template->delete(); // Redirect back to the manage templates page. - redirect(new moodle_url('/mod/customcert/manage_templates.php')); + redirect(new moodle_url('/mod/htmlcert/manage_templates.php')); } else if ($action == 'duplicate') { if (!$confirm) { // Show a confirmation page. - $PAGE->navbar->add(get_string('duplicateconfirm', 'customcert')); - $message = get_string('duplicatetemplateconfirm', 'customcert'); + $PAGE->navbar->add(get_string('duplicateconfirm', 'htmlcert')); + $message = get_string('duplicatetemplateconfirm', 'htmlcert'); echo $OUTPUT->header(); echo $OUTPUT->heading($heading); echo $OUTPUT->confirm($message, $yesurl, $nourl); @@ -106,27 +106,27 @@ if ($tid) { // Create another template to copy the data to. $newtemplate = new \stdClass(); - $newtemplate->name = $template->get_name() . ' (' . strtolower(get_string('duplicate', 'customcert')) . ')'; + $newtemplate->name = $template->get_name() . ' (' . strtolower(get_string('duplicate', 'htmlcert')) . ')'; $newtemplate->contextid = $template->get_contextid(); $newtemplate->timecreated = time(); $newtemplate->timemodified = $newtemplate->timecreated; - $newtemplateid = $DB->insert_record('customcert_templates', $newtemplate); + $newtemplateid = $DB->insert_record('htmlcert_templates', $newtemplate); // Copy the data to the new template. $template->copy_to_template($newtemplateid); // Redirect back to the manage templates page. - redirect(new moodle_url('/mod/customcert/manage_templates.php')); + redirect(new moodle_url('/mod/htmlcert/manage_templates.php')); } } } -$table = new \mod_customcert\manage_templates_table($context); +$table = new \mod_htmlcert\manage_templates_table($context); $table->define_baseurl($pageurl); echo $OUTPUT->header(); echo $OUTPUT->heading($heading); $table->out($perpage, false); -$url = new moodle_url('/mod/customcert/edit.php?contextid=' . $contextid); -echo $OUTPUT->single_button($url, get_string('createtemplate', 'customcert'), 'get'); +$url = new moodle_url('/mod/htmlcert/edit.php?contextid=' . $contextid); +echo $OUTPUT->single_button($url, get_string('createtemplate', 'htmlcert'), 'get'); echo $OUTPUT->footer(); diff --git a/mobile/pluginfile.php b/mobile/pluginfile.php index bce6ebb..f66f236 100644 --- a/mobile/pluginfile.php +++ b/mobile/pluginfile.php @@ -17,7 +17,7 @@ /** * Serves files for the mobile app. * - * @package mod_customcert + * @package mod_htmlcert * @copyright 2018 Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -54,25 +54,25 @@ if (empty($enabledfiledownload)) { throw new webservice_access_exception('Web service file downloading must be enabled in external service settings'); } -$cm = get_coursemodule_from_instance('customcert', $certificateid, 0, false, MUST_EXIST); +$cm = get_coursemodule_from_instance('htmlcert', $certificateid, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); -$certificate = $DB->get_record('customcert', ['id' => $certificateid], '*', MUST_EXIST); -$template = $DB->get_record('customcert_templates', ['id' => $certificate->templateid], '*', MUST_EXIST); +$certificate = $DB->get_record('htmlcert', ['id' => $certificateid], '*', MUST_EXIST); +$template = $DB->get_record('htmlcert_templates', ['id' => $certificate->templateid], '*', MUST_EXIST); // Capabilities check. -require_capability('mod/customcert:view', \context_module::instance($cm->id)); +require_capability('mod/htmlcert:view', \context_module::instance($cm->id)); if ($userid != $USER->id) { - require_capability('mod/customcert:viewreport', \context_module::instance($cm->id)); + require_capability('mod/htmlcert:viewreport', \context_module::instance($cm->id)); } else { // Make sure the user has met the required time. if ($certificate->requiredtime) { - if (\mod_customcert\certificate::get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { + if (\mod_htmlcert\certificate::get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { exit(); } } } -$issue = $DB->get_record('customcert_issues', ['customcertid' => $certificateid, 'userid' => $userid]); +$issue = $DB->get_record('htmlcert_issues', ['htmlcertid' => $certificateid, 'userid' => $userid]); // If we are doing it for the logged in user then we want to issue the certificate. if (!$issue) { @@ -81,7 +81,7 @@ if (!$issue) { exit(); } - \mod_customcert\certificate::issue_certificate($certificate->id, $USER->id); + \mod_htmlcert\certificate::issue_certificate($certificate->id, $USER->id); // Set the custom certificate as viewed. $completion = new completion_info($course); @@ -89,6 +89,6 @@ if (!$issue) { } // Now we want to generate the PDF. -$template = new \mod_customcert\template($template); +$template = new \mod_htmlcert\template($template); $template->generate_pdf(false, $userid); exit(); diff --git a/mod_form.php b/mod_form.php index e82c4a5..7861100 100644 --- a/mod_form.php +++ b/mod_form.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -use mod_customcert\certificate; +use mod_htmlcert\certificate; defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); @@ -31,11 +31,11 @@ require_once($CFG->dirroot.'/course/moodleform_mod.php'); /** * Instance add/edit form. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class mod_customcert_mod_form extends moodleform_mod { +class mod_htmlcert_mod_form extends moodleform_mod { /** * Form definition. @@ -47,7 +47,7 @@ class mod_customcert_mod_form extends moodleform_mod { $mform->addElement('header', 'general', get_string('general', 'form')); - $mform->addElement('text', 'name', get_string('name', 'customcert'), array('size' => '64')); + $mform->addElement('text', 'name', get_string('name', 'htmlcert'), array('size' => '64')); if (!empty($CFG->formatstringstriptags)) { $mform->setType('name', PARAM_TEXT); } else { @@ -55,58 +55,58 @@ class mod_customcert_mod_form extends moodleform_mod { } $mform->addRule('name', null, 'required', null, 'client'); - $this->standard_intro_elements(get_string('description', 'customcert')); + $this->standard_intro_elements(get_string('description', 'htmlcert')); - $mform->addElement('header', 'options', get_string('options', 'customcert')); + $mform->addElement('header', 'options', get_string('options', 'htmlcert')); $deliveryoptions = [ - certificate::DELIVERY_OPTION_INLINE => get_string('deliveryoptioninline', 'customcert'), - certificate::DELIVERY_OPTION_DOWNLOAD => get_string('deliveryoptiondownload', 'customcert') + certificate::DELIVERY_OPTION_INLINE => get_string('deliveryoptioninline', 'htmlcert'), + certificate::DELIVERY_OPTION_DOWNLOAD => get_string('deliveryoptiondownload', 'htmlcert') ]; - $mform->addElement('select', 'deliveryoption', get_string('deliveryoptions', 'customcert'), $deliveryoptions); + $mform->addElement('select', 'deliveryoption', get_string('deliveryoptions', 'htmlcert'), $deliveryoptions); $mform->setDefault('deliveryoption', certificate::DELIVERY_OPTION_INLINE); - if (has_capability('mod/customcert:manageemailstudents', $this->get_context())) { - $mform->addElement('selectyesno', 'emailstudents', get_string('emailstudents', 'customcert')); - $mform->setDefault('emailstudents', get_config('customcert', 'emailstudents')); - $mform->addHelpButton('emailstudents', 'emailstudents', 'customcert'); + if (has_capability('mod/htmlcert:manageemailstudents', $this->get_context())) { + $mform->addElement('selectyesno', 'emailstudents', get_string('emailstudents', 'htmlcert')); + $mform->setDefault('emailstudents', get_config('htmlcert', 'emailstudents')); + $mform->addHelpButton('emailstudents', 'emailstudents', 'htmlcert'); $mform->setType('emailstudents', PARAM_INT); } - if (has_capability('mod/customcert:manageemailteachers', $this->get_context())) { - $mform->addElement('selectyesno', 'emailteachers', get_string('emailteachers', 'customcert')); - $mform->setDefault('emailteachers', get_config('customcert', 'emailteachers')); - $mform->addHelpButton('emailteachers', 'emailteachers', 'customcert'); + if (has_capability('mod/htmlcert:manageemailteachers', $this->get_context())) { + $mform->addElement('selectyesno', 'emailteachers', get_string('emailteachers', 'htmlcert')); + $mform->setDefault('emailteachers', get_config('htmlcert', 'emailteachers')); + $mform->addHelpButton('emailteachers', 'emailteachers', 'htmlcert'); $mform->setType('emailteachers', PARAM_INT); } - if (has_capability('mod/customcert:manageemailothers', $this->get_context())) { - $mform->addElement('text', 'emailothers', get_string('emailothers', 'customcert'), array('size' => '40')); - $mform->addHelpButton('emailothers', 'emailothers', 'customcert'); - $mform->setDefault('emailothers', get_config('customcert', 'emailothers')); + if (has_capability('mod/htmlcert:manageemailothers', $this->get_context())) { + $mform->addElement('text', 'emailothers', get_string('emailothers', 'htmlcert'), array('size' => '40')); + $mform->addHelpButton('emailothers', 'emailothers', 'htmlcert'); + $mform->setDefault('emailothers', get_config('htmlcert', 'emailothers')); $mform->setType('emailothers', PARAM_TEXT); } - if (has_capability('mod/customcert:manageverifyany', $this->get_context())) { - $mform->addElement('selectyesno', 'verifyany', get_string('verifycertificateanyone', 'customcert')); - $mform->addHelpButton('verifyany', 'verifycertificateanyone', 'customcert'); - $mform->setDefault('verifyany', get_config('customcert', 'verifyany')); + if (has_capability('mod/htmlcert:manageverifyany', $this->get_context())) { + $mform->addElement('selectyesno', 'verifyany', get_string('verifycertificateanyone', 'htmlcert')); + $mform->addHelpButton('verifyany', 'verifycertificateanyone', 'htmlcert'); + $mform->setDefault('verifyany', get_config('htmlcert', 'verifyany')); $mform->setType('verifyany', PARAM_INT); } - if (has_capability('mod/customcert:managerequiredtime', $this->get_context())) { - $mform->addElement('text', 'requiredtime', get_string('coursetimereq', 'customcert'), array('size' => '3')); - $mform->addHelpButton('requiredtime', 'coursetimereq', 'customcert'); - $mform->setDefault('requiredtime', get_config('customcert', 'requiredtime')); + if (has_capability('mod/htmlcert:managerequiredtime', $this->get_context())) { + $mform->addElement('text', 'requiredtime', get_string('coursetimereq', 'htmlcert'), array('size' => '3')); + $mform->addHelpButton('requiredtime', 'coursetimereq', 'htmlcert'); + $mform->setDefault('requiredtime', get_config('htmlcert', 'requiredtime')); $mform->setType('requiredtime', PARAM_INT); } - if (has_capability('mod/customcert:manageprotection', $this->get_context())) { - $mform->addElement('checkbox', 'protection_print', get_string('setprotection', 'customcert'), - get_string('print', 'customcert')); - $mform->addElement('checkbox', 'protection_modify', '', get_string('modify', 'customcert')); - $mform->addElement('checkbox', 'protection_copy', '', get_string('copy', 'customcert')); - $mform->addHelpButton('protection_print', 'setprotection', 'customcert'); + if (has_capability('mod/htmlcert:manageprotection', $this->get_context())) { + $mform->addElement('checkbox', 'protection_print', get_string('setprotection', 'htmlcert'), + get_string('print', 'htmlcert')); + $mform->addElement('checkbox', 'protection_modify', '', get_string('modify', 'htmlcert')); + $mform->addElement('checkbox', 'protection_copy', '', get_string('copy', 'htmlcert')); + $mform->addHelpButton('protection_print', 'setprotection', 'htmlcert'); $mform->setType('protection_print', PARAM_BOOL); $mform->setType('protection_modify', PARAM_BOOL); $mform->setType('protection_copy', PARAM_BOOL); @@ -134,9 +134,9 @@ class mod_customcert_mod_form extends moodleform_mod { $defaultvalues['protection_copy'] = $protection->protection_copy; } } else { - $defaultvalues['protection_print'] = get_config('customcert', 'protection_print'); - $defaultvalues['protection_modify'] = get_config('customcert', 'protection_modify'); - $defaultvalues['protection_copy'] = get_config('customcert', 'protection_copy'); + $defaultvalues['protection_print'] = get_config('htmlcert', 'protection_print'); + $defaultvalues['protection_modify'] = get_config('htmlcert', 'protection_modify'); + $defaultvalues['protection_copy'] = get_config('htmlcert', 'protection_copy'); } } @@ -156,15 +156,15 @@ class mod_customcert_mod_form extends moodleform_mod { if (!empty($data->add)) { foreach ($this->get_options_elements_with_required_caps() as $name => $capability) { if (!isset($data->$name) && !has_capability($capability, $this->get_context())) { - $data->$name = get_config('customcert', $name); + $data->$name = get_config('htmlcert', $name); } } } else { // If updating, but a user can't manage protection, then get data from database. - if (!has_capability('mod/customcert:manageprotection', $this->get_context())) { - $customcert = $DB->get_record('customcert', array('id' => $data->instance)); + if (!has_capability('mod/htmlcert:manageprotection', $this->get_context())) { + $htmlcert = $DB->get_record('htmlcert', array('id' => $data->instance)); - $protection = $this->build_protection_data($customcert->protection); + $protection = $this->build_protection_data($htmlcert->protection); $data->protection_print = $protection->protection_print; $data->protection_modify = $protection->protection_modify; $data->protection_copy = $protection->protection_copy; @@ -185,7 +185,7 @@ class mod_customcert_mod_form extends moodleform_mod { // Check that the required time entered is valid if it was entered at all. if (!empty($data['requiredtime'])) { if ((!is_number($data['requiredtime']) || $data['requiredtime'] < 0)) { - $errors['requiredtime'] = get_string('requiredtimenotvalid', 'customcert'); + $errors['requiredtime'] = get_string('requiredtimenotvalid', 'htmlcert'); } } @@ -199,14 +199,14 @@ class mod_customcert_mod_form extends moodleform_mod { */ protected function get_options_elements_with_required_caps() { return [ - 'emailstudents' => 'mod/customcert:manageemailstudents', - 'emailteachers' => 'mod/customcert:manageemailteachers', - 'emailothers' => 'mod/customcert:manageemailothers', - 'verifyany' => 'mod/customcert:manageverifyany', - 'requiredtime' => 'mod/customcert:managerequiredtime', - 'protection_print' => 'mod/customcert:manageprotection', - 'protection_modify' => 'mod/customcert:manageprotection', - 'protection_copy' => 'mod/customcert:manageprotection' + 'emailstudents' => 'mod/htmlcert:manageemailstudents', + 'emailteachers' => 'mod/htmlcert:manageemailteachers', + 'emailothers' => 'mod/htmlcert:manageemailothers', + 'verifyany' => 'mod/htmlcert:manageverifyany', + 'requiredtime' => 'mod/htmlcert:managerequiredtime', + 'protection_print' => 'mod/htmlcert:manageprotection', + 'protection_modify' => 'mod/htmlcert:manageprotection', + 'protection_copy' => 'mod/htmlcert:manageprotection' ]; } diff --git a/my_certificates.php b/my_certificates.php index 71332aa..0a1c5b9 100644 --- a/my_certificates.php +++ b/my_certificates.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2016 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -29,16 +29,16 @@ $download = optional_param('download', null, PARAM_ALPHA); $downloadcert = optional_param('downloadcert', '', PARAM_BOOL); if ($downloadcert) { $certificateid = required_param('certificateid', PARAM_INT); - $customcert = $DB->get_record('customcert', array('id' => $certificateid), '*', MUST_EXIST); + $htmlcert = $DB->get_record('htmlcert', array('id' => $certificateid), '*', MUST_EXIST); // Check there exists an issued certificate for this user. - if (!$issue = $DB->get_record('customcert_issues', ['userid' => $userid, 'customcertid' => $customcert->id])) { + if (!$issue = $DB->get_record('htmlcert_issues', ['userid' => $userid, 'htmlcertid' => $htmlcert->id])) { throw new moodle_exception('You have not been issued a certificate'); } } $page = optional_param('page', 0, PARAM_INT); -$perpage = optional_param('perpage', \mod_customcert\certificate::CUSTOMCERT_PER_PAGE, PARAM_INT); -$pageurl = $url = new moodle_url('/mod/customcert/my_certificates.php', array('userid' => $userid, +$perpage = optional_param('perpage', \mod_htmlcert\certificate::HTMLCERT_PER_PAGE, PARAM_INT); +$pageurl = $url = new moodle_url('/mod/htmlcert/my_certificates.php', array('userid' => $userid, 'page' => $page, 'perpage' => $perpage)); // Requires a login. @@ -48,25 +48,25 @@ require_login(); $user = \core_user::get_user($userid, '*', MUST_EXIST); // If we are viewing certificates that are not for the currently logged in user then do a capability check. -if (($userid != $USER->id) && !has_capability('mod/customcert:viewallcertificates', context_system::instance())) { +if (($userid != $USER->id) && !has_capability('mod/htmlcert:viewallcertificates', context_system::instance())) { throw new moodle_exception('You are not allowed to view these certificates'); } $PAGE->set_url($pageurl); $PAGE->set_context(context_user::instance($userid)); -$PAGE->set_title(get_string('mycertificates', 'customcert')); +$PAGE->set_title(get_string('mycertificates', 'htmlcert')); $PAGE->set_pagelayout('standard'); $PAGE->navigation->extend_for_user($user); // Check if we requested to download a certificate. if ($downloadcert) { - $template = $DB->get_record('customcert_templates', array('id' => $customcert->templateid), '*', MUST_EXIST); - $template = new \mod_customcert\template($template); + $template = $DB->get_record('htmlcert_templates', array('id' => $htmlcert->templateid), '*', MUST_EXIST); + $template = new \mod_htmlcert\template($template); $template->generate_pdf(false, $userid); exit(); } -$table = new \mod_customcert\my_certificates_table($userid, $download); +$table = new \mod_htmlcert\my_certificates_table($userid, $download); $table->define_baseurl($pageurl); if ($table->is_downloading()) { @@ -76,10 +76,10 @@ if ($table->is_downloading()) { // Additional page setup. $PAGE->navbar->add(get_string('profile'), new moodle_url('/user/profile.php', array('id' => $userid))); -$PAGE->navbar->add(get_string('mycertificates', 'customcert')); +$PAGE->navbar->add(get_string('mycertificates', 'htmlcert')); echo $OUTPUT->header(); -echo $OUTPUT->heading(get_string('mycertificates', 'customcert')); -echo html_writer::div(get_string('mycertificatesdescription', 'customcert')); +echo $OUTPUT->heading(get_string('mycertificates', 'htmlcert')); +echo html_writer::div(get_string('mycertificatesdescription', 'htmlcert')); $table->out($perpage, false); echo $OUTPUT->footer(); diff --git a/rearrange.php b/rearrange.php deleted file mode 100644 index 2c612cc..0000000 --- a/rearrange.php +++ /dev/null @@ -1,144 +0,0 @@ -. - -/** - * Handles position elements on the PDF via drag and drop. - * - * @package mod_customcert - * @copyright 2013 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once('../../config.php'); - -// The page of the customcert we are editing. -$pid = required_param('pid', PARAM_INT); - -$page = $DB->get_record('customcert_pages', array('id' => $pid), '*', MUST_EXIST); -$template = $DB->get_record('customcert_templates', array('id' => $page->templateid), '*', MUST_EXIST); -$elements = $DB->get_records('customcert_elements', array('pageid' => $pid), 'sequence'); - -// Set the template. -$template = new \mod_customcert\template($template); -// Perform checks. -if ($cm = $template->get_cm()) { - require_login($cm->course, false, $cm); -} else { - require_login(); -} -// Make sure the user has the required capabilities. -$template->require_manage(); - -if ($template->get_context()->contextlevel == CONTEXT_MODULE) { - $customcert = $DB->get_record('customcert', ['id' => $cm->instance], '*', MUST_EXIST); - $title = $customcert->name; - $heading = format_string($title); -} else { - $title = $SITE->fullname; - $heading = $title; -} - -// Set the $PAGE settings. -$pageurl = new moodle_url('/mod/customcert/rearrange.php', array('pid' => $pid)); -\mod_customcert\page_helper::page_setup($pageurl, $template->get_context(), $title); - -// Add more links to the navigation. -if (!$cm = $template->get_cm()) { - $str = get_string('managetemplates', 'customcert'); - $link = new moodle_url('/mod/customcert/manage_templates.php'); - $PAGE->navbar->add($str, new \action_link($link, $str)); -} - -$str = get_string('editcustomcert', 'customcert'); -$link = new moodle_url('/mod/customcert/edit.php', array('tid' => $template->get_id())); -$PAGE->navbar->add($str, new \action_link($link, $str)); - -$PAGE->navbar->add(get_string('rearrangeelements', 'customcert')); - -// Include the JS we need. -$PAGE->requires->yui_module('moodle-mod_customcert-rearrange', 'Y.M.mod_customcert.rearrange.init', - array($template->get_id(), - $page, - $elements)); - -// Create the buttons to save the position of the elements. -$html = html_writer::start_tag('div', array('class' => 'buttons')); -$html .= $OUTPUT->single_button(new moodle_url('/mod/customcert/edit.php', array('tid' => $template->get_id())), - get_string('saveandclose', 'customcert'), 'get', array('class' => 'savepositionsbtn')); -$html .= $OUTPUT->single_button(new moodle_url('/mod/customcert/rearrange.php', array('pid' => $pid)), - get_string('saveandcontinue', 'customcert'), 'get', array('class' => 'applypositionsbtn')); -$html .= $OUTPUT->single_button(new moodle_url('/mod/customcert/edit.php', array('tid' => $template->get_id())), - get_string('cancel'), 'get', array('class' => 'cancelbtn')); -$html .= html_writer::end_tag('div'); - -// Create the div that represents the PDF. -$style = 'height: ' . $page->height . 'mm; line-height: normal; width: ' . $page->width . 'mm;'; -$marginstyle = 'height: ' . $page->height . 'mm; width:1px; float:left; position:relative;'; -$html .= html_writer::start_tag('div', array( - 'data-templateid' => $template->get_id(), - 'data-contextid' => $template->get_contextid(), - 'id' => 'pdf', - 'style' => $style) -); -if ($page->leftmargin) { - $position = 'left:' . $page->leftmargin . 'mm;'; - $html .= "
"; -} -if ($elements) { - foreach ($elements as $element) { - // Get an instance of the element class. - if ($e = \mod_customcert\element_factory::get_element_instance($element)) { - switch ($element->refpoint) { - case \mod_customcert\element_helper::CUSTOMCERT_REF_POINT_TOPRIGHT: - $class = 'element refpoint-right'; - break; - case \mod_customcert\element_helper::CUSTOMCERT_REF_POINT_TOPCENTER: - $class = 'element refpoint-center'; - break; - case \mod_customcert\element_helper::CUSTOMCERT_REF_POINT_TOPLEFT: - default: - $class = 'element refpoint-left'; - } - switch ($element->alignment) { - case \mod_customcert\element::ALIGN_CENTER: - $class .= ' align-center'; - break; - case \mod_customcert\element::ALIGN_RIGHT: - $class .= ' align-right'; - break; - case \mod_customcert\element::ALIGN_LEFT: - default: - $class .= ' align-left'; - break; - } - $html .= html_writer::tag('div', $e->render_html(), array('class' => $class, - 'data-refpoint' => $element->refpoint, 'id' => 'element-' . $element->id)); - } - } -} -if ($page->rightmargin) { - $position = 'left:' . ($page->width - $page->rightmargin) . 'mm;'; - $html .= "
"; -} -$html .= html_writer::end_tag('div'); - -echo $OUTPUT->header(); -echo $OUTPUT->heading($heading); -echo $OUTPUT->heading(get_string('rearrangeelementsheading', 'customcert'), 3); -echo $OUTPUT->notification(get_string('exampledatawarning', 'customcert'), \core\output\notification::NOTIFY_WARNING); -echo $html; -$PAGE->requires->js_call_amd('mod_customcert/rearrange-area', 'init', array('#pdf')); -echo $OUTPUT->footer(); diff --git a/report.php b/report.php index fde4f26..96acab5 100644 --- a/report.php +++ b/report.php @@ -1,5 +1,5 @@ . /** - * Handles viewing a report that shows who has received a customcert. + * Handles viewing a report that shows who has received a htmlcert. * * This is now just a stub page - all logic has been moved to view.php. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -28,9 +28,9 @@ require_once('../../config.php'); $id = required_param('id', PARAM_INT); -$cm = get_coursemodule_from_id('customcert', $id, 0, false, MUST_EXIST); +$cm = get_coursemodule_from_id('htmlcert', $id, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_login($course, false, $cm); -redirect(new moodle_url('/mod/customcert/view.php', ['id' => $id])); +redirect(new moodle_url('/mod/htmlcert/view.php', ['id' => $id])); diff --git a/settings.php b/settings.php index 6a648ed..4cdea55 100644 --- a/settings.php +++ b/settings.php @@ -17,39 +17,39 @@ /** * Creates a link to the upload form on the settings page. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die; -$url = $CFG->wwwroot . '/mod/customcert/verify_certificate.php'; +$url = $CFG->wwwroot . '/mod/htmlcert/verify_certificate.php'; -$ADMIN->add('modsettings', new admin_category('customcert', get_string('pluginname', 'mod_customcert'))); -$settings = new admin_settingpage('modsettingcustomcert', new lang_string('customcertsettings', 'mod_customcert')); +$ADMIN->add('modsettings', new admin_category('htmlcert', get_string('pluginname', 'mod_htmlcert'))); +$settings = new admin_settingpage('modsettinghtmlcert', new lang_string('htmlcertsettings', 'mod_htmlcert')); -$settings->add(new admin_setting_configcheckbox('customcert/verifyallcertificates', - get_string('verifyallcertificates', 'customcert'), - get_string('verifyallcertificates_desc', 'customcert', $url), +$settings->add(new admin_setting_configcheckbox('htmlcert/verifyallcertificates', + get_string('verifyallcertificates', 'htmlcert'), + get_string('verifyallcertificates_desc', 'htmlcert', $url), 0)); -$settings->add(new admin_setting_configcheckbox('customcert/showposxy', - get_string('showposxy', 'customcert'), - get_string('showposxy_desc', 'customcert'), +$settings->add(new admin_setting_configcheckbox('htmlcert/showposxy', + get_string('showposxy', 'htmlcert'), + get_string('showposxy_desc', 'htmlcert'), 0)); -$settings->add(new \mod_customcert\admin_setting_link('customcert/verifycertificate', - get_string('verifycertificate', 'customcert'), get_string('verifycertificatedesc', 'customcert'), - get_string('verifycertificate', 'customcert'), new moodle_url('/mod/customcert/verify_certificate.php'), '')); +$settings->add(new \mod_htmlcert\admin_setting_link('htmlcert/verifycertificate', + get_string('verifycertificate', 'htmlcert'), get_string('verifycertificatedesc', 'htmlcert'), + get_string('verifycertificate', 'htmlcert'), new moodle_url('/mod/htmlcert/verify_certificate.php'), '')); -$settings->add(new \mod_customcert\admin_setting_link('customcert/managetemplates', - get_string('managetemplates', 'customcert'), get_string('managetemplatesdesc', 'customcert'), - get_string('managetemplates', 'customcert'), new moodle_url('/mod/customcert/manage_templates.php'), '')); +$settings->add(new \mod_htmlcert\admin_setting_link('htmlcert/managetemplates', + get_string('managetemplates', 'htmlcert'), get_string('managetemplatesdesc', 'htmlcert'), + get_string('managetemplates', 'htmlcert'), new moodle_url('/mod/htmlcert/manage_templates.php'), '')); -$settings->add(new \mod_customcert\admin_setting_link('customcert/uploadimage', - get_string('uploadimage', 'customcert'), get_string('uploadimagedesc', 'customcert'), - get_string('uploadimage', 'customcert'), new moodle_url('/mod/customcert/upload_image.php'), '')); +$settings->add(new \mod_htmlcert\admin_setting_link('htmlcert/uploadimage', + get_string('uploadimage', 'htmlcert'), get_string('uploadimagedesc', 'htmlcert'), + get_string('uploadimage', 'htmlcert'), new moodle_url('/mod/htmlcert/upload_image.php'), '')); $settings->add(new admin_setting_heading('defaults', get_string('modeditdefaults', 'admin'), get_string('condifmodeditdefaults', 'admin'))); @@ -59,37 +59,37 @@ $yesnooptions = [ 1 => get_string('yes'), ]; -$settings->add(new admin_setting_configselect('customcert/emailstudents', - get_string('emailstudents', 'customcert'), get_string('emailstudents_help', 'customcert'), 0, $yesnooptions)); -$settings->add(new admin_setting_configselect('customcert/emailteachers', - get_string('emailteachers', 'customcert'), get_string('emailteachers_help', 'customcert'), 0, $yesnooptions)); -$settings->add(new admin_setting_configtext('customcert/emailothers', - get_string('emailothers', 'customcert'), get_string('emailothers_help', 'customcert'), '', PARAM_TEXT)); -$settings->add(new admin_setting_configselect('customcert/verifyany', - get_string('verifycertificateanyone', 'customcert'), get_string('verifycertificateanyone_help', 'customcert'), +$settings->add(new admin_setting_configselect('htmlcert/emailstudents', + get_string('emailstudents', 'htmlcert'), get_string('emailstudents_help', 'htmlcert'), 0, $yesnooptions)); +$settings->add(new admin_setting_configselect('htmlcert/emailteachers', + get_string('emailteachers', 'htmlcert'), get_string('emailteachers_help', 'htmlcert'), 0, $yesnooptions)); +$settings->add(new admin_setting_configtext('htmlcert/emailothers', + get_string('emailothers', 'htmlcert'), get_string('emailothers_help', 'htmlcert'), '', PARAM_TEXT)); +$settings->add(new admin_setting_configselect('htmlcert/verifyany', + get_string('verifycertificateanyone', 'htmlcert'), get_string('verifycertificateanyone_help', 'htmlcert'), 0, $yesnooptions)); -$settings->add(new admin_setting_configtext('customcert/requiredtime', - get_string('coursetimereq', 'customcert'), get_string('coursetimereq_help', 'customcert'), 0, PARAM_INT)); -$settings->add(new admin_setting_configcheckbox('customcert/protection_print', - get_string('preventprint', 'customcert'), - get_string('preventprint_desc', 'customcert'), +$settings->add(new admin_setting_configtext('htmlcert/requiredtime', + get_string('coursetimereq', 'htmlcert'), get_string('coursetimereq_help', 'htmlcert'), 0, PARAM_INT)); +$settings->add(new admin_setting_configcheckbox('htmlcert/protection_print', + get_string('preventprint', 'htmlcert'), + get_string('preventprint_desc', 'htmlcert'), 0)); -$settings->add(new admin_setting_configcheckbox('customcert/protection_modify', - get_string('preventmodify', 'customcert'), - get_string('preventmodify_desc', 'customcert'), +$settings->add(new admin_setting_configcheckbox('htmlcert/protection_modify', + get_string('preventmodify', 'htmlcert'), + get_string('preventmodify_desc', 'htmlcert'), 0)); -$settings->add(new admin_setting_configcheckbox('customcert/protection_copy', - get_string('preventcopy', 'customcert'), - get_string('preventcopy_desc', 'customcert'), +$settings->add(new admin_setting_configcheckbox('htmlcert/protection_copy', + get_string('preventcopy', 'htmlcert'), + get_string('preventcopy_desc', 'htmlcert'), 0)); -$ADMIN->add('customcert', $settings); +$ADMIN->add('htmlcert', $settings); // Element plugin settings. -$ADMIN->add('customcert', new admin_category('customcertelements', get_string('elementplugins', 'customcert'))); -$plugins = \core_plugin_manager::instance()->get_plugins_of_type('customcertelement'); +$ADMIN->add('htmlcert', new admin_category('htmlcertelements', get_string('elementplugins', 'htmlcert'))); +$plugins = \core_plugin_manager::instance()->get_plugins_of_type('htmlcertelement'); foreach ($plugins as $plugin) { - $plugin->load_settings($ADMIN, 'customcertelements', $hassiteconfig); + $plugin->load_settings($ADMIN, 'htmlcertelements', $hassiteconfig); } // Tell core we already added the settings structure. diff --git a/styles.css b/styles.css index 3f98cdf..8709f11 100644 --- a/styles.css +++ b/styles.css @@ -1,35 +1,35 @@ -#page-mod-customcert-edit .deletebutton { +#page-mod-htmlcert-edit .deletebutton { text-align: right; } -#page-mod-customcert-edit .addpage { +#page-mod-htmlcert-edit .addpage { border-top: 1px solid #f4f4f4; text-align: right; } -#page-mod-customcert-edit #id_replace { +#page-mod-htmlcert-edit #id_replace { margin-left: 10px; } -#page-mod-customcert-report .centre { +#page-mod-htmlcert-report .centre { margin-left: auto; margin-right: auto; } -#page-mod-customcert-rearrange .savepositionsbtn, -#page-mod-customcert-rearrange .applypositionsbtn, -#page-mod-customcert-rearrange .cancelbtn { +#page-mod-htmlcert-rearrange .savepositionsbtn, +#page-mod-htmlcert-rearrange .applypositionsbtn, +#page-mod-htmlcert-rearrange .cancelbtn { float: left; } -#page-mod-customcert-rearrange .element { +#page-mod-htmlcert-rearrange .element { display: inline-block; position: absolute; word-wrap: break-word; } -#page-mod-customcert-rearrange .element:before { - background-image: url([[pix:mod_customcert|target]]); +#page-mod-htmlcert-rearrange .element:before { + background-image: url([[pix:mod_htmlcert|target]]); background-repeat: no-repeat; content: ""; display: block; @@ -38,48 +38,48 @@ width: 100%; } -#page-mod-customcert-rearrange .element:hover { +#page-mod-htmlcert-rearrange .element:hover { cursor: move; } -#page-mod-customcert-rearrange .element.refpoint-left:before { +#page-mod-htmlcert-rearrange .element.refpoint-left:before { background-position: left top; margin: -4px -5px -5px -4px; } -#page-mod-customcert-rearrange .element.refpoint-center:before { +#page-mod-htmlcert-rearrange .element.refpoint-center:before { background-position: center top; margin: -4px 0 -5px 0; } -#page-mod-customcert-rearrange .element.refpoint-right:before { +#page-mod-htmlcert-rearrange .element.refpoint-right:before { background-position: right top; margin: -4px -5px -5px 4px; } -#page-mod-customcert-rearrange .element.align-left { +#page-mod-htmlcert-rearrange .element.align-left { text-align: left; } -#page-mod-customcert-rearrange .element.align-center { +#page-mod-htmlcert-rearrange .element.align-center { text-align: center; } -#page-mod-customcert-rearrange .element.align-right { +#page-mod-htmlcert-rearrange .element.align-right { text-align: right; } -#page-mod-customcert-rearrange #pdf { +#page-mod-htmlcert-rearrange #pdf { border-style: solid; border-width: 1px; clear: both; } -#page-mod-customcert-rearrange div#leftmargin { +#page-mod-htmlcert-rearrange div#leftmargin { border-left: 1px dotted black; } -#page-mod-customcert-rearrange div#rightmargin { +#page-mod-htmlcert-rearrange div#rightmargin { border-right: 1px dotted black; } diff --git a/templates/email_certificate_html.mustache b/templates/email_certificate_html.mustache index ecbd6cb..088d75d 100644 --- a/templates/email_certificate_html.mustache +++ b/templates/email_certificate_html.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/email_certificate_html + @template mod_htmlcert/email_certificate_html The certificate verification result @@ -35,7 +35,7 @@ { "emailgreeting": "Dear Angus MacGyver", "emailbody": "Attached is your certificate 'The basics' for the course 'Survival as an '80s action hero'", - "emailcertificatelink": "http://yoursite.com/mod/customcert/view.php?id=4", + "emailcertificatelink": "http://yoursite.com/mod/htmlcert/view.php?id=4", "emailcertificatelinktext": "Certificate report" } }} diff --git a/templates/email_certificate_text.mustache b/templates/email_certificate_text.mustache index 4a58760..b8d8fbd 100644 --- a/templates/email_certificate_text.mustache +++ b/templates/email_certificate_text.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/email_certificate_text + @template mod_htmlcert/email_certificate_text The certificate verification result @@ -35,7 +35,7 @@ { "emailgreeting": "Dear Angus MacGyver", "emailbodyplaintext": "Attached is your certificate 'The basics' for the course 'Survival as an '80s action hero'", - "emailcertificatelink": "http://yoursite.com/mod/customcert/view.php?id=4", + "emailcertificatelink": "http://yoursite.com/mod/htmlcert/view.php?id=4", "emailcertificatelinktext": "Certificate report" } }} diff --git a/templates/mobile_view_activity_page_ionic3.mustache b/templates/mobile_view_activity_page_ionic3.mustache index 72d2e2d..64942d8 100644 --- a/templates/mobile_view_activity_page_ionic3.mustache +++ b/templates/mobile_view_activity_page_ionic3.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/mobile_view_activity_page + @template mod_htmlcert/mobile_view_activity_page The main page to view the custom certificate activity @@ -63,7 +63,7 @@ ], "canmanage": "true", "requiredtimemet": "true", - "fileurl": "http://yoursite.com/mod/customcert/mobile/pluginfile.php?id=4", + "fileurl": "http://yoursite.com/mod/htmlcert/mobile/pluginfile.php?id=4", "showreport": "true", "hasrecipients": "true", "recipients": [ @@ -71,7 +71,7 @@ "id": "2", "issueid": "3", "displayname": "Michaelangelo (Mickey)", - "fileurl": "http://yoursite.com/mod/customcert/mobile/pluginfile.php?id=4", + "fileurl": "http://yoursite.com/mod/htmlcert/mobile/pluginfile.php?id=4", "timecreated": "1528370177" } ], @@ -80,26 +80,26 @@ }} {{=<% %>=}}
- + <%^canmanage%> <%#requiredtimemet%> - {{ 'plugin.mod_customcert.receiveddate' | translate }} + {{ 'plugin.mod_htmlcert.receiveddate' | translate }}
<%#issue%> {{ <% timecreated %> | coreToLocaleString }} <%/issue%> <%^issue%> - {{ 'plugin.mod_customcert.notissued' | translate }} + {{ 'plugin.mod_htmlcert.notissued' | translate }} <%/issue%>
- @@ -109,25 +109,25 @@ <%/requiredtimemet%> <%^requiredtimemet%> -

{{ 'plugin.mod_customcert.requiredtimenotmet' | translate: {$a: { requiredtime: <% certificate.requiredtime %>} } }}

+

{{ 'plugin.mod_htmlcert.requiredtimenotmet' | translate: {$a: { requiredtime: <% certificate.requiredtime %>} } }}

<%/requiredtimemet%> <%/canmanage%> <%#canmanage%> - <%/canmanage%> <%#showreport%> - {{ 'plugin.mod_customcert.listofissues' | translate }} + {{ 'plugin.mod_htmlcert.listofissues' | translate }} <%#showgroups%> - {{ 'plugin.mod_customcert.selectagroup' | translate }} + {{ 'plugin.mod_htmlcert.selectagroup' | translate }} <%#groups%> selected<%/selected%>><% name %> @@ -147,14 +147,14 @@
{{ <% timecreated %> | coreToLocaleString }}
- <%#canmanage%> - @@ -168,7 +168,7 @@ <%/hasrecipients%> <%^hasrecipients%> - {{ 'plugin.mod_customcert.nothingtodisplay' | translate }} + {{ 'plugin.mod_htmlcert.nothingtodisplay' | translate }} <%/hasrecipients%> <%/showreport%> diff --git a/templates/mobile_view_activity_page_latest.mustache b/templates/mobile_view_activity_page_latest.mustache index 6018c2e..93d6fb3 100644 --- a/templates/mobile_view_activity_page_latest.mustache +++ b/templates/mobile_view_activity_page_latest.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/mobile_view_activity_page + @template mod_htmlcert/mobile_view_activity_page The main page to view the custom certificate activity @@ -63,7 +63,7 @@ ], "canmanage": "true", "requiredtimemet": "true", - "fileurl": "http://yoursite.com/mod/customcert/mobile/pluginfile.php?id=4", + "fileurl": "http://yoursite.com/mod/htmlcert/mobile/pluginfile.php?id=4", "showreport": "true", "hasrecipients": "true", "recipients": [ @@ -71,7 +71,7 @@ "id": "2", "issueid": "3", "displayname": "Michaelangelo (Mickey)", - "fileurl": "http://yoursite.com/mod/customcert/mobile/pluginfile.php?id=4", + "fileurl": "http://yoursite.com/mod/htmlcert/mobile/pluginfile.php?id=4", "timecreated": "1528370177" } ], @@ -79,25 +79,25 @@ } }} {{=<% %>=}} - + <%^canmanage%> <%#requiredtimemet%> - {{ 'plugin.mod_customcert.receiveddate' | translate }} + {{ 'plugin.mod_htmlcert.receiveddate' | translate }}
<%#issue%> {{ <% timecreated %> | coreToLocaleString }} <%/issue%> <%^issue%> - {{ 'plugin.mod_customcert.notissued' | translate }} + {{ 'plugin.mod_htmlcert.notissued' | translate }} <%/issue%>
- +
@@ -106,26 +106,26 @@ <%^requiredtimemet%> -

{{ 'plugin.mod_customcert.requiredtimenotmet' | translate: {$a: { requiredtime: <% certificate.requiredtime %>} } }}

+

{{ 'plugin.mod_htmlcert.requiredtimenotmet' | translate: {$a: { requiredtime: <% certificate.requiredtime %>} } }}

<%/requiredtimemet%> <%/canmanage%> <%#canmanage%> - + - {{ 'plugin.mod_customcert.getcustomcert' | translate }} + {{ 'plugin.mod_htmlcert.gethtmlcert' | translate }} <%/canmanage%> <%#showreport%> - {{ 'plugin.mod_customcert.listofissues' | translate: { $a: <% numrecipients %> } }} + {{ 'plugin.mod_htmlcert.listofissues' | translate: { $a: <% numrecipients %> } }} <%#showgroups%> - {{ 'plugin.mod_customcert.selectagroup' | translate }} + {{ 'plugin.mod_htmlcert.selectagroup' | translate }} <%#groups%> <% name %> @@ -142,14 +142,14 @@
{{ <% timecreated %> | coreToLocaleString }}
- + <%#canmanage%> - @@ -161,7 +161,7 @@ <%^hasrecipients%> - {{ 'plugin.mod_customcert.nothingtodisplay' | translate }} + {{ 'plugin.mod_htmlcert.nothingtodisplay' | translate }} <%/hasrecipients%> diff --git a/templates/verify_certificate_result.mustache b/templates/verify_certificate_result.mustache index 8b71a6b..3dd0fd3 100644 --- a/templates/verify_certificate_result.mustache +++ b/templates/verify_certificate_result.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/verify_certificate_result + @template mod_htmlcert/verify_certificate_result The certificate verification result @@ -44,5 +44,5 @@
  • {{#str}}fullname{{/str}}: {{userfullname}}
  • {{#str}}course{{/str}}: {{coursefullname}}
  • -
  • {{#str}}certificate, customcert{{/str}}: {{certificatename}}
  • +
  • {{#str}}certificate, htmlcert{{/str}}: {{certificatename}}
diff --git a/templates/verify_certificate_results.mustache b/templates/verify_certificate_results.mustache index 82abe10..8d544db 100644 --- a/templates/verify_certificate_results.mustache +++ b/templates/verify_certificate_results.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template mod_customcert/verify_certificate_results + @template mod_htmlcert/verify_certificate_results The certificate verification results page @@ -34,7 +34,7 @@ }} {{#success}} {{#issues}} - {{> mod_customcert/verify_certificate_result }} + {{> mod_htmlcert/verify_certificate_result }} {{/issues}} {{> core/notification_success}} {{/success}} diff --git a/tests/behat/activity_options.feature b/tests/behat/activity_options.feature deleted file mode 100644 index 2ef9d27..0000000 --- a/tests/behat/activity_options.feature +++ /dev/null @@ -1,109 +0,0 @@ -@mod @mod_customcert -Feature: Being able to correctly display options on the certificate activity edit form - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - - Scenario: Edit an activity as an Editing Teacher I can see all custom certificate options - And I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I follow "Custom certificate 1" - And I navigate to "Edit settings" in current page administration - And I should see "Email students" - And I should see "Email teachers" - And I should see "Email others" - And I should see "Allow anyone to verify a certificate" - And I should see "Required minutes in course" - And I should see "Set protection" - - @javascript - Scenario: Create an activity as an Editing Teacher without required capabilities I can't see all custom certificate options - And I log in as "admin" - And I set the following system permissions of "Teacher" role: - | capability | permission | - | mod/customcert:manageemailstudents | Prevent | - | mod/customcert:manageemailteachers | Prevent | - | mod/customcert:manageemailothers | Prevent | - | mod/customcert:manageverifyany | Prevent | - | mod/customcert:managerequiredtime | Prevent | - | mod/customcert:manageprotection | Prevent | - And I log out - When I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add a "Custom certificate" to section "1" - And I should not see "Email students" - And I should not see "Email teachers" - And I should not see "Email others" - And I should not see "Allow anyone to verify a certificate" - And I should not see "Required minutes in course" - And I should not see "Set protection" - - Scenario: Edit an activity as an Editing Teacher without required capabilities I can't see all custom certificate options - And I log in as "admin" - And I set the following system permissions of "Teacher" role: - | capability | permission | - | mod/customcert:manageemailstudents | Prevent | - | mod/customcert:manageemailteachers | Prevent | - | mod/customcert:manageemailothers | Prevent | - | mod/customcert:manageverifyany | Prevent | - | mod/customcert:managerequiredtime | Prevent | - | mod/customcert:manageprotection | Prevent | - And I log out - When I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I follow "Custom certificate 1" - And I navigate to "Edit settings" in current page administration - And I should not see "Email students" - And I should not see "Email teachers" - And I should not see "Email others" - And I should not see "Allow anyone to verify a certificate" - And I should not see "Required minutes in course" - And I should not see "Set protection" - - @javascript - Scenario: Add an activity using default custom certificate options - And I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add a "Custom certificate" to section "0" - And the field "emailstudents" matches value "0" - And the field "emailteachers" matches value "0" - And the field "emailothers" matches value "" - And the field "verifyany" matches value "0" - And the field "requiredtime" matches value "0" - And the field "protection_print" matches value "0" - And the field "protection_modify" matches value "0" - And the field "protection_copy" matches value "0" - - @javascript - Scenario: Add an activity using configured custom certificate options - And the following config values are set as admin: - | emailstudents | 1 | customcert | - | emailteachers | 1 | customcert | - | emailothers | test@moodle.com | customcert | - | verifyany | 1 | customcert | - | requiredtime | 5 | customcert | - | protection_print | 1 | customcert | - | protection_modify | 1 | customcert | - | protection_copy | 1 | customcert | - And I log in as "teacher1" - And I am on "Course 1" course homepage with editing mode on - And I add a "Custom certificate" to section "1" - And the field "emailstudents" matches value "1" - And the field "emailteachers" matches value "1" - And the field "emailothers" matches value "test@moodle.com" - And the field "verifyany" matches value "1" - And the field "requiredtime" matches value "5" - And the field "protection_print" matches value "1" - And the field "protection_modify" matches value "1" - And the field "protection_copy" matches value "1" diff --git a/tests/behat/behat_mod_customcert.php b/tests/behat/behat_mod_customcert.php deleted file mode 100644 index f210962..0000000 --- a/tests/behat/behat_mod_customcert.php +++ /dev/null @@ -1,150 +0,0 @@ -. - -/** - * Contains the class responsible for step definitions related to mod_customcert. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. - -require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); - -/** - * The class responsible for step definitions related to mod_customcert. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class behat_mod_customcert extends behat_base { - - /** - * Adds an element to the specified page of a template. - * - * phpcs:ignore - * @Given /^I add the element "(?P(?:[^"]|\\")*)" to page "(?P\d+)" of the "(?P(?:[^"]|\\")*)" certificate template$/ - * @param string $elementname - * @param int $pagenum - * @param string $templatename - */ - public function i_add_the_element_to_the_certificate_template_page($elementname, $pagenum, $templatename) { - global $DB; - - $template = $DB->get_record('customcert_templates', array('name' => $templatename), '*', MUST_EXIST); - $page = $DB->get_record('customcert_pages', array('templateid' => $template->id, 'sequence' => $pagenum), - '*', MUST_EXIST); - - $this->execute('behat_forms::i_set_the_field_to', array($this->escape('element_' . $page->id), - $this->escape($elementname))); - $this->execute('behat_forms::press_button', get_string('addelement', 'customcert')); - } - - /** - * Deletes an element from a specified page of a template. - * - * @Given /^I delete page "(?P\d+)" of the "(?P(?:[^"]|\\")*)" certificate template$/ - * @param int $pagenum - * @param string $templatename - */ - public function i_delete_the_certificate_page($pagenum, $templatename) { - global $DB; - - $template = $DB->get_record('customcert_templates', array('name' => $templatename), '*', MUST_EXIST); - $page = $DB->get_record('customcert_pages', array('templateid' => $template->id, 'sequence' => $pagenum), - '*', MUST_EXIST); - - $this->execute('behat_general::i_click_on_in_the', array('Delete page', 'link', - $this->escape('#id_page_' . $page->id), 'css_element')); - $this->execute('behat_forms::press_button', get_string('continue')); - } - - /** - * Verifies the certificate code for a user. - * - * @Given /^I verify the "(?P(?:[^"]|\\")*)" certificate for the user "(?P(?:[^"]|\\")*)"$/ - * @param string $certificatename - * @param string $username - */ - public function i_verify_the_custom_certificate_for_user($certificatename, $username) { - global $DB; - - $certificate = $DB->get_record('customcert', array('name' => $certificatename), '*', MUST_EXIST); - $user = $DB->get_record('user', array('username' => $username), '*', MUST_EXIST); - $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $certificate->id), - '*', MUST_EXIST); - - $this->execute('behat_forms::i_set_the_field_to', array(get_string('code', 'customcert'), $issue->code)); - $this->execute('behat_forms::press_button', get_string('verify', 'customcert')); - $this->execute('behat_general::assert_page_contains_text', get_string('verified', 'customcert')); - $this->execute('behat_general::assert_page_not_contains_text', get_string('notverified', 'customcert')); - } - - /** - * Verifies the certificate code for a user. - * - * @Given /^I can not verify the "(?P(?:[^"]|\\")*)" certificate for the user "(?P(?:[^"]|\\")*)"$/ - * @param string $certificatename - * @param string $username - */ - public function i_can_not_verify_the_custom_certificate_for_user($certificatename, $username) { - global $DB; - - $certificate = $DB->get_record('customcert', array('name' => $certificatename), '*', MUST_EXIST); - $user = $DB->get_record('user', array('username' => $username), '*', MUST_EXIST); - $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $certificate->id), - '*', MUST_EXIST); - - $this->execute('behat_forms::i_set_the_field_to', array(get_string('code', 'customcert'), $issue->code)); - $this->execute('behat_forms::press_button', get_string('verify', 'customcert')); - $this->execute('behat_general::assert_page_contains_text', get_string('notverified', 'customcert')); - $this->execute('behat_general::assert_page_not_contains_text', get_string('verified', 'customcert')); - } - - /** - * Directs the user to the URL for verifying a certificate. - * - * This has been created as we allow non-users to verify certificates and they can not navigate to - * the page like a conventional user. - * - * @Given /^I visit the verification url for the "(?P(?:[^"]|\\")*)" certificate$/ - * @param string $certificatename - */ - public function i_visit_the_verification_url_for_custom_certificate($certificatename) { - global $DB; - - $certificate = $DB->get_record('customcert', array('name' => $certificatename), '*', MUST_EXIST); - $template = $DB->get_record('customcert_templates', array('id' => $certificate->templateid), '*', MUST_EXIST); - - $url = new moodle_url('/mod/customcert/verify_certificate.php', array('contextid' => $template->contextid)); - $this->getSession()->visit($this->locate_path($url->out_as_local_url())); - } - - /** - * Directs the user to the URL for verifying all certificates on the site. - * - * @Given /^I visit the verification url for the site$/ - */ - public function i_visit_the_verification_url_for_the_site() { - $url = new moodle_url('/mod/customcert/verify_certificate.php'); - $this->getSession()->visit($this->locate_path($url->out_as_local_url())); - } -} diff --git a/tests/behat/managing_elements.feature b/tests/behat/managing_elements.feature deleted file mode 100644 index f734eb3..0000000 --- a/tests/behat/managing_elements.feature +++ /dev/null @@ -1,377 +0,0 @@ -@mod @mod_customcert -Feature: Being able to manage elements in a certificate template - In order to ensure managing elements in a certificate template works as expected - As a teacher - I need to manage elements in a certificate template - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | teacher2 | Teacher | 2 | teacher2@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | teacher2 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | assign | Assignment 1 | Assignment 1 intro | C1 | assign1 | - | assign | Assignment 2 | Assignment 2 intro | C1 | assign2 | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Edit certificate" in current page administration - - Scenario: Add and edit elements in a certificate template - # Background image. - And I add the element "Background image" to page "1" of the "Custom certificate 1" certificate template - And I press "Save changes" - And I should see "Background image" in the "elementstable" "table" - # Border. - And I add the element "Border" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Width | 2 | - | Colour | #045ECD | - And I press "Save changes" - And I should see "Border" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Border" "table_row" - And the following fields match these values: - | Width | 2 | - | Colour | #045ECD | - And I press "Save changes" - # Category name. - And I add the element "Category name" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Category name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Category name" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Code. - And I add the element "Code" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Code" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Code" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Course field. - And I add the element "Course field" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Course field" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Course field" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Course name. - And I add the element "Course name" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Type | Short name | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Course name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Course name" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Type | Short name | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Date. - And I add the element "Date" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Date item | Course start date | - | Date format | 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Date" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Date" "table_row" - And the following fields match these values: - | Date item | Course start date | - | Date format | 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Date range. - And I add the element "Date range" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Date item | Course start date | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - | Fallback string | {{range_first_year}} | - | id_startdate_0_day | 24 | - | id_startdate_0_month | October | - | id_startdate_0_year | 2015 | - | id_enddate_0_day | 21 | - | id_enddate_0_month | March | - | id_enddate_0_year | 2016 | - | String | Oct to March | - And I press "Save changes" - And I should see "Date range" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Date range" "table_row" - And the following fields match these values: - | Date item | Course start date | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - | Fallback string | {{range_first_year}} | - | id_startdate_0_day | 24 | - | id_startdate_0_month | October | - | id_startdate_0_year | 2015 | - | id_enddate_0_day | 21 | - | id_enddate_0_month | March | - | id_enddate_0_year | 2016 | - | String | Oct to March | - And I press "Save changes" - # Digital signature. - And I add the element "Digital signature" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Signature name | This is the signature name | - | Signature password | Some awesome password | - | Signature location | Mordor | - | Signature reason | Meh, felt like it. | - | Signature contact info | Sauron | - | Width | 25 | - | Height | 15 | - And I press "Save changes" - And I should see "Digital signature" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Digital signature" "table_row" - And the following fields match these values: - | Signature name | This is the signature name | - | Signature password | Some awesome password | - | Signature location | Mordor | - | Signature reason | Meh, felt like it. | - | Signature contact info | Sauron | - | Width | 25 | - | Height | 15 | - And I press "Save changes" - # Grade. - And I add the element "Grade" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Grade item | Activity : Assignment 1 | - | Grade format | Percentage | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Grade" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Grade" "table_row" - And the following fields match these values: - | Grade item | Activity : Assignment 1 | - | Grade format | Percentage | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Grade item name. - And I add the element "Grade item name" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Grade item | Activity : Assignment 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Grade item name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Grade item name" "table_row" - And the following fields match these values: - | Grade item | Activity : Assignment 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Image. - And I add the element "Image" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Width | 25 | - | Height | 15 | - | Alpha channel | 0.7 | - And I press "Save changes" - And I should see "Image" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Image" "table_row" - And the following fields match these values: - | Width | 25 | - | Height | 15 | - | Alpha channel | 0.7 | - And I press "Save changes" - # Student name. - And I add the element "Student name" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Student name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Student name" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Teacher name. - And I add the element "Teacher name" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Teacher | Teacher 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Teacher name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Teacher name" "table_row" - And the following fields match these values: - | Teacher | Teacher 2 | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # Text. - And I add the element "Text" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Text | Test this | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "Text" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Text" "table_row" - And the following fields match these values: - | Text | Test this | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # User field. - And I add the element "User field" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | User field | Country | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I should see "User field" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "User field" "table_row" - And the following fields match these values: - | User field | Country | - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - # User picture. - And I add the element "User picture" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Width | 10 | - | Height | 10 | - And I press "Save changes" - And I should see "User picture" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "User picture" "table_row" - And the following fields match these values: - | Width | 10 | - | Height | 10 | - And I press "Save changes" - # QR Code. - And I add the element "QR code" to page "1" of the "Custom certificate 1" certificate template - And I set the following fields to these values: - | Width | 25 | - | Height | 15 | - And I press "Save changes" - And I should see "QR code" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "QR code" "table_row" - And the following fields match these values: - | Width | 25 | - | Height | 15 | - And I press "Save changes" - # Just to test there are no exceptions being thrown. - And I follow "Reposition elements" - And I press "Save and close" - And I press "Save changes and preview" - - Scenario: Delete an element from a certificate template - And I add the element "Background image" to page "1" of the "Custom certificate 1" certificate template - And I press "Save changes" - And I should see "Background image" in the "elementstable" "table" - And I add the element "Student name" to page "1" of the "Custom certificate 1" certificate template - And I press "Save changes" - And I should see "Student name" in the "elementstable" "table" - And I click on ".delete-icon" "css_element" in the "Student name" "table_row" - And I press "Cancel" - And I should see "Background image" in the "elementstable" "table" - And I should see "Student name" in the "elementstable" "table" - And I click on ".delete-icon" "css_element" in the "Student name" "table_row" - And I press "Continue" - And I should see "Background image" in the "elementstable" "table" - And I should not see "Student name" in the "elementstable" "table" diff --git a/tests/behat/managing_pages.feature b/tests/behat/managing_pages.feature deleted file mode 100644 index 43e1a74..0000000 --- a/tests/behat/managing_pages.feature +++ /dev/null @@ -1,42 +0,0 @@ -@mod @mod_customcert -Feature: Being able to manage pages in a certificate template - In order to ensure managing pages in a certificate template works as expected - As a teacher - I need to manage pages in a certificate template - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Edit certificate" in current page administration - - Scenario: Adding a page to a certificate template - And I follow "Add page" - And I should see "Page 1" - And I should see "Page 2" - - Scenario: Deleting a page from a certificate template - And I add the element "Background image" to page "1" of the "Custom certificate 1" certificate template - And I press "Save changes" - And I add the element "Student name" to page "1" of the "Custom certificate 1" certificate template - And I press "Save changes" - And I follow "Add page" - And I should see "Page 1" - And I should see "Page 2" - And I delete page "2" of the "Custom certificate 1" certificate template - And I should see "Background image" in the "elementstable" "table" - And I should see "Student name" in the "elementstable" "table" - And I should not see "Page 1" - And I should not see "Page 2" diff --git a/tests/behat/managing_templates.feature b/tests/behat/managing_templates.feature deleted file mode 100644 index a79fabc..0000000 --- a/tests/behat/managing_templates.feature +++ /dev/null @@ -1,102 +0,0 @@ -@mod @mod_customcert -Feature: Being able to manage site templates - In order to ensure managing site templates works as expected - As an admin - I need to manage and load site templates - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - And I log in as "admin" - - Scenario: Adding a site template and loading it into a course certificate - And I navigate to "Plugins" in site administration - And I follow "Manage activities" - And I click on "Settings" "link" in the "Custom certificate" "table_row" - And I follow "Manage templates" - And I press "Create template" - And I set the field "Name" to "Site template" - And I press "Save changes" - And I add the element "Border" to page "1" of the "Site template" certificate template - And I set the following fields to these values: - | Width | 5 | - | Colour | #045ECD | - And I press "Save changes" - And I add the element "Category name" to page "1" of the "Site template" certificate template - And I set the following fields to these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - And I press "Save changes" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Edit certificate" in current page administration - And I set the field "ltid" to "Site template" - And I click on "Load" "button" in the "#loadtemplateform" "css_element" - And I should see "Are you sure you wish to load this template" - And I press "Cancel" - And "elementstable" "table" should not exist - And I set the field "ltid" to "Site template" - And I click on "Load" "button" in the "#loadtemplateform" "css_element" - And I should see "Are you sure you wish to load this template" - And I press "Continue" - And I should see "Border" in the "elementstable" "table" - And I should see "Category name" in the "elementstable" "table" - And I click on ".edit-icon" "css_element" in the "Border" "table_row" - And the following fields match these values: - | Width | 5 | - | Colour | #045ECD | - And I press "Save changes" - And I click on ".edit-icon" "css_element" in the "Category name" "table_row" - And the following fields match these values: - | Font | Helvetica | - | Size | 20 | - | Colour | #045ECD | - | Width | 20 | - | Reference point location | Top left | - - Scenario: Deleting a site template - And I navigate to "Plugins" in site administration - And I follow "Manage activities" - And I click on "Settings" "link" in the "Custom certificate" "table_row" - And I follow "Manage templates" - And I press "Create template" - And I set the field "Name" to "Site template" - And I press "Save changes" - And I follow "Manage templates" - And I click on ".delete-icon" "css_element" in the "Site template" "table_row" - And I press "Cancel" - And I should see "Site template" - And I click on ".delete-icon" "css_element" in the "Site template" "table_row" - And I press "Continue" - And I should not see "Site template" - - Scenario: Duplicating a site template - And I navigate to "Plugins" in site administration - And I follow "Manage activities" - And I click on "Settings" "link" in the "Custom certificate" "table_row" - And I follow "Manage templates" - And I press "Create template" - And I set the field "Name" to "Site template" - And I press "Save changes" - And I follow "Manage templates" - And I click on ".duplicate-icon" "css_element" in the "Site template" "table_row" - And I press "Cancel" - And I should see "Site template" - And I should not see "Site template (duplicate)" - And I click on ".duplicate-icon" "css_element" in the "Site template" "table_row" - And I press "Continue" - And I should see "Site template" - And I should see "Site template (duplicate)" diff --git a/tests/behat/my_certificates.feature b/tests/behat/my_certificates.feature deleted file mode 100644 index cc59261..0000000 --- a/tests/behat/my_certificates.feature +++ /dev/null @@ -1,39 +0,0 @@ -@mod @mod_customcert -Feature: Being able to view the certificates you have been issued - In order to ensure that a user can view the certificates they have been issued - As a student - I need to view the certificates I have been issued - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - | Course 2 | C2 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - | student1 | C2 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - | customcert | Custom certificate 2 | Custom certificate 2 intro | C2 | customcert2 | - - Scenario: View your issued certificates on the my certificates page - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I follow "Profile" in the user menu - And I follow "My certificates" - And I should see "Custom certificate 1" - And I should not see "Custom certificate 2" - And I am on "Course 2" course homepage - And I follow "Custom certificate 2" - And I press "View certificate" - And I follow "Profile" in the user menu - And I follow "My certificates" - And I should see "Custom certificate 1" - And I should see "Custom certificate 2" diff --git a/tests/behat/required_minutes.feature b/tests/behat/required_minutes.feature deleted file mode 100644 index e65cf4d..0000000 --- a/tests/behat/required_minutes.feature +++ /dev/null @@ -1,39 +0,0 @@ -@mod @mod_customcert -Feature: Being able to set the required minutes in a course before viewing the certificate - In order to ensure the required minutes in a course setting works as expected - As a teacher - I need to ensure students can not view a certificate until the required minutes have passed - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | requiredtime | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 1 | - - Scenario: Check the user can not access the certificate before the required time - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I should see "You must spend at least a minimum of" - And I should not see "View certificate" - And I press "Continue" - And I should see "Custom certificate 1" - - Scenario: Check the user can access the certificate after the required time - And I log in as "student1" - And I am on "Course 1" course homepage - And I wait "60" seconds - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I should not see "You must spend at least a minimum of" - And I should see "View certificate" diff --git a/tests/behat/show_position_x_y.feature b/tests/behat/show_position_x_y.feature deleted file mode 100644 index e4aad1d..0000000 --- a/tests/behat/show_position_x_y.feature +++ /dev/null @@ -1,52 +0,0 @@ -@mod @mod_customcert -Feature: Being able to set a site setting to determine whether or not to display the position X and Y fields - In order to ensure the show position X and Y fields setting works as expected - As an admin - I need to ensure teachers can see the position X and Y fields depending on the site setting - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - - Scenario: Adding an element with the show position X and Y setting disabled - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Edit certificate" in current page administration - And I add the element "Code" to page "1" of the "Custom certificate 1" certificate template - And I should not see "Position X" - And I should not see "Position Y" - - Scenario: Adding an element with the show position X and Y setting enabled - And I log in as "admin" - And I navigate to "Plugins" in site administration - And I follow "Manage activities" - And I click on "Settings" "link" in the "Custom certificate" "table_row" - And I set the field "Show position X and Y" to "1" - And I press "Save changes" - And I log out - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Edit certificate" in current page administration - And I add the element "Code" to page "1" of the "Custom certificate 1" certificate template - And I should see "Position X" - And I should see "Position Y" - And I set the following fields to these values: - | Position X | 5 | - | Position Y | 10 | - And I press "Save changes" - And I click on ".edit-icon" "css_element" in the "Code" "table_row" - And the following fields match these values: - | Position X | 5 | - | Position Y | 10 | diff --git a/tests/behat/verify_certificates.feature b/tests/behat/verify_certificates.feature deleted file mode 100644 index 936bdac..0000000 --- a/tests/behat/verify_certificates.feature +++ /dev/null @@ -1,108 +0,0 @@ -@mod @mod_customcert -Feature: Being able to verify that a certificate is valid or not - In order to ensure that a user can verify a certificate is valid - As a teacher and non-user - I need to be able to verify a certificate - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | verifyany | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 0 | - | customcert | Custom certificate 2 | Custom certificate 2 intro | C1 | customcert2 | 1 | - - Scenario: Verify a certificate as a teacher - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I log out - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I navigate to "Verify certificate" in current page administration - And I set the field "Code" to "NOTAVALIDCODE" - And I press "Verify" - And I should see "Not verified" - And I verify the "Custom certificate 1" certificate for the user "student1" - - Scenario: Attempt to verify a certificate as a non-user - And I visit the verification url for the "Custom certificate 1" certificate - # User should get redirected to log in as we do not allow non-users to verify. - And I should see "Remember username" - - Scenario: Verify a certificate as a non-user - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 2" - And I press "View certificate" - And I log out - And I visit the verification url for the "Custom certificate 2" certificate - And I set the field "Code" to "NOTAVALIDCODE" - And I press "Verify" - And I should see "Not verified" - And I verify the "Custom certificate 2" certificate for the user "student1" - - Scenario: Attempt to verify a certificate as a non-user using the site-wide URL - And the following config values are set as admin: - | verifyallcertificates | 0 | customcert | - And I visit the verification url for the site - # User should see an error message as we do not allow non-users to verify all certificates on the site. - And I should see "You do not have the permission to verify all certificates on the site" - - Scenario: Attempt to verify a certificate as a teacher using the site-wide URL - And the following config values are set as admin: - | verifyallcertificates | 0 | customcert | - And I log in as "teacher1" - And I visit the verification url for the site - # User should see an error message as we do not allow teachers to verify all certificates on the site. - And I should see "You do not have the permission to verify all certificates on the site" - - Scenario: Verify a certificate as an admin using the site-wide URL - And the following config values are set as admin: - | verifyallcertificates | 0 | customcert | - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I am on "Course 1" course homepage - And I follow "Custom certificate 2" - And I press "View certificate" - And I log out - And I log in as "admin" - # The admin (or anyone with the capability 'mod/customcert:verifyallcertificates') can visit the URL regardless of the setting. - And I visit the verification url for the site - And I set the field "Code" to "NOTAVALIDCODE" - And I press "Verify" - And I should see "Not verified" - # The admin (or anyone with the capability 'mod/customcert:verifyallcertificates') can verify any certificate regardless of the 'verifyany' setting. - And I verify the "Custom certificate 1" certificate for the user "student1" - And I verify the "Custom certificate 2" certificate for the user "student1" - - Scenario: Verify a certificate as a non-user using the site-wide URL - And the following config values are set as admin: - | verifyallcertificates | 1 | customcert | - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I am on "Course 1" course homepage - And I follow "Custom certificate 2" - And I press "View certificate" - And I log out - And I visit the verification url for the site - And I set the field "Code" to "NOTAVALIDCODE" - And I press "Verify" - And I should see "Not verified" - And I can not verify the "Custom certificate 1" certificate for the user "student1" - And I verify the "Custom certificate 2" certificate for the user "student1" diff --git a/tests/behat/view_issued_certificates.feature b/tests/behat/view_issued_certificates.feature deleted file mode 100644 index c8ffd10..0000000 --- a/tests/behat/view_issued_certificates.feature +++ /dev/null @@ -1,73 +0,0 @@ -@mod @mod_customcert -Feature: Being able to view the certificates that have been issued - In order to ensure that a user can view the certificates that have been issued - As a teacher - I need to view the certificates that have been issued - - Background: - Given the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | - And the following config values are set as admin: - | showuseridentity | username,email | - - Scenario: View the issued certificates - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I log out - And I log in as "student2" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I log out - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I should see "Student 1" - And I should see "Student 2" - And I should see "Email address" - And I should see "Username" - And "Student 1" row "Email address" column of "generaltable" table should contain "student1@example.com" - And "Student 1" row "Username" column of "generaltable" table should contain "student1" - And "Student 2" row "Email address" column of "generaltable" table should contain "student2@example.com" - And "Student 2" row "Username" column of "generaltable" table should contain "student2" - - Scenario: Delete an issued certificate - And I log in as "student1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I log out - And I log in as "student2" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I press "View certificate" - And I log out - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I follow "Custom certificate 1" - And I should see "Student 1" - And I should see "Student 2" - And I click on ".delete-icon" "css_element" in the "Student 2" "table_row" - And I press "Cancel" - And I should see "Student 1" - And I should see "Student 2" - And I click on ".delete-icon" "css_element" in the "Student 2" "table_row" - And I press "Continue" - And I should see "Student 1" - And I should not see "Student 2" diff --git a/tests/element_helper_test.php b/tests/element_helper_test.php deleted file mode 100644 index df8a12a..0000000 --- a/tests/element_helper_test.php +++ /dev/null @@ -1,393 +0,0 @@ -. - -/** - * File contains the unit tests for the element helper class. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; - -/** - * Unit tests for the element helper class. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_customcert_element_helper_testcase extends advanced_testcase { - - /** - * Test set up. - */ - public function setUp(): void { - $this->resetAfterTest(); - } - - /** - * Tests we are returning the correct course id for an element in a course customcert activity. - */ - public function test_get_courseid_element_in_course_certificate() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a custom certificate in the course. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - - // Get the template to add elements to. - $template = $DB->get_record('customcert_templates', array('contextid' => context_module::instance($customcert->cmid)->id)); - $template = new \mod_customcert\template($template); - - // Add a page to the template. - $pageid = $template->add_page(); - - // Add an element to this page. - $element = new \stdClass(); - $element->name = 'Test element'; - $element->element = 'testelement'; - $element->pageid = $pageid; - $element->sequence = \mod_customcert\element_helper::get_element_sequence($element->pageid); - $element->timecreated = time(); - $element->id = $DB->insert_record('customcert_elements', $element); - - // Confirm the correct course id is returned. - $this->assertEquals($course->id, \mod_customcert\element_helper::get_courseid($element->id)); - } - - /** - * Tests we are returning the correct course id for an element in a site template. - */ - public function test_get_courseid_element_in_site_template() { - global $DB, $SITE; - - // Add a template to the site. - $template = \mod_customcert\template::create('Site template', context_system::instance()->id); - - // Add a page to the template. - $pageid = $template->add_page(); - - // Add an element to this page. - $element = new \stdClass(); - $element->name = 'Test element'; - $element->element = 'testelement'; - $element->pageid = $pageid; - $element->sequence = \mod_customcert\element_helper::get_element_sequence($element->pageid); - $element->timecreated = time(); - $element->id = $DB->insert_record('customcert_elements', $element); - - // Confirm the correct course id is returned. - $this->assertEquals($SITE->id, \mod_customcert\element_helper::get_courseid($element->id)); - } - - /** - * Tests we are returning the correct course module id for an element in a course customcert activity. - */ - public function test_get_context_element_in_course_certificate() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a custom certificate in the course. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - - // Get the template to add elements to. - $template = $DB->get_record('customcert_templates', array('contextid' => context_module::instance($customcert->cmid)->id)); - $template = new \mod_customcert\template($template); - - // Add a page to the template. - $pageid = $template->add_page(); - - // Add an element to this page. - $element = new \stdClass(); - $element->name = 'Test element'; - $element->element = 'testelement'; - $element->pageid = $pageid; - $element->sequence = \mod_customcert\element_helper::get_element_sequence($element->pageid); - $element->timecreated = time(); - $element->id = $DB->insert_record('customcert_elements', $element); - - // Confirm the correct course module id is returned. - $this->assertEquals(context_module::instance($customcert->cmid), - \mod_customcert\element_helper::get_context($element->id)); - } - - /** - * Tests we are returning the correct course module id for an element in a site template. - */ - public function test_get_context_element_in_site_template() { - global $DB; - - // Add a template to the site. - $template = \mod_customcert\template::create('Site template', context_system::instance()->id); - - // Add a page to the template. - $pageid = $template->add_page(); - - // Add an element to this page. - $element = new \stdClass(); - $element->name = 'Test element'; - $element->element = 'testelement'; - $element->pageid = $pageid; - $element->sequence = \mod_customcert\element_helper::get_element_sequence($element->pageid); - $element->timecreated = time(); - $element->id = $DB->insert_record('customcert_elements', $element); - - // Confirm the correct course module id is returned. - $this->assertEquals(context_system::instance(), \mod_customcert\element_helper::get_context($element->id)); - } - - /** - * Test we return the correct grade items in a course. - */ - public function test_get_grade_items() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a few gradeable items. - $assign1 = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); - $assign2 = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); - $assign3 = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); - - // Create a manual grade item. - $gi = $this->getDataGenerator()->create_grade_item(['courseid' => $course->id]); - - // Create a category grade item. - $gc = $this->getDataGenerator()->create_grade_category(['courseid' => $course->id]); - $gc = $DB->get_record('grade_items', ['itemtype' => 'category', 'iteminstance' => $gc->id]); - - // Create an item attached to an outcome. - $outcome = $this->getDataGenerator()->create_grade_outcome(['courseid' => $course->id, 'shortname' => 'outcome']); - $go = $this->getDataGenerator()->create_grade_item( - [ - 'courseid' => $course->id, - 'outcomeid' => $outcome->id - ] - ); - - // Confirm the function returns the correct number of grade items. - $gradeitems = \mod_customcert\element_helper::get_grade_items($course); - $this->assertCount(6, $gradeitems); - $this->assertArrayHasKey($assign1->cmid, $gradeitems); - $this->assertArrayHasKey($assign2->cmid, $gradeitems); - $this->assertArrayHasKey($assign3->cmid, $gradeitems); - $this->assertArrayHasKey('gradeitem:' . $gi->id, $gradeitems); - $this->assertArrayHasKey('gradeitem:' . $gc->id, $gradeitems); - $this->assertArrayHasKey('gradeitem:' . $go->id, $gradeitems); - } - - /** - * Test we return the correct grade information for an activity. - */ - public function test_get_mod_grade_info() { - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Set that we want 3 decimals to display. - grade_set_setting($course->id, 'decimalpoints', 3); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Create a gradeable item. - $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); - - // Give a grade to the student. - $gi = grade_item::fetch( - [ - 'itemtype' => 'mod', - 'itemmodule' => 'assign', - 'iteminstance' => $assign->id, - 'courseid' => $course->id - ] - ); - $datagrade = 50; - $time = time(); - $grade = new grade_grade(); - $grade->itemid = $gi->id; - $grade->userid = $student1->id; - $grade->rawgrade = $datagrade; - $grade->finalgrade = $datagrade; - $grade->rawgrademax = 100; - $grade->rawgrademin = 0; - $grade->timecreated = $time; - $grade->timemodified = $time; - $grade->insert(); - - // Check that the user received the grade. - $grade = \mod_customcert\element_helper::get_mod_grade_info( - $assign->cmid, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student1->id - ); - - $this->assertEquals($assign->name, $grade->get_name()); - $this->assertEquals('50.00000', $grade->get_grade()); - $this->assertEquals('50.000 %', $grade->get_displaygrade()); - $this->assertEquals($time, $grade->get_dategraded()); - - // Check that the user we did not grade has no grade. - $grade = \mod_customcert\element_helper::get_mod_grade_info( - $assign->cmid, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student2->id - ); - $this->assertEquals($assign->name, $grade->get_name()); - $this->assertEquals(null, $grade->get_grade()); - $this->assertEquals('-', $grade->get_displaygrade()); - $this->assertEquals(null, $grade->get_dategraded()); - - grade_get_setting($course->id, null, null, true); - } - - /** - * Test we return the correct grade information for a course. - */ - public function test_get_course_grade_info() { - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Set that we want 3 decimals to display. - grade_set_setting($course->id, 'decimalpoints', 3); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Get the course item. - $coursegradeitem = grade_item::fetch_course_item($course->id); - - $datagrade = 50; - $time = time(); - $grade = new grade_grade(); - $grade->itemid = $coursegradeitem->id; - $grade->userid = $student1->id; - $grade->rawgrade = $datagrade; - $grade->finalgrade = $datagrade; - $grade->rawgrademax = 100; - $grade->rawgrademin = 0; - $grade->timecreated = $time; - $grade->timemodified = $time; - $grade->insert(); - - // Check that the user received the grade. - $grade = \mod_customcert\element_helper::get_course_grade_info( - $course->id, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student1->id - ); - - $this->assertEquals(get_string('coursetotal', 'grades'), $grade->get_name()); - $this->assertEquals('50.00000', $grade->get_grade()); - $this->assertEquals('50.000 %', $grade->get_displaygrade()); - $this->assertEquals($time, $grade->get_dategraded()); - - // Check that the user we did not grade has no grade. - $grade = \mod_customcert\element_helper::get_course_grade_info( - $course->id, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student2->id - ); - $this->assertEquals(get_string('coursetotal', 'grades'), $grade->get_name()); - $this->assertEquals(null, $grade->get_grade()); - $this->assertEquals('-', $grade->get_displaygrade()); - $this->assertEquals(null, $grade->get_dategraded()); - - grade_get_setting($course->id, null, null, true); - } - - /** - * Test we return the correct grade information for a grade item. - */ - public function test_get_grade_item_info() { - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Set that we want 3 decimals to display. - grade_set_setting($course->id, 'decimalpoints', 3); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Create a manual grade item. - $gi = $this->getDataGenerator()->create_grade_item(['itemname' => 'Grade item yo', 'courseid' => $course->id]); - - // Give a grade to the student. - $gi = grade_item::fetch(['id' => $gi->id]); - $datagrade = 50; - $time = time(); - $grade = new grade_grade(); - $grade->itemid = $gi->id; - $grade->userid = $student1->id; - $grade->rawgrade = $datagrade; - $grade->finalgrade = $datagrade; - $grade->rawgrademax = 100; - $grade->rawgrademin = 0; - $grade->timecreated = $time; - $grade->timemodified = $time; - $grade->insert(); - - // Check that the user received the grade. - $grade = \mod_customcert\element_helper::get_grade_item_info( - $gi->id, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student1->id - ); - - $this->assertEquals('Grade item yo', $grade->get_name()); - $this->assertEquals('50.00000', $grade->get_grade()); - $this->assertEquals('50.000 %', $grade->get_displaygrade()); - $this->assertEquals($time, $grade->get_dategraded()); - - // Check that the user we did not grade has no grade. - $grade = \mod_customcert\element_helper::get_grade_item_info( - $gi->id, - GRADE_DISPLAY_TYPE_PERCENTAGE, - $student2->id - ); - $this->assertEquals('Grade item yo', $grade->get_name()); - $this->assertEquals(null, $grade->get_grade()); - $this->assertEquals('-', $grade->get_displaygrade()); - $this->assertEquals(null, $grade->get_dategraded()); - - grade_get_setting($course->id, null, null, true); - } -} diff --git a/tests/email_certificate_task_test.php b/tests/email_certificate_task_test.php deleted file mode 100644 index e942e70..0000000 --- a/tests/email_certificate_task_test.php +++ /dev/null @@ -1,419 +0,0 @@ -. - -/** - * File contains the unit tests for the email certificate task. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Unit tests for the email certificate task. - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_customcert_task_email_certificate_task_testcase extends advanced_testcase { - - /** - * Test set up. - */ - public function setUp(): void { - $this->resetAfterTest(); - } - - /** - * Tests the email certificate task when there are no elements. - */ - public function test_email_certificates_no_elements() { - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a user. - $user1 = $this->getDataGenerator()->create_user(); - - // Create a custom certificate with no elements. - $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); - - // Enrol the user as a student. - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm that we did not send any emails because the certificate has no elements. - $this->assertCount(0, $emails); - } - - /** - * Tests the email certificate task for users without a capability to receive a certificate. - */ - public function test_email_certificates_no_cap() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create some users. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - - // Enrol two of them in the course as students but revoke their right to receive a certificate issue. - $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - $this->getDataGenerator()->enrol_user($user2->id, $course->id); - - unassign_capability('mod/customcert:receiveissue', $roleids['student']); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm that we did not send any emails. - $this->assertCount(0, $emails); - } - - /** - * Tests the email certificate task for students. - */ - public function test_email_certificates_students() { - global $CFG, $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create some users. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - $user3 = $this->getDataGenerator()->create_user(array('firstname' => 'Teacher', 'lastname' => 'One')); - - // Enrol two of them in the course as students. - $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - $this->getDataGenerator()->enrol_user($user2->id, $course->id); - - // Enrol one of the users as a teacher. - $this->getDataGenerator()->enrol_user($user3->id, $course->id, $roleids['editingteacher']); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, - 'emailstudents' => 1)); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Ok, now issue this to one user. - \mod_customcert\certificate::issue_certificate($customcert->id, $user1->id); - - // Confirm there is only one entry in this table. - $this->assertEquals(1, $DB->count_records('customcert_issues')); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Get the issues from the issues table now. - $issues = $DB->get_records('customcert_issues'); - $this->assertCount(2, $issues); - - // Confirm that it was marked as emailed and was not issued to the teacher. - foreach ($issues as $issue) { - $this->assertEquals(1, $issue->emailed); - $this->assertNotEquals($user3->id, $issue->userid); - } - - // Confirm that we sent out emails to the two users. - $this->assertCount(2, $emails); - - $this->assertEquals($CFG->noreplyaddress, $emails[0]->from); - $this->assertEquals($user1->email, $emails[0]->to); - - $this->assertEquals($CFG->noreplyaddress, $emails[1]->from); - $this->assertEquals($user2->email, $emails[1]->to); - - // Now, run the task again and ensure we did not issue any more certificates. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - $issues = $DB->get_records('customcert_issues'); - - $this->assertCount(2, $issues); - $this->assertCount(0, $emails); - } - - /** - * Tests the email certificate task for teachers. - */ - public function test_email_certificates_teachers() { - global $CFG, $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create some users. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - $user3 = $this->getDataGenerator()->create_user(array('firstname' => 'Teacher', 'lastname' => 'One')); - - // Enrol two of them in the course as students. - $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - $this->getDataGenerator()->enrol_user($user2->id, $course->id); - - // Enrol one of the users as a teacher. - $this->getDataGenerator()->enrol_user($user3->id, $course->id, $roleids['editingteacher']); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, - 'emailteachers' => 1)); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm that we only sent out 2 emails, both emails to the teacher for the two students. - $this->assertCount(2, $emails); - - $this->assertEquals($CFG->noreplyaddress, $emails[0]->from); - $this->assertEquals($user3->email, $emails[0]->to); - - $this->assertEquals($CFG->noreplyaddress, $emails[1]->from); - $this->assertEquals($user3->email, $emails[1]->to); - } - - /** - * Tests the email certificate task for others. - */ - public function test_email_certificates_others() { - global $CFG, $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create some users. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - - // Enrol two of them in the course as students. - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - $this->getDataGenerator()->enrol_user($user2->id, $course->id); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, - 'emailothers' => 'testcustomcert@example.com, doo@dah')); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm that we only sent out 2 emails, both emails to the other address that was valid for the two students. - $this->assertCount(2, $emails); - - $this->assertEquals($CFG->noreplyaddress, $emails[0]->from); - $this->assertEquals('testcustomcert@example.com', $emails[0]->to); - - $this->assertEquals($CFG->noreplyaddress, $emails[1]->from); - $this->assertEquals('testcustomcert@example.com', $emails[1]->to); - } - - /** - * Tests the email certificate task when the certificate is not visible. - */ - public function test_email_certificates_students_not_visible() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a user. - $user1 = $this->getDataGenerator()->create_user(); - - // Enrol them in the course. - $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Remove the permission for the user to view the certificate. - assign_capability('mod/customcert:view', CAP_PROHIBIT, $roleids['student'], \context_course::instance($course->id)); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm there are no issues as the user did not have permissions to view it. - $issues = $DB->get_records('customcert_issues'); - $this->assertCount(0, $issues); - - // Confirm no emails were sent. - $this->assertCount(0, $emails); - } - - /** - * Tests the email certificate task when the student has not met the required time for the course. - */ - public function test_email_certificates_students_havent_met_required_time() { - global $DB; - - // Set the standard log to on. - set_config('enabled_stores', 'logstore_standard', 'tool_log'); - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a user. - $user1 = $this->getDataGenerator()->create_user(); - - // Enrol them in the course. - $this->getDataGenerator()->enrol_user($user1->id, $course->id); - - // Create a custom certificate. - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailstudents' => 1, - 'requiredtime' => '60')); - - // Create template object. - $template = new stdClass(); - $template->id = $customcert->templateid; - $template->name = 'A template'; - $template->contextid = context_course::instance($course->id)->id; - $template = new \mod_customcert\template($template); - - // Add a page to this template. - $pageid = $template->add_page(); - - // Add an element to the page. - $element = new stdClass(); - $element->pageid = $pageid; - $element->name = 'Image'; - $DB->insert_record('customcert_elements', $element); - - // Run the task. - $sink = $this->redirectEmails(); - $task = new \mod_customcert\task\email_certificate_task(); - $task->execute(); - $emails = $sink->get_messages(); - - // Confirm there are no issues as the user did not meet the required time. - $issues = $DB->get_records('customcert_issues'); - $this->assertCount(0, $issues); - - // Confirm no emails were sent. - $this->assertCount(0, $emails); - } -} diff --git a/tests/external_test.php b/tests/external_test.php deleted file mode 100644 index c46f303..0000000 --- a/tests/external_test.php +++ /dev/null @@ -1,150 +0,0 @@ -. - -/** - * File contains the unit tests for the webservices. - * - * @package mod_customcert - * @category test - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; - -/** - * Unit tests for the webservices. - * - * @package mod_customcert - * @category test - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_customcert_external_test_testcase extends advanced_testcase { - - /** - * Test set up. - */ - public function setUp(): void { - $this->resetAfterTest(); - } - - /** - * Test the delete_issue web service. - */ - public function test_delete_issue() { - global $DB; - - $this->setAdminUser(); - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a custom certificate in the course. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Issue them both certificates. - $i1 = \mod_customcert\certificate::issue_certificate($customcert->id, $student1->id); - $i2 = \mod_customcert\certificate::issue_certificate($customcert->id, $student2->id); - - $this->assertEquals(2, $DB->count_records('customcert_issues')); - - $result = \mod_customcert\external::delete_issue($customcert->id, $i2); - - // We need to execute the return values cleaning process to simulate the web service server. - external_api::clean_returnvalue(\mod_customcert\external::delete_issue_returns(), $result); - - $issues = $DB->get_records('customcert_issues'); - $this->assertCount(1, $issues); - - $issue = reset($issues); - $this->assertEquals($student1->id, $issue->userid); - } - - /** - * Test the delete_issue web service. - */ - public function test_delete_issue_no_login() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a custom certificate in the course. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Issue them both certificates. - $i1 = \mod_customcert\certificate::issue_certificate($customcert->id, $student1->id); - $i2 = \mod_customcert\certificate::issue_certificate($customcert->id, $student2->id); - - $this->assertEquals(2, $DB->count_records('customcert_issues')); - - // Try and delete without logging in. - $this->expectException('require_login_exception'); - \mod_customcert\external::delete_issue($customcert->id, $i2); - } - - /** - * Test the delete_issue web service. - */ - public function test_delete_issue_no_capability() { - global $DB; - - // Create a course. - $course = $this->getDataGenerator()->create_course(); - - // Create a custom certificate in the course. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Create two users. - $student1 = $this->getDataGenerator()->create_user(); - $student2 = $this->getDataGenerator()->create_user(); - - $this->setUser($student1); - - // Enrol them into the course. - $this->getDataGenerator()->enrol_user($student1->id, $course->id); - $this->getDataGenerator()->enrol_user($student2->id, $course->id); - - // Issue them both certificates. - $i1 = \mod_customcert\certificate::issue_certificate($customcert->id, $student1->id); - $i2 = \mod_customcert\certificate::issue_certificate($customcert->id, $student2->id); - - $this->assertEquals(2, $DB->count_records('customcert_issues')); - - // Try and delete without the required capability. - $this->expectException('required_capability_exception'); - \mod_customcert\external::delete_issue($customcert->id, $i2); - } -} diff --git a/tests/generator/lib.php b/tests/generator/lib.php deleted file mode 100644 index edc4c26..0000000 --- a/tests/generator/lib.php +++ /dev/null @@ -1,64 +0,0 @@ -. - -/** - * Contains the class responsible for data generation during unit tests - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * The class responsible for data generation during unit tests - * - * @package mod_customcert - * @category test - * @copyright 2017 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_customcert_generator extends testing_module_generator { - - /** - * Creates an instance of the custom certificate. - * - * @param array|stdClass|null $record - * @param array|null $options - * @return stdClass - */ - public function create_instance($record = null, array $options = null) { - $record = (object)(array)$record; - - $defaultsettings = array( - 'requiredtime' => 0, - 'emailstudents' => 0, - 'emailteachers' => 0, - 'emailothers' => '', - 'protection' => '' - ); - - foreach ($defaultsettings as $name => $value) { - if (!isset($record->{$name})) { - $record->{$name} = $value; - } - } - - return parent::create_instance($record, (array)$options); - } -} diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php deleted file mode 100644 index 52bb532..0000000 --- a/tests/privacy_provider_test.php +++ /dev/null @@ -1,304 +0,0 @@ -. - -/** - * Privacy provider tests. - * - * @package mod_customcert - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -use mod_customcert\privacy\provider; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy provider tests class. - * - * @package mod_customcert - * @copyright 2018 Mark Nelson - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mod_customcert_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { - - /** - * Test for provider::get_contexts_for_userid(). - */ - public function test_get_contexts_for_userid() { - $this->resetAfterTest(); - - $course = $this->getDataGenerator()->create_course(); - - // The customcert activity the user will have an issue from. - $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Another customcert activity that has no issued certificates. - $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Create a user who will be issued a certificate. - $user = $this->getDataGenerator()->create_user(); - - // Issue the certificate. - $this->create_certificate_issue($customcert->id, $user->id); - - // Check the context supplied is correct. - $contextlist = provider::get_contexts_for_userid($user->id); - $this->assertCount(1, $contextlist); - - $contextformodule = $contextlist->current(); - $cmcontext = context_module::instance($customcert->cmid); - $this->assertEquals($cmcontext->id, $contextformodule->id); - } - - /** - * Test for provider::get_users_in_context(). - */ - public function test_get_users_in_context() { - $this->resetAfterTest(); - - $course = $this->getDataGenerator()->create_course(); - - // The customcert activity the user will have an issue from. - $customcert1 = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - $customcert2 = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id]); - - // Call get_users_in_context() when the customcert hasn't any user. - $cm = get_coursemodule_from_instance('customcert', $customcert1->id); - $cmcontext = context_module::instance($cm->id); - $userlist = new \core_privacy\local\request\userlist($cmcontext, 'mod_customcert'); - provider::get_users_in_context($userlist); - - // Check no user has been returned. - $this->assertCount(0, $userlist->get_userids()); - - // Create some users who will be issued a certificate. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - $user3 = $this->getDataGenerator()->create_user(); - $this->create_certificate_issue($customcert1->id, $user1->id); - $this->create_certificate_issue($customcert1->id, $user2->id); - $this->create_certificate_issue($customcert2->id, $user3->id); - - // Call get_users_in_context() again. - provider::get_users_in_context($userlist); - - // Check this time there are 2 users. - $this->assertCount(2, $userlist->get_userids()); - $this->assertContains((int) $user1->id, $userlist->get_userids()); - $this->assertContains((int) $user2->id, $userlist->get_userids()); - $this->assertNotContains((int) $user3->id, $userlist->get_userids()); - } - - /** - * Test for provider::get_users_in_context() with invalid context type. - */ - public function test_get_users_in_context_invalid_context_type() { - $systemcontext = context_system::instance(); - - $userlist = new \core_privacy\local\request\userlist($systemcontext, 'mod_customcert'); - \mod_customcert\privacy\provider::get_users_in_context($userlist); - - $this->assertCount(0, $userlist->get_userids()); - } - - /** - * Test for provider::export_user_data(). - */ - public function test_export_for_context() { - $this->resetAfterTest(); - - $course = $this->getDataGenerator()->create_course(); - - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - - // Create users who will be issued a certificate. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - - $this->create_certificate_issue($customcert->id, $user1->id); - $this->create_certificate_issue($customcert->id, $user1->id); - $this->create_certificate_issue($customcert->id, $user2->id); - - // Export all of the data for the context for user 1. - $cmcontext = context_module::instance($customcert->cmid); - $this->export_context_data_for_user($user1->id, $cmcontext, 'mod_customcert'); - $writer = \core_privacy\local\request\writer::with_context($cmcontext); - - $this->assertTrue($writer->has_any_data()); - - $data = $writer->get_data(); - $this->assertCount(2, $data->issues); - - $issues = $data->issues; - foreach ($issues as $issue) { - $this->assertArrayHasKey('code', $issue); - $this->assertArrayHasKey('emailed', $issue); - $this->assertArrayHasKey('timecreated', $issue); - } - } - - /** - * Test for provider::delete_data_for_all_users_in_context(). - */ - public function test_delete_data_for_all_users_in_context() { - global $DB; - - $this->resetAfterTest(); - - $course = $this->getDataGenerator()->create_course(); - - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - $customcert2 = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - - // Create users who will be issued a certificate. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - - $this->create_certificate_issue($customcert->id, $user1->id); - $this->create_certificate_issue($customcert->id, $user2->id); - - $this->create_certificate_issue($customcert2->id, $user1->id); - $this->create_certificate_issue($customcert2->id, $user2->id); - - // Before deletion, we should have 2 issued certificates for the first certificate. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]); - $this->assertEquals(2, $count); - - // Delete data based on context. - $cmcontext = context_module::instance($customcert->cmid); - provider::delete_data_for_all_users_in_context($cmcontext); - - // After deletion, the issued certificates for the activity should have been deleted. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]); - $this->assertEquals(0, $count); - - // We should still have the issues for the second certificate. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert2->id]); - $this->assertEquals(2, $count); - } - - /** - * Test for provider::delete_data_for_user(). - */ - public function test_delete_data_for_user() { - global $DB; - - $this->resetAfterTest(); - - $course = $this->getDataGenerator()->create_course(); - - $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - - // Create users who will be issued a certificate. - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - - $this->create_certificate_issue($customcert->id, $user1->id); - $this->create_certificate_issue($customcert->id, $user2->id); - - // Before deletion we should have 2 issued certificates. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id]); - $this->assertEquals(2, $count); - - $context = \context_module::instance($customcert->cmid); - $contextlist = new \core_privacy\local\request\approved_contextlist($user1, 'customcert', - [$context->id]); - provider::delete_data_for_user($contextlist); - - // After deletion, the issued certificates for the first user should have been deleted. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert->id, 'userid' => $user1->id]); - $this->assertEquals(0, $count); - - // Check the issue for the other user is still there. - $customcertissue = $DB->get_records('customcert_issues'); - $this->assertCount(1, $customcertissue); - $lastissue = reset($customcertissue); - $this->assertEquals($user2->id, $lastissue->userid); - } - - /** - * Test for provider::delete_data_for_users(). - */ - public function test_delete_data_for_users() { - global $DB; - - $this->resetAfterTest(); - - // Create course, customcert and users who will be issued a certificate. - $course = $this->getDataGenerator()->create_course(); - $customcert1 = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - $customcert2 = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id)); - $cm1 = get_coursemodule_from_instance('customcert', $customcert1->id); - $cm2 = get_coursemodule_from_instance('customcert', $customcert2->id); - $user1 = $this->getDataGenerator()->create_user(); - $user2 = $this->getDataGenerator()->create_user(); - $user3 = $this->getDataGenerator()->create_user(); - $this->create_certificate_issue($customcert1->id, $user1->id); - $this->create_certificate_issue($customcert1->id, $user2->id); - $this->create_certificate_issue($customcert1->id, $user3->id); - $this->create_certificate_issue($customcert2->id, $user1->id); - $this->create_certificate_issue($customcert2->id, $user2->id); - - // Before deletion we should have 3 + 2 issued certificates. - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert1->id]); - $this->assertEquals(3, $count); - $count = $DB->count_records('customcert_issues', ['customcertid' => $customcert2->id]); - $this->assertEquals(2, $count); - - $context1 = context_module::instance($cm1->id); - $approveduserlist = new \core_privacy\local\request\approved_userlist($context1, 'customcert', - [$user1->id, $user2->id]); - provider::delete_data_for_users($approveduserlist); - - // After deletion, the customcert of the 2 students provided above should have been deleted - // from the activity. So there should only remain 1 certificate which is for $user3. - $customcertissues1 = $DB->get_records('customcert_issues', ['customcertid' => $customcert1->id]); - $this->assertCount(1, $customcertissues1); - $lastissue = reset($customcertissues1); - $this->assertEquals($user3->id, $lastissue->userid); - - // Confirm that the certificates issues in the other activity are intact. - $customcertissues1 = $DB->get_records('customcert_issues', ['customcertid' => $customcert2->id]); - $this->assertCount(2, $customcertissues1); - } - - /** - * Mimicks the creation of a customcert issue. - * - * There is no API we can use to insert an customcert issue, so we - * will simply insert directly into the database. - * - * @param int $customcertid - * @param int $userid - */ - protected function create_certificate_issue(int $customcertid, int $userid) { - global $DB; - - static $i = 1; - - $customcertissue = new stdClass(); - $customcertissue->customcertid = $customcertid; - $customcertissue->userid = $userid; - $customcertissue->code = \mod_customcert\certificate::generate_code(); - $customcertissue->timecreated = time() + $i; - - // Insert the record into the database. - $DB->insert_record('customcert_issues', $customcertissue); - - $i++; - } -} diff --git a/upload_image.php b/upload_image.php index dbfa1c7..e584be3 100644 --- a/upload_image.php +++ b/upload_image.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -29,24 +29,24 @@ require_login(); $context = context_system::instance(); require_capability('moodle/site:config', $context); -$struploadimage = get_string('uploadimage', 'customcert'); +$struploadimage = get_string('uploadimage', 'htmlcert'); // Set the page variables. -$pageurl = new moodle_url('/mod/customcert/upload_image.php'); -\mod_customcert\page_helper::page_setup($pageurl, $context, $SITE->fullname); +$pageurl = new moodle_url('/mod/htmlcert/upload_image.php'); +\mod_htmlcert\page_helper::page_setup($pageurl, $context, $SITE->fullname); // Additional page setup. $PAGE->navbar->add($struploadimage); -$uploadform = new \mod_customcert\upload_image_form(); +$uploadform = new \mod_htmlcert\upload_image_form(); if ($uploadform->is_cancelled()) { - redirect(new moodle_url('/admin/settings.php?section=modsettingcustomcert')); + redirect(new moodle_url('/admin/settings.php?section=modsettinghtmlcert')); } else if ($data = $uploadform->get_data()) { // Handle file uploads. - \mod_customcert\certificate::upload_files($data->customcertimage, $context->id); + \mod_htmlcert\certificate::upload_files($data->htmlcertimage, $context->id); - redirect(new moodle_url('/mod/customcert/upload_image.php'), get_string('changessaved')); + redirect(new moodle_url('/mod/htmlcert/upload_image.php'), get_string('changessaved')); } echo $OUTPUT->header(); diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..6ba06f3 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + private $vendorDir; + + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + private static $registeredLoaders = array(); + + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + //no-op + } elseif ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..04ac709 --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,311 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * To require it's presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + private static $installed = array ( + 'root' => + array ( + 'pretty_version' => 'dev-main', + 'version' => 'dev-main', + 'aliases' => + array ( + ), + 'reference' => '311e243ca5c94983372d3e1f78bd29ffdcdd9eeb', + 'name' => '__root__', + ), + 'versions' => + array ( + '__root__' => + array ( + 'pretty_version' => 'dev-main', + 'version' => 'dev-main', + 'aliases' => + array ( + ), + 'reference' => '311e243ca5c94983372d3e1f78bd29ffdcdd9eeb', + ), + 'mikehaertl/php-shellcommand' => + array ( + 'pretty_version' => '1.6.4', + 'version' => '1.6.4.0', + 'aliases' => + array ( + ), + 'reference' => '3488d7803df1e8f1a343d3d0ca452d527ad8d5e5', + ), + 'mikehaertl/php-tmpfile' => + array ( + 'pretty_version' => '1.2.1', + 'version' => '1.2.1.0', + 'aliases' => + array ( + ), + 'reference' => '70a5b70b17bc0d9666388e6a551ecc93d0b40a10', + ), + 'mikehaertl/phpwkhtmltopdf' => + array ( + 'pretty_version' => '2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '17ee71341591415d942774eda2c98d8ba7ea9e90', + ), + ), +); + private static $canGetVendors; + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @return bool + */ + public static function isInstalled($packageName) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return true; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @return array[] + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list} + */ + public static function getRawData() + { + return self::$installed; + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[]}, versions: list} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + // @phpstan-ignore-next-line + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + } + } + } + + $installed[] = self::$installed; + + return $installed; + } +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..62ecfd8 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..b26f1b1 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/mikehaertl/phpwkhtmltopdf/src'), + 'mikehaertl\\tmp\\' => array($vendorDir . '/mikehaertl/php-tmpfile/src'), + 'mikehaertl\\shellcommand\\' => array($vendorDir . '/mikehaertl/php-shellcommand/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..6dee133 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,57 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitd5163d9829f6dd144313228bd4c17d7f::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..312d811 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,46 @@ + + array ( + 'mikehaertl\\wkhtmlto\\' => 20, + 'mikehaertl\\tmp\\' => 15, + 'mikehaertl\\shellcommand\\' => 24, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'mikehaertl\\wkhtmlto\\' => + array ( + 0 => __DIR__ . '/..' . '/mikehaertl/phpwkhtmltopdf/src', + ), + 'mikehaertl\\tmp\\' => + array ( + 0 => __DIR__ . '/..' . '/mikehaertl/php-tmpfile/src', + ), + 'mikehaertl\\shellcommand\\' => + array ( + 0 => __DIR__ . '/..' . '/mikehaertl/php-shellcommand/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitd5163d9829f6dd144313228bd4c17d7f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitd5163d9829f6dd144313228bd4c17d7f::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitd5163d9829f6dd144313228bd4c17d7f::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..896b836 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,156 @@ +{ + "packages": [ + { + "name": "mikehaertl/php-shellcommand", + "version": "1.6.4", + "version_normalized": "1.6.4.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-shellcommand.git", + "reference": "3488d7803df1e8f1a343d3d0ca452d527ad8d5e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-shellcommand/zipball/3488d7803df1e8f1a343d3d0ca452d527ad8d5e5", + "reference": "3488d7803df1e8f1a343d3d0ca452d527ad8d5e5", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <=9.4" + }, + "time": "2021-03-17T06:54:33+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "mikehaertl\\shellcommand\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "An object oriented interface to shell commands", + "keywords": [ + "shell" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-shellcommand/issues", + "source": "https://github.com/mikehaertl/php-shellcommand/tree/1.6.4" + }, + "install-path": "../mikehaertl/php-shellcommand" + }, + { + "name": "mikehaertl/php-tmpfile", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/php-tmpfile.git", + "reference": "70a5b70b17bc0d9666388e6a551ecc93d0b40a10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/php-tmpfile/zipball/70a5b70b17bc0d9666388e6a551ecc93d0b40a10", + "reference": "70a5b70b17bc0d9666388e6a551ecc93d0b40a10", + "shasum": "" + }, + "require-dev": { + "php": ">=5.3.0", + "phpunit/phpunit": ">4.0 <=9.4" + }, + "time": "2021-03-01T18:26:25+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "mikehaertl\\tmp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A convenience class for temporary files", + "keywords": [ + "files" + ], + "support": { + "issues": "https://github.com/mikehaertl/php-tmpfile/issues", + "source": "https://github.com/mikehaertl/php-tmpfile/tree/1.2.1" + }, + "install-path": "../mikehaertl/php-tmpfile" + }, + { + "name": "mikehaertl/phpwkhtmltopdf", + "version": "2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/mikehaertl/phpwkhtmltopdf.git", + "reference": "17ee71341591415d942774eda2c98d8ba7ea9e90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikehaertl/phpwkhtmltopdf/zipball/17ee71341591415d942774eda2c98d8ba7ea9e90", + "reference": "17ee71341591415d942774eda2c98d8ba7ea9e90", + "shasum": "" + }, + "require": { + "mikehaertl/php-shellcommand": "^1.5.0", + "mikehaertl/php-tmpfile": "^1.2.1", + "php": ">=5.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <9.4" + }, + "time": "2021-03-01T19:41:06+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "mikehaertl\\wkhtmlto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Haertl", + "email": "haertl.mike@gmail.com" + } + ], + "description": "A slim PHP wrapper around wkhtmltopdf with an easy to use and clean OOP interface", + "homepage": "http://mikehaertl.github.com/phpwkhtmltopdf/", + "keywords": [ + "pdf", + "wkhtmltoimage", + "wkhtmltopdf" + ], + "support": { + "issues": "https://github.com/mikehaertl/phpwkhtmltopdf/issues", + "source": "https://github.com/mikehaertl/phpwkhtmltopdf/tree/2.5.0" + }, + "install-path": "../mikehaertl/phpwkhtmltopdf" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000..f6ccb3d --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,51 @@ + + array ( + 'pretty_version' => 'dev-main', + 'version' => 'dev-main', + 'aliases' => + array ( + ), + 'reference' => '311e243ca5c94983372d3e1f78bd29ffdcdd9eeb', + 'name' => '__root__', + ), + 'versions' => + array ( + '__root__' => + array ( + 'pretty_version' => 'dev-main', + 'version' => 'dev-main', + 'aliases' => + array ( + ), + 'reference' => '311e243ca5c94983372d3e1f78bd29ffdcdd9eeb', + ), + 'mikehaertl/php-shellcommand' => + array ( + 'pretty_version' => '1.6.4', + 'version' => '1.6.4.0', + 'aliases' => + array ( + ), + 'reference' => '3488d7803df1e8f1a343d3d0ca452d527ad8d5e5', + ), + 'mikehaertl/php-tmpfile' => + array ( + 'pretty_version' => '1.2.1', + 'version' => '1.2.1.0', + 'aliases' => + array ( + ), + 'reference' => '70a5b70b17bc0d9666388e6a551ecc93d0b40a10', + ), + 'mikehaertl/phpwkhtmltopdf' => + array ( + 'pretty_version' => '2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '17ee71341591415d942774eda2c98d8ba7ea9e90', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 0000000..7621d4f --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 50300)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 5.3.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/mikehaertl/php-shellcommand/.github/workflows/tests.yml b/vendor/mikehaertl/php-shellcommand/.github/workflows/tests.yml new file mode 100644 index 0000000..94c02ab --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/.github/workflows/tests.yml @@ -0,0 +1,48 @@ +name: Tests +on: pull_request +jobs: + phpunit: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-latest + strategy: + matrix: + php: + - "5.3" + - "5.4" + - "5.5" + - "5.6" + - "7.0" + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + + - name: Update composer + run: composer self-update + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install composer packages + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run phpunit + run: vendor/bin/phpunit --color=always diff --git a/vendor/mikehaertl/php-shellcommand/CHANGELOG.md b/vendor/mikehaertl/php-shellcommand/CHANGELOG.md new file mode 100644 index 0000000..0448f28 --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/CHANGELOG.md @@ -0,0 +1,49 @@ +# CHANGELOG + +## 1.2.2 + + * Issue #16: Command on different drive didn't work on windows + +## 1.2.1 + + * Issue #1: Command with spaces didn't work on windows + +## 1.2.0 + + * Add option to return untrimmed output and error + +## 1.1.0 + + * Issue #7: UTF-8 encoded arguments where truncated + +## 1.0.7 + + * Issue #6: Solve `proc_open()` pipe configuration for both, Windows / Linux + +## 1.0.6 + + * Undid `proc_open()` changes as it broke error capturing + +## 1.0.5 + + * Improve `proc_open()` pipe configuration + +## 1.0.4 + + * Add `$useExec` option to fix Windows issues (#3) + +## 1.0.3 + + * Add `getExecuted()` to find out execution status of the command + +## 1.0.2 + + * Add `$escape` parameter to `addArg()` to override escaping settings per call + +## 1.0.1 + + * Minor fixes + +## 1.0.0 + + * Initial release diff --git a/vendor/mikehaertl/php-shellcommand/LICENSE b/vendor/mikehaertl/php-shellcommand/LICENSE new file mode 100644 index 0000000..c60edfb --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Michael Härtl + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/mikehaertl/php-shellcommand/README.md b/vendor/mikehaertl/php-shellcommand/README.md new file mode 100644 index 0000000..6697397 --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/README.md @@ -0,0 +1,145 @@ +php-shellcommand +=========== + +[![GitHub Tests](https://github.com/mikehaertl/php-shellcommand/workflows/Tests/badge.svg)](https://github.com/mikehaertl/php-shellcommand/actions) +[![Packagist Version](https://img.shields.io/packagist/v/mikehaertl/php-shellcommand?label=version)](https://packagist.org/packages/mikehaertl/php-shellcommand) +[![Packagist Downloads](https://img.shields.io/packagist/dt/mikehaertl/php-shellcommand)](https://packagist.org/packages/mikehaertl/php-shellcommand) +[![GitHub license](https://img.shields.io/github/license/mikehaertl/php-shellcommand)](https://github.com/mikehaertl/php-shellcommand/blob/master/LICENSE) +[![Packagist PHP Version Support](https://img.shields.io/packagist/php-v/mikehaertl/php-shellcommand)](https://packagist.org/packages/mikehaertl/php-shellcommand) + +php-shellcommand provides a simple object oriented interface to execute shell commands. + +## Installing + +### Prerequisites + +Your php version must be `5.4` or later. + +### Installing with composer + +This package can be installed easily using composer. + +``` +composer require mikehaertl/php-shellcommand +``` + +## Features + + * Catches `stdOut`, `stdErr` and `exitCode` + * Handle argument escaping + * Pass environment vars and other options to `proc_open()` + +## Examples + +### Basic Example + +```php +execute()) { + echo $command->getOutput(); +} else { + echo $command->getError(); + $exitCode = $command->getExitCode(); +} +``` + +### Advanced Features + +```php +// Create command with options array +$command = new Command(array( + 'command' => '/usr/local/bin/mycommand', + + // Will be passed as environment variables to the command + 'procEnv' => array( + 'DEMOVAR' => 'demovalue' + ), + + // Will be passed as options to proc_open() + 'procOptions' => array( + 'bypass_shell' => true, + ), +)); + +// Add arguments with correct escaping: +// results in --name='d'\''Artagnan' +$command->addArg('--name=', "d'Artagnan"); + +// Add argument with several values +// results in --keys key1 key2 +$command->addArg('--keys', array('key1','key2')); + +// Add string to pipe to command on standard input +$command->setStdIn('string'); +``` + +## API + +### Properties + + * `$escapeArgs`: Whether to escape any argument passed through `addArg()`. Default is `true`. + * `$escapeCommand`: Whether to escape the command passed to `setCommand()` or the constructor. + This is only useful if `$escapeArgs` is `false`. Default is `false`. + * `$useExec`: Whether to use `exec()` instead of `proc_open()`. This is a workaround for OS which + have problems with `proc_open()`. Default is `false`. + * `$captureStdErr`: Whether to capture stderr when `useExec` is set. This will try to redirect + the otherwhise unavailable `stderr` to `stdout`, so that both have the same content on error. + Default is `true`. + * `$procCwd`: The initial working dir passed to `proc_open()`. Default is `null` for current + PHP working dir. + * `$procEnv`: An array with environment variables to pass to `proc_open()`. Default is `null` for none. + * `$procOptions`: An array of `other_options` for `proc_open()`. Default is `null` for none. + * `$nonBlockingMode`: Whether to set the stdin/stdout/stderr streams to non-blocking + mode when `proc_open()` is used. This allows to have huge inputs/outputs + without making the process hang. The default is `null` which will enable + the feature on Non-Windows systems. Set it to `true` or `false` to manually + enable/disable it. Note that it doesn't work on Windows. + * `$timeout`: The time in seconds after which the command should be + terminated. This only works in non-blocking mode. Default is `null` which + means the process is never terminated. + * `$locale`: The locale to (temporarily) set with `setlocale()` before running the command. + This can be set to e.g. `en_US.UTF-8` if you have issues with UTF-8 encoded arguments. + +You can configure all these properties via an array that you pass in the constructor. You can also +pass `command`, `execCommand` and `args` as options. This will call the respective setter (`setCommand()`, +`setExecCommand()`, etc.). + +### Methods + + * `__construct($options = null)` + * `$options`: either a command string or an options array (see `setOptions()`) + * `setOptions($options)`: Set command options + * `$options`: array of name => value options that should be applied to the object. + You can also pass options that use a setter, e.g. you can pass a `command` option which + will be passed to `setCommand().` + * `setCommand($command)`: Set command + * `$command`: The command or full command string to execute, like `gzip` or `gzip -d`. + You can still call `addArg()` to add more arguments to the command. If `$escapeCommand` was + set to `true`, the command gets escaped through `escapeshellcmd()`. + * `getCommand()`: The command that was set through `setCommand()` or passed to the constructor. + * `getExecCommand()`: The full command string to execute. + * `setArgs($args)`: Set argument as string + * `$args`: The command arguments as string. Note, that these will not get escaped! + * `getArgs()`: The command arguments that where set through `setArgs()` or `addArg()`, as string + * `addArg($key, $value=null, $escape=null)`: Add argument with correct escaping + * `$key`: The argument key to add e.g. `--feature` or `--name=`. If the key does not end with + and `=`, the `$value` will be separated by a space, if any. Keys are not escaped unless + `$value` is null and `$escape` is `true`. + * `$value`: The optional argument value which will get escaped if `$escapeArgs` is true. + An array can be passed to add more than one value for a key, e.g. `addArg('--exclude', array('val1','val2'))` + which will create the option "--exclude 'val1' 'val2'". + * `$escape`: If set, this overrides the `$escapeArgs` setting and enforces escaping/no escaping + * `setStdIn()`: String or resource to supply to command via standard input. + * `getOutput()`: The command output as string. Empty if none. + * `getError()`: The error message, either stderr or internal message. Empty if no error. + * `getStdErr()`: The stderr output. Empty if none. + * `getExitCode()`: The exit code. + * `getExecuted()`: Whether the command was successfully executed. + * `execute()`: Executes the command and returns `true` on success, `false` otherwhise. + +> **Note:** `getError()`, `getStdErr()` and `getOutput()` return the trimmed output. +> You can pass `false` to these methods if you need any possible line breaks at the end. diff --git a/vendor/mikehaertl/php-shellcommand/composer.json b/vendor/mikehaertl/php-shellcommand/composer.json new file mode 100644 index 0000000..a638fca --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/composer.json @@ -0,0 +1,28 @@ +{ + "name": "mikehaertl/php-shellcommand", + "description": "An object oriented interface to shell commands", + "keywords": ["shell"], + "license": "MIT", + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "require": { + "php": ">= 5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <=9.4" + }, + "autoload": { + "psr-4": { + "mikehaertl\\shellcommand\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "tests\\": "tests" + } + } +} diff --git a/vendor/mikehaertl/php-shellcommand/src/Command.php b/vendor/mikehaertl/php-shellcommand/src/Command.php new file mode 100644 index 0000000..c552724 --- /dev/null +++ b/vendor/mikehaertl/php-shellcommand/src/Command.php @@ -0,0 +1,546 @@ + + * @license http://www.opensource.org/licenses/MIT + */ +class Command +{ + /** + * @var bool whether to escape any argument passed through `addArg()`. + * Default is `true`. + */ + public $escapeArgs = true; + + /** + * @var bool whether to escape the command passed to `setCommand()` or the + * constructor. This is only useful if `$escapeArgs` is `false`. Default + * is `false`. + */ + public $escapeCommand = false; + + /** + * @var bool whether to use `exec()` instead of `proc_open()`. This can be + * used on Windows system to workaround some quirks there. Note, that any + * errors from your command will be output directly to the PHP output + * stream. `getStdErr()` will also not work anymore and thus you also won't + * get the error output from `getError()` in this case. You also can't pass + * any environment variables to the command if this is enabled. Default is + * `false`. + */ + public $useExec = false; + + /** + * @var bool whether to capture stderr (2>&1) when `useExec` is true. This + * will try to redirect the stderr to stdout and provide the complete + * output of both in `getStdErr()` and `getError()`. Default is `true`. + */ + public $captureStdErr = true; + + /** + * @var string|null the initial working dir for `proc_open()`. Default is + * `null` for current PHP working dir. + */ + public $procCwd; + + /** + * @var array|null an array with environment variables to pass to + * `proc_open()`. Default is `null` for none. + */ + public $procEnv; + + /** + * @var array|null an array of other_options for `proc_open()`. Default is + * `null` for none. + */ + public $procOptions; + + /** + * @var bool|null whether to set the stdin/stdout/stderr streams to + * non-blocking mode when `proc_open()` is used. This allows to have huge + * inputs/outputs without making the process hang. The default is `null` + * which will enable the feature on Non-Windows systems. Set it to `true` + * or `false` to manually enable/disable it. It does not work on Windows. + */ + public $nonBlockingMode; + + /** + * @var int the time in seconds after which a command should be terminated. + * This only works in non-blocking mode. Default is `null` which means the + * process is never terminated. + */ + public $timeout; + + /** + * @var null|string the locale to temporarily set before calling + * `escapeshellargs()`. Default is `null` for none. + */ + public $locale; + + /** + * @var null|string|resource to pipe to standard input + */ + protected $_stdIn; + + /** + * @var string the command to execute + */ + protected $_command; + + /** + * @var array the list of command arguments + */ + protected $_args = array(); + + /** + * @var string the stdout output + */ + protected $_stdOut = ''; + + /** + * @var string the stderr output + */ + protected $_stdErr = ''; + + /** + * @var int the exit code + */ + protected $_exitCode; + + /** + * @var string the error message + */ + protected $_error = ''; + + /** + * @var bool whether the command was successfully executed + */ + protected $_executed = false; + + /** + * @param string|array $options either a command string or an options array + * @see setOptions + */ + public function __construct($options = null) + { + if (is_array($options)) { + $this->setOptions($options); + } elseif (is_string($options)) { + $this->setCommand($options); + } + } + + /** + * @param array $options array of name => value options that should be + * applied to the object You can also pass options that use a setter, e.g. + * you can pass a `fileName` option which will be passed to + * `setFileName()`. + * @throws \Exception + * @return static for method chaining + */ + public function setOptions($options) + { + foreach ($options as $key => $value) { + if (property_exists($this, $key)) { + $this->$key = $value; + } else { + $method = 'set'.ucfirst($key); + if (method_exists($this, $method)) { + call_user_func(array($this,$method), $value); + } else { + throw new \Exception("Unknown configuration option '$key'"); + } + } + } + return $this; + } + + /** + * @param string $command the command or full command string to execute, + * like 'gzip' or 'gzip -d'. You can still call addArg() to add more + * arguments to the command. If $escapeCommand was set to true, the command + * gets escaped with escapeshellcmd(). + * @return static for method chaining + */ + public function setCommand($command) + { + if ($this->escapeCommand) { + $command = escapeshellcmd($command); + } + if ($this->getIsWindows()) { + // Make sure to switch to correct drive like "E:" first if we have + // a full path in command + if (isset($command[1]) && $command[1]===':') { + $position = 1; + // Could be a quoted absolute path because of spaces. + // i.e. "C:\Program Files (x86)\file.exe" + } elseif (isset($command[2]) && $command[2]===':') { + $position = 2; + } else { + $position = false; + } + + // Absolute path. If it's a relative path, let it slide. + if ($position) { + $command = sprintf( + $command[$position - 1] . ': && cd %s && %s', + escapeshellarg(dirname($command)), + escapeshellarg(basename($command)) + ); + } + } + $this->_command = $command; + return $this; + } + + /** + * @param string|resource $stdIn If set, the string will be piped to the + * command via standard input. This enables the same functionality as + * piping on the command line. It can also be a resource like a file + * handle or a stream in which case its content will be piped into the + * command like an input redirection. + * @return static for method chaining + */ + public function setStdIn($stdIn) { + $this->_stdIn = $stdIn; + return $this; + } + + /** + * @return string|null the command that was set through setCommand() or + * passed to the constructor. `null` if none. + */ + public function getCommand() + { + return $this->_command; + } + + /** + * @return string|bool the full command string to execute. If no command + * was set with setCommand() or passed to the constructor it will return + * `false`. + */ + public function getExecCommand() + { + $command = $this->getCommand(); + if (!$command) { + $this->_error = 'Could not locate any executable command'; + return false; + } + + $args = $this->getArgs(); + return $args ? $command.' '.$args : $command; + } + + /** + * @param string $args the command arguments as string. Note that these + * will not get escaped! + * @return static for method chaining + */ + public function setArgs($args) + { + $this->_args = array($args); + return $this; + } + + /** + * @return string the command args that where set with setArgs() or added + * with addArg() separated by spaces + */ + public function getArgs() + { + return implode(' ', $this->_args); + } + + /** + * @param string $key the argument key to add e.g. `--feature` or + * `--name=`. If the key does not end with and `=`, the $value will be + * separated by a space, if any. Keys are not escaped unless $value is null + * and $escape is `true`. + * @param string|array|null $value the optional argument value which will + * get escaped if $escapeArgs is true. An array can be passed to add more + * than one value for a key, e.g. `addArg('--exclude', + * array('val1','val2'))` which will create the option `'--exclude' 'val1' + * 'val2'`. + * @param bool|null $escape if set, this overrides the $escapeArgs setting + * and enforces escaping/no escaping + * @return static for method chaining + */ + public function addArg($key, $value = null, $escape = null) + { + $doEscape = $escape !== null ? $escape : $this->escapeArgs; + $useLocale = $doEscape && $this->locale !== null; + + if ($useLocale) { + $locale = setlocale(LC_CTYPE, 0); // Returns current locale setting + setlocale(LC_CTYPE, $this->locale); + } + if ($value === null) { + $this->_args[] = $doEscape ? escapeshellarg($key) : $key; + } else { + if (substr($key, -1) === '=') { + $separator = '='; + $argKey = substr($key, 0, -1); + } else { + $separator = ' '; + $argKey = $key; + } + $argKey = $doEscape ? escapeshellarg($argKey) : $argKey; + + if (is_array($value)) { + $params = array(); + foreach ($value as $v) { + $params[] = $doEscape ? escapeshellarg($v) : $v; + } + $this->_args[] = $argKey . $separator . implode(' ', $params); + } else { + $this->_args[] = $argKey . $separator . + ($doEscape ? escapeshellarg($value) : $value); + } + } + if ($useLocale) { + setlocale(LC_CTYPE, $locale); + } + + return $this; + } + + /** + * @param bool $trim whether to `trim()` the return value. The default is `true`. + * @return string the command output (stdout). Empty if none. + */ + public function getOutput($trim = true) + { + return $trim ? trim($this->_stdOut) : $this->_stdOut; + } + + /** + * @param bool $trim whether to `trim()` the return value. The default is `true`. + * @return string the error message, either stderr or an internal message. + * Empty string if none. + */ + public function getError($trim = true) + { + return $trim ? trim($this->_error) : $this->_error; + } + + /** + * @param bool $trim whether to `trim()` the return value. The default is `true`. + * @return string the stderr output. Empty if none. + */ + public function getStdErr($trim = true) + { + return $trim ? trim($this->_stdErr) : $this->_stdErr; + } + + /** + * @return int|null the exit code or null if command was not executed yet + */ + public function getExitCode() + { + return $this->_exitCode; + } + + /** + * @return string whether the command was successfully executed + */ + public function getExecuted() + { + return $this->_executed; + } + + /** + * Execute the command + * + * @return bool whether execution was successful. If `false`, error details + * can be obtained from getError(), getStdErr() and getExitCode(). + */ + public function execute() + { + $command = $this->getExecCommand(); + + if (!$command) { + return false; + } + + if ($this->useExec) { + $execCommand = $this->captureStdErr ? "$command 2>&1" : $command; + exec($execCommand, $output, $this->_exitCode); + $this->_stdOut = implode("\n", $output); + if ($this->_exitCode !== 0) { + $this->_stdErr = $this->_stdOut; + $this->_error = empty($this->_stdErr) ? 'Command failed' : $this->_stdErr; + return false; + } + } else { + $isInputStream = $this->_stdIn !== null && + is_resource($this->_stdIn) && + in_array(get_resource_type($this->_stdIn), array('file', 'stream')); + $isInputString = is_string($this->_stdIn); + $hasInput = $isInputStream || $isInputString; + $hasTimeout = $this->timeout !== null && $this->timeout > 0; + + $descriptors = array( + 1 => array('pipe','w'), + 2 => array('pipe', $this->getIsWindows() ? 'a' : 'w'), + ); + if ($hasInput) { + $descriptors[0] = array('pipe', 'r'); + } + + + // Issue #20 Set non-blocking mode to fix hanging processes + $nonBlocking = $this->nonBlockingMode === null ? + !$this->getIsWindows() : $this->nonBlockingMode; + + $startTime = $hasTimeout ? time() : 0; + $process = proc_open($command, $descriptors, $pipes, $this->procCwd, $this->procEnv, $this->procOptions); + + if (is_resource($process)) { + + if ($nonBlocking) { + stream_set_blocking($pipes[1], false); + stream_set_blocking($pipes[2], false); + if ($hasInput) { + $writtenBytes = 0; + $isInputOpen = true; + stream_set_blocking($pipes[0], false); + if ($isInputStream) { + stream_set_blocking($this->_stdIn, false); + } + } + + // Due to the non-blocking streams we now have to check in + // a loop if the process is still running. We also need to + // ensure that all the pipes are written/read alternately + // until there's nothing left to write/read. + $isRunning = true; + while ($isRunning) { + $status = proc_get_status($process); + $isRunning = $status['running']; + + // We first write to stdIn if we have an input. For big + // inputs it will only write until the input buffer of + // the command is full (the command may now wait that + // we read the output buffers - see below). So we may + // have to continue writing in another cycle. + // + // After everything is written it's safe to close the + // input pipe. + if ($isRunning && $hasInput && $isInputOpen) { + if ($isInputStream) { + $written = stream_copy_to_stream($this->_stdIn, $pipes[0], 16 * 1024, $writtenBytes); + if ($written === false || $written === 0) { + $isInputOpen = false; + fclose($pipes[0]); + } else { + $writtenBytes += $written; + } + } else { + if ($writtenBytes < strlen($this->_stdIn)) { + $writtenBytes += fwrite($pipes[0], substr($this->_stdIn, $writtenBytes)); + } else { + $isInputOpen = false; + fclose($pipes[0]); + } + } + } + + // Read out the output buffers because if they are full + // the command may block execution. We do this even if + // $isRunning is `false`, because there could be output + // left in the buffers. + // + // The latter is only an assumption and needs to be + // verified - but it does not hurt either and works as + // expected. + // + while (($out = fgets($pipes[1])) !== false) { + $this->_stdOut .= $out; + } + while (($err = fgets($pipes[2])) !== false) { + $this->_stdErr .= $err; + } + + $runTime = $hasTimeout ? time() - $startTime : 0; + if ($isRunning && $hasTimeout && $runTime >= $this->timeout) { + // Only send a SIGTERM and handle status in the next cycle + proc_terminate($process); + } + + if (!$isRunning) { + $this->_exitCode = $status['exitcode']; + if ($this->_exitCode !== 0 && empty($this->_stdErr)) { + if ($status['stopped']) { + $signal = $status['stopsig']; + $this->_stdErr = "Command stopped by signal $signal"; + } elseif ($status['signaled']) { + $signal = $status['termsig']; + $this->_stdErr = "Command terminated by signal $signal"; + } else { + $this->_stdErr = 'Command unexpectedly terminated without error message'; + } + } + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + } else { + // The command is still running. Let's wait some + // time before we start the next cycle. + usleep(10000); + } + } + } else { + if ($hasInput) { + if ($isInputStream) { + stream_copy_to_stream($this->_stdIn, $pipes[0]); + } elseif ($isInputString) { + fwrite($pipes[0], $this->_stdIn); + } + fclose($pipes[0]); + } + $this->_stdOut = stream_get_contents($pipes[1]); + $this->_stdErr = stream_get_contents($pipes[2]); + fclose($pipes[1]); + fclose($pipes[2]); + $this->_exitCode = proc_close($process); + } + + if ($this->_exitCode !== 0) { + $this->_error = $this->_stdErr ? + $this->_stdErr : + "Failed without error message: $command (Exit code: {$this->_exitCode})"; + return false; + } + } else { + $this->_error = "Could not run command $command"; + return false; + } + } + + $this->_executed = true; + + return true; + } + + /** + * @return bool whether we are on a Windows OS + */ + public function getIsWindows() + { + return strncasecmp(PHP_OS, 'WIN', 3)===0; + } + + /** + * @return string the current command string to execute + */ + public function __toString() + { + return (string) $this->getExecCommand(); + } +} diff --git a/vendor/mikehaertl/php-tmpfile/.github/workflows/tests.yml b/vendor/mikehaertl/php-tmpfile/.github/workflows/tests.yml new file mode 100644 index 0000000..94c02ab --- /dev/null +++ b/vendor/mikehaertl/php-tmpfile/.github/workflows/tests.yml @@ -0,0 +1,48 @@ +name: Tests +on: pull_request +jobs: + phpunit: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-latest + strategy: + matrix: + php: + - "5.3" + - "5.4" + - "5.5" + - "5.6" + - "7.0" + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + + - name: Update composer + run: composer self-update + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install composer packages + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run phpunit + run: vendor/bin/phpunit --color=always diff --git a/vendor/mikehaertl/php-tmpfile/LICENSE b/vendor/mikehaertl/php-tmpfile/LICENSE new file mode 100644 index 0000000..28dbb2a --- /dev/null +++ b/vendor/mikehaertl/php-tmpfile/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Michael Härtl + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/mikehaertl/php-tmpfile/README.md b/vendor/mikehaertl/php-tmpfile/README.md new file mode 100644 index 0000000..86d7b4a --- /dev/null +++ b/vendor/mikehaertl/php-tmpfile/README.md @@ -0,0 +1,64 @@ +php-tmpfile +=========== + +[![GitHub Tests](https://github.com/mikehaertl/php-tmpfile/workflows/Tests/badge.svg)](https://github.com/mikehaertl/php-tmpfile/actions) +[![Packagist Version](https://img.shields.io/packagist/v/mikehaertl/php-tmpfile?label=version)](https://packagist.org/packages/mikehaertl/php-tmpfile) +[![Packagist Downloads](https://img.shields.io/packagist/dt/mikehaertl/php-tmpfile)](https://packagist.org/packages/mikehaertl/php-tmpfile) +[![GitHub license](https://img.shields.io/github/license/mikehaertl/php-tmpfile)](https://github.com/mikehaertl/php-tmpfile/blob/master/LICENSE) + +A convenience class for temporary files. + +## Features + + * Create temporary file with arbitrary content + * Delete file after use (can be disabled) + * Send file to client, either inline or with save dialog, optionally with custom HTTP headers + * Save file locally + +## Examples + +```php +send('home.html'); +// ... with custom content type (autodetected otherwhise) +$file->send('home.html', 'application/pdf'); +// ... for inline display (download dialog otherwhise) +$file->send('home.html', 'application/pdf', true); +// ... with custom headers +$file->send('home.html', 'application/pdf', true, [ + 'X-Header' => 'Example', +]); + +// save to disk +$file->saveAs('/dir/test.html'); + +// Access file name and directory +echo $file->getFileName(); +echo $file->getTempDir(); +``` + +If you want to keep the temporary file, e.g. for debugging, you can set the `$delete` property to false: + +```php +delete = false; +``` + +Default HTTP headers can also be added: +```php +send('home.html'); +``` diff --git a/vendor/mikehaertl/php-tmpfile/composer.json b/vendor/mikehaertl/php-tmpfile/composer.json new file mode 100644 index 0000000..c28c46a --- /dev/null +++ b/vendor/mikehaertl/php-tmpfile/composer.json @@ -0,0 +1,26 @@ +{ + "name": "mikehaertl/php-tmpfile", + "description": "A convenience class for temporary files", + "keywords": ["files"], + "license": "MIT", + "authors": [ + { + "name": "Michael Härtl", + "email": "haertl.mike@gmail.com" + } + ], + "require-dev": { + "php": ">=5.3.0", + "phpunit/phpunit": ">4.0 <=9.4" + }, + "autoload": { + "psr-4": { + "mikehaertl\\tmp\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "tests\\": "tests" + } + } +} diff --git a/vendor/mikehaertl/php-tmpfile/src/File.php b/vendor/mikehaertl/php-tmpfile/src/File.php new file mode 100644 index 0000000..2271260 --- /dev/null +++ b/vendor/mikehaertl/php-tmpfile/src/File.php @@ -0,0 +1,197 @@ + + * @license http://www.opensource.org/licenses/MIT + */ +class File +{ + const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + + /** + * @var bool whether to delete the tmp file when it's no longer referenced + * or when the request ends. Default is `true`. + */ + public $delete = true; + + /** + * @var array the list of static default headers to send when `send()` is + * called as key/value pairs. + */ + public static $defaultHeaders = array( + 'Pragma' => 'public', + 'Expires' => 0, + 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', + 'Content-Transfer-Encoding' => 'binary', + ); + + /** + * @var string the name of this file + */ + protected $_fileName; + + /** + * Constructor + * + * @param string $content the tmp file content + * @param string|null $suffix the optional suffix for the tmp file + * @param string|null $prefix the optional prefix for the tmp file. If null + * 'php_tmpfile_' is used. + * @param string|null $directory directory where the file should be + * created. Autodetected if not provided. + */ + public function __construct($content, $suffix = null, $prefix = null, $directory = null) + { + if ($directory === null) { + $directory = self::getTempDir(); + } + + if ($prefix === null) { + $prefix = 'php_tmpfile_'; + } + + $this->_fileName = tempnam($directory,$prefix); + if ($suffix !== null) { + $newName = $this->_fileName . $suffix; + rename($this->_fileName, $newName); + $this->_fileName = $newName; + } + file_put_contents($this->_fileName, $content); + } + + /** + * Delete tmp file on shutdown if `$delete` is `true` + */ + public function __destruct() + { + if ($this->delete && file_exists($this->_fileName)) { + unlink($this->_fileName); + } + } + + /** + * Send tmp file to client, either inline or as download + * + * @param string|null $filename the filename to send. If empty, the file is + * streamed inline. + * @param string|null $contentType the Content-Type header to send. If + * `null` the type is auto-detected and if that fails + * 'application/octet-stream' is used. + * @param bool $inline whether to force inline display of the file, even if + * filename is present. + * @param array $headers a list of additional HTTP headers to send in the + * response as an array. The array keys are the header names like + * 'Cache-Control' and the array values the header value strings to send. + * Each array value can also be another array of strings if the same header + * should be sent multiple times. This can also be used to override + * automatically created headers like 'Expires' or 'Content-Length'. To suppress + * automatically created headers, `false` can also be used as header value. + */ + public function send($filename = null, $contentType = null, $inline = false, $headers = array()) + { + $headers = array_merge(self::$defaultHeaders, $headers); + + if ($contentType !== null) { + $headers['Content-Type'] = $contentType; + } elseif (!isset($headers['Content-Type'])) { + $contentType = @mime_content_type($this->_filename); + if ($contentType === false) { + $contentType = self::DEFAULT_CONTENT_TYPE; + } + $headers['Content-Type'] = $contentType; + } + + if (!isset($headers['Content-Length'])) { + // #11 Undefined index: HTTP_USER_AGENT + $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; + + // #84: Content-Length leads to "network connection was lost" on iOS + $isIOS = preg_match('/i(phone|pad|pod)/i', $userAgent); + if (!$isIOS) { + $headers['Content-Length'] = filesize($this->_fileName); + } + } + + if (($filename !== null || $inline) && !isset($headers['Content-Disposition'])) { + $disposition = $inline ? 'inline' : 'attachment'; + $encodedFilename = rawurlencode($filename); + $headers['Content-Disposition'] = "$disposition; " . + "filename=\"$filename\"; " . + "filename*=UTF-8''$encodedFilename"; + } + + $this->sendHeaders($headers); + readfile($this->_fileName); + } + + /** + * @param string $name the name to save the file as + * @return bool whether the file could be saved + */ + public function saveAs($name) + { + return copy($this->_fileName, $name); + } + + /** + * @return string the full file name + */ + public function getFileName() + { + return $this->_fileName; + } + + /** + * @return string the path to the temp directory + */ + public static function getTempDir() + { + if (function_exists('sys_get_temp_dir')) { + return sys_get_temp_dir(); + } elseif ( + ($tmp = getenv('TMP')) || + ($tmp = getenv('TEMP')) || + ($tmp = getenv('TMPDIR')) + ) { + return realpath($tmp); + } else { + return '/tmp'; + } + } + + /** + * @return string the full file name + */ + public function __toString() + { + return $this->_fileName; + } + + /** + * Send the given list of headers + * + * @param array $headers the list of headers to send as key/value pairs. + * Value can either be a string or an array of strings to send the same + * header multiple times. + */ + protected function sendHeaders($headers) + { + foreach ($headers as $name => $value) { + if ($value === false) { + continue; + } + if (is_array($value)) { + foreach ($value as $v) { + header("$name: $v"); + } + } else { + header("$name: $value"); + } + } + } +} diff --git a/vendor/mikehaertl/phpwkhtmltopdf/.github/workflows/tests.yml b/vendor/mikehaertl/phpwkhtmltopdf/.github/workflows/tests.yml new file mode 100644 index 0000000..ab56ab9 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/.github/workflows/tests.yml @@ -0,0 +1,60 @@ +name: Tests +on: pull_request +jobs: + phpunit: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-latest + strategy: + matrix: + php: + - "5.3" + - "5.4" + - "5.5" + - "5.6" + - "7.0" + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install xvfb + run: | + sudo apt-get update + sudo apt-get install xvfb + + - name: Install wkhtmltopdf + run: | + cd /tmp + sudo wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb + sudo apt install -y -q ./wkhtmltox_0.12.6-1.focal_amd64.deb + wkhtmltopdf --version + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + + - name: Update composer + run: composer self-update + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer cache + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install composer packages + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run phpunit + run: vendor/bin/phpunit --color=always diff --git a/vendor/mikehaertl/phpwkhtmltopdf/CHANGELOG.md b/vendor/mikehaertl/phpwkhtmltopdf/CHANGELOG.md new file mode 100644 index 0000000..165e267 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/CHANGELOG.md @@ -0,0 +1,146 @@ +# CHANGELOG + +## 2.5.0 + + * Enhancement: Issue #366 Allow to pass additional HTTP headers to the `send()` method + +## 2.4.2 + + * This release only contains fixes for the test setup. + +## 2.4.1 + + * Fix: Pushed version constraints for php-shellcommand and php-tmpfile which should fix hanging issues. + +## 2.4.0 + + * Enhancement: Issue #307 Improved and unified detection of URL, File, HTML and XML content + +## 2.3.1 + + * Fix: Issue #264 Problem with tmpDir passed in constructor + +## 2.3.0 + + * Issue #258 Add toString() method to Image class + +## 2.2.2 + + * Also create tmp file for xsl-style-sheet and user-style-sheet if required + +## 2.2.1 + + * Issue #219: Make `header-html` and `footer-html` also work for Toc and cover page + +## 2.2.0 + + * Add a `$type` parameter to `addPage()` and `addToc()` (#169) + +## 2.1.1 + + * Add `-a` to default `xvfb-run` options + +## 2.1.0 + + * We now follow [semver](http://semver.org/)! + * Issue #112: Add toString() to get raw PDF content as string + +## 2.0.4 + + * Issue #100: Fix issue with header-/footer-html + +## 2.0.3 + + * Make dependencies in `composer.json` less restrictive + * Remove `composer.lock` to allow for independent updates of dependencies + +## 2.0.2 + + * Issue #56: Fix issue with `proc_open()` on windows + * Add detection for XML strings + +## 2.0.1 + + * Issue #61: Fix ignored `tmpDir` + +## 2.0.0 + +In this major release we have added a wrapper for wkhtmltoimage and cleaned +up the code and interface. We also introduced namespaces and Travis testing. +Please have a look at the README.md for the new API. + +## 1.2.6 + + * Issue #54: Add binary autodetection for windows + * Issue #47: Add escaping to temp files to improve behavior on windows + +## 1.2.5 + + * Issue #46: Add 'ignoreWarnings' option + * Issue #45: Fix for missing sys_get_temp_dir() on older PHP 5 versions + * Issue #41: Fix escaping of some parameters + +## 1.2.4 + + * Add support for HTML strings in html-footer and html-header + +## 1.2.3 + + * Issue #36: Bugfix in send() + +## 1.2.2 + + * Issue #34: Allow to set filename even when PDF is streamed inline + * Issue #35: Support repeatable wkhtmltopdf options + +## 1.2.1 + + * Issue #29: Add Xvfb support + +## 1.2.0 + +A minor change in the options was introduced in this release. If you used the `bin` +option before you have to rename it to `binPath` now. Please check the docs for +full documentation. + + * Issue #27: Add autodetection of wkhtmltopdf binary on Unix based systems (thanks eusonlito) + * Issue #28: Implement optional passing of environment variables to proc_open (thanks eusonlito) + * Issue #30: Bug with options without an argument + +## 1.1.6 + + * Issue #21: Add support for wkhtmltopdf 0.9 versions + +## 1.1.5 + + * Add composer autoloading (thanks igorw) + * Issue #10: Improve error reporting + +## 1.1.4 + + * Add composer.jsone + +## 1.1.3 + + * Made getCommand() public to ease debugging + * Issue #6: Fix typo that prevented shell escaping on windows + * Issue #5: Updated docs: wkhtmltopdf can not process PDF files + +## 1.1.2 + + * Issue #4: Fix issue with longer PDFs + +## 1.1.1 + + * Issue #2: Fix escaping of arguments + * Issue #3: Fix HTML detection regex + + +## 1.1.0 + + * Issue #1: Allow to add HTML as string + + +## 1.0.0 + + * Initial release diff --git a/vendor/mikehaertl/phpwkhtmltopdf/LICENSE b/vendor/mikehaertl/phpwkhtmltopdf/LICENSE new file mode 100644 index 0000000..28dbb2a --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Michael Härtl + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/mikehaertl/phpwkhtmltopdf/README.md b/vendor/mikehaertl/phpwkhtmltopdf/README.md new file mode 100644 index 0000000..f0d3fcb --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/README.md @@ -0,0 +1,423 @@ +PHP WkHtmlToPdf +=============== + +[![GitHub Tests](https://github.com/mikehaertl/phpwkhtmltopdf/workflows/Tests/badge.svg)](https://github.com/mikehaertl/phpwkhtmltopdf/actions) +[![Packagist Version](https://img.shields.io/packagist/v/mikehaertl/phpwkhtmltopdf?label=version)](https://packagist.org/packages/mikehaertl/phpwkhtmltopdf) +[![Packagist Downloads](https://img.shields.io/packagist/dt/mikehaertl/phpwkhtmltopdf)](https://packagist.org/packages/mikehaertl/phpwkhtmltopdf) +[![GitHub license](https://img.shields.io/github/license/mikehaertl/phpwkhtmltopdf)](https://github.com/mikehaertl/phpwkhtmltopdf/blob/master/LICENSE) +[![Packagist PHP Version Support](https://img.shields.io/packagist/php-v/mikehaertl/phpwkhtmltopdf)](https://packagist.org/packages/mikehaertl/phpwkhtmltopdf) + +PHP WkHtmlToPdf provides a simple and clean interface to ease PDF and image creation with +[wkhtmltopdf](http://wkhtmltopdf.org). **The `wkhtmltopdf` and - optionally - `wkhtmltoimage` +command must be installed and working on your system.** See the section below for details. + +For Windows systems make sure to set the path to wkhtmltopdf.exe in the binary option. Alternatively you can add the wkhtmltopdf "bin" directory to the system PATH variable to allow wkhtmltopdf command available to Windows CMD. + +## Installation + +Install the package through [composer](http://getcomposer.org): + +``` +composer require mikehaertl/phpwkhtmltopdf +``` + +Make sure, that you include the composer [autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading) +somewhere in your codebase. + +## Examples + +### Single page PDF + +```php +use mikehaertl\wkhtmlto\Pdf; + +// You can pass a filename, a HTML string, an URL or an options array to the constructor +$pdf = new Pdf('/path/to/page.html'); + +// On some systems you may have to set the path to the wkhtmltopdf executable +// $pdf->binary = 'C:\...'; + +if (!$pdf->saveAs('/path/to/page.pdf')) { + $error = $pdf->getError(); + // ... handle error here +} +``` + +### Multi page PDF with Toc and Cover page + + +```php +use mikehaertl\wkhtmlto\Pdf; + +$pdf = new Pdf; +$pdf->addPage('/path/to/page.html'); +$pdf->addPage('....'); +$pdf->addPage('http://www.example.com'); + +// Add a cover (same sources as above are possible) +$pdf->addCover('/path/to/mycover.html'); + +// Add a Table of contents +$pdf->addToc(); + +// Save the PDF +if (!$pdf->saveAs('/path/to/report.pdf')) { + $error = $pdf->getError(); + // ... handle error here +} + +// ... or send to client for inline display +if (!$pdf->send()) { + $error = $pdf->getError(); + // ... handle error here +} + +// ... or send to client as file download +if (!$pdf->send('report.pdf')) { + $error = $pdf->getError(); + // ... handle error here +} + +// ... or you can get the raw pdf as a string +$content = $pdf->toString(); +``` + +### Creating an image + +```php +use mikehaertl\wkhtmlto\Image; + +// You can pass a filename, a HTML string, an URL or an options array to the constructor +$image = new Image('/path/to/page.html'); +$image->saveAs('/path/to/page.png'); + +// ... or send to client for inline display +if (!$image->send()) { + $error = $image->getError(); + // ... handle error here +} + +// ... or send to client as file download +if (!$image->send('page.png')) { + $error = $image->getError(); + // ... handle error here +} +``` + +## Setting options + +The `wkhtmltopdf` shell command accepts different types of options: + + * global options (e.g. to set the document's DPI or the default page options) + * page options (e.g. to supply a custom CSS file for a page) + * toc options (e.g. to set a TOC header) + +Please see `wkhtmltopdf -H` for a full explanation. All options are passed as array, for example: + +```php +$options = array( + 'no-outline', // option without argument + 'encoding' => 'UTF-8', // option with argument + + // Option with 2 arguments + 'cookie' => array('name'=>'value'), + + // Repeatable options with single argument + 'run-script' => array( + '/path/to/local1.js', + '/path/to/local2.js', + ), + + // Repeatable options with 2 arguments + 'replace' => array( + 'number' => $page++, // Replace '[number]' + 'title' => $pageTitle, // Replace '[title]' + ), +); +``` + +Options can be passed to several methods for PDFs: + +```php +$pdf = new Pdf($globalOptions); // Set global PDF options +$pdf->setOptions($globalOptions); // Set global PDF options (alternative) +$pdf->addPage($page, $pageOptions); // Add page with options +$pdf->addCover($page, $pageOptions); // Add cover with options +$pdf->addToc($tocOptions); // Add TOC with options +``` + +> Note, that you can also use page options in the global PDF options. `wkhtmltopdf` +> will apply them to all pages unless you override them when you add a page. + +For `wkhtmltoimage` there's only one set of options: + +```php +$image = new Image($options); // Set image options +$image->setOptions($options); // Set image options (alternative) +``` + +### Wrapper options + +The wrapper itself is configured by the following special options that can be passed +to the constructor, set as object properties or via `setOptions()`: + + * `binary`: Full path to the `wkhtmltopdf` command. Default is `wkhtmltopdf` which assumes that the + command is in your shell's search path. + * `commandOptions`: Options to pass to https://github.com/mikehaertl/php-shellcommand. + * `tmpDir`: Path to tmp directory. Defaults to the PHP temp dir. + * `ignoreWarnings`: Whether to ignore any errors if a PDF file was still created. Default is `false`. + * `version9`: Whether to use command line syntax for older wkhtmltopdf versions. + +In addition to the `binary`, `commandOptions`, `tmpDir` and `ignoreWarnings` options above, +the `Image` class also has a `type` option: + + * `type`: The image type. Default is `png`. You can also use `jpg` or `bmp`. + +`commandOptions` can be used to set environment variables for `wkhtmltopdf`. For example, if you +want to pass UTF-8 encoded arguments, you may have to set the `LANG` environment variable. + +```php +$pdf = new Pdf(array( + 'binary' => '/obscure/path/to/wkhtmltopdf', + 'ignoreWarnings' => true, + 'commandOptions' => array( + 'useExec' => true, // Can help on Windows systems + 'procEnv' => array( + // Check the output of 'locale -a' on your system to find supported languages + 'LANG' => 'en_US.utf-8', + ), + ), +)); +``` + +### Passing strings + +Some options like `header-html` usually expect a URL or a filename. With our +library you can also pass a string. The class will try to detect if the +argument is a URL, a filename or some HTML or XML content. To make detection +easier you can surround your content in `` tag. + +If this doesn't work correctly you can also pass an instance of our `File` +helper as a last resort: + +```php +use mikehaertl\tmp\File; +$options = [ + 'header-html' => new File('Complex content', '.html'), +]; +``` + +## Error handling + +`send()`, `saveAs()` and `toString()` will return `false` on error. In this case the detailed error message is +available from `getError()`: + +```php +if (!$pdf->send()) { + throw new Exception('Could not create PDF: '.$pdf->getError()); +} + +$content = $pdf->toString(); +if ($content === false) { + throw new Exception('Could not create PDF: '.$pdf->getError()); +} +``` + +## Note for Windows users + +If you use double quotes (`"`) or percent signs (`%`) as option values, they may get converted to spaces. +In this case you can disable argument escaping in the [command](https://github.com/mikehaertl/php-shellcommand). +There are also two interesting options to `proc_open()` that you may want to use: + +```php +$pdf = new Pdf(array( + 'commandOptions' => array( + 'escapeArgs' => false, + 'procOptions' => array( + // This will bypass the cmd.exe which seems to be recommended on Windows + 'bypass_shell' => true, + // Also worth a try if you get unexplainable errors + 'suppress_errors' => true, + ), + ), + ... +)); +``` + +But then you have to take care of proper argument escaping yourself. In some cases it may be neccessary to +surround your argument values with extra double quotes. + +I also found that some options don't work on Windows (tested with wkhtmltopdf 0.11 rc2), like the +`user-style-sheet` option used in the example below. + + +## Installation of wkhtmltopdf + +It's recommended that you download the latest wkhtmltopdf from their website: + + http://wkhtmltopdf.org/downloads.html + +These versions should run out of the box. + +If for some reason you can't do so, you may run into an issue with the dynamically linked version of +`wkhtmltopdf`. This is what you get for example on Ubuntu 12.04 LTS if you install the wkhtmltopdf package. +It will work, but to use all features it requires an X server which is usually not available on headless +webservers. + +We therefore provide two Xvfb based workarounds. You can either use + + * the built in Xvfb support or + * a standalone Xvfb server. + +Both require the Xvfb package to be installed on the system and both also have some drawbacks. + +#### Built in Xvfb support + +This wraps each call to `wkhtmltopdf` with [xvfb-run](http://manpages.ubuntu.com/manpages/lucid/man1/xvfb-run.1.html). +`xvfb-run` will run any given command in a X environment without all the overhead of a full X session. +The drawback with this solution is, that there's still a new session fired up for each an every PDF you create, +which will create quite some extra load on your CPU. So this setup is only recommended for low frequency sites. + +To use the built in support you have to set `enableXvfb` in the `commandOptions`. There are also some options you can set. + +```php +$pdf = new Pdf(array( + // Explicitly tell wkhtmltopdf that we're using an X environment + 'use-xserver', + + // Enable built in Xvfb support in the command + 'commandOptions' => array( + 'enableXvfb' => true, + + // Optional: Set your path to xvfb-run. Default is just 'xvfb-run'. + // 'xvfbRunBinary' => '/usr/bin/xvfb-run', + + // Optional: Set options for xfvb-run. The following defaults are used. + // 'xvfbRunOptions' => '--server-args="-screen 0, 1024x768x24"', + ), +)); +``` + +#### Standalone Xvfb + +It's better to start a Xvfb process once and reuse it for all your PHP requests +(thanks to Larry Williamson for [the original idea](https://coderwall.com/p/tog9eq)). +This requires that you have root access to your machine as you have to add a startup script +for that process. We have provided an example [init script](https://gist.github.com/eusonlito/7889622) +for Ubuntu (thanks eusonlito). You can put it to `/etc/init.d/xvfb` and add it to your startup files with +`update-rc.d xvfb defaults 10`. + +If your system is based on systemd [this config](https://gist.github.com/nkm/91006178753df6f503c1) +should help (thanks nkm). + +If your `Xvfb` process is running, you just have to tell the class to use this X display for +rendering. This is done via an environment variable. + +```php +$pdf = new Pdf(array( + 'use-xserver', + 'commandOptions' => array( + // You can change ':0' to whatever display you pick in your daemon script + 'procEnv' => array( 'DISPLAY' => ':0' ), + ), +)); +``` + +## Full example + +For me `wkhtmltopdf` seems to create best results with smart shrinking turned off. +But then I had scaling issues which went away after I set all margins to zero and instead +added the margins through CSS. You can also use `cm` or `in` in CSS as this is more apropriate for print styles. + +```php +use mikehaertl\wkhtmlto\Pdf; + +// Create a new Pdf object with some global PDF options +$pdf = new Pdf(array( + 'no-outline', // Make Chrome not complain + 'margin-top' => 0, + 'margin-right' => 0, + 'margin-bottom' => 0, + 'margin-left' => 0, + + // Default page options + 'disable-smart-shrinking', + 'user-style-sheet' => '/path/to/pdf.css', +)); + +// Add a page. To override above page defaults, you could add +// another $options array as second argument. +$pdf->addPage('/path/to/demo.html'); + +if (!$pdf->send()) { + $error = $pdf->getError(); + // ... handle error here +} +``` + +**demo.html** +```html + + + + + + + + + + +``` + +**pdf.css** +```css +/* Define page size. Requires print-area adjustment! */ +body { + margin: 0; + padding: 0; + width: 21cm; + height: 29.7cm; +} + +/* Printable area */ +#print-area { + position: relative; + top: 1cm; + left: 1cm; + width: 19cm; + height: 27.6cm; + + font-size: 10px; + font-family: Arial; +} + +#header { + height: 3cm; + + background: #ccc; +} +#footer { + position: absolute; + bottom: 0; + width: 100%; + height: 3cm; + + background: #ccc; +} +``` + +## Links + +Also check out my [php-pdftk](https://github.com/mikehaertl/php-pdftk) wrapper around `pdftk` +which brings the full power of `pdftk` to PHP. diff --git a/vendor/mikehaertl/phpwkhtmltopdf/composer.json b/vendor/mikehaertl/phpwkhtmltopdf/composer.json new file mode 100644 index 0000000..059ad22 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/composer.json @@ -0,0 +1,32 @@ +{ + "name": "mikehaertl/phpwkhtmltopdf", + "description": "A slim PHP wrapper around wkhtmltopdf with an easy to use and clean OOP interface", + "keywords": ["pdf", "wkhtmltopdf", "wkhtmltoimage" ], + "homepage": "http://mikehaertl.github.com/phpwkhtmltopdf/", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Michael Haertl", + "email": "haertl.mike@gmail.com" + } + ], + "require": { + "php": ">=5.0.0", + "mikehaertl/php-tmpfile": "^1.2.1", + "mikehaertl/php-shellcommand": "^1.5.0" + }, + "autoload": { + "psr-4": { + "mikehaertl\\wkhtmlto\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "tests\\": "tests" + } + }, + "require-dev": { + "phpunit/phpunit": ">4.0 <9.4" + } +} diff --git a/vendor/mikehaertl/phpwkhtmltopdf/src/Command.php b/vendor/mikehaertl/phpwkhtmltopdf/src/Command.php new file mode 100644 index 0000000..0071992 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/src/Command.php @@ -0,0 +1,106 @@ + + * @license http://www.opensource.org/licenses/MIT + */ +class Command extends BaseCommand +{ + /** + * @var bool whether to enable the built in Xvfb support (uses xvfb-run) + */ + public $enableXvfb = false; + + /** + * @var string the name of the xvfb-run comand. Default is `xvfb-run`. You + * can also configure a full path here. + */ + public $xvfbRunBinary = 'xvfb-run'; + + /** + * @var string options to pass to the xfvb-run command. Default is + * `--server-args="-screen 0, 1024x768x24"`. + */ + public $xvfbRunOptions = '-a --server-args="-screen 0, 1024x768x24"'; + + /** + * @param array $args args to add to the command. These can be: + * ``` + * [ + * // Special argument 'input' will not get prepended with '--'. + * 'input' => 'cover', + * + * // Special argument 'inputArg' is treated like 'input' but will get escaped + * // Both 'input' and 'inputArg' can be used in combination + * 'inputArg' => '/tmp/tmpFileName.html', + * + * 'no-outline', // option without argument + * 'encoding' => 'UTF-8', // option with argument + * + * // Option with 2 arguments + * 'cookie' => array('name'=>'value'), + * + * // Repeatable options with single argument + * 'run-script' => array( + * 'local1.js', + * 'local2.js', + * ), + * + * // Repeatable options with 2 arguments + * 'replace' => array( + * '{page}' => $page++, + * '{title}' => $pageTitle, + * ), + * ] + * ``` + */ + public function addArgs($args) + { + if (isset($args['input'])) { + // Typecasts TmpFile to filename + $this->addArg((string) $args['input']); + unset($args['input']); + } + if (isset($args['inputArg'])) { + // Typecasts TmpFile to filename and escapes argument + $this->addArg((string) $args['inputArg'], null, true); + unset($args['inputArg']); + } + foreach($args as $key => $val) { + if (is_numeric($key)) { + $this->addArg("--$val"); + } elseif (is_array($val)) { + foreach($val as $vkey => $vval) { + if (is_int($vkey)) { + $this->addArg("--$key", $vval); + } else { + $this->addArg("--$key", array($vkey, $vval)); + } + } + } else { + $this->addArg("--$key", $val); + } + } + } + + /** + * @return string|bool the command to execute with optional Xfvb wrapper + * applied. Null if none set. + */ + public function getExecCommand() + { + $command = parent::getExecCommand(); + if ($this->enableXvfb) { + return $this->xvfbRunBinary.' '.$this->xvfbRunOptions.' '.$command; + } + return $command; + } +} diff --git a/vendor/mikehaertl/phpwkhtmltopdf/src/Image.php b/vendor/mikehaertl/phpwkhtmltopdf/src/Image.php new file mode 100644 index 0000000..ce02dd9 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/src/Image.php @@ -0,0 +1,264 @@ + + * @license http://www.opensource.org/licenses/MIT + */ +class Image +{ + // Regular expression to detect HTML strings + const REGEX_HTML = '/ 'val', + * ...]` + */ + protected $_options = array(); + + /** + * @var \mikehaertl\tmp\File the temporary image file + */ + protected $_tmpImageFile; + + /** + * @var Command the command instance that executes wkhtmltopdf + */ + protected $_command; + + /** + * @var string the detailed error message. Empty string if none. + */ + protected $_error = ''; + + /** + * @param array|string $options global options for wkhtmltoimage, a page + * URL, a HTML string or a filename + */ + public function __construct($options = null) + { + if (is_array($options)) { + $this->setOptions($options); + } elseif (is_string($options)) { + $this->setPage($options); + } + } + + /** + * Add a page object to the output + * + * @param string $page either a URL, a HTML string or a filename + * @return static the Image instance for method chaining + */ + public function setPage($page) + { + $this->_page = preg_match(self::REGEX_HTML, $page) ? new File($page, '.html') : $page; + return $this; + } + + /** + * Save the image to given filename (triggers image creation) + * + * @param string $filename to save image as + * @return bool whether image was created successfully + */ + public function saveAs($filename) + { + if (!$this->_isCreated && !$this->createImage()) { + return false; + } + if (!$this->_tmpImageFile->saveAs($filename)) { + $tmpFile = $this->_tmpImageFile->getFileName(); + $this->_error = "Could not copy image from tmp location '$tmpFile' to '$filename'"; + return false; + } + return true; + } + + /** + * Send image to client, either inline or as download (triggers image + * creation) + * + * @param string|null $filename the filename to send. If empty, the PDF is + * streamed inline. Note, that the file extension must match what you + * configured as $type (png, jpg, ...). + * @param bool $inline whether to force inline display of the image, even + * if filename is present. + * @param array $headers a list of additional HTTP headers to send in the + * response as an array. The array keys are the header names like + * 'Cache-Control' and the array values the header value strings to send. + * Each array value can also be another array of strings if the same header + * should be sent multiple times. This can also be used to override + * automatically created headers like 'Expires' or 'Content-Length'. To suppress + * automatically created headers, `false` can also be used as header value. + * @return bool whether image was created successfully + */ + public function send($filename = null, $inline = false, $headers = array()) + { + if (!$this->_isCreated && !$this->createImage()) { + return false; + } + $this->_tmpImageFile->send($filename, $this->getMimeType(), $inline, $headers); + return true; + } + + /** + * Get the raw Image contents (triggers Image creation). + * @return string|bool The Image content as a string or `false` if the + * Image wasn't created successfully. + */ + public function toString() + { + if (!$this->_isCreated && !$this->createImage()) { + return false; + } + return file_get_contents($this->_tmpImageFile->getFileName()); + } + + /** + * Set options + * + * @param array $options list of image options to set as name/value pairs + * @return static the Image instance for method chaining + */ + public function setOptions($options = array()) + { + foreach ($options as $key => $val) { + if (is_int($key)) { + $this->_options[] = $val; + } elseif ($key[0]!=='_' && property_exists($this, $key)) { + $this->$key = $val; + } else { + $this->_options[$key] = $val; + } + } + return $this; + } + + /** + * @return Command the command instance that executes wkhtmltopdf + */ + public function getCommand() + { + if ($this->_command === null) { + $options = $this->commandOptions; + if (!isset($options['command'])) { + $options['command'] = $this->binary; + } + $this->_command = new Command($options); + } + return $this->_command; + } + + /** + * @return string the detailed error message. Empty string if none. + */ + public function getError() + { + return $this->_error; + } + + /** + * @return string the filename of the temporary image file + */ + public function getImageFilename() + { + if ($this->_tmpImageFile === null) { + $this->_tmpImageFile = new File('', '.'.$this->type, self::TMP_PREFIX); + } + return $this->_tmpImageFile->getFileName(); + } + + /** + * @return string the mime type for the current image + * @throws \Exception + */ + public function getMimeType() + { + if ($this->type === 'jpg') { + return 'image/jpeg'; + } elseif ($this->type === 'png') { + return 'image/png'; + } elseif ($this->type === 'bmp') { + return 'image/bmp'; + } else { + throw new \Exception('Invalid image type'); + } + } + + /** + * Run the Command to create the tmp image file + * + * @return bool whether creation was successful + */ + protected function createImage() + { + if ($this->_isCreated) { + return false; + } + $command = $this->getCommand(); + $fileName = $this->getImageFilename(); + + $command->addArgs($this->_options); + // Always escape input and output filename + $command->addArg((string) $this->_page, null, true); + $command->addArg($fileName, null, true); + if (!$command->execute()) { + $this->_error = $command->getError(); + if (!(file_exists($fileName) && filesize($fileName)!==0 && $this->ignoreWarnings)) { + return false; + } + } + $this->_isCreated = true; + return true; + } +} diff --git a/vendor/mikehaertl/phpwkhtmltopdf/src/Pdf.php b/vendor/mikehaertl/phpwkhtmltopdf/src/Pdf.php new file mode 100644 index 0000000..4fdc209 --- /dev/null +++ b/vendor/mikehaertl/phpwkhtmltopdf/src/Pdf.php @@ -0,0 +1,369 @@ + + * @license http://www.opensource.org/licenses/MIT + */ +class Pdf +{ + // Type hints for `addPage()` and `addCover()` + const TYPE_HTML = 'html'; + const TYPE_XML = 'xml'; + + // Regular expression to detect HTML strings + const REGEX_HTML = '/<(?:!doctype )?html/i'; + + // Regular expression to detect XML strings + const REGEX_XML = '/<\??xml/i'; + + // Regular expression to detect URL strings + const REGEX_URL = '/^(https?:)?\/\//i'; + + // Regular expression to detect options that expect an URL or a file name, + // so we need to create a tmp file for the content. + const REGEX_OPTS_TMPFILE = '/^((header|footer)-html|(xsl|user)-style-sheet)$/i'; + + // Prefix for tmp files + const TMP_PREFIX = 'tmp_wkhtmlto_pdf_'; + + // Maximum length of a file path if PHP_MAXPATHLEN is not defined + const MAX_PATHLEN = 255; + + /** + * @var string the name of the `wkhtmltopdf` binary. Default is + * `wkhtmltopdf`. You can also configure a full path here. + */ + public $binary = 'wkhtmltopdf'; + + /** + * @var array options to pass to the Command constructor. Default is none. + */ + public $commandOptions = array(); + + /** + * @var string|null the directory to use for temporary files. If null + * (default) the dir is autodetected. + */ + public $tmpDir; + + /** + * @var bool whether to ignore any errors if some PDF file was still + * created. Default is false. + */ + public $ignoreWarnings = false; + + /** + * @var bool whether the old version 9 of wkhtmltopdf is used (slightly + * different syntax). Default is false. + */ + public $version9 = false; + + /** + * @var bool whether the PDF was created + */ + protected $_isCreated = false; + + /** + * @var array global options for `wkhtmltopdf` as `['--opt1', '--opt2' => + * 'val', ...]` + */ + protected $_options = array(); + + /** + * @var array list of wkhtmltopdf objects as arrays + */ + protected $_objects = array(); + + /** + * @var \mikehaertl\tmp\File the temporary PDF file + */ + protected $_tmpPdfFile; + + /** + * @var \mikehaertl\tmp\File[] list of tmp file objects. This is here to + * keep a reference to `File` and thus avoid too early call of + * [[File::__destruct]] if the file is not referenced anymore. + */ + protected $_tmpFiles = array(); + + /** + * @var Command the command instance that executes wkhtmltopdf + */ + protected $_command; + + /** + * @var string the detailed error message. Empty string if none. + */ + protected $_error = ''; + + /** + * @param array|string $options global options for wkhtmltopdf, a page URL, + * a HTML string or a filename + */ + public function __construct($options = null) + { + if (is_array($options)) { + $this->setOptions($options); + } elseif (is_string($options)) { + $this->addPage($options); + } + } + + /** + * Add a page object to the output + * + * @param string $input either a URL, a HTML string or a filename + * @param array $options optional options for this page + * @param string|null $type a type hint if the input is a string of known + * type. This can either be `TYPE_HTML` or `TYPE_XML`. If `null` (default) + * the type is auto detected from the string content. + * @return static the Pdf instance for method chaining + */ + public function addPage($input, $options = array(), $type = null) + { + $options['inputArg'] = $this->ensureUrlOrFile($input, $type); + $this->_objects[] = $this->ensureUrlOrFileOptions($options); + return $this; + } + + /** + * Add a cover page object to the output + * + * @param string $input either a URL, a HTML string or a filename + * @param array $options optional options for the cover page + * @param string|null $type a type hint if the input is a string of known + * type. This can either be `TYPE_HTML` or `TYPE_XML`. If `null` (default) + * the type is auto detected from the string content. + * @return static the Pdf instance for method chaining + */ + public function addCover($input, $options = array(), $type = null) + { + $options['input'] = ($this->version9 ? '--' : '') . 'cover'; + $options['inputArg'] = $this->ensureUrlOrFile($input, $type); + $this->_objects[] = $this->ensureUrlOrFileOptions($options); + return $this; + } + + /** + * Add a TOC object to the output + * + * @param array $options optional options for the table of contents + * @return static the Pdf instance for method chaining + */ + public function addToc($options = array()) + { + $options['input'] = ($this->version9 ? '--' : '') . 'toc'; + $this->_objects[] = $this->ensureUrlOrFileOptions($options); + return $this; + } + + /** + * Save the PDF to given filename (triggers PDF creation) + * + * @param string $filename to save PDF as + * @return bool whether PDF was created successfully + */ + public function saveAs($filename) + { + if (!$this->_isCreated && !$this->createPdf()) { + return false; + } + if (!$this->_tmpPdfFile->saveAs($filename)) { + $this->_error = "Could not save PDF as '$filename'"; + return false; + } + return true; + } + + /** + * Send PDF to client, either inline or as download (triggers PDF creation) + * + * @param string|null $filename the filename to send. If empty, the PDF is + * streamed inline. + * @param bool $inline whether to force inline display of the PDF, even if + * filename is present. + * @param array $headers a list of additional HTTP headers to send in the + * response as an array. The array keys are the header names like + * 'Cache-Control' and the array values the header value strings to send. + * Each array value can also be another array of strings if the same header + * should be sent multiple times. This can also be used to override + * automatically created headers like 'Expires' or 'Content-Length'. To suppress + * automatically created headers, `false` can also be used as header value. + * @return bool whether PDF was created successfully + */ + public function send($filename = null, $inline = false, $headers = array()) + { + if (!$this->_isCreated && !$this->createPdf()) { + return false; + } + $this->_tmpPdfFile->send($filename, 'application/pdf', $inline, $headers); + return true; + } + + /** + * Get the raw PDF contents (triggers PDF creation). + * @return string|bool The PDF content as a string or `false` if the PDF + * wasn't created successfully. + */ + public function toString() + { + if (!$this->_isCreated && !$this->createPdf()) { + return false; + } + return file_get_contents($this->_tmpPdfFile->getFileName()); + } + + /** + * Set global option(s) + * + * @param array $options list of global PDF options to set as name/value pairs + * @return static the Pdf instance for method chaining + */ + public function setOptions($options = array()) + { + // #264 tmpDir must be set before calling ensureUrlOrFileOptions + if (isset($options['tmpDir'])) { + $this->tmpDir = $options['tmpDir']; + unset($options['tmpDir']); + } + $options = $this->ensureUrlOrFileOptions($options); + foreach ($options as $key => $val) { + if (is_int($key)) { + $this->_options[] = $val; + } elseif ($key[0] !== '_' && property_exists($this, $key)) { + $this->$key = $val; + } else { + $this->_options[$key] = $val; + } + } + return $this; + } + + /** + * @return Command the command instance that executes wkhtmltopdf + */ + public function getCommand() + { + if ($this->_command === null) { + $options = $this->commandOptions; + if (!isset($options['command'])) { + $options['command'] = $this->binary; + } + $this->_command = new Command($options); + } + return $this->_command; + } + + /** + * @return string the detailed error message. Empty string if none. + */ + public function getError() + { + return $this->_error; + } + + /** + * @return string the filename of the temporary PDF file + */ + public function getPdfFilename() + { + if ($this->_tmpPdfFile === null) { + $this->_tmpPdfFile = new File('', '.pdf', self::TMP_PREFIX, $this->tmpDir); + } + return $this->_tmpPdfFile->getFileName(); + } + + /** + * Run the Command to create the tmp PDF file + * + * @return bool whether creation was successful + */ + protected function createPdf() + { + if ($this->_isCreated) { + return false; + } + $command = $this->getCommand(); + $fileName = $this->getPdfFilename(); + + $command->addArgs($this->_options); + foreach ($this->_objects as $object) { + $command->addArgs($object); + } + $command->addArg($fileName, null, true); // Always escape filename + if (!$command->execute()) { + $this->_error = $command->getError(); + if (!(file_exists($fileName) && filesize($fileName) !== 0 && $this->ignoreWarnings)) { + return false; + } + } + $this->_isCreated = true; + return true; + } + + /** + * This method creates a temporary file if the passed argument is neither a + * File instance or URL nor contains XML or HTML and is also not a valid + * file name. + * + * @param string|File $input the input argument File to check + * @param string|null $type a type hint if the input is a string of known + * type. This can either be `TYPE_HTML` or `TYPE_XML`. If `null` (default) + * the type is auto detected from the string content. + * @return \mikehaertl\tmp\File|string a File object if the input is a HTML + * or XML string. The unchanged input otherwhise. + */ + protected function ensureUrlOrFile($input, $type = null) + { + if ($input instanceof File) { + $this->_tmpFiles[] = $input; + return $input; + } elseif (preg_match(self::REGEX_URL, $input)) { + return $input; + } elseif ($type === self::TYPE_XML || $type === null && preg_match(self::REGEX_XML, $input)) { + $ext = '.xml'; + } else { + // First check for obvious HTML content to avoid is_file() as much + // as possible as it can trigger open_basedir restriction warnings + // with long strings. + $isHtml = $type === self::TYPE_HTML || preg_match(self::REGEX_HTML, $input); + if (!$isHtml) { + $maxPathLen = defined('PHP_MAXPATHLEN') ? + constant('PHP_MAXPATHLEN') : self::MAX_PATHLEN; + if (strlen($input) <= $maxPathLen && is_file($input)) { + return $input; + } + } + $ext = '.html'; + } + $file = new File($input, $ext, self::TMP_PREFIX, $this->tmpDir); + $this->_tmpFiles[] = $file; + return $file; + } + + /** + * @param array $options list of options as name/value pairs + * @return array options with raw HTML/XML/String content converted to tmp + * files where neccessary + */ + protected function ensureUrlOrFileOptions($options = array()) + { + foreach ($options as $key => $val) { + // Some options expect a URL or a file name, so check if we need a temp file + if (is_string($val) && preg_match(self::REGEX_OPTS_TMPFILE, $key) ) { + $file = $this->ensureUrlOrFile($val); + if ($file instanceof File) { + $options[$key] = $file; + } + } + } + return $options; + } +} diff --git a/verify_certificate.php b/verify_certificate.php index dead636..21c6c76 100644 --- a/verify_certificate.php +++ b/verify_certificate.php @@ -1,5 +1,5 @@ + * @package mod_htmlcert + * @copyright 2017 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -33,7 +33,7 @@ $qrcode = optional_param('qrcode', false, PARAM_BOOL); $context = context::instance_by_id($contextid); // Set up the page. -$pageurl = new moodle_url('/mod/customcert/verify_certificate.php', array('contextid' => $contextid)); +$pageurl = new moodle_url('/mod/htmlcert/verify_certificate.php', array('contextid' => $contextid)); if ($code) { $pageurl->param('code', $code); @@ -41,21 +41,21 @@ if ($code) { // Ok, a certificate was specified. if ($context->contextlevel != CONTEXT_SYSTEM) { - $cm = get_coursemodule_from_id('customcert', $context->instanceid, 0, false, MUST_EXIST); + $cm = get_coursemodule_from_id('htmlcert', $context->instanceid, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); - $customcert = $DB->get_record('customcert', array('id' => $cm->instance), '*', MUST_EXIST); + $htmlcert = $DB->get_record('htmlcert', array('id' => $cm->instance), '*', MUST_EXIST); // Check if we are allowing anyone to verify, if so, no need to check login, or permissions. - if (!$customcert->verifyany) { + if (!$htmlcert->verifyany) { // Need to be logged in. require_login($course, false, $cm); // Ok, now check the user has the ability to verify certificates. - require_capability('mod/customcert:verifycertificate', $context); + require_capability('mod/htmlcert:verifycertificate', $context); } else { $PAGE->set_cm($cm, $course); } - $title = $customcert->name; + $title = $htmlcert->name; $heading = format_string($title); $checkallofsite = false; } else { @@ -64,42 +64,42 @@ if ($context->contextlevel != CONTEXT_SYSTEM) { $checkallofsite = true; } -\mod_customcert\page_helper::page_setup($pageurl, $context, $title); +\mod_htmlcert\page_helper::page_setup($pageurl, $context, $title); // Additional page setup. if ($context->contextlevel == CONTEXT_SYSTEM) { - $PAGE->navbar->add(get_string('verifycertificate', 'customcert')); + $PAGE->navbar->add(get_string('verifycertificate', 'htmlcert')); } if ($checkallofsite) { - // If the 'verifyallcertificates' is not set and the user does not have the capability 'mod/customcert:verifyallcertificates' + // If the 'verifyallcertificates' is not set and the user does not have the capability 'mod/htmlcert:verifyallcertificates' // then show them a message letting them know they can not proceed. - $verifyallcertificates = get_config('customcert', 'verifyallcertificates'); - $canverifyallcertificates = has_capability('mod/customcert:verifyallcertificates', $context); + $verifyallcertificates = get_config('htmlcert', 'verifyallcertificates'); + $canverifyallcertificates = has_capability('mod/htmlcert:verifyallcertificates', $context); if (!$verifyallcertificates && !$canverifyallcertificates) { echo $OUTPUT->header(); echo $OUTPUT->heading($heading); - echo $OUTPUT->notification(get_string('cannotverifyallcertificates', 'customcert')); + echo $OUTPUT->notification(get_string('cannotverifyallcertificates', 'htmlcert')); echo $OUTPUT->footer(); exit(); } } // The form we are using to verify these codes. -$form = new \mod_customcert\verify_certificate_form($pageurl); +$form = new \mod_htmlcert\verify_certificate_form($pageurl); if ($code) { $result = new stdClass(); $result->issues = array(); // Ok, now check if the code is valid. - $userfields = \mod_customcert\helper::get_all_user_name_fields('u'); + $userfields = \mod_htmlcert\helper::get_all_user_name_fields('u'); $sql = "SELECT ci.id, u.id as userid, $userfields, co.id as courseid, co.fullname as coursefullname, c.id as certificateid, c.name as certificatename, c.verifyany - FROM {customcert} c - JOIN {customcert_issues} ci - ON c.id = ci.customcertid + FROM {htmlcert} c + JOIN {htmlcert_issues} ci + ON c.id = ci.htmlcertid JOIN {course} co ON c.course = co.id JOIN {user} u @@ -113,8 +113,8 @@ if ($code) { } $params = ['code' => $code]; } else { - $sql .= " AND c.id = :customcertid"; - $params = ['code' => $code, 'customcertid' => $customcert->id]; + $sql .= " AND c.id = :htmlcertid"; + $params = ['code' => $code, 'htmlcertid' => $htmlcert->id]; } // It is possible (though unlikely) that there is the same code for issued certificates. @@ -134,8 +134,8 @@ if (!$qrcode) { echo $form->display(); } if (isset($result)) { - $renderer = $PAGE->get_renderer('mod_customcert'); - $result = new \mod_customcert\output\verify_certificate_results($result); + $renderer = $PAGE->get_renderer('mod_htmlcert'); + $result = new \mod_htmlcert\output\verify_certificate_results($result); echo $renderer->render($result); } echo $OUTPUT->footer(); diff --git a/version.php b/version.php index 12b71b5..757ad31 100644 --- a/version.php +++ b/version.php @@ -1,5 +1,5 @@ . /** - * Code fragment to define the version of the customcert module + * Code fragment to define the version of the htmlcert module * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); -$plugin->version = 2021051702; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2021112300; // The current module version (Date: YYYYMMDDXX). $plugin->requires = 2021051700; // Requires this Moodle version (3.11). $plugin->cron = 0; // Period for cron to check this module (secs). -$plugin->component = 'mod_customcert'; +$plugin->component = 'mod_htmlcert'; $plugin->maturity = MATURITY_STABLE; -$plugin->release = "3.11.1"; // User-friendly version number. +$plugin->release = "0.1"; // User-friendly version number. diff --git a/view.php b/view.php index 9b8af82..ce3b5b6 100644 --- a/view.php +++ b/view.php @@ -1,5 +1,5 @@ . /** - * Handles viewing a customcert. + * Handles viewing a htmlcert. * - * @package mod_customcert - * @copyright 2013 Mark Nelson + * @package mod_htmlcert + * @copyright 2013 Mark Nelson , 2021 Klaus-Uwe Mitterer * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -31,33 +31,33 @@ $downloadissue = optional_param('downloadissue', 0, PARAM_INT); $deleteissue = optional_param('deleteissue', 0, PARAM_INT); $confirm = optional_param('confirm', false, PARAM_BOOL); $page = optional_param('page', 0, PARAM_INT); -$perpage = optional_param('perpage', \mod_customcert\certificate::CUSTOMCERT_PER_PAGE, PARAM_INT); +$perpage = optional_param('perpage', \mod_htmlcert\certificate::HTMLCERT_PER_PAGE, PARAM_INT); -$cm = get_coursemodule_from_id('customcert', $id, 0, false, MUST_EXIST); +$cm = get_coursemodule_from_id('htmlcert', $id, 0, false, MUST_EXIST); $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); -$customcert = $DB->get_record('customcert', array('id' => $cm->instance), '*', MUST_EXIST); -$template = $DB->get_record('customcert_templates', array('id' => $customcert->templateid), '*', MUST_EXIST); +$htmlcert = $DB->get_record('htmlcert', array('id' => $cm->instance), '*', MUST_EXIST); +$template = $DB->get_record('htmlcert_templates', array('id' => $htmlcert->templateid), '*', MUST_EXIST); // Ensure the user is allowed to view this page. require_login($course, false, $cm); $context = context_module::instance($cm->id); -require_capability('mod/customcert:view', $context); +require_capability('mod/htmlcert:view', $context); -$canreceive = has_capability('mod/customcert:receiveissue', $context); -$canmanage = has_capability('mod/customcert:manage', $context); -$canviewreport = has_capability('mod/customcert:viewreport', $context); +$canreceive = has_capability('mod/htmlcert:receiveissue', $context); +$canmanage = has_capability('mod/htmlcert:manage', $context); +$canviewreport = has_capability('mod/htmlcert:viewreport', $context); // Initialise $PAGE. -$pageurl = new moodle_url('/mod/customcert/view.php', array('id' => $cm->id)); -\mod_customcert\page_helper::page_setup($pageurl, $context, format_string($customcert->name)); +$pageurl = new moodle_url('/mod/htmlcert/view.php', array('id' => $cm->id)); +\mod_htmlcert\page_helper::page_setup($pageurl, $context, format_string($htmlcert->name)); // Check if the user can view the certificate based on time spent in course. -if ($customcert->requiredtime && !$canmanage) { - if (\mod_customcert\certificate::get_course_time($course->id) < ($customcert->requiredtime * 60)) { +if ($htmlcert->requiredtime && !$canmanage) { + if (\mod_htmlcert\certificate::get_course_time($course->id) < ($htmlcert->requiredtime * 60)) { $a = new stdClass; - $a->requiredtime = $customcert->requiredtime; + $a->requiredtime = $htmlcert->requiredtime; $url = new moodle_url('/course/view.php', ['id' => $course->id]); - notice(get_string('requiredtimenotmet', 'customcert', $a), $url); + notice(get_string('requiredtimenotmet', 'htmlcert', $a), $url); die; } } @@ -65,8 +65,8 @@ if ($customcert->requiredtime && !$canmanage) { // Check if we are deleting an issue. if ($deleteissue && $canmanage && confirm_sesskey()) { if (!$confirm) { - $nourl = new moodle_url('/mod/customcert/view.php', ['id' => $id]); - $yesurl = new moodle_url('/mod/customcert/view.php', + $nourl = new moodle_url('/mod/htmlcert/view.php', ['id' => $id]); + $yesurl = new moodle_url('/mod/htmlcert/view.php', [ 'id' => $id, 'deleteissue' => $deleteissue, @@ -76,28 +76,28 @@ if ($deleteissue && $canmanage && confirm_sesskey()) { ); // Show a confirmation page. - $PAGE->navbar->add(get_string('deleteconfirm', 'customcert')); - $message = get_string('deleteissueconfirm', 'customcert'); + $PAGE->navbar->add(get_string('deleteconfirm', 'htmlcert')); + $message = get_string('deleteissueconfirm', 'htmlcert'); echo $OUTPUT->header(); - echo $OUTPUT->heading(format_string($customcert->name)); + echo $OUTPUT->heading(format_string($htmlcert->name)); echo $OUTPUT->confirm($message, $yesurl, $nourl); echo $OUTPUT->footer(); exit(); } // Delete the issue. - $DB->delete_records('customcert_issues', array('id' => $deleteissue, 'customcertid' => $customcert->id)); + $DB->delete_records('htmlcert_issues', array('id' => $deleteissue, 'htmlcertid' => $htmlcert->id)); // Redirect back to the manage templates page. - redirect(new moodle_url('/mod/customcert/view.php', array('id' => $id))); + redirect(new moodle_url('/mod/htmlcert/view.php', array('id' => $id))); } -$event = \mod_customcert\event\course_module_viewed::create(array( - 'objectid' => $customcert->id, +$event = \mod_htmlcert\event\course_module_viewed::create(array( + 'objectid' => $htmlcert->id, 'context' => $context, )); $event->add_record_snapshot('course', $course); -$event->add_record_snapshot('customcert', $customcert); +$event->add_record_snapshot('htmlcert', $htmlcert); $event->trigger(); // Check that we are not downloading a certificate PDF. @@ -110,7 +110,7 @@ if (!$downloadown && !$downloadissue) { // Generate the table to the report if there are issues to display. if ($canviewreport) { // Get the total number of issues. - $reporttable = new \mod_customcert\report_table($customcert->id, $cm, $groupmode, $downloadtable); + $reporttable = new \mod_htmlcert\report_table($htmlcert->id, $cm, $groupmode, $downloadtable); $reporttable->define_baseurl($pageurl); if ($reporttable->is_downloading()) { @@ -121,25 +121,25 @@ if (!$downloadown && !$downloadissue) { // Generate the intro content if it exists. $intro = ''; - if (!empty($customcert->intro)) { - $intro = $OUTPUT->box(format_module_intro('customcert', $customcert, $cm->id), 'generalbox', 'intro'); + if (!empty($htmlcert->intro)) { + $intro = $OUTPUT->box(format_module_intro('htmlcert', $htmlcert, $cm->id), 'generalbox', 'intro'); } - // If the current user has been issued a customcert generate HTML to display the details. + // If the current user has been issued a htmlcert generate HTML to display the details. $issuehtml = ''; - $issues = $DB->get_records('customcert_issues', array('userid' => $USER->id, 'customcertid' => $customcert->id)); + $issues = $DB->get_records('htmlcert_issues', array('userid' => $USER->id, 'htmlcertid' => $htmlcert->id)); if ($issues && !$canmanage) { // Get the most recent issue (there should only be one). $issue = reset($issues); - $issuestring = get_string('receiveddate', 'customcert') . ': ' . userdate($issue->timecreated); + $issuestring = get_string('receiveddate', 'htmlcert') . ': ' . userdate($issue->timecreated); $issuehtml = $OUTPUT->box($issuestring); } - // Create the button to download the customcert. + // Create the button to download the htmlcert. $downloadbutton = ''; if ($canreceive) { - $linkname = get_string('getcustomcert', 'customcert'); - $link = new moodle_url('/mod/customcert/view.php', array('id' => $cm->id, 'downloadown' => true)); + $linkname = get_string('gethtmlcert', 'htmlcert'); + $link = new moodle_url('/mod/htmlcert/view.php', array('id' => $cm->id, 'downloadown' => true)); $downloadbutton = new single_button($link, $linkname, 'get', true); $downloadbutton->class .= ' m-b-1'; // Seems a bit hackish, ahem. $downloadbutton = $OUTPUT->render($downloadbutton); @@ -147,13 +147,13 @@ if (!$downloadown && !$downloadissue) { // Output all the page data. echo $OUTPUT->header(); - echo $OUTPUT->heading(format_string($customcert->name)); + echo $OUTPUT->heading(format_string($htmlcert->name)); echo $intro; echo $issuehtml; echo $downloadbutton; if (isset($reporttable)) { - $numissues = \mod_customcert\certificate::get_number_of_issues($customcert->id, $cm, $groupmode); - echo $OUTPUT->heading(get_string('listofissues', 'customcert', $numissues), 3); + $numissues = \mod_htmlcert\certificate::get_number_of_issues($htmlcert->id, $cm, $groupmode); + echo $OUTPUT->heading(get_string('listofissues', 'htmlcert', $numissues), 3); groups_print_activity_menu($cm, $pageurl); echo $reporttable->out($perpage, false); } @@ -163,9 +163,9 @@ if (!$downloadown && !$downloadissue) { // Set the userid value of who we are downloading the certificate for. $userid = $USER->id; if ($downloadown) { - // Create new customcert issue record if one does not already exist. - if (!$DB->record_exists('customcert_issues', array('userid' => $USER->id, 'customcertid' => $customcert->id))) { - \mod_customcert\certificate::issue_certificate($customcert->id, $USER->id); + // Create new htmlcert issue record if one does not already exist. + if (!$DB->record_exists('htmlcert_issues', array('userid' => $USER->id, 'htmlcertid' => $htmlcert->id))) { + \mod_htmlcert\certificate::issue_certificate($htmlcert->id, $USER->id); } // Set the custom certificate as viewed. @@ -177,13 +177,13 @@ if (!$downloadown && !$downloadissue) { // Hack alert - don't initiate the download when running Behat. if (defined('BEHAT_SITE_RUNNING')) { - redirect(new moodle_url('/mod/customcert/view.php', array('id' => $cm->id))); + redirect(new moodle_url('/mod/htmlcert/view.php', array('id' => $cm->id))); } \core\session\manager::write_close(); // Now we want to generate the PDF. - $template = new \mod_customcert\template($template); + $template = new \mod_htmlcert\template($template); $template->generate_pdf(false, $userid); exit(); } diff --git a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-debug.js b/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-debug.js deleted file mode 100644 index 72812f3..0000000 --- a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-debug.js +++ /dev/null @@ -1,314 +0,0 @@ -YUI.add('moodle-mod_customcert-rearrange', function (Y, NAME) { - -/** - * Rearrange elements in the custom certificate - * - * @class Y.M.mod_customcert.rearrange - * @constructor - */ -var Rearrange = function() { - Rearrange.superclass.constructor.apply(this, [arguments]); -}; -Y.extend(Rearrange, Y.Base, { - - /** - * The template id. - */ - templateid: 0, - - /** - * The customcert page we are displaying. - */ - page: [], - - /** - * The custom certificate elements to display. - */ - elements: [], - - /** - * Store the X coordinates of the top left of the pdf div. - */ - pdfx: 0, - - /** - * Store the Y coordinates of the top left of the pdf div. - */ - pdfy: 0, - - /** - * Store the width of the pdf div. - */ - pdfwidth: 0, - - /** - * Store the height of the pdf div. - */ - pdfheight: 0, - - /** - * Store the location of the element before we move. - */ - elementxy: 0, - - /** - * Store the left boundary of the pdf div. - */ - pdfleftboundary: 0, - - /** - * Store the right boundary of the pdf div. - */ - pdfrightboundary: 0, - - /** - * The number of pixels in a mm. - */ - pixelsinmm: 3.779527559055, // 3.779528. - - /** - * Initialise. - * - * @param {Array} params - */ - initializer: function(params) { - // Set the course module id. - this.templateid = params[0]; - // Set the page. - this.page = params[1]; - // Set the elements. - this.elements = params[2]; - - // Set the PDF dimensions. - this.setPdfDimensions(); - - // Set the boundaries. - this.setBoundaries(); - - this.setpositions(); - this.createevents(); - window.addEventListener("resize", this.checkWindownResize.bind(this)); - }, - - /** - * Sets the current position of the elements. - */ - setpositions: function() { - // Go through the elements and set their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var posx = this.pdfx + element.posx * this.pixelsinmm; - var posy = this.pdfy + element.posy * this.pixelsinmm; - var nodewidth = parseFloat(Y.one('#element-' + element.id).getComputedStyle('width')); - var maxwidth = element.width * this.pixelsinmm; - - if (maxwidth && (nodewidth > maxwidth)) { - nodewidth = maxwidth; - } - - switch (element.refpoint) { - case '1': // Top-center. - posx -= nodewidth / 2; - break; - case '2': // Top-right. - posx = posx - nodewidth + 2; - break; - } - - Y.one('#element-' + element.id).setX(posx); - Y.one('#element-' + element.id).setY(posy); - } - }, - - /** - * Sets the PDF dimensions. - */ - setPdfDimensions: function() { - this.pdfx = Y.one('#pdf').getX(); - this.pdfy = Y.one('#pdf').getY(); - this.pdfwidth = parseFloat(Y.one('#pdf').getComputedStyle('width')); - this.pdfheight = parseFloat(Y.one('#pdf').getComputedStyle('height')); - }, - - /** - * Sets the boundaries. - */ - setBoundaries: function() { - this.pdfleftboundary = this.pdfx; - if (this.page.leftmargin) { - this.pdfleftboundary += parseInt(this.page.leftmargin * this.pixelsinmm, 10); - } - - this.pdfrightboundary = this.pdfx + this.pdfwidth; - if (this.page.rightmargin) { - this.pdfrightboundary -= parseInt(this.page.rightmargin * this.pixelsinmm, 10); - } - }, - - /** - * Check browser resize and reset position. - */ - checkWindownResize: function() { - this.setPdfDimensions(); - this.setBoundaries(); - this.setpositions(); - }, - - /** - * Creates the JS events for changing element positions. - */ - createevents: function() { - // Trigger a save event when save button is pushed. - Y.one('.savepositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - }, this); - - // Trigger a save event when apply button is pushed. - Y.one('.applypositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - e.preventDefault(); - }, this); - - // Define the container and the elements that are draggable. - var del = new Y.DD.Delegate({ - container: '#pdf', - nodes: '.element' - }); - - // When we start dragging keep track of it's position as we may set it back. - del.on('drag:start', function() { - var node = del.get('currentNode'); - this.elementxy = node.getXY(); - }, this); - - // When we finish the dragging action check that the node is in bounds, - // if not, set it back to where it was. - del.on('drag:end', function() { - var node = del.get('currentNode'); - if (this.isoutofbounds(node)) { - node.setXY(this.elementxy); - } - }, this); - }, - - /** - * Returns true if any part of the element is placed outside of the PDF div, false otherwise. - * - * @param {Node} node - * @returns {boolean} - */ - isoutofbounds: function(node) { - // Get the width and height of the node. - var nodewidth = parseFloat(node.getComputedStyle('width')); - var nodeheight = parseFloat(node.getComputedStyle('height')); - - // Store the positions of each edge of the node. - var left = node.getX(); - var right = left + nodewidth; - var top = node.getY(); - var bottom = top + nodeheight; - - // Check if it is out of bounds horizontally. - if ((left < this.pdfleftboundary) || (right > this.pdfrightboundary)) { - return true; - } - - // Check if it is out of bounds vertically. - if ((top < this.pdfy) || (bottom > (this.pdfy + this.pdfheight))) { - return true; - } - - return false; - }, - - /** - * Perform an AJAX call and save the positions of the elements. - * - * @param {Event} e - */ - savepositions: function(e) { - // The parameters to send the AJAX call. - var params = { - tid: this.templateid, - values: [] - }; - - // Go through the elements and save their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var node = Y.one('#element-' + element.id); - - // Get the current X and Y positions and refpoint for this element. - var posx = node.getX() - this.pdfx; - var posy = node.getY() - this.pdfy; - var refpoint = node.getData('refpoint'); - - var nodewidth = parseFloat(node.getComputedStyle('width')); - - switch (refpoint) { - case '1': // Top-center. - posx += nodewidth / 2; - break; - case '2': // Top-right. - posx += nodewidth; - break; - } - - // Set the parameters to pass to the AJAX request. - params.values.push({ - id: element.id, - posx: Math.round(parseFloat(posx / this.pixelsinmm)), - posy: Math.round(parseFloat(posy / this.pixelsinmm)) - }); - } - - params.values = JSON.stringify(params.values); - - // Save these positions. - Y.io(M.cfg.wwwroot + '/mod/customcert/ajax.php', { - method: 'POST', - data: params, - on: { - failure: function(tid, response) { - this.ajaxfailure(response); - }, - success: function() { - var formnode = e.currentTarget.ancestor('form', true); - var baseurl = formnode.getAttribute('action'); - var pageinput = formnode.one('[name=pid]'); - if (pageinput) { - var pageid = pageinput.get('value'); - window.location = baseurl + '?pid=' + pageid; - } else { - var templateid = formnode.one('[name=tid]').get('value'); - window.location = baseurl + '?tid=' + templateid; - } - } - }, - context: this - }); - - e.preventDefault(); - }, - - /** - * Handles any failures during an AJAX call. - * - * @param {XMLHttpRequest} response - * @returns {M.core.exception} - */ - ajaxfailure: function(response) { - var e = { - name: response.status + ' ' + response.statusText, - message: response.responseText - }; - return new M.core.exception(e); - } -}); - -Y.namespace('M.mod_customcert.rearrange').init = function(templateid, page, elements) { - new Rearrange(templateid, page, elements); -}; - - -}, '@VERSION@', {"requires": ["dd-delegate", "dd-drag"]}); diff --git a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-min.js b/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-min.js deleted file mode 100644 index 993d22e..0000000 --- a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-min.js +++ /dev/null @@ -1 +0,0 @@ -YUI.add("moodle-mod_customcert-rearrange",function(r,t){var s=function(){s.superclass.constructor.apply(this,[arguments])};r.extend(s,r.Base,{templateid:0,page:[],elements:[],pdfx:0,pdfy:0,pdfwidth:0,pdfheight:0,elementxy:0,pdfleftboundary:0,pdfrightboundary:0,pixelsinmm:3.779527559055,initializer:function(t){this.templateid=t[0],this.page=t[1],this.elements=t[2],this.setPdfDimensions(),this.setBoundaries(),this.setpositions(),this.createevents(),window.addEventListener("resize",this.checkWindownResize.bind(this))},setpositions:function(){var t,e,i,s,n,o;for(t in this.elements){switch(e=this.elements[t],i=this.pdfx+e.posx*this.pixelsinmm,s=this.pdfy+e.posy*this.pixelsinmm,n=parseFloat(r.one("#element-"+e.id).getComputedStyle("width")),(o=e.width*this.pixelsinmm)&&othis.pdfrightboundary||(othis.pdfy+this.pdfheight)},savepositions:function(o){var t,e,i,s,n,a,d,p={tid:this.templateid,values:[]};for(t in this.elements){switch(e=this.elements[t],s=(i=r.one("#element-"+e.id)).getX()-this.pdfx,n=i.getY()-this.pdfy,a=i.getData("refpoint"),d=parseFloat(i.getComputedStyle("width")),a){case"1":s+=d/2;break;case"2":s+=d}p.values.push({id:e.id,posx:Math.round(parseFloat(s/this.pixelsinmm)),posy:Math.round(parseFloat(n/this.pixelsinmm))})}p.values=JSON.stringify(p.values),r.io(M.cfg.wwwroot+"/mod/customcert/ajax.php",{method:"POST",data:p,on:{failure:function(t,e){this.ajaxfailure(e)},success:function(){var t,e,i=o.currentTarget.ancestor("form",!0),s=i.getAttribute("action"),n=i.one("[name=pid]");n?(t=n.get("value"),window.location=s+"?pid="+t):(e=i.one("[name=tid]").get("value"),window.location=s+"?tid="+e)}},context:this}),o.preventDefault()},ajaxfailure:function(t){var e={name:t.status+" "+t.statusText,message:t.responseText};return new M.core.exception(e)}}),r.namespace("M.mod_customcert.rearrange").init=function(t,e,i){new s(t,e,i)}},"@VERSION@",{requires:["dd-delegate","dd-drag"]}); \ No newline at end of file diff --git a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange.js b/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange.js deleted file mode 100644 index 72812f3..0000000 --- a/yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange.js +++ /dev/null @@ -1,314 +0,0 @@ -YUI.add('moodle-mod_customcert-rearrange', function (Y, NAME) { - -/** - * Rearrange elements in the custom certificate - * - * @class Y.M.mod_customcert.rearrange - * @constructor - */ -var Rearrange = function() { - Rearrange.superclass.constructor.apply(this, [arguments]); -}; -Y.extend(Rearrange, Y.Base, { - - /** - * The template id. - */ - templateid: 0, - - /** - * The customcert page we are displaying. - */ - page: [], - - /** - * The custom certificate elements to display. - */ - elements: [], - - /** - * Store the X coordinates of the top left of the pdf div. - */ - pdfx: 0, - - /** - * Store the Y coordinates of the top left of the pdf div. - */ - pdfy: 0, - - /** - * Store the width of the pdf div. - */ - pdfwidth: 0, - - /** - * Store the height of the pdf div. - */ - pdfheight: 0, - - /** - * Store the location of the element before we move. - */ - elementxy: 0, - - /** - * Store the left boundary of the pdf div. - */ - pdfleftboundary: 0, - - /** - * Store the right boundary of the pdf div. - */ - pdfrightboundary: 0, - - /** - * The number of pixels in a mm. - */ - pixelsinmm: 3.779527559055, // 3.779528. - - /** - * Initialise. - * - * @param {Array} params - */ - initializer: function(params) { - // Set the course module id. - this.templateid = params[0]; - // Set the page. - this.page = params[1]; - // Set the elements. - this.elements = params[2]; - - // Set the PDF dimensions. - this.setPdfDimensions(); - - // Set the boundaries. - this.setBoundaries(); - - this.setpositions(); - this.createevents(); - window.addEventListener("resize", this.checkWindownResize.bind(this)); - }, - - /** - * Sets the current position of the elements. - */ - setpositions: function() { - // Go through the elements and set their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var posx = this.pdfx + element.posx * this.pixelsinmm; - var posy = this.pdfy + element.posy * this.pixelsinmm; - var nodewidth = parseFloat(Y.one('#element-' + element.id).getComputedStyle('width')); - var maxwidth = element.width * this.pixelsinmm; - - if (maxwidth && (nodewidth > maxwidth)) { - nodewidth = maxwidth; - } - - switch (element.refpoint) { - case '1': // Top-center. - posx -= nodewidth / 2; - break; - case '2': // Top-right. - posx = posx - nodewidth + 2; - break; - } - - Y.one('#element-' + element.id).setX(posx); - Y.one('#element-' + element.id).setY(posy); - } - }, - - /** - * Sets the PDF dimensions. - */ - setPdfDimensions: function() { - this.pdfx = Y.one('#pdf').getX(); - this.pdfy = Y.one('#pdf').getY(); - this.pdfwidth = parseFloat(Y.one('#pdf').getComputedStyle('width')); - this.pdfheight = parseFloat(Y.one('#pdf').getComputedStyle('height')); - }, - - /** - * Sets the boundaries. - */ - setBoundaries: function() { - this.pdfleftboundary = this.pdfx; - if (this.page.leftmargin) { - this.pdfleftboundary += parseInt(this.page.leftmargin * this.pixelsinmm, 10); - } - - this.pdfrightboundary = this.pdfx + this.pdfwidth; - if (this.page.rightmargin) { - this.pdfrightboundary -= parseInt(this.page.rightmargin * this.pixelsinmm, 10); - } - }, - - /** - * Check browser resize and reset position. - */ - checkWindownResize: function() { - this.setPdfDimensions(); - this.setBoundaries(); - this.setpositions(); - }, - - /** - * Creates the JS events for changing element positions. - */ - createevents: function() { - // Trigger a save event when save button is pushed. - Y.one('.savepositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - }, this); - - // Trigger a save event when apply button is pushed. - Y.one('.applypositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - e.preventDefault(); - }, this); - - // Define the container and the elements that are draggable. - var del = new Y.DD.Delegate({ - container: '#pdf', - nodes: '.element' - }); - - // When we start dragging keep track of it's position as we may set it back. - del.on('drag:start', function() { - var node = del.get('currentNode'); - this.elementxy = node.getXY(); - }, this); - - // When we finish the dragging action check that the node is in bounds, - // if not, set it back to where it was. - del.on('drag:end', function() { - var node = del.get('currentNode'); - if (this.isoutofbounds(node)) { - node.setXY(this.elementxy); - } - }, this); - }, - - /** - * Returns true if any part of the element is placed outside of the PDF div, false otherwise. - * - * @param {Node} node - * @returns {boolean} - */ - isoutofbounds: function(node) { - // Get the width and height of the node. - var nodewidth = parseFloat(node.getComputedStyle('width')); - var nodeheight = parseFloat(node.getComputedStyle('height')); - - // Store the positions of each edge of the node. - var left = node.getX(); - var right = left + nodewidth; - var top = node.getY(); - var bottom = top + nodeheight; - - // Check if it is out of bounds horizontally. - if ((left < this.pdfleftboundary) || (right > this.pdfrightboundary)) { - return true; - } - - // Check if it is out of bounds vertically. - if ((top < this.pdfy) || (bottom > (this.pdfy + this.pdfheight))) { - return true; - } - - return false; - }, - - /** - * Perform an AJAX call and save the positions of the elements. - * - * @param {Event} e - */ - savepositions: function(e) { - // The parameters to send the AJAX call. - var params = { - tid: this.templateid, - values: [] - }; - - // Go through the elements and save their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var node = Y.one('#element-' + element.id); - - // Get the current X and Y positions and refpoint for this element. - var posx = node.getX() - this.pdfx; - var posy = node.getY() - this.pdfy; - var refpoint = node.getData('refpoint'); - - var nodewidth = parseFloat(node.getComputedStyle('width')); - - switch (refpoint) { - case '1': // Top-center. - posx += nodewidth / 2; - break; - case '2': // Top-right. - posx += nodewidth; - break; - } - - // Set the parameters to pass to the AJAX request. - params.values.push({ - id: element.id, - posx: Math.round(parseFloat(posx / this.pixelsinmm)), - posy: Math.round(parseFloat(posy / this.pixelsinmm)) - }); - } - - params.values = JSON.stringify(params.values); - - // Save these positions. - Y.io(M.cfg.wwwroot + '/mod/customcert/ajax.php', { - method: 'POST', - data: params, - on: { - failure: function(tid, response) { - this.ajaxfailure(response); - }, - success: function() { - var formnode = e.currentTarget.ancestor('form', true); - var baseurl = formnode.getAttribute('action'); - var pageinput = formnode.one('[name=pid]'); - if (pageinput) { - var pageid = pageinput.get('value'); - window.location = baseurl + '?pid=' + pageid; - } else { - var templateid = formnode.one('[name=tid]').get('value'); - window.location = baseurl + '?tid=' + templateid; - } - } - }, - context: this - }); - - e.preventDefault(); - }, - - /** - * Handles any failures during an AJAX call. - * - * @param {XMLHttpRequest} response - * @returns {M.core.exception} - */ - ajaxfailure: function(response) { - var e = { - name: response.status + ' ' + response.statusText, - message: response.responseText - }; - return new M.core.exception(e); - } -}); - -Y.namespace('M.mod_customcert.rearrange').init = function(templateid, page, elements) { - new Rearrange(templateid, page, elements); -}; - - -}, '@VERSION@', {"requires": ["dd-delegate", "dd-drag"]}); diff --git a/yui/src/rearrange/build.json b/yui/src/rearrange/build.json deleted file mode 100644 index 246cfbb..0000000 --- a/yui/src/rearrange/build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "moodle-mod_customcert-rearrange", - "builds": { - "moodle-mod_customcert-rearrange": { - "jsfiles": [ - "rearrange.js" - ] - } - } -} diff --git a/yui/src/rearrange/js/rearrange.js b/yui/src/rearrange/js/rearrange.js deleted file mode 100644 index 127c7cc..0000000 --- a/yui/src/rearrange/js/rearrange.js +++ /dev/null @@ -1,309 +0,0 @@ -/** - * Rearrange elements in the custom certificate - * - * @class Y.M.mod_customcert.rearrange - * @constructor - */ -var Rearrange = function() { - Rearrange.superclass.constructor.apply(this, [arguments]); -}; -Y.extend(Rearrange, Y.Base, { - - /** - * The template id. - */ - templateid: 0, - - /** - * The customcert page we are displaying. - */ - page: [], - - /** - * The custom certificate elements to display. - */ - elements: [], - - /** - * Store the X coordinates of the top left of the pdf div. - */ - pdfx: 0, - - /** - * Store the Y coordinates of the top left of the pdf div. - */ - pdfy: 0, - - /** - * Store the width of the pdf div. - */ - pdfwidth: 0, - - /** - * Store the height of the pdf div. - */ - pdfheight: 0, - - /** - * Store the location of the element before we move. - */ - elementxy: 0, - - /** - * Store the left boundary of the pdf div. - */ - pdfleftboundary: 0, - - /** - * Store the right boundary of the pdf div. - */ - pdfrightboundary: 0, - - /** - * The number of pixels in a mm. - */ - pixelsinmm: 3.779527559055, // 3.779528. - - /** - * Initialise. - * - * @param {Array} params - */ - initializer: function(params) { - // Set the course module id. - this.templateid = params[0]; - // Set the page. - this.page = params[1]; - // Set the elements. - this.elements = params[2]; - - // Set the PDF dimensions. - this.setPdfDimensions(); - - // Set the boundaries. - this.setBoundaries(); - - this.setpositions(); - this.createevents(); - window.addEventListener("resize", this.checkWindownResize.bind(this)); - }, - - /** - * Sets the current position of the elements. - */ - setpositions: function() { - // Go through the elements and set their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var posx = this.pdfx + element.posx * this.pixelsinmm; - var posy = this.pdfy + element.posy * this.pixelsinmm; - var nodewidth = parseFloat(Y.one('#element-' + element.id).getComputedStyle('width')); - var maxwidth = element.width * this.pixelsinmm; - - if (maxwidth && (nodewidth > maxwidth)) { - nodewidth = maxwidth; - } - - switch (element.refpoint) { - case '1': // Top-center. - posx -= nodewidth / 2; - break; - case '2': // Top-right. - posx = posx - nodewidth + 2; - break; - } - - Y.one('#element-' + element.id).setX(posx); - Y.one('#element-' + element.id).setY(posy); - } - }, - - /** - * Sets the PDF dimensions. - */ - setPdfDimensions: function() { - this.pdfx = Y.one('#pdf').getX(); - this.pdfy = Y.one('#pdf').getY(); - this.pdfwidth = parseFloat(Y.one('#pdf').getComputedStyle('width')); - this.pdfheight = parseFloat(Y.one('#pdf').getComputedStyle('height')); - }, - - /** - * Sets the boundaries. - */ - setBoundaries: function() { - this.pdfleftboundary = this.pdfx; - if (this.page.leftmargin) { - this.pdfleftboundary += parseInt(this.page.leftmargin * this.pixelsinmm, 10); - } - - this.pdfrightboundary = this.pdfx + this.pdfwidth; - if (this.page.rightmargin) { - this.pdfrightboundary -= parseInt(this.page.rightmargin * this.pixelsinmm, 10); - } - }, - - /** - * Check browser resize and reset position. - */ - checkWindownResize: function() { - this.setPdfDimensions(); - this.setBoundaries(); - this.setpositions(); - }, - - /** - * Creates the JS events for changing element positions. - */ - createevents: function() { - // Trigger a save event when save button is pushed. - Y.one('.savepositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - }, this); - - // Trigger a save event when apply button is pushed. - Y.one('.applypositionsbtn [type=submit]').on('click', function(e) { - this.savepositions(e); - e.preventDefault(); - }, this); - - // Define the container and the elements that are draggable. - var del = new Y.DD.Delegate({ - container: '#pdf', - nodes: '.element' - }); - - // When we start dragging keep track of it's position as we may set it back. - del.on('drag:start', function() { - var node = del.get('currentNode'); - this.elementxy = node.getXY(); - }, this); - - // When we finish the dragging action check that the node is in bounds, - // if not, set it back to where it was. - del.on('drag:end', function() { - var node = del.get('currentNode'); - if (this.isoutofbounds(node)) { - node.setXY(this.elementxy); - } - }, this); - }, - - /** - * Returns true if any part of the element is placed outside of the PDF div, false otherwise. - * - * @param {Node} node - * @returns {boolean} - */ - isoutofbounds: function(node) { - // Get the width and height of the node. - var nodewidth = parseFloat(node.getComputedStyle('width')); - var nodeheight = parseFloat(node.getComputedStyle('height')); - - // Store the positions of each edge of the node. - var left = node.getX(); - var right = left + nodewidth; - var top = node.getY(); - var bottom = top + nodeheight; - - // Check if it is out of bounds horizontally. - if ((left < this.pdfleftboundary) || (right > this.pdfrightboundary)) { - return true; - } - - // Check if it is out of bounds vertically. - if ((top < this.pdfy) || (bottom > (this.pdfy + this.pdfheight))) { - return true; - } - - return false; - }, - - /** - * Perform an AJAX call and save the positions of the elements. - * - * @param {Event} e - */ - savepositions: function(e) { - // The parameters to send the AJAX call. - var params = { - tid: this.templateid, - values: [] - }; - - // Go through the elements and save their positions. - for (var key in this.elements) { - var element = this.elements[key]; - var node = Y.one('#element-' + element.id); - - // Get the current X and Y positions and refpoint for this element. - var posx = node.getX() - this.pdfx; - var posy = node.getY() - this.pdfy; - var refpoint = node.getData('refpoint'); - - var nodewidth = parseFloat(node.getComputedStyle('width')); - - switch (refpoint) { - case '1': // Top-center. - posx += nodewidth / 2; - break; - case '2': // Top-right. - posx += nodewidth; - break; - } - - // Set the parameters to pass to the AJAX request. - params.values.push({ - id: element.id, - posx: Math.round(parseFloat(posx / this.pixelsinmm)), - posy: Math.round(parseFloat(posy / this.pixelsinmm)) - }); - } - - params.values = JSON.stringify(params.values); - - // Save these positions. - Y.io(M.cfg.wwwroot + '/mod/customcert/ajax.php', { - method: 'POST', - data: params, - on: { - failure: function(tid, response) { - this.ajaxfailure(response); - }, - success: function() { - var formnode = e.currentTarget.ancestor('form', true); - var baseurl = formnode.getAttribute('action'); - var pageinput = formnode.one('[name=pid]'); - if (pageinput) { - var pageid = pageinput.get('value'); - window.location = baseurl + '?pid=' + pageid; - } else { - var templateid = formnode.one('[name=tid]').get('value'); - window.location = baseurl + '?tid=' + templateid; - } - } - }, - context: this - }); - - e.preventDefault(); - }, - - /** - * Handles any failures during an AJAX call. - * - * @param {XMLHttpRequest} response - * @returns {M.core.exception} - */ - ajaxfailure: function(response) { - var e = { - name: response.status + ' ' + response.statusText, - message: response.responseText - }; - return new M.core.exception(e); - } -}); - -Y.namespace('M.mod_customcert.rearrange').init = function(templateid, page, elements) { - new Rearrange(templateid, page, elements); -}; diff --git a/yui/src/rearrange/meta/rearrange.json b/yui/src/rearrange/meta/rearrange.json deleted file mode 100644 index 7bd9ba7..0000000 --- a/yui/src/rearrange/meta/rearrange.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "moodle-mod_customcert-rearrange": { - "requires": [ - "dd-delegate", - "dd-drag" - ] - } -}