├── mobile ├── styles.css └── pluginfile.php ├── pix ├── icon.gif ├── icon.png ├── target.gif ├── download.png └── download.svg ├── db ├── subplugins.json ├── tasks.php ├── log.php ├── services.php └── mobile.php ├── yui ├── src │ └── rearrange │ │ ├── meta │ │ └── rearrange.json │ │ └── build.json └── build │ └── moodle-mod_customcert-rearrange │ └── moodle-mod_customcert-rearrange-min.js ├── composer.json ├── amd ├── build │ ├── dialogue.min.js │ └── rearrange-area.min.js └── src │ └── dialogue.js ├── element ├── code │ ├── lang │ │ └── en │ │ │ └── customcertelement_code.php │ ├── version.php │ └── classes │ │ ├── privacy │ │ └── provider.php │ │ └── element.php ├── bgimage │ ├── lang │ │ └── en │ │ │ └── customcertelement_bgimage.php │ ├── version.php │ ├── classes │ │ └── privacy │ │ │ └── provider.php │ └── db │ │ └── upgrade.php ├── coursename │ ├── lang │ │ └── en │ │ │ └── customcertelement_coursename.php │ ├── version.php │ └── classes │ │ ├── privacy │ │ └── provider.php │ │ └── element.php ├── studentname │ ├── lang │ │ └── en │ │ │ └── customcertelement_studentname.php │ ├── version.php │ └── classes │ │ ├── privacy │ │ └── provider.php │ │ └── element.php ├── categoryname │ ├── lang │ │ └── en │ │ │ └── customcertelement_categoryname.php │ ├── version.php │ └── classes │ │ ├── privacy │ │ └── provider.php │ │ └── element.php ├── text │ ├── lang │ │ └── en │ │ │ └── customcertelement_text.php │ ├── version.php │ └── classes │ │ ├── privacy │ │ └── provider.php │ │ └── element.php ├── date │ ├── version.php │ ├── classes │ │ └── privacy │ │ │ └── provider.php │ └── lang │ │ └── en │ │ └── customcertelement_date.php ├── teachername │ ├── lang │ │ └── en │ │ │ └── customcertelement_teachername.php │ ├── version.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── grade │ ├── version.php │ ├── lang │ │ └── en │ │ │ └── customcertelement_grade.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── image │ ├── version.php │ ├── classes │ │ └── privacy │ │ │ └── provider.php │ ├── lang │ │ └── en │ │ │ └── customcertelement_image.php │ └── db │ │ └── upgrade.php ├── qrcode │ ├── lang │ │ └── en │ │ │ └── customcertelement_qrcode.php │ ├── version.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── userfield │ ├── lang │ │ └── en │ │ │ └── customcertelement_userfield.php │ ├── version.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── border │ ├── version.php │ ├── lang │ │ └── en │ │ │ └── customcertelement_border.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── daterange │ ├── version.php │ ├── tests │ │ └── fixtures │ │ │ └── fake_datarange_element.php │ ├── classes │ │ └── privacy │ │ │ └── provider.php │ └── lang │ │ └── en │ │ └── customcertelement_daterange.php ├── userpicture │ ├── version.php │ ├── lang │ │ └── en │ │ │ └── customcertelement_userpicture.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── gradeitemname │ ├── lang │ │ └── en │ │ │ └── customcertelement_gradeitemname.php │ ├── version.php │ └── classes │ │ └── privacy │ │ └── provider.php ├── coursefield │ ├── lang │ │ └── en │ │ │ └── customcertelement_coursefield.php │ ├── version.php │ └── classes │ │ └── privacy │ │ └── provider.php └── digitalsignature │ ├── version.php │ ├── lang │ └── en │ │ └── customcertelement_digitalsignature.php │ └── classes │ └── privacy │ └── provider.php ├── classes ├── search │ └── activity.php ├── event │ ├── course_module_instance_list_viewed.php │ └── course_module_viewed.php ├── output │ ├── email │ │ ├── renderer.php │ │ └── renderer_textemail.php │ ├── renderer.php │ ├── verify_certificate_results.php │ └── verify_certificate_result.php ├── verify_certificate_form.php ├── page_helper.php ├── upload_image_form.php ├── element_factory.php ├── admin_setting_link.php ├── plugininfo │ └── customcertelement.php ├── load_template_form.php ├── grade_information.php └── edit_element_form.php ├── templates ├── verify_certificate_results.mustache ├── email_certificate_text.mustache ├── email_certificate_html.mustache └── verify_certificate_result.mustache ├── .travis.yml ├── report.php ├── version.php ├── README.md ├── tests ├── behat │ ├── my_certificates.feature │ ├── required_minutes.feature │ ├── managing_pages.feature │ ├── show_position_x_y.feature │ └── view_issued_certificates.feature └── generator │ └── lib.php ├── ajax.php ├── upload_image.php ├── styles.css ├── backup └── moodle2 │ └── backup_customcert_activity_task.class.php ├── includes └── colourpicker.php └── my_certificates.php /mobile/styles.css: -------------------------------------------------------------------------------- 1 | .timerewarded { 2 | font-size: 14px; 3 | } 4 | -------------------------------------------------------------------------------- /pix/icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinaglancy/moodle-mod_customcert/MOODLE_310_STABLE/pix/icon.gif -------------------------------------------------------------------------------- /pix/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinaglancy/moodle-mod_customcert/MOODLE_310_STABLE/pix/icon.png -------------------------------------------------------------------------------- /pix/target.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinaglancy/moodle-mod_customcert/MOODLE_310_STABLE/pix/target.gif -------------------------------------------------------------------------------- /pix/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marinaglancy/moodle-mod_customcert/MOODLE_310_STABLE/pix/download.png -------------------------------------------------------------------------------- /db/subplugins.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugintypes": { 3 | "customcertelement": "mod\/customcert\/element" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /yui/src/rearrange/meta/rearrange.json: -------------------------------------------------------------------------------- 1 | { 2 | "moodle-mod_customcert-rearrange": { 3 | "requires": [ 4 | "dd-delegate", 5 | "dd-drag" 6 | ] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /yui/src/rearrange/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moodle-mod_customcert-rearrange", 3 | "builds": { 4 | "moodle-mod_customcert-rearrange": { 5 | "jsfiles": [ 6 | "rearrange.js" 7 | ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mdjnelson/moodle-mod_customcert", 3 | "type": "moodle-mod", 4 | "require": { 5 | "composer/installers": "~1.0" 6 | }, 7 | "extra": { 8 | "installer-name": "customcert" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /pix/download.svg: -------------------------------------------------------------------------------- 1 | 3 | ]> -------------------------------------------------------------------------------- /amd/build/dialogue.min.js: -------------------------------------------------------------------------------- 1 | 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}); 2 | //# sourceMappingURL=dialogue.min.js.map 3 | -------------------------------------------------------------------------------- /element/code/lang/en/customcertelement_code.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_code', language 'en'. 19 | * 20 | * @package customcertelement_code 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Code'; 26 | $string['privacy:metadata'] = 'The Code plugin does not store any personal data.'; 27 | -------------------------------------------------------------------------------- /element/bgimage/lang/en/customcertelement_bgimage.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_bgimage', language 'en'. 19 | * 20 | * @package customcertelement_bgimage 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Background image'; 26 | $string['privacy:metadata'] = 'The Background image plugin does not store any personal data.'; 27 | -------------------------------------------------------------------------------- /element/coursename/lang/en/customcertelement_coursename.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_coursename', language 'en'. 19 | * 20 | * @package customcertelement_coursename 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Course name'; 26 | $string['privacy:metadata'] = 'The Course name plugin does not store any personal data.'; 27 | -------------------------------------------------------------------------------- /element/studentname/lang/en/customcertelement_studentname.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_studentname', language 'en'. 19 | * 20 | * @package customcertelement_studentname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Student name'; 26 | $string['privacy:metadata'] = 'The Student name plugin does not store any personal data.'; 27 | -------------------------------------------------------------------------------- /element/categoryname/lang/en/customcertelement_categoryname.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_categoryname', language 'en'. 19 | * 20 | * @package customcertelement_categoryname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Category name'; 26 | $string['privacy:metadata'] = 'The Category name plugin does not store any personal data.'; 27 | -------------------------------------------------------------------------------- /element/text/lang/en/customcertelement_text.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_text', language 'en'. 19 | * 20 | * @package customcertelement_text 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Text'; 26 | $string['privacy:metadata'] = 'The Text plugin does not store any personal data.'; 27 | $string['text'] = 'Text'; 28 | $string['text_help'] = 'This is the text that will display on the PDF.'; 29 | -------------------------------------------------------------------------------- /db/tasks.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Definition of customcert scheduled tasks. 19 | * 20 | * @package mod_customcert 21 | * @category task 22 | * @copyright 2017 Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | $tasks = array( 29 | array( 30 | 'classname' => 'mod_customcert\task\email_certificate_task', 31 | 'blocking' => 0, 32 | 'minute' => '*', 33 | 'hour' => '*', 34 | 'day' => '*', 35 | 'month' => '*', 36 | 'dayofweek' => '*' 37 | ) 38 | ); 39 | -------------------------------------------------------------------------------- /element/code/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the code plugin. 19 | * 20 | * @package customcertelement_code 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_code'; 30 | -------------------------------------------------------------------------------- /element/date/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the date plugin. 19 | * 20 | * @package customcertelement_date 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_date'; 30 | -------------------------------------------------------------------------------- /element/teachername/lang/en/customcertelement_teachername.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_teachername', language 'en'. 19 | * 20 | * @package customcertelement_teachername 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Teacher name'; 26 | $string['privacy:metadata'] = 'The Teacher name plugin does not store any personal data.'; 27 | $string['teacher'] = 'Teacher'; 28 | $string['teacher_help'] = 'This is the teacher name that will be displayed.'; 29 | -------------------------------------------------------------------------------- /element/text/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the text plugin. 19 | * 20 | * @package customcertelement_text 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_text'; 30 | -------------------------------------------------------------------------------- /element/grade/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the grade plugin. 19 | * 20 | * @package customcertelement_grade 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_grade'; 30 | -------------------------------------------------------------------------------- /element/image/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the image plugin. 19 | * 20 | * @package customcertelement_image 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_image'; 30 | -------------------------------------------------------------------------------- /element/qrcode/lang/en/customcertelement_qrcode.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_qrcode', language 'en'. 19 | * 20 | * @package customcertelement_qrcode 21 | * @copyright 2019 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['height'] = 'Height'; 26 | $string['height_help'] = 'Height help'; 27 | $string['pluginname'] = 'QR code'; 28 | $string['privacy:metadata'] = 'The QR code plugin does not store any personal data.'; 29 | $string['width'] = 'Width'; 30 | $string['width_help'] = 'width help'; 31 | -------------------------------------------------------------------------------- /element/userfield/lang/en/customcertelement_userfield.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_userfield', language 'en'. 19 | * 20 | * @package customcertelement_userfield 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'User field'; 26 | $string['privacy:metadata'] = 'The User field plugin does not store any personal data.'; 27 | $string['userfield'] = 'User field'; 28 | $string['userfield_help'] = 'This is the user field that will be displayed on the PDF.'; 29 | -------------------------------------------------------------------------------- /element/border/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the border plugin. 19 | * 20 | * @package customcertelement_border 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_border'; 30 | -------------------------------------------------------------------------------- /element/qrcode/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the QR code plugin. 19 | * 20 | * @package customcertelement_qrcode 21 | * @copyright 2019 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_qrcode'; 30 | -------------------------------------------------------------------------------- /element/bgimage/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the background image plugin. 19 | * 20 | * @package customcertelement_bgimage 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_bgimage'; 30 | -------------------------------------------------------------------------------- /element/userfield/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the userfield plugin. 19 | * 20 | * @package customcertelement_userfield 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_userfield'; 30 | -------------------------------------------------------------------------------- /element/border/lang/en/customcertelement_border.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_border', language 'en'. 19 | * 20 | * @package customcertelement_border 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['pluginname'] = 'Border'; 26 | $string['privacy:metadata'] = 'The Border plugin does not store any personal data.'; 27 | $string['invalidwidth'] = 'The width has to be a valid number greater than 0.'; 28 | $string['width'] = 'Width'; 29 | $string['width_help'] = 'Width of the border in mm.'; 30 | -------------------------------------------------------------------------------- /element/coursename/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the coursename plugin. 19 | * 20 | * @package customcertelement_coursename 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_coursename'; 30 | -------------------------------------------------------------------------------- /element/categoryname/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the categoryname plugin. 19 | * 20 | * @package customcertelement_categoryname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_categoryname'; 30 | -------------------------------------------------------------------------------- /element/daterange/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the date plugin. 19 | * 20 | * @package customcertelement_daterange 21 | * @copyright 2018 Dmitrii Metelkin 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_daterange'; 30 | -------------------------------------------------------------------------------- /element/studentname/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the studentname plugin. 19 | * 20 | * @package customcertelement_studentname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_studentname'; 30 | -------------------------------------------------------------------------------- /element/teachername/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the teachername plugin. 19 | * 20 | * @package customcertelement_teachername 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_teachername'; 30 | -------------------------------------------------------------------------------- /element/userpicture/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the userpicture plugin. 19 | * 20 | * @package customcertelement_userpicture 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_userpicture'; 30 | -------------------------------------------------------------------------------- /element/gradeitemname/lang/en/customcertelement_gradeitemname.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_gradeitemname', language 'en'. 19 | * 20 | * @package customcertelement_gradeitemname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['gradeitem'] = 'Grade item'; 26 | $string['gradeitem_help'] = 'The name of the selected item will be displayed on the PDF.'; 27 | $string['pluginname'] = 'Grade item name'; 28 | $string['privacy:metadata'] = 'The Grade item name plugin does not store any personal data.'; 29 | -------------------------------------------------------------------------------- /element/gradeitemname/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the gradeitemname plugin. 19 | * 20 | * @package customcertelement_gradeitemname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_gradeitemname'; 30 | -------------------------------------------------------------------------------- /element/coursefield/lang/en/customcertelement_coursefield.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_coursefield', language 'en'. 19 | * 20 | * @package customcertelement_coursefield 21 | * @copyright 2019 Catalyst IT 22 | * @author Dan Marsden 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | $string['pluginname'] = 'Course field'; 27 | $string['privacy:metadata'] = 'The course field plugin does not store any personal data.'; 28 | $string['coursefield'] = 'Course field'; 29 | $string['coursefield_help'] = 'This is the course field that will be displayed on the PDF.'; 30 | -------------------------------------------------------------------------------- /element/coursefield/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the coursefield plugin. 19 | * 20 | * @package customcertelement_coursefield 21 | * @copyright 2019 Catalyst IT 22 | * @author Dan Marsden 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 27 | 28 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 29 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 30 | $plugin->component = 'customcertelement_coursefield'; 31 | -------------------------------------------------------------------------------- /element/digitalsignature/version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the version information for the digital signature plugin. 19 | * 20 | * @package customcertelement_digitalsignature 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->component = 'customcertelement_digitalsignature'; 30 | -------------------------------------------------------------------------------- /classes/search/activity.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Search area for mod_customcert activities. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\search; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Search area for mod_customcert activities. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2016 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class activity extends \core_search\base_activity { 37 | 38 | } 39 | -------------------------------------------------------------------------------- /templates/verify_certificate_results.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template mod_customcert/verify_certificate_results 19 | 20 | The certificate verification results page 21 | 22 | Classes required for JS: 23 | * None 24 | 25 | Data attibutes required for JS: 26 | * All data attributes are required 27 | 28 | Context variables required for this template: 29 | * None 30 | 31 | Example context (json): 32 | { 33 | } 34 | }} 35 | {{#success}} 36 | {{#issues}} 37 | {{> mod_customcert/verify_certificate_result }} 38 | {{/issues}} 39 | {{> core/notification_success}} 40 | {{/success}} 41 | {{^success}} 42 | {{> core/notification_error}} 43 | {{/success}} 44 | -------------------------------------------------------------------------------- /classes/event/course_module_instance_list_viewed.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains the course module instance list viewed event class. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\event; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The course module instance list viewed event class. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { 37 | } 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | # For javascript behat tests we need sudo. 4 | sudo: true 5 | 6 | cache: 7 | directories: 8 | - $HOME/.composer/cache 9 | - $HOME/.npm 10 | 11 | php: 12 | - 7.2 13 | - 7.4 14 | 15 | addons: 16 | firefox: 47.0.1 17 | postgresql: "9.6" 18 | apt: 19 | packages: 20 | - openjdk-8-jre-headless 21 | 22 | services: 23 | - mysql 24 | - postgresql 25 | 26 | env: 27 | global: 28 | - MOODLE_BRANCH=MOODLE_310_STABLE 29 | - IGNORE_NAMES=mobile_*.mustache # Mobile mustache has specific syntax, ignore their templates 30 | matrix: 31 | - DB=pgsql 32 | - DB=mysqli 33 | 34 | before_install: 35 | - phpenv config-rm xdebug.ini 36 | - cd ../.. 37 | - composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3 38 | - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" 39 | 40 | install: 41 | - moodle-plugin-ci install 42 | 43 | script: 44 | - moodle-plugin-ci phplint 45 | # - moodle-plugin-ci phpcpd # subplugins often have similar code and cause "duplicated code" errors 46 | # - moodle-plugin-ci phpmd # too much noise from this check, maybe, some day... 47 | - moodle-plugin-ci codechecker 48 | - moodle-plugin-ci validate 49 | - moodle-plugin-ci savepoints 50 | - moodle-plugin-ci mustache 51 | - moodle-plugin-ci grunt 52 | # - moodle-plugin-ci phpdoc # Complains about missing PHPDocs when they exist in parent class. 53 | - moodle-plugin-ci phpunit 54 | - moodle-plugin-ci behat 55 | -------------------------------------------------------------------------------- /db/log.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Definition of log events 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $logs = array( 28 | array('module' => 'customcert', 'action' => 'view', 'mtable' => 'customcert', 'field' => 'name'), 29 | array('module' => 'customcert', 'action' => 'add', 'mtable' => 'customcert', 'field' => 'name'), 30 | array('module' => 'customcert', 'action' => 'update', 'mtable' => 'customcert', 'field' => 'name'), 31 | array('module' => 'customcert', 'action' => 'received', 'mtable' => 'customcert', 'field' => 'name'), 32 | ); 33 | -------------------------------------------------------------------------------- /report.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Handles viewing a report that shows who has received a customcert. 19 | * 20 | * This is now just a stub page - all logic has been moved to view.php. 21 | * 22 | * @package mod_customcert 23 | * @copyright 2013 Mark Nelson 24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 | */ 26 | 27 | require_once('../../config.php'); 28 | 29 | $id = required_param('id', PARAM_INT); 30 | 31 | $cm = get_coursemodule_from_id('customcert', $id, 0, false, MUST_EXIST); 32 | $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); 33 | 34 | require_login($course, false, $cm); 35 | 36 | redirect(new moodle_url('/mod/customcert/view.php', ['id' => $id])); 37 | -------------------------------------------------------------------------------- /version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Code fragment to define the version of the customcert module 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $plugin->version = 2020110900; // The current module version (Date: YYYYMMDDXX). 28 | $plugin->requires = 2020110900; // Requires this Moodle version (3.10). 29 | $plugin->cron = 0; // Period for cron to check this module (secs). 30 | $plugin->component = 'mod_customcert'; 31 | 32 | $plugin->maturity = MATURITY_STABLE; 33 | $plugin->release = "3.10.0"; // User-friendly version number. 34 | -------------------------------------------------------------------------------- /classes/output/email/renderer.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Email certificate as html renderer. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\output\email; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Email certificate as html renderer. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class renderer extends \mod_customcert\output\renderer { 37 | 38 | /** 39 | * The template name for this renderer. 40 | * 41 | * @return string 42 | */ 43 | public function get_template_name() { 44 | return 'email_certificate_html'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /classes/output/email/renderer_textemail.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Email certificate as text renderer. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\output\email; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Email certificate as text renderer. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class renderer_textemail extends \mod_customcert\output\renderer { 37 | 38 | /** 39 | * The template name for this renderer. 40 | * 41 | * @return string 42 | */ 43 | public function get_template_name() { 44 | return 'email_certificate_text'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /templates/email_certificate_text.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template mod_customcert/email_certificate_text 19 | 20 | The certificate verification result 21 | 22 | Classes required for JS: 23 | * None 24 | 25 | Data attibutes required for JS: 26 | * All data attributes are required 27 | 28 | Context variables required for this template: 29 | * emailgreeting 30 | * emailbodyplaintext 31 | * emailcertificatelink 32 | * emailcertificatelinktext 33 | 34 | Example context (json): 35 | { 36 | "emailgreeting": "Dear Angus MacGyver", 37 | "emailbodyplaintext": "Attached is your certificate 'The basics' for the course 'Survival as an '80s action hero'", 38 | "emailcertificatelink": "http://yoursite.com/mod/customcert/view.php?id=4", 39 | "emailcertificatelinktext": "Certificate report" 40 | } 41 | }} 42 | {{{emailgreeting}}} 43 | 44 | {{{emailbodyplaintext}}} 45 | -------------------------------------------------------------------------------- /element/digitalsignature/lang/en/customcertelement_digitalsignature.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_digitalsignature', language 'en'. 19 | * 20 | * @package customcertelement_digitalsignature 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['digitalsignature'] = 'Digital signature'; 26 | $string['nosignature'] = 'No signature'; 27 | $string['pluginname'] = 'Digital signature'; 28 | $string['privacy:metadata'] = 'The Digital signature plugin does not store any personal data.'; 29 | $string['signaturename'] = 'Signature name'; 30 | $string['signaturepassword'] = 'Signature password'; 31 | $string['signaturelocation'] = 'Signature location'; 32 | $string['signaturereason'] = 'Signature reason'; 33 | $string['signaturecontactinfo'] = 'Signature contact info'; 34 | $string['uploaddigitalsignature'] = 'Upload digital signature'; 35 | -------------------------------------------------------------------------------- /element/userpicture/lang/en/customcertelement_userpicture.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_userpicture', language 'en'. 19 | * 20 | * @package customcertelement_userpicture 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['height'] = 'Height'; 26 | $string['height_help'] = 'Height of the image in mm. If equal to zero, it is automatically calculated.'; 27 | $string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.'; 28 | $string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.'; 29 | $string['pluginname'] = 'User picture'; 30 | $string['privacy:metadata'] = 'The User picture plugin does not store any personal data.'; 31 | $string['width'] = 'Width'; 32 | $string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.'; 33 | -------------------------------------------------------------------------------- /element/grade/lang/en/customcertelement_grade.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_grade', language 'en'. 19 | * 20 | * @package customcertelement_grade 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['coursegrade'] = 'Course grade'; 26 | $string['gradeitem'] = 'Grade item'; 27 | $string['gradeitem_help'] = 'The grade item you wish to display the grade of.'; 28 | $string['gradeformat'] = 'Grade format'; 29 | $string['gradeformat_help'] = 'The format you wish to use when displaying the grade.'; 30 | $string['gradeitem'] = 'Grade item'; 31 | $string['gradepercent'] = 'Percentage'; 32 | $string['gradepoints'] = 'Points'; 33 | $string['gradeletter'] = 'Letter'; 34 | $string['pluginname'] = 'Grade'; 35 | $string['previewgrade'] = 'Preview grade'; 36 | $string['privacy:metadata'] = 'The Grade plugin does not store any personal data.'; 37 | -------------------------------------------------------------------------------- /templates/email_certificate_html.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template mod_customcert/email_certificate_html 19 | 20 | The certificate verification result 21 | 22 | Classes required for JS: 23 | * None 24 | 25 | Data attibutes required for JS: 26 | * All data attributes are required 27 | 28 | Context variables required for this template: 29 | * emailgreeting 30 | * emailbody 31 | * emailcertificatelink 32 | * emailcertificatelinktext 33 | 34 | Example context (json): 35 | { 36 | "emailgreeting": "Dear Angus MacGyver", 37 | "emailbody": "Attached is your certificate 'The basics' for the course 'Survival as an '80s action hero'", 38 | "emailcertificatelink": "http://yoursite.com/mod/customcert/view.php?id=4", 39 | "emailcertificatelinktext": "Certificate report" 40 | } 41 | }} 42 | {{{emailgreeting}}} 43 | 44 | {{{emailbody}}} 45 | 46 | {{emailcertificatelinktext}}. 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The custom certificate activity 2 | 3 | This activity allows the dynamic generation of PDF certificates with complete customisation via the web browser. 4 | 5 | ## Installation 6 | 7 | There are two installation methods that are available. 8 | 9 | Follow one of these, then log into your Moodle site as an administrator and visit the notifications page to complete the install. 10 | 11 | ### Git 12 | 13 | This requires Git being installed. If you do not have Git installed, please visit the [Git website](https://git-scm.com/downloads "Git website"). 14 | 15 | Once you have Git installed, simply visit your Moodle mod directory and clone the repository using the following command. 16 | 17 | ``` 18 | git clone https://github.com/mdjnelson/moodle-mod_customcert.git customcert 19 | ``` 20 | 21 | Then checkout the branch corresponding to the version of Moodle you are using with the following command. Make sure to replace MOODLE_32_STABLE with the version of Moodle you are using. 22 | 23 | ``` 24 | git checkout MOODLE_32_STABLE 25 | ``` 26 | 27 | Use `git pull` to update this repository periodically to ensure you have the most recent updates. 28 | 29 | ### Download the zip 30 | 31 | Visit the [Moodle plugins website](https://moodle.org/plugins/mod_customcert "Moodle plugins website") and download the zip corresponding to the version of Moodle you are using. Extract the zip and place the 'customcert' folder in the mod folder in your Moodle directory. 32 | 33 | ## More information 34 | 35 | Visit the [wiki page](https://docs.moodle.org/en/Custom_certificate_module "Wiki page") for more details. Also, it is a wiki, so please feel free to edit it. :) 36 | 37 | ## License 38 | 39 | Licensed under the [GNU GPL License](http://www.gnu.org/copyleft/gpl.html). -------------------------------------------------------------------------------- /element/code/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_code. 19 | * 20 | * @package customcertelement_code 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_code\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_code implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/date/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_date. 19 | * 20 | * @package customcertelement_date 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_date\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_date implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/text/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_text. 19 | * 20 | * @package customcertelement_text 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_text\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_text implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/grade/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_grade. 19 | * 20 | * @package customcertelement_grade 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_grade\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_grade implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/image/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_image. 19 | * 20 | * @package customcertelement_image 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_image\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_image implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/border/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_border. 19 | * 20 | * @package customcertelement_border 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_border\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_border implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/qrcode/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_qrcode. 19 | * 20 | * @package customcertelement_qrcode 21 | * @copyright 2019 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_qrcode\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_qrcode implementing null_provider. 31 | * 32 | * @copyright 2019 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/bgimage/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_bgimage. 19 | * 20 | * @package customcertelement_bgimage 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_bgimage\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_bgimage implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/daterange/tests/fixtures/fake_datarange_element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Fake datarange element for testing. 19 | * 20 | * @package customcertelement_daterange 21 | * @copyright 2018 Dmitrii Metelkin 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | /** 28 | * Fake datarange element for testing. 29 | * 30 | * @package customcertelement_daterange 31 | * @copyright 2018 Dmitrii Metelkin 32 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 | */ 34 | class fake_datarange_element extends \customcertelement_daterange\element { 35 | 36 | /** 37 | * Override protected method for testing. 38 | * 39 | * @param int $date 40 | * 41 | * @return string 42 | */ 43 | public function get_daterange_string($date) { 44 | $result = parent::get_daterange_string($date); 45 | return $result; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /element/coursefield/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_coursefield. 19 | * 20 | * @package customcertelement_coursefield 21 | * @copyright 2019 Catalyst IT 22 | * @author Dan Marsden 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | namespace customcertelement_coursefield\privacy; 27 | 28 | defined('MOODLE_INTERNAL') || die(); 29 | 30 | /** 31 | * Privacy Subsystem for customcertelement_coursefield implementing null_provider. 32 | * 33 | * @copyright 2019 Catalyst IT 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class provider implements \core_privacy\local\metadata\null_provider { 37 | 38 | /** 39 | * Get the language string identifier with the component's language 40 | * file to explain why this plugin stores no data. 41 | * 42 | * @return string 43 | */ 44 | public static function get_reason() : string { 45 | return 'privacy:metadata'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /element/userfield/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_userfield. 19 | * 20 | * @package customcertelement_userfield 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_userfield\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_userfield implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/coursename/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_coursename. 19 | * 20 | * @package customcertelement_coursename 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_coursename\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_coursename implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/studentname/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_studentname. 19 | * 20 | * @package customcertelement_studentname 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_studentname\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_studentname implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/teachername/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_teachername. 19 | * 20 | * @package customcertelement_teachername 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_teachername\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_teachername implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/userpicture/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_userpicture. 19 | * 20 | * @package customcertelement_userpicture 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_userpicture\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_userpicture implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/categoryname/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_categoryname. 19 | * 20 | * @package customcertelement_categoryname 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_categoryname\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_categoryname implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/gradeitemname/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_gradeitemname. 19 | * 20 | * @package customcertelement_gradeitemname 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_gradeitemname\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_gradeitemname implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/daterange/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_daterange. 19 | * 20 | * @package customcertelement_daterange 21 | * @copyright 2018 Dmitrii Metelkin 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_daterange\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_daterange implementing null_provider. 31 | * 32 | * @copyright 2018 Dmitrii Metelkin 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /element/digitalsignature/classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy Subsystem implementation for customcertelement_digitalsignature. 19 | * 20 | * @package customcertelement_digitalsignature 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_digitalsignature\privacy; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Privacy Subsystem for customcertelement_digitalsignature implementing null_provider. 31 | * 32 | * @copyright 2018 Mark Nelson 33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 | */ 35 | class provider implements \core_privacy\local\metadata\null_provider { 36 | 37 | /** 38 | * Get the language string identifier with the component's language 39 | * file to explain why this plugin stores no data. 40 | * 41 | * @return string 42 | */ 43 | public static function get_reason() : string { 44 | return 'privacy:metadata'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /classes/event/course_module_viewed.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains the course module viewed event class. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\event; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The course module viewed event class. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class course_module_viewed extends \core\event\course_module_viewed { 37 | 38 | /** 39 | * Initialises the event. 40 | */ 41 | protected function init() { 42 | $this->data['objecttable'] = 'customcert'; 43 | parent::init(); 44 | } 45 | 46 | public static function get_objectid_mapping() { 47 | return array('db' => 'customcert', 'restore' => 'customcert'); 48 | } 49 | 50 | public static function get_other_mapping() { 51 | // No need to map. 52 | return false; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/behat/my_certificates.feature: -------------------------------------------------------------------------------- 1 | @mod @mod_customcert 2 | Feature: Being able to view the certificates you have been issued 3 | In order to ensure that a user can view the certificates they have been issued 4 | As a student 5 | I need to view the certificates I have been issued 6 | 7 | Background: 8 | Given the following "courses" exist: 9 | | fullname | shortname | category | 10 | | Course 1 | C1 | 0 | 11 | | Course 2 | C2 | 0 | 12 | And the following "users" exist: 13 | | username | firstname | lastname | email | 14 | | student1 | Student | 1 | student1@example.com | 15 | And the following "course enrolments" exist: 16 | | user | course | role | 17 | | student1 | C1 | student | 18 | | student1 | C2 | student | 19 | And the following "activities" exist: 20 | | activity | name | intro | course | idnumber | 21 | | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 22 | | customcert | Custom certificate 2 | Custom certificate 2 intro | C2 | customcert2 | 23 | 24 | Scenario: View your issued certificates on the my certificates page 25 | And I log in as "student1" 26 | And I am on "Course 1" course homepage 27 | And I follow "Custom certificate 1" 28 | And I press "View certificate" 29 | And I follow "Profile" in the user menu 30 | And I follow "My certificates" 31 | And I should see "Custom certificate 1" 32 | And I should not see "Custom certificate 2" 33 | And I am on "Course 2" course homepage 34 | And I follow "Custom certificate 2" 35 | And I press "View certificate" 36 | And I follow "Profile" in the user menu 37 | And I follow "My certificates" 38 | And I should see "Custom certificate 1" 39 | And I should see "Custom certificate 2" 40 | -------------------------------------------------------------------------------- /element/image/lang/en/customcertelement_image.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_image', language 'en'. 19 | * 20 | * @package customcertelement_image 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['alphachannel'] = 'Alpha channel'; 26 | $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).'; 27 | $string['courseimage'] = 'Course image: {$a}'; 28 | $string['height'] = 'Height'; 29 | $string['height_help'] = 'Height of the image in mm. If equal to zero, it is automatically calculated.'; 30 | $string['image'] = 'Image'; 31 | $string['invalidheight'] = 'The height has to be a valid number greater than or equal to 0.'; 32 | $string['invalidwidth'] = 'The width has to be a valid number greater than or equal to 0.'; 33 | $string['pluginname'] = 'Image'; 34 | $string['privacy:metadata'] = 'The Image plugin does not store any personal data.'; 35 | $string['systemimage'] = 'Site image: {$a}'; 36 | $string['width'] = 'Width'; 37 | $string['width_help'] = 'Width of the image in mm. If equal to zero, it is automatically calculated.'; 38 | -------------------------------------------------------------------------------- /tests/behat/required_minutes.feature: -------------------------------------------------------------------------------- 1 | @mod @mod_customcert 2 | Feature: Being able to set the required minutes in a course before viewing the certificate 3 | In order to ensure the required minutes in a course setting works as expected 4 | As a teacher 5 | I need to ensure students can not view a certificate until the required minutes have passed 6 | 7 | Background: 8 | Given the following "courses" exist: 9 | | fullname | shortname | category | 10 | | Course 1 | C1 | 0 | 11 | And the following "users" exist: 12 | | username | firstname | lastname | email | 13 | | teacher1 | Teacher | 1 | teacher1@example.com | 14 | | student1 | Student | 1 | student1@example.com | 15 | And the following "course enrolments" exist: 16 | | user | course | role | 17 | | teacher1 | C1 | editingteacher | 18 | | student1 | C1 | student | 19 | And the following "activities" exist: 20 | | activity | name | intro | course | idnumber | requiredtime | 21 | | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 1 | 22 | 23 | Scenario: Check the user can not access the certificate before the required time 24 | And I log in as "student1" 25 | And I am on "Course 1" course homepage 26 | And I follow "Custom certificate 1" 27 | And I should see "You must spend at least a minimum of" 28 | And I should not see "View certificate" 29 | And I press "Continue" 30 | And I should see "Custom certificate 1" 31 | 32 | Scenario: Check the user can access the certificate after the required time 33 | And I log in as "student1" 34 | And I am on "Course 1" course homepage 35 | And I wait "60" seconds 36 | And I am on "Course 1" course homepage 37 | And I follow "Custom certificate 1" 38 | And I should not see "You must spend at least a minimum of" 39 | And I should see "View certificate" 40 | -------------------------------------------------------------------------------- /templates/verify_certificate_result.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template mod_customcert/verify_certificate_result 19 | 20 | The certificate verification result 21 | 22 | Classes required for JS: 23 | * None 24 | 25 | Data attibutes required for JS: 26 | * All data attributes are required 27 | 28 | Context variables required for this template: 29 | * userprofileurl The URL to the user's profile 30 | * userfullname The fullname of the user 31 | * courseurl The URL of the course 32 | * coursefullname The full name of the course 33 | * certificatename The name of the certificate 34 | 35 | Example context (json): 36 | { 37 | "userprofileurl": "http://www.example.com", 38 | "userfullname": "Mark Smith", 39 | "courseurl": "http://www.example.com", 40 | "coursefullname": "Computing 101", 41 | "certificatename": "Ability to write 'Hello world' in Java." 42 | } 43 | }} 44 | 49 | -------------------------------------------------------------------------------- /ajax.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Handles AJAX requests for the customcert module. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(__DIR__ . '/../../config.php'); 26 | 27 | if (!defined('AJAX_SCRIPT')) { 28 | define('AJAX_SCRIPT', true); 29 | } 30 | 31 | $tid = required_param('tid', PARAM_INT); 32 | $values = required_param('values', PARAM_RAW); 33 | $values = json_decode($values); 34 | 35 | // Make sure the template exists. 36 | $template = $DB->get_record('customcert_templates', array('id' => $tid), '*', MUST_EXIST); 37 | 38 | // Set the template. 39 | $template = new \mod_customcert\template($template); 40 | // Perform checks. 41 | if ($cm = $template->get_cm()) { 42 | $courseid = $cm->course; 43 | require_login($courseid, false, $cm); 44 | } else { 45 | require_login(); 46 | } 47 | // Make sure the user has the required capabilities. 48 | $template->require_manage(); 49 | 50 | // Loop through the data. 51 | foreach ($values as $value) { 52 | $element = new stdClass(); 53 | $element->id = $value->id; 54 | $element->posx = $value->posx; 55 | $element->posy = $value->posy; 56 | $DB->update_record('customcert_elements', $element); 57 | } -------------------------------------------------------------------------------- /element/date/lang/en/customcertelement_date.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_date', language 'en'. 19 | * 20 | * @package customcertelement_date 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $string['completiondate'] = 'Completion date'; 26 | $string['courseenddate'] = 'Course end date'; 27 | $string['coursegradedate'] = 'Course grade date'; 28 | $string['coursestartdate'] = 'Course start date'; 29 | $string['enrolmentenddate'] = 'Enrolment end date'; 30 | $string['enrolmentstartdate'] = 'Enrolment start date'; 31 | $string['currentdate'] = 'Current date'; 32 | $string['dateformat'] = 'Date format'; 33 | $string['dateformat_help'] = 'This is the format of the date that will be displayed'; 34 | $string['dateitem'] = 'Date item'; 35 | $string['dateitem_help'] = 'This will be the date that is printed on the certificate'; 36 | $string['issueddate'] = 'Issued date'; 37 | $string['pluginname'] = 'Date'; 38 | $string['privacy:metadata'] = 'The Date plugin does not store any personal data.'; 39 | $string['numbersuffix_nd_as_in_second'] = 'nd'; 40 | $string['numbersuffix_rd_as_in_third'] = 'rd'; 41 | $string['numbersuffix_st_as_in_first'] = 'st'; 42 | $string['userdateformat'] = 'User date format'; 43 | -------------------------------------------------------------------------------- /upload_image.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Handles uploading files 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require('../../config.php'); 26 | 27 | require_login(); 28 | 29 | $context = context_system::instance(); 30 | require_capability('moodle/site:config', $context); 31 | 32 | $struploadimage = get_string('uploadimage', 'customcert'); 33 | 34 | // Set the page variables. 35 | $pageurl = new moodle_url('/mod/customcert/upload_image.php'); 36 | \mod_customcert\page_helper::page_setup($pageurl, $context, $SITE->fullname); 37 | 38 | // Additional page setup. 39 | $PAGE->navbar->add($struploadimage); 40 | 41 | $uploadform = new \mod_customcert\upload_image_form(); 42 | 43 | if ($uploadform->is_cancelled()) { 44 | redirect(new moodle_url('/admin/settings.php?section=modsettingcustomcert')); 45 | } else if ($data = $uploadform->get_data()) { 46 | // Handle file uploads. 47 | \mod_customcert\certificate::upload_files($data->customcertimage, $context->id); 48 | 49 | redirect(new moodle_url('/mod/customcert/upload_image.php'), get_string('changessaved')); 50 | } 51 | 52 | echo $OUTPUT->header(); 53 | echo $OUTPUT->heading($SITE->fullname); 54 | $uploadform->display(); 55 | echo $OUTPUT->footer(); 56 | -------------------------------------------------------------------------------- /tests/behat/managing_pages.feature: -------------------------------------------------------------------------------- 1 | @mod @mod_customcert 2 | Feature: Being able to manage pages in a certificate template 3 | In order to ensure managing pages in a certificate template works as expected 4 | As a teacher 5 | I need to manage pages in a certificate template 6 | 7 | Background: 8 | Given the following "courses" exist: 9 | | fullname | shortname | category | 10 | | Course 1 | C1 | 0 | 11 | And the following "users" exist: 12 | | username | firstname | lastname | email | 13 | | teacher1 | Teacher | 1 | teacher1@example.com | 14 | And the following "course enrolments" exist: 15 | | user | course | role | 16 | | teacher1 | C1 | editingteacher | 17 | And the following "activities" exist: 18 | | activity | name | intro | course | idnumber | 19 | | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 20 | And I log in as "teacher1" 21 | And I am on "Course 1" course homepage 22 | And I follow "Custom certificate 1" 23 | And I navigate to "Edit certificate" in current page administration 24 | 25 | Scenario: Adding a page to a certificate template 26 | And I follow "Add page" 27 | And I should see "Page 1" 28 | And I should see "Page 2" 29 | 30 | Scenario: Deleting a page from a certificate template 31 | And I add the element "Background image" to page "1" of the "Custom certificate 1" certificate template 32 | And I press "Save changes" 33 | And I add the element "Student name" to page "1" of the "Custom certificate 1" certificate template 34 | And I press "Save changes" 35 | And I follow "Add page" 36 | And I should see "Page 1" 37 | And I should see "Page 2" 38 | And I delete page "2" of the "Custom certificate 1" certificate template 39 | And I should see "Background image" in the "elementstable" "table" 40 | And I should see "Student name" in the "elementstable" "table" 41 | And I should not see "Page 1" 42 | And I should not see "Page 2" 43 | -------------------------------------------------------------------------------- /db/services.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Web service for mod customcert. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $functions = array( 28 | 'mod_customcert_delete_issue' => array( 29 | 'classname' => 'mod_customcert\external', 30 | 'methodname' => 'delete_issue', 31 | 'classpath' => '', 32 | 'description' => 'Delete an issue for a certificate', 33 | 'type' => 'write', 34 | 'ajax' => true, 35 | 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) 36 | ), 37 | 'mod_customcert_save_element' => array( 38 | 'classname' => 'mod_customcert\external', 39 | 'methodname' => 'save_element', 40 | 'classpath' => '', 41 | 'description' => 'Saves data for an element', 42 | 'type' => 'write', 43 | 'ajax' => true 44 | ), 45 | 'mod_customcert_get_element_html' => array( 46 | 'classname' => 'mod_customcert\external', 47 | 'methodname' => 'get_element_html', 48 | 'classpath' => '', 49 | 'description' => 'Returns the HTML to display for an element', 50 | 'type' => 'read', 51 | 'ajax' => true 52 | ), 53 | ); 54 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | #page-mod-customcert-edit .deletebutton { 2 | text-align: right; 3 | } 4 | 5 | #page-mod-customcert-edit .addpage { 6 | border-top: 1px solid #f4f4f4; 7 | text-align: right; 8 | } 9 | 10 | #page-mod-customcert-edit #id_replace { 11 | margin-left: 10px; 12 | } 13 | 14 | #page-mod-customcert-report .centre { 15 | margin-left: auto; 16 | margin-right: auto; 17 | } 18 | 19 | #page-mod-customcert-rearrange .savepositionsbtn, 20 | #page-mod-customcert-rearrange .applypositionsbtn, 21 | #page-mod-customcert-rearrange .cancelbtn { 22 | float: left; 23 | } 24 | 25 | #page-mod-customcert-rearrange .element { 26 | display: inline-block; 27 | position: absolute; 28 | word-wrap: break-word; 29 | } 30 | 31 | #page-mod-customcert-rearrange .element:before { 32 | background-image: url([[pix:mod_customcert|target]]); 33 | background-repeat: no-repeat; 34 | content: ""; 35 | display: block; 36 | float: left; 37 | height: 9px; 38 | width: 100%; 39 | } 40 | 41 | #page-mod-customcert-rearrange .element:hover { 42 | cursor: move; 43 | } 44 | 45 | #page-mod-customcert-rearrange .element.refpoint-left:before { 46 | background-position: left top; 47 | margin: -4px -5px -5px -4px; 48 | } 49 | 50 | #page-mod-customcert-rearrange .element.refpoint-center:before { 51 | background-position: center top; 52 | margin: -4px 0 -5px 0; 53 | } 54 | 55 | #page-mod-customcert-rearrange .element.refpoint-right:before { 56 | background-position: right top; 57 | margin: -4px -5px -5px 4px; 58 | } 59 | 60 | #page-mod-customcert-rearrange #pdf { 61 | border-style: solid; 62 | border-width: 1px; 63 | clear: both; 64 | } 65 | 66 | #page-mod-customcert-rearrange div#leftmargin { 67 | border-left: 1px dotted black; 68 | } 69 | 70 | #page-mod-customcert-rearrange div#rightmargin { 71 | border-right: 1px dotted black; 72 | } 73 | 74 | /* 75 | This is a hack - the fieldset being returned by the edit_element_form class contains 76 | the CSS class 'hidden' which when shown in a dialogue hides the fieldset. 77 | */ 78 | .moodle-dialogue #editelementform fieldset.hidden { 79 | display: block; 80 | } 81 | -------------------------------------------------------------------------------- /tests/generator/lib.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains the class responsible for data generation during unit tests 19 | * 20 | * @package mod_customcert 21 | * @category test 22 | * @copyright 2017 Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | /** 29 | * The class responsible for data generation during unit tests 30 | * 31 | * @package mod_customcert 32 | * @category test 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class mod_customcert_generator extends testing_module_generator { 37 | 38 | /** 39 | * Creates an instance of the custom certificate. 40 | * 41 | * @param array|stdClass|null $record 42 | * @param array|null $options 43 | * @return stdClass 44 | */ 45 | public function create_instance($record = null, array $options = null) { 46 | $record = (object)(array)$record; 47 | 48 | $defaultsettings = array( 49 | 'requiredtime' => 0, 50 | 'emailstudents' => 0, 51 | 'emailteachers' => 0, 52 | 'emailothers' => '', 53 | 'protection' => '' 54 | ); 55 | 56 | foreach ($defaultsettings as $name => $value) { 57 | if (!isset($record->{$name})) { 58 | $record->{$name} = $value; 59 | } 60 | } 61 | 62 | return parent::create_instance($record, (array)$options); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /classes/verify_certificate_form.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This files contains the form for verifying a certificate. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 28 | 29 | require_once($CFG->libdir . '/formslib.php'); 30 | 31 | /** 32 | * The form for verifying a certificate. 33 | * 34 | * @package mod_customcert 35 | * @copyright 2017 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class verify_certificate_form extends \moodleform { 39 | 40 | /** 41 | * Form definition. 42 | */ 43 | public function definition() { 44 | $mform =& $this->_form; 45 | 46 | $mform->addElement('text', 'code', get_string('code', 'customcert')); 47 | $mform->setType('code', PARAM_ALPHANUM); 48 | 49 | $mform->addElement('submit', 'verify', get_string('verify', 'customcert')); 50 | } 51 | 52 | /** 53 | * Validation. 54 | * 55 | * @param array $data 56 | * @param array $files 57 | * @return array the errors that were found 58 | */ 59 | public function validation($data, $files) { 60 | $errors = array(); 61 | 62 | if ($data['code'] === '') { 63 | $errors['code'] = get_string('invalidcode', 'customcert'); 64 | } 65 | 66 | return $errors; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /classes/output/renderer.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains renderer class. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\output; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | use plugin_renderer_base; 30 | 31 | /** 32 | * Renderer class. 33 | * 34 | * @package mod_customcert 35 | * @copyright 2017 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class renderer extends plugin_renderer_base { 39 | 40 | /** 41 | * Renders the verify certificate results. 42 | * 43 | * Defer to template. 44 | * 45 | * @param \mod_customcert\output\verify_certificate_results $page 46 | * @return string html for the page 47 | */ 48 | public function render_verify_certificate_results(verify_certificate_results $page) { 49 | $data = $page->export_for_template($this); 50 | return parent::render_from_template('mod_customcert/verify_certificate_results', $data); 51 | } 52 | 53 | /** 54 | * Formats the email used to send the certificate by the email_certificate_task. 55 | * 56 | * @param email_certificate $certificate The certificate to email 57 | * @return string 58 | */ 59 | public function render_email_certificate(email_certificate $certificate) { 60 | $data = $certificate->export_for_template($this); 61 | return $this->render_from_template('mod_customcert/' . $this->get_template_name(), $data); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /element/studentname/classes/element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the customcert element studentname's core interaction API. 19 | * 20 | * @package customcertelement_studentname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_studentname; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The customcert element studentname's core interaction API. 31 | * 32 | * @package customcertelement_studentname 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element extends \mod_customcert\element { 37 | 38 | /** 39 | * Handles rendering the element on the pdf. 40 | * 41 | * @param \pdf $pdf the pdf object 42 | * @param bool $preview true if it is a preview, false otherwise 43 | * @param \stdClass $user the user we are rendering this for 44 | */ 45 | public function render($pdf, $preview, $user) { 46 | \mod_customcert\element_helper::render_content($pdf, $this, fullname($user)); 47 | } 48 | 49 | /** 50 | * Render the element in html. 51 | * 52 | * This function is used to render the element when we are using the 53 | * drag and drop interface to position it. 54 | * 55 | * @return string the html 56 | */ 57 | public function render_html() { 58 | global $USER; 59 | 60 | return \mod_customcert\element_helper::render_html_content($this, fullname($USER)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /db/mobile.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Defines mobile handlers. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $addons = [ 28 | 'mod_customcert' => [ // Plugin identifier. 29 | 'handlers' => [ // Different places where the plugin will display content. 30 | 'issueview' => [ // Handler unique name. 31 | 'displaydata' => [ 32 | 'icon' => $CFG->wwwroot . '/mod/customcert/pix/icon.png', 33 | 'class' => 'core-course-module-customcert-handler', 34 | ], 35 | 'delegate' => 'CoreCourseModuleDelegate', // Delegate (where to display the link to the plugin). 36 | 'method' => 'mobile_view_activity', // Main function in \mod_customcert\output\mobile. 37 | 'styles' => [ 38 | 'url' => '/mod/customcert/mobile/styles.css', 39 | 'version' => 1 40 | ] 41 | ] 42 | ], 43 | 'lang' => [ // Language strings that are used in all the handlers. 44 | ['deleteissueconfirm', 'customcert'], 45 | ['getcustomcert', 'customcert'], 46 | ['listofissues', 'customcert'], 47 | ['nothingtodisplay', 'moodle'], 48 | ['notissued', 'customcert'], 49 | ['pluginname', 'customcert'], 50 | ['receiveddate', 'customcert'], 51 | ['requiredtimenotmet', 'customcert'], 52 | ['selectagroup', 'moodle'] 53 | ] 54 | ] 55 | ]; 56 | -------------------------------------------------------------------------------- /classes/page_helper.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Provides useful functions related to setting up the page. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * Class helper. 31 | * 32 | * Provides useful functions. 33 | * 34 | * @package mod_customcert 35 | * @copyright 2016 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class page_helper { 39 | 40 | /** 41 | * Sets up the page variables. 42 | * 43 | * @param \moodle_url $pageurl 44 | * @param \context $context 45 | * @param string $title the page title 46 | */ 47 | public static function page_setup($pageurl, $context, $title) { 48 | global $COURSE, $PAGE, $SITE; 49 | 50 | $PAGE->set_url($pageurl); 51 | $PAGE->set_context($context); 52 | $PAGE->set_title(format_string($title)); 53 | 54 | // If we are in the system context then we are managing templates, and we want to show that in the navigation. 55 | if ($context->contextlevel == CONTEXT_SYSTEM) { 56 | $PAGE->set_pagelayout('admin'); 57 | $PAGE->set_heading($SITE->fullname); 58 | 59 | $urloverride = new \moodle_url('/admin/settings.php?section=modsettingcustomcert'); 60 | \navigation_node::override_active_url($urloverride); 61 | } else { 62 | $PAGE->set_heading(format_string($COURSE->fullname)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/behat/show_position_x_y.feature: -------------------------------------------------------------------------------- 1 | @mod @mod_customcert 2 | Feature: Being able to set a site setting to determine whether or not to display the position X and Y fields 3 | In order to ensure the show position X and Y fields setting works as expected 4 | As an admin 5 | I need to ensure teachers can see the position X and Y fields depending on the site setting 6 | 7 | Background: 8 | Given the following "courses" exist: 9 | | fullname | shortname | category | 10 | | Course 1 | C1 | 0 | 11 | And the following "users" exist: 12 | | username | firstname | lastname | email | 13 | | teacher1 | Teacher | 1 | teacher1@example.com | 14 | And the following "course enrolments" exist: 15 | | user | course | role | 16 | | teacher1 | C1 | editingteacher | 17 | And the following "activities" exist: 18 | | activity | name | intro | course | idnumber | 19 | | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 20 | 21 | Scenario: Adding an element with the show position X and Y setting disabled 22 | And I log in as "teacher1" 23 | And I am on "Course 1" course homepage 24 | And I follow "Custom certificate 1" 25 | And I navigate to "Edit certificate" in current page administration 26 | And I add the element "Code" to page "1" of the "Custom certificate 1" certificate template 27 | And I should not see "Position X" 28 | And I should not see "Position Y" 29 | 30 | Scenario: Adding an element with the show position X and Y setting enabled 31 | And I log in as "admin" 32 | And I navigate to "Plugins" in site administration 33 | And I follow "Manage activities" 34 | And I click on "Settings" "link" in the "Custom certificate" "table_row" 35 | And I set the field "Show position X and Y" to "1" 36 | And I press "Save changes" 37 | And I log out 38 | And I log in as "teacher1" 39 | And I am on "Course 1" course homepage 40 | And I follow "Custom certificate 1" 41 | And I navigate to "Edit certificate" in current page administration 42 | And I add the element "Code" to page "1" of the "Custom certificate 1" certificate template 43 | And I should see "Position X" 44 | And I should see "Position Y" 45 | And I set the following fields to these values: 46 | | Position X | 5 | 47 | | Position Y | 10 | 48 | And I press "Save changes" 49 | And I click on ".edit-icon" "css_element" in the "Code" "table_row" 50 | And the following fields match these values: 51 | | Position X | 5 | 52 | | Position Y | 10 | 53 | -------------------------------------------------------------------------------- /classes/upload_image_form.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the class that handles uploading files. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 28 | 29 | require_once($CFG->libdir.'/formslib.php'); 30 | 31 | /** 32 | * Handles uploading files. 33 | * 34 | * @package mod_customcert 35 | * @copyright 2013 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class upload_image_form extends \moodleform { 39 | 40 | /** @var array the filemanager options */ 41 | protected $filemanageroptions = array(); 42 | 43 | /** 44 | * Form definition. 45 | */ 46 | public function definition() { 47 | global $CFG; 48 | 49 | $mform = $this->_form; 50 | $this->filemanageroptions = array( 51 | 'maxbytes' => $CFG->maxbytes, 52 | 'subdirs' => 1, 53 | 'accepted_types' => 'image'); 54 | $mform->addElement('filemanager', 'customcertimage', get_string('uploadimage', 'customcert'), '', 55 | $this->filemanageroptions); 56 | 57 | $this->add_action_buttons(); 58 | } 59 | 60 | /** 61 | * Fill in the current page data for this customcert. 62 | */ 63 | public function definition_after_data() { 64 | $mform = $this->_form; 65 | 66 | // Editing existing instance - copy existing files into draft area. 67 | $draftitemid = file_get_submitted_draft_itemid('customcertimage'); 68 | file_prepare_draft_area($draftitemid, \context_system::instance()->id, 'mod_customcert', 'image', 0, 69 | $this->filemanageroptions); 70 | $element = $mform->getElement('customcertimage'); 71 | $element->setValue($draftitemid); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /classes/element_factory.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains the factory class responsible for creating custom certificate instances. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The factory class responsible for creating custom certificate instances. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element_factory { 37 | 38 | /** 39 | * Returns an instance of the element class. 40 | * 41 | * @param \stdClass $element the element 42 | * @return \mod_customcert\element|bool returns the instance of the element class, or false if element 43 | * class does not exists. 44 | */ 45 | public static function get_element_instance($element) { 46 | // Get the class name. 47 | $classname = '\\customcertelement_' . $element->element . '\\element'; 48 | 49 | $data = new \stdClass(); 50 | $data->id = $element->id ?? null; 51 | $data->pageid = $element->pageid ?? null; 52 | $data->name = $element->name ?? get_string('pluginname', 'customcertelement_' . $element->element); 53 | $data->element = $element->element; 54 | $data->data = $element->data ?? null; 55 | $data->font = $element->font ?? null; 56 | $data->fontsize = $element->fontsize ?? null; 57 | $data->colour = $element->colour ?? null; 58 | $data->posx = $element->posx ?? null; 59 | $data->posy = $element->posy ?? null; 60 | $data->width = $element->width ?? null; 61 | $data->refpoint = $element->refpoint ?? null; 62 | 63 | // Ensure the necessary class exists. 64 | if (class_exists($classname)) { 65 | return new $classname($data); 66 | } 67 | 68 | return false; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /element/coursename/classes/element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the customcert element coursename's core interaction API. 19 | * 20 | * @package customcertelement_coursename 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_coursename; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The customcert element coursename's core interaction API. 31 | * 32 | * @package customcertelement_coursename 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element extends \mod_customcert\element { 37 | 38 | /** 39 | * Handles rendering the element on the pdf. 40 | * 41 | * @param \pdf $pdf the pdf object 42 | * @param bool $preview true if it is a preview, false otherwise 43 | * @param \stdClass $user the user we are rendering this for 44 | */ 45 | public function render($pdf, $preview, $user) { 46 | \mod_customcert\element_helper::render_content($pdf, $this, $this->get_course_name()); 47 | } 48 | 49 | /** 50 | * Render the element in html. 51 | * 52 | * This function is used to render the element when we are using the 53 | * drag and drop interface to position it. 54 | * 55 | * @return string the html 56 | */ 57 | public function render_html() { 58 | return \mod_customcert\element_helper::render_html_content($this, $this->get_course_name()); 59 | } 60 | 61 | /** 62 | * Helper function that returns the category name. 63 | * 64 | * @return string 65 | */ 66 | protected function get_course_name() : string { 67 | $courseid = \mod_customcert\element_helper::get_courseid($this->get_id()); 68 | $course = get_course($courseid); 69 | $context = \mod_customcert\element_helper::get_context($this->get_id()); 70 | 71 | return format_string($course->fullname, true, ['context' => $context]); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/behat/view_issued_certificates.feature: -------------------------------------------------------------------------------- 1 | @mod @mod_customcert 2 | Feature: Being able to view the certificates that have been issued 3 | In order to ensure that a user can view the certificates that have been issued 4 | As a teacher 5 | I need to view the certificates that have been issued 6 | 7 | Background: 8 | Given the following "courses" exist: 9 | | fullname | shortname | category | 10 | | Course 1 | C1 | 0 | 11 | And the following "users" exist: 12 | | username | firstname | lastname | email | 13 | | teacher1 | Teacher | 1 | teacher1@example.com | 14 | | student1 | Student | 1 | student1@example.com | 15 | | student2 | Student | 2 | student2@example.com | 16 | And the following "course enrolments" exist: 17 | | user | course | role | 18 | | teacher1 | C1 | editingteacher | 19 | | student1 | C1 | student | 20 | | student2 | C1 | student | 21 | And the following "activities" exist: 22 | | activity | name | intro | course | idnumber | 23 | | customcert | Custom certificate 1 | Custom certificate 1 intro | C1 | customcert1 | 24 | 25 | Scenario: View the issued certificates 26 | And I log in as "student1" 27 | And I am on "Course 1" course homepage 28 | And I follow "Custom certificate 1" 29 | And I press "View certificate" 30 | And I log out 31 | And I log in as "student2" 32 | And I am on "Course 1" course homepage 33 | And I follow "Custom certificate 1" 34 | And I press "View certificate" 35 | And I log out 36 | And I log in as "teacher1" 37 | And I am on "Course 1" course homepage 38 | And I follow "Custom certificate 1" 39 | And I should see "Student 1" 40 | And I should see "Student 2" 41 | 42 | Scenario: Delete an issued certificate 43 | And I log in as "student1" 44 | And I am on "Course 1" course homepage 45 | And I follow "Custom certificate 1" 46 | And I press "View certificate" 47 | And I log out 48 | And I log in as "student2" 49 | And I am on "Course 1" course homepage 50 | And I follow "Custom certificate 1" 51 | And I press "View certificate" 52 | And I log out 53 | And I log in as "teacher1" 54 | And I am on "Course 1" course homepage 55 | And I follow "Custom certificate 1" 56 | And I should see "Student 1" 57 | And I should see "Student 2" 58 | And I click on ".delete-icon" "css_element" in the "Student 2" "table_row" 59 | And I press "Cancel" 60 | And I should see "Student 1" 61 | And I should see "Student 2" 62 | And I click on ".delete-icon" "css_element" in the "Student 2" "table_row" 63 | And I press "Continue" 64 | And I should see "Student 1" 65 | And I should not see "Student 2" 66 | -------------------------------------------------------------------------------- /element/image/db/upgrade.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Customcert image element upgrade code. 19 | * 20 | * @package customcertelement_image 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die; 26 | 27 | /** 28 | * Customcert image element upgrade code. 29 | * 30 | * @param int $oldversion the version we are upgrading from 31 | * @return bool always true 32 | */ 33 | function xmldb_customcertelement_image_upgrade($oldversion) { 34 | global $DB; 35 | 36 | if ($oldversion < 2016120501) { 37 | // Go through each 'image' element and update the file stored information. 38 | if ($images = $DB->get_records_select('customcert_elements', $DB->sql_compare_text('element') . ' = \'image\'')) { 39 | // Create a file storage instance we are going to use to create pathname hashes. 40 | $fs = get_file_storage(); 41 | // Go through and update the details. 42 | foreach ($images as $image) { 43 | // Get the current data we have stored for this element. 44 | $elementinfo = json_decode($image->data); 45 | if ($file = $fs->get_file_by_hash($elementinfo->pathnamehash)) { 46 | $arrtostore = array( 47 | 'contextid' => $file->get_contextid(), 48 | 'filearea' => $file->get_filearea(), 49 | 'itemid' => $file->get_itemid(), 50 | 'filepath' => $file->get_filepath(), 51 | 'filename' => $file->get_filename(), 52 | 'width' => (int) $elementinfo->width, 53 | 'height' => (int) $elementinfo->height 54 | ); 55 | $arrtostore = json_encode($arrtostore); 56 | $DB->set_field('customcert_elements', 'data', $arrtostore, array('id' => $image->id)); 57 | } 58 | } 59 | } 60 | 61 | // Savepoint reached. 62 | upgrade_plugin_savepoint(true, 2016120501, 'customcertelement', 'image'); 63 | } 64 | 65 | return true; 66 | } 67 | -------------------------------------------------------------------------------- /element/bgimage/db/upgrade.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Customcert background image element upgrade code. 19 | * 20 | * @package customcertelement_bgimage 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die; 26 | 27 | /** 28 | * Customcert background image element upgrade code. 29 | * 30 | * @param int $oldversion the version we are upgrading from 31 | * @return bool always true 32 | */ 33 | function xmldb_customcertelement_bgimage_upgrade($oldversion) { 34 | global $DB; 35 | 36 | if ($oldversion < 2016120501) { 37 | // Go through each 'image' element and update the file stored information. 38 | if ($images = $DB->get_records_select('customcert_elements', $DB->sql_compare_text('element') . ' = \'bgimage\'')) { 39 | // Create a file storage instance we are going to use to create pathname hashes. 40 | $fs = get_file_storage(); 41 | // Go through and update the details. 42 | foreach ($images as $image) { 43 | // Get the current data we have stored for this element. 44 | $elementinfo = json_decode($image->data); 45 | if ($file = $fs->get_file_by_hash($elementinfo->pathnamehash)) { 46 | $arrtostore = array( 47 | 'contextid' => $file->get_contextid(), 48 | 'filearea' => $file->get_filearea(), 49 | 'itemid' => $file->get_itemid(), 50 | 'filepath' => $file->get_filepath(), 51 | 'filename' => $file->get_filename(), 52 | 'width' => (int) $elementinfo->width, 53 | 'height' => (int) $elementinfo->height 54 | ); 55 | $arrtostore = json_encode($arrtostore); 56 | $DB->set_field('customcert_elements', 'data', $arrtostore, array('id' => $image->id)); 57 | } 58 | } 59 | } 60 | 61 | // Savepoint reached. 62 | upgrade_plugin_savepoint(true, 2016120501, 'customcertelement', 'bgimage'); 63 | } 64 | 65 | return true; 66 | } 67 | -------------------------------------------------------------------------------- /classes/admin_setting_link.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Creates an upload form on the settings page. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | require_once($CFG->libdir.'/adminlib.php'); 30 | 31 | /** 32 | * Class extends admin setting class to allow/process an uploaded file 33 | * 34 | * @package mod_customcert 35 | * @copyright 2013 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class admin_setting_link extends \admin_setting_configtext { 39 | 40 | /** 41 | * @var string the link. 42 | */ 43 | protected $link; 44 | 45 | /** 46 | * @var string the link name. 47 | */ 48 | protected $linkname; 49 | 50 | /** 51 | * The admin_setting_link constructor. 52 | * 53 | * @param string $name 54 | * @param string $visiblename 55 | * @param string $description 56 | * @param string $linkname 57 | * @param mixed|string $link 58 | * @param int|null $defaultsetting 59 | * @param string $paramtype 60 | * @param null $size 61 | */ 62 | public function __construct($name, $visiblename, $description, $linkname, $link, $defaultsetting, 63 | $paramtype = PARAM_RAW, $size=null) { 64 | $this->link = $link; 65 | $this->linkname = $linkname; 66 | parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype, $size); 67 | } 68 | 69 | /** 70 | * Output the link to the upload image page. 71 | * 72 | * @param mixed $data 73 | * @param string $query 74 | * @return string 75 | */ 76 | public function output_html($data, $query = '') { 77 | // Create a dummy variable for this field to avoid being redirected back to the upgrade settings page. 78 | $this->config_write($this->name, ''); 79 | 80 | return format_admin_setting($this, $this->visiblename, 81 | \html_writer::link($this->link, $this->linkname), $this->description, true, '', null, $query); 82 | } 83 | } -------------------------------------------------------------------------------- /backup/moodle2/backup_customcert_activity_task.class.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the backup tasks that provides all the settings and steps to perform a backup of the activity. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | require_once($CFG->dirroot . '/mod/customcert/backup/moodle2/backup_customcert_stepslib.php'); 28 | 29 | /** 30 | * Handles creating tasks to peform in order to create the backup. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class backup_customcert_activity_task extends backup_activity_task { 37 | 38 | /** 39 | * Define particular settings this activity can have. 40 | */ 41 | protected function define_my_settings() { 42 | // No particular settings for this activity. 43 | } 44 | 45 | /** 46 | * Define particular steps this activity can have. 47 | */ 48 | protected function define_my_steps() { 49 | // The customcert only has one structure step. 50 | $this->add_step(new backup_customcert_activity_structure_step('customcert_structure', 'customcert.xml')); 51 | } 52 | 53 | /** 54 | * Code the transformations to perform in the activity in order to get transportable (encoded) links. 55 | * 56 | * @param string $content 57 | * @return mixed|string 58 | */ 59 | static public function encode_content_links($content) { 60 | global $CFG; 61 | 62 | $base = preg_quote($CFG->wwwroot, "/"); 63 | 64 | // Link to the list of customcerts. 65 | $search = "/(".$base."\/mod\/customcert\/index.php\?id\=)([0-9]+)/"; 66 | $content = preg_replace($search, '$@CUSTOMCERTINDEX*$2@$', $content); 67 | 68 | // Link to customcert view by moduleid. 69 | $search = "/(".$base."\/mod\/customcert\/view.php\?id\=)([0-9]+)/"; 70 | $content = preg_replace($search, '$@CUSTOMCERTVIEWBYID*$2@$', $content); 71 | 72 | return $content; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /classes/plugininfo/customcertelement.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Subplugin info class. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | namespace mod_customcert\plugininfo; 25 | 26 | use core\plugininfo\base; 27 | 28 | defined('MOODLE_INTERNAL') || die(); 29 | 30 | /** 31 | * Subplugin info class. 32 | * 33 | * @package mod_customcert 34 | * @copyright 2013 Mark Nelson 35 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 | */ 37 | class customcertelement extends base { 38 | 39 | /** 40 | * Do not allow users to uninstall these plugins as it could cause customcerts to break. 41 | * 42 | * @return bool 43 | */ 44 | public function is_uninstall_allowed() { 45 | return false; 46 | } 47 | 48 | /** 49 | * Loads plugin settings to the settings tree. 50 | * 51 | * @param \part_of_admin_tree $adminroot 52 | * @param string $parentnodename 53 | * @param bool $hassiteconfig whether the current user has moodle/site:config capability 54 | */ 55 | public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) { 56 | global $CFG, $USER, $DB, $OUTPUT, $PAGE; 57 | $ADMIN = $adminroot; 58 | $plugininfo = $this; 59 | 60 | if (!$this->is_installed_and_upgraded()) { 61 | return; 62 | } 63 | 64 | if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) { 65 | return; 66 | } 67 | 68 | $section = $this->get_settings_section_name(); 69 | $settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', false); 70 | 71 | include($this->full_path('settings.php')); 72 | $ADMIN->add($parentnodename, $settings); 73 | } 74 | 75 | /** 76 | * Get the settings section name. 77 | * 78 | * @return null|string the settings section name. 79 | */ 80 | public function get_settings_section_name() { 81 | if (file_exists($this->full_path('settings.php'))) { 82 | return 'customcertelement_' . $this->name; 83 | } else { 84 | return null; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /classes/output/verify_certificate_results.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains class used to prepare verification results for display. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\output; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | use renderable; 30 | use templatable; 31 | 32 | /** 33 | * Class to prepare verification results for display. 34 | * 35 | * @package mod_customcert 36 | * @copyright 2017 Mark Nelson 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 | */ 39 | class verify_certificate_results implements templatable, renderable { 40 | 41 | /** 42 | * @var bool Was the code successfully verified? 43 | */ 44 | public $success; 45 | 46 | /** 47 | * @var string The message to display. 48 | */ 49 | public $message; 50 | 51 | /** 52 | * @var array The certificates issued with the matching code. 53 | */ 54 | public $issues; 55 | 56 | /** 57 | * Constructor. 58 | * 59 | * @param \stdClass $result 60 | */ 61 | public function __construct($result) { 62 | $this->success = $result->success; 63 | if ($this->success) { 64 | $this->message = get_string('verified', 'customcert'); 65 | } else { 66 | $this->message = get_string('notverified', 'customcert'); 67 | } 68 | $this->issues = $result->issues; 69 | } 70 | 71 | /** 72 | * Function to export the renderer data in a format that is suitable for a mustache template. 73 | * 74 | * @param \renderer_base $output Used to do a final render of any components that need to be rendered for export. 75 | * @return \stdClass|array 76 | */ 77 | public function export_for_template(\renderer_base $output) { 78 | $result = new \stdClass(); 79 | $result->success = $this->success; 80 | $result->message = $this->message; 81 | $result->issues = array(); 82 | foreach ($this->issues as $issue) { 83 | $resultissue = new verify_certificate_result($issue); 84 | $result->issues[] = $resultissue->export_for_template($output); 85 | } 86 | 87 | return $result; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /element/code/classes/element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the customcert element code's core interaction API. 19 | * 20 | * @package customcertelement_code 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_code; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The customcert element code's core interaction API. 31 | * 32 | * @package customcertelement_code 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element extends \mod_customcert\element { 37 | 38 | /** 39 | * Handles rendering the element on the pdf. 40 | * 41 | * @param \pdf $pdf the pdf object 42 | * @param bool $preview true if it is a preview, false otherwise 43 | * @param \stdClass $user the user we are rendering this for 44 | */ 45 | public function render($pdf, $preview, $user) { 46 | global $DB; 47 | 48 | if ($preview) { 49 | $code = \mod_customcert\certificate::generate_code(); 50 | } else { 51 | // Get the page. 52 | $page = $DB->get_record('customcert_pages', array('id' => $this->get_pageid()), '*', MUST_EXIST); 53 | // Get the customcert this page belongs to. 54 | $customcert = $DB->get_record('customcert', array('templateid' => $page->templateid), '*', MUST_EXIST); 55 | // Now we can get the issue for this user. 56 | $issue = $DB->get_record('customcert_issues', array('userid' => $user->id, 'customcertid' => $customcert->id), 57 | '*', IGNORE_MULTIPLE); 58 | $code = $issue->code; 59 | } 60 | 61 | \mod_customcert\element_helper::render_content($pdf, $this, $code); 62 | } 63 | 64 | /** 65 | * Render the element in html. 66 | * 67 | * This function is used to render the element when we are using the 68 | * drag and drop interface to position it. 69 | * 70 | * @return string the html 71 | */ 72 | public function render_html() { 73 | $code = \mod_customcert\certificate::generate_code(); 74 | 75 | return \mod_customcert\element_helper::render_html_content($this, $code); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /classes/load_template_form.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the form for loading customcert templates. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 28 | 29 | require_once($CFG->libdir . '/formslib.php'); 30 | 31 | /** 32 | * The form for loading customcert templates. 33 | * 34 | * @package mod_customcert 35 | * @copyright 2013 Mark Nelson 36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 | */ 38 | class load_template_form extends \moodleform { 39 | 40 | /** 41 | * Form definition. 42 | */ 43 | public function definition() { 44 | global $DB; 45 | 46 | $mform =& $this->_form; 47 | 48 | // Get the context. 49 | $context = $this->_customdata['context']; 50 | 51 | $mform->addElement('header', 'loadtemplateheader', get_string('loadtemplate', 'customcert')); 52 | 53 | // Display a link to the manage templates page. 54 | if ($context->contextlevel != CONTEXT_SYSTEM && has_capability('mod/customcert:manage', \context_system::instance())) { 55 | $link = \html_writer::link(new \moodle_url('/mod/customcert/manage_templates.php'), 56 | get_string('managetemplates', 'customcert')); 57 | $mform->addElement('static', 'managetemplates', '', $link); 58 | } 59 | 60 | $templates = $DB->get_records_menu('customcert_templates', 61 | array('contextid' => \context_system::instance()->id), 'name ASC', 'id, name'); 62 | if ($templates) { 63 | $group = array(); 64 | $group[] = $mform->createElement('select', 'ltid', '', $templates); 65 | $group[] = $mform->createElement('submit', 'loadtemplatesubmit', get_string('load', 'customcert')); 66 | $mform->addElement('group', 'loadtemplategroup', '', $group, '', false); 67 | $mform->setType('ltid', PARAM_INT); 68 | } else { 69 | $msg = \html_writer::tag('div', get_string('notemplates', 'customcert'), array('class' => 'alert')); 70 | $mform->addElement('static', 'notemplates', '', $msg); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /classes/grade_information.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains the class that provides a grade object to be used by elements for display purposes. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The class that provides a grade object to be used by elements for display purposes. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2017 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class grade_information { 37 | 38 | /** 39 | * @var string The grade name. 40 | */ 41 | protected $name; 42 | 43 | /** 44 | * @var float The raw grade. 45 | */ 46 | protected $grade; 47 | 48 | /** 49 | * @var string The grade to display 50 | */ 51 | protected $displaygrade; 52 | 53 | /** 54 | * @var int The date it was graded. 55 | */ 56 | protected $dategraded; 57 | 58 | /** 59 | * The constructor. 60 | * 61 | * @param string $name 62 | * @param float $grade 63 | * @param string $displaygrade 64 | * @param int $dategraded 65 | */ 66 | public function __construct($name, $grade, $displaygrade, $dategraded) { 67 | $this->name = $name; 68 | $this->grade = $grade; 69 | $this->displaygrade = $displaygrade; 70 | $this->dategraded = $dategraded; 71 | } 72 | 73 | /** 74 | * Returns the name. 75 | * 76 | * @return string 77 | */ 78 | public function get_name() { 79 | return $this->name; 80 | } 81 | 82 | /** 83 | * Returns the raw grade. 84 | * 85 | * @return float 86 | */ 87 | public function get_grade() { 88 | return $this->grade; 89 | } 90 | 91 | /** 92 | * Returns the display grade. 93 | * 94 | * @return string 95 | */ 96 | public function get_displaygrade() { 97 | return $this->displaygrade; 98 | } 99 | 100 | /** 101 | * Returns the date it was graded. 102 | * 103 | * @return int 104 | */ 105 | public function get_dategraded() { 106 | return $this->dategraded; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /amd/build/rearrange-area.min.js: -------------------------------------------------------------------------------- 1 | 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)}}}); 2 | //# sourceMappingURL=rearrange-area.min.js.map 3 | -------------------------------------------------------------------------------- /element/categoryname/classes/element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the customcert element categoryname's core interaction API. 19 | * 20 | * @package customcertelement_categoryname 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_categoryname; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The customcert element categoryname's core interaction API. 31 | * 32 | * @package customcertelement_categoryname 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element extends \mod_customcert\element { 37 | 38 | /** 39 | * Handles rendering the element on the pdf. 40 | * 41 | * @param \pdf $pdf the pdf object 42 | * @param bool $preview true if it is a preview, false otherwise 43 | * @param \stdClass $user the user we are rendering this for 44 | */ 45 | public function render($pdf, $preview, $user) { 46 | \mod_customcert\element_helper::render_content($pdf, $this, $this->get_category_name()); 47 | } 48 | 49 | /** 50 | * Render the element in html. 51 | * 52 | * This function is used to render the element when we are using the 53 | * drag and drop interface to position it. 54 | * 55 | * @return string the html 56 | */ 57 | public function render_html() { 58 | return \mod_customcert\element_helper::render_html_content($this, $this->get_category_name()); 59 | } 60 | 61 | /** 62 | * Helper function that returns the category name. 63 | * 64 | * @return string 65 | */ 66 | protected function get_category_name() : string { 67 | global $DB, $SITE; 68 | 69 | $courseid = \mod_customcert\element_helper::get_courseid($this->get_id()); 70 | $course = get_course($courseid); 71 | $context = \mod_customcert\element_helper::get_context($this->get_id()); 72 | 73 | // Check that there is a course category available. 74 | if (!empty($course->category)) { 75 | $categoryname = $DB->get_field('course_categories', 'name', array('id' => $course->category), MUST_EXIST); 76 | } else { // Must be in a site template. 77 | $categoryname = $SITE->fullname; 78 | } 79 | 80 | return format_string($categoryname, true, ['context' => $context]); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /yui/build/moodle-mod_customcert-rearrange/moodle-mod_customcert-rearrange-min.js: -------------------------------------------------------------------------------- 1 | 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"]}); -------------------------------------------------------------------------------- /element/daterange/lang/en/customcertelement_daterange.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Strings for component 'customcertelement_daterange', language 'en'. 19 | * 20 | * @package customcertelement_daterange 21 | * @copyright 2018 Dmitrii Metelkin 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | $string['addrange'] = 'Add another range'; 28 | $string['completiondate'] = 'Completion date'; 29 | $string['courseenddate'] = 'Course end date'; 30 | $string['coursegradedate'] = 'Course grade date'; 31 | $string['coursestartdate'] = 'Course start date'; 32 | $string['currentdate'] = 'Current date'; 33 | $string['dateitem'] = 'Date item'; 34 | $string['dateitem_help'] = 'This will be the date that is printed on the certificate'; 35 | $string['dateranges'] = 'Date ranges'; 36 | $string['datestring'] = 'String'; 37 | $string['end'] = 'End'; 38 | $string['error:atleastone'] = 'You must have at least one date range configured'; 39 | $string['error:datestring'] = 'You must provide string representation for the date range'; 40 | $string['error:enddate'] = 'End date must occur after the start date'; 41 | $string['error:recurring'] = 'Recurring range must not be longer than 12 months'; 42 | $string['fallbackstring'] = 'Fallback string'; 43 | $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.'; 44 | $string['help'] = 'Configure a string representation for your date ranges.

If your ranges overlap the first matched date range will be applied.'; 45 | $string['issueddate'] = 'Issued date'; 46 | $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.'; 47 | $string['pluginname'] = 'Date range'; 48 | $string['preview'] = 'Preview {$a}'; 49 | $string['privacy:metadata'] = 'The Date range plugin does not store any personal data.'; 50 | $string['recurring'] = 'Recurring'; 51 | $string['recurring_help'] = 'If you mark a date range as recurring then the configured year will not be considered.'; 52 | $string['setdeleted'] = 'Delete'; 53 | $string['start'] = 'Start'; 54 | -------------------------------------------------------------------------------- /includes/colourpicker.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the form element for handling the colour picker. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 26 | 27 | require_once($CFG->dirroot . '/lib/form/editor.php'); 28 | 29 | /** 30 | * Form element for handling the colour picker. 31 | * 32 | * @package mod_customcert 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class moodlequickform_customcert_colourpicker extends moodlequickform_editor { 37 | 38 | /** 39 | * Sets the value of the form element 40 | * 41 | * @param string $value 42 | */ 43 | public function setvalue($value) { 44 | $this->updateAttributes(array('value' => $value)); 45 | } 46 | 47 | /** 48 | * Gets the value of the form element 49 | */ 50 | public function getvalue() { 51 | return $this->getAttribute('value'); 52 | } 53 | 54 | /** 55 | * Returns the html string to display this element. 56 | * 57 | * @return string 58 | */ 59 | public function tohtml() { 60 | global $PAGE, $OUTPUT; 61 | 62 | $PAGE->requires->js_init_call('M.util.init_colour_picker', array($this->getAttribute('id'), null)); 63 | $content = ''; 64 | $content .= html_writer::start_tag('div', array('class' => 'form-colourpicker defaultsnext')); 65 | $content .= html_writer::tag('div', $OUTPUT->pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', 66 | array('class' => 'loadingicon')), array('class' => 'admin_colourpicker clearfix')); 67 | $content .= html_writer::empty_tag('input', array('type' => 'text', 'id' => $this->getAttribute('id'), 68 | 'name' => $this->getName(), 'value' => $this->getValue(), 'size' => '12')); 69 | $content .= html_writer::end_tag('div'); 70 | 71 | return $content; 72 | } 73 | 74 | /** 75 | * Function to export the renderer data in a format that is suitable for a mustache template. 76 | * 77 | * @param \renderer_base $output Used to do a final render of any components that need to be rendered for export. 78 | * @return \stdClass|array 79 | */ 80 | public function export_for_template(renderer_base $output) { 81 | $context = $this->export_for_template_base($output); 82 | $context['html'] = $this->toHtml(); 83 | 84 | return $context; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /classes/output/verify_certificate_result.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Contains class used to prepare a verification result for display. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2017 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert\output; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | use renderable; 30 | use templatable; 31 | 32 | /** 33 | * Class to prepare a verification result for display. 34 | * 35 | * @package mod_customcert 36 | * @copyright 2017 Mark Nelson 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 | */ 39 | class verify_certificate_result implements templatable, renderable { 40 | 41 | /** 42 | * @var string The URL to the user's profile. 43 | */ 44 | public $userprofileurl; 45 | 46 | /** 47 | * @var string The user's fullname. 48 | */ 49 | public $userfullname; 50 | 51 | /** 52 | * @var string The URL to the course page. 53 | */ 54 | public $courseurl; 55 | 56 | /** 57 | * @var string The course's fullname. 58 | */ 59 | public $coursefullname; 60 | 61 | /** 62 | * @var string The certificate's name. 63 | */ 64 | public $certificatename; 65 | 66 | /** 67 | * Constructor. 68 | * 69 | * @param \stdClass $result 70 | */ 71 | public function __construct($result) { 72 | $cm = get_coursemodule_from_instance('customcert', $result->certificateid); 73 | $context = \context_module::instance($cm->id); 74 | 75 | $this->userprofileurl = new \moodle_url('/user/view.php', array('id' => $result->userid, 76 | 'course' => $result->courseid)); 77 | $this->userfullname = fullname($result); 78 | $this->courseurl = new \moodle_url('/course/view.php', array('id' => $result->courseid)); 79 | $this->coursefullname = format_string($result->coursefullname, true, ['context' => $context]); 80 | $this->certificatename = format_string($result->certificatename, true, ['context' => $context]); 81 | } 82 | 83 | /** 84 | * Function to export the renderer data in a format that is suitable for a mustache template. 85 | * 86 | * @param \renderer_base $output Used to do a final render of any components that need to be rendered for export. 87 | * @return \stdClass|array 88 | */ 89 | public function export_for_template(\renderer_base $output) { 90 | $result = new \stdClass(); 91 | $result->userprofileurl = $this->userprofileurl; 92 | $result->userfullname = $this->userfullname; 93 | $result->coursefullname = $this->coursefullname; 94 | $result->courseurl = $this->courseurl; 95 | $result->certificatename = $this->certificatename; 96 | 97 | return $result; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /classes/edit_element_form.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the form for handling editing a customcert element. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_customcert; 26 | 27 | defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); 28 | 29 | require_once($CFG->dirroot . '/course/moodleform_mod.php'); 30 | require_once($CFG->dirroot . '/mod/customcert/includes/colourpicker.php'); 31 | 32 | \MoodleQuickForm::registerElementType('customcert_colourpicker', 33 | $CFG->dirroot . '/mod/customcert/includes/colourpicker.php', 'MoodleQuickForm_customcert_colourpicker'); 34 | 35 | /** 36 | * The form for handling editing a customcert element. 37 | * 38 | * @package mod_customcert 39 | * @copyright 2013 Mark Nelson 40 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 | */ 42 | class edit_element_form extends \moodleform { 43 | 44 | /** 45 | * @var \mod_customcert\element The element object. 46 | */ 47 | protected $element; 48 | 49 | /** 50 | * Form definition. 51 | */ 52 | public function definition() { 53 | $mform =& $this->_form; 54 | 55 | $mform->updateAttributes(array('id' => 'editelementform')); 56 | 57 | $element = $this->_customdata['element']; 58 | 59 | // Add the field for the name of the element, this is required for all elements. 60 | $mform->addElement('text', 'name', get_string('elementname', 'customcert'), 'maxlength="255"'); 61 | $mform->setType('name', PARAM_TEXT); 62 | $mform->setDefault('name', get_string('pluginname', 'customcertelement_' . $element->element)); 63 | $mform->addRule('name', get_string('required'), 'required', null, 'client'); 64 | $mform->addHelpButton('name', 'elementname', 'customcert'); 65 | 66 | $this->element = \mod_customcert\element_factory::get_element_instance($element); 67 | $this->element->set_edit_element_form($this); 68 | $this->element->render_form_elements($mform); 69 | 70 | $this->add_action_buttons(true); 71 | } 72 | 73 | /** 74 | * Fill in the current page data for this customcert. 75 | */ 76 | public function definition_after_data() { 77 | $this->element->definition_after_data($this->_form); 78 | } 79 | 80 | /** 81 | * Validation. 82 | * 83 | * @param array $data 84 | * @param array $files 85 | * @return array the errors that were found 86 | */ 87 | public function validation($data, $files) { 88 | $errors = array(); 89 | 90 | if (\core_text::strlen($data['name']) > 255) { 91 | $errors['name'] = get_string('nametoolong', 'customcert'); 92 | } 93 | 94 | $errors += $this->element->validate_form_elements($data, $files); 95 | 96 | return $errors; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /my_certificates.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Handles viewing the certificates for a certain user. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2016 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once('../../config.php'); 26 | 27 | $userid = optional_param('userid', $USER->id, PARAM_INT); 28 | $download = optional_param('download', null, PARAM_ALPHA); 29 | $downloadcert = optional_param('downloadcert', '', PARAM_BOOL); 30 | if ($downloadcert) { 31 | $certificateid = required_param('certificateid', PARAM_INT); 32 | $customcert = $DB->get_record('customcert', array('id' => $certificateid), '*', MUST_EXIST); 33 | 34 | // Check there exists an issued certificate for this user. 35 | if (!$issue = $DB->get_record('customcert_issues', ['userid' => $userid, 'customcertid' => $customcert->id])) { 36 | throw new moodle_exception('You have not been issued a certificate'); 37 | } 38 | } 39 | $page = optional_param('page', 0, PARAM_INT); 40 | $perpage = optional_param('perpage', \mod_customcert\certificate::CUSTOMCERT_PER_PAGE, PARAM_INT); 41 | $pageurl = $url = new moodle_url('/mod/customcert/my_certificates.php', array('userid' => $userid, 42 | 'page' => $page, 'perpage' => $perpage)); 43 | 44 | // Requires a login. 45 | require_login(); 46 | 47 | // Check that we have a valid user. 48 | $user = \core_user::get_user($userid, '*', MUST_EXIST); 49 | 50 | // If we are viewing certificates that are not for the currently logged in user then do a capability check. 51 | if (($userid != $USER->id) && !has_capability('mod/customcert:viewallcertificates', context_system::instance())) { 52 | print_error('You are not allowed to view these certificates'); 53 | } 54 | 55 | // Check if we requested to download a certificate. 56 | if ($downloadcert) { 57 | $template = $DB->get_record('customcert_templates', array('id' => $customcert->templateid), '*', MUST_EXIST); 58 | $template = new \mod_customcert\template($template); 59 | $template->generate_pdf(false, $userid); 60 | exit(); 61 | } 62 | 63 | $table = new \mod_customcert\my_certificates_table($userid, $download); 64 | $table->define_baseurl($pageurl); 65 | 66 | if ($table->is_downloading()) { 67 | $table->download(); 68 | exit(); 69 | } 70 | 71 | $PAGE->set_url($pageurl); 72 | $PAGE->set_context(context_user::instance($userid)); 73 | $PAGE->set_title(get_string('mycertificates', 'customcert')); 74 | $PAGE->set_pagelayout('standard'); 75 | $PAGE->navigation->extend_for_user($user); 76 | 77 | // Additional page setup. 78 | $PAGE->navbar->add(get_string('profile'), new moodle_url('/user/profile.php', array('id' => $userid))); 79 | $PAGE->navbar->add(get_string('mycertificates', 'customcert')); 80 | 81 | echo $OUTPUT->header(); 82 | echo $OUTPUT->heading(get_string('mycertificates', 'customcert')); 83 | echo html_writer::div(get_string('mycertificatesdescription', 'customcert')); 84 | $table->out($perpage, false); 85 | echo $OUTPUT->footer(); 86 | -------------------------------------------------------------------------------- /mobile/pluginfile.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Serves files for the mobile app. 19 | * 20 | * @package mod_customcert 21 | * @copyright 2018 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | /** 26 | * AJAX_SCRIPT - exception will be converted into JSON. 27 | */ 28 | define('AJAX_SCRIPT', true); 29 | 30 | /** 31 | * NO_MOODLE_COOKIES - we don't want any cookie. 32 | */ 33 | define('NO_MOODLE_COOKIES', true); 34 | 35 | require_once('../../../config.php'); 36 | require_once($CFG->libdir . '/filelib.php'); 37 | require_once($CFG->libdir . '/completionlib.php'); 38 | require_once($CFG->dirroot . '/webservice/lib.php'); 39 | 40 | // Allow CORS requests. 41 | header('Access-Control-Allow-Origin: *'); 42 | 43 | // Authenticate the user. 44 | $token = required_param('token', PARAM_ALPHANUM); 45 | $certificateid = required_param('certificateid', PARAM_INT); 46 | $userid = required_param('userid', PARAM_INT); 47 | 48 | $webservicelib = new webservice(); 49 | $authenticationinfo = $webservicelib->authenticate_user($token); 50 | 51 | // Check the service allows file download. 52 | $enabledfiledownload = (int) ($authenticationinfo['service']->downloadfiles); 53 | if (empty($enabledfiledownload)) { 54 | throw new webservice_access_exception('Web service file downloading must be enabled in external service settings'); 55 | } 56 | 57 | $cm = get_coursemodule_from_instance('customcert', $certificateid, 0, false, MUST_EXIST); 58 | $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); 59 | $certificate = $DB->get_record('customcert', ['id' => $certificateid], '*', MUST_EXIST); 60 | $template = $DB->get_record('customcert_templates', ['id' => $certificate->templateid], '*', MUST_EXIST); 61 | 62 | // Capabilities check. 63 | require_capability('mod/customcert:view', \context_module::instance($cm->id)); 64 | if ($userid != $USER->id) { 65 | require_capability('mod/customcert:viewreport', \context_module::instance($cm->id)); 66 | } else { 67 | // Make sure the user has met the required time. 68 | if ($certificate->requiredtime) { 69 | if (\mod_customcert\certificate::get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { 70 | exit(); 71 | } 72 | } 73 | } 74 | 75 | $issue = $DB->get_record('customcert_issues', ['customcertid' => $certificateid, 'userid' => $userid]); 76 | 77 | // If we are doing it for the logged in user then we want to issue the certificate. 78 | if (!$issue) { 79 | // If the other user doesn't have an issue, then there is nothing to do. 80 | if ($userid != $USER->id) { 81 | exit(); 82 | } 83 | 84 | \mod_customcert\certificate::issue_certificate($certificate->id, $USER->id); 85 | 86 | // Set the custom certificate as viewed. 87 | $completion = new completion_info($course); 88 | $completion->set_module_viewed($cm); 89 | } 90 | 91 | // Now we want to generate the PDF. 92 | $template = new \mod_customcert\template($template); 93 | $template->generate_pdf(false, $userid); 94 | exit(); 95 | -------------------------------------------------------------------------------- /amd/src/dialogue.js: -------------------------------------------------------------------------------- 1 | // This file is part of Moodle - http://moodle.org/ 2 | // 3 | // Moodle is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Moodle is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Moodle. If not, see . 15 | 16 | /** 17 | * Wrapper for the YUI M.core.notification class. Allows us to 18 | * use the YUI version in AMD code until it is replaced. 19 | * 20 | * @module mod_customcert/dialogue 21 | * @package mod_customcert 22 | * @copyright 2016 Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | define(['core/yui'], function(Y) { 26 | 27 | /** 28 | * Constructor 29 | * 30 | * @param {String} title Title for the window. 31 | * @param {String} content The content for the window. 32 | * @param {function} afterShow Callback executed after the window is opened. 33 | * @param {function} afterHide Callback executed after the window is closed. 34 | * @param {Boolean} wide Specify we want an extra wide dialogue (the size is standard, but wider than the default). 35 | */ 36 | var dialogue = function(title, content, afterShow, afterHide, wide) { 37 | this.yuiDialogue = null; 38 | var parent = this; 39 | 40 | // Default for wide is false. 41 | if (typeof wide == 'undefined') { 42 | wide = false; 43 | } 44 | 45 | Y.use('moodle-core-notification', 'timers', function() { 46 | var width = '480px'; 47 | if (wide) { 48 | width = '800px'; 49 | } 50 | 51 | parent.yuiDialogue = new M.core.dialogue({ 52 | headerContent: title, 53 | bodyContent: content, 54 | draggable: true, 55 | visible: false, 56 | center: true, 57 | modal: true, 58 | width: width 59 | }); 60 | 61 | parent.yuiDialogue.after('visibleChange', function(e) { 62 | if (e.newVal) { 63 | // Delay the callback call to the next tick, otherwise it can happen that it is 64 | // executed before the dialogue constructor returns. 65 | if ((typeof afterShow !== 'undefined')) { 66 | Y.soon(function() { 67 | afterShow(parent); 68 | parent.yuiDialogue.centerDialogue(); 69 | }); 70 | } 71 | } else { 72 | if ((typeof afterHide !== 'undefined')) { 73 | Y.soon(function() { 74 | afterHide(parent); 75 | }); 76 | } 77 | } 78 | }); 79 | 80 | parent.yuiDialogue.show(); 81 | }); 82 | }; 83 | 84 | /** 85 | * Close this window. 86 | */ 87 | dialogue.prototype.close = function() { 88 | this.yuiDialogue.hide(); 89 | this.yuiDialogue.destroy(); 90 | }; 91 | 92 | /** 93 | * Get content. 94 | * 95 | * @returns {HTMLElement} 96 | */ 97 | dialogue.prototype.getContent = function() { 98 | return this.yuiDialogue.bodyNode.getDOMNode(); 99 | }; 100 | 101 | return dialogue; 102 | }); 103 | -------------------------------------------------------------------------------- /element/text/classes/element.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * This file contains the customcert element text's core interaction API. 19 | * 20 | * @package customcertelement_text 21 | * @copyright 2013 Mark Nelson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace customcertelement_text; 26 | 27 | defined('MOODLE_INTERNAL') || die(); 28 | 29 | /** 30 | * The customcert element text's core interaction API. 31 | * 32 | * @package customcertelement_text 33 | * @copyright 2013 Mark Nelson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class element extends \mod_customcert\element { 37 | 38 | /** 39 | * This function renders the form elements when adding a customcert element. 40 | * 41 | * @param \MoodleQuickForm $mform the edit_form instance 42 | */ 43 | public function render_form_elements($mform) { 44 | $mform->addElement('textarea', 'text', get_string('text', 'customcertelement_text')); 45 | $mform->setType('text', PARAM_RAW); 46 | $mform->addHelpButton('text', 'text', 'customcertelement_text'); 47 | 48 | parent::render_form_elements($mform); 49 | } 50 | 51 | /** 52 | * This will handle how form data will be saved into the data column in the 53 | * customcert_elements table. 54 | * 55 | * @param \stdClass $data the form data 56 | * @return string the text 57 | */ 58 | public function save_unique_data($data) { 59 | return $data->text; 60 | } 61 | 62 | /** 63 | * Handles rendering the element on the pdf. 64 | * 65 | * @param \pdf $pdf the pdf object 66 | * @param bool $preview true if it is a preview, false otherwise 67 | * @param \stdClass $user the user we are rendering this for 68 | */ 69 | public function render($pdf, $preview, $user) { 70 | \mod_customcert\element_helper::render_content($pdf, $this, $this->get_text()); 71 | } 72 | 73 | /** 74 | * Render the element in html. 75 | * 76 | * This function is used to render the element when we are using the 77 | * drag and drop interface to position it. 78 | * 79 | * @return string the html 80 | */ 81 | public function render_html() { 82 | return \mod_customcert\element_helper::render_html_content($this, $this->get_text()); 83 | } 84 | 85 | /** 86 | * Sets the data on the form when editing an element. 87 | * 88 | * @param \MoodleQuickForm $mform the edit_form instance 89 | */ 90 | public function definition_after_data($mform) { 91 | if (!empty($this->get_data())) { 92 | $element = $mform->getElement('text'); 93 | $element->setValue($this->get_data()); 94 | } 95 | parent::definition_after_data($mform); 96 | } 97 | 98 | /** 99 | * Helper function that returns the text. 100 | * 101 | * @return string 102 | */ 103 | protected function get_text() : string { 104 | $context = \mod_customcert\element_helper::get_context($this->get_id()); 105 | return format_text($this->get_data(), FORMAT_HTML, ['context' => $context]); 106 | } 107 | } 108 | --------------------------------------------------------------------------------