├── README.txt ├── backup └── moodle2 │ ├── backup_certificate_activity_task.class.php │ ├── backup_certificate_settingslib.php │ ├── backup_certificate_stepslib.php │ ├── restore_certificate_activity_task.class.php │ └── restore_certificate_stepslib.php ├── classes ├── admin_setting_font.php ├── admin_setting_upload.php ├── event │ ├── course_module_instance_list_viewed.php │ └── course_module_viewed.php ├── external.php └── privacy │ └── provider.php ├── composer.json ├── db ├── access.php ├── install.xml ├── log.php ├── mobile.php ├── services.php └── upgrade.php ├── deprecatedlib.php ├── index.php ├── lang └── en │ └── certificate.php ├── lib.php ├── locallib.php ├── mobile └── mod_certificate.zip ├── mod_form.php ├── pix ├── borders │ ├── Fancy1-black.jpg │ ├── Fancy1-blue.jpg │ ├── Fancy1-brown.jpg │ ├── Fancy1-green.jpg │ ├── Fancy2-black.jpg │ ├── Fancy2-blue.jpg │ ├── Fancy2-brown.jpg │ └── Fancy2-green.jpg ├── icon.gif ├── seals │ ├── Fancy.png │ ├── Logo.png │ ├── Plain.png │ ├── Quality.png │ └── Teamwork.png ├── signatures │ ├── Line.png │ └── RVincent.png └── watermarks │ ├── Crest.png │ └── Fleursdelis.png ├── report.php ├── review.php ├── settings.php ├── tests ├── generator │ └── lib.php ├── generator_test.php └── privacy_test.php ├── type ├── A4_embedded │ └── certificate.php ├── A4_non_embedded │ └── certificate.php ├── letter_embedded │ └── certificate.php └── letter_non_embedded │ └── certificate.php ├── upload_image.php ├── upload_image_form.php ├── version.php └── view.php /README.txt: -------------------------------------------------------------------------------- 1 | QUICK INSTALL 2 | ============= 3 | 4 | There are two installation methods that are available. Follow one of these, then log into your Moodle site as an administrator and visit the notifications page to complete the install. 5 | 6 | ==================== MOST RECOMMENDED METHOD - Git ==================== 7 | 8 | If you do not have git installed, please see the below link. Please note, it is not necessary to set up the SSH Keys. This is only needed if you are going to create a repository of your own on github.com. 9 | 10 | Information on installing git - http://help.github.com/set-up-git-redirect/ 11 | 12 | Once you have git installed, simply visit the Moodle mod directory and clone git://github.com/markn86/moodle-mod_certificate.git, remember to rename the folder to certificate if you do not specify this in the clone command 13 | 14 | Eg. Linux command line would be as follow - 15 | 16 | git clone git://github.com/markn86/moodle-mod_certificate.git certificate 17 | 18 | Use git pull to update this repository periodically to ensure you have the latest version. 19 | 20 | ==================== Download the certificate module. ==================== 21 | 22 | Visit https://github.com/markn86/moodle-mod_certificate and download the zip, uncompress this zip and extract the folder. The folder will have a name similar to markn86-moodle-mod_certificate-c9fbadb, you MUST rename this to certificate. Place this folder in your mod folder in your Moodle directory. 23 | 24 | nb. The reason this is not the recommended method is due to the fact you have to over-write the contents of this folder to apply any future updates to the certificate module. In the above method there is a simple command to update the files. 25 | -------------------------------------------------------------------------------- /backup/moodle2/backup_certificate_activity_task.class.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * @package mod_certificate 20 | * @subpackage backup-moodle2 21 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once($CFG->dirroot . '/mod/certificate/backup/moodle2/backup_certificate_stepslib.php'); // Because it exists (must) 26 | require_once($CFG->dirroot . '/mod/certificate/backup/moodle2/backup_certificate_settingslib.php'); // Because it exists (optional) 27 | 28 | /** 29 | * certificate backup task that provides all the settings and steps to perform one 30 | * complete backup of the activity 31 | */ 32 | class backup_certificate_activity_task extends backup_activity_task { 33 | 34 | /** 35 | * Define (add) particular settings this activity can have 36 | */ 37 | protected function define_my_settings() { 38 | // No particular settings for this activity 39 | } 40 | 41 | /** 42 | * Define (add) particular steps this activity can have 43 | */ 44 | protected function define_my_steps() { 45 | // Certificate only has one structure step 46 | $this->add_step(new backup_certificate_activity_structure_step('certificate_structure', 'certificate.xml')); 47 | } 48 | 49 | /** 50 | * Code the transformations to perform in the activity in 51 | * order to get transportable (encoded) links 52 | */ 53 | static public function encode_content_links($content) { 54 | global $CFG; 55 | 56 | $base = preg_quote($CFG->wwwroot,"/"); 57 | 58 | // Link to the list of certificates 59 | $search="/(".$base."\/mod\/certificate\/index.php\?id\=)([0-9]+)/"; 60 | $content= preg_replace($search, '$@CERTIFICATEINDEX*$2@$', $content); 61 | 62 | // Link to certificate view by moduleid 63 | $search="/(".$base."\/mod\/certificate\/view.php\?id\=)([0-9]+)/"; 64 | $content= preg_replace($search, '$@CERTIFICATEVIEWBYID*$2@$', $content); 65 | 66 | return $content; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /backup/moodle2/backup_certificate_settingslib.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * @package mod_certificate 20 | * @subpackage backup-moodle2 21 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | // This activity has no particular settings but the inherited from the generic 26 | // backup_activity_task so here there isn't any class definition, like the ones 27 | // existing in /backup/moodle2/backup_settingslib.php (activities section) 28 | -------------------------------------------------------------------------------- /backup/moodle2/backup_certificate_stepslib.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * @package mod_certificate 20 | * @subpackage backup-moodle2 21 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | /** 26 | * Define all the backup steps that will be used by the backup_certificate_activity_task 27 | */ 28 | 29 | /** 30 | * Define the complete certificate structure for backup, with file and id annotations 31 | */ 32 | class backup_certificate_activity_structure_step extends backup_activity_structure_step { 33 | 34 | protected function define_structure() { 35 | 36 | // To know if we are including userinfo 37 | $userinfo = $this->get_setting_value('userinfo'); 38 | 39 | // Define each element separated 40 | $certificate = new backup_nested_element('certificate', array('id'), array( 41 | 'name', 'intro', 'introformat', 'emailteachers', 'emailothers', 42 | 'savecert', 'reportcert', 'delivery', 'certificatetype', 'orientation', 43 | 'borderstyle', 'bordercolor', 'printwmark', 'printdate', 'datefmt', 'printnumber', 44 | 'printgrade', 'gradefmt', 'printoutcome', 'printhours', 'printteacher', 'customtext', 45 | 'printsignature', 'printseal', 'timecreated', 'timemodified')); 46 | 47 | $issues = new backup_nested_element('issues'); 48 | 49 | $issue = new backup_nested_element('issue', array('id'), array( 50 | 'certificateid', 'userid', 'timecreated', 'code')); 51 | 52 | // Build the tree 53 | $certificate->add_child($issues); 54 | $issues->add_child($issue); 55 | 56 | // Define sources 57 | $certificate->set_source_table('certificate', array('id' => backup::VAR_ACTIVITYID)); 58 | 59 | // All the rest of elements only happen if we are including user info 60 | if ($userinfo) { 61 | $issue->set_source_table('certificate_issues', array('certificateid' => backup::VAR_PARENTID)); 62 | } 63 | 64 | // Annotate the user id's where required. 65 | $issue->annotate_ids('user', 'userid'); 66 | 67 | // Define file annotations 68 | $certificate->annotate_files('mod_certificate', 'intro', null); // This file area hasn't itemid 69 | $issue->annotate_files('mod_certificate', 'issue', 'id'); 70 | 71 | // Return the root element (certificate), wrapped into standard activity structure 72 | return $this->prepare_activity_structure($certificate); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /backup/moodle2/restore_certificate_activity_task.class.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * @package mod_certificate 20 | * @subpackage backup-moodle2 21 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | require_once($CFG->dirroot . '/mod/certificate/backup/moodle2/restore_certificate_stepslib.php'); // Because it exists (must) 28 | 29 | /** 30 | * certificate restore task that provides all the settings and steps to perform one 31 | * complete restore of the activity 32 | */ 33 | class restore_certificate_activity_task extends restore_activity_task { 34 | 35 | /** 36 | * Define (add) particular settings this activity can have 37 | */ 38 | protected function define_my_settings() { 39 | // No particular settings for this activity 40 | } 41 | 42 | /** 43 | * Define (add) particular steps this activity can have 44 | */ 45 | protected function define_my_steps() { 46 | // Certificate only has one structure step 47 | $this->add_step(new restore_certificate_activity_structure_step('certificate_structure', 'certificate.xml')); 48 | } 49 | 50 | /** 51 | * Define the contents in the activity that must be 52 | * processed by the link decoder 53 | */ 54 | static public function define_decode_contents() { 55 | $contents = array(); 56 | 57 | $contents[] = new restore_decode_content('certificate', array('intro'), 'certificate'); 58 | 59 | return $contents; 60 | } 61 | 62 | /** 63 | * Define the decoding rules for links belonging 64 | * to the activity to be executed by the link decoder 65 | */ 66 | static public function define_decode_rules() { 67 | $rules = array(); 68 | 69 | $rules[] = new restore_decode_rule('CERTIFICATEVIEWBYID', '/mod/certificate/view.php?id=$1', 'course_module'); 70 | $rules[] = new restore_decode_rule('CERTIFICATEINDEX', '/mod/certificate/index.php?id=$1', 'course'); 71 | 72 | return $rules; 73 | 74 | } 75 | 76 | /** 77 | * Define the restore log rules that will be applied 78 | * by the {@link restore_logs_processor} when restoring 79 | * certificate logs. It must return one array 80 | * of {@link restore_log_rule} objects 81 | */ 82 | static public function define_restore_log_rules() { 83 | $rules = array(); 84 | 85 | $rules[] = new restore_log_rule('certificate', 'add', 'view.php?id={course_module}', '{certificate}'); 86 | $rules[] = new restore_log_rule('certificate', 'update', 'view.php?id={course_module}', '{certificate}'); 87 | $rules[] = new restore_log_rule('certificate', 'view', 'view.php?id={course_module}', '{certificate}'); 88 | $rules[] = new restore_log_rule('certificate', 'received', 'report.php?a={certificate}', '{certificate}'); 89 | $rules[] = new restore_log_rule('certificate', 'view report', 'report.php?id={certificate}', '{certificate}'); 90 | 91 | return $rules; 92 | } 93 | 94 | /** 95 | * Define the restore log rules that will be applied 96 | * by the {@link restore_logs_processor} when restoring 97 | * course logs. It must return one array 98 | * of {@link restore_log_rule} objects 99 | * 100 | * Note this rules are applied when restoring course logs 101 | * by the restore final task, but are defined here at 102 | * activity level. All them are rules not linked to any module instance (cmid = 0) 103 | */ 104 | static public function define_restore_log_rules_for_course() { 105 | $rules = array(); 106 | 107 | // Fix old wrong uses (missing extension) 108 | $rules[] = new restore_log_rule('certificate', 'view all', 'index.php?id={course}', null); 109 | 110 | return $rules; 111 | } 112 | 113 | /* 114 | * This function is called after all the activities in the backup have been restored. 115 | * This allows us to get the new course module ids, as they may have been restored 116 | * after the certificate module, meaning no id was available at the time. 117 | */ 118 | public function after_restore() { 119 | global $DB; 120 | 121 | // Get the new module 122 | $sql = "SELECT c.* 123 | FROM {certificate} c 124 | INNER JOIN {course_modules} cm 125 | ON c.id = cm.instance 126 | WHERE cm.id = :cmid"; 127 | if ($certificate = $DB->get_record_sql($sql, (array('cmid'=>$this->get_moduleid())))) { 128 | // A flag to check if we need to update the database or not 129 | $update = false; 130 | if ($certificate->printdate > 2) { // If greater than 2, then it is a grade item value 131 | if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->printdate)) { 132 | $update = true; 133 | $certificate->printdate = $newitem->newitemid; 134 | } 135 | } 136 | if ($certificate->printgrade > 2) { 137 | if ($newitem = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'course_module', $certificate->printgrade)) { 138 | $update = true; 139 | $certificate->printgrade = $newitem->newitemid; 140 | } 141 | } 142 | if ($update) { 143 | // Update the certificate 144 | $DB->update_record('certificate', $certificate); 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /backup/moodle2/restore_certificate_stepslib.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * @package mod_certificate 20 | * @subpackage backup-moodle2 21 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | /** 26 | * Define all the restore steps that will be used by the restore_certificate_activity_task 27 | */ 28 | 29 | /** 30 | * Structure step to restore one certificate activity 31 | */ 32 | class restore_certificate_activity_structure_step extends restore_activity_structure_step { 33 | 34 | protected function define_structure() { 35 | 36 | $paths = array(); 37 | $userinfo = $this->get_setting_value('userinfo'); 38 | 39 | $paths[] = new restore_path_element('certificate', '/activity/certificate'); 40 | 41 | if ($userinfo) { 42 | $paths[] = new restore_path_element('certificate_issue', '/activity/certificate/issues/issue'); 43 | } 44 | 45 | // Return the paths wrapped into standard activity structure 46 | return $this->prepare_activity_structure($paths); 47 | } 48 | 49 | protected function process_certificate($data) { 50 | global $DB; 51 | 52 | $data = (object)$data; 53 | $oldid = $data->id; 54 | $data->course = $this->get_courseid(); 55 | $data->timecreated = $this->apply_date_offset($data->timecreated); 56 | $data->timemodified = $this->apply_date_offset($data->timemodified); 57 | 58 | // insert the certificate record 59 | $newitemid = $DB->insert_record('certificate', $data); 60 | // immediately after inserting "activity" record, call this 61 | $this->apply_activity_instance($newitemid); 62 | } 63 | 64 | protected function process_certificate_issue($data) { 65 | global $DB; 66 | 67 | $data = (object)$data; 68 | $oldid = $data->id; 69 | 70 | $data->certificateid = $this->get_new_parentid('certificate'); 71 | $data->timecreated = $this->apply_date_offset($data->timecreated); 72 | if ($data->userid > 0) { 73 | $data->userid = $this->get_mappingid('user', $data->userid); 74 | } 75 | 76 | $newitemid = $DB->insert_record('certificate_issues', $data); 77 | $this->set_mapping('certificate_issue', $oldid, $newitemid); 78 | } 79 | 80 | protected function after_execute() { 81 | // Add certificate related files, no need to match by itemname (just internally handled context) 82 | $this->add_related_files('mod_certificate', 'issue', 'certificate_issue'); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /classes/admin_setting_font.php: -------------------------------------------------------------------------------- 1 | . 15 | 16 | /** 17 | * Certificate module data generator. 18 | * 19 | * @package mod_certificate 20 | * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/} 21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 | * @author Petr Skoda 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | require_once($CFG->libdir.'/adminlib.php'); 28 | 29 | class mod_certificate_admin_setting_font extends admin_setting_configselect { 30 | /** 31 | * Constructor 32 | * @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting' for ones in config_plugins. 33 | * @param string $visiblename localised 34 | * @param string $description long localised info 35 | * @param string|int $defaultsetting 36 | */ 37 | public function __construct($name, $visiblename, $description, $defaultsetting) { 38 | parent::__construct($name, $visiblename, $description, $defaultsetting, null); 39 | } 40 | /** 41 | * Lazy load the font options. 42 | * 43 | * @return bool true if loaded, false if error 44 | */ 45 | public function load_choices() { 46 | global $CFG; 47 | 48 | if (is_array($this->choices)) { 49 | return true; 50 | } 51 | 52 | require_once("$CFG->libdir/pdflib.php"); 53 | 54 | $doc = new pdf(); 55 | 56 | if (method_exists($doc, 'get_font_families')) { 57 | $this->choices = array(); 58 | $fontfamilies = $doc->get_font_families(); 59 | foreach ($fontfamilies as $family => $fonts) { 60 | $this->choices[$family] = $family; 61 | } 62 | 63 | } else { 64 | $this->choices = array( 65 | 'freeserif' => 'freeserif', 66 | 'freesans' => 'freesans', 67 | ); 68 | } 69 | 70 | return true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /classes/admin_setting_upload.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Creates an upload form on the settings page 20 | * 21 | * @package mod_certificate 22 | * @copyright Michael Avelar 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | require_once($CFG->libdir.'/adminlib.php'); 29 | 30 | /** 31 | * Class extends admin setting class to allow/process an uploaded file 32 | **/ 33 | class mod_certificate_admin_setting_upload extends admin_setting_configtext { 34 | public function __construct($name, $visiblename, $description, $defaultsetting) { 35 | parent::__construct($name, $visiblename, $description, $defaultsetting, PARAM_RAW, 50); 36 | } 37 | 38 | function output_html($data, $query='') { 39 | // Create a dummy var for this field. 40 | $this->config_write($this->name, ''); 41 | 42 | return format_admin_setting($this, $this->visiblename, 43 | html_writer::link(new moodle_url('/mod/certificate/upload_image.php'), get_string('upload')), 44 | $this->description, true, '', null, $query); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /classes/event/course_module_instance_list_viewed.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * This page lists all the instances of certificate in a particular course 20 | * 21 | * @package mod 22 | * @subpackage certificate 23 | * @copyright Mark Nelson 24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 | */ 26 | 27 | namespace mod_certificate\event; 28 | 29 | defined('MOODLE_INTERNAL') || die(); 30 | 31 | class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { 32 | } 33 | -------------------------------------------------------------------------------- /classes/event/course_module_viewed.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * This page lists all the instances of certificate in a particular course 20 | * 21 | * @package mod 22 | * @subpackage certificate 23 | * @copyright Mark Nelson 24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 | */ 26 | 27 | namespace mod_certificate\event; 28 | 29 | defined('MOODLE_INTERNAL') || die(); 30 | 31 | class course_module_viewed extends \core\event\course_module_viewed { 32 | protected function init() { 33 | $this->data['objecttable'] = 'certificate'; 34 | parent::init(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /classes/external.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Certificate module external API 19 | * 20 | * @package mod_certificate 21 | * @category external 22 | * @copyright 2016 Juan Leyva 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die; 27 | 28 | require_once($CFG->libdir . '/externallib.php'); 29 | require_once($CFG->dirroot . '/mod/certificate/locallib.php'); 30 | 31 | /** 32 | * Certificate module external functions 33 | * 34 | * @package mod_certificate 35 | * @category external 36 | * @copyright 2015 Juan Leyva 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 | */ 39 | class mod_certificate_external extends external_api { 40 | 41 | /** 42 | * Describes the parameters for get_certificates_by_courses. 43 | * 44 | * @return external_function_parameters 45 | */ 46 | public static function get_certificates_by_courses_parameters() { 47 | return new external_function_parameters ( 48 | array( 49 | 'courseids' => new external_multiple_structure( 50 | new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array() 51 | ), 52 | ) 53 | ); 54 | } 55 | 56 | /** 57 | * Returns a list of certificates in a provided list of courses, 58 | * if no list is provided all certificates that the user can view will be returned. 59 | * 60 | * @param array $courseids the course ids 61 | * @return array the certificate details 62 | */ 63 | public static function get_certificates_by_courses($courseids = array()) { 64 | global $CFG; 65 | 66 | $returnedcertificates = array(); 67 | $warnings = array(); 68 | 69 | $params = self::validate_parameters(self::get_certificates_by_courses_parameters(), array('courseids' => $courseids)); 70 | 71 | if (empty($params['courseids'])) { 72 | $params['courseids'] = array_keys(enrol_get_my_courses()); 73 | } 74 | 75 | // Ensure there are courseids to loop through. 76 | if (!empty($params['courseids'])) { 77 | 78 | list($courses, $warnings) = external_util::validate_courses($params['courseids']); 79 | 80 | // Get the certificates in this course, this function checks users visibility permissions. 81 | // We can avoid then additional validate_context calls. 82 | $certificates = get_all_instances_in_courses("certificate", $courses); 83 | 84 | foreach ($certificates as $certificate) { 85 | 86 | $context = context_module::instance($certificate->coursemodule); 87 | 88 | // Entry to return. 89 | $module = array(); 90 | 91 | // First, we return information that any user can see in (or can deduce from) the web interface. 92 | $module['id'] = $certificate->id; 93 | $module['coursemodule'] = $certificate->coursemodule; 94 | $module['course'] = $certificate->course; 95 | $module['name'] = external_format_string($certificate->name, $context->id); 96 | 97 | $viewablefields = []; 98 | if (has_capability('mod/certificate:view', $context)) { 99 | list($module['intro'], $module['introformat']) = 100 | external_format_text($certificate->intro, $certificate->introformat, $context->id, 101 | 'mod_certificate', 'intro', $certificate->id); 102 | 103 | // Check certificate requeriments for current user. 104 | $viewablefields[] = 'requiredtime'; 105 | $module['requiredtimenotmet'] = 0; 106 | if ($certificate->requiredtime && !has_capability('mod/certificate:manage', $context)) { 107 | if (certificate_get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { 108 | $module['requiredtimenotmet'] = 1; 109 | } 110 | } 111 | } 112 | 113 | // Check additional permissions for returning optional private settings. 114 | if (has_capability('moodle/course:manageactivities', $context)) { 115 | 116 | $additionalfields = array('emailteachers', 'emailothers', 'savecert', 117 | 'reportcert', 'delivery', 'certificatetype', 'orientation', 'borderstyle', 'bordercolor', 118 | 'printwmark', 'printdate', 'datefmt', 'printnumber', 'printgrade', 'gradefmt', 'printoutcome', 119 | 'printhours', 'printteacher', 'customtext', 'printsignature', 'printseal', 'timecreated', 'timemodified', 120 | 'section', 'visible', 'groupmode', 'groupingid'); 121 | $viewablefields = array_merge($viewablefields, $additionalfields); 122 | 123 | } 124 | 125 | foreach ($viewablefields as $field) { 126 | $module[$field] = $certificate->{$field}; 127 | } 128 | 129 | $returnedcertificates[] = $module; 130 | } 131 | } 132 | 133 | $result = array(); 134 | $result['certificates'] = $returnedcertificates; 135 | $result['warnings'] = $warnings; 136 | return $result; 137 | } 138 | 139 | /** 140 | * Describes the get_certificates_by_courses return value. 141 | * 142 | * @return external_single_structure 143 | */ 144 | public static function get_certificates_by_courses_returns() { 145 | 146 | return new external_single_structure( 147 | array( 148 | 'certificates' => new external_multiple_structure( 149 | new external_single_structure( 150 | array( 151 | 'id' => new external_value(PARAM_INT, 'Certificate id'), 152 | 'coursemodule' => new external_value(PARAM_INT, 'Course module id'), 153 | 'course' => new external_value(PARAM_INT, 'Course id'), 154 | 'name' => new external_value(PARAM_RAW, 'Certificate name'), 155 | 'intro' => new external_value(PARAM_RAW, 'The Certificate intro', VALUE_OPTIONAL), 156 | 'introformat' => new external_format_value('intro', VALUE_OPTIONAL), 157 | 'requiredtimenotmet' => new external_value(PARAM_INT, 'Whether the time req is met', VALUE_OPTIONAL), 158 | 'emailteachers' => new external_value(PARAM_INT, 'Email teachers?', VALUE_OPTIONAL), 159 | 'emailothers' => new external_value(PARAM_RAW, 'Email others?', VALUE_OPTIONAL), 160 | 'savecert' => new external_value(PARAM_INT, 'Save certificate?', VALUE_OPTIONAL), 161 | 'reportcert' => new external_value(PARAM_INT, 'Report certificate?', VALUE_OPTIONAL), 162 | 'delivery' => new external_value(PARAM_INT, 'Delivery options', VALUE_OPTIONAL), 163 | 'requiredtime' => new external_value(PARAM_INT, 'Required time', VALUE_OPTIONAL), 164 | 'certificatetype' => new external_value(PARAM_RAW, 'Type', VALUE_OPTIONAL), 165 | 'orientation' => new external_value(PARAM_ALPHANUM, 'Orientation', VALUE_OPTIONAL), 166 | 'borderstyle' => new external_value(PARAM_RAW, 'Border style', VALUE_OPTIONAL), 167 | 'bordercolor' => new external_value(PARAM_RAW, 'Border color', VALUE_OPTIONAL), 168 | 'printwmark' => new external_value(PARAM_RAW, 'Print water mark?', VALUE_OPTIONAL), 169 | 'printdate' => new external_value(PARAM_RAW, 'Print date?', VALUE_OPTIONAL), 170 | 'datefmt' => new external_value(PARAM_INT, 'Date format', VALUE_OPTIONAL), 171 | 'printnumber' => new external_value(PARAM_INT, 'Print number?', VALUE_OPTIONAL), 172 | 'printgrade' => new external_value(PARAM_INT, 'Print grade?', VALUE_OPTIONAL), 173 | 'gradefmt' => new external_value(PARAM_INT, 'Grade format', VALUE_OPTIONAL), 174 | 'printoutcome' => new external_value(PARAM_INT, 'Print outcome?', VALUE_OPTIONAL), 175 | 'printhours' => new external_value(PARAM_TEXT, 'Print hours?', VALUE_OPTIONAL), 176 | 'printteacher' => new external_value(PARAM_INT, 'Print teacher?', VALUE_OPTIONAL), 177 | 'customtext' => new external_value(PARAM_RAW, 'Custom text', VALUE_OPTIONAL), 178 | 'printsignature' => new external_value(PARAM_RAW, 'Print signature?', VALUE_OPTIONAL), 179 | 'printseal' => new external_value(PARAM_RAW, 'Print seal?', VALUE_OPTIONAL), 180 | 'timecreated' => new external_value(PARAM_INT, 'Time created', VALUE_OPTIONAL), 181 | 'timemodified' => new external_value(PARAM_INT, 'Time modified', VALUE_OPTIONAL), 182 | 'section' => new external_value(PARAM_INT, 'course section id', VALUE_OPTIONAL), 183 | 'visible' => new external_value(PARAM_INT, 'visible', VALUE_OPTIONAL), 184 | 'groupmode' => new external_value(PARAM_INT, 'group mode', VALUE_OPTIONAL), 185 | 'groupingid' => new external_value(PARAM_INT, 'group id', VALUE_OPTIONAL), 186 | ), 'Tool' 187 | ) 188 | ), 189 | 'warnings' => new external_warnings(), 190 | ) 191 | ); 192 | } 193 | 194 | /** 195 | * Returns description of method parameters 196 | * 197 | * @return external_function_parameters 198 | */ 199 | public static function view_certificate_parameters() { 200 | return new external_function_parameters( 201 | array( 202 | 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') 203 | ) 204 | ); 205 | } 206 | 207 | /** 208 | * Trigger the course module viewed event and update the module completion status. 209 | * 210 | * @param int $certificateid the certificate instance id 211 | * @return array of warnings and status result 212 | * @throws moodle_exception 213 | */ 214 | public static function view_certificate($certificateid) { 215 | global $DB; 216 | 217 | $params = self::validate_parameters(self::view_certificate_parameters(), 218 | array( 219 | 'certificateid' => $certificateid 220 | ) 221 | ); 222 | $warnings = array(); 223 | 224 | // Request and permission validation. 225 | $certificate = $DB->get_record('certificate', array('id' => $params['certificateid']), '*', MUST_EXIST); 226 | list($course, $cm) = get_course_and_cm_from_instance($certificate, 'certificate'); 227 | 228 | $context = context_module::instance($cm->id); 229 | self::validate_context($context); 230 | require_capability('mod/certificate:view', $context); 231 | 232 | $event = \mod_certificate\event\course_module_viewed::create(array( 233 | 'objectid' => $certificate->id, 234 | 'context' => $context, 235 | )); 236 | $event->add_record_snapshot('course', $course); 237 | $event->add_record_snapshot('certificate', $certificate); 238 | $event->trigger(); 239 | 240 | $completion = new completion_info($course); 241 | $completion->set_module_viewed($cm); 242 | 243 | $result = array(); 244 | $result['status'] = true; 245 | $result['warnings'] = $warnings; 246 | return $result; 247 | } 248 | 249 | /** 250 | * Returns description of method result value 251 | * 252 | * @return external_description 253 | */ 254 | public static function view_certificate_returns() { 255 | return new external_single_structure( 256 | array( 257 | 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 258 | 'warnings' => new external_warnings() 259 | ) 260 | ); 261 | } 262 | 263 | /** 264 | * Check if the user can issue certificates. 265 | * 266 | * @param int $certificateid certificate instance id 267 | * @return array array containing context related data 268 | */ 269 | private static function check_can_issue($certificateid) { 270 | global $DB; 271 | 272 | $certificate = $DB->get_record('certificate', array('id' => $certificateid), '*', MUST_EXIST); 273 | list($course, $cm) = get_course_and_cm_from_instance($certificate, 'certificate'); 274 | 275 | $context = context_module::instance($cm->id); 276 | self::validate_context($context); 277 | require_capability('mod/certificate:view', $context); 278 | 279 | // Check if the user can view the certificate. 280 | if ($certificate->requiredtime && !has_capability('mod/certificate:manage', $context)) { 281 | if (certificate_get_course_time($course->id) < ($certificate->requiredtime * 60)) { 282 | $a = new stdClass(); 283 | $a->requiredtime = $certificate->requiredtime; 284 | throw new moodle_exception('requiredtimenotmet', 'certificate', '', $a); 285 | } 286 | } 287 | return array($certificate, $course, $cm, $context); 288 | } 289 | 290 | /** 291 | * Returns a issued certificated structure 292 | * 293 | * @return external_single_structure External single structure 294 | */ 295 | private static function issued_structure() { 296 | return new external_single_structure( 297 | array( 298 | 'id' => new external_value(PARAM_INT, 'Issue id'), 299 | 'userid' => new external_value(PARAM_INT, 'User id'), 300 | 'certificateid' => new external_value(PARAM_INT, 'Certificate id'), 301 | 'code' => new external_value(PARAM_RAW, 'Certificate code'), 302 | 'timecreated' => new external_value(PARAM_INT, 'Time created'), 303 | 'filename' => new external_value(PARAM_FILE, 'Time created'), 304 | 'fileurl' => new external_value(PARAM_URL, 'Time created'), 305 | 'mimetype' => new external_value(PARAM_RAW, 'mime type'), 306 | 'grade' => new external_value(PARAM_NOTAGS, 'Certificate grade', VALUE_OPTIONAL), 307 | ) 308 | ); 309 | } 310 | 311 | /** 312 | * Add extra required information to the issued certificate 313 | * 314 | * @param stdClass $issue issue object 315 | * @param stdClass $certificate certificate object 316 | * @param stdClass $course course object 317 | * @param stdClass $cm course module object 318 | * @param stdClass $context context object 319 | */ 320 | private static function add_extra_issue_data($issue, $certificate, $course, $cm, $context) { 321 | global $CFG; 322 | 323 | // Grade data. 324 | if ($certificate->printgrade) { 325 | $issue->grade = certificate_get_grade($certificate, $course); 326 | } 327 | 328 | // File data. 329 | $issue->mimetype = 'application/pdf'; 330 | $issue->filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; 331 | // We need to use a special file area to be able to download certificates (in most cases are not stored in the site). 332 | $issue->fileurl = moodle_url::make_webservice_pluginfile_url( 333 | $context->id, 'mod_certificate', 'onthefly', $issue->id, '/', $issue->filename)->out(false); 334 | } 335 | 336 | /** 337 | * Returns description of method parameters 338 | * 339 | * @return external_function_parameters 340 | */ 341 | public static function issue_certificate_parameters() { 342 | return new external_function_parameters( 343 | array( 344 | 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') 345 | ) 346 | ); 347 | } 348 | 349 | /** 350 | * Create new certificate record, or return existing record. 351 | * 352 | * @param int $certificateid the certificate instance id 353 | * @return array of warnings and status result 354 | * @throws moodle_exception 355 | */ 356 | public static function issue_certificate($certificateid) { 357 | global $USER; 358 | 359 | $params = self::validate_parameters(self::issue_certificate_parameters(), 360 | array( 361 | 'certificateid' => $certificateid 362 | ) 363 | ); 364 | $warnings = array(); 365 | 366 | // Request and permission validation. 367 | list($certificate, $course, $cm, $context) = self::check_can_issue($params['certificateid']); 368 | 369 | $issue = certificate_get_issue($course, $USER, $certificate, $cm); 370 | self::add_extra_issue_data($issue, $certificate, $course, $cm, $context); 371 | 372 | $result = array(); 373 | $result['issue'] = $issue; 374 | $result['warnings'] = $warnings; 375 | return $result; 376 | } 377 | 378 | /** 379 | * Returns description of method result value 380 | * 381 | * @return external_description 382 | */ 383 | public static function issue_certificate_returns() { 384 | return new external_single_structure( 385 | array( 386 | 'issue' => self::issued_structure(), 387 | 'warnings' => new external_warnings() 388 | ) 389 | ); 390 | } 391 | 392 | /** 393 | * Returns description of method parameters 394 | * 395 | * @return external_function_parameters 396 | */ 397 | public static function get_issued_certificates_parameters() { 398 | return new external_function_parameters( 399 | array( 400 | 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') 401 | ) 402 | ); 403 | } 404 | 405 | /** 406 | * Get the list of issued certificates for the current user. 407 | * 408 | * @param int $certificateid the certificate instance id 409 | * @return array of warnings and status result 410 | * @throws moodle_exception 411 | */ 412 | public static function get_issued_certificates($certificateid) { 413 | 414 | $params = self::validate_parameters(self::get_issued_certificates_parameters(), 415 | array( 416 | 'certificateid' => $certificateid 417 | ) 418 | ); 419 | $warnings = array(); 420 | 421 | // Request and permission validation. 422 | list($certificate, $course, $cm, $context) = self::check_can_issue($params['certificateid']); 423 | 424 | $issues = certificate_get_attempts($certificate->id); 425 | 426 | if ($issues !== false ) { 427 | foreach ($issues as $issue) { 428 | self::add_extra_issue_data($issue, $certificate, $course, $cm, $context); 429 | 430 | } 431 | } else { 432 | $issues = array(); 433 | } 434 | 435 | $result = array(); 436 | $result['issues'] = $issues; 437 | $result['warnings'] = $warnings; 438 | return $result; 439 | } 440 | 441 | /** 442 | * Returns description of method result value 443 | * 444 | * @return external_description 445 | */ 446 | public static function get_issued_certificates_returns() { 447 | return new external_single_structure( 448 | array( 449 | 'issues' => new external_multiple_structure(self::issued_structure()), 450 | 'warnings' => new external_warnings() 451 | ) 452 | ); 453 | } 454 | 455 | } 456 | -------------------------------------------------------------------------------- /classes/privacy/provider.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Privacy subsystem implementation for mod_certificate. 19 | * 20 | * @package mod_certificate 21 | * @copyright 2018 Huong Nguyen 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace mod_certificate\privacy; 26 | 27 | use context; 28 | use core_privacy\local\metadata\collection; 29 | use core_privacy\local\request\approved_contextlist; 30 | use core_privacy\local\request\contextlist; 31 | use core_privacy\local\request\transform; 32 | use core_privacy\local\request\writer; 33 | use core_privacy\local\request\approved_userlist; 34 | use core_privacy\local\request\userlist; 35 | 36 | defined('MOODLE_INTERNAL') || die(); 37 | 38 | /** 39 | * Implementation of the privacy subsystem plugin provider for the mod_certificate. 40 | * 41 | * @package mod_certificate 42 | * @copyright 2018 Huong Nguyen 43 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 44 | */ 45 | class provider implements 46 | \core_privacy\local\metadata\provider, 47 | \core_privacy\local\request\plugin\provider, 48 | \core_privacy\local\request\core_userlist_provider { 49 | 50 | /** 51 | * Returns meta data about this system. 52 | * 53 | * @param collection $items The initialised collection to add items to. 54 | * @return collection A listing of user data stored through this system. 55 | */ 56 | public static function get_metadata(collection $items): collection { 57 | $items->add_database_table('certificate_issues', [ 58 | 'userid' => 'privacy:metadata:mod_certificate:userid', 59 | 'certificateid' => 'privacy:metadata:mod_certificate:certificateid', 60 | 'code' => 'privacy:metadata:mod_certificate:code', 61 | 'timecreated' => 'privacy:metadata:mod_certificate:timecreated', 62 | ], 'privacy:metadata:mod_certificate'); 63 | 64 | $items->link_subsystem('core_files', 'privacy:metadata:core_files'); 65 | 66 | return $items; 67 | } 68 | 69 | /** 70 | * Get the list of contexts that contain user information for the specified user. 71 | * 72 | * @param int $userid The user to search. 73 | * @return contextlist The contextlist containing the list of contexts used in this plugin. 74 | */ 75 | public static function get_contexts_for_userid(int $userid): contextlist { 76 | $contextlist = new contextlist(); 77 | 78 | $sql = "SELECT c.id 79 | FROM {context} c 80 | JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel 81 | JOIN {modules} m ON m.id = cm.module AND m.name = :modname 82 | JOIN {certificate_issues} ci ON ci.certificateid = cm.instance 83 | JOIN {user} u ON u.id = ci.userid 84 | WHERE u.id = :userid"; 85 | 86 | $params = [ 87 | 'modname' => 'certificate', 88 | 'contextlevel' => CONTEXT_MODULE, 89 | 'userid' => $userid 90 | ]; 91 | 92 | $contextlist->add_from_sql($sql, $params); 93 | 94 | return $contextlist; 95 | } 96 | 97 | /** 98 | * Get the list of users who have data within a context. 99 | * 100 | * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. 101 | */ 102 | public static function get_users_in_context(userlist $userlist) { 103 | $context = $userlist->get_context(); 104 | if (!$context instanceof \context_module) { 105 | return; 106 | } 107 | // Fetch all users who have a certificate. 108 | $sql = "SELECT ci.userid 109 | FROM {course_modules} cm 110 | JOIN {modules} m 111 | ON m.id = cm.module AND m.name = :modname 112 | JOIN {certificate} cer 113 | ON cer.id = cm.instance 114 | JOIN {certificate_issues} ci 115 | ON ci.certificateid = cer.id 116 | WHERE cm.id = :cmid"; 117 | $params = [ 118 | 'cmid' => $context->instanceid, 119 | 'modname' => 'certificate', 120 | ]; 121 | $userlist->add_from_sql('userid', $sql, $params); 122 | } 123 | 124 | /** 125 | * Export all user data for the specified user, in the specified contexts. 126 | * 127 | * @param approved_contextlist $contextlist The approved contexts to export information for. 128 | */ 129 | public static function export_user_data(approved_contextlist $contextlist) { 130 | global $DB; 131 | 132 | if (empty($contextlist)) { 133 | return; 134 | } 135 | 136 | $user = $contextlist->get_user(); 137 | list($contextsql, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED); 138 | 139 | $sql = "SELECT c.id as contextid, 140 | ci.* 141 | FROM {context} c 142 | JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel 143 | JOIN {modules} m ON m.id = cm.module AND m.name = :modname 144 | JOIN {certificate_issues} ci ON ci.certificateid = cm.instance 145 | JOIN {user} u ON u.id = ci.userid 146 | WHERE u.id = :userid 147 | AND (c.id {$contextsql})"; 148 | 149 | $params = [ 150 | 'modname' => 'certificate', 151 | 'contextlevel' => CONTEXT_MODULE, 152 | 'userid' => $user->id, 153 | ]; 154 | 155 | $params += $contextparams; 156 | 157 | $certificateissues = $DB->get_recordset_sql($sql, $params); 158 | 159 | foreach ($certificateissues as $c) { 160 | $context = context::instance_by_id($c->contextid); 161 | $cidata = (object) [ 162 | 'userid' => transform::user($c->userid), 163 | 'certificateid' => $c->certificateid, 164 | 'code' => $c->code, 165 | 'timecreated' => transform::datetime($c->timecreated), 166 | ]; 167 | $area = [$c->id]; 168 | writer::with_context($context)->export_data($area, $cidata); 169 | writer::with_context($context)->export_area_files($area, 'mod_certificate', 'issue', $c->id); 170 | } 171 | 172 | $certificateissues->close(); 173 | } 174 | 175 | /** 176 | * Delete all data for all users in the specified context. 177 | * 178 | * @param context $context The specific context to delete data for. 179 | */ 180 | public static function delete_data_for_all_users_in_context(context $context) { 181 | global $DB; 182 | 183 | $sql = "SELECT ci.certificateid 184 | FROM {context} c 185 | JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel 186 | JOIN {modules} m ON m.id = cm.module AND m.name = :modname 187 | JOIN {certificate_issues} ci ON ci.certificateid = cm.instance 188 | WHERE c.id = :contextid"; 189 | 190 | $params = [ 191 | 'modname' => 'certificate', 192 | 'contextlevel' => CONTEXT_MODULE, 193 | 'contextid' => $context->id 194 | ]; 195 | 196 | $records = $DB->get_records_sql($sql, $params); 197 | if ($records) { 198 | foreach ($records as $r) { 199 | $DB->delete_records('certificate_issues', ['certificateid' => $r->certificateid]); 200 | } 201 | } 202 | $fs = get_file_storage(); 203 | $fs->delete_area_files($context->id, 'mod_certificate', 'issue'); 204 | } 205 | 206 | /** 207 | * Delete all user data for the specified user, in the specified contexts. 208 | * 209 | * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. 210 | */ 211 | public static function delete_data_for_user(approved_contextlist $contextlist) { 212 | global $DB; 213 | 214 | $user = $contextlist->get_user(); 215 | $fs = get_file_storage(); 216 | 217 | foreach ($contextlist as $context) { 218 | $sql = "SELECT ci.certificateid, ci.id 219 | FROM {context} c 220 | JOIN {course_modules} cm ON cm.id = c.instanceid AND c.contextlevel = :contextlevel 221 | JOIN {modules} m ON m.id = cm.module AND m.name = :modname 222 | JOIN {certificate_issues} ci ON ci.certificateid = cm.instance 223 | JOIN {user} u ON u.id = ci.userid 224 | WHERE u.id = :userid AND c.id = :modcontextid"; 225 | $params = [ 226 | 'modname' => 'certificate', 227 | 'contextlevel' => CONTEXT_MODULE, 228 | 'userid' => $user->id, 229 | 'modcontextid' => $context->id 230 | ]; 231 | 232 | $records = $DB->get_records_sql($sql, $params); 233 | if ($records) { 234 | foreach ($records as $r) { 235 | $DB->delete_records('certificate_issues', ['certificateid' => $r->certificateid, 'userid' => $user->id]); 236 | $fs->delete_area_files($context->id, 'mod_certificate', 'issue', $r->id); 237 | } 238 | } 239 | } 240 | } 241 | 242 | /** 243 | * Delete multiple users within a single context. 244 | * 245 | * @param approved_userlist $userlist The approved context and user information to delete information for. 246 | */ 247 | public static function delete_data_for_users(approved_userlist $userlist) { 248 | global $DB; 249 | $context = $userlist->get_context(); 250 | if (!$context instanceof \context_module) { 251 | return; 252 | } 253 | $cm = get_coursemodule_from_id('certificate', $context->instanceid); 254 | if (!$cm) { 255 | // Only certificate module will be handled. 256 | return; 257 | } 258 | $userids = $userlist->get_userids(); 259 | list($usersql, $userparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); 260 | $select = "certificateid = :certificateid AND userid $usersql"; 261 | $params = ['certificateid' => $cm->instance] + $userparams; 262 | $DB->delete_records_select('certificate_issues', $select, $params); 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "markn86/moodle-mod_certificate", 3 | "type": "moodle-mod", 4 | "require": { 5 | "composer/installers": "~1.0" 6 | }, 7 | "extra": { 8 | "installer-name": "certificate" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /db/access.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Certificate module capability definition 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | $capabilities = array( 27 | 28 | 'mod/certificate:addinstance' => array( 29 | 'riskbitmask' => RISK_XSS, 30 | 'captype' => 'write', 31 | 'contextlevel' => CONTEXT_COURSE, 32 | 'archetypes' => array( 33 | 'editingteacher' => CAP_ALLOW, 34 | 'manager' => CAP_ALLOW 35 | ), 36 | 'clonepermissionsfrom' => 'moodle/course:manageactivities' 37 | ), 38 | 39 | 'mod/certificate:view' => array( 40 | 41 | 'captype' => 'read', 42 | 'contextlevel' => CONTEXT_MODULE, 43 | 'archetypes' => array( 44 | 'student' => CAP_ALLOW, 45 | 'teacher' => CAP_ALLOW, 46 | 'editingteacher' => CAP_ALLOW, 47 | 'manager' => CAP_ALLOW 48 | ) 49 | ), 50 | 51 | 'mod/certificate:manage' => array( 52 | 53 | 'captype' => 'read', 54 | 'contextlevel' => CONTEXT_MODULE, 55 | 'archetypes' => array( 56 | 'teacher' => CAP_ALLOW, 57 | 'editingteacher' => CAP_ALLOW, 58 | 'manager' => CAP_ALLOW 59 | ) 60 | ), 61 | 62 | 'mod/certificate:printteacher' => array( 63 | 64 | 'captype' => 'read', 65 | 'contextlevel' => CONTEXT_MODULE, 66 | 'archetypes' => array( 67 | 'teacher' => CAP_ALLOW, 68 | 'editingteacher' => CAP_ALLOW 69 | ) 70 | ), 71 | 72 | ); 73 | -------------------------------------------------------------------------------- /db/install.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /db/log.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Definition of log events 20 | * 21 | * @package mod_certificate 22 | * @copyright 2010 Petr Skoda (http://skodak.org) 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | $logs = array( 29 | array('module'=>'certificate', 'action'=>'view', 'mtable'=>'certificate', 'field'=>'name'), 30 | array('module'=>'certificate', 'action'=>'add', 'mtable'=>'certificate', 'field'=>'name'), 31 | array('module'=>'certificate', 'action'=>'update', 'mtable'=>'certificate', 'field'=>'name'), 32 | array('module'=>'certificate', 'action'=>'received', 'mtable'=>'certificate', 'field'=>'name'), 33 | ); 34 | -------------------------------------------------------------------------------- /db/mobile.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Certificate module capability definition 19 | * 20 | * @package mod_certificate 21 | * @copyright 2016 Juan Leyva 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | $addons = array( 26 | "mod_certificate" => array() 27 | ); -------------------------------------------------------------------------------- /db/services.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Certificate external functions and service definitions. 19 | * 20 | * @package mod_certificate 21 | * @category external 22 | * @copyright 2016 Juan Leyva 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | $functions = array( 27 | 28 | 'mod_certificate_get_certificates_by_courses' => array( 29 | 'classname' => 'mod_certificate_external', 30 | 'methodname' => 'get_certificates_by_courses', 31 | 'description' => 'Returns a list of certificate instances in a provided set of courses, if 32 | no courses are provided then all the certificate instances the user has access to will be returned.', 33 | 'type' => 'read', 34 | 'capabilities' => 'mod/certificate:view', 35 | 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), 36 | ), 37 | 38 | 'mod_certificate_view_certificate' => array( 39 | 'classname' => 'mod_certificate_external', 40 | 'methodname' => 'view_certificate', 41 | 'description' => 'Trigger the course module viewed event and update the module completion status.', 42 | 'type' => 'write', 43 | 'capabilities' => 'mod/certificate:view', 44 | 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), 45 | ), 46 | 47 | 'mod_certificate_issue_certificate' => array( 48 | 'classname' => 'mod_certificate_external', 49 | 'methodname' => 'issue_certificate', 50 | 'description' => 'Create new certificate record, or return existing record for the current user.', 51 | 'type' => 'write', 52 | 'capabilities' => 'mod/certificate:view', 53 | 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), 54 | ), 55 | 56 | 'mod_certificate_get_issued_certificates' => array( 57 | 'classname' => 'mod_certificate_external', 58 | 'methodname' => 'get_issued_certificates', 59 | 'description' => 'Get the list of issued certificates for the current user.', 60 | 'type' => 'read', 61 | 'capabilities' => 'mod/certificate:view', 62 | 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), 63 | ), 64 | ); 65 | -------------------------------------------------------------------------------- /db/upgrade.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * This file keeps track of upgrades to the certificate module 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | function xmldb_certificate_upgrade($oldversion=0) { 27 | 28 | global $CFG, $THEME, $DB; 29 | $dbman = $DB->get_manager(); 30 | 31 | // ===== 1.9.0 or older upgrade line ======// 32 | if ($oldversion < 2007061300) { 33 | // Add new fields to certificate table 34 | $table = new xmldb_table('certificate'); 35 | $field = new xmldb_field('emailothers'); 36 | $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'emailteachers'); 37 | if (!$dbman->field_exists($table, $field)) { 38 | $dbman->add_field($table, $field); 39 | } 40 | 41 | $table = new xmldb_table('certificate'); 42 | $field = new xmldb_field('printhours'); 43 | $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'gradefmt'); 44 | if (!$dbman->field_exists($table, $field)) { 45 | $dbman->add_field($table, $field); 46 | } 47 | 48 | $table = new xmldb_table('certificate'); 49 | $field = new xmldb_field('lockgrade'); 50 | $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'printhours'); 51 | if (!$dbman->field_exists($table, $field)) { 52 | $dbman->add_field($table, $field); 53 | } 54 | 55 | $table = new xmldb_table('certificate'); 56 | $field = new xmldb_field('requiredgrade'); 57 | $field->set_attributes(XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'lockgrade'); 58 | if (!$dbman->field_exists($table, $field)) { 59 | $dbman->add_field($table, $field); 60 | } 61 | 62 | // Rename field save to savecert 63 | $field = new xmldb_field('save'); 64 | if ($dbman->field_exists($table, $field)) { 65 | $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers'); 66 | // Launch rename field savecert 67 | $dbman->rename_field($table, $field, 'savecert'); 68 | } else { 69 | $field = new xmldb_field('savecert'); 70 | $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers'); 71 | 72 | $dbman->add_field($table, $field); 73 | } 74 | 75 | // Certificate savepoint reached 76 | upgrade_mod_savepoint(true, 2007061300, 'certificate'); 77 | } 78 | 79 | if ($oldversion < 2007061301) { 80 | $table = new xmldb_table('certificate_linked_modules'); 81 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null); 82 | $table->add_field('certificate_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id'); 83 | $table->add_field('linkid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'certificate_id'); 84 | $table->add_field('linkgrade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkid'); 85 | $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkgrade'); 86 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'), null, null); 87 | $table->add_index('certificate_id', XMLDB_INDEX_NOTUNIQUE, array('certificate_id')); 88 | $table->add_index('linkid', XMLDB_INDEX_NOTUNIQUE, array('linkid')); 89 | if (!$dbman->table_exists($table)) { 90 | $dbman->create_table($table); 91 | } 92 | 93 | // Certificate savepoint reached 94 | upgrade_mod_savepoint(true, 2007061301, 'certificate'); 95 | } 96 | 97 | if ($oldversion < 2007102800) { 98 | // Add new fields to certificate table 99 | $table = new xmldb_table('certificate'); 100 | $field = new xmldb_field('reportcert'); 101 | $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'savecert'); 102 | if (!$dbman->field_exists($table, $field)) { 103 | $dbman->add_field($table, $field); 104 | } 105 | 106 | $table = new xmldb_table('certificate_issues'); 107 | $field = new xmldb_field('reportgrade'); 108 | $field->set_attributes(XMLDB_TYPE_CHAR, '10', null, null, null, null, 'certdate'); 109 | if (!$dbman->field_exists($table, $field)) { 110 | $dbman->add_field($table, $field); 111 | } 112 | 113 | // Certificate savepoint reached 114 | upgrade_mod_savepoint(true, 2007102800, 'certificate'); 115 | } 116 | 117 | if ($oldversion < 2007102806) { 118 | // Add new fields to certificate table 119 | $table = new xmldb_table('certificate'); 120 | $field = new xmldb_field('printoutcome'); 121 | $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'gradefmt'); 122 | if (!$dbman->field_exists($table, $field)) { 123 | $dbman->add_field($table, $field); 124 | } 125 | 126 | // Certificate savepoint reached 127 | upgrade_mod_savepoint(true, 2007102806, 'certificate'); 128 | } 129 | 130 | if ($oldversion < 2008080904) { 131 | // Add new fields to certificate table if they dont already exist 132 | $table = new xmldb_table('certificate'); 133 | $field = new xmldb_field('intro'); 134 | $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'name'); 135 | if (!$dbman->field_exists($table, $field)) { 136 | $dbman->add_field($table, $field); 137 | } 138 | 139 | // Certificate savepoint reached 140 | upgrade_mod_savepoint(true, 2008080904, 'certificate'); 141 | } 142 | 143 | //===== 2.0 or older upgrade line ======// 144 | 145 | // Note, fresh 1.9 installs add the version 2009080900, so they miss this when upgrading from 1.9 -> 2.0. 146 | if ($oldversion < 2009062900) { 147 | // Add new field to certificate table 148 | $table = new xmldb_table('certificate'); 149 | $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'intro'); 150 | if (!$dbman->field_exists($table, $field)) { 151 | $dbman->add_field($table, $field); 152 | } 153 | 154 | $field = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, ' ', 'certificatetype'); 155 | if (!$dbman->field_exists($table, $field)) { 156 | $dbman->add_field($table, $field); 157 | } 158 | 159 | $field = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert'); 160 | if (!$dbman->field_exists($table, $field)) { 161 | $dbman->add_field($table, $field); 162 | } 163 | 164 | // Set default orientation accordingly 165 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'portrait')); 166 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'letter_portrait')); 167 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'unicode_portrait')); 168 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'landscape')); 169 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'letter_landscape')); 170 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'unicode_landscape')); 171 | 172 | // Update all the certificate types 173 | $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'landscape')); 174 | $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'portrait')); 175 | $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_landscape')); 176 | $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_portrait')); 177 | $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_landscape')); 178 | $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_portrait')); 179 | 180 | // savepoint reached 181 | upgrade_mod_savepoint(true, 2009062900, 'certificate'); 182 | } 183 | 184 | if ($oldversion < 2011030105) { 185 | 186 | // Define field id to be added to certificate 187 | $table = new xmldb_table('certificate'); 188 | $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 0, 'intro'); 189 | 190 | // Conditionally launch add field id 191 | if (!$dbman->field_exists($table, $field)) { 192 | $dbman->add_field($table, $field); 193 | } 194 | 195 | // Certificate savepoint reached 196 | upgrade_mod_savepoint(true, 2011030105, 'certificate'); 197 | } 198 | 199 | // The Moodle 2.0 CVS certificate version sets it to 2011110101, if the user performed an upgrade 200 | // then this upgrade will take care of several issues, if it's a fresh install then nothing is done. 201 | if ($oldversion < 2011110102) { 202 | require_once($CFG->libdir.'/conditionlib.php'); 203 | 204 | $table = new xmldb_table('certificate'); 205 | 206 | // It is possible for these fields not to be added, ever, it is included in the upgrade 207 | // process but fresh certificate 1.9 install from CVS MOODLE_19_STABLE set the Moodle version 208 | // to 2009080900, which means it missed all the earlier code written for upgrading to 2.0. 209 | $reissuefield = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert'); 210 | $orientationfield = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, ' ', 'certificatetype'); 211 | 212 | // Have to check, may be added during earlier upgrade, or may be missing due to not being included in install.xml 213 | if (!$dbman->field_exists($table, $reissuefield)) { 214 | $dbman->add_field($table, $reissuefield); 215 | } 216 | 217 | if (!$dbman->field_exists($table, $orientationfield)) { 218 | $dbman->add_field($table, $orientationfield); 219 | } 220 | 221 | // Fresh 2.0 installs won't have this table, but upgrades from 1.9 will 222 | if ($dbman->table_exists('certificate_linked_modules')) { 223 | // No longer need lock grade, or required grade, but first need to 224 | // convert so that the restrictions are still in place for Moodle 2.0 225 | if ($certs = $DB->get_records('certificate')) { 226 | foreach ($certs as $cert) { 227 | if ($cert->lockgrade == 0) { 228 | // Can skip this certificate, no course grade required 229 | continue; 230 | } 231 | if (!$cm = get_coursemodule_from_instance('certificate', $cert->id)) { 232 | // Not valid skip it 233 | continue; 234 | } 235 | if (!$gradeitem = $DB->get_record('grade_items', array('courseid' => $cm->course, 'itemtype' => 'course'))) { 236 | // Not valid skip it 237 | continue; 238 | } 239 | $condition_info = new condition_info($cm, CONDITION_MISSING_EVERYTHING); 240 | $condition_info->add_grade_condition($gradeitem->id, $cert->requiredgrade, '110'); 241 | } 242 | } 243 | // Fresh installs won't have this table, but upgrades will 244 | // Lock grade and required grade field are not needed anymore 245 | if ($dbman->field_exists($table, 'lockgrade')) { 246 | $field = new xmldb_field('lockgrade'); 247 | $dbman->drop_field($table, $field); 248 | } 249 | if ($dbman->field_exists($table, 'requiredgrade')) { 250 | $field = new xmldb_field('requiredgrade'); 251 | $dbman->drop_field($table, $field); 252 | } 253 | // Now we need to loop through the restrictions in the certificate_linked_modules 254 | // table and convert it into the new Moodle 2.0 restrictions 255 | if ($certlinks = $DB->get_records('certificate_linked_modules')) { 256 | foreach ($certlinks as $link) { 257 | // If the link id is '-1' then the setting applies to the time spent in the course and is not 258 | // related to a module, meaning we can skip it for this section 259 | if ($link->linkid == '-1') { 260 | continue; 261 | } 262 | // Get the course module 263 | if (!$cm = get_coursemodule_from_instance('certificate', $link->certificate_id)) { 264 | // Not valid skip it 265 | continue; 266 | } 267 | // Get grade item for module specified - is there an API function for this ?? 268 | $sql = "SELECT gi.id 269 | FROM {course_modules} cm 270 | INNER JOIN {modules} m 271 | ON cm.module = m.id 272 | INNER JOIN {grade_items} gi 273 | ON m.name = gi.itemmodule 274 | WHERE cm.id = :cmid 275 | AND cm.course = :courseid 276 | AND cm.instance = gi.iteminstance"; 277 | if (!$gradeitem = $DB->get_record_sql($sql, array('cmid'=>$link->linkid, 'courseid'=>$cm->course))) { 278 | // Not valid skip it 279 | continue; 280 | } 281 | $condition_info = new condition_info($cm, CONDITION_MISSING_EVERYTHING); 282 | $condition_info->add_grade_condition($gradeitem->id, $link->linkgrade, '110', true); 283 | } 284 | } 285 | } 286 | // Certificate savepoint reached 287 | upgrade_mod_savepoint(true, 2011110102, 'certificate'); 288 | } 289 | 290 | // Note - the date has not changed as it has been set in the future, so I am incrementing 291 | // last digits. Actual date - 15/09/11 292 | if ($oldversion < 2011110103) { 293 | // New orientation field needs a value in order to view the cert, otherwise you get 294 | // an issue with FPDF and invalid orientation. This should be done during the upgrade, 295 | // but due to version number issues it is possible it was not executed, so do it now. 296 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'portrait')); 297 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'letter_portrait')); 298 | $DB->set_field('certificate', 'orientation', 'P', array('certificatetype' => 'unicode_portrait')); 299 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'landscape')); 300 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'letter_landscape')); 301 | $DB->set_field('certificate', 'orientation', 'L', array('certificatetype' => 'unicode_landscape')); 302 | 303 | // If the certificate type does not match any of the orientations in the above then set to 'L' 304 | $sql = "UPDATE {certificate} 305 | SET orientation = 'L' 306 | WHERE orientation = ''"; 307 | $DB->execute($sql); 308 | 309 | // Update all the certificate types 310 | $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'landscape')); 311 | $DB->set_field('certificate', 'certificatetype', 'A4_non_embedded', array('certificatetype' => 'portrait')); 312 | $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_landscape')); 313 | $DB->set_field('certificate', 'certificatetype', 'A4_embedded', array('certificatetype' => 'unicode_portrait')); 314 | $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_landscape')); 315 | $DB->set_field('certificate', 'certificatetype', 'letter_non_embedded', array('certificatetype' => 'letter_portrait')); 316 | 317 | // Certificate savepoint reached 318 | upgrade_mod_savepoint(true, 2011110103, 'certificate'); 319 | } 320 | 321 | if ($oldversion < 2012022001) { 322 | // CONTRIB-3470 - certdate remaining 0 on issued certificates, need to update 323 | $sql = "UPDATE {certificate_issues} 324 | SET certdate = timecreated 325 | WHERE certdate = 0"; 326 | $DB->execute($sql); 327 | 328 | // Certificate savepoint reached 329 | upgrade_mod_savepoint(true, 2012022001, 'certificate'); 330 | } 331 | 332 | if ($oldversion < 2012060901) { 333 | // Editing this table 334 | $table = new xmldb_table('certificate'); 335 | 336 | // Get rid of the reissue cert column, this was a hack introduced later 337 | // in 1.9 when the bug was brought up that grades were not refreshing 338 | // since they were being stored in the issues table. 339 | // The certificate will now always return the current grade, student name 340 | // and course name. 341 | $field = new xmldb_field('reissuecert'); 342 | if ($dbman->field_exists($table, $field)) { 343 | $dbman->drop_field($table, $field); 344 | } 345 | 346 | // The poor certificate_issues table is going to have a lot of 347 | // duplicates, we don't need that now, just keep the latest one 348 | $sql = "SELECT MAX(id) id1, MAX(id) as id2 349 | FROM {certificate_issues} 350 | GROUP BY certificateid, userid"; 351 | if ($arrids = $DB->get_records_sql_menu($sql)) { 352 | $idstokeep = implode(",", $arrids); 353 | $sql = "DELETE 354 | FROM {certificate_issues} 355 | WHERE id NOT IN ($idstokeep)"; 356 | $DB->execute($sql); 357 | } 358 | 359 | // Going to be editing this table 360 | $table = new xmldb_table('certificate_issues'); 361 | 362 | // Conditionally remove columns no longer needed 363 | $field = new xmldb_field('studentname'); 364 | if ($dbman->field_exists($table, $field)) { 365 | $dbman->drop_field($table, $field); 366 | } 367 | $field = new xmldb_field('classname'); 368 | if ($dbman->field_exists($table, $field)) { 369 | $dbman->drop_field($table, $field); 370 | } 371 | $field = new xmldb_field('certdate'); 372 | if ($dbman->field_exists($table, $field)) { 373 | $dbman->drop_field($table, $field); 374 | } 375 | $field = new xmldb_field('reportgrade'); 376 | if ($dbman->field_exists($table, $field)) { 377 | $dbman->drop_field($table, $field); 378 | } 379 | $field = new xmldb_field('mailed'); 380 | if ($dbman->field_exists($table, $field)) { 381 | $dbman->drop_field($table, $field); 382 | } 383 | 384 | // Certificate savepoint reached 385 | upgrade_mod_savepoint(true, 2012060901, 'certificate'); 386 | } 387 | 388 | if ($oldversion < 2012072501) { 389 | // Add a column to store the required grade 390 | $table = new xmldb_table('certificate'); 391 | $requiredtimefield = new xmldb_field('requiredtime', XMLDB_TYPE_INTEGER, '10', null, 392 | XMLDB_NOTNULL, null, '0', 'delivery'); 393 | 394 | if (!$dbman->field_exists($table, $requiredtimefield)) { 395 | $dbman->add_field($table, $requiredtimefield); 396 | } 397 | 398 | // If this table still exists, then the install was from a 1.9 version 399 | if ($dbman->table_exists('certificate_linked_modules')) { 400 | // Now we need to loop through the restrictions in the certificate_linked_modules 401 | // table and check if there were any required time conditions 402 | if ($certlinks = $DB->get_records('certificate_linked_modules')) { 403 | foreach ($certlinks as $link) { 404 | // If the link id is '-1' then the setting applies to the time spent in the course 405 | if ($link->linkid == '-1') { 406 | // Make sure the certificate exists 407 | if ($certificate = $DB->get_record('certificate', array('id' => $link->certificate_id))) { 408 | $certificate->requiredtime = $link->linkgrade; 409 | $DB->update_record('certificate', $certificate); 410 | } 411 | } 412 | } 413 | } 414 | // We can now get rid of this table 415 | $table = new xmldb_table('certificate_linked_modules'); 416 | $dbman->drop_table($table); 417 | } 418 | 419 | // Certificate savepoint reached 420 | upgrade_mod_savepoint(true, 2012072501, 'certificate'); 421 | } 422 | 423 | if ($oldversion < 2012082401) { 424 | $table = new xmldb_table('certificate'); 425 | 426 | // Change length of the fields that store images, so longer image names can be stored 427 | $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); 428 | $dbman->change_field_precision($table, $field); 429 | 430 | $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); 431 | $dbman->change_field_precision($table, $field); 432 | 433 | $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); 434 | $dbman->change_field_precision($table, $field); 435 | 436 | $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); 437 | $dbman->change_field_precision($table, $field); 438 | 439 | // Change length of fields that are unnecessarily large 440 | $field = new xmldb_field('printnumber', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); 441 | $dbman->change_field_precision($table, $field); 442 | 443 | $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, 0); 444 | $dbman->change_field_precision($table, $field); 445 | 446 | $field = new xmldb_field('emailteachers', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); 447 | $dbman->change_field_precision($table, $field); 448 | 449 | $field = new xmldb_field('savecert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); 450 | $dbman->change_field_precision($table, $field); 451 | 452 | $field = new xmldb_field('reportcert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); 453 | $dbman->change_field_precision($table, $field); 454 | 455 | // Certificate savepoint reached 456 | upgrade_mod_savepoint(true, 2012082401, 'certificate'); 457 | } 458 | 459 | if ($oldversion < 2012090901) { 460 | $table = new xmldb_table('certificate'); 461 | 462 | $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, 0, 0, 'printseal'); 463 | if (!$dbman->field_exists($table, $field)) { 464 | $dbman->add_field($table, $field); 465 | } 466 | 467 | // Set the time created to the time modified 468 | $sql = "UPDATE {certificate} 469 | SET timecreated = timemodified"; 470 | $DB->execute($sql); 471 | 472 | // Certificate savepoint reached 473 | upgrade_mod_savepoint(true, 2012090901, 'certificate'); 474 | } 475 | 476 | if ($oldversion < 2014081901) { 477 | // Fix previous upgrades. 478 | 479 | $table = new xmldb_table('certificate'); 480 | 481 | $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); 482 | $dbman->change_field_default($table, $field); 483 | 484 | $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); 485 | $dbman->change_field_default($table, $field); 486 | 487 | $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, null); 488 | $dbman->change_field_default($table, $field); 489 | 490 | $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); 491 | $dbman->change_field_default($table, $field); 492 | 493 | $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); 494 | $dbman->change_field_default($table, $field); 495 | 496 | // Certificate savepoint reached. 497 | upgrade_mod_savepoint(true, 2014081901, 'certificate'); 498 | } 499 | 500 | if ($oldversion < 2020082500) { 501 | // Fix previous upgrades. 502 | 503 | $table = new xmldb_table('certificate'); 504 | $field = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, 'certificatetype'); 505 | $dbman->change_field_default($table, $field); 506 | 507 | // Certificate savepoint reached. 508 | upgrade_mod_savepoint(true, 2020082500, 'certificate'); 509 | } 510 | 511 | return true; 512 | } 513 | -------------------------------------------------------------------------------- /deprecatedlib.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Deprecated certificate functions. 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | /** 27 | * Prepare to be print the date -- defaults to time. 28 | * 29 | * @deprecated since certificate version 2012052501 30 | * @param stdClass $certificate 31 | * @param stdClass $course 32 | * @return string the date 33 | */ 34 | function certificate_generate_date($certificate, $course) { 35 | debugging('certificate_generate_date is deprecated, please use certificate_get_date instead which will 36 | return a date in a human readable format.', DEBUG_DEVELOPER); 37 | 38 | global $DB, $USER; 39 | 40 | // Set certificate date to current time, can be overwritten later 41 | $date = time(); 42 | 43 | if ($certificate->printdate == '2') { 44 | // Get the enrolment end date 45 | $sql = "SELECT MAX(c.timecompleted) as timecompleted 46 | FROM {course_completions} c 47 | WHERE c.userid = :userid 48 | AND c.course = :courseid"; 49 | if ($timecompleted = $DB->get_record_sql($sql, array('userid' => $USER->id, 'courseid' => $course->id))) { 50 | if (!empty($timecompleted->timecompleted)) { 51 | $date = $timecompleted->timecompleted; 52 | } 53 | } 54 | } else if ($certificate->printdate > 2) { 55 | if ($modinfo = certificate_get_mod_grade($course, $certificate->printdate, $USER->id)) { 56 | $date = $modinfo->dategraded; 57 | } 58 | } 59 | 60 | return $date; 61 | } 62 | 63 | /** 64 | * Prepare to print the course grade. 65 | * 66 | * @deprecated since certificate version 2012052501 67 | * @param stdClass $course 68 | * @return mixed 69 | */ 70 | function certificate_print_course_grade($course){ 71 | debugging('certificate_print_course_grade is deprecated, please use certificate_get_grade instead. Ideally 72 | you should be using certificate_get_grade in your certificate type which will either get the course 73 | or module grade depending on your certificate settings.', DEBUG_DEVELOPER); 74 | 75 | global $USER, $DB; 76 | 77 | if ($course_item = grade_item::fetch_course_item($course->id)) { 78 | $grade = new grade_grade(array('itemid'=>$course_item->id, 'userid'=>$USER->id)); 79 | $course_item->gradetype = GRADE_TYPE_VALUE; 80 | $coursegrade = new stdClass; 81 | $coursegrade->points = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals=2); 82 | $coursegrade->percentage = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals=2); 83 | $coursegrade->letter = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals=0); 84 | 85 | return $coursegrade; 86 | } 87 | 88 | return false; 89 | } 90 | 91 | /** 92 | * Prepare to print an activity grade. 93 | * 94 | * @deprecated since certificate version 2012052501 95 | * @param stdClass $course 96 | * @param int $moduleid 97 | * @return mixed 98 | */ 99 | function certificate_print_mod_grade($course, $moduleid){ 100 | debugging('certificate_print_mod_grade is deprecated, please use certificate_get_mod_grade instead. Ideally 101 | you should be using certificate_get_grade in your certificate type which will either get the course 102 | or module grade depending on your certificate settings.', DEBUG_DEVELOPER); 103 | 104 | global $USER; 105 | 106 | return certificate_get_mod_grade($course, $moduleid, $USER->id); 107 | } 108 | 109 | 110 | /** 111 | * Prepare to print an outcome. 112 | * 113 | * @deprecated since certificate version 2012052501 114 | * @param stdClass $course 115 | * @param int $moduleid 116 | * @return mixed 117 | */ 118 | function certificate_print_outcome($course, $id) { 119 | debugging('certificate_print_outcome is deprecated, please use certificate_get_outcome instead', DEBUG_DEVELOPER); 120 | 121 | return certificate_get_outcome($certificate, $course); 122 | } 123 | 124 | /** 125 | * Creates rectangles for line border for A4 size paper. 126 | * 127 | * @deprecated since certificate version 2012052501 128 | * @param stdClass $pdf 129 | * @param stdClass $certificate 130 | * @return null 131 | */ 132 | function draw_frame($pdf, $certificate) { 133 | debugging('draw_frame is deprecated, please use certificate_draw_frame instead', DEBUG_DEVELOPER); 134 | 135 | certificate_draw_frame($pdf, $certificate); 136 | } 137 | 138 | /** 139 | * Creates rectangles for line border for letter size paper. 140 | * 141 | * @deprecated since certificate version 2012052501 142 | * @param stdClass $pdf 143 | * @param stdClass $certificate 144 | * @return null 145 | */ 146 | function draw_frame_letter($pdf, $certificate) { 147 | debugging('draw_frame_letter is deprecated, please use certificate_draw_frame_letter instead', DEBUG_DEVELOPER); 148 | 149 | certificate_draw_frame_letter($pdf, $certificate); 150 | } 151 | 152 | /** 153 | * Prints border images from the borders folder in PNG or JPG formats. 154 | * 155 | * @deprecated since certificate version 2012052501 156 | * @param stdClass $pdf; 157 | * @param stdClass $certificate 158 | * @param int $x x position 159 | * @param int $y y position 160 | * @param int $w the width 161 | * @param int $h the height 162 | * @return null 163 | */ 164 | function print_border($pdf, $certificate, $x, $y, $w, $h) { 165 | debugging('print_watermark is deprecated, please use certificate_print_image instead', DEBUG_DEVELOPER); 166 | 167 | certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $x, $y, $w, $h); 168 | } 169 | 170 | /** 171 | * Prints watermark images. 172 | * 173 | * @deprecated since certificate version 2012052501 174 | * @param stdClass $pdf; 175 | * @param stdClass $certificate 176 | * @param int $x x position 177 | * @param int $y y position 178 | * @param int $w the width 179 | * @param int $h the height 180 | * @return null 181 | */ 182 | function print_watermark($pdf, $certificate, $x, $y, $w, $h) { 183 | debugging('print_watermark is deprecated, please use certificate_print_image instead', DEBUG_DEVELOPER); 184 | 185 | certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $x, $y, $w, $h); 186 | } 187 | 188 | /** 189 | * Prints signature images or a line. 190 | * 191 | * @deprecated since certificate version 2012052501 192 | * @param stdClass $pdf 193 | * @param stdClass $certificate 194 | * @param int $x x position 195 | * @param int $y y position 196 | * @param int $w the width 197 | * @param int $h the height 198 | * @return null 199 | */ 200 | function print_signature($pdf, $certificate, $x, $y, $w, $h) { 201 | debugging('print_signature is deprecated, please use certificate_print_image instead', DEBUG_DEVELOPER); 202 | 203 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $x, $y, $w, $h); 204 | } 205 | 206 | /** 207 | * Prints seal images. 208 | * 209 | * @deprecated since certificate version 2012052501 210 | * @param stdClass $pdf; 211 | * @param stdClass $certificate 212 | * @param int $x x position 213 | * @param int $y y position 214 | * @param int $w the width 215 | * @param int $h the height 216 | * @return null 217 | */ 218 | function print_seal($pdf, $certificate, $x, $y, $w, $h) { 219 | debugging('print_seal is deprecated, please use certificate_print_image instead', DEBUG_DEVELOPER); 220 | 221 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $x, $y, $w, $h); 222 | } 223 | 224 | /** 225 | * Sends text to output given the following params. 226 | * 227 | * @deprecated since certificate version 2012052501 228 | * @param stdClass $pdf 229 | * @param int $x horizontal position 230 | * @param int $y vertical position 231 | * @param char $align L=left, C=center, R=right 232 | * @param string $font any available font in font directory 233 | * @param char $style ''=normal, B=bold, I=italic, U=underline 234 | * @param int $size font size in points 235 | * @param string $text the text to print 236 | * @return null 237 | */ 238 | function cert_printtext($pdf, $x, $y, $align, $font, $style, $size, $text) { 239 | static $hasbeenwarned = false; 240 | 241 | if (!$hasbeenwarned) { 242 | debugging('cert_printtext is deprecated, please use certificate_print_text instead', DEBUG_DEVELOPER); 243 | } 244 | 245 | $hasbeenwarned = true; 246 | certificate_print_text($pdf, $x, $y, $align, $font, $style, $size, $text); 247 | } 248 | 249 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * This page lists all the instances of certificate in a particular course 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | require_once('../../config.php'); 27 | require_once('locallib.php'); 28 | 29 | $id = required_param('id', PARAM_INT); // Course Module ID 30 | 31 | // Ensure that the course specified is valid 32 | if (!$course = $DB->get_record('course', array('id'=> $id))) { 33 | print_error('Course ID is incorrect'); 34 | } 35 | 36 | // Requires a login 37 | require_login($course); 38 | 39 | // Declare variables 40 | $currentsection = ""; 41 | $printsection = ""; 42 | $timenow = time(); 43 | 44 | // Strings used multiple times 45 | $strcertificates = get_string('modulenameplural', 'certificate'); 46 | $strissued = get_string('issued', 'certificate'); 47 | $strname = get_string("name"); 48 | $strsectionname = get_string('sectionname', 'format_'.$course->format); 49 | 50 | // Print the header 51 | $PAGE->set_pagelayout('incourse'); 52 | $PAGE->set_url('/mod/certificate/index.php', array('id'=>$course->id)); 53 | $PAGE->navbar->add($strcertificates); 54 | $PAGE->set_title($strcertificates); 55 | $PAGE->set_heading($course->fullname); 56 | 57 | // Add the page view to the Moodle log 58 | $event = \mod_certificate\event\course_module_instance_list_viewed::create(array( 59 | 'context' => context_course::instance($course->id) 60 | )); 61 | $event->add_record_snapshot('course', $course); 62 | $event->trigger(); 63 | 64 | // Get the certificates, if there are none display a notice 65 | if (!$certificates = get_all_instances_in_course('certificate', $course)) { 66 | echo $OUTPUT->header(); 67 | notice(get_string('nocertificates', 'certificate'), "$CFG->wwwroot/course/view.php?id=$course->id"); 68 | echo $OUTPUT->footer(); 69 | exit(); 70 | } 71 | 72 | $usesections = course_format_uses_sections($course->format); 73 | 74 | $table = new html_table(); 75 | 76 | if ($usesections) { 77 | $table->head = array ($strsectionname, $strname, $strissued); 78 | } else { 79 | $table->head = array ($strname, $strissued); 80 | } 81 | 82 | foreach ($certificates as $certificate) { 83 | if (!$certificate->visible) { 84 | // Show dimmed if the mod is hidden 85 | $link = html_writer::tag('a', $certificate->name, array('class' => 'dimmed', 86 | 'href' => $CFG->wwwroot . '/mod/certificate/view.php?id=' . $certificate->coursemodule)); 87 | } else { 88 | // Show normal if the mod is visible 89 | $link = html_writer::tag('a', $certificate->name, array('class' => 'dimmed', 90 | 'href' => $CFG->wwwroot . '/mod/certificate/view.php?id=' . $certificate->coursemodule)); 91 | } 92 | 93 | $strsection = ''; 94 | if ($certificate->section != $currentsection) { 95 | if ($certificate->section) { 96 | $strsection = get_section_name($course, $certificate->section); 97 | } 98 | if ($currentsection !== '') { 99 | $table->data[] = 'hr'; 100 | } 101 | $currentsection = $certificate->section; 102 | } 103 | 104 | // Get the latest certificate issue 105 | if ($certrecord = $DB->get_record('certificate_issues', array('userid' => $USER->id, 'certificateid' => $certificate->id))) { 106 | $issued = userdate($certrecord->timecreated); 107 | } else { 108 | $issued = get_string('notreceived', 'certificate'); 109 | } 110 | 111 | if ($usesections) { 112 | $table->data[] = array ($strsection, $link, $issued); 113 | } else { 114 | $table->data[] = array ($link, $issued); 115 | } 116 | } 117 | 118 | echo $OUTPUT->header(); 119 | echo '
'; 120 | echo html_writer::table($table); 121 | echo $OUTPUT->footer(); 122 | -------------------------------------------------------------------------------- /lang/en/certificate.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Language strings for the certificate module 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | $string['addlinklabel'] = 'Add another linked activity option'; 27 | $string['addlinktitle'] = 'Click to add another linked activity option'; 28 | $string['areaintro'] = 'Certificate introduction'; 29 | $string['awarded'] = 'Awarded'; 30 | $string['awardedto'] = 'Awarded To'; 31 | $string['back'] = 'Back'; 32 | $string['border'] = 'Border'; 33 | $string['borderblack'] = 'Black'; 34 | $string['borderblue'] = 'Blue'; 35 | $string['borderbrown'] = 'Brown'; 36 | $string['bordercolor'] = 'Border Lines'; 37 | $string['bordercolor_help'] = 'Since images can substantially increase the size of the pdf file, you may choose to print a border of lines instead of using a border image (be sure the Border Image option is set to No). The Border Lines option will print a nice border of three lines of varying widths in the chosen color.'; 38 | $string['bordergreen'] = 'Green'; 39 | $string['borderlines'] = 'Lines'; 40 | $string['borderstyle'] = 'Border Image'; 41 | $string['borderstyle_help'] = 'The Border Image option allows you to choose a border image from the certificate/pix/borders folder. Select the border image that you want around the certificate edges or select no border.'; 42 | $string['certificate'] = 'Verification for certificate code:'; 43 | $string['certificate:addinstance'] = 'Add a certificate instance'; 44 | $string['certificate:manage'] = 'Manage a certificate instance'; 45 | $string['certificate:printteacher'] = 'Be listed as a teacher on the certificate if the print teacher setting is on'; 46 | $string['certificate:student'] = 'Retrieve a certificate'; 47 | $string['certificate:view'] = 'View a certificate'; 48 | $string['certificatename'] = 'Certificate Name'; 49 | $string['certificatereport'] = 'Certificates Report'; 50 | $string['certificatesfor'] = 'Certificates for'; 51 | $string['certificatetype'] = 'Certificate Type'; 52 | $string['certificatetype_help'] = 'This is where you determine the layout of the certificate. The certificate type folder includes four default certificates: 53 | A4 Embedded prints on A4 size paper with embedded font. 54 | A4 Non-Embedded prints on A4 size paper without embedded fonts. 55 | Letter Embedded prints on letter size paper with embedded font. 56 | Letter Non-Embedded prints on letter size paper without embedded fonts. 57 | 58 | The non-embedded types use the Helvetica and Times fonts. If you feel your users will not have these fonts on their computer, or if your language uses characters or symbols that are not accommodated by the Helvetica and Times fonts, then choose an embedded type. The embedded types use the Dejavusans and Dejavuserif fonts. This will make the pdf files rather large; thus it is not recommended to use an embedded type unless you must. 59 | 60 | New type folders can be added to the certificate/type folder. The name of the folder and any new language strings for the new type must be added to the certificate language file.'; 61 | $string['certify'] = 'This is to certify that'; 62 | $string['code'] = 'Code'; 63 | $string['completiondate'] = 'Course Completion'; 64 | $string['course'] = 'For'; 65 | $string['coursegrade'] = 'Course Grade'; 66 | $string['coursename'] = 'Course'; 67 | $string['coursetimereq'] = 'Required minutes in course'; 68 | $string['coursetimereq_help'] = 'Enter here the minimum amount of time, in minutes, that a student must be logged into the course before they will be able to receive the certificate.'; 69 | $string['credithours'] = 'Credit Hours'; 70 | $string['customtext'] = 'Custom Text'; 71 | $string['customtext_help'] = 'If you want the certificate to print different names for the teacher than those who are assigned 72 | the role of teacher, do not select Print Teacher or any signature image except for the line image. Enter the teacher names in this text box as you would like them to appear. By default, this text is placed in the lower left of the certificate. The following html tags are available: <br>, <p>, <b>, <i>, <u>, <img> (src and width (or height) are mandatory), <a> (href is mandatory), <font> (possible attributes are: color, (hex color code), face, (arial, times, courier, helvetica, symbol)).'; 73 | $string['date'] = 'On'; 74 | $string['datefmt'] = 'Date Format'; 75 | $string['datefmt_help'] = 'Choose a date format to print the date on the certificate. Or, choose the last option to have the date printed in the format of the user\'s chosen language.'; 76 | $string['datehelp'] = 'Date'; 77 | $string['deletissuedcertificates'] = 'Delete issued certificates'; 78 | $string['delivery'] = 'Delivery'; 79 | $string['delivery_help'] = 'Choose here how you would like your students to get their certificate. 80 | Open in Browser: Opens the certificate in a new browser window. 81 | Force Download: Opens the browser file download window. 82 | Email Certificate: Choosing this option sends the certificate to the student as an email attachment. 83 | After a user receives their certificate, if they click on the certificate link from the course homepage, they will see the date they received their certificate and will be able to review their received certificate.'; 84 | $string['designoptions'] = 'Design Options'; 85 | $string['download'] = 'Force download'; 86 | $string['emailcertificate'] = 'Email'; 87 | $string['emailothers'] = 'Email Others'; 88 | $string['emailothers_help'] = 'Enter the email addresses here, separated by a comma, of those who should be alerted with an email whenever students receive a certificate.'; 89 | $string['emailstudenttext'] = 'Attached is your certificate for {$a->course}.'; 90 | $string['emailteachers'] = 'Email Teachers'; 91 | $string['emailteachers_help'] = 'If enabled, then teachers are alerted with an email whenever students receive a certificate.'; 92 | $string['emailteachermail'] = ' 93 | {$a->student} has received their certificate: \'{$a->certificate}\' 94 | for {$a->course}. 95 | 96 | You can review it here: 97 | 98 | {$a->url}'; 99 | $string['emailteachermailhtml'] = ' 100 | {$a->student} has received their certificate: \'{$a->certificate}\' 101 | for {$a->course}. 102 | 103 | You can review it here: 104 | 105 | Certificate Report.'; 106 | $string['entercode'] = 'Enter certificate code to verify:'; 107 | $string['fontsans'] = 'Sans-serif font family'; 108 | $string['fontsans_desc'] = 'Sans-serif font family for certificates with embedded fonts'; 109 | $string['fontserif'] = 'Serif font family'; 110 | $string['fontserif_desc'] = 'Serif font family for certificates with embedded fonts'; 111 | $string['getcertificate'] = 'Get your certificate'; 112 | $string['grade'] = 'Grade'; 113 | $string['gradedate'] = 'Grade Date'; 114 | $string['gradefmt'] = 'Grade Format'; 115 | $string['gradefmt_help'] = 'There are three available formats if you choose to print a grade on the certificate: 116 | 117 | Percentage Grade: Prints the grade as a percentage. 118 | Points Grade: Prints the point value of the grade. 119 | Letter Grade: Prints the percentage grade as a letter.'; 120 | $string['gradeletter'] = 'Letter Grade'; 121 | $string['gradepercent'] = 'Percentage Grade'; 122 | $string['gradepoints'] = 'Points Grade'; 123 | $string['imagetype'] = 'Image Type'; 124 | $string['incompletemessage'] = 'In order to download your certificate, you must first complete all required activities. Please return to the course to complete your coursework.'; 125 | $string['intro'] = 'Introduction'; 126 | $string['issueoptions'] = 'Issue Options'; 127 | $string['issued'] = 'Issued'; 128 | $string['issueddate'] = 'Date Issued'; 129 | $string['landscape'] = 'Landscape'; 130 | $string['lastviewed'] = 'You last received this certificate on:'; 131 | $string['letter'] = 'Letter'; 132 | $string['lockingoptions'] = 'Locking Options'; 133 | $string['modulename'] = 'Certificate'; 134 | $string['modulename_help'] = 'This module allows for the dynamic generation of certificates based on predefined conditions set by the teacher.'; 135 | $string['modulename_link'] = 'Certificate_module'; 136 | $string['modulenameplural'] = 'Certificates'; 137 | $string['mycertificates'] = 'My Certificates'; 138 | $string['nocertificates'] = 'There are no certificates'; 139 | $string['nocertificatesissued'] = 'There are no certificates that have been issued'; 140 | $string['nocertificatesreceived'] = 'has not received any course certificates.'; 141 | $string['nofileselected'] = 'Must choose a file to upload!'; 142 | $string['nogrades'] = 'No grades available'; 143 | $string['notapplicable'] = 'N/A'; 144 | $string['notfound'] = 'The certificate number could not be validated.'; 145 | $string['notissued'] = 'Not Issued'; 146 | $string['notissuedyet'] = 'Not issued yet'; 147 | $string['notreceived'] = 'You have not received this certificate'; 148 | $string['openbrowser'] = 'Open in new window'; 149 | $string['opendownload'] = 'Click the button below to save your certificate to your computer.'; 150 | $string['openemail'] = 'Click the button below and your certificate will be sent to you as an email attachment.'; 151 | $string['openwindow'] = 'Click the button below to open your certificate in a new browser window.'; 152 | $string['or'] = 'Or'; 153 | $string['orientation'] = 'Orientation'; 154 | $string['orientation_help'] = 'Choose whether you want your certificate orientation to be portrait or landscape.'; 155 | $string['pluginadministration'] = 'Certificate administration'; 156 | $string['pluginname'] = 'Certificate'; 157 | $string['portrait'] = 'Portrait'; 158 | $string['printdate'] = 'Print Date'; 159 | $string['printdate_help'] = 'This is the date that will be printed, if a print date is selected. If the course completion date is selected but the student has not completed the course, the date received will be printed. You can also choose to print the date based on when an activity was graded. If a certificate is issued before that activity is graded, the date received will be printed.'; 160 | $string['printerfriendly'] = 'Printer-friendly page'; 161 | $string['printhours'] = 'Print Credit Hours'; 162 | $string['printhours_help'] = 'Enter here the number of credit hours to be printed on the certificate.'; 163 | $string['printgrade'] = 'Print Grade'; 164 | $string['printgrade_help'] = 'You can choose any available course grade items from the gradebook to print the user\'s grade received for that item on the certificate. The grade items are listed in the order in which they appear in the gradebook. Choose the format of the grade below.'; 165 | $string['printnumber'] = 'Print Code'; 166 | $string['printnumber_help'] = 'A unique 10-digit code of random letters and numbers can be printed on the certificate. This number can then be verified by comparing it to the code number displayed in the certificates report.'; 167 | $string['printoutcome'] = 'Print Outcome'; 168 | $string['printoutcome_help'] = 'You can choose any course outcome to print the name of the outcome and the user\'s received outcome on the certificate. An example might be: Assignment Outcome: Proficient.'; 169 | $string['printseal'] = 'Seal or Logo Image'; 170 | $string['printseal_help'] = 'This option allows you to select a seal or logo to print on the certificate from the certificate/pix/seals folder. By default, this image is placed in the lower right corner of the certificate.'; 171 | $string['printsignature'] = 'Signature Image'; 172 | $string['printsignature_help'] = 'This option allows you to print a signature image from the certificate/pix/signatures folder. You can print a graphic representation of a signature, or print a line for a written signature. By default, this image is placed in the lower left of the certificate.'; 173 | $string['printteacher'] = 'Print Teacher Name(s)'; 174 | $string['printteacher_help'] = 'For printing the teacher name on the certificate, set the role of teacher at the module level. Do this if, for example, you have more than one teacher for the course or you have more than one certificate in the course and you want to print different teacher names on each certificate. Click to edit the certificate, then click on the Locally assigned roles tab. Then assign the role of Teacher (editing teacher) to the certificate (they do not HAVE to be a teacher in the course--you can assign that role to anyone). Those names will be printed on the certificate for teacher.'; 175 | $string['printwmark'] = 'Watermark Image'; 176 | $string['printwmark_help'] = 'A watermark file can be placed in the background of the certificate. A watermark is a faded graphic. A watermark could be a logo, seal, crest, wording, or whatever you want to use as a graphic background.'; 177 | $string['receivedcerts'] = 'Received certificates'; 178 | $string['receiveddate'] = 'Date Received'; 179 | $string['removecert'] = 'Issued certificates removed'; 180 | $string['report'] = 'Report'; 181 | $string['reportcert'] = 'Report Certificates'; 182 | $string['reportcert_help'] = 'If you choose yes here, then this certificate\'s date received, code number, and the course name will be shown on the user certificate reports. If you choose to print a grade on this certificate, then that grade will also be shown on the certificate report.'; 183 | $string['requiredtimenotmet'] = 'You must spend at least a minimum of {$a->requiredtime} minutes in the course before you can access this certificate'; 184 | $string['requiredtimenotvalid'] = 'The required time must be a valid number greater than 0'; 185 | $string['reviewcertificate'] = 'Review your certificate'; 186 | $string['savecert'] = 'Save Certificates'; 187 | $string['savecert_help'] = 'If you choose this option, then a copy of each user\'s certificate pdf file is saved in the course files moddata folder for that certificate. A link to each user\'s saved certificate will be displayed in the certificate report.'; 188 | $string['seal'] = 'Seal'; 189 | $string['sigline'] = 'line'; 190 | $string['signature'] = 'Signature'; 191 | $string['statement'] = 'has completed the course'; 192 | $string['summaryofattempts'] = 'Summary of previously received certificates'; 193 | $string['textoptions'] = 'Text Options'; 194 | $string['title'] = 'CERTIFICATE of ACHIEVEMENT'; 195 | $string['to'] = 'Awarded to'; 196 | $string['typeA4_embedded'] = 'A4 Embedded'; 197 | $string['typeA4_non_embedded'] = 'A4 Non-Embedded'; 198 | $string['typeletter_embedded'] = 'Letter Embedded'; 199 | $string['typeletter_non_embedded'] = 'Letter Non-Embedded'; 200 | $string['unsupportedfiletype'] = 'File must be a jpeg or png file'; 201 | $string['uploadimage'] = 'Upload image'; 202 | $string['uploadimagedesc'] = 'This button will take you to a new screen where you will be able to upload images.'; 203 | $string['userdateformat'] = 'User\'s Language Date Format'; 204 | $string['validate'] = 'Verify'; 205 | $string['verifycertificate'] = 'Verify Certificate'; 206 | $string['viewcertificateviews'] = 'View {$a} issued certificates'; 207 | $string['viewed'] = 'You received this certificate on:'; 208 | $string['viewtranscript'] = 'View Certificates'; 209 | $string['watermark'] = 'Watermark'; 210 | 211 | $string['privacy:metadata:mod_certificate'] = 'Info about issued certificates'; 212 | $string['privacy:metadata:mod_certificate:userid'] = 'User info'; 213 | $string['privacy:metadata:mod_certificate:certificateid'] = 'Certificate info'; 214 | $string['privacy:metadata:mod_certificate:code'] = 'Code info'; 215 | $string['privacy:metadata:mod_certificate:timecreated'] = 'Time created info'; 216 | $string['privacy:metadata:core_files'] = 'Files linked to issued certificates are stored using the core_files system'; 217 | -------------------------------------------------------------------------------- /lib.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Certificate module core interaction API 20 | * 21 | * @package mod_certificate 22 | * @copyright 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 | * Add certificate instance. 30 | * 31 | * @param stdClass $certificate 32 | * @return int new certificate instance id 33 | */ 34 | function certificate_add_instance($certificate) { 35 | global $DB; 36 | 37 | // Create the certificate. 38 | $certificate->timecreated = time(); 39 | $certificate->timemodified = $certificate->timecreated; 40 | 41 | return $DB->insert_record('certificate', $certificate); 42 | } 43 | 44 | /** 45 | * Update certificate instance. 46 | * 47 | * @param stdClass $certificate 48 | * @return bool true 49 | */ 50 | function certificate_update_instance($certificate) { 51 | global $DB; 52 | 53 | // Update the certificate. 54 | $certificate->timemodified = time(); 55 | $certificate->id = $certificate->instance; 56 | 57 | return $DB->update_record('certificate', $certificate); 58 | } 59 | 60 | /** 61 | * Given an ID of an instance of this module, 62 | * this function will permanently delete the instance 63 | * and any data that depends on it. 64 | * 65 | * @param int $id 66 | * @return bool true if successful 67 | */ 68 | function certificate_delete_instance($id) { 69 | global $DB; 70 | 71 | // Ensure the certificate exists 72 | if (!$certificate = $DB->get_record('certificate', array('id' => $id))) { 73 | return false; 74 | } 75 | 76 | // Prepare file record object 77 | if (!$cm = get_coursemodule_from_instance('certificate', $id)) { 78 | return false; 79 | } 80 | 81 | $result = true; 82 | $DB->delete_records('certificate_issues', array('certificateid' => $id)); 83 | if (!$DB->delete_records('certificate', array('id' => $id))) { 84 | $result = false; 85 | } 86 | 87 | // Delete any files associated with the certificate 88 | $context = context_module::instance($cm->id); 89 | $fs = get_file_storage(); 90 | $fs->delete_area_files($context->id); 91 | 92 | return $result; 93 | } 94 | 95 | /** 96 | * This function is used by the reset_course_userdata function in moodlelib. 97 | * This function will remove all posts from the specified certificate 98 | * and clean up any related data. 99 | * 100 | * Written by Jean-Michel Vedrine 101 | * 102 | * @param $data the data submitted from the reset course. 103 | * @return array status array 104 | */ 105 | function certificate_reset_userdata($data) { 106 | global $DB; 107 | 108 | $componentstr = get_string('modulenameplural', 'certificate'); 109 | $status = array(); 110 | 111 | if (!empty($data->reset_certificate)) { 112 | $sql = "SELECT cert.id 113 | FROM {certificate} cert 114 | WHERE cert.course = :courseid"; 115 | $params = array('courseid' => $data->courseid); 116 | $certificates = $DB->get_records_sql($sql, $params); 117 | $fs = get_file_storage(); 118 | if ($certificates) { 119 | foreach ($certificates as $certid => $unused) { 120 | if (!$cm = get_coursemodule_from_instance('certificate', $certid)) { 121 | continue; 122 | } 123 | $context = context_module::instance($cm->id); 124 | $fs->delete_area_files($context->id, 'mod_certificate', 'issue'); 125 | } 126 | } 127 | 128 | $DB->delete_records_select('certificate_issues', "certificateid IN ($sql)", $params); 129 | $status[] = array('component' => $componentstr, 'item' => get_string('removecert', 'certificate'), 'error' => false); 130 | } 131 | // Updating dates - shift may be negative too 132 | if ($data->timeshift) { 133 | shift_course_mod_dates('certificate', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid); 134 | $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); 135 | } 136 | 137 | return $status; 138 | } 139 | 140 | /** 141 | * Implementation of the function for printing the form elements that control 142 | * whether the course reset functionality affects the certificate. 143 | * 144 | * Written by Jean-Michel Vedrine 145 | * 146 | * @param $mform form passed by reference 147 | */ 148 | function certificate_reset_course_form_definition(&$mform) { 149 | $mform->addElement('header', 'certificateheader', get_string('modulenameplural', 'certificate')); 150 | $mform->addElement('advcheckbox', 'reset_certificate', get_string('deletissuedcertificates', 'certificate')); 151 | } 152 | 153 | /** 154 | * Course reset form defaults. 155 | * 156 | * Written by Jean-Michel Vedrine 157 | * 158 | * @param stdClass $course 159 | * @return array 160 | */ 161 | function certificate_reset_course_form_defaults($course) { 162 | return array('reset_certificate' => 1); 163 | } 164 | 165 | /** 166 | * Returns information about received certificate. 167 | * Used for user activity reports. 168 | * 169 | * @param stdClass $course 170 | * @param stdClass $user 171 | * @param stdClass $mod 172 | * @param stdClass $certificate 173 | * @return stdClass the user outline object 174 | */ 175 | function certificate_user_outline($course, $user, $mod, $certificate) { 176 | global $DB; 177 | 178 | $result = new stdClass; 179 | if ($issue = $DB->get_record('certificate_issues', array('certificateid' => $certificate->id, 'userid' => $user->id))) { 180 | $result->info = get_string('issued', 'certificate'); 181 | $result->time = $issue->timecreated; 182 | } else { 183 | $result->info = get_string('notissued', 'certificate'); 184 | } 185 | 186 | return $result; 187 | } 188 | 189 | /** 190 | * Returns information about received certificate. 191 | * Used for user activity reports. 192 | * 193 | * @param stdClass $course 194 | * @param stdClass $user 195 | * @param stdClass $mod 196 | * @param stdClass $certificate 197 | * @return string the user complete information 198 | */ 199 | function certificate_user_complete($course, $user, $mod, $certificate) { 200 | global $DB, $OUTPUT, $CFG; 201 | require_once($CFG->dirroot.'/mod/certificate/locallib.php'); 202 | 203 | if ($issue = $DB->get_record('certificate_issues', array('certificateid' => $certificate->id, 'userid' => $user->id))) { 204 | echo $OUTPUT->box_start(); 205 | echo get_string('issued', 'certificate') . ": "; 206 | echo userdate($issue->timecreated); 207 | $cm = get_coursemodule_from_instance('certificate', $certificate->id, $course->id); 208 | certificate_print_user_files($certificate, $user->id, context_module::instance($cm->id)->id); 209 | echo '
'; 210 | echo $OUTPUT->box_end(); 211 | } else { 212 | print_string('notissuedyet', 'certificate'); 213 | } 214 | } 215 | 216 | /** 217 | * Must return an array of user records (all data) who are participants 218 | * for a given instance of certificate. 219 | * 220 | * @param int $certificateid 221 | * @return stdClass list of participants 222 | */ 223 | function certificate_get_participants($certificateid) { 224 | global $DB; 225 | 226 | $sql = "SELECT DISTINCT u.id, u.id 227 | FROM {user} u, {certificate_issues} a 228 | WHERE a.certificateid = :certificateid 229 | AND u.id = a.userid"; 230 | return $DB->get_records_sql($sql, array('certificateid' => $certificateid)); 231 | } 232 | 233 | /** 234 | * @uses FEATURE_GROUPS 235 | * @uses FEATURE_GROUPINGS 236 | * @uses FEATURE_GROUPMEMBERSONLY 237 | * @uses FEATURE_MOD_INTRO 238 | * @uses FEATURE_COMPLETION_TRACKS_VIEWS 239 | * @uses FEATURE_GRADE_HAS_GRADE 240 | * @uses FEATURE_GRADE_OUTCOMES 241 | * @param string $feature FEATURE_xx constant for requested feature 242 | * @return mixed True if module supports feature, null if doesn't know 243 | */ 244 | function certificate_supports($feature) { 245 | switch ($feature) { 246 | case FEATURE_GROUPS: return true; 247 | case FEATURE_GROUPINGS: return true; 248 | case FEATURE_GROUPMEMBERSONLY: return true; 249 | case FEATURE_MOD_INTRO: return true; 250 | case FEATURE_COMPLETION_TRACKS_VIEWS: return true; 251 | case FEATURE_BACKUP_MOODLE2: return true; 252 | 253 | default: return null; 254 | } 255 | } 256 | 257 | /** 258 | * Serves certificate issues and other files. 259 | * 260 | * @param stdClass $course 261 | * @param stdClass $cm 262 | * @param stdClass $context 263 | * @param string $filearea 264 | * @param array $args 265 | * @param bool $forcedownload 266 | * @return bool|nothing false if file not found, does not return anything if found - just send the file 267 | */ 268 | function certificate_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { 269 | global $CFG, $DB, $USER; 270 | 271 | if ($context->contextlevel != CONTEXT_MODULE) { 272 | return false; 273 | } 274 | 275 | if (!$certificate = $DB->get_record('certificate', array('id' => $cm->instance))) { 276 | return false; 277 | } 278 | 279 | require_login($course, false, $cm); 280 | 281 | require_once($CFG->libdir.'/filelib.php'); 282 | 283 | $certrecord = (int)array_shift($args); 284 | 285 | if (!$certrecord = $DB->get_record('certificate_issues', array('id' => $certrecord))) { 286 | return false; 287 | } 288 | 289 | $canmanagecertificate = has_capability('mod/certificate:manage', $context); 290 | if ($USER->id != $certrecord->userid and !$canmanagecertificate) { 291 | return false; 292 | } 293 | 294 | if ($filearea === 'issue') { 295 | $relativepath = implode('/', $args); 296 | $fullpath = "/{$context->id}/mod_certificate/issue/$certrecord->id/$relativepath"; 297 | 298 | $fs = get_file_storage(); 299 | if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 300 | return false; 301 | } 302 | send_stored_file($file, 0, 0, true); // download MUST be forced - security! 303 | } else if ($filearea === 'onthefly') { 304 | require_once($CFG->dirroot.'/mod/certificate/locallib.php'); 305 | require_once("$CFG->libdir/pdflib.php"); 306 | 307 | if (!$certificate = $DB->get_record('certificate', array('id' => $certrecord->certificateid))) { 308 | return false; 309 | } 310 | 311 | if ($certificate->requiredtime && !$canmanagecertificate) { 312 | if (certificate_get_course_time($course->id) < ($certificate->requiredtime * 60)) { 313 | return false; 314 | } 315 | } 316 | 317 | // Load the specific certificate type. It will fill the $pdf var. 318 | require("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php"); 319 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; 320 | $filecontents = $pdf->Output('', 'S'); 321 | send_file($filecontents, $filename, 0, 0, true, true, 'application/pdf'); 322 | } 323 | } 324 | 325 | /** 326 | * Used for course participation report (in case certificate is added). 327 | * 328 | * @return array 329 | */ 330 | function certificate_get_view_actions() { 331 | return array('view', 'view all', 'view report'); 332 | } 333 | 334 | /** 335 | * Used for course participation report (in case certificate is added). 336 | * 337 | * @return array 338 | */ 339 | function certificate_get_post_actions() { 340 | return array('received'); 341 | } 342 | -------------------------------------------------------------------------------- /mobile/mod_certificate.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/mobile/mod_certificate.zip -------------------------------------------------------------------------------- /mod_form.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Instance add/edit form 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | if (!defined('MOODLE_INTERNAL')) { 27 | die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page 28 | } 29 | 30 | require_once ($CFG->dirroot.'/course/moodleform_mod.php'); 31 | require_once($CFG->dirroot.'/mod/certificate/locallib.php'); 32 | 33 | class mod_certificate_mod_form extends moodleform_mod { 34 | 35 | function definition() { 36 | global $CFG; 37 | 38 | $mform =& $this->_form; 39 | 40 | $mform->addElement('header', 'general', get_string('general', 'form')); 41 | 42 | $mform->addElement('text', 'name', get_string('certificatename', 'certificate'), array('size'=>'64')); 43 | if (!empty($CFG->formatstringstriptags)) { 44 | $mform->setType('name', PARAM_TEXT); 45 | } else { 46 | $mform->setType('name', PARAM_CLEAN); 47 | } 48 | $mform->addRule('name', null, 'required', null, 'client'); 49 | 50 | $this->standard_intro_elements(get_string('intro', 'certificate')); 51 | 52 | // Issue options 53 | $mform->addElement('header', 'issueoptions', get_string('issueoptions', 'certificate')); 54 | $ynoptions = array( 0 => get_string('no'), 1 => get_string('yes')); 55 | $mform->addElement('select', 'emailteachers', get_string('emailteachers', 'certificate'), $ynoptions); 56 | $mform->setDefault('emailteachers', 0); 57 | $mform->addHelpButton('emailteachers', 'emailteachers', 'certificate'); 58 | 59 | $mform->addElement('text', 'emailothers', get_string('emailothers', 'certificate'), array('size'=>'40', 'maxsize'=>'200')); 60 | $mform->setType('emailothers', PARAM_TEXT); 61 | $mform->addHelpButton('emailothers', 'emailothers', 'certificate'); 62 | 63 | $deliveryoptions = array( 0 => get_string('openbrowser', 'certificate'), 1 => get_string('download', 'certificate'), 2 => get_string('emailcertificate', 'certificate')); 64 | $mform->addElement('select', 'delivery', get_string('delivery', 'certificate'), $deliveryoptions); 65 | $mform->setDefault('delivery', 0); 66 | $mform->addHelpButton('delivery', 'delivery', 'certificate'); 67 | 68 | $mform->addElement('select', 'savecert', get_string('savecert', 'certificate'), $ynoptions); 69 | $mform->setDefault('savecert', 0); 70 | $mform->addHelpButton('savecert', 'savecert', 'certificate'); 71 | 72 | $reportfile = "$CFG->dirroot/certificates/index.php"; 73 | if (file_exists($reportfile)) { 74 | $mform->addElement('select', 'reportcert', get_string('reportcert', 'certificate'), $ynoptions); 75 | $mform->setDefault('reportcert', 0); 76 | $mform->addHelpButton('reportcert', 'reportcert', 'certificate'); 77 | } 78 | 79 | $mform->addElement('text', 'requiredtime', get_string('coursetimereq', 'certificate'), array('size'=>'3')); 80 | $mform->setType('requiredtime', PARAM_INT); 81 | $mform->addHelpButton('requiredtime', 'coursetimereq', 'certificate'); 82 | 83 | // Text Options 84 | $mform->addElement('header', 'textoptions', get_string('textoptions', 'certificate')); 85 | 86 | $modules = certificate_get_mods(); 87 | $dateoptions = certificate_get_date_options() + $modules; 88 | $mform->addElement('select', 'printdate', get_string('printdate', 'certificate'), $dateoptions); 89 | $mform->setDefault('printdate', 'N'); 90 | $mform->addHelpButton('printdate', 'printdate', 'certificate'); 91 | 92 | $dateformatoptions = array( 1 => 'January 1, 2000', 2 => 'January 1st, 2000', 3 => '1 January 2000', 93 | 4 => 'January 2000', 5 => get_string('userdateformat', 'certificate')); 94 | $mform->addElement('select', 'datefmt', get_string('datefmt', 'certificate'), $dateformatoptions); 95 | $mform->setDefault('datefmt', 0); 96 | $mform->addHelpButton('datefmt', 'datefmt', 'certificate'); 97 | 98 | $mform->addElement('select', 'printnumber', get_string('printnumber', 'certificate'), $ynoptions); 99 | $mform->setDefault('printnumber', 0); 100 | $mform->addHelpButton('printnumber', 'printnumber', 'certificate'); 101 | 102 | $gradeoptions = certificate_get_grade_options() + certificate_get_grade_categories($this->current->course) + $modules; 103 | $mform->addElement('select', 'printgrade', get_string('printgrade', 'certificate'),$gradeoptions); 104 | $mform->setDefault('printgrade', 0); 105 | $mform->addHelpButton('printgrade', 'printgrade', 'certificate'); 106 | 107 | $gradeformatoptions = array( 1 => get_string('gradepercent', 'certificate'), 2 => get_string('gradepoints', 'certificate'), 108 | 3 => get_string('gradeletter', 'certificate')); 109 | $mform->addElement('select', 'gradefmt', get_string('gradefmt', 'certificate'), $gradeformatoptions); 110 | $mform->setDefault('gradefmt', 0); 111 | $mform->addHelpButton('gradefmt', 'gradefmt', 'certificate'); 112 | 113 | $outcomeoptions = certificate_get_outcomes(); 114 | $mform->addElement('select', 'printoutcome', get_string('printoutcome', 'certificate'),$outcomeoptions); 115 | $mform->setDefault('printoutcome', 0); 116 | $mform->addHelpButton('printoutcome', 'printoutcome', 'certificate'); 117 | 118 | $mform->addElement('text', 'printhours', get_string('printhours', 'certificate'), array('size'=>'5', 'maxlength' => '255')); 119 | $mform->setType('printhours', PARAM_TEXT); 120 | $mform->addHelpButton('printhours', 'printhours', 'certificate'); 121 | 122 | $mform->addElement('select', 'printteacher', get_string('printteacher', 'certificate'), $ynoptions); 123 | $mform->setDefault('printteacher', 0); 124 | $mform->addHelpButton('printteacher', 'printteacher', 'certificate'); 125 | 126 | $mform->addElement('textarea', 'customtext', get_string('customtext', 'certificate'), array('cols'=>'40', 'rows'=>'4', 'wrap'=>'virtual')); 127 | $mform->setType('customtext', PARAM_RAW); 128 | $mform->addHelpButton('customtext', 'customtext', 'certificate'); 129 | 130 | // Design Options 131 | $mform->addElement('header', 'designoptions', get_string('designoptions', 'certificate')); 132 | $mform->addElement('select', 'certificatetype', get_string('certificatetype', 'certificate'), certificate_types()); 133 | $mform->setDefault('certificatetype', 'A4_non_embedded'); 134 | $mform->addHelpButton('certificatetype', 'certificatetype', 'certificate'); 135 | 136 | $orientation = array( 'L' => get_string('landscape', 'certificate'), 'P' => get_string('portrait', 'certificate')); 137 | $mform->addElement('select', 'orientation', get_string('orientation', 'certificate'), $orientation); 138 | $mform->setDefault('orientation', 'L'); 139 | $mform->addHelpButton('orientation', 'orientation', 'certificate'); 140 | 141 | $mform->addElement('select', 'borderstyle', get_string('borderstyle', 'certificate'), certificate_get_images(CERT_IMAGE_BORDER)); 142 | $mform->setDefault('borderstyle', '0'); 143 | $mform->addHelpButton('borderstyle', 'borderstyle', 'certificate'); 144 | 145 | $printframe = array( 0 => get_string('no'), 1 => get_string('borderblack', 'certificate'), 2 => get_string('borderbrown', 'certificate'), 146 | 3 => get_string('borderblue', 'certificate'), 4 => get_string('bordergreen', 'certificate')); 147 | $mform->addElement('select', 'bordercolor', get_string('bordercolor', 'certificate'), $printframe); 148 | $mform->setDefault('bordercolor', '0'); 149 | $mform->addHelpButton('bordercolor', 'bordercolor', 'certificate'); 150 | 151 | $mform->addElement('select', 'printwmark', get_string('printwmark', 'certificate'), certificate_get_images(CERT_IMAGE_WATERMARK)); 152 | $mform->setDefault('printwmark', '0'); 153 | $mform->addHelpButton('printwmark', 'printwmark', 'certificate'); 154 | 155 | $mform->addElement('select', 'printsignature', get_string('printsignature', 'certificate'), certificate_get_images(CERT_IMAGE_SIGNATURE)); 156 | $mform->setDefault('printsignature', '0'); 157 | $mform->addHelpButton('printsignature', 'printsignature', 'certificate'); 158 | 159 | $mform->addElement('select', 'printseal', get_string('printseal', 'certificate'), certificate_get_images(CERT_IMAGE_SEAL)); 160 | $mform->setDefault('printseal', '0'); 161 | $mform->addHelpButton('printseal', 'printseal', 'certificate'); 162 | 163 | $this->standard_coursemodule_elements(); 164 | 165 | $this->add_action_buttons(); 166 | } 167 | 168 | /** 169 | * Some basic validation 170 | * 171 | * @param $data 172 | * @param $files 173 | * @return array 174 | */ 175 | public function validation($data, $files) { 176 | $errors = parent::validation($data, $files); 177 | 178 | // Check that the required time entered is valid 179 | if ((!is_number($data['requiredtime']) || $data['requiredtime'] < 0)) { 180 | $errors['requiredtime'] = get_string('requiredtimenotvalid', 'certificate'); 181 | } 182 | 183 | return $errors; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /pix/borders/Fancy1-black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy1-black.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy1-blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy1-blue.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy1-brown.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy1-brown.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy1-green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy1-green.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy2-black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy2-black.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy2-blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy2-blue.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy2-brown.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy2-brown.jpg -------------------------------------------------------------------------------- /pix/borders/Fancy2-green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/borders/Fancy2-green.jpg -------------------------------------------------------------------------------- /pix/icon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/icon.gif -------------------------------------------------------------------------------- /pix/seals/Fancy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/seals/Fancy.png -------------------------------------------------------------------------------- /pix/seals/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/seals/Logo.png -------------------------------------------------------------------------------- /pix/seals/Plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/seals/Plain.png -------------------------------------------------------------------------------- /pix/seals/Quality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/seals/Quality.png -------------------------------------------------------------------------------- /pix/seals/Teamwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/seals/Teamwork.png -------------------------------------------------------------------------------- /pix/signatures/Line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/signatures/Line.png -------------------------------------------------------------------------------- /pix/signatures/RVincent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/signatures/RVincent.png -------------------------------------------------------------------------------- /pix/watermarks/Crest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/watermarks/Crest.png -------------------------------------------------------------------------------- /pix/watermarks/Fleursdelis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdjnelson/moodle-mod_certificate/39e7616450c9090015a8243946dcf233c04b5d0f/pix/watermarks/Fleursdelis.png -------------------------------------------------------------------------------- /report.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Handles viewing the report 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | require_once('../../config.php'); 27 | require_once('locallib.php'); 28 | 29 | $id = required_param('id', PARAM_INT); // Course module ID 30 | $sort = optional_param('sort', '', PARAM_RAW); 31 | $download = optional_param('download', '', PARAM_ALPHA); 32 | $action = optional_param('action', '', PARAM_ALPHA); 33 | 34 | $page = optional_param('page', 0, PARAM_INT); 35 | $perpage = optional_param('perpage', CERT_PER_PAGE, PARAM_INT); 36 | 37 | // Ensure the perpage variable does not exceed the max allowed if 38 | // the user has not specified they wish to view all certificates. 39 | if (CERT_PER_PAGE !== 0) { 40 | if (($perpage > CERT_MAX_PER_PAGE) || ($perpage <= 0)) { 41 | $perpage = CERT_MAX_PER_PAGE; 42 | } 43 | } else { 44 | $perpage = '9999999'; 45 | } 46 | 47 | $url = new moodle_url('/mod/certificate/report.php', array('id'=>$id, 'page' => $page, 'perpage' => $perpage)); 48 | if ($download) { 49 | $url->param('download', $download); 50 | } 51 | if ($action) { 52 | $url->param('action', $action); 53 | } 54 | $PAGE->set_url($url); 55 | 56 | if (!$cm = get_coursemodule_from_id('certificate', $id)) { 57 | print_error('Course Module ID was incorrect'); 58 | } 59 | 60 | if (!$course = $DB->get_record('course', array('id'=> $cm->course))) { 61 | print_error('Course is misconfigured'); 62 | } 63 | 64 | if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) { 65 | print_error('Certificate ID was incorrect'); 66 | } 67 | 68 | // Requires a course login 69 | require_login($course, false, $cm); 70 | 71 | // Check capabilities 72 | $context = context_module::instance($cm->id); 73 | require_capability('mod/certificate:manage', $context); 74 | 75 | // Declare some variables 76 | $strcertificates = get_string('modulenameplural', 'certificate'); 77 | $strcertificate = get_string('modulename', 'certificate'); 78 | $strto = get_string('awardedto', 'certificate'); 79 | $strdate = get_string('receiveddate', 'certificate'); 80 | $strgrade = get_string('grade','certificate'); 81 | $strcode = get_string('code', 'certificate'); 82 | $strreport= get_string('report', 'certificate'); 83 | 84 | if (!$download) { 85 | $PAGE->navbar->add($strreport); 86 | $PAGE->set_title(format_string($certificate->name).": $strreport"); 87 | $PAGE->set_heading($course->fullname); 88 | // Check to see if groups are being used in this choice 89 | if ($groupmode = groups_get_activity_groupmode($cm)) { 90 | groups_get_activity_group($cm, true); 91 | } 92 | } else { 93 | $groupmode = groups_get_activity_groupmode($cm); 94 | // Get all results when $page and $perpage are 0 95 | $page = $perpage = 0; 96 | } 97 | 98 | // Ensure there are issues to display, if not display notice 99 | if (!$users = certificate_get_issues($certificate->id, $DB->sql_fullname(), $groupmode, $cm, $page, $perpage)) { 100 | echo $OUTPUT->header(); 101 | groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/certificate/report.php?id='.$id); 102 | echo $OUTPUT->notification(get_string('nocertificatesissued', 'certificate')); 103 | echo $OUTPUT->footer($course); 104 | exit(); 105 | } 106 | 107 | // Get extra fields to show the user. 108 | $extrafields = get_extra_user_fields($context); 109 | 110 | if ($download == "ods") { 111 | require_once("$CFG->libdir/odslib.class.php"); 112 | 113 | // Calculate file name 114 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.ods'; 115 | // Creating a workbook 116 | $workbook = new MoodleODSWorkbook("-"); 117 | // Send HTTP headers 118 | $workbook->send($filename); 119 | // Creating the first worksheet 120 | $myxls = $workbook->add_worksheet($strreport); 121 | 122 | // Print names of all the fields 123 | $myxls->write_string(0, 0, get_string("lastname")); 124 | $myxls->write_string(0, 1, get_string("firstname")); 125 | $nextposition = 2; 126 | foreach ($extrafields as $field) { 127 | $myxls->write_string(0, $nextposition, get_user_field_name($field)); 128 | $nextposition++; 129 | } 130 | $myxls->write_string(0, $nextposition, get_string("group")); 131 | $myxls->write_string(0, $nextposition + 1, $strdate); 132 | $myxls->write_string(0, $nextposition + 2, $strgrade); 133 | $myxls->write_string(0, $nextposition + 3, $strcode); 134 | 135 | // Generate the data for the body of the spreadsheet 136 | $i = 0; 137 | $row = 1; 138 | if ($users) { 139 | foreach ($users as $user) { 140 | $myxls->write_string($row, 0, $user->lastname); 141 | $myxls->write_string($row, 1, $user->firstname); 142 | $nextposition = 2; 143 | foreach ($extrafields as $field) { 144 | $myxls->write_string($row, $nextposition, $user->$field); 145 | $nextposition++; 146 | } 147 | $ug2 = ''; 148 | if ($usergrps = groups_get_all_groups($course->id, $user->id)) { 149 | foreach ($usergrps as $ug) { 150 | $ug2 = $ug2. $ug->name; 151 | } 152 | } 153 | $myxls->write_string($row, $nextposition, $ug2); 154 | $myxls->write_string($row, $nextposition + 1, userdate($user->timecreated)); 155 | $myxls->write_string($row, $nextposition + 2, certificate_get_grade($certificate, $course, $user->id)); 156 | $myxls->write_string($row, $nextposition + 3, $user->code); 157 | $row++; 158 | } 159 | $pos = 6; 160 | } 161 | // Close the workbook 162 | $workbook->close(); 163 | exit; 164 | } 165 | 166 | if ($download == "xls") { 167 | require_once("$CFG->libdir/excellib.class.php"); 168 | 169 | // Calculate file name 170 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.xls'; 171 | // Creating a workbook 172 | $workbook = new MoodleExcelWorkbook("-"); 173 | // Send HTTP headers 174 | $workbook->send($filename); 175 | // Creating the first worksheet 176 | $myxls = $workbook->add_worksheet($strreport); 177 | 178 | // Print names of all the fields 179 | $myxls->write_string(0, 0, get_string("lastname")); 180 | $myxls->write_string(0, 1, get_string("firstname")); 181 | $nextposition = 2; 182 | foreach ($extrafields as $field) { 183 | $myxls->write_string(0, $nextposition, get_user_field_name($field)); 184 | $nextposition++; 185 | } 186 | $myxls->write_string(0, $nextposition, get_string("group")); 187 | $myxls->write_string(0, $nextposition + 1, $strdate); 188 | $myxls->write_string(0, $nextposition + 2, $strgrade); 189 | $myxls->write_string(0, $nextposition + 3, $strcode); 190 | 191 | // Generate the data for the body of the spreadsheet 192 | $i = 0; 193 | $row = 1; 194 | if ($users) { 195 | foreach ($users as $user) { 196 | $myxls->write_string($row, 0, $user->lastname); 197 | $myxls->write_string($row, 1, $user->firstname); 198 | $nextposition = 2; 199 | foreach ($extrafields as $field) { 200 | $myxls->write_string($row, $nextposition, $user->$field); 201 | $nextposition++; 202 | } 203 | $ug2 = ''; 204 | if ($usergrps = groups_get_all_groups($course->id, $user->id)) { 205 | foreach ($usergrps as $ug) { 206 | $ug2 = $ug2 . $ug->name; 207 | } 208 | } 209 | $myxls->write_string($row, $nextposition, $ug2); 210 | $myxls->write_string($row, $nextposition + 1, userdate($user->timecreated)); 211 | $myxls->write_string($row, $nextposition + 2, certificate_get_grade($certificate, $course, $user->id)); 212 | $myxls->write_string($row, $nextposition + 3, $user->code); 213 | $row++; 214 | } 215 | $pos = 6; 216 | } 217 | // Close the workbook 218 | $workbook->close(); 219 | exit; 220 | } 221 | 222 | if ($download == "txt") { 223 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.txt'; 224 | 225 | header("Content-Type: application/download\n"); 226 | header("Content-Disposition: attachment; filename=\"$filename\""); 227 | header("Expires: 0"); 228 | header("Cache-Control: must-revalidate,post-check=0,pre-check=0"); 229 | header("Pragma: public"); 230 | 231 | // Print names of all the fields 232 | echo get_string("lastname"). "\t" .get_string("firstname") . "\t"; 233 | foreach ($extrafields as $field) { 234 | echo get_user_field_name($field) . "\t"; 235 | } 236 | echo get_string("group"). "\t"; 237 | echo $strdate. "\t"; 238 | echo $strgrade. "\t"; 239 | echo $strcode. "\n"; 240 | 241 | // Generate the data for the body of the spreadsheet 242 | $i=0; 243 | $row=1; 244 | if ($users) foreach ($users as $user) { 245 | echo $user->lastname; 246 | echo "\t" . $user->firstname . "\t"; 247 | foreach ($extrafields as $field) { 248 | echo $user->$field . "\t"; 249 | } 250 | $ug2 = ''; 251 | if ($usergrps = groups_get_all_groups($course->id, $user->id)) { 252 | foreach ($usergrps as $ug) { 253 | $ug2 = $ug2. $ug->name; 254 | } 255 | } 256 | echo $ug2 . "\t"; 257 | echo userdate($user->timecreated) . "\t"; 258 | echo certificate_get_grade($certificate, $course, $user->id) . "\t"; 259 | echo $user->code . "\n"; 260 | $row++; 261 | } 262 | exit; 263 | } 264 | 265 | $usercount = count(certificate_get_issues($certificate->id, $DB->sql_fullname(), $groupmode, $cm)); 266 | 267 | // Create the table for the users 268 | $table = new html_table(); 269 | $table->width = "95%"; 270 | $table->tablealign = "center"; 271 | $table->head = array($strto); 272 | $table->align = array('left'); 273 | foreach ($extrafields as $field) { 274 | $table->head[] = get_user_field_name($field); 275 | $table->align[] = 'left'; 276 | } 277 | $table->head = array_merge($table->head, array($strdate, $strgrade, $strcode)); 278 | $table->align = array_merge($table->align, array('left', 'center', 'center')); 279 | foreach ($users as $user) { 280 | $name = $OUTPUT->user_picture($user) . fullname($user); 281 | $date = userdate($user->timecreated) . certificate_print_user_files($certificate, $user->id, $context->id); 282 | $code = $user->code; 283 | $data = array(); 284 | $data[] = $name; 285 | foreach ($extrafields as $field) { 286 | $data[] = $user->$field; 287 | } 288 | $data = array_merge($data, array($date, certificate_get_grade($certificate, $course, $user->id), $code)); 289 | $table->data[] = $data; 290 | } 291 | 292 | // Create table to store buttons 293 | $tablebutton = new html_table(); 294 | $tablebutton->attributes['class'] = 'downloadreport'; 295 | $btndownloadods = $OUTPUT->single_button(new moodle_url("report.php", array('id'=>$cm->id, 'download'=>'ods')), get_string("downloadods")); 296 | $btndownloadxls = $OUTPUT->single_button(new moodle_url("report.php", array('id'=>$cm->id, 'download'=>'xls')), get_string("downloadexcel")); 297 | $btndownloadtxt = $OUTPUT->single_button(new moodle_url("report.php", array('id'=>$cm->id, 'download'=>'txt')), get_string("downloadtext")); 298 | $tablebutton->data[] = array($btndownloadods, $btndownloadxls, $btndownloadtxt); 299 | 300 | echo $OUTPUT->header(); 301 | groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/certificate/report.php?id='.$id); 302 | echo $OUTPUT->heading(get_string('modulenameplural', 'certificate')); 303 | echo $OUTPUT->paging_bar($usercount, $page, $perpage, $url); 304 | echo '
'; 305 | echo html_writer::table($table); 306 | echo html_writer::tag('div', html_writer::table($tablebutton), array('style' => 'margin:auto; width:50%')); 307 | echo $OUTPUT->footer($course); 308 | -------------------------------------------------------------------------------- /review.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * This page reviews a certificate 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | require_once('../../config.php'); 27 | require_once('locallib.php'); 28 | require_once("$CFG->libdir/pdflib.php"); 29 | 30 | // Retrieve any variables that are passed 31 | $id = required_param('id', PARAM_INT); // Course Module ID 32 | $action = optional_param('action', '', PARAM_ALPHA); 33 | 34 | if (!$cm = get_coursemodule_from_id('certificate', $id)) { 35 | print_error('Course Module ID was incorrect'); 36 | } 37 | 38 | if (!$course = $DB->get_record('course', array('id'=> $cm->course))) { 39 | print_error('course is misconfigured'); 40 | } 41 | 42 | if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) { 43 | print_error('course module is incorrect'); 44 | } 45 | 46 | // Requires a course login 47 | require_login($course, true, $cm); 48 | 49 | // Check the capabilities 50 | $context = context_module::instance($cm->id); 51 | require_capability('mod/certificate:view', $context); 52 | 53 | // Initialize $PAGE, compute blocks 54 | $PAGE->set_url('/mod/certificate/review.php', array('id' => $cm->id)); 55 | $PAGE->set_context($context); 56 | $PAGE->set_cm($cm); 57 | $PAGE->set_title(format_string($certificate->name)); 58 | $PAGE->set_heading(format_string($course->fullname)); 59 | 60 | // Get previous cert record 61 | if (!$certrecord = $DB->get_record('certificate_issues', array('userid' => $USER->id, 'certificateid' => $certificate->id))) { 62 | notice(get_string('nocertificatesissued', 'certificate'), "$CFG->wwwroot/course/view.php?id=$course->id"); 63 | die; 64 | } 65 | 66 | // Load the specific certificatetype 67 | require ("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php"); 68 | 69 | if ($action) { 70 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; 71 | $filecontents = $pdf->Output('', 'S'); 72 | // Open in browser. 73 | send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); 74 | exit(); 75 | } 76 | 77 | echo $OUTPUT->header(); 78 | 79 | $reviewurl = new moodle_url('/mod/certificate/review.php', array('id' => $cm->id)); 80 | groups_print_activity_menu($cm, $reviewurl); 81 | $currentgroup = groups_get_activity_group($cm); 82 | $groupmode = groups_get_activity_groupmode($cm); 83 | 84 | if (has_capability('mod/certificate:manage', $context)) { 85 | $numusers = count(certificate_get_issues($certificate->id, 'ci.timecreated ASC', $groupmode, $cm)); 86 | $url = html_writer::tag('a', get_string('viewcertificateviews', 'certificate', $numusers), 87 | array('href' => $CFG->wwwroot . '/mod/certificate/report.php?id=' . $cm->id)); 88 | echo html_writer::tag('div', $url, array('class' => 'reportlink')); 89 | } 90 | 91 | if (!empty($certificate->intro)) { 92 | echo $OUTPUT->box(format_module_intro('certificate', $certificate, $cm->id), 'generalbox', 'intro'); 93 | } 94 | 95 | echo html_writer::tag('p', get_string('viewed', 'certificate'). '
' . userdate($certrecord->timecreated), array('style' => 'text-align:center')); 96 | 97 | $link = new moodle_url('/mod/certificate/review.php?id='.$cm->id.'&action=get'); 98 | $linkname = get_string('reviewcertificate', 'certificate'); 99 | $button = new single_button($link, $linkname); 100 | $button->add_action(new popup_action('click', $link, array('height' => 600, 'width' => 800))); 101 | 102 | echo html_writer::tag('div', $OUTPUT->render($button), array('style' => 'text-align:center')); 103 | 104 | echo $OUTPUT->footer($course); 105 | -------------------------------------------------------------------------------- /settings.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Provides some custom settings for the certificate module 20 | * 21 | * @package mod_certificate 22 | * @copyright Michael Avelar 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die; 27 | 28 | if ($ADMIN->fulltree) { 29 | 30 | $settings->add(new mod_certificate_admin_setting_upload('certificate/uploadimage', 31 | get_string('uploadimage', 'mod_certificate'), get_string('uploadimagedesc', 'certificate'), '')); 32 | 33 | $settings->add(new mod_certificate_admin_setting_font('certificate/fontsans', 34 | get_string('fontsans', 'mod_certificate'), get_string('fontsans_desc', 'mod_certificate'), 'freesans')); 35 | 36 | $settings->add(new mod_certificate_admin_setting_font('certificate/fontserif', 37 | get_string('fontserif', 'mod_certificate'), get_string('fontserif_desc', 'mod_certificate'), 'freeserif')); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/generator/lib.php: -------------------------------------------------------------------------------- 1 | . 15 | 16 | /** 17 | * Certificate module data generator. 18 | * 19 | * @package mod_certificate 20 | * @category test 21 | * @author Russell England 22 | * @copyright Catalyst IT Ltd 2013 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | class mod_certificate_generator extends testing_module_generator { 29 | 30 | /** 31 | * Create new certificate module instance 32 | * @param array|stdClass $record data for module being generated. Requires 'course' key 33 | * (an id or the full object). Also can have any fields from add module form. 34 | * @param null|array $options general options for course module. Since 2.6 it is 35 | * possible to omit this argument by merging options into $record 36 | * @return stdClass record from module-defined table with additional field 37 | * cmid (corresponding id in course_modules table) 38 | */ 39 | public function create_instance($record = null, array $options = null) { 40 | global $CFG; 41 | require_once("$CFG->dirroot/mod/certificate/lib.php"); 42 | 43 | $this->instancecount++; 44 | $i = $this->instancecount; 45 | 46 | $record = (object)(array)$record; 47 | $options = (array)$options; 48 | 49 | if (empty($record->course)) { 50 | throw new coding_exception('module generator requires $record->course'); 51 | } 52 | 53 | $defaults = array(); 54 | $defaults['name'] = get_string('pluginname', 'certificate').' '.$i; 55 | $defaults['intro'] = 'Test certificate '.$i; 56 | $defaults['introformat'] = FORMAT_MOODLE; 57 | $defaults['emailteachers'] = 0; 58 | $defaults['savecert'] = 0; 59 | $defaults['reportcert'] = 0; 60 | $defaults['delivery'] = 0; 61 | $defaults['certificatetype'] = 'A4_non_embedded'; 62 | $defaults['orientation'] = 'L'; 63 | $defaults['borderstyle'] = '0'; 64 | $defaults['bordercolor'] = '0'; 65 | $defaults['printwmark'] = '0'; 66 | $defaults['printdate'] = 0; 67 | $defaults['datefmt'] = 0; 68 | $defaults['printnumber'] = 0; 69 | $defaults['printgrade'] = 0; 70 | $defaults['gradefmt'] = 0; 71 | $defaults['printoutcome'] = 0; 72 | $defaults['printhours'] = ''; 73 | $defaults['printteacher'] = 0; 74 | $defaults['printsignature'] = '0'; 75 | $defaults['printseal'] = '0'; 76 | foreach ($defaults as $field => $value) { 77 | if (!isset($record->$field)) { 78 | $record->$field = $value; 79 | } 80 | } 81 | 82 | if (isset($options['idnumber'])) { 83 | $record->cmidnumber = $options['idnumber']; 84 | } else { 85 | $record->cmidnumber = ''; 86 | } 87 | 88 | // Do work to actually add the instance. 89 | return parent::create_instance($record, (array)$options); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/generator_test.php: -------------------------------------------------------------------------------- 1 | . 15 | 16 | /** 17 | * Certificate module data generator. 18 | * 19 | * @package mod_certificate 20 | * @category test 21 | * @author Russell England 22 | * @copyright Catalyst IT Ltd 2013 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | class mod_certificate_generator_testcase extends advanced_testcase { 29 | public function test_generator() { 30 | global $DB; 31 | 32 | $this->resetAfterTest(true); 33 | 34 | $this->assertEquals(0, $DB->count_records('certificate')); 35 | 36 | $course = $this->getDataGenerator()->create_course(); 37 | 38 | /** @var mod_certificate_generator $generator */ 39 | $generator = $this->getDataGenerator()->get_plugin_generator('mod_certificate'); 40 | $this->assertInstanceOf('mod_certificate_generator', $generator); 41 | $this->assertEquals('certificate', $generator->get_modulename()); 42 | 43 | $generator->create_instance(array('course' => $course->id)); 44 | $generator->create_instance(array('course' => $course->id)); 45 | $certificate = $generator->create_instance(array('course' => $course->id)); 46 | $this->assertEquals(3, $DB->count_records('certificate')); 47 | 48 | $cm = get_coursemodule_from_instance('certificate', $certificate->id); 49 | $this->assertEquals($certificate->id, $cm->instance); 50 | $this->assertEquals('certificate', $cm->modname); 51 | $this->assertEquals($course->id, $cm->course); 52 | 53 | $context = context_module::instance($cm->id); 54 | $this->assertEquals($certificate->cmid, $context->instanceid); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/privacy_test.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Tests for the implementation of the Privacy Provider API for mod_certificate. 19 | * 20 | * @package mod_certificate 21 | * @copyright 2018 Huong Nguyen 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | use core_privacy\local\request\approved_contextlist; 28 | use core_privacy\local\request\transform; 29 | use core_privacy\local\request\writer; 30 | use mod_certificate\privacy\provider; 31 | 32 | /** 33 | * Tests for the implementation of the Privacy Provider API for mod_certificate. 34 | * 35 | * @package mod_certificate 36 | * @copyright 2018 Huong Nguyen 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 | */ 39 | class mod_certificate_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { 40 | 41 | protected $currentuser = ''; 42 | protected $course = ''; 43 | protected $cm = ''; 44 | protected $certificate = ''; 45 | protected $issue = ''; 46 | 47 | /** 48 | * Prepares things before this test case is initialised 49 | * 50 | * @return void 51 | */ 52 | public static function setUpBeforeClass(): void { 53 | global $CFG; 54 | require_once($CFG->dirroot . '/mod/certificate/locallib.php'); 55 | } 56 | 57 | /** 58 | * Test setUp. 59 | */ 60 | public function setUp(): void { 61 | $this->resetAfterTest(true); 62 | $course = $this->getDataGenerator()->create_course(); 63 | $generator = $this->getDataGenerator()->get_plugin_generator('mod_certificate'); 64 | $user = $this->getDataGenerator()->create_user(); 65 | $certificate = $generator->create_instance(array('course' => $course->id)); 66 | $cm = get_coursemodule_from_id('certificate', $certificate->cmid); 67 | $issue = certificate_get_issue($course, $user, $certificate, $cm); 68 | $context = context_module::instance($certificate->cmid); 69 | $this->course = $course; 70 | $this->currentuser = $user; 71 | $this->certificate = $certificate; 72 | $this->cm = $cm; 73 | $this->issue = $issue; 74 | $fs = get_file_storage(); 75 | // Add a fake certificate. 76 | $fs->create_file_from_string([ 77 | 'contextid' => $context->id, 78 | 'component' => 'mod_certificate', 79 | 'filearea' => 'issue', 80 | 'itemid' => $issue->id, 81 | 'filepath' => '/', 82 | 'filename' => 'fakecertificate.pdf', 83 | ], 'image contents (not really)'); 84 | } 85 | 86 | /** 87 | * Test for provider::get_users_in_context(). 88 | */ 89 | public function test_get_users_in_context() { 90 | $this->resetAfterTest(); 91 | 92 | $course = $this->getDataGenerator()->create_course(); 93 | 94 | // The cert activity the user will have an issue from. 95 | $cert1 = $this->getDataGenerator()->create_module('certificate', ['course' => $course->id]); 96 | $cert2 = $this->getDataGenerator()->create_module('certificate', ['course' => $course->id]); 97 | 98 | // Call get_users_in_context() when the certificate hasn't any user. 99 | $cm = get_coursemodule_from_instance('certificate', $cert1->id); 100 | $cm2 = get_coursemodule_from_instance('certificate', $cert2->id); 101 | $cmcontext = context_module::instance($cm->id); 102 | $userlist = new \core_privacy\local\request\userlist($cmcontext, 'certificate'); 103 | provider::get_users_in_context($userlist); 104 | 105 | // Check no user has been returned. 106 | $this->assertCount(0, $userlist->get_userids()); 107 | 108 | // Create some users who will be issued a certificate. 109 | $user1 = $this->getDataGenerator()->create_user(); 110 | $user2 = $this->getDataGenerator()->create_user(); 111 | $user3 = $this->getDataGenerator()->create_user(); 112 | 113 | certificate_get_issue($course, $user1, $cert1, $cm); 114 | certificate_get_issue($course, $user2, $cert1, $cm); 115 | certificate_get_issue($course, $user3, $cert2, $cm2); 116 | 117 | // Call get_users_in_context() again. 118 | provider::get_users_in_context($userlist); 119 | 120 | // Check this time there are 2 users. 121 | $this->assertCount(2, $userlist->get_userids()); 122 | $users = $userlist->get_userids(); 123 | $this->assertContains((int) $user1->id, $users); 124 | $this->assertContains((int) $user2->id, $users); 125 | $this->assertNotContains((int) $user3->id, $users); 126 | } 127 | 128 | 129 | /** 130 | * Test get context for userid. 131 | */ 132 | public function test_get_contexts_for_userid() { 133 | $contextlist = provider::get_contexts_for_userid($this->currentuser->id); 134 | $context = context_module::instance($this->certificate->cmid); 135 | 136 | $this->assertEquals(1, count($contextlist->get_contextids())); 137 | $this->assertEquals($context, $contextlist->current()); 138 | } 139 | 140 | /** 141 | * Test that data is exported correctly for this plugin. 142 | */ 143 | public function test_export_user_data() { 144 | $user = $this->currentuser; 145 | $context = context_module::instance($this->certificate->cmid); 146 | $contextids = provider::get_contexts_for_userid($user->id)->get_contextids(); 147 | $appctx = new approved_contextlist($user, 'mod_certificate', $contextids); 148 | provider::export_user_data($appctx); 149 | $contextdata = writer::with_context($context); 150 | $issue = $this->issue; 151 | $area[] = $issue->id; 152 | $exporteddata = $contextdata->get_data([$issue->id]); 153 | 154 | $this->assertEquals(transform::user($issue->userid), $exporteddata->userid); 155 | $this->assertEquals($issue->certificateid, $exporteddata->certificateid); 156 | $this->assertEquals($issue->code, $exporteddata->code); 157 | $this->assertEquals(transform::datetime($issue->timecreated), $exporteddata->timecreated); 158 | $this->assertArrayHasKey('fakecertificate.pdf', $contextdata->get_files($area)); 159 | } 160 | 161 | /** 162 | * Test delete data for user. 163 | */ 164 | public function test_delete_data_for_user() { 165 | $user = $this->currentuser; 166 | $context = context_module::instance($this->certificate->cmid); 167 | $fs = get_file_storage(); 168 | $issue = $this->issue; 169 | $contextids = provider::get_contexts_for_userid($user->id)->get_contextids(); 170 | $appctx = new approved_contextlist($user, 'mod_certificate', $contextids); 171 | 172 | provider::delete_data_for_user($appctx); 173 | writer::reset(); 174 | provider::export_user_data($appctx); 175 | $contextdata = writer::with_context($context); 176 | 177 | $this->assertFalse($contextdata->has_any_data()); 178 | $this->assertEmpty($fs->get_area_files($context->id, 179 | 'mod_certificate', 'issue', $issue->id)); 180 | } 181 | 182 | /** 183 | * Test delete data for all users in context. 184 | */ 185 | public function test_delete_data_for_all_users_in_context() { 186 | global $DB; 187 | 188 | $user = $this->currentuser; 189 | $context = context_module::instance($this->certificate->cmid); 190 | $fs = get_file_storage(); 191 | $issue = $this->issue; 192 | $contextids = provider::get_contexts_for_userid($user->id)->get_contextids(); 193 | $appctx = new approved_contextlist($user, 'mod_certificate', $contextids); 194 | provider::export_user_data($appctx); 195 | $this->assertTrue(writer::with_context($context)->has_any_data()); 196 | writer::reset(); 197 | provider::delete_data_for_all_users_in_context($context); 198 | $area[] = $issue->id; 199 | $module = $DB->get_record('certificate_issues', ['id' => $issue->certificateid]); 200 | 201 | $this->assertEmpty(writer::with_context($context)->get_data($area)); 202 | $this->assertEmpty($fs->get_area_files($context->id, 203 | 'mod_certificate', 'issue', $issue->id)); 204 | $this->assertEmpty($module); 205 | } 206 | 207 | 208 | /** 209 | * Test for provider::delete_data_for_users(). 210 | */ 211 | public function test_delete_data_for_users() { 212 | global $DB; 213 | 214 | $this->resetAfterTest(); 215 | 216 | // Create course, certificate and users who will be issued a certificate. 217 | $course = $this->getDataGenerator()->create_course(); 218 | $cert1 = $this->getDataGenerator()->create_module('certificate', ['course' => $course->id]); 219 | $cert2 = $this->getDataGenerator()->create_module('certificate', ['course' => $course->id]); 220 | 221 | $cm1 = get_coursemodule_from_instance('certificate', $cert1->id); 222 | $cm2 = get_coursemodule_from_instance('certificate', $cert2->id); 223 | 224 | $user1 = $this->getDataGenerator()->create_user(); 225 | $user2 = $this->getDataGenerator()->create_user(); 226 | $user3 = $this->getDataGenerator()->create_user(); 227 | certificate_get_issue($course, $user1, $cert1, $cm1); 228 | certificate_get_issue($course, $user2, $cert1, $cm1); 229 | certificate_get_issue($course, $user3, $cert1, $cm1); 230 | certificate_get_issue($course, $user1, $cert2, $cm2); 231 | certificate_get_issue($course, $user2, $cert2, $cm2); 232 | 233 | // Before deletion we should have 3 + 2 issued certificates. 234 | $count = $DB->count_records('certificate_issues', ['certificateid' => $cert1->id]); 235 | $this->assertEquals(3, $count); 236 | $count = $DB->count_records('certificate_issues', ['certificateid' => $cert2->id]); 237 | $this->assertEquals(2, $count); 238 | 239 | $context1 = context_module::instance($cm1->id); 240 | $approveduserlist = new \core_privacy\local\request\approved_userlist($context1, 'mod_certificate', 241 | [$user1->id, $user2->id]); 242 | provider::delete_data_for_users($approveduserlist); 243 | 244 | // After deletion, the certificate of the 2 students provided above should have been deleted 245 | // from the activity. So there should only remain 1 certificate which is for $user3. 246 | $certissues1 = $DB->get_records('certificate_issues', ['certificateid' => $cert1->id]); 247 | $this->assertCount(1, $certissues1); 248 | $lastissue = reset($certissues1); 249 | $this->assertEquals($user3->id, $lastissue->userid); 250 | 251 | // Confirm that the certificates issues in the other activity are intact. 252 | $certissues1 = $DB->get_records('certificate_issues', ['certificateid' => $cert2->id]); 253 | $this->assertCount(2, $certissues1); 254 | } 255 | 256 | /** 257 | * Test for provider::get_users_in_context() with invalid context type. 258 | */ 259 | public function test_get_users_in_context_invalid_context_type() { 260 | $systemcontext = context_system::instance(); 261 | $userlist = new \core_privacy\local\request\userlist($systemcontext, 'mod_certificate'); 262 | \mod_certificate\privacy\provider::get_users_in_context($userlist); 263 | $this->assertCount(0, $userlist->get_userids()); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /type/A4_embedded/certificate.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * A4_embedded certificate type 20 | * 21 | * @package mod_certificate 22 | * @copyright 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 | $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); 29 | 30 | $pdf->SetTitle($certificate->name); 31 | $pdf->SetProtection(array('modify')); 32 | $pdf->setPrintHeader(false); 33 | $pdf->setPrintFooter(false); 34 | $pdf->SetAutoPageBreak(false, 0); 35 | $pdf->AddPage(); 36 | 37 | // Define variables 38 | // Landscape 39 | if ($certificate->orientation == 'L') { 40 | $x = 10; 41 | $y = 30; 42 | $sealx = 230; 43 | $sealy = 150; 44 | $sigx = 47; 45 | $sigy = 155; 46 | $custx = 47; 47 | $custy = 155; 48 | $wmarkx = 40; 49 | $wmarky = 31; 50 | $wmarkw = 212; 51 | $wmarkh = 148; 52 | $brdrx = 0; 53 | $brdry = 0; 54 | $brdrw = 297; 55 | $brdrh = 210; 56 | $codey = 175; 57 | } else { // Portrait 58 | $x = 10; 59 | $y = 40; 60 | $sealx = 150; 61 | $sealy = 220; 62 | $sigx = 30; 63 | $sigy = 230; 64 | $custx = 30; 65 | $custy = 230; 66 | $wmarkx = 26; 67 | $wmarky = 58; 68 | $wmarkw = 158; 69 | $wmarkh = 170; 70 | $brdrx = 0; 71 | $brdry = 0; 72 | $brdrw = 210; 73 | $brdrh = 297; 74 | $codey = 250; 75 | } 76 | 77 | // Get font families. 78 | $fontsans = get_config('certificate', 'fontsans'); 79 | $fontserif = get_config('certificate', 'fontserif'); 80 | 81 | // Add images and lines 82 | certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); 83 | certificate_draw_frame($pdf, $certificate); 84 | // Set alpha to semi-transparency 85 | $pdf->SetAlpha(0.2); 86 | certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); 87 | $pdf->SetAlpha(1); 88 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); 89 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, '', ''); 90 | 91 | // Add text 92 | $pdf->SetTextColor(0, 0, 120); 93 | certificate_print_text($pdf, $x, $y, 'C', $fontsans, '', 30, get_string('title', 'certificate')); 94 | $pdf->SetTextColor(0, 0, 0); 95 | certificate_print_text($pdf, $x, $y + 20, 'C', $fontserif, '', 20, get_string('certify', 'certificate')); 96 | certificate_print_text($pdf, $x, $y + 36, 'C', $fontsans, '', 30, fullname($USER)); 97 | certificate_print_text($pdf, $x, $y + 55, 'C', $fontsans, '', 20, get_string('statement', 'certificate')); 98 | certificate_print_text($pdf, $x, $y + 72, 'C', $fontsans, '', 20, format_string($course->fullname)); 99 | certificate_print_text($pdf, $x, $y + 92, 'C', $fontsans, '', 14, certificate_get_date($certificate, $certrecord, $course)); 100 | certificate_print_text($pdf, $x, $y + 102, 'C', $fontserif, '', 10, certificate_get_grade($certificate, $course)); 101 | certificate_print_text($pdf, $x, $y + 112, 'C', $fontserif, '', 10, certificate_get_outcome($certificate, $course)); 102 | if ($certificate->printhours) { 103 | certificate_print_text($pdf, $x, $y + 122, 'C', $fontserif, '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); 104 | } 105 | certificate_print_text($pdf, $x, $codey, 'C', $fontserif, '', 10, certificate_get_code($certificate, $certrecord)); 106 | $i = 0; 107 | if ($certificate->printteacher) { 108 | $context = context_module::instance($cm->id); 109 | if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { 110 | foreach ($teachers as $teacher) { 111 | $i++; 112 | certificate_print_text($pdf, $sigx, $sigy + ($i * 4), 'L', $fontserif, '', 12, fullname($teacher)); 113 | } 114 | } 115 | } 116 | 117 | certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); 118 | -------------------------------------------------------------------------------- /type/A4_non_embedded/certificate.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * A4_non_embedded certificate type 20 | * 21 | * @package mod_certificate 22 | * @copyright 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 | $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); 29 | 30 | $pdf->SetTitle($certificate->name); 31 | $pdf->SetProtection(array('modify')); 32 | $pdf->setPrintHeader(false); 33 | $pdf->setPrintFooter(false); 34 | $pdf->SetAutoPageBreak(false, 0); 35 | $pdf->AddPage(); 36 | 37 | // Define variables 38 | // Landscape 39 | if ($certificate->orientation == 'L') { 40 | $x = 10; 41 | $y = 30; 42 | $sealx = 230; 43 | $sealy = 150; 44 | $sigx = 47; 45 | $sigy = 155; 46 | $custx = 47; 47 | $custy = 155; 48 | $wmarkx = 40; 49 | $wmarky = 31; 50 | $wmarkw = 212; 51 | $wmarkh = 148; 52 | $brdrx = 0; 53 | $brdry = 0; 54 | $brdrw = 297; 55 | $brdrh = 210; 56 | $codey = 175; 57 | } else { // Portrait 58 | $x = 10; 59 | $y = 40; 60 | $sealx = 150; 61 | $sealy = 220; 62 | $sigx = 30; 63 | $sigy = 230; 64 | $custx = 30; 65 | $custy = 230; 66 | $wmarkx = 26; 67 | $wmarky = 58; 68 | $wmarkw = 158; 69 | $wmarkh = 170; 70 | $brdrx = 0; 71 | $brdry = 0; 72 | $brdrw = 210; 73 | $brdrh = 297; 74 | $codey = 250; 75 | } 76 | 77 | // Add images and lines 78 | certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); 79 | certificate_draw_frame($pdf, $certificate); 80 | // Set alpha to semi-transparency 81 | $pdf->SetAlpha(0.2); 82 | certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); 83 | $pdf->SetAlpha(1); 84 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); 85 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, '', ''); 86 | 87 | // Add text 88 | $pdf->SetTextColor(0, 0, 120); 89 | certificate_print_text($pdf, $x, $y, 'C', 'Helvetica', '', 30, get_string('title', 'certificate')); 90 | $pdf->SetTextColor(0, 0, 0); 91 | certificate_print_text($pdf, $x, $y + 20, 'C', 'Times', '', 20, get_string('certify', 'certificate')); 92 | certificate_print_text($pdf, $x, $y + 36, 'C', 'Helvetica', '', 30, fullname($USER)); 93 | certificate_print_text($pdf, $x, $y + 55, 'C', 'Helvetica', '', 20, get_string('statement', 'certificate')); 94 | certificate_print_text($pdf, $x, $y + 72, 'C', 'Helvetica', '', 20, format_string($course->fullname)); 95 | certificate_print_text($pdf, $x, $y + 92, 'C', 'Helvetica', '', 14, certificate_get_date($certificate, $certrecord, $course)); 96 | certificate_print_text($pdf, $x, $y + 102, 'C', 'Times', '', 10, certificate_get_grade($certificate, $course)); 97 | certificate_print_text($pdf, $x, $y + 112, 'C', 'Times', '', 10, certificate_get_outcome($certificate, $course)); 98 | if ($certificate->printhours) { 99 | certificate_print_text($pdf, $x, $y + 122, 'C', 'Times', '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); 100 | } 101 | certificate_print_text($pdf, $x, $codey, 'C', 'Times', '', 10, certificate_get_code($certificate, $certrecord)); 102 | $i = 0; 103 | if ($certificate->printteacher) { 104 | $context = context_module::instance($cm->id); 105 | if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { 106 | foreach ($teachers as $teacher) { 107 | $i++; 108 | certificate_print_text($pdf, $sigx, $sigy + ($i * 4), 'L', 'Times', '', 12, fullname($teacher)); 109 | } 110 | } 111 | } 112 | 113 | certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); 114 | -------------------------------------------------------------------------------- /type/letter_embedded/certificate.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * letter_embedded certificate type 20 | * 21 | * @package mod_certificate 22 | * @copyright 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 | $pdf = new PDF($certificate->orientation, 'pt', 'LETTER', true, 'UTF-8', false); 29 | 30 | $pdf->SetTitle($certificate->name); 31 | $pdf->SetProtection(array('modify')); 32 | $pdf->setPrintHeader(false); 33 | $pdf->setPrintFooter(false); 34 | $pdf->SetAutoPageBreak(false, 0); 35 | $pdf->AddPage(); 36 | 37 | // Define variables 38 | // Landscape 39 | if ($certificate->orientation == 'L') { 40 | $x = 28; 41 | $y = 125; 42 | $sealx = 590; 43 | $sealy = 425; 44 | $sigx = 130; 45 | $sigy = 440; 46 | $custx = 133; 47 | $custy = 440; 48 | $wmarkx = 100; 49 | $wmarky = 90; 50 | $wmarkw = 600; 51 | $wmarkh = 420; 52 | $brdrx = 0; 53 | $brdry = 0; 54 | $brdrw = 792; 55 | $brdrh = 612; 56 | $codey = 505; 57 | } else { // Portrait 58 | $x = 28; 59 | $y = 170; 60 | $sealx = 440; 61 | $sealy = 590; 62 | $sigx = 85; 63 | $sigy = 580; 64 | $custx = 88; 65 | $custy = 580; 66 | $wmarkx = 78; 67 | $wmarky = 130; 68 | $wmarkw = 450; 69 | $wmarkh = 480; 70 | $brdrx = 10; 71 | $brdry = 10; 72 | $brdrw = 594; 73 | $brdrh = 771; 74 | $codey = 660; 75 | } 76 | 77 | // Get font families. 78 | $fontsans = get_config('certificate', 'fontsans'); 79 | $fontserif = get_config('certificate', 'fontserif'); 80 | 81 | // Add images and lines 82 | certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); 83 | certificate_draw_frame_letter($pdf, $certificate); 84 | // Set alpha to semi-transparency 85 | $pdf->SetAlpha(0.1); 86 | certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); 87 | $pdf->SetAlpha(1); 88 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); 89 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, '', ''); 90 | 91 | // Add text 92 | $pdf->SetTextColor(0, 0, 120); 93 | certificate_print_text($pdf, $x, $y, 'C', $fontsans, '', 30, get_string('title', 'certificate')); 94 | $pdf->SetTextColor(0, 0, 0); 95 | certificate_print_text($pdf, $x, $y + 55, 'C', $fontserif, '', 20, get_string('certify', 'certificate')); 96 | certificate_print_text($pdf, $x, $y + 105, 'C', $fontserif, '', 30, fullname($USER)); 97 | certificate_print_text($pdf, $x, $y + 155, 'C', $fontserif, '', 20, get_string('statement', 'certificate')); 98 | certificate_print_text($pdf, $x, $y + 205, 'C', $fontserif, '', 20, format_string($course->fullname)); 99 | certificate_print_text($pdf, $x, $y + 255, 'C', $fontserif, '', 14, certificate_get_date($certificate, $certrecord, $course)); 100 | certificate_print_text($pdf, $x, $y + 283, 'C', $fontserif, '', 10, certificate_get_grade($certificate, $course)); 101 | certificate_print_text($pdf, $x, $y + 311, 'C', $fontserif, '', 10, certificate_get_outcome($certificate, $course)); 102 | if ($certificate->printhours) { 103 | certificate_print_text($pdf, $x, $y + 339, 'C', $fontserif, '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); 104 | } 105 | certificate_print_text($pdf, $x, $codey, 'C', $fontserif, '', 10, certificate_get_code($certificate, $certrecord)); 106 | $i = 0; 107 | if ($certificate->printteacher) { 108 | $context = context_module::instance($cm->id); 109 | if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { 110 | foreach ($teachers as $teacher) { 111 | $i++; 112 | certificate_print_text($pdf, $sigx, $sigy + ($i * 12), 'L', $fontserif, '', 12, fullname($teacher)); 113 | } 114 | } 115 | } 116 | 117 | certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); 118 | -------------------------------------------------------------------------------- /type/letter_non_embedded/certificate.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * letter_non_embedded certificate type 20 | * 21 | * @package mod_certificate 22 | * @copyright 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 | $pdf = new PDF($certificate->orientation, 'pt', 'LETTER', true, 'UTF-8', false); 29 | 30 | $pdf->SetTitle($certificate->name); 31 | $pdf->SetProtection(array('modify')); 32 | $pdf->setPrintHeader(false); 33 | $pdf->setPrintFooter(false); 34 | $pdf->SetAutoPageBreak(false, 0); 35 | $pdf->AddPage(); 36 | 37 | // Define variables 38 | // Landscape 39 | if ($certificate->orientation == 'L') { 40 | $x = 28; 41 | $y = 125; 42 | $sealx = 590; 43 | $sealy = 425; 44 | $sigx = 130; 45 | $sigy = 440; 46 | $custx = 133; 47 | $custy = 440; 48 | $wmarkx = 100; 49 | $wmarky = 90; 50 | $wmarkw = 600; 51 | $wmarkh = 420; 52 | $brdrx = 0; 53 | $brdry = 0; 54 | $brdrw = 792; 55 | $brdrh = 612; 56 | $codey = 505; 57 | } else { // Portrait 58 | $x = 28; 59 | $y = 170; 60 | $sealx = 440; 61 | $sealy = 590; 62 | $sigx = 85; 63 | $sigy = 580; 64 | $custx = 88; 65 | $custy = 580; 66 | $wmarkx = 78; 67 | $wmarky = 130; 68 | $wmarkw = 450; 69 | $wmarkh = 480; 70 | $brdrx = 10; 71 | $brdry = 10; 72 | $brdrw = 594; 73 | $brdrh = 771; 74 | $codey = 660; 75 | } 76 | 77 | // Add images and lines 78 | certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); 79 | certificate_draw_frame_letter($pdf, $certificate); 80 | // Set alpha to semi-transparency 81 | $pdf->SetAlpha(0.1); 82 | certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); 83 | $pdf->SetAlpha(1); 84 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); 85 | certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, '', ''); 86 | 87 | // Add text 88 | $pdf->SetTextColor(0, 0, 120); 89 | certificate_print_text($pdf, $x, $y, 'C', 'Helvetica', '', 30, get_string('title', 'certificate')); 90 | $pdf->SetTextColor(0, 0, 0); 91 | certificate_print_text($pdf, $x, $y + 55, 'C', 'Times', '', 20, get_string('certify', 'certificate')); 92 | certificate_print_text($pdf, $x, $y + 105, 'C', 'Helvetica', '', 30, fullname($USER)); 93 | certificate_print_text($pdf, $x, $y + 155, 'C', 'Helvetica', '', 20, get_string('statement', 'certificate')); 94 | certificate_print_text($pdf, $x, $y + 205, 'C', 'Helvetica', '', 20, format_string($course->fullname)); 95 | certificate_print_text($pdf, $x, $y + 255, 'C', 'Helvetica', '', 14, certificate_get_date($certificate, $certrecord, $course)); 96 | certificate_print_text($pdf, $x, $y + 283, 'C', 'Times', '', 10, certificate_get_grade($certificate, $course)); 97 | certificate_print_text($pdf, $x, $y + 311, 'C', 'Times', '', 10, certificate_get_outcome($certificate, $course)); 98 | if ($certificate->printhours) { 99 | certificate_print_text($pdf, $x, $y + 339, 'C', 'Times', '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); 100 | } 101 | certificate_print_text($pdf, $x, $codey, 'C', 'Times', '', 10, certificate_get_code($certificate, $certrecord)); 102 | $i = 0; 103 | if ($certificate->printteacher) { 104 | $context = context_module::instance($cm->id); 105 | if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { 106 | foreach ($teachers as $teacher) { 107 | $i++; 108 | certificate_print_text($pdf, $sigx, $sigy + ($i * 12), 'L', 'Times', '', 12, fullname($teacher)); 109 | } 110 | } 111 | } 112 | 113 | certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); 114 | -------------------------------------------------------------------------------- /upload_image.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Handles uploading files 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | require('../../config.php'); 27 | require_once($CFG->dirroot.'/mod/certificate/locallib.php'); 28 | require_once($CFG->dirroot.'/mod/certificate/upload_image_form.php'); 29 | 30 | require_login(); 31 | 32 | $context = context_system::instance(); 33 | require_capability('moodle/site:config', $context); 34 | 35 | $struploadimage = get_string('uploadimage', 'certificate'); 36 | 37 | $PAGE->set_url('/admin/settings.php', array('section' => 'modsettingcertificate')); 38 | $PAGE->set_pagetype('admin-setting-modsettingcertificate'); 39 | $PAGE->set_pagelayout('admin'); 40 | $PAGE->set_context($context); 41 | $PAGE->set_title($struploadimage); 42 | $PAGE->set_heading($SITE->fullname); 43 | $PAGE->navbar->add($struploadimage); 44 | 45 | $upload_form = new mod_certificate_upload_image_form(); 46 | 47 | if ($upload_form->is_cancelled()) { 48 | redirect(new moodle_url('/admin/settings.php?section=modsettingcertificate')); 49 | } else if ($data = $upload_form->get_data()) { 50 | // Ensure the directory for storing is created 51 | $uploaddir = "mod/certificate/pix/$data->imagetype"; 52 | $filename = $upload_form->get_new_filename('certificateimage'); 53 | make_upload_directory($uploaddir); 54 | $destination = $CFG->dataroot . '/' . $uploaddir . '/' . $filename; 55 | if (!$upload_form->save_file('certificateimage', $destination, true)) { 56 | throw new coding_exception('File upload failed'); 57 | } 58 | 59 | redirect(new moodle_url('/admin/settings.php?section=modsettingcertificate'), get_string('changessaved')); 60 | } 61 | 62 | echo $OUTPUT->header(); 63 | echo $upload_form->display(); 64 | echo $OUTPUT->footer(); 65 | -------------------------------------------------------------------------------- /upload_image_form.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Handles uploading files 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | if (!defined('MOODLE_INTERNAL')) { 27 | die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page 28 | } 29 | 30 | require_once($CFG->libdir.'/formslib.php'); 31 | require_once($CFG->dirroot.'/mod/certificate/locallib.php'); 32 | 33 | class mod_certificate_upload_image_form extends moodleform { 34 | 35 | function definition() { 36 | global $CFG; 37 | 38 | $mform =& $this->_form; 39 | 40 | $imagetypes = array( 41 | CERT_IMAGE_BORDER => get_string('border', 'certificate'), 42 | CERT_IMAGE_WATERMARK => get_string('watermark', 'certificate'), 43 | CERT_IMAGE_SIGNATURE => get_string('signature', 'certificate'), 44 | CERT_IMAGE_SEAL => get_string('seal', 'certificate') 45 | ); 46 | 47 | $mform->addElement('select', 'imagetype', get_string('imagetype', 'certificate'), $imagetypes); 48 | 49 | $mform->addElement('filepicker', 'certificateimage', ''); 50 | $mform->addRule('certificateimage', null, 'required', null, 'client'); 51 | 52 | $this->add_action_buttons(); 53 | } 54 | 55 | /** 56 | * Some validation - Michael Avelar 57 | */ 58 | function validation($data, $files) { 59 | $errors = parent::validation($data, $files); 60 | 61 | $supportedtypes = array('jpe' => 'image/jpeg', 62 | 'jpeIE' => 'image/pjpeg', 63 | 'jpeg' => 'image/jpeg', 64 | 'jpegIE' => 'image/pjpeg', 65 | 'jpg' => 'image/jpeg', 66 | 'jpgIE' => 'image/pjpeg', 67 | 'png' => 'image/png', 68 | 'pngIE' => 'image/x-png'); 69 | 70 | $files = $this->get_draft_files('certificateimage'); 71 | if ($files) { 72 | foreach ($files as $file) { 73 | if (!in_array($file->get_mimetype(), $supportedtypes)) { 74 | $errors['certificateimage'] = get_string('unsupportedfiletype', 'certificate'); 75 | } 76 | } 77 | } else { 78 | $errors['certificateimage'] = get_string('nofileselected', 'certificate'); 79 | } 80 | 81 | return $errors; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /version.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Code fragment to define the version of the certificate module 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late 24 | */ 25 | 26 | defined('MOODLE_INTERNAL') || die(); 27 | 28 | $plugin->version = 2020082500; // The current module version (Date: YYYYMMDDXX) 29 | $plugin->requires = 2016052300; // Requires this Moodle version (3.1) 30 | $plugin->cron = 0; // Period for cron to check this module (secs) 31 | $plugin->component = 'mod_certificate'; 32 | 33 | $plugin->maturity = MATURITY_STABLE; 34 | $plugin->release = "Master (Build: 2020082500)"; // User-friendly version number 35 | -------------------------------------------------------------------------------- /view.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | /** 19 | * Handles viewing a certificate 20 | * 21 | * @package mod_certificate 22 | * @copyright Mark Nelson 23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 | */ 25 | 26 | require_once("../../config.php"); 27 | require_once("$CFG->dirroot/mod/certificate/locallib.php"); 28 | require_once("$CFG->dirroot/mod/certificate/deprecatedlib.php"); 29 | require_once("$CFG->libdir/pdflib.php"); 30 | 31 | $id = required_param('id', PARAM_INT); // Course Module ID 32 | $action = optional_param('action', '', PARAM_ALPHA); 33 | $edit = optional_param('edit', -1, PARAM_BOOL); 34 | 35 | if (!$cm = get_coursemodule_from_id('certificate', $id)) { 36 | print_error('Course Module ID was incorrect'); 37 | } 38 | if (!$course = $DB->get_record('course', array('id'=> $cm->course))) { 39 | print_error('course is misconfigured'); 40 | } 41 | if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) { 42 | print_error('course module is incorrect'); 43 | } 44 | 45 | require_login($course, false, $cm); 46 | $context = context_module::instance($cm->id); 47 | require_capability('mod/certificate:view', $context); 48 | 49 | $event = \mod_certificate\event\course_module_viewed::create(array( 50 | 'objectid' => $certificate->id, 51 | 'context' => $context, 52 | )); 53 | $event->add_record_snapshot('course', $course); 54 | $event->add_record_snapshot('certificate', $certificate); 55 | $event->trigger(); 56 | 57 | $completion=new completion_info($course); 58 | $completion->set_module_viewed($cm); 59 | 60 | // Initialize $PAGE, compute blocks 61 | $PAGE->set_url('/mod/certificate/view.php', array('id' => $cm->id)); 62 | $PAGE->set_context($context); 63 | $PAGE->set_cm($cm); 64 | $PAGE->set_title(format_string($certificate->name)); 65 | $PAGE->set_heading(format_string($course->fullname)); 66 | 67 | if (($edit != -1) and $PAGE->user_allowed_editing()) { 68 | $USER->editing = $edit; 69 | } 70 | 71 | // Add block editing button 72 | if ($PAGE->user_allowed_editing()) { 73 | $editvalue = $PAGE->user_is_editing() ? 'off' : 'on'; 74 | $strsubmit = $PAGE->user_is_editing() ? get_string('blockseditoff') : get_string('blocksediton'); 75 | $url = new moodle_url($CFG->wwwroot . '/mod/certificate/view.php', array('id' => $cm->id, 'edit' => $editvalue)); 76 | $PAGE->set_button($OUTPUT->single_button($url, $strsubmit)); 77 | } 78 | 79 | // Check if the user can view the certificate 80 | if ($certificate->requiredtime && !has_capability('mod/certificate:manage', $context)) { 81 | if (certificate_get_course_time($course->id) < ($certificate->requiredtime * 60)) { 82 | $a = new stdClass; 83 | $a->requiredtime = $certificate->requiredtime; 84 | notice(get_string('requiredtimenotmet', 'certificate', $a), "$CFG->wwwroot/course/view.php?id=$course->id"); 85 | die; 86 | } 87 | } 88 | 89 | // Create new certificate record, or return existing record 90 | $certrecord = certificate_get_issue($course, $USER, $certificate, $cm); 91 | 92 | make_cache_directory('tcpdf'); 93 | 94 | // Load the specific certificate type. 95 | require("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php"); 96 | 97 | if (empty($action)) { // Not displaying PDF 98 | echo $OUTPUT->header(); 99 | 100 | $viewurl = new moodle_url('/mod/certificate/view.php', array('id' => $cm->id)); 101 | groups_print_activity_menu($cm, $viewurl); 102 | $currentgroup = groups_get_activity_group($cm); 103 | $groupmode = groups_get_activity_groupmode($cm); 104 | 105 | if (has_capability('mod/certificate:manage', $context)) { 106 | $numusers = count(certificate_get_issues($certificate->id, 'ci.timecreated ASC', $groupmode, $cm)); 107 | $url = html_writer::tag('a', get_string('viewcertificateviews', 'certificate', $numusers), 108 | array('href' => $CFG->wwwroot . '/mod/certificate/report.php?id=' . $cm->id)); 109 | echo html_writer::tag('div', $url, array('class' => 'reportlink')); 110 | } 111 | 112 | if (!empty($certificate->intro)) { 113 | echo $OUTPUT->box(format_module_intro('certificate', $certificate, $cm->id), 'generalbox', 'intro'); 114 | } 115 | 116 | if ($attempts = certificate_get_attempts($certificate->id)) { 117 | echo certificate_print_attempts($course, $certificate, $attempts); 118 | } 119 | if ($certificate->delivery == 0) { 120 | $str = get_string('openwindow', 'certificate'); 121 | } elseif ($certificate->delivery == 1) { 122 | $str = get_string('opendownload', 'certificate'); 123 | } elseif ($certificate->delivery == 2) { 124 | $str = get_string('openemail', 'certificate'); 125 | } 126 | echo html_writer::tag('p', $str, array('style' => 'text-align:center')); 127 | $linkname = get_string('getcertificate', 'certificate'); 128 | 129 | $link = new moodle_url('/mod/certificate/view.php?id='.$cm->id.'&action=get'); 130 | $button = new single_button($link, $linkname); 131 | if ($certificate->delivery != 1) { 132 | $button->add_action(new popup_action('click', $link, 'view' . $cm->id, array('height' => 600, 'width' => 800))); 133 | } 134 | 135 | echo html_writer::tag('div', $OUTPUT->render($button), array('style' => 'text-align:center')); 136 | echo $OUTPUT->footer($course); 137 | exit; 138 | } else { // Output to pdf 139 | 140 | // No debugging here, sorry. 141 | $CFG->debugdisplay = 0; 142 | @ini_set('display_errors', '0'); 143 | @ini_set('log_errors', '1'); 144 | 145 | $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; 146 | 147 | // PDF contents are now in $file_contents as a string. 148 | $filecontents = $pdf->Output('', 'S'); 149 | 150 | if ($certificate->savecert == 1) { 151 | certificate_save_pdf($filecontents, $certrecord->id, $filename, $context->id); 152 | } 153 | 154 | if ($certificate->delivery == 0) { 155 | // Open in browser. 156 | send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); 157 | } elseif ($certificate->delivery == 1) { 158 | // Force download. 159 | send_file($filecontents, $filename, 0, 0, true, true, 'application/pdf'); 160 | } elseif ($certificate->delivery == 2) { 161 | certificate_email_student($course, $certificate, $certrecord, $context, $filecontents, $filename); 162 | // Open in browser after sending email. 163 | send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); 164 | } 165 | } 166 | --------------------------------------------------------------------------------